1.1.7多语言版本
@ -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 = "";
|
||||||
|
|||||||
22
relax.offline.mp3.music/Assets.xcassets/Positive/Player/Change Sort'logo.imageset/Contents.json
vendored
Normal 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
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
relax.offline.mp3.music/Assets.xcassets/Positive/Player/Change Sort'logo.imageset/Frame@2x.png
vendored
Normal file
|
After Width: | Height: | Size: 634 B |
BIN
relax.offline.mp3.music/Assets.xcassets/Positive/Player/Change Sort'logo.imageset/Frame@3x.png
vendored
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
22
relax.offline.mp3.music/Assets.xcassets/Positive/Player/Play next.imageset/Contents.json
vendored
Normal 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
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
relax.offline.mp3.music/Assets.xcassets/Positive/Player/Play next.imageset/Group_1597880550@2x.png
vendored
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
relax.offline.mp3.music/Assets.xcassets/Positive/Player/Play next.imageset/Group_1597880550@3x.png
vendored
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 665 B |
|
After Width: | Height: | Size: 1.2 KiB |
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 658 B |
|
After Width: | Height: | Size: 1.2 KiB |
@ -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"/>
|
||||||
|
|||||||
@ -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" = "تم نسخ عنوان البريد الإلكتروني بنجاح إلى الحافظة";
|
||||||
|
|||||||
@ -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";
|
||||||
|
|||||||
@ -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";
|
||||||
|
|||||||
@ -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";
|
||||||
|
|||||||
@ -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";
|
||||||
|
|||||||
@ -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";
|
||||||
|
|||||||
@ -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";
|
||||||
|
|||||||
@ -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.";
|
||||||
|
|||||||
@ -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?()
|
||||||
|
|||||||
@ -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 {
|
||||||
|
|||||||
@ -16,6 +16,12 @@ class MP_CoreDataHandlerManager {
|
|||||||
lazy var persistentContainer: NSPersistentContainer = {
|
lazy var persistentContainer: NSPersistentContainer = {
|
||||||
//数据仓库名为XXX.cdatamodeld中的XXX
|
//数据仓库名为XXX.cdatamodeld中的XXX
|
||||||
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 {
|
||||||
//加载数据仓库失败
|
//加载数据仓库失败
|
||||||
|
|||||||
@ -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",
|
||||||
|
|||||||
@ -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?
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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?
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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!
|
||||||
|
///排序方案(0为时间排序,1为字母排序,为空的情况默认为0)
|
||||||
|
@NSManaged var sortType:NSNumber?
|
||||||
///歌曲信息组
|
///歌曲信息组
|
||||||
@NSManaged var videos:NSSet!
|
@NSManaged var videos:NSSet!
|
||||||
|
|
||||||
|
|||||||
@ -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?
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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: "Pop‘logo"), for: .normal)
|
btn.setBackgroundImage(UIImage(named: "Pop‘logo"), 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}
|
||||||
|
|||||||
@ -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 ?? "")
|
||||||
|
|||||||
@ -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()
|
||||||
|
|||||||
@ -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()
|
||||||
//成功新建歌单列表
|
//成功新建歌单列表
|
||||||
|
|||||||
@ -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] = []
|
||||||
|
//排序sort的Videos
|
||||||
|
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 ?? "")
|
||||||
//更改播放器播放类型
|
//更改播放器播放类型
|
||||||
|
|||||||
@ -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()
|
||||||
|
|||||||
@ -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)
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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 {
|
||||||
|
|||||||
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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)
|
||||||
|
|||||||