1.1.7多语言版本

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

View File

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

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 634 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 665 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 658 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<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">
<attribute name="addTime" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
<attribute name="artistId" optional="YES" attributeType="String"/>
<attribute name="coverImage" optional="YES" attributeType="URI"/>
<attribute name="subtitle" optional="YES" attributeType="String"/>
@ -14,6 +15,7 @@
<attribute name="title" optional="YES" attributeType="String"/>
</entity>
<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="lyricsID" optional="YES" attributeType="String"/>
<attribute name="relatedID" optional="YES" attributeType="String"/>
@ -24,6 +26,7 @@
<entity name="MPPositive_CustomPlayListModel" representedClassName="MPPositive_CustomPlayListModel" syncable="YES">
<attribute name="createTime" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
<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"/>
<relationship name="videos" optional="YES" toMany="YES" deletionRule="Cascade" destinationEntity="MPPositive_CustomVideoModel" inverseName="playList" inverseEntity="MPPositive_CustomVideoModel"/>
</entity>
@ -38,6 +41,7 @@
<relationship name="playList" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="MPPositive_CustomPlayListModel" inverseName="videos" inverseEntity="MPPositive_CustomPlayListModel"/>
</entity>
<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="lengthText" optional="YES" attributeType="String"/>
<attribute name="longBylineText" optional="YES" attributeType="String"/>

View File

@ -101,7 +101,7 @@
///播放列表
"Playlists" = "قائمة التشغيل";
///收藏播放列表
"Collect PlayLists" = "قائمة التشغيل المفضلة";
"Collect Playlists" = "قائمة التشغيل المفضلة";
///命名您的播放列表
"Name Your PlayList" = "قم بتسمية قائمة التشغيل الخاصة بك";
///删除这首歌曲
@ -112,6 +112,20 @@
"Cancel Song Download Task" = "إلغاء مهمة تنزيل الأغنية";
///您确定要取消这首歌曲的下载任务吗?
"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文本
///已成功将电子邮件地址复制到剪贴板
"Successfully copied the e-mail address to the clipboard" = "تم نسخ عنوان البريد الإلكتروني بنجاح إلى الحافظة";

View File

@ -112,6 +112,20 @@
"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?";
///修改名字
"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文本
///已成功将电子邮件地址复制到剪贴板
"Successfully copied the e-mail address to the clipboard" = "E-Mail-Adresse erfolgreich in die Zwischenablage kopiert";

View File

@ -112,6 +112,20 @@
"Cancel Song Download Task" = "Cancel Song Download Task";
///您确定要取消这首歌曲的下载任务吗?
"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文本
///已成功将电子邮件地址复制到剪贴板
"Successfully copied the e-mail address to the clipboard" = "Successfully copied the e-mail address to the clipboard";

View File

@ -112,6 +112,20 @@
"Cancel Song Download Task" = "Cancelar tarea de descarga de canción";
///您确定要取消这首歌曲的下载任务吗?
"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文本
///已成功将电子邮件地址复制到剪贴板
"Successfully copied the e-mail address to the clipboard" = "Dirección de correo electrónico copiada correctamente al portapapeles";

View File

@ -112,6 +112,20 @@
"Cancel Song Download Task" = "Annuler la tâche de téléchargement de chanson";
///您确定要取消这首歌曲的下载任务吗?
"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文本
///已成功将电子邮件地址复制到剪贴板
"Successfully copied the e-mail address to the clipboard" = "Adresse e-mail copiée avec succès dans le presse-papiers";

View File

@ -112,6 +112,20 @@
"Cancel Song Download Task" = "Annulla l'attività di download del brano";
///您确定要取消这首歌曲的下载任务吗?
"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文本
///已成功将电子邮件地址复制到剪贴板
"Successfully copied the e-mail address to the clipboard" = "Indirizzo email copiato con successo negli appunti";

View File

@ -112,6 +112,20 @@
"Cancel Song Download Task" = "Cancelar tarefa de download de música";
///您确定要取消这首歌曲的下载任务吗?
"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文本
///已成功将电子邮件地址复制到剪贴板
"Successfully copied the e-mail address to the clipboard" = "Endereço de e-mail copiado com sucesso para a área de transferência";

View File

@ -112,6 +112,20 @@
"Cancel Song Download Task" = "Şarkı indirme görevini iptal et";
///您确定要取消这首歌曲的下载任务吗?
"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文本
///已成功将电子邮件地址复制到剪贴板
"Successfully copied the e-mail address to the clipboard" = "Herhangi bir yorumunuz veya öneriniz varsa lütfen aşağıdaki e-posta adresinden bizimle iletişime geçin.";

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -9,9 +9,9 @@ import UIKit
///b
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
private lazy var popBtn:UIButton = {
lazy var popBtn:UIButton = {
let btn = UIButton()
btn.setBackgroundImage(UIImage(named: "Poplogo"), for: .normal)
btn.addTarget(self, action: #selector(popActionClick(_ :)), for: .touchUpInside)
@ -73,6 +73,7 @@ class MPPositive_BaseViewController: MP_BaseViewController, UIGestureRecognizerD
}
//pop
@objc func popActionClick(_ sender:UIButton) {
view.endEditing(true)
MPPositive_Debouncer.shared.call(0.1) {
[weak self] in
guard let self = self else {return}

View File

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

View File

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

View File

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

View File

@ -111,7 +111,9 @@ class MPPositive_CustomPlayListViewController: MPPositive_BaseViewController, UI
//
private var isSearchStyle:Bool = false
//Videos
private var videos:[MPPositive_CustomVideoModel] = []
private var searchVideos:[MPPositive_CustomVideoModel] = []
//sortVideos
private var sortVideos:[MPPositive_CustomVideoModel] = []
init(_ playList:MPPositive_CustomPlayListModel) {
super.init(nibName: nil, bundle: nil)
DispatchQueue.main.async {
@ -119,6 +121,7 @@ class MPPositive_CustomPlayListViewController: MPPositive_BaseViewController, UI
guard let self = self else {return}
self.list = playList
}
print("当前排序类型-\(playList.sortType ?? 0)")
setTitle("")
setPopBtn()
configure()
@ -132,20 +135,7 @@ class MPPositive_CustomPlayListViewController: MPPositive_BaseViewController, UI
searchShowView.cancelBlock = {
[weak self] in
guard let self = self else {return}
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)
}
cancelSearchAction()
}
searchShowView.textBlock = {
[weak self] (text) in
@ -164,23 +154,28 @@ class MPPositive_CustomPlayListViewController: MPPositive_BaseViewController, UI
backImageView.kf.setImage(with: coverURL, placeholder: placeholderImage)
coverImageView.kf.setImage(with: coverURL, placeholder: placeholderImage)
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")))"
playAllBtn.setTitle(" Play (\(list.videosArray.count))", for: .normal)
playAllBtn.setTitle(" Play (\(self.sortVideos.count))", for: .normal)
tableView.reloadData()
}
//
private func reloadSearch(_ text:String) {
if text.isEmpty {
//
videos = list.videosArray
searchVideos = list.videosArray
}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)
}
//
private func configure() {
//
@ -267,6 +262,9 @@ class MPPositive_CustomPlayListViewController: MPPositive_BaseViewController, UI
//
@objc private func moreClick(_ sender:UIButton) {
view.endEditing(true)
//
cancelSearchAction()
MPPositive_ModalType = .PlayListEdit
//
let moreVC = MPPositive_PlayListMoreViewController(list.title)
@ -285,10 +283,43 @@ class MPPositive_CustomPlayListViewController: MPPositive_BaseViewController, UI
MPPositive_LoadCoreModel.shared.reloadCustomPlayLists(nil)
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.modalPresentationStyle = .custom
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? {
return MPPositive_PresentationController(presentedViewController: presented, presenting: presenting)
}
@ -387,20 +418,20 @@ class MPPositive_CustomPlayListViewController: MPPositive_BaseViewController, UI
//MARK: - tableView
extension MPPositive_CustomPlayListViewController: UITableViewDataSource, UITableViewDelegate {
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 {
let cell = tableView.dequeueReusableCell(withIdentifier: MPPositive_SearchResultShowTableViewCellID, for: indexPath) as! MPPositive_SearchResultShowTableViewCell
if isSearchStyle {
cell.videoModel = videos[indexPath.row]
cell.videoModel = searchVideos[indexPath.row]
}else {
cell.videoModel = list?.videosArray[indexPath.row]
cell.videoModel = sortVideos[indexPath.row]
}
cell.moreBlock = {
[weak self] in
guard let self = self else {return}
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
let moreVC = MPPositive_MoreSongOperationsViewController(self.list, video: item)
moreVC.disMissBlock = {
@ -419,7 +450,7 @@ extension MPPositive_CustomPlayListViewController: UITableViewDataSource, UITabl
let cancel = UIAlertAction(title: "Cancel".localizableString(), style: .cancel)
alertController.addAction(cancel)
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_HUD.progress("Loading...".localizableString(), delay: 0.5) {
@ -439,7 +470,7 @@ extension MPPositive_CustomPlayListViewController: UITableViewDataSource, UITabl
let cancel = UIAlertAction(title: "Cancel".localizableString(), style: .cancel)
alertController.addAction(cancel)
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_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)
MP_AnalyticsManager.shared.player_b_impAction()
//
//
var array:[MPPositive_SongItemModel] = []
for (index,song) in list.videosArray.enumerated() {
let item = MPPositive_SongItemModel()
@ -479,7 +510,7 @@ extension MPPositive_CustomPlayListViewController: UITableViewDataSource, UITabl
item.relatedID = song.relatedID
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 ?? "")
lodaViewModel.improveData(currentVideo.videoId ?? "")
//

View File

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

View File

@ -7,7 +7,7 @@
import UIKit
class MPPositive_LoveArtistsViewController: MPPositive_BaseViewController {
class MPPositive_LoveArtistsViewController: MPPositive_BaseViewController, UIViewControllerTransitioningDelegate {
///广View
fileprivate lazy var adContainerView:UIView = {
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)
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 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() {
super.viewDidLoad()
setTitle("Love Artists".localizableString())
@ -43,6 +77,18 @@ class MPPositive_LoveArtistsViewController: MPPositive_BaseViewController {
guard let adContainerView = adContainerView else {return}
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) {
super.viewWillAppear(animated)
@ -53,12 +99,68 @@ class MPPositive_LoveArtistsViewController: MPPositive_BaseViewController {
MPPositive_LoadCoreModel.shared.reloadCollectionArtistViewModels {
[weak self] in
guard let self = self else {return}
tableView.showMessage(MPPositive_LoadCoreModel.shared.artistViewModels.count, title: "No Artists")
numbersLabel.text = "\(MPPositive_LoadCoreModel.shared.artistViewModels.count) \("Artists".localizableString())"
artists = MPPositive_LoadCoreModel.shared.artistViewModels
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()
}
//
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() {
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)
adContainerView.snp.makeConstraints { make in
make.left.right.equalToSuperview()
@ -76,19 +178,73 @@ class MPPositive_LoveArtistsViewController: MPPositive_BaseViewController {
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
extension MPPositive_LoveArtistsViewController: UITableViewDataSource, UITableViewDelegate {
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 {
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
}
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: "")
navigationController?.pushViewController(artistVC, animated: true)

View File

@ -15,6 +15,22 @@ class MPPositive_LoveSongsViewController: MPPositive_BaseViewController, UIViewC
return adContainerView
}()
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
private lazy var tableView:UITableView = {
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
}()
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() {
super.viewDidLoad()
setTitle("Love Songs".localizableString())
@ -43,6 +78,18 @@ class MPPositive_LoveSongsViewController: MPPositive_BaseViewController, UIViewC
guard let adContainerView = adContainerView else {return}
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) {
super.viewWillAppear(animated)
@ -53,12 +100,68 @@ class MPPositive_LoveSongsViewController: MPPositive_BaseViewController, UIViewC
MPPositive_LoadCoreModel.shared.reloadCollectionSongViewModel {
[weak self] in
guard let self = self else {return}
tableView.showMessage(MPPositive_LoadCoreModel.shared.songViewModels.count, title: "No Songs")
numbersLabel.text = "\(MPPositive_LoadCoreModel.shared.songViewModels.count) \("Songs".localizableString())"
songs = MPPositive_LoadCoreModel.shared.songViewModels
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()
}
//
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() {
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)
adContainerView.snp.makeConstraints { make in
make.left.right.equalToSuperview()
@ -76,22 +179,73 @@ class MPPositive_LoveSongsViewController: MPPositive_BaseViewController, UIViewC
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
extension MPPositive_LoveSongsViewController: UITableViewDataSource, UITableViewDelegate {
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 {
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 = {
[weak self] in
guard let self = self else {return}
MPPositive_Debouncer.shared.call {
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 = {
self.reload()
}
@ -109,7 +263,7 @@ extension MPPositive_LoveSongsViewController: UITableViewDataSource, UITableView
let cancel = UIAlertAction(title: "Cancel".localizableString(), style: .cancel)
alertController.addAction(cancel)
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_HUD.progress("Loading...".localizableString(), delay: 0.5) {
@ -129,7 +283,7 @@ extension MPPositive_LoveSongsViewController: UITableViewDataSource, UITableView
let cancel = UIAlertAction(title: "Cancel".localizableString(), style: .cancel)
alertController.addAction(cancel)
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_HUD.text("Cancel".localizableString(), delay: 1.0, completion: nil)
@ -169,8 +323,9 @@ extension MPPositive_LoveSongsViewController: UITableViewDataSource, UITableView
item.relatedID = song.collectionSong.relatedID
array.append(item)
}
let lodaViewModel = MPPositive_PlayerLoadViewModel(array, currentVideoId: MPPositive_LoadCoreModel.shared.songViewModels[indexPath.row].collectionSong.videoId ?? "")
lodaViewModel.improveData(MPPositive_LoadCoreModel.shared.songViewModels[indexPath.row].collectionSong.videoId ?? "")
let currentVideo = isSearchStyle ? searchSongs[indexPath.row]:showSongs[indexPath.row]
let lodaViewModel = MPPositive_PlayerLoadViewModel(array, currentVideoId: currentVideo.collectionSong.videoId ?? "")
lodaViewModel.improveData(currentVideo.collectionSong.videoId ?? "")
//
MP_PlayerManager.shared.setPlayType(.normal)
MP_PlayerManager.shared.loadPlayer = lodaViewModel

View File

@ -15,6 +15,22 @@ class MPPositive_OfflineSongsViewController: MPPositive_BaseViewController {
return adContainerView
}()
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
private lazy var tableView:UITableView = {
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
}()
private let MPPositive_SearchResultShowTableViewCellID = "MPPositive_SearchResultShowTableViewCell"
//
private var isSearchStyle:Bool = false
//
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() {
super.viewDidLoad()
setTitle("Offline Songs".localizableString())
@ -44,6 +77,18 @@ class MPPositive_OfflineSongsViewController: MPPositive_BaseViewController {
guard let adContainerView = adContainerView else {return}
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) {
super.viewWillAppear(animated)
@ -57,10 +102,66 @@ class MPPositive_OfflineSongsViewController: MPPositive_BaseViewController {
offlines = MPPositive_LoadCoreModel.shared.loadViewModels
tableView.showMessage(offlines.count, title: "No Songs")
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()
}
//
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() {
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)
adContainerView.snp.makeConstraints { make in
make.left.right.equalToSuperview()
@ -78,20 +179,71 @@ class MPPositive_OfflineSongsViewController: MPPositive_BaseViewController {
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
extension MPPositive_OfflineSongsViewController: UITableViewDataSource, UITableViewDelegate, UIViewControllerTransitioningDelegate{
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 {
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 = {
[weak self] in
guard let self = self else {return}
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()
song.coverUrls = [item.loadItem.coverImage]
song.reviewUrls = [item.loadItem.reviewImage]
@ -121,7 +273,7 @@ extension MPPositive_OfflineSongsViewController: UITableViewDataSource, UITableV
let cancel = UIAlertAction(title: "Cancel".localizableString(), style: .cancel)
alertController.addAction(cancel)
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_HUD.progress("Loading...".localizableString(), delay: 0.5) {
@ -141,7 +293,7 @@ extension MPPositive_OfflineSongsViewController: UITableViewDataSource, UITableV
let cancel = UIAlertAction(title: "Cancel".localizableString(), style: .cancel)
alertController.addAction(cancel)
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_HUD.text("Cancel".localizableString(), delay: 1.0, completion: nil)
@ -180,8 +332,9 @@ extension MPPositive_OfflineSongsViewController: UITableViewDataSource, UITableV
item.relatedID = song.loadItem.relatedID
array.append(item)
}
let lodaViewModel = MPPositive_PlayerLoadViewModel(array, currentVideoId: offlines[indexPath.row].loadItem.videoId ?? "")
lodaViewModel.improveData(offlines[indexPath.row].loadItem.videoId ?? "")
let currentVideo = isSearchStyle ? searchSongs[indexPath.row]:showSongs[indexPath.row]
let lodaViewModel = MPPositive_PlayerLoadViewModel(array, currentVideoId: currentVideo.loadItem.videoId ?? "")
lodaViewModel.improveData(currentVideo.loadItem.videoId ?? "")
//
MP_PlayerManager.shared.setPlayType(.normal)
MP_PlayerManager.shared.loadPlayer = lodaViewModel

View File

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

View File

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

View File

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

View File

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

View File

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