100Years преди 2 месеца
родител
ревизия
80e203ccca
променени са 52 файла, в които са добавени 1874 реда и са изтрити 682 реда
  1. 48 0
      TSLiveWallpaper.xcodeproj/project.pbxproj
  2. 6 0
      TSLiveWallpaper/Assets.xcassets/AIList/Contents.json
  3. 22 0
      TSLiveWallpaper/Assets.xcassets/AIList/aiList_Colorize.imageset/Contents.json
  4. BIN
      TSLiveWallpaper/Assets.xcassets/AIList/aiList_Colorize.imageset/aiList_Colorize@2x.png
  5. BIN
      TSLiveWallpaper/Assets.xcassets/AIList/aiList_Colorize.imageset/aiList_Colorize@3x.png
  6. 22 0
      TSLiveWallpaper/Assets.xcassets/AIList/aiList_Descratch.imageset/Contents.json
  7. BIN
      TSLiveWallpaper/Assets.xcassets/AIList/aiList_Descratch.imageset/aiList_Descratch@2x.png
  8. BIN
      TSLiveWallpaper/Assets.xcassets/AIList/aiList_Descratch.imageset/aiList_Descratch@3x.png
  9. 22 0
      TSLiveWallpaper/Assets.xcassets/AIList/aiList_Enhance.imageset/Contents.json
  10. BIN
      TSLiveWallpaper/Assets.xcassets/AIList/aiList_Enhance.imageset/aiList_Enhance@2x.png
  11. BIN
      TSLiveWallpaper/Assets.xcassets/AIList/aiList_Enhance.imageset/aiList_Enhance@3x.png
  12. 22 0
      TSLiveWallpaper/Assets.xcassets/AIList/ai_null.imageset/Contents.json
  13. BIN
      TSLiveWallpaper/Assets.xcassets/AIList/ai_null.imageset/ai_null@2x.png
  14. BIN
      TSLiveWallpaper/Assets.xcassets/AIList/ai_null.imageset/ai_null@3x.png
  15. 22 0
      TSLiveWallpaper/Assets.xcassets/AIList/hint_image.imageset/Contents.json
  16. BIN
      TSLiveWallpaper/Assets.xcassets/AIList/hint_image.imageset/hint_image@2x.png
  17. BIN
      TSLiveWallpaper/Assets.xcassets/AIList/hint_image.imageset/hint_image@3x.png
  18. 22 0
      TSLiveWallpaper/Assets.xcassets/AIList/left_Contrast_right.imageset/Contents.json
  19. BIN
      TSLiveWallpaper/Assets.xcassets/AIList/left_Contrast_right.imageset/left_Contrast_right@2x.png
  20. BIN
      TSLiveWallpaper/Assets.xcassets/AIList/left_Contrast_right.imageset/left_Contrast_right@3x.png
  21. 22 0
      TSLiveWallpaper/Assets.xcassets/AIList/nav_title_ailist.imageset/Contents.json
  22. BIN
      TSLiveWallpaper/Assets.xcassets/AIList/nav_title_ailist.imageset/nav_title_ailist@2x.png
  23. BIN
      TSLiveWallpaper/Assets.xcassets/AIList/nav_title_ailist.imageset/nav_title_ailist@3x.png
  24. 22 0
      TSLiveWallpaper/Assets.xcassets/AIList/replace_photo.imageset/Contents.json
  25. BIN
      TSLiveWallpaper/Assets.xcassets/AIList/replace_photo.imageset/replace_photo@2x.png
  26. BIN
      TSLiveWallpaper/Assets.xcassets/AIList/replace_photo.imageset/replace_photo@3x.png
  27. 22 0
      TSLiveWallpaper/Assets.xcassets/Common/delete.imageset/Contents.json
  28. BIN
      TSLiveWallpaper/Assets.xcassets/Common/delete.imageset/delete@2x.png
  29. BIN
      TSLiveWallpaper/Assets.xcassets/Common/delete.imageset/delete@3x.png
  30. 22 0
      TSLiveWallpaper/Assets.xcassets/Common/nav_shadow.imageset/Contents.json
  31. BIN
      TSLiveWallpaper/Assets.xcassets/Common/nav_shadow.imageset/nav_shadow@2x.png
  32. BIN
      TSLiveWallpaper/Assets.xcassets/Common/nav_shadow.imageset/nav_shadow@3x.png
  33. 22 0
      TSLiveWallpaper/Assets.xcassets/Common/record.imageset/Contents.json
  34. BIN
      TSLiveWallpaper/Assets.xcassets/Common/record.imageset/record@2x.png
  35. BIN
      TSLiveWallpaper/Assets.xcassets/Common/record.imageset/record@3x.png
  36. 22 0
      TSLiveWallpaper/Assets.xcassets/Tabbar/tabbar_select_ailist.imageset/Contents.json
  37. BIN
      TSLiveWallpaper/Assets.xcassets/Tabbar/tabbar_select_ailist.imageset/tabbar_select_ailist@2x.png
  38. BIN
      TSLiveWallpaper/Assets.xcassets/Tabbar/tabbar_select_ailist.imageset/tabbar_select_ailist@3x.png
  39. 45 0
      TSLiveWallpaper/Business/BusinessView/TSPageNullView.swift
  40. 259 250
      TSLiveWallpaper/Business/TSAIListVC/TSAIAgeImageHintVC/TSAIListHintBaseVC.swift
  41. 138 0
      TSLiveWallpaper/Business/TSAIListVC/TSAIList+Enmu.swift
  42. 92 0
      TSLiveWallpaper/Business/TSAIListVC/TSAIListHistoryVC/TSAIListHistoryCell.swift
  43. 117 0
      TSLiveWallpaper/Business/TSAIListVC/TSAIListHistoryVC/TSAIListHistoryVC.swift
  44. 26 9
      TSLiveWallpaper/Business/TSAIListVC/TSAIListVC/TSAILIstCell.swift
  45. 263 260
      TSLiveWallpaper/Business/TSAIListVC/TSAIListVC/TSAIListVC.swift
  46. 391 0
      TSLiveWallpaper/Business/TSAIListVC/TSAIUploadPhotoVC/TSAIUploadPhotoVC.swift
  47. 20 3
      TSLiveWallpaper/Business/TSTabBarController/TSTabBarController.swift
  48. 10 0
      TSLiveWallpaper/Common/Ex/UIFont+Ex.swift
  49. 31 0
      TSLiveWallpaper/Common/TSPhotoSizeHelper.swift
  50. 160 160
      TSLiveWallpaper/Common/ViewTool/TSPhotoPickerManager/TSPhotoPickerManager.swift
  51. 4 0
      TSLiveWallpaper/Info.plist
  52. BIN
      TSLiveWallpaper/Resource/Font/ZillaSlab-Bold.ttf

+ 48 - 0
TSLiveWallpaper.xcodeproj/project.pbxproj

@@ -177,6 +177,14 @@
 		A86857AC2DF921160089D222 /* TSAIListHintBaseVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A86857AA2DF921160089D222 /* TSAIListHintBaseVC.swift */; };
 		A86857B02DF921970089D222 /* TSAppBtnView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A86857AE2DF921970089D222 /* TSAppBtnView.swift */; };
 		A86857B22DF921F90089D222 /* TSView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A86857B12DF921F90089D222 /* TSView.swift */; };
+		A86857B72DF9258D0089D222 /* TSAIUploadPhotoVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A86857B52DF9258D0089D222 /* TSAIUploadPhotoVC.swift */; };
+		A86857B92DF925A20089D222 /* TSAIList+Enmu.swift in Sources */ = {isa = PBXBuildFile; fileRef = A86857B82DF9259C0089D222 /* TSAIList+Enmu.swift */; };
+		A86857BC2DF926110089D222 /* TSAIListHistoryVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A86857BB2DF9260D0089D222 /* TSAIListHistoryVC.swift */; };
+		A86857BE2DF926220089D222 /* TSAIListHistoryCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A86857BD2DF9261D0089D222 /* TSAIListHistoryCell.swift */; };
+		A86857C02DF926870089D222 /* TSPageNullView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A86857BF2DF926870089D222 /* TSPageNullView.swift */; };
+		A86857C22DF926ED0089D222 /* TSPhotoSizeHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = A86857C12DF926EB0089D222 /* TSPhotoSizeHelper.swift */; };
+		A86857C42DF92AEB0089D222 /* UIFont+Ex.swift in Sources */ = {isa = PBXBuildFile; fileRef = A86857C32DF92AE30089D222 /* UIFont+Ex.swift */; };
+		A86857C62DF92BE70089D222 /* ZillaSlab-Bold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = A86857C52DF92BE70089D222 /* ZillaSlab-Bold.ttf */; };
 		A8C4C0982D242154003C46FC /* LivePhoto.swift in Sources */ = {isa = PBXBuildFile; fileRef = A858EE162D1CF49B004B680F /* LivePhoto.swift */; };
 		A8C4C0A42D24218A003C46FC /* metadata.mov in Resources */ = {isa = PBXBuildFile; fileRef = A8C4C09E2D24218A003C46FC /* metadata.mov */; };
 		A8C4C0A52D24218A003C46FC /* Converter4Video.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8C4C09B2D24218A003C46FC /* Converter4Video.swift */; };
@@ -382,6 +390,14 @@
 		A86857AA2DF921160089D222 /* TSAIListHintBaseVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSAIListHintBaseVC.swift; sourceTree = "<group>"; };
 		A86857AE2DF921970089D222 /* TSAppBtnView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSAppBtnView.swift; sourceTree = "<group>"; };
 		A86857B12DF921F90089D222 /* TSView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSView.swift; sourceTree = "<group>"; };
+		A86857B52DF9258D0089D222 /* TSAIUploadPhotoVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSAIUploadPhotoVC.swift; sourceTree = "<group>"; };
+		A86857B82DF9259C0089D222 /* TSAIList+Enmu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TSAIList+Enmu.swift"; sourceTree = "<group>"; };
+		A86857BB2DF9260D0089D222 /* TSAIListHistoryVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSAIListHistoryVC.swift; sourceTree = "<group>"; };
+		A86857BD2DF9261D0089D222 /* TSAIListHistoryCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSAIListHistoryCell.swift; sourceTree = "<group>"; };
+		A86857BF2DF926870089D222 /* TSPageNullView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSPageNullView.swift; sourceTree = "<group>"; };
+		A86857C12DF926EB0089D222 /* TSPhotoSizeHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSPhotoSizeHelper.swift; sourceTree = "<group>"; };
+		A86857C32DF92AE30089D222 /* UIFont+Ex.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIFont+Ex.swift"; sourceTree = "<group>"; };
+		A86857C52DF92BE70089D222 /* ZillaSlab-Bold.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "ZillaSlab-Bold.ttf"; sourceTree = "<group>"; };
 		A8C4C0992D24218A003C46FC /* AVAssetExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AVAssetExtension.swift; sourceTree = "<group>"; };
 		A8C4C09A2D24218A003C46FC /* Converter4Image.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Converter4Image.swift; sourceTree = "<group>"; };
 		A8C4C09B2D24218A003C46FC /* Converter4Video.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Converter4Video.swift; sourceTree = "<group>"; };
@@ -758,6 +774,7 @@
 		A81CA4662D156A8100A3AAC8 /* Common */ = {
 			isa = PBXGroup;
 			children = (
+				A86857C12DF926EB0089D222 /* TSPhotoSizeHelper.swift */,
 				A86857A52DF920400089D222 /* ViewTool */,
 				A86857832DF81B510089D222 /* TSNetWork */,
 				A8F76C452D3510E700AA6E93 /* NetworkManager */,
@@ -781,6 +798,7 @@
 		A81CA4752D15778800A3AAC8 /* Ex */ = {
 			isa = PBXGroup;
 			children = (
+				A86857C32DF92AE30089D222 /* UIFont+Ex.swift */,
 				A81F5B4E2D19673500740085 /* AVAsset+Ex.swift */,
 				A81CA4B72D16A6B600A3AAC8 /* View+Ex.swift */,
 				A81CA49E2D1655BE00A3AAC8 /* UICollectionView+Ex.swift */,
@@ -922,6 +940,7 @@
 		A81CA4B22D1695F800A3AAC8 /* Font */ = {
 			isa = PBXGroup;
 			children = (
+				A86857C52DF92BE70089D222 /* ZillaSlab-Bold.ttf */,
 			);
 			path = Font;
 			sourceTree = "<group>";
@@ -1096,6 +1115,7 @@
 		A868578D2DF845D00089D222 /* BusinessView */ = {
 			isa = PBXGroup;
 			children = (
+				A86857BF2DF926870089D222 /* TSPageNullView.swift */,
 				A86857AE2DF921970089D222 /* TSAppBtnView.swift */,
 				A86857B12DF921F90089D222 /* TSView.swift */,
 				A86857972DF846FB0089D222 /* TSDynamicBlurView.swift */,
@@ -1142,6 +1162,9 @@
 		A86857A92DF9210D0089D222 /* TSAIListVC */ = {
 			isa = PBXGroup;
 			children = (
+				A86857BA2DF926070089D222 /* TSAIListHistoryVC */,
+				A86857B82DF9259C0089D222 /* TSAIList+Enmu.swift */,
+				A86857B62DF9258D0089D222 /* TSAIUploadPhotoVC */,
 				A86857AB2DF921160089D222 /* TSAIAgeImageHintVC */,
 				A868579F2DF91EA10089D222 /* TSAIListVC */,
 			);
@@ -1163,6 +1186,23 @@
 			path = General;
 			sourceTree = "<group>";
 		};
+		A86857B62DF9258D0089D222 /* TSAIUploadPhotoVC */ = {
+			isa = PBXGroup;
+			children = (
+				A86857B52DF9258D0089D222 /* TSAIUploadPhotoVC.swift */,
+			);
+			path = TSAIUploadPhotoVC;
+			sourceTree = "<group>";
+		};
+		A86857BA2DF926070089D222 /* TSAIListHistoryVC */ = {
+			isa = PBXGroup;
+			children = (
+				A86857BB2DF9260D0089D222 /* TSAIListHistoryVC.swift */,
+				A86857BD2DF9261D0089D222 /* TSAIListHistoryCell.swift */,
+			);
+			path = TSAIListHistoryVC;
+			sourceTree = "<group>";
+		};
 		A8C4C0A12D24218A003C46FC /* Util */ = {
 			isa = PBXGroup;
 			children = (
@@ -1328,6 +1368,7 @@
 			files = (
 				606372D82D545E6C005C82CF /* Example Music.mp3 in Resources */,
 				A8C4C0A42D24218A003C46FC /* metadata.mov in Resources */,
+				A86857C62DF92BE70089D222 /* ZillaSlab-Bold.ttf in Resources */,
 				60553FC42D3B528A00BAAD7F /* IJKPlayer.md in Resources */,
 				609B6EA52D6F1221007942D4 /* Localizable.strings in Resources */,
 				A8E56BF92D1520EC003C54AF /* Assets.xcassets in Resources */,
@@ -1466,6 +1507,7 @@
 				60553F7D2D3B528A00BAAD7F /* PlayDetailTopView.swift in Sources */,
 				60553F7E2D3B528A00BAAD7F /* CWOperateViewController+Ext.swift in Sources */,
 				A868577E2DF81A940089D222 /* TSDBActionInfoModel.swift in Sources */,
+				A86857B72DF9258D0089D222 /* TSAIUploadPhotoVC.swift in Sources */,
 				60553F7F2D3B528A00BAAD7F /* OperateTopView.swift in Sources */,
 				A86857822DF81AD40089D222 /* TSActionInfoModel.swift in Sources */,
 				60553F802D3B528A00BAAD7F /* PlayDetailViewController+Ext.swift in Sources */,
@@ -1491,6 +1533,7 @@
 				60553F8D2D3B528A00BAAD7F /* CWCustomProgressView.swift in Sources */,
 				60553F8E2D3B528A00BAAD7F /* PlaylistDetailViewController.swift in Sources */,
 				60553F8F2D3B528A00BAAD7F /* SleepTimeViewController.swift in Sources */,
+				A86857BE2DF926220089D222 /* TSAIListHistoryCell.swift in Sources */,
 				60553F902D3B528A00BAAD7F /* CWLoadingView.swift in Sources */,
 				60553F912D3B528A00BAAD7F /* PlayListDetaiViewModel.swift in Sources */,
 				60553F922D3B528A00BAAD7F /* SJIJKMediaPlayerLayerView.m in Sources */,
@@ -1522,6 +1565,7 @@
 				60553FA92D3B528A00BAAD7F /* CustomTextField.swift in Sources */,
 				60553FAA2D3B528A00BAAD7F /* CWOperateButton.swift in Sources */,
 				60553FAB2D3B528A00BAAD7F /* PlayListViewModel.swift in Sources */,
+				A86857B92DF925A20089D222 /* TSAIList+Enmu.swift in Sources */,
 				60553FAC2D3B528A00BAAD7F /* TagListView.swift in Sources */,
 				60553FAD2D3B528A00BAAD7F /* ImageTextControl.swift in Sources */,
 				60553FAE2D3B528A00BAAD7F /* CWProgressView.swift in Sources */,
@@ -1530,7 +1574,9 @@
 				60553FB12D3B528A00BAAD7F /* SongDownloadCell.swift in Sources */,
 				60553FB22D3B528A00BAAD7F /* LocalSearchViewModel.swift in Sources */,
 				A86857922DF845F60089D222 /* TSGeneratoringAnimationView.swift in Sources */,
+				A86857BC2DF926110089D222 /* TSAIListHistoryVC.swift in Sources */,
 				A86857932DF845F60089D222 /* TSGeneratorErrorView.swift in Sources */,
+				A86857C02DF926870089D222 /* TSPageNullView.swift in Sources */,
 				A86857942DF845F60089D222 /* TSGeneratorloadingView.swift in Sources */,
 				60553FB32D3B528A00BAAD7F /* SortMenuViewController.swift in Sources */,
 				60553FB42D3B528A00BAAD7F /* ImportFilesManager.swift in Sources */,
@@ -1558,6 +1604,7 @@
 				606372E12D54BC37005C82CF /* GoogleMobileAdsConsentManager.swift in Sources */,
 				A86857982DF846FE0089D222 /* TSDynamicBlurView.swift in Sources */,
 				A83946332D1D66A900ABFF0D /* TSPrivacyPolicyVC.swift in Sources */,
+				A86857C22DF926ED0089D222 /* TSPhotoSizeHelper.swift in Sources */,
 				A839463A2D1D6E3000ABFF0D /* TSRandomWallpaperTutorialsVC.swift in Sources */,
 				A84C239F2D1E88CD00B61B55 /* TSFileManagerTool.swift in Sources */,
 				A81F5B562D1982BF00740085 /* TSImageDataCenter.swift in Sources */,
@@ -1567,6 +1614,7 @@
 				A81CA4972D1652BD00A3AAC8 /* TSRandomWallpaperVC.swift in Sources */,
 				A81F5B622D1AB17E00740085 /* TSRandomWallpaperBrowseVC.swift in Sources */,
 				A839463F2D1D6FB700ABFF0D /* TSLiveWallpaperTutorialsVC.swift in Sources */,
+				A86857C42DF92AEB0089D222 /* UIFont+Ex.swift in Sources */,
 				A86857A12DF91EB90089D222 /* TSAIListVC.swift in Sources */,
 				A81F5B5F2D1A909300740085 /* TSRandomWallpaperModel.swift in Sources */,
 				A8F778B72D1BE9A500BF55D5 /* TSLiveWallpaperBrowseVC.swift in Sources */,

+ 6 - 0
TSLiveWallpaper/Assets.xcassets/AIList/Contents.json

@@ -0,0 +1,6 @@
+{
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

+ 22 - 0
TSLiveWallpaper/Assets.xcassets/AIList/aiList_Colorize.imageset/Contents.json

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

BIN
TSLiveWallpaper/Assets.xcassets/AIList/aiList_Colorize.imageset/aiList_Colorize@2x.png


BIN
TSLiveWallpaper/Assets.xcassets/AIList/aiList_Colorize.imageset/aiList_Colorize@3x.png


+ 22 - 0
TSLiveWallpaper/Assets.xcassets/AIList/aiList_Descratch.imageset/Contents.json

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

BIN
TSLiveWallpaper/Assets.xcassets/AIList/aiList_Descratch.imageset/aiList_Descratch@2x.png


BIN
TSLiveWallpaper/Assets.xcassets/AIList/aiList_Descratch.imageset/aiList_Descratch@3x.png


+ 22 - 0
TSLiveWallpaper/Assets.xcassets/AIList/aiList_Enhance.imageset/Contents.json

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

BIN
TSLiveWallpaper/Assets.xcassets/AIList/aiList_Enhance.imageset/aiList_Enhance@2x.png


BIN
TSLiveWallpaper/Assets.xcassets/AIList/aiList_Enhance.imageset/aiList_Enhance@3x.png


+ 22 - 0
TSLiveWallpaper/Assets.xcassets/AIList/ai_null.imageset/Contents.json

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

BIN
TSLiveWallpaper/Assets.xcassets/AIList/ai_null.imageset/ai_null@2x.png


BIN
TSLiveWallpaper/Assets.xcassets/AIList/ai_null.imageset/ai_null@3x.png


+ 22 - 0
TSLiveWallpaper/Assets.xcassets/AIList/hint_image.imageset/Contents.json

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

BIN
TSLiveWallpaper/Assets.xcassets/AIList/hint_image.imageset/hint_image@2x.png


BIN
TSLiveWallpaper/Assets.xcassets/AIList/hint_image.imageset/hint_image@3x.png


+ 22 - 0
TSLiveWallpaper/Assets.xcassets/AIList/left_Contrast_right.imageset/Contents.json

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

BIN
TSLiveWallpaper/Assets.xcassets/AIList/left_Contrast_right.imageset/left_Contrast_right@2x.png


BIN
TSLiveWallpaper/Assets.xcassets/AIList/left_Contrast_right.imageset/left_Contrast_right@3x.png


+ 22 - 0
TSLiveWallpaper/Assets.xcassets/AIList/nav_title_ailist.imageset/Contents.json

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

BIN
TSLiveWallpaper/Assets.xcassets/AIList/nav_title_ailist.imageset/nav_title_ailist@2x.png


BIN
TSLiveWallpaper/Assets.xcassets/AIList/nav_title_ailist.imageset/nav_title_ailist@3x.png


+ 22 - 0
TSLiveWallpaper/Assets.xcassets/AIList/replace_photo.imageset/Contents.json

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

BIN
TSLiveWallpaper/Assets.xcassets/AIList/replace_photo.imageset/replace_photo@2x.png


BIN
TSLiveWallpaper/Assets.xcassets/AIList/replace_photo.imageset/replace_photo@3x.png


+ 22 - 0
TSLiveWallpaper/Assets.xcassets/Common/delete.imageset/Contents.json

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

BIN
TSLiveWallpaper/Assets.xcassets/Common/delete.imageset/delete@2x.png


BIN
TSLiveWallpaper/Assets.xcassets/Common/delete.imageset/delete@3x.png


+ 22 - 0
TSLiveWallpaper/Assets.xcassets/Common/nav_shadow.imageset/Contents.json

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

BIN
TSLiveWallpaper/Assets.xcassets/Common/nav_shadow.imageset/nav_shadow@2x.png


BIN
TSLiveWallpaper/Assets.xcassets/Common/nav_shadow.imageset/nav_shadow@3x.png


+ 22 - 0
TSLiveWallpaper/Assets.xcassets/Common/record.imageset/Contents.json

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

BIN
TSLiveWallpaper/Assets.xcassets/Common/record.imageset/record@2x.png


BIN
TSLiveWallpaper/Assets.xcassets/Common/record.imageset/record@3x.png


+ 22 - 0
TSLiveWallpaper/Assets.xcassets/Tabbar/tabbar_select_ailist.imageset/Contents.json

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

BIN
TSLiveWallpaper/Assets.xcassets/Tabbar/tabbar_select_ailist.imageset/tabbar_select_ailist@2x.png


BIN
TSLiveWallpaper/Assets.xcassets/Tabbar/tabbar_select_ailist.imageset/tabbar_select_ailist@3x.png


+ 45 - 0
TSLiveWallpaper/Business/BusinessView/TSPageNullView.swift

@@ -0,0 +1,45 @@
+//
+//  TSPageNullView.swift
+//  AIEmoji
+//
+//  Created by 100Years on 2025/2/13.
+//
+
+
+class TSPageNullView: TSBaseView {
+
+    lazy var imageView: UIImageView = {
+        return UIImageView.createImageView(imageName: "pageNull")
+    }()
+    
+    lazy var titleLabel: UILabel = {
+        let titleLabel = UILabel.createLabel(text:"No record".localized ,font:.font(size: 14.0),textColor: .white,textAlignment: .center,numberOfLines: 0)
+        return titleLabel
+    }()
+    
+    
+
+    override func creatUI() {
+        
+        self.frame = CGRectMake(0, 0, k_ScreenWidth, k_ScreenHeight - k_Nav_Height)
+        
+        contentView.addSubview(imageView)
+        imageView.snp.makeConstraints { make in
+            make.top.equalTo(151)
+            make.centerX.equalToSuperview()
+            make.width.height.equalTo(120)
+        }
+
+        contentView.addSubview(titleLabel)
+        titleLabel.snp.makeConstraints { make in
+            make.top.equalTo(imageView.snp.bottom)
+            make.leading.equalTo(16)
+            make.trailing.equalTo(-16)
+            make.height.equalTo(20)
+        }
+
+    }
+    
+    
+    
+}

+ 259 - 250
TSLiveWallpaper/Business/TSAIListVC/TSAIAgeImageHintVC/TSAIListHintBaseVC.swift

@@ -5,254 +5,263 @@
 //  Created by 100Years on 2025/4/9.
 //
 
-//import PhotosUI
-//class TSAIListHintBaseVC: TSBaseVC {
-//    static var userDefaultsKey:String = "isFirstAIListAge"
-//    
-//    struct Config {
-//        var imageMaxBitSize:Int
-//        var goodImageNamed:String
-//        var badImageNamed:String
-//
-//        var titleText:String
-//        var titleSubText:String
-//        
-//        var goodText:String
-//        var goodInfoText:String
-//      
-//        var badText:String
-//        var badInfoText:String
-//        
-//        
-//        init(imageMaxBitSize: Int, goodImageNamed: String, badImageNamed: String, titleText: String, titleSubText: String, goodText: String, goodInfoText: String, badText: String, badInfoText: String) {
-//            self.imageMaxBitSize = imageMaxBitSize
-//            self.goodImageNamed = goodImageNamed
-//            self.badImageNamed = badImageNamed
-//            self.titleText = titleText
-//            self.titleSubText = titleSubText
-//            self.goodText = goodText
-//            self.goodInfoText = goodInfoText
-//            self.badText = badText
-//            self.badInfoText = badInfoText
-//        }
-//        
-//        static func getDefaultConfig(imageMaxBitSize:Int) -> Config {
-//            var config = defaultConfig
-//            config.imageMaxBitSize = imageMaxBitSize
-//            return config
-//        }
-//        
-//        static var defaultConfig:Config {
-//            return Config(imageMaxBitSize: kUploadImageMaxBit10Size,
-//                          goodImageNamed: "ptp_goodImage",
-//                          badImageNamed: "ptp_badImage",
-//                          titleText: "Upload your photos".localized,
-//                          titleSubText: "",
-//                          goodText: "Good photo examples".localized,
-//                          goodInfoText: "Fully clear and visible face, in good lighting".localized,
-//                          badText: "Bad photo examples".localized,
-//                          badInfoText: "Group photos, covered faces, nudes".localized)
-//        }
-//        
-//        static var changeHairConfig:Config {
-//            return Config(imageMaxBitSize: kUploadImageMaxBit5Size,
-//                          goodImageNamed: "ptp_hair_goodImage",
-//                          badImageNamed: "ptp_hair_badImage",
-//                          titleText: "Upload your photos".localized,
-//                          titleSubText: "",
-//                          goodText: "Good photo examples".localized,
-//                          goodInfoText: "Obvious hairstyle, Fully clear and visible face".localized,
-//                          badText: "Bad photo examples".localized,
-//                          badInfoText: "Group photos, covered faces, skinhead".localized)
-//        }
-//        
-//        static var catTohumanConfig:Config {
-//            return Config(imageMaxBitSize: kUploadImageMaxBit10Size,
-//                          goodImageNamed: "ptp_catTohuman_goodImage",
-//                          badImageNamed: "ptp_catTohuman_badImage",
-//                          titleText: "Upload your photos".localized,
-//                          titleSubText: "",
-//                          goodText: "Good photo examples".localized,
-//                          goodInfoText: "Select pet photos with clear faces".localized,
-//                          badText: "Bad photo examples".localized,
-//                          badInfoText: "No clear faces or group shots".localized)
-//        }
-//        
-//        
-//        static var futureBabyConfig:Config {
-//            return Config(imageMaxBitSize: kUploadImageMaxBit10Size,
-//                          goodImageNamed: "ptp_futureBaby_goodImage",
-//                          badImageNamed: "ptp_badImage",
-//                          titleText: "Upload your photos".localized,
-//                          titleSubText: "",
-//                          goodText: "Good photo examples".localized,
-//                          goodInfoText: "Fully clear and visible face, in good lighting".localized,
-//                          badText: "Bad photo examples".localized,
-//                          badInfoText: "Group photos, covered faces, nudes".localized)
-//        }
-//    }
-//    
-//    var config:Config = Config.defaultConfig
-//    init(config: Config, clickUpImageHandle: ((UIImage?) -> Void)? = nil) {
-//        self.config = config
-//        self.clickUpImageHandle = clickUpImageHandle
-//        super.init()
-//    }
-//    
-//    @MainActor required init?(coder: NSCoder) {
-//        fatalError("init(coder:) has not been implemented")
-//    }
-//    
-//    var clickUpImageHandle:((UIImage?)->Void)?
-//    lazy var popupContentView: UIView = {
-//        let popupContentView = UIView()
-//        popupContentView.backgroundColor = "#222222".uiColor
-//        popupContentView.cornerRadius = 20.0
-//        return popupContentView
-//    }()
-//    
-//    lazy var photoPickerManager: TSPhotoPickerManager = {
-//        let photoPickerManager = TSPhotoPickerManager(viewController: self)
-//        return photoPickerManager
-//    }()
-//    
-//    lazy var submitBtn: UIButton = {
-//        let submitBtn = kCreateNormalSubmitBtn(title: "Upload Photo".localized) { [weak self]  in
-//            guard let self = self else { return }
-//            pickSinglePhoto()
-//        }
-//        submitBtn.cornerRadius = 24.0
-//        return submitBtn
-//    }()
-//    
-//    override func createView() {
-//        setNavBarViewHidden(true)
-//        view.backgroundColor = .black.withAlphaComponent(0.7)
-//        
-//        view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(clickView)))
-//        
-//        contentView.addSubview(popupContentView)
-//        popupContentView.center = view.center
-//        
-//        popupContentView.snp.makeConstraints { make in
-//            make.leading.equalTo(20)
-//            make.trailing.equalTo(-20)
-//            make.center.equalToSuperview()
-//        }
-//        
-//        setUpUI()
-//    }
-//    
-//    @objc func clickView() {
-//        dismiss(animated: true)
-//    }
-//    
-//    
-//    func setUpUI(){
-// 
-//        let fullText = config.titleText+config.titleSubText
-//        let attString = NSMutableAttributedString(string: fullText)
+import PhotosUI
+class TSAIListHintBaseVC: TSBaseVC {
+    static var userDefaultsKey:String = "isFirstAIListAge"
+    
+    struct Config {
+        var imageMaxBitSize:Int
+        var goodImageNamed:String
+        var badImageNamed:String
+
+        var titleText:String
+        var titleSubText:String
+        
+        var goodText:String
+        var goodInfoText:String
+      
+        var badText:String
+        var badInfoText:String
+        
+        
+        init(imageMaxBitSize: Int, goodImageNamed: String, badImageNamed: String, titleText: String, titleSubText: String, goodText: String, goodInfoText: String, badText: String, badInfoText: String) {
+            self.imageMaxBitSize = imageMaxBitSize
+            self.goodImageNamed = goodImageNamed
+            self.badImageNamed = badImageNamed
+            self.titleText = titleText
+            self.titleSubText = titleSubText
+            self.goodText = goodText
+            self.goodInfoText = goodInfoText
+            self.badText = badText
+            self.badInfoText = badInfoText
+        }
+        
+        static func getDefaultConfig(imageMaxBitSize:Int) -> Config {
+            var config = defaultConfig
+            config.imageMaxBitSize = imageMaxBitSize
+            return config
+        }
+        
+        static var defaultConfig:Config {
+            return Config(imageMaxBitSize: kUploadImageMaxBit10Size,
+                          goodImageNamed: "ptp_goodImage",
+                          badImageNamed: "ptp_badImage",
+                          titleText: "Upload your photos".localized,
+                          titleSubText: "",
+                          goodText: "Good photo examples".localized,
+                          goodInfoText: "Fully clear and visible face, in good lighting".localized,
+                          badText: "Bad photo examples".localized,
+                          badInfoText: "Group photos, covered faces, nudes".localized)
+        }
+        
+        static var changeHairConfig:Config {
+            return Config(imageMaxBitSize: kUploadImageMaxBit5Size,
+                          goodImageNamed: "ptp_hair_goodImage",
+                          badImageNamed: "ptp_hair_badImage",
+                          titleText: "Upload your photos".localized,
+                          titleSubText: "",
+                          goodText: "Good photo examples".localized,
+                          goodInfoText: "Obvious hairstyle, Fully clear and visible face".localized,
+                          badText: "Bad photo examples".localized,
+                          badInfoText: "Group photos, covered faces, skinhead".localized)
+        }
+        
+        static var catTohumanConfig:Config {
+            return Config(imageMaxBitSize: kUploadImageMaxBit10Size,
+                          goodImageNamed: "ptp_catTohuman_goodImage",
+                          badImageNamed: "ptp_catTohuman_badImage",
+                          titleText: "Upload your photos".localized,
+                          titleSubText: "",
+                          goodText: "Good photo examples".localized,
+                          goodInfoText: "Select pet photos with clear faces".localized,
+                          badText: "Bad photo examples".localized,
+                          badInfoText: "No clear faces or group shots".localized)
+        }
+        
+        
+        static var futureBabyConfig:Config {
+            return Config(imageMaxBitSize: kUploadImageMaxBit10Size,
+                          goodImageNamed: "ptp_futureBaby_goodImage",
+                          badImageNamed: "ptp_badImage",
+                          titleText: "Upload your photos".localized,
+                          titleSubText: "",
+                          goodText: "Good photo examples".localized,
+                          goodInfoText: "Fully clear and visible face, in good lighting".localized,
+                          badText: "Bad photo examples".localized,
+                          badInfoText: "Group photos, covered faces, nudes".localized)
+        }
+    }
+    
+    var config:Config = Config.defaultConfig
+    init(config: Config, clickUpImageHandle: ((UIImage?) -> Void)? = nil) {
+        self.config = config
+        self.clickUpImageHandle = clickUpImageHandle
+        super.init()
+    }
+    
+    @MainActor required init?(coder: NSCoder) {
+        fatalError("init(coder:) has not been implemented")
+    }
+    
+    var clickUpImageHandle:((UIImage?)->Void)?
+    lazy var popupContentView: UIView = {
+        let popupContentView = UIView()
+        popupContentView.backgroundColor = .clear
+        return popupContentView
+    }()
+    
+    lazy var photoPickerManager: TSPhotoPickerManager = {
+        let photoPickerManager = TSPhotoPickerManager(viewController: self)
+        return photoPickerManager
+    }()
+    
+    lazy var submitBtn: UIButton = {
+        let submitBtn = kCreateNormalSubmitBtn(title: "Upload Photo".localized) { [weak self]  in
+            guard let self = self else { return }
+            pickSinglePhoto()
+        }
+        submitBtn.cornerRadius = 24.0
+        return submitBtn
+    }()
+    
+    override func createView() {
+        addNormalNavBarView()
+        _ = setNavigationItem("", imageName: "ic-close", direction: .right, action: #selector(clickView))
+        view.backgroundColor = .black.withAlphaComponent(0.7)
+     
+        contentView.addSubview(popupContentView)
+        popupContentView.center = view.center
+        
+        popupContentView.snp.makeConstraints { make in
+            make.top.equalTo(0)
+            make.bottom.equalTo(0)
+            make.leading.equalTo(28)
+            make.trailing.equalTo(-28)
+        }
+        
+        setUpUI()
+    }
+    
+    @objc func clickView() {
+        dismiss(animated: true)
+    }
+    
+    
+    func setUpUI(){
+
+        let iconImageView:UIImageView = UIImageView.createImageView(image: .hint)
+        iconImageView.addSubview(iconImageView)
+        iconImageView.snp.makeConstraints { make in
+            make.top.equalTo(16)
+            make.leading.equalTo(32)
+            make.trailing.equalTo(-32)
+        }
+        
+       let fullText = config.titleText+config.titleSubText
+       let attString = NSMutableAttributedString(string: fullText)
 //        let mainRange = NSRange(location: 0, length: config.titleText.count)
-//        attString.addAttributes([.font:UIFont.font(size: 18,weight: .semibold),.foregroundColor:UIColor.white], range: NSRange(location: 0, length: config.titleText.count))
-//        attString.addAttributes([.font:UIFont.font(size: 12),.foregroundColor:UIColor.white.withAlphaComponent(0.6)], range: NSRange(location: config.titleText.count, length: config.titleSubText.count))
-//
-//        let titleLabel = UILabel.createLabel(numberOfLines: 0)
-//        titleLabel.attributedText = attString
-//        popupContentView.addSubview(titleLabel)
-//        titleLabel.snp.makeConstraints { make in
-//            make.leading.top.equalTo(32)
-//            make.trailing.equalTo(-32)
-//        }
-//        
-//        let goodLabel = UILabel.createLabel(text: config.goodText,font: .font(size: 16,weight: .medium),textColor: .white,numberOfLines: 0)
-//        popupContentView.addSubview(goodLabel)
-//        goodLabel.snp.makeConstraints { make in
-//            make.top.equalTo(titleLabel.snp.bottom).offset(28)
-//            make.leading.equalTo(32)
-//            make.trailing.equalTo(-32)
-//        }
-//        
-//        let goodInfoLabel = UILabel.createLabel(text: config.goodInfoText,font: .font(size: 14),textColor: .white.withAlphaComponent(0.6),numberOfLines: 0)
-//        popupContentView.addSubview(goodInfoLabel)
-//        goodInfoLabel.snp.makeConstraints { make in
-//            make.top.equalTo(goodLabel.snp.bottom).offset(8)
-//            make.leading.equalTo(32)
-//            make.trailing.equalTo(-32)
-//        }
-//        
-//        let goodImageView = UIImageView.createImageView(imageName: config.goodImageNamed)
-//        popupContentView.addSubview(goodImageView)
-//        goodImageView.snp.makeConstraints { make in
-//            make.top.equalTo(goodInfoLabel.snp.bottom).offset(12)
-//            make.leading.equalTo(32)
-//            make.trailing.equalTo(-32)
-//            make.height.equalTo(108*kDesignScale)
-//        }
-//        
-//        let badLabel = UILabel.createLabel(text: config.badText,font: .font(size: 16,weight: .medium),textColor: .white,numberOfLines: 0)
-//        popupContentView.addSubview(badLabel)
-//        badLabel.snp.makeConstraints { make in
-//            make.top.equalTo(goodImageView.snp.bottom).offset(28)
-//            make.leading.equalTo(32)
-//            make.trailing.equalTo(-32)
-//        }
-//        
-//        let badInfoLabel = UILabel.createLabel(text: config.badInfoText,font: .font(size: 14),textColor: .white.withAlphaComponent(0.6),numberOfLines: 0)
-//        popupContentView.addSubview(badInfoLabel)
-//        badInfoLabel.snp.makeConstraints { make in
-//            make.top.equalTo(badLabel.snp.bottom).offset(8)
-//            make.leading.equalTo(32)
-//            make.trailing.equalTo(-32)
-//        }
-//        
-//        let badImageView = UIImageView.createImageView(imageName: config.badImageNamed)
-//        popupContentView.addSubview(badImageView)
-//        badImageView.snp.makeConstraints { make in
-//            make.top.equalTo(badInfoLabel.snp.bottom).offset(12)
-//            make.leading.equalTo(32)
-//            make.trailing.equalTo(-32)
-//            make.height.equalTo(108*kDesignScale)
-//        }
-//        
-//        popupContentView.addSubview(submitBtn)
-//        submitBtn.snp.makeConstraints { make in
-//            make.top.equalTo(badImageView.snp.bottom).offset(35)
-//            make.centerX.equalToSuperview()
-//            make.width.equalTo(250*kDesignScale)
-//            make.height.equalTo(48)
-//            make.bottom.equalTo(-24)
-//        }
-//    }
-//
-//    static var isShowUploadImageHint:Bool{
-//        get {
-//            return UserDefaults.standard.string(forKey: userDefaultsKey) == nil
-//        }
-//        
-//        set {
-//            UserDefaults.standard.set(newValue ? nil : "1", forKey: userDefaultsKey)
-//            UserDefaults.standard.synchronize()
-//        }
-//    }
-//    
-//    func pickSinglePhoto()  {
-//        self.submitBtn.isUserInteractionEnabled = false
-//        photoPickerManager.pickCustomSinglePhoto() { [weak self] image, errorString in
-//            guard let self = self else { return }
-//            self.submitBtn.isUserInteractionEnabled = true
-//            if let errorString = errorString {
-//                TSToastShared.showToast(text: errorString)
-//            }else{
-//                self.clickUpImageHandle?(image)
-//            }
-//        }
-//        
-//  
-//    }
-//    
-//    func dismissPageVC(){
-//        self.view.isHidden = true
-//        self.photoPickerManager.dismissPageVC()
-//        self.dismiss(animated: true)
-//    }
-//}
+       attString.addAttributes([.font:UIFont.font(name:.ZillaSlabBold ,size: 26,weight: .bold),.foregroundColor:UIColor.white], range: NSRange(location: 0, length: config.titleText.count))
+       attString.addAttributes([.font:UIFont.font(size: 12),.foregroundColor:UIColor.white.withAlphaComponent(0.6)], range: NSRange(location: config.titleText.count, length: config.titleSubText.count))
+
+        let titleLabel = UILabel.createLabel(numberOfLines: 0)
+        titleLabel.attributedText = attString
+        popupContentView.addSubview(titleLabel)
+        titleLabel.snp.makeConstraints { make in
+            make.leading.equalTo(0)
+            make.top.equalTo(iconImageView.snp.bottom).offset(24)
+            make.width.height.equalTo(40)
+        }
+        
+        let goodImageView = UIImageView.createImageView(imageName: config.goodImageNamed)
+        popupContentView.addSubview(goodImageView)
+        goodImageView.snp.makeConstraints { make in
+            make.top.equalTo(titleLabel.snp.bottom).offset(32)
+            make.leading.equalTo(0)
+            make.trailing.equalTo(0)
+            make.height.equalTo(112*kDesignScale)
+        }
+        
+        let goodLabel = UILabel.createLabel(text: config.goodText,font: .font(size: 16,weight: .medium),textColor: .white,numberOfLines: 0)
+        popupContentView.addSubview(goodLabel)
+        goodLabel.snp.makeConstraints { make in
+            make.top.equalTo(goodImageView.snp.bottom).offset(12)
+            make.leading.equalTo(0)
+            make.trailing.equalTo(0)
+        }
+        
+        let goodInfoLabel = UILabel.createLabel(text: config.goodInfoText,font: .font(size: 14),textColor: .white.withAlphaComponent(0.6),numberOfLines: 0)
+        popupContentView.addSubview(goodInfoLabel)
+        goodInfoLabel.snp.makeConstraints { make in
+            make.top.equalTo(goodLabel.snp.bottom).offset(8)
+            make.leading.equalTo(0)
+            make.trailing.equalTo(0)
+        }
+        
+        let badImageView = UIImageView.createImageView(imageName: config.badImageNamed)
+        popupContentView.addSubview(badImageView)
+        badImageView.snp.makeConstraints { make in
+            make.top.equalTo(goodInfoLabel.snp.bottom).offset(20)
+            make.leading.equalTo(0)
+            make.trailing.equalTo(0)
+            make.height.equalTo(112*kDesignScale)
+        }
+        
+        let badLabel = UILabel.createLabel(text: config.badText,font: .font(size: 16,weight: .medium),textColor: .white,numberOfLines: 0)
+        popupContentView.addSubview(badLabel)
+        badLabel.snp.makeConstraints { make in
+            make.top.equalTo(badImageView.snp.bottom).offset(12)
+            make.leading.equalTo(0)
+            make.trailing.equalTo(0)
+        }
+        
+        let badInfoLabel = UILabel.createLabel(text: config.badInfoText,font: .font(size: 14),textColor: .white.withAlphaComponent(0.6),numberOfLines: 0)
+        popupContentView.addSubview(badInfoLabel)
+        badInfoLabel.snp.makeConstraints { make in
+            make.top.equalTo(badLabel.snp.bottom).offset(8)
+            make.leading.equalTo(0)
+            make.trailing.equalTo(0)
+            make.bottom.equalTo(0)
+        }
+        
+
+        popupContentView.addSubview(submitBtn)
+        submitBtn.snp.makeConstraints { make in
+            make.centerX.equalToSuperview()
+            make.width.equalTo(248*kDesignScale)
+            make.height.equalTo(48)
+            make.bottom.equalTo(-43-k_Height_safeAreaInsetsBottom())
+        }
+    }
+
+    static var isShowUploadImageHint:Bool{
+        get {
+            return UserDefaults.standard.string(forKey: userDefaultsKey) == nil
+        }
+        
+        set {
+            UserDefaults.standard.set(newValue ? nil : "1", forKey: userDefaultsKey)
+            UserDefaults.standard.synchronize()
+        }
+    }
+    
+    func pickSinglePhoto()  {
+        self.submitBtn.isUserInteractionEnabled = false
+        photoPickerManager.pickCustomSinglePhoto() { [weak self] image, errorString in
+            guard let self = self else { return }
+            self.submitBtn.isUserInteractionEnabled = true
+            if let errorString = errorString {
+                TSToastShared.showToast(text: errorString)
+            }else{
+                self.clickUpImageHandle?(image)
+            }
+        }
+        
+  
+    }
+    
+    func dismissPageVC(){
+        self.view.isHidden = true
+        self.photoPickerManager.dismissPageVC()
+        self.dismiss(animated: true)
+    }
+}

+ 138 - 0
TSLiveWallpaper/Business/TSAIListVC/TSAIList+Enmu.swift

@@ -0,0 +1,138 @@
+//
+//  TSAIList+Enmu.swift
+//  TSLiveWallpaper
+//
+//  Created by 100Years on 2025/6/10.
+//
+
+enum TSGeneratorImageStyle {
+    case ageOld      //变老
+    case ageChild   //变年轻
+    case oldPhoto   //旧照片修复
+    case eyeOpen    //开眼
+    case pretty     //变美
+    case photoLive     //把照片变活
+    case photoExpand     //照片扩展
+    case photoQuality    //照片变高清
+    case motherDay    //母亲节
+    case catTohuman    //猫变人
+    case futureBaby    //预测宝宝
+    
+    
+    var imageMaxKb:Int{
+        switch self {
+        case .ageOld:
+            return 10*1024
+        case .ageChild:
+            return 10*1024
+        case .oldPhoto:
+            return 5*1024
+        case .eyeOpen:
+            return 5*1024
+        case .pretty:
+            return 5*1024
+        case .photoLive:
+            return 10*1024
+        case .photoExpand:
+            return 10*1024
+        case .photoQuality:
+            return 10*1024
+        case .motherDay:
+            return 10*1024
+        case .catTohuman:
+            return 10*1024
+        case .futureBaby:
+            return 10*1024
+        }
+    }
+    
+    var imageMaxBitSize:Int{
+        switch self {
+        case .ageOld:
+            return kUploadImageMaxBit10Size
+        case .ageChild:
+            return kUploadImageMaxBit10Size
+        case .oldPhoto:
+            return kUploadImageMaxBit5Size
+        case .eyeOpen:
+            return kUploadImageMaxBit5Size
+        case .pretty:
+            return kUploadImageMaxBit5Size
+        case .photoLive:
+            return kUploadImageMaxBit10Size
+        case .photoExpand:
+            return kUploadImageMaxBit10Size
+        case .photoQuality:
+            return kUploadImageMaxBit10Size
+        case .motherDay:
+            return kUploadImageMaxBit10Size
+        case .catTohuman:
+            return kUploadImageMaxBit10Size
+        case .futureBaby:
+            return kUploadImageMaxBit10Size
+        }
+    }
+    
+    var userDefaultsKey:String{
+        switch self {
+        case .ageOld:
+            return "isFirstAIListAgeOldHintVC"
+        case .ageChild:
+            return "isFirstAIListAgeChildHintVC"
+        case .oldPhoto:
+            return "isFirstAIChangeRestOldPhoto"
+        case .eyeOpen:
+            return "isFirstAIEyeOpenPhoto"
+        case .pretty:
+            return "isFirstAIPrettyPhoto"
+        case .photoLive:
+            return "isFirstAILivePhoto"
+        case .photoExpand:
+            return ""
+        case .photoQuality:
+            return ""
+        case .motherDay:
+            return "isFirstAIMotherDay"
+        case .catTohuman:
+            return "isFirstAICatTohuman"
+        case .futureBaby:
+            return "isFirstAIFutureBaby"
+        }
+    }
+    
+    var config:TSAIListHintBaseVC.Config{
+        switch self {
+        case .ageOld:
+            return .defaultConfig
+        case .ageChild:
+            return .defaultConfig
+        case .oldPhoto:
+            return .getDefaultConfig(imageMaxBitSize: imageMaxBitSize)
+        case .eyeOpen:
+            return .getDefaultConfig(imageMaxBitSize: imageMaxBitSize)
+        case .pretty:
+            return .getDefaultConfig(imageMaxBitSize:imageMaxBitSize)
+        case .photoLive:
+            return .getDefaultConfig(imageMaxBitSize: imageMaxBitSize)
+        case .photoExpand:
+            return .getDefaultConfig(imageMaxBitSize:imageMaxBitSize)
+        case .photoQuality:
+            return .defaultConfig
+        case .motherDay:
+            return .getDefaultConfig(imageMaxBitSize: imageMaxBitSize)
+        case .catTohuman:
+            return .catTohumanConfig
+        case .futureBaby:
+            return .futureBabyConfig
+        }
+    }
+    
+    var advance:Bool{
+        switch self {
+        case .catTohuman,.motherDay,.futureBaby:
+            return true
+        default:
+            return false
+        }
+    }
+}

+ 92 - 0
TSLiveWallpaper/Business/TSAIListVC/TSAIListHistoryVC/TSAIListHistoryCell.swift

@@ -0,0 +1,92 @@
+//
+//  TSAIListHistoryCell.swift
+//  TSLiveWallpaper
+//
+//  Created by 100Years on 2025/6/10.
+//
+
+class TSAIListHistoryCell: TSBaseCollectionCell,TSSimpleConfigurableView {
+    weak var delegate: (any TSSmalCoacopods.TSSimpleCollectionViewDelegate)?
+    var indexPath: IndexPath = IndexPath(item: 0, section: 0)
+    var data: Any? {
+        didSet {
+//            debugPrint("TSAIListHistoryBaseCell data didSet")
+            if let dataModel = data as? TSActionInfoModel{
+                videoIconImageView.isHidden = true
+                exampleView.isHidden = true
+                if dataModel.modelType == .example {
+                    textLabel.text = "Example".localized
+                    exampleView.isHidden = false
+                    showImageView.image = UIImage(named: dataModel.response.resultUrl)
+                }else{
+                    if dataModel.isVideo {
+                        videoIconImageView.isHidden = false
+                        self.showImageView.image = UIImage(contentsOfFile: dataModel.videoThumbnailURL.path)
+                    }else {
+                        showImageView.setAsyncImage(urlString: dataModel.response.resultUrl,contentMode: .scaleAspectFill,backgroundColor: .white.withAlphaComponent(0.1))
+                    }
+                }
+            }
+        }
+    }
+    
+    lazy var textLabel: UILabel = {
+        let textLabel = UILabel.createLabel(
+            text: "Example".localized,
+            font: .font(size: 12),
+            textColor: .white
+        )
+        return textLabel
+    }()
+    
+    lazy var exampleView: UIView = {
+        let exampleView = UIView()
+        exampleView.backgroundColor = "#232323".uiColor.withAlphaComponent(0.3)
+        
+        exampleView.addSubview(textLabel)
+        textLabel.snp.makeConstraints { make in
+            make.top.edges.equalTo(UIEdgeInsets(top: 4, left: 6, bottom: 4, right: 6))
+        }
+        exampleView.isHidden = true
+        exampleView.cornerRadius = 10.0
+        return exampleView
+    }()
+    
+    lazy var showImageView: UIImageView = {
+        let showImageView = UIImageView.createImageView(imageName:"",contentMode: .scaleAspectFill)
+        showImageView.backgroundColor = .gray
+        showImageView.layer.cornerRadius = 18
+        return showImageView
+    }()
+    
+    lazy var videoIconImageView: UIImageView = {
+        let videoIconImageView = UIImageView.createImageView(imageName:"video_icon",contentMode: .scaleToFill)
+        videoIconImageView.isHidden = true
+        return videoIconImageView
+    }()
+    
+    
+    override func creatUI() {
+//        debugPrint("TSAIListHistoryBaseCell creatUI")
+        contentView.addSubview(showImageView)
+        showImageView.snp.makeConstraints { make in
+            make.top.equalTo(0)
+            make.leading.equalTo(0)
+            make.trailing.bottom.equalTo(0)
+        }
+        
+        contentView.addSubview(exampleView)
+        exampleView.snp.makeConstraints { make in
+            make.top.equalTo(8)
+            make.leading.equalTo(8)
+            make.height.equalTo(20)
+        }
+        
+        contentView.addSubview(videoIconImageView)
+        videoIconImageView.snp.makeConstraints { make in
+            make.top.equalTo(8)
+            make.leading.equalTo(8)
+            make.width.height.equalTo(24)
+        }
+    }
+}

+ 117 - 0
TSLiveWallpaper/Business/TSAIListVC/TSAIListHistoryVC/TSAIListHistoryVC.swift

@@ -0,0 +1,117 @@
+//
+//  TSAIListHistoryVC.swift
+//  TSLiveWallpaper
+//
+//  Created by 100Years on 2025/6/10.
+//
+
+
+class TSAIListHistoryVC: TSBaseVC {
+
+    var listModelArray: [TSActionInfoModel] = []
+    //###################################### 集合视图 ######################################
+    let collectionViewBtootm:CGFloat = 80
+    lazy var collectionView: TSSimpleCollectionView = {
+        let identifier = "TSAIListHistoryCell"
+        
+        let itemW = (k_ScreenWidth-32.0-12.0-2.0)/2.0
+        let itemH = kGetScaleHeight(originalSize: CGSize(width: 165.0, height: 293.0), width: itemW)
+        
+        let layout = UICollectionViewFlowLayout()
+        let cp = TSSimpleCollectionView()
+        cp.layout.itemSize = CGSize(width: itemW, height: itemH)
+        cp.layout.minimumLineSpacing = 12
+        cp.layout.minimumInteritemSpacing = 12
+        cp.delegate = self
+        cp.collectionView.contentInset = UIEdgeInsets(top: 16, left: 16, bottom: collectionViewBtootm, right: 16)
+        cp.registerCell(TSAIListHistoryCell.self,identifier:identifier)
+        cp.cellIdentifierForItem = { data in
+            return identifier
+        }
+
+        return cp
+    }()
+    
+    lazy var pageNullView: TSPageNullView = {
+        let pageNullView = TSPageNullView()
+        pageNullView.isHidden = true
+        return pageNullView
+    }()
+    
+    override func createData() {
+        
+    }
+    
+    var navRightBtn = UIButton()
+    override func createView() {
+        addNormalNavBarView()
+        
+        setPageTitle("History".localized)
+        navRightBtn = setNavigationItem("", imageName: "ai_delete", direction: .right, action: #selector(clickNavRight))
+   
+        contentView.addSubview(pageNullView)
+        contentView.addSubview(collectionView)
+        collectionView.snp.makeConstraints { make in
+            make.edges.equalToSuperview()
+        }
+    }
+    
+    override func dealThings() {
+        updateDataView()
+    }
+    
+    func updateDataView(){
+        dbHistory.getModelList { [weak self] array in
+            guard let self = self else { return }
+            listModelArray = array
+            updateView()
+        }
+    }
+    
+    func updateView() {
+        collectionView.reload(with:[TSSimpleSectionData(items: listModelArray)])
+        
+        navRightBtn.isHidden = listModelArray.count <= 0
+        pageNullView.isHidden = listModelArray.count > 0
+    }
+    
+    @objc func clickNavRight() {
+        showCustomAlert(message: "Are you sure to delete all histories?".localized, rightActionString: "Delete All".localized ,deleteHandler:  {
+            self.removeAllHistoryList()
+            self.updateDataView()
+        })
+    }
+    
+}
+
+extension TSAIListHistoryVC: TSSimpleCollectionViewDelegate {
+    
+    func collectionView(didTrigger event: TSSmalCoacopods.TSSimpleCellEvent) {
+        switch event.action {
+//        case .tap:
+//            let browseVC = TSAIPhotoBrowseVC()
+//            browseVC.dataModelArray = listModelArray
+//            browseVC.currentIndex = event.indexPath.item
+//            browseVC.deleteComplete = { [weak self]  deleteModel in
+//                guard let self = self else { return }
+//                dbHistory.deleteListModel(id: deleteModel.id)
+//                updateDataView()
+//            }
+//            kPresentModalVC(target: self, modelVC: browseVC,transitionStyle: .crossDissolve)
+        default:
+            break
+        }
+    }
+    
+}
+
+extension TSAIListHistoryVC{
+    func removeAllHistoryList(){
+        dbHistory.delete()
+        updateView()
+    }
+    
+    var dbHistory:TSDBHistory{
+        TSRMShared.aiListDB
+    }
+}

+ 26 - 9
TSLiveWallpaper/Business/TSAIListVC/TSAIListVC/TSAILIstCell.swift

@@ -28,7 +28,7 @@ class TSAILIstCell: TSBaseCollectionCell {
     
     
     lazy var titleLab: UILabel = {
-        let titleLab = UILabel.createLabel(font: .font(size: 18,weight: .medium),textColor: .fromHex("FFFFFF"),numberOfLines: 0)
+        let titleLab = UILabel.createLabel(font: .font(name: .ZillaSlabBold,size: 18,weight: .bold),textColor:.fromHex("FFFFFF"),numberOfLines: 0)
         return titleLab
     }()
     
@@ -37,6 +37,17 @@ class TSAILIstCell: TSBaseCollectionCell {
         return infoLab
     }()
     
+    
+    lazy var tryBtn: UIButton = {
+        let tryBtn = UIButton.createButton(title: "Try".localized,font: .font(name: .ZillaSlabBold,size: 14,weight: .medium),titleColor: "#121212".uiColor,corner: 13)
+        tryBtn.isUserInteractionEnabled = false
+        tryBtn.contentEdgeInsets = UIEdgeInsets(top: 6, left: 20, bottom: 6, right: 20)
+        kMainAsync {
+            tryBtn.addGradientBg(colors: ["#F1D3AB".uiCGColor,"#E4A858".uiCGColor])
+        }
+        return tryBtn
+    }()
+    
     override func creatUI() {
         bgContentView.clipsToBounds = true
         bgContentView.addSubview(bgImageView)
@@ -44,22 +55,28 @@ class TSAILIstCell: TSBaseCollectionCell {
             make.top.bottom.leading.trailing.equalTo(0)
         }
         
-        let leading = 12.0
-        let trailing = -155.0*kDesignScale
+        let leading = 16.0
+        let trailing = -186.0*kDesignScale
+        bgContentView.addSubview(titleLab)
+        titleLab.snp.makeConstraints { make in
+            make.trailing.equalTo(trailing)
+            make.leading.equalTo(leading)
+            make.top.equalTo(43)
+        }
+
         bgContentView.addSubview(infoLab)
         infoLab.snp.makeConstraints { make in
             make.trailing.equalTo(trailing)
             make.leading.equalTo(leading)
-            make.bottom.equalTo(-12)
+            make.top.equalTo(titleLab.snp.bottom).offset(8)
             make.height.greaterThanOrEqualTo(16)
         }
 
-        bgContentView.addSubview(titleLab)
-        titleLab.snp.makeConstraints { make in
-            make.trailing.equalTo(trailing)
+        bgContentView.addSubview(tryBtn)
+        tryBtn.snp.makeConstraints { make in
+            make.bottom.equalTo(-43)
             make.leading.equalTo(leading)
-            make.bottom.equalTo(infoLab.snp.top).offset(-8)
-            make.height.greaterThanOrEqualTo(18)
+            make.height.equalTo(26)
         }
     }
     

+ 263 - 260
TSLiveWallpaper/Business/TSAIListVC/TSAIListVC/TSAIListVC.swift

@@ -6,270 +6,273 @@
 //
 
 
-//class TSAILIstVC: TSBaseVC {
-//    
-//    lazy var dataArray: [TSBasicSectionModel] = {
-//        var dataArray = [TSBasicSectionModel]()
-//        let sectionModel = TSBasicSectionModel()
-//        dataArray.append(sectionModel)
-//        
-//        //照片高清修复
-//        sectionModel.addSubItemModel(
-//            createItemModel(
-//                leftImageName:"aiList_quality",
-//                leftTitle: "Photo Enhancer".localized,
-//                leftSubTitle: "Enhance photo's quality".localized,
-//                rightViewStyle: 0,
-//                tapBlock: { [weak self] model, _, _ in
-//                   guard let self = self else { return }
-//                    enterSelectPhotos(
-//                        userDefaultsKey: "",,
-//                        maxBitSize: kUploadImageMaxBit10Size,
-//                        config:.defaultConfig
-//                    ) { image in
-//                    let baseVc = TSAIUploadPhotoBaseVC(titleString: model.leftTitle ?? "",upLoadImage: nil,imageMaxBitSize: kUploadImageMaxBit10Size, generatorStyle: .photoQuality)
-//                        kPushVC(target: self, modelVC: baseVc)
-//                    }
-//        }))
-//        //老照片修复
-//        sectionModel.addSubItemModel(
-//            createItemModel(
-//                leftImageName:"aiList_restOldPhoto",
-//                leftTitle: "Restoring Photo".localized,
-//                leftSubTitle: "AI helps you find the good moments of the past".localized,
-//                rightViewStyle: 0,
-//                tapBlock: { [weak self] model, _, _ in
-//                   guard let self = self else { return }
-//                    enterSelectPhotos(
-//                        userDefaultsKey: "isFirstAIChangeRestOldPhoto",
-//                        maxBitSize: kUploadImageMaxBit5Size,
-//                        config: .getDefaultConfig(imageMaxBitSize: kUploadImageMaxBit5Size)
-//                    ) { image in
-//                        let baseVc = TSAIUploadPhotoBaseVC(titleString: model.leftTitle ?? "",upLoadImage: nil,imageMaxBitSize: kUploadImageMaxBit5Size, generatorStyle: .oldPhoto)
-//                        kPushVC(target: self, modelVC: baseVc)
-//                    }
-//        }))
-//
-//        return dataArray
-//
-//    }()
-//    
-//    var hintBaseVC:TSAIListHintBaseVC = TSAIListHintBaseVC(config: .defaultConfig)
-//    //###################################### 导航栏 view ######################################
-//
-//    lazy var vipBtn: UIButton = {
-//       let vipBtn = UIButton.createButton(image: UIImage(named: "nav_vip")) { [weak self]  in
-//           guard let self = self else { return }
-//           TSPurchaseVC.show(target: self) {}
-//       }
-//       return vipBtn
-//   }()
-//    
-//
-//    lazy var navBarView: TSBaseNavContentBarView = {
-//       let navBarView = TSBaseNavContentBarView()
-//       
-//       let titleImageView = UIImageView.createImageView(imageName: "nav_title_ailist",contentMode: .scaleToFill)
-//       navBarView.barView.addSubview(titleImageView)
-//       titleImageView.snp.makeConstraints { make in
-//           make.centerY.equalToSuperview()
-//           make.left.equalTo(16)
-//       }
-//       
-//       navBarView.barView.addSubview(vipBtn)
-//       vipBtn.snp.makeConstraints { make in
-//           make.centerY.equalToSuperview()
-//           make.trailing.equalTo(-16)
-//           make.width.height.equalTo(24)
-//       }
-//       
-//       return navBarView
-//   }()
-//    
-//    //###################################### 导航栏 ######################################
-//    lazy var layout: UICollectionViewFlowLayout = {
-//        let layout = UICollectionViewFlowLayout()
-//        layout.scrollDirection = .vertical
-//        let w = k_ScreenWidth-32
-//        let h = kGetScaleHeight(originalSize: CGSizeMake(343, 124), width: w)
-//        layout.itemSize = CGSize(width: w, height: h)
-//        layout.minimumInteritemSpacing = 9.0
-//        layout.minimumLineSpacing = 16.0
-//        
-//        layout.sectionInset = UIEdgeInsets(top: 16, left: 16, bottom: 16, right: 16)
-//        return layout
-//    }()
-//    lazy var collectionView: UICollectionView = {
-//        let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
-//        collectionView.delegate = self
-//        collectionView.dataSource = self
-//        collectionView.showsVerticalScrollIndicator = false
-//        collectionView.showsHorizontalScrollIndicator = false
-//        collectionView.backgroundColor = .clear
-//        collectionView.register(TSAILIstCell.self, forCellWithReuseIdentifier: TSAILIstCell.cellID)
-//        if #available(iOS 11.0, *) {
-//            collectionView.contentInsetAdjustmentBehavior = .never
-//        }
-//        return collectionView
-//    }()
-//
-//    lazy var photoPickerManager: TSPhotoPickerManager = {
-//        let photoPickerManager = TSPhotoPickerManager(viewController: self)
-//        return photoPickerManager
-//    }()
-//    
-//    override func createView() {
-//        
-//        navBarContentView.addSubview(navBarView)
-//        navBarView.snp.makeConstraints { make in
-//            make.edges.equalToSuperview()
-//        }
-//
-//        contentView.addSubview(collectionView)
-//        collectionView.snp.makeConstraints { make in
-//            make.edges.equalToSuperview()
-//        }
-//    }
-//    
-//    override func dealThings() {
+class TSAIListVC: TSBaseVC {
+    
+    lazy var dataArray: [TSBasicSectionModel] = {
+        var dataArray = [TSBasicSectionModel]()
+        let sectionModel = TSBasicSectionModel()
+        dataArray.append(sectionModel)
+        
+        //照片高清修复
+        sectionModel.addSubItemModel(
+            createItemModel(
+                leftImageName:"aiList_Enhance",
+                leftTitle: "Enhance".localized,
+                leftSubTitle: "Remove blur, sharpen, add details".localized,
+                rightViewStyle: 0,
+                tapBlock: { [weak self] model, _, _ in
+                   guard let self = self else { return }
+                    enterSelectPhotos(
+                        userDefaultsKey: "kEnhanceTipsHint",
+                        maxBitSize: kUploadImageMaxBit10Size,
+                        config:.defaultConfig
+                    ) { image in
+                    let baseVc = TSAIUploadPhotoVC(titleString: model.leftTitle ?? "",upLoadImage: nil,imageMaxBitSize: kUploadImageMaxBit10Size, generatorStyle: .photoQuality)
+                        kPushVC(target: self, modelVC: baseVc)
+                    }
+        }))
+        
+        //黑白照片变颜色
+        sectionModel.addSubItemModel(
+            createItemModel(
+                leftImageName:"aiList_Colorize",
+                leftTitle: "Colorize".localized,
+                leftSubTitle: "Add colors to black-and-white photos".localized,
+                rightViewStyle: 0,
+                tapBlock: { [weak self] model, _, _ in
+                   guard let self = self else { return }
+                    enterSelectPhotos(
+                        userDefaultsKey: "kColorizeTipsHint",
+                        maxBitSize: kUploadImageMaxBit10Size,
+                        config:.defaultConfig
+                    ) { image in
+                    let baseVc = TSAIUploadPhotoVC(titleString: model.leftTitle ?? "",upLoadImage: nil,imageMaxBitSize: kUploadImageMaxBit10Size, generatorStyle: .photoQuality)
+                        kPushVC(target: self, modelVC: baseVc)
+                    }
+        }))
+        
+        //老照片修复
+        sectionModel.addSubItemModel(
+            createItemModel(
+                leftImageName:"aiList_Descratch",
+                leftTitle: "Descratch".localized,
+                leftSubTitle: "Remove scratches and dirt".localized,
+                rightViewStyle: 0,
+                tapBlock: { [weak self] model, _, _ in
+                   guard let self = self else { return }
+                    enterSelectPhotos(
+                        userDefaultsKey: "kDescratchTipsHint",
+                        maxBitSize: kUploadImageMaxBit5Size,
+                        config: .getDefaultConfig(imageMaxBitSize: kUploadImageMaxBit5Size)
+                    ) { image in
+                        let baseVc = TSAIUploadPhotoVC(titleString: model.leftTitle ?? "",upLoadImage: nil,imageMaxBitSize: kUploadImageMaxBit5Size, generatorStyle: .oldPhoto)
+                        kPushVC(target: self, modelVC: baseVc)
+                    }
+        }))
+
+        return dataArray
+
+    }()
+    
+    var hintBaseVC:TSAIListHintBaseVC = TSAIListHintBaseVC(config: .defaultConfig)
+    //###################################### 导航栏 view ######################################
+
+    lazy var recordBtn: UIButton = {
+       let recordBtn = UIButton.createButton(image: UIImage(named: "record")) { [weak self]  in
+           guard let self = self else { return }
+           kPushVC(target: self, modelVC: TSAIListHistoryVC())
+       }
+       return recordBtn
+   }()
+    
+
+    lazy var navBarView: TSBaseNavContentBarView = {
+       let navBarView = TSBaseNavContentBarView()
+       
+       let titleImageView = UIImageView.createImageView(imageName: "nav_title_ailist",contentMode: .scaleToFill)
+       navBarView.barView.addSubview(titleImageView)
+       titleImageView.snp.makeConstraints { make in
+           make.centerY.equalToSuperview()
+           make.left.equalTo(16)
+       }
+       
+       navBarView.barView.addSubview(recordBtn)
+        recordBtn.snp.makeConstraints { make in
+           make.centerY.equalToSuperview()
+           make.trailing.equalTo(-16)
+           make.width.height.equalTo(24)
+       }
+       
+       return navBarView
+   }()
+    
+    //###################################### 导航栏 ######################################
+    lazy var layout: UICollectionViewFlowLayout = {
+        let layout = UICollectionViewFlowLayout()
+        layout.scrollDirection = .vertical
+        let w = k_ScreenWidth-32
+        let h = kGetScaleHeight(originalSize: CGSizeMake(343, 230), width: w)
+        layout.itemSize = CGSize(width: w, height: h)
+        layout.minimumInteritemSpacing = 8
+        layout.minimumLineSpacing = 8
+        
+        layout.sectionInset = UIEdgeInsets(top: 10, left: 16, bottom: k_Height_TabBar+20, right: 16)
+        return layout
+    }()
+    lazy var collectionView: UICollectionView = {
+        let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
+        collectionView.delegate = self
+        collectionView.dataSource = self
+        collectionView.showsVerticalScrollIndicator = false
+        collectionView.showsHorizontalScrollIndicator = false
+        collectionView.backgroundColor = .clear
+        collectionView.register(TSAILIstCell.self, forCellWithReuseIdentifier: TSAILIstCell.cellID)
+        if #available(iOS 11.0, *) {
+            collectionView.contentInsetAdjustmentBehavior = .never
+        }
+        return collectionView
+    }()
+
+    lazy var photoPickerManager: TSPhotoPickerManager = {
+        let photoPickerManager = TSPhotoPickerManager(viewController: self)
+        return photoPickerManager
+    }()
+    
+    override func createView() {
+        
+        navBarContentView.addSubview(navBarView)
+        navBarView.snp.makeConstraints { make in
+            make.edges.equalToSuperview()
+        }
+
+        contentView.addSubview(collectionView)
+        collectionView.snp.makeConstraints { make in
+            make.edges.equalToSuperview()
+        }
+    }
+    
+    override func dealThings() {
 //        NotificationCenter.default.addObserver(self, selector: #selector(updateVipView), name: .kPurchaseDidChanged, object: nil)
 //        updateVipView()
-//        
-//        NotificationCenter.default.addObserver(forName: .kOpenMotherDayVC, object: nil, queue: OperationQueue.main) { [weak self] _ in
-//            guard let self = self else { return }
-//            DispatchQueue.main.async {
-//                let baseVc = TSAIUploadPhotoBaseVC(titleString: "Happy Mother's Day".localized,upLoadImage: nil,imageMaxBitSize: kUploadImageMaxBit10Size, generatorStyle: .motherDay)
-//                kPushVC(target: self, modelVC: baseVc)
-//            }
-//        }
-//        
-//        NotificationCenter.default.addObserver(forName: .kOpenCatTohumanVC, object: nil, queue: OperationQueue.main) { [weak self] _ in
-//            guard let self = self else { return }
-//            DispatchQueue.main.async {
-//                let baseVc = TSAIUploadPhotoBaseVC(titleString: "Pet Humanization".localized,upLoadImage: nil,imageMaxBitSize: kUploadImageMaxBit10Size, generatorStyle: .catTohuman)
-//                kPushVC(target: self, modelVC: baseVc)
-//            }
-//        }
-//
-//    }
-//}
-//
-//
-//extension TSAILIstVC {
-//
+    }
+}
+
+
+extension TSAIListVC {
+
 //    @objc func updateVipView() {
 //        kMainAsync {
 //            self.vipBtn.isHidden = PurchaseManager.default.isVip
 //        }
 //    }
-//
-//    func createItemModel(leftImageName: String,
-//                         leftTitle: String,
-//                         leftSubTitle: String,
-//                        rightViewStyle: Int,
-//                        tapBlock: @escaping ((TSBasicItemModel, Int, Any?) -> Void)) -> TSBasicItemModel {
-//        let model = TSBasicItemModel()
-//        model.leftImageName = leftImageName
-//        model.leftTitle = leftTitle
-//        model.leftSubTitle = leftSubTitle
-//        model.rightViewStyle = rightViewStyle
-//        model.tapBlock = tapBlock
-//        return model
-//    }
-//}
-//
-//extension TSAILIstVC: UICollectionViewDataSource ,UICollectionViewDelegate {
-//    
-//    public func numberOfSections(in collectionView: UICollectionView) -> Int {
-//        return dataArray.count
-//    }
-//    
-//    public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
-//        if let sectionModel = dataArray.safeObj(At: section){
-//            return sectionModel.itemsArray.count
-//        }
-//        return 0
-//    }
-//    
-//    public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
-//        
-//        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: TSAILIstCell.cellID, for: indexPath)
-//        if let cell = cell as? TSAILIstCell {
-//            if let sectionModel = dataArray.safeObj(At: indexPath.section),let itemModel = sectionModel.itemsArray.safeObj(At: indexPath.row){
-//                cell.itemModel = itemModel
-//            }
-//        }
-//        
-//        return cell
-//    }
-//
-//    public func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
-//        if let sectionModel = dataArray.safeObj(At: indexPath.section),let itemModel = sectionModel.itemsArray.safeObj(At: indexPath.row){
-//            itemModel.tapBlock?(itemModel,indexPath.row,nil)
-//        }
-//    }
-//}
-//
-//extension TSAILIstVC{
-//    
-//    func enterSelectPhotos(userDefaultsKey:String,maxBitSize:Int,config:TSAIListHintBaseVC.Config,complete: @escaping (UIImage)->Void){
-//        if userDefaultsKey.count == 0 {
-//            self.pickSinglePhoto(maxBitSize:maxBitSize,complete:complete)
-//        }else{
-//            TSAIListHintBaseVC.userDefaultsKey = userDefaultsKey
-//            if TSAIListHintBaseVC.isShowUploadImageHint{
-//                TSAIListHintBaseVC.isShowUploadImageHint = false
-//                self.presentModalHintVC(config:config,complete:complete)
-//            }else {
-//                self.pickSinglePhoto(maxBitSize:maxBitSize,complete:complete)
-//            }
-//        }
-//    }
-//    
-//    
-//    func presentModalHintVC(config:TSAIListHintBaseVC.Config,complete:@escaping (UIImage)->Void){
-//        hintBaseVC = TSAIListHintBaseVC(config: config) { [weak self] image in
-//            guard let self = self else { return }
-//            if let image = image {
-//                complete(image)
-//            }else{
-//                dePrint("图片异常")
-//            }
-//            kDelayMainShort {
-//                self.hintBaseVC.dismissPageVC()
-//            }
-//        }
-//        kPresentModalVC(target: self, modelVC: hintBaseVC,transitionStyle: .crossDissolve)
-//    }
-//    
-//    func pickSinglePhoto(maxBitSize:Int,complete: @escaping (UIImage)->Void)  {
-////        photoPickerManager.pickSinglePhoto(maxBitSize: maxBitSize) { [weak self] image, errorString in
-//        photoPickerManager.pickCustomSinglePhoto() { [weak self] image, errorString in
-//            guard let self = self else { return }
-//            if let errorString = errorString {
-//                TSToastShared.showToast(text: errorString)
-//            }else if let image = image {
-//                complete(image)
-//            }else{
-//                dePrint("图片异常")
-//            }
-//            kDelayMainShort {
-//                self.photoPickerManager.dismissPageVC()
-//            }
-//            
-//        }
-//    }
-//}
-//
-//extension TSAILIstVC{
-//    func openMotherDayVC(titleString:String){
-//        enterSelectPhotos(
-//            userDefaultsKey: "isFirstAIListMotherDayHintVC",
-//            maxBitSize: kUploadImageMaxBit10Size,
-//            config:.defaultConfig
-//        ) { image in
-//            let baseVc = TSAIUploadPhotoBaseVC(titleString: titleString,upLoadImage: image,imageMaxBitSize: kUploadImageMaxBit10Size, generatorStyle: .motherDay)
-//            kPushVC(target: self, modelVC: baseVc)
-//        }
-//    }
-//}
+
+    func createItemModel(leftImageName: String,
+                         leftTitle: String,
+                         leftSubTitle: String,
+                        rightViewStyle: Int,
+                        tapBlock: @escaping ((TSBasicItemModel, Int, Any?) -> Void)) -> TSBasicItemModel {
+        let model = TSBasicItemModel()
+        model.leftImageName = leftImageName
+        model.leftTitle = leftTitle
+        model.leftSubTitle = leftSubTitle
+        model.rightViewStyle = rightViewStyle
+        model.tapBlock = tapBlock
+        return model
+    }
+}
+
+extension TSAIListVC: UICollectionViewDataSource ,UICollectionViewDelegate {
+    
+    public func numberOfSections(in collectionView: UICollectionView) -> Int {
+        return dataArray.count
+    }
+    
+    public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
+        if let sectionModel = dataArray.safeObj(At: section){
+            return sectionModel.itemsArray.count
+        }
+        return 0
+    }
+    
+    public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
+        
+        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: TSAILIstCell.cellID, for: indexPath)
+        if let cell = cell as? TSAILIstCell {
+            if let sectionModel = dataArray.safeObj(At: indexPath.section),let itemModel = sectionModel.itemsArray.safeObj(At: indexPath.row){
+                cell.itemModel = itemModel
+            }
+        }
+        
+        return cell
+    }
+
+    public func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
+        if let sectionModel = dataArray.safeObj(At: indexPath.section),let itemModel = sectionModel.itemsArray.safeObj(At: indexPath.row){
+            itemModel.tapBlock?(itemModel,indexPath.row,nil)
+        }
+    }
+}
+
+extension TSAIListVC{
+    
+    func enterSelectPhotos(userDefaultsKey:String,maxBitSize:Int,config:TSAIListHintBaseVC.Config,complete: @escaping (UIImage)->Void){
+        if userDefaultsKey.count == 0 {
+            self.pickSinglePhoto(maxBitSize:maxBitSize,complete:complete)
+        }else{
+            TSAIListHintBaseVC.userDefaultsKey = userDefaultsKey
+            if TSAIListHintBaseVC.isShowUploadImageHint{
+                TSAIListHintBaseVC.isShowUploadImageHint = false
+                self.presentModalHintVC(config:config,complete:complete)
+            }else {
+                self.pickSinglePhoto(maxBitSize:maxBitSize,complete:complete)
+            }
+        }
+    }
+    
+    
+    func presentModalHintVC(config:TSAIListHintBaseVC.Config,complete:@escaping (UIImage)->Void){
+        hintBaseVC = TSAIListHintBaseVC(config: config) { [weak self] image in
+            guard let self = self else { return }
+            if let image = image {
+                complete(image)
+            }else{
+                dePrint("图片异常")
+            }
+            kDelayMainShort {
+                self.hintBaseVC.dismissPageVC()
+            }
+        }
+        kPresentModalVC(target: self, modelVC: hintBaseVC,transitionStyle: .crossDissolve)
+    }
+    
+    func pickSinglePhoto(maxBitSize:Int,complete: @escaping (UIImage)->Void)  {
+//        photoPickerManager.pickSinglePhoto(maxBitSize: maxBitSize) { [weak self] image, errorString in
+        photoPickerManager.pickCustomSinglePhoto() { [weak self] image, errorString in
+            guard let self = self else { return }
+            if let errorString = errorString {
+                TSToastShared.showToast(text: errorString)
+            }else if let image = image {
+                complete(image)
+            }else{
+                dePrint("图片异常")
+            }
+            kDelayMainShort {
+                self.photoPickerManager.dismissPageVC()
+            }
+            
+        }
+    }
+}
+
+extension TSAIListVC{
+    func openMotherDayVC(titleString:String){
+        enterSelectPhotos(
+            userDefaultsKey: "isFirstAIListMotherDayHintVC",
+            maxBitSize: kUploadImageMaxBit10Size,
+            config:.defaultConfig
+        ) { image in
+            let baseVc = TSAIUploadPhotoVC(titleString: titleString,upLoadImage: image,imageMaxBitSize: kUploadImageMaxBit10Size, generatorStyle: .motherDay)
+            kPushVC(target: self, modelVC: baseVc)
+        }
+    }
+}

+ 391 - 0
TSLiveWallpaper/Business/TSAIListVC/TSAIUploadPhotoVC/TSAIUploadPhotoVC.swift

@@ -0,0 +1,391 @@
+//
+//  TSAIUploadPhotoVC.swift
+//  AIEmoji
+//
+//  Created by 100Years on 2025/4/9.
+//
+
+import PhotosUI
+import BetterSegmentedControl
+
+class TSAIUploadPhotoVC: TSBaseVC {
+    var generatorStyle:TSGeneratorImageStyle
+    var titleString:String
+    var imageMaxBitSize:Int
+    init(titleString:String,upLoadImage:UIImage?,imageMaxBitSize:Int,generatorStyle:TSGeneratorImageStyle) {
+        self.titleString = titleString
+        self.upLoadImage = upLoadImage
+        self.imageMaxBitSize = imageMaxBitSize
+        self.generatorStyle = generatorStyle
+        super.init()
+    }
+    
+    @MainActor required init?(coder: NSCoder) {
+        fatalError("init(coder:) has not been implemented")
+    }
+    
+    //#####################################数据区#####################################
+    let lineSpacing = 6.0
+    lazy var photoPickerManager: TSPhotoPickerManager = {
+        let photoPickerManager = TSPhotoPickerManager(viewController: self)
+        return photoPickerManager
+    }()
+    
+    var hintBaseVC:TSAIListHintBaseVC = TSAIListHintBaseVC(config: .defaultConfig)
+    //#####################################底部基础#####################################
+    lazy var cusStackView: TSCustomStackView = {
+        let cusStackView = TSCustomStackView(axis: .vertical,spacing: 0)
+        return cusStackView
+    }()
+
+    
+    lazy var submitBtn: UIButton = {
+        let submitBtn = kCreateNormalSubmitBtn(title: generatingText) { [weak self]  in
+            guard let self = self else { return }
+            generateImage()
+        }
+        submitBtn.cornerRadius = 24.0
+        return submitBtn
+    }()
+
+    //#####################################上传 view#####################################
+    var upLoadImage:UIImage? = nil {
+        didSet{
+            if let image = upLoadImage {
+                upLoadView.isHidden = true
+                uploadImageView.isHidden = false
+                deleteBtn.isHidden = false
+                uploadImageView.image = image
+                submitBtn.isEnabled = true
+            }else {
+                upLoadView.isHidden = false
+                uploadImageView.isHidden = true
+                deleteBtn.isHidden = true
+                uploadImageView.image = nil
+                submitBtn.isEnabled = false
+            }
+        }
+    }
+    
+    
+    lazy var subInfoLabel: UILabel = {
+        let textLabel = UILabel.createLabel(text: "Select an image with face fully visible".localized,font: .font(size: 12),textColor: UIColor.white.withAlphaComponent(0.6),textAlignment: .center,numberOfLines: 0)
+        return textLabel
+    }()
+    
+    lazy var upLoadView: UIView = {
+        let bgView = UIView()
+        
+        let addImageView = UIImageView.createImageView(imageName: "add")
+        bgView.addSubview(addImageView)
+        addImageView.snp.makeConstraints { make in
+            make.top.equalTo(0)
+            make.centerX.equalToSuperview()
+            make.width.height.equalTo(24)
+        }
+        
+        let textLabel = UILabel.createLabel(text: "Upload Photo".localized,font: .font(size: 16),textColor: .white,textAlignment: .center,numberOfLines: 0)
+        bgView.addSubview(textLabel)
+        textLabel.snp.makeConstraints { make in
+            make.top.equalTo(addImageView.snp.bottom).offset(16)
+            make.leading.equalTo(18)
+            make.trailing.equalTo(-18)
+        }
+        
+        bgView.addSubview(subInfoLabel)
+        subInfoLabel.snp.makeConstraints { make in
+            make.top.equalTo(textLabel.snp.bottom).offset(8)
+            make.leading.equalTo(18)
+            make.trailing.equalTo(-18)
+            make.bottom.equalToSuperview()
+        }
+        
+        return bgView
+    }()
+
+    lazy var uploadImageView: UIImageView = {
+        let uploadImageView = UIImageView()
+        uploadImageView.contentMode = .scaleAspectFit
+        uploadImageView.cornerRadius = 12
+        return uploadImageView
+    }()
+    
+    
+    lazy var uploadImageBgView: UIView = {
+        
+        let bgView = UIView()
+        bgView.addGestureRecognizer(UITapGestureRecognizer(target: self, action:#selector(clickBgView)))
+        let bgImageView = UIImageView.createImageView(imageName: "ailist_upload_big_bg")
+        bgImageView.contentMode = .scaleToFill
+        bgView.addSubview(bgImageView)
+        bgImageView.snp.makeConstraints { make in
+            make.leading.bottom.trailing.top.equalTo(0)
+        }
+
+        bgView.addSubview(upLoadView)
+        upLoadView.snp.makeConstraints { make in
+            make.top.equalTo(244*kDesignScale)
+            make.centerX.equalToSuperview()
+            make.width.lessThanOrEqualTo(k_ScreenWidth - 80)
+        }
+
+        bgView.addSubview(uploadImageView)
+        uploadImageView.snp.makeConstraints { make in
+            make.top.leading.equalTo(8)
+            make.bottom.trailing.equalTo(-8)
+        }
+        
+        return bgView
+    }()
+    
+    
+    lazy var deleteBtn: UIButton = {
+        let deleteBtn = UIButton.createButton(backgroundImage: UIImage(named: "delete_redRound")) { [weak self]  in
+            guard let self = self else { return }
+            upLoadImage = nil
+        }
+        deleteBtn.isHidden = true
+        return deleteBtn
+    }()
+
+    lazy var segmentedView: BetterSegmentedControl = {
+        let segmentedView = BetterSegmentedControl(
+            frame: .zero,
+            segments:
+                LabelSegment.segments(
+                    withTitles: ["Female".localized,"Male".localized,"Random".localized],
+                    normalFont: .font(size: 12.0),
+                    normalTextColor: .white.withAlphaComponent(0.4),
+                    selectedFont: .font(size: 12.0),
+                    selectedTextColor: "#111111".uiColor),
+            options:[.backgroundColor(.white.withAlphaComponent(0.1)),
+                     .indicatorViewBackgroundColor(.white),
+                     .indicatorViewInset(2),
+                     .cornerRadius(20.0),
+                     .animationSpringDamping(1.0)]
+        )
+        segmentedView.addTarget(self,action: #selector(segmentedControlValueChanged(_:)),for: .valueChanged)
+        return segmentedView
+    }()
+    var additionalPrompt = ",female"
+    @objc func segmentedControlValueChanged(_ sender: BetterSegmentedControl) {
+        switch sender.index {
+        case 0:
+            additionalPrompt = ",female"//女
+        case 1:
+            additionalPrompt = ",male"//男
+        default:
+            additionalPrompt = ""
+        }
+    }
+    
+    override func createView() {
+        
+        addNormalNavBarView()
+        setPageTitle(titleString)
+        _ = setNavigationItem("", imageName: "aichat_history", direction: .right, action: #selector(clickNavRight))
+        
+        contentView.addSubview(submitBtn)
+        submitBtn.snp.makeConstraints { make in
+            make.centerX.equalToSuperview()
+            make.width.equalTo(250*kDesignScale)
+            make.height.equalTo(48)
+            make.bottom.equalTo(-10-k_Height_safeAreaInsetsBottom())
+        }
+        
+        contentView.addSubview(cusStackView)
+        cusStackView.snp.makeConstraints { make in
+            make.top.equalTo(0)
+            make.leading.trailing.equalToSuperview()
+            make.bottom.equalTo(submitBtn.snp.top).offset(-10)
+        }
+        
+        setUpStackView()
+        
+        let image = upLoadImage
+        upLoadImage = image
+        
+        subInfoLabel.isHidden = generatorStyle == .catTohuman ? false : true
+    }
+
+    
+    override func dealThings() {
+        kSetBtnVipIcon(btn: self.submitBtn, show: true)
+    }
+    
+}
+
+extension TSAIUploadPhotoVC {
+    
+    func setUpStackView(){
+        //添加上传一大块
+        let bgView = UIView()
+        bgView.addSubview(uploadImageBgView)
+        cusStackView.addSubviewToStack(bgView)
+    
+        uploadImageBgView.snp.makeConstraints { make in
+            make.width.equalTo(296*kDesignScale)
+            make.height.equalTo(528*kDesignScale)
+            make.centerX.equalToSuperview()
+            make.top.equalTo(8)
+            make.bottom.equalTo(-16)
+        }
+
+        bgView.addSubview(deleteBtn)
+        deleteBtn.snp.makeConstraints { make in
+            make.top.equalTo(0)
+            make.trailing.equalTo(-32*kDesignScale)
+            make.width.height.equalTo(32)
+        }
+        
+        if generatorStyle == .catTohuman {
+            cusStackView.addSpacing(length: 9)
+            cusStackView.addSubviewToStackWhiteBoard(segmentedView, length: 46)
+            segmentedView.snp.makeConstraints { make in
+                make.width.equalTo(k_ScreenWidth-70)
+                make.height.equalTo(40)
+                make.center.equalToSuperview()
+            }
+        }else{
+            //文字信息区域
+            cusStackView.addSubviewToStack(getTextInfoCell(text: "Single photo with face fully visible".localized))
+            cusStackView.addSpacing(length: lineSpacing)
+            cusStackView.addSubviewToStack(getTextInfoCell(text: "No group photos, covered faces, nudes".localized))
+        }
+
+    }
+    
+    func getTextInfoCell(text:String) -> UIView {
+        
+        let bgView = UIView()
+        let pointView = UIView()
+        pointView.backgroundColor = .white.withAlphaComponent(0.7)
+        pointView.cornerRadius = 1
+        bgView.addSubview(pointView)
+        pointView.snp.makeConstraints { make in
+            make.top.equalTo(7)
+            make.leading.equalTo(22)
+            make.width.height.equalTo(2)
+        }
+        let textLabel1 = UILabel.createLabel(text: text,font: .font(size: 12),textColor: .white.withAlphaComponent(0.6),numberOfLines: 0)
+        textLabel1.setLineSpacing(lineSpacing)
+        bgView.addSubview(textLabel1)
+        textLabel1.snp.makeConstraints { make in
+            make.top.bottom.equalToSuperview()
+            make.leading.equalTo(16+16)
+            make.trailing.equalTo(-16)
+        }
+        return bgView
+    }
+    
+    var generatingText:String{
+        if generatorStyle == .oldPhoto {
+            return "Restore".localized
+        }else
+        if generatorStyle == .pretty {
+            return "Change".localized
+        }
+        return "Generate".localized
+    }
+}
+
+extension TSAIUploadPhotoVC {
+
+    @objc func clickNavRight() {
+        kPushVC(target: self, modelVC: TSAIListHistoryVC())
+    }
+    
+    @objc func clickBgView() {
+        pickSinglePhoto()
+    }
+    
+    func pickSinglePhoto()  {
+//        photoPickerManager.pickCustomSinglePhoto() { [weak self] image, errorString in
+//            guard let self = self else { return }
+//            if let errorString = errorString {
+//                TSToastShared.showToast(text: errorString)
+//            }else{
+//                upLoadImage = image
+//            }
+//        }
+        enterSelectPhotos(userDefaultsKey: generatorStyle.userDefaultsKey, maxBitSize: generatorStyle.imageMaxBitSize, config: generatorStyle.config) { [weak self] image in
+                guard let self = self else { return }
+            upLoadImage = image
+        }
+    }
+}
+
+
+extension TSAIUploadPhotoVC {
+    
+    func generateImage() {
+        if kJudgeVip(externalBool: true, vc: self){ return } //判断 vip
+        guard let upLoadImage = upLoadImage else { return }
+        if generatorStyle != .catTohuman {
+            additionalPrompt = ""
+        }
+//        let gennerateVC = TSAIListPhotoGeneratorBaseVC(generatorModel: TSAIListPhotoGeneratorModel(upLoadImage: upLoadImage, generatorStyle: generatorStyle,additionalPrompt: additionalPrompt)){ [weak self] model in
+//            guard let self = self else { return }
+//            saveModel(model: model)
+//        }
+        
+//        kPresentModalVC(target: self, modelVC: gennerateVC,transitionStyle: .crossDissolve)
+    }
+    
+    func saveModel(model:TSActionInfoModel){
+        TSRMShared.aiListDB.updateData(model)
+    }
+
+}
+
+
+extension TSAIUploadPhotoVC{
+    
+    func enterSelectPhotos(userDefaultsKey:String,maxBitSize:Int,config:TSAIListHintBaseVC.Config,complete: @escaping (UIImage)->Void){
+        if userDefaultsKey.count == 0 {
+            self.pickSinglePhoto(maxBitSize:maxBitSize,complete:complete)
+        }else{
+            TSAIListHintBaseVC.userDefaultsKey = userDefaultsKey
+            if TSAIListHintBaseVC.isShowUploadImageHint{
+                TSAIListHintBaseVC.isShowUploadImageHint = false
+                self.presentModalHintVC(config:config,complete:complete)
+            }else {
+                self.pickSinglePhoto(maxBitSize:maxBitSize,complete:complete)
+            }
+        }
+    }
+    
+    
+    func presentModalHintVC(config:TSAIListHintBaseVC.Config,complete:@escaping (UIImage)->Void){
+        hintBaseVC = TSAIListHintBaseVC(config: config) { [weak self] image in
+            guard let self = self else { return }
+            if let image = image {
+                complete(image)
+            }else{
+                dePrint("图片异常")
+            }
+            kDelayMainShort {
+                self.hintBaseVC.dismissPageVC()
+            }
+        }
+        kPresentModalVC(target: self, modelVC: hintBaseVC,transitionStyle: .crossDissolve)
+    }
+    
+    func pickSinglePhoto(maxBitSize:Int,complete: @escaping (UIImage)->Void)  {
+//        photoPickerManager.pickSinglePhoto(maxBitSize: maxBitSize) { [weak self] image, errorString in
+        photoPickerManager.pickCustomSinglePhoto() { [weak self] image, errorString in
+            guard let self = self else { return }
+            if let errorString = errorString {
+                TSToastShared.showToast(text: errorString)
+            }else if let image = image {
+                complete(image)
+            }else{
+                dePrint("图片异常")
+            }
+            kDelayMainShort {
+                self.photoPickerManager.dismissPageVC()
+            }
+            
+        }
+    }
+}

+ 20 - 3
TSLiveWallpaper/Business/TSTabBarController/TSTabBarController.swift

@@ -45,15 +45,32 @@ class TSTabBarController: UITabBarController {
     }
 
     @objc private func setUpData() {
+//        viewControllerArray = ["MusicHomeContainerViewController",
+//                               "MusicPlaylistContainerViewController",
+//                               "TSHomeVC",
+//                              "TSMineVC"]
+//        selectedImageArray = [
+//            "tabbar_select_music",
+//            "tabbar_select_playlist",
+//            "tabbar_select_random",
+//            "tabbar_select_mine",
+//        ]
+//        unselectedImageArray = [
+//            "tabbar_unSelect_music",
+//            "tabbar_unSelect_playlist",
+//            "tabbar_unSelect_random",
+//            "tabbar_unSelect_mine",
+//        ]
+//
         viewControllerArray = ["MusicHomeContainerViewController",
                                "MusicPlaylistContainerViewController",
-                               "TSHomeVC",
+                               "TSAIListVC",
                                "TSMineVC"]
-
+        
         selectedImageArray = [
             "tabbar_select_music",
             "tabbar_select_playlist",
-            "tabbar_select_random",
+            "tabbar_select_ailist",
             "tabbar_select_mine",
         ]
         unselectedImageArray = [

+ 10 - 0
TSLiveWallpaper/Common/Ex/UIFont+Ex.swift

@@ -0,0 +1,10 @@
+//
+//  UIFont+Ex.swift
+//  TSLiveWallpaper
+//
+//  Created by 100Years on 2025/6/10.
+//
+
+public extension FontName {
+    static let ZillaSlabBold   = "Zilla Slab"
+}

+ 31 - 0
TSLiveWallpaper/Common/TSPhotoSizeHelper.swift

@@ -0,0 +1,31 @@
+//
+//  TSPhotoSizeHelper.swift
+//  TSLiveWallpaper
+//
+//  Created by 100Years on 2025/6/10.
+//
+
+import Photos
+
+// MARK: - 精准获取图片大小(单位:字节)
+struct TSPhotoSizeHelper {
+    /// 同步获取(适合快速判断)
+    static func getImageFileSizeSync(asset: PHAsset) -> Int {
+        let resources = PHAssetResource.assetResources(for: asset)
+        guard let resource = resources.first else { return 0 }
+        return Int(resource.value(forKey: "fileSize") as? Int64 ?? 0)
+    }
+    
+    /// 异步获取(推荐主线程使用)
+    static func getImageFileSizeAsync(asset: PHAsset, completion: @escaping (Int) -> Void) {
+        DispatchQueue.global(qos: .userInitiated).async {
+            let size = getImageFileSizeSync(asset: asset)
+            DispatchQueue.main.async { completion(size) }
+        }
+    }
+    
+    /// 快速判断是否超过10MB
+    static func isLargerThan10MB(asset: PHAsset) -> Bool {
+        return getImageFileSizeSync(asset: asset) > 10 * 1024 * 1024
+    }
+}

+ 160 - 160
TSLiveWallpaper/Common/ViewTool/TSPhotoPickerManager/TSPhotoPickerManager.swift

@@ -8,166 +8,166 @@
 import UIKit
 import PhotosUI
 
-//class TSPhotoPickerManager: NSObject {
-//    
-//    // MARK: - Properties
-//    private weak var viewController: UIViewController?
-//    private var completionHandler: ((UIImage?,PHAsset?) -> Void)?
-//    private var completionSizeHandler: ((UIImage?,String?) -> Void)?
-//    private var imagePicker = UIImagePickerController()
-//    // MARK: - Initializers
-//    init(viewController: UIViewController) {
-//        self.viewController = viewController
-//    }
-//    
-//    // MARK: - Public Methods
-//    /// 打开照片选择器,单选一张照片
-//    func pickSinglePhoto(completion: @escaping (UIImage?,PHAsset?) -> Void) {
-//        self.completionHandler = completion
-//        // 检查相册权限
-//        checkPhotoLibraryPermission { [weak self] authorized in
-//            guard let self = self else { return }
-//            if authorized {
-//                self.openPhotoPicker()
-//            } else {
-//                self.showPermissionAlert()
-//            }
-//        }
-//    }
-//    
-//    // MARK: - Private Methods
-//    /// 检查相册权限
-//    private func checkPhotoLibraryPermission(completion: @escaping (Bool) -> Void) {
-//        let status = PHPhotoLibrary.authorizationStatus()
-//        switch status {
-//        case .authorized:
-//            completion(true)
-//        case .notDetermined:
-//            PHPhotoLibrary.requestAuthorization { newStatus in
-//                DispatchQueue.main.async {
-//                    completion(newStatus == .authorized)
-//                }
-//            }
-//        default:
-//            completion(false)
-//        }
-//    }
-//    
-//    /// 打开照片选择器
-//    private func openPhotoPicker() {
-//        imagePicker = UIImagePickerController()
-//        imagePicker.sourceType = .photoLibrary
-//        imagePicker.delegate = self
-//        imagePicker.mediaTypes = ["public.image"] // 只选择照片
-////        imagePicker.modalPresentationStyle = .custom
-////        imagePicker.modalTransitionStyle = .crossDissolve
-//        if #available(iOS 13.0, *) {
-//            imagePicker.overrideUserInterfaceStyle = .dark
+class TSPhotoPickerManager: NSObject {
+    
+    // MARK: - Properties
+    private weak var viewController: UIViewController?
+    private var completionHandler: ((UIImage?,PHAsset?) -> Void)?
+    private var completionSizeHandler: ((UIImage?,String?) -> Void)?
+    private var imagePicker = UIImagePickerController()
+    // MARK: - Initializers
+    init(viewController: UIViewController) {
+        self.viewController = viewController
+    }
+    
+    // MARK: - Public Methods
+    /// 打开照片选择器,单选一张照片
+    func pickSinglePhoto(completion: @escaping (UIImage?,PHAsset?) -> Void) {
+        self.completionHandler = completion
+        // 检查相册权限
+        checkPhotoLibraryPermission { [weak self] authorized in
+            guard let self = self else { return }
+            if authorized {
+                self.openPhotoPicker()
+            } else {
+                self.showPermissionAlert()
+            }
+        }
+    }
+    
+    // MARK: - Private Methods
+    /// 检查相册权限
+    private func checkPhotoLibraryPermission(completion: @escaping (Bool) -> Void) {
+        let status = PHPhotoLibrary.authorizationStatus()
+        switch status {
+        case .authorized:
+            completion(true)
+        case .notDetermined:
+            PHPhotoLibrary.requestAuthorization { newStatus in
+                DispatchQueue.main.async {
+                    completion(newStatus == .authorized)
+                }
+            }
+        default:
+            completion(false)
+        }
+    }
+    
+    /// 打开照片选择器
+    private func openPhotoPicker() {
+        imagePicker = UIImagePickerController()
+        imagePicker.sourceType = .photoLibrary
+        imagePicker.delegate = self
+        imagePicker.mediaTypes = ["public.image"] // 只选择照片
+//        imagePicker.modalPresentationStyle = .custom
+//        imagePicker.modalTransitionStyle = .crossDissolve
+        if #available(iOS 13.0, *) {
+            imagePicker.overrideUserInterfaceStyle = .dark
+        }
+        viewController?.present(imagePicker, animated: true, completion: nil)
+    }
+    
+    /// 显示权限提示
+    private func showPermissionAlert() {
+        let alert = UIAlertController(
+            title: "No photos permission".localized,
+            message: "Please enable photo permission in settings to select photos".localized,
+            preferredStyle: .alert
+        )
+        alert.addAction(UIAlertAction(title: "Cancel".localized, style: .cancel, handler: nil))
+        alert.addAction(UIAlertAction(title: "Go to Settings".localized, style: .default) { _ in
+            if let url = URL(string: UIApplication.openSettingsURLString) {
+                UIApplication.shared.open(url, options: [:], completionHandler: nil)
+            }
+        })
+        viewController?.present(alert, animated: true, completion: nil)
+    }
+    
+    deinit {
+        debugPrint("♻️♻️♻️ TSPhotoPickerManager -> TSPhotoPickerManager deinit ♻️♻️♻️")
+    }
+}
+
+// MARK: - UIImagePickerControllerDelegate & UINavigationControllerDelegate (iOS 14 以下)
+extension TSPhotoPickerManager: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
+    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
+//        picker.dismiss(animated: true) {
+            if let image = info[.originalImage] as? UIImage {
+                self.completionHandler?(image,info[.phAsset] as? PHAsset )
+            } else {
+                self.completionHandler?(nil,nil)
+            }
 //        }
-//        viewController?.present(imagePicker, animated: true, completion: nil)
-//    }
-//    
-//    /// 显示权限提示
-//    private func showPermissionAlert() {
-//        let alert = UIAlertController(
-//            title: "No photos permission".localized,
-//            message: "Please enable photo permission in settings to select photos".localized,
-//            preferredStyle: .alert
-//        )
-//        alert.addAction(UIAlertAction(title: "Cancel".localized, style: .cancel, handler: nil))
-//        alert.addAction(UIAlertAction(title: "Go to Settings".localized, style: .default) { _ in
-//            if let url = URL(string: UIApplication.openSettingsURLString) {
-//                UIApplication.shared.open(url, options: [:], completionHandler: nil)
-//            }
-//        })
-//        viewController?.present(alert, animated: true, completion: nil)
-//    }
-//    
-//    deinit {
-//        debugPrint("♻️♻️♻️ TSPhotoPickerManager -> TSPhotoPickerManager deinit ♻️♻️♻️")
-//    }
-//}
-//
-//// MARK: - UIImagePickerControllerDelegate & UINavigationControllerDelegate (iOS 14 以下)
-//extension TSPhotoPickerManager: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
-//    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
-////        picker.dismiss(animated: true) {
-//            if let image = info[.originalImage] as? UIImage {
-//                self.completionHandler?(image,info[.phAsset] as? PHAsset )
-//            } else {
-//                self.completionHandler?(nil,nil)
-//            }
-////        }
-//        
+        
+        if completionSizeHandler == nil {
+            picker.dismiss(animated: true, completion: nil)
+        }
+
+    }
+    
+    func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
+//        self.completionHandler?(nil,nil)
 //        if completionSizeHandler == nil {
-//            picker.dismiss(animated: true, completion: nil)
-//        }
-//
-//    }
-//    
-//    func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
-////        self.completionHandler?(nil,nil)
-////        if completionSizeHandler == nil {
-//            picker.dismiss(animated: true, completion: nil)
-////        }
-//    }
-//}
-//
-//
-//
-//extension TSPhotoPickerManager{
-//    
-//    func pickCustomSinglePhoto(completion: @escaping (UIImage?,String?) -> Void) {
-//        self.completionSizeHandler = completion
-//        pickSinglePhoto { [weak self] image,phAsset in
-//            guard let self = self else { return }
-//            self.completionSizeHandler?(image,nil)
-//            self.completionSizeHandler = nil
-//        }
-//    }
-//    
-//    // MARK: - Public Methods
-//    /// 打开照片选择器,单选一张照片
-//    func pickSinglePhoto(maxBitSize:Int, completion: @escaping (UIImage?,String?) -> Void) {
-//        self.completionSizeHandler = completion
-//
-//        let maxmbSize = Int(Double(maxBitSize) / (1024 * 1024))
-//        pickSinglePhoto { [weak self] image,phAsset in
-//            guard let self = self else { return }
-//            if let image = image,let phAsset = phAsset {
-//                // 方法2:异步获取详细大小(不阻塞主线程)
-//                TSPhotoSizeHelper.getImageFileSizeAsync(asset: phAsset) {[weak self] size in
-//                    guard let self = self else { return }
-//                    
-//                    let mbSize = Double(size) / (1024 * 1024)
-//                    print("精确大小: \(mbSize) MB,size = \(size)")
-//                    if size > maxBitSize {
-//                        self.completionSizeHandler?(nil,String(format: "Photo must be smaller than %dMB.".localized, maxmbSize))
-//                    }else{
-//                        self.completionSizeHandler?(image,nil)
-//                        self.completionSizeHandler = nil
-////                        imagePicker.dismiss(animated: true)
-//                    }
-//                }
-//            }else{
-//                if let image = image {
-//                    if image.isLargerThan(byteSize: maxBitSize) {
-//                        self.completionSizeHandler?(nil,String(format: "Photo must be smaller than %dMB.".localized, maxmbSize))
-//                    }else{
-//                        self.completionSizeHandler?(image,nil)
-//                        self.completionSizeHandler = nil
-////                        imagePicker.dismiss(animated: true)
-//                    }
-//                }else{
-//                    self.completionSizeHandler?(nil,nil)
-////                    imagePicker.dismiss(animated: true)
-//                }
-//            }
+            picker.dismiss(animated: true, completion: nil)
 //        }
-//    }
-//    
-//    func dismissPageVC(){
-//        self.imagePicker.view.isHidden = true
-//        self.imagePicker.dismiss(animated: true)
-//    }
-//}
+    }
+}
+
+
+
+extension TSPhotoPickerManager{
+    
+    func pickCustomSinglePhoto(completion: @escaping (UIImage?,String?) -> Void) {
+        self.completionSizeHandler = completion
+        pickSinglePhoto { [weak self] image,phAsset in
+            guard let self = self else { return }
+            self.completionSizeHandler?(image,nil)
+            self.completionSizeHandler = nil
+        }
+    }
+    
+    // MARK: - Public Methods
+    /// 打开照片选择器,单选一张照片
+    func pickSinglePhoto(maxBitSize:Int, completion: @escaping (UIImage?,String?) -> Void) {
+        self.completionSizeHandler = completion
+
+        let maxmbSize = Int(Double(maxBitSize) / (1024 * 1024))
+        pickSinglePhoto { [weak self] image,phAsset in
+            guard let self = self else { return }
+            if let image = image,let phAsset = phAsset {
+                // 方法2:异步获取详细大小(不阻塞主线程)
+                TSPhotoSizeHelper.getImageFileSizeAsync(asset: phAsset) {[weak self] size in
+                    guard let self = self else { return }
+                    
+                    let mbSize = Double(size) / (1024 * 1024)
+                    print("精确大小: \(mbSize) MB,size = \(size)")
+                    if size > maxBitSize {
+                        self.completionSizeHandler?(nil,String(format: "Photo must be smaller than %dMB.".localized, maxmbSize))
+                    }else{
+                        self.completionSizeHandler?(image,nil)
+                        self.completionSizeHandler = nil
+//                        imagePicker.dismiss(animated: true)
+                    }
+                }
+            }else{
+                if let image = image {
+                    if image.isLargerThan(byteSize: maxBitSize) {
+                        self.completionSizeHandler?(nil,String(format: "Photo must be smaller than %dMB.".localized, maxmbSize))
+                    }else{
+                        self.completionSizeHandler?(image,nil)
+                        self.completionSizeHandler = nil
+//                        imagePicker.dismiss(animated: true)
+                    }
+                }else{
+                    self.completionSizeHandler?(nil,nil)
+//                    imagePicker.dismiss(animated: true)
+                }
+            }
+        }
+    }
+    
+    func dismissPageVC(){
+        self.imagePicker.view.isHidden = true
+        self.imagePicker.dismiss(animated: true)
+    }
+}

+ 4 - 0
TSLiveWallpaper/Info.plist

@@ -9,6 +9,10 @@
 		<key>NSAllowsArbitraryLoads</key>
 		<true/>
 	</dict>
+	<key>UIAppFonts</key>
+	<array>
+		<string>ZillaSlab-Bold.ttf</string>
+	</array>
 	<key>UIBackgroundModes</key>
 	<array>
 		<string>audio</string>

BIN
TSLiveWallpaper/Resource/Font/ZillaSlab-Bold.ttf