1.1.7多语言版本

This commit is contained in:
Mr.zhou 2024-08-16 18:41:40 +08:00
parent c11a46d012
commit b262a3cfd9
45 changed files with 990 additions and 93 deletions

View File

@ -251,6 +251,8 @@
CBC81FBA2C3694990028143B /* MPPositive_HomeSinglesTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBC81FB92C3694990028143B /* MPPositive_HomeSinglesTableViewCell.swift */; }; CBC81FBA2C3694990028143B /* MPPositive_HomeSinglesTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBC81FB92C3694990028143B /* MPPositive_HomeSinglesTableViewCell.swift */; };
CBC81FBC2C3696230028143B /* MPPositive_HomeSingleCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBC81FBB2C3696230028143B /* MPPositive_HomeSingleCollectionViewCell.swift */; }; CBC81FBC2C3696230028143B /* MPPositive_HomeSingleCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBC81FBB2C3696230028143B /* MPPositive_HomeSingleCollectionViewCell.swift */; };
CBCB8DD32C631CD200E6438D /* MPPositive_SearchHistoryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBCB8DD22C631CD200E6438D /* MPPositive_SearchHistoryView.swift */; }; CBCB8DD32C631CD200E6438D /* MPPositive_SearchHistoryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBCB8DD22C631CD200E6438D /* MPPositive_SearchHistoryView.swift */; };
CBCBA7D92C6DFD93004E5BEF /* MPPositive_SortTypeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBCBA7D82C6DFD93004E5BEF /* MPPositive_SortTypeViewController.swift */; };
CBCBA7DB2C6DFE31004E5BEF /* MPPositive_SortTypeTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBCBA7DA2C6DFE31004E5BEF /* MPPositive_SortTypeTableViewCell.swift */; };
CBD1E19F2C57650F00DF20E5 /* MP_IAPManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBD1E19E2C57650F00DF20E5 /* MP_IAPManager.swift */; }; CBD1E19F2C57650F00DF20E5 /* MP_IAPManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBD1E19E2C57650F00DF20E5 /* MP_IAPManager.swift */; };
CBD344DA2C3FACB30095F18F /* MPPositive_JsonGenres.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBD344D92C3FACB30095F18F /* MPPositive_JsonGenres.swift */; }; CBD344DA2C3FACB30095F18F /* MPPositive_JsonGenres.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBD344D92C3FACB30095F18F /* MPPositive_JsonGenres.swift */; };
CBD344DC2C3FCA270095F18F /* MPPositive_GridModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBD344DB2C3FCA270095F18F /* MPPositive_GridModel.swift */; }; CBD344DC2C3FCA270095F18F /* MPPositive_GridModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBD344DB2C3FCA270095F18F /* MPPositive_GridModel.swift */; };
@ -537,6 +539,8 @@
CBC81FB92C3694990028143B /* MPPositive_HomeSinglesTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPPositive_HomeSinglesTableViewCell.swift; sourceTree = "<group>"; }; CBC81FB92C3694990028143B /* MPPositive_HomeSinglesTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPPositive_HomeSinglesTableViewCell.swift; sourceTree = "<group>"; };
CBC81FBB2C3696230028143B /* MPPositive_HomeSingleCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPPositive_HomeSingleCollectionViewCell.swift; sourceTree = "<group>"; }; CBC81FBB2C3696230028143B /* MPPositive_HomeSingleCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPPositive_HomeSingleCollectionViewCell.swift; sourceTree = "<group>"; };
CBCB8DD22C631CD200E6438D /* MPPositive_SearchHistoryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPPositive_SearchHistoryView.swift; sourceTree = "<group>"; }; CBCB8DD22C631CD200E6438D /* MPPositive_SearchHistoryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPPositive_SearchHistoryView.swift; sourceTree = "<group>"; };
CBCBA7D82C6DFD93004E5BEF /* MPPositive_SortTypeViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPPositive_SortTypeViewController.swift; sourceTree = "<group>"; };
CBCBA7DA2C6DFE31004E5BEF /* MPPositive_SortTypeTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPPositive_SortTypeTableViewCell.swift; sourceTree = "<group>"; };
CBD1E19E2C57650F00DF20E5 /* MP_IAPManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MP_IAPManager.swift; sourceTree = "<group>"; }; CBD1E19E2C57650F00DF20E5 /* MP_IAPManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MP_IAPManager.swift; sourceTree = "<group>"; };
CBD344D92C3FACB30095F18F /* MPPositive_JsonGenres.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPPositive_JsonGenres.swift; sourceTree = "<group>"; }; CBD344D92C3FACB30095F18F /* MPPositive_JsonGenres.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPPositive_JsonGenres.swift; sourceTree = "<group>"; };
CBD344DB2C3FCA270095F18F /* MPPositive_GridModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPPositive_GridModel.swift; sourceTree = "<group>"; }; CBD344DB2C3FCA270095F18F /* MPPositive_GridModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPPositive_GridModel.swift; sourceTree = "<group>"; };
@ -895,6 +899,7 @@
CBAFCA662C0A10500054500E /* MPPositive_LibraryViewController.swift */, CBAFCA662C0A10500054500E /* MPPositive_LibraryViewController.swift */,
CB0033F32C294DBF00B18FD3 /* MPPositive_CustomPlayListViewController.swift */, CB0033F32C294DBF00B18FD3 /* MPPositive_CustomPlayListViewController.swift */,
CB0033FB2C29753D00B18FD3 /* MPPositive_PlayListMoreViewController.swift */, CB0033FB2C29753D00B18FD3 /* MPPositive_PlayListMoreViewController.swift */,
CBCBA7D82C6DFD93004E5BEF /* MPPositive_SortTypeViewController.swift */,
CB0033F72C29626900B18FD3 /* MPPositive_ChoosePlayListViewController.swift */, CB0033F72C29626900B18FD3 /* MPPositive_ChoosePlayListViewController.swift */,
CBAFCA682C0A10500054500E /* MPPositive_LoveSongsViewController.swift */, CBAFCA682C0A10500054500E /* MPPositive_LoveSongsViewController.swift */,
CBAFCA672C0A10500054500E /* MPPositive_LoveArtistsViewController.swift */, CBAFCA672C0A10500054500E /* MPPositive_LoveArtistsViewController.swift */,
@ -969,6 +974,7 @@
CB7FC5472C2AC25C00292A43 /* MPPositive_CenterListSearchView.swift */, CB7FC5472C2AC25C00292A43 /* MPPositive_CenterListSearchView.swift */,
CBAFCA7E2C0A10500054500E /* MPPositive_LibraryTableViewCell.swift */, CBAFCA7E2C0A10500054500E /* MPPositive_LibraryTableViewCell.swift */,
CBAFCA7F2C0A10500054500E /* MPPositive_LoveArtistTableViewCell.swift */, CBAFCA7F2C0A10500054500E /* MPPositive_LoveArtistTableViewCell.swift */,
CBCBA7DA2C6DFE31004E5BEF /* MPPositive_SortTypeTableViewCell.swift */,
); );
path = Center; path = Center;
sourceTree = "<group>"; sourceTree = "<group>";
@ -1521,6 +1527,7 @@
CB2CAAD82C5A1AC500EF691D /* MP_IAPViewController.swift in Sources */, CB2CAAD82C5A1AC500EF691D /* MP_IAPViewController.swift in Sources */,
CBC1FB7E2C509BB400AC0633 /* MPPositive_LibraryListViewModel.swift in Sources */, CBC1FB7E2C509BB400AC0633 /* MPPositive_LibraryListViewModel.swift in Sources */,
CBAFCB992C0A10500054500E /* MPSideA_CustomTabBarView.swift in Sources */, CBAFCB992C0A10500054500E /* MPSideA_CustomTabBarView.swift in Sources */,
CBCBA7DB2C6DFE31004E5BEF /* MPPositive_SortTypeTableViewCell.swift in Sources */,
CB0B368F2C65B026004036E2 /* MP_WaveAnimationMaskView.swift in Sources */, CB0B368F2C65B026004036E2 /* MP_WaveAnimationMaskView.swift in Sources */,
CBAFCB342C0A10500054500E /* MPPositive_DownloadViewModel.swift in Sources */, CBAFCB342C0A10500054500E /* MPPositive_DownloadViewModel.swift in Sources */,
CBAFCB1E2C0A10500054500E /* MPPositive_JsonRecommend.swift in Sources */, CBAFCB1E2C0A10500054500E /* MPPositive_JsonRecommend.swift in Sources */,
@ -1613,6 +1620,7 @@
CBAFCB9B2C0A10500054500E /* MPSideA_CenterTableViewCell.swift in Sources */, CBAFCB9B2C0A10500054500E /* MPSideA_CenterTableViewCell.swift in Sources */,
CBC3F2B22C3E76160075DC74 /* MPPositive_AdModelModel.swift in Sources */, CBC3F2B22C3E76160075DC74 /* MPPositive_AdModelModel.swift in Sources */,
CBAFCB412C0A10500054500E /* MPPositive_BaseViewController.swift in Sources */, CBAFCB412C0A10500054500E /* MPPositive_BaseViewController.swift in Sources */,
CBCBA7D92C6DFD93004E5BEF /* MPPositive_SortTypeViewController.swift in Sources */,
CBAFCB4E2C0A10500054500E /* MPPositive_PlayerListShowViewController.swift in Sources */, CBAFCB4E2C0A10500054500E /* MPPositive_PlayerListShowViewController.swift in Sources */,
CBD1E19F2C57650F00DF20E5 /* MP_IAPManager.swift in Sources */, CBD1E19F2C57650F00DF20E5 /* MP_IAPManager.swift in Sources */,
CBAFCB8B2C0A10500054500E /* MPSideA_ServiceViewController.swift in Sources */, CBAFCB8B2C0A10500054500E /* MPSideA_ServiceViewController.swift in Sources */,
@ -1871,7 +1879,7 @@
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CODE_SIGN_STYLE = Manual; CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 1.1.6.1; CURRENT_PROJECT_VERSION = 1.1.7.1;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = ""; DEVELOPMENT_TEAM = "";
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = RAQJ4FNZUH; "DEVELOPMENT_TEAM[sdk=iphoneos*]" = RAQJ4FNZUH;
@ -1892,7 +1900,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.1.6; MARKETING_VERSION = 1.1.7;
PRODUCT_BUNDLE_IDENTIFIER = relax.offline.mp3.music; PRODUCT_BUNDLE_IDENTIFIER = relax.offline.mp3.music;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = ""; PROVISIONING_PROFILE_SPECIFIER = "";
@ -1917,7 +1925,7 @@
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CODE_SIGN_STYLE = Manual; CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 1.1.6.1; CURRENT_PROJECT_VERSION = 1.1.7.1;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = ""; DEVELOPMENT_TEAM = "";
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = RAQJ4FNZUH; "DEVELOPMENT_TEAM[sdk=iphoneos*]" = RAQJ4FNZUH;
@ -1938,7 +1946,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.1.6; MARKETING_VERSION = 1.1.7;
PRODUCT_BUNDLE_IDENTIFIER = relax.offline.mp3.music; PRODUCT_BUNDLE_IDENTIFIER = relax.offline.mp3.music;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = ""; PROVISIONING_PROFILE_SPECIFIER = "";

View File

@ -0,0 +1,22 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "Frame@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "Frame@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 634 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -0,0 +1,22 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "Group_1597880550@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "Group_1597880550@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

@ -0,0 +1,22 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "Frame_1@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "Frame_1@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 665 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -0,0 +1,22 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "Frame_2@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "Frame_2@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 658 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="22757" systemVersion="23E224" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier=""> <model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="22757" systemVersion="23E224" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier="">
<entity name="MPPositive_CollectionArtistModel" representedClassName="MPPositive_CollectionArtistModel" syncable="YES"> <entity name="MPPositive_CollectionArtistModel" representedClassName="MPPositive_CollectionArtistModel" syncable="YES">
<attribute name="addTime" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
<attribute name="artistId" optional="YES" attributeType="String"/> <attribute name="artistId" optional="YES" attributeType="String"/>
<attribute name="coverImage" optional="YES" attributeType="URI"/> <attribute name="coverImage" optional="YES" attributeType="URI"/>
<attribute name="subtitle" optional="YES" attributeType="String"/> <attribute name="subtitle" optional="YES" attributeType="String"/>
@ -14,6 +15,7 @@
<attribute name="title" optional="YES" attributeType="String"/> <attribute name="title" optional="YES" attributeType="String"/>
</entity> </entity>
<entity name="MPPositive_CollectionSongModel" representedClassName="MPPositive_CollectionSongModel" syncable="YES"> <entity name="MPPositive_CollectionSongModel" representedClassName="MPPositive_CollectionSongModel" syncable="YES">
<attribute name="addTime" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
<attribute name="coverImage" optional="YES" attributeType="URI"/> <attribute name="coverImage" optional="YES" attributeType="URI"/>
<attribute name="lyricsID" optional="YES" attributeType="String"/> <attribute name="lyricsID" optional="YES" attributeType="String"/>
<attribute name="relatedID" optional="YES" attributeType="String"/> <attribute name="relatedID" optional="YES" attributeType="String"/>
@ -24,6 +26,7 @@
<entity name="MPPositive_CustomPlayListModel" representedClassName="MPPositive_CustomPlayListModel" syncable="YES"> <entity name="MPPositive_CustomPlayListModel" representedClassName="MPPositive_CustomPlayListModel" syncable="YES">
<attribute name="createTime" optional="YES" attributeType="Date" usesScalarValueType="NO"/> <attribute name="createTime" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
<attribute name="playListId" optional="YES" attributeType="String"/> <attribute name="playListId" optional="YES" attributeType="String"/>
<attribute name="sortType" optional="YES" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="YES"/>
<attribute name="title" optional="YES" attributeType="String"/> <attribute name="title" optional="YES" attributeType="String"/>
<relationship name="videos" optional="YES" toMany="YES" deletionRule="Cascade" destinationEntity="MPPositive_CustomVideoModel" inverseName="playList" inverseEntity="MPPositive_CustomVideoModel"/> <relationship name="videos" optional="YES" toMany="YES" deletionRule="Cascade" destinationEntity="MPPositive_CustomVideoModel" inverseName="playList" inverseEntity="MPPositive_CustomVideoModel"/>
</entity> </entity>
@ -38,6 +41,7 @@
<relationship name="playList" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="MPPositive_CustomPlayListModel" inverseName="videos" inverseEntity="MPPositive_CustomPlayListModel"/> <relationship name="playList" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="MPPositive_CustomPlayListModel" inverseName="videos" inverseEntity="MPPositive_CustomPlayListModel"/>
</entity> </entity>
<entity name="MPPositive_DownloadItemModel" representedClassName="MPPositive_DownloadItemModel" syncable="YES"> <entity name="MPPositive_DownloadItemModel" representedClassName="MPPositive_DownloadItemModel" syncable="YES">
<attribute name="addTime" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
<attribute name="coverImage" optional="YES" attributeType="String"/> <attribute name="coverImage" optional="YES" attributeType="String"/>
<attribute name="lengthText" optional="YES" attributeType="String"/> <attribute name="lengthText" optional="YES" attributeType="String"/>
<attribute name="longBylineText" optional="YES" attributeType="String"/> <attribute name="longBylineText" optional="YES" attributeType="String"/>

View File

@ -101,7 +101,7 @@
///播放列表 ///播放列表
"Playlists" = "قائمة التشغيل"; "Playlists" = "قائمة التشغيل";
///收藏播放列表 ///收藏播放列表
"Collect PlayLists" = "قائمة التشغيل المفضلة"; "Collect Playlists" = "قائمة التشغيل المفضلة";
///命名您的播放列表 ///命名您的播放列表
"Name Your PlayList" = "قم بتسمية قائمة التشغيل الخاصة بك"; "Name Your PlayList" = "قم بتسمية قائمة التشغيل الخاصة بك";
///删除这首歌曲 ///删除这首歌曲
@ -112,6 +112,20 @@
"Cancel Song Download Task" = "إلغاء مهمة تنزيل الأغنية"; "Cancel Song Download Task" = "إلغاء مهمة تنزيل الأغنية";
///您确定要取消这首歌曲的下载任务吗? ///您确定要取消这首歌曲的下载任务吗?
"Are you sure you want to cancel the download task of this song?" = "هل أنت متأكد أنك تريد إلغاء مهمة التنزيل لهذه الأغنية؟"; "Are you sure you want to cancel the download task of this song?" = "هل أنت متأكد أنك تريد إلغاء مهمة التنزيل لهذه الأغنية؟";
///修改名字
"Modify Title" = "تعديل العنوان";
///更改排序
"Change Sort" = "تغيير النوع";
///删除列表
"Delete List" = "حذف القائمة";
///从新到旧排序
"Sort by newest to oldest" = "الترتيب من الأحدث إلى الأقدم";
///从旧到新排序
"Sort by oldest to newest" = "الترتيب من الأقدم إلى الأحدث";
///以标题排序
"Sort by title" = "الترتيب حسب العنوان";
///以艺术家排序
"Sort by artist" = "الترتيب حسب الفنان";
//MARK: - HUD文本 //MARK: - HUD文本
///已成功将电子邮件地址复制到剪贴板 ///已成功将电子邮件地址复制到剪贴板
"Successfully copied the e-mail address to the clipboard" = "تم نسخ عنوان البريد الإلكتروني بنجاح إلى الحافظة"; "Successfully copied the e-mail address to the clipboard" = "تم نسخ عنوان البريد الإلكتروني بنجاح إلى الحافظة";

View File

@ -112,6 +112,20 @@
"Cancel Song Download Task" = "Song-Download-Aufgabe abbrechen"; "Cancel Song Download Task" = "Song-Download-Aufgabe abbrechen";
///您确定要取消这首歌曲的下载任务吗? ///您确定要取消这首歌曲的下载任务吗?
"Are you sure you want to cancel the download task of this song?" = "Möchten Sie den Download-Auftrag für diesen Song wirklich abbrechen?"; "Are you sure you want to cancel the download task of this song?" = "Möchten Sie den Download-Auftrag für diesen Song wirklich abbrechen?";
///修改名字
"Modify Title" = "Titel ändern";
///更改排序
"Change Sort" = "Sortierung ändern";
///删除列表
"Delete List" = "Liste löschen";
///从新到旧排序
"Sort by newest to oldest" = "Sortieren Sie vom Neuesten zum Ältesten";
///从旧到新排序
"Sort by oldest to newest" = "Sortieren Sie vom Ältesten zum Neuesten";
///以标题排序
"Sort by title" = "Nach Titel sortieren";
///以艺术家排序
"Sort by artist" = "Nach Künstler sortieren";
//MARK: - HUD文本 //MARK: - HUD文本
///已成功将电子邮件地址复制到剪贴板 ///已成功将电子邮件地址复制到剪贴板
"Successfully copied the e-mail address to the clipboard" = "E-Mail-Adresse erfolgreich in die Zwischenablage kopiert"; "Successfully copied the e-mail address to the clipboard" = "E-Mail-Adresse erfolgreich in die Zwischenablage kopiert";

View File

@ -112,6 +112,20 @@
"Cancel Song Download Task" = "Cancel Song Download Task"; "Cancel Song Download Task" = "Cancel Song Download Task";
///您确定要取消这首歌曲的下载任务吗? ///您确定要取消这首歌曲的下载任务吗?
"Are you sure you want to cancel the download task of this song?" = "Are you sure you want to cancel the download task of this song?"; "Are you sure you want to cancel the download task of this song?" = "Are you sure you want to cancel the download task of this song?";
///修改名字
"Modify Title" = "Modify Title";
///更改排序
"Change Sort" = "Change Sort";
///删除列表
"Delete List" = "Delete List";
///从新到旧排序
"Sort by newest to oldest" = "Sort by newest to oldest";
///从旧到新排序
"Sort by oldest to newest" = "Sort by oldest to newest";
///以标题排序
"Sort by title" = "Sort by title";
///以艺术家排序
"Sort by artist" = "Sort by artist";
//MARK: - HUD文本 //MARK: - HUD文本
///已成功将电子邮件地址复制到剪贴板 ///已成功将电子邮件地址复制到剪贴板
"Successfully copied the e-mail address to the clipboard" = "Successfully copied the e-mail address to the clipboard"; "Successfully copied the e-mail address to the clipboard" = "Successfully copied the e-mail address to the clipboard";

View File

@ -112,6 +112,20 @@
"Cancel Song Download Task" = "Cancelar tarea de descarga de canción"; "Cancel Song Download Task" = "Cancelar tarea de descarga de canción";
///您确定要取消这首歌曲的下载任务吗? ///您确定要取消这首歌曲的下载任务吗?
"Are you sure you want to cancel the download task of this song?" = "¿Estás seguro de que deseas cancelar la tarea de descarga de esta canción?"; "Are you sure you want to cancel the download task of this song?" = "¿Estás seguro de que deseas cancelar la tarea de descarga de esta canción?";
///修改名字
"Modify Title" = "Modificar título";
///更改排序
"Change Sort" = "Cambiar Tipo";
///删除列表
"Delete List" = "Eliminar Lista";
///从新到旧排序
"Sort by newest to oldest" = "Ordenar del más nuevo al más antiguo";
///从旧到新排序
"Sort by oldest to newest" = "Ordenar del más antiguo al más nuevo";
///以标题排序
"Sort by title" = "Ordenar por título";
///以艺术家排序
"Sort by artist" = "Ordenar por artista";
//MARK: - HUD文本 //MARK: - HUD文本
///已成功将电子邮件地址复制到剪贴板 ///已成功将电子邮件地址复制到剪贴板
"Successfully copied the e-mail address to the clipboard" = "Dirección de correo electrónico copiada correctamente al portapapeles"; "Successfully copied the e-mail address to the clipboard" = "Dirección de correo electrónico copiada correctamente al portapapeles";

View File

@ -112,6 +112,20 @@
"Cancel Song Download Task" = "Annuler la tâche de téléchargement de chanson"; "Cancel Song Download Task" = "Annuler la tâche de téléchargement de chanson";
///您确定要取消这首歌曲的下载任务吗? ///您确定要取消这首歌曲的下载任务吗?
"Are you sure you want to cancel the download task of this song?" = "Êtes-vous sûr de vouloir annuler la tâche de téléchargement de cette chanson ?"; "Are you sure you want to cancel the download task of this song?" = "Êtes-vous sûr de vouloir annuler la tâche de téléchargement de cette chanson ?";
///修改名字
"Modify Title" = "Modifier le titre";
///更改排序
"Change Sort" = "Changer le tri";
///删除列表
"Delete List" = "Supprimer la liste";
///从新到旧排序
"Sort by newest to oldest" = "Trier du plus récent au plus ancien";
///从旧到新排序
"Sort by oldest to newest" = "Trier du plus ancien au plus récent";
///以标题排序
"Sort by title" = "Trier par titre";
///以艺术家排序
"Sort by artist" = "Trier par artiste";
//MARK: - HUD文本 //MARK: - HUD文本
///已成功将电子邮件地址复制到剪贴板 ///已成功将电子邮件地址复制到剪贴板
"Successfully copied the e-mail address to the clipboard" = "Adresse e-mail copiée avec succès dans le presse-papiers"; "Successfully copied the e-mail address to the clipboard" = "Adresse e-mail copiée avec succès dans le presse-papiers";

View File

@ -112,6 +112,20 @@
"Cancel Song Download Task" = "Annulla l'attività di download del brano"; "Cancel Song Download Task" = "Annulla l'attività di download del brano";
///您确定要取消这首歌曲的下载任务吗? ///您确定要取消这首歌曲的下载任务吗?
"Are you sure you want to cancel the download task of this song?" = "Sei sicuro di voler annullare l'attività di download per questo brano?"; "Are you sure you want to cancel the download task of this song?" = "Sei sicuro di voler annullare l'attività di download per questo brano?";
///修改名字
"Modify Title" = "Modifica titolo";
///更改排序
"Change Sort" = "Cambia ordinamento";
///删除列表
"Delete List" = "Eliminare l'elenco";
///从新到旧排序
"Sort by newest to oldest" = "Ordina dal più recente al più vecchio";
///从旧到新排序
"Sort by oldest to newest" = "Ordina dal più vecchio al più recente";
///以标题排序
"Sort by title" = "Ordina per titolo";
///以艺术家排序
"Sort by artist" = "Ordina per artista";
//MARK: - HUD文本 //MARK: - HUD文本
///已成功将电子邮件地址复制到剪贴板 ///已成功将电子邮件地址复制到剪贴板
"Successfully copied the e-mail address to the clipboard" = "Indirizzo email copiato con successo negli appunti"; "Successfully copied the e-mail address to the clipboard" = "Indirizzo email copiato con successo negli appunti";

View File

@ -112,6 +112,20 @@
"Cancel Song Download Task" = "Cancelar tarefa de download de música"; "Cancel Song Download Task" = "Cancelar tarefa de download de música";
///您确定要取消这首歌曲的下载任务吗? ///您确定要取消这首歌曲的下载任务吗?
"Are you sure you want to cancel the download task of this song?" = "Tem certeza de que deseja cancelar a tarefa de download desta música?"; "Are you sure you want to cancel the download task of this song?" = "Tem certeza de que deseja cancelar a tarefa de download desta música?";
///修改名字
"Modify Title" = "Modificar título";
///更改排序
"Change Sort" = "Alterar classificação";
///删除列表
"Delete List" = "Excluir lista";
///从新到旧排序
"Sort by newest to oldest" = "Classifique do mais recente para o mais antigo";
///从旧到新排序
"Sort by oldest to newest" = "Ordenar do mais antigo para o mais recente";
///以标题排序
"Sort by title" = "Classificar por título";
///以艺术家排序
"Sort by artist" = "Classificar por artista";
//MARK: - HUD文本 //MARK: - HUD文本
///已成功将电子邮件地址复制到剪贴板 ///已成功将电子邮件地址复制到剪贴板
"Successfully copied the e-mail address to the clipboard" = "Endereço de e-mail copiado com sucesso para a área de transferência"; "Successfully copied the e-mail address to the clipboard" = "Endereço de e-mail copiado com sucesso para a área de transferência";

View File

@ -112,6 +112,20 @@
"Cancel Song Download Task" = "Şarkı indirme görevini iptal et"; "Cancel Song Download Task" = "Şarkı indirme görevini iptal et";
///您确定要取消这首歌曲的下载任务吗? ///您确定要取消这首歌曲的下载任务吗?
"Are you sure you want to cancel the download task of this song?" = "Bu şarkının indirme görevini iptal etmek istediğinizden emin misiniz?"; "Are you sure you want to cancel the download task of this song?" = "Bu şarkının indirme görevini iptal etmek istediğinizden emin misiniz?";
///修改名字
"Modify Title" = "Başlığı değiştir";
///更改排序
"Change Sort" = "Sıralamayı değiştir";
///删除列表
"Delete List" = "Listeyi sil";
///从新到旧排序
"Sort by newest to oldest" = "En yeniden en eskiye doğru sırala";
///从旧到新排序
"Sort by oldest to newest" = "En eskiden en yeniye doğru sırala";
///以标题排序
"Sort by title" = "Başlığa göre sırala";
///以艺术家排序
"Sort by artist" = "Sanatçıya göre sırala";
//MARK: - HUD文本 //MARK: - HUD文本
///已成功将电子邮件地址复制到剪贴板 ///已成功将电子邮件地址复制到剪贴板
"Successfully copied the e-mail address to the clipboard" = "Herhangi bir yorumunuz veya öneriniz varsa lütfen aşağıdaki e-posta adresinden bizimle iletişime geçin."; "Successfully copied the e-mail address to the clipboard" = "Herhangi bir yorumunuz veya öneriniz varsa lütfen aşağıdaki e-posta adresinden bizimle iletişime geçin.";

View File

@ -443,6 +443,7 @@ func saveLoadVideoItem(_ song:MPPositive_SongItemModel, completion:(() -> Void)?
item.lyricsID = song.lyricsID item.lyricsID = song.lyricsID
item.videoId = song.videoId item.videoId = song.videoId
item.relatedID = song.relatedID item.relatedID = song.relatedID
item.addTime = Date()
// //
MPPositive_DownloadItemModel.save() MPPositive_DownloadItemModel.save()
completion?() completion?()

View File

@ -21,7 +21,7 @@ class MP_AdMobManager: NSObject, GADAudioVideoManagerDelegate, GADFullScreenCont
///广 ///广
private var openAdStatus:Bool = true private var openAdStatus:Bool = true
///使广 ///使广
private var internalAdStatus:Bool = false private var internalAdStatus:Bool = true
///广 ///广
func setOpenAdStatus(_ bool:Bool) { func setOpenAdStatus(_ bool:Bool) {
DispatchQueue.main.async { DispatchQueue.main.async {

View File

@ -16,6 +16,12 @@ class MP_CoreDataHandlerManager {
lazy var persistentContainer: NSPersistentContainer = { lazy var persistentContainer: NSPersistentContainer = {
//XXX.cdatamodeldXXX //XXX.cdatamodeldXXX
let container = NSPersistentContainer(name: "relax.offline.mp3") let container = NSPersistentContainer(name: "relax.offline.mp3")
//
let description = container.persistentStoreDescriptions.first
//
description?.shouldMigrateStoreAutomatically = true
//
description?.shouldInferMappingModelAutomatically = true
container.loadPersistentStores { (_, error) in container.loadPersistentStores { (_, error) in
if let error = error { if let error = error {
// //

View File

@ -200,9 +200,9 @@ class MP_NetWorkManager: NSObject {
self.monitor = NWPathMonitor() self.monitor = NWPathMonitor()
super.init() super.init()
reloadVersion() reloadVersion()
if let string = UserDefaults.standard.string(forKey: "Visitor_Data") { // if let string = UserDefaults.standard.string(forKey: "Visitor_Data") {
self.visitorData = string // self.visitorData = string
} // }
} }
// //
func reloadVersion() { func reloadVersion() {
@ -312,7 +312,11 @@ extension MP_NetWorkManager {
guard let data = value.data, let code = data.isoCode else { guard let data = value.data, let code = data.isoCode else {
return return
} }
if codes.contains(code) {
locaton = code locaton = code
}else {
locaton = "US"
}
if banIPs.contains(code) == true { if banIPs.contains(code) == true {
// //
completion(false) completion(false)
@ -353,7 +357,7 @@ extension MP_NetWorkManager {
"client":[ "client":[
//web //web
"clientName": "WEB_REMIX", "clientName": "WEB_REMIX",
"visitorData":visitorData ?? "", // "visitorData":visitorData ?? "",
//访 //访
"clientVersion": clientVersion, "clientVersion": clientVersion,
"platform":"MOBILE", "platform":"MOBILE",
@ -379,7 +383,7 @@ extension MP_NetWorkManager {
if data != self.visitorData { if data != self.visitorData {
print("Visitor_Data更改了") print("Visitor_Data更改了")
self.visitorData = data self.visitorData = data
UserDefaults.standard.setValue(data, forKey: "Visitor_Data") // UserDefaults.standard.setValue(data, forKey: "Visitor_Data")
} }
} }
// //
@ -598,14 +602,14 @@ extension MP_NetWorkManager {
"browseId":browseId, "browseId":browseId,
"params":params, "params":params,
"prettyPrint":"false", "prettyPrint":"false",
"clickTracking":[ // "clickTracking":[
"clickTrackingParams": clickTrackingParams ?? "" // "clickTrackingParams": clickTrackingParams ?? ""
], // ],
"context":[ "context":[
"client":[ "client":[
//web //web
"clientName": "WEB_REMIX", "clientName": "WEB_REMIX",
"visitorData":visitorData, // "visitorData":visitorData,
//访 //访
"clientVersion": clientVersion, "clientVersion": clientVersion,
"platform":"MOBILE", "platform":"MOBILE",
@ -665,14 +669,14 @@ extension MP_NetWorkManager {
let parameters:[String:Any] = [ let parameters:[String:Any] = [
"browseId":browseId, "browseId":browseId,
"prettyPrint":"false", "prettyPrint":"false",
"clickTracking":[ // "clickTracking":[
"clickTrackingParams": clickTrackingParams ?? "" // "clickTrackingParams": clickTrackingParams ?? ""
], // ],
"context":[ "context":[
"client":[ "client":[
//web //web
"clientName": "WEB_REMIX", "clientName": "WEB_REMIX",
"visitorData":visitorData, // "visitorData":visitorData,
//访 //访
"clientVersion": clientVersion, "clientVersion": clientVersion,
"platform":"MOBILE", "platform":"MOBILE",
@ -728,7 +732,7 @@ extension MP_NetWorkManager {
"client":[ "client":[
//web //web
"clientName": "WEB_REMIX", "clientName": "WEB_REMIX",
"visitorData":visitorData, // "visitorData":visitorData,
//访 //访
"clientVersion": clientVersion, "clientVersion": clientVersion,
"platform":"MOBILE", "platform":"MOBILE",
@ -781,7 +785,7 @@ extension MP_NetWorkManager {
"client":[ "client":[
//web //web
"clientName": "WEB_REMIX", "clientName": "WEB_REMIX",
"visitorData":visitorData, // "visitorData":visitorData,
//访 //访
"clientVersion": clientVersion, "clientVersion": clientVersion,
"platform":"MOBILE", "platform":"MOBILE",
@ -937,7 +941,7 @@ extension MP_NetWorkManager {
"client":[ "client":[
//web //web
"clientName": "WEB_REMIX", "clientName": "WEB_REMIX",
"visitorData":visitorData, // "visitorData":visitorData,
//访 //访
"clientVersion": clientVersion, "clientVersion": clientVersion,
"platform":"MOBILE", "platform":"MOBILE",
@ -1048,13 +1052,13 @@ extension MP_NetWorkManager {
let parameters:[String:Any] = [ let parameters:[String:Any] = [
"videoId":videoId, "videoId":videoId,
"prettyPrint":"false", "prettyPrint":"false",
"clickTracking":[ // "clickTracking":[
"clickTrackingParams": clickTrackingParams ?? "" // "clickTrackingParams": clickTrackingParams ?? ""
], // ],
"context":[ "context":[
"client":[ "client":[
"clientName": "ANDROID_MUSIC", "clientName": "ANDROID_MUSIC",
"visitorData":visitorData, // "visitorData":visitorData,
"clientVersion": playerVersion, "clientVersion": playerVersion,
"platform":"MOBILE", "platform":"MOBILE",
"browserVersion":"125.0.0.0", "browserVersion":"125.0.0.0",
@ -1327,7 +1331,7 @@ extension MP_NetWorkManager {
"client":[ "client":[
//web //web
"clientName": "WEB_REMIX", "clientName": "WEB_REMIX",
"visitorData":visitorData, // "visitorData":visitorData,
//访 //访
"clientVersion": clientVersion, "clientVersion": clientVersion,
"platform":"MOBILE", "platform":"MOBILE",
@ -1389,7 +1393,7 @@ extension MP_NetWorkManager {
"client":[ "client":[
//web //web
"clientName": "WEB_REMIX", "clientName": "WEB_REMIX",
"visitorData":visitorData, // "visitorData":visitorData,
//访 //访
"clientVersion": clientVersion, "clientVersion": clientVersion,
"platform":"DESKTOP", "platform":"DESKTOP",
@ -1452,7 +1456,7 @@ extension MP_NetWorkManager {
"client":[ "client":[
//web //web
"clientName": "WEB_REMIX", "clientName": "WEB_REMIX",
"visitorData":visitorData, // "visitorData":visitorData,
//访 //访
"clientVersion": clientVersion, "clientVersion": clientVersion,
"platform":"MOBILE", "platform":"MOBILE",

View File

@ -19,4 +19,6 @@ class MPPositive_CollectionArtistModel: NSManagedObject, MP_CoreDataManageableDe
@NSManaged var subtitle:String! @NSManaged var subtitle:String!
///Id ///Id
@NSManaged var artistId:String? @NSManaged var artistId:String?
///
@NSManaged var addTime:Date?
} }

View File

@ -23,4 +23,6 @@ class MPPositive_CollectionSongModel: NSManagedObject, MP_CoreDataManageableDele
@NSManaged var lyricsID:String? @NSManaged var lyricsID:String?
///ID ///ID
@NSManaged var relatedID:String? @NSManaged var relatedID:String?
///
@NSManaged var addTime:Date?
} }

View File

@ -18,6 +18,8 @@ class MPPositive_CustomPlayListModel: NSManagedObject, MP_CoreDataManageableDele
@NSManaged var title:String! @NSManaged var title:String!
/// ///
@NSManaged var createTime:Date! @NSManaged var createTime:Date!
///(010)
@NSManaged var sortType:NSNumber?
/// ///
@NSManaged var videos:NSSet! @NSManaged var videos:NSSet!

View File

@ -31,4 +31,6 @@ class MPPositive_DownloadItemModel: NSManagedObject, MP_CoreDataManageableDelega
@NSManaged var videoId:String! @NSManaged var videoId:String!
///ID ///ID
@NSManaged var relatedID:String! @NSManaged var relatedID:String!
///
@NSManaged var addTime:Date?
} }

View File

@ -9,9 +9,9 @@ import UIKit
///b ///b
class MPPositive_BaseViewController: MP_BaseViewController, UIGestureRecognizerDelegate { class MPPositive_BaseViewController: MP_BaseViewController, UIGestureRecognizerDelegate {
// //
private lazy var navTitleLabel:UILabel = createLabel(font: .systemFont(ofSize: 20*width, weight: .regular), textColor: .white, textAlignment: .center) lazy var navTitleLabel:UILabel = createLabel(font: .systemFont(ofSize: 20*width, weight: .regular), textColor: .white, textAlignment: .center)
//pop //pop
private lazy var popBtn:UIButton = { lazy var popBtn:UIButton = {
let btn = UIButton() let btn = UIButton()
btn.setBackgroundImage(UIImage(named: "Poplogo"), for: .normal) btn.setBackgroundImage(UIImage(named: "Poplogo"), for: .normal)
btn.addTarget(self, action: #selector(popActionClick(_ :)), for: .touchUpInside) btn.addTarget(self, action: #selector(popActionClick(_ :)), for: .touchUpInside)
@ -73,6 +73,7 @@ class MPPositive_BaseViewController: MP_BaseViewController, UIGestureRecognizerD
} }
//pop //pop
@objc func popActionClick(_ sender:UIButton) { @objc func popActionClick(_ sender:UIButton) {
view.endEditing(true)
MPPositive_Debouncer.shared.call(0.1) { MPPositive_Debouncer.shared.call(0.1) {
[weak self] in [weak self] in
guard let self = self else {return} guard let self = self else {return}

View File

@ -324,6 +324,7 @@ class MPPositive_MoreSongOperationsViewController: UIViewController, UIViewContr
item.videoId = song.videoId item.videoId = song.videoId
item.lyricsID = song.lyricsID item.lyricsID = song.lyricsID
item.relatedID = song.relatedID item.relatedID = song.relatedID
item.addTime = Date()
MPPositive_CollectionSongModel.save() MPPositive_CollectionSongModel.save()
MPPositive_LoadCoreModel.shared.reloadCollectionSongViewModel(nil) MPPositive_LoadCoreModel.shared.reloadCollectionSongViewModel(nil)
MP_AnalyticsManager.shared.player_b_love_clickAction(song.videoId, videoname: song.title ?? "", artistname: song.shortBylineText ?? "") MP_AnalyticsManager.shared.player_b_love_clickAction(song.videoId, videoname: song.title ?? "", artistname: song.shortBylineText ?? "")

View File

@ -16,6 +16,8 @@ enum MPPositive_PresentModal{
case NewList case NewList
/// ///
case PlayListEdit case PlayListEdit
///
case SortType
/// ///
case Guide case Guide
} }
@ -53,7 +55,7 @@ class MPPositive_PresentationController: UIPresentationController {
case .PlayListEdit: case .PlayListEdit:
presentedView?.snp.makeConstraints({ (make) in presentedView?.snp.makeConstraints({ (make) in
make.left.right.bottom.equalToSuperview() make.left.right.bottom.equalToSuperview()
make.height.equalTo(220*width+bottomPadding) make.height.equalTo(270*width+bottomPadding)
}) })
case .Guide: case .Guide:
presentedView?.snp.makeConstraints({ (make) in presentedView?.snp.makeConstraints({ (make) in
@ -61,6 +63,12 @@ class MPPositive_PresentationController: UIPresentationController {
make.width.equalTo(282*width) make.width.equalTo(282*width)
make.height.equalTo(354*width) make.height.equalTo(354*width)
}) })
case .SortType:
presentedView?.snp.makeConstraints({ (make) in
make.center.equalToSuperview()
make.width.equalTo(270*width)
make.height.equalTo(120*width)
})
} }
// //
setMask() setMask()

View File

@ -100,6 +100,7 @@ class MPPositive_ChoosePlayListViewController: UIViewController, UIViewControlle
list.playListId = Date().timeZone().toString(.custom("YYYY/MM/dd/HH:mm:ss")) list.playListId = Date().timeZone().toString(.custom("YYYY/MM/dd/HH:mm:ss"))
list.title = text list.title = text
list.createTime = Date().timeZone() list.createTime = Date().timeZone()
list.sortType = 0
list.addToRelationshipToCustomVideos([]) list.addToRelationshipToCustomVideos([])
MPPositive_CustomPlayListModel.save() MPPositive_CustomPlayListModel.save()
// //

View File

@ -111,7 +111,9 @@ class MPPositive_CustomPlayListViewController: MPPositive_BaseViewController, UI
// //
private var isSearchStyle:Bool = false private var isSearchStyle:Bool = false
//Videos //Videos
private var videos:[MPPositive_CustomVideoModel] = [] private var searchVideos:[MPPositive_CustomVideoModel] = []
//sortVideos
private var sortVideos:[MPPositive_CustomVideoModel] = []
init(_ playList:MPPositive_CustomPlayListModel) { init(_ playList:MPPositive_CustomPlayListModel) {
super.init(nibName: nil, bundle: nil) super.init(nibName: nil, bundle: nil)
DispatchQueue.main.async { DispatchQueue.main.async {
@ -119,6 +121,7 @@ class MPPositive_CustomPlayListViewController: MPPositive_BaseViewController, UI
guard let self = self else {return} guard let self = self else {return}
self.list = playList self.list = playList
} }
print("当前排序类型-\(playList.sortType ?? 0)")
setTitle("") setTitle("")
setPopBtn() setPopBtn()
configure() configure()
@ -132,20 +135,7 @@ class MPPositive_CustomPlayListViewController: MPPositive_BaseViewController, UI
searchShowView.cancelBlock = { searchShowView.cancelBlock = {
[weak self] in [weak self] in
guard let self = self else {return} guard let self = self else {return}
UIView.animate(withDuration: 0.2) { cancelSearchAction()
[weak self] in
guard let self = self else {return}
searchShowView.isUserInteractionEnabled = false
searchShowView.alpha = 0
isSearchStyle = false
} completion: { [weak self] statu in
guard let self = self else {return}
searchShowView.isHidden = true
playAllBtn.isUserInteractionEnabled = true
shuffleBtn.isUserInteractionEnabled = true
searchBtn.isUserInteractionEnabled = true
reload(list)
}
} }
searchShowView.textBlock = { searchShowView.textBlock = {
[weak self] (text) in [weak self] (text) in
@ -164,23 +154,28 @@ class MPPositive_CustomPlayListViewController: MPPositive_BaseViewController, UI
backImageView.kf.setImage(with: coverURL, placeholder: placeholderImage) backImageView.kf.setImage(with: coverURL, placeholder: placeholderImage)
coverImageView.kf.setImage(with: coverURL, placeholder: placeholderImage) coverImageView.kf.setImage(with: coverURL, placeholder: placeholderImage)
titleLabel.text = list.title titleLabel.text = list.title
switch list.sortType {
case 0:
self.sortVideos = list.videosArray
default:
self.sortVideos = list.videosArray.sorted(by: {$0.addTime < $1.addTime})
}
createTimeLabel.text = "Create Time: \(list.createTime.toString(.custom("YYYY/MM/dd-HH:mm")))" createTimeLabel.text = "Create Time: \(list.createTime.toString(.custom("YYYY/MM/dd-HH:mm")))"
playAllBtn.setTitle(" Play (\(list.videosArray.count))", for: .normal) playAllBtn.setTitle(" Play (\(self.sortVideos.count))", for: .normal)
tableView.reloadData() tableView.reloadData()
} }
// //
private func reloadSearch(_ text:String) { private func reloadSearch(_ text:String) {
if text.isEmpty { if text.isEmpty {
// //
videos = list.videosArray searchVideos = list.videosArray
}else { }else {
// //
videos = list.videosArray.filter({$0.title.contains(text) || $0.subtitle.contains(text)}) searchVideos = list.videosArray.filter({$0.title.contains(text) || $0.subtitle.contains(text)})
} }
// //
tableView.reloadSections(.init(integer: 0), with: .automatic) tableView.reloadSections(.init(integer: 0), with: .automatic)
} }
// //
private func configure() { private func configure() {
// //
@ -267,6 +262,9 @@ class MPPositive_CustomPlayListViewController: MPPositive_BaseViewController, UI
// //
@objc private func moreClick(_ sender:UIButton) { @objc private func moreClick(_ sender:UIButton) {
view.endEditing(true)
//
cancelSearchAction()
MPPositive_ModalType = .PlayListEdit MPPositive_ModalType = .PlayListEdit
// //
let moreVC = MPPositive_PlayListMoreViewController(list.title) let moreVC = MPPositive_PlayListMoreViewController(list.title)
@ -285,10 +283,43 @@ class MPPositive_CustomPlayListViewController: MPPositive_BaseViewController, UI
MPPositive_LoadCoreModel.shared.reloadCustomPlayLists(nil) MPPositive_LoadCoreModel.shared.reloadCustomPlayLists(nil)
navigationController?.popViewController(animated: true) navigationController?.popViewController(animated: true)
} }
moreVC.changeBlock = {
[weak self] in
guard let self = self else {return}
MPPositive_ModalType = .SortType
let sortVC = MPPositive_SortTypeViewController(Int(truncating: list.sortType ?? 0))
sortVC.chooseBlock = {
[weak self] (type) in
guard let self = self else {return}
list.sortType = (type) as NSNumber
MPPositive_CustomPlayListModel.save()
reload(list)
}
sortVC.transitioningDelegate = self
sortVC.modalPresentationStyle = .custom
present(sortVC, animated: true)
}
moreVC.transitioningDelegate = self moreVC.transitioningDelegate = self
moreVC.modalPresentationStyle = .custom moreVC.modalPresentationStyle = .custom
present(moreVC, animated: true) present(moreVC, animated: true)
} }
//
private func cancelSearchAction() {
UIView.animate(withDuration: 0.2) {
[weak self] in
guard let self = self else {return}
searchShowView.isUserInteractionEnabled = false
searchShowView.alpha = 0
isSearchStyle = false
} completion: { [weak self] statu in
guard let self = self else {return}
searchShowView.isHidden = true
playAllBtn.isUserInteractionEnabled = true
shuffleBtn.isUserInteractionEnabled = true
searchBtn.isUserInteractionEnabled = true
reload(list)
}
}
func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? { func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? {
return MPPositive_PresentationController(presentedViewController: presented, presenting: presenting) return MPPositive_PresentationController(presentedViewController: presented, presenting: presenting)
} }
@ -387,20 +418,20 @@ class MPPositive_CustomPlayListViewController: MPPositive_BaseViewController, UI
//MARK: - tableView //MARK: - tableView
extension MPPositive_CustomPlayListViewController: UITableViewDataSource, UITableViewDelegate { extension MPPositive_CustomPlayListViewController: UITableViewDataSource, UITableViewDelegate {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return isSearchStyle ? videos.count:list?.videosArray.count ?? 0 return isSearchStyle ? searchVideos.count:sortVideos.count
} }
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: MPPositive_SearchResultShowTableViewCellID, for: indexPath) as! MPPositive_SearchResultShowTableViewCell let cell = tableView.dequeueReusableCell(withIdentifier: MPPositive_SearchResultShowTableViewCellID, for: indexPath) as! MPPositive_SearchResultShowTableViewCell
if isSearchStyle { if isSearchStyle {
cell.videoModel = videos[indexPath.row] cell.videoModel = searchVideos[indexPath.row]
}else { }else {
cell.videoModel = list?.videosArray[indexPath.row] cell.videoModel = sortVideos[indexPath.row]
} }
cell.moreBlock = { cell.moreBlock = {
[weak self] in [weak self] in
guard let self = self else {return} guard let self = self else {return}
MPPositive_Debouncer.shared.call { MPPositive_Debouncer.shared.call {
let item = self.isSearchStyle ? self.videos[indexPath.row]:self.list?.videosArray[indexPath.row] let item = self.isSearchStyle ? self.searchVideos[indexPath.row]:self.sortVideos[indexPath.row]
MPPositive_ModalType = .MoreOperations MPPositive_ModalType = .MoreOperations
let moreVC = MPPositive_MoreSongOperationsViewController(self.list, video: item) let moreVC = MPPositive_MoreSongOperationsViewController(self.list, video: item)
moreVC.disMissBlock = { moreVC.disMissBlock = {
@ -419,7 +450,7 @@ extension MPPositive_CustomPlayListViewController: UITableViewDataSource, UITabl
let cancel = UIAlertAction(title: "Cancel".localizableString(), style: .cancel) let cancel = UIAlertAction(title: "Cancel".localizableString(), style: .cancel)
alertController.addAction(cancel) alertController.addAction(cancel)
let sure = UIAlertAction(title: "Confirm".localizableString(), style: .destructive) {(action) in let sure = UIAlertAction(title: "Confirm".localizableString(), style: .destructive) {(action) in
guard let videoId = self.isSearchStyle ? self.videos[indexPath.row].videoId:self.list?.videosArray[indexPath.row].videoId else {return} guard let videoId = self.isSearchStyle ? self.searchVideos[indexPath.row].videoId:self.sortVideos[indexPath.row].videoId else {return}
// //
MP_DownloadManager.shared.deleteFileDocuments(videoId) { videoId in MP_DownloadManager.shared.deleteFileDocuments(videoId) { videoId in
MP_HUD.progress("Loading...".localizableString(), delay: 0.5) { MP_HUD.progress("Loading...".localizableString(), delay: 0.5) {
@ -439,7 +470,7 @@ extension MPPositive_CustomPlayListViewController: UITableViewDataSource, UITabl
let cancel = UIAlertAction(title: "Cancel".localizableString(), style: .cancel) let cancel = UIAlertAction(title: "Cancel".localizableString(), style: .cancel)
alertController.addAction(cancel) alertController.addAction(cancel)
let sure = UIAlertAction(title: "Confirm".localizableString(), style: .destructive) {(action) in let sure = UIAlertAction(title: "Confirm".localizableString(), style: .destructive) {(action) in
guard let videoId = self.isSearchStyle ? self.videos[indexPath.row].videoId:self.list?.videosArray[indexPath.row].videoId else {return} guard let videoId = self.isSearchStyle ? self.searchVideos[indexPath.row].videoId:self.sortVideos[indexPath.row].videoId else {return}
// //
MP_DownloadManager.shared.cancelDownloadTask(videoId) { videoId in MP_DownloadManager.shared.cancelDownloadTask(videoId) { videoId in
MP_HUD.text("Cancel".localizableString(), delay: 1.0, completion: nil) MP_HUD.text("Cancel".localizableString(), delay: 1.0, completion: nil)
@ -465,7 +496,7 @@ extension MPPositive_CustomPlayListViewController: UITableViewDataSource, UITabl
// //
NotificationCenter.notificationKey.post(notificationName: .pup_player_vc) NotificationCenter.notificationKey.post(notificationName: .pup_player_vc)
MP_AnalyticsManager.shared.player_b_impAction() MP_AnalyticsManager.shared.player_b_impAction()
// //
var array:[MPPositive_SongItemModel] = [] var array:[MPPositive_SongItemModel] = []
for (index,song) in list.videosArray.enumerated() { for (index,song) in list.videosArray.enumerated() {
let item = MPPositive_SongItemModel() let item = MPPositive_SongItemModel()
@ -479,7 +510,7 @@ extension MPPositive_CustomPlayListViewController: UITableViewDataSource, UITabl
item.relatedID = song.relatedID item.relatedID = song.relatedID
array.append(item) array.append(item)
} }
let currentVideo = isSearchStyle ? videos[indexPath.row]:list.videosArray[indexPath.row] let currentVideo = isSearchStyle ? searchVideos[indexPath.row]:sortVideos[indexPath.row]
let lodaViewModel = MPPositive_PlayerLoadViewModel(array, currentVideoId: currentVideo.videoId ?? "") let lodaViewModel = MPPositive_PlayerLoadViewModel(array, currentVideoId: currentVideo.videoId ?? "")
lodaViewModel.improveData(currentVideo.videoId ?? "") lodaViewModel.improveData(currentVideo.videoId ?? "")
// //

View File

@ -275,6 +275,7 @@ extension MPPositive_LibraryViewController:JXSegmentedListContainerViewDataSourc
list.playListId = Date().timeZone().toString(.custom("YYYY/MM/dd/HH:mm:ss")) list.playListId = Date().timeZone().toString(.custom("YYYY/MM/dd/HH:mm:ss"))
list.title = text list.title = text
list.createTime = Date().timeZone() list.createTime = Date().timeZone()
list.sortType = 0
list.addToRelationshipToCustomVideos([]) list.addToRelationshipToCustomVideos([])
MPPositive_CustomPlayListModel.save() MPPositive_CustomPlayListModel.save()
MP_AnalyticsManager.shared.create_list_actionAction() MP_AnalyticsManager.shared.create_list_actionAction()

View File

@ -7,7 +7,7 @@
import UIKit import UIKit
class MPPositive_LoveArtistsViewController: MPPositive_BaseViewController { class MPPositive_LoveArtistsViewController: MPPositive_BaseViewController, UIViewControllerTransitioningDelegate {
///广View ///广View
fileprivate lazy var adContainerView:UIView = { fileprivate lazy var adContainerView:UIView = {
let adContainerView:UIView = .init(frame: .init(x: 0, y: 0, width: screen_Width, height: 300*width)) let adContainerView:UIView = .init(frame: .init(x: 0, y: 0, width: screen_Width, height: 300*width))
@ -31,7 +31,41 @@ class MPPositive_LoveArtistsViewController: MPPositive_BaseViewController {
tableView.contentInset = .init(top: 0, left: 0, bottom: 70*width, right: 0) tableView.contentInset = .init(top: 0, left: 0, bottom: 70*width, right: 0)
return tableView return tableView
}() }()
//
private lazy var rightBtn:UIButton = {
let btn:UIButton = .init(frame: .init(x: 0, y: 0, width: 24*width, height: 24*width))
btn.setBackgroundImage(UIImage(named: "Change Sort'logo"), for: .normal)
btn.addTarget(self, action: #selector(sortTypeClick(_ :)), for: .touchUpInside)
return btn
}()
//View
private lazy var searchShowView:MPPositive_CenterListSearchView = .init(frame: .init(x: 0, y: 0, width: screen_Width, height: 30*width))
///
private lazy var searchBtn:UIButton = {
let btn = UIButton()
btn.setBackgroundImage(UIImage(named: "Center_Search'logo"), for: .normal)
btn.addTarget(self, action: #selector(searchActionShowClick(_ :)), for: .touchUpInside)
return btn
}()
private let MPPositive_LoveArtistTableViewCellID = "MPPositive_LoveArtistTableViewCell" private let MPPositive_LoveArtistTableViewCellID = "MPPositive_LoveArtistTableViewCell"
//
private var isSearchStyle:Bool = false
//
private var artists:[MPPositive_CollectionArtistViewModel] = []
//
private var searchArtists:[MPPositive_CollectionArtistViewModel] = []
//
private var showArtists:[MPPositive_CollectionArtistViewModel] = []
//
private var sortType:Int{
get{
if let type = UserDefaults.standard.object(forKey: "Love_Artists_SortType") as? Int {
return type
}else {
return 0
}
}
}
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
setTitle("Love Artists".localizableString()) setTitle("Love Artists".localizableString())
@ -43,6 +77,18 @@ class MPPositive_LoveArtistsViewController: MPPositive_BaseViewController {
guard let adContainerView = adContainerView else {return} guard let adContainerView = adContainerView else {return}
MP_AdMobManager.shared.layoutLibraryNativeAd(in: adContainerView, index: 1) MP_AdMobManager.shared.layoutLibraryNativeAd(in: adContainerView, index: 1)
} }
searchShowView.cancelBlock = {
[weak self] in
guard let self = self else {return}
cancelSearchAction()
}
searchShowView.textBlock = {
[weak self] (text) in
guard let self = self else {return}
isSearchStyle = true
//
reloadSearch(text)
}
} }
override func viewWillAppear(_ animated: Bool) { override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated) super.viewWillAppear(animated)
@ -53,12 +99,68 @@ class MPPositive_LoveArtistsViewController: MPPositive_BaseViewController {
MPPositive_LoadCoreModel.shared.reloadCollectionArtistViewModels { MPPositive_LoadCoreModel.shared.reloadCollectionArtistViewModels {
[weak self] in [weak self] in
guard let self = self else {return} guard let self = self else {return}
tableView.showMessage(MPPositive_LoadCoreModel.shared.artistViewModels.count, title: "No Artists") artists = MPPositive_LoadCoreModel.shared.artistViewModels
numbersLabel.text = "\(MPPositive_LoadCoreModel.shared.artistViewModels.count) \("Artists".localizableString())" numbersLabel.text = "\(artists.count) \("Artists".localizableString())"
isSearchStyle ? reloadSearch(self.searchShowView.textField.text ?? ""):reloadShow()
}
}
//
private func reloadShow() {
tableView.showMessage(artists.count, title: "No Artists")
switch sortType {
case 0://
showArtists = artists.sorted(by: { item1, item2 in
if let date1 = item1.collectionArtist.addTime, let date2 = item2.collectionArtist.addTime {
return date1 > date2
}else {
return false
}
})
default://
showArtists = artists.sorted(by: { item1, item2 in
if let date1 = item1.collectionArtist.addTime, let date2 = item2.collectionArtist.addTime {
return date1 < date2
}else {
return true
}
})
}
tableView.reloadData() tableView.reloadData()
} }
//
private func reloadSearch(_ text:String) {
if text.isEmpty {
//
searchArtists = artists
}else {
//
searchArtists = artists.filter({($0.title ?? "").contains(text)})
}
tableView.reloadSections(.init(integer: 0), with: .automatic)
} }
private func configure() { private func configure() {
navView.addSubview(rightBtn)
rightBtn.snp.makeConstraints { make in
make.width.height.equalTo(24*width)
make.centerY.equalToSuperview()
make.right.equalToSuperview().offset(-16*width)
}
navView.addSubview(searchBtn)
searchBtn.snp.makeConstraints { make in
make.right.equalTo(rightBtn.snp.left).offset(-10*width)
make.width.height.equalTo(24*width)
make.centerY.equalTo(rightBtn)
}
navView.addSubview(searchShowView)
searchShowView.snp.makeConstraints { make in
make.height.equalTo(40*width)
make.left.equalTo(popBtn.snp.right).offset(5*width)
make.right.equalTo(rightBtn)
make.centerY.equalTo(searchBtn)
}
searchShowView.alpha = 0
searchShowView.isHidden = true
searchShowView.isUserInteractionEnabled = false
view.addSubview(adContainerView) view.addSubview(adContainerView)
adContainerView.snp.makeConstraints { make in adContainerView.snp.makeConstraints { make in
make.left.right.equalToSuperview() make.left.right.equalToSuperview()
@ -76,19 +178,73 @@ class MPPositive_LoveArtistsViewController: MPPositive_BaseViewController {
make.left.right.bottom.equalToSuperview() make.left.right.bottom.equalToSuperview()
} }
} }
//
@objc private func sortTypeClick(_ sender:UIButton) {
view.endEditing(true)
//
cancelSearchAction()
MPPositive_ModalType = .SortType
let sortVC = MPPositive_SortTypeViewController(sortType)
sortVC.chooseBlock = {
[weak self] (type) in
guard let self = self else {return}
UserDefaults.standard.set(type, forKey: "Love_Artists_SortType")
reloadShow()
}
sortVC.transitioningDelegate = self
sortVC.modalPresentationStyle = .custom
present(sortVC, animated: true)
}
//
@objc private func searchActionShowClick(_ sender:UIButton) {
//
UIView.animate(withDuration: 0.2) {
[weak self] in
guard let self = self else {return}
searchShowView.isHidden = false
//searchView
searchShowView.alpha = 1
searchBtn.isUserInteractionEnabled = false
} completion: { [weak self] statu in
guard let self = self else {return}
searchShowView.isUserInteractionEnabled = true
}
}
//
private func cancelSearchAction() {
UIView.animate(withDuration: 0.2) {
[weak self] in
guard let self = self else {return}
searchShowView.isUserInteractionEnabled = false
searchShowView.alpha = 0
isSearchStyle = false
} completion: { [weak self] statu in
guard let self = self else {return}
searchShowView.isHidden = true
searchBtn.isUserInteractionEnabled = true
reloadShow()
}
}
func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? {
return MPPositive_PresentationController(presentedViewController: presented, presenting: presenting)
}
} }
//MARK: - tableView //MARK: - tableView
extension MPPositive_LoveArtistsViewController: UITableViewDataSource, UITableViewDelegate { extension MPPositive_LoveArtistsViewController: UITableViewDataSource, UITableViewDelegate {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return MPPositive_LoadCoreModel.shared.artistViewModels.count return isSearchStyle ? searchArtists.count:showArtists.count
} }
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: MPPositive_LoveArtistTableViewCellID, for: indexPath) as! MPPositive_LoveArtistTableViewCell let cell = tableView.dequeueReusableCell(withIdentifier: MPPositive_LoveArtistTableViewCellID, for: indexPath) as! MPPositive_LoveArtistTableViewCell
cell.artistViewModel = MPPositive_LoadCoreModel.shared.artistViewModels[indexPath.row] if isSearchStyle {
cell.artistViewModel = searchArtists[indexPath.row]
}else {
cell.artistViewModel = showArtists[indexPath.row]
}
return cell return cell
} }
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let item = MPPositive_LoadCoreModel.shared.artistViewModels[indexPath.row] let item = isSearchStyle ? searchArtists[indexPath.row]:showArtists[indexPath.row]
// //
let artistVC = MPPositive_ArtistShowViewController(item.collectionArtist.artistId ?? "", clickTrackingParams: "") let artistVC = MPPositive_ArtistShowViewController(item.collectionArtist.artistId ?? "", clickTrackingParams: "")
navigationController?.pushViewController(artistVC, animated: true) navigationController?.pushViewController(artistVC, animated: true)

View File

@ -15,6 +15,22 @@ class MPPositive_LoveSongsViewController: MPPositive_BaseViewController, UIViewC
return adContainerView return adContainerView
}() }()
private lazy var numbersLabel:UILabel = createLabel(font: .systemFont(ofSize: 18*width, weight: .regular), textColor: .white, textAlignment: .left) private lazy var numbersLabel:UILabel = createLabel(font: .systemFont(ofSize: 18*width, weight: .regular), textColor: .white, textAlignment: .left)
//
private lazy var rightBtn:UIButton = {
let btn:UIButton = .init(frame: .init(x: 0, y: 0, width: 24*width, height: 24*width))
btn.setBackgroundImage(UIImage(named: "Change Sort'logo"), for: .normal)
btn.addTarget(self, action: #selector(sortTypeClick(_ :)), for: .touchUpInside)
return btn
}()
///
private lazy var searchBtn:UIButton = {
let btn = UIButton()
btn.setBackgroundImage(UIImage(named: "Center_Search'logo"), for: .normal)
btn.addTarget(self, action: #selector(searchActionShowClick(_ :)), for: .touchUpInside)
return btn
}()
//View
private lazy var searchShowView:MPPositive_CenterListSearchView = .init(frame: .init(x: 0, y: 0, width: screen_Width, height: 30*width))
///tableView ///tableView
private lazy var tableView:UITableView = { private lazy var tableView:UITableView = {
let tableView = UITableView(frame: .init(x: 0, y: 0, width: screen_Width, height: screen_Height), style: .plain) let tableView = UITableView(frame: .init(x: 0, y: 0, width: screen_Width, height: screen_Height), style: .plain)
@ -32,6 +48,25 @@ class MPPositive_LoveSongsViewController: MPPositive_BaseViewController, UIViewC
return tableView return tableView
}() }()
private let MPPositive_SearchResultShowTableViewCellID = "MPPositive_SearchResultShowTableViewCell" private let MPPositive_SearchResultShowTableViewCellID = "MPPositive_SearchResultShowTableViewCell"
//
private var isSearchStyle:Bool = false
//
private var songs:[MPPositive_CollectionSongViewModel] = []
//
private var searchSongs:[MPPositive_CollectionSongViewModel] = []
//
private var showSongs:[MPPositive_CollectionSongViewModel] = []
//
private var sortType:Int{
get{
if let type = UserDefaults.standard.object(forKey: "Love_Songs_SortType") as? Int {
return type
}else {
return 0
}
}
}
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
setTitle("Love Songs".localizableString()) setTitle("Love Songs".localizableString())
@ -43,6 +78,18 @@ class MPPositive_LoveSongsViewController: MPPositive_BaseViewController, UIViewC
guard let adContainerView = adContainerView else {return} guard let adContainerView = adContainerView else {return}
MP_AdMobManager.shared.layoutLibraryNativeAd(in: adContainerView, index: 1) MP_AdMobManager.shared.layoutLibraryNativeAd(in: adContainerView, index: 1)
} }
searchShowView.cancelBlock = {
[weak self] in
guard let self = self else {return}
cancelSearchAction()
}
searchShowView.textBlock = {
[weak self] (text) in
guard let self = self else {return}
isSearchStyle = true
//
reloadSearch(text)
}
} }
override func viewWillAppear(_ animated: Bool) { override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated) super.viewWillAppear(animated)
@ -53,12 +100,68 @@ class MPPositive_LoveSongsViewController: MPPositive_BaseViewController, UIViewC
MPPositive_LoadCoreModel.shared.reloadCollectionSongViewModel { MPPositive_LoadCoreModel.shared.reloadCollectionSongViewModel {
[weak self] in [weak self] in
guard let self = self else {return} guard let self = self else {return}
tableView.showMessage(MPPositive_LoadCoreModel.shared.songViewModels.count, title: "No Songs") songs = MPPositive_LoadCoreModel.shared.songViewModels
numbersLabel.text = "\(MPPositive_LoadCoreModel.shared.songViewModels.count) \("Songs".localizableString())" numbersLabel.text = "\(songs.count) \("Songs".localizableString())"
isSearchStyle ? reloadSearch(self.searchShowView.textField.text ?? ""):reloadShow()
}
}
//
private func reloadShow() {
tableView.showMessage(songs.count, title: "No Songs")
switch sortType {
case 0://
showSongs = songs.sorted(by: { item1, item2 in
if let date1 = item1.collectionSong.addTime, let date2 = item2.collectionSong.addTime {
return date1 > date2
}else {
return false
}
})
default://
showSongs = songs.sorted(by: { item1, item2 in
if let date1 = item1.collectionSong.addTime, let date2 = item2.collectionSong.addTime {
return date1 < date2
}else {
return true
}
})
}
tableView.reloadData() tableView.reloadData()
} }
//
private func reloadSearch(_ text:String) {
if text.isEmpty {
//
searchSongs = songs
}else {
//
searchSongs = songs.filter({($0.title ?? "").contains(text) || ($0.subtitle ?? "").contains(text)})
}
tableView.reloadSections(.init(integer: 0), with: .automatic)
} }
private func configure() { private func configure() {
navView.addSubview(rightBtn)
rightBtn.snp.makeConstraints { make in
make.width.height.equalTo(24*width)
make.centerY.equalToSuperview()
make.right.equalToSuperview().offset(-16*width)
}
navView.addSubview(searchBtn)
searchBtn.snp.makeConstraints { make in
make.right.equalTo(rightBtn.snp.left).offset(-10*width)
make.width.height.equalTo(24*width)
make.centerY.equalTo(rightBtn)
}
navView.addSubview(searchShowView)
searchShowView.snp.makeConstraints { make in
make.height.equalTo(40*width)
make.left.equalTo(popBtn.snp.right).offset(5*width)
make.right.equalTo(rightBtn)
make.centerY.equalTo(searchBtn)
}
searchShowView.alpha = 0
searchShowView.isHidden = true
searchShowView.isUserInteractionEnabled = false
view.addSubview(adContainerView) view.addSubview(adContainerView)
adContainerView.snp.makeConstraints { make in adContainerView.snp.makeConstraints { make in
make.left.right.equalToSuperview() make.left.right.equalToSuperview()
@ -76,22 +179,73 @@ class MPPositive_LoveSongsViewController: MPPositive_BaseViewController, UIViewC
make.left.right.bottom.equalToSuperview() make.left.right.bottom.equalToSuperview()
} }
} }
//
@objc private func sortTypeClick(_ sender:UIButton) {
view.endEditing(true)
//
cancelSearchAction()
MPPositive_ModalType = .SortType
let sortVC = MPPositive_SortTypeViewController(sortType)
sortVC.chooseBlock = {
[weak self] (type) in
guard let self = self else {return}
UserDefaults.standard.set(type, forKey: "Love_Songs_SortType")
reloadShow()
}
sortVC.transitioningDelegate = self
sortVC.modalPresentationStyle = .custom
present(sortVC, animated: true)
}
//
@objc private func searchActionShowClick(_ sender:UIButton) {
//
UIView.animate(withDuration: 0.2) {
[weak self] in
guard let self = self else {return}
searchShowView.isHidden = false
//searchView
searchShowView.alpha = 1
searchBtn.isUserInteractionEnabled = false
} completion: { [weak self] statu in
guard let self = self else {return}
searchShowView.isUserInteractionEnabled = true
}
}
//
private func cancelSearchAction() {
UIView.animate(withDuration: 0.2) {
[weak self] in
guard let self = self else {return}
searchShowView.isUserInteractionEnabled = false
searchShowView.alpha = 0
isSearchStyle = false
} completion: { [weak self] statu in
guard let self = self else {return}
searchShowView.isHidden = true
searchBtn.isUserInteractionEnabled = true
reloadShow()
}
}
} }
//MARK: - tableView //MARK: - tableView
extension MPPositive_LoveSongsViewController: UITableViewDataSource, UITableViewDelegate { extension MPPositive_LoveSongsViewController: UITableViewDataSource, UITableViewDelegate {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return MPPositive_LoadCoreModel.shared.songViewModels.count return isSearchStyle ? searchSongs.count:showSongs.count
} }
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: MPPositive_SearchResultShowTableViewCellID, for: indexPath) as! MPPositive_SearchResultShowTableViewCell let cell = tableView.dequeueReusableCell(withIdentifier: MPPositive_SearchResultShowTableViewCellID, for: indexPath) as! MPPositive_SearchResultShowTableViewCell
cell.songViewModel = MPPositive_LoadCoreModel.shared.songViewModels[indexPath.row] if isSearchStyle {
cell.songViewModel = searchSongs[indexPath.row]
}else {
cell.songViewModel = showSongs[indexPath.row]
}
cell.moreBlock = { cell.moreBlock = {
[weak self] in [weak self] in
guard let self = self else {return} guard let self = self else {return}
MPPositive_Debouncer.shared.call { MPPositive_Debouncer.shared.call {
MPPositive_ModalType = .MoreOperations MPPositive_ModalType = .MoreOperations
let moreVC = MPPositive_MoreSongOperationsViewController(MPPositive_LoadCoreModel.shared.songViewModels[indexPath.row]) let item = self.isSearchStyle ? self.searchSongs[indexPath.row]:self.showSongs[indexPath.row]
let moreVC = MPPositive_MoreSongOperationsViewController(item)
moreVC.disMissBlock = { moreVC.disMissBlock = {
self.reload() self.reload()
} }
@ -109,7 +263,7 @@ extension MPPositive_LoveSongsViewController: UITableViewDataSource, UITableView
let cancel = UIAlertAction(title: "Cancel".localizableString(), style: .cancel) let cancel = UIAlertAction(title: "Cancel".localizableString(), style: .cancel)
alertController.addAction(cancel) alertController.addAction(cancel)
let sure = UIAlertAction(title: "Confirm".localizableString(), style: .destructive) {(action) in let sure = UIAlertAction(title: "Confirm".localizableString(), style: .destructive) {(action) in
guard let videoId = MPPositive_LoadCoreModel.shared.songViewModels[indexPath.row].collectionSong.videoId else {return} guard let videoId = self.isSearchStyle ? self.searchSongs[indexPath.row].collectionSong.videoId:self.showSongs[indexPath.row].collectionSong.videoId else {return}
// //
MP_DownloadManager.shared.deleteFileDocuments(videoId) { videoId in MP_DownloadManager.shared.deleteFileDocuments(videoId) { videoId in
MP_HUD.progress("Loading...".localizableString(), delay: 0.5) { MP_HUD.progress("Loading...".localizableString(), delay: 0.5) {
@ -129,7 +283,7 @@ extension MPPositive_LoveSongsViewController: UITableViewDataSource, UITableView
let cancel = UIAlertAction(title: "Cancel".localizableString(), style: .cancel) let cancel = UIAlertAction(title: "Cancel".localizableString(), style: .cancel)
alertController.addAction(cancel) alertController.addAction(cancel)
let sure = UIAlertAction(title: "Confirm".localizableString(), style: .destructive) {(action) in let sure = UIAlertAction(title: "Confirm".localizableString(), style: .destructive) {(action) in
guard let videoId = MPPositive_LoadCoreModel.shared.songViewModels[indexPath.row].collectionSong.videoId else {return} guard let videoId = self.isSearchStyle ? self.searchSongs[indexPath.row].collectionSong.videoId:self.showSongs[indexPath.row].collectionSong.videoId else {return}
// //
MP_DownloadManager.shared.cancelDownloadTask(videoId) { videoId in MP_DownloadManager.shared.cancelDownloadTask(videoId) { videoId in
MP_HUD.text("Cancel".localizableString(), delay: 1.0, completion: nil) MP_HUD.text("Cancel".localizableString(), delay: 1.0, completion: nil)
@ -169,8 +323,9 @@ extension MPPositive_LoveSongsViewController: UITableViewDataSource, UITableView
item.relatedID = song.collectionSong.relatedID item.relatedID = song.collectionSong.relatedID
array.append(item) array.append(item)
} }
let lodaViewModel = MPPositive_PlayerLoadViewModel(array, currentVideoId: MPPositive_LoadCoreModel.shared.songViewModels[indexPath.row].collectionSong.videoId ?? "") let currentVideo = isSearchStyle ? searchSongs[indexPath.row]:showSongs[indexPath.row]
lodaViewModel.improveData(MPPositive_LoadCoreModel.shared.songViewModels[indexPath.row].collectionSong.videoId ?? "") let lodaViewModel = MPPositive_PlayerLoadViewModel(array, currentVideoId: currentVideo.collectionSong.videoId ?? "")
lodaViewModel.improveData(currentVideo.collectionSong.videoId ?? "")
// //
MP_PlayerManager.shared.setPlayType(.normal) MP_PlayerManager.shared.setPlayType(.normal)
MP_PlayerManager.shared.loadPlayer = lodaViewModel MP_PlayerManager.shared.loadPlayer = lodaViewModel

View File

@ -15,6 +15,22 @@ class MPPositive_OfflineSongsViewController: MPPositive_BaseViewController {
return adContainerView return adContainerView
}() }()
private lazy var numbersLabel:UILabel = createLabel(font: .systemFont(ofSize: 18*width, weight: .regular), textColor: .white, textAlignment: .left) private lazy var numbersLabel:UILabel = createLabel(font: .systemFont(ofSize: 18*width, weight: .regular), textColor: .white, textAlignment: .left)
//
private lazy var rightBtn:UIButton = {
let btn:UIButton = .init(frame: .init(x: 0, y: 0, width: 24*width, height: 24*width))
btn.setBackgroundImage(UIImage(named: "Change Sort'logo"), for: .normal)
btn.addTarget(self, action: #selector(sortTypeClick(_ :)), for: .touchUpInside)
return btn
}()
///
private lazy var searchBtn:UIButton = {
let btn = UIButton()
btn.setBackgroundImage(UIImage(named: "Center_Search'logo"), for: .normal)
btn.addTarget(self, action: #selector(searchActionShowClick(_ :)), for: .touchUpInside)
return btn
}()
//View
private lazy var searchShowView:MPPositive_CenterListSearchView = .init(frame: .init(x: 0, y: 0, width: screen_Width, height: 30*width))
///tableView ///tableView
private lazy var tableView:UITableView = { private lazy var tableView:UITableView = {
let tableView = UITableView(frame: .init(x: 0, y: 0, width: screen_Width, height: screen_Height), style: .plain) let tableView = UITableView(frame: .init(x: 0, y: 0, width: screen_Width, height: screen_Height), style: .plain)
@ -32,7 +48,24 @@ class MPPositive_OfflineSongsViewController: MPPositive_BaseViewController {
return tableView return tableView
}() }()
private let MPPositive_SearchResultShowTableViewCellID = "MPPositive_SearchResultShowTableViewCell" private let MPPositive_SearchResultShowTableViewCellID = "MPPositive_SearchResultShowTableViewCell"
//
private var isSearchStyle:Bool = false
//
private var offlines:[MPPositive_DownloadViewModel] = [] private var offlines:[MPPositive_DownloadViewModel] = []
//
private var searchSongs:[MPPositive_DownloadViewModel] = []
//
private var showSongs:[MPPositive_DownloadViewModel] = []
//
private var sortType:Int{
get{
if let type = UserDefaults.standard.object(forKey: "Offline_Songs_SortType") as? Int {
return type
}else {
return 0
}
}
}
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
setTitle("Offline Songs".localizableString()) setTitle("Offline Songs".localizableString())
@ -44,6 +77,18 @@ class MPPositive_OfflineSongsViewController: MPPositive_BaseViewController {
guard let adContainerView = adContainerView else {return} guard let adContainerView = adContainerView else {return}
MP_AdMobManager.shared.layoutLibraryNativeAd(in: adContainerView, index: 1) MP_AdMobManager.shared.layoutLibraryNativeAd(in: adContainerView, index: 1)
} }
searchShowView.cancelBlock = {
[weak self] in
guard let self = self else {return}
cancelSearchAction()
}
searchShowView.textBlock = {
[weak self] (text) in
guard let self = self else {return}
isSearchStyle = true
//
reloadSearch(text)
}
} }
override func viewWillAppear(_ animated: Bool) { override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated) super.viewWillAppear(animated)
@ -57,10 +102,66 @@ class MPPositive_OfflineSongsViewController: MPPositive_BaseViewController {
offlines = MPPositive_LoadCoreModel.shared.loadViewModels offlines = MPPositive_LoadCoreModel.shared.loadViewModels
tableView.showMessage(offlines.count, title: "No Songs") tableView.showMessage(offlines.count, title: "No Songs")
numbersLabel.text = "\(offlines.count) \("Songs".localizableString())" numbersLabel.text = "\(offlines.count) \("Songs".localizableString())"
isSearchStyle ? reloadSearch(self.searchShowView.textField.text ?? ""):reloadShow()
}
}
//
private func reloadShow() {
tableView.showMessage(offlines.count, title: "No Songs")
switch sortType {
case 0://
showSongs = offlines.sorted(by: { item1, item2 in
if let date1 = item1.loadItem.addTime, let date2 = item2.loadItem.addTime {
return date1 > date2
}else {
return false
}
})
default://
showSongs = offlines.sorted(by: { item1, item2 in
if let date1 = item1.loadItem.addTime, let date2 = item2.loadItem.addTime {
return date1 < date2
}else {
return true
}
})
}
tableView.reloadData() tableView.reloadData()
} }
//
private func reloadSearch(_ text:String) {
if text.isEmpty {
//
searchSongs = offlines
}else {
//
searchSongs = offlines.filter({($0.title ?? "").contains(text) || ($0.subtitle ?? "").contains(text)})
}
tableView.reloadSections(.init(integer: 0), with: .automatic)
} }
private func configure() { private func configure() {
navView.addSubview(rightBtn)
rightBtn.snp.makeConstraints { make in
make.width.height.equalTo(24*width)
make.centerY.equalToSuperview()
make.right.equalToSuperview().offset(-16*width)
}
navView.addSubview(searchBtn)
searchBtn.snp.makeConstraints { make in
make.right.equalTo(rightBtn.snp.left).offset(-10*width)
make.width.height.equalTo(24*width)
make.centerY.equalTo(rightBtn)
}
navView.addSubview(searchShowView)
searchShowView.snp.makeConstraints { make in
make.height.equalTo(40*width)
make.left.equalTo(popBtn.snp.right).offset(5*width)
make.right.equalTo(rightBtn)
make.centerY.equalTo(searchBtn)
}
searchShowView.alpha = 0
searchShowView.isHidden = true
searchShowView.isUserInteractionEnabled = false
view.addSubview(adContainerView) view.addSubview(adContainerView)
adContainerView.snp.makeConstraints { make in adContainerView.snp.makeConstraints { make in
make.left.right.equalToSuperview() make.left.right.equalToSuperview()
@ -78,20 +179,71 @@ class MPPositive_OfflineSongsViewController: MPPositive_BaseViewController {
make.left.right.bottom.equalToSuperview() make.left.right.bottom.equalToSuperview()
} }
} }
//
@objc private func sortTypeClick(_ sender:UIButton) {
view.endEditing(true)
//
cancelSearchAction()
MPPositive_ModalType = .SortType
let sortVC = MPPositive_SortTypeViewController(sortType)
sortVC.chooseBlock = {
[weak self] (type) in
guard let self = self else {return}
UserDefaults.standard.set(type, forKey: "Offline_Songs_SortType")
reloadShow()
}
sortVC.transitioningDelegate = self
sortVC.modalPresentationStyle = .custom
present(sortVC, animated: true)
}
//
@objc private func searchActionShowClick(_ sender:UIButton) {
//
UIView.animate(withDuration: 0.2) {
[weak self] in
guard let self = self else {return}
searchShowView.isHidden = false
//searchView
searchShowView.alpha = 1
searchBtn.isUserInteractionEnabled = false
} completion: { [weak self] statu in
guard let self = self else {return}
searchShowView.isUserInteractionEnabled = true
}
}
//
private func cancelSearchAction() {
UIView.animate(withDuration: 0.2) {
[weak self] in
guard let self = self else {return}
searchShowView.isUserInteractionEnabled = false
searchShowView.alpha = 0
isSearchStyle = false
} completion: { [weak self] statu in
guard let self = self else {return}
searchShowView.isHidden = true
searchBtn.isUserInteractionEnabled = true
reloadShow()
}
}
} }
//MARK: - tableView //MARK: - tableView
extension MPPositive_OfflineSongsViewController: UITableViewDataSource, UITableViewDelegate, UIViewControllerTransitioningDelegate{ extension MPPositive_OfflineSongsViewController: UITableViewDataSource, UITableViewDelegate, UIViewControllerTransitioningDelegate{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return offlines.count return isSearchStyle ? searchSongs.count:showSongs.count
} }
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: MPPositive_SearchResultShowTableViewCellID, for: indexPath) as! MPPositive_SearchResultShowTableViewCell let cell = tableView.dequeueReusableCell(withIdentifier: MPPositive_SearchResultShowTableViewCellID, for: indexPath) as! MPPositive_SearchResultShowTableViewCell
cell.loadViewModel = offlines[indexPath.row] if isSearchStyle {
cell.loadViewModel = searchSongs[indexPath.row]
}else {
cell.loadViewModel = showSongs[indexPath.row]
}
cell.moreBlock = { cell.moreBlock = {
[weak self] in [weak self] in
guard let self = self else {return} guard let self = self else {return}
MPPositive_Debouncer.shared.call { MPPositive_Debouncer.shared.call {
let item = self.offlines[indexPath.row] let item = self.isSearchStyle ? self.searchSongs[indexPath.row]:self.showSongs[indexPath.row]
let song = MPPositive_SongItemModel() let song = MPPositive_SongItemModel()
song.coverUrls = [item.loadItem.coverImage] song.coverUrls = [item.loadItem.coverImage]
song.reviewUrls = [item.loadItem.reviewImage] song.reviewUrls = [item.loadItem.reviewImage]
@ -121,7 +273,7 @@ extension MPPositive_OfflineSongsViewController: UITableViewDataSource, UITableV
let cancel = UIAlertAction(title: "Cancel".localizableString(), style: .cancel) let cancel = UIAlertAction(title: "Cancel".localizableString(), style: .cancel)
alertController.addAction(cancel) alertController.addAction(cancel)
let sure = UIAlertAction(title: "Confirm".localizableString(), style: .destructive) {(action) in let sure = UIAlertAction(title: "Confirm".localizableString(), style: .destructive) {(action) in
guard let videoId = self.offlines[indexPath.row].loadItem.videoId else {return} guard let videoId = self.isSearchStyle ? self.searchSongs[indexPath.row].loadItem.videoId:self.showSongs[indexPath.row].loadItem.videoId else {return}
// //
MP_DownloadManager.shared.deleteFileDocuments(videoId) { videoId in MP_DownloadManager.shared.deleteFileDocuments(videoId) { videoId in
MP_HUD.progress("Loading...".localizableString(), delay: 0.5) { MP_HUD.progress("Loading...".localizableString(), delay: 0.5) {
@ -141,7 +293,7 @@ extension MPPositive_OfflineSongsViewController: UITableViewDataSource, UITableV
let cancel = UIAlertAction(title: "Cancel".localizableString(), style: .cancel) let cancel = UIAlertAction(title: "Cancel".localizableString(), style: .cancel)
alertController.addAction(cancel) alertController.addAction(cancel)
let sure = UIAlertAction(title: "Confirm".localizableString(), style: .destructive) {(action) in let sure = UIAlertAction(title: "Confirm".localizableString(), style: .destructive) {(action) in
guard let videoId = self.offlines[indexPath.row].loadItem.videoId else {return} guard let videoId = self.isSearchStyle ? self.searchSongs[indexPath.row].loadItem.videoId:self.showSongs[indexPath.row].loadItem.videoId else {return}
// //
MP_DownloadManager.shared.cancelDownloadTask(videoId) { videoId in MP_DownloadManager.shared.cancelDownloadTask(videoId) { videoId in
MP_HUD.text("Cancel".localizableString(), delay: 1.0, completion: nil) MP_HUD.text("Cancel".localizableString(), delay: 1.0, completion: nil)
@ -180,8 +332,9 @@ extension MPPositive_OfflineSongsViewController: UITableViewDataSource, UITableV
item.relatedID = song.loadItem.relatedID item.relatedID = song.loadItem.relatedID
array.append(item) array.append(item)
} }
let lodaViewModel = MPPositive_PlayerLoadViewModel(array, currentVideoId: offlines[indexPath.row].loadItem.videoId ?? "") let currentVideo = isSearchStyle ? searchSongs[indexPath.row]:showSongs[indexPath.row]
lodaViewModel.improveData(offlines[indexPath.row].loadItem.videoId ?? "") let lodaViewModel = MPPositive_PlayerLoadViewModel(array, currentVideoId: currentVideo.loadItem.videoId ?? "")
lodaViewModel.improveData(currentVideo.loadItem.videoId ?? "")
// //
MP_PlayerManager.shared.setPlayType(.normal) MP_PlayerManager.shared.setPlayType(.normal)
MP_PlayerManager.shared.loadPlayer = lodaViewModel MP_PlayerManager.shared.loadPlayer = lodaViewModel

View File

@ -13,12 +13,15 @@ class MPPositive_PlayListMoreViewController: UIViewController, UIViewControllerT
//Label //Label
private lazy var titleLabel:UILabel = createLabel(font: .systemFont(ofSize: 14*width), textColor: .white, textAlignment: .left) private lazy var titleLabel:UILabel = createLabel(font: .systemFont(ofSize: 14*width), textColor: .white, textAlignment: .left)
//EditView //EditView
private lazy var editView:UIView = createNewView("Edit", image: UIImage(named: "Center_Edit'logo")!, tag: 0) private lazy var editView:UIView = createNewView("Modify Title".localizableString(), image: UIImage(named: "Center_Edit'logo")!, tag: 0)
//ChangeView
private lazy var changeView:UIView = createNewView("Change Sort".localizableString(), image: UIImage(named: "Change Sort'logo")!, tag: 1)
//DeleteView //DeleteView
private lazy var deleteView:UIView = createNewView("Delete", image: UIImage(named: "Center_Delete'logo")!, tag: 1) private lazy var deleteView:UIView = createNewView("Delete List".localizableString(), image: UIImage(named: "Center_Delete'logo")!, tag: 2)
// //
private var text:String! private var text:String!
var editBlock:((String) -> Void)? var editBlock:((String) -> Void)?
var changeBlock:(() -> Void)?
var deleteBlock:(() -> Void)? var deleteBlock:(() -> Void)?
init(_ text:String) { init(_ text:String) {
super.init(nibName: nil, bundle: nil) super.init(nibName: nil, bundle: nil)
@ -57,9 +60,15 @@ class MPPositive_PlayListMoreViewController: UIViewController, UIViewControllerT
make.height.equalTo(56*width) make.height.equalTo(56*width)
make.left.right.equalToSuperview() make.left.right.equalToSuperview()
} }
view.addSubview(changeView)
changeView.snp.makeConstraints { make in
make.top.equalTo(editView.snp.bottom)
make.height.equalTo(56*width)
make.left.right.equalToSuperview()
}
view.addSubview(deleteView) view.addSubview(deleteView)
deleteView.snp.makeConstraints { make in deleteView.snp.makeConstraints { make in
make.top.equalTo(editView.snp.bottom) make.top.equalTo(changeView.snp.bottom)
make.height.equalTo(56*width) make.height.equalTo(56*width)
make.left.right.equalToSuperview() make.left.right.equalToSuperview()
} }
@ -90,8 +99,8 @@ class MPPositive_PlayListMoreViewController: UIViewController, UIViewControllerT
// //
@objc private func chooseClick(_ sender:UITapGestureRecognizer) { @objc private func chooseClick(_ sender:UITapGestureRecognizer) {
let tag = sender.view?.tag ?? 0 let tag = sender.view?.tag ?? 0
if tag == 0 { switch tag {
// case 0://
MPPositive_ModalType = .NewList MPPositive_ModalType = .NewList
let listVC = MPSideA_RenameViewController() let listVC = MPSideA_RenameViewController()
listVC.titleText = "Edit Name" listVC.titleText = "Edit Name"
@ -107,7 +116,14 @@ class MPPositive_PlayListMoreViewController: UIViewController, UIViewControllerT
listVC.transitioningDelegate = self listVC.transitioningDelegate = self
listVC.modalPresentationStyle = .custom listVC.modalPresentationStyle = .custom
present(listVC, animated: true) present(listVC, animated: true)
}else { case 1://
dismiss(animated: true) {
[weak self] in
if let block = self?.changeBlock {
block()
}
}
default://
dismiss(animated: true) { dismiss(animated: true) {
[weak self] in [weak self] in
if let block = self?.deleteBlock { if let block = self?.deleteBlock {

View File

@ -0,0 +1,69 @@
//
// MPPositive_SortTypeViewController.swift
// relax.offline.mp3.music
//
// Created by Mr.Zhou on 2024/8/15.
//
import UIKit
class MPPositive_SortTypeViewController: UIViewController {
private lazy var tableView:UITableView = {
let tableView = UITableView(frame: .init(x: 0, y: 0, width: screen_Width, height: screen_Height), style: .plain)
if #available(iOS 15.0, *) {
tableView.sectionHeaderTopPadding = 0
}
tableView.backgroundColor = .clear
tableView.separatorStyle = .none
tableView.rowHeight = 60*width
tableView.dataSource = self
tableView.delegate = self
tableView.register(MPPositive_SortTypeTableViewCell.self, forCellReuseIdentifier: MPPositive_SortTypeTableViewCellID)
return tableView
}()
private let MPPositive_SortTypeTableViewCellID = "MPPositive_SortTypeTableViewCell"
private var titles:[String] = ["Sort by newest to oldest","Sort by oldest to newest"]
private var type:Int = 0
var chooseBlock:((Int) -> Void)?
init(_ type:Int) {
super.init(nibName: nil, bundle: nil)
self.type = type
}
required init?(coder: NSCoder) {
super.init(coder: coder)
}
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .init(hex: "#282A2C")
view.layer.masksToBounds = true
view.layer.cornerRadius = 18*width
configure()
}
private func configure() {
view.addSubview(tableView)
tableView.snp.makeConstraints { make in
make.left.top.right.bottom.equalToSuperview()
}
}
}
//MARK: - tableView
extension MPPositive_SortTypeViewController:UITableViewDataSource, UITableViewDelegate {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return titles.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: MPPositive_SortTypeTableViewCellID, for: indexPath) as! MPPositive_SortTypeTableViewCell
cell.title = titles[indexPath.row]
cell.chooseView.isHidden = !(indexPath.row == type)
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
dismiss(animated: true) {
[weak self] in
guard let self = self else {return}
if let block = chooseBlock {
block(indexPath.row)
}
}
}
}

View File

@ -0,0 +1,73 @@
//
// MPPositive_SortTypeTableViewCell.swift
// relax.offline.mp3.music
//
// Created by Mr.Zhou on 2024/8/15.
//
import UIKit
class MPPositive_SortTypeTableViewCell: UITableViewCell {
//icon
private lazy var iconImageView:UIImageView = {
let imageView:UIImageView = .init()
imageView.contentMode = .scaleAspectFill
imageView.layer.masksToBounds = true
return imageView
}()
//Label
private lazy var titleLabel:UILabel = createLabel(font: .systemFont(ofSize: 14*width, weight: .medium), textColor: .white, textAlignment: .left)
//View
lazy var chooseView:UIView = {
let view:UIView = .init(frame: .init(x: 0, y: 0, width: 20*width, height: 20*width))
view.backgroundColor = greenTextColor
view.layer.masksToBounds = true
view.layer.cornerRadius = 10*width
return view
}()
var title:String!{
didSet{
iconImageView.image = UIImage(named: title)
titleLabel.text = title.localizableString()
}
}
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
selectionStyle = .none
backgroundColor = .clear
configure()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
}
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
private func configure() {
contentView.addSubview(iconImageView)
iconImageView.snp.makeConstraints { make in
make.width.height.equalTo(24*width)
make.centerY.equalToSuperview()
make.left.equalToSuperview().offset(18*width)
}
contentView.addSubview(chooseView)
chooseView.snp.makeConstraints { make in
make.width.height.equalTo(20*width)
make.centerY.equalToSuperview()
make.right.equalToSuperview().offset(-10*width)
}
contentView.addSubview(titleLabel)
titleLabel.snp.makeConstraints { make in
make.centerY.equalToSuperview()
make.left.equalTo(iconImageView.snp.right).offset(12*width)
make.right.equalTo(chooseView.snp.left).offset(-12*width)
}
}
}

View File

@ -113,10 +113,10 @@ class MPPositive_ArtistShowHeaderView: UIView {
item.coverImage = URL(string: header.thumbnails?.last ?? "") item.coverImage = URL(string: header.thumbnails?.last ?? "")
item.subtitle = header.subscriptionedText item.subtitle = header.subscriptionedText
item.artistId = self.artistid item.artistId = self.artistid
item.addTime = Date()
MPPositive_CollectionArtistModel.save() MPPositive_CollectionArtistModel.save()
MPPositive_LoadCoreModel.shared.reloadCollectionArtistViewModels(nil) MPPositive_LoadCoreModel.shared.reloadCollectionArtistViewModels(nil)
} }
} }
} }
} }

View File

@ -297,6 +297,7 @@ class MPPositive_PlayerCoverView: UIView, PKDownloadButtonDelegate {
item.coverImage = MP_PlayerManager.shared.loadPlayer?.currentVideo.coverUrl item.coverImage = MP_PlayerManager.shared.loadPlayer?.currentVideo.coverUrl
item.lyricsID = MP_PlayerManager.shared.loadPlayer?.currentVideo.song.lyricsID item.lyricsID = MP_PlayerManager.shared.loadPlayer?.currentVideo.song.lyricsID
item.relatedID = MP_PlayerManager.shared.loadPlayer?.currentVideo.song.relatedID item.relatedID = MP_PlayerManager.shared.loadPlayer?.currentVideo.song.relatedID
item.addTime = Date()
MPPositive_CollectionSongModel.save() MPPositive_CollectionSongModel.save()
MP_PlayerManager.shared.loadPlayer?.currentVideo.reloadCollectionAndDownLoad() MP_PlayerManager.shared.loadPlayer?.currentVideo.reloadCollectionAndDownLoad()
MPPositive_LoadCoreModel.shared.reloadCollectionSongViewModel(nil) MPPositive_LoadCoreModel.shared.reloadCollectionSongViewModel(nil)