Bläddra i källkod

feat:3.6.23(1)
1.新增视频 v2生成功能
2.首页 UI 改版

100Years 1 dag sedan
förälder
incheckning
b4d18d62cf
100 ändrade filer med 2922 tillägg och 566 borttagningar
  1. 128 8
      AIEmoji.xcodeproj/project.pbxproj
  2. 22 0
      AIEmoji/Assets.xcassets/AIList/hint/hint_kiss_badImage.imageset/Contents.json
  3. BIN
      AIEmoji/Assets.xcassets/AIList/hint/hint_kiss_badImage.imageset/hint_kiss_badImage@2x.png
  4. BIN
      AIEmoji/Assets.xcassets/AIList/hint/hint_kiss_badImage.imageset/hint_kiss_badImage@3x.png
  5. 22 0
      AIEmoji/Assets.xcassets/AIList/hint/hint_oscar_badImage.imageset/Contents.json
  6. BIN
      AIEmoji/Assets.xcassets/AIList/hint/hint_oscar_badImage.imageset/hint_oscar_badImage@2x.png
  7. BIN
      AIEmoji/Assets.xcassets/AIList/hint/hint_oscar_badImage.imageset/hint_oscar_badImage@3x.png
  8. 22 0
      AIEmoji/Assets.xcassets/AIList/hint/hint_oscar_goodImage.imageset/Contents.json
  9. BIN
      AIEmoji/Assets.xcassets/AIList/hint/hint_oscar_goodImage.imageset/hint_oscar_goodImage@2x.png
  10. BIN
      AIEmoji/Assets.xcassets/AIList/hint/hint_oscar_goodImage.imageset/hint_oscar_goodImage@3x.png
  11. 22 0
      AIEmoji/Assets.xcassets/AIList/hint/hint_pet_badImage.imageset/Contents.json
  12. BIN
      AIEmoji/Assets.xcassets/AIList/hint/hint_pet_badImage.imageset/hint_pet_badImage@2x.png
  13. BIN
      AIEmoji/Assets.xcassets/AIList/hint/hint_pet_badImage.imageset/hint_pet_badImage@3x.png
  14. 22 0
      AIEmoji/Assets.xcassets/AIList/hint/hint_pet_goodImage.imageset/Contents.json
  15. BIN
      AIEmoji/Assets.xcassets/AIList/hint/hint_pet_goodImage.imageset/hint_pet_goodImage@2x.png
  16. BIN
      AIEmoji/Assets.xcassets/AIList/hint/hint_pet_goodImage.imageset/hint_pet_goodImage@3x.png
  17. 22 0
      AIEmoji/Assets.xcassets/AIList/hint/hint_singleMmultiple_badImage.imageset/Contents.json
  18. BIN
      AIEmoji/Assets.xcassets/AIList/hint/hint_singleMmultiple_badImage.imageset/hint_singleMmultiple_badImage@2x.png
  19. BIN
      AIEmoji/Assets.xcassets/AIList/hint/hint_singleMmultiple_badImage.imageset/hint_singleMmultiple_badImage@3x.png
  20. 22 0
      AIEmoji/Assets.xcassets/AIList/hint/hint_singleMmultiple_goodImage.imageset/Contents.json
  21. BIN
      AIEmoji/Assets.xcassets/AIList/hint/hint_singleMmultiple_goodImage.imageset/hint_singleMmultiple_goodImage@2x.png
  22. BIN
      AIEmoji/Assets.xcassets/AIList/hint/hint_singleMmultiple_goodImage.imageset/hint_singleMmultiple_goodImage@3x.png
  23. 22 0
      AIEmoji/Assets.xcassets/Discover/discover_bannerl_shaow.imageset/Contents.json
  24. BIN
      AIEmoji/Assets.xcassets/Discover/discover_bannerl_shaow.imageset/discover_bmall_shaow@2x.png
  25. BIN
      AIEmoji/Assets.xcassets/Discover/discover_bannerl_shaow.imageset/discover_bmall_shaow@3x.png
  26. 6 0
      AIEmoji/Assets.xcassets/Discover/video/Contents.json
  27. 21 0
      AIEmoji/Assets.xcassets/Discover/video/ptp_style_WalkingwithBeasts.imageset/Contents.json
  28. BIN
      AIEmoji/Assets.xcassets/Discover/video/ptp_style_WalkingwithBeasts.imageset/ptp_style_WalkingwithBeasts@2x.png
  29. 21 0
      AIEmoji/Assets.xcassets/Discover/video/video_style_AnimalDivingShow.imageset/Contents.json
  30. BIN
      AIEmoji/Assets.xcassets/Discover/video/video_style_AnimalDivingShow.imageset/video_style_AnimalDivingShow@2x.png
  31. 21 0
      AIEmoji/Assets.xcassets/Discover/video/video_style_AnimeMe.imageset/Contents.json
  32. BIN
      AIEmoji/Assets.xcassets/Discover/video/video_style_AnimeMe.imageset/video_style_AnimeMe@2x.png
  33. 21 0
      AIEmoji/Assets.xcassets/Discover/video/video_style_Fairy.imageset/Contents.json
  34. BIN
      AIEmoji/Assets.xcassets/Discover/video/video_style_Fairy.imageset/video_style_Fairy@2x.png
  35. 21 0
      AIEmoji/Assets.xcassets/Discover/video/video_style_Fly.imageset/Contents.json
  36. BIN
      AIEmoji/Assets.xcassets/Discover/video/video_style_Fly.imageset/video_style_Fly@2x.png
  37. 21 0
      AIEmoji/Assets.xcassets/Discover/video/video_style_FrenchKiss.imageset/Contents.json
  38. BIN
      AIEmoji/Assets.xcassets/Discover/video/video_style_FrenchKiss.imageset/video_style_FrenchKiss@2x.png
  39. 21 0
      AIEmoji/Assets.xcassets/Discover/video/video_style_FunnyPet.imageset/Contents.json
  40. BIN
      AIEmoji/Assets.xcassets/Discover/video/video_style_FunnyPet.imageset/video_style_FunnyPet@2x.png
  41. 21 0
      AIEmoji/Assets.xcassets/Discover/video/video_style_Grabdoll.imageset/Contents.json
  42. BIN
      AIEmoji/Assets.xcassets/Discover/video/video_style_Grabdoll.imageset/video_style_Grabdoll@2x.png
  43. 21 0
      AIEmoji/Assets.xcassets/Discover/video/video_style_HappyBirthday.imageset/Contents.json
  44. BIN
      AIEmoji/Assets.xcassets/Discover/video/video_style_HappyBirthday.imageset/video_style_HappyBirthday@2x.png
  45. 21 0
      AIEmoji/Assets.xcassets/Discover/video/video_style_Hulk.imageset/Contents.json
  46. BIN
      AIEmoji/Assets.xcassets/Discover/video/video_style_Hulk.imageset/video_style_Hulk@2x.png
  47. 21 0
      AIEmoji/Assets.xcassets/Discover/video/video_style_Lafufu.imageset/Contents.json
  48. BIN
      AIEmoji/Assets.xcassets/Discover/video/video_style_Lafufu.imageset/video_style_Lafufu@2x.png
  49. 21 0
      AIEmoji/Assets.xcassets/Discover/video/video_style_MakingFace.imageset/Contents.json
  50. BIN
      AIEmoji/Assets.xcassets/Discover/video/video_style_MakingFace.imageset/video_style_MakingFace@2x.png
  51. 21 0
      AIEmoji/Assets.xcassets/Discover/video/video_style_Mermaid.imageset/Contents.json
  52. BIN
      AIEmoji/Assets.xcassets/Discover/video/video_style_Mermaid.imageset/video_style_Mermaid@2x.png
  53. 21 0
      AIEmoji/Assets.xcassets/Discover/video/video_style_MuscleUp.imageset/Contents.json
  54. BIN
      AIEmoji/Assets.xcassets/Discover/video/video_style_MuscleUp.imageset/video_style_MuscleUp@2x.png
  55. 21 0
      AIEmoji/Assets.xcassets/Discover/video/video_style_OscarGala.imageset/Contents.json
  56. BIN
      AIEmoji/Assets.xcassets/Discover/video/video_style_OscarGala.imageset/video_style_OscarGala@2x.png
  57. 21 0
      AIEmoji/Assets.xcassets/Discover/video/video_style_PettoHuman.imageset/Contents.json
  58. BIN
      AIEmoji/Assets.xcassets/Discover/video/video_style_PettoHuman.imageset/video_style_PettoHuman@2x.png
  59. 21 0
      AIEmoji/Assets.xcassets/Discover/video/video_style_PhotoAnimater.imageset/Contents.json
  60. BIN
      AIEmoji/Assets.xcassets/Discover/video/video_style_PhotoAnimater.imageset/video_style_PhotoAnimater@2x.png
  61. 21 0
      AIEmoji/Assets.xcassets/Discover/video/video_style_Pinch.imageset/Contents.json
  62. BIN
      AIEmoji/Assets.xcassets/Discover/video/video_style_Pinch.imageset/video_style_Pinch@2x.png
  63. 21 0
      AIEmoji/Assets.xcassets/Discover/video/video_style_Robot.imageset/Contents.json
  64. BIN
      AIEmoji/Assets.xcassets/Discover/video/video_style_Robot.imageset/video_style_Robot@2x.png
  65. 21 0
      AIEmoji/Assets.xcassets/Discover/video/video_style_SurpriseFlower.imageset/Contents.json
  66. BIN
      AIEmoji/Assets.xcassets/Discover/video/video_style_SurpriseFlower.imageset/video_style_SurpriseFlower@2x.png
  67. 21 0
      AIEmoji/Assets.xcassets/Discover/video/video_style_ToyMe.imageset/Contents.json
  68. BIN
      AIEmoji/Assets.xcassets/Discover/video/video_style_ToyMe.imageset/video_style_ToyMe@2x.png
  69. 22 0
      AIEmoji/Assets.xcassets/Discover/video_mute.imageset/Contents.json
  70. BIN
      AIEmoji/Assets.xcassets/Discover/video_mute.imageset/video_mute@2x.png
  71. BIN
      AIEmoji/Assets.xcassets/Discover/video_mute.imageset/video_mute@3x.png
  72. 22 0
      AIEmoji/Assets.xcassets/Discover/video_sound.imageset/Contents.json
  73. BIN
      AIEmoji/Assets.xcassets/Discover/video_sound.imageset/video_Sound@2x.png
  74. BIN
      AIEmoji/Assets.xcassets/Discover/video_sound.imageset/video_Sound@3x.png
  75. 4 0
      AIEmoji/Business/General/Ex/Notification+Ex.swift
  76. 83 1
      AIEmoji/Business/TSAILIstVC/TSAIAgeImageHintVC/TSAIListHintBaseVC.swift
  77. 26 3
      AIEmoji/Business/TSAILIstVC/TSAIListVideoPlayerVC/TSAIListVideoPlayerVC.swift
  78. 4 0
      AIEmoji/Business/TSAILIstVC/TSAIPhotoGeneratorBaseVC/TSAIListPhotoGeneratorBaseVC.swift
  79. 7 1
      AIEmoji/Business/TSAILIstVC/TSAIUploadPhotoBaseVC/TSAIUploadPhotoBaseVC.swift
  80. 6 4
      AIEmoji/Business/TSPTPGeneratorVC/TSAIPhotoGeneratorBaseVC/TSAIPhotoBrowseVC.swift
  81. 2 1
      AIEmoji/Business/TSPTPGeneratorVC/TSPhotoToPhotoVC/M/TSPTPStyleModel.swift
  82. 3 0
      AIEmoji/Business/TSTextGeneralPictureVC/TSTTPInputVC/View/TSTitleView.swift
  83. 240 0
      AIEmoji/Business2/CommonVC/TSVideoPlayer/TSVideoPlayer.swift
  84. 151 0
      AIEmoji/Business2/CommonVC/TSVideoPlayer/VideoFrameExtractor.swift
  85. 555 0
      AIEmoji/Business2/DisCover/Data/TSDiscoverViewModel+Data.swift
  86. 337 0
      AIEmoji/Business2/DisCover/Data/TSDiscoverViewModel+Dic.swift
  87. 16 483
      AIEmoji/Business2/DisCover/Data/TSDiscoverViewModel.swift
  88. 6 5
      AIEmoji/Business2/DisCover/Data/TSFuncStyle.swift
  89. 3 0
      AIEmoji/Business2/DisCover/TSAIGenerateVC/TSAIGenerateBaseVC/TSAIGenerateBaseVC.swift
  90. 2 1
      AIEmoji/Business2/DisCover/TSAIGenerateVC/TSAIGenerateVC.swift
  91. 269 0
      AIEmoji/Business2/DisCover/TSDiscoverVC/Cell/TSDiscoverBannerCell.swift
  92. 0 1
      AIEmoji/Business2/DisCover/TSDiscoverVC/Cell/TSDiscoverBaseCell.swift
  93. 12 0
      AIEmoji/Business2/DisCover/TSDiscoverVC/Cell/TSDiscoverHeaderView.swift
  94. 173 4
      AIEmoji/Business2/DisCover/TSDiscoverVC/Cell/TSDiscoverStyleMoreCell/TSDiscoverStyleMoreCell.swift
  95. 24 2
      AIEmoji/Business2/DisCover/TSDiscoverVC/TSDiscoverStyleMoreVC/TSDiscoverStyleMoreVC.swift
  96. 64 13
      AIEmoji/Business2/DisCover/TSDiscoverVC/TSDiscoverVC.swift
  97. 14 0
      AIEmoji/Business2/DisCover/TSGenerateHistoryVC/TSGenerateHistoryVC.swift
  98. 53 14
      AIEmoji/Business2/DisCover/TSGenerateHistoryVC/View/TSGenerateHistoryCell.swift
  99. 50 9
      AIEmoji/Business2/DisCover/TSPTPUploadImageVC/TSPTPUploadImageVC+View.swift
  100. 23 16
      AIEmoji/Business2/DisCover/TSPTPUploadImageVC/TSPTPUploadImageVC.swift

+ 128 - 8
AIEmoji.xcodeproj/project.pbxproj

@@ -20,6 +20,12 @@
 		A804B9812DBF500E00C494C7 /* SwiftUIX in Frameworks */ = {isa = PBXBuildFile; productRef = A804B9802DBF500E00C494C7 /* SwiftUIX */; };
 		A804B98F2DC0F0F700C494C7 /* TSTTPRatioView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A804B98E2DC0F0D800C494C7 /* TSTTPRatioView.swift */; };
 		A804B9922DC1CD1800C494C7 /* TSAbnormalPopUpAlertVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A804B9912DC1CD1700C494C7 /* TSAbnormalPopUpAlertVC.swift */; };
+		A807E6302E288AF100A175AF /* VideoFrameExtractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = A807E62F2E288AEE00A175AF /* VideoFrameExtractor.swift */; };
+		A807E6322E28ECC200A175AF /* TSUploadVideoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A807E6312E28ECB200A175AF /* TSUploadVideoView.swift */; };
+		A807E6362E2904D400A175AF /* Oscar Gala.mp4 in Resources */ = {isa = PBXBuildFile; fileRef = A807E6342E2904D400A175AF /* Oscar Gala.mp4 */; };
+		A807E6372E2904D400A175AF /* Photo Animater.mp4 in Resources */ = {isa = PBXBuildFile; fileRef = A807E6352E2904D400A175AF /* Photo Animater.mp4 */; };
+		A807E6382E2904D400A175AF /* Animal Diving Show.mp4 in Resources */ = {isa = PBXBuildFile; fileRef = A807E6332E2904D400A175AF /* Animal Diving Show.mp4 */; };
+		A807E63A2E29056600A175AF /* TSDiscoverBannerCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A807E6392E29054E00A175AF /* TSDiscoverBannerCell.swift */; };
 		A80E721A2D3F393A00C64288 /* DiyStickerModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A80E72192D3F393500C64288 /* DiyStickerModel.swift */; };
 		A80E721E2D3F3A7500C64288 /* DiyElement.swift in Sources */ = {isa = PBXBuildFile; fileRef = A80E721D2D3F3A7500C64288 /* DiyElement.swift */; };
 		A80E72202D3F3A8600C64288 /* DiyElementBaseView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A80E721F2D3F3A8600C64288 /* DiyElementBaseView.swift */; };
@@ -102,6 +108,26 @@
 		A81BECAC2DD31F4E005D06A2 /* TSImageComparisonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A81BECAB2DD31F4E005D06A2 /* TSImageComparisonView.swift */; };
 		A81BECAE2DD31FF0005D06A2 /* TYCycleImageComparisonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A81BECAD2DD31FEE005D06A2 /* TYCycleImageComparisonView.swift */; };
 		A81BECB12DD4AE9A005D06A2 /* Poppins-BoldItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = A81BECB02DD4AE9A005D06A2 /* Poppins-BoldItalic.otf */; };
+		A82542D22E27996900F54FE5 /* TSVideoPlayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = A82542D12E27996800F54FE5 /* TSVideoPlayer.swift */; };
+		A82542D42E279C0200F54FE5 /* TSDiscoverViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A82542D32E279C0100F54FE5 /* TSDiscoverViewModel.swift */; };
+		A82542D72E279C5100F54FE5 /* Anime Me.mp4 in Resources */ = {isa = PBXBuildFile; fileRef = A82542D62E279C5100F54FE5 /* Anime Me.mp4 */; };
+		A82542EA2E279C5A00F54FE5 /* Funny Pet.mp4 in Resources */ = {isa = PBXBuildFile; fileRef = A82542DC2E279C5A00F54FE5 /* Funny Pet.mp4 */; };
+		A82542EB2E279C5A00F54FE5 /* Toy Me.mp4 in Resources */ = {isa = PBXBuildFile; fileRef = A82542E82E279C5A00F54FE5 /* Toy Me.mp4 */; };
+		A82542EC2E279C5A00F54FE5 /* Mermaid.mp4 in Resources */ = {isa = PBXBuildFile; fileRef = A82542E22E279C5A00F54FE5 /* Mermaid.mp4 */; };
+		A82542ED2E279C5A00F54FE5 /* Fly.mp4 in Resources */ = {isa = PBXBuildFile; fileRef = A82542DA2E279C5A00F54FE5 /* Fly.mp4 */; };
+		A82542EE2E279C5A00F54FE5 /* Happy Birthday.mp4 in Resources */ = {isa = PBXBuildFile; fileRef = A82542DE2E279C5A00F54FE5 /* Happy Birthday.mp4 */; };
+		A82542EF2E279C5A00F54FE5 /* Fairy.mp4 in Resources */ = {isa = PBXBuildFile; fileRef = A82542D92E279C5A00F54FE5 /* Fairy.mp4 */; };
+		A82542F02E279C5A00F54FE5 /* MuscleUp.mp4 in Resources */ = {isa = PBXBuildFile; fileRef = A82542E32E279C5A00F54FE5 /* MuscleUp.mp4 */; };
+		A82542F12E279C5A00F54FE5 /* Grab doll.mp4 in Resources */ = {isa = PBXBuildFile; fileRef = A82542DD2E279C5A00F54FE5 /* Grab doll.mp4 */; };
+		A82542F22E279C5A00F54FE5 /* Surprise Flower.mp4 in Resources */ = {isa = PBXBuildFile; fileRef = A82542E72E279C5A00F54FE5 /* Surprise Flower.mp4 */; };
+		A82542F32E279C5A00F54FE5 /* Pinch.mp4 in Resources */ = {isa = PBXBuildFile; fileRef = A82542E52E279C5A00F54FE5 /* Pinch.mp4 */; };
+		A82542F42E279C5A00F54FE5 /* Hulk.mp4 in Resources */ = {isa = PBXBuildFile; fileRef = A82542DF2E279C5A00F54FE5 /* Hulk.mp4 */; };
+		A82542F52E279C5A00F54FE5 /* Lafufu.mp4 in Resources */ = {isa = PBXBuildFile; fileRef = A82542E02E279C5A00F54FE5 /* Lafufu.mp4 */; };
+		A82542F62E279C5A00F54FE5 /* Making Face.mp4 in Resources */ = {isa = PBXBuildFile; fileRef = A82542E12E279C5A00F54FE5 /* Making Face.mp4 */; };
+		A82542F72E279C5A00F54FE5 /* Robot.mp4 in Resources */ = {isa = PBXBuildFile; fileRef = A82542E62E279C5A00F54FE5 /* Robot.mp4 */; };
+		A82542F82E279C5A00F54FE5 /* Pet to Human.mp4 in Resources */ = {isa = PBXBuildFile; fileRef = A82542E42E279C5A00F54FE5 /* Pet to Human.mp4 */; };
+		A82542FA2E279C5A00F54FE5 /* Walking with Beasts.mp4 in Resources */ = {isa = PBXBuildFile; fileRef = A82542E92E279C5A00F54FE5 /* Walking with Beasts.mp4 */; };
+		A82542FB2E279C5A00F54FE5 /* French Kiss.mp4 in Resources */ = {isa = PBXBuildFile; fileRef = A82542DB2E279C5A00F54FE5 /* French Kiss.mp4 */; };
 		A82D60792DB7703D00596190 /* TSAIExpandImageVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A82D60782DB7703C00596190 /* TSAIExpandImageVC.swift */; };
 		A82D607B2DB7724700596190 /* TSAIExpandStyleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A82D607A2DB7724600596190 /* TSAIExpandStyleView.swift */; };
 		A82D607D2DB7748800596190 /* ai_expand_image_style.json in Resources */ = {isa = PBXBuildFile; fileRef = A82D607C2DB7748200596190 /* ai_expand_image_style.json */; };
@@ -209,7 +235,6 @@
 		A89EA6CA2D642C0A000EB181 /* TSChatViewController+SendMsg.swift in Sources */ = {isa = PBXBuildFile; fileRef = A89EA6C92D642C03000EB181 /* TSChatViewController+SendMsg.swift */; };
 		A89EA6CC2D642CE2000EB181 /* TSChatViewController+NaviBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = A89EA6CB2D642CD4000EB181 /* TSChatViewController+NaviBar.swift */; };
 		A89EA6CF2D6430F3000EB181 /* TSChatViewController+Keyboard.swift in Sources */ = {isa = PBXBuildFile; fileRef = A89EA6CE2D6430EE000EB181 /* TSChatViewController+Keyboard.swift */; };
-		A8B70BC62E06B9D7003177FA /* TSDiscoverViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8B70BC52E06B9C7003177FA /* TSDiscoverViewModel.swift */; };
 		A8B70BC92E08E416003177FA /* TSGenerateHistoryVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8B70BC82E08E416003177FA /* TSGenerateHistoryVC.swift */; };
 		A8B70BCB2E08F28F003177FA /* TSGenerateHistoryCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8B70BCA2E08F28B003177FA /* TSGenerateHistoryCell.swift */; };
 		A8B70BD22E08F2F4003177FA /* TSGenerateBaseOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8B70BCD2E08F2F4003177FA /* TSGenerateBaseOperation.swift */; };
@@ -230,6 +255,7 @@
 		A8BA76722DA65A95000B6707 /* TSAIUploadPhotoBaseVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8BA76712DA65A94000B6707 /* TSAIUploadPhotoBaseVC.swift */; };
 		A8BA76752DA67E66000B6707 /* TSAIListHistoryBaseVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8BA76742DA67E65000B6707 /* TSAIListHistoryBaseVC.swift */; };
 		A8BA76772DA68619000B6707 /* TSAIListHistoryBaseVM.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8BA76762DA68617000B6707 /* TSAIListHistoryBaseVM.swift */; };
+		A8BD92C82E29F8FF0014C3C5 /* TSDiscoverViewModel+Data.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8BD92C72E29F8FB0014C3C5 /* TSDiscoverViewModel+Data.swift */; };
 		A8BE26E82DBC6A9F00A1DD18 /* TSDBHistoryManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8BE26E72DBC6A9700A1DD18 /* TSDBHistoryManager.swift */; };
 		A8D638352DB10BAC00A96C0E /* CrashReporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8D638342DB10BAB00A96C0E /* CrashReporter.swift */; };
 		A8D6383C2DB1FC8D00A96C0E /* TSAIListVideoPlayerVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8D6383B2DB1FC8A00A96C0E /* TSAIListVideoPlayerVC.swift */; };
@@ -329,6 +355,12 @@
 		A80327C42D81582F00AF7878 /* TSGeneralBtnView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSGeneralBtnView.swift; sourceTree = "<group>"; };
 		A804B98E2DC0F0D800C494C7 /* TSTTPRatioView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSTTPRatioView.swift; sourceTree = "<group>"; };
 		A804B9912DC1CD1700C494C7 /* TSAbnormalPopUpAlertVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSAbnormalPopUpAlertVC.swift; sourceTree = "<group>"; };
+		A807E62F2E288AEE00A175AF /* VideoFrameExtractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoFrameExtractor.swift; sourceTree = "<group>"; };
+		A807E6312E28ECB200A175AF /* TSUploadVideoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSUploadVideoView.swift; sourceTree = "<group>"; };
+		A807E6332E2904D400A175AF /* Animal Diving Show.mp4 */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Animal Diving Show.mp4"; sourceTree = "<group>"; };
+		A807E6342E2904D400A175AF /* Oscar Gala.mp4 */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Oscar Gala.mp4"; sourceTree = "<group>"; };
+		A807E6352E2904D400A175AF /* Photo Animater.mp4 */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Photo Animater.mp4"; sourceTree = "<group>"; };
+		A807E6392E29054E00A175AF /* TSDiscoverBannerCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSDiscoverBannerCell.swift; sourceTree = "<group>"; };
 		A80E72192D3F393500C64288 /* DiyStickerModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DiyStickerModel.swift; sourceTree = "<group>"; };
 		A80E721D2D3F3A7500C64288 /* DiyElement.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DiyElement.swift; sourceTree = "<group>"; };
 		A80E721F2D3F3A8600C64288 /* DiyElementBaseView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DiyElementBaseView.swift; sourceTree = "<group>"; };
@@ -417,6 +449,26 @@
 		A81BECAB2DD31F4E005D06A2 /* TSImageComparisonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSImageComparisonView.swift; sourceTree = "<group>"; };
 		A81BECAD2DD31FEE005D06A2 /* TYCycleImageComparisonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TYCycleImageComparisonView.swift; sourceTree = "<group>"; };
 		A81BECB02DD4AE9A005D06A2 /* Poppins-BoldItalic.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Poppins-BoldItalic.otf"; sourceTree = "<group>"; };
+		A82542D12E27996800F54FE5 /* TSVideoPlayer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSVideoPlayer.swift; sourceTree = "<group>"; };
+		A82542D32E279C0100F54FE5 /* TSDiscoverViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSDiscoverViewModel.swift; sourceTree = "<group>"; };
+		A82542D62E279C5100F54FE5 /* Anime Me.mp4 */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Anime Me.mp4"; sourceTree = "<group>"; };
+		A82542D92E279C5A00F54FE5 /* Fairy.mp4 */ = {isa = PBXFileReference; lastKnownFileType = file; path = Fairy.mp4; sourceTree = "<group>"; };
+		A82542DA2E279C5A00F54FE5 /* Fly.mp4 */ = {isa = PBXFileReference; lastKnownFileType = file; path = Fly.mp4; sourceTree = "<group>"; };
+		A82542DB2E279C5A00F54FE5 /* French Kiss.mp4 */ = {isa = PBXFileReference; lastKnownFileType = file; path = "French Kiss.mp4"; sourceTree = "<group>"; };
+		A82542DC2E279C5A00F54FE5 /* Funny Pet.mp4 */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Funny Pet.mp4"; sourceTree = "<group>"; };
+		A82542DD2E279C5A00F54FE5 /* Grab doll.mp4 */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Grab doll.mp4"; sourceTree = "<group>"; };
+		A82542DE2E279C5A00F54FE5 /* Happy Birthday.mp4 */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Happy Birthday.mp4"; sourceTree = "<group>"; };
+		A82542DF2E279C5A00F54FE5 /* Hulk.mp4 */ = {isa = PBXFileReference; lastKnownFileType = file; path = Hulk.mp4; sourceTree = "<group>"; };
+		A82542E02E279C5A00F54FE5 /* Lafufu.mp4 */ = {isa = PBXFileReference; lastKnownFileType = file; path = Lafufu.mp4; sourceTree = "<group>"; };
+		A82542E12E279C5A00F54FE5 /* Making Face.mp4 */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Making Face.mp4"; sourceTree = "<group>"; };
+		A82542E22E279C5A00F54FE5 /* Mermaid.mp4 */ = {isa = PBXFileReference; lastKnownFileType = file; path = Mermaid.mp4; sourceTree = "<group>"; };
+		A82542E32E279C5A00F54FE5 /* MuscleUp.mp4 */ = {isa = PBXFileReference; lastKnownFileType = file; path = MuscleUp.mp4; sourceTree = "<group>"; };
+		A82542E42E279C5A00F54FE5 /* Pet to Human.mp4 */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Pet to Human.mp4"; sourceTree = "<group>"; };
+		A82542E52E279C5A00F54FE5 /* Pinch.mp4 */ = {isa = PBXFileReference; lastKnownFileType = file; path = Pinch.mp4; sourceTree = "<group>"; };
+		A82542E62E279C5A00F54FE5 /* Robot.mp4 */ = {isa = PBXFileReference; lastKnownFileType = file; path = Robot.mp4; sourceTree = "<group>"; };
+		A82542E72E279C5A00F54FE5 /* Surprise Flower.mp4 */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Surprise Flower.mp4"; sourceTree = "<group>"; };
+		A82542E82E279C5A00F54FE5 /* Toy Me.mp4 */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Toy Me.mp4"; sourceTree = "<group>"; };
+		A82542E92E279C5A00F54FE5 /* Walking with Beasts.mp4 */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Walking with Beasts.mp4"; sourceTree = "<group>"; };
 		A82D60782DB7703C00596190 /* TSAIExpandImageVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSAIExpandImageVC.swift; sourceTree = "<group>"; };
 		A82D607A2DB7724600596190 /* TSAIExpandStyleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSAIExpandStyleView.swift; sourceTree = "<group>"; };
 		A82D607C2DB7748200596190 /* ai_expand_image_style.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = ai_expand_image_style.json; sourceTree = "<group>"; };
@@ -543,7 +595,6 @@
 		A89EA6C92D642C03000EB181 /* TSChatViewController+SendMsg.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TSChatViewController+SendMsg.swift"; sourceTree = "<group>"; };
 		A89EA6CB2D642CD4000EB181 /* TSChatViewController+NaviBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TSChatViewController+NaviBar.swift"; sourceTree = "<group>"; };
 		A89EA6CE2D6430EE000EB181 /* TSChatViewController+Keyboard.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TSChatViewController+Keyboard.swift"; sourceTree = "<group>"; };
-		A8B70BC52E06B9C7003177FA /* TSDiscoverViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSDiscoverViewModel.swift; sourceTree = "<group>"; };
 		A8B70BC82E08E416003177FA /* TSGenerateHistoryVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSGenerateHistoryVC.swift; sourceTree = "<group>"; };
 		A8B70BCA2E08F28B003177FA /* TSGenerateHistoryCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSGenerateHistoryCell.swift; sourceTree = "<group>"; };
 		A8B70BCD2E08F2F4003177FA /* TSGenerateBaseOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSGenerateBaseOperation.swift; sourceTree = "<group>"; };
@@ -566,6 +617,7 @@
 		A8BA76712DA65A94000B6707 /* TSAIUploadPhotoBaseVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSAIUploadPhotoBaseVC.swift; sourceTree = "<group>"; };
 		A8BA76742DA67E65000B6707 /* TSAIListHistoryBaseVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSAIListHistoryBaseVC.swift; sourceTree = "<group>"; };
 		A8BA76762DA68617000B6707 /* TSAIListHistoryBaseVM.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSAIListHistoryBaseVM.swift; sourceTree = "<group>"; };
+		A8BD92C72E29F8FB0014C3C5 /* TSDiscoverViewModel+Data.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TSDiscoverViewModel+Data.swift"; sourceTree = "<group>"; };
 		A8BE26E72DBC6A9700A1DD18 /* TSDBHistoryManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSDBHistoryManager.swift; sourceTree = "<group>"; };
 		A8D638342DB10BAB00A96C0E /* CrashReporter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CrashReporter.swift; sourceTree = "<group>"; };
 		A8D6383B2DB1FC8A00A96C0E /* TSAIListVideoPlayerVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSAIListVideoPlayerVC.swift; sourceTree = "<group>"; };
@@ -1280,6 +1332,43 @@
 			path = TSGeneratorloadingView;
 			sourceTree = "<group>";
 		};
+		A82542D02E27996000F54FE5 /* TSVideoPlayer */ = {
+			isa = PBXGroup;
+			children = (
+				A807E62F2E288AEE00A175AF /* VideoFrameExtractor.swift */,
+				A82542D12E27996800F54FE5 /* TSVideoPlayer.swift */,
+			);
+			path = TSVideoPlayer;
+			sourceTree = "<group>";
+		};
+		A82542D52E279C4700F54FE5 /* Video */ = {
+			isa = PBXGroup;
+			children = (
+				A807E6332E2904D400A175AF /* Animal Diving Show.mp4 */,
+				A807E6342E2904D400A175AF /* Oscar Gala.mp4 */,
+				A807E6352E2904D400A175AF /* Photo Animater.mp4 */,
+				A82542D62E279C5100F54FE5 /* Anime Me.mp4 */,
+				A82542D92E279C5A00F54FE5 /* Fairy.mp4 */,
+				A82542DA2E279C5A00F54FE5 /* Fly.mp4 */,
+				A82542DB2E279C5A00F54FE5 /* French Kiss.mp4 */,
+				A82542DC2E279C5A00F54FE5 /* Funny Pet.mp4 */,
+				A82542DD2E279C5A00F54FE5 /* Grab doll.mp4 */,
+				A82542DE2E279C5A00F54FE5 /* Happy Birthday.mp4 */,
+				A82542DF2E279C5A00F54FE5 /* Hulk.mp4 */,
+				A82542E02E279C5A00F54FE5 /* Lafufu.mp4 */,
+				A82542E12E279C5A00F54FE5 /* Making Face.mp4 */,
+				A82542E22E279C5A00F54FE5 /* Mermaid.mp4 */,
+				A82542E32E279C5A00F54FE5 /* MuscleUp.mp4 */,
+				A82542E42E279C5A00F54FE5 /* Pet to Human.mp4 */,
+				A82542E52E279C5A00F54FE5 /* Pinch.mp4 */,
+				A82542E62E279C5A00F54FE5 /* Robot.mp4 */,
+				A82542E72E279C5A00F54FE5 /* Surprise Flower.mp4 */,
+				A82542E82E279C5A00F54FE5 /* Toy Me.mp4 */,
+				A82542E92E279C5A00F54FE5 /* Walking with Beasts.mp4 */,
+			);
+			path = Video;
+			sourceTree = "<group>";
+		};
 		A82D60772DB7703000596190 /* TSAIExpandImageVC */ = {
 			isa = PBXGroup;
 			children = (
@@ -1440,6 +1529,7 @@
 		A8708A142E095A1200601686 /* Cell */ = {
 			isa = PBXGroup;
 			children = (
+				A807E6392E29054E00A175AF /* TSDiscoverBannerCell.swift */,
 				A8708A202E0A3A0A00601686 /* TSDiscoverHeaderView.swift */,
 				A8708A172E095A1E00601686 /* TSDiscoverBaseCell.swift */,
 				A8708A1A2E095A7800601686 /* TSDiscoverFuncItemsCell.swift */,
@@ -1472,6 +1562,7 @@
 		A8708A2D2E0AA02A00601686 /* View */ = {
 			isa = PBXGroup;
 			children = (
+				A807E6312E28ECB200A175AF /* TSUploadVideoView.swift */,
 				A8708A2E2E0AA03000601686 /* TSUploadImageView.swift */,
 			);
 			path = View;
@@ -1529,6 +1620,7 @@
 		A8708A4B2E0C0A8100601686 /* CommonVC */ = {
 			isa = PBXGroup;
 			children = (
+				A82542D02E27996000F54FE5 /* TSVideoPlayer */,
 				A8708A4D2E0C0A8900601686 /* TSAppUpdateAlertVC */,
 			);
 			path = CommonVC;
@@ -1746,7 +1838,8 @@
 				A8708A392E0B8C2800601686 /* TSAIGeneratorModel.swift */,
 				A8708A222E0A46B900601686 /* ts111.swift */,
 				A8708A0D2E093E9100601686 /* TSFuncStyle.swift */,
-				A8B70BC52E06B9C7003177FA /* TSDiscoverViewModel.swift */,
+				A82542D32E279C0100F54FE5 /* TSDiscoverViewModel.swift */,
+				A8BD92C72E29F8FB0014C3C5 /* TSDiscoverViewModel+Data.swift */,
 				A8708A0F2E09438E00601686 /* TSDiscoverViewModel+Dic.swift */,
 			);
 			path = Data;
@@ -2317,6 +2410,7 @@
 		A8FB02AE2D3E38FA0031A396 /* Res */ = {
 			isa = PBXGroup;
 			children = (
+				A82542D52E279C4700F54FE5 /* Video */,
 				A8EB38422E13FEF3002F90E9 /* Gift.apng */,
 				A8708A522E0D4FA000601686 /* discover_0_AnimatePhoto1.gif */,
 				A83404D62D9D34ED00C140E4 /* Kelsi-fill.otf */,
@@ -2453,7 +2547,27 @@
 			files = (
 				A83404D82D9D34ED00C140E4 /* Kelsi-fill.otf in Resources */,
 				A83404D92D9D34ED00C140E4 /* Kelsi-Regular.otf in Resources */,
+				A82542EA2E279C5A00F54FE5 /* Funny Pet.mp4 in Resources */,
+				A82542EB2E279C5A00F54FE5 /* Toy Me.mp4 in Resources */,
+				A82542EC2E279C5A00F54FE5 /* Mermaid.mp4 in Resources */,
+				A82542ED2E279C5A00F54FE5 /* Fly.mp4 in Resources */,
+				A82542EE2E279C5A00F54FE5 /* Happy Birthday.mp4 in Resources */,
+				A82542EF2E279C5A00F54FE5 /* Fairy.mp4 in Resources */,
+				A82542F02E279C5A00F54FE5 /* MuscleUp.mp4 in Resources */,
+				A82542F12E279C5A00F54FE5 /* Grab doll.mp4 in Resources */,
+				A82542F22E279C5A00F54FE5 /* Surprise Flower.mp4 in Resources */,
+				A82542F32E279C5A00F54FE5 /* Pinch.mp4 in Resources */,
+				A82542F42E279C5A00F54FE5 /* Hulk.mp4 in Resources */,
+				A82542F52E279C5A00F54FE5 /* Lafufu.mp4 in Resources */,
+				A82542F62E279C5A00F54FE5 /* Making Face.mp4 in Resources */,
+				A82542F72E279C5A00F54FE5 /* Robot.mp4 in Resources */,
+				A82542F82E279C5A00F54FE5 /* Pet to Human.mp4 in Resources */,
+				A82542FA2E279C5A00F54FE5 /* Walking with Beasts.mp4 in Resources */,
+				A82542FB2E279C5A00F54FE5 /* French Kiss.mp4 in Resources */,
 				A80E72482D3F4F0A00C64288 /* templates.json in Resources */,
+				A807E6362E2904D400A175AF /* Oscar Gala.mp4 in Resources */,
+				A807E6372E2904D400A175AF /* Photo Animater.mp4 in Resources */,
+				A807E6382E2904D400A175AF /* Animal Diving Show.mp4 in Resources */,
 				A83404CC2D9BEED800C140E4 /* Poppins-BlackItalic.ttf in Resources */,
 				A87587162D81734300286A66 /* text_to_photo_style.json in Resources */,
 				A8FDB1812DCC8C5600E9919B /* catPaw_left.gif in Resources */,
@@ -2470,6 +2584,7 @@
 				A8F413552DA8BA4E001E715A /* ai_change_emote_style.json in Resources */,
 				A8EEADE72D3E76860032C5A0 /* Drink🥤.json in Resources */,
 				A83404DB2D9D382200C140E4 /* AccentURW-Reg.ttf in Resources */,
+				A82542D72E279C5100F54FE5 /* Anime Me.mp4 in Resources */,
 				A82D607D2DB7748800596190 /* ai_expand_image_style.json in Resources */,
 				A8F413642DAA6F8C001E715A /* ai_change_hair_style.json in Resources */,
 				A80EDE082D700395003CD332 /* rotatingAnimation_1.gif in Resources */,
@@ -2557,6 +2672,7 @@
 				A89EA6582D59A9F4000EB181 /* TSLayoutSizeCalculator.swift in Sources */,
 				A83404DD2D9E1D8C00C140E4 /* ImagesAnimateScrollView.swift in Sources */,
 				A8708A412E0B93E400601686 /* TSAIGenerateBaseVC+Image.swift in Sources */,
+				A82542D22E27996900F54FE5 /* TSVideoPlayer.swift in Sources */,
 				A89EA6592D59A9F4000EB181 /* CustomMessageFlowLayout.swift in Sources */,
 				A8FD8F2D2DFAD6C6008CAACF /* CustomActivityItemProvider.swift in Sources */,
 				A80E72792D42285500C64288 /* TSBootPageVC.swift in Sources */,
@@ -2575,6 +2691,7 @@
 				A80E726F2D40DE2B00C64288 /* TSWallpaperPreviewVC.swift in Sources */,
 				A8EB38382E137F48002F90E9 /* TSPurchasePromotionalVC.swift in Sources */,
 				A8F775492D3935D600AA6E93 /* TSBusinessWebVC.swift in Sources */,
+				A8BD92C82E29F8FF0014C3C5 /* TSDiscoverViewModel+Data.swift in Sources */,
 				A8F776392D3B38E600AA6E93 /* TSGenmojiGennerateVC.swift in Sources */,
 				A85E47C02D6961BB0018D62D /* TSChatMessageUIModel.swift in Sources */,
 				A8F774E02D38EA8C00AA6E93 /* TSCommonTool.swift in Sources */,
@@ -2583,6 +2700,7 @@
 				A80327C52D81584500AF7878 /* TSGeneralBtnView.swift in Sources */,
 				A8F7762F2D3A765400AA6E93 /* TSGenmojiViewModel.swift in Sources */,
 				A8F7751B2D38EC9800AA6E93 /* TSGenmojiVC.swift in Sources */,
+				A807E63A2E29056600A175AF /* TSDiscoverBannerCell.swift in Sources */,
 				A80EDD462D6C3F82003CD332 /* MarkdownEscaping.swift in Sources */,
 				A80EDD472D6C3F82003CD332 /* MarkdownItalic.swift in Sources */,
 				A80EDD482D6C3F82003CD332 /* MarkdownBold.swift in Sources */,
@@ -2597,6 +2715,7 @@
 				A80EDD4F2D6C3F82003CD332 /* MarkdownParser+UIKit.swift in Sources */,
 				A8990EEC2DEE8EED00DD55FE /* TSPredictBabyStyleView.swift in Sources */,
 				A88508882DBCD944000FBCEC /* MemoryLeakChecker.swift in Sources */,
+				A807E6322E28ECC200A175AF /* TSUploadVideoView.swift in Sources */,
 				A8F4134A2DA75863001E715A /* TSUploadPhotoPrivacyAlertVC.swift in Sources */,
 				A80EDD502D6C3F82003CD332 /* MarkdownFont+Traits.swift in Sources */,
 				A80EDD512D6C3F82003CD332 /* MarkdownCode.swift in Sources */,
@@ -2615,6 +2734,7 @@
 				A80EDD592D6C3F82003CD332 /* MarkdownLink+UIKit.swift in Sources */,
 				A8D6384A2DB252F100A96C0E /* TSAIListHistoryBaseCell.swift in Sources */,
 				A80EDD5A2D6C3F82003CD332 /* MarkdownParser.swift in Sources */,
+				A807E6302E288AF100A175AF /* VideoFrameExtractor.swift in Sources */,
 				A80EDD5B2D6C3F82003CD332 /* MarkdownCommonElement.swift in Sources */,
 				A8EB38482E140848002F90E9 /* TSPurchaseCountdownView.swift in Sources */,
 				A82D60792DB7703D00596190 /* TSAIExpandImageVC.swift in Sources */,
@@ -2725,6 +2845,7 @@
 				A80E72272D3F3A9A00C64288 /* DiyTextElement.swift in Sources */,
 				A8FB02BA2D3E3BB20031A396 /* TSEmojisCoLItemCell.swift in Sources */,
 				A87587182D81814500286A66 /* TSAIThinkingView.swift in Sources */,
+				A82542D42E279C0200F54FE5 /* TSDiscoverViewModel.swift in Sources */,
 				A85E47962D672ADA0018D62D /* TSTextPicGennerateVC.swift in Sources */,
 				A82D60A02DBA1B0500596190 /* TSImageGenerateView.swift in Sources */,
 				A80E72562D3F98D700C64288 /* TSDiyKeyboardViewVC.swift in Sources */,
@@ -2743,7 +2864,6 @@
 				A83404D32D9D23FA00C140E4 /* TSGeneratorloadingView.swift in Sources */,
 				A8F776372D3A806E00AA6E93 /* TSGenmojiItemCell.swift in Sources */,
 				A89EA6692D59AA31000EB181 /* CameraInputBarAccessoryView.swift in Sources */,
-				A8B70BC62E06B9D7003177FA /* TSDiscoverViewModel.swift in Sources */,
 				A89EA66B2D59AA31000EB181 /* TSTextMessageContentCell.swift in Sources */,
 				605E205B2DCCB8D20069F4B6 /* TSCustomAlertController+Ext.swift in Sources */,
 				A8B70BD22E08F2F4003177FA /* TSGenerateBaseOperation.swift in Sources */,
@@ -2873,7 +2993,7 @@
 				ENABLE_USER_SCRIPT_SANDBOXING = NO;
 				GENERATE_INFOPLIST_FILE = YES;
 				INFOPLIST_FILE = AIEmoji/Info.plist;
-				INFOPLIST_KEY_CFBundleDisplayName = Picguru;
+				INFOPLIST_KEY_CFBundleDisplayName = Aurart;
 				INFOPLIST_KEY_NSPhotoLibraryUsageDescription = "Allow us to access photos to upload your photos to generate new styles.";
 				INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
 				INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen;
@@ -2884,7 +3004,7 @@
 					"$(inherited)",
 					"@executable_path/Frameworks",
 				);
-				MARKETING_VERSION = 3.6.22;
+				MARKETING_VERSION = 3.6.23;
 				PRODUCT_BUNDLE_IDENTIFIER = com.girl.music.wallpaper;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
@@ -2912,7 +3032,7 @@
 				ENABLE_USER_SCRIPT_SANDBOXING = NO;
 				GENERATE_INFOPLIST_FILE = YES;
 				INFOPLIST_FILE = AIEmoji/Info.plist;
-				INFOPLIST_KEY_CFBundleDisplayName = Picguru;
+				INFOPLIST_KEY_CFBundleDisplayName = Aurart;
 				INFOPLIST_KEY_NSPhotoLibraryUsageDescription = "Allow us to access photos to upload your photos to generate new styles.";
 				INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
 				INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen;
@@ -2923,7 +3043,7 @@
 					"$(inherited)",
 					"@executable_path/Frameworks",
 				);
-				MARKETING_VERSION = 3.6.22;
+				MARKETING_VERSION = 3.6.23;
 				PRODUCT_BUNDLE_IDENTIFIER = com.girl.music.wallpaper;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";

+ 22 - 0
AIEmoji/Assets.xcassets/AIList/hint/hint_kiss_badImage.imageset/Contents.json

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

BIN
AIEmoji/Assets.xcassets/AIList/hint/hint_kiss_badImage.imageset/hint_kiss_badImage@2x.png


BIN
AIEmoji/Assets.xcassets/AIList/hint/hint_kiss_badImage.imageset/hint_kiss_badImage@3x.png


+ 22 - 0
AIEmoji/Assets.xcassets/AIList/hint/hint_oscar_badImage.imageset/Contents.json

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

BIN
AIEmoji/Assets.xcassets/AIList/hint/hint_oscar_badImage.imageset/hint_oscar_badImage@2x.png


BIN
AIEmoji/Assets.xcassets/AIList/hint/hint_oscar_badImage.imageset/hint_oscar_badImage@3x.png


+ 22 - 0
AIEmoji/Assets.xcassets/AIList/hint/hint_oscar_goodImage.imageset/Contents.json

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

BIN
AIEmoji/Assets.xcassets/AIList/hint/hint_oscar_goodImage.imageset/hint_oscar_goodImage@2x.png


BIN
AIEmoji/Assets.xcassets/AIList/hint/hint_oscar_goodImage.imageset/hint_oscar_goodImage@3x.png


+ 22 - 0
AIEmoji/Assets.xcassets/AIList/hint/hint_pet_badImage.imageset/Contents.json

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

BIN
AIEmoji/Assets.xcassets/AIList/hint/hint_pet_badImage.imageset/hint_pet_badImage@2x.png


BIN
AIEmoji/Assets.xcassets/AIList/hint/hint_pet_badImage.imageset/hint_pet_badImage@3x.png


+ 22 - 0
AIEmoji/Assets.xcassets/AIList/hint/hint_pet_goodImage.imageset/Contents.json

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

BIN
AIEmoji/Assets.xcassets/AIList/hint/hint_pet_goodImage.imageset/hint_pet_goodImage@2x.png


BIN
AIEmoji/Assets.xcassets/AIList/hint/hint_pet_goodImage.imageset/hint_pet_goodImage@3x.png


+ 22 - 0
AIEmoji/Assets.xcassets/AIList/hint/hint_singleMmultiple_badImage.imageset/Contents.json

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

BIN
AIEmoji/Assets.xcassets/AIList/hint/hint_singleMmultiple_badImage.imageset/hint_singleMmultiple_badImage@2x.png


BIN
AIEmoji/Assets.xcassets/AIList/hint/hint_singleMmultiple_badImage.imageset/hint_singleMmultiple_badImage@3x.png


+ 22 - 0
AIEmoji/Assets.xcassets/AIList/hint/hint_singleMmultiple_goodImage.imageset/Contents.json

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

BIN
AIEmoji/Assets.xcassets/AIList/hint/hint_singleMmultiple_goodImage.imageset/hint_singleMmultiple_goodImage@2x.png


BIN
AIEmoji/Assets.xcassets/AIList/hint/hint_singleMmultiple_goodImage.imageset/hint_singleMmultiple_goodImage@3x.png


+ 22 - 0
AIEmoji/Assets.xcassets/Discover/discover_bannerl_shaow.imageset/Contents.json

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

BIN
AIEmoji/Assets.xcassets/Discover/discover_bannerl_shaow.imageset/discover_bmall_shaow@2x.png


BIN
AIEmoji/Assets.xcassets/Discover/discover_bannerl_shaow.imageset/discover_bmall_shaow@3x.png


+ 6 - 0
AIEmoji/Assets.xcassets/Discover/video/Contents.json

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

+ 21 - 0
AIEmoji/Assets.xcassets/Discover/video/ptp_style_WalkingwithBeasts.imageset/Contents.json

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

BIN
AIEmoji/Assets.xcassets/Discover/video/ptp_style_WalkingwithBeasts.imageset/ptp_style_WalkingwithBeasts@2x.png


+ 21 - 0
AIEmoji/Assets.xcassets/Discover/video/video_style_AnimalDivingShow.imageset/Contents.json

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

BIN
AIEmoji/Assets.xcassets/Discover/video/video_style_AnimalDivingShow.imageset/video_style_AnimalDivingShow@2x.png


+ 21 - 0
AIEmoji/Assets.xcassets/Discover/video/video_style_AnimeMe.imageset/Contents.json

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

BIN
AIEmoji/Assets.xcassets/Discover/video/video_style_AnimeMe.imageset/video_style_AnimeMe@2x.png


+ 21 - 0
AIEmoji/Assets.xcassets/Discover/video/video_style_Fairy.imageset/Contents.json

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

BIN
AIEmoji/Assets.xcassets/Discover/video/video_style_Fairy.imageset/video_style_Fairy@2x.png


+ 21 - 0
AIEmoji/Assets.xcassets/Discover/video/video_style_Fly.imageset/Contents.json

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

BIN
AIEmoji/Assets.xcassets/Discover/video/video_style_Fly.imageset/video_style_Fly@2x.png


+ 21 - 0
AIEmoji/Assets.xcassets/Discover/video/video_style_FrenchKiss.imageset/Contents.json

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

BIN
AIEmoji/Assets.xcassets/Discover/video/video_style_FrenchKiss.imageset/video_style_FrenchKiss@2x.png


+ 21 - 0
AIEmoji/Assets.xcassets/Discover/video/video_style_FunnyPet.imageset/Contents.json

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

BIN
AIEmoji/Assets.xcassets/Discover/video/video_style_FunnyPet.imageset/video_style_FunnyPet@2x.png


+ 21 - 0
AIEmoji/Assets.xcassets/Discover/video/video_style_Grabdoll.imageset/Contents.json

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

BIN
AIEmoji/Assets.xcassets/Discover/video/video_style_Grabdoll.imageset/video_style_Grabdoll@2x.png


+ 21 - 0
AIEmoji/Assets.xcassets/Discover/video/video_style_HappyBirthday.imageset/Contents.json

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

BIN
AIEmoji/Assets.xcassets/Discover/video/video_style_HappyBirthday.imageset/video_style_HappyBirthday@2x.png


+ 21 - 0
AIEmoji/Assets.xcassets/Discover/video/video_style_Hulk.imageset/Contents.json

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

BIN
AIEmoji/Assets.xcassets/Discover/video/video_style_Hulk.imageset/video_style_Hulk@2x.png


+ 21 - 0
AIEmoji/Assets.xcassets/Discover/video/video_style_Lafufu.imageset/Contents.json

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

BIN
AIEmoji/Assets.xcassets/Discover/video/video_style_Lafufu.imageset/video_style_Lafufu@2x.png


+ 21 - 0
AIEmoji/Assets.xcassets/Discover/video/video_style_MakingFace.imageset/Contents.json

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

BIN
AIEmoji/Assets.xcassets/Discover/video/video_style_MakingFace.imageset/video_style_MakingFace@2x.png


+ 21 - 0
AIEmoji/Assets.xcassets/Discover/video/video_style_Mermaid.imageset/Contents.json

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

BIN
AIEmoji/Assets.xcassets/Discover/video/video_style_Mermaid.imageset/video_style_Mermaid@2x.png


+ 21 - 0
AIEmoji/Assets.xcassets/Discover/video/video_style_MuscleUp.imageset/Contents.json

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

BIN
AIEmoji/Assets.xcassets/Discover/video/video_style_MuscleUp.imageset/video_style_MuscleUp@2x.png


+ 21 - 0
AIEmoji/Assets.xcassets/Discover/video/video_style_OscarGala.imageset/Contents.json

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

BIN
AIEmoji/Assets.xcassets/Discover/video/video_style_OscarGala.imageset/video_style_OscarGala@2x.png


+ 21 - 0
AIEmoji/Assets.xcassets/Discover/video/video_style_PettoHuman.imageset/Contents.json

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

BIN
AIEmoji/Assets.xcassets/Discover/video/video_style_PettoHuman.imageset/video_style_PettoHuman@2x.png


+ 21 - 0
AIEmoji/Assets.xcassets/Discover/video/video_style_PhotoAnimater.imageset/Contents.json

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

BIN
AIEmoji/Assets.xcassets/Discover/video/video_style_PhotoAnimater.imageset/video_style_PhotoAnimater@2x.png


+ 21 - 0
AIEmoji/Assets.xcassets/Discover/video/video_style_Pinch.imageset/Contents.json

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

BIN
AIEmoji/Assets.xcassets/Discover/video/video_style_Pinch.imageset/video_style_Pinch@2x.png


+ 21 - 0
AIEmoji/Assets.xcassets/Discover/video/video_style_Robot.imageset/Contents.json

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

BIN
AIEmoji/Assets.xcassets/Discover/video/video_style_Robot.imageset/video_style_Robot@2x.png


+ 21 - 0
AIEmoji/Assets.xcassets/Discover/video/video_style_SurpriseFlower.imageset/Contents.json

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

BIN
AIEmoji/Assets.xcassets/Discover/video/video_style_SurpriseFlower.imageset/video_style_SurpriseFlower@2x.png


+ 21 - 0
AIEmoji/Assets.xcassets/Discover/video/video_style_ToyMe.imageset/Contents.json

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

BIN
AIEmoji/Assets.xcassets/Discover/video/video_style_ToyMe.imageset/video_style_ToyMe@2x.png


+ 22 - 0
AIEmoji/Assets.xcassets/Discover/video_mute.imageset/Contents.json

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

BIN
AIEmoji/Assets.xcassets/Discover/video_mute.imageset/video_mute@2x.png


BIN
AIEmoji/Assets.xcassets/Discover/video_mute.imageset/video_mute@3x.png


+ 22 - 0
AIEmoji/Assets.xcassets/Discover/video_sound.imageset/Contents.json

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

BIN
AIEmoji/Assets.xcassets/Discover/video_sound.imageset/video_Sound@2x.png


BIN
AIEmoji/Assets.xcassets/Discover/video_sound.imageset/video_Sound@3x.png


+ 4 - 0
AIEmoji/Business/General/Ex/Notification+Ex.swift

@@ -30,4 +30,8 @@ extension Notification.Name {
     
     static let kCloseTSPurchaseVC = Notification.Name("kCloseTSPurchaseVC")   //关闭了订阅页
     static let kCloseTSPurchasePromotionalVC = Notification.Name("kCloseTSPurchasePromotionalVC")   //关闭了优惠订阅页
+    
+    
+    static let kDiscoverScrollViewWillBegin = Notification.Name("kDiscoverScrollViewWillBegin")   //关闭了订阅页
+    static let kDiscoverScrollViewEndDecelerating = Notification.Name("kDiscoverScrollViewEndDecelerating")   //关闭了优惠订阅页
 }

+ 83 - 1
AIEmoji/Business/TSAILIstVC/TSAIAgeImageHintVC/TSAIListHintBaseVC.swift

@@ -23,7 +23,7 @@ class TSAIListHintBaseVC: TSBaseVC {
         var badText:String
         var badInfoText:String
         
-        
+       
         init(imageMaxBitSize: Int, goodImageNamed: String, badImageNamed: String, titleText: String, titleSubText: String, goodText: String, goodInfoText: String, badText: String, badInfoText: String) {
             self.imageMaxBitSize = imageMaxBitSize
             self.goodImageNamed = goodImageNamed
@@ -90,6 +90,88 @@ class TSAIListHintBaseVC: TSBaseVC {
                           badText: "Bad photo examples".localized,
                           badInfoText: "Group photos, covered faces, nudes".localized)
         }
+        //宠物
+        static var petConfig:Config {
+            return Config(imageMaxBitSize: kUploadImageMaxBit10Size,
+                          goodImageNamed: "hint_pet_goodImage",
+                          badImageNamed: "hint_pet_badImage",
+                          titleText: "Upload your photos".localized,
+                          titleSubText: "",
+                          goodText: "Good photo examples".localized,
+                          goodInfoText:"•" + "Front view of single pet".localized + "\n" + "•" + "Show upper or full body".localized,
+                          badText: "Bad photo examples".localized,
+                          badInfoText: "•" + "Not a single pet".localized
+            )
+        }
+        
+        
+        //单人
+        static var singlePersonConfig:Config {
+            return Config(imageMaxBitSize: kUploadImageMaxBit10Size,
+                          goodImageNamed: "ptp_futureBaby_goodImage",
+                          badImageNamed: "ptp_badImage",
+                          titleText: "Upload your photos".localized,
+                          titleSubText: "",
+                          goodText: "Good photo examples".localized,
+                          goodInfoText: "•" + "Front view of one person with clear face".localized + "\n" + "•" + "Show upper or full body".localized,
+                          badText: "Bad photo examples".localized,
+                          badInfoText: "•" + "2+ subjects or covered face".localized
+            )
+        }
+            
+        //单人或多人SingleMmultiplePeople
+        static var singleMmultiplePeopleConfig:Config {
+            return Config(imageMaxBitSize: kUploadImageMaxBit10Size,
+                          goodImageNamed: "hint_singleMmultiple_goodImage",
+                          badImageNamed: "hint_singleMmultiple_badImage",
+                          titleText: "Upload your photos".localized,
+                          titleSubText: "",
+                          goodText: "Good photo examples".localized,
+                          goodInfoText: "•" + "Two similar-height people showing upper bodies".localized + "\n" + "•" + "No props in hands".localized,
+                          badText: "Bad photo examples".localized,
+                          badInfoText: "•" + "Single person or large height differences".localized
+            )
+        }
+        
+        //亲吻
+        static var kissConfig:Config {
+            return Config(imageMaxBitSize: kUploadImageMaxBit10Size,
+                          goodImageNamed: "hint_singleMmultiple_goodImage",
+                          badImageNamed: "hint_kiss_badImage",
+                          titleText: "Upload your photos".localized,
+                          titleSubText: "",
+                          goodText: "Good photo examples".localized,
+                          goodInfoText: "•" + "Two similar-height people showing upper bodies".localized + "\n" + "•" + "No props in hands".localized,
+                          badText: "Bad photo examples".localized,
+                          badInfoText: "•" + "Single person or large height differences".localized
+            )
+        }
+        
+        //亲吻
+        static var oscarConfig:Config {
+            return Config(imageMaxBitSize: kUploadImageMaxBit10Size,
+                          goodImageNamed: "hint_oscar_goodImage",
+                          badImageNamed: "hint_oscar_badImage",
+                          titleText: "Upload your photos".localized,
+                          titleSubText: "",
+                          goodText: "Good photo examples".localized,
+                          goodInfoText: "•" + "Close-up photo from shoulders upward".localized + "\n" + "•" + "No visible clothing".localized,
+                          badText: "Bad photo examples".localized,
+                          badInfoText: "•" + "Covered or unclear face, full-body photo".localized
+            )
+        }
+        
+        
+        static func getConfig(hint:Int)->Config{
+            switch hint {
+            case 1:return .petConfig
+            case 2:return .singlePersonConfig
+            case 3:return .singleMmultiplePeopleConfig
+            case 4:return .kissConfig
+            case 5:return .oscarConfig
+            default:return .singleMmultiplePeopleConfig
+            }
+        }
     }
     
     var config:Config = Config.defaultConfig

+ 26 - 3
AIEmoji/Business/TSAILIstVC/TSAIListVideoPlayerVC/TSAIListVideoPlayerVC.swift

@@ -42,6 +42,18 @@ class TSAIListVideoPlayerVC: UIViewController {
         return button
     }()
     
+    
+    lazy var mutedButton: TSUIExpandedTouchButton = {
+        let touchButton = TSUIExpandedTouchButton()
+        touchButton.setUpButton(image:.videoMute){ [weak self]  in
+            guard let self = self else { return }
+            touchButton.isSelected = !touchButton.isSelected
+            self.player?.isMuted = !touchButton.isSelected
+        }
+        touchButton.setImage(.videoSound, for: .selected)
+        touchButton.isSelected = true
+        return touchButton
+    }()
 
     private lazy var progressSlider: TSProgressSlider = {
         let slider = TSProgressSlider()
@@ -91,7 +103,8 @@ class TSAIListVideoPlayerVC: UIViewController {
     
     func dealThings() {
         // 监听应用生命周期事件
-        NotificationCenter.default.addObserver(forName: UIApplication.didEnterBackgroundNotification, object: nil, queue: .main) { _ in
+        NotificationCenter.default.addObserver(forName: UIApplication.didEnterBackgroundNotification, object: nil, queue: .main) { [weak self] _ in
+            guard let self = self else { return }
             self.playPause()
             self.setControlsView(isHidden: false)
         }
@@ -105,6 +118,8 @@ class TSAIListVideoPlayerVC: UIViewController {
     
     deinit {
         removePeriodicTimeObserver()
+        NotificationCenter.default.removeObserver(self)
+        debugPrint("♻️♻️♻️ TSAIListVideoPlayerVC deinit ♻️♻️♻️")
     }
     
     @objc private func clickBgView() {
@@ -144,11 +159,19 @@ class TSAIListVideoPlayerVC: UIViewController {
         controlsContainerView.addSubview(progressSlider)
         controlsContainerView.addSubview(currentTimeLabel)
         controlsContainerView.addSubview(durationLabel)
+        controlsContainerView.addSubview(mutedButton)
+        
+        mutedButton.snp.makeConstraints { make in
+            make.width.height.equalTo(32)
+            make.right.equalTo(-14)
+            make.top.equalTo(0)
+        }
         
         progressSlider.snp.makeConstraints { make in
             make.left.equalTo(16)
             make.right.equalTo(-16)
-            make.top.equalTo(0)
+//            make.top.equalTo(0)
+            make.top.equalTo(mutedButton.snp.bottom).offset(20)
             make.height.equalTo(10)
         }
         
@@ -283,7 +306,7 @@ class TSAIListVideoPlayerVC: UIViewController {
         }
     }
     
-    private func removePeriodicTimeObserver() {
+    func removePeriodicTimeObserver() {
         if let token = timeObserverToken {
             player?.removeTimeObserver(token)
             timeObserverToken = nil

+ 4 - 0
AIEmoji/Business/TSAILIstVC/TSAIPhotoGeneratorBaseVC/TSAIListPhotoGeneratorBaseVC.swift

@@ -263,6 +263,10 @@ class TSAIListPhotoGeneratorBaseVC: TSAIPhotoGeneratorBaseVC {
         }.store(in: &cancellable)
     }
     
+    deinit {
+
+    }
+    
 }
 
 extension TSAIListPhotoGeneratorBaseVC {

+ 7 - 1
AIEmoji/Business/TSAILIstVC/TSAIUploadPhotoBaseVC/TSAIUploadPhotoBaseVC.swift

@@ -315,7 +315,13 @@ extension TSAIUploadPhotoBaseVC {
     }
     
     func pickSinglePhoto()  {
-        enterSelectPhotos(userDefaultsKey: generatorStyle.userDefaultsKey, maxBitSize: generatorStyle.imageMaxBitSize, config: generatorStyle.config) { [weak self] image in
+        
+        var config:TSAIListHintBaseVC.Config = generatorStyle.config
+        if generatorStyle == .videoV2 || generatorStyle == .photoLive {
+            config = TSAIListHintBaseVC.Config.getConfig(hint: disCoverItemModel?.generateModel?.hintType ?? 0)
+        }
+        
+        enterSelectPhotos(userDefaultsKey: generatorStyle.userDefaultsKey, maxBitSize: generatorStyle.imageMaxBitSize, config: config) { [weak self] image in
                 guard let self = self else { return }
             upLoadImage = image
         }

+ 6 - 4
AIEmoji/Business/TSPTPGeneratorVC/TSAIPhotoGeneratorBaseVC/TSAIPhotoBrowseVC.swift

@@ -340,10 +340,7 @@ extension TSAIPhotoBrowseVC:UICollectionViewDataSource,UICollectionViewDelegate
         if let model = dataModelArray[safe:indexPath.item]{
             if model.isVideo {
                 guard let cell = cell as? TSAIVideoBrowseCell else { return }
-                cell.model = model.getModel()
-            }else{
-                guard let cell = cell as? TSAIPhotoBrowseCell else { return }
-                cell.model = model.getModel()
+                cell.videoPlayerVC?.runloppPlay()
             }
         }
     }
@@ -443,6 +440,8 @@ class TSAIVideoBrowseCell : TSBaseCollectionCell{
     var model:TSActionInfoModel = TSActionInfoModel(){
         didSet{
             self.videoPlayerVC?.view.removeFromSuperview()
+            self.bgContentView.removeAllSubViews()
+            self.videoPlayerVC = nil
             self.videoPlayerVC = TSAIListVideoPlayerVC(videoURL: self.model.videoURL)
             self.bgContentView.addSubview(self.videoPlayerVC!.view)
             self.videoPlayerVC!.view.snp.remakeConstraints { make in
@@ -453,4 +452,7 @@ class TSAIVideoBrowseCell : TSBaseCollectionCell{
             self.videoPlayerVC?.runloppPlay()
         }
     }
+    
+    deinit {
+    }
 }

+ 2 - 1
AIEmoji/Business/TSPTPGeneratorVC/TSPhotoToPhotoVC/M/TSPTPStyleModel.swift

@@ -18,7 +18,7 @@ class TSGenerateModel: TSBaseModel {
     var input:Bool = false   //是否输入框
     var model:String = ""       //走新的通道,根据内容确定
     var unionType:Int = 0 //聚合类型,相同的为一类
-    
+    var hintType:Int = 1 // 提示上传图片类型
     override func mapping(map: ObjectMapper.Map) {
         imageName               <- map["imageName"]
         imageText               <- map["imageText"]
@@ -28,6 +28,7 @@ class TSGenerateModel: TSBaseModel {
         input                   <- map["input"]
         model                   <- map["model"]
         unionType               <- map["unionType"]
+        hintType                <- map["hintType"]
     }
     
 }

+ 3 - 0
AIEmoji/Business/TSTextGeneralPictureVC/TSTTPInputVC/View/TSTitleView.swift

@@ -36,6 +36,9 @@ class TSTitleView: TSBaseView {
             make.leading.equalTo(titleLab.snp.trailing).offset(kSectionTitleViewCenterYOffset)
             make.centerY.equalTo(titleLab)
         }
+        
+        contentView.setNeedsLayout()
+        contentView.setNeedsDisplay()
     }
 }
 

+ 240 - 0
AIEmoji/Business2/CommonVC/TSVideoPlayer/TSVideoPlayer.swift

@@ -0,0 +1,240 @@
+//
+//  TSVideoPlayer.swift
+//  AIEmoji
+//
+//  Created by 100Years on 2025/7/16.
+//
+
+class AVPlayerPool {
+    private static var pool: [URL: AVPlayer] = [:]
+    private static let lock = NSLock()
+    
+    static func player(for url: URL) -> AVPlayer {
+        lock.lock()
+        defer { lock.unlock() }
+        
+        // 查找可复用的播放器
+        if let player = pool[url] {
+            player.seek(to: .zero)
+            return player
+        }
+        
+        // 创建新播放器
+        let asset = AVAsset(url: url)
+        let playerItem = AVPlayerItem(asset: asset)
+        let player = AVPlayer(playerItem: playerItem)
+        pool[url] = player
+        
+        // 设置自动清理
+        NotificationCenter.default.addObserver(
+            forName: .AVPlayerItemDidPlayToEndTime,
+            object: playerItem,
+            queue: nil
+        ) { _ in
+            player.seek(to: .zero)
+        }
+        
+        return player
+    }
+    
+    static func releasePlayer(for url: URL) {
+        lock.lock()
+        defer { lock.unlock() }
+        pool[url]?.pause()
+        pool[url] = nil
+    }
+}
+
+import AVKit
+class TSVideoPlayer:NSObject {
+    var player: AVPlayer?
+    var playerLayer: AVPlayerLayer?
+    var playerItem: AVPlayerItem?
+    var loopInterval: TimeInterval = 0
+    private var timer: Timer?
+    private var isBackgroundPaused = false
+    
+    // 播放状态回调
+    var onPlaybackStart: (() -> Void)?
+    var onPlaybackEnd: (() -> Void)?
+    
+    // 最大同时播放数限制
+    private static var activePlayers = 0
+    private static let maxActivePlayers = 100 // 同时最多2个播放器
+    
+    var url:URL?
+    deinit {
+        cleanup()
+    }
+    
+    func setupPlayer(with url: URL) {
+        // 检查是否超过最大播放器数量
+        guard Self.activePlayers < Self.maxActivePlayers else {
+            print("已达到最大播放器数量限制")
+            return
+        }
+        self.url = url
+        
+        playerItem = AVPlayerItem(asset: AVURLAsset(url: url, options: [AVURLAssetPreferPreciseDurationAndTimingKey: false]))
+        
+        player = AVPlayer(playerItem: playerItem)
+        player?.volume = 0.5
+        player?.isMuted = true // 静音播放减少资源占用
+        player?.actionAtItemEnd = .pause
+
+        playerLayer = AVPlayerLayer(player: player)
+        playerLayer?.videoGravity = .resizeAspectFill
+        playerLayer?.shouldRasterize = true
+        playerLayer?.rasterizationScale = UIScreen.main.scale
+        
+        
+        // 设置音频会话
+        do {
+            let audioSession = AVAudioSession.sharedInstance()
+            try audioSession.setCategory(.playback)
+            try audioSession.setActive(true)
+        } catch {
+            print("TSAudioPlayer 音频会话设置失败: \(error.localizedDescription)")
+        }
+        
+        setupNotifications()
+        Self.activePlayers += 1
+    }
+    
+    func replaceUrl(with url: URL) {
+        playerItem = AVPlayerItem(asset: AVURLAsset(url: url, options: [AVURLAssetPreferPreciseDurationAndTimingKey: false]))
+        player?.replaceCurrentItem(with: playerItem)
+    }
+    private func setupNotifications() {
+        NotificationCenter.default.addObserver(
+            self,
+            selector: #selector(playerItemDidReachEnd),
+            name: .AVPlayerItemDidPlayToEndTime,
+            object: playerItem
+        )
+        
+        NotificationCenter.default.addObserver(
+            self,
+            selector: #selector(applicationDidEnterBackground),
+            name: UIApplication.didEnterBackgroundNotification,
+            object: nil
+        )
+        
+        NotificationCenter.default.addObserver(
+            self,
+            selector: #selector(applicationWillEnterForeground),
+            name: UIApplication.willEnterForegroundNotification,
+            object: nil
+        )
+        
+    }
+    
+    static func getFirstFrameOnly(url:URL)->UIImage? {
+        let urlString = "TSVideoPlayer/" + url.lastPathComponent
+        
+        if let image = TSImageStoreTool.retrieveImageInMemoryCache(urlString: urlString) {
+            dePrint("从缓存中取图片")
+            return image
+        }
+
+        
+        let asset = AVAsset(url: url)
+        let generator = AVAssetImageGenerator(asset: asset)
+        generator.appliesPreferredTrackTransform = true
+        
+        do {
+            let cgImage = try generator.copyCGImage(at: CMTime(seconds: 0, preferredTimescale: 1), actualTime: nil)
+            let image = UIImage(cgImage: cgImage)
+            TSImageStoreTool.storeImage(image: image, urlString: urlString)
+            return image
+        } catch {
+            dePrint("获取第一帧失败: \(error)")
+        }
+        
+        return nil
+    }
+    
+    @objc private func applicationDidEnterBackground() {
+        if player?.rate != 0 {
+            isBackgroundPaused = true
+            pause()
+        }
+    }
+    
+    @objc private func applicationWillEnterForeground() {
+        if isBackgroundPaused {
+            play()
+            isBackgroundPaused = false
+        }
+    }
+    
+    @objc private func playerItemDidReachEnd(notification: Notification) {
+        onPlaybackEnd?()
+        
+        if loopInterval > 0 {
+            timer?.invalidate()
+            timer = Timer.scheduledTimer(
+                withTimeInterval: loopInterval,
+                repeats: false,
+                block: { [weak self] _ in
+                    self?.restartPlayback()
+                }
+            )
+        } else {
+            restartPlayback()
+        }
+    }
+    
+    private func restartPlayback() {
+        player?.seek(to: .zero)
+        player?.play()
+        onPlaybackStart?()
+    }
+    
+    func addPlayerLayer(to view: UIView, frame: CGRect) {
+        guard let playerLayer = playerLayer else { return }
+        
+        playerLayer.frame = frame
+        view.layer.insertSublayer(playerLayer, at: 0)
+    }
+    
+    func play() {
+        playerLayer?.isHidden = false
+        // 检查是否超过最大播放器数量
+        guard Self.activePlayers < Self.maxActivePlayers else {
+            print("已达到最大播放器数量限制")
+            return
+        }
+        
+//        if player?.currentItem?.status == .readyToPlay {
+            player?.play()
+            onPlaybackStart?()
+//        }
+    }
+    
+    func pause() {
+        player?.pause()
+        playerLayer?.isHidden = true
+    }
+    
+    func stop() {
+        pause()
+        player?.seek(to: .zero)
+        timer?.invalidate()
+        timer = nil
+    }
+    
+    func cleanup() {
+        stop()
+        NotificationCenter.default.removeObserver(self)
+        self.playerLayer?.removeFromSuperlayer()
+        playerItem = nil
+        player = nil
+        playerLayer = nil
+        Self.activePlayers -= 1
+    }
+    
+    func updateFrame(_ frame: CGRect) {
+        playerLayer?.frame = frame
+    }
+}

+ 151 - 0
AIEmoji/Business2/CommonVC/TSVideoPlayer/VideoFrameExtractor.swift

@@ -0,0 +1,151 @@
+//
+//  VideoFrameExtractor.swift
+//  AIEmoji
+//
+//  Created by 100Years on 2025/7/16.
+//
+
+import AVFoundation
+import UIKit
+
+class VideoFrameExtractor {
+//    static func extractFrames(from url: URL, frameRate: Int = 10) async throws -> [UIImage] {
+//        var frames: [UIImage] = []
+//
+//        let asset = AVAsset(url: url)
+//        let duration = asset.duration
+//        let generator = AVAssetImageGenerator(asset: asset)
+//        generator.appliesPreferredTrackTransform = true
+//
+//        let totalFrames = Int(CMTimeGetSeconds(duration) * Double(frameRate))
+//        for i in 0..<totalFrames {
+//            let time = CMTime(seconds: Double(i) / Double(frameRate), preferredTimescale: 600)
+//            do {
+//                let cgImage = try generator.copyCGImage(at: time, actualTime: nil)
+//                frames.append(UIImage(cgImage: cgImage))
+//            } catch {
+//                print("⚠️ Failed to extract frame \(i): \(error)")
+//            }
+//        }
+//
+//        return frames
+//    }
+    
+    static func extractFrames(from url: URL, frameRate: Int = 10, maxSize: CGSize = CGSize(width: 150, height: 200)) async throws -> [UIImage] {
+        var frames: [UIImage] = []
+
+        let asset = AVAsset(url: url)
+        let duration = asset.duration
+        let generator = AVAssetImageGenerator(asset: asset)
+        generator.appliesPreferredTrackTransform = true
+        generator.maximumSize = maxSize  // ⬅️ 降低图像分辨率
+
+        let totalFrames = Int(CMTimeGetSeconds(duration) * Double(frameRate))
+        for i in 0..<totalFrames {
+            let time = CMTime(seconds: Double(i) / Double(frameRate), preferredTimescale: 600)
+            do {
+                let cgImage = try generator.copyCGImage(at: time, actualTime: nil)
+                frames.append(UIImage(cgImage: cgImage))
+            } catch {
+                print("⚠️ 忽略帧 \(i): \(error)")
+            }
+        }
+
+        return frames
+    }
+}
+
+
+import UIKit
+
+class VideoFrameCache {
+    static let shared = VideoFrameCache()
+    private let cacheDirectory: URL
+
+    init() {
+        let paths = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask)
+        self.cacheDirectory = paths[0].appendingPathComponent("VideoFrames")
+        try? FileManager.default.createDirectory(at: cacheDirectory, withIntermediateDirectories: true)
+    }
+
+    func cachePath(for videoName: String) -> URL {
+        return cacheDirectory.appendingPathComponent(videoName)
+    }
+
+    func save(frames: [UIImage], for videoName: String) {
+        let path = cachePath(for: videoName)
+        try? FileManager.default.createDirectory(at: path, withIntermediateDirectories: true)
+        for (i, image) in frames.enumerated() {
+            let data = image.pngData()
+            let file = path.appendingPathComponent("\(i).png")
+            try? data?.write(to: file)
+        }
+    }
+
+    func loadFrames(for videoName: String) -> [UIImage]? {
+        let path = cachePath(for: videoName)
+        guard FileManager.default.fileExists(atPath: path.path) else { return nil }
+
+        let files = (try? FileManager.default.contentsOfDirectory(at: path, includingPropertiesForKeys: nil)) ?? []
+        let images = files.sorted { $0.lastPathComponent < $1.lastPathComponent }
+        return images.compactMap { UIImage(contentsOfFile: $0.path) }
+    }
+}
+
+
+import UIKit
+
+class VideoAnimationView: UIImageView {
+    private var isPlaying = false
+    private var videoName: String = ""
+
+    /// 主方法:加载视频并播放
+    func loadAndPlay(
+        videoName: String,
+        frameRate: Int = 10,
+        repeatCount: Int = 0,
+        placeholder: UIImage? = nil,
+        bundle: Bundle = .main
+    ) {
+        self.videoName = videoName
+        self.image = placeholder  // 加载期间的占位图
+
+        // 1. 查缓存
+        if let cached = VideoFrameCache.shared.loadFrames(for: videoName) {
+            playFrames(cached, frameRate: frameRate, repeatCount: repeatCount)
+            return
+        }
+
+        // 2. 异步解码
+        Task {
+            guard let url = bundle.url(forResource: videoName, withExtension: nil) else {
+                print("❌ 视频不存在: \(videoName)")
+                return
+            }
+
+            do {
+                let frames = try await VideoFrameExtractor.extractFrames(from: url, frameRate: frameRate)
+                VideoFrameCache.shared.save(frames: frames, for: videoName)
+                DispatchQueue.main.async {
+                    self.playFrames(frames, frameRate: frameRate, repeatCount: repeatCount)
+                }
+            } catch {
+                print("❌ 解码失败: \(error)")
+            }
+        }
+    }
+
+    /// 播放提取的帧图
+    private func playFrames(_ frames: [UIImage], frameRate: Int, repeatCount: Int) {
+        self.animationImages = frames
+        self.animationDuration = Double(frames.count) / Double(frameRate)
+        self.animationRepeatCount = repeatCount
+        self.startAnimating()
+        isPlaying = true
+    }
+
+    func stop() {
+        stopAnimating()
+        isPlaying = false
+    }
+}

+ 555 - 0
AIEmoji/Business2/DisCover/Data/TSDiscoverViewModel+Data.swift

@@ -0,0 +1,555 @@
+//
+//  TSDiscoverViewModel+Data.swift
+//  AIEmoji
+//
+//  Created by 100Years on 2025/7/17.
+//
+
+//MARK: 组装数据
+let kTSDiscoverVM = TSDiscoverViewModel.shared
+class TSDiscoverViewModel {
+
+    static let shared:TSDiscoverViewModel = TSDiscoverViewModel()
+    
+    lazy var bannerSection: TSDiscoverSectionModel = {
+        let section = TSDiscoverSectionModel()
+        section.style = .banner
+        section.setTitle(title: "")
+        section.items = [[
+            TSDiscoverItemModel(style: .photoLive,
+                                viewModel: TSDiscoverAnimationItemVM(title: "",style: .video, imageNameds: ["Photo Animater.mp4"]),
+                                generateModel: TSGenerateModel(json: video_PhotoAnimater)),
+            TSDiscoverItemModel(style: .videoV2,
+                                viewModel: TSDiscoverAnimationItemVM(title: "",style: .video, imageNameds: ["Animal Diving Show.mp4"]),
+                                generateModel: TSGenerateModel(json: video_AnimalDivingShow)),
+            TSDiscoverItemModel(style: .videoV2,
+                                viewModel: TSDiscoverAnimationItemVM(title: "",style: .video, imageNameds: ["Oscar Gala.mp4"]),
+                                generateModel: TSGenerateModel(json: video_OscarGala)),
+        ]]
+        
+        return section
+    }()
+    
+    
+    lazy var videoEffectSection: TSDiscoverSectionModel = {
+        let section = TSDiscoverSectionModel()
+        section.style = .styleMore
+        section.setTitle(title: "🎞️ " + "Video Effect".localized,colors: ["#E7D1AB","#FFFFFF"])
+        section.items = [[
+            TSDiscoverItemModel(style: .videoV2,
+                                viewModel: TSDiscoverAnimationItemVM(title: "",style: .video, imageNameds: ["Mermaid.mp4"]),
+                                generateModel: TSGenerateModel(json: video_Mermaid)),
+            TSDiscoverItemModel(style: .videoV2,
+                                viewModel: TSDiscoverAnimationItemVM(title: "",style: .video, imageNameds: ["Fairy.mp4"]),
+                                generateModel: TSGenerateModel(json: video_Fairy)),
+            TSDiscoverItemModel(style: .videoV2,
+                                viewModel: TSDiscoverAnimationItemVM(title: "",style: .video, imageNameds: ["Happy Birthday.mp4"]),
+                                generateModel: TSGenerateModel(json: video_HappyBirthday)),
+            TSDiscoverItemModel(style: .videoV2,
+                                viewModel: TSDiscoverAnimationItemVM(title: "",style: .video, imageNameds: ["Surprise Flower.mp4"]),
+                                generateModel: TSGenerateModel(json: video_SurpriseFlower)),
+            TSDiscoverItemModel(style: .videoV2,
+                                viewModel: TSDiscoverAnimationItemVM(title: "",style: .video, imageNameds: ["Lafufu.mp4"]),
+                                generateModel: TSGenerateModel(json: video_Lafufu)),
+            TSDiscoverItemModel(style: .videoV2,
+                                viewModel: TSDiscoverAnimationItemVM(title: "",style: .video, imageNameds: ["Anime Me.mp4"]),
+                                generateModel: TSGenerateModel(json: video_AnimeMe)),
+            TSDiscoverItemModel(style: .videoV2,
+                                viewModel: TSDiscoverAnimationItemVM(title: "",style: .video, imageNameds: ["Pet to Human.mp4"]),
+                                generateModel: TSGenerateModel(json: video_PettoHuman)),
+            TSDiscoverItemModel(style: .videoV2,
+                                viewModel: TSDiscoverAnimationItemVM(title: "",style: .video, imageNameds: ["Making Face.mp4"]),
+                                generateModel: TSGenerateModel(json: video_MakingFace)),
+            TSDiscoverItemModel(style: .videoV2,
+                                viewModel: TSDiscoverAnimationItemVM(title: "",style: .video, imageNameds: ["Robot.mp4"]),
+                                generateModel: TSGenerateModel(json: video_Robot)),
+            TSDiscoverItemModel(style: .videoV2,
+                                viewModel: TSDiscoverAnimationItemVM(title: "",style: .video, imageNameds: ["Walking with Beasts.mp4"]),
+                                generateModel: TSGenerateModel(json: video_WalkingwithBeasts)),
+            TSDiscoverItemModel(style: .videoV2,
+                                viewModel: TSDiscoverAnimationItemVM(title: "",style: .video, imageNameds: ["Funny Pet.mp4"]),
+                                generateModel: TSGenerateModel(json: video_FunnyPet)),
+            TSDiscoverItemModel(style: .videoV2,
+                                viewModel: TSDiscoverAnimationItemVM(title: "",style: .video, imageNameds: ["Fly.mp4"]),
+                                generateModel: TSGenerateModel(json: video_Fly)),
+            TSDiscoverItemModel(style: .videoV2,
+                                viewModel: TSDiscoverAnimationItemVM(title: "",style: .video, imageNameds: ["Pinch.mp4"]),
+                                generateModel: TSGenerateModel(json: video_Pinch)),
+            TSDiscoverItemModel(style: .videoV2,
+                                viewModel: TSDiscoverAnimationItemVM(title: "",style: .video, imageNameds: ["Grab doll.mp4"]),
+                                generateModel: TSGenerateModel(json: video_Grabdoll)),
+            TSDiscoverItemModel(style: .videoV2,
+                                viewModel: TSDiscoverAnimationItemVM(title: "",style: .video, imageNameds: ["Toy Me.mp4"]),
+                                generateModel: TSGenerateModel(json: video_ToyMe)),
+            TSDiscoverItemModel(style: .videoV2,
+                                viewModel: TSDiscoverAnimationItemVM(title: "",style: .video, imageNameds: ["Hulk.mp4"]),
+                                generateModel: TSGenerateModel(json: video_Hulk)),
+            TSDiscoverItemModel(style: .videoV2,
+                                viewModel: TSDiscoverAnimationItemVM(title: "",style: .video, imageNameds: ["MuscleUp.mp4"]),
+                                generateModel: TSGenerateModel(json: video_MuscleUp)),
+            TSDiscoverItemModel(style: .videoV2,
+                                viewModel: TSDiscoverAnimationItemVM(title: "",style: .video, imageNameds: ["French Kiss.mp4"]),
+                                generateModel: TSGenerateModel(json: video_FrenchKiss))
+        ]]
+        
+        return section
+    }()
+    
+//    //顶部按钮功能(金刚区)
+//    lazy var topFuncSection:TSDiscoverSectionModel = {
+//        let section = TSDiscoverSectionModel()
+//        section.style = .funcItems
+//        section.items = [[
+////            TSDiscoverItemModel(style: .futureBaby,
+////                                viewModel: TSDiscoverBaseItemVM(title: "AI Baby", imageNamed: "discover_AIBaby"),
+////                                generateModel: TSFuncStyle.futureBaby.generateModel),
+//            TSDiscoverItemModel(style: .ttp,
+//                                viewModel: TSDiscoverBaseItemVM(title: "Text to Image", imageNamed: "discover_TextImage")),
+//            TSDiscoverItemModel(style: .chat,
+//                                viewModel: TSDiscoverBaseItemVM(title: "AI Assistant", imageNamed: "discover_AIAssistant")),
+//            TSDiscoverItemModel(style: .photoQuality,
+//                                viewModel: TSDiscoverBaseItemVM(title: "Enhance Photo", imageNamed: "discover_HD"),
+//                                generateModel: TSFuncStyle.oldPhoto.generateModel),
+//            TSDiscoverItemModel(style: .photoLive,
+//                                viewModel: TSDiscoverBaseItemVM(title: "Old Photo Animation", imageNamed: "discover_PredictOld"),
+//                                generateModel: TSFuncStyle.photoLive.generateModel),
+//        ]]
+//        return section
+//    }()
+
+    
+    lazy var popularStylesSection: TSDiscoverSectionModel = {
+        let section = TSDiscoverSectionModel()
+        section.style = .styleMore
+        
+        section.items = [[
+            TSDiscoverItemModel(style: .ptp,
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_ToonMe","discover_1_ToonMe"]),
+                                generateModel: TSGenerateModel(json: ptp_ToonMe)),
+            
+            TSDiscoverItemModel(style: .ptp,
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_ChibiSticker","discover_1_ChibiSticker"]),
+                                generateModel: TSGenerateModel(json: ptp_ChibiSticker)),
+            TSDiscoverItemModel(style: .ptp,
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Irasutoya","discover_1_Irasutoya"]),
+                                generateModel: TSGenerateModel(json: ptp_Irasutoya)),
+
+            TSDiscoverItemModel(style: .ptp,
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_BlytheDoll","discover_1_BlytheDoll"]),
+                                generateModel: TSGenerateModel(json: ptp_BlytheDoll)),
+            TSDiscoverItemModel(style: .ptp,
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Caricature","discover_1_Caricature"]),
+                                generateModel: TSGenerateModel(json: ptp_Caricature)),
+            
+            TSDiscoverItemModel(style: .ptp,
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Illustration","discover_1_Illustration"]),
+                                generateModel: TSGenerateModel(json: ptp_Illustration)),
+            TSDiscoverItemModel(style: .ptp,
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_90sAnime","discover_1_90sAnime"]),
+                                generateModel: TSGenerateModel(json: ptp_90sAnime)),
+            
+            TSDiscoverItemModel(style: .ptp,
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_FreshWatercolor","discover_1_FreshWatercolor"]),
+                                generateModel: TSGenerateModel(json: ptp_FreshWatercolor)),
+
+//            TSDiscoverItemModel(style: .ptp,
+//                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_FairyTail","discover_1_FairyTail"]),
+//                                generateModel: TSGenerateModel(json: ptp_FairyTail)),
+//            TSDiscoverItemModel(style: .ptp,
+//                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_TouhouSeries","discover_1_TouhouSeries"]),
+//                                generateModel: TSGenerateModel(json: ptp_TouhouSeries)),
+//            TSDiscoverItemModel(style: .ptp,
+//                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Anime","discover_1_Anime"]),
+//                                generateModel: TSGenerateModel(json: ptp_Anime)),
+        ]]
+        return section
+    }()
+    
+    
+    
+    lazy var petToHumanSection: TSDiscoverSectionModel = {
+        let section = TSDiscoverSectionModel()
+        section.style = .fullCard
+        section.items = [
+            TSDiscoverItemModel(style: .catTohuman,
+                                viewModel: TSDiscoverBaseItemVM(
+                                    title: "Pet Humanization".localized,
+                                    imageNamed: "aiList_catTohuman",
+                                    info: "Curious about what your pet is like?".localized
+                                ),
+                                generateModel: TSGenerateModel(json: catTohuman)),
+        ]
+        
+        return section
+    }()
+    
+    
+    lazy var figuresToysSection: TSDiscoverSectionModel = {
+        let section = TSDiscoverSectionModel()
+        section.style = .styleMore
+        section.setTitle(title: "🧸 " + "Figures&Toys".localized,colors: ["#D7A863","#FFFFFF"])
+        section.items = [[
+            TSDiscoverItemModel(style: .ptp,
+                                
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_AnimeFigure","discover_1_AnimeFigure"]),
+                                generateModel: TSGenerateModel(json: ptp_ActionFigure)),
+            TSDiscoverItemModel(style: .ptp,
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Lafufu","discover_1_Lafufu"]),
+                                generateModel: TSGenerateModel(json: ptp_Lafufu)),
+            TSDiscoverItemModel(style: .ptp,
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_WhimsicalDoll","discover_1_WhimsicalDoll"]),
+                                generateModel: TSGenerateModel(json: ptp_WhimsicalDoll)),
+            TSDiscoverItemModel(style: .ptp,
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_PushToy","discover_1_PushToy"]),
+                                generateModel: TSGenerateModel(json: ptp_PlushToy)),
+            TSDiscoverItemModel(style: .ptp,
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Polaroid","discover_1_Polaroid"]),
+                                generateModel: TSGenerateModel(json: ptp_Polaroid)),
+            TSDiscoverItemModel(style: .ptp,
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_MusicBox","discover_1_MusicBox"]),
+                                generateModel: TSGenerateModel(json: ptp_MusicBox)),
+            TSDiscoverItemModel(style: .ptp,
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Earphone","discover_1_Earphone"]),
+                                generateModel: TSGenerateModel(json: ptp_Earphone)),
+            TSDiscoverItemModel(style: .ptp,
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Kulomi","discover_1_Kulomi"]),
+                                generateModel: TSGenerateModel(json: ptp_Kulomi))
+        ]]
+        return section
+    }()
+    
+//    lazy var babyCardSection: TSDiscoverSectionModel = {
+//        let section = TSDiscoverSectionModel()
+//        section.style = .fullCard
+//        section.items = [
+//            TSDiscoverItemModel(style: .futureBaby,
+//                                viewModel: TSDiscoverAnimationItemVM(
+//                                    title: "Future Baby".localized,
+//                                    info: "To see what will your future baby look like".localized,
+//                                    style: .apng,
+//                                    imageNameds: ["animated_aiBaby.apng"]
+//                                ),
+//                                generateModel: TSGenerateModel(json: futureBaby)),
+//        ]
+//
+//        return section
+//    }()
+    
+    lazy var babyCardSection: TSDiscoverSectionModel = {
+        let section = TSDiscoverSectionModel()
+        section.style = .fullCard
+        section.items = [
+            TSDiscoverItemModel(style: .futureBaby,
+                                viewModel: TSDiscoverBaseItemVM(
+                                    title: "Future Baby".localized,
+                                    imageNamed: "discover_aiBaby",
+                                    info: "To see what will your future baby look like".localized
+                                ),
+                                generateModel: TSGenerateModel(json: futureBaby)),
+        ]
+        return section
+    }()
+    
+
+    lazy var coolPersonalitySection: TSDiscoverSectionModel = {
+        let section = TSDiscoverSectionModel()
+        section.style = .styleMore
+        section.setTitle(title: "🧸 " + "Cool Personality".localized,colors: ["#DB6BE6","#FFFFFF"])
+        section.items = [[
+            TSDiscoverItemModel(style: .ptp,
+                                
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Cyberpunk","discover_1_Cyberpunk"]),
+                                generateModel: TSGenerateModel(json: ptp_Cyberpunk)),
+            TSDiscoverItemModel(style: .ptp,
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Gothic","discover_1_Gothic"]),
+                                generateModel: TSGenerateModel(json: ptp_Gothic)),
+            TSDiscoverItemModel(style: .ptp,
+                                
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Y2K","discover_1_Y2K"]),
+                                generateModel: TSGenerateModel(json: ptp_Y2KMillennium)),
+            TSDiscoverItemModel(style: .ptp,
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Dopamine","discover_1_Dopamine"]),
+                                generateModel: TSGenerateModel(json: ptp_Dopamine)),
+            TSDiscoverItemModel(style: .ptp,
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Neon","discover_1_Neon"]),
+                                generateModel: TSGenerateModel(json: ptp_Neon)),
+            TSDiscoverItemModel(style: .ptp,
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_DarkAcademia","discover_1_DarkAcademia"]),
+                                generateModel: TSGenerateModel(json: ptp_DarkAcademia)),
+        ]]
+        return section
+    }()
+    
+    
+    
+    lazy var animeCartoonSection: TSDiscoverSectionModel = {
+        let section = TSDiscoverSectionModel()
+        section.style = .styleMore
+        section.setTitle(title: "🧚🏻‍♀️ " + "Anime&Cartoon".localized,colors: ["#A4EAD4","#FFFFFF"])
+        section.items = [[
+            TSDiscoverItemModel(style: .ptp,
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_AnimalCrossing","discover_1_AnimalCrossing"]),
+                                generateModel: TSGenerateModel(json: ptp_AnimalCrossing)),
+            TSDiscoverItemModel(style: .ptp,
+                                
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_YellowBunch","discover_1_YellowBunch"]),
+                                generateModel: TSGenerateModel(json: ptp_YellowBunch)),
+            TSDiscoverItemModel(style: .ptp,
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_SweetieCat","discover_1_SweetieCat"]),
+                                generateModel: TSGenerateModel(json: ptp_SweetieCat)),
+            TSDiscoverItemModel(style: .ptp,
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Puppy","discover_1_Puppy"]),
+                                generateModel: TSGenerateModel(json: ptp_Puppy)),
+            TSDiscoverItemModel(style: .ptp,
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Cibi","discover_1_Cibi"]),
+                                generateModel: TSGenerateModel(json: ptp_Cibi)),
+            TSDiscoverItemModel(style: .ptp,
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_MarinerKing","discover_1_MarinerKing"]),
+                                generateModel: TSGenerateModel(json: ptp_MarinerKing)),
+            TSDiscoverItemModel(style: .ptp,
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_SonOfDragon","discover_1_SonOfDragon"]),
+                                generateModel: TSGenerateModel(json: ptp_SonOfDragon)),
+            
+            TSDiscoverItemModel(style: .ptp,
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Barbie","discover_1_Barbie"]),
+                                generateModel: TSGenerateModel(json: ptp_Barbie)),
+            
+            TSDiscoverItemModel(style: .ptp,
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Chiikawa","discover_1_Chiikawa"]),
+                                generateModel: TSGenerateModel(json: ptp_Chiikawa)),
+            
+            TSDiscoverItemModel(style: .ptp,
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_3DBox","discover_1_3DBox"]),
+                                generateModel: TSGenerateModel(json: ptp_3DBox)),
+            
+            TSDiscoverItemModel(style: .ptp,
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_BattleBlitz","discover_1_BattleBlitz"]),
+                                generateModel: TSGenerateModel(json: ptp_BattleBlitz)),
+
+            
+            TSDiscoverItemModel(style: .ptp,
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Mythos","discover_1_Mythos"]),
+                                generateModel: TSGenerateModel(json: ptp_Mythos)),
+            
+            TSDiscoverItemModel(style: .ptp,
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_EmpireDash","discover_1_EmpireDash"]),
+                                generateModel: TSGenerateModel(json: ptp_EmpireDash)),
+            
+            TSDiscoverItemModel(style: .ptp,
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_PocketBeasts","discover_1_PocketBeasts"]),
+                                generateModel: TSGenerateModel(json: ptp_PocketBeasts)),
+        ]]
+        
+        return section
+    }()
+    
+    
+    
+    lazy var ttpCardSection: TSDiscoverSectionModel = {
+        let section = TSDiscoverSectionModel()
+        section.style = .fullCard
+        section.items = [
+            TSDiscoverItemModel(style: .ttp,
+                                viewModel: TSDiscoverBaseItemVM(
+                                    title: "Text to Image".localized,
+                                    imageNamed: "discover_ttp",
+                                    info: "Turn words into visually stunning artwork".localized
+                                ),
+                                generateModel: nil),
+        ]
+        
+        return section
+    }()
+    
+    
+    lazy var trendingSection: TSDiscoverSectionModel = {
+        let section = TSDiscoverSectionModel()
+        section.style = .styleMore
+        section.setTitle(title: "🚀 " + "Trending".localized,colors: ["#4887BB","#FFFFFF"])
+        section.items = [[
+            TSDiscoverItemModel(style: .ptp,
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Fairy","discover_1_Fairy"]),
+                                generateModel: TSGenerateModel(json: ptp_Fairy)),
+            TSDiscoverItemModel(style: .ptp,
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_CyberFairy","discover_1_CyberFairy"]),
+                                generateModel: TSGenerateModel(json: ptp_CyberFairy)),
+            
+            TSDiscoverItemModel(style: .ptp,
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Mermaid","discover_1_Mermaid"]),
+                                generateModel: TSGenerateModel(json: ptp_Mermaid)),
+
+            TSDiscoverItemModel(style: .ptp,
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Mermaid","discover_1_CyberMermaid"]),
+                                generateModel: TSGenerateModel(json: ptp_CyberpunkMermaid)),
+            TSDiscoverItemModel(style: .ptp,
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Mermaid","discover_1_CuteMermaid"]),
+                                generateModel: TSGenerateModel(json: ptp_CuteMermaid)),
+            TSDiscoverItemModel(style: .ptp,
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Mermaid","discover_1_DarckMermaid"]),
+                                generateModel: TSGenerateModel(json: ptp_DarkMermaid)),
+        ]]
+        
+        return section
+    }()
+    
+
+
+    lazy var processPhotoSection: TSDiscoverSectionModel = {
+        let section = TSDiscoverSectionModel()
+        section.style = .styleMore
+        section.setTitle(title: "🚀 " + "Process Photo".localized,colors: ["#DEA94E","#FFFFFF"])
+        section.items = [[
+            TSDiscoverItemModel(style: .photoLive,
+                                viewModel: TSDiscoverAnimationItemVM(title: "",style: .gif, imageNameds: ["discover_0_AnimatePhoto1"]),
+                                generateModel: TSGenerateModel(json: photoLive)),
+            
+            TSDiscoverItemModel(style: .photoQuality,
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_EnhancerPhoto","discover_1_EnhancerPhoto"]),
+                                generateModel: TSGenerateModel(json: photoQuality)),
+            
+            TSDiscoverItemModel(style: .process,
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_RecreatePhoto","discover_1_RecreatePhoto"]),
+                                generateModel: TSGenerateModel(json: recreatePhoto)),
+            
+            TSDiscoverItemModel(style: .oldPhoto,
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_RestorPhoto","discover_1_RestorPhoto"]),
+                                generateModel: TSGenerateModel(json: oldPhoto)),
+            
+            TSDiscoverItemModel(style: .process,
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Colorize","discover_1_Colorize"]),
+                                generateModel: TSGenerateModel(json: colorize)),
+
+            TSDiscoverItemModel(style: .photoExpand,
+                                viewModel: TSDiscoverBaseItemVM(title: "", imageNamed: "discover_0_ExpandPhoto"),
+                                generateModel: TSGenerateModel(json: photoExpand)),
+        ]]
+        
+        return section
+    }()
+
+    lazy var chatCardSection: TSDiscoverSectionModel = {
+        let section = TSDiscoverSectionModel()
+        section.style = .fullCard
+        section.items = [
+            TSDiscoverItemModel(style: .chat,
+                                viewModel: TSDiscoverBaseItemVM(
+                                    title: "AI Assistant".localized,
+                                    imageNamed: "aiList_aiChat",
+                                    info: "Get smart and instant answers".localized
+                                ),
+                                generateModel: nil),
+        ]
+        
+        return section
+    }()
+    
+    lazy var artFilterSection: TSDiscoverSectionModel = {
+        let section = TSDiscoverSectionModel()
+        section.style = .styleMore
+        section.setTitle(title: "🖼️ " + "Art Filter".localized,colors: ["#6CCC2B","#FFFFFF"])
+        section.items = [[
+            TSDiscoverItemModel(style: .ptp,
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_OilPainting","discover_1_OilPainting"]),
+                                generateModel: TSGenerateModel(json: ptp_OilPainting)),
+            TSDiscoverItemModel(style: .ptp,
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_MonaLisa","discover_1_MonaLisa"]),
+                                generateModel: TSGenerateModel(json: ptp_MonaLisa)),
+            TSDiscoverItemModel(style: .ptp,
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Pixel","discover_1_Pixel"]),
+                                generateModel: TSGenerateModel(json: ptp_Pixel)),
+            TSDiscoverItemModel(style: .ptp,
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Sketch","discover_1_Sketch"]),
+                                generateModel: TSGenerateModel(json: ptp_Sketch)),
+            TSDiscoverItemModel(style: .ptp,
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Watercolor","discover_1_Watercolor"]),
+                                generateModel: TSGenerateModel(json: ptp_Watercolor)),
+            TSDiscoverItemModel(style: .ptp,
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_VanGogh","discover_1_VanGogh"]),
+                                generateModel: TSGenerateModel(json: ptp_VanGogh)),
+            TSDiscoverItemModel(style: .ptp,
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Dreamcore","discover_1_Dreamcore"]),
+                                generateModel: TSGenerateModel(json: ptp_Dreamcore)),
+            TSDiscoverItemModel(style: .ptp,
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Doodle","discover_1_Doodle"]),
+                                generateModel: TSGenerateModel(json: ptp_Doodle)),
+        ]]
+        return section
+    }()
+
+    
+    lazy var bePrettySection: TSDiscoverSectionModel = {
+        let section = TSDiscoverSectionModel()
+        section.style = .styleMore
+        section.setTitle(title: "🥰  " + "Be Pretty".localized,colors: ["#FFA537","#FFFFFF"])
+        section.items = [[
+            TSDiscoverItemModel(style: .changehair,
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_HairSalon","discover_1_HairSalon","discover_2_HairSalon"]),
+                                generateModel: TSGenerateModel(json: hairSalon)),
+            
+            TSDiscoverItemModel(style: .changehairColor,
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_HairColor","discover_1_HairColor","discover_2_HairColor"]),
+                                generateModel: TSGenerateModel(json: hairColor)),
+            
+            TSDiscoverItemModel(style: .pretty,
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Pretty","discover_1_Pretty"]),
+                                generateModel: TSGenerateModel(json: pretty)),
+            
+            TSDiscoverItemModel(style: .eyeOpen,
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_FaceFix","discover_1_FaceFix"]),
+                                generateModel: TSGenerateModel(json: eyeOpen)),
+            
+            TSDiscoverItemModel(style: .changeEmote,
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_FacialExpression","discover_1_FacialExpression"]),
+                                generateModel: TSGenerateModel(json: changeEmotion)),
+ 
+            TSDiscoverItemModel(style: .ageChild,
+                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_BackToBaby","discover_1_BackToBaby"]),
+                                generateModel: TSGenerateModel(json: ageChild)),
+        ]]
+        
+        return section
+    }()
+    
+    
+    lazy var oldAgeCardSection: TSDiscoverSectionModel = {
+        let section = TSDiscoverSectionModel()
+        section.style = .fullCard
+        section.setTitle(title: "🪄  " + "More AI Tools".localized,colors: ["#FFFF73","#FFFFFF"])
+        section.items = [
+            TSDiscoverItemModel(style: .ageOld,
+                                viewModel: TSDiscoverBaseItemVM(
+                                    title: "Predicting Old Age".localized,
+                                    imageNamed: "aiList_oldPeople",
+                                    info: "AI predicts what you look like in your old age".localized
+                                ),
+                                generateModel: TSGenerateModel(json: ageOld)),
+        ]
+        
+        return section
+    }()
+    
+    
+    
+    lazy var discoverDatas: [TSDiscoverSectionModel] = {
+        return [
+            bannerSection,
+            videoEffectSection,
+            popularStylesSection,
+            processPhotoSection,
+            figuresToysSection,
+            babyCardSection,
+            animeCartoonSection,
+            coolPersonalitySection,
+            ttpCardSection,
+            trendingSection,
+            artFilterSection,
+            bePrettySection,
+            oldAgeCardSection,
+            petToHumanSection,
+            chatCardSection,
+        ]
+    }()
+    
+
+
+}

+ 337 - 0
AIEmoji/Business2/DisCover/Data/TSDiscoverViewModel+Dic.swift

@@ -17,6 +17,17 @@ let kie = "kie"                 //走kie--chatgpt
 let volcengine = "volcengine"   //走火山引擎
 let flux = "flux"               //走kie--flux
 
+//1紫色 2 橙色 3 黑色 4 多人
+
+/*
+上传提示:
+第一种:宠物,适用于文档橙色说明文字
+第二种:单人,适用于文档紫色说明文字
+第三种:单人或多人多主体,适用于文档蓝色说明文字
+第四种:适用于法式热吻,文档玫红色说明文字
+第五种:适用于奥斯卡奖项特效,文档黑色说明文字
+ */
+private let hintType = "hintType"
 
 
 //MARK: 功能性模型
@@ -146,14 +157,340 @@ extension TSDiscoverViewModel {
             
             //Predicting old age
             TSGenerateModel(json: ageOld),
+            
+            //video
+            TSGenerateModel(json: video_Mermaid),
+            TSGenerateModel(json: video_Fairy),
+            TSGenerateModel(json: video_HappyBirthday),
+            TSGenerateModel(json: video_SurpriseFlower),
+            TSGenerateModel(json: video_Lafufu),
+            TSGenerateModel(json: video_AnimeMe),
+            TSGenerateModel(json: video_PettoHuman),
+            TSGenerateModel(json: video_MakingFace),
+            TSGenerateModel(json: video_Robot),
+            TSGenerateModel(json: video_WalkingwithBeasts),
+            TSGenerateModel(json: video_FunnyPet),
+            TSGenerateModel(json: video_Fly),
+            TSGenerateModel(json: video_Pinch),
+            TSGenerateModel(json: video_Grabdoll),
+            TSGenerateModel(json: video_ToyMe),
+            TSGenerateModel(json: video_Hulk),
+            TSGenerateModel(json: video_MuscleUp),
+            TSGenerateModel(json: video_FrenchKiss),
+            TSGenerateModel(json: video_PhotoAnimater),
+            TSGenerateModel(json: video_AnimalDivingShow),
+            TSGenerateModel(json: video_OscarGala)
         ]
         return array
     }
     
+//    func getAllVideoGenerateModel()->[TSGenerateModel?]{
+//        let array:[TSGenerateModel?] = [
+//            TSGenerateModel(json: video_Mermaid),
+//            TSGenerateModel(json: video_Fairy),
+//            TSGenerateModel(json: video_HappyBirthday),
+//            TSGenerateModel(json: video_SurpriseFlower),
+//            TSGenerateModel(json: video_Lafufu),
+//            TSGenerateModel(json: video_AnimeMe),
+//            TSGenerateModel(json: video_PettoHuman),
+//            TSGenerateModel(json: video_MakingFace),
+//            TSGenerateModel(json: video_Robot),
+//            TSGenerateModel(json: video_WalkingwithBeasts),
+//            TSGenerateModel(json: video_FunnyPet),
+//            TSGenerateModel(json: video_Fly),
+//            TSGenerateModel(json: video_Pinch),
+//            TSGenerateModel(json: video_Grabdoll),
+//            TSGenerateModel(json: video_ToyMe),
+//            TSGenerateModel(json: video_Hulk),
+//            TSGenerateModel(json: video_MuscleUp),
+//            TSGenerateModel(json: video_FrenchKiss)
+//        ]
+//        return array
+//    }
+}
+
+
+let videoUnionType = 2
+//MARK: video
+extension TSDiscoverViewModel {
+    
+    
+    var video_Mermaid:[String:Any]{
+        [
+            imageName: "video_style_Mermaid",
+            imageText: "Mermaid",
+            prompt:"fishermen",
+            specialStyle:0,
+            isVip: true,
+            unionType: videoUnionType,
+            hintType:2,
+            model:kie
+        ]
+    }
+    
+    var video_Fairy:[String:Any]{
+        [
+            imageName: "video_style_Fairy",
+            imageText: "Fairy",
+            prompt:"fairy_me",
+            specialStyle:0,
+            isVip: true,
+            unionType: videoUnionType,
+            hintType:2,
+            model:kie
+        ]
+    }
+    
+    var video_HappyBirthday:[String:Any]{
+        [
+            imageName: "video_style_HappyBirthday",
+            imageText: "Happy Birthday",
+            prompt:"happy_birthday",
+            specialStyle:0,
+            isVip: false,
+            unionType: videoUnionType,
+            hintType:2,
+            model:kie
+        ]
+    }
+    
+    var video_SurpriseFlower:[String:Any]{
+        [
+            imageName: "video_style_SurpriseFlower",
+            imageText: "Surprise Flower",
+            prompt:"flower_receive",
+            specialStyle:0,
+            isVip: true,
+            unionType: videoUnionType,
+            hintType:2,
+            model:kie
+        ]
+    }
+
+    var video_Lafufu:[String:Any]{
+        [
+            imageName: "video_style_Lafufu",
+            imageText: "Lafufu",
+            prompt:"ladudu_me_random",
+            specialStyle:0,
+            isVip: true,
+            unionType: videoUnionType,
+            hintType:2,
+            model:kie
+        ]
+    }
+    
+    var video_AnimeMe:[String:Any]{
+        [
+            imageName: "video_style_AnimeMe",
+            imageText: "Anime Me",
+            prompt:"ghibli",
+            specialStyle:0,
+            isVip: false,
+            unionType: videoUnionType,
+            hintType:3,
+            model:kie
+        ]
+    }
     
+    var video_PettoHuman:[String:Any]{
+        [
+            imageName: "video_style_PettoHuman",
+            imageText: "Pet to Human",
+            prompt:"pet2human",
+            specialStyle:0,
+            isVip: false,
+            unionType: videoUnionType,
+            hintType:1,
+            model:kie
+        ]
+    }
     
+    var video_MakingFace:[String:Any]{
+        [
+            imageName: "video_style_MakingFace",
+            imageText: "Making Face",
+            prompt:"make_face",
+            specialStyle:0,
+            isVip: true,
+            unionType: videoUnionType,
+            hintType:2,
+            model:kie
+        ]
+    }
+    
+    var video_Robot:[String:Any]{
+        [
+            imageName: "video_style_Robot",
+            imageText: "Robot",
+            prompt:"mecha_x",
+            specialStyle:0,
+            isVip: true,
+            unionType: videoUnionType,
+            hintType:2,
+            model:kie
+        ]
+    }
     
+    var video_WalkingwithBeasts:[String:Any]{
+        [
+            imageName: "ptp_style_WalkingwithBeasts",
+            imageText: "Walking with Beasts",
+            prompt:"beast_companion",
+            specialStyle:0,
+            isVip: false,
+            unionType: videoUnionType,
+            hintType:2,
+            model:kie
+        ]
+    }
+    
+    var video_FunnyPet:[String:Any]{
+        [
+            imageName: "video_style_FunnyPet",
+            imageText: "Funny Pet",
+            prompt:"split_stance_pet",
+            specialStyle:0,
+            isVip: true,
+            unionType: videoUnionType,
+            hintType:1,
+            model:kie
+        ]
+    }
+    
+    var video_Fly:[String:Any]{
+        [
+            imageName: "video_style_Fly",
+            imageText: "Fly",
+            prompt:"flying",
+            specialStyle:0,
+            isVip: true,
+            unionType: videoUnionType,
+            hintType:2,
+            model:kie
+        ]
+    }
+    
+    
+    var video_Pinch:[String:Any]{
+        [
+            imageName: "video_style_Pinch",
+            imageText: "Pinch",
+            prompt:"pinch",
+            specialStyle:0,
+            isVip: true,
+            unionType: videoUnionType,
+            hintType:3,
+            model:kie
+        ]
+    }
+    
+    var video_Grabdoll:[String:Any]{
+        [
+            imageName: "video_style_Grabdoll",
+            imageText: "Grab doll",
+            prompt:"claw_me",
+            specialStyle:0,
+            isVip: false,
+            unionType: videoUnionType,
+            hintType:3,
+            model:kie
+        ]
+    }
+    
+    var video_ToyMe:[String:Any]{
+        [
+            imageName: "video_style_ToyMe",
+            imageText: "Toy Me",
+            prompt:"toy_me",
+            specialStyle:0,
+            isVip: true,
+            unionType: videoUnionType,
+            hintType:3,
+            model:kie
+        ]
+    }
+    
+    var video_Hulk:[String:Any]{
+        [
+            imageName: "video_style_Hulk",
+            imageText: "Hulk",
+            prompt:"hulk",
+            specialStyle:0,
+            isVip: false,
+            unionType: videoUnionType,
+            hintType:2,
+            model:kie
+        ]
+    }
+    
+    var video_MuscleUp:[String:Any]{
+        [
+            imageName: "video_style_MuscleUp",
+            imageText: "MuscleUp",
+            prompt:"muscling",
+            specialStyle:0,
+            isVip: true,
+            unionType: videoUnionType,
+            hintType:2,
+            model:kie
+        ]
+    }
+    
+    var video_FrenchKiss:[String:Any]{
+        [
+            imageName: "video_style_FrenchKiss",
+            imageText: "French Kiss",
+            prompt:"french_kiss",
+            specialStyle:0,
+            isVip: true,
+            unionType: videoUnionType,
+            hintType:4,
+            model:kie
+        ]
+    }
+    
+    
+    var video_PhotoAnimater:[String:Any]{
+        [
+            imageName: "video_style_PhotoAnimater",
+            imageText: "Photo Animater",
+            prompt:"Create a smooth and realistic animation based on the uploaded photo. Keep the original identity, style, and appearance while adding natural, subtle, and lively movements. The animation should feel real and immersive, with elegant head tilts, breathing, blinking, and slight body or fur motions to enhance realism. Avoid exaggerated or artificial movements.",
+            specialStyle:0,
+            isVip: false,
+            unionType: videoUnionType,
+            hintType:2,
+            model:kie
+        ]
+    }
+    
+    var video_AnimalDivingShow:[String:Any]{
+        [
+            imageName: "video_style_AnimalDivingShow",
+            imageText: "Animal Diving Show",
+            prompt:"fluffy_plunge",
+            specialStyle:0,
+            isVip: true,
+            unionType: videoUnionType,
+            hintType:1,
+            model:kie
+        ]
+    }
+    
+    var video_OscarGala:[String:Any]{
+        [
+            imageName: "video_style_OscarGala",
+            imageText: "Oscar Gala",
+            prompt:"oscar_gala",
+            specialStyle:0,
+            isVip: true,
+            unionType: videoUnionType,
+            hintType:5,
+            model:kie
+        ]
+    }
 }
+
 //MARK: 功能性模型
 extension TSDiscoverViewModel {
     //变老

+ 16 - 483
AIEmoji/Business2/DisCover/Data/TSDiscoverViewModel.swift

@@ -1,10 +1,11 @@
 //
-//  TSHomeViewModel.swift
+//  TSDiscoverViewModel.swift
 //  AIEmoji
 //
-//  Created by 100Years on 2025/6/21.
+//  Created by 100Years on 2025/7/16.
 //
 
+
 import ObjectMapper
 
 
@@ -14,6 +15,7 @@ enum TSDiscoverItemAnimationStyle:CaseIterable {
     case comparison
     case gif
     case apng
+    case video
 }
 
 
@@ -27,7 +29,7 @@ enum TSDiscoverViewStyle:CaseIterable {
     case funcItems  //功能按钮块
     case styleMore  //更多风格
     case fullCard   //大卡片
- 
+    case banner   //大卡片
     var itemSize:CGSize {
         switch self {
         case .funcItems:
@@ -36,20 +38,11 @@ enum TSDiscoverViewStyle:CaseIterable {
             return CGSize(width: k_ScreenWidth, height: 200.0)
         case .fullCard:
             return fullCardSize
+        case .banner:
+            return CGSize(width: k_ScreenWidth, height: 281)
         }
     }
     
-//    var sectionEdge:UIEdgeInsets {
-//        switch self {
-//        case .funcItems:
-//            return UIEdgeInsets(top: 0, left: kDiscoverSection.left, bottom: 0, right: kDiscoverSection.right)
-//        case .styleMore:
-//            return UIEdgeInsets(top: 0, left: kDiscoverSection.left, bottom: 0, right: kDiscoverSection.right)
-//        case .fullCard:
-//            return UIEdgeInsets(top: 24, left: kDiscoverSection.left, bottom: 0, right: kDiscoverSection.right)
-//        }
-//    }
-    
     var cell:TSDiscoverBaseCell.Type {
         switch self {
         case .funcItems:
@@ -58,6 +51,8 @@ enum TSDiscoverViewStyle:CaseIterable {
             return TSDiscoverStyleMoreCell.self
         case .fullCard:
             return TSDiscoverFullCardCell.self
+        case .banner:
+            return TSDiscoverBannerCell.self
         }
     }
 }
@@ -83,6 +78,7 @@ class TSDiscoverAnimationItemVM:TSDiscoverBaseItemVM{
         self.imageNameds = imageNameds
         super.init(title: title, imageNamed: "",info: info)
     }
+    
 }
 //MARK: 分区
 
@@ -90,10 +86,12 @@ let kDiscoverSectionH = 56.0
 
 class TSDiscoverSectionModel {
     var title:String = ""
+    var colors:[String] = []
     var style:TSDiscoverViewStyle = .styleMore
     var items:[Any] = []
-    func setTitle(title:String) {
+    func setTitle(title:String,colors:[String] = []) {
         self.title = title
+        self.colors = colors
     }
 }
 
@@ -116,6 +114,9 @@ class TSDiscoverItemModel {
         if !viewModel.imageNamed.isEmpty {
             return viewModel.imageNamed
         }
+        if let model = viewModel as? TSDiscoverAnimationItemVM {
+            return model.imageNameds.first ?? ""
+        }
         return ""
     }
     
@@ -127,471 +128,3 @@ class TSDiscoverItemModel {
         self.generateModel = generateModel
     }
 }
-//MARK: 组装数据
-let kTSDiscoverVM = TSDiscoverViewModel.shared
-class TSDiscoverViewModel {
-
-    static let shared:TSDiscoverViewModel = TSDiscoverViewModel()
-    
-    lazy var images: [String] = {
-        let images = ["aiList_hair","aiList_hairColor"]
-        return images
-    }()
-    
-//    //顶部按钮功能(金刚区)
-//    lazy var topFuncSection:TSDiscoverSectionModel = {
-//        let section = TSDiscoverSectionModel()
-//        section.style = .funcItems
-//        section.items = [[
-////            TSDiscoverItemModel(style: .futureBaby,
-////                                viewModel: TSDiscoverBaseItemVM(title: "AI Baby", imageNamed: "discover_AIBaby"),
-////                                generateModel: TSFuncStyle.futureBaby.generateModel),
-//            TSDiscoverItemModel(style: .ttp,
-//                                viewModel: TSDiscoverBaseItemVM(title: "Text to Image", imageNamed: "discover_TextImage")),
-//            TSDiscoverItemModel(style: .chat,
-//                                viewModel: TSDiscoverBaseItemVM(title: "AI Assistant", imageNamed: "discover_AIAssistant")),
-//            TSDiscoverItemModel(style: .photoQuality,
-//                                viewModel: TSDiscoverBaseItemVM(title: "Enhance Photo", imageNamed: "discover_HD"),
-//                                generateModel: TSFuncStyle.oldPhoto.generateModel),
-//            TSDiscoverItemModel(style: .photoLive,
-//                                viewModel: TSDiscoverBaseItemVM(title: "Old Photo Animation", imageNamed: "discover_PredictOld"),
-//                                generateModel: TSFuncStyle.photoLive.generateModel),
-//        ]]
-//        return section
-//    }()
-
-    
-    lazy var popularStylesSection: TSDiscoverSectionModel = {
-        let section = TSDiscoverSectionModel()
-        section.style = .styleMore
-        section.setTitle(title: "Popular")
-        section.items = [[
-            TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_ToonMe","discover_1_ToonMe"]),
-                                generateModel: TSGenerateModel(json: ptp_ToonMe)),
-            
-            TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_ChibiSticker","discover_1_ChibiSticker"]),
-                                generateModel: TSGenerateModel(json: ptp_ChibiSticker)),
-            TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Irasutoya","discover_1_Irasutoya"]),
-                                generateModel: TSGenerateModel(json: ptp_Irasutoya)),
-
-            TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_BlytheDoll","discover_1_BlytheDoll"]),
-                                generateModel: TSGenerateModel(json: ptp_BlytheDoll)),
-            TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Caricature","discover_1_Caricature"]),
-                                generateModel: TSGenerateModel(json: ptp_Caricature)),
-            
-            TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Illustration","discover_1_Illustration"]),
-                                generateModel: TSGenerateModel(json: ptp_Illustration)),
-            TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_90sAnime","discover_1_90sAnime"]),
-                                generateModel: TSGenerateModel(json: ptp_90sAnime)),
-            
-            TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_FreshWatercolor","discover_1_FreshWatercolor"]),
-                                generateModel: TSGenerateModel(json: ptp_FreshWatercolor)),
-
-//            TSDiscoverItemModel(style: .ptp,
-//                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_FairyTail","discover_1_FairyTail"]),
-//                                generateModel: TSGenerateModel(json: ptp_FairyTail)),
-//            TSDiscoverItemModel(style: .ptp,
-//                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_TouhouSeries","discover_1_TouhouSeries"]),
-//                                generateModel: TSGenerateModel(json: ptp_TouhouSeries)),
-//            TSDiscoverItemModel(style: .ptp,
-//                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Anime","discover_1_Anime"]),
-//                                generateModel: TSGenerateModel(json: ptp_Anime)),
-        ]]
-        return section
-    }()
-    
-    
-    
-    lazy var petToHumanSection: TSDiscoverSectionModel = {
-        let section = TSDiscoverSectionModel()
-        section.style = .fullCard
-        section.items = [
-            TSDiscoverItemModel(style: .catTohuman,
-                                viewModel: TSDiscoverBaseItemVM(
-                                    title: "Pet Humanization".localized,
-                                    imageNamed: "aiList_catTohuman",
-                                    info: "Curious about what your pet is like?".localized
-                                ),
-                                generateModel: TSGenerateModel(json: catTohuman)),
-        ]
-        
-        return section
-    }()
-    
-    
-    lazy var figuresToysSection: TSDiscoverSectionModel = {
-        let section = TSDiscoverSectionModel()
-        section.style = .styleMore
-        section.setTitle(title: "Figures&Toys")
-        section.items = [[
-            TSDiscoverItemModel(style: .ptp,
-                                
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_AnimeFigure","discover_1_AnimeFigure"]),
-                                generateModel: TSGenerateModel(json: ptp_ActionFigure)),
-            TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Lafufu","discover_1_Lafufu"]),
-                                generateModel: TSGenerateModel(json: ptp_Lafufu)),
-            TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_WhimsicalDoll","discover_1_WhimsicalDoll"]),
-                                generateModel: TSGenerateModel(json: ptp_WhimsicalDoll)),
-            TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_PushToy","discover_1_PushToy"]),
-                                generateModel: TSGenerateModel(json: ptp_PlushToy)),
-            TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Polaroid","discover_1_Polaroid"]),
-                                generateModel: TSGenerateModel(json: ptp_Polaroid)),
-            TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_MusicBox","discover_1_MusicBox"]),
-                                generateModel: TSGenerateModel(json: ptp_MusicBox)),
-            TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Earphone","discover_1_Earphone"]),
-                                generateModel: TSGenerateModel(json: ptp_Earphone)),
-            TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Kulomi","discover_1_Kulomi"]),
-                                generateModel: TSGenerateModel(json: ptp_Kulomi))
-        ]]
-        return section
-    }()
-    
-//    lazy var babyCardSection: TSDiscoverSectionModel = {
-//        let section = TSDiscoverSectionModel()
-//        section.style = .fullCard
-//        section.items = [
-//            TSDiscoverItemModel(style: .futureBaby,
-//                                viewModel: TSDiscoverAnimationItemVM(
-//                                    title: "Future Baby".localized,
-//                                    info: "To see what will your future baby look like".localized,
-//                                    style: .apng,
-//                                    imageNameds: ["animated_aiBaby.apng"]
-//                                ),
-//                                generateModel: TSGenerateModel(json: futureBaby)),
-//        ]
-//        
-//        return section
-//    }()
-    
-    lazy var babyCardSection: TSDiscoverSectionModel = {
-        let section = TSDiscoverSectionModel()
-        section.style = .fullCard
-        section.items = [
-            TSDiscoverItemModel(style: .futureBaby,
-                                viewModel: TSDiscoverBaseItemVM(
-                                    title: "Future Baby".localized,
-                                    imageNamed: "discover_aiBaby",
-                                    info: "To see what will your future baby look like".localized
-                                ),
-                                generateModel: TSGenerateModel(json: futureBaby)),
-        ]
-        return section
-    }()
-    
-
-    lazy var coolPersonalitySection: TSDiscoverSectionModel = {
-        let section = TSDiscoverSectionModel()
-        section.style = .styleMore
-        section.setTitle(title: "Cool Personality")
-        section.items = [[
-            TSDiscoverItemModel(style: .ptp,
-                                
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Cyberpunk","discover_1_Cyberpunk"]),
-                                generateModel: TSGenerateModel(json: ptp_Cyberpunk)),
-            TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Gothic","discover_1_Gothic"]),
-                                generateModel: TSGenerateModel(json: ptp_Gothic)),
-            TSDiscoverItemModel(style: .ptp,
-                                
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Y2K","discover_1_Y2K"]),
-                                generateModel: TSGenerateModel(json: ptp_Y2KMillennium)),
-            TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Dopamine","discover_1_Dopamine"]),
-                                generateModel: TSGenerateModel(json: ptp_Dopamine)),
-            TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Neon","discover_1_Neon"]),
-                                generateModel: TSGenerateModel(json: ptp_Neon)),
-            TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_DarkAcademia","discover_1_DarkAcademia"]),
-                                generateModel: TSGenerateModel(json: ptp_DarkAcademia)),
-        ]]
-        return section
-    }()
-    
-    
-    
-    lazy var animeCartoonSection: TSDiscoverSectionModel = {
-        let section = TSDiscoverSectionModel()
-        section.style = .styleMore
-        section.setTitle(title: "Anime&Cartoon")
-        section.items = [[
-            TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_AnimalCrossing","discover_1_AnimalCrossing"]),
-                                generateModel: TSGenerateModel(json: ptp_AnimalCrossing)),
-            TSDiscoverItemModel(style: .ptp,
-                                
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_YellowBunch","discover_1_YellowBunch"]),
-                                generateModel: TSGenerateModel(json: ptp_YellowBunch)),
-            TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_SweetieCat","discover_1_SweetieCat"]),
-                                generateModel: TSGenerateModel(json: ptp_SweetieCat)),
-            TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Puppy","discover_1_Puppy"]),
-                                generateModel: TSGenerateModel(json: ptp_Puppy)),
-            TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Cibi","discover_1_Cibi"]),
-                                generateModel: TSGenerateModel(json: ptp_Cibi)),
-            TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_MarinerKing","discover_1_MarinerKing"]),
-                                generateModel: TSGenerateModel(json: ptp_MarinerKing)),
-            TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_SonOfDragon","discover_1_SonOfDragon"]),
-                                generateModel: TSGenerateModel(json: ptp_SonOfDragon)),
-            
-            TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Barbie","discover_1_Barbie"]),
-                                generateModel: TSGenerateModel(json: ptp_Barbie)),
-            
-            TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Chiikawa","discover_1_Chiikawa"]),
-                                generateModel: TSGenerateModel(json: ptp_Chiikawa)),
-            
-            TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_3DBox","discover_1_3DBox"]),
-                                generateModel: TSGenerateModel(json: ptp_3DBox)),
-            
-            TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_BattleBlitz","discover_1_BattleBlitz"]),
-                                generateModel: TSGenerateModel(json: ptp_BattleBlitz)),
-
-            
-            TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Mythos","discover_1_Mythos"]),
-                                generateModel: TSGenerateModel(json: ptp_Mythos)),
-            
-            TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_EmpireDash","discover_1_EmpireDash"]),
-                                generateModel: TSGenerateModel(json: ptp_EmpireDash)),
-            
-            TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_PocketBeasts","discover_1_PocketBeasts"]),
-                                generateModel: TSGenerateModel(json: ptp_PocketBeasts)),
-        ]]
-        
-        return section
-    }()
-    
-    
-    
-    lazy var ttpCardSection: TSDiscoverSectionModel = {
-        let section = TSDiscoverSectionModel()
-        section.style = .fullCard
-        section.items = [
-            TSDiscoverItemModel(style: .ttp,
-                                viewModel: TSDiscoverBaseItemVM(
-                                    title: "Text to Image".localized,
-                                    imageNamed: "discover_ttp",
-                                    info: "Turn words into visually stunning artwork".localized
-                                ),
-                                generateModel: nil),
-        ]
-        
-        return section
-    }()
-    
-    
-    lazy var trendingSection: TSDiscoverSectionModel = {
-        let section = TSDiscoverSectionModel()
-        section.style = .styleMore
-        section.setTitle(title: "Trending")
-        section.items = [[
-            TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Fairy","discover_1_Fairy"]),
-                                generateModel: TSGenerateModel(json: ptp_Fairy)),
-            TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_CyberFairy","discover_1_CyberFairy"]),
-                                generateModel: TSGenerateModel(json: ptp_CyberFairy)),
-            
-            TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Mermaid","discover_1_Mermaid"]),
-                                generateModel: TSGenerateModel(json: ptp_Mermaid)),
-
-            TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Mermaid","discover_1_CyberMermaid"]),
-                                generateModel: TSGenerateModel(json: ptp_CyberpunkMermaid)),
-            TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Mermaid","discover_1_CuteMermaid"]),
-                                generateModel: TSGenerateModel(json: ptp_CuteMermaid)),
-            TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Mermaid","discover_1_DarckMermaid"]),
-                                generateModel: TSGenerateModel(json: ptp_DarkMermaid)),
-        ]]
-        
-        return section
-    }()
-    
-
-
-    lazy var processPhotoSection: TSDiscoverSectionModel = {
-        let section = TSDiscoverSectionModel()
-        section.style = .styleMore
-        section.setTitle(title: "Process Photo")
-        section.items = [[
-            TSDiscoverItemModel(style: .photoLive,
-                                viewModel: TSDiscoverAnimationItemVM(title: "",style: .gif, imageNameds: ["discover_0_AnimatePhoto1"]),
-                                generateModel: TSGenerateModel(json: photoLive)),
-            
-            TSDiscoverItemModel(style: .photoQuality,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_EnhancerPhoto","discover_1_EnhancerPhoto"]),
-                                generateModel: TSGenerateModel(json: photoQuality)),
-            
-            TSDiscoverItemModel(style: .process,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_RecreatePhoto","discover_1_RecreatePhoto"]),
-                                generateModel: TSGenerateModel(json: recreatePhoto)),
-            
-            TSDiscoverItemModel(style: .oldPhoto,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_RestorPhoto","discover_1_RestorPhoto"]),
-                                generateModel: TSGenerateModel(json: oldPhoto)),
-            
-            TSDiscoverItemModel(style: .process,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Colorize","discover_1_Colorize"]),
-                                generateModel: TSGenerateModel(json: colorize)),
-
-            TSDiscoverItemModel(style: .photoExpand,
-                                viewModel: TSDiscoverBaseItemVM(title: "", imageNamed: "discover_0_ExpandPhoto"),
-                                generateModel: TSGenerateModel(json: photoExpand)),
-        ]]
-        
-        return section
-    }()
-
-    lazy var chatCardSection: TSDiscoverSectionModel = {
-        let section = TSDiscoverSectionModel()
-        section.style = .fullCard
-        section.items = [
-            TSDiscoverItemModel(style: .chat,
-                                viewModel: TSDiscoverBaseItemVM(
-                                    title: "AI Assistant".localized,
-                                    imageNamed: "aiList_aiChat",
-                                    info: "Get smart and instant answers".localized
-                                ),
-                                generateModel: nil),
-        ]
-        
-        return section
-    }()
-    
-    lazy var artFilterSection: TSDiscoverSectionModel = {
-        let section = TSDiscoverSectionModel()
-        section.style = .styleMore
-        section.setTitle(title: "Art Filter")
-        
-        section.items = [[
-            TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_OilPainting","discover_1_OilPainting"]),
-                                generateModel: TSGenerateModel(json: ptp_OilPainting)),
-            TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_MonaLisa","discover_1_MonaLisa"]),
-                                generateModel: TSGenerateModel(json: ptp_MonaLisa)),
-            TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Pixel","discover_1_Pixel"]),
-                                generateModel: TSGenerateModel(json: ptp_Pixel)),
-            TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Sketch","discover_1_Sketch"]),
-                                generateModel: TSGenerateModel(json: ptp_Sketch)),
-            TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Watercolor","discover_1_Watercolor"]),
-                                generateModel: TSGenerateModel(json: ptp_Watercolor)),
-            TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_VanGogh","discover_1_VanGogh"]),
-                                generateModel: TSGenerateModel(json: ptp_VanGogh)),
-            TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Dreamcore","discover_1_Dreamcore"]),
-                                generateModel: TSGenerateModel(json: ptp_Dreamcore)),
-            TSDiscoverItemModel(style: .ptp,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Doodle","discover_1_Doodle"]),
-                                generateModel: TSGenerateModel(json: ptp_Doodle)),
-        ]]
-        return section
-    }()
-
-    
-    lazy var bePrettySection: TSDiscoverSectionModel = {
-        let section = TSDiscoverSectionModel()
-        section.style = .styleMore
-        section.setTitle(title: "Be Pretty")
-        section.items = [[
-            TSDiscoverItemModel(style: .changehair,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_HairSalon","discover_1_HairSalon","discover_2_HairSalon"]),
-                                generateModel: TSGenerateModel(json: hairSalon)),
-            
-            TSDiscoverItemModel(style: .changehairColor,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_HairColor","discover_1_HairColor","discover_2_HairColor"]),
-                                generateModel: TSGenerateModel(json: hairColor)),
-            
-            TSDiscoverItemModel(style: .pretty,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_Pretty","discover_1_Pretty"]),
-                                generateModel: TSGenerateModel(json: pretty)),
-            
-            TSDiscoverItemModel(style: .eyeOpen,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_FaceFix","discover_1_FaceFix"]),
-                                generateModel: TSGenerateModel(json: eyeOpen)),
-            
-            TSDiscoverItemModel(style: .changeEmote,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_FacialExpression","discover_1_FacialExpression"]),
-                                generateModel: TSGenerateModel(json: changeEmotion)),
- 
-            TSDiscoverItemModel(style: .ageChild,
-                                viewModel: TSDiscoverAnimationItemVM(title: "", imageNameds: ["discover_0_BackToBaby","discover_1_BackToBaby"]),
-                                generateModel: TSGenerateModel(json: ageChild)),
-        ]]
-        
-        return section
-    }()
-    
-    
-    lazy var oldAgeCardSection: TSDiscoverSectionModel = {
-        let section = TSDiscoverSectionModel()
-        section.style = .fullCard
-        section.setTitle(title: "More AI Tools")
-        section.items = [
-            TSDiscoverItemModel(style: .ageOld,
-                                viewModel: TSDiscoverBaseItemVM(
-                                    title: "Predicting Old Age".localized,
-                                    imageNamed: "aiList_oldPeople",
-                                    info: "AI predicts what you look like in your old age".localized
-                                ),
-                                generateModel: TSGenerateModel(json: ageOld)),
-        ]
-        
-        return section
-    }()
-    
-    
-    
-    lazy var discoverDatas: [TSDiscoverSectionModel] = {
-        return [
-            popularStylesSection,
-            processPhotoSection,
-            figuresToysSection,
-            babyCardSection,
-            animeCartoonSection,
-            coolPersonalitySection,
-            ttpCardSection,
-            trendingSection,
-            artFilterSection,
-            bePrettySection,
-            oldAgeCardSection,
-            petToHumanSection,
-            chatCardSection,
-        ]
-    }()
-    
-
-
-}

+ 6 - 5
AIEmoji/Business2/DisCover/Data/TSFuncStyle.swift

@@ -12,7 +12,7 @@ enum TSFuncStyle:Int,Equatable,CaseIterable {
     case oldPhoto = 3    //旧照片修复
     case eyeOpen = 4     //开眼
     case pretty = 5      //变美
-    case photoLive = 6      //把照片变活
+    case photoLive = 6      //把照片动起来
     case photoExpand = 7      //照片扩展
     case photoQuality = 8     //照片变高清
     case motherDay = 9     //母亲节
@@ -28,6 +28,7 @@ enum TSFuncStyle:Int,Equatable,CaseIterable {
     case ttp = 16
     case chat = 17
     case process = 18     // 走变老变年轻那套交互流程,接口用图生图的接口
+    case videoV2 = 19     //视频v2,有声音
     
     
     var imageMaxKb:Int{
@@ -121,11 +122,11 @@ enum TSFuncStyle:Int,Equatable,CaseIterable {
         }
     }
     
-    var isVideo:Bool{
-        if self == .photoLive {
-            return true
+    var vipFreeNumType:VipFreeNumType{
+        if self == .videoV2 || self == .photoLive {
+            return .videoV2
         }
-        return false
+        return .aiGenerate
     }
 }
 

+ 3 - 0
AIEmoji/Business2/DisCover/TSAIGenerateVC/TSAIGenerateBaseVC/TSAIGenerateBaseVC.swift

@@ -126,6 +126,9 @@ class TSAIGenerateBaseVC: TSBaseVC {
             closePage()
         }
     }
+    
+    deinit {
+    }
 }
 
 extension TSAIGenerateBaseVC {

+ 2 - 1
AIEmoji/Business2/DisCover/TSAIGenerateVC/TSAIGenerateVC.swift

@@ -143,7 +143,8 @@ class TSAIGenerateVC: TSAIGenerateBaseVC {
     //重新生成
     @objc override func clickRegenerateBtn(){
         //判断 vip
-        if kJudgeVip(externalBool: kPurchaseDefault.freeNumAvailable(type: .aiGenerate) == false, vc: self) { return }
+//        if kJudgeVip(externalBool: kPurchaseDefault.freeNumAvailable(type: .aiGenerate) == false, vc: self) { return }
+        if kJudgeVip(externalBool: kPurchaseDefault.freeNumAvailable(type: generatorModel.generatorStyle.vipFreeNumType) == false, vc: self) { return }
         self.infoModel?.actionStatus = .failed//状态设为失败,走generatorCreat
         self.uuidString = UUID().uuidString//设置新的uuid,新的储存数据
         generatorOperation()//开始生成

+ 269 - 0
AIEmoji/Business2/DisCover/TSDiscoverVC/Cell/TSDiscoverBannerCell.swift

@@ -0,0 +1,269 @@
+//
+//  TSDiscoverBannerView.swift
+//  AIEmoji
+//
+//  Created by 100Years on 2025/7/17.
+//
+
+import TYCyclePagerView
+
+class TSDiscoverBannerCell: TSDiscoverBaseCell {
+    var lastIndex:Int = 0
+    var itemSize:CGSize = UIScreen.main.bounds.size
+    lazy var models:[TSDiscoverItemModel] = [TSDiscoverItemModel](){
+        didSet{
+            itemSize = self.bounds.size
+            pageControl.numberOfPages = models.count
+            cyclePagerView.reloadData()
+            
+            kMainShort {
+                guard let collectionView = self.cyclePagerView.collectionView else { return }
+                let indexPath = IndexPath(item: 0, section: 0)
+                if let cell = collectionView.cellForItem(at: indexPath) as? TSBaseCollectionCell {
+                    cell.willDisplay(indexPath: indexPath)
+                }
+            }
+        }
+    }
+        
+    lazy var titleLabel: UILabel = {
+        let titleLabel = UILabel.createLabel(text: "Anime Effect".localized,font: .font(size: 14.0),textColor: .white.withAlphaComponent(0.6))
+        return titleLabel
+    }()
+
+    lazy var pageControl: TYPageControl = {
+        let pageControl = TYPageControl()
+        pageControl.currentPageIndicatorSize = CGSize(width: 6, height: 6)
+        pageControl.pageIndicatorSize = CGSize(width: 6, height: 6)
+        pageControl.currentPageIndicatorTintColor = .white
+        pageControl.pageIndicatorTintColor = .white.withAlphaComponent(0.5)
+        pageControl.pageIndicatorSpaing = 8
+        return pageControl
+    }()
+    lazy var cyclePagerView: TYCyclePagerView = {
+        let pagerView = TYCyclePagerView()
+        pagerView.isInfiniteLoop = true
+        pagerView.autoScrollInterval = 3.0
+        pagerView.delegate = self
+        pagerView.dataSource = self
+        pagerView.layout.layoutType = TYCyclePagerTransformLayoutType.linear
+        pagerView.register(TSDiscoverBannerViewCell.classForCoder(), forCellWithReuseIdentifier: TSDiscoverBannerViewCell.reuseIdentifier)
+        
+        pagerView.addSubview(pageControl)
+        pageControl.snp.makeConstraints { make in
+            make.bottom.equalTo(0)
+            make.leading.trailing.equalTo(0)
+            make.height.equalTo(14)
+        }
+        
+        
+        return pagerView
+    }()
+    
+    override func upDateModel() {
+        if let models = items as? [TSDiscoverItemModel] {
+            self.models = models
+        }
+    }
+    
+    override func creatUI() {
+
+        addSubview(cyclePagerView)
+        cyclePagerView.snp.makeConstraints { make in
+            make.edges.equalToSuperview()
+        }
+    }
+
+    override func willDisplay(indexPath: IndexPath) {
+        super.willDisplay(indexPath: indexPath)
+        let visibleCells = cyclePagerView.collectionView!.getAllLoadedCells()
+        for cell in visibleCells {
+            if let cl = cell as? TSBaseCollectionCell {
+                cl.willDisplay(indexPath: indexPath)
+            }
+        }
+    }
+    
+    override func didEndDisplaying(indexPath: IndexPath) {
+        super.didEndDisplaying(indexPath: indexPath)
+        let visibleCells = cyclePagerView.collectionView!.getAllLoadedCells()
+        for cell in visibleCells {
+            if let cl = cell as? TSBaseCollectionCell {
+                cl.didEndDisplaying(indexPath: indexPath)
+            }
+        }
+    }
+
+}
+
+
+extension TSDiscoverBannerCell : TYCyclePagerViewDelegate, TYCyclePagerViewDataSource{
+    
+    func numberOfItems(in pageView: TYCyclePagerView) -> Int {
+        return models.count
+    }
+    
+    func pagerView(_ pagerView: TYCyclePagerView, cellForItemAt index: Int) -> UICollectionViewCell {
+        let cell = pagerView.dequeueReusableCell(withReuseIdentifier: TSDiscoverBannerViewCell.reuseIdentifier, for: index) as! TSDiscoverBannerViewCell
+        
+        if let itemModel = models.safeObj(At: index) {
+            cell.model = itemModel
+        }
+        
+        return cell
+    }
+    
+    func layout(for pageView: TYCyclePagerView) -> TYCyclePagerViewLayout {
+        let layout = TYCyclePagerViewLayout()
+        layout.itemSize = itemSize
+        layout.itemSpacing = 0
+        layout.itemHorizontalCenter = true
+        layout.layoutType = .normal
+        return layout
+    }
+
+    func pagerView(_ pageView: TYCyclePagerView, didSelectedItemCell cell: UICollectionViewCell, at index: Int) {
+        if let model = models.safeObj(At: index) {
+            clickBlock?(model)
+        }
+    }
+    
+    func pagerViewDidScroll(_ pageView: TYCyclePagerView) {
+
+    }
+    
+    
+    func pagerView(_ pageView: TYCyclePagerView, didScrollFrom fromIndex: Int, to toIndex: Int) {
+        self.pageControl.currentPage = toIndex;
+        
+        guard let collectionView = pageView.collectionView else { return }
+        for section in 0..<collectionView.numberOfSections {
+            for item in 0..<collectionView.numberOfItems(inSection: section) {
+                let indexPath = IndexPath(item: item, section: section)
+                if let cell = collectionView.cellForItem(at: indexPath) as? TSBaseCollectionCell {
+                    if indexPath.item == pageView.curIndex{
+                        cell.willDisplay(indexPath: indexPath)
+                    }else{
+                        cell.didEndDisplaying(indexPath: indexPath)
+                    }
+                }
+            }
+        }
+        
+    }
+}
+
+
+//MARK: TSDiscoverBannerViewCell
+class TSDiscoverBannerViewCell: TSBaseCollectionCell {
+    static let reuseIdentifier = "TSDiscoverBannerViewCell"
+    
+    lazy var textLabel: UILabel = {
+        let textLabel = UILabel.createLabel(font: .font(size: 22,weight: .semibold),textColor: .white)
+        return textLabel
+    }()
+    
+    lazy var imageView: UIImageView = {
+        let imageView = UIImageView.createImageView(contentMode: .scaleAspectFill,backgroundColor: .white.withAlphaComponent(0.2))
+        return imageView
+    }()
+    
+    lazy var shadowView: UIImageView = {
+        let imageView = UIImageView.createImageView(image:.discoverBannerlShaow,contentMode: .scaleToFill)
+        return imageView
+    }()
+    
+    lazy var tryNowBtn: UIButton = {
+        let tryNowBtn = UIButton.createButton(title: "Try Now".localized,backgroundColor: .themeColor,font: .font(size: 12),titleColor: "#111111".uiColor,corner: 12)
+        tryNowBtn.isUserInteractionEnabled = false
+        tryNowBtn.contentEdgeInsets = UIEdgeInsets(top: 0, left: 12, bottom: 0, right: 12)
+        return tryNowBtn
+    }()
+    
+    var videoPlayer: TSVideoPlayer?
+    var videoURL:URL?
+    
+    var model:TSDiscoverItemModel? {
+        didSet {
+            guard let model = model else { return }
+            textLabel.text = model.name
+    
+            if let animationModel = model.viewModel as? TSDiscoverAnimationItemVM,let imageNamed = animationModel.imageNameds.first {
+                if let videoURL = Bundle.main.url(forResource: imageNamed, withExtension: nil) {
+                    self.videoURL = videoURL
+                    imageView.image = TSVideoPlayer.getFirstFrameOnly(url: videoURL)
+                    dePrint("UICollectionViewCell model set")
+                }
+            }
+        }
+    }
+    
+    override func creatUI() {
+        bgContentView.addSubview(imageView)
+        bgContentView.addSubview(shadowView)
+        bgContentView.addSubview(textLabel)
+        bgContentView.addSubview(tryNowBtn)
+        
+        imageView.snp.makeConstraints { make in
+            make.edges.equalToSuperview()
+        }
+        
+        shadowView.snp.makeConstraints { make in
+            make.height.equalTo(100)
+            make.leading.trailing.bottom.equalToSuperview()
+        }
+        
+        textLabel.snp.makeConstraints { make in
+            make.leading.equalTo(16)
+            make.trailing.equalTo(-111)
+            make.bottom.equalTo(-18)
+            make.height.equalTo(52)
+        }
+        
+        tryNowBtn.snp.makeConstraints { make in
+            make.trailing.equalTo(-16)
+            make.centerY.equalTo(textLabel)
+            make.height.equalTo(24)
+        }
+    }
+    
+
+    func setVideoPlayer(){
+        guard let videoURL = self.videoURL else { return }
+         //如果URL相同且播放器存在,则只更新播放状态
+        if  videoPlayer?.url == videoURL, videoPlayer != nil {
+            videoPlayer?.play()
+            return
+        }
+        
+        // 清理之前的播放器
+        videoPlayer?.cleanup()
+        videoPlayer = nil
+        
+        self.videoPlayer = TSVideoPlayer()
+        self.videoPlayer?.setupPlayer(with: videoURL)
+      
+        self.videoPlayer?.addPlayerLayer(to: self.imageView, frame: self.contentView.bounds)
+        self.videoPlayer?.play()
+    }
+  
+    override func willDisplay(indexPath: IndexPath)  {
+        super.willDisplay(indexPath: indexPath)
+        kMainAfter(0.1) {
+            if self.isCellDisplay {
+                self.setVideoPlayer()
+                dePrint("UICollectionViewCell 视频播放")
+            }else{
+                dePrint("UICollectionViewCell self.isDisplay 不可见了")
+                self.videoPlayer?.pause()
+            }
+        }
+    }
+    
+    override func didEndDisplaying(indexPath: IndexPath)  {
+        super.didEndDisplaying(indexPath: indexPath)
+        videoPlayer?.pause()
+        dePrint("UICollectionViewCell 视频暂停")
+    }
+}
+

+ 0 - 1
AIEmoji/Business2/DisCover/TSDiscoverVC/Cell/TSDiscoverBaseCell.swift

@@ -6,7 +6,6 @@
 //
 
 class TSDiscoverBaseCell: TSBaseCollectionCell {
-    
     var clickBlock:((TSDiscoverItemModel)->Void)?
     var items:Any? {
         didSet {

+ 12 - 0
AIEmoji/Business2/DisCover/TSDiscoverVC/Cell/TSDiscoverHeaderView.swift

@@ -12,6 +12,18 @@ class TSDiscoverHeaderView: UICollectionReusableView {
         didSet{
             moreView.titleLab.text = sectionModel.title.localized
             moreView.moreView.isHidden = sectionModel.style != .styleMore
+            
+            if sectionModel.colors.count == 1 {
+                moreView.titleLab.textColor = sectionModel.colors.first?.toColor()
+            }else if sectionModel.colors.count > 1 {
+                var colors:[UIColor] = []
+                for colorString in self.sectionModel.colors {
+                    colors.append(colorString.uiColor)
+                }
+                kMainAsync {
+                    self.moreView.titleLab.applyGradient(colors: colors)
+                }
+            }
         }
     }
     

+ 173 - 4
AIEmoji/Business2/DisCover/TSDiscoverVC/Cell/TSDiscoverStyleMoreCell/TSDiscoverStyleMoreCell.swift

@@ -6,8 +6,8 @@
 //
 class TSDiscoverStyleMoreCell : TSDiscoverBaseCell {
     
-    lazy var collectionView: UICollectionView = {
-        let layout = UICollectionViewFlowLayout()
+    lazy var collectionView: TSBaseCollectionView = {
+        let layout = TSBaseCollectionViewFlowLayout()
         layout.scrollDirection = .horizontal
         layout.minimumLineSpacing = 16
         layout.minimumInteritemSpacing = 16
@@ -18,6 +18,7 @@ class TSDiscoverStyleMoreCell : TSDiscoverBaseCell {
         collectionView.register(TSDiscoverStyleMoreBaseCell.self, forCellWithReuseIdentifier: "TSDiscoverStyleMoreBaseCell")
         collectionView.register(TSDiscoverStyleMoreAnimationCellCell.self, forCellWithReuseIdentifier: "TSDiscoverStyleMoreAnimationCellCell")
         collectionView.register(TSDiscoverStyleMoreAnimationGifCell.self, forCellWithReuseIdentifier: "TSDiscoverStyleMoreAnimationGifCell")
+        collectionView.register(TSDiscoverStyleMoreAnimationVideoCell.self, forCellWithReuseIdentifier: "TSDiscoverStyleMoreAnimationVideoCell")
         collectionView.contentInset = kDiscoverSection
         return collectionView
     }()
@@ -35,6 +36,30 @@ class TSDiscoverStyleMoreCell : TSDiscoverBaseCell {
             make.edges.equalToSuperview()
         }
     }
+    
+    
+    override func willDisplay(indexPath: IndexPath) {
+        super.willDisplay(indexPath: indexPath)
+        let visibleCells = collectionView.getAllLoadedCells()
+        for cell in visibleCells {
+            if let cl = cell as? TSBaseCollectionCell {
+                cl.willDisplay(indexPath: indexPath)
+            }
+        }
+    }
+    
+    override func didEndDisplaying(indexPath: IndexPath) {
+        super.didEndDisplaying(indexPath: indexPath)
+        let visibleCells = collectionView.getAllLoadedCells()
+        for cell in visibleCells {
+            if let cl = cell as? TSBaseCollectionCell {
+                cl.didEndDisplaying(indexPath: indexPath)
+            }
+        }
+    }
+    
+
+    
 }
 extension TSDiscoverStyleMoreCell: UICollectionViewDataSource ,UICollectionViewDelegate {
     public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
@@ -56,6 +81,19 @@ extension TSDiscoverStyleMoreCell: UICollectionViewDataSource ,UICollectionViewD
                         return cell
                     }
                 }
+                else if animationModel.style == .video {
+                    if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "TSDiscoverStyleMoreAnimationVideoCell", for: indexPath) as? TSDiscoverStyleMoreAnimationVideoCell{
+                        cell.model = dbModel
+                        return cell
+                    }
+                }
+                
+                else{
+                    if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "TSDiscoverStyleMoreAnimationGifCell", for: indexPath) as? TSDiscoverStyleMoreAnimationGifCell{
+                        cell.model = dbModel
+                        return cell
+                    }
+                }
             }else{
                 if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "TSDiscoverStyleMoreBaseCell", for: indexPath) as? TSDiscoverStyleMoreBaseCell{
                     cell.model = dbModel
@@ -71,12 +109,47 @@ extension TSDiscoverStyleMoreCell: UICollectionViewDataSource ,UICollectionViewD
             clickBlock?(model)
         }
     }
+    
+    // 当cell即将显示时恢复播放
+    func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
+        if let cell = cell as? TSBaseCollectionCell {
+            cell.willDisplay(indexPath: indexPath)
+        }
+    }
+    
+    // 当cell结束显示时暂停播放
+    func collectionView(_ collectionView: UICollectionView, didEndDisplaying cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
+        if let cell = cell as? TSBaseCollectionCell {
+            cell.didEndDisplaying(indexPath: indexPath)
+        }
+    }
 }
 
+//> 2500    极速惯性滚动    手指快速滑动后立即松开    暂停所有媒体,取消所有加载,只显示占位图,释放非核心资源
+//1800-2500    快速惯性滚动    中等力度快速滑动    暂停非中心区域媒体,降低图片质量,减少图层特效
+//1000-1800    中速惯性滚动    正常滑动后松开    保持中心区域内容加载,预加载即将进入视区的cell
+//400-1000    慢速惯性滚动    轻滑动或即将停止    开始加载高清资源,准备恢复播放,预加载更多相邻内容
+//< 400    即将停止/慢速滑动    自然减速到最后或用户缓慢滑动    恢复所有媒体播放,加载最佳质量资源,执行完整布局渲染
+extension UIScrollView {
+    /// 当前惯性滚动速度(points/sec)
+    var inertialScrollVelocity: CGPoint {
+        return panGestureRecognizer.velocity(in: self)
+    }
+    
+    /// 判断是否处于快速惯性滚动状态
+    var isFastDecelerating: Bool {
+        guard isDecelerating else { return false }
+        let velocity = abs(inertialScrollVelocity.y)
+        debugPrint("velocity=\(velocity)")
+        return velocity > 1800 // 使用推荐阈值
+    }
+}
 
 
 private let CellCornerRadius = 16.0
 class TSDiscoverStyleMoreBaseCell: TSBaseCollectionCell {
+    
+    static var collectionView:UICollectionView?
     var model:TSDiscoverItemModel? {
         didSet {
             guard let model = model else { return }
@@ -86,7 +159,7 @@ class TSDiscoverStyleMoreBaseCell: TSBaseCollectionCell {
     }
 
     lazy var imageView: UIImageView = {
-        let imageView = UIImageView.createImageView(contentMode: .scaleToFill,backgroundColor: .white.withAlphaComponent(0.2))
+        let imageView = UIImageView.createImageView(contentMode: .scaleAspectFill,backgroundColor: .white.withAlphaComponent(0.2))
         imageView.cornerRadius = CellCornerRadius
         return imageView
     }()
@@ -175,7 +248,7 @@ class TSDiscoverStyleMoreAnimationGifCell: TSDiscoverStyleMoreBaseCell {
                 if let gifURL = Bundle.main.url(forResource: imageNamed, withExtension: "gif") {
                     animatedImageView.kf.setImage(with: gifURL, options: [.cacheOriginalImage]){ result in
                         switch result {
-                        case .success(let _):
+                        case .success(_):
                             self.animatedImageView.startAnimating()
                         case .failure(let error):
                             print("GIF 加载失败: \(error.localizedDescription)")
@@ -189,6 +262,7 @@ class TSDiscoverStyleMoreAnimationGifCell: TSDiscoverStyleMoreBaseCell {
     lazy var animatedImageView: AnimatedImageView = {
         let animatedImageView = AnimatedImageView()
         animatedImageView.autoPlayAnimatedImage = false
+        animatedImageView.contentMode = .scaleAspectFill
         return animatedImageView
     }()
     
@@ -198,6 +272,101 @@ class TSDiscoverStyleMoreAnimationGifCell: TSDiscoverStyleMoreBaseCell {
         animatedImageView.snp.makeConstraints { make in
             make.edges.equalToSuperview()
         }
+    }
+    
+    override func willDisplay(indexPath: IndexPath)  {
+        super.willDisplay(indexPath: indexPath)
+        animatedImageView.startAnimating()
+    }
+    
+    override func didEndDisplaying(indexPath: IndexPath) {
+        super.didEndDisplaying(indexPath: indexPath)
+        animatedImageView.stopAnimating()
+    }
+}
 
+class TSDiscoverStyleMoreAnimationVideoCell: TSDiscoverStyleMoreBaseCell {
+    var videoPlayer: TSVideoPlayer?
+    var videoURL:URL?
+    override var model:TSDiscoverItemModel? {
+        didSet {
+            guard let model = model else { return }
+            textLabel.text = model.name
+    
+            if let animationModel = model.viewModel as? TSDiscoverAnimationItemVM,let imageNamed = animationModel.imageNameds.first {
+                if let videoURL = Bundle.main.url(forResource: imageNamed, withExtension: nil) {
+                    self.videoURL = videoURL
+                    imageView.image = TSVideoPlayer.getFirstFrameOnly(url: videoURL)
+                    dePrint("UICollectionViewCell model set")
+                }
+            }
+        }
+    }
+    
+    func isFastDecelerating() -> Bool {
+        guard let collectionView = Self.collectionView else { return false }
+        return collectionView.isFastDecelerating
+    }
+    
+    func setVideoPlayer(){
+        guard let videoURL = self.videoURL else { return }
+         //如果URL相同且播放器存在,则只更新播放状态
+        if  videoPlayer?.url == videoURL, videoPlayer != nil {
+            videoPlayer?.play()
+            return
+        }
+        
+        // 清理之前的播放器
+        videoPlayer?.cleanup()
+        videoPlayer = nil
+        
+        self.videoPlayer = TSVideoPlayer()
+        self.videoPlayer?.setupPlayer(with: videoURL)
+      
+        self.videoPlayer?.addPlayerLayer(to: self.imageView, frame: self.contentView.bounds)
+        self.videoPlayer?.play()
     }
+  
+    override func willDisplay(indexPath: IndexPath)  {
+        super.willDisplay(indexPath: indexPath)
+        kMainAfter(kVideoDelayedPlay) {
+            if self.isCellDisplay {
+                self.setVideoPlayer()
+                dePrint("UICollectionViewCell 视频播放")
+            }else{
+                dePrint("UICollectionViewCell self.isDisplay 不可见了")
+                self.videoPlayer?.pause()
+            }
+        }
+    }
+    
+    override func didEndDisplaying(indexPath: IndexPath)  {
+        super.didEndDisplaying(indexPath: indexPath)
+        videoPlayer?.pause()
+        dePrint("UICollectionViewCell 视频暂停")
+    }
+    
+//    override func dealThings() {
+//        NotificationCenter.default.addObserver(forName: .kDiscoverScrollViewWillBegin, object: nil, queue: .main) {[weak self] notification in
+//            guard let self = self else { return }
+//            videoPlayer?.pause()
+//        }
+//        
+//        NotificationCenter.default.addObserver(forName: .kDiscoverScrollViewEndDecelerating, object: nil, queue: .main) {[weak self] notification in
+//            guard let self = self else { return }
+//  
+//            if self.isCellDisplay {
+//                self.setVideoPlayer()
+//                dePrint("UICollectionViewCell 视频播放")
+//            }else{
+//                dePrint("UICollectionViewCell self.isDisplay 不可见了")
+//                self.videoPlayer?.pause()
+//            }
+//        }
+//    }
+//    
+//    deinit {
+//        dePrint("TSDiscoverStyleMoreAnimationVideoCell deinit")
+//        NotificationCenter.default.removeObserver(self)
+//    }
 }

+ 24 - 2
AIEmoji/Business2/DisCover/TSDiscoverVC/TSDiscoverStyleMoreVC/TSDiscoverStyleMoreVC.swift

@@ -29,8 +29,8 @@ class TSDiscoverStyleMoreVC: TSBaseVC {
     
     //###################################### 集合视图 ######################################
     let collectionViewBtootm:CGFloat = k_Height_safeAreaInsetsBottom() + 10
-    lazy var collectionView: UICollectionView = {
-        let layout = UICollectionViewFlowLayout()
+    lazy var collectionView: TSBaseCollectionView = {
+        let layout = TSBaseCollectionViewFlowLayout()
         layout.scrollDirection = .vertical
         
         let itemW = (k_ScreenWidth-32.0-13.0-2.0)/2.0
@@ -47,6 +47,7 @@ class TSDiscoverStyleMoreVC: TSBaseVC {
         collectionView.register(TSDiscoverStyleMoreBaseCell.self, forCellWithReuseIdentifier: "TSDiscoverStyleMoreBaseCell")
         collectionView.register(TSDiscoverStyleMoreAnimationCellCell.self, forCellWithReuseIdentifier: "TSDiscoverStyleMoreAnimationCellCell")
         collectionView.register(TSDiscoverStyleMoreAnimationGifCell.self, forCellWithReuseIdentifier: "TSDiscoverStyleMoreAnimationGifCell")
+        collectionView.register(TSDiscoverStyleMoreAnimationVideoCell.self, forCellWithReuseIdentifier: "TSDiscoverStyleMoreAnimationVideoCell")
         return collectionView
     }()
     
@@ -84,6 +85,11 @@ extension TSDiscoverStyleMoreVC: UICollectionViewDataSource ,UICollectionViewDel
                         cell.model = dbModel
                         return cell
                     }
+                }else if animationModel.style == .video {
+                    if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "TSDiscoverStyleMoreAnimationVideoCell", for: indexPath) as? TSDiscoverStyleMoreAnimationVideoCell{
+                        cell.model = dbModel
+                        return cell
+                    }
                 }
             }else{
                 if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "TSDiscoverStyleMoreBaseCell", for: indexPath) as? TSDiscoverStyleMoreBaseCell{
@@ -100,5 +106,21 @@ extension TSDiscoverStyleMoreVC: UICollectionViewDataSource ,UICollectionViewDel
             TSDiscoverVC.clickCell(target: self,indexPath: indexPath, itemModel:model,secModel: sectionModel)
         }
     }
+    
+    // 当cell即将显示时恢复播放
+    func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
+        if let cell = cell as? TSDiscoverStyleMoreBaseCell {
+            dePrint("UICollectionViewCell willDisplay indexPath.item=\(indexPath.item)")
+            cell.willDisplay(indexPath: indexPath)
+        }
+    }
+    
+    // 当cell结束显示时暂停播放
+    func collectionView(_ collectionView: UICollectionView, didEndDisplaying cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
+        if let cell = cell as? TSDiscoverStyleMoreBaseCell {
+            dePrint("UICollectionViewCell Displaying  indexPath.item=\(indexPath.item)")
+            cell.didEndDisplaying(indexPath: indexPath)
+        }
+    }
 }
 

+ 64 - 13
AIEmoji/Business2/DisCover/TSDiscoverVC/TSDiscoverVC.swift

@@ -6,7 +6,7 @@
 //
 
 class TSDiscoverVC: TSBaseVC {
-    
+
     let viewModel = kTSDiscoverVM
     var hintBaseVC:TSAIListHintBaseVC = TSAIListHintBaseVC(config: .defaultConfig)
     lazy var photoPickerManager: TSPhotoPickerManager = TSPhotoPickerManager(viewController: self)
@@ -37,7 +37,7 @@ class TSDiscoverVC: TSBaseVC {
     lazy var navBarView: TSBaseNavContentBarView = {
         let navBarView = TSBaseNavContentBarView()
 
-        let label = UILabel.createLabel(text: "Discover",font: .font(name: .KelsiFill,size: 28))
+        let label = UILabel.createLabel(text: "Discover".localized,font: .font(size: 22,weight: .semibold),textColor: .white)
         navBarView.barView.addSubview(label)
         label.snp.makeConstraints { make in
             make.centerY.equalToSuperview()
@@ -61,10 +61,7 @@ class TSDiscoverVC: TSBaseVC {
         purchaseCountdownView.snp.makeConstraints { make in
             make.height.equalTo(24)
         }
-        
-        kMainAsync {
-            label.applyGradient(colors: ["#FA794F".uiColor,"#F8C32A".uiColor,"#FEFBF4".uiColor])
-        }
+
         
        return navBarView
     }()
@@ -79,7 +76,7 @@ class TSDiscoverVC: TSBaseVC {
             collectionView.register(cases.cell, forCellWithReuseIdentifier: String(describing: cases.cell))
         }
         collectionView.register(TSDiscoverHeaderView.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: "TSDiscoverHeaderView")
-        
+  
         return collectionView
     }()
     
@@ -91,10 +88,16 @@ class TSDiscoverVC: TSBaseVC {
             make.edges.equalToSuperview()
         }
         
+        contentView.snp.updateConstraints { make in
+            make.top.equalTo(0)
+        }
+        
         contentView.addSubview(collectionView)
         collectionView.snp.makeConstraints { make in
             make.edges.equalToSuperview()
         }
+        
+        TSDiscoverStyleMoreBaseCell.collectionView = collectionView
     }
     
     override func dealThings() {
@@ -186,7 +189,7 @@ extension TSDiscoverVC: UICollectionViewDataSource ,UICollectionViewDelegate,UIC
     func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets{
         if let secModel = viewModel.discoverDatas.safeObj(At:section) {
             var sectionEdge = UIEdgeInsets(top: 0, left: kDiscoverSection.left, bottom: 0, right: kDiscoverSection.right)
-            if secModel.title.isEmpty {
+            if secModel.title.isEmpty,section != 0 {
                 sectionEdge = UIEdgeInsets(top: 20, left: kDiscoverSection.left, bottom: 0, right: kDiscoverSection.right)
             }
             if section == viewModel.discoverDatas.count-1 {
@@ -203,8 +206,50 @@ extension TSDiscoverVC: UICollectionViewDataSource ,UICollectionViewDelegate,UIC
         }
         return .zero
     }
+    
+    // 当cell即将显示时恢复播放
+    func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
+        if let cell = cell as? TSDiscoverBaseCell {
+            cell.willDisplay(indexPath: indexPath)
+        }
+    }
+    
+    // 当cell结束显示时暂停播放
+    func collectionView(_ collectionView: UICollectionView, didEndDisplaying cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
+        if let cell = cell as? TSDiscoverBaseCell {
+            cell.didEndDisplaying(indexPath: indexPath)
+        }
+    }
 }
 
+//extension TSDiscoverVC: UIScrollViewDelegate {
+//    // 开始拖拽(用户开始滚动)
+//    func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
+//        print("滚动开始")
+//        NotificationCenter.default.post(name: .kDiscoverScrollViewWillBegin, object: nil)
+//    }
+//
+//    // 结束拖拽(用户手指离开屏幕)
+//    func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
+//        if !decelerate {
+//            print("滚动完全停止(无减速动画)")
+//            NotificationCenter.default.post(name: .kDiscoverScrollViewEndDecelerating, object: nil)
+//        }
+//    }
+//    
+//    // 结束减速(滚动完全停止)
+//    func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
+//        print("滚动完全停止")
+//        NotificationCenter.default.post(name: .kDiscoverScrollViewEndDecelerating, object: nil)
+//    }
+//    
+//    // 以下方法组合可以准确判断滚动是否真正结束
+//    func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) {
+//        print("编程触发的滚动动画结束")
+//        NotificationCenter.default.post(name: .kDiscoverScrollViewEndDecelerating, object: nil)
+//    }
+//}
+
 extension TSDiscoverVC {
     
     func clickHeader(indexPath:IndexPath,model:TSDiscoverSectionModel) {
@@ -217,9 +262,16 @@ extension TSDiscoverVC {
            TSGenerateBasePhotoOperationQueue.isAvailabilityHandle(view: target.view)
         { return }
         
+        var style = itemModel.style
         
-        dePrint("\(itemModel.style)")
-        switch itemModel.style {
+        if style == .photoLive,
+           let animationModel = itemModel.viewModel as? TSDiscoverAnimationItemVM,
+           animationModel.style == .video {
+            style = .videoV2
+        }
+        
+        dePrint("\(style)")
+        switch style{
         case .ageOld, .ageChild, .oldPhoto, .eyeOpen, .pretty, .photoLive, .photoQuality, .catTohuman,.process:
             kPushVC(target: target, modelVC: TSAIUploadPhotoBaseVC(titleString: itemModel.name, generatorStyle: itemModel.style,disCoverItemModel: itemModel))
         case .photoExpand:
@@ -246,12 +298,11 @@ extension TSDiscoverVC {
             let vc = TSChatViewController()
             vc.viewModel.uiStyle = .chat
             kPushVC(target: target, modelVC: vc)
-        case .ptp:
+        case .ptp,.videoV2:
             if let generateModel = itemModel.generateModel{
-                kPushVC(target: target, modelVC: TSPTPUploadImageVC(generateModel: generateModel, sectionModel: secModel))
+                kPushVC(target: target, modelVC: TSPTPUploadImageVC(itemModel:itemModel,generateModel: generateModel, sectionModel: secModel))
             }
         default:
-            
             break
         }
     }

+ 14 - 0
AIEmoji/Business2/DisCover/TSGenerateHistoryVC/TSGenerateHistoryVC.swift

@@ -250,6 +250,20 @@ extension TSGenerateHistoryVC: UICollectionViewDataSource ,UICollectionViewDeleg
         }
         kPresentModalVC(target: self, modelVC: browseVC,transitionStyle: .crossDissolve)
     }
+    
+    // 当cell即将显示时恢复播放
+    func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
+        if let cell = cell as? TSBaseCollectionCell {
+            cell.willDisplay(indexPath: indexPath)
+        }
+    }
+    
+    // 当cell结束显示时暂停播放
+    func collectionView(_ collectionView: UICollectionView, didEndDisplaying cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
+        if let cell = cell as? TSBaseCollectionCell {
+            cell.didEndDisplaying(indexPath: indexPath)
+        }
+    }
 }
 
 extension TSGenerateHistoryVC{

+ 53 - 14
AIEmoji/Business2/DisCover/TSGenerateHistoryVC/View/TSGenerateHistoryCell.swift

@@ -97,12 +97,12 @@ class TSGenerateHistoryCell: TSBaseCollectionCell {
         return showImageView
     }()
     
-    lazy var hiddenImageView: UIImageView = {
-        let hiddenImageView = UIImageView.createImageView(imageName:"",contentMode: .scaleAspectFill)
-        hiddenImageView.backgroundColor = .gray
-        hiddenImageView.isHidden = true
-        return hiddenImageView
-    }()
+//    lazy var hiddenImageView: UIImageView = {
+//        let hiddenImageView = UIImageView.createImageView(imageName:"",contentMode: .scaleAspectFill)
+//        hiddenImageView.backgroundColor = .gray
+//        hiddenImageView.isHidden = true
+//        return hiddenImageView
+//    }()
     
     lazy var videoIconImageView: UIImageView = {
         let videoIconImageView = UIImageView.createImageView(image:.videoIcon,contentMode: .scaleToFill,autoMirrored:false)
@@ -123,12 +123,12 @@ class TSGenerateHistoryCell: TSBaseCollectionCell {
         contentView.addGestureRecognizer(longPressRecognizer)
         contentView.cornerRadius = 12.0
 
-        contentView.addSubview(hiddenImageView)
-        hiddenImageView.snp.makeConstraints { make in
-            make.top.equalTo(0)
-            make.leading.equalTo(0)
-            make.trailing.bottom.equalTo(0)
-        }
+//        contentView.addSubview(hiddenImageView)
+//        hiddenImageView.snp.makeConstraints { make in
+//            make.top.equalTo(0)
+//            make.leading.equalTo(0)
+//            make.trailing.bottom.equalTo(0)
+//        }
         
         contentView.addSubview(showImageView)
         showImageView.snp.makeConstraints { make in
@@ -156,6 +156,44 @@ class TSGenerateHistoryCell: TSBaseCollectionCell {
             make.edges.equalToSuperview()
         }
     }
+    var videoPlayer: TSVideoPlayer?
+    var videoURL:URL?
+    override func willDisplay(indexPath: IndexPath)  {
+        super.willDisplay(indexPath: indexPath)
+        kMainAfter(kVideoDelayedPlay) {
+            if self.isCellDisplay {
+                self.setVideoPlayer()
+                dePrint("UICollectionViewCell 视频播放")
+            }else{
+                dePrint("UICollectionViewCell self.isDisplay 不可见了")
+                self.videoPlayer?.pause()
+            }
+        }
+    }
+    
+    override func didEndDisplaying(indexPath: IndexPath)  {
+        super.didEndDisplaying(indexPath: indexPath)
+        videoPlayer?.pause()
+        dePrint("UICollectionViewCell 视频暂停")
+    }
+    
+    func setVideoPlayer(){
+        guard let videoURL = self.videoURL else { return }
+         //如果URL相同且播放器存在,则只更新播放状态
+        if  videoPlayer?.url == videoURL, videoPlayer != nil {
+            videoPlayer?.play()
+            return
+        }
+        // 清理之前的播放器
+        videoPlayer?.cleanup()
+        videoPlayer = nil
+        
+        self.videoPlayer = TSVideoPlayer()
+        self.videoPlayer?.setupPlayer(with: videoURL)
+      
+        self.videoPlayer?.addPlayerLayer(to: self.showImageView, frame: self.contentView.bounds)
+        self.videoPlayer?.play()
+    }
 }
 
 extension TSGenerateHistoryCell {
@@ -183,10 +221,11 @@ extension TSGenerateHistoryCell {
                 videoIconImageView.isHidden = !model.isVideo
                 if dataModel.isVideo {
                     videoIconImageView.isHidden = false
-                    showImageView.setAsyncImage(urlString: model.videoPreviewUrlString,contentMode: .scaleAspectFill,backgroundColor: .white.withAlphaComponent(0.1))
+                    self.videoURL = model.videoURL
+                    showImageView.image = TSVideoPlayer.getFirstFrameOnly(url: self.videoURL!)
                 }else {
                     showImageView.setAsyncImage(urlString: model.response.resultUrl,contentMode: .scaleAspectFill,backgroundColor: .white.withAlphaComponent(0.1))
-                    hiddenImageView.setAsyncImage(urlString: model.request.imageUrl,contentMode: .scaleAspectFill)
+//                    hiddenImageView.setAsyncImage(urlString: model.request.imageUrl,contentMode: .scaleAspectFill)
                 }
             }
 

+ 50 - 9
AIEmoji/Business2/DisCover/TSPTPUploadImageVC/TSPTPUploadImageVC+View.swift

@@ -27,6 +27,45 @@ extension TSPTPUploadImageVC {
             viewModel.selectedStyleIndex = indexPath.item
             
             setTitleText(model.imageText.localized)
+            
+            if viewModel.style == .videoV2 ||  viewModel.style == .photoLive{
+                var array:[Any] = []
+                
+                if let arr = TSDiscoverViewModel.shared.bannerSection.items.first as? [TSDiscoverItemModel] {
+                    array.append(contentsOf: arr)
+                }
+                if let arr = TSDiscoverViewModel.shared.videoEffectSection.items.first as? [TSDiscoverItemModel] {
+                    array.append(contentsOf: arr)
+                }
+                
+//                for item in TSDiscoverViewModel.shared.bannerSection.items.first! {
+//                    array.append(item)
+//                }
+//                for item in TSDiscoverViewModel.shared.videoEffectSection.items.first! {
+//                    array.append(item)
+//                }
+
+//                    array.append(contentsOf: TSDiscoverViewModel.shared.bannerSection.items)
+//                array.append(contentsOf: TSDiscoverViewModel.shared.videoEffectSection.items)
+//                let array = TSDiscoverViewModel.shared.bannerSection.items.first + TSDiscoverViewModel.shared.videoEffectSection.items.first
+        
+//                let model2 = array.first(where: { model1 in
+//                    guard let model1 = model1 as? TSDiscoverItemModel else{
+//                         return false
+//                     }
+//                    return model1.generateModel?.imageText == model.imageText
+//                })
+//                
+//                if let discoverItemModel = model2 as? TSDiscoverItemModel,
+//                    let animationItemVM = discoverItemModel.viewModel as? TSDiscoverAnimationItemVM{
+//                    self.uploadView.uploadVideoView.setVideoName(name: animationItemVM.imageNamed)
+//                }
+//                if let discoverItemModel = self.sectionModel.items.safeObj(At: indexPath.item) as? TSDiscoverItemModel,
+//                    let animationItemVM = discoverItemModel.viewModel as? TSDiscoverAnimationItemVM{
+//                    self.uploadView.uploadVideoView.setVideoName(name: animationItemVM.imageNamed)
+//                }
+            }
+    
         }
         selectStyleVC.scrollHandle = { [weak self] scroll in
             guard let self = self else { return }
@@ -38,29 +77,31 @@ extension TSPTPUploadImageVC {
     
     func creatCreatBtnView() -> TSAppBtnView {
         let creatBtnView = TSAppBtnView()
-        creatBtnView.setUpButton(style: .generate, vipFreeNumType: .aiGenerate) { [weak self] in
+        let vipFreeNumType = viewModel.style.vipFreeNumType
+        creatBtnView.setUpButton(style: .generate, vipFreeNumType: vipFreeNumType) { [weak self] in
             guard let self = self else { return }
             generateImage()
         }
         creatBtnView.setBtnEnabled(isEnabled: false)
         creatBtnView.isIconVipBlock = { [weak self] in
             guard let self = self else { return false }
-            var showVip = kPurchaseDefault.generateVipShow(type: .aiGenerate)
-//            if showVip == false {
-//                showVip = self.viewModel.selectedPTPStyleModel.isVip
-//            }
+            var showVip = kPurchaseDefault.generateVipShow(type: vipFreeNumType)
+            if showVip == false,vipFreeNumType == .videoV2 {
+                showVip = self.viewModel.selectedPTPStyleModel.isVip
+            }
             return showVip
         }
         creatBtnView.isClickVipBlock = { [weak self] in
             guard let self = self else { return false }
-            var isVip = kPurchaseDefault.freeNumAvailable(type: .aiGenerate) == false
-//            if viewModel.selectedPTPStyleModel.isVip == true {
-//                isVip = true
-//            }
+            var isVip = kPurchaseDefault.freeNumAvailable(type: vipFreeNumType) == false
+            if isVip == false,vipFreeNumType == .videoV2 {
+                isVip = self.viewModel.selectedPTPStyleModel.isVip
+            }
             return isVip
         }
         return creatBtnView
     }
+
 }
 
 

+ 23 - 16
AIEmoji/Business2/DisCover/TSPTPUploadImageVC/TSPTPUploadImageVC.swift

@@ -6,32 +6,28 @@
 //
 
 class TSPTPUploadImageVC: TSBaseVC {
-    var generateModel:TSGenerateModel
+//    var generateModel:TSGenerateModel
     var sectionModel:TSDiscoverSectionModel
-    init(generateModel:TSGenerateModel,sectionModel: TSDiscoverSectionModel) {
-        self.generateModel = generateModel
+    var viewModel: TSPTPUploadImageVM
+    var itemModel:TSDiscoverItemModel
+    init(itemModel:TSDiscoverItemModel,generateModel:TSGenerateModel,sectionModel: TSDiscoverSectionModel) {
+//        self.generateModel = generateModel
         self.sectionModel = sectionModel
+        self.itemModel = itemModel
+        self.viewModel = TSPTPUploadImageVM(style:itemModel.style,generateModel:generateModel,sectionModel: sectionModel)
         super.init()
     }
     
     @MainActor required init?(coder: NSCoder) {
         fatalError("init(coder:) has not been implemented")
     }
-    
-    lazy var viewModel: TSPTPUploadImageVM = {
-        let viewModel = TSPTPUploadImageVM(generateModel:generateModel,sectionModel: sectionModel)
-        viewModel.isCanGennerateBlock = { [weak self] _ in
-            guard let self = self else { return }
-            setCreatBtnEnabled()
-        }
-        return viewModel
-    }()
-    
+
     lazy var photoPickerManager: TSPhotoPickerManager = TSPhotoPickerManager(viewController: self)
     lazy var uploadView: TSUploadImageView = creatUploadView()
     lazy var selectStyleVC: TSGennertatorStyleVC = creatSelectStyleVC()
     lazy var creatBtnView: TSAppBtnView = creatCreatBtnView() //Button
 
+    
     override func createView() {
         addNormalNavBarView()
         setPageTitle(viewModel.selectedPTPStyleModel.imageText.localized)
@@ -44,7 +40,6 @@ class TSPTPUploadImageVC: TSBaseVC {
             make.height.equalTo(280*kDesignScale)
         }
         
-        
         self.addChild(selectStyleVC)
         contentView.addSubview(selectStyleVC.view)
         selectStyleVC.view.snp.makeConstraints { make in
@@ -52,7 +47,6 @@ class TSPTPUploadImageVC: TSBaseVC {
             make.top.equalTo(uploadView.snp.bottom).offset(24)
         }
         
-        
         contentView.addSubview(creatBtnView)
         creatBtnView.snp.makeConstraints { make in
             make.bottom.equalTo(-k_Height_safeAreaInsetsBottom())
@@ -60,11 +54,24 @@ class TSPTPUploadImageVC: TSBaseVC {
             make.trailing.equalTo(-16)
             make.height.equalTo(48)
         }
+        
+        if viewModel.style == .videoV2 ||  viewModel.style == .photoLive{
+            kMainAsync {
+                self.uploadView.uploadVideoView.setVideoName(name: self.itemModel.imageNamed)
+                self.uploadView.upLoadImage = self.uploadView.upLoadImage
+            }
+        }
+
     }
     
     override func dealThings() {
         NotificationCenter.default.addObserver(self, selector: #selector(updateVipView), name: .kPurchaseDidChanged, object: nil)
         updateVipView()
+        
+        self.viewModel.isCanGennerateBlock = { [weak self] _ in
+            guard let self = self else { return }
+            setCreatBtnEnabled()
+        }
     }
     
 }
@@ -86,7 +93,7 @@ extension TSPTPUploadImageVC {
 }
 
 extension TSPTPUploadImageVC {
-    func pickSinglePhoto() {
+    @objc func pickSinglePhoto() {
         photoPickerManager.pickCustomSinglePhoto { [weak self] image, errorString in
             guard let self = self else { return }
             if let errorString = errorString {

Vissa filer visades inte eftersom för många filer har ändrats