Przeglądaj źródła

图片扩展开发完毕

100Years 1 tydzień temu
rodzic
commit
d0f492fd74
98 zmienionych plików z 2696 dodań i 524 usunięć
  1. 3 9
      Podfile
  2. 62 1
      Podfile.lock
  3. 94 14
      TSLiveWallpaper.xcodeproj/project.pbxproj
  4. 2 1
      TSLiveWallpaper/AppDelegate.swift
  5. 6 0
      TSLiveWallpaper/Assets.xcassets/AIList/ai_expand/Contents.json
  6. 21 0
      TSLiveWallpaper/Assets.xcassets/AIList/ai_expand/ai_expand_16_9.imageset/Contents.json
  7. BIN
      TSLiveWallpaper/Assets.xcassets/AIList/ai_expand/ai_expand_16_9.imageset/ai_expand_16_9@2x.png
  8. 21 0
      TSLiveWallpaper/Assets.xcassets/AIList/ai_expand/ai_expand_1_1.imageset/Contents.json
  9. BIN
      TSLiveWallpaper/Assets.xcassets/AIList/ai_expand/ai_expand_1_1.imageset/ai_expand_1_1@2x.png
  10. 21 0
      TSLiveWallpaper/Assets.xcassets/AIList/ai_expand/ai_expand_2_3.imageset/Contents.json
  11. BIN
      TSLiveWallpaper/Assets.xcassets/AIList/ai_expand/ai_expand_2_3.imageset/ai_expand_2_3@2x.png
  12. 21 0
      TSLiveWallpaper/Assets.xcassets/AIList/ai_expand/ai_expand_3_2.imageset/Contents.json
  13. BIN
      TSLiveWallpaper/Assets.xcassets/AIList/ai_expand/ai_expand_3_2.imageset/ai_expand_3_2@2x.png
  14. 21 0
      TSLiveWallpaper/Assets.xcassets/AIList/ai_expand/ai_expand_3_4.imageset/Contents.json
  15. BIN
      TSLiveWallpaper/Assets.xcassets/AIList/ai_expand/ai_expand_3_4.imageset/ai_expand_3_4@2x.png
  16. 21 0
      TSLiveWallpaper/Assets.xcassets/AIList/ai_expand/ai_expand_4_3.imageset/Contents.json
  17. BIN
      TSLiveWallpaper/Assets.xcassets/AIList/ai_expand/ai_expand_4_3.imageset/ai_expand_4_3@2x.png
  18. 21 0
      TSLiveWallpaper/Assets.xcassets/AIList/ai_expand/ai_expand_9_16.imageset/Contents.json
  19. BIN
      TSLiveWallpaper/Assets.xcassets/AIList/ai_expand/ai_expand_9_16.imageset/ai_expand_9_16@2x 2.png
  20. 22 0
      TSLiveWallpaper/Assets.xcassets/AIList/clear_Bg.imageset/Contents.json
  21. BIN
      TSLiveWallpaper/Assets.xcassets/AIList/clear_Bg.imageset/clear_Bg@2x.png
  22. BIN
      TSLiveWallpaper/Assets.xcassets/AIList/clear_Bg.imageset/clear_Bg@3x.png
  23. 22 0
      TSLiveWallpaper/Assets.xcassets/AIList/home/alistHome_0_ExpandPhoto.imageset/Contents.json
  24. BIN
      TSLiveWallpaper/Assets.xcassets/AIList/home/alistHome_0_ExpandPhoto.imageset/alistHome_0_ExpandPhoto@2x.png
  25. BIN
      TSLiveWallpaper/Assets.xcassets/AIList/home/alistHome_0_ExpandPhoto.imageset/alistHome_0_ExpandPhoto@3x.png
  26. 6 0
      TSLiveWallpaper/Assets.xcassets/AIList/ptp_style/Contents.json
  27. 21 0
      TSLiveWallpaper/Assets.xcassets/AIList/ptp_style/ptp_style_AdjustLight.imageset/Contents.json
  28. BIN
      TSLiveWallpaper/Assets.xcassets/AIList/ptp_style/ptp_style_AdjustLight.imageset/ptp_style_AdjustLight@3x.png
  29. 21 0
      TSLiveWallpaper/Assets.xcassets/AIList/ptp_style/ptp_style_Colorize.imageset/Contents.json
  30. BIN
      TSLiveWallpaper/Assets.xcassets/AIList/ptp_style/ptp_style_Colorize.imageset/ptp_style_Colorize@3x.png
  31. 21 0
      TSLiveWallpaper/Assets.xcassets/AIList/ptp_style/ptp_style_Descratch.imageset/Contents.json
  32. BIN
      TSLiveWallpaper/Assets.xcassets/AIList/ptp_style/ptp_style_Descratch.imageset/ptp_style_Descratch@3x.png
  33. 21 0
      TSLiveWallpaper/Assets.xcassets/AIList/ptp_style/ptp_style_Enhance.imageset/Contents.json
  34. BIN
      TSLiveWallpaper/Assets.xcassets/AIList/ptp_style/ptp_style_Enhance.imageset/ptp_style_Enhance@3x.png
  35. 21 0
      TSLiveWallpaper/Assets.xcassets/AIList/ptp_style/ptp_style_Recreate.imageset/Contents.json
  36. BIN
      TSLiveWallpaper/Assets.xcassets/AIList/ptp_style/ptp_style_Recreate.imageset/ptp_style_Recreate@3x.png
  37. 6 0
      TSLiveWallpaper/Assets.xcassets/AIList/selectedPhotoStyleCamera/Contents.json
  38. 21 0
      TSLiveWallpaper/Assets.xcassets/AIList/selectedPhotoStyleCamera/selectedPhotoStyleCamera.imageset/Contents.json
  39. BIN
      TSLiveWallpaper/Assets.xcassets/AIList/selectedPhotoStyleCamera/selectedPhotoStyleCamera.imageset/selectedPhotoStyleCamera@2x.png
  40. 21 0
      TSLiveWallpaper/Assets.xcassets/AIList/selectedPhotoStyleCamera/selectedPhotoStyleOldPhoto.imageset/Contents.json
  41. BIN
      TSLiveWallpaper/Assets.xcassets/AIList/selectedPhotoStyleCamera/selectedPhotoStyleOldPhoto.imageset/selectedPhotoStyleOldPhoto@2x.png
  42. 21 0
      TSLiveWallpaper/Assets.xcassets/AIList/selectedPhotoStyleCamera/selectedPhotoStylePhoto.imageset/Contents.json
  43. BIN
      TSLiveWallpaper/Assets.xcassets/AIList/selectedPhotoStyleCamera/selectedPhotoStylePhoto.imageset/selectedPhotoStylePhoto@2x.png
  44. 22 0
      TSLiveWallpaper/Assets.xcassets/AIList/switch_original_picture.imageset/Contents.json
  45. BIN
      TSLiveWallpaper/Assets.xcassets/AIList/switch_original_picture.imageset/switch_original_picture@2x.png
  46. BIN
      TSLiveWallpaper/Assets.xcassets/AIList/switch_original_picture.imageset/switch_original_picture@3x.png
  47. 1 1
      TSLiveWallpaper/Business/TSAIListVC/TSAIAgeImageHintVC/TSAIListHintBaseVC.swift
  48. 262 0
      TSLiveWallpaper/Business/TSAIListVC/TSAIExpandImageVC/TSAIExpandImageVC.swift
  49. 103 0
      TSLiveWallpaper/Business/TSAIListVC/TSAIExpandImageVC/TSAIExpandImageVM.swift
  50. 0 0
      TSLiveWallpaper/Business/TSAIListVC/TSAIExpandImageVC/View/TSAIExpandChangeView.swift
  51. 165 0
      TSLiveWallpaper/Business/TSAIListVC/TSAIExpandImageVC/View/TSAIExpandStyleView.swift
  52. 5 3
      TSLiveWallpaper/Business/TSAIListVC/TSAIList+Enmu.swift
  53. 46 47
      TSLiveWallpaper/Business/TSAIListVC/TSAIListHistoryVC/TSAIListHistoryVC.swift
  54. 1 0
      TSLiveWallpaper/Business/TSAIListVC/TSAIListVC/TSAIListStyleMoreVC/TSAIListStyleMoreVC.swift
  55. 51 13
      TSLiveWallpaper/Business/TSAIListVC/TSAIListVC/TSAIListVC.swift
  56. 0 193
      TSLiveWallpaper/Business/TSAIListVC/TSAIListVC/TSAIListVM.swift
  57. 45 28
      TSLiveWallpaper/Business/TSAIListVC/TSAIListVC/VM/TSAIListDataVM+Dic.swift
  58. 8 8
      TSLiveWallpaper/Business/TSAIListVC/TSAIListVC/VM/TSAIListDataVM.swift
  59. 1 0
      TSLiveWallpaper/Business/TSAIListVC/TSAIListVC/View/TSAILIstBannerCell.swift
  60. 4 0
      TSLiveWallpaper/Business/TSAIListVC/TSAIListVC/View/TSAILIstCell.swift
  61. 4 1
      TSLiveWallpaper/Business/TSAIListVC/TSAIListVC/View/TSAILIstStyleMoreCell.swift
  62. 10 0
      TSLiveWallpaper/Business/TSAIListVC/TSAIPhotoGeneratorVC/Model/TSAIListPhotoGeneratorModel.swift
  63. 2 2
      TSLiveWallpaper/Business/TSAIListVC/TSAIPhotoGeneratorVC/TSAIListPhotoGeneratorVC.swift
  64. 0 0
      TSLiveWallpaper/Business/TSAIListVC/TSAIPhotoGeneratorVC/TSAIPhotoDetailsVC/TSAIPhotoDetailsVC+Comparison.swift
  65. 67 0
      TSLiveWallpaper/Business/TSAIListVC/TSAIPhotoGeneratorVC/TSAIPhotoDetailsVC/TSAIPhotoDetailsVC+Expand.swift
  66. 1 1
      TSLiveWallpaper/Business/TSAIListVC/TSAIPhotoGeneratorVC/TSAIPhotoDetailsVC/TSAIPhotoDetailsVC+Image.swift
  67. 0 0
      TSLiveWallpaper/Business/TSAIListVC/TSAIPhotoGeneratorVC/TSAIPhotoDetailsVC/TSAIPhotoDetailsVC+Video.swift
  68. 0 0
      TSLiveWallpaper/Business/TSAIListVC/TSAIPhotoGeneratorVC/TSAIPhotoDetailsVC/TSAIPhotoDetailsVC+View.swift
  69. 22 15
      TSLiveWallpaper/Business/TSAIListVC/TSAIPhotoGeneratorVC/TSAIPhotoDetailsVC/TSAIPhotoDetailsVC.swift
  70. 0 1
      TSLiveWallpaper/Business/TSAIListVC/TSAIUploadPhotoVC/TSAIRemovePhotlVC/TSAIRemovePhotlVC.swift
  71. 0 34
      TSLiveWallpaper/Business/TSAIListVC/TSAIUploadPhotoVC/TSAIUploadPhotoVC+Remove.swift
  72. 48 0
      TSLiveWallpaper/Business/TSAIListVC/TSAIUploadPhotoVC/TSAIUploadPhotoVC+Style.swift
  73. 1 1
      TSLiveWallpaper/Business/TSAIListVC/TSAIUploadPhotoVC/TSAIUploadPhotoVC+View.swift
  74. 12 29
      TSLiveWallpaper/Business/TSAIListVC/TSAIUploadPhotoVC/TSAIUploadPhotoVC.swift
  75. 114 0
      TSLiveWallpaper/Business/TSAIListVC/TSAIUploadPhotoVC/View/TSAIUploadPhotoMoreStyleBarView.swift
  76. 0 1
      TSLiveWallpaper/Business/TSAIListVC/TSFusionImageVC/TSFusionImageVC.swift
  77. 267 0
      TSLiveWallpaper/Business/TSAIListVC/TSSelectedPhotoStyleVC/TSSelectedPhotoStyleVC.swift
  78. 111 0
      TSLiveWallpaper/Business/TSAIResultsFrameVC/TSAIResultsFrameVC.swift
  79. 260 0
      TSLiveWallpaper/Business/TSAIResultsFrameVC/TSAIUsedPhotoVC/TSAIUsedPhotoVC.swift
  80. 2 1
      TSLiveWallpaper/Business/TSBusinessWebVC/TSBusinessWebVC.swift
  81. 1 1
      TSLiveWallpaper/Business/TSPurchaseMembershipVC/TSPurchaseVC.swift
  82. 3 1
      TSLiveWallpaper/Business/TSTabBarController/TSTabBarController.swift
  83. 11 0
      TSLiveWallpaper/Common/Ex/Notification+Ex.swift
  84. 0 1
      TSLiveWallpaper/Common/Purchase/TSPurchaseEnum.swift
  85. 1 1
      TSLiveWallpaper/Common/TSConfig.swift
  86. 1 1
      TSLiveWallpaper/Common/TSNetWork/TSNetWork+Business.swift
  87. 195 0
      TSLiveWallpaper/Common/ViewTool/TSPhotoPickerManager/KFImageView.swift
  88. 0 51
      TSLiveWallpaper/Common/ViewTool/TSPhotoPickerManager/TSHXPhotoPickerManager.swift
  89. 102 49
      TSLiveWallpaper/Common/ViewTool/TSPhotoPickerManager/TSPhotoPickerManager.swift
  90. 14 0
      TSLiveWallpaper/Data/Model/TSActionInfoModel.swift
  91. 1 0
      TSLiveWallpaper/Data/OperationQueue/TSGenerateBaseOperation/TSGenerateBaseOperation.swift
  92. 15 1
      TSLiveWallpaper/Data/OperationQueue/TSGenerateBaseOperation/TSGenerateBasePhotoOperation.swift
  93. 18 0
      TSLiveWallpaper/Data/TSDBManager/TSDBActionInfoModel.swift
  94. 96 0
      TSLiveWallpaper/Data/TSDBManager/TSDBKeyManager.swift
  95. 1 2
      TSLiveWallpaper/Data/TSDBManager/TSDBManager.swift
  96. 2 1
      TSLiveWallpaper/Data/TSRealmManager/TSRealmManager.swift
  97. 11 11
      TSLiveWallpaper/LaunchVC/TSLaunchVC.swift
  98. 51 0
      TSLiveWallpaper/Resource/Json/ai_expand_image_style.json

+ 3 - 9
Podfile

@@ -16,15 +16,6 @@ target 'TSLiveWallpaper' do
   pod 'TYCyclePagerView'
   pod 'Alamofire'
   
-#  pod 'TZImagePickerController'
-#  pod 'MarqueeLabel'
-#  pod 'MJRefresh'
-#  pod 'KLExtension',:git=>"https://gitee.com/WanlanNeel/klextension.git"
-#  pod 'KLTips',:git=>"https://gitee.com/WanlanNeel/kltips.git"
-#  pod 'Localize-Swift', '~> 3.2'
-#  pod "KingfisherWebP"
-
-
   pod 'AFNetworking',:git => "https://github.com/xlDon/AFNetworking-PrivacyInfo.git"
   pod 'BetterSegmentedControl', '~> 2.0'
   pod 'RealmSwift', '~>10'
@@ -33,6 +24,9 @@ target 'TSLiveWallpaper' do
   pod "HXPhotoPicker/Picker" #只有选择器
   pod "HXPhotoPicker/Camera/Lite"#不包含定位功能
   pod "HXPhotoPicker/Editor" #只有编辑器
+  
+  pod 'JXSegmentedView'
+  pod 'IQKeyboardManagerSwift'
 end
 
 

+ 62 - 1
Podfile.lock

@@ -28,6 +28,47 @@ PODS:
   - HXPhotoPicker/Picker (5.0.3):
     - HXPhotoPicker/Core
   - HXPhotoPicker/Resources (5.0.3)
+  - IQKeyboardCore (1.0.5)
+  - IQKeyboardManagerSwift (8.0.1):
+    - IQKeyboardManagerSwift/Appearance (= 8.0.1)
+    - IQKeyboardManagerSwift/Core (= 8.0.1)
+    - IQKeyboardManagerSwift/IQKeyboardReturnManager (= 8.0.1)
+    - IQKeyboardManagerSwift/IQKeyboardToolbarManager (= 8.0.1)
+    - IQKeyboardManagerSwift/IQTextView (= 8.0.1)
+    - IQKeyboardManagerSwift/Resign (= 8.0.1)
+  - IQKeyboardManagerSwift/Appearance (8.0.1):
+    - IQKeyboardManagerSwift/Core
+  - IQKeyboardManagerSwift/Core (8.0.1):
+    - IQKeyboardNotification
+    - IQTextInputViewNotification
+  - IQKeyboardManagerSwift/IQKeyboardReturnManager (8.0.1):
+    - IQKeyboardReturnManager
+  - IQKeyboardManagerSwift/IQKeyboardToolbarManager (8.0.1):
+    - IQKeyboardManagerSwift/Core
+    - IQKeyboardToolbarManager
+  - IQKeyboardManagerSwift/IQTextView (8.0.1):
+    - IQTextView
+  - IQKeyboardManagerSwift/Resign (8.0.1):
+    - IQKeyboardManagerSwift/Core
+  - IQKeyboardNotification (1.0.3)
+  - IQKeyboardReturnManager (1.0.4):
+    - IQKeyboardCore (= 1.0.5)
+  - IQKeyboardToolbar (1.1.1):
+    - IQKeyboardCore
+    - IQKeyboardToolbar/Core (= 1.1.1)
+  - IQKeyboardToolbar/Core (1.1.1):
+    - IQKeyboardCore
+    - IQKeyboardToolbar/Placeholderable
+  - IQKeyboardToolbar/Placeholderable (1.1.1):
+    - IQKeyboardCore
+  - IQKeyboardToolbarManager (1.1.3):
+    - IQKeyboardToolbar
+    - IQTextInputViewNotification
+  - IQTextInputViewNotification (1.0.8):
+    - IQKeyboardCore
+  - IQTextView (1.0.5):
+    - IQKeyboardToolbar/Placeholderable
+  - JXSegmentedView (1.4.1)
   - Kingfisher (7.10.0)
   - ObjectMapper (4.2.0)
   - Realm (10.54.4):
@@ -55,6 +96,8 @@ DEPENDENCIES:
   - HXPhotoPicker/Camera/Lite
   - HXPhotoPicker/Editor
   - HXPhotoPicker/Picker
+  - IQKeyboardManagerSwift
+  - JXSegmentedView
   - Kingfisher (= 7.10.0)
   - ObjectMapper (= 4.2)
   - RealmSwift (~> 10)
@@ -69,6 +112,15 @@ SPEC REPOS:
     - BetterSegmentedControl
     - DynamicBlurView
     - HXPhotoPicker
+    - IQKeyboardCore
+    - IQKeyboardManagerSwift
+    - IQKeyboardNotification
+    - IQKeyboardReturnManager
+    - IQKeyboardToolbar
+    - IQKeyboardToolbarManager
+    - IQTextInputViewNotification
+    - IQTextView
+    - JXSegmentedView
     - Kingfisher
     - ObjectMapper
     - Realm
@@ -94,6 +146,15 @@ SPEC CHECKSUMS:
   BetterSegmentedControl: 09607b27861d49cbce48b7673b74f9150a3d371a
   DynamicBlurView: b57e2f6aa33f85b2bcca272265162a3c7c5cc499
   HXPhotoPicker: 3250e3d7b5c1e9a35888a35f8b8abc99a18ed17f
+  IQKeyboardCore: 28c8bf3bcd8ba5aa1570b318cbc4da94b861711e
+  IQKeyboardManagerSwift: 835fc9c6e4732398113406d84900ad2e8f141218
+  IQKeyboardNotification: d7382c4466c5a5adef92c7452ebf861b36050088
+  IQKeyboardReturnManager: 972be48528ce9e7508ab3ab15ac7efac803f17f5
+  IQKeyboardToolbar: d4bdccfb78324aec2f3920659c77bb89acd33312
+  IQKeyboardToolbarManager: 6c693c8478d6327a7ef2107528d29698b3514dbb
+  IQTextInputViewNotification: f5e954d8881fd9808b744e49e024cc0d4bcfe572
+  IQTextView: ae13b4922f22e6f027f62c557d9f4f236b19d5c7
+  JXSegmentedView: cd73555ce2134d1656db2cb383ba9c2f36fb5078
   Kingfisher: a18f05d3b6d37d8650ee4a3e61d57a28fc6207f6
   ObjectMapper: 1eb41f610210777375fa806bf161dc39fb832b81
   Realm: 8b5cda39a41f17a1734da2f39c6004eb8745587a
@@ -103,6 +164,6 @@ SPEC CHECKSUMS:
   TSSmalCoacopods: 6aa97167f0c76b16fc7d1fd1eb198bb6aece4f68
   TYCyclePagerView: 2b051dade0615c70784aa34f40c646feeddb7344
 
-PODFILE CHECKSUM: 19b7027a35730c08f77747b5c613c30b920ded05
+PODFILE CHECKSUM: 19e32c6322d1f94d4a7e24d95dda07f4fbfe5038
 
 COCOAPODS: 1.16.2

+ 94 - 14
TSLiveWallpaper.xcodeproj/project.pbxproj

@@ -50,13 +50,12 @@
 		A83F28A42E165043009A4975 /* aiList_Kiss.gif in Resources */ = {isa = PBXBuildFile; fileRef = A83F289B2E165043009A4975 /* aiList_Kiss.gif */; };
 		A83F28A52E165043009A4975 /* aiList_Stroll.gif in Resources */ = {isa = PBXBuildFile; fileRef = A83F289E2E165043009A4975 /* aiList_Stroll.gif */; };
 		A83F28A62E165043009A4975 /* aiList_ForeheadKiss.gif in Resources */ = {isa = PBXBuildFile; fileRef = A83F28982E165043009A4975 /* aiList_ForeheadKiss.gif */; };
-		A83F28A92E165B1D009A4975 /* TSAIUploadPhotoVC+Remove.swift in Sources */ = {isa = PBXBuildFile; fileRef = A83F28A82E165B17009A4975 /* TSAIUploadPhotoVC+Remove.swift */; };
+		A83F28A92E165B1D009A4975 /* TSAIUploadPhotoVC+Style.swift in Sources */ = {isa = PBXBuildFile; fileRef = A83F28A82E165B17009A4975 /* TSAIUploadPhotoVC+Style.swift */; };
 		A83F28AB2E165C0A009A4975 /* launch4.png in Resources */ = {isa = PBXBuildFile; fileRef = A83F28AA2E165C0A009A4975 /* launch4.png */; };
 		A83F28AE2E166391009A4975 /* TSAIRemovePhotlVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A83F28AD2E166390009A4975 /* TSAIRemovePhotlVC.swift */; };
 		A83F28B02E168237009A4975 /* UIView+Ex.swift in Sources */ = {isa = PBXBuildFile; fileRef = A83F28AF2E168232009A4975 /* UIView+Ex.swift */; };
 		A8477C972D22737900DF0B93 /* TSBusinessWebVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8477C962D22737800DF0B93 /* TSBusinessWebVC.swift */; };
 		A84C239F2D1E88CD00B61B55 /* TSFileManagerTool.swift in Sources */ = {isa = PBXBuildFile; fileRef = A84C239E2D1E88C500B61B55 /* TSFileManagerTool.swift */; };
-		A864C1732E211C8C0077DADF /* TSHXPhotoPickerManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = A864C1722E211C810077DADF /* TSHXPhotoPickerManager.swift */; };
 		A868577C2DF819BB0089D222 /* TSDBManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = A868577B2DF819BA0089D222 /* TSDBManager.swift */; };
 		A868577E2DF81A940089D222 /* TSDBActionInfoModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A868577D2DF81A930089D222 /* TSDBActionInfoModel.swift */; };
 		A86857822DF81AD40089D222 /* TSActionInfoModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A86857812DF81ACF0089D222 /* TSActionInfoModel.swift */; };
@@ -91,6 +90,7 @@
 		A86857D72DF983620089D222 /* generat_loading.gif in Resources */ = {isa = PBXBuildFile; fileRef = A86857D62DF983620089D222 /* generat_loading.gif */; };
 		A86857DA2DF994600089D222 /* TSAIPhotoDetailsVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A86857D92DF9945F0089D222 /* TSAIPhotoDetailsVC.swift */; };
 		A86857DD2DF99C200089D222 /* TSImageIPanComparisonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A86857DC2DF99C200089D222 /* TSImageIPanComparisonView.swift */; };
+		A8722EFF2E371F6A004C3F8A /* Notification+Ex.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8722EFE2E371F66004C3F8A /* Notification+Ex.swift */; };
 		A87CF8522E0296B30063CB7E /* TSAIPhotoDetailsBrowserVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A87CF8512E0296960063CB7E /* TSAIPhotoDetailsBrowserVC.swift */; };
 		A87CF8542E029B450063CB7E /* TSAIPhotoDetailsBrowserCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A87CF8532E029B3F0063CB7E /* TSAIPhotoDetailsBrowserCell.swift */; };
 		A87CF85A2E02AF070063CB7E /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = A87CF8582E02AF070063CB7E /* InfoPlist.strings */; };
@@ -119,6 +119,12 @@
 		A8EB1A582E307572001F58D7 /* aiList_JazzDance.gif in Resources */ = {isa = PBXBuildFile; fileRef = A8EB1A422E307572001F58D7 /* aiList_JazzDance.gif */; };
 		A8EB1A592E307572001F58D7 /* aiList_Laugh.gif in Resources */ = {isa = PBXBuildFile; fileRef = A8EB1A442E307572001F58D7 /* aiList_Laugh.gif */; };
 		A8EB1A5A2E307572001F58D7 /* aiList_SendRose.gif in Resources */ = {isa = PBXBuildFile; fileRef = A8EB1A492E307572001F58D7 /* aiList_SendRose.gif */; };
+		A8EB1A5D2E30B955001F58D7 /* TSAIResultsFrameVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8EB1A5C2E30B954001F58D7 /* TSAIResultsFrameVC.swift */; };
+		A8EB1A602E30CB0C001F58D7 /* TSAIUsedPhotoVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8EB1A5F2E30CB0B001F58D7 /* TSAIUsedPhotoVC.swift */; };
+		A8EB1A622E30D034001F58D7 /* TSDBKeyManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8EB1A612E30D02D001F58D7 /* TSDBKeyManager.swift */; };
+		A8EE843F2E33228C00CA04F0 /* TSAIUploadPhotoMoreStyleBarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8EE843E2E33228400CA04F0 /* TSAIUploadPhotoMoreStyleBarView.swift */; };
+		A8EE84422E33605200CA04F0 /* TSSelectedPhotoStyleVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8EE84412E33605000CA04F0 /* TSSelectedPhotoStyleVC.swift */; };
+		A8EE84462E33931100CA04F0 /* KFImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8EE84452E33931000CA04F0 /* KFImageView.swift */; };
 		A8EE92C02DFFC3B50077DFFD /* TSImageProComparisonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8EE92BF2DFFC39C0077DFFD /* TSImageProComparisonView.swift */; };
 		A8EE92C22DFFC54C0077DFFD /* TSBootModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8EE92C12DFFC54A0077DFFD /* TSBootModel.swift */; };
 		A8EE92C42DFFC5830077DFFD /* TSBootCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8EE92C32DFFC5820077DFFD /* TSBootCell.swift */; };
@@ -127,7 +133,6 @@
 		A8EE92CF2DFFF2860077DFFD /* TSGenerateBasePhotoOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8EE92C82DFFF2860077DFFD /* TSGenerateBasePhotoOperation.swift */; };
 		A8EE92D02DFFF2860077DFFD /* TSBaseOperationQueue.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8EE92CA2DFFF2860077DFFD /* TSBaseOperationQueue.swift */; };
 		A8EE92D22DFFFE2F0077DFFD /* TSMineVM.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8EE92D12DFFFE250077DFFD /* TSMineVM.swift */; };
-		A8EE92D42DFFFFAD0077DFFD /* TSAIListVM.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8EE92D32DFFFFAA0077DFFD /* TSAIListVM.swift */; };
 		A8EE92D62E0005F70077DFFD /* Pacifico-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = A8EE92D52E0005F70077DFFD /* Pacifico-Regular.ttf */; };
 		A8EE92DB2E00121A0077DFFD /* TSGennerateCellView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8EE92DA2E0012180077DFFD /* TSGennerateCellView.swift */; };
 		A8F3D64D2E2E399600DE6C9D /* TSAIPhotoRemoveVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F3D64C2E2E399500DE6C9D /* TSAIPhotoRemoveVC.swift */; };
@@ -150,6 +155,11 @@
 		A8F8BCE32E0423B100EF4AA6 /* TSAIPhotoDetailsVC+View.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F8BCE22E0423AD00EF4AA6 /* TSAIPhotoDetailsVC+View.swift */; };
 		A8F8BCE62E04F62400EF4AA6 /* TSAIListPhotoGeneratorModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F8BCE52E04F62200EF4AA6 /* TSAIListPhotoGeneratorModel.swift */; };
 		A8F8BCEB2E0501DC00EF4AA6 /* TSAppUpdateAlertVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F8BCEA2E0501DB00EF4AA6 /* TSAppUpdateAlertVC.swift */; };
+		A8F9F2F22E372C17007FE237 /* TSAIExpandImageVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F9F2F12E372C15007FE237 /* TSAIExpandImageVC.swift */; };
+		A8F9F2F42E372C35007FE237 /* TSAIExpandStyleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F9F2F32E372C33007FE237 /* TSAIExpandStyleView.swift */; };
+		A8F9F2F62E372C49007FE237 /* TSAIExpandImageVM.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F9F2F52E372C47007FE237 /* TSAIExpandImageVM.swift */; };
+		A8F9F2F82E372CD8007FE237 /* ai_expand_image_style.json in Resources */ = {isa = PBXBuildFile; fileRef = A8F9F2F72E372CD8007FE237 /* ai_expand_image_style.json */; };
+		A8F9F2FA2E375FE7007FE237 /* TSAIPhotoDetailsVC+Expand.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F9F2F92E375FD7007FE237 /* TSAIPhotoDetailsVC+Expand.swift */; };
 		A8FD8F332DFBCB85008CAACF /* ZillaSlab-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = A8FD8F322DFBCB85008CAACF /* ZillaSlab-Regular.ttf */; };
 		A8FD8F342DFBCB85008CAACF /* ZillaSlab-Medium.ttf in Resources */ = {isa = PBXBuildFile; fileRef = A8FD8F312DFBCB85008CAACF /* ZillaSlab-Medium.ttf */; };
 		A8FD8F352DFBCB85008CAACF /* ZillaSlab-BoldItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = A8FD8F302DFBCB85008CAACF /* ZillaSlab-BoldItalic.ttf */; };
@@ -206,7 +216,7 @@
 		A83F289C2E165043009A4975 /* aiList_SayHi.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = aiList_SayHi.gif; sourceTree = "<group>"; };
 		A83F289D2E165043009A4975 /* aiList_Smile.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = aiList_Smile.gif; sourceTree = "<group>"; };
 		A83F289E2E165043009A4975 /* aiList_Stroll.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = aiList_Stroll.gif; sourceTree = "<group>"; };
-		A83F28A82E165B17009A4975 /* TSAIUploadPhotoVC+Remove.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TSAIUploadPhotoVC+Remove.swift"; sourceTree = "<group>"; };
+		A83F28A82E165B17009A4975 /* TSAIUploadPhotoVC+Style.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TSAIUploadPhotoVC+Style.swift"; sourceTree = "<group>"; };
 		A83F28AA2E165C0A009A4975 /* launch4.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = launch4.png; sourceTree = "<group>"; };
 		A83F28AD2E166390009A4975 /* TSAIRemovePhotlVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSAIRemovePhotlVC.swift; sourceTree = "<group>"; };
 		A83F28AF2E168232009A4975 /* UIView+Ex.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+Ex.swift"; sourceTree = "<group>"; };
@@ -227,7 +237,6 @@
 		A864C16E2E20C3B10077DADF /* pt-PT */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "pt-PT"; path = "pt-PT.lproj/LaunchScreen.strings"; sourceTree = "<group>"; };
 		A864C16F2E20C3B10077DADF /* pt-PT */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "pt-PT"; path = "pt-PT.lproj/InfoPlist.strings"; sourceTree = "<group>"; };
 		A864C1702E20C3B10077DADF /* pt-PT */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "pt-PT"; path = "pt-PT.lproj/Localizable.strings"; sourceTree = "<group>"; };
-		A864C1722E211C810077DADF /* TSHXPhotoPickerManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSHXPhotoPickerManager.swift; sourceTree = "<group>"; };
 		A868577B2DF819BA0089D222 /* TSDBManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSDBManager.swift; sourceTree = "<group>"; };
 		A868577D2DF81A930089D222 /* TSDBActionInfoModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSDBActionInfoModel.swift; sourceTree = "<group>"; };
 		A86857812DF81ACF0089D222 /* TSActionInfoModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSActionInfoModel.swift; sourceTree = "<group>"; };
@@ -262,6 +271,7 @@
 		A86857D62DF983620089D222 /* generat_loading.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = generat_loading.gif; sourceTree = "<group>"; };
 		A86857D92DF9945F0089D222 /* TSAIPhotoDetailsVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSAIPhotoDetailsVC.swift; sourceTree = "<group>"; };
 		A86857DC2DF99C200089D222 /* TSImageIPanComparisonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSImageIPanComparisonView.swift; sourceTree = "<group>"; };
+		A8722EFE2E371F66004C3F8A /* Notification+Ex.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Notification+Ex.swift"; sourceTree = "<group>"; };
 		A87CF8512E0296960063CB7E /* TSAIPhotoDetailsBrowserVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSAIPhotoDetailsBrowserVC.swift; sourceTree = "<group>"; };
 		A87CF8532E029B3F0063CB7E /* TSAIPhotoDetailsBrowserCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSAIPhotoDetailsBrowserCell.swift; sourceTree = "<group>"; };
 		A87CF8592E02AF070063CB7E /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
@@ -297,6 +307,12 @@
 		A8EB1A4A2E307572001F58D7 /* aiList_Shock.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = aiList_Shock.gif; sourceTree = "<group>"; };
 		A8EB1A4B2E307572001F58D7 /* aiList_SpookyGhostface.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = aiList_SpookyGhostface.gif; sourceTree = "<group>"; };
 		A8EB1A4C2E307572001F58D7 /* aiList_SurpriseKiss.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = aiList_SurpriseKiss.gif; sourceTree = "<group>"; };
+		A8EB1A5C2E30B954001F58D7 /* TSAIResultsFrameVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSAIResultsFrameVC.swift; sourceTree = "<group>"; };
+		A8EB1A5F2E30CB0B001F58D7 /* TSAIUsedPhotoVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSAIUsedPhotoVC.swift; sourceTree = "<group>"; };
+		A8EB1A612E30D02D001F58D7 /* TSDBKeyManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSDBKeyManager.swift; sourceTree = "<group>"; };
+		A8EE843E2E33228400CA04F0 /* TSAIUploadPhotoMoreStyleBarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSAIUploadPhotoMoreStyleBarView.swift; sourceTree = "<group>"; };
+		A8EE84412E33605000CA04F0 /* TSSelectedPhotoStyleVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSSelectedPhotoStyleVC.swift; sourceTree = "<group>"; };
+		A8EE84452E33931000CA04F0 /* KFImageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KFImageView.swift; sourceTree = "<group>"; };
 		A8EE92BF2DFFC39C0077DFFD /* TSImageProComparisonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSImageProComparisonView.swift; sourceTree = "<group>"; };
 		A8EE92C12DFFC54A0077DFFD /* TSBootModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSBootModel.swift; sourceTree = "<group>"; };
 		A8EE92C32DFFC5820077DFFD /* TSBootCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSBootCell.swift; sourceTree = "<group>"; };
@@ -305,7 +321,6 @@
 		A8EE92CA2DFFF2860077DFFD /* TSBaseOperationQueue.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSBaseOperationQueue.swift; sourceTree = "<group>"; };
 		A8EE92CB2DFFF2860077DFFD /* TSBaseOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSBaseOperation.swift; sourceTree = "<group>"; };
 		A8EE92D12DFFFE250077DFFD /* TSMineVM.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSMineVM.swift; sourceTree = "<group>"; };
-		A8EE92D32DFFFFAA0077DFFD /* TSAIListVM.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSAIListVM.swift; sourceTree = "<group>"; };
 		A8EE92D52E0005F70077DFFD /* Pacifico-Regular.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Pacifico-Regular.ttf"; sourceTree = "<group>"; };
 		A8EE92DA2E0012180077DFFD /* TSGennerateCellView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSGennerateCellView.swift; sourceTree = "<group>"; };
 		A8F3D64C2E2E399500DE6C9D /* TSAIPhotoRemoveVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSAIPhotoRemoveVC.swift; sourceTree = "<group>"; };
@@ -337,6 +352,11 @@
 		A8F8BCF52E0535E200EF4AA6 /* zh-Hant */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hant"; path = "zh-Hant.lproj/LaunchScreen.strings"; sourceTree = "<group>"; };
 		A8F8BCF62E0535E200EF4AA6 /* zh-Hant */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hant"; path = "zh-Hant.lproj/InfoPlist.strings"; sourceTree = "<group>"; };
 		A8F8BCF72E0535E200EF4AA6 /* zh-Hant */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hant"; path = "zh-Hant.lproj/Localizable.strings"; sourceTree = "<group>"; };
+		A8F9F2F12E372C15007FE237 /* TSAIExpandImageVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSAIExpandImageVC.swift; sourceTree = "<group>"; };
+		A8F9F2F32E372C33007FE237 /* TSAIExpandStyleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSAIExpandStyleView.swift; sourceTree = "<group>"; };
+		A8F9F2F52E372C47007FE237 /* TSAIExpandImageVM.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSAIExpandImageVM.swift; sourceTree = "<group>"; };
+		A8F9F2F72E372CD8007FE237 /* ai_expand_image_style.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = ai_expand_image_style.json; sourceTree = "<group>"; };
+		A8F9F2F92E375FD7007FE237 /* TSAIPhotoDetailsVC+Expand.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TSAIPhotoDetailsVC+Expand.swift"; sourceTree = "<group>"; };
 		A8FD8F302DFBCB85008CAACF /* ZillaSlab-BoldItalic.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "ZillaSlab-BoldItalic.ttf"; sourceTree = "<group>"; };
 		A8FD8F312DFBCB85008CAACF /* ZillaSlab-Medium.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "ZillaSlab-Medium.ttf"; sourceTree = "<group>"; };
 		A8FD8F322DFBCB85008CAACF /* ZillaSlab-Regular.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "ZillaSlab-Regular.ttf"; sourceTree = "<group>"; };
@@ -413,6 +433,7 @@
 		A81CA4752D15778800A3AAC8 /* Ex */ = {
 			isa = PBXGroup;
 			children = (
+				A8722EFE2E371F66004C3F8A /* Notification+Ex.swift */,
 				A83F28AF2E168232009A4975 /* UIView+Ex.swift */,
 				A86857C32DF92AE30089D222 /* UIFont+Ex.swift */,
 				A81F5B4E2D19673500740085 /* AVAsset+Ex.swift */,
@@ -450,6 +471,7 @@
 		A81CA48C2D15855300A3AAC8 /* Business */ = {
 			isa = PBXGroup;
 			children = (
+				A8EB1A5B2E30B935001F58D7 /* TSAIResultsFrameVC */,
 				A8E590372DFFAE3100C2533F /* TSBootVC */,
 				A86857AD2DF9218C0089D222 /* General */,
 				A86857A92DF9210D0089D222 /* TSAIListVC */,
@@ -529,6 +551,7 @@
 			isa = PBXGroup;
 			children = (
 				A81F5B512D19685900740085 /* response.json */,
+				A8F9F2F72E372CD8007FE237 /* ai_expand_image_style.json */,
 			);
 			path = Json;
 			sourceTree = "<group>";
@@ -629,6 +652,7 @@
 			children = (
 				A868577B2DF819BA0089D222 /* TSDBManager.swift */,
 				A868577D2DF81A930089D222 /* TSDBActionInfoModel.swift */,
+				A8EB1A612E30D02D001F58D7 /* TSDBKeyManager.swift */,
 			);
 			path = TSDBManager;
 			sourceTree = "<group>";
@@ -705,7 +729,6 @@
 				A8EB1A3C2E2F8785001F58D7 /* TSAIListStyleMoreVC */,
 				A83F28872E16231E009A4975 /* VM */,
 				A8EE92D92E00120F0077DFFD /* View */,
-				A8EE92D32DFFFFAA0077DFFD /* TSAIListVM.swift */,
 				A86857A02DF91EB80089D222 /* TSAIListVC.swift */,
 			);
 			path = TSAIListVC;
@@ -723,7 +746,7 @@
 		A86857A72DF9204B0089D222 /* TSPhotoPickerManager */ = {
 			isa = PBXGroup;
 			children = (
-				A864C1722E211C810077DADF /* TSHXPhotoPickerManager.swift */,
+				A8EE84452E33931000CA04F0 /* KFImageView.swift */,
 				A86857A62DF9204B0089D222 /* TSPhotoPickerManager.swift */,
 			);
 			path = TSPhotoPickerManager;
@@ -732,10 +755,11 @@
 		A86857A92DF9210D0089D222 /* TSAIListVC */ = {
 			isa = PBXGroup;
 			children = (
+				A8F9F2EF2E372BFB007FE237 /* TSAIExpandImageVC */,
+				A8EE84402E33603D00CA04F0 /* TSSelectedPhotoStyleVC */,
 				A81E81612E24F05700207EB8 /* TSFusionImageVC */,
 				A8F8BCD72E0407C800EF4AA6 /* TSAIListVideoPlayerVC */,
 				A86857D82DF9943E0089D222 /* TSAIPhotoDetailsVC */,
-				A86857D42DF97A2A0089D222 /* TSAIExpandChangeView.swift */,
 				A86857CD2DF9775D0089D222 /* TSAIPhotoGeneratorVC */,
 				A86857BA2DF926070089D222 /* TSAIListHistoryVC */,
 				A86857B82DF9259C0089D222 /* TSAIList+Enmu.swift */,
@@ -772,7 +796,7 @@
 				A8F8BCD42E03FE4C00EF4AA6 /* TSAIUploadPhotoVC+View.swift */,
 				A8F8BCD02E03FC4E00EF4AA6 /* TSAIUploadPhotoVC+Image.swift */,
 				A8F8BCD22E03FD4A00EF4AA6 /* TSAIUploadPhotoVC+Video.swift */,
-				A83F28A82E165B17009A4975 /* TSAIUploadPhotoVC+Remove.swift */,
+				A83F28A82E165B17009A4975 /* TSAIUploadPhotoVC+Style.swift */,
 			);
 			path = TSAIUploadPhotoVC;
 			sourceTree = "<group>";
@@ -789,6 +813,7 @@
 		A86857CD2DF9775D0089D222 /* TSAIPhotoGeneratorVC */ = {
 			isa = PBXGroup;
 			children = (
+				A8F8BCE12E04211300EF4AA6 /* TSAIPhotoDetailsVC */,
 				A8F8BCE42E04F61C00EF4AA6 /* Model */,
 				A86857CE2DF977630089D222 /* TSAIListPhotoGeneratorVC.swift */,
 				A86857D02DF9778B0089D222 /* TSAIListPhotoGeneratorVM.swift */,
@@ -799,7 +824,6 @@
 		A86857D82DF9943E0089D222 /* TSAIPhotoDetailsVC */ = {
 			isa = PBXGroup;
 			children = (
-				A8F8BCE12E04211300EF4AA6 /* TSAIPhotoDetailsVC */,
 				A87CF8512E0296960063CB7E /* TSAIPhotoDetailsBrowserVC.swift */,
 				A87CF8532E029B3F0063CB7E /* TSAIPhotoDetailsBrowserCell.swift */,
 			);
@@ -873,6 +897,31 @@
 			path = TSAIListStyleMoreVC;
 			sourceTree = "<group>";
 		};
+		A8EB1A5B2E30B935001F58D7 /* TSAIResultsFrameVC */ = {
+			isa = PBXGroup;
+			children = (
+				A8EB1A5E2E30CAF6001F58D7 /* TSAIUsedPhotoVC */,
+				A8EB1A5C2E30B954001F58D7 /* TSAIResultsFrameVC.swift */,
+			);
+			path = TSAIResultsFrameVC;
+			sourceTree = "<group>";
+		};
+		A8EB1A5E2E30CAF6001F58D7 /* TSAIUsedPhotoVC */ = {
+			isa = PBXGroup;
+			children = (
+				A8EB1A5F2E30CB0B001F58D7 /* TSAIUsedPhotoVC.swift */,
+			);
+			path = TSAIUsedPhotoVC;
+			sourceTree = "<group>";
+		};
+		A8EE84402E33603D00CA04F0 /* TSSelectedPhotoStyleVC */ = {
+			isa = PBXGroup;
+			children = (
+				A8EE84412E33605000CA04F0 /* TSSelectedPhotoStyleVC.swift */,
+			);
+			path = TSSelectedPhotoStyleVC;
+			sourceTree = "<group>";
+		};
 		A8EE92C92DFFF2860077DFFD /* TSGenerateBaseOperation */ = {
 			isa = PBXGroup;
 			children = (
@@ -945,6 +994,7 @@
 		A8F8BCCD2E03F88700EF4AA6 /* View */ = {
 			isa = PBXGroup;
 			children = (
+				A8EE843E2E33228400CA04F0 /* TSAIUploadPhotoMoreStyleBarView.swift */,
 				A8F8BCCE2E03F8BB00EF4AA6 /* TSAIUploadPhotoTextView.swift */,
 			);
 			path = View;
@@ -966,6 +1016,7 @@
 				A8F8BCE22E0423AD00EF4AA6 /* TSAIPhotoDetailsVC+View.swift */,
 				A8F8BCDD2E0420EB00EF4AA6 /* TSAIPhotoDetailsVC+Image.swift */,
 				A8F8BCDF2E0420FB00EF4AA6 /* TSAIPhotoDetailsVC+Video.swift */,
+				A8F9F2F92E375FD7007FE237 /* TSAIPhotoDetailsVC+Expand.swift */,
 			);
 			path = TSAIPhotoDetailsVC;
 			sourceTree = "<group>";
@@ -986,6 +1037,25 @@
 			path = TSAppUpdateAlertVC;
 			sourceTree = "<group>";
 		};
+		A8F9F2EF2E372BFB007FE237 /* TSAIExpandImageVC */ = {
+			isa = PBXGroup;
+			children = (
+				A8F9F2F52E372C47007FE237 /* TSAIExpandImageVM.swift */,
+				A8F9F2F12E372C15007FE237 /* TSAIExpandImageVC.swift */,
+				A8F9F2F02E372C0B007FE237 /* View */,
+			);
+			path = TSAIExpandImageVC;
+			sourceTree = "<group>";
+		};
+		A8F9F2F02E372C0B007FE237 /* View */ = {
+			isa = PBXGroup;
+			children = (
+				A86857D42DF97A2A0089D222 /* TSAIExpandChangeView.swift */,
+				A8F9F2F32E372C33007FE237 /* TSAIExpandStyleView.swift */,
+			);
+			path = View;
+			sourceTree = "<group>";
+		};
 		A8FD8F362DFBD650008CAACF /* View */ = {
 			isa = PBXGroup;
 			children = (
@@ -1106,6 +1176,7 @@
 				A8EB1A5A2E307572001F58D7 /* aiList_SendRose.gif in Resources */,
 				A8FD8F332DFBCB85008CAACF /* ZillaSlab-Regular.ttf in Resources */,
 				A8FD8F342DFBCB85008CAACF /* ZillaSlab-Medium.ttf in Resources */,
+				A8F9F2F82E372CD8007FE237 /* ai_expand_image_style.json in Resources */,
 				A8FD8F352DFBCB85008CAACF /* ZillaSlab-BoldItalic.ttf in Resources */,
 				A83F289F2E165043009A4975 /* aiList_Hug.gif in Resources */,
 				A83F28A02E165043009A4975 /* aiList_Smile.gif in Resources */,
@@ -1185,6 +1256,7 @@
 				A8EB1A302E2F6D8C001F58D7 /* TSAILIstBannerCell.swift in Sources */,
 				A8F3D6512E2E535700DE6C9D /* TSRevokeTool.swift in Sources */,
 				A8F8BCCF2E03F8BC00EF4AA6 /* TSAIUploadPhotoTextView.swift in Sources */,
+				A8EE843F2E33228C00CA04F0 /* TSAIUploadPhotoMoreStyleBarView.swift in Sources */,
 				A8EE92CE2DFFF2860077DFFD /* TSGenerateBaseOperation.swift in Sources */,
 				A8EE92CF2DFFF2860077DFFD /* TSGenerateBasePhotoOperation.swift in Sources */,
 				A8EE92D02DFFF2860077DFFD /* TSBaseOperationQueue.swift in Sources */,
@@ -1192,6 +1264,7 @@
 				A83F28892E162343009A4975 /* TSAIListDataVM.swift in Sources */,
 				A8EB1A3E2E2F879C001F58D7 /* TSAIListStyleMoreVC.swift in Sources */,
 				A83F288D2E162B19009A4975 /* TSAILIstFullCardCell.swift in Sources */,
+				A8F9F2F42E372C35007FE237 /* TSAIExpandStyleView.swift in Sources */,
 				A8EB1A322E2F716A001F58D7 /* TSImagesComparisonView.swift in Sources */,
 				A8F76C4D2D3747B400AA6E93 /* TSPurchaseVC.swift in Sources */,
 				A895B5002E01370E004F9B85 /* TSTextToastView.swift in Sources */,
@@ -1202,6 +1275,7 @@
 				A81CA4AA2D16943800A3AAC8 /* TSMineCell.swift in Sources */,
 				A83946212D1D61D600ABFF0D /* TSRateUsVC.swift in Sources */,
 				A81F5B4F2D19674600740085 /* AVAsset+Ex.swift in Sources */,
+				A8EE84422E33605200CA04F0 /* TSSelectedPhotoStyleVC.swift in Sources */,
 				A8E56BF62D1520EC003C54AF /* AppDelegate.swift in Sources */,
 				A8F778B42D1BB8F600BF55D5 /* PhotoManager.swift in Sources */,
 				A83A6A862E1FC99E0084197A /* LanguageManager.swift in Sources */,
@@ -1220,9 +1294,8 @@
 				A81CA4852D1582A600A3AAC8 /* UIButton+Ex.swift in Sources */,
 				A81CA47F2D15789C00A3AAC8 /* TSConfig.swift in Sources */,
 				A87CF8542E029B450063CB7E /* TSAIPhotoDetailsBrowserCell.swift in Sources */,
-				A864C1732E211C8C0077DADF /* TSHXPhotoPickerManager.swift in Sources */,
 				A81CA4652D15685F00A3AAC8 /* TSLaunchVC.swift in Sources */,
-				A83F28A92E165B1D009A4975 /* TSAIUploadPhotoVC+Remove.swift in Sources */,
+				A83F28A92E165B1D009A4975 /* TSAIUploadPhotoVC+Style.swift in Sources */,
 				A8F8BCEB2E0501DC00EF4AA6 /* TSAppUpdateAlertVC.swift in Sources */,
 				A81F5B402D194EA900740085 /* UIDevice+Extension.swift in Sources */,
 				A83946272D1D623800ABFF0D /* TSShareUsVC.swift in Sources */,
@@ -1234,6 +1307,7 @@
 				A8884B612E2DE7A3001B41AC /* TSAIPhotoRemoveBgView.swift in Sources */,
 				A86857B22DF921F90089D222 /* TSView.swift in Sources */,
 				A87CF8522E0296B30063CB7E /* TSAIPhotoDetailsBrowserVC.swift in Sources */,
+				A8F9F2F22E372C17007FE237 /* TSAIExpandImageVC.swift in Sources */,
 				A86857872DF81B660089D222 /* TSNetWork+Business.swift in Sources */,
 				A86857882DF81B660089D222 /* TSNetworkManager.swift in Sources */,
 				A86857892DF81B660089D222 /* TSNetworkManager+Loading.swift in Sources */,
@@ -1245,6 +1319,7 @@
 				A8EE92D22DFFFE2F0077DFFD /* TSMineVM.swift in Sources */,
 				A86857BE2DF926220089D222 /* TSAIListHistoryCell.swift in Sources */,
 				A86857DD2DF99C200089D222 /* TSImageIPanComparisonView.swift in Sources */,
+				A8EB1A602E30CB0C001F58D7 /* TSAIUsedPhotoVC.swift in Sources */,
 				A86857D32DF978740089D222 /* TSProgressState.swift in Sources */,
 				A868579A2DF915950089D222 /* TSPurchaseEnum.swift in Sources */,
 				A86857B92DF925A20089D222 /* TSAIList+Enmu.swift in Sources */,
@@ -1257,11 +1332,13 @@
 				A86857C02DF926870089D222 /* TSPageNullView.swift in Sources */,
 				A8F8BCD32E03FD5400EF4AA6 /* TSAIUploadPhotoVC+Video.swift in Sources */,
 				A86857942DF845F60089D222 /* TSGeneratorView.swift in Sources */,
+				A8F9F2F62E372C49007FE237 /* TSAIExpandImageVM.swift in Sources */,
 				A868578C2DF843F90089D222 /* TSRealmManager.swift in Sources */,
-				A8EE92D42DFFFFAD0077DFFD /* TSAIListVM.swift in Sources */,
+				A8EB1A5D2E30B955001F58D7 /* TSAIResultsFrameVC.swift in Sources */,
 				A86857D12DF977980089D222 /* TSAIListPhotoGeneratorVM.swift in Sources */,
 				A8E590392DFFAE4400C2533F /* TSBootVC.swift in Sources */,
 				A8EE92DB2E00121A0077DFFD /* TSGennerateCellView.swift in Sources */,
+				A8EB1A622E30D034001F58D7 /* TSDBKeyManager.swift in Sources */,
 				A83F288B2E162369009A4975 /* TSAIListDataVM+Dic.swift in Sources */,
 				A86857982DF846FE0089D222 /* TSDynamicBlurView.swift in Sources */,
 				A83946332D1D66A900ABFF0D /* TSPrivacyPolicyVC.swift in Sources */,
@@ -1274,6 +1351,8 @@
 				A8477C972D22737900DF0B93 /* TSBusinessWebVC.swift in Sources */,
 				A8F8BCD82E0407C800EF4AA6 /* TSAIListVideoPlayerVC.swift in Sources */,
 				A8EB1A342E2F7327001F58D7 /* TSAIListHeaderView.swift in Sources */,
+				A8F9F2FA2E375FE7007FE237 /* TSAIPhotoDetailsVC+Expand.swift in Sources */,
+				A8722EFF2E371F6A004C3F8A /* Notification+Ex.swift in Sources */,
 				A8EE92C02DFFC3B50077DFFD /* TSImageProComparisonView.swift in Sources */,
 				A86857C42DF92AEB0089D222 /* UIFont+Ex.swift in Sources */,
 				A86857A12DF91EB90089D222 /* TSAIListVC.swift in Sources */,
@@ -1282,6 +1361,7 @@
 				A81CA48F2D15857B00A3AAC8 /* TSTabBarController.swift in Sources */,
 				A81E81652E24F09600207EB8 /* TSAISmallUploadView.swift in Sources */,
 				A8F8BCDE2E0420EE00EF4AA6 /* TSAIPhotoDetailsVC+Image.swift in Sources */,
+				A8EE84462E33931100CA04F0 /* KFImageView.swift in Sources */,
 				A86857AC2DF921160089D222 /* TSAIListHintBaseVC.swift in Sources */,
 				A8F8BCDC2E040D9E00EF4AA6 /* TSBusinessFileManager.swift in Sources */,
 				A8F3D6532E2E540C00DE6C9D /* TSColorPickerVC.swift in Sources */,

+ 2 - 1
TSLiveWallpaper/AppDelegate.swift

@@ -84,7 +84,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
     }
 }
 
-
+import IQKeyboardManagerSwift
 extension AppDelegate {
     
     static func isFirstInstallApp() -> Bool {
@@ -114,6 +114,7 @@ extension AppDelegate {
     
     func checkAppConfig() {
         TSAppUpdateManager.checkAppConfig()
+        IQKeyboardManager.shared.isEnabled = true
     }
     
     

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

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

+ 21 - 0
TSLiveWallpaper/Assets.xcassets/AIList/ai_expand/ai_expand_16_9.imageset/Contents.json

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

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


+ 21 - 0
TSLiveWallpaper/Assets.xcassets/AIList/ai_expand/ai_expand_1_1.imageset/Contents.json

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

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


+ 21 - 0
TSLiveWallpaper/Assets.xcassets/AIList/ai_expand/ai_expand_2_3.imageset/Contents.json

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

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


+ 21 - 0
TSLiveWallpaper/Assets.xcassets/AIList/ai_expand/ai_expand_3_2.imageset/Contents.json

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

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


+ 21 - 0
TSLiveWallpaper/Assets.xcassets/AIList/ai_expand/ai_expand_3_4.imageset/Contents.json

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

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


+ 21 - 0
TSLiveWallpaper/Assets.xcassets/AIList/ai_expand/ai_expand_4_3.imageset/Contents.json

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

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


+ 21 - 0
TSLiveWallpaper/Assets.xcassets/AIList/ai_expand/ai_expand_9_16.imageset/Contents.json

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

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


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

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

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


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


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

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

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


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


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

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

+ 21 - 0
TSLiveWallpaper/Assets.xcassets/AIList/ptp_style/ptp_style_AdjustLight.imageset/Contents.json

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

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


+ 21 - 0
TSLiveWallpaper/Assets.xcassets/AIList/ptp_style/ptp_style_Colorize.imageset/Contents.json

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

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


+ 21 - 0
TSLiveWallpaper/Assets.xcassets/AIList/ptp_style/ptp_style_Descratch.imageset/Contents.json

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

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


+ 21 - 0
TSLiveWallpaper/Assets.xcassets/AIList/ptp_style/ptp_style_Enhance.imageset/Contents.json

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

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


+ 21 - 0
TSLiveWallpaper/Assets.xcassets/AIList/ptp_style/ptp_style_Recreate.imageset/Contents.json

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

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


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

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

+ 21 - 0
TSLiveWallpaper/Assets.xcassets/AIList/selectedPhotoStyleCamera/selectedPhotoStyleCamera.imageset/Contents.json

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

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


+ 21 - 0
TSLiveWallpaper/Assets.xcassets/AIList/selectedPhotoStyleCamera/selectedPhotoStyleOldPhoto.imageset/Contents.json

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

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


+ 21 - 0
TSLiveWallpaper/Assets.xcassets/AIList/selectedPhotoStyleCamera/selectedPhotoStylePhoto.imageset/Contents.json

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

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


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

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

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


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


+ 1 - 1
TSLiveWallpaper/Business/TSAIListVC/TSAIAgeImageHintVC/TSAIListHintBaseVC.swift

@@ -277,6 +277,6 @@ class TSAIListHintBaseVC: TSBaseVC {
     
     func dismissPageVC(){
         self.view.isHidden = true
-        self.dismiss(animated: false)
+        self.dismiss(animated: true)
     }
 }

+ 262 - 0
TSLiveWallpaper/Business/TSAIListVC/TSAIExpandImageVC/TSAIExpandImageVC.swift

@@ -0,0 +1,262 @@
+//
+//  TSAIExpandImageVC.swift
+//  TSLiveWallpaper
+//
+//  Created by 100Years on 2025/7/27.
+//
+
+class TSAIExpandImageVC: TSBaseVC {
+    
+    var upLoadImage:UIImage?{
+        didSet{
+            submitBtn.isEnabled = !(upLoadImage == nil)
+            expandAreaView.setImage(showImage: upLoadImage)
+        }
+    }
+    
+    init(upLoadImage: UIImage?) {
+        self.upLoadImage = upLoadImage
+        super.init()
+    }
+    
+    @MainActor required init?(coder: NSCoder) {
+        fatalError("init(coder:) has not been implemented")
+    }
+
+    lazy var viewModel: TSAIExpandImageVM = {
+        let viewModel:TSAIExpandImageVM = TSAIExpandImageVM()
+        return viewModel
+    }()
+    
+    var photoExpand = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
+
+    lazy var photoPickerManager: TSPhotoPickerManager = {
+        let photoPickerManager = TSPhotoPickerManager(viewController: self)
+        return photoPickerManager
+    }()
+
+    //###################################### topImageView ######################################
+    lazy var expandAreaView: TSAIExpandChangeView = {
+        let view = TSAIExpandChangeView()
+        view.clickAddViewBlock = { [weak self]  in
+            guard let self = self else { return }
+            self.pickSinglePhoto()
+        }
+        return view
+    }()
+    //###################################### style类型 ######################################
+    lazy var styleView: TSAIExpandStyleView = {
+        let styleView = TSAIExpandStyleView()
+        styleView.dataArray = viewModel.selectStyleModels
+        styleView.currentIndexPath = IndexPath(item: viewModel.selectedStyleIndex, section: 0)
+        styleView.selectedValueBlock = { [weak self] model in
+            guard let self = self else { return }
+            handelSelectedValueBlock(model: model)
+        }
+        return styleView
+    }()
+    
+    //###################################### 提交按钮 ######################################
+    lazy var submitBtn: UIButton = {
+        let submitBtn = kCreateNormalSubmitBtn(title: "Expand".localized) { [weak self]  in
+            guard let self = self else { return }
+            generateImage()
+        }
+        return submitBtn
+    }()
+    //###################################### createView ######################################
+    override func createView() {
+        addNormalNavBarView()
+        setPageTitle("AI Expand Photo".localized)
+        _ = setNavigationItem("", imageName: "replace_photo", direction: .right, action: #selector(clickNavRight))
+        
+        contentView.addSubview(submitBtn)
+        contentView.addSubview(styleView)
+        contentView.addSubview(expandAreaView)
+
+
+        submitBtn.snp.makeConstraints { make in
+            make.centerX.equalToSuperview()
+            make.width.equalTo(250*kDesignScale)
+            make.height.equalTo(48)
+            make.bottom.equalTo(-12-k_Height_safeAreaInsetsBottom())
+        }
+        
+        styleView.snp.makeConstraints { make in
+            make.bottom.equalTo(submitBtn.snp.top).offset(-36)
+            make.leading.trailing.equalTo(0)
+          }
+        
+        expandAreaView.snp.makeConstraints { make in
+            make.top.leading.trailing.equalTo(0)
+            make.bottom.equalTo(styleView.snp.top).offset(-61)
+        }
+
+        let image = upLoadImage
+        upLoadImage = image
+        updateExpandArea()
+    }
+    
+    override func dealThings() {
+        NotificationCenter.default.addObserver(self, selector: #selector(updateVipView), name: .kPurchaseDidChanged, object: nil)
+        updateVipView()
+    }
+    
+    @objc func updateVipView() {
+        kMainAsync{
+            kSetBtnVipIcon(btn: self.submitBtn, show: kPurchaseBusiness.generateVipShow(type: .general))
+        }
+    }
+}
+
+extension TSAIExpandImageVC {
+    
+    @objc func clickNavRight() {
+        pickSinglePhoto()
+    }
+    
+    func handelSelectedValueBlock(model:TSGenerateStyleModel)  {
+        if model.clickType == 2 { //换图
+            self.pickSinglePhoto()
+        }else{
+            viewModel.selectStyleModel = model
+            styleView.agreeWillSelectIndexPath()
+            updateExpandArea()
+        }
+    }
+    
+    func pickSinglePhoto()  {
+        pickSinglePhoto{ [weak self] image in
+            guard let self = self else { return }
+            upLoadImage = image
+            viewModel.upLoadImage = image
+            updateExpandArea()
+            
+            if upLoadImage == nil {
+                pop()
+            }
+        }
+    }
+
+    
+    func pickSinglePhoto(complete: @escaping (UIImage)->Void)  {
+        photoPickerManager.pickPhoto() { [weak self] images in
+            guard let self = self else { return }
+            if let image = images.first {
+                complete(image)
+            }else{
+                dePrint("图片异常")
+            }
+         
+            self.photoPickerManager.dismissPageVC()
+        }
+    }
+
+    // MARK: - 更新扩图区域
+    private func updateExpandArea() {
+        var imageSize = CGSizeMake(500, 500)
+        if let upLoadImage = upLoadImage {
+            imageSize = upLoadImage.size
+        }
+        
+        let imageAspectRatio = imageSize.width / imageSize.height
+        let targetAspectRatio = viewModel.currentRatio.value
+        let maxSize = expandAreaView.maxSize
+        dePrint("imageAspectRatio=\(imageAspectRatio)")
+        dePrint("targetAspectRatio=\(targetAspectRatio)")
+        dePrint("\n")
+        
+        var expandWidth: CGFloat
+        var expandHeight: CGFloat
+        
+        if targetAspectRatio >= 1.0 {
+            // 以宽度为基准
+            expandWidth = maxSize.width
+            expandHeight = expandWidth / targetAspectRatio
+        }else {
+            // 以高度为基准
+            expandHeight = maxSize.height
+            expandWidth = expandHeight * targetAspectRatio
+        }
+        
+        // 确保扩图区域不超过最大限制(100%)
+        let maxExpandWidth = maxSize.width
+        let maxExpandHeight = maxSize.height
+        print("\n")
+        expandWidth = min(expandWidth, maxExpandWidth)
+        expandHeight = min(expandHeight, maxExpandHeight)
+        
+        print("expandWidth=\(expandWidth)")
+        print("expandHeight=\(expandHeight)")
+        print("\n")
+        
+        let difference = abs(targetAspectRatio - imageAspectRatio) <= 0.01
+        print("targetAspectRatio=\(targetAspectRatio),imageAspectRatio=\(imageAspectRatio),difference=\(difference)")
+        
+        // 使用 SnapKit 更新约束
+        expandAreaView.updateExpandAreaView(width: expandWidth, height: expandHeight)
+        let imageRatio = min(expandWidth/imageSize.width,expandHeight/imageSize.height)
+        var scaleFactor = 1.0
+        if difference {
+            scaleFactor = 0.67
+        }
+        
+        let imageViewW = imageSize.width * imageRatio * scaleFactor
+        let imageViewH = imageSize.height * imageRatio * scaleFactor
+        
+        dePrint("expandWidth=\(imageViewW)")
+        dePrint("expandHeight=\(imageViewH)")
+        
+        expandAreaView.updateImageView(width: imageViewW, height: imageViewH)
+        
+        let ws = expandWidth/imageViewW - 1.0
+        let hs = expandHeight/imageViewH - 1.0
+        
+
+        if difference {
+            photoExpand = UIEdgeInsets(top: 0.25, left: 0.25, bottom: 0.25, right: 0.25)
+        }else{
+            photoExpand = UIEdgeInsets(top: hs/2.0, left: ws/2.0, bottom: hs/2.0, right: ws/2.0)
+        }
+        
+        print("ws=\(ws),hs=\(hs)")
+        print("postEdge=\(photoExpand)")
+        
+        UIView.animate(withDuration: 0.3) {
+            self.expandAreaView.layoutIfNeeded()
+        }
+    }
+}
+
+extension TSAIExpandImageVC {
+    
+    func generateImage() {
+        if kPurchaseBusiness.kJudgeVipFreeType(vipFreeNumType: .general){ return }//判断 vip
+        
+        guard let upLoadImage = upLoadImage else { return }
+        let generatorStyle:TSGeneratorImageStyle = .photoExpand
+        let generatorModel = TSAIListPhotoGeneratorModel(
+            upLoadImage: upLoadImage,
+            generatorStyle: generatorStyle,
+            expandEdge: photoExpand,
+            expandViewSizes: (expandAreaView.bgImageView.size,expandAreaView.showImageView.size)
+        )
+        
+        if let promptModel = generatorStyle.generateModel{
+            generatorModel.prompt = promptModel.prompt
+            generatorModel.model = promptModel.model
+        }
+        
+        
+        let gennerateVC = TSAIListPhotoGeneratorVC(generatorModel:generatorModel){[weak self] model in
+            guard let self = self else { return }
+            updateVipView()
+        }
+        
+        gennerateVC.backstageBlock = { [weak self]  in
+            guard let self = self else { return }
+            self.navigationController?.popToRootViewController(animated: false)
+        }
+        kPresentModalVC(target: self, modelVC: gennerateVC,transitionStyle: .crossDissolve)
+    }
+}

+ 103 - 0
TSLiveWallpaper/Business/TSAIListVC/TSAIExpandImageVC/TSAIExpandImageVM.swift

@@ -0,0 +1,103 @@
+//
+//  TSAIExpandImageVM.swift
+//  TSLiveWallpaper
+//
+//  Created by 100Years on 2025/7/27.
+//
+
+
+import ObjectMapper
+
+// MARK: - 比例枚举
+enum AspectRatio: Int,CaseIterable {
+    case ratio1_1 = 0
+    case ratio16_9
+    case ratio9_16
+    case ratio4_3
+    case ratio3_4
+    case ratio2_3
+    case ratio3_2
+    
+    var value: CGFloat {
+        switch self {
+        case .ratio1_1: return 1.0
+        case .ratio16_9: return 16.0/9.0
+        case .ratio9_16: return 9.0/16.0
+        case .ratio4_3: return 4.0/3.0
+        case .ratio3_4: return 3.0/4.0
+        case .ratio2_3: return 2.0/3.0
+        case .ratio3_2: return 3.0/2.0
+        }
+    }
+    
+    var displayName: String {
+        switch self {
+        case .ratio1_1: return "1:1"
+        case .ratio16_9: return "16:9"
+        case .ratio9_16: return "9:16"
+        case .ratio4_3: return "4:3"
+        case .ratio3_4: return "3:4"
+        case .ratio2_3: return "2:3"
+        case .ratio3_2: return "3:2"
+        }
+    }
+    
+    static func creatAspectRatio(string:String)->AspectRatio{
+        switch string {
+        case "1:1": return .ratio1_1
+        case "16:9": return .ratio16_9
+        case "9:16": return .ratio9_16
+        case "4:3": return .ratio4_3
+        case "3:4": return .ratio3_4
+        case "2:3": return .ratio2_3
+        case "3:2": return .ratio3_2
+        default: return .ratio1_1
+        }
+    }
+}
+
+extension AspectRatio {
+    
+//    //ttp文生图比例 size
+//    var ttpSize:CGSize{
+//        switch self {
+//        case .ratio1_1: return CGSize(width: 1440, height: 1440)
+//        case .ratio16_9: return CGSize(width: 1440, height: 800)
+//        case .ratio9_16: return CGSize(width: 800, height: 1440)
+//        case .ratio4_3: return CGSize(width: 1440, height: 1056)
+//        case .ratio3_4: return CGSize(width: 1056, height: 1440)
+//        case .ratio2_3: return CGSize(width: 960, height: 1440)
+//        case .ratio3_2: return CGSize(width: 1440, height: 960)
+//        }
+//    }
+}
+
+
+
+class TSAIExpandImageVM {
+    
+    var currentRatio: AspectRatio{
+        if let selectStyleModel = selectStyleModel {
+            return AspectRatio.creatAspectRatio(string: selectStyleModel.imageText)
+        }
+        return AspectRatio.ratio1_1
+    }
+    
+    //###################################### 样式选择 ######################################
+    var selectedStyleIndex:Int = 1
+    lazy var selectStyleModels: [TSGenerateStyleModel] = {
+        var selectStyleModels = [TSGenerateStyleModel]()
+        if let dataArray = Mapper<TSGenerateStyleModel>().mapArray(JSONfile: "ai_expand_image_style.json"){
+            selectStyleModels = dataArray
+            
+            if let model = dataArray.safeObj(At: selectedStyleIndex) {
+                selectStyleModel = model //加上默认的选择
+            }
+        }
+        return selectStyleModels
+    }()
+    
+    var selectStyleModel:TSGenerateStyleModel?
+    var upLoadImage:UIImage?
+    
+}

+ 0 - 0
TSLiveWallpaper/Business/TSAIListVC/TSAIExpandChangeView.swift → TSLiveWallpaper/Business/TSAIListVC/TSAIExpandImageVC/View/TSAIExpandChangeView.swift


+ 165 - 0
TSLiveWallpaper/Business/TSAIListVC/TSAIExpandImageVC/View/TSAIExpandStyleView.swift

@@ -0,0 +1,165 @@
+//
+//  TSAIExpandStyleView.swift
+//  TSLiveWallpaper
+//
+//  Created by 100Years on 2025/7/27.
+//
+
+
+
+class TSAIExpandStyleView:TSBaseView {
+    
+    var selectedValueBlock:((TSGenerateStyleModel)->Void)?
+    
+    var dataArray: [TSGenerateStyleModel] = [TSGenerateStyleModel](){
+        didSet{
+            styleCollectionView.reloadData()
+            if dataArray.count > 0 {
+                self.styleCollectionView.selectItem(at: self.currentIndexPath, animated: false, scrollPosition: .centeredHorizontally)
+            }
+        }
+    }
+    
+    lazy var layout: TSBaseCollectionViewFlowLayout = {
+        let layout = TSBaseCollectionViewFlowLayout()
+        layout.scrollDirection = .horizontal
+        layout.itemSize = CGSize(width: k_ScreenWidth/7.0, height: 52)
+        layout.minimumInteritemSpacing = 0.0
+        layout.minimumLineSpacing = 0.0
+        layout.sectionInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
+        return layout
+    }()
+    
+    
+    lazy var styleCollectionView: TSBaseCollectionView = {
+        let collectionView = TSBaseCollectionView(frame: .zero, collectionViewLayout: layout)
+        collectionView.delegate = self
+        collectionView.dataSource = self
+        collectionView.showsVerticalScrollIndicator = false
+        collectionView.showsHorizontalScrollIndicator = false
+        collectionView.backgroundColor = .clear
+        collectionView.register(TSAIExpandStyleCell.self, forCellWithReuseIdentifier: TSAIExpandStyleCell.cellID)
+        if #available(iOS 11.0, *) {
+            collectionView.contentInsetAdjustmentBehavior = .never
+        }
+        return collectionView
+    }()
+    lazy var willSelectIndexPath = currentIndexPath
+    var currentIndexPath:IndexPath = IndexPath(item: 0, section: 0){
+        didSet{
+            for (i,model) in dataArray.enumerated(){
+                if i == currentIndexPath.item {
+                    model.isSelected = true
+                }else {
+                    model.isSelected = false
+                }
+            }
+            UIView.performWithoutAnimation {
+                self.styleCollectionView.reloadData()
+            }
+        }
+    }
+    
+    override func creatUI() {
+
+        currentIndexPath = IndexPath(item: 0, section: 0)
+        contentView.addSubview(styleCollectionView)
+        styleCollectionView.snp.makeConstraints { make in
+            make.top.equalTo(0)
+            make.leading.trailing.equalTo(0)
+            make.height.equalTo(52)
+            make.bottom.equalTo(0)
+        }
+    }
+    
+    func unCheck(){
+        styleCollectionView.deselectItem(at: currentIndexPath, animated: true)
+    }
+    
+    func agreeWillSelectIndexPath(){
+        currentIndexPath = willSelectIndexPath
+    }
+    
+}
+
+extension TSAIExpandStyleView: UICollectionViewDataSource ,UICollectionViewDelegate {
+    
+    public func numberOfSections(in collectionView: UICollectionView) -> Int {
+        return 1
+    }
+    
+    public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
+        return dataArray.count
+    }
+    
+    public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
+        
+        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: TSAIExpandStyleCell.cellID, for: indexPath)
+        if let cell = cell as? TSAIExpandStyleCell,let itemModel = dataArray.safeObj(At: indexPath.item){
+            cell.itemModel = itemModel
+        }
+        return cell
+    }
+
+    public func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
+        if let model = dataArray.safeObj(At: indexPath.item){
+            willSelectIndexPath = indexPath
+            selectedValueBlock?(model)
+        }
+    }
+}
+
+class TSAIExpandStyleCell: TSBaseCollectionCell {
+    
+    static let cellID = "TSAIExpandStyleCell"
+
+    var itemModel:TSGenerateStyleModel = TSGenerateStyleModel(){
+        didSet{
+            if let image = UIImage(named: itemModel.imageName)?.withRenderingMode(.alwaysTemplate) {
+                imageView.image = image
+            }
+            textLabel.text = itemModel.imageText.localized
+            
+            if itemModel.isSelected {
+                textLabel.textColor = .themeColor
+                imageView.tintColor = .themeColor
+            }else{
+                textLabel.textColor = .white
+                imageView.tintColor = .white
+            }
+        }
+    }
+    
+    lazy var imageView: UIImageView = {
+        let imageView = UIImageView()
+        return imageView
+    }()
+    
+    lazy var textLabel: UILabel = {
+        let textLabel = UILabel.createLabel(font: .font(size: 10,weight: .medium),textColor: .white,textAlignment: .center,numberOfLines: 2)
+        textLabel.adjustsFontSizeToFitWidth = true
+        textLabel.contentMode = .bottom
+        return textLabel
+    }()
+    
+    override func creatUI() {
+        //cell 100*110
+        bgContentView.addSubview(imageView)
+        imageView.snp.makeConstraints { make in
+            make.top.equalTo(0)
+            make.centerX.equalToSuperview()
+            make.width.equalTo(22)
+            make.height.equalTo(24)
+        }
+        
+
+        bgContentView.addSubview(textLabel)
+        textLabel.snp.makeConstraints { make in
+            make.height.equalTo(16.0)
+            make.bottom.equalTo(0)
+            make.leading.trailing.equalToSuperview()
+        }
+    }
+    
+}
+

+ 5 - 3
TSLiveWallpaper/Business/TSAIListVC/TSAIList+Enmu.swift

@@ -19,7 +19,7 @@ enum TSGeneratorImageStyle:String {
     case portraitFusion = "PortraitFusion"  //照片融合
     case removeBg = "removeBg"      //删除图片的背景
     case removeWatermark = "RemoveWatermark"      //移除水印
-    case expandPhoto = "ExpandPhoto"      // AI扩图
+    case photoExpand = "ExpandPhoto"      // AI扩图
     
     var imageMaxKb:Int{
         switch self {
@@ -126,17 +126,19 @@ extension TSGeneratorImageStyle {
         let vm = TSAIListDataVM.shared
         switch self {
         case .enhance:
-            return TSGenerateModel(json: vm.ptp_PhotoEnhance)
+            return TSGenerateModel(json: vm.ptp_Enhance)
         case .colorize:
             return TSGenerateModel(json: vm.ptp_Colorize)
         case .descratch:
             return TSGenerateModel(json: vm.ptp_Descratch)
         case .enlighten:
-            return TSGenerateModel(json: vm.ptp_Enlighten)
+            return TSGenerateModel(json: vm.ptp_AdjustLight)
         case .recreate:
             return TSGenerateModel(json: vm.ptp_Recreate)
         case .creatVideo:
             return TSGenerateModel(json: vm.video_Creat)
+        case .photoExpand:
+            return TSGenerateModel(json: vm.ptp_PhotoExpand)
         default:
             return nil
         }

+ 46 - 47
TSLiveWallpaper/Business/TSAIListVC/TSAIListHistoryVC/TSAIListHistoryVC.swift

@@ -11,37 +11,37 @@ class TSAIListHistoryVC: TSBaseVC {
 
     var listModelArray:[TSActionInfoModel] = []
     
-    //###################################### 导航栏 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 label = UILabel.createLabel(text: "History".localized,font: .font(name: .Pacifico, size: 24))
-        navBarView.barView.addSubview(label)
-        label.snp.makeConstraints { make in
-           make.center.equalToSuperview()
-        }
-        
-        navBarView.barView.addSubview(vipBtn)
-        vipBtn.snp.makeConstraints { make in
-            make.centerY.equalToSuperview()
-            make.trailing.equalTo(-16)
-            make.width.height.equalTo(32)
-        }
-        
-        kMainAsync {
-            label.applyGradient(colors: ["#F1D3AB".uiColor,"#E4A858".uiColor])
-        }
-        
-       return navBarView
-    }()
+//    //###################################### 导航栏 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 label = UILabel.createLabel(text: "History".localized,font: .font(name: .Pacifico, size: 24))
+//        navBarView.barView.addSubview(label)
+//        label.snp.makeConstraints { make in
+//           make.center.equalToSuperview()
+//        }
+//        
+//        navBarView.barView.addSubview(vipBtn)
+//        vipBtn.snp.makeConstraints { make in
+//            make.centerY.equalToSuperview()
+//            make.trailing.equalTo(-16)
+//            make.width.height.equalTo(32)
+//        }
+//        
+//        kMainAsync {
+//            label.applyGradient(colors: ["#F1D3AB".uiColor,"#E4A858".uiColor])
+//        }
+//        
+//       return navBarView
+//    }()
     
     //###################################### 集合视图 ######################################
     let collectionViewBtootm:CGFloat = 80
@@ -78,15 +78,17 @@ class TSAIListHistoryVC: TSBaseVC {
     
     var navRightBtn = UIButton()
     override func createView() {
-        addNormalNavBarView()
-        
-//        setPageTitle("History".localized)
-//        navRightBtn = setNavigationItem("", imageName: "ai_delete", direction: .right, action: #selector(clickNavRight))
+//        addNormalNavBarView()
+//        
+////        setPageTitle("History".localized)
+////        navRightBtn = setNavigationItem("", imageName: "ai_delete", direction: .right, action: #selector(clickNavRight))
+//        
+//        navBarContentView.addSubview(navBarView)
+//        navBarView.snp.makeConstraints { make in
+//            make.edges.equalToSuperview()
+//        }
         
-        navBarContentView.addSubview(navBarView)
-        navBarView.snp.makeConstraints { make in
-            make.edges.equalToSuperview()
-        }
+        setNavBarViewHidden(true)
         
         contentView.addSubview(pageNullView)
         contentView.addSubview(collectionView)
@@ -114,7 +116,6 @@ class TSAIListHistoryVC: TSBaseVC {
     
     @objc func updateVipView() {
         kMainAsync{
-            self.vipBtn.isHidden = PurchaseManager.default.isVip
             self.collectionView.reloadData()
         }
     }
@@ -255,16 +256,14 @@ extension TSAIListHistoryVC{
         TSRMShared.aiListDB
     }
 }
-extension TSAIListHistoryVC{
-
-    static func showPosition(){
-        AppDelegate.tabbar?.changeSelectedIndex(index: 1)
-    }
-    
-}
 
 extension TSAIListHistoryVC:TSTabBarControllerProtocol {
     func tabBarDoubleTap(_ tabbar: UITabBarController){
         collectionView.setContentOffset(CGPoint(x: 0, y: 0), animated: true)
     }
 }
+
+import JXSegmentedView
+extension TSAIListHistoryVC: JXSegmentedListContainerViewListDelegate {
+    func listView() -> UIView { return view }
+}

+ 1 - 0
TSLiveWallpaper/Business/TSAIListVC/TSAIListVC/TSAIListStyleMoreVC/TSAIListStyleMoreVC.swift

@@ -161,6 +161,7 @@ class TSAILIstStyleMoreImageCell: TSAILIstStyleMoreBaseCell {
     }()
     
     override func creatUI() {
+        super.creatUI()
         ctxView.addSubview(imageView)
         imageView.snp.makeConstraints { make in
             make.edges.equalToSuperview()

+ 51 - 13
TSLiveWallpaper/Business/TSAIListVC/TSAIListVC/TSAIListVC.swift

@@ -8,10 +8,7 @@
 
 class TSAIListVC: TSBaseVC {
     
-    lazy var viewModel: TSAIListDataVM = {
-        let viewModel = TSAIListDataVM()
-        return viewModel
-    }()
+    lazy var viewModel:TSAIListDataVM = TSAIListDataVM.shared
     
     //###################################### 导航栏 view ######################################
     lazy var vipBtn: UIButton = {
@@ -68,10 +65,10 @@ class TSAIListVC: TSBaseVC {
 
     override func createView() {
         
-        navBarContentView.addSubview(navBarView)
-        navBarView.snp.makeConstraints { make in
-            make.edges.equalToSuperview()
-        }
+//        navBarContentView.addSubview(navBarView)
+//        navBarView.snp.makeConstraints { make in
+//            make.edges.equalToSuperview()
+//        }
         
         contentView.snp.updateConstraints { make in
             make.top.equalTo(0)
@@ -186,7 +183,7 @@ extension TSAIListVC: UICollectionViewDataSource ,UICollectionViewDelegate,UICol
 func kShowGenerateBusyView(view:UIView) ->Bool{
     if TSGenerateBasePhotoOperationQueue.shared.isAvailability == false {
         kTextToastShared.show(atView: view,text: "1 task is processing".localized){
-            TSAIListHistoryVC.showPosition()
+            NotificationCenter.default.post(name: .kGenerateoBackStage, object: nil)
         }
         return true
     }
@@ -217,9 +214,13 @@ extension TSAIListVC {
         if itemModel.style == .removeBg {
             if kPurchaseBusiness.kJudgeVipFreeType(vipFreeNumType: .generalRemoveBg){ return }//判断 vip
         }
-  
+        
         Self.enterSelectPhotos(target: target,style: itemModel.style) { images in
-            if itemModel.style == .remove {
+            if itemModel.style == .photoExpand {
+                target.push(TSAIExpandImageVC(upLoadImage: images.first!),animated: false) {
+                    closeSelectPhotos()
+                }
+            }else if itemModel.style == .remove {
                 target.push(TSAIRemovePhotlVC(titleString: itemModel.name,upLoadImage: images.first!, generatorStyle: itemModel.style,disCoverItemModel: itemModel),animated: false) {
                     closeSelectPhotos()
                 }
@@ -243,6 +244,8 @@ extension TSAIListVC {
 extension TSAIListVC{
     static var hintBaseVC:TSAIListHintBaseVC?
     static var photoPickerManager:TSPhotoPickerManager?
+    static var selectedPhotoStyleVC:TSSelectedPhotoStyleVC?
+    
     static func enterSelectPhotos(target:UIViewController,style:TSGeneratorImageStyle,complete: @escaping ([UIImage])->Void){
         if style.userDefaultsKey.count == 0 {
             self.pickSinglePhoto(target:target,style:style,complete:complete)
@@ -260,12 +263,14 @@ extension TSAIListVC{
     static func presentModalHintVC(target:UIViewController,style:TSGeneratorImageStyle,complete:@escaping ([UIImage])->Void){
         let hintBaseVC = TSAIListHintBaseVC(config: style.config)
         hintBaseVC.clickUpImageHandle = { image in
-            pickSinglePhoto(target: Self.hintBaseVC!, style: style, complete: complete)
+//            pickSinglePhoto(target: Self.hintBaseVC!, style: style, complete: complete)
+//            pickSinglePhoto(target: target, style: style, complete: complete)
+            pickPhotoListView(target: target, style: style, complete: complete)
         }
         kPresentModalVC(target: target, modelVC: hintBaseVC,transitionStyle: .crossDissolve)
         Self.hintBaseVC = hintBaseVC
     }
-
+    
     static func pickSinglePhoto(target:UIViewController,style:TSGeneratorImageStyle,complete: @escaping ([UIImage])->Void)  {
         let photoPickerManager = TSPhotoPickerManager(viewController: target)
         photoPickerManager.pickPhoto(maxSelected: style.needPhotos) {images in
@@ -274,11 +279,44 @@ extension TSAIListVC{
         Self.photoPickerManager = photoPickerManager
     }
     
+    static func pickPhotoListView(target:UIViewController,style:TSGeneratorImageStyle,complete: @escaping ([UIImage])->Void)  {
+        
+        closeSelectPhotos()
+        let selectedPhotoStyleVC = TSSelectedPhotoStyleVC(maxSelected: style.needPhotos,complete: { type in
+            pickPhoto(target: target, style: style, type: type, complete: complete)
+        })
+
+        kPresentModalVC(target: target, modelVC: selectedPhotoStyleVC,transitionStyle: .crossDissolve)
+        Self.selectedPhotoStyleVC = selectedPhotoStyleVC
+    }
+                                                          
+                                                          
+    static func pickPhoto(target:UIViewController,style:TSGeneratorImageStyle,type:Int,complete: @escaping ([UIImage])->Void)  {
+        closeSelectPhotos()
+        if type == 0 {
+            pickSinglePhoto(target: target, style: style, complete: complete)
+        }else if type == 1 {
+            pickSinglePhoto(target: target, style: style, complete: complete)
+        }else if type == 2 {
+            pickLoactionPhoto(target: target, style: style, complete: complete)
+        }
+    }
+    
+    static func pickLoactionPhoto(target:UIViewController,style:TSGeneratorImageStyle,complete: @escaping ([UIImage])->Void)  {
+        let photoPickerManager = TSPhotoPickerManager(viewController: target)
+        photoPickerManager.pickLoactionPhoto(maxSelected: style.needPhotos) {images in
+            complete(images)
+        }
+        Self.photoPickerManager = photoPickerManager
+    }
+    
     static func closeSelectPhotos(){
         photoPickerManager?.dismissPageVC()
         hintBaseVC?.dismissPageVC()
+        selectedPhotoStyleVC?.dismiss()
         hintBaseVC = nil
         photoPickerManager = nil
+        selectedPhotoStyleVC = nil
     }
 }
 

+ 0 - 193
TSLiveWallpaper/Business/TSAIListVC/TSAIListVC/TSAIListVM.swift

@@ -1,193 +0,0 @@
-//
-//  TSAIListVM.swift
-//  TSLiveWallpaper
-//
-//  Created by 100Years on 2025/6/16.
-//
-
-//class TSAIListVM {
-//    
-//    init(target: UIViewController) {
-//        self.target = target
-//    }
-//    
-//    var target:UIViewController
-//    var hintBaseVC:TSAIListHintBaseVC = TSAIListHintBaseVC(config: .descratchConfig)
-//    
-//    lazy var photoPickerManager: TSPhotoPickerManager = {
-//        let photoPickerManager = TSPhotoPickerManager(viewController: self.target)
-//        return photoPickerManager
-//    }()
-//
-//    lazy var dataArray: [TSBasicSectionModel] = {
-//        var dataArray = [TSBasicSectionModel]()
-//        let sectionModel = TSBasicSectionModel()
-//        dataArray.append(sectionModel)
-//    
-//        //黑白照片变颜色
-//        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(style: .colorize) { image in
-//                    let baseVc = TSAIUploadPhotoVC(titleString: model.leftTitle ?? "",upLoadImage: image, generatorStyle: .colorize)
-//                        kPushVC(target: self.target, 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(style: .descratch) { image in
-//                        let baseVc = TSAIUploadPhotoVC(titleString: model.leftTitle ?? "",upLoadImage: image, generatorStyle: .descratch)
-//                        kPushVC(target: self.target, modelVC: baseVc)
-//                    }
-//        }))
-//        
-//        
-//        //视频照片
-//        let animatedItemModel = createItemModel(
-//            leftImageName:"aiList_Animated",
-//            leftTitle: "Animated Photo".localized,
-//            leftSubTitle: "Turn photos into live moments".localized,
-//            rightViewStyle: 0,
-//            tapBlock: { [weak self] model, _, _ in
-//               guard let self = self else { return }
-//                enterSelectPhotos(style: .creatVideo) { image in
-//                    let baseVc = TSAIUploadPhotoVC(titleString: model.leftTitle ?? "",upLoadImage: image, generatorStyle: .creatVideo)
-//                    kPushVC(target: self.target, modelVC: baseVc)
-//                }
-//            })
-//        
-//        animatedItemModel.leftImagePath = "animated_example.gif"
-////        animatedItemModel.leftImagePath = "animated_photos.webp"
-//        sectionModel.addSubItemModel(animatedItemModel)
-//
-//        
-//        //照片高清修复
-//        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(style: .enhance) { image in
-//                    let baseVc = TSAIUploadPhotoVC(titleString: model.leftTitle ?? "",upLoadImage: image, generatorStyle: .enhance)
-//                        kPushVC(target: self.target, modelVC: baseVc)
-//                    }
-//        }))
-//        
-//        //修复和上色老照片
-//        sectionModel.addSubItemModel(
-//            createItemModel(
-//                leftImageName:"aiList_Recreate",
-//                leftTitle: "Recreate".localized,
-//                leftSubTitle: "Bring new life to old photos".localized,
-//                rightViewStyle: 0,
-//                tapBlock: { [weak self] model, _, _ in
-//                   guard let self = self else { return }
-//                    enterSelectPhotos(style: .recreate) { image in
-//                    let baseVc = TSAIUploadPhotoVC(titleString: model.leftTitle ?? "",upLoadImage: image, generatorStyle: .recreate)
-//                        kPushVC(target: self.target, modelVC: baseVc)
-//                    }
-//        }))
-//        
-//        //调整光线
-//        sectionModel.addSubItemModel(
-//            createItemModel(
-//                leftImageName:"aiList_Enlighten",
-//                leftTitle: "Adjust Light".localized,
-//                leftSubTitle: "Easily fix lighting issues on photos".localized,
-//                rightViewStyle: 0,
-//                tapBlock: { [weak self] model, _, _ in
-//                   guard let self = self else { return }
-//                    enterSelectPhotos(style: .enlighten) { image in
-//                    let baseVc = TSAIUploadPhotoVC(titleString: model.leftTitle ?? "",upLoadImage: image, generatorStyle: .enlighten)
-//                        kPushVC(target: self.target, modelVC: baseVc)
-//                    }
-//        }))
-//        
-//
-//        return dataArray
-//
-//    }()
-//    
-//    
-//}
-//
-//extension TSAIListVM {
-//
-//    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 TSAIListVM{
-//    
-//    func enterSelectPhotos(style:TSGeneratorImageStyle,complete: @escaping (UIImage)->Void){
-//        if style.userDefaultsKey.isEmpty{
-//            self.pickSinglePhoto(maxBitSize:style.imageMaxBitSize,complete:complete)
-//        }else{
-//            TSAIListHintBaseVC.userDefaultsKey = style.userDefaultsKey
-//            if TSAIListHintBaseVC.isShowUploadImageHint{
-//                TSAIListHintBaseVC.isShowUploadImageHint = false
-//                self.presentModalHintVC(config:style.config,complete:complete)
-//            }else {
-//                self.pickSinglePhoto(maxBitSize:style.imageMaxBitSize,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.target, modelVC: hintBaseVC,transitionStyle: .crossDissolve)
-//    }
-//    
-//    func pickSinglePhoto(maxBitSize:Int,complete: @escaping (UIImage)->Void)  {
-//        photoPickerManager.pickPhoto() { [weak self] images in
-//            guard let self = self else { return }
-//            if let image = images.first {
-//                complete(image)
-//            }else{
-//                dePrint("图片异常")
-//            }
-//            self.photoPickerManager.dismissPageVC()
-//        }
-//    }
-//}
-//
-//

+ 45 - 28
TSLiveWallpaper/Business/TSAIListVC/TSAIListVC/VM/TSAIListDataVM+Dic.swift

@@ -20,6 +20,23 @@ let flux = "flux"               //走kie--flux
 private let input = "input"
 
 //MARK: 功能性模型
+
+
+extension TSAIListDataVM {
+    
+    var unionTypeDict:[Int:[TSGenerateModel]]{
+        return[
+            1:[
+                TSGenerateModel(json: ptp_Colorize)!,
+                TSGenerateModel(json: ptp_Enhance)!,
+                TSGenerateModel(json: ptp_Descratch)!,
+                TSGenerateModel(json: ptp_Recreate)!,
+                TSGenerateModel(json: ptp_AdjustLight)!,
+            ]
+        ]
+    }
+    
+}
 extension TSAIListDataVM {
     
     var video_Angry:[String:Any]{
@@ -228,14 +245,14 @@ extension TSAIListDataVM {
 //MARK: 图生图的模型
 extension TSAIListDataVM {
     
-    var ptp_AIExpandPhoto:[String:Any]{
+    var ptp_PhotoExpand:[String:Any]{
         [
             imageName: "",
-           imageText: "AI Expand Photo",
-           prompt:"",
+            imageText: "Al Extender Photo",
+            prompt:"高清智能扩图上传的照片,无缝衔接,自然延伸,风格一致,内容协调,细节丰富,过渡平滑,色彩统一,符合原图,合理补全",
             specialStyle:1,
             isVip: true,
-            unionType: 1,
+            unionType: 0,
             model:volcengine
         ]
     }
@@ -243,11 +260,11 @@ extension TSAIListDataVM {
     var ptp_RemoveWatermark:[String:Any]{
         [
             imageName: "",
-           imageText: "Remove Watermark",
-           prompt:"",
+            imageText: "Remove Watermark",
+            prompt:"",
             specialStyle:1,
             isVip: true,
-            unionType: 1,
+            unionType: 0,
             model:kie
         ]
     }
@@ -255,11 +272,11 @@ extension TSAIListDataVM {
     var ptp_RemoveBg:[String:Any]{
         [
             imageName: "",
-           imageText: "Remove Background",
-           prompt:"Remove Background",
+            imageText: "Remove Background",
+            prompt:"Remove Background",
             specialStyle:1,
             isVip: true,
-            unionType: 1,
+            unionType: 0,
             model:kie
         ]
     }
@@ -267,20 +284,20 @@ extension TSAIListDataVM {
     var ptp_Remove:[String:Any]{
         [
             imageName: "",
-           imageText: "",
-           prompt:"",
+            imageText: "",
+            prompt:"",
             specialStyle:1,
             isVip: true,
-            unionType: 1,
+            unionType: 0,
             model:volcengine
         ]
     }
     
-    var ptp_PhotoEnhance:[String:Any]{
+    var ptp_Enhance:[String:Any]{
         [
             imageName: "ptp_style_Enhance",
-           imageText: "Photo Enhance",
-           prompt:"Upscale the image to high resolution. Do not modify colors, lighting, people, background, or any visual elements. Only improve sharpness, clarity, and pixel detail while preserving all original features",
+            imageText: "Enhance",
+            prompt:"Upscale the image to high resolution. Do not modify colors, lighting, people, background, or any visual elements. Only improve sharpness, clarity, and pixel detail while preserving all original features",
             specialStyle:1,
             isVip: true,
             unionType: 1,
@@ -291,8 +308,8 @@ extension TSAIListDataVM {
     var ptp_Colorize:[String:Any]{
         [
             imageName: "ptp_style_Colorize",
-           imageText: "Colorize",
-           prompt:"Add suitable colors to photos",
+            imageText: "Colorize",
+            prompt:"Add suitable colors to photos",
             specialStyle:0,
             isVip: true,
             unionType: 1,
@@ -303,8 +320,8 @@ extension TSAIListDataVM {
     var ptp_Descratch:[String:Any]{
         [
             imageName: "ptp_style_Descratch",
-           imageText: "Descratch",
-           prompt:"Remove the photo's scratches and dirt",
+            imageText: "Descratch",
+            prompt:"Remove the photo's scratches and dirt",
             specialStyle:0,
             isVip: false,
             unionType: 1,
@@ -312,11 +329,11 @@ extension TSAIListDataVM {
         ]
     }
     
-    var ptp_Enlighten:[String:Any]{
+    var ptp_AdjustLight:[String:Any]{
         [
             imageName: "ptp_style_AdjustLight",
-           imageText: "Enlighten",
-           prompt:"Adjust the light and darkness of the photo to make the overall look coordinated",
+            imageText: "Adjust Light",
+            prompt:"Adjust the light and darkness of the photo to make the overall look coordinated",
             specialStyle:0,
             isVip: true,
             unionType: 1,
@@ -327,8 +344,8 @@ extension TSAIListDataVM {
     var ptp_Recreate:[String:Any]{
         [
             imageName: "ptp_style_Recreate",
-           imageText: "Recreate",
-           prompt:"Recreate damaged portraits and added suitable color for photo",
+            imageText: "Recreate",
+            prompt:"Recreate damaged portraits and added suitable color for photo",
             isVip: false,
             unionType: 1,
             model:kie
@@ -338,11 +355,11 @@ extension TSAIListDataVM {
     var ptp_PortraitFusion:[String:Any]{
         [
             imageName: "alistHome_0_PortraitFusion",
-           imageText: "Portrait Fusion",
-           prompt:"Merge two input images into one realistic group photo. Use only the original people, once each. Choose the background from one of the two input images — do not invent a new one. Maintain natural body positioning, realistic size, consistent lighting and shadows. Final image must look like a real, candid photo with everyone together — no added or duplicated people or animals.",
+            imageText: "Portrait Fusion",
+            prompt:"Merge two input images into one realistic group photo. Use only the original people, once each. Choose the background from one of the two input images — do not invent a new one. Maintain natural body positioning, realistic size, consistent lighting and shadows. Final image must look like a real, candid photo with everyone together — no added or duplicated people or animals.",
             specialStyle:0,
             isVip: true,
-            unionType: 1,
+            unionType: 0,
             model:kie
         ]
     }

+ 8 - 8
TSLiveWallpaper/Business/TSAIListVC/TSAIListVC/VM/TSAIListDataVM.swift

@@ -24,8 +24,8 @@ class TSAIListDataVM {
                                 viewModel: TSDiscoverBaseItemVM(imageNamed: "alistHome_0_PortraitFusion"),
                                 generateModel: TSGenerateModel(json: ptp_PortraitFusion)),
             TSDiscoverItemModel(style: .enhance,
-                                viewModel: TSDiscoverAnimationItemVM(title: "",style: .comparison, imageNameds: ["alistHome_0_PhotoEnhance","alistHome_1_PhotoEnhance"]),
-                                generateModel: TSGenerateModel(json: ptp_PhotoEnhance))
+                                viewModel: TSDiscoverAnimationItemVM(title: "Photo Enhance",style: .comparison, imageNameds: ["alistHome_0_PhotoEnhance","alistHome_1_PhotoEnhance"]),
+                                generateModel: TSGenerateModel(json: ptp_Enhance))
         ]]
         return section
     }()
@@ -37,7 +37,7 @@ class TSAIListDataVM {
         section.items = [[
             TSDiscoverItemModel(style: .recreate,
                                 viewModel: TSDiscoverAnimationItemVM(title: "",style: .comparison, imageNameds: ["alistHome_0_Recreate","alistHome_1_Recreate"]),
-                                generateModel: TSGenerateModel(json: ptp_PortraitFusion)),
+                                generateModel: TSGenerateModel(json: ptp_Recreate)),
             
             TSDiscoverItemModel(style: .descratch,
                                 viewModel: TSDiscoverAnimationItemVM(title: "",style: .comparison, imageNameds: ["alistHome_0_Descratch","alistHome_1_Descratch"]),
@@ -49,11 +49,11 @@ class TSAIListDataVM {
             
             TSDiscoverItemModel(style: .enhance,
                                 viewModel: TSDiscoverAnimationItemVM(title: "",style: .comparison, imageNameds: ["alistHome_0_Enhance","alistHome_1_Enhance"]),
-                                generateModel: TSGenerateModel(json: ptp_PhotoEnhance)),
+                                generateModel: TSGenerateModel(json: ptp_Enhance)),
             
             TSDiscoverItemModel(style: .enlighten,
                                 viewModel: TSDiscoverAnimationItemVM(title: "",style: .comparison, imageNameds: ["alistHome_0_AdjustLight","alistHome_1_AdjustLight"]),
-                                generateModel: TSGenerateModel(json: ptp_Enlighten)),
+                                generateModel: TSGenerateModel(json: ptp_AdjustLight)),
         ]]
         
         return section
@@ -166,9 +166,9 @@ class TSAIListDataVM {
             TSDiscoverItemModel(style: .removeWatermark,
                                 viewModel: TSDiscoverAnimationItemVM(style: .crossDissolve, imageNameds: ["alistHome_0_RemoveWatermark","alistHome_1_RemoveWatermark"]),
                                 generateModel: TSGenerateModel(json: ptp_RemoveWatermark)),
-//            TSDiscoverItemModel(style: .expandPhoto,
-//                                viewModel: TSDiscoverAnimationItemVM(style: .comparison, imageNameds: ["alistHome_0_ExpandPhoto","alistHome_1_ExpandPhoto"]),
-//                                generateModel: TSGenerateModel(json: ptp_AIExpandPhoto)),
+            TSDiscoverItemModel(style: .photoExpand,
+                                viewModel: TSDiscoverBaseItemVM(imageNamed: "alistHome_0_ExpandPhoto"),
+                                generateModel: TSGenerateModel(json: ptp_PhotoExpand)),
         ]]
         return section
     }()

+ 1 - 0
TSLiveWallpaper/Business/TSAIListVC/TSAIListVC/View/TSAILIstBannerCell.swift

@@ -57,6 +57,7 @@ class TSAILIstBannerCell: TSAILIstBaseCell {
         
         return pagerView
     }()
+
     
     override func upDateModel() {
         if let models = items as? [TSDiscoverItemModel] {

+ 4 - 0
TSLiveWallpaper/Business/TSAIListVC/TSAIListVC/View/TSAILIstCell.swift

@@ -7,6 +7,10 @@
 
 class TSAILIstBaseCell: TSBaseCollectionCell {
     var clickBlock:((TSDiscoverItemModel)->Void)?
+    
+    /// 点击特殊事件
+    var clickSpecialBlock:((String,Any?)->Void)?
+    
     var items:Any? {
         didSet {
             upDateModel()

+ 4 - 1
TSLiveWallpaper/Business/TSAIListVC/TSAIListVC/View/TSAILIstStyleMoreCell.swift

@@ -15,7 +15,10 @@ class TSAILIstStyleMoreCell : TSAILIstBaseCell {
     }()
     
     lazy var styleMoreVC: TSAIListStyleMoreVC = {
-        let styleMoreVC = TSAIListStyleMoreVC(titleString: "", models: [], layout: layout, clickBlock: clickBlock)
+        let styleMoreVC = TSAIListStyleMoreVC(titleString: "", models: [], layout: layout) { [weak self] model in
+            guard let self = self else { return }
+            clickBlock?(model)
+        }
         return styleMoreVC
     }()
     

+ 10 - 0
TSLiveWallpaper/Business/TSAIListVC/TSAIPhotoGeneratorVC/Model/TSAIListPhotoGeneratorModel.swift

@@ -59,3 +59,13 @@ class TSGenerateModel: TSBaseModel {
     }
     
 }
+
+
+class TSGenerateStyleModel: TSGenerateModel {
+    var clickType:Int = 0 //0 无响应, 1空类型 2.换图
+    override func mapping(map: ObjectMapper.Map) {
+        super.mapping(map: map)
+        clickType               <- map["clickType"]
+    }
+    var isSelected: Bool = false    //改风格,是否被选中
+}

+ 2 - 2
TSLiveWallpaper/Business/TSAIListVC/TSAIPhotoGeneratorVC/TSAIListPhotoGeneratorVC.swift

@@ -7,12 +7,11 @@
 
 import Kingfisher
 class TSAIListPhotoGeneratorVC: TSAIPhotoDetailsVC {
-    var generatorModel:TSAIListPhotoGeneratorModel
     init(generatorModel:TSAIListPhotoGeneratorModel,infoModel:TSActionInfoModel? = nil,complete:@escaping ((TSActionInfoModel)->Void)) {
         self.complete = complete
-        self.generatorModel = generatorModel
         super.init()
         self.infoModel = infoModel
+        self.generatorModel = generatorModel
     }
     @MainActor required init?(coder: NSCoder) {
         fatalError("init(coder:) has not been implemented")
@@ -74,6 +73,7 @@ class TSAIListPhotoGeneratorVC: TSAIPhotoDetailsVC {
     @objc func clickBackstageBtn() {
         self.operation?.backstageGeneration()
         NotificationCenter.default.post(name: .kAIPhotoDataChanged, object: nil)
+        NotificationCenter.default.post(name: .kGenerateoBackStage, object: nil)
         backstageBlock?()
         self.dismiss(animated: true, completion: nil)
     }

+ 0 - 0
TSLiveWallpaper/Business/TSAIListVC/TSAIPhotoDetailsVC/TSAIPhotoDetailsVC/TSAIPhotoDetailsVC+Comparison.swift → TSLiveWallpaper/Business/TSAIListVC/TSAIPhotoGeneratorVC/TSAIPhotoDetailsVC/TSAIPhotoDetailsVC+Comparison.swift


+ 67 - 0
TSLiveWallpaper/Business/TSAIListVC/TSAIPhotoGeneratorVC/TSAIPhotoDetailsVC/TSAIPhotoDetailsVC+Expand.swift

@@ -0,0 +1,67 @@
+//
+//  TSAIPhotoDetailsVC+Expand.swift
+//  TSLiveWallpaper
+//
+//  Created by 100Years on 2025/7/28.
+//
+
+//图片扩展
+extension TSAIPhotoDetailsVC {
+    func creatSwitchOriginalPictureBtn() -> TSUIExpandedTouchButton {
+        let switchOriginalPictureBtn = TSUIExpandedTouchButton()
+        switchOriginalPictureBtn.setUpButton(image:UIImage(named: "switch_original_picture"))
+        switchOriginalPictureBtn.addTarget(self, action: #selector(switchOriginalPictureTouchDown), for: .touchDown)
+        switchOriginalPictureBtn.addTarget(self, action: #selector(switchOriginalPictureTouchUp), for: [.touchUpInside, .touchUpOutside, .touchCancel])
+        switchOriginalPictureBtn.isHidden = false
+        return switchOriginalPictureBtn
+    }
+    
+    @objc func switchOriginalPictureTouchDown() {
+        expandAreaView.onlyBgImage(only: false)
+    }
+    
+    @objc func switchOriginalPictureTouchUp() {
+        expandAreaView.onlyBgImage(only: true)
+    }
+}
+
+extension TSAIPhotoDetailsVC {
+    
+    func setExpandAreaImage(){
+        guard let infoModel = infoModel else { return }
+        netWorkImageView.image = nil
+        
+        if expandAreaView.superview == nil {
+            setUpExpandAreaView()
+        }
+        
+        expandAreaView.bgImageView.setAsyncImage(urlString: infoModel.response.resultUrl)
+        expandAreaView.showImageView.setAsyncImage(urlString: infoModel.request.imageUrl)
+    }
+    
+    
+    func setUpExpandAreaView(){
+        self.panComparisonView.isHidden = true
+        self.contentView.insertSubview(self.expandAreaView, at: 0)
+        expandAreaView.snp.makeConstraints { make in
+            make.top.leading.trailing.bottom.equalTo(0)
+        }
+        
+        expandAreaView.showImageView.isHidden = true
+        expandAreaView.boardView.isHidden = true
+        
+        if let sizes = self.generatorModel.expandViewSizes {
+            expandAreaView.updateExpandAreaView(width: sizes.0.width, height: sizes.0.height)
+            expandAreaView.updateImageView(width: sizes.1.width, height: sizes.1.height)
+        }
+        
+        //对比按钮
+        contentView.addSubview(switchOriginalPictureBtn)
+        switchOriginalPictureBtn.snp.makeConstraints { make in
+            make.bottom.equalTo(saveBtn.snp.top).offset(-20)
+            make.trailing.equalTo(-16)
+            make.width.equalTo(40)
+            make.height.equalTo(40)
+        }
+    }
+}

+ 1 - 1
TSLiveWallpaper/Business/TSAIListVC/TSAIPhotoDetailsVC/TSAIPhotoDetailsVC/TSAIPhotoDetailsVC+Image.swift → TSLiveWallpaper/Business/TSAIListVC/TSAIPhotoGeneratorVC/TSAIPhotoDetailsVC/TSAIPhotoDetailsVC+Image.swift

@@ -12,7 +12,7 @@ extension TSAIPhotoDetailsVC {
         guard let infoModel = infoModel else { return }
         self.panComparisonView.isHidden = true
         netWorkImageView.removeFromSuperview()
-        contentView.addSubview(netWorkImageView)
+        self.contentView.insertSubview(self.netWorkImageView, at: 0)
         netWorkImageView.snp.makeConstraints { make in
             make.height.equalTo(k_ScreenHeight)
             make.leading.trailing.equalTo(0)

+ 0 - 0
TSLiveWallpaper/Business/TSAIListVC/TSAIPhotoDetailsVC/TSAIPhotoDetailsVC/TSAIPhotoDetailsVC+Video.swift → TSLiveWallpaper/Business/TSAIListVC/TSAIPhotoGeneratorVC/TSAIPhotoDetailsVC/TSAIPhotoDetailsVC+Video.swift


+ 0 - 0
TSLiveWallpaper/Business/TSAIListVC/TSAIPhotoDetailsVC/TSAIPhotoDetailsVC/TSAIPhotoDetailsVC+View.swift → TSLiveWallpaper/Business/TSAIListVC/TSAIPhotoGeneratorVC/TSAIPhotoDetailsVC/TSAIPhotoDetailsVC+View.swift


+ 22 - 15
TSLiveWallpaper/Business/TSAIListVC/TSAIPhotoDetailsVC/TSAIPhotoDetailsVC/TSAIPhotoDetailsVC.swift → TSLiveWallpaper/Business/TSAIListVC/TSAIPhotoGeneratorVC/TSAIPhotoDetailsVC/TSAIPhotoDetailsVC.swift

@@ -7,6 +7,7 @@
 
 class TSAIPhotoDetailsVC: TSBaseVC {
     var deleteBlock:(()->Void)?
+    var generatorModel:TSAIListPhotoGeneratorModel!
     var infoModel:TSActionInfoModel?{
         didSet{
             updateImageView()
@@ -14,18 +15,31 @@ class TSAIPhotoDetailsVC: TSBaseVC {
     }
 
     lazy var bottomViewH = 60+k_Height_safeAreaInsetsBottom()
-    lazy var panComparisonView : TSImageIPanComparisonView = TSImageIPanComparisonView()
-    var videoPlayerVC: TSAIListVideoPlayerVC = TSAIListVideoPlayerVC(videoURL: URL(string: "www.baidu.com")!)
-    lazy var expandAreaView: TSAIExpandChangeView = TSAIExpandChangeView()
-    lazy var netWorkImageView: UIImageView = UIImageView.createImageView()//图片生成
-    
     lazy var shareBtn: TSVerticalButton = creatShareBtn()
     lazy var saveBtn: UIButton = creatSaveBtn()
     var navRightBtn:UIButton = UIButton()
     var isSavePhotoMark:Bool = false
     
+    //拖动对比
+    lazy var panComparisonView : TSImageIPanComparisonView = TSImageIPanComparisonView()
+
+    
+    //图片延伸
+    lazy var expandAreaView: TSAIExpandChangeView = TSAIExpandChangeView()
+    lazy var switchOriginalPictureBtn: TSUIExpandedTouchButton = creatSwitchOriginalPictureBtn()//新旧对比切换按钮
+
+    
+    //普通的单张图片
+    lazy var netWorkImageView: UIImageView = UIImageView.createImageView()//图片生成
+    
+
+    
+    //视频
     lazy var videoBlurEffect: UIVisualEffectView = createBlurEffectView(style: .dark)
     lazy var unlockVipBtn: UIButton = creatUnlockVipBtn()
+    var videoPlayerVC: TSAIListVideoPlayerVC = TSAIListVideoPlayerVC(videoURL: URL(string: "www.baidu.com")!)
+    
+
     
     override func createView() {
         
@@ -60,15 +74,6 @@ class TSAIPhotoDetailsVC: TSBaseVC {
             make.height.equalTo(48)
             make.bottom.equalTo(bottomBtnTop)
         }
-        
-//        contentView.addSubview(switchOriginalPictureBtn)
-//        switchOriginalPictureBtn.snp.makeConstraints { make in
-//            make.bottom.equalTo(-k_Height_safeAreaInsetsBottom() - 76)
-//            make.trailing.equalTo(-16)
-//            make.width.equalTo(40)
-//            make.height.equalTo(40)
-//        }
-
     }
     
     //分享功能
@@ -158,7 +163,9 @@ extension TSAIPhotoDetailsVC {
     func updateImageView(){
         kMainAsync {
             guard let infoModel = self.infoModel else { return }
-            if infoModel.isVideo {
+            if infoModel.isPhotoExpand {
+                self.setExpandAreaImage()
+            }else if infoModel.isVideo {
                 self.setVideoURL()
             }else if infoModel.isShowSingleImage{
                 self.updateNetWorkImageView()

+ 0 - 1
TSLiveWallpaper/Business/TSAIListVC/TSAIUploadPhotoVC/TSAIRemovePhotlVC/TSAIRemovePhotlVC.swift

@@ -437,7 +437,6 @@ class TSAIRemovePhotlVC: TSAIUploadPhotoVC {
         let gennerateVC = TSAIListPhotoGeneratorVC(generatorModel:generatorModel){ model in }
         gennerateVC.backstageBlock = { [weak self]  in
             guard let self = self else { return }
-            TSAIListHistoryVC.showPosition()
             self.navigationController?.popToRootViewController(animated: false)
         }
         kPresentModalVC(target: self, modelVC: gennerateVC,transitionStyle: .crossDissolve)

+ 0 - 34
TSLiveWallpaper/Business/TSAIListVC/TSAIUploadPhotoVC/TSAIUploadPhotoVC+Remove.swift

@@ -1,34 +0,0 @@
-//
-//  TSAIUploadPhotoVC+Remove.swift
-//  TSLiveWallpaper
-//
-//  Created by 100Years on 2025/7/2.
-//
-
-//extension TSAIUploadPhotoVC {
-//    
-//    func creatRemoveView() -> UIView {
-//        let textView = TSAIUploadPhotoTextView()
-//        textView.placeholderTextView.textViewTextChanged = { [weak self] text in
-//            guard let self = self else { return }
-//            additionalPrompt = text
-//        }
-//        return textView
-//    }
-//    
-//}
-//
-//extension TSAIUploadPhotoVC {
-//    func setUpRemoveUploadView(){
-//        let spaceH = 176.0
-//        uploadImageViewMaxHeight = k_ScreenHeight-spaceH-k_Height_safeAreaInsetsBottom()-k_Nav_Height
-//        
-//        cusStackView.addSubviewToStack(uploadImageBgView)
-//        uploadImageBgView.snp.makeConstraints { make in
-//            make.width.equalTo(k_ScreenWidth)
-//            make.height.equalTo(k_ScreenHeight-spaceH-k_Height_safeAreaInsetsBottom()-k_Nav_Height)
-//        }
-//        cusStackView.addSpacing(length: 32)
-//        cusStackView.addSubviewToStack(self.textView)
-//    }
-//}

+ 48 - 0
TSLiveWallpaper/Business/TSAIListVC/TSAIUploadPhotoVC/TSAIUploadPhotoVC+Style.swift

@@ -0,0 +1,48 @@
+//
+//  TSAIUploadPhotoVC+Style.swift
+//  TSLiveWallpaper
+//
+//  Created by 100Years on 2025/7/2.
+
+
+extension TSAIUploadPhotoVC {
+    
+    func creatMoreStyleBarView() -> TSAIUploadPhotoMoreStyleBarView {
+        let styleBarView = TSAIUploadPhotoMoreStyleBarView()
+        styleBarView.selsetedBlock = { [weak self] model in
+            guard let self = self else { return }
+            generateModel = model
+        }
+        return styleBarView
+    }
+    
+    func getStyleArray() -> [TSGenerateModel] {
+        if let generateModel = generateModel {
+            if let array = TSAIListDataVM.shared.unionTypeDict[generateModel.unionType] {
+                return array
+            }
+        }
+        return []
+    }
+    
+}
+
+extension TSAIUploadPhotoVC {
+    func setUpMoreStyleBarView(styleModels:[TSGenerateModel]){
+        let spaceH = 176.0
+        uploadImageViewMaxHeight = k_ScreenHeight-spaceH-k_Height_safeAreaInsetsBottom()-k_Nav_Height
+        
+        cusStackView.addSubviewToStack(uploadImageBgView)
+        uploadImageBgView.snp.makeConstraints { make in
+            make.width.equalTo(k_ScreenWidth)
+            make.height.equalTo(k_ScreenHeight-spaceH-k_Height_safeAreaInsetsBottom()-k_Nav_Height)
+        }
+        cusStackView.addSpacing(length: 14)
+        
+        self.styleBarView.modelArray = styleModels
+        self.styleBarView.selectedIndex = styleModels.firstIndex(where: {$0.imageText == generateModel!.imageText}) ?? 0
+        self.generateModel = styleModels.safeObj(At: self.styleBarView.selectedIndex)
+        cusStackView.addSubviewToStack(self.styleBarView)
+
+    }
+}

+ 1 - 1
TSLiveWallpaper/Business/TSAIListVC/TSAIUploadPhotoVC/TSAIUploadPhotoVC+View.swift

@@ -78,7 +78,7 @@ extension TSAIUploadPhotoVC {
 extension TSAIUploadPhotoVC {
     
     func creatSubmitBtn() -> UIButton {
-        let submitBtn = kCreateNormalSubmitBtn(title: generatorStyle.generatorBtnTitle) { [weak self]  in
+        let submitBtn = kCreateNormalSubmitBtn(title: "Generate".localized /*generatorStyle.generatorBtnTitle*/ ) { [weak self]  in
             guard let self = self else { return }
             generateImage()
         }

+ 12 - 29
TSLiveWallpaper/Business/TSAIListVC/TSAIUploadPhotoVC/TSAIUploadPhotoVC.swift

@@ -12,11 +12,13 @@ class TSAIUploadPhotoVC: TSBaseVC {
     var generatorStyle:TSGeneratorImageStyle
     var titleString:String
     var disCoverItemModel:TSDiscoverItemModel?
+    var generateModel:TSGenerateModel?
     init(titleString:String,upLoadImage:UIImage,generatorStyle:TSGeneratorImageStyle,disCoverItemModel:TSDiscoverItemModel? = nil) {
         self.titleString = titleString
         self.upLoadImage = upLoadImage
         self.generatorStyle = generatorStyle
         self.disCoverItemModel = disCoverItemModel
+        self.generateModel = disCoverItemModel?.generateModel
         super.init()
     }
     
@@ -42,7 +44,8 @@ class TSAIUploadPhotoVC: TSBaseVC {
     //###### 视频区域 ######
     lazy var textView: TSAIUploadPhotoTextView = creatTextView()
     
-
+    //更多样式区域
+    lazy var styleBarView: TSAIUploadPhotoMoreStyleBarView = creatMoreStyleBarView()
 
     //###### 数据区 ######
     var uploadImageViewMaxHeight:CGFloat = k_ScreenHeight-76-k_Height_safeAreaInsetsBottom()-k_Nav_Height
@@ -76,7 +79,9 @@ class TSAIUploadPhotoVC: TSBaseVC {
         addNormalNavBarView()
         setPageTitle(titleString)
         _ = setNavigationItem("", imageName: "replace_photo", direction: .right, action: #selector(clickNavRight))
-        view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(clickView)))
+        let tap = UITapGestureRecognizer(target: self, action: #selector(clickView))
+        tap.cancelsTouchesInView = false
+        view.addGestureRecognizer(tap)
         
         contentView.addSubview(submitBtn)
         submitBtn.snp.makeConstraints { make in
@@ -99,12 +104,7 @@ class TSAIUploadPhotoVC: TSBaseVC {
         upLoadImage = image
     }
 
-    
     override func dealThings() {
-        // 监听键盘事件
-        NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(_:)), name: UIResponder.keyboardWillShowNotification, object: nil)
-        NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(_:)), name: UIResponder.keyboardWillHideNotification, object: nil)
-        
         NotificationCenter.default.addObserver(self, selector: #selector(updateVipView), name: .kPurchaseDidChanged, object: nil)
         updateVipView()
     
@@ -115,9 +115,11 @@ class TSAIUploadPhotoVC: TSBaseVC {
             kSetBtnVipIcon(btn: self.submitBtn, show: kPurchaseBusiness.generateVipShow(type: self.generatorStyle == .creatVideo ? .generalVideo :.general))
         }
     }
-    
     func setUpStackView(){
-        if generatorStyle == .creatVideo {
+        let styleModels = getStyleArray()
+        if styleModels.count > 0 {
+            setUpMoreStyleBarView(styleModels: styleModels)
+        }else if generatorStyle == .creatVideo {
             setUpVideoUploadView()
         }else{
             setUpImageUploadView()
@@ -150,7 +152,7 @@ class TSAIUploadPhotoVC: TSBaseVC {
         guard let upLoadImage = upLoadImage else { return }
         let generatorModel = TSAIListPhotoGeneratorModel(upLoadImage: upLoadImage, generatorStyle: generatorStyle,additionalPrompt: additionalPrompt)
 
-        if let generateModel = disCoverItemModel?.generateModel{
+        if let generateModel = generateModel{
             generatorModel.prompt = generateModel.prompt + additionalPrompt
             generatorModel.model = generateModel.model
         }else{
@@ -167,7 +169,6 @@ class TSAIUploadPhotoVC: TSBaseVC {
         
         gennerateVC.backstageBlock = { [weak self]  in
             guard let self = self else { return }
-            TSAIListHistoryVC.showPosition()
             self.navigationController?.popToRootViewController(animated: false)
         }
         kPresentModalVC(target: self, modelVC: gennerateVC,transitionStyle: .crossDissolve)
@@ -211,21 +212,3 @@ extension TSAIUploadPhotoVC {
     }
 
 }
-
-extension TSAIUploadPhotoVC {
-    @objc func keyboardWillShow(_ notification: Notification) {
-        guard let keyboardFrame = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect else { return }
-        let scrollView = cusStackView.scrollView
-        let keyboardHeight = keyboardFrame.height - view.safeAreaInsets.bottom
-//        let textViewFrame = scrollView.convert(customTextView.frame, from: customTextView.superview)
-//        let scrollDistance = textViewFrame.maxY - (scrollView.bounds.height - keyboardHeight)
-        let y = keyboardHeight//(scrollView.bounds.height - keyboardHeight)
-        scrollView.setContentOffset(CGPoint(x: 0, y: y), animated: true)
-    }
-
-    // MARK: - 键盘隐藏时恢复
-
-    @objc private func keyboardWillHide(_ notification: Notification) {
-        cusStackView.scrollView.contentOffset = CGPoint(x: 0, y: 0)
-    }
-}

+ 114 - 0
TSLiveWallpaper/Business/TSAIListVC/TSAIUploadPhotoVC/View/TSAIUploadPhotoMoreStyleBarView.swift

@@ -0,0 +1,114 @@
+//
+//  TSAIUploadPhotoMoreStyleBarView.swift
+//  TSLiveWallpaper
+//
+//  Created by 100Years on 2025/7/24.
+//
+
+class TSAIUploadPhotoMoreStyleBarView : TSBaseView {
+    var selsetedBlock:((TSGenerateModel)->Void)?
+    var modelArray:[TSGenerateModel] = []{
+        didSet{
+            let itemW = (k_ScreenWidth - 32)/CGFloat(modelArray.count)
+            layout.itemSize = CGSize(width: itemW, height: 88)
+            collectionView.reloadData()
+        }
+    }
+    
+    var selectedIndex:Int = 0{
+        didSet{
+            collectionView.selectItem(at: IndexPath(item: selectedIndex, section: 0), animated: true, scrollPosition: .centeredHorizontally)
+        }
+    }
+    
+    lazy var layout: TSBaseCollectionViewFlowLayout = {
+        let layout = TSBaseCollectionViewFlowLayout()
+        layout.scrollDirection = .horizontal
+        layout.minimumLineSpacing = 0
+        layout.minimumInteritemSpacing = 0
+        return layout
+    }()
+    lazy var collectionView: TSBaseCollectionView = {
+        let collectionView = TSBaseCollectionView(frame: .zero, collectionViewLayout: layout)
+        collectionView.delegate = self
+        collectionView.dataSource = self
+        collectionView.register(TSAIUploadPhotoMoreStyleBarViewCell.self, forCellWithReuseIdentifier: "TSAIUploadPhotoMoreStyleBarViewCell")
+        collectionView.contentInset = UIEdgeInsets(top: 0, left: 16, bottom: 0, right: 16)
+        return collectionView
+    }()
+
+    override func creatUI() {
+        contentView.addSubview(collectionView)
+        collectionView.snp.makeConstraints { make in
+            make.edges.equalToSuperview()
+            make.height.equalTo(100)
+        }
+    }
+}
+extension TSAIUploadPhotoMoreStyleBarView: UICollectionViewDataSource ,UICollectionViewDelegate {
+    public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
+        return modelArray.count
+    }
+    
+    public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
+        if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "TSAIUploadPhotoMoreStyleBarViewCell", for: indexPath) as? TSAIUploadPhotoMoreStyleBarViewCell{
+            cell.model = modelArray.safeObj(At: indexPath.row)
+            return cell
+        }
+        return UICollectionViewCell()
+    }
+
+    public func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
+        if let model = modelArray.safeObj(At: indexPath.row) {
+            selsetedBlock?(model)
+            selectedIndex = indexPath.item
+        }
+    }
+}
+
+
+class TSAIUploadPhotoMoreStyleBarViewCell: TSBaseCollectionCell {
+    var model:TSGenerateModel? {
+        didSet{
+            guard let model = model else { return }
+            imageView.image = UIImage(named: model.imageName)
+            textLabel.text = model.imageText.localized
+        }
+    }
+    
+    override var isSelected: Bool{
+        didSet{
+            textLabel.textColor = isSelected ? .themeColor : .white
+            imageView.layer.borderColor = isSelected ? UIColor.themeColor.cgColor : UIColor.clear.cgColor
+        }
+    }
+
+    lazy var imageView: UIImageView = {
+        let imageView = UIImageView.createImageView(contentMode: .scaleToFill,backgroundColor: .white.withAlphaComponent(0.2))
+        imageView.layer.borderWidth = 1.0
+        return imageView
+    }()
+    
+    lazy var textLabel: UILabel = {
+        let textLabel = UILabel.createLabel(font: .font(size: 10),textColor: .white,textAlignment: .center)
+        return textLabel
+    }()
+
+
+    override func creatUI() {
+        bgContentView.addSubview(imageView)
+        imageView.snp.makeConstraints { make in
+            make.top.equalTo(5)
+            make.width.height.equalTo(40)
+            make.centerX.equalToSuperview()
+        }
+        
+        bgContentView.addSubview(textLabel)
+        textLabel.snp.makeConstraints { make in
+            make.top.equalTo(imageView.snp.bottom).offset(5)
+            make.bottom.equalTo(-4)
+            make.leading.equalTo(2)
+            make.trailing.equalTo(-2)
+        }
+    }
+}

+ 0 - 1
TSLiveWallpaper/Business/TSAIListVC/TSFusionImageVC/TSFusionImageVC.swift

@@ -240,7 +240,6 @@ extension TSFusionImageVC {
         
         gennerateVC.backstageBlock = { [weak self]  in
             guard let self = self else { return }
-            TSAIListHistoryVC.showPosition()
             self.navigationController?.popToRootViewController(animated: false)
         }
         kPresentModalVC(target: self, modelVC: gennerateVC,transitionStyle: .crossDissolve)

+ 267 - 0
TSLiveWallpaper/Business/TSAIListVC/TSSelectedPhotoStyleVC/TSSelectedPhotoStyleVC.swift

@@ -0,0 +1,267 @@
+//
+//  TSSelectedPhotoStyleVC.swift
+//  TSLiveWallpaper
+//
+//  Created by 100Years on 2025/7/24.
+//
+
+class TSSelectedPhotoStyleVC: TSBaseVC {
+    
+    var maxSelected:Int
+    var complete:(Int)->Void
+    init(maxSelected: Int,complete: @escaping (Int)->Void) {
+        self.maxSelected = maxSelected
+        self.complete = complete
+        super.init()
+    }
+    
+    @MainActor required init?(coder: NSCoder) {
+        fatalError("init(coder:) has not been implemented")
+    }
+    
+    
+    lazy var minvc = TSMineVC()
+    lazy var photoPickerManager: TSPhotoPickerManager = {
+        let photoPickerManager = TSPhotoPickerManager(viewController: self)
+        return photoPickerManager
+    }()
+    
+    lazy var dataArray: [TSBasicSectionModel] = {
+        var dataArray = [TSBasicSectionModel]()
+        let sectionModel = TSBasicSectionModel()
+        dataArray.append(sectionModel)
+
+        sectionModel.addSubItemModel(
+            createItemModel(
+                leftImage: .selectedPhotoStylePhoto,
+            leftTitle: "Choose from Photo".localized,
+            tapBlock: { [weak self] _, _, _ in
+                guard let self = self else { return }
+                complete(0)
+            })
+        )
+        
+        sectionModel.addSubItemModel(
+            createItemModel(
+                leftImage: .selectedPhotoStyleCamera,
+            leftTitle: "Take a Photo".localized,
+            tapBlock: { [weak self] _, _, _ in
+                guard let self = self else { return }
+                complete(1)
+            })
+        )
+        
+        sectionModel.addSubItemModel(
+            createItemModel(
+                leftImage: .selectedPhotoStyleOldPhoto,
+            leftTitle: "Used Photo".localized,
+            tapBlock: { [weak self] _, _, _ in
+                guard let self = self else { return }
+                complete(2)
+            })
+        )
+
+        return dataArray
+    }()
+    
+    
+    lazy var simpleTableView: TSSimpleTableView = {
+        let simpleTableView = TSSimpleTableView()
+        simpleTableView.reuseClass = ["TSSelectedPhotoStyleCell"]
+        simpleTableView.dataArray = dataArray
+        return simpleTableView
+    }()
+    
+    override func createView() {
+        setNavBarViewHidden(true)
+        view.backgroundColor = .black.withAlphaComponent(0.6)
+        view.addTapAction { [weak self]  in
+            self?.dismiss()
+        }
+        
+        let bottomView = UIView()
+        bottomView.backgroundColor = .alert
+        contentView.addSubview(bottomView)
+    
+        bottomView.snp.makeConstraints { make in
+            make.leading.trailing.bottom.equalToSuperview()
+        }
+        
+        let colseBtn = TSUIExpandedTouchButton()
+        colseBtn.setUpButton(image:.closeGary){ [weak self]  in
+            guard let self = self else { return }
+            self.dismiss()
+        }
+        
+        bottomView.addSubview(colseBtn)
+        colseBtn.snp.makeConstraints { make in
+            make.width.height.equalTo(16)
+            make.top.equalTo(12)
+            make.trailing.equalTo(-12)
+        }
+        
+        
+        bottomView.addSubview(simpleTableView.tableView)
+        simpleTableView.tableView.snp.makeConstraints { make in
+            make.leading.equalTo(16)
+            make.trailing.equalTo(-16)
+            make.top.equalTo(44)
+            make.bottom.equalTo(-15-k_Height_safeAreaInsetsBottom())
+            make.height.equalTo(dataArray.first!.itemsArray.count*80)
+        }
+    }
+
+    func createItemModel(
+        leftImage:UIImage,
+        leftTitle: String,
+        height: CGFloat = 80,
+        tapBlock: @escaping ((TSBasicItemModel, Int, Any?) -> Void))
+    -> TSBasicItemModel
+    {
+        let model = TSBasicItemModel()
+        model.leftImage = leftImage
+        model.leftTitle = leftTitle
+        model.height = height
+        model.tapBlock = tapBlock
+        return model
+    }
+}
+
+class TSSelectedPhotoStyleCell: TSSimpleTableViewCell {
+
+    lazy var leftImageView: UIImageView = {
+        return UIImageView()
+    }()
+    
+    lazy var leftLab: UILabel = {
+        return UILabel.createLabel(font: .font(name:.ZillaSlab,size: 16),textColor: .white)
+    }()
+
+    override var itemModel:TSBasicItemModel{
+        didSet{
+            leftImageView.image = itemModel.leftImage
+            leftLab.text = itemModel.leftTitle
+        }
+    }
+    
+    override func creatUI() {
+        bgContentView.snp.updateConstraints { make in
+            make.bottom.equalTo(-16)
+        }
+        bgContentView.backgroundColor = .white.withAlphaComponent(0.1)
+        bgContentView.addSubview(leftImageView)
+        bgContentView.addSubview(leftLab)
+
+        leftImageView.snp.makeConstraints { make in
+            make.leading.equalTo(16)
+            make.centerY.equalToSuperview()
+            make.width.height.equalTo(24)
+        }
+        
+        leftLab.snp.makeConstraints { make in
+            make.leading.equalTo(leftImageView.snp.trailing).offset(12)
+            make.centerY.equalToSuperview()
+        }
+        
+    }
+    
+    deinit {
+        dePrint("TSSelectedPhotoStyleVC")
+    }
+
+}
+
+
+
+import UIKit
+
+// MARK: - 动画控制器
+private class CrossDissolveAnimator: NSObject, UIViewControllerAnimatedTransitioning {
+    func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
+        return 0.35
+    }
+    
+    func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
+        guard let toVC = transitionContext.viewController(forKey: .to) else {
+            transitionContext.completeTransition(false)
+            return
+        }
+        
+        let containerView = transitionContext.containerView
+        toVC.view.alpha = 0
+        containerView.addSubview(toVC.view)
+        
+        UIView.animate(withDuration: transitionDuration(using: transitionContext), animations: {
+            toVC.view.alpha = 1
+        }) { finished in
+            transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
+        }
+    }
+}
+
+// MARK: - 封装方法
+extension UINavigationController {
+    /// Push 转场时使用淡入淡出效果
+    /// - Parameters:
+    ///   - viewController: 要push的视图控制器
+    ///   - animated: 是否使用动画
+    func pushViewControllerWithCrossDissolve(_ viewController: UIViewController, animated: Bool = true) {
+        let originalDelegate = self.delegate
+        let transitionDelegate = NavigationControllerTransitionDelegate(originalDelegate: originalDelegate)
+        
+        // 临时保存代理
+        objc_setAssociatedObject(self, &AssociatedKeys.transitionDelegate, transitionDelegate, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
+        viewController.hidesBottomBarWhenPushed = true
+        self.delegate = transitionDelegate
+        self.pushViewController(viewController, animated: animated)
+        
+        // 动画完成后恢复原始代理
+        DispatchQueue.main.asyncAfter(deadline: .now() + 0.4) {
+            if self.delegate === transitionDelegate {
+                self.delegate = originalDelegate
+            }
+        }
+    }
+}
+
+// MARK: - 辅助类型
+private class NavigationControllerTransitionDelegate: NSObject, UINavigationControllerDelegate {
+    weak var originalDelegate: UINavigationControllerDelegate?
+    
+    init(originalDelegate: UINavigationControllerDelegate?) {
+        self.originalDelegate = originalDelegate
+    }
+    
+    func navigationController(_ navigationController: UINavigationController,
+                           animationControllerFor operation: UINavigationController.Operation,
+                           from fromVC: UIViewController,
+                           to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
+        // 只对push操作使用淡入淡出效果
+        if operation == .push {
+            return CrossDissolveAnimator()
+        }
+        
+        // 其他操作使用原始代理的处理
+        return originalDelegate?.navigationController?(navigationController,
+                                                     animationControllerFor: operation,
+                                                     from: fromVC,
+                                                     to: toVC)
+    }
+    
+    // 转发其他代理方法给原始代理
+    override func responds(to aSelector: Selector!) -> Bool {
+        return super.responds(to: aSelector) || originalDelegate?.responds(to: aSelector) == true
+    }
+    
+    override func forwardingTarget(for aSelector: Selector!) -> Any? {
+        if originalDelegate?.responds(to: aSelector) == true {
+            return originalDelegate
+        }
+        return super.forwardingTarget(for: aSelector)
+    }
+}
+
+// MARK: - 关联对象键
+private struct AssociatedKeys {
+    static var transitionDelegate = "transitionDelegate"
+}

+ 111 - 0
TSLiveWallpaper/Business/TSAIResultsFrameVC/TSAIResultsFrameVC.swift

@@ -0,0 +1,111 @@
+//
+//  TSAIResultsFrameVC.swift
+//  TSLiveWallpaper
+//
+//  Created by 100Years on 2025/7/22.
+//
+
+
+import JXSegmentedView
+
+class TSAIResultsFrameVC: TSBaseVC {
+
+    //###################################### 导航栏 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()
+        navBarView.barView.addSubview(vipBtn)
+        vipBtn.snp.makeConstraints { make in
+            make.centerY.equalToSuperview()
+            make.trailing.equalTo(-16)
+            make.width.height.equalTo(32)
+        }
+
+       return navBarView
+    }()
+
+    
+    lazy var listContainerView: JXSegmentedListContainerView = {
+        let listContainerView = JXSegmentedListContainerView(dataSource: self)
+        listContainerView.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height: k_ScreenHeight - k_Nav_Height)
+        return listContainerView
+    }()
+
+    lazy var segmentedDataSource: JXSegmentedTitleDataSource = {
+        let dataSource = JXSegmentedTitleDataSource()
+        dataSource.isTitleColorGradientEnabled = true
+        dataSource.itemSpacing = 20
+        dataSource.isItemSpacingAverageEnabled = false
+        dataSource.titles = ["Results".localized, "Used Photo".localized]
+        dataSource.titleNormalColor = .white.withAlphaComponent(0.4)
+        dataSource.titleSelectedColor = .white
+        dataSource.titleNormalFont = .font(name:.ZillaSlab,size: 24)
+        return dataSource
+    }()
+    
+    lazy var segmentedView: JXSegmentedView = {
+        let segmentedView = JXSegmentedView(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height: 44.0))
+        segmentedView.delegate = self
+        segmentedView.dataSource = segmentedDataSource
+        segmentedView.backgroundColor = .clear
+//        segmentedView.contentEdgeInsetLeft = 16
+        segmentedView.listContainer = listContainerView
+        return segmentedView
+    }()
+ 
+    
+   lazy var viewControllers: [UIViewController] = {
+       return [TSAIListHistoryVC(), TSAIUsedPhotoVC()]
+   }()
+       
+
+    override func createView() {
+        addNormalNavBarView()
+        navBarContentView.addSubview(navBarView)
+        navBarView.snp.makeConstraints { make in
+            make.edges.equalToSuperview()
+        }
+        
+        navBarView.barView.addSubview(segmentedView)
+        contentView.addSubview(listContainerView)
+    }
+    
+    override func dealThings() {
+        NotificationCenter.default.addObserver(forName: .kGenerateoBackStage, object: nil, queue: .main) { [weak self] _ in
+            guard let self = self else { return }
+            AppDelegate.tabbar?.changeSelectedIndex(index: 1)
+            segmentedView.selectItemAt(index: 0)
+        }
+    }
+}
+
+extension TSAIResultsFrameVC: JXSegmentedViewDelegate {
+    func segmentedView(_ segmentedView: JXSegmentedView, didSelectedItemAt index: Int) {
+        self.navigationController?.interactivePopGestureRecognizer?.isEnabled = (index == 0)
+    }
+}
+
+extension TSAIResultsFrameVC: JXSegmentedListContainerViewDataSource {
+    func numberOfLists(in listContainerView: JXSegmentedListContainerView) -> Int {
+        return viewControllers.count
+    }
+
+    func listContainerView(_ listContainerView: JXSegmentedListContainerView, initListAt index: Int) -> JXSegmentedListContainerViewListDelegate {
+        return viewControllers[index] as! JXSegmentedListContainerViewListDelegate
+    }
+}
+
+extension TSAIResultsFrameVC:TSTabBarControllerProtocol {
+    func tabBarDoubleTap(_ tabbar: UITabBarController){
+        if let vc = viewControllers[segmentedView.selectedIndex] as? TSTabBarControllerProtocol {
+            vc.tabBarDoubleTap(tabbar)
+        }
+    }
+}

+ 260 - 0
TSLiveWallpaper/Business/TSAIResultsFrameVC/TSAIUsedPhotoVC/TSAIUsedPhotoVC.swift

@@ -0,0 +1,260 @@
+//
+//  TSAIUsedPhotoVC.swift
+//  TSLiveWallpaper
+//
+//  Created by 100Years on 2025/7/23.
+//
+
+class TSAIUsedPhotoVC: TSBaseVC {
+
+    var listImageKeylArray:[String] = []
+    
+    
+    
+    var isShowtips:Bool{
+        set{
+            UserDefaults.standard.set(newValue ? nil : "1", forKey: "TSAIUsedPhotoVCIsShowtips")
+            UserDefaults.standard.synchronize()
+        }
+        get{
+            return UserDefaults.standard.string(forKey: "TSAIUsedPhotoVCIsShowtips") == nil
+        }
+    }
+    
+    //###################################### 集合视图 ######################################
+    let collectionViewBtootm:CGFloat = 80
+
+    let identifier = "TSAIUsedPhotoVCCell"
+    lazy var collectionView: UICollectionView = {
+        let layout = UICollectionViewFlowLayout()
+        layout.scrollDirection = .vertical
+        
+        let itemW = (k_ScreenWidth-32.0-13.0-2.0)/2.0
+        let itemH = kGetScaleHeight(originalSize: CGSize(width: 165.0, height: 220.0), width: itemW)
+
+        layout.itemSize = CGSize(width: itemW, height: itemH)
+        layout.minimumInteritemSpacing = 13
+        layout.minimumLineSpacing = 16
+        layout.sectionInset = UIEdgeInsets(top: 10, left: 16, bottom: k_Height_TabBar+20, right: 16)
+        
+        let collectionView = TSBaseCollectionView(frame: .zero, collectionViewLayout: layout)
+        collectionView.delegate = self
+        collectionView.dataSource = self
+        collectionView.register(TSAIUsedPhotoVCCell.self, forCellWithReuseIdentifier: identifier)
+        return collectionView
+    }()
+    
+    lazy var pageNullView: TSPageNullView = {
+        let pageNullView = TSPageNullView()
+        pageNullView.isHidden = true
+        return pageNullView
+    }()
+    
+    
+    lazy var tipsView: UIView = {
+        
+        let tipsView = UIView()
+        tipsView.backgroundColor = .white.withAlphaComponent(0.1)
+        let imageView = UIImageView.createImageView(image:.tips)
+        tipsView.addSubview(imageView)
+        
+        let lab = UILabel.createLabel(text: "The photos are stored locally for your convenience to use them anytime".localized,font: .font(size: 14),textColor: .white.withAlphaComponent(0.7))
+        tipsView.addSubview(lab)
+        
+        let closeBtn = TSUIExpandedTouchButton()
+        closeBtn.setUpButton(image: .closeGary){ [weak self]  in
+            guard let self = self else { return }
+            isShowtips = false
+            setUpShowtips()
+        }
+        tipsView.addSubview(closeBtn)
+        
+        imageView.snp.makeConstraints { make in
+            make.width.height.equalTo(16)
+            make.leading.equalTo(8)
+            make.top.equalTo(12)
+        }
+        
+        lab.snp.makeConstraints { make in
+            make.leading.equalTo(32)
+            make.trailing.equalTo(-8)
+            make.top.equalTo(12)
+            make.bottom.equalTo(-12)
+        }
+
+        closeBtn.snp.makeConstraints { make in
+            make.trailing.equalTo(-4)
+            make.top.equalTo(4)
+            make.width.height.equalTo(12)
+        }
+        
+        return tipsView
+    }()
+    
+    override func createView() {
+        setNavBarViewHidden(true)
+        
+        contentView.addSubview(pageNullView)
+        contentView.addSubview(collectionView)
+        collectionView.snp.makeConstraints { make in
+            make.top.bottom.leading.trailing.equalTo(0)
+        }
+
+        setUpShowtips()
+    }
+    
+    
+    override func dealThings() {
+        updateDataView()
+    }
+    
+    @objc func updateDataView(){
+        listImageKeylArray = TSDBKeyManager.getAllKeyStringArray()
+        updateView()
+    }
+    
+
+    func updateView() {
+        collectionView.reloadData()
+        pageNullView.isHidden = listImageKeylArray.count > 0
+    }
+    
+    override func viewWillAppear(_ animated: Bool) {
+        super.viewWillAppear(animated)
+    }
+    
+    
+    func setUpShowtips(){
+        if isShowtips,tipsView.superview == nil {
+            contentView.addSubview(tipsView)
+            tipsView.snp.remakeConstraints{ make in
+                make.leading.equalTo(16)
+                make.trailing.equalTo(-16)
+                make.top.equalTo(16)
+            }
+            
+            collectionView.snp.remakeConstraints{ make in
+                make.top.equalTo(tipsView.snp.bottom)
+                make.bottom.leading.trailing.equalTo(0)
+            }
+        }else{
+            tipsView.removeFromSuperview()
+            collectionView.snp.remakeConstraints{ make in
+                make.top.bottom.leading.trailing.equalTo(0)
+            }
+        }
+
+    }
+}
+
+extension TSAIUsedPhotoVC: UICollectionViewDataSource ,UICollectionViewDelegate {
+    
+
+    public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
+        return listImageKeylArray.count
+    }
+    
+    public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
+        
+        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: identifier, for: indexPath)
+        if let cell = cell as? TSAIUsedPhotoVCCell ,let keyString = listImageKeylArray.safeObj(At:indexPath.row){
+            cell.keyString = keyString
+            cell.buttonTapped = { [weak self] cmd in
+                self?.handelCellCmd(cmd: cmd,indexPath: indexPath)
+            }
+        }
+        
+        return cell
+    }
+
+    public func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
+        
+        if kShowGenerateBusyView(view: WindowHelper.getCurrentWindow() ?? self.view) { return }
+        
+        if let keyString = listImageKeylArray.safeObj(At:indexPath.row){
+            TSImageStoreTool.retrieveImage(urlString: keyString) { [weak self] image in
+                guard let self = self else { return }
+                guard let image = image else { return }
+                let itemModel = TSDiscoverItemModel(style: .colorize,viewModel: TSDiscoverAnimationItemVM(),generateModel: TSGenerateModel(json: TSAIListDataVM.shared.ptp_Colorize))
+                self.push(TSAIUploadPhotoVC(titleString: "",upLoadImage: image, generatorStyle: .colorize,disCoverItemModel: itemModel),animated: true)
+            }
+        }
+    }
+}
+
+
+extension TSAIUsedPhotoVC{
+    func handelCellCmd(cmd:String,indexPath: IndexPath){
+        if let imageKey = listImageKeylArray.safeObj(At: indexPath.item){
+
+            if cmd == "delete" {
+                TSCustomAlertController.show(in: self, config: TSCustomAlertController.AlertConfig(
+                    message: "Are you sure to delete?".localized,
+                    cancelTitle: "Delete".localized,
+                    cancelColor: .red,
+                    confirmTitle: "Retain".localized,
+                    confirmColor: .white,
+                    cancelAction: { [weak self]  in
+                        guard let self = self else { return }
+                        TSDBKeyManager.removeKey(imageKey)
+                        updateDataView()
+                    }
+                ))
+            }
+        }
+    }
+}
+
+extension TSAIUsedPhotoVC:TSTabBarControllerProtocol {
+    func tabBarDoubleTap(_ tabbar: UITabBarController){
+        collectionView.setContentOffset(CGPoint(x: 0, y: 0), animated: true)
+    }
+}
+
+import JXSegmentedView
+extension TSAIUsedPhotoVC: JXSegmentedListContainerViewListDelegate {
+    func listView() -> UIView { return view }
+}
+
+
+
+class TSAIUsedPhotoVCCell: TSBaseCollectionCell {
+    var buttonTapped:((String)->Void)?
+    var operation:TSGenerateBasePhotoOperation?
+    var keyString:String = String(){
+        didSet {
+            TSImageStoreTool.retrieveImage(urlString: keyString) { [weak self] image in
+                guard let self = self else { return }
+                showImageView.image = image
+            }
+        }
+    }
+    
+    lazy var showImageView: UIImageView = {
+        let showImageView = UIImageView.createImageView(imageName:"",contentMode: .scaleAspectFill)
+        showImageView.backgroundColor = .gray
+        return showImageView
+    }()
+
+    @objc func handleLongPress(_ gestureRecognizer: UILongPressGestureRecognizer) {
+        // 确保只在手势开始时触发一次
+        guard gestureRecognizer.state == .began else { return }
+        buttonTapped?("delete")
+    }
+    
+    override func creatUI() {
+        let longPressRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(handleLongPress(_:)))
+        longPressRecognizer.minimumPressDuration = 0.5 // 设置最小长按时间(秒)
+        contentView.addGestureRecognizer(longPressRecognizer)
+        
+        contentView.layer.borderWidth = 3
+        contentView.layer.borderColor = "#DFD7C0".uiCGColor
+   
+        contentView.addSubview(showImageView)
+        showImageView.snp.makeConstraints { make in
+            make.top.equalTo(0)
+            make.leading.equalTo(0)
+            make.trailing.bottom.equalTo(0)
+        }
+    }
+}

+ 2 - 1
TSLiveWallpaper/Business/TSBusinessWebVC/TSBusinessWebVC.swift

@@ -47,6 +47,8 @@ class TSBusinessWebVC: TSBaseVC , WKNavigationDelegate {
         loadURL()
     }
     
+    lazy var styleBarView: TSAIUploadPhotoMoreStyleBarView = TSAIUploadPhotoMoreStyleBarView()
+    
     private func setupWebView() {
         // 初始化 WKWebView
         let webConfiguration = WKWebViewConfiguration()
@@ -57,7 +59,6 @@ class TSBusinessWebVC: TSBaseVC , WKNavigationDelegate {
         webView.snp.makeConstraints { make in
             make.edges.equalToSuperview()
         }
-
     }
 
     private func loadURL() {

+ 1 - 1
TSLiveWallpaper/Business/TSPurchaseMembershipVC/TSPurchaseVC.swift

@@ -304,7 +304,7 @@ struct PurchaseView :View {
                 }
                 
                 HStack(spacing: 8) {
-                    Text("Terms of us".localized)
+                    Text("User Agreement".localized)
                         .onTapGesture {
                             viewModel.termPublisher.send(true)
                         }

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

@@ -51,7 +51,7 @@ class TSTabBarController: UITabBarController {
     @objc private func setUpData() {
         viewControllerArray = [
             "TSAIListVC",
-            "TSAIListHistoryVC",
+            "TSAIResultsFrameVC",
             "TSMineVC"]
         
         selectedImageArray = [
@@ -234,6 +234,8 @@ extension TSTabBarController {
     func setupDoubleTapToScrollTop() {
         let doubleTap = UITapGestureRecognizer(target: self, action: #selector(handleDoubleTap(_:)))
         doubleTap.numberOfTapsRequired = 2
+        doubleTap.delaysTouchesBegan = false  // 默认是true,会延迟单击响应
+        doubleTap.delaysTouchesEnded = false
         tabBar.addGestureRecognizer(doubleTap)
     }
 

+ 11 - 0
TSLiveWallpaper/Common/Ex/Notification+Ex.swift

@@ -0,0 +1,11 @@
+//
+//  Notification+Ex.swift
+//  TSLiveWallpaper
+//
+//  Created by 100Years on 2025/7/27.
+//
+
+public extension Notification.Name {
+    
+    
+}

+ 0 - 1
TSLiveWallpaper/Common/Purchase/TSPurchaseEnum.swift

@@ -97,7 +97,6 @@ public extension Notification.Name {
     static let kPurchasePrepared = Self.init("kPurchaseProductPrepared")
     static let kPurchaseDidChanged = Self.init("kPurchaseDidChanged")
     static let kVipFreeNumChanged = Notification.Name("kVipFreeNumChanged")   //Vip免费次数发生变化
-    
 }
 
 

+ 1 - 1
TSLiveWallpaper/Common/TSConfig.swift

@@ -42,7 +42,7 @@ extension UIColor {
     static let button = UIColor(named: "c_button")!
     
     /// 警示色
-    static let alert = UIColor(named: "c_alert")!
+    static let alert = "#222222".uiColor
     
     /// 主色调
     static let mainGlowing = "#D553FA".toColor()!

+ 1 - 1
TSLiveWallpaper/Common/TSNetWork/TSNetWork+Business.swift

@@ -19,7 +19,7 @@ enum TSNeURLType:String {
     case createVideo = "/api/video/create"               //视频生成
     case imageInpaint = "/api/image/inpaint"             //图片涂抹
     case removeBg = "/api/image/remove-background"       //移除背景
-    
+    case photoExpand = "/api/image/outpaint"          //照片扩展
     
     func getUrlString() -> String {
         if Locale.current.identifier.contains("_CN") {//中国区

+ 195 - 0
TSLiveWallpaper/Common/ViewTool/TSPhotoPickerManager/KFImageView.swift

@@ -0,0 +1,195 @@
+//
+//  KFImageView.swift
+//  TSLiveWallpaper
+//
+//  Created by 100Years on 2025/7/25.
+//
+
+import Kingfisher
+import HXPhotoPicker
+public class KFImageView: AnimatedImageView, HXImageViewProtocol {
+    public func setImageData(_ imageData: Data?) {
+        guard let imageData else { return }
+        let image: KFCrossPlatformImage? = DefaultImageProcessor.default.process(item: .data(imageData), options: .init([]))
+        self.image = image
+    }
+    
+    @discardableResult
+    public func setImage(with resource: ImageDownloadResource, placeholder: UIImage?, options: ImageDownloadOptionsInfo?, progressHandler: ((CGFloat) -> Void)?, completionHandler: ((Result<UIImage, ImageDownloadError>) -> Void)?) -> ImageDownloadTask? {
+        var kfOptions: KingfisherOptionsInfo = []
+        if let options {
+            for option in options {
+                switch option {
+                case .fade(let duration):
+                    kfOptions += [.transition(.fade(duration))]
+                case .imageProcessor(let size):
+                    let imageProcessor = DownsamplingImageProcessor(size: size)
+                    kfOptions += [.processor(imageProcessor)]
+                case .onlyLoadFirstFrame:
+                    kfOptions += [.onlyLoadFirstFrame]
+                case .cacheOriginalImage:
+                    kfOptions += [.cacheOriginalImage]
+                case .memoryCacheExpirationExpired:
+                    kfOptions += [.memoryCacheExpiration(.expired)]
+                case .scaleFactor(let scale):
+                    kfOptions += [.scaleFactor(scale)]
+                }
+            }
+        }
+        let imageResource = Kingfisher.ImageResource(downloadURL: resource.downloadURL, cacheKey: resource.cacheKey)
+        if let indicatorColor = resource.indicatorColor {
+            kf.indicatorType = .activity
+            (kf.indicator?.view as? UIActivityIndicatorView)?.color = indicatorColor
+        }
+        let task = kf.setImage(with: imageResource, placeholder: placeholder, options: kfOptions) { receivedSize, totalSize in
+            progressHandler?(CGFloat(receivedSize) / CGFloat(totalSize))
+        } completionHandler: {
+            switch $0 {
+            case .success(let result):
+                completionHandler?(.success(result.image))
+            case .failure(let error):
+                completionHandler?(.failure(error.isTaskCancelled ? .cancel : .error(error)))
+            }
+        }
+        let downloadTask = ImageDownloadTask {
+            task?.cancel()
+        }
+        return downloadTask
+    }
+    
+    public func setVideoCover(with url: URL, placeholder: UIImage?, completionHandler: ((Result<UIImage, ImageDownloadError>) -> Void)?) -> ImageDownloadTask? {
+        let provider = AVAssetImageDataProvider(assetURL: url, seconds: 0.1)
+        provider.assetImageGenerator.appliesPreferredTrackTransform = true
+        let task = KF.dataProvider(provider)
+            .placeholder(placeholder)
+            .onSuccess { result in
+                completionHandler?(.success(result.image))
+            }
+            .onFailure { error in
+                completionHandler?(.failure(error.isTaskCancelled ? .cancel : .error(error)))
+            }
+            .set(to: self)
+        let downloadTask = ImageDownloadTask {
+            task?.cancel()
+        }
+        return downloadTask
+    }
+    
+    @discardableResult
+    public static func download(with resource: ImageDownloadResource, options: ImageDownloadOptionsInfo?, progressHandler: ((CGFloat) -> Void)?, completionHandler: ((Result<ImageDownloadResult, ImageDownloadError>) -> Void)?) -> ImageDownloadTask? {
+        let key = resource.cacheKey
+        var kfOptions: KingfisherOptionsInfo = []
+        if let options {
+            for option in options {
+                switch option {
+                case .fade(let duration):
+                    kfOptions += [.transition(.fade(duration))]
+                case .imageProcessor(let size):
+                    let imageProcessor = DownsamplingImageProcessor(size: size)
+                    kfOptions += [.processor(imageProcessor)]
+                case .onlyLoadFirstFrame:
+                    kfOptions += [.onlyLoadFirstFrame]
+                case .cacheOriginalImage:
+                    kfOptions += [.cacheOriginalImage]
+                case .memoryCacheExpirationExpired:
+                    kfOptions += [.memoryCacheExpiration(.expired)]
+                case .scaleFactor(let scale):
+                    kfOptions += [.scaleFactor(scale)]
+                }
+            }
+        }
+        if  KingfisherManager.shared.cache.isCached(forKey: key) {
+             KingfisherManager.shared.cache.retrieveImage(
+                forKey: key,
+                options: kfOptions
+            ) { (result) in
+                switch result {
+                case .success(let value):
+                    if let data = value.image?.kf.gifRepresentation() {
+                        completionHandler?(.success(.init(imageData: data)))
+                    }else if let image = value.image {
+                        completionHandler?(.success(.init(image: image)))
+                    }else {
+                        completionHandler?(.failure(.error(nil)))
+                    }
+                case .failure(let error):
+                    completionHandler?(.failure(.error(error)))
+                }
+            }
+            return nil
+        }
+        let task =  ImageDownloader.default.downloadImage(with: resource.downloadURL, options: kfOptions) { receivedSize, totalSize in
+            let progress = CGFloat(receivedSize) / CGFloat(totalSize)
+            progressHandler?(progress)
+        } completionHandler: {
+            switch $0 {
+            case .success(let value):
+                DispatchQueue.global().async {
+                    if let gifImage = DefaultImageProcessor.default.process(
+                        item: .data(value.originalData),
+                        options: .init([])
+                    ) {
+                         KingfisherManager.shared.cache.store(
+                            gifImage,
+                            original: value.originalData,
+                            forKey: key
+                        )
+                        DispatchQueue.main.async {
+                            completionHandler?(.success(.init( imageData: value.originalData)))
+                        }
+                        return
+                    }
+                     KingfisherManager.shared.cache.store(
+                        value.image,
+                        original: value.originalData,
+                        forKey: key
+                    )
+                    DispatchQueue.main.async {
+                        completionHandler?(.success(.init(image: value.image)))
+                    }
+                }
+            case .failure(let error):
+                completionHandler?(.failure(.error(error)))
+            }
+        }
+        let downloadTask = ImageDownloadTask {
+            task?.cancel()
+        }
+        return downloadTask
+    }
+    
+    public func _startAnimating() {
+        startAnimating()
+    }
+    
+    public func _stopAnimating() {
+        stopAnimating()
+    }
+    
+    public static func getCacheKey(forURL url: URL) -> String {
+        url.cacheKey
+    }
+    
+    public static func getCachePath(forKey key: String) -> String {
+         KingfisherManager.shared.cache.cachePath(forKey: key)
+    }
+    
+    public static func isCached(forKey key: String) -> Bool {
+         KingfisherManager.shared.cache.isCached(forKey: key)
+    }
+    
+    public static func getInMemoryCacheImage(forKey key: String) -> UIImage? {
+         KingfisherManager.shared.cache.retrieveImageInMemoryCache(forKey: key)
+    }
+    
+    public static func getCacheImage(forKey key: String, completionHandler: ((UIImage?) -> Void)?) {
+         KingfisherManager.shared.cache.retrieveImage(forKey: key, options: []) {
+            switch $0 {
+            case .success(let result):
+                completionHandler?(result.image)
+            case .failure:
+                completionHandler?(nil)
+            }
+        }
+    }
+}

+ 0 - 51
TSLiveWallpaper/Common/ViewTool/TSPhotoPickerManager/TSHXPhotoPickerManager.swift

@@ -1,51 +0,0 @@
-//
-//  TSHXPhotoPickerManager.swift
-//  TSLiveWallpaper
-//
-//  Created by 100Years on 2025/7/11.
-//
-
-//import HXPhotoPicker
-
-
-
-//let kPhotoPickerManager = TSHXPhotoPickerManager()
-//class TSHXPhotoPickerManager {
-//    private var completionHandler: ((UIImage?) -> Void)!
-//    lazy var config: PickerConfiguration = {
-//        var config = PickerConfiguration()
-//        config.modalPresentationStyle = .automatic
-//        config.selectOptions = .photo
-//        config.selectMode = .single
-//        config.photoList.sort = .desc
-//        config.photoSelectionTapAction = .quickSelect
-//        config.photoList.finishSelectionAfterTakingPhoto = true
-//        var a = SystemCameraConfiguration()
-//        a.allowsEditing = false
-//        config.photoList.cameraType = .system(a)
-//        return config
-//    }()
-//    
-//    func pickSinglePhoto(target:UIViewController,completionHandler:@escaping ((UIImage?) -> Void)) -> Void {
-//        self.completionHandler = completionHandler
-//        let picker = PhotoPickerController(splitPicker: config)
-//        picker.pickerDelegate = self
-//        picker.autoDismiss = false
-//        let split = PhotoSplitViewController(picker: picker)
-//        target.present(split, animated: true, completion: nil)
-//    }
-//
-//}
-//
-//extension TSHXPhotoPickerManager: PhotoPickerControllerDelegate {
-//    func pickerController(_ pickerController: PhotoPickerController, didFinishSelection result: PickerResult) {
-//        result.getImage { images in
-//            self.completionHandler(images.first)
-//        }
-//        pickerController.dismiss(animated: true, completion: nil)
-//    }
-//    
-//    func pickerController(didCancel pickerController: PhotoPickerController) {
-//        pickerController.dismiss(animated: true, completion: nil)
-//    }
-//}

+ 102 - 49
TSLiveWallpaper/Common/ViewTool/TSPhotoPickerManager/TSPhotoPickerManager.swift

@@ -9,35 +9,10 @@ import UIKit
 import PhotosUI
 import HXPhotoPicker
 class TSPhotoPickerManager: NSObject {
-//    lazy var config: PickerConfiguration = {
-//        var config = PickerConfiguration()
-//        config.modalPresentationStyle = .fullScreen
-//        config.themeColor = .themeColor
-//        config.selectOptions = .photo
-//        config.selectMode = .multiple
-//        config.maximumSelectedCount = 1
-//        config.isSelectedOriginal = true
-//        config.photoList.sort = .desc
-//        
-//        config.photoSelectionTapAction = .preview
-//        config.photoList.finishSelectionAfterTakingPhoto = false
-//        config.photoList.isSaveSystemAlbum = true
-//        
-//        config.photoList.takePictureCompletionToSelected = true
-//        config.previewView.bottomView.isHiddenOriginalButton = true
-//        config.photoList.bottomView.isHiddenOriginalButton = true
-//        
-//        config.appearanceStyle = .dark
-//        var cameraConfig = SystemCameraConfiguration()
-//        cameraConfig.allowsEditing = false
-//        config.photoList.cameraType = .system(cameraConfig)
-//        return config
-//    }()
-    
+
     var picker: PhotoPickerController?
     lazy var multipleConfig: PickerConfiguration = {
         var config = PickerConfiguration()
-//        config.modalPresentationStyle = .automatic
         config.modalPresentationStyle = .overFullScreen
         config.themeColor = .themeColor
         config.selectOptions = .photo
@@ -54,7 +29,6 @@ class TSPhotoPickerManager: NSObject {
         config.previewView.bottomView.isHiddenOriginalButton = true
         
         config.photoList.bottomView.isHiddenOriginalButton = true
-        
         config.navigationBarStyle = .black
     
 //        config.photoSelectionTapAction = .quickSelect
@@ -91,7 +65,6 @@ class TSPhotoPickerManager: NSObject {
 //        cameraConfig.allowsEditing = false
 //        config.photoList.cameraType = .system(cameraConfig)
         
-        
         var customCameraConfig = CameraConfiguration()
         customCameraConfig.isSaveSystemAlbum = true
         customCameraConfig.sessionPreset = .hd1920x1080
@@ -101,11 +74,10 @@ class TSPhotoPickerManager: NSObject {
         config.photoList.cameraType = .custom(customCameraConfig)
     
         config.appearanceStyle = .dark
+   
         return config
     }()
     
-    
-    
     // MARK: - Properties
     private weak var viewController: UIViewController?
     private var completionHandler: (([UIImage]) -> Void)?
@@ -120,17 +92,84 @@ class TSPhotoPickerManager: NSObject {
     func pickPhoto(maxSelected:Int = 1,completion: @escaping ([UIImage]) -> Void) {
         self.completionHandler = completion
         self.maxSelected = maxSelected
-        // 检查相册权限
+        
+        var config = multipleConfig
+        config.maximumSelectedCount = maxSelected
+        config.languageType = LanguageManager.shared.currentLanguage.languageType
+        config.customLanguages = [CustomLanguage(language: "it", bundle: Bundle(path: Bundle.main.path(forResource: "it", ofType: "lproj")!)!)]
+        
         checkPhotoLibraryPermission { [weak self] authorized in
             guard let self = self else { return }
             if authorized {
-                self.openPhotoPicker()
+                
+                let picker = PhotoPickerController(splitPicker: config)
+                picker.pickerDelegate = self
+                picker.autoDismiss = false
+                picker.modalTransitionStyle = .coverVertical
+                viewController?.present(picker, animated: true, completion: nil)
+                self.picker = picker
+                
             } else {
                 self.showPermissionAlert()
             }
         }
+        
     }
     
+    func pickLoactionPhoto(maxSelected:Int = 1,completion: @escaping ([UIImage]) -> Void) {
+        
+        self.completionHandler = completion
+        self.maxSelected = maxSelected
+        
+        PickerConfiguration.imageViewProtocol = KFImageView.self
+        
+        var config = multipleConfig
+        config.maximumSelectedCount = maxSelected
+        config.languageType = LanguageManager.shared.currentLanguage.languageType
+        config.customLanguages = [CustomLanguage(language: "it", bundle: Bundle(path: Bundle.main.path(forResource: "it", ofType: "lproj")!)!)]
+        config.selectOptions = []
+        config.photoList.allowAddCamera = false
+        
+        
+        checkPhotoLibraryPermission { [weak self] authorized in
+            guard let self = self else { return }
+            if authorized {
+                
+                var photoAsset:[PhotoAsset] = []
+                let allKeys = TSDBKeyManager.getAllKeys()
+//                let url = URL(string: "https://miaobi-lite.bj.bcebos.com/miaobi/5mao/b%276Jyh56yU5bCP5paw5oOF5L6j5aS05YOPXzE3Mjg5NDgyODguMjQ1MjcyMg%3D%3D%27/0.png")
+                for item in allKeys {
+                    let key = item.key
+                    let url = URL(string:key)
+                    photoAsset.append( PhotoAsset(
+                        networkImageAsset:
+                            NetworkImageAsset(
+                                thumbnailURL: url,
+                                originalURL: url,
+                                thumbailCacheKey: key,
+                                originalCacheKey: key
+                            )
+                    ))
+                }
+      
+                let picker = PhotoPickerController(splitPicker: config)
+                picker.pickerDelegate = self
+                picker.autoDismiss = false
+                picker.localAssetArray = photoAsset
+                picker.modalTransitionStyle = .coverVertical
+                viewController?.present(picker, animated: true, completion: nil)
+                self.picker = picker
+                
+            } else {
+                self.showPermissionAlert()
+            }
+        }
+    }
+    
+
+    
+    
+    
     // MARK: - Private Methods
     /// 检查相册权限
     private func checkPhotoLibraryPermission(completion: @escaping (Bool) -> Void) {
@@ -148,22 +187,7 @@ class TSPhotoPickerManager: NSObject {
             completion(false)
         }
     }
-    
-    /// 打开照片选择器
-    private func openPhotoPicker() {
- 
-        var config = multipleConfig
-        config.maximumSelectedCount = maxSelected
-        config.languageType = LanguageManager.shared.currentLanguage.languageType
-        config.customLanguages = [CustomLanguage(language: "it", bundle: Bundle(path: Bundle.main.path(forResource: "it", ofType: "lproj")!)!)]
-        
-        let picker = PhotoPickerController(splitPicker: config)
-        picker.pickerDelegate = self
-        picker.autoDismiss = false
-        viewController?.present(picker, animated: true, completion: nil)
-        self.picker = picker
-    }
-    
+
     /// 显示权限提示
     private func showPermissionAlert() {
         let alert = UIAlertController(
@@ -186,7 +210,7 @@ class TSPhotoPickerManager: NSObject {
     
     func dismissPageVC(){
         self.picker?.view.isHidden = true
-        self.picker?.dismiss(animated: false)
+        self.picker?.dismiss(animated: true)
         self.picker = nil
     }
 }
@@ -196,6 +220,17 @@ extension TSPhotoPickerManager: PhotoPickerControllerDelegate {
         result.getImage(compressionScale: 1.0) { images in
             self.completionHandler?(images)
             pickerController.dismiss(animated: true, completion: nil)
+            for image in images {
+                if var imageKey = image.uniqueIdentifier() {
+                    imageKey = imageKey
+                    TSDBKeyManager.addOrUpdateKey(imageKey)
+                    TSImageStoreTool.storeImage(image: image, urlString: imageKey)
+                    
+                    
+                    
+                
+                }
+            }
         }
     }
     
@@ -203,3 +238,21 @@ extension TSPhotoPickerManager: PhotoPickerControllerDelegate {
         pickerController.dismiss(animated: true, completion: nil)
     }
 }
+
+
+
+
+import Foundation
+import CommonCrypto
+
+extension UIImage {
+    func uniqueIdentifier() -> String? {
+        guard let imageData = self.pngData() else { return nil }
+        
+        var digest = [UInt8](repeating: 0, count: Int(CC_SHA256_DIGEST_LENGTH))
+        imageData.withUnsafeBytes {
+            _ = CC_SHA256($0.baseAddress, CC_LONG(imageData.count), &digest)
+        }
+        return digest.map { String(format: "%02hhx", $0) }.joined()
+    }
+}

+ 14 - 0
TSLiveWallpaper/Data/Model/TSActionInfoModel.swift

@@ -61,6 +61,10 @@ extension TSActionInfoModel {
         return request.generatorStyle == TSGeneratorImageStyle.creatVideo
     }
     
+    var isPhotoExpand:Bool{
+        return request.generatorStyle == TSGeneratorImageStyle.photoExpand
+    }
+    
     //是否是只显示单张的图片
     var isShowSingleImage:Bool{
         return request.generatorStyle == TSGeneratorImageStyle.portraitFusion || request.generatorStyle == TSGeneratorImageStyle.removeBg
@@ -92,6 +96,11 @@ class TSActionRequestModel : TSBaseModel {
     var model:String = ""   //决定生图的模型
     var maskUrl:String = ""
     var imageUrls:[String] = []
+    
+    var top:Float = 0
+    var bottom:Float = 0
+    var left:Float = 0
+    var right:Float = 0
 
     override func mapping(map: ObjectMapper.Map) {
         prompt              <- map["prompt"]
@@ -104,6 +113,11 @@ class TSActionRequestModel : TSBaseModel {
         generatorStyle      <- map["generatorStyle"]
         model               <- map["model"]
         maskUrl             <- map["maskUrl"]
+        
+        top                 <- map["top"]
+        bottom              <- map["bottom"]
+        left                <- map["left"]
+        right               <- map["right"]
     }
 }
 

+ 1 - 0
TSLiveWallpaper/Data/OperationQueue/TSGenerateBaseOperation/TSGenerateBaseOperation.swift

@@ -15,6 +15,7 @@ extension Notification.Name {
     
 
     static let kAIPhotoDataChanged = Notification.Name("kGenerateBasePhotoChanged") //生成图片数据发生改变
+    static let kGenerateoBackStage = Notification.Name("kGenerateoBackStage") //后台生成数据通知
 }
 
 

+ 15 - 1
TSLiveWallpaper/Data/OperationQueue/TSGenerateBaseOperation/TSGenerateBasePhotoOperation.swift

@@ -112,7 +112,7 @@ class TSGenerateBasePhotoOperation: TSGenerateBaseOperation , @unchecked Sendabl
     
     private var uploadRequest:Request?
     private var creatRequest:Request?
-    
+    var generateStyleModel:TSAIListPhotoGeneratorModel?
     func createActionInfoModel(generateStyleModel:TSAIListPhotoGeneratorModel) -> TSActionInfoModel? {
         guard let upLoadImageUrl = generateStyleModel.upLoadImageUrl else { return nil }
 
@@ -128,6 +128,11 @@ class TSGenerateBasePhotoOperation: TSGenerateBaseOperation , @unchecked Sendabl
         infoModel.request.generatorStyle = generateStyleModel.generatorStyle
         infoModel.request.model = generateStyleModel.model
         
+        infoModel.request.top =  Float(generateStyleModel.expandEdge.top)
+        infoModel.request.bottom = Float(generateStyleModel.expandEdge.bottom)
+        infoModel.request.left = Float(generateStyleModel.expandEdge.left)
+        infoModel.request.right = Float(generateStyleModel.expandEdge.right)
+        
         return infoModel
     }
 
@@ -211,6 +216,7 @@ extension TSGenerateBasePhotoOperation {
     
     //上传一张图片
     func uploadImage(generateStyleModel:TSAIListPhotoGeneratorModel,complete:@escaping (TSActionInfoModel?)->Void) {
+        self.generateStyleModel = generateStyleModel
         //走多张图片上传逻辑
         if let upLoadImages = generateStyleModel.upLoadImages ,upLoadImages.count > 0{
             uploadImages(generateStyleModel: generateStyleModel, complete: complete)
@@ -337,6 +343,14 @@ extension TSGenerateBasePhotoOperation {
         case .removeBg:
             urlType = .removeBg
             postDict["maskUrl"] = request.imageUrls.last ?? request.imageUrl
+        case .photoExpand:
+            urlType = .photoExpand
+            guard let generatorModel = generateStyleModel else { return nil}
+            postDict["prompt"] = request.prompt
+            postDict["top"] = request.top
+            postDict["left"] = request.left
+            postDict["bottom"] = request.bottom
+            postDict["right"] = request.right
         default:
             postDict["prompt"] = request.prompt
             break;

+ 18 - 0
TSLiveWallpaper/Data/TSDBManager/TSDBActionInfoModel.swift

@@ -138,6 +138,13 @@ class TSDBActionRequestModel : Object {
     @Persisted var model:String = ""
     @Persisted var generatorStyle:String = ""
     
+    
+    @Persisted var top:Float = 0
+    @Persisted var bottom:Float = 0
+    @Persisted var left:Float = 0
+    @Persisted var right:Float = 0
+    
+    
     static func createDBModel(requestModel:TSActionRequestModel) -> TSDBActionRequestModel{
         let dbModel = TSDBActionRequestModel()
         dbModel.saveData(requestModel: requestModel)
@@ -160,6 +167,12 @@ class TSDBActionRequestModel : Object {
         list.append(objectsIn: requestModel.imageUrls)
         self.imageUrls = list
         self.maskUrl = requestModel.maskUrl
+        
+        
+        self.top = requestModel.top
+        self.bottom = requestModel.bottom
+        self.left = requestModel.left
+        self.right = requestModel.right
     }
     
     
@@ -177,6 +190,11 @@ class TSDBActionRequestModel : Object {
         model.model = self.model
         model.generatorStyle = TSGeneratorImageStyle(rawValue: self.generatorStyle) ?? .enhance
         
+        model.top = self.top
+        model.bottom = self.bottom
+        model.left = self.left
+        model.right = self.right
+        
         return model
     }
 

+ 96 - 0
TSLiveWallpaper/Data/TSDBManager/TSDBKeyManager.swift

@@ -0,0 +1,96 @@
+//
+//  TSDBKeyManager.swift
+//  TSLiveWallpaper
+//
+//  Created by 100Years on 2025/7/23.
+//
+
+
+import RealmSwift
+
+class TSDBKeyStringItem: Object {
+    @Persisted(primaryKey: true) var key: String
+    @Persisted var createdAt: Date
+    @Persisted var updatedAt: Date
+    
+    convenience init(key: String) {
+        self.init()
+        self.key = key
+        let now = Date()
+        self.createdAt = now
+        self.updatedAt = now
+    }
+}
+
+let kDBKeyManagerShared = TSDBKeyManager()
+class TSDBKeyManager {
+
+    static var realm:Realm{
+        return TSRMShared.realm
+    }
+    
+    // 添加或更新键值(重复则移动到第一位)
+    static func addOrUpdateKey(_ key: String) {
+        do {
+            try realm.write {
+                // 检查是否已存在
+                if let existingItem = realm.object(ofType: TSDBKeyStringItem.self, forPrimaryKey: key) {
+                    // 更新更新时间
+                    existingItem.updatedAt = Date()
+                } else {
+                    // 创建新项
+                    let newItem = TSDBKeyStringItem(key: key)
+                    realm.add(newItem)
+                }
+            }
+        } catch {
+            print("Error adding/updating key: \(error)")
+        }
+    }
+    
+    // 获取所有键值(按更新时间降序排列)
+    static func getAllKeys() -> Results<TSDBKeyStringItem> {
+        return realm.objects(TSDBKeyStringItem.self)
+            .sorted(byKeyPath: "updatedAt", ascending: false)
+    }
+    
+    static func getAllKeyStringArray() -> [String] {
+        var stringArray:[String] = []
+        let allKeys = TSDBKeyManager.getAllKeys()
+        for item in allKeys {
+            let key = item.key
+            stringArray.append(key)
+        }
+        return stringArray
+    }
+    
+    
+    // 检查键值是否存在
+    static func containsKey(_ key: String) -> Bool {
+        return realm.object(ofType: TSDBKeyStringItem.self, forPrimaryKey: key) != nil
+    }
+    
+    // 删除键值
+    static func removeKey(_ key: String) {
+        do {
+            try realm.write {
+                if let item = realm.object(ofType: TSDBKeyStringItem.self, forPrimaryKey: key) {
+                    realm.delete(item)
+                }
+            }
+        } catch {
+            print("Error removing key: \(error)")
+        }
+    }
+    
+    // 清空所有键值
+    static func clearAll() {
+        do {
+            try realm.write {
+                realm.delete(realm.objects(TSDBKeyStringItem.self))
+            }
+        } catch {
+            print("Error clearing all keys: \(error)")
+        }
+    }
+}

+ 1 - 2
TSLiveWallpaper/Data/TSDBManager/TSDBManager.swift

@@ -14,7 +14,6 @@ enum TSDBHistoryType: String,CaseIterable {
     case aiList = "kDBAIList"              //旧照片修复
 }
 
-
 //MARK: TSDBAIChatList - 用于存储会话及消息列表
 class TSDBHistory: Object {
     @Persisted(primaryKey: true) var primaryKey: String = ""
@@ -116,7 +115,7 @@ class TSDBHistory: Object {
                 }
             } else {
                 TSRMShared.writeThread {
-//                    dePrint("updateData 插入 \(dbModel)")
+                    dePrint("updateData 插入 \(dbModel)")
                     listModels.insert(dbModel, at: 0)// 如果没有找到,添加到末尾
                 }
             }

+ 2 - 1
TSLiveWallpaper/Data/TSRealmManager/TSRealmManager.swift

@@ -25,9 +25,10 @@ class TSRealmManager {
          3.6.1 ->4
          3.6.6 ->7
          3.6.8 ->8
+         3.6.11 ->9
          **/
    
-        let newSchemaVersion: UInt64 = 8
+        let newSchemaVersion: UInt64 = 9
         // 获取默认配置
         var config = Realm.Configuration.defaultConfiguration
         // 设置新版本号

+ 11 - 11
TSLiveWallpaper/LaunchVC/TSLaunchVC.swift

@@ -55,17 +55,17 @@ class TSLaunchVC: UIViewController {
 
     func enterApp() {
         dismissHandler?()
-        DispatchQueue.main.async {
-            let keyWindow = WindowHelper.getCurrentWindow()
-            if (keyWindow?.rootViewController is TSTabBarController) == false {
-                let vc = TSTabBarController()
-                keyWindow?.rootViewController = vc
-                keyWindow?.makeKeyAndVisible()
-            } else if let _ = self.presentingViewController {
-                self.dismiss(animated: false)
-            }
-            self.dismissHandler?()
-        }
+//        DispatchQueue.main.async {
+//            let keyWindow = WindowHelper.getCurrentWindow()
+//            if (keyWindow?.rootViewController is TSTabBarController) == false {
+//                let vc = TSTabBarController()
+//                keyWindow?.rootViewController = vc
+//                keyWindow?.makeKeyAndVisible()
+//            } else if let _ = self.presentingViewController {
+//                self.dismiss(animated: false)
+//            }
+//            self.dismissHandler?()
+//        }
     }
     
 

+ 51 - 0
TSLiveWallpaper/Resource/Json/ai_expand_image_style.json

@@ -0,0 +1,51 @@
+[
+    {
+        "imageName": "ai_expand_1_1",
+        "imageText": "1:1",
+        "prompt":"",
+        "style":"",
+        "isVip": true
+    },
+    {
+        "imageName": "ai_expand_16_9",
+        "imageText": "16:9",
+        "prompt":"",
+        "style":"",
+        "isVip": true
+    },
+    {
+        "imageName": "ai_expand_9_16",
+        "imageText": "9:16",
+        "prompt":"",
+        "style":"",
+        "isVip": true
+    },
+    {
+        "imageName": "ai_expand_4_3",
+        "imageText": "4:3",
+        "prompt":"",
+        "style":"",
+        "isVip": true
+    },
+    {
+        "imageName": "ai_expand_3_4",
+        "imageText": "3:4",
+        "prompt":"",
+        "style":"",
+        "isVip": true
+    },
+    {
+        "imageName": "ai_expand_2_3",
+        "imageText": "2:3",
+        "prompt":"",
+        "style":"",
+        "isVip": true
+    },
+    {
+        "imageName": "ai_expand_3_2",
+        "imageText": "3:2",
+        "prompt":"",
+        "style":"",
+        "isVip": true
+    }
+]