瀏覽代碼

1.基础框架替换为本地 pod库
2.整体大功能点基本调通

100Years 2 月之前
父節點
當前提交
b9c47b76c4
共有 87 個文件被更改,包括 1056 次插入4643 次删除
  1. 20 196
      AIEmoji.xcodeproj/project.pbxproj
  2. 14 1
      AIEmoji/AppDelegate.swift
  3. 22 0
      AIEmoji/Assets.xcassets/AIChat/aichat_avatar.imageset/Contents.json
  4. 二進制
      AIEmoji/Assets.xcassets/AIChat/aichat_avatar.imageset/aichat_avatar@2x.png
  5. 二進制
      AIEmoji/Assets.xcassets/AIChat/aichat_avatar.imageset/aichat_avatar@3x.png
  6. 22 0
      AIEmoji/Assets.xcassets/Common/delete_white.imageset/Contents.json
  7. 二進制
      AIEmoji/Assets.xcassets/Common/delete_white.imageset/delete_white@2x.png
  8. 二進制
      AIEmoji/Assets.xcassets/Common/delete_white.imageset/delete_white@3x.png
  9. 22 0
      AIEmoji/Assets.xcassets/Common/pageNull.imageset/Contents.json
  10. 二進制
      AIEmoji/Assets.xcassets/Common/pageNull.imageset/pageNull@2x.png
  11. 二進制
      AIEmoji/Assets.xcassets/Common/pageNull.imageset/pageNull@3x.png
  12. 17 74
      AIEmoji/Business/AIChat/TSAIChatContainerVC.swift
  13. 5 0
      AIEmoji/Business/AIChat/TSAIChatHistoryVC/M/TSAIChatHistoryModel.swift
  14. 212 99
      AIEmoji/Business/AIChat/TSAIChatHistoryVC/TSAIChatHistoryVC.swift
  15. 136 0
      AIEmoji/Business/AIChat/TSAIChatHistoryVC/TSViewController.swift
  16. 47 54
      AIEmoji/Business/AIChat/TSAIChatHistoryVC/VM/TSAIChatHistoryVM.swift
  17. 40 19
      AIEmoji/Business/AIChat/TSChatViewController/Models/TSDBAIChatList.swift
  18. 161 154
      AIEmoji/Business/AIChat/TSChatViewController/TSChatViewController.swift
  19. 15 8
      AIEmoji/Business/AIChat/TSChatViewController/ViewModel/TSAIChatVM.swift
  20. 0 66
      AIEmoji/Business/AIChat/TSChatViewController/Views/CustomCell.swift
  21. 124 116
      AIEmoji/Business/AIChat/TSChatViewController/Views/CustomMessageContentCell.swift
  22. 43 46
      AIEmoji/Business/AIChat/TSChatViewController/Views/CustomTextMessageContentCell.swift
  23. 12 0
      AIEmoji/Business/General/Ex/Notification+Ex.swift
  24. 1 1
      AIEmoji/Business/General/TSBottomAlertVC.swift
  25. 14 1
      AIEmoji/Business/General/TSSmallIconBrowseVC/TSSmallIconBrowseVC.swift
  26. 3 3
      AIEmoji/Business/TSEmojisVC/TSEmojisChildVC/TSEmojisChildVC.swift
  27. 4 1
      AIEmoji/Business/TSEmojisVC/TSEmojisChildVC/VIew/TSEmojisCoLItemCell.swift
  28. 4 4
      AIEmoji/Business/TSEmojisVC/TSEmojisChildVC/ViewModel/TSEmojisChildColViewModel.swift
  29. 1 1
      AIEmoji/Business/TSEmojisVC/TSEmojisChildVC/ViewModel/TSEmojisChildViewModel.swift
  30. 2 2
      AIEmoji/Business/TSGenmojiVC/TSGenmojiVC/TSGenmojiVC.swift
  31. 1 1
      AIEmoji/Business/TSGenmojiVC/TSGenmojiVC/View/TSGenmojiColSectionView.swift
  32. 2 2
      AIEmoji/Business/TSGenmojiVC/TSGenmojiVC/View/TSGenmojiGennerateCell.swift
  33. 1 1
      AIEmoji/Business/TSGenmojiVC/TSGenmojiVC/View/TSGenmojiItemCell.swift
  34. 6 6
      AIEmoji/Business/TSGenmojiVC/TSGenmojiVC/ViewModel/TSGenmojiCollectionViewModel.swift
  35. 1 1
      AIEmoji/Business/TSGenmojiVC/TSGenmojiVC/ViewModel/TSGenmojiViewModel.swift
  36. 3 2
      AIEmoji/Business/TSSetingVC/SetingVC/TSSetingViewModel.swift
  37. 1 1
      AIEmoji/Business/TSSetingVC/SetingVC/View/SettingPurchaseTopView.swift
  38. 1 1
      AIEmoji/Business/TSTabBarController/TSTabBarController.swift
  39. 2 2
      AIEmoji/Business/TSWallpaperVC/DiyWallpaper/Elemnet/DiyFixedTextElement.swift
  40. 2 2
      AIEmoji/Business/TSWallpaperVC/DiyWallpaper/Elemnet/DiyTextElement.swift
  41. 1 1
      AIEmoji/Business/TSWallpaperVC/DiyWallpaper/Templates/DiyPaperTemplateBaseView.swift
  42. 2 2
      AIEmoji/Business/TSWallpaperVC/TSDiyKeyboardVC/TSWallpaperVC.swift
  43. 2 2
      AIEmoji/Business/TSWallpaperVC/TSDiyKeyboardViewVC/View/TSKeyboardView.swift
  44. 45 0
      AIEmoji/Business/VIewTool/TSPageNullView.swift
  45. 1 1
      AIEmoji/Business/VIewTool/TSViewTool.swift
  46. 0 142
      AIEmoji/Common/BaseClass/TSBaseCollectionCell.swift
  47. 0 52
      AIEmoji/Common/BaseClass/TSBaseModel.swift
  48. 0 166
      AIEmoji/Common/BaseClass/TSBaseNavigationBarView.swift
  49. 0 110
      AIEmoji/Common/BaseClass/TSBaseNavigationC.swift
  50. 0 40
      AIEmoji/Common/BaseClass/TSBaseTabViewCell.swift
  51. 0 240
      AIEmoji/Common/BaseClass/TSBaseVC.swift
  52. 0 41
      AIEmoji/Common/BaseClass/TSBaseView.swift
  53. 0 24
      AIEmoji/Common/BaseClass/TSBaseViewModel.swift
  54. 0 144
      AIEmoji/Common/BaseClass/TSBasicItemModel.swift
  55. 0 78
      AIEmoji/Common/Ex/AVAsset+Ex.swift
  56. 0 47
      AIEmoji/Common/Ex/Array+Ex.swift
  57. 0 37
      AIEmoji/Common/Ex/CGFloat+Ex.swift
  58. 0 32
      AIEmoji/Common/Ex/Date+Ex.swift
  59. 0 45
      AIEmoji/Common/Ex/Dictionary+Ex.swift
  60. 0 33
      AIEmoji/Common/Ex/Int+Ex.swift
  61. 0 295
      AIEmoji/Common/Ex/NSString+Ex.swift
  62. 0 47
      AIEmoji/Common/Ex/SwiftUI/Color+Ex.swift
  63. 0 16
      AIEmoji/Common/Ex/SwiftUI/Font+Ex.swift
  64. 0 12
      AIEmoji/Common/Ex/UIApplication+Ex.swift
  65. 0 123
      AIEmoji/Common/Ex/UIButton+Ex.swift
  66. 0 139
      AIEmoji/Common/Ex/UICollectionView+Ex.swift
  67. 0 49
      AIEmoji/Common/Ex/UIColor+Ex.swift
  68. 0 110
      AIEmoji/Common/Ex/UIDevice+Extension.swift
  69. 0 66
      AIEmoji/Common/Ex/UIFont+Ex.swift
  70. 0 130
      AIEmoji/Common/Ex/UIImage+Ex.swift
  71. 0 124
      AIEmoji/Common/Ex/UIImageView+Ex.swift
  72. 0 88
      AIEmoji/Common/Ex/UILabel+Ex.swift
  73. 0 43
      AIEmoji/Common/Ex/UIScreen.swift
  74. 0 195
      AIEmoji/Common/Ex/UITableView+Ex.swift
  75. 0 7
      AIEmoji/Common/Ex/UITextView+Ex.swift
  76. 0 319
      AIEmoji/Common/Ex/UIView+Ex.swift
  77. 0 54
      AIEmoji/Common/Ex/UIViewController+Ex.swift
  78. 0 30
      AIEmoji/Common/Ex/UserDefault+Ex.swift
  79. 12 3
      AIEmoji/Common/GlobalImports/GlobalImports.swift
  80. 0 302
      AIEmoji/Common/View/UICollectionView+Component/CollectionViewComponent.swift
  81. 0 63
      AIEmoji/Common/View/UICollectionView+Component/CommonSectionComponent.swift
  82. 0 64
      AIEmoji/Common/View/UICollectionView+Component/Component.swift
  83. 0 164
      AIEmoji/Common/View/UICollectionView+Component/UICollectionView+More.swift
  84. 0 76
      AIEmoji/Common/View/UITableView+TSItemModel/TSSimpleTableView.swift
  85. 19 20
      AIEmoji/DataManger/Config/TSConfig.swift
  86. 1 1
      Podfile
  87. 12 1
      Podfile.lock

+ 20 - 196
AIEmoji.xcodeproj/project.pbxproj

@@ -21,7 +21,6 @@
 		A80E723F2D3F4D3700C64288 /* Universe🌍.json in Resources */ = {isa = PBXBuildFile; fileRef = A80E723E2D3F4D3000C64288 /* Universe🌍.json */; };
 		A80E72462D3F4EED00C64288 /* sticker.json in Resources */ = {isa = PBXBuildFile; fileRef = A80E72452D3F4EED00C64288 /* sticker.json */; };
 		A80E72482D3F4F0A00C64288 /* templates.json in Resources */ = {isa = PBXBuildFile; fileRef = A80E72472D3F4F0500C64288 /* templates.json */; };
-		A80E724D2D3F515B00C64288 /* TSBaseViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A80E724C2D3F515200C64288 /* TSBaseViewModel.swift */; };
 		A80E724F2D3F6D7F00C64288 /* DiyFixedTextElement.swift in Sources */ = {isa = PBXBuildFile; fileRef = A80E724E2D3F6D6000C64288 /* DiyFixedTextElement.swift */; };
 		A80E72532D3F985E00C64288 /* TSWallpaperVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A80E72522D3F985D00C64288 /* TSWallpaperVC.swift */; };
 		A80E72562D3F98D700C64288 /* TSDiyKeyboardViewVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A80E72552D3F98D600C64288 /* TSDiyKeyboardViewVC.swift */; };
@@ -34,7 +33,6 @@
 		A80E726C2D409E8300C64288 /* TSDiyTLPinkAnimalView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A80E726B2D409E8000C64288 /* TSDiyTLPinkAnimalView.swift */; };
 		A80E726F2D40DE2B00C64288 /* TSWallpaperPreviewVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A80E726E2D40DE2900C64288 /* TSWallpaperPreviewVC.swift */; };
 		A80E72722D40F86000C64288 /* TSLaunchVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A80E72712D40F86000C64288 /* TSLaunchVC.swift */; };
-		A80E72742D40FEA600C64288 /* UIApplication+Ex.swift in Sources */ = {isa = PBXBuildFile; fileRef = A80E72732D40FEA000C64288 /* UIApplication+Ex.swift */; };
 		A80E72772D41EFF900C64288 /* TSEmojisTutorialsVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A80E72762D41EFF700C64288 /* TSEmojisTutorialsVC.swift */; };
 		A80E72792D42285500C64288 /* TSBootPageVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A80E72782D42285500C64288 /* TSBootPageVC.swift */; };
 		A80E73E12D533E5800C64288 /* TSPurchaseVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A80E73D82D533E5800C64288 /* TSPurchaseVC.swift */; };
@@ -51,7 +49,6 @@
 		A89EA66B2D59AA31000EB181 /* CustomTextMessageContentCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A89EA6662D59AA31000EB181 /* CustomTextMessageContentCell.swift */; };
 		A89EA66C2D59AA31000EB181 /* CustomMessageContentCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A89EA6652D59AA31000EB181 /* CustomMessageContentCell.swift */; };
 		A89EA66D2D59AA31000EB181 /* TableViewCells.swift in Sources */ = {isa = PBXBuildFile; fileRef = A89EA6672D59AA31000EB181 /* TableViewCells.swift */; };
-		A89EA66E2D59AA31000EB181 /* CustomCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A89EA6642D59AA31000EB181 /* CustomCell.swift */; };
 		A89EA6762D59C93E000EB181 /* TSAIChatContainerVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A89EA6752D59C932000EB181 /* TSAIChatContainerVC.swift */; };
 		A89EA67A2D59D25F000EB181 /* TSAIChatVM.swift in Sources */ = {isa = PBXBuildFile; fileRef = A89EA6792D59D248000EB181 /* TSAIChatVM.swift */; };
 		A89EA67D2D59F1AF000EB181 /* StreamPostRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = A89EA67C2D59F1AC000EB181 /* StreamPostRequest.swift */; };
@@ -62,6 +59,9 @@
 		A89EA6B12D5C9D0C000EB181 /* TSAIChatHistoryVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A89EA6B02D5C9D0B000EB181 /* TSAIChatHistoryVC.swift */; };
 		A89EA6B42D5C9D43000EB181 /* TSAIChatHistoryVM.swift in Sources */ = {isa = PBXBuildFile; fileRef = A89EA6B32D5C9D3D000EB181 /* TSAIChatHistoryVM.swift */; };
 		A89EA6B82D5D7EE9000EB181 /* TSAIChatHistoryModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A89EA6B72D5D7EE4000EB181 /* TSAIChatHistoryModel.swift */; };
+		A89EA6BA2D5DDE5B000EB181 /* TSPageNullView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A89EA6B92D5DDE4E000EB181 /* TSPageNullView.swift */; };
+		A89EA6BC2D5DFB12000EB181 /* TSViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A89EA6BB2D5DFB0D000EB181 /* TSViewController.swift */; };
+		A89EA6BF2D5E03D6000EB181 /* Notification+Ex.swift in Sources */ = {isa = PBXBuildFile; fileRef = A89EA6BE2D5E03D3000EB181 /* Notification+Ex.swift */; };
 		A8EEADD42D3E6C660032C5A0 /* Flower💐.json in Resources */ = {isa = PBXBuildFile; fileRef = A8EEADD32D3E6C610032C5A0 /* Flower💐.json */; };
 		A8EEADD62D3E6CD80032C5A0 /* Fish🐠.json in Resources */ = {isa = PBXBuildFile; fileRef = A8EEADD52D3E6CD30032C5A0 /* Fish🐠.json */; };
 		A8EEADD82D3E74D20032C5A0 /* Pink🩷.json in Resources */ = {isa = PBXBuildFile; fileRef = A8EEADD72D3E74CB0032C5A0 /* Pink🩷.json */; };
@@ -73,52 +73,16 @@
 		A8F7748B2D38E8B700AA6E93 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F774812D38E8B700AA6E93 /* AppDelegate.swift */; };
 		A8F7748E2D38E8B700AA6E93 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A8F774822D38E8B700AA6E93 /* Assets.xcassets */; };
 		A8F774902D38E8B700AA6E93 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = A8F774852D38E8B700AA6E93 /* LaunchScreen.storyboard */; };
-		A8F774D92D38EA8C00AA6E93 /* UICollectionView+More.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F774D22D38EA8C00AA6E93 /* UICollectionView+More.swift */; };
-		A8F774DA2D38EA8C00AA6E93 /* UIFont+Ex.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F774AA2D38EA8C00AA6E93 /* UIFont+Ex.swift */; };
-		A8F774DB2D38EA8C00AA6E93 /* AVAsset+Ex.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F774A02D38EA8C00AA6E93 /* AVAsset+Ex.swift */; };
-		A8F774DC2D38EA8C00AA6E93 /* NSString+Ex.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F774A52D38EA8C00AA6E93 /* NSString+Ex.swift */; };
-		A8F774DE2D38EA8C00AA6E93 /* UIDevice+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F774A92D38EA8C00AA6E93 /* UIDevice+Extension.swift */; };
 		A8F774E02D38EA8C00AA6E93 /* TSCommonTool.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F774C72D38EA8C00AA6E93 /* TSCommonTool.swift */; };
 		A8F774E12D38EA8C00AA6E93 /* TSFileManagerTool.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F774CA2D38EA8C00AA6E93 /* TSFileManagerTool.swift */; };
-		A8F774E22D38EA8C00AA6E93 /* UICollectionView+Ex.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F774A72D38EA8C00AA6E93 /* UICollectionView+Ex.swift */; };
-		A8F774E32D38EA8C00AA6E93 /* TSBasicItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F7749A2D38EA8C00AA6E93 /* TSBasicItemModel.swift */; };
-		A8F774E42D38EA8C00AA6E93 /* Component.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F774D12D38EA8C00AA6E93 /* Component.swift */; };
-		A8F774E52D38EA8C00AA6E93 /* Color+Ex.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F7749C2D38EA8C00AA6E93 /* Color+Ex.swift */; };
-		A8F774E62D38EA8C00AA6E93 /* UIScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F774AE2D38EA8C00AA6E93 /* UIScreen.swift */; };
-		A8F774E82D38EA8C00AA6E93 /* CollectionViewComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F774CF2D38EA8C00AA6E93 /* CollectionViewComponent.swift */; };
-		A8F774E92D38EA8C00AA6E93 /* UILabel+Ex.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F774AD2D38EA8C00AA6E93 /* UILabel+Ex.swift */; };
-		A8F774EB2D38EA8C00AA6E93 /* TSBaseNavigationC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F774962D38EA8C00AA6E93 /* TSBaseNavigationC.swift */; };
 		A8F774EC2D38EA8C00AA6E93 /* TSToastTool.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F774CC2D38EA8C00AA6E93 /* TSToastTool.swift */; };
-		A8F774ED2D38EA8C00AA6E93 /* Font+Ex.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F7749D2D38EA8C00AA6E93 /* Font+Ex.swift */; };
-		A8F774EE2D38EA8C00AA6E93 /* UIViewController+Ex.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F774B02D38EA8C00AA6E93 /* UIViewController+Ex.swift */; };
-		A8F774EF2D38EA8C00AA6E93 /* UIImage+Ex.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F774AB2D38EA8C00AA6E93 /* UIImage+Ex.swift */; };
-		A8F774F02D38EA8C00AA6E93 /* TSBaseCollectionCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F774932D38EA8C00AA6E93 /* TSBaseCollectionCell.swift */; };
-		A8F774F12D38EA8C00AA6E93 /* CGFloat+Ex.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F774A12D38EA8C00AA6E93 /* CGFloat+Ex.swift */; };
-		A8F774F22D38EA8C00AA6E93 /* TSBaseView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F774992D38EA8C00AA6E93 /* TSBaseView.swift */; };
-		A8F774F42D38EA8C00AA6E93 /* TSBaseNavigationBarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F774952D38EA8C00AA6E93 /* TSBaseNavigationBarView.swift */; };
-		A8F774F52D38EA8C00AA6E93 /* Array+Ex.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F7749F2D38EA8C00AA6E93 /* Array+Ex.swift */; };
-		A8F774F62D38EA8C00AA6E93 /* UIImageView+Ex.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F774AC2D38EA8C00AA6E93 /* UIImageView+Ex.swift */; };
-		A8F774F82D38EA8C00AA6E93 /* TSSimpleTableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F774D42D38EA8C00AA6E93 /* TSSimpleTableView.swift */; };
-		A8F774F92D38EA8C00AA6E93 /* UIColor+Ex.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F774A82D38EA8C00AA6E93 /* UIColor+Ex.swift */; };
-		A8F774FA2D38EA8C00AA6E93 /* TSBaseModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F774942D38EA8C00AA6E93 /* TSBaseModel.swift */; };
-		A8F774FE2D38EA8C00AA6E93 /* Int+Ex.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F774A42D38EA8C00AA6E93 /* Int+Ex.swift */; };
-		A8F774FF2D38EA8C00AA6E93 /* UserDefault+Ex.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F774B12D38EA8C00AA6E93 /* UserDefault+Ex.swift */; };
 		A8F775002D38EA8C00AA6E93 /* WindowHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F774CD2D38EA8C00AA6E93 /* WindowHelper.swift */; };
-		A8F775012D38EA8C00AA6E93 /* UIButton+Ex.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F774A62D38EA8C00AA6E93 /* UIButton+Ex.swift */; };
-		A8F775022D38EA8C00AA6E93 /* Dictionary+Ex.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F774A32D38EA8C00AA6E93 /* Dictionary+Ex.swift */; };
 		A8F775032D38EA8C00AA6E93 /* GlobalImports.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F774B42D38EA8C00AA6E93 /* GlobalImports.swift */; };
-		A8F775062D38EA8C00AA6E93 /* Date+Ex.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F774A22D38EA8C00AA6E93 /* Date+Ex.swift */; };
-		A8F775072D38EA8C00AA6E93 /* UIView+Ex.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F774B22D38EA8C00AA6E93 /* UIView+Ex.swift */; };
-		A8F775082D38EA8C00AA6E93 /* UITableView+Ex.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F774AF2D38EA8C00AA6E93 /* UITableView+Ex.swift */; };
-		A8F775092D38EA8C00AA6E93 /* CommonSectionComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F774D02D38EA8C00AA6E93 /* CommonSectionComponent.swift */; };
 		A8F7750A2D38EA8C00AA6E93 /* TSNetworkTool.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F774CB2D38EA8C00AA6E93 /* TSNetworkTool.swift */; };
-		A8F7750B2D38EA8C00AA6E93 /* TSBaseTabViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F774972D38EA8C00AA6E93 /* TSBaseTabViewCell.swift */; };
-		A8F7750D2D38EA8C00AA6E93 /* TSBaseVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F774982D38EA8C00AA6E93 /* TSBaseVC.swift */; };
 		A8F775172D38EB7400AA6E93 /* TSTabBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F775162D38EB7400AA6E93 /* TSTabBarController.swift */; };
 		A8F775192D38EC6800AA6E93 /* TSEmojisVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F775182D38EC6700AA6E93 /* TSEmojisVC.swift */; };
 		A8F7751B2D38EC9800AA6E93 /* TSGenmojiVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F7751A2D38EC9700AA6E93 /* TSGenmojiVC.swift */; };
 		A8F775252D38ED8300AA6E93 /* TSConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F775232D38ED8300AA6E93 /* TSConfig.swift */; };
-		A8F775322D38FA5E00AA6E93 /* UITextView+Ex.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F775312D38FA5200AA6E93 /* UITextView+Ex.swift */; };
 		A8F775352D38FC9A00AA6E93 /* TSViewTool.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F775342D38FC9A00AA6E93 /* TSViewTool.swift */; };
 		A8F775382D390C3C00AA6E93 /* TSNetworkManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F775372D390C3C00AA6E93 /* TSNetworkManager.swift */; };
 		A8F7753B2D3918DE00AA6E93 /* TSNetworkManager+Loading.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8F7753A2D3918D700AA6E93 /* TSNetworkManager+Loading.swift */; };
@@ -172,7 +136,6 @@
 		A80E723E2D3F4D3000C64288 /* Universe🌍.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = "Universe🌍.json"; sourceTree = "<group>"; };
 		A80E72452D3F4EED00C64288 /* sticker.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = sticker.json; sourceTree = "<group>"; };
 		A80E72472D3F4F0500C64288 /* templates.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = templates.json; sourceTree = "<group>"; };
-		A80E724C2D3F515200C64288 /* TSBaseViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSBaseViewModel.swift; sourceTree = "<group>"; };
 		A80E724E2D3F6D6000C64288 /* DiyFixedTextElement.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DiyFixedTextElement.swift; sourceTree = "<group>"; };
 		A80E72522D3F985D00C64288 /* TSWallpaperVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSWallpaperVC.swift; sourceTree = "<group>"; };
 		A80E72552D3F98D600C64288 /* TSDiyKeyboardViewVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSDiyKeyboardViewVC.swift; sourceTree = "<group>"; };
@@ -185,7 +148,6 @@
 		A80E726B2D409E8000C64288 /* TSDiyTLPinkAnimalView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSDiyTLPinkAnimalView.swift; sourceTree = "<group>"; };
 		A80E726E2D40DE2900C64288 /* TSWallpaperPreviewVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSWallpaperPreviewVC.swift; sourceTree = "<group>"; };
 		A80E72712D40F86000C64288 /* TSLaunchVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSLaunchVC.swift; sourceTree = "<group>"; };
-		A80E72732D40FEA000C64288 /* UIApplication+Ex.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIApplication+Ex.swift"; sourceTree = "<group>"; };
 		A80E72762D41EFF700C64288 /* TSEmojisTutorialsVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSEmojisTutorialsVC.swift; sourceTree = "<group>"; };
 		A80E72782D42285500C64288 /* TSBootPageVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSBootPageVC.swift; sourceTree = "<group>"; };
 		A80E73D82D533E5800C64288 /* TSPurchaseVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSPurchaseVC.swift; sourceTree = "<group>"; };
@@ -198,7 +160,6 @@
 		A89EA6522D59A9F4000EB181 /* TSChatUser.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSChatUser.swift; sourceTree = "<group>"; };
 		A89EA65E2D59AA11000EB181 /* TSChatViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSChatViewController.swift; sourceTree = "<group>"; };
 		A89EA6632D59AA31000EB181 /* CameraInputBarAccessoryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CameraInputBarAccessoryView.swift; sourceTree = "<group>"; };
-		A89EA6642D59AA31000EB181 /* CustomCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomCell.swift; sourceTree = "<group>"; };
 		A89EA6652D59AA31000EB181 /* CustomMessageContentCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomMessageContentCell.swift; sourceTree = "<group>"; };
 		A89EA6662D59AA31000EB181 /* CustomTextMessageContentCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomTextMessageContentCell.swift; sourceTree = "<group>"; };
 		A89EA6672D59AA31000EB181 /* TableViewCells.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TableViewCells.swift; sourceTree = "<group>"; };
@@ -212,6 +173,9 @@
 		A89EA6B02D5C9D0B000EB181 /* TSAIChatHistoryVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSAIChatHistoryVC.swift; sourceTree = "<group>"; };
 		A89EA6B32D5C9D3D000EB181 /* TSAIChatHistoryVM.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSAIChatHistoryVM.swift; sourceTree = "<group>"; };
 		A89EA6B72D5D7EE4000EB181 /* TSAIChatHistoryModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSAIChatHistoryModel.swift; sourceTree = "<group>"; };
+		A89EA6B92D5DDE4E000EB181 /* TSPageNullView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSPageNullView.swift; sourceTree = "<group>"; };
+		A89EA6BB2D5DFB0D000EB181 /* TSViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSViewController.swift; sourceTree = "<group>"; };
+		A89EA6BE2D5E03D3000EB181 /* Notification+Ex.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Notification+Ex.swift"; sourceTree = "<group>"; };
 		A8EEADD32D3E6C610032C5A0 /* Flower💐.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = "Flower💐.json"; sourceTree = "<group>"; };
 		A8EEADD52D3E6CD30032C5A0 /* Fish🐠.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = "Fish🐠.json"; sourceTree = "<group>"; };
 		A8EEADD72D3E74CB0032C5A0 /* Pink🩷.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = "Pink🩷.json"; sourceTree = "<group>"; };
@@ -225,52 +189,16 @@
 		A8F774822D38E8B700AA6E93 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
 		A8F774832D38E8B700AA6E93 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
 		A8F774842D38E8B700AA6E93 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
-		A8F774932D38EA8C00AA6E93 /* TSBaseCollectionCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSBaseCollectionCell.swift; sourceTree = "<group>"; };
-		A8F774942D38EA8C00AA6E93 /* TSBaseModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSBaseModel.swift; sourceTree = "<group>"; };
-		A8F774952D38EA8C00AA6E93 /* TSBaseNavigationBarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSBaseNavigationBarView.swift; sourceTree = "<group>"; };
-		A8F774962D38EA8C00AA6E93 /* TSBaseNavigationC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSBaseNavigationC.swift; sourceTree = "<group>"; };
-		A8F774972D38EA8C00AA6E93 /* TSBaseTabViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSBaseTabViewCell.swift; sourceTree = "<group>"; };
-		A8F774982D38EA8C00AA6E93 /* TSBaseVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSBaseVC.swift; sourceTree = "<group>"; };
-		A8F774992D38EA8C00AA6E93 /* TSBaseView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSBaseView.swift; sourceTree = "<group>"; };
-		A8F7749A2D38EA8C00AA6E93 /* TSBasicItemModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSBasicItemModel.swift; sourceTree = "<group>"; };
-		A8F7749C2D38EA8C00AA6E93 /* Color+Ex.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Color+Ex.swift"; sourceTree = "<group>"; };
-		A8F7749D2D38EA8C00AA6E93 /* Font+Ex.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Font+Ex.swift"; sourceTree = "<group>"; };
-		A8F7749F2D38EA8C00AA6E93 /* Array+Ex.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Array+Ex.swift"; sourceTree = "<group>"; };
-		A8F774A02D38EA8C00AA6E93 /* AVAsset+Ex.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AVAsset+Ex.swift"; sourceTree = "<group>"; };
-		A8F774A12D38EA8C00AA6E93 /* CGFloat+Ex.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CGFloat+Ex.swift"; sourceTree = "<group>"; };
-		A8F774A22D38EA8C00AA6E93 /* Date+Ex.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Date+Ex.swift"; sourceTree = "<group>"; };
-		A8F774A32D38EA8C00AA6E93 /* Dictionary+Ex.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Dictionary+Ex.swift"; sourceTree = "<group>"; };
-		A8F774A42D38EA8C00AA6E93 /* Int+Ex.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Int+Ex.swift"; sourceTree = "<group>"; };
-		A8F774A52D38EA8C00AA6E93 /* NSString+Ex.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSString+Ex.swift"; sourceTree = "<group>"; };
-		A8F774A62D38EA8C00AA6E93 /* UIButton+Ex.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIButton+Ex.swift"; sourceTree = "<group>"; };
-		A8F774A72D38EA8C00AA6E93 /* UICollectionView+Ex.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UICollectionView+Ex.swift"; sourceTree = "<group>"; };
-		A8F774A82D38EA8C00AA6E93 /* UIColor+Ex.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIColor+Ex.swift"; sourceTree = "<group>"; };
-		A8F774A92D38EA8C00AA6E93 /* UIDevice+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIDevice+Extension.swift"; sourceTree = "<group>"; };
-		A8F774AA2D38EA8C00AA6E93 /* UIFont+Ex.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIFont+Ex.swift"; sourceTree = "<group>"; };
-		A8F774AB2D38EA8C00AA6E93 /* UIImage+Ex.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIImage+Ex.swift"; sourceTree = "<group>"; };
-		A8F774AC2D38EA8C00AA6E93 /* UIImageView+Ex.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIImageView+Ex.swift"; sourceTree = "<group>"; };
-		A8F774AD2D38EA8C00AA6E93 /* UILabel+Ex.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UILabel+Ex.swift"; sourceTree = "<group>"; };
-		A8F774AE2D38EA8C00AA6E93 /* UIScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIScreen.swift; sourceTree = "<group>"; };
-		A8F774AF2D38EA8C00AA6E93 /* UITableView+Ex.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UITableView+Ex.swift"; sourceTree = "<group>"; };
-		A8F774B02D38EA8C00AA6E93 /* UIViewController+Ex.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIViewController+Ex.swift"; sourceTree = "<group>"; };
-		A8F774B12D38EA8C00AA6E93 /* UserDefault+Ex.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UserDefault+Ex.swift"; sourceTree = "<group>"; };
-		A8F774B22D38EA8C00AA6E93 /* UIView+Ex.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+Ex.swift"; sourceTree = "<group>"; };
 		A8F774B42D38EA8C00AA6E93 /* GlobalImports.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GlobalImports.swift; sourceTree = "<group>"; };
 		A8F774C72D38EA8C00AA6E93 /* TSCommonTool.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSCommonTool.swift; sourceTree = "<group>"; };
 		A8F774CA2D38EA8C00AA6E93 /* TSFileManagerTool.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSFileManagerTool.swift; sourceTree = "<group>"; };
 		A8F774CB2D38EA8C00AA6E93 /* TSNetworkTool.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSNetworkTool.swift; sourceTree = "<group>"; };
 		A8F774CC2D38EA8C00AA6E93 /* TSToastTool.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSToastTool.swift; sourceTree = "<group>"; };
 		A8F774CD2D38EA8C00AA6E93 /* WindowHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WindowHelper.swift; sourceTree = "<group>"; };
-		A8F774CF2D38EA8C00AA6E93 /* CollectionViewComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollectionViewComponent.swift; sourceTree = "<group>"; };
-		A8F774D02D38EA8C00AA6E93 /* CommonSectionComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CommonSectionComponent.swift; sourceTree = "<group>"; };
-		A8F774D12D38EA8C00AA6E93 /* Component.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Component.swift; sourceTree = "<group>"; };
-		A8F774D22D38EA8C00AA6E93 /* UICollectionView+More.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UICollectionView+More.swift"; sourceTree = "<group>"; };
-		A8F774D42D38EA8C00AA6E93 /* TSSimpleTableView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSSimpleTableView.swift; sourceTree = "<group>"; };
 		A8F775162D38EB7400AA6E93 /* TSTabBarController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSTabBarController.swift; sourceTree = "<group>"; };
 		A8F775182D38EC6700AA6E93 /* TSEmojisVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSEmojisVC.swift; sourceTree = "<group>"; };
 		A8F7751A2D38EC9700AA6E93 /* TSGenmojiVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSGenmojiVC.swift; sourceTree = "<group>"; };
 		A8F775232D38ED8300AA6E93 /* TSConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSConfig.swift; sourceTree = "<group>"; };
-		A8F775312D38FA5200AA6E93 /* UITextView+Ex.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UITextView+Ex.swift"; sourceTree = "<group>"; };
 		A8F775342D38FC9A00AA6E93 /* TSViewTool.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSViewTool.swift; sourceTree = "<group>"; };
 		A8F775372D390C3C00AA6E93 /* TSNetworkManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSNetworkManager.swift; sourceTree = "<group>"; };
 		A8F7753A2D3918D700AA6E93 /* TSNetworkManager+Loading.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TSNetworkManager+Loading.swift"; sourceTree = "<group>"; };
@@ -518,7 +446,6 @@
 			isa = PBXGroup;
 			children = (
 				A89EA6632D59AA31000EB181 /* CameraInputBarAccessoryView.swift */,
-				A89EA6642D59AA31000EB181 /* CustomCell.swift */,
 				A89EA6652D59AA31000EB181 /* CustomMessageContentCell.swift */,
 				A89EA6662D59AA31000EB181 /* CustomTextMessageContentCell.swift */,
 				A89EA6672D59AA31000EB181 /* TableViewCells.swift */,
@@ -560,6 +487,7 @@
 		A89EA6AF2D5C9861000EB181 /* TSAIChatHistoryVC */ = {
 			isa = PBXGroup;
 			children = (
+				A89EA6BB2D5DFB0D000EB181 /* TSViewController.swift */,
 				A89EA6B62D5D7ED2000EB181 /* M */,
 				A89EA6B22D5C9D36000EB181 /* VM */,
 				A89EA6B02D5C9D0B000EB181 /* TSAIChatHistoryVC.swift */,
@@ -583,6 +511,14 @@
 			path = M;
 			sourceTree = "<group>";
 		};
+		A89EA6BD2D5E03CD000EB181 /* Ex */ = {
+			isa = PBXGroup;
+			children = (
+				A89EA6BE2D5E03D3000EB181 /* Notification+Ex.swift */,
+			);
+			path = Ex;
+			sourceTree = "<group>";
+		};
 		A8F774602D38E8B000AA6E93 = {
 			isa = PBXGroup;
 			children = (
@@ -633,61 +569,6 @@
 			path = Business;
 			sourceTree = "<group>";
 		};
-		A8F7749B2D38EA8C00AA6E93 /* BaseClass */ = {
-			isa = PBXGroup;
-			children = (
-				A80E724C2D3F515200C64288 /* TSBaseViewModel.swift */,
-				A8F774932D38EA8C00AA6E93 /* TSBaseCollectionCell.swift */,
-				A8F774942D38EA8C00AA6E93 /* TSBaseModel.swift */,
-				A8F774952D38EA8C00AA6E93 /* TSBaseNavigationBarView.swift */,
-				A8F774962D38EA8C00AA6E93 /* TSBaseNavigationC.swift */,
-				A8F774972D38EA8C00AA6E93 /* TSBaseTabViewCell.swift */,
-				A8F774982D38EA8C00AA6E93 /* TSBaseVC.swift */,
-				A8F774992D38EA8C00AA6E93 /* TSBaseView.swift */,
-				A8F7749A2D38EA8C00AA6E93 /* TSBasicItemModel.swift */,
-			);
-			path = BaseClass;
-			sourceTree = "<group>";
-		};
-		A8F7749E2D38EA8C00AA6E93 /* SwiftUI */ = {
-			isa = PBXGroup;
-			children = (
-				A8F7749C2D38EA8C00AA6E93 /* Color+Ex.swift */,
-				A8F7749D2D38EA8C00AA6E93 /* Font+Ex.swift */,
-			);
-			path = SwiftUI;
-			sourceTree = "<group>";
-		};
-		A8F774B32D38EA8C00AA6E93 /* Ex */ = {
-			isa = PBXGroup;
-			children = (
-				A80E72732D40FEA000C64288 /* UIApplication+Ex.swift */,
-				A8F7749E2D38EA8C00AA6E93 /* SwiftUI */,
-				A8F7749F2D38EA8C00AA6E93 /* Array+Ex.swift */,
-				A8F774A02D38EA8C00AA6E93 /* AVAsset+Ex.swift */,
-				A8F774A12D38EA8C00AA6E93 /* CGFloat+Ex.swift */,
-				A8F774A22D38EA8C00AA6E93 /* Date+Ex.swift */,
-				A8F774A32D38EA8C00AA6E93 /* Dictionary+Ex.swift */,
-				A8F774A42D38EA8C00AA6E93 /* Int+Ex.swift */,
-				A8F774A52D38EA8C00AA6E93 /* NSString+Ex.swift */,
-				A8F774A62D38EA8C00AA6E93 /* UIButton+Ex.swift */,
-				A8F774A72D38EA8C00AA6E93 /* UICollectionView+Ex.swift */,
-				A8F774A82D38EA8C00AA6E93 /* UIColor+Ex.swift */,
-				A8F774A92D38EA8C00AA6E93 /* UIDevice+Extension.swift */,
-				A8F774AA2D38EA8C00AA6E93 /* UIFont+Ex.swift */,
-				A8F774AB2D38EA8C00AA6E93 /* UIImage+Ex.swift */,
-				A8F774AC2D38EA8C00AA6E93 /* UIImageView+Ex.swift */,
-				A8F774AD2D38EA8C00AA6E93 /* UILabel+Ex.swift */,
-				A8F774AE2D38EA8C00AA6E93 /* UIScreen.swift */,
-				A8F774AF2D38EA8C00AA6E93 /* UITableView+Ex.swift */,
-				A8F774B02D38EA8C00AA6E93 /* UIViewController+Ex.swift */,
-				A8F774B12D38EA8C00AA6E93 /* UserDefault+Ex.swift */,
-				A8F774B22D38EA8C00AA6E93 /* UIView+Ex.swift */,
-				A8F775312D38FA5200AA6E93 /* UITextView+Ex.swift */,
-			);
-			path = Ex;
-			sourceTree = "<group>";
-		};
 		A8F774B52D38EA8C00AA6E93 /* GlobalImports */ = {
 			isa = PBXGroup;
 			children = (
@@ -732,31 +613,10 @@
 			path = Tool;
 			sourceTree = "<group>";
 		};
-		A8F774D32D38EA8C00AA6E93 /* UICollectionView+Component */ = {
-			isa = PBXGroup;
-			children = (
-				A8F774CF2D38EA8C00AA6E93 /* CollectionViewComponent.swift */,
-				A8F774D02D38EA8C00AA6E93 /* CommonSectionComponent.swift */,
-				A8F774D12D38EA8C00AA6E93 /* Component.swift */,
-				A8F774D22D38EA8C00AA6E93 /* UICollectionView+More.swift */,
-			);
-			path = "UICollectionView+Component";
-			sourceTree = "<group>";
-		};
-		A8F774D62D38EA8C00AA6E93 /* UITableView+TSItemModel */ = {
-			isa = PBXGroup;
-			children = (
-				A8F774D42D38EA8C00AA6E93 /* TSSimpleTableView.swift */,
-			);
-			path = "UITableView+TSItemModel";
-			sourceTree = "<group>";
-		};
 		A8F774D72D38EA8C00AA6E93 /* View */ = {
 			isa = PBXGroup;
 			children = (
 				A8F776292D3A70AA00AA6E93 /* UILabel */,
-				A8F774D32D38EA8C00AA6E93 /* UICollectionView+Component */,
-				A8F774D62D38EA8C00AA6E93 /* UITableView+TSItemModel */,
 			);
 			path = View;
 			sourceTree = "<group>";
@@ -766,8 +626,6 @@
 			children = (
 				A89EA6AA2D5B3EE8000EB181 /* TSRealmManager */,
 				A80E73E32D533EB000C64288 /* Purchase */,
-				A8F7749B2D38EA8C00AA6E93 /* BaseClass */,
-				A8F774B32D38EA8C00AA6E93 /* Ex */,
 				A8F774B52D38EA8C00AA6E93 /* GlobalImports */,
 				A8F774B72D38EA8C00AA6E93 /* NetworkManager */,
 				A8F774C62D38EA8C00AA6E93 /* ThirdParty */,
@@ -844,6 +702,7 @@
 		A8F775332D38FC8E00AA6E93 /* VIewTool */ = {
 			isa = PBXGroup;
 			children = (
+				A89EA6B92D5DDE4E000EB181 /* TSPageNullView.swift */,
 				A8F7763B2D3B429A00AA6E93 /* TSCommonloadingView.swift */,
 				A8F776282D3A709200AA6E93 /* UILabel */,
 				A8F775342D38FC9A00AA6E93 /* TSViewTool.swift */,
@@ -975,6 +834,7 @@
 		A8F776402D3B75EA00AA6E93 /* General */ = {
 			isa = PBXGroup;
 			children = (
+				A89EA6BD2D5E03CD000EB181 /* Ex */,
 				A8F776412D3B75EF00AA6E93 /* TSBottomAlertVC.swift */,
 				A8F776432D3DE89900AA6E93 /* TSSmallIconBrowseVC */,
 			);
@@ -1182,11 +1042,9 @@
 			buildActionMask = 2147483647;
 			files = (
 				A8F775252D38ED8300AA6E93 /* TSConfig.swift in Sources */,
-				A8F774D92D38EA8C00AA6E93 /* UICollectionView+More.swift in Sources */,
 				A80E726C2D409E8300C64288 /* TSDiyTLPinkAnimalView.swift in Sources */,
 				A80E72652D409B0D00C64288 /* DiyStaticElement.swift in Sources */,
 				A89EA6B42D5C9D43000EB181 /* TSAIChatHistoryVM.swift in Sources */,
-				A8F774DA2D38EA8C00AA6E93 /* UIFont+Ex.swift in Sources */,
 				A80E72532D3F985E00C64288 /* TSWallpaperVC.swift in Sources */,
 				A8FB02B32D3E39A40031A396 /* TSEmojisModel.swift in Sources */,
 				A89EA6542D59A9F4000EB181 /* CustomTextLayoutSizeCalculator.swift in Sources */,
@@ -1194,38 +1052,28 @@
 				A89EA6562D59A9F4000EB181 /* TSChatUser.swift in Sources */,
 				A89EA6582D59A9F4000EB181 /* CustomLayoutSizeCalculator.swift in Sources */,
 				A89EA6592D59A9F4000EB181 /* CustomMessageFlowLayout.swift in Sources */,
-				A8F774DB2D38EA8C00AA6E93 /* AVAsset+Ex.swift in Sources */,
 				A80E72792D42285500C64288 /* TSBootPageVC.swift in Sources */,
 				A80E726A2D409E5400C64288 /* TSDiyTLYFlowersView.swift in Sources */,
 				A8F7764E2D3E00A800AA6E93 /* TSEmojisColViewModel.swift in Sources */,
 				A8F776422D3B75FC00AA6E93 /* TSBottomAlertVC.swift in Sources */,
-				A8F774DC2D38EA8C00AA6E93 /* NSString+Ex.swift in Sources */,
 				A8F775192D38EC6800AA6E93 /* TSEmojisVC.swift in Sources */,
 				A80E725C2D3FB09400C64288 /* TSKeyboardView.swift in Sources */,
 				A8F7753B2D3918DE00AA6E93 /* TSNetworkManager+Loading.swift in Sources */,
-				A8F774DE2D38EA8C00AA6E93 /* UIDevice+Extension.swift in Sources */,
 				A80E721A2D3F393A00C64288 /* DiyStickerModel.swift in Sources */,
-				A80E724D2D3F515B00C64288 /* TSBaseViewModel.swift in Sources */,
 				A80E726F2D40DE2B00C64288 /* TSWallpaperPreviewVC.swift in Sources */,
 				A8F775492D3935D600AA6E93 /* TSBusinessWebVC.swift in Sources */,
 				A8F776392D3B38E600AA6E93 /* TSGenmojiGennerateVC.swift in Sources */,
 				A8F774E02D38EA8C00AA6E93 /* TSCommonTool.swift in Sources */,
+				A89EA6BF2D5E03D6000EB181 /* Notification+Ex.swift in Sources */,
 				A8F774E12D38EA8C00AA6E93 /* TSFileManagerTool.swift in Sources */,
-				A8F774E22D38EA8C00AA6E93 /* UICollectionView+Ex.swift in Sources */,
 				A80E73E42D533EB000C64288 /* TSPurchaseManager.swift in Sources */,
-				A8F774E32D38EA8C00AA6E93 /* TSBasicItemModel.swift in Sources */,
 				A8F7762F2D3A765400AA6E93 /* TSGenmojiViewModel.swift in Sources */,
 				A8F7751B2D38EC9800AA6E93 /* TSGenmojiVC.swift in Sources */,
-				A8F774E42D38EA8C00AA6E93 /* Component.swift in Sources */,
-				A8F774E52D38EA8C00AA6E93 /* Color+Ex.swift in Sources */,
 				A8F7754E2D39E59100AA6E93 /* TSGenmojiModel.swift in Sources */,
 				A8F776452D3DE8A800AA6E93 /* TSSmallIconBrowseVC.swift in Sources */,
 				A80E72632D40925000C64288 /* TSDiyKeyboardVM.swift in Sources */,
-				A8F774E62D38EA8C00AA6E93 /* UIScreen.swift in Sources */,
 				A8F775432D39346400AA6E93 /* TSSetingModel.swift in Sources */,
-				A8F774E82D38EA8C00AA6E93 /* CollectionViewComponent.swift in Sources */,
-				A8F774E92D38EA8C00AA6E93 /* UILabel+Ex.swift in Sources */,
-				A8F774EB2D38EA8C00AA6E93 /* TSBaseNavigationC.swift in Sources */,
+				A89EA6BA2D5DDE5B000EB181 /* TSPageNullView.swift in Sources */,
 				A8F774EC2D38EA8C00AA6E93 /* TSToastTool.swift in Sources */,
 				A8F775502D39ECED00AA6E93 /* PhotoManager.swift in Sources */,
 				A8F7763F2D3B68E100AA6E93 /* TSGenmojiGennerateViewModel.swift in Sources */,
@@ -1235,40 +1083,24 @@
 				A80E72722D40F86000C64288 /* TSLaunchVC.swift in Sources */,
 				A8F775352D38FC9A00AA6E93 /* TSViewTool.swift in Sources */,
 				A80E72592D3FA67800C64288 /* TSWallpaperViewModel.swift in Sources */,
-				A8F774ED2D38EA8C00AA6E93 /* Font+Ex.swift in Sources */,
 				A89EA67D2D59F1AF000EB181 /* StreamPostRequest.swift in Sources */,
-				A8F774EE2D38EA8C00AA6E93 /* UIViewController+Ex.swift in Sources */,
-				A8F774EF2D38EA8C00AA6E93 /* UIImage+Ex.swift in Sources */,
-				A8F774F02D38EA8C00AA6E93 /* TSBaseCollectionCell.swift in Sources */,
 				A80E722F2D3F3E1400C64288 /* TSDiyCanvasView.swift in Sources */,
-				A8F774F12D38EA8C00AA6E93 /* CGFloat+Ex.swift in Sources */,
-				A8F774F22D38EA8C00AA6E93 /* TSBaseView.swift in Sources */,
-				A8F774F42D38EA8C00AA6E93 /* TSBaseNavigationBarView.swift in Sources */,
-				A8F774F52D38EA8C00AA6E93 /* Array+Ex.swift in Sources */,
 				A80E72672D409C7D00C64288 /* Template+More.swift in Sources */,
 				A89EA6AC2D5B3EFB000EB181 /* TSRealmManager.swift in Sources */,
 				A8F775172D38EB7400AA6E93 /* TSTabBarController.swift in Sources */,
-				A8F774F62D38EA8C00AA6E93 /* UIImageView+Ex.swift in Sources */,
 				A8F776272D3A6EC200AA6E93 /* TSGenmojiTextView.swift in Sources */,
 				A80E73E12D533E5800C64288 /* TSPurchaseVC.swift in Sources */,
-				A8F774F82D38EA8C00AA6E93 /* TSSimpleTableView.swift in Sources */,
 				A8F776352D3A7C2B00AA6E93 /* TSGenmojiColSectionView.swift in Sources */,
-				A8F774F92D38EA8C00AA6E93 /* UIColor+Ex.swift in Sources */,
 				A80E724F2D3F6D7F00C64288 /* DiyFixedTextElement.swift in Sources */,
-				A8F774FA2D38EA8C00AA6E93 /* TSBaseModel.swift in Sources */,
 				A8F775452D39347100AA6E93 /* TSSetingViewModel.swift in Sources */,
 				A80E72202D3F3A8600C64288 /* DiyElementBaseView.swift in Sources */,
 				A8F776212D3A3F0200AA6E93 /* TSEmojisChildVC.swift in Sources */,
 				A80E72222D3F3A9200C64288 /* DiyStickerElement.swift in Sources */,
-				A8F774FE2D38EA8C00AA6E93 /* Int+Ex.swift in Sources */,
-				A8F774FF2D38EA8C00AA6E93 /* UserDefault+Ex.swift in Sources */,
 				A8F775002D38EA8C00AA6E93 /* WindowHelper.swift in Sources */,
 				A8F7764B2D3E008500AA6E93 /* TSEmojisChildColViewModel.swift in Sources */,
 				A89EA6762D59C93E000EB181 /* TSAIChatContainerVC.swift in Sources */,
 				A89EA6812D59F44D000EB181 /* TSAIChatVC.swift in Sources */,
-				A8F775012D38EA8C00AA6E93 /* UIButton+Ex.swift in Sources */,
 				A80E72772D41EFF900C64288 /* TSEmojisTutorialsVC.swift in Sources */,
-				A8F775022D38EA8C00AA6E93 /* Dictionary+Ex.swift in Sources */,
 				A8F776482D3DE9F600AA6E93 /* TSSmallIconBrowseCell.swift in Sources */,
 				A8F7753D2D3918F800AA6E93 /* TSNetWork+Business.swift in Sources */,
 				A80E72262D3F3A9A00C64288 /* HYHAddImageView.m in Sources */,
@@ -1277,23 +1109,17 @@
 				A80E72562D3F98D700C64288 /* TSDiyKeyboardViewVC.swift in Sources */,
 				A8F775032D38EA8C00AA6E93 /* GlobalImports.swift in Sources */,
 				A89EA67A2D59D25F000EB181 /* TSAIChatVM.swift in Sources */,
-				A8F775062D38EA8C00AA6E93 /* Date+Ex.swift in Sources */,
-				A8F775072D38EA8C00AA6E93 /* UIView+Ex.swift in Sources */,
-				A8F775082D38EA8C00AA6E93 /* UITableView+Ex.swift in Sources */,
 				A8F7763C2D3B429B00AA6E93 /* TSCommonloadingView.swift in Sources */,
-				A8F775092D38EA8C00AA6E93 /* CommonSectionComponent.swift in Sources */,
 				A8F776322D3A771400AA6E93 /* TSGenmojiCollectionViewModel.swift in Sources */,
-				A80E72742D40FEA600C64288 /* UIApplication+Ex.swift in Sources */,
 				A80E721E2D3F3A7500C64288 /* DiyElement.swift in Sources */,
 				A8F776372D3A806E00AA6E93 /* TSGenmojiItemCell.swift in Sources */,
 				A89EA6692D59AA31000EB181 /* CameraInputBarAccessoryView.swift in Sources */,
 				A89EA66B2D59AA31000EB181 /* CustomTextMessageContentCell.swift in Sources */,
 				A89EA66C2D59AA31000EB181 /* CustomMessageContentCell.swift in Sources */,
 				A89EA66D2D59AA31000EB181 /* TableViewCells.swift in Sources */,
-				A89EA66E2D59AA31000EB181 /* CustomCell.swift in Sources */,
 				A8F7750A2D38EA8C00AA6E93 /* TSNetworkTool.swift in Sources */,
 				A8F7762D2D3A74A100AA6E93 /* TSGenmojiGennerateCell.swift in Sources */,
-				A8F775322D38FA5E00AA6E93 /* UITextView+Ex.swift in Sources */,
+				A89EA6BC2D5DFB12000EB181 /* TSViewController.swift in Sources */,
 				A89EA6832D59F4F9000EB181 /* TSChatViewController+Ex.swift in Sources */,
 				A89EA6A32D5B26E3000EB181 /* TSDBAIChatList.swift in Sources */,
 				A8F7753F2D39340E00AA6E93 /* TSSetingVC.swift in Sources */,
@@ -1302,9 +1128,7 @@
 				A80E72382D3F473B00C64288 /* DiyPaperProtocol.swift in Sources */,
 				A8F775382D390C3C00AA6E93 /* TSNetworkManager.swift in Sources */,
 				A89EA65F2D59AA11000EB181 /* TSChatViewController.swift in Sources */,
-				A8F7750B2D38EA8C00AA6E93 /* TSBaseTabViewCell.swift in Sources */,
 				A89EA6B12D5C9D0C000EB181 /* TSAIChatHistoryVC.swift in Sources */,
-				A8F7750D2D38EA8C00AA6E93 /* TSBaseVC.swift in Sources */,
 				A8FB02B72D3E3A3D0031A396 /* TSEmojisChildViewModel.swift in Sources */,
 				A8F7754B2D39376800AA6E93 /* TSSettingListView.swift in Sources */,
 				A8F7748B2D38E8B700AA6E93 /* AppDelegate.swift in Sources */,

+ 14 - 1
AIEmoji/AppDelegate.swift

@@ -16,7 +16,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
         window = UIWindow(frame: UIScreen.main.bounds)
         window?.backgroundColor = UIColor.white
         window?.makeKeyAndVisible()
-        
+        initPlatform()
         goToLoadVC()
         return true
     }
@@ -48,6 +48,19 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
         }
     }
     
+    
+    
+    func initPlatform() {
+        TSColorConfigShared.naviMianTextColor = .white
+    }
 
 }
 
+extension AppDelegate {
+    
+    func applicationWillTerminate(_ application: UIApplication) {
+        // 当应用即将被终止时,这里也可以添加数据保存逻辑,但系统留给的时间很有限
+        NotificationCenter.default.post(name: .kApplicationWillTerminate, object: nil)
+    }
+}
+

+ 22 - 0
AIEmoji/Assets.xcassets/AIChat/aichat_avatar.imageset/Contents.json

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

二進制
AIEmoji/Assets.xcassets/AIChat/aichat_avatar.imageset/aichat_avatar@2x.png


二進制
AIEmoji/Assets.xcassets/AIChat/aichat_avatar.imageset/aichat_avatar@3x.png


+ 22 - 0
AIEmoji/Assets.xcassets/Common/delete_white.imageset/Contents.json

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

二進制
AIEmoji/Assets.xcassets/Common/delete_white.imageset/delete_white@2x.png


二進制
AIEmoji/Assets.xcassets/Common/delete_white.imageset/delete_white@3x.png


+ 22 - 0
AIEmoji/Assets.xcassets/Common/pageNull.imageset/Contents.json

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

二進制
AIEmoji/Assets.xcassets/Common/pageNull.imageset/pageNull@2x.png


二進制
AIEmoji/Assets.xcassets/Common/pageNull.imageset/pageNull@3x.png


+ 17 - 74
AIEmoji/Business/AIChat/TSAIChatContainerVC.swift

@@ -63,20 +63,33 @@ class TSAIChatContainerVC: TSBaseVC {
         return navBarView
     }()
     
+    
+    lazy var viewModel : TSAIChatVM = {
+        let viewModel = TSAIChatVM()
+        return viewModel
+    }()
+    
+    
     lazy var chatVC: TSChatViewController = {
         let chatVC = TSChatViewController()
+        chatVC.viewModel = viewModel
         return chatVC
     }()
     
     
     override func createView() {
         edgesForExtendedLayout = []
-        navBarContentView.addSubview(navBarView)
-        navBarView.snp.makeConstraints { make in
-            make.edges.equalToSuperview()
+    
+        if viewModel.uiStyle == .history {
+            addNormalNavBarView()
+            setPageTitle("History".localized)
+        }else{
+            navBarContentView.addSubview(navBarView)
+            navBarView.snp.makeConstraints { make in
+                make.edges.equalToSuperview()
+            }
         }
         
-        
         addChild(chatVC)
         contentView.addSubview(chatVC.view)
         
@@ -84,75 +97,5 @@ class TSAIChatContainerVC: TSBaseVC {
             make.edges.equalToSuperview()
         }
         
-        
-        
-//        let user = TSChatUser(senderId: "user123", displayName: "Alice")
-//        let chatList = TSDBAIChatList(sessionId: UUID().uuidString, message: [TSChatMessage(kind: .text("Hello"), user: user, messageId:  "msg123", date: Date())])
-//        do {
-//            try TSDBAIChatListDAO().insertChatList(chatList)
-//        } catch {
-//            print("Error inserting chat list: \(error)")
-//        }
-        
-//        do {
-//            try TSDBAIChatListDAO().deleteChatList(sessionId: "chatLists")
-//        }catch {
-//            print("Error deleteChatList lists: \(error)")
-//        }
-//        
-//        // 获取所有数据
-//        do {
-//            let allChatLists = try TSDBAIChatListDAO().fetchChatLists()
-//            print("Fetched \(allChatLists.count) chat lists.")
-//        } catch {
-//            print("Error fetching chat lists: \(error)")
-//        }
-
-//        // 删除数据
-//        do {
-//            try TSDBAIChatListDAO().deleteChatList(sessionId: chatList.sessionId)
-//            print("Deleted chat list.")
-//        } catch {
-//            print("Error deleting chat list: \(error)")
-//        }
-        
-        
-//        // 初始化数据库
-//        TSDBAIChatListDAO.initializeDatabase()
-//
-//        
-//        let user = TSChatUser(senderId: "1", displayName: "Alice1")
-//        let chatList = TSDBAIChatList(sessionId: "1", message: [TSChatMessage(kind: .text("Hello1"), user: user, messageId: "msg1", date: Date())])
-//        // 插入数据
-//        let insertResult = TSDBAIChatListDAO.insertChatList(chatList)
-//        print(insertResult ? "Insert succeeded" : "Insert failed")
-//
-//        // 更新数据
-//        let updatedChatList = TSDBAIChatList(sessionId: "2", message: [TSChatMessage(kind: .text("Hello2"), user: user, messageId: "msg2", date: Date())])
-//        let updateResult = TSDBAIChatListDAO.updateChatList(updatedChatList)
-//        print(updateResult ? "Update succeeded" : "Update failed")
-
-        // 删除数据
-//        let deleteResult = TSDBAIChatListDAO.deleteChatList(sessionId: "12345")
-//        print(deleteResult ? "Delete succeeded" : "Delete failed")
-        
-        
-        // 创建数据
-//        let person = Person()
-//        person.name = "John"
-//        person.age = 30
-//        TSRealmManager.shared.create(person)
-        // 读取数据
-//        let allPersons = TSRealmManager.shared.read(Person.self)
-//        for person in allPersons {
-//            print("Name: \(person.name), Age: \(person.age)")
-//        }
-        // 更新数据
-//        if let firstPerson = allPersons.first {
-//            TSRealmManager.shared.update(firstPerson) { person in
-//                person.age = 31
-//            }
-//        }
-
     }
 }

+ 5 - 0
AIEmoji/Business/AIChat/TSAIChatHistoryVC/M/TSAIChatHistoryModel.swift

@@ -9,4 +9,9 @@
 class TSAIChatHistoryModel {
     var title:String = ""
     var chatList:[TSDBAIChatList] = []
+    
+    init(title: String, chatList: [TSDBAIChatList]) {
+        self.title = title
+        self.chatList = chatList
+    }
 }

+ 212 - 99
AIEmoji/Business/AIChat/TSAIChatHistoryVC/TSAIChatHistoryVC.swift

@@ -14,116 +14,229 @@ class TSAIChatHistoryVC: TSBaseVC {
         return viewModel
     }()
     
-    
     lazy var layout: UICollectionViewFlowLayout = {
         let layout = UICollectionViewFlowLayout()
         layout.scrollDirection = .vertical
-        layout.itemSize = CGSize(width: 40, height: 40)
-        layout.minimumInteritemSpacing = 16.0
-        layout.minimumLineSpacing = 0.0
+        layout.itemSize = CGSize(width: k_ScreenWidth-32, height: 74)
+        layout.minimumInteritemSpacing = 10.0
+        layout.minimumLineSpacing = 18.0
+        layout.headerReferenceSize = CGSizeMake(k_ScreenWidth, 48)
         return layout
     }()
     
-//    lazy var collectionView: UICollectionView = {
-//        let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
-//        collectionView.delegate = self
-//        collectionView.dataSource = self
-//        collectionView.showsVerticalScrollIndicator = false
-//        collectionView.showsHorizontalScrollIndicator = false
-//        collectionView.backgroundColor = .clear
-//        collectionView.register(TSAIChatHistoryCell.self, forCellWithReuseIdentifier: TSAIChatHistoryCell.cellID)
-//        if #available(iOS 11.0, *) {
-//            collectionView.contentInsetAdjustmentBehavior = .never
-//        }
-//        return collectionView
-//    }()
+    lazy var collectionView: UICollectionView = {
+        let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
+        collectionView.delegate = self
+        collectionView.dataSource = self
+        collectionView.showsVerticalScrollIndicator = false
+        collectionView.showsHorizontalScrollIndicator = false
+        collectionView.backgroundColor = .clear
+        collectionView.register(TSAIChatHistoryCell.self, forCellWithReuseIdentifier: TSAIChatHistoryCell.cellID)
+        collectionView.register(TSAIChatHistorySectionHeaderView.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: TSAIChatHistorySectionHeaderView.reuseIdentifier)
+        if #available(iOS 11.0, *) {
+            collectionView.contentInsetAdjustmentBehavior = .never
+        }
+        return collectionView
+    }()
+    
+    lazy var pageNullView: TSPageNullView = {
+        let pageNullView = TSPageNullView()
+        pageNullView.isHidden = true
+        return pageNullView
+    }()
     
     
     override func createView() {
-//        addSubview(collectionView)
-//        collectionView.snp.makeConstraints { make in
-//            make.edges.equalToSuperview()
-//        }
+        
+        addNormalNavBarView()
+        setPageTitle("History".localized)
+        
+        contentView.addSubview(pageNullView)
+        contentView.addSubview(collectionView)
+        collectionView.snp.makeConstraints { make in
+            make.edges.equalToSuperview()
+        }
     }
 
+    override func dealThings() {
+        
+        pageNullView.isHidden = viewModel.historyModelChatList.count > 0 ? true : false
+        
+        
+    }
+    
+    
+    
     
+    func updateListView(){
+        pageNullView.isHidden = viewModel.historyModelChatList.count > 0 ? true : false
+        collectionView.reloadData()
+    }
 }
 
-//extension TSAIChatHistoryVC: UICollectionViewDataSource ,UICollectionViewDelegate {
-//    
-//    public func numberOfSections(in collectionView: UICollectionView) -> Int {
-//        return 1
-//    }
-//    
-//    public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
-//        return dataArray.count
-//    }
-//    
-//    public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
-//        
-//        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: TSAIChatHistoryCell.cellID, for: indexPath)
-//        if let cell = cell as? TSAIChatHistoryCell,let colorModel = dataArray.safeObj(At: indexPath.item){
-//            cell.colorModel = colorModel
-//        }
-//        return cell
-//    }
-//
-//    public func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
-//        if let colorModel = dataArray.safeObj(At: indexPath.item){
-//            selectedColorComplete?(colorModel)
-//            currentIndexPath = indexPath
-//        }
-//    }
-//}
-//
-//
-//class TSAIChatHistoryCell: SwipeCollectionViewCell {
-//    
-//    static let cellID = "TSAIChatHistoryCell"
-//
-//    override var isSelected: Bool{
-//        didSet{
-//            imageView.isHidden = !isSelected
-//        }
-//    }
-//    
-//    
-//    lazy var imageView: UIImageView = {
-//        let imageView = UIImageView.createImageView(imageName: "select")
-//        imageView.isHidden = true
-//        return imageView
-//    }()
-//    
-//    lazy var shapeImageView: UIImageView = {
-//        let imageView = UIImageView.createImageView(imageName: "")
-//        imageView.isHidden = true
-//        return imageView
-//    }()
-//
-//    lazy var colorView: UIView = {
-//        let colorView = UIView()
-//        return colorView
-//    }()
-//    
-//    override func creatUI() {
-//        
-//        contentView.addSubview(shapeImageView)
-//        shapeImageView.snp.makeConstraints { make in
-//            make.edges.equalToSuperview()
-//        }
-//
-//        contentView.addSubview(colorView)
-//        colorView.snp.makeConstraints { make in
-//            make.edges.equalToSuperview()
-//        }
-//        
-//        colorView.cornerRadius = self.bounds.size.width/2
-//        
-//        bgContentView.addSubview(imageView)
-//        imageView.snp.makeConstraints { make in
-//            make.width.height.equalTo(24.0)
-//            make.center.equalToSuperview()
-//        }
-//        
-//    }
-//}
+extension TSAIChatHistoryVC: UICollectionViewDataSource ,UICollectionViewDelegate {
+    
+    public func numberOfSections(in collectionView: UICollectionView) -> Int {
+        return viewModel.historyModelChatList.count
+    }
+    
+    public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
+        if let sectionModel = viewModel.historyModelChatList.safeObj(At: section) {
+            return sectionModel.chatList.count
+        }
+        return 0
+    }
+    
+    public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
+        
+        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: TSAIChatHistoryCell.cellID, for: indexPath)
+        
+        if let sectionModel = viewModel.historyModelChatList.safeObj(At: indexPath.section),
+            let itemModel = sectionModel.chatList.safeObj(At: indexPath.item),
+           let cell = cell as? TSAIChatHistoryCell
+        {
+            cell.delegate = self
+            cell.model = itemModel
+        }
+        
+        return cell
+    }
+
+    public func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
+        if let sectionModel = viewModel.historyModelChatList.safeObj(At: indexPath.section),
+           let itemModel = sectionModel.chatList.safeObj(At: indexPath.item)
+        {
+            
+            let chatVC = TSAIChatContainerVC()
+            chatVC.viewModel.uiStyle = .history
+            chatVC.viewModel.dbAIChatList = itemModel
+            self.navigationController?.pushViewController(chatVC, animated: true)
+        }
+    }
+    
+    
+    public func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
+        if let sectionModel = viewModel.historyModelChatList.safeObj(At: indexPath.section) {
+            if kind == UICollectionView.elementKindSectionHeader {
+                if let header = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: TSAIChatHistorySectionHeaderView.reuseIdentifier, for: indexPath) as? TSAIChatHistorySectionHeaderView {
+                    header.titleLabel.text = sectionModel.title
+                    return header
+                }
+            }
+        }
+        return TSAIChatHistorySectionHeaderView()
+    }
+}
+
+extension TSAIChatHistoryVC: SwipeCollectionViewCellDelegate {
+    
+    func collectionView(_ collectionView: UICollectionView, editActionsForItemAt indexPath: IndexPath, for orientation: SwipeActionsOrientation) -> [SwipeAction]? {
+        guard orientation == .right else { return nil }
+
+        // 删除操作
+        let deleteAction = SwipeAction(style: .destructive, title: nil) {[weak self] action, indexPath in
+            guard let self = self else { return }
+            if let sectionModel = viewModel.historyModelChatList.safeObj(At: indexPath.section),
+            let itemModel = sectionModel.chatList.safeObj(At: indexPath.item){
+                sectionModel.chatList.remove(at: indexPath.item)
+                itemModel.delete()
+            
+                if sectionModel.chatList.count == 0 {
+                    viewModel.historyModelChatList.remove(at: indexPath.section)
+                }
+                
+                updateListView()
+            }
+        }
+        deleteAction.backgroundColor = "#E83E3E".uiColor
+        deleteAction.image = UIImage(named: "delete_white")
+        return [deleteAction]
+    }
+    
+    func collectionView(_ collectionView: UICollectionView, editActionsOptionsForItemAt indexPath: IndexPath, for orientation: SwipeActionsOrientation) -> SwipeOptions {
+        var options = SwipeOptions()
+        options.expansionStyle = .destructive(automaticallyDelete: false) // 完全滑动时是否自动触发操作
+        options.transitionStyle = .border // 滑动动画样式
+        return options
+    }
+    
+}
+class TSAIChatHistoryCell: SwipeCollectionViewCell {
+    
+    override init(frame: CGRect) {
+        super.init(frame: frame)
+        creatUI()
+    }
+    
+    required public init?(coder: NSCoder) {
+        fatalError("init(coder:) has not been implemented")
+    }
+
+    
+    static let cellID = "TSAIChatHistoryCell"
+    
+    lazy var titleLabel: UILabel = {
+        let titleLabel = UILabel.createLabel( font:.font(size: 16.0),textColor: .white)
+        return titleLabel
+    }()
+    
+    lazy var infoLabel: UILabel = {
+        let titleLabel = UILabel.createLabel( font:.font(size: 14.0),textColor: .white.withAlphaComponent(0.4))
+        return titleLabel
+    }()
+    
+    
+    var model:TSDBAIChatList?{
+        didSet{
+            if let dbMessage = model?.messages.first {
+                titleLabel.text = dbMessage.kind
+                infoLabel.text = dbMessage.sentDate.dateTimeString
+            }
+        }
+    }
+    
+    func creatUI() {
+
+        backgroundColor = "#333333".uiColor
+        cornerRadius = 16.0
+        
+        contentView.addSubview(titleLabel)
+        titleLabel.snp.makeConstraints { make in
+            make.top.leading.equalTo(16)
+            make.trailing.equalTo(-16)
+            make.height.equalTo(16)
+        }
+
+        contentView.addSubview(infoLabel)
+        infoLabel.snp.makeConstraints { make in
+            make.top.equalTo(44)
+            make.leading.equalTo(16)
+            make.trailing.equalTo(-16)
+            make.height.equalTo(14)
+        }
+    }
+}
+
+class TSAIChatHistorySectionHeaderView: UICollectionReusableView {
+    static let reuseIdentifier = "TSAIChatHistorySectionHeaderView"
+    
+    let titleLabel: UILabel = {
+        let label = UILabel.createLabel(text: "",font: .font(size: 16),textColor: .white)
+        return label
+    }()
+    
+    override init(frame: CGRect) {
+        super.init(frame: frame)
+        
+        addSubview(titleLabel)
+        titleLabel.snp.makeConstraints { make in
+            make.leading.equalTo(16)
+            make.trailing.equalTo(-16)
+            make.centerY.equalTo(16)
+        }
+    }
+    
+    required init?(coder: NSCoder) {
+        fatalError("init(coder:) has not been implemented")
+    }
+}

+ 136 - 0
AIEmoji/Business/AIChat/TSAIChatHistoryVC/TSViewController.swift

@@ -0,0 +1,136 @@
+//
+//  TSViewController.swift
+//  AIEmoji
+//
+//  Created by 100Years on 2025/2/13.
+//
+
+import UIKit
+import SwipeCellKit
+
+class ViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, SwipeCollectionViewCellDelegate {
+    
+    // MARK: - UI Components
+    private var collectionView: UICollectionView!
+    
+    // MARK: - Data
+    private var data: [String] = [
+        "Cell 1", "Cell 2", "Cell 3", "Cell 4", "Cell 5",
+        "Cell 6", "Cell 7", "Cell 8", "Cell 9", "Cell 10"
+    ]
+    
+    // MARK: - Lifecycle
+    override func viewDidLoad() {
+        super.viewDidLoad()
+        setupUI()
+    }
+    
+    // MARK: - Setup UI
+    private func setupUI() {
+        view.backgroundColor = .white
+        title = "SwipeCellKit with UICollectionView"
+        
+        // 设置 UICollectionViewLayout
+        let layout = UICollectionViewFlowLayout()
+        layout.itemSize = CGSize(width: view.frame.width, height: 60) // 每个 Cell 的宽度为屏幕宽度
+        layout.minimumLineSpacing = 10 // 行间距
+        layout.scrollDirection = .vertical
+        
+        // 初始化 UICollectionView
+        collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
+        collectionView.translatesAutoresizingMaskIntoConstraints = false
+        collectionView.backgroundColor = .white
+        collectionView.delegate = self
+        collectionView.dataSource = self
+        collectionView.register(CustomSwipeCell.self, forCellWithReuseIdentifier: "CustomSwipeCell")
+        
+        // 添加 UICollectionView 到视图
+        view.addSubview(collectionView)
+        
+        // 设置约束
+        NSLayoutConstraint.activate([
+            collectionView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
+            collectionView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
+            collectionView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
+            collectionView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
+        ])
+    }
+    
+    // MARK: - UICollectionViewDataSource
+    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
+        return data.count
+    }
+    
+    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
+        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CustomSwipeCell", for: indexPath) as! CustomSwipeCell
+        cell.textLabel.text = data[indexPath.row]
+        cell.delegate = self // 设置 SwipeCollectionViewCellDelegate
+        return cell
+    }
+    
+    // MARK: - SwipeCollectionViewCellDelegate
+    func collectionView(_ collectionView: UICollectionView, editActionsForItemAt indexPath: IndexPath, for orientation: SwipeActionsOrientation) -> [SwipeAction]? {
+        guard orientation == .right else { return nil }
+        
+        // 删除操作
+        let deleteAction = SwipeAction(style: .destructive, title: "Delete") { action, indexPath in
+            print("Delete action for cell \(indexPath.row)")
+            self.data.remove(at: indexPath.row) // 删除数据源
+            self.collectionView.deleteItems(at: [indexPath]) // 删除 Cell
+        }
+        deleteAction.backgroundColor = .red
+        deleteAction.image = UIImage(systemName: "trash")
+        
+        // 更多操作
+        let moreAction = SwipeAction(style: .default, title: "More") { action, indexPath in
+            print("More action for cell \(indexPath.row)")
+        }
+        moreAction.backgroundColor = .blue
+        moreAction.image = UIImage(systemName: "ellipsis")
+        
+        return [deleteAction, moreAction]
+    }
+    
+    func collectionView(_ collectionView: UICollectionView, editActionsOptionsForItemAt indexPath: IndexPath, for orientation: SwipeActionsOrientation) -> SwipeOptions {
+        var options = SwipeOptions()
+        options.expansionStyle = .destructive(automaticallyDelete: false) // 完全滑动时是否自动触发操作
+        options.transitionStyle = .border // 滑动动画样式
+        return options
+    }
+}
+
+// MARK: - CustomSwipeCell
+class CustomSwipeCell: SwipeCollectionViewCell {
+    
+    // 文本标签
+    let textLabel: UILabel = {
+        let label = UILabel()
+        label.translatesAutoresizingMaskIntoConstraints = false
+        label.font = UIFont.systemFont(ofSize: 16, weight: .medium)
+        label.textColor = .black
+        return label
+    }()
+    
+    override init(frame: CGRect) {
+        super.init(frame: frame)
+        setupUI()
+    }
+    
+    required init?(coder: NSCoder) {
+        fatalError("init(coder:) has not been implemented")
+    }
+    
+    private func setupUI() {
+        backgroundColor = .lightGray
+        layer.cornerRadius = 8
+        clipsToBounds = true
+        // 添加文本标签
+        contentView.addSubview(textLabel)
+        
+        // 设置约束
+        NSLayoutConstraint.activate([
+            textLabel.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 16),
+            textLabel.centerYAnchor.constraint(equalTo: contentView.centerYAnchor)
+        ])
+    }
+}

+ 47 - 54
AIEmoji/Business/AIChat/TSAIChatHistoryVC/VM/TSAIChatHistoryVM.swift

@@ -7,73 +7,66 @@
 
 class TSAIChatHistoryVM {
     
-    lazy var historyChatList: [TSDBAIChatList] = {
+    lazy var historyDBChatList: [TSDBAIChatList] = {
         let list = TSDBAIChatList.getAll()
         return list
     }()
     
+    lazy var historyModelChatList: [TSAIChatHistoryModel] = {
+        return categorizeDates()
+    }()
     
-    
-    
-    
-    func getTimeCategorieslist(list:[TSDBAIChatList]) -> Void {
-        
-//        let categorizedDates = categorizeDates(sampleDates)
-//        print("今天: \(categorizedDates.today)")
-//        print("昨天: \(categorizedDates.yesterday)")
-//        print("一周内: \(categorizedDates.withinWeek)")
-//        print("30 天内: \(categorizedDates.within30Days)")
-        
+    func categorizeDates() -> [TSAIChatHistoryModel] {
+        let calendar = Calendar.current
+        let now = Date()
+        let todayStart = calendar.startOfDay(for: now)
+        let yesterdayStart = calendar.date(byAdding: .day, value: -1, to: todayStart)!
+        let oneWeekAgo = calendar.date(byAdding: .day, value: -7, to: todayStart)!
+        let thirtyDaysAgo = calendar.date(byAdding: .day, value: -30, to: todayStart)!
         
+        var todayDates: [TSDBAIChatList] = []
+        var yesterdayDates: [TSDBAIChatList] = []
+        var withinWeekDates: [TSDBAIChatList] = []
+        var within30DaysDates: [TSDBAIChatList] = []
         
+        for model in historyDBChatList {
+            let date = Date(timeIntervalSince1970: TimeInterval(model.creatTimestampInt))
+            let dateStart = calendar.startOfDay(for: date)
+            if dateStart == todayStart {
+                todayDates.append(model)
+            } else if dateStart == yesterdayStart {
+                yesterdayDates.append(model)
+            } else if dateStart > oneWeekAgo {
+                withinWeekDates.append(model)
+            } else if dateStart > thirtyDaysAgo {
+                within30DaysDates.append(model)
+            }
+        }
         
+        todayDates = todayDates.sorted { $0.creatTimestampInt > $1.creatTimestampInt}
+        yesterdayDates = yesterdayDates.sorted { $0.creatTimestampInt > $1.creatTimestampInt }
+        withinWeekDates = withinWeekDates.sorted { $0.creatTimestampInt > $1.creatTimestampInt }
+        within30DaysDates = within30DaysDates.sorted { $0.creatTimestampInt > $1.creatTimestampInt }
         
+        var result = [TSAIChatHistoryModel]()
         
+        if todayDates.count > 0 {
+            result.append(TSAIChatHistoryModel(title: "Today".localized, chatList: todayDates))
+        }
         
+        if yesterdayDates.count > 0 {
+            result.append(TSAIChatHistoryModel(title: "1 Days".localized, chatList: yesterdayDates))
+        }
         
+        if withinWeekDates.count > 0 {
+            result.append(TSAIChatHistoryModel(title: "7 Days".localized, chatList: withinWeekDates))
+        }
         
+        if within30DaysDates.count > 0 {
+            result.append(TSAIChatHistoryModel(title: "30 Days".localized, chatList: within30DaysDates))
+        }
         
+        return result
     }
-    
-    
-    
-    
-//    func categorizeDates(_ dates: [Date]) -> (today: [TSDBAIChatList], yesterday: [TSDBAIChatList], withinWeek: [TSDBAIChatList], within30Days: [TSDBAIChatList]) {
-//        let calendar = Calendar.current
-//        let now = Date()
-//        let todayStart = calendar.startOfDay(for: now)
-//        let yesterdayStart = calendar.date(byAdding: .day, value: -1, to: todayStart)!
-//        let oneWeekAgo = calendar.date(byAdding: .day, value: -7, to: todayStart)!
-//        let thirtyDaysAgo = calendar.date(byAdding: .day, value: -30, to: todayStart)!
-//        
-//        var todayDates: [TSDBAIChatList] = []
-//        var yesterdayDates: [TSDBAIChatList] = []
-//        var withinWeekDates: [TSDBAIChatList] = []
-//        var within30DaysDates: [TSDBAIChatList] = []
-//        
-//        for model in historyChatList {
-//            if let date = model.creatDate {
-//                let dateStart = calendar.startOfDay(for: date)
-//                if dateStart == todayStart {
-//                    todayDates.append(model)
-//                } else if dateStart == yesterdayStart {
-//                    yesterdayDates.append(model)
-//                } else if dateStart > oneWeekAgo {
-//                    withinWeekDates.append(model)
-//                } else if dateStart > thirtyDaysAgo {
-//                    within30DaysDates.append(model)
-//                }
-//            }
-//        }
-//        
-//        todayDates = todayDates.sorted { $0.creatDate ?? Date() > $1.creatDate ?? Date()}
-//        yesterdayDates = yesterdayDates.sorted { $0.creatDate > $1.creatDate }
-//        withinWeekDates = withinWeekDates.sorted { $0.creatDate > $1.creatDate }
-//        within30DaysDates = within30DaysDates.sorted { $0.creatDate > $1.creatDate }
-//        
-//        return (today: todayDates, yesterday: yesterdayDates, withinWeek: withinWeekDates, within30Days: within30DaysDates)
-//    }
-    
-    
-    
+
 }

+ 40 - 19
AIEmoji/Business/AIChat/TSChatViewController/Models/TSDBAIChatList.swift

@@ -12,22 +12,20 @@ import MessageKit
 class TSDBAIChatList: Object {
     @objc dynamic var sessionId = UUID().uuidString
     dynamic var messages = List<TSDBChatMessage>()
-    dynamic var creatDate:Int = 0
+    @objc dynamic var creatTimestampInt:Int = 0
     
     
     
-    lazy var messageList: [TSChatMessage] = {
-        return getMessageList()
-    }()
+//    var messageList: [TSChatMessage] = []
     
     override static func primaryKey() -> String? {
         return "sessionId"
     }
 
-    //获取 App 层的 最新的 TSChatMessage 数组
-    func getMessageListLatestData() {
-        messageList = getMessageList()
-    }
+//    //获取 App 层的 最新的 TSChatMessage 数组
+//    func getMessageListLatestData() {
+//        messageList = getMessageList()
+//    }
     
     //获取 App 层的 TSChatMessage 数组
     func getMessageList() -> [TSChatMessage] {
@@ -38,14 +36,19 @@ class TSDBAIChatList: Object {
         return msgModel
     }
     
-    //添加 App 层的 TSChatMessage 数组
-    func updateMessageList(list:[TSChatMessage]){
-        messages.removeAll()
-        for model in list {
-            messages.append(getTSDBChatMessage(chatMsg: model))
-        }
-        TSRMShared.update(self)
-    }
+//    //添加 App 层的 TSChatMessage 数组
+//    func updateMessageList(list:[TSChatMessage]){
+//        TSRMShared.writeThread {
+//            if creatTimestampInt == 0 {
+//                creatTimestampInt = Date.timestampInt
+//            }
+//            messages.removeAll()
+//            for model in list {
+//                messages.append(getTSDBChatMessage(chatMsg: model))
+//            }
+//        }
+//        TSRMShared.update(self)
+//    }
     
     func delete() {
         TSRMShared.delete(self)
@@ -54,8 +57,8 @@ class TSDBAIChatList: Object {
     
     func updateMessage(msgModel:TSChatMessage){
         TSRMShared.writeThread {
-            if creatDate == 0 {
-                creatDate = Date.timestampInt
+            if creatTimestampInt == 0 {
+                creatTimestampInt = Date.timestampInt
             }
             let dbModel = getTSDBChatMessage(chatMsg: msgModel)
             if let index = messages.firstIndex(where: { $0.messageId == dbModel.messageId }) {
@@ -67,6 +70,24 @@ class TSDBAIChatList: Object {
         TSRMShared.update(self)
     }
     
+    
+    func updateMessages(msgModels:[TSChatMessage]){
+        TSRMShared.writeThread {
+            if creatTimestampInt == 0 {
+                creatTimestampInt = Date.timestampInt
+            }
+            for msgModel in msgModels {
+                let dbModel = getTSDBChatMessage(chatMsg: msgModel)
+                if let index = messages.firstIndex(where: { $0.messageId == dbModel.messageId }) {
+                    messages[index] = dbModel// 如果找到,替换该元素
+                } else {
+                    messages.append(dbModel)// 如果没有找到,添加到末尾
+                }
+            }
+        }
+        TSRMShared.update(self)
+    }
+    
 }
 
 
@@ -129,7 +150,7 @@ extension MessageKind {
     
     
     static func textKind(_ string: String) -> MessageKind {
-        return .text("")
+        return .text(string)
     }
     
 }

+ 161 - 154
AIEmoji/Business/AIChat/TSChatViewController/TSChatViewController.swift

@@ -29,61 +29,70 @@ import MapKit
 
 /// A base class for the example controllers
 class TSChatViewController: MessagesViewController, MessagesDataSource {
-  // MARK: Internal
-    lazy var viewModel : TSAIChatVM = {
-        let viewModel = TSAIChatVM()
-        return viewModel
-    }()
+    // MARK: Internal
+    var viewModel:TSAIChatVM = TSAIChatVM()
     
-
     
-  // MARK: - Public properties
-  lazy var messageList: [TSChatMessage] = []
-
-  private(set) lazy var refreshControl: UIRefreshControl = {
-    let control = UIRefreshControl()
-    control.addTarget(self, action: #selector(loadMoreMessages), for: .valueChanged)
-    return control
-  }()
-
+    // MARK: - Public properties
+    lazy var messageList: [TSChatMessage] = []
+    
+    private(set) lazy var refreshControl: UIRefreshControl = {
+        let control = UIRefreshControl()
+        control.addTarget(self, action: #selector(loadMoreMessages), for: .valueChanged)
+        return control
+    }()
+    
     // MARK: Private
-     lazy var textMessageSizeCalculator = CustomTextLayoutSizeCalculator(
-      layout: self.messagesCollectionView
-        .messagesCollectionViewFlowLayout)
+    lazy var textMessageSizeCalculator = CustomTextLayoutSizeCalculator(layout: self.messagesCollectionView.messagesCollectionViewFlowLayout)
     
+    override func viewDidLoad() {
+        super.viewDidLoad()
+        navigationItem.title = "MessageKit"
 
-
-  override func viewDidLoad() {
-    super.viewDidLoad()
-    navigationItem.title = "MessageKit"
-
-    configureMessageCollectionView()
-    configureMessageInputBar()
-    loadFirstMessages()
-  }
-
-  override func viewDidAppear(_ animated: Bool) {
-    super.viewDidAppear(animated)
-  }
-
-  override func viewDidDisappear(_ animated: Bool) {
-    super.viewDidDisappear(animated)
-  }
-
-  func loadFirstMessages() {
-      //获取消息数量
-      self.messageList = viewModel.getHistoryChatMessage()
-      self.messagesCollectionView.reloadData()
-      self.messagesCollectionView.scrollToLastItem(animated: false)
-  }
-
-  @objc
-  func loadMoreMessages() {
-      //获取更多消息数量
-
-  }
-
+        configureMessageCollectionView()
+        configureMessageInputBar()
+        loadFirstMessages()
+        
+        
+        if viewModel.uiStyle == .chat {
+            // 注册通知监听,App死的时候,保存本次聊天记录到本地
+            NotificationCenter.default.addObserver(self, selector: #selector(saveChatList), name: .kApplicationWillTerminate, object: nil)
+        }
+    }
+    
+    @objc func saveChatList() {
+        messageList.remove(at: 0)
+        viewModel.updateMessages(msgModels: messageList)
+    }
+    
+    override func viewDidAppear(_ animated: Bool) {
+        super.viewDidAppear(animated)
+    }
+    
+    override func viewDidDisappear(_ animated: Bool) {
+        super.viewDidDisappear(animated)
+    }
+    
+    func loadFirstMessages() {
+        //获取消息数量
+        self.messageList = viewModel.getHistoryChatMessage()
+        self.messagesCollectionView.reloadData()
+        self.messagesCollectionView.scrollToLastItem(animated: false)
+    }
+    
+    @objc
+    func loadMoreMessages() {
+        //获取更多消息数量
+        
+    }
+    
     func configureMessageCollectionView() {
+        if let flowLayout = messagesCollectionView.collectionViewLayout as? UICollectionViewFlowLayout {
+            flowLayout.sectionInset = UIEdgeInsets(top: 4, left: 0, bottom: 4, right: 0)
+        }
+        
+        messagesCollectionView.backgroundColor = .clear
+        view.backgroundColor = .clear
         messagesCollectionView.register(CustomTextMessageContentCell.self)
         messagesCollectionView.messagesLayoutDelegate = self
         messagesCollectionView.messagesDisplayDelegate = self
@@ -93,19 +102,19 @@ class TSChatViewController: MessagesViewController, MessagesDataSource {
         scrollsToLastItemOnKeyboardBeginsEditing = true // default false
         maintainPositionOnInputBarHeightChanged = true // default false
         showMessageTimestampOnSwipeLeft = false // default false
-
-        messagesCollectionView.refreshControl = refreshControl
+        
+        //        messagesCollectionView.refreshControl = refreshControl
         messagesCollectionView.reloadData()
     }
-
+    
     func configureMessageInputBar() {
         messageInputBar.delegate = self
         messageInputBar.inputTextView.tintColor = .themeColor
         messageInputBar.sendButton.setTitleColor(.themeColor, for: .normal)
         messageInputBar.sendButton.setTitleColor(
-        UIColor.themeColor.withAlphaComponent(0.3),for: .highlighted)
+            UIColor.themeColor.withAlphaComponent(0.3),for: .highlighted)
     }
-
+    
     // MARK: - Helpers
     var lastIndexPath:IndexPath{
         if messageList.count == 0 {
@@ -126,24 +135,24 @@ class TSChatViewController: MessagesViewController, MessagesDataSource {
             }
         })
     }
-
-  func isLastSectionVisible() -> Bool {
-    guard !messageList.isEmpty else { return false }
-    return messagesCollectionView.indexPathsForVisibleItems.contains(lastIndexPath)
-  }
-
-
-  private let formatter: DateFormatter = {
-    let formatter = DateFormatter()
-    formatter.dateStyle = .medium
-    return formatter
-  }()
+    
+    func isLastSectionVisible() -> Bool {
+        guard !messageList.isEmpty else { return false }
+        return messagesCollectionView.indexPathsForVisibleItems.contains(lastIndexPath)
+    }
+    
+    
+    private let formatter: DateFormatter = {
+        let formatter = DateFormatter()
+        formatter.dateStyle = .medium
+        return formatter
+    }()
 }
 
 
 // MARK: MessagesDataSource
 extension TSChatViewController {
-
+    
     var currentSender: SenderType {
         return viewModel.kUserSender
     }
@@ -155,131 +164,130 @@ extension TSChatViewController {
     func numberOfItems(inSection section: Int, in messagesCollectionView: MessagesCollectionView) -> Int{
         messageList.count
     }
-
+    
     func messageForItem(at indexPath: IndexPath, in _: MessagesCollectionView) -> MessageType {
         messageList[indexPath.item]
     }
-
+    
     func cellTopLabelAttributedText(for message: MessageType, at indexPath: IndexPath) -> NSAttributedString? {
-        if indexPath.item % 3 == 0 {
-        return NSAttributedString(
-          string: MessageKitDateFormatter.shared.string(from: message.sentDate),
-          attributes: [
-            NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: 10),
-            NSAttributedString.Key.foregroundColor: UIColor.darkGray,
-          ])
-      }
-      return nil
+//        if indexPath.item % 3 == 0 {
+//            return NSAttributedString(
+//                string: MessageKitDateFormatter.shared.string(from: message.sentDate),
+//                attributes: [
+//                    NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: 10),
+//                    NSAttributedString.Key.foregroundColor: UIColor.darkGray,
+//                ])
+//        }
+        return nil
     }
-
+    
     func cellBottomLabelAttributedText(for _: MessageType, at _: IndexPath) -> NSAttributedString? {
-      NSAttributedString(
-        string: "Read",
-        attributes: [
-          NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: 10),
-          NSAttributedString.Key.foregroundColor: UIColor.darkGray,
-        ])
+        NSAttributedString(
+            string: "Read",
+            attributes: [
+                NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: 10),
+                NSAttributedString.Key.foregroundColor: UIColor.darkGray,
+            ])
     }
-
+    
     func messageTopLabelAttributedText(for message: MessageType, at _: IndexPath) -> NSAttributedString? {
-      let name = message.sender.displayName
-      return NSAttributedString(
-        string: name,
-        attributes: [NSAttributedString.Key.font: UIFont.preferredFont(forTextStyle: .caption1)])
+        let name = message.sender.displayName
+        return NSAttributedString(
+            string: name,
+            attributes: [NSAttributedString.Key.font: UIFont.preferredFont(forTextStyle: .caption1)])
     }
-
+    
     func messageBottomLabelAttributedText(for message: MessageType, at _: IndexPath) -> NSAttributedString? {
-      let dateString = formatter.string(from: message.sentDate)
-      return NSAttributedString(
-        string: dateString,
-        attributes: [NSAttributedString.Key.font: UIFont.preferredFont(forTextStyle: .caption2)])
+        let dateString = formatter.string(from: message.sentDate)
+        return NSAttributedString(
+            string: dateString,
+            attributes: [NSAttributedString.Key.font: UIFont.preferredFont(forTextStyle: .caption2)])
     }
-
-      func textCell(
+    
+    func textCell(
         for message: MessageType,
         at indexPath: IndexPath,
         in messagesCollectionView: MessagesCollectionView)
-        -> UICollectionViewCell?
-      {
+    -> UICollectionViewCell?
+    {
         let cell = messagesCollectionView.dequeueReusableCell(
-          CustomTextMessageContentCell.self,
-          for: indexPath)
+            CustomTextMessageContentCell.self,
+            for: indexPath)
         cell.configure(
-          with: message,
-          at: indexPath,
-          in: messagesCollectionView,
-          dataSource: self,
-          and: textMessageSizeCalculator)
-
+            with: message,
+            at: indexPath,
+            in: messagesCollectionView,
+            dataSource: self,
+            and: textMessageSizeCalculator)
+        
         return cell
-      }
+    }
 }
 
 
 // MARK: InputBarAccessoryViewDelegate
 
 extension TSChatViewController: InputBarAccessoryViewDelegate {
-  // MARK: Internal
-
-  @objc
-  func inputBar(_: InputBarAccessoryView, didPressSendButtonWith _: String) {
-    processInputBar(messageInputBar)
-  }
-
+    // MARK: Internal
+    
+    @objc
+    func inputBar(_: InputBarAccessoryView, didPressSendButtonWith _: String) {
+        processInputBar(messageInputBar)
+    }
+    
     //聊天发送内容
-  func processInputBar(_ inputBar: InputBarAccessoryView) {
-    // Here we can parse for which substrings were autocompleted
-    let attributedText = inputBar.inputTextView.attributedText!
-    let range = NSRange(location: 0, length: attributedText.length)
-    attributedText.enumerateAttribute(.autocompleted, in: range, options: []) { _, range, _ in
-
-      let substring = attributedText.attributedSubstring(from: range)
-      let context = substring.attribute(.autocompletedContext, at: 0, effectiveRange: nil)
-      print("Autocompleted: `", substring, "` with context: ", context ?? "-")
+    func processInputBar(_ inputBar: InputBarAccessoryView) {
+        // Here we can parse for which substrings were autocompleted
+        let attributedText = inputBar.inputTextView.attributedText!
+        let range = NSRange(location: 0, length: attributedText.length)
+        attributedText.enumerateAttribute(.autocompleted, in: range, options: []) { _, range, _ in
+            
+            let substring = attributedText.attributedSubstring(from: range)
+            let context = substring.attribute(.autocompletedContext, at: 0, effectiveRange: nil)
+            print("Autocompleted: `", substring, "` with context: ", context ?? "-")
+        }
+        
+        let components = inputBar.inputTextView.components
+        inputBar.inputTextView.text = String()
+        inputBar.invalidatePlugins()
+        
+        inputBar.inputTextView.placeholder = "Aa"
+        sendMessages(components)
+        messagesCollectionView.scrollToLastItem(animated: true)
     }
-
-    let components = inputBar.inputTextView.components
-    inputBar.inputTextView.text = String()
-    inputBar.invalidatePlugins()
-      
-      inputBar.inputTextView.placeholder = "Aa"
-      sendMessages(components)
-      messagesCollectionView.scrollToLastItem(animated: true)
-  }
-
+    
     // MARK: Private
-
+    
     private func sendMessages(_ data: [Any]) {
         let user = viewModel.kUserSender
         for component in data {
-          if let str = component as? String {
-              let message = TSChatMessage(text: str, user: user, messageId: UUID().uuidString, date: Date())
-              insertMessage(message)
-              //保存这条消息到本地数据库
-              viewModel.updateMessage(msgModel: message)
-              //发送消息后,进行AI 对话生成
-              generativeAIChat(message: message)
-          } else if let img = component as? UIImage {
-//              let message = TSChatMessage(image: img, user: user, messageId: UUID().uuidString, date: Date())
-//              insertMessage(message)
-          }
+            if let str = component as? String {
+                let message = TSChatMessage(text: str, user: user, messageId: UUID().uuidString, date: Date())
+                insertMessage(message)
+                //保存这条消息到本地数据库
+                //发送消息后,进行AI 对话生成
+                generativeAIChat(message: message)
+            } else if let img = component as? UIImage {
+                //              let message = TSChatMessage(image: img, user: user, messageId: UUID().uuidString, date: Date())
+                //              insertMessage(message)
+            }
         }
     }
     
     func generativeAIChat(message:TSChatMessage) {
         var messageString = ""
         switch message.kind {
-            case .text(let message):
-                messageString = message
-            default:
-                break
+        case .text(let message):
+            messageString = message
+        default:
+            break
         }
         
         if messageString.count == 0 {
             return
         }
         
-
+        
         let message = TSChatMessage(text: "...", user: viewModel.kAIUser, messageId: UUID().uuidString, date: Date())
         message.sendState = .start
         insertMessage(message)
@@ -291,17 +299,16 @@ extension TSChatViewController: InputBarAccessoryViewDelegate {
             self?.updataAIChatCell(string: string)
             
         } completion: {[weak self] data, error in
-
+            
             guard let self = self else { return }
             if let netData = data {
                 message.sendState = .success("netData")
                 
                 //保存这条消息到本地数据库
-                viewModel.updateMessage(msgModel: message)
             }else {
                 message.kind = .text(kAIErrorString)
                 message.sendState = .failed(kAIErrorString)
-                viewModel.updateMessage(msgModel: message)
+                //保存这条消息到本地数据库
             }
             
             updataAIChatCellUI()

+ 15 - 8
AIEmoji/Business/AIChat/TSChatViewController/ViewModel/TSAIChatVM.swift

@@ -12,7 +12,7 @@ class TSAIChatVM {
 
     enum UIStype {
         case chat
-        case onlyRead
+        case history
     }
         
     lazy var dbAIChatList: TSDBAIChatList = {
@@ -61,8 +61,8 @@ extension TSAIChatVM {
 extension TSAIChatVM {
     
     func getHistoryChatMessage() -> [TSChatMessage] {
-        if uiStyle == .onlyRead {
-            return self.dbAIChatList.messageList
+        if uiStyle == .history {
+            return self.dbAIChatList.getMessageList()
         }else {
             let aiString = "I can tackle your questions, my skillset includes, but is not limited to:\n\n📧 Composing high-quality emails  \n🇺🇸 Facilitating language learning  \n📑 Assisting in your studies  \n💡 Brainstorming ideas and much more!"
             let msg = TSChatMessage(kind: .text(aiString), user: kAIUser, messageId: "", date: Date())
@@ -71,15 +71,22 @@ extension TSAIChatVM {
         }
     }
     
-    func updateMessage(msgModel:TSChatMessage){
-        
+//    func updateMessage(msgModel:TSChatMessage){
+//        kExecuteOnMainThread {
+//            //保存数据库
+//            self.dbAIChatList.updateMessage(msgModel: msgModel)
+//            //保存服务器
+//        }
+//    }
+   
+    
+    func updateMessages(msgModels:[TSChatMessage]){
         kExecuteOnMainThread {
             //保存数据库
-            self.dbAIChatList.updateMessage(msgModel: msgModel)
+            self.dbAIChatList.updateMessages(msgModels: msgModels)
             //保存服务器
         }
         
-
+        
     }
-   
 }

+ 0 - 66
AIEmoji/Business/AIChat/TSChatViewController/Views/CustomCell.swift

@@ -1,66 +0,0 @@
-// MIT License
-//
-// Copyright (c) 2017-2019 MessageKit
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all
-// copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
-
-import MessageKit
-import UIKit
-
-open class CustomCell: UICollectionViewCell {
-  // MARK: Lifecycle
-
-  public override init(frame: CGRect) {
-    super.init(frame: frame)
-    setupSubviews()
-  }
-
-  public required init?(coder aDecoder: NSCoder) {
-    super.init(coder: aDecoder)
-    setupSubviews()
-  }
-
-  // MARK: Open
-
-  open func setupSubviews() {
-    contentView.addSubview(label)
-    label.textAlignment = .center
-    label.font = UIFont.italicSystemFont(ofSize: 13)
-  }
-
-  open override func layoutSubviews() {
-    super.layoutSubviews()
-    label.frame = contentView.bounds
-  }
-
-  open func configure(with message: MessageType, at _: IndexPath, and _: MessagesCollectionView) {
-    // Do stuff
-    switch message.kind {
-    case .custom(let data):
-      guard let systemMessage = data as? String else { return }
-      label.text = systemMessage
-    default:
-      break
-    }
-  }
-
-  // MARK: Internal
-
-  let label = UILabel()
-}

+ 124 - 116
AIEmoji/Business/AIChat/TSChatViewController/Views/CustomMessageContentCell.swift

@@ -10,123 +10,131 @@ import MessageKit
 import UIKit
 
 class CustomMessageContentCell: MessageCollectionViewCell {
-  // MARK: Lifecycle
-
-  override init(frame: CGRect) {
-    super.init(frame: frame)
-    contentView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
-    setupSubviews()
-  }
-
-  required init?(coder aDecoder: NSCoder) {
-    super.init(coder: aDecoder)
-    contentView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
-    setupSubviews()
-  }
-
-  // MARK: Internal
-
-  /// The `MessageCellDelegate` for the cell.
-  weak var delegate: MessageCellDelegate?
-
-  /// The container used for styling and holding the message's content view.
-  var messageContainerView: UIView = {
-    let containerView = UIView()
-    containerView.clipsToBounds = true
-    containerView.layer.masksToBounds = true
-    return containerView
-  }()
-
-  /// The top label of the cell.
-  var cellTopLabel: UILabel = {
-    let label = UILabel()
-    label.numberOfLines = 0
-    label.textAlignment = .center
-    return label
-  }()
-
-  var cellDateLabel: UILabel = {
-    let label = UILabel()
-    label.numberOfLines = 0
-    label.textAlignment = .right
-    return label
-  }()
-
-  override func prepareForReuse() {
-    super.prepareForReuse()
-    cellTopLabel.text = nil
-    cellTopLabel.attributedText = nil
-    cellDateLabel.text = nil
-    cellDateLabel.attributedText = nil
-  }
-
-  /// Handle tap gesture on contentView and its subviews.
-  override func handleTapGesture(_ gesture: UIGestureRecognizer) {
-    let touchLocation = gesture.location(in: self)
-
-    switch true {
-    case messageContainerView.frame
-      .contains(touchLocation) && !cellContentView(canHandle: convert(touchLocation, to: messageContainerView)):
-      delegate?.didTapMessage(in: self)
-    case cellTopLabel.frame.contains(touchLocation):
-      delegate?.didTapCellTopLabel(in: self)
-    case cellDateLabel.frame.contains(touchLocation):
-      delegate?.didTapMessageBottomLabel(in: self)
-    default:
-      delegate?.didTapBackground(in: self)
+    // MARK: Lifecycle
+    
+    override init(frame: CGRect) {
+        super.init(frame: frame)
+        contentView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
+        setupSubviews()
     }
-  }
-
-  /// Handle long press gesture, return true when gestureRecognizer's touch point in `messageContainerView`'s frame
-  override func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
-    let touchPoint = gestureRecognizer.location(in: self)
-    guard gestureRecognizer.isKind(of: UILongPressGestureRecognizer.self) else { return false }
-    return messageContainerView.frame.contains(touchPoint)
-  }
-
-  func setupSubviews() {
-    messageContainerView.layer.cornerRadius = 5
-
-    contentView.addSubview(cellTopLabel)
-    contentView.addSubview(messageContainerView)
-    messageContainerView.addSubview(cellDateLabel)
-  }
-
-  func configure(
-    with message: MessageType,
-    at indexPath: IndexPath,
-    in messagesCollectionView: MessagesCollectionView,
-    dataSource: MessagesDataSource,
-    and sizeCalculator: CustomLayoutSizeCalculator)
-  {
-    guard let displayDelegate = messagesCollectionView.messagesDisplayDelegate else {
-      return
+    
+    required init?(coder aDecoder: NSCoder) {
+        super.init(coder: aDecoder)
+        contentView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
+        setupSubviews()
+    }
+    
+    // MARK: Internal
+    
+    /// The `MessageCellDelegate` for the cell.
+    weak var delegate: MessageCellDelegate?
+    
+    /// The container used for styling and holding the message's content view.
+    var messageContainerView: UIView = {
+        let containerView = UIView()
+        containerView.cornerRadius = 16
+        return containerView
+    }()
+    
+    /// 用来显示消息框上的时间之类的
+    var cellTopLabel: UILabel = {
+        let label = UILabel()
+        label.numberOfLines = 0
+        label.textAlignment = .center
+        return label
+    }()
+    
+    var leadingAvatarImageView: UIImageView = {
+        let imageView = UIImageView.createImageView(imageName: "aichat_avatar")
+        return imageView
+    }()
+    
+    //  var cellDateLabel: UILabel = {
+    //    let label = UILabel()
+    //    label.numberOfLines = 0
+    //    label.textAlignment = .right
+    //    return label
+    //  }()
+    
+    override func prepareForReuse() {
+        super.prepareForReuse()
+        cellTopLabel.text = nil
+        cellTopLabel.attributedText = nil
+        //    cellDateLabel.text = nil
+        //    cellDateLabel.attributedText = nil
     }
-    cellTopLabel.frame = sizeCalculator.cellTopLabelFrame(
-      for: message,
-      at: indexPath)
-    cellDateLabel.frame = sizeCalculator.cellMessageBottomLabelFrame(
-      for: message,
-      at: indexPath)
-    messageContainerView.frame = sizeCalculator.messageContainerFrame(
-      for: message,
-      at: indexPath,
-      fromCurrentSender: dataSource
-        .isFromCurrentSender(message: message))
-    cellTopLabel.attributedText = dataSource.cellTopLabelAttributedText(
-      for: message,
-      at: indexPath)
-    cellDateLabel.attributedText = dataSource.messageBottomLabelAttributedText(
-      for: message,
-      at: indexPath)
-    messageContainerView.backgroundColor = displayDelegate.backgroundColor(
-      for: message,
-      at: indexPath,
-      in: messagesCollectionView)
-  }
+    
+    /// Handle tap gesture on contentView and its subviews.
+    override func handleTapGesture(_ gesture: UIGestureRecognizer) {
+        let touchLocation = gesture.location(in: self)
+        
+        switch true {
+        case messageContainerView.frame
+                .contains(touchLocation) && !cellContentView(canHandle: convert(touchLocation, to: messageContainerView)):
+            delegate?.didTapMessage(in: self)
+        case cellTopLabel.frame.contains(touchLocation):
+            delegate?.didTapCellTopLabel(in: self)
+            //    case cellDateLabel.frame.contains(touchLocation):
+            //      delegate?.didTapMessageBottomLabel(in: self)
+        default:
+            delegate?.didTapBackground(in: self)
+        }
+    }
+    
+    /// Handle long press gesture, return true when gestureRecognizer's touch point in `messageContainerView`'s frame
+    override func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
+        let touchPoint = gestureRecognizer.location(in: self)
+        guard gestureRecognizer.isKind(of: UILongPressGestureRecognizer.self) else { return false }
+        return messageContainerView.frame.contains(touchPoint)
+    }
+    
+    func setupSubviews() {
+        contentView.addSubview(cellTopLabel)
+        contentView.addSubview(leadingAvatarImageView)
+        contentView.addSubview(messageContainerView)
 
-  /// Handle `ContentView`'s tap gesture, return false when `ContentView` doesn't needs to handle gesture
-  func cellContentView(canHandle _: CGPoint) -> Bool {
-    false
-  }
+    }
+    
+    func configure(
+        with message: MessageType,
+        at indexPath: IndexPath,
+        in messagesCollectionView: MessagesCollectionView,
+        dataSource: MessagesDataSource,
+        and sizeCalculator: CustomLayoutSizeCalculator)
+    {
+        guard let displayDelegate = messagesCollectionView.messagesDisplayDelegate else {
+            return
+        }
+        cellTopLabel.frame = sizeCalculator.cellTopLabelFrame(
+            for: message,
+            at: indexPath)
+        
+        cellTopLabel.attributedText = dataSource.cellTopLabelAttributedText(
+            for: message,
+            at: indexPath)
+        
+        
+        //    cellDateLabel.frame = sizeCalculator.cellMessageBottomLabelFrame(
+        //      for: message,
+        //      at: indexPath)
+        //      cellDateLabel.attributedText = dataSource.messageBottomLabelAttributedText(
+        //        for: message,
+        //        at: indexPath)
+        
+        messageContainerView.frame = sizeCalculator.messageContainerFrame(
+            for: message,
+            at: indexPath,
+            fromCurrentSender: dataSource
+                .isFromCurrentSender(message: message))
+        
+        messageContainerView.backgroundColor = displayDelegate.backgroundColor(
+            for: message,
+            at: indexPath,
+            in: messagesCollectionView)
+    }
+    
+    /// Handle `ContentView`'s tap gesture, return false when `ContentView` doesn't needs to handle gesture
+    func cellContentView(canHandle _: CGPoint) -> Bool {
+        false
+    }
 }

+ 43 - 46
AIEmoji/Business/AIChat/TSChatViewController/Views/CustomTextMessageContentCell.swift

@@ -10,64 +10,61 @@ import MessageKit
 import UIKit
 import SwiftyMarkdown
 class CustomTextMessageContentCell: CustomMessageContentCell {
-  /// The label used to display the message's text.
-  var messageLabel: UILabel = {
-    let label = UILabel()
-    label.numberOfLines = 0
-    label.font = UIFont.preferredFont(forTextStyle: .body)
-    return label
-  }()
+    var messageLabel: UILabel = {
+        let label = UILabel.createLabel(font: .font(size: 16),numberOfLines: 0)
+        return label
+    }()
     
     override func prepareForReuse() {
         super.prepareForReuse()
-//        messageLabel.attributedText = nil
-//        messageLabel.text = nil
+        //        messageLabel.attributedText = nil
+        //        messageLabel.text = nil
     }
-
-  override func setupSubviews() {
-     super.setupSubviews()
-     messageContainerView.addSubview(messageLabel)
-  }
-
-  override func configure(
-    with message: MessageType,
-    at indexPath: IndexPath,
-    in messagesCollectionView: MessagesCollectionView,
-    dataSource: MessagesDataSource,
-    and sizeCalculator: CustomLayoutSizeCalculator)
-  {
-    super.configure(
-      with: message,
-      at: indexPath,
-      in: messagesCollectionView,
-      dataSource: dataSource,
-      and: sizeCalculator)
-
-    guard let displayDelegate = messagesCollectionView.messagesDisplayDelegate else {
-      return
+    
+    override func setupSubviews() {
+        super.setupSubviews()
+        messageContainerView.addSubview(messageLabel)
     }
-
-    let calculator = sizeCalculator as? CustomTextLayoutSizeCalculator
-    messageLabel.frame = calculator?.messageLabelFrame(for: message,at: indexPath) ?? .zero
-    let textMessageKind = message.kind
-    switch textMessageKind {
-        case .text(let text), .emoji(let text):
-//            let textColor = displayDelegate.textColor(for: message, at: indexPath, in: messagesCollectionView)
-//            messageLabel.textColor = textColor
+    
+    override func configure(
+        with message: MessageType,
+        at indexPath: IndexPath,
+        in messagesCollectionView: MessagesCollectionView,
+        dataSource: MessagesDataSource,
+        and sizeCalculator: CustomLayoutSizeCalculator)
+    {
+        super.configure(
+            with: message,
+            at: indexPath,
+            in: messagesCollectionView,
+            dataSource: dataSource,
+            and: sizeCalculator)
+        
+        guard let displayDelegate = messagesCollectionView.messagesDisplayDelegate else {
+            return
+        }
         
-        messageLabel.text = text
-        messageLabel.attributedText = SwiftyMarkdown(string: text).attributedString()
-//        extractAndPrintSubstring(from: messageLabel.text ?? "", to: text)
+        let calculator = sizeCalculator as? CustomTextLayoutSizeCalculator
+        messageLabel.frame = calculator?.messageLabelFrame(for: message,at: indexPath) ?? .zero
+        let textMessageKind = message.kind
+        switch textMessageKind {
+        case .text(let text), .emoji(let text):
+            //            let textColor = displayDelegate.textColor(for: message, at: indexPath, in: messagesCollectionView)
+            //            messageLabel.textColor = textColor
+            
+            messageLabel.text = text
+            messageLabel.attributedText = SwiftyMarkdown(string: text).attributedString()
+            //        extractAndPrintSubstring(from: messageLabel.text ?? "", to: text)
+            
             
-
         case .attributedText(let text):
             messageLabel.attributedText = text
         default:
-          break
+            break
+        }
     }
-  }
     
-
+    
     func extractAndPrintSubstring(from sourceString: String, to targetString: String) {
         // 查找 sourceString 在 targetString 中的结束位置
         if let range = targetString.range(of: sourceString) {

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

@@ -0,0 +1,12 @@
+//
+//  Notification+Ex.swift
+//  AIEmoji
+//
+//  Created by 100Years on 2025/2/13.
+//
+
+import Foundation
+
+extension Notification.Name {
+    static let kApplicationWillTerminate = Notification.Name("applicationWillTerminate")
+}

+ 1 - 1
AIEmoji/Business/General/TSBottomAlertVC.swift

@@ -18,7 +18,7 @@ class TSBottomAlertVC: TSBaseVC {
     
     lazy var bottomView: UIView = {
         let bottomView = UIView(frame: CGRectMake(0, k_ScreenHeight-448, k_ScreenWidth, 448))
-        bottomView.backgroundColor = "#222222".color
+        bottomView.backgroundColor = "#222222".uiColor
         bottomView.cornersRound(radius: 20, corner: [.topLeft,.topRight])
         return bottomView
     }()

+ 14 - 1
AIEmoji/Business/General/TSSmallIconBrowseVC/TSSmallIconBrowseVC.swift

@@ -31,7 +31,20 @@ class TSSmallIconBrowseVC: TSBottomAlertVC {
     }
     
     lazy var collectionView: UICollectionView = {
-        let collectionView = UICollectionView.createCommon(delegate: self, cellReuseIds: [cellId])
+
+        let layout = UICollectionViewFlowLayout()
+        layout.scrollDirection = .vertical
+        
+        let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
+        collectionView.delegate = self
+        collectionView.dataSource = self
+        collectionView.showsVerticalScrollIndicator = false
+        collectionView.showsHorizontalScrollIndicator = false
+        collectionView.backgroundColor = .clear
+        if #available(iOS 11.0, *) {
+            collectionView.contentInsetAdjustmentBehavior = .never
+        }
+        collectionView.register(TSSmallIconBrowseCell.self, forCellWithReuseIdentifier: cellId)
         collectionView.isPagingEnabled = true
         collectionView.isHidden = true
         if let flowLayout = collectionView.collectionViewLayout as? UICollectionViewFlowLayout {

+ 3 - 3
AIEmoji/Business/TSEmojisVC/TSEmojisChildVC/TSEmojisChildVC.swift

@@ -28,9 +28,9 @@ class TSEmojisChildVC: TSBaseVC {
     //联动滚动回调
     var listViewDidScrollCallback: ((UIScrollView) -> ())?
     
-    lazy var collectionComponent: CollectionViewComponent = {
+    lazy var collectionComponent: TSCollectionViewComponent = {
         let layout = UICollectionViewFlowLayout()
-        let cp = CollectionViewComponent(frame: CGRect.zero, layout: layout, attributes: [ :])
+        let cp = TSCollectionViewComponent(frame: CGRect.zero, layout: layout, attributes: [ :])
         cp.collectionView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
         cp.didScrollHandler = { [weak self] scrollView in
             guard let self = self else { return }
@@ -61,7 +61,7 @@ class TSEmojisChildVC: TSBaseVC {
 
 
     override func createView() {
-        view.backgroundColor = "#222222".color
+        view.backgroundColor = "#222222".uiColor
         view.cornersRound(radius: 20, corner: [.topLeft,.topRight])
         edgesForExtendedLayout = []
         setNavBarViewHidden(true)

+ 4 - 1
AIEmoji/Business/TSEmojisVC/TSEmojisChildVC/VIew/TSEmojisCoLItemCell.swift

@@ -37,12 +37,15 @@ class TSEmojisCoLItemCell: TSBaseCollectionCell {
         }
     }
     
-    override func renderView(with object: Any?, component: CollectionViewComponent, attributes: [String : Any]?) {
+    
+    
+    override func renderView(with object: Any?, component: TSCollectionViewComponent, attributes: [String : Any]?) {
         super.renderView(with: object, component: component, attributes: attributes)
         if let itemModel = object as? TSEmojisColItemModel{
             showImageView.setAsyncImage(urlString: itemModel.dataModel.imageUrl,placeholder: kPlaceholderImage)
             vipImageView.isHidden = !itemModel.dataModel.vip
         }
     }
+
     
 }

+ 4 - 4
AIEmoji/Business/TSEmojisVC/TSEmojisChildVC/ViewModel/TSEmojisChildColViewModel.swift

@@ -26,7 +26,7 @@ class TSEmojisColSectionModel: TSBaseModel {
 
 private let emojisColSection = UIEdgeInsets(top: 24, left: 24, bottom: 24, right: 24)
 private let itemW = (k_ScreenWidth - emojisColSection.left - emojisColSection.right - 64 - 1)/3.0
-extension TSEmojisColSectionModel : CollectionViewSectionComponent{
+extension TSEmojisColSectionModel : TSCollectionViewSectionComponent{
     var sectionInset: UIEdgeInsets {
         return emojisColSection
     }
@@ -38,12 +38,12 @@ extension TSEmojisColSectionModel : CollectionViewSectionComponent{
     var itemSpacing: CGFloat {
         return 32
     }
-    var headerComponent: CollectionViewReuseViewComponent? {
+    var headerComponent: TSCollectionViewReuseViewComponent? {
         //暂时没有分区头,但是已经预留有模型了
         return nil
     }
     
-    var cells: [CollectionViewCellComponent] {
+    var cells: [TSCollectionViewCellComponent] {
         return items
     }
 }
@@ -58,7 +58,7 @@ class TSEmojisColItemModel: TSBaseModel {
     }
 }
 
-extension TSEmojisColItemModel: CollectionViewCellComponent{
+extension TSEmojisColItemModel: TSCollectionViewCellComponent{
     var cellClass: UICollectionViewCell.Type {
         return TSEmojisCoLItemCell.self
     }

+ 1 - 1
AIEmoji/Business/TSEmojisVC/TSEmojisChildVC/ViewModel/TSEmojisChildViewModel.swift

@@ -15,7 +15,7 @@ class TSEmojisChildViewModel {
     }
     
     var dataArray:[TSEmojisModel] = [TSEmojisModel]()
-    var colDataArray:[Component] = [Component]()
+    var colDataArray:[TSComponent] = [TSComponent]()
 }
 
 extension TSEmojisChildViewModel {

+ 2 - 2
AIEmoji/Business/TSGenmojiVC/TSGenmojiVC/TSGenmojiVC.swift

@@ -53,9 +53,9 @@ class TSGenmojiVC: TSBaseVC {
     }()
     
     
-    lazy var collectionComponent: CollectionViewComponent = {
+    lazy var collectionComponent: TSCollectionViewComponent = {
         let layout = UICollectionViewFlowLayout()
-        let cp = CollectionViewComponent(frame: CGRect.zero, layout: layout, attributes: [ :])
+        let cp = TSCollectionViewComponent(frame: CGRect.zero, layout: layout, attributes: [ :])
         cp.collectionView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: k_Height_TabBar, right: 0)
         cp.itemActionHandler = { [weak self] cellCp, indexPath in
             guard let self = self else { return }

+ 1 - 1
AIEmoji/Business/TSGenmojiVC/TSGenmojiVC/View/TSGenmojiColSectionView.swift

@@ -37,7 +37,7 @@ class TSGenmojiColSectionView: TSBaseCollectionnReusableView {
         }
     }
     
-    override func renderView(with object: Any?, component: CollectionViewComponent, attributes: [String : Any]?) {
+    override func renderView(with object: Any?, component: TSCollectionViewComponent, attributes: [String : Any]?) {
         super.renderView(with: object, component: component, attributes: attributes)
         if let componentReuseViewModel = object as? TSGenmojiColComponentReuseViewModel {
             leftLab.text = componentReuseViewModel.sectionModel.name

+ 2 - 2
AIEmoji/Business/TSGenmojiVC/TSGenmojiVC/View/TSGenmojiGennerateCell.swift

@@ -17,7 +17,7 @@ class TSGenmojiGennerateCell : TSBaseCollectionCell{
             text: "",
             font: .font(size: 12),
             textColor: .white,
-            backgroundColor: "#333333".color,
+            backgroundColor: "#333333".uiColor,
             textInsets: UIEdgeInsets(top: 21, left: 16, bottom: 21, right: 16)
         )
         customTextView.delegate = self
@@ -71,7 +71,7 @@ class TSGenmojiGennerateCell : TSBaseCollectionCell{
         return "Generate (\(kPurchaseDefault.freeNum))"
     }
     
-    override func renderView(with object: Any?, component: CollectionViewComponent, attributes: [String : Any]?) {
+    override func renderView(with object: Any?, component: TSCollectionViewComponent, attributes: [String : Any]?) {
         super.renderView(with: object, component: component, attributes: attributes)
         submitBtn.setTitle(getVipText(), for: .normal)
     }

+ 1 - 1
AIEmoji/Business/TSGenmojiVC/TSGenmojiVC/View/TSGenmojiItemCell.swift

@@ -25,7 +25,7 @@ class TSGenmojiItemCell: TSBaseCollectionCell {
     }
     
     
-    override func renderView(with object: Any?, component: CollectionViewComponent, attributes: [String : Any]?) {
+    override func renderView(with object: Any?, component: TSCollectionViewComponent, attributes: [String : Any]?) {
         super.renderView(with: object, component: component, attributes: attributes)
         
         if let itemModel = object as? TSGenmojiCoLItemModel{

+ 6 - 6
AIEmoji/Business/TSGenmojiVC/TSGenmojiVC/ViewModel/TSGenmojiCollectionViewModel.swift

@@ -102,7 +102,7 @@ class TSGenmojiCoLSectionModel: TSBaseModel {
 }
 
 
-extension TSGenmojiCoLSectionModel : CollectionViewSectionComponent{
+extension TSGenmojiCoLSectionModel : TSCollectionViewSectionComponent{
     var sectionInset: UIEdgeInsets {
         return style.sectionInset
     }
@@ -114,11 +114,11 @@ extension TSGenmojiCoLSectionModel : CollectionViewSectionComponent{
     var itemSpacing: CGFloat {
         return style.itemSpacing
     }
-    var headerComponent: CollectionViewReuseViewComponent? {
+    var headerComponent: TSCollectionViewReuseViewComponent? {
         return TSGenmojiColComponentReuseViewModel(sectionModel: self)
     }
     
-    var cells: [CollectionViewCellComponent] {
+    var cells: [TSCollectionViewCellComponent] {
         return items
     }
 }
@@ -137,7 +137,7 @@ class TSGenmojiCoLItemModel: TSBaseModel {
     }
 }
 
-extension TSGenmojiCoLItemModel: CollectionViewCellComponent{
+extension TSGenmojiCoLItemModel: TSCollectionViewCellComponent{
     var cellClass: UICollectionViewCell.Type {
         style.cellClass
     }
@@ -149,7 +149,7 @@ extension TSGenmojiCoLItemModel: CollectionViewCellComponent{
 
 
 //MARK: 分区头
-class TSGenmojiColComponentReuseViewModel : TSBaseModel ,CollectionViewReuseViewComponent {
+class TSGenmojiColComponentReuseViewModel : TSBaseModel ,TSCollectionViewReuseViewComponent {
     var sectionModel:TSGenmojiCoLSectionModel
 
     init(sectionModel:TSGenmojiCoLSectionModel) {
@@ -180,7 +180,7 @@ class TSGenmojiColComponentReuseViewModel : TSBaseModel ,CollectionViewReuseView
         return sectionModel.style.headerViewSize
     }
     
-    var viewType: CollectionViewReuseViewType {
+    var viewType: TSCollectionViewReuseViewType {
         return .header
     }
 }

+ 1 - 1
AIEmoji/Business/TSGenmojiVC/TSGenmojiVC/ViewModel/TSGenmojiViewModel.swift

@@ -9,7 +9,7 @@
 import ObjectMapper
 
 class TSGenmojiViewModel {
-    var colDataArray:[Component] = [Component]()
+    var colDataArray:[TSComponent] = [TSComponent]()
 
     lazy var generateSectionModel: TSGenmojiCoLSectionModel = {
         let generateSectionModel = TSGenmojiCoLSectionModel()

+ 3 - 2
AIEmoji/Business/TSSetingVC/SetingVC/TSSetingViewModel.swift

@@ -12,6 +12,7 @@ class TSSetingViewModel: ObservableObject {
     @Published var settingTypes: [SettingType] = SettingType.allCases
     @Published var isViper: Bool = PurchaseManager.default.isVip
     
+    var appid = "6740220736"
     // todo.kailen-privacy
     func showPrivacy(parent: UIViewController) {
         let vc = TSBusinessWebVC(urlType: .privacy)
@@ -28,7 +29,7 @@ class TSSetingViewModel: ObservableObject {
 
     // todo.kailen-logo
     func shareApp(parent: UIViewController) {
-        let httpAppStoreLink = "https://apps.apple.com/app/id\(TSConfig.appid)"
+        let httpAppStoreLink = "https://apps.apple.com/app/id\(appid)"
         let text = ""
         let url = URL(string: httpAppStoreLink)!
         var image = UIImage()
@@ -61,7 +62,7 @@ class TSSetingViewModel: ObservableObject {
         /// 如果当前版本 弹过一次 那么下一次就走url
         /// 如果当前版本 没弹过,那就弹
         if count >= 4 {
-            let openStr = "itms-apps://itunes.apple.com/app/\(TSConfig.appid)?action=write-review"
+            let openStr = "itms-apps://itunes.apple.com/app/\(appid)?action=write-review"
             if let url = URL(string: openStr), UIApplication.shared.canOpenURL(url) {
                 if #available(iOS 10.0, *) {
                     UIApplication.shared.open(url, options: [:], completionHandler: nil)

+ 1 - 1
AIEmoji/Business/TSSetingVC/SetingVC/View/SettingPurchaseTopView.swift

@@ -32,7 +32,7 @@ struct SettingPurchaseTopView: View {
                         .font(.font(size: 14,weight: .medium))
                         .padding(EdgeInsets(top: 0, leading: 12, bottom: 0, trailing: 12))
                         .frame(height: 34)
-                        .foregroundColor("#010101".color.color)
+                        .foregroundColor("#010101".uiColor.color)
                         .background(UIColor.themeColor.color)
                         .cornerRadius(14.0)
                     

+ 1 - 1
AIEmoji/Business/TSTabBarController/TSTabBarController.swift

@@ -65,7 +65,7 @@ class TSTabBarController: UITabBarController {
         
         
         tabBar.isTranslucent = false
-        tabBar.backgroundColor = "#262626".color
+        tabBar.backgroundColor = "#262626".uiColor
         tabBar.backgroundImage = UIImage.colorFrom(color: tabBar.backgroundColor!, size: CGSize(width: k_ScreenWidth, height: k_TabBar_Height))
         
         // 自定义 TabBarItem 字体颜色和选中颜色

+ 2 - 2
AIEmoji/Business/TSWallpaperVC/DiyWallpaper/Elemnet/DiyFixedTextElement.swift

@@ -39,7 +39,7 @@ class DiyFixedTextView: DiyElementBaseView {
     lazy var label: UILabel = {
         var label = UILabel()
         if let textElement = element as? DiyFixedTextElement{
-            label = UILabel.createLabel(text: textElement.text,font: .font(size: 16*kDiyDesignScaleW),textColor: textElement.textColor?.color,textAlignment: .center,numberOfLines: 0)
+            label = UILabel.createLabel(text: textElement.text,font: .font(size: 16*kDiyDesignScaleW),textColor: textElement.textColor?.uiColor,textAlignment: .center,numberOfLines: 0)
         }
         return label
     }()
@@ -60,7 +60,7 @@ class DiyFixedTextView: DiyElementBaseView {
         }
         
         if let textElement = element as? DiyFixedTextElement{
-            contentView.backgroundColor = textElement.backgroundColor?.color
+            contentView.backgroundColor = textElement.backgroundColor?.uiColor
        
         }
         updateContent()

+ 2 - 2
AIEmoji/Business/TSWallpaperVC/DiyWallpaper/Elemnet/DiyTextElement.swift

@@ -83,14 +83,14 @@ class DiyTextView: DiyElementBaseView {
             style.lineSpacing = textElement.lineSpace
             style.alignment = textElement.alignment
             label.attributedText = NSAttributedString(string: textElement.text ?? "Add Text".localized, attributes: [
-                        .foregroundColor: textElement.textColor?.color ?? "#111111".color,
+                        .foregroundColor: textElement.textColor?.uiColor ?? "#111111".uiColor,
                         .font: UIFont.font(name: textElement.fontName, size: textElement.fontSize),
                         .paragraphStyle: style])
         } else {
             label.textAlignment = textElement.alignment
             label.text = textElement.text ?? "Add Text".localized
             label.font = UIFont.font(name: textElement.fontName, size: textElement.fontSize)
-            label.textColor = textElement.textColor?.color ?? "#111111".color
+            label.textColor = textElement.textColor?.uiColor ?? "#111111".uiColor
         }
         
         setNeedsDisplay()

+ 1 - 1
AIEmoji/Business/TSWallpaperVC/DiyWallpaper/Templates/DiyPaperTemplateBaseView.swift

@@ -87,7 +87,7 @@ class DiyPaperTemplateBaseView: UIView, DiyPaperTemplateBaseProtocol {
                 imageView.setAsyncImage(urlString: string)
             } else if string.hasPrefix("#") {
                 // 颜色
-                imageView.backgroundColor = string.color
+                imageView.backgroundColor = string.uiColor
             } else if let image = UIImage(named: string) {
                 imageView.image = image
             }

+ 2 - 2
AIEmoji/Business/TSWallpaperVC/TSDiyKeyboardVC/TSWallpaperVC.swift

@@ -36,7 +36,7 @@ class TSWallpaperVC: TSBaseVC {
         let segmentedView = JXSegmentedView()
         segmentedView.delegate = self
         segmentedView.dataSource = segmentedDataSource
-        segmentedView.backgroundColor = "#F1F4F8".color
+        segmentedView.backgroundColor = "#F1F4F8".uiColor
         segmentedView.cornerRadius = segmentedViewH/2.0
         //配置指示器
         let indicator = JXSegmentedIndicatorLineView()
@@ -181,7 +181,7 @@ extension TSWallpaperVC {
     
     func getCurrentDiyPreviewColor() -> UIColor? {
         if let model = viewModel.templateModels.safeObj(At: segmentedView.selectedIndex) {
-            return model.textColor?.color
+            return model.textColor?.uiColor
         }
         return nil
     }

+ 2 - 2
AIEmoji/Business/TSWallpaperVC/TSDiyKeyboardViewVC/View/TSKeyboardView.swift

@@ -62,7 +62,7 @@ struct TSKeyboardItemView : View {
 
                 Spacer().frame(height: 2)
             }
-            .background("#F1F4F8".color.color)
+            .background("#F1F4F8".uiColor.color)
             .cornerRadius(5)
             .shadow(color: .black.opacity(0.2), radius: 2, x: 0, y: 2) // 设置阴影
             
@@ -80,7 +80,7 @@ struct TSKeyboardDeleteView : View {
                 Image(model.imageUrl ?? "").resizable().frame(width: 23, height: 17)
             }
             .frame(width: 42,height: 42)
-            .background("#F1F4F8".color.color)
+            .background("#F1F4F8".uiColor.color)
             .cornerRadius(5)
             .shadow(color: .black.opacity(0.2), radius: 2, x: 0, y: 2) // 设置阴影
         }

+ 45 - 0
AIEmoji/Business/VIewTool/TSPageNullView.swift

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

+ 1 - 1
AIEmoji/Business/VIewTool/TSViewTool.swift

@@ -51,7 +51,7 @@ class TSSavePhotoSuccessTool {
     
     private lazy var textLabel:UILabel = {
         let textLabel = UILabel()
-        textLabel.textColor = "#4A5178".color
+        textLabel.textColor = "#4A5178".uiColor
         textLabel.text = "Save Successfully".localized
         textLabel.font = UIFont.font(size: 14)
         return textLabel

+ 0 - 142
AIEmoji/Common/BaseClass/TSBaseCollectionCell.swift

@@ -1,142 +0,0 @@
-//
-//  CWBaseCollectionViewCell.swift
-//  ClockWidget
-//
-//  Created by fff on 2024/11/12.
-//
-
-
-class TSBaseCollectionCell: UICollectionViewCell,ComponentView  {
-    
-    var colComponent:CollectionViewComponent?
-    var colAttributes:[String : Any]?
-    
-    lazy var bgContentView:UIView = {
-        let view = UIView()
-        view.backgroundColor = .clear
-        return view
-    }()
-    
-    override init(frame: CGRect) {
-        super.init(frame: frame)
-        self.backgroundColor = .clear
-        self.addSubview(bgContentView)
-        bgContentView.snp.makeConstraints { make in
-            make.top.leading.trailing.bottom.equalTo(0)
-        }
-        creatUI()
-        dealThings()
-    }
-    
-    required init?(coder: NSCoder) {
-        fatalError("init(coder:) has not been implemented")
-    }
-    
-    func creatUI(){
-        
-    }
-    
-    func dealThings(){
-        
-    }
-    
-    func renderView(with object: Any?, component: CollectionViewComponent, attributes: [String : Any]?) {
-        self.colComponent = component
-        self.colAttributes = attributes
-    }
-    
-    deinit {
-        debugPrint("<---deinit \(String(describing: self))")
-    }
-    
-}
-
-extension TSBaseCollectionCell{
-    var indexPath:IndexPath?{
-        if let attributes = colAttributes , let IndexPath = attributes[kIndexPath] as? IndexPath{
-            return IndexPath
-        }
-        return nil
-    }
-    
-    var itemActionHandler: ((Any?, IndexPath) -> Void)?{
-        if let colComponent = colComponent,let itemActionHandler = colComponent.itemActionHandler {
-            return itemActionHandler
-        }
-        return nil
-    }
-    
-    func actionHandler(any:Any?){
-        if let sectionActionHandler = itemActionHandler ,let indexPath = indexPath{
-            sectionActionHandler(any,indexPath)
-        }
-    }
-}
-
-
-
-
-
-
-class TSBaseCollectionnReusableView : UICollectionReusableView ,ComponentView  {
-    
-    var colComponent:CollectionViewComponent?
-    var colAttributes:[String : Any]?
-    
-    lazy var bgContentView:UIView = {
-        let view = UIView()
-        view.backgroundColor = .clear
-        return view
-    }()
-    
-    override init(frame: CGRect) {
-        super.init(frame: frame)
-        self.backgroundColor = .clear
-        self.addSubview(bgContentView)
-        bgContentView.snp.makeConstraints { make in
-            make.top.leading.trailing.bottom.equalTo(0)
-        }
-        creatUI()
-    }
-    
-    required init?(coder: NSCoder) {
-        fatalError("init(coder:) has not been implemented")
-    }
-    
-    func creatUI(){
-        
-    }
-
-    func renderView(with object: Any?, component: CollectionViewComponent, attributes: [String : Any]?) {
-        self.colComponent = component
-        self.colAttributes = attributes
-    }
-    
-    
-    deinit {
-        debugPrint("<---deinit \(String(describing: self))")
-    }
-    
-}
-
-extension TSBaseCollectionnReusableView{
-    var indexPath:IndexPath?{
-        if let attributes = colAttributes , let IndexPath = attributes[kIndexPath] as? IndexPath{
-            return IndexPath
-        }
-        return nil
-    }
-    
-    var sectionActionHandler: ((Any?, IndexPath) -> Void)?{
-        if let colComponent = colComponent,let sectionActionHandler = colComponent.sectionActionHandler {
-            return sectionActionHandler
-        }
-        return nil
-    }
-    
-    func actionHandler(any:Any?){
-        if let sectionActionHandler = sectionActionHandler ,let indexPath = indexPath{
-            sectionActionHandler(any,indexPath)
-        }
-    }
-}

+ 0 - 52
AIEmoji/Common/BaseClass/TSBaseModel.swift

@@ -1,52 +0,0 @@
-//
-//  TSBaseModel.swift
-//  TSLiveWallpaper
-//
-//  Created by 100Years on 2024/12/22.
-//
-
-import ObjectMapper
-
-class TSBaseModel: NSObject, Mappable, NSCopying {
-    static func model(data: Data) -> TSBaseModel? {
-        do {
-            let object = try JSONSerialization.jsonObject(with: data)
-            if let dict = object as? [String: AnyHashable] {
-                return Self.init(json: dict)
-            }
-        } catch _ {
-            return nil
-        }
-        return nil
-    }
-    
-    var data: Data? {
-        let json = toJSON()
-        do {
-            let data = try JSONSerialization.data(withJSONObject: json)
-            return data
-        } catch _ {
-            return nil
-        }
-    }
-    
-    required convenience init?(map: ObjectMapper.Map) {
-        self.init()
-        mapping(map: map)
-    }
-    
-    required convenience init?(json: [String: Any]) {
-        self.init(JSON: json)
-    }
-    
-    func mapping(map: ObjectMapper.Map) {}
-    
-    func copy(with zone: NSZone? = nil) -> Any {
-        let json = toJSON()
-        return Self.init(JSON: json) ?? Self.init(JSON: [:])!
-    }
-    
-//    deinit {
-//        debugPrint("♻️♻️♻️ TGRootViewController -> \(type(of: self)) deinit ♻️♻️♻️")
-//    }
-}

+ 0 - 166
AIEmoji/Common/BaseClass/TSBaseNavigationBarView.swift

@@ -1,166 +0,0 @@
-//
-//  TSBaseNavigationBarView.swift
-//  TSLiveWallpaper
-//
-//  Created by 100Years on 2024/12/20.
-//
-
-
-class TSBaseNavContentBarView: UIView {
-    
-    lazy var statuView: UIView = {
-       let view = UIView()
-       return view
-   }()
-
-    lazy var barView: UIView = {
-       let view = UIView()
-       return view
-   }()
-    
-    
-    override init(frame: CGRect) {
-        super.init(frame: frame)
-        
-        addSubview(statuView)
-        addSubview(barView)
-        
-        statuView.snp.makeConstraints { make in
-            make.top.leading.trailing.equalTo(0)
-            make.height.equalTo(k_Height_StatusBar)
-        }
-
-        barView.snp.makeConstraints { make in
-            make.leading.trailing.equalTo(0)
-            make.top.equalTo(k_Height_StatusBar)
-            make.height.equalTo(k_Height_NavBar)
-        }
-
-    }
-    
-    
-    required init?(coder: NSCoder) {
-        fatalError("init(coder:) has not been implemented")
-    }
-}
-
-class TSNormalNavigationBarView: TSBaseNavContentBarView {
-
-    // MARK: - Properties
-     var navBgColor: UIColor!
-     var navTitleColor: UIColor!
-     var navTitleFont: UIFont!
-     var navLeftFont: UIFont!
-     var navRightFont: UIFont!
-
-     lazy var leftNavBtn: UIButton = {
-        let button = createNavButton()
-        button.contentHorizontalAlignment = .left
-        button.contentEdgeInsets = UIEdgeInsets(top: 0, left: 10, bottom: 0, right: 0)
-        return button
-    }()
-
-     lazy var titleNavBtn: UIButton = {
-        let button = createNavButton()
-        button.titleLabel?.font = navTitleFont
-        return button
-    }()
-
-     lazy var rightNavBtn: UIButton = {
-        let button = createNavButton()
-        button.titleLabel?.font = navRightFont
-        button.titleLabel?.adjustsFontSizeToFitWidth = true
-        button.contentHorizontalAlignment = .right
-        button.setTitleColor(.themeColor, for: .normal)
-        button.contentEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 10)
-        return button
-    }()
-
-    // MARK: - Initializers
-    override init(frame: CGRect) {
-        super.init(frame: frame)
-        createData()
-        createView()
-    }
-    
-    @MainActor required init?(coder: NSCoder) {
-        fatalError("init(coder:) has not been implemented")
-    }
-    
-
-    // MARK: - Setup Methods
-    private func createData() {
-        navBgColor = .naviMianBgColor
-        navTitleColor = .naviMianTextColor
-        navTitleFont = .font(size: 18,weight:.medium)
-        navLeftFont = .font(size: 16,weight:.medium)
-        navRightFont = .font(size: 16,weight:.medium)
-    }
-
-    private func createView() {
-        let space: CGFloat = 10
-        let margins: CGFloat = 6
-
-        backgroundColor = navBgColor
-
-  
-        barView.addSubview(leftNavBtn)
-        barView.addSubview(titleNavBtn)
-        barView.addSubview(rightNavBtn)
-
-        leftNavBtn.snp.makeConstraints { make in
-            make.leading.equalTo(margins)
-            make.centerY.equalToSuperview()
-            make.width.height.equalTo(44.0)
-        }
-        
-        rightNavBtn.snp.makeConstraints { make in
-            make.trailing.equalTo(-margins)
-            make.centerY.equalToSuperview()
-            make.width.height.equalTo(44.0)
-        }
-        
-         titleNavBtn.snp.makeConstraints { make in
-             make.leading.equalTo(leftNavBtn.snp.trailing).offset(margins)
-             make.trailing.equalTo(rightNavBtn.snp.leading).offset(-margins)
-             make.centerY.equalToSuperview()
-             make.height.equalTo(44.0)
-         }
-         
-    }
-
-    // MARK: - Helper Methods
-    func setTitleName(_ name: String) -> UIButton {
-        titleNavBtn.setTitle(name.localized, for: .normal)
-        return titleNavBtn
-    }
-
-    func setTitleNavigationItem(name: String, imageName: String, target: Any?, action: Selector) -> UIButton {
-        setNavButton(button: titleNavBtn, name: name, imageName: imageName, target: target, action: action)
-        return titleNavBtn
-    }
-
-    func setLeftNavigationItem(name: String, imageName: String, target: Any?, action: Selector) -> UIButton {
-        setNavButton(button: leftNavBtn, name: name, imageName: imageName, target: target, action: action)
-        return leftNavBtn
-    }
-
-    func setRightNavigationItem(name: String, imageName: String, target: Any?, action: Selector) -> UIButton {
-        setNavButton(button: rightNavBtn, name: name, imageName: imageName, target: target, action: action)
-        return rightNavBtn
-    }
-
-    private func setNavButton(button: UIButton, name: String, imageName: String, target: Any?, action: Selector) {
-        button.setTitle(name.localized, for: .normal)
-        button.setImage(UIImage(named: imageName), for: .normal)
-        button.addTarget(target, action: action, for: .touchUpInside)
-    }
-
-    private func createNavButton() -> UIButton {
-        let button = UIButton()
-        button.setTitleColor(navTitleColor, for: .normal)
-        button.titleLabel?.font = navRightFont
-        button.titleLabel?.adjustsFontSizeToFitWidth = true
-        return button
-    }
-}

+ 0 - 110
AIEmoji/Common/BaseClass/TSBaseNavigationC.swift

@@ -1,110 +0,0 @@
-//
-//  TSBaseNavigationC.swift
-//  TSLiveWallpaper
-//
-//  Created by 100Years on 2024/12/20.
-//
-
-import UIKit
-
-class TSBaseNavigationC: UINavigationController, UIGestureRecognizerDelegate, UINavigationControllerDelegate, UINavigationBarDelegate {
-
-//    /// Whether to use system pop gesture. If false, full-screen pop gesture will be set.
-//    static let useSystemGesture: Bool = false
-//    /// Whether to enable global pop gestures. The default is true.
-//    static let popGestureEnabled: Bool = true
-//
-//    private var vcsDic: [String: Bool] = [:]
-
-    override func viewDidLoad() {
-        super.viewDidLoad()
-        configureNavigationBar()
-//        configureNavigationGestures()
-        view.backgroundColor = .clear
-        interactivePopGestureRecognizer?.isEnabled = true;
-    }
-
-    private func configureNavigationBar() {
-        self.navigationBar.isHidden = true
-    }
-//
-//    private func configureNavigationGestures() {
-//        vcsDic = [:]
-//        self.interactivePopGestureRecognizer?.delegate = self
-//    }
-//
-//    // Override pushViewController to initialize interactive pop gesture here.
-//    override func pushViewController(_ viewController: UIViewController, animated: Bool) {
-//        // Hide bottom bar only for the first pushed view controller
-//        viewController.hidesBottomBarWhenPushed = self.viewControllers.count == 1
-//        super.pushViewController(viewController, animated: animated)
-//        self.interactivePopGestureRecognizer?.isEnabled = TSBaseNavigationC.popGestureEnabled
-//    }
-//
-//    // MARK: - UIGestureRecognizerDelegate
-//
-//    func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
-//        // Disable pop gesture if it's the root view controller
-//        if self.viewControllers.count == 1 {
-//            return false
-//        }
-//        let vcKey = vcKeyFromVC(self.topViewController)
-//        if let vcKey = vcKey, let isEnabled = vcsDic[vcKey] {
-//            return isEnabled
-//        }
-//        return self.interactivePopGestureRecognizer?.isEnabled ?? true
-//    }
-//
-//    // MARK: - UINavigationControllerDelegate
-//
-//    func navigationController(_ navigationController: UINavigationController,
-//                              willShow viewController: UIViewController,
-//                              animated: Bool) {
-//        if #available(iOS 10.0, *) {
-//            viewController.transitionCoordinator?.notifyWhenInteractionChanges { context in
-//                if context.isCancelled { return }
-//                debugPrint("notifyWhenInteractionChanges context.isCancelled=\(context.isCancelled)")
-//            }
-//        }
-//    }
-//
-//    func navigationController(_ navigationController: UINavigationController,
-//                              didShow viewController: UIViewController,
-//                              animated: Bool) {
-//        let vcKey = vcKeyFromVC(viewController)
-//        if let vcKey = vcKey, vcsDic[vcKey] == nil {
-//            // Save pop gesture enabled value for each child view controller
-//            vcsDic[vcKey] = self.interactivePopGestureRecognizer?.isEnabled ?? true
-//        }
-//    }
-//
-//    // MARK: - UINavigationBarDelegate
-//
-//    func navigationBar(_ navigationBar: UINavigationBar, shouldPop item: UINavigationItem) -> Bool {
-//        return true
-//    }
-//
-//    // MARK: - Convenience Methods
-//
-//    private func vcKeyFromVC(_ viewController: UIViewController?) -> String? {
-//        guard let viewController = viewController else { return nil }
-//        return String(describing: type(of: viewController))
-//    }
-//
-//    func setSpecifiedViewControllerInteractivePopGestureEnabled(_ enabled: Bool) {
-//        let vcKey = vcKeyFromVC(self.topViewController)
-//        if let vcKey = vcKey {
-//            vcsDic[vcKey] = enabled
-//        }
-//    }
-//
-//    // MARK: - Status Bar
-//
-//    override var childForStatusBarStyle: UIViewController? {
-//        return self.topViewController
-//    }
-//
-//    deinit {
-////        debugPrint("TGRootNavigationController deinitialized")
-//    }
-}

+ 0 - 40
AIEmoji/Common/BaseClass/TSBaseTabViewCell.swift

@@ -1,40 +0,0 @@
-//
-//  CWBaseTabViewCell.swift
-//  ClockWidget
-//
-//  Created by fff on 2024/11/12.
-//
-
-
-class TSBaseTabViewCell: UITableViewCell {
-    
-    lazy var bgContentView:UIView = {
-        let view = UIView()
-        view.backgroundColor = .clear
-        return view
-    }()
-    
-    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
-        super.init(style: style, reuseIdentifier: reuseIdentifier)
-        
-        self.selectionStyle = .none
-        self.backgroundColor = .clear
-        self.addSubview(bgContentView)
-        bgContentView.snp.makeConstraints { make in
-            make.top.leading.trailing.bottom.equalTo(0)
-        }
-        creatUI()
-    }
-    
-    required init?(coder: NSCoder) {
-        fatalError("init(coder:) has not been implemented")
-    }
-    
-    func creatUI(){
-        
-    }
-    
-    deinit {
-        debugPrint("<---deinit \(String(describing: self))")
-    }
-}

+ 0 - 240
AIEmoji/Common/BaseClass/TSBaseVC.swift

@@ -1,240 +0,0 @@
-//
-//  TSBaseVC.swift
-//  TSLiveWallpaper
-//
-//  Created by 100Years on 2024/12/20.
-//
-
-import UIKit
-import Combine
-
-class TSBaseVC: UIViewController {
-    
-    var cancellable: [AnyCancellable] = []
-    
-    private var blurEffect: UIBlurEffect?
-    private lazy var navBlurView: UIVisualEffectView = {
-        let view = UIVisualEffectView()
-        return view
-    }()
-    
-    lazy var contentView: UIView = {
-        let view = UIView()
-        return view
-    }()
-    
-    
-    lazy var navBarContentView: UIView = {
-        let view = UIView()
-        view.backgroundColor = .clear
-        return view
-    }()
-    
-    private lazy var normalNavBarView: TSNormalNavigationBarView = {
-        let view = TSNormalNavigationBarView()
-        return view
-    }()
-    
-    
-    lazy var viewBgImageView: UIImageView = {
-        let view = UIImageView()
-        view.backgroundColor = .clear
-        return view
-    }()
-    
-    lazy var nullView: UIView = {
-        let view = UIView()
-        view.backgroundColor = .clear
-        return view
-    }()
-    
-    lazy var netWorkView: UIView = {
-        let view = UIView()
-        view.backgroundColor = .clear
-        return view
-    }()
-    
-    
-    override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
-        super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
-    }
-
-    required init?(coder: NSCoder) {
-        super.init(coder: coder)
-    }
-
-    /// 提供一个无参数的默认初始化方法
-    init() {
-        super.init(nibName: nil, bundle: nil)
-    }
-    
-    override func viewDidLoad() {
-        super.viewDidLoad()
-        setupSuperSomeView()
-        createData()
-        createView()
-        dealThings()
-    }
-    
-    private func setupSuperSomeView() {
-        edgesForExtendedLayout = [.all]
-        
-        view.addSubview(contentView)
-        view.addSubview(navBarContentView)
-        
-        contentView.snp.makeConstraints { make in
-            make.top.equalTo(k_Nav_Height)
-            make.leading.trailing.bottom.equalToSuperview()
-        }
-        
-        navBarContentView.snp.makeConstraints { make in
-            make.leading.top.trailing.equalToSuperview()
-            make.height.equalTo(k_Nav_Height)
-        }
-
-        
-        view.backgroundColor = .mainBg
-        view.layoutIfNeeded()
-    }
-    
-    
-    
-    
-    func setViewBgImageNamed(named:String){
-        if viewBgImageView.superview == nil {
-            view.insertSubview(viewBgImageView, at: 0)
-            viewBgImageView.snp.makeConstraints { make in
-                make.edges.equalToSuperview()
-            }
-        }
-        viewBgImageView.image = UIImage(named: named)
-    }
-    
-    
-    //子类重写
-    func createData(){
-        
-        
-    }
-    func createView(){
-        
-        
-    }
-    
-    func dealThings(){
-        
-        
-    }
-    
-
-    func addNormalNavBarView(){
-        navBarContentView.addSubview(normalNavBarView)
-        normalNavBarView.snp.makeConstraints { make in
-            make.edges.equalToSuperview()
-        }
-    }
-    
-//    func useTransparentBlurredNavigationBar() {
-//        navBarView.removeFromSuperview()
-//        edgesForExtendedLayout = .all
-//        
-//        view.addSubview(navBlurView)
-//        navBlurView.snp.makeConstraints { make in
-//            make.left.top.right.equalToSuperview()
-//            make.height.equalTo(k_Nav_Height)
-//        }
-//        
-//        setClearNavigationBar()
-//        navBarView.titleNavBtn?.titleLabel?.alpha = 0.0
-//        navBlurView.contentView.addSubview(navBarView)
-//        
-//        navBarView.snp.makeConstraints { make in
-//            make.edges.equalToSuperview()
-//        }
-//        
-//        contentView.snp.updateConstraints { make in
-//            make.top.equalToSuperview()
-//        }
-//    }
-//    
-//    func handleTransparentBlurredNavigationBar(scrollViewY: CGFloat) {
-//        if scrollViewY >= - kStatusBar_Height {
-//            navBlurView.effect = blurEffect
-//            navBarView.titleNavBtn?.titleLabel?.alpha = 1.0
-//        } else {
-//            navBlurView.effect = nil
-//            navBarView.titleNavBtn?.titleLabel?.alpha = 0.0
-//        }
-//    }
-    
-    
-
-    
-    // ... 其他方法根据需要重写 ...
-    
-    
-    
-    
-    
-    override func viewWillAppear(_ animated: Bool) {
-//        super.viewWillAppear(animated)
-        debugPrint("进入------>\(String(describing: type(of: self)))")
-    }
-
-    deinit {
-        NotificationCenter.default.removeObserver(self)
-        cancellable.removeAll()
-        debugPrint("♻️♻️♻️ TGRootViewController -> \(type(of: self)) deinit ♻️♻️♻️")
-    }
-
-    // MARK: - 导航栏方法
-
-    func setTitleText(_ title: String) {
-       _ = normalNavBarView.setTitleName(NSLocalizedString(title, comment: ""))
-    }
-
-    func setPageTitle(_ title: String) {
-        let pageTitle = title
-        let backTitle = " "
-        setTitleText(pageTitle)
-        _ = setNavigationItem(backTitle, imageName: "navi_back_white", direction: .left, action: #selector(navBarClickLeftAction))
-    }
-
-    func setNavigationItem(_ name: String, imageName: String, direction: NSTextAlignment, action: Selector) -> UIButton {
-        if direction == .left {
-            return normalNavBarView.setLeftNavigationItem(name: name, imageName: imageName, target: self, action: action)
-        } else {
-            return normalNavBarView.setRightNavigationItem(name: name, imageName: imageName, target: self, action: action)
-        }
-    }
-
-    @objc func navBarClickLeftAction() {
-        debugPrint("navBarClickLeftAction -> \(type(of: self))")
-        pop()
-    }
-
-    func pop() {
-        if navigationController == nil {
-            dismiss(animated: true, completion: nil)
-        } else if navigationController?.presentingViewController != nil, navigationController?.viewControllers.count == 1 {
-            navigationController?.dismiss(animated: true, completion: nil)
-        } else {
-            navigationController?.popViewController(animated: true)
-        }
-    }
-
-}
-
-
-extension TSBaseVC {
-    
-    func setNavBarViewHidden(_ isHidden: Bool) {
-        navBarContentView.snp.updateConstraints { make in
-            make.height.equalTo(isHidden ? 0 : k_Nav_Height)
-        }
-        
-        contentView.snp.updateConstraints { make in
-            make.top.equalTo(isHidden ? 0 : k_Nav_Height)
-        }
-    }
-}

+ 0 - 41
AIEmoji/Common/BaseClass/TSBaseView.swift

@@ -1,41 +0,0 @@
-//
-//  TSBaseView.swift
-//  TSLiveWallpaper
-//
-//  Created by 100Years on 2024/12/24.
-//
-
-class TSBaseView : UIView {
-    
-    lazy var contentView:UIView = {
-        let view = UIView()
-        view.backgroundColor = .clear
-        return view
-    }()
-    
-    override init(frame: CGRect) {
-        super.init(frame: frame)
-        self.backgroundColor = .clear
-        self.addSubview(contentView)
-        contentView.snp.makeConstraints { make in
-            make.top.leading.trailing.bottom.equalTo(0)
-        }
-        creatUI()
-        dealThings()
-    }
-    
-    required init?(coder: NSCoder) {
-        fatalError("init(coder:) has not been implemented")
-    }
-    
-    func creatUI(){
-        
-    }
-    
-    
-    func dealThings(){
-        
-        
-    }
-    
-}

+ 0 - 24
AIEmoji/Common/BaseClass/TSBaseViewModel.swift

@@ -1,24 +0,0 @@
-//
-//  TSBaseViewModel.swift
-//  AIEmoji
-//
-//  Created by 100Years on 2025/1/20.
-//
-
-class TSBaseViewModel {
-    
-    init() {
-        creatData()
-        dealThings()
-    }
-    
-    func creatData () {
-        
-        
-    }
-    
-    func dealThings () {
-        
-        
-    }
-}

+ 0 - 144
AIEmoji/Common/BaseClass/TSBasicItemModel.swift

@@ -1,144 +0,0 @@
-//
-//  TSBasicItemModel.swift
-//  TSLiveWallpaper
-//
-//  Created by 100Years on 2024/12/20.
-//
-
-class TSBasicItemModel {
-    // MARK: - Properties
-    var index: Int = 0
-//    var clickBlock: ((Any?) -> Void)?
-    var tapBlock: ((TSBasicItemModel, Int, Any?) -> Void)?
-    var updateDataBlock: ((TSBasicItemModel) -> Void)?
-    
-    var leftImageName: String?
-    var leftImage: UIImage?
-    var leftImagePath: String?
-    var leftTitle: String?
-    var leftSubTitle: String?
-    var rightString: String?
-    var rightSubString: String?
-    var rightIntValue: Int = 0
-    var itemData: Any?
-    var identifier: String?
-    var parametView: UIView?
-    var rightIsHave: Bool = false
-    var bottomIsHave: Bool = false
-    var isSelected: Bool = false
-    var isWhether: Bool = false
-    var rightViewStyle: Int = 0
-    var rectCorner: UIRectCorner = []
-    var topSpace: Bool = false
-    var bottomSpace: Bool = false
-    var height: CGFloat = 0.0
-    var width: CGFloat = 0.0
-    var type: Int = 0
-    weak var attributionSection: TSBasicSectionModel?
-    
-    // MARK: - Methods
-    func setCornerView(_ view: UIView, corner: CGFloat) {
-        if rectCorner.isEmpty {
-            view.layer.cornerRadius = 0
-        } else {
-            let path = UIBezierPath(roundedRect: view.bounds, byRoundingCorners: rectCorner, cornerRadii: CGSize(width: corner, height: corner))
-            let mask = CAShapeLayer()
-            mask.path = path.cgPath
-            view.layer.mask = mask
-        }
-    }
-    
-    func updateData() {
-        updateDataBlock?(self)
-    }
-    
-    
-    static func createItemModel(leftTitle: String,
-                                rightViewStyle: Int,
-                                rightString: String,
-                                rightIsHave: Bool,
-                                height: CGFloat,
-                                rectCorner: UIRectCorner,
-                                tapBlock: @escaping ((TSBasicItemModel, Int, Any?) -> Void)) -> TSBasicItemModel {
-        let model = TSBasicItemModel()
-        model.leftTitle = leftTitle
-        model.rightViewStyle = rightViewStyle
-        model.rightString = rightString
-        model.rightIsHave = rightIsHave
-        model.height = height
-        model.rectCorner = rectCorner
-        model.tapBlock = tapBlock
-        return model
-    }
-    
-    
-    static func setEdge(with dataArray: [TSBasicItemModel]) {
-        guard !dataArray.isEmpty else { return }
-        if dataArray.count == 1 {
-            dataArray.first?.rectCorner = .allCorners
-        } else {
-            dataArray.first?.rectCorner = [.topLeft, .topRight]
-            dataArray.last?.rectCorner = [.bottomLeft, .bottomRight]
-        }
-    }
-}
-
-
-
-class TSBasicSectionModel {
-    // MARK: - Properties
-    var index: Int = 0
-    var sectionData: Any?
-    var leftTitle: String?
-    var leftSubTitle: String?
-    var rightString: String?
-    var rightSubString: String?
-    var rightIsHave: Bool = false
-    var bottomIsHave: Bool = false
-    var topIsHave: Bool = false
-    var isOpen: Bool = false
-    var type: Int = 0
-    var rectCorner: UIRectCorner = []
-    var height: CGFloat = 0.0
-    var isFooter: Bool = false
-    var itemsArray: [TSBasicItemModel] = []
-    var selectedItemsIndex: Int = 0
-    
-    // MARK: - Methods
-    func setCornerView(_ view: UIView, corner: CGFloat) {
-        if rectCorner.isEmpty {
-            view.layer.cornerRadius = 0
-        } else {
-            let path = UIBezierPath(roundedRect: view.bounds, byRoundingCorners: rectCorner, cornerRadii: CGSize(width: corner, height: corner))
-            let mask = CAShapeLayer()
-            mask.path = path.cgPath
-            view.layer.mask = mask
-        }
-    }
-    
-    func addSubItemModel(_ itemModel: TSBasicItemModel) {
-        itemModel.attributionSection = self
-        itemsArray.append(itemModel)
-    }
-    
-    static func createSectionModel(leftTitle: String, height: CGFloat, index: Int = 0) -> TSBasicSectionModel {
-        let model = TSBasicSectionModel()
-        model.leftTitle = leftTitle
-        model.height = height
-        model.index = index
-        return model
-    }
-    
-    static func setEdge(with dataArray: [TSBasicSectionModel]) {
-        for section in dataArray {
-            let itemsArray = section.itemsArray
-            guard !itemsArray.isEmpty else { continue }
-            if itemsArray.count == 1 {
-                itemsArray.first?.rectCorner = .allCorners
-            } else {
-                itemsArray.first?.rectCorner = [.topLeft, .topRight]
-                itemsArray.last?.rectCorner = [.bottomLeft, .bottomRight]
-            }
-        }
-    }
-}

+ 0 - 78
AIEmoji/Common/Ex/AVAsset+Ex.swift

@@ -1,78 +0,0 @@
-//
-//  AVAsset+Ex.swift
-//  TSLiveWallpaper
-//
-//  Created by 100Years on 2024/12/23.
-//
-
-import UIKit
-import AVFoundation
-
-extension AVAsset {
-    func getImage(at time: TimeInterval, videoComposition: AVVideoComposition? = nil) -> UIImage? {
-        let assetImageGenerator = AVAssetImageGenerator(asset: self)
-        assetImageGenerator.appliesPreferredTrackTransform = true
-        assetImageGenerator.videoComposition = videoComposition
-        assetImageGenerator.apertureMode = .encodedPixels
-        do {
-            let thumbnailImageRef = try assetImageGenerator.copyCGImage(
-                at: CMTime(
-                    value: CMTimeValue(time),
-                    timescale: duration.timescale
-                ),
-                actualTime: nil
-            )
-            let image = UIImage.init(cgImage: thumbnailImageRef)
-            return image
-        } catch {
-            return nil
-        }
-    }
-    func getImage(
-        at time: TimeInterval,
-        videoComposition: AVVideoComposition? = nil,
-        imageGenerator: ((AVAssetImageGenerator) -> Void)? = nil,
-        completion: @escaping (AVAsset, UIImage?, AVAssetImageGenerator.Result) -> Void
-    ) {
-        loadValuesAsynchronously(forKeys: ["duration"]) { [weak self] in
-            guard let self = self else {
-                DispatchQueue.main.async {
-                    completion(.init(), nil, .failed)
-                }
-                return
-            }
-            if self.statusOfValue(forKey: "duration", error: nil) != .loaded {
-                DispatchQueue.main.async {
-                    completion(self, nil, .failed)
-                }
-                return
-            }
-            let generator = AVAssetImageGenerator(asset: self)
-            generator.appliesPreferredTrackTransform = true
-            generator.videoComposition = videoComposition
-            let time = CMTime(value: CMTimeValue(time), timescale: self.duration.timescale)
-            let array = [NSValue(time: time)]
-            generator.generateCGImagesAsynchronously(
-                forTimes: array
-            ) { (_, cgImage, _, result, _) in
-                if let image = cgImage, result == .succeeded {
-                    var image = UIImage(cgImage: image)
-                    if image.imageOrientation != .up,
-                       let img = image.normalizedImage() {
-                        image = img
-                    }
-                    DispatchQueue.main.async {
-                        completion(self, image, result)
-                    }
-                }else {
-                    DispatchQueue.main.async {
-                        completion(self, nil, result)
-                    }
-                }
-            }
-            DispatchQueue.main.async {
-                imageGenerator?(generator)
-            }
-        }
-    }
-}

+ 0 - 47
AIEmoji/Common/Ex/Array+Ex.swift

@@ -1,47 +0,0 @@
-//
-//  Array+Ex.swift
-//  TSLiveWallpaper
-//
-//  Created by 100Years on 2024/12/20.
-//
-
-extension Array {
-    
-    func safeString(At index: Int) -> String {
-        return safeObject(At: index, defaultValue: "")
-    }
-    
-    func safeStringInt(At index: Int) -> String {
-        return safeObject(At: index, defaultValue: "0")
-    }
-    
-    func safeArray(At index: Int) -> [Any] {
-        return safeObject(At: index, defaultValue: [])
-    }
-    
-    func safeDictionary(At index: Int) -> [String: Any] {
-        return safeObject(At: index, defaultValue: [:])
-    }
-    
-    func safeNumber(At index: Int) -> NSNumber {
-        return safeObject(At: index, defaultValue: NSNumber(value: 0))
-    }
-    
-    func safeObject(At index: Int) -> Any {
-        return safeObject(At: index, defaultValue: NSObject())
-    }
-    
-    private func safeObject<T>(At index: Int, defaultValue: T) -> T {
-        guard index >= 0 && index < count else { return defaultValue }
-        let value = self[index]
-        if value is NSNull { return defaultValue }
-        return value as? T ?? defaultValue
-    }
-    
-    func safeObj(At index: Int) -> Element? {
-        if index >= 0,  index < count {
-            return self[index]
-        }
-        return nil
-    }
-}

+ 0 - 37
AIEmoji/Common/Ex/CGFloat+Ex.swift

@@ -1,37 +0,0 @@
-//
-//  CGFloat+Ex.swift
-//  TSLiveWallpaper
-//
-//  Created by 100Years on 2024/12/23.
-//
-
-extension CGFloat {
-    
-    static var max: CGFloat {
-        CGFloat(MAXFLOAT)
-    }
-    
-    var compressionQuality: CGFloat {
-        if self > 30000000 {
-            return 30000000 / self
-        }else if self > 15000000 {
-            return 10000000 / self
-        }else if self > 10000000 {
-            return 6000000 / self
-        }else {
-            return 3000000 / self
-        }
-    }
-    
-    var transitionCompressionQuality: CGFloat {
-        if self > 6000000 {
-            return 3000000 / self
-        }else if self > 3000000 {
-            return 1000000 / self
-        }else if self > 1000000 {
-            return 600000 / self
-        }else {
-            return 1000000 / self
-        }
-    }
-}

+ 0 - 32
AIEmoji/Common/Ex/Date+Ex.swift

@@ -1,32 +0,0 @@
-//
-//  Date+Ex.swift
-//  TSLiveWallpaper
-//
-//  Created by 100Years on 2024/12/20.
-//
-
-extension Date {
-    private static var HmsFormatter: DateFormatter {
-        let formatter = DateFormatter()
-        formatter.dateFormat = "HH:mm:ss:SSS"
-        formatter.locale = Locale(identifier: "en")
-        return formatter
-    }
-    
-    static var hmsString: String {
-        return HmsFormatter.string(from: Date())
-    }
-    
-    static var timestampString: String {
-        return String(timestampInt)
-    }
-
-    
-    static var timestampInt: Int {
-        return Int(Date().timeIntervalSince1970)
-    }
-    
-    var timestampInt: Int {
-        return Int(self.timeIntervalSince1970)
-    }
-}

+ 0 - 45
AIEmoji/Common/Ex/Dictionary+Ex.swift

@@ -1,45 +0,0 @@
-//
-//  Dictionary+Ex.swift
-//  TSLiveWallpaper
-//
-//  Created by 100Years on 2024/12/20.
-//
-
-import Foundation
-
-extension Dictionary where Key == String {
-    
-    func safeString(forKey key: String) -> String {
-        return safeObject(forKey: key, defaultValue: "")
-    }
-    
-    func safeStringInt(forKey key: String) -> String {
-        return safeObject(forKey: key, defaultValue: "0")
-    }
-    
-    func safeArray(forKey key: String) -> [Any] {
-        return safeObject(forKey: key, defaultValue: [])
-    }
-    
-    func safeDictionary(forKey key: String) -> [String: Any] {
-        return safeObject(forKey: key, defaultValue: [:])
-    }
-    
-    func safeNumber(forKey key: String) -> NSNumber {
-        return safeObject(forKey: key, defaultValue: NSNumber(value: 0))
-    }
-    
-    func safeInt(forKey key: String) -> Int {
-        guard let value = self[key] , let valueInt = value as? Int else { return 0 }
-        return valueInt
-    }
-    
-    func safeObject(forKey key: String) -> Any {
-        return safeObject(forKey: key, defaultValue: NSObject())
-    }
-    
-    private func safeObject<T>(forKey key: String, defaultValue: T) -> T {
-        guard let value = self[key]  , let valueT = value as? T else { return defaultValue }
-        return valueT
-    }
-}

+ 0 - 33
AIEmoji/Common/Ex/Int+Ex.swift

@@ -1,33 +0,0 @@
-//
-//  Int+Ex.swift
-//  TSLiveWallpaper
-//
-//  Created by 100Years on 2024/12/20.
-//
-
-extension Int {
-    var localNumber: String? {
-        return localNumber()
-    }
-    
-    func localNumber(_ minimumIntegerDigits: Int? = nil, locale: Locale? = nil) -> String? {
-        let formatter = NumberFormatter()
-        if let locale = locale {
-            formatter.locale = locale
-        }
-        else {
-            formatter.locale = Locale.local
-        }
-        
-        formatter.numberStyle = .decimal
-        if let value = minimumIntegerDigits {
-            formatter.minimumIntegerDigits = value
-        }
-        return formatter.string(for: self);
-    }
-}
-extension Locale {
-    static var local: Locale {
-        return Locale(identifier: TSConfig.appLanguage)
-    }
-}

+ 0 - 295
AIEmoji/Common/Ex/NSString+Ex.swift

@@ -1,295 +0,0 @@
-//
-//  NSString+Ex.swift
-//  TSLiveWallpaper
-//
-//  Created by 100Years on 2024/12/20.
-//
-import CommonCrypto
-extension String {
-    
-    var color: UIColor {
-        if isEmpty {
-            return .clear
-        }
-        return UIColor.fromHex(self)
-    }
-    
-    var localFilePath: String {
-        var path = self
-        if path.lowercased().hasPrefix("file://") {
-            path.removeFirst("file://".count)
-        }
-        return path
-    }
-    
-    func toCgRect() -> CGRect {
-        NSCoder.cgRect(for: self)
-    }
-    
-    func toCgPoint() -> CGPoint {
-        NSCoder.cgPoint(for: self)
-    }
-
-
-    func toRgba() -> (r: CGFloat, g: CGFloat, b: CGFloat, a: CGFloat)? {
-        var r:CGFloat = 0;
-        var g:CGFloat = 0;
-        var b:CGFloat = 0;
-        var a:CGFloat = 0;
-        var prefix: Int = 0;
-
-        let color: String = trimmingCharacters(in: .whitespacesAndNewlines).uppercased()
-        if (color.hasPrefix("#")) {
-            prefix = 1
-        }
-        else if (color.hasPrefix("0X")) {
-            prefix = 2
-        }
-        let length: Int = color.count - prefix
-        //         RGB            RGBA          RRGGBB        RRGGBBAA
-        
-        func componentFrom(string: String, start: Int, length: Int) -> CGFloat {
-            guard start >= 0, start + length <= string.count else {
-                return 0
-            }
-            
-            let begin = string.index(startIndex, offsetBy: start)
-            let end = string.index(startIndex, offsetBy: start + length)
-            
-            let sub = string[begin..<end]
-            var full = String(sub)
-            if length == 1 {
-                full += full
-            }
-            
-            var hex: UInt64 = 0
-            Scanner(string: full).scanHexInt64(&hex)
-            
-            let float = CGFloat(hex) / 255.0
-            return float
-        }
-        
-        switch length {
-        case 3: // RGB
-            r = componentFrom(string: color, start: prefix, length: 1)
-            g = componentFrom(string: color, start: prefix + 1, length: 1)
-            b = componentFrom(string: color, start: prefix + 2, length: 1)
-            a = 1
-        case 4: // RGBA
-            r = componentFrom(string: color, start: prefix, length: 1)
-            g = componentFrom(string: color, start: prefix + 1, length: 1)
-            b = componentFrom(string: color, start: prefix + 2, length: 1)
-            a = componentFrom(string: color, start: prefix + 3, length: 1)
-        case 6: // RRGGBB
-            r = componentFrom(string: color, start: prefix, length: 2)
-            g = componentFrom(string: color, start: prefix + 2, length: 2)
-            b = componentFrom(string: color, start: prefix + 4, length: 2)
-            a = 1
-        case 8: // RRGGBBAA
-            r = componentFrom(string: color, start: prefix, length: 2)
-            g = componentFrom(string: color, start: prefix + 2, length: 2)
-            b = componentFrom(string: color, start: prefix + 4, length: 2)
-            a = componentFrom(string: color, start: prefix + 6, length: 2)
-        default:
-            return nil
-        }
-        
-        return (r, g, b, a)
-
-    }
-    
-    func toColor() -> UIColor? {
-        if let rgba = toRgba() {
-            return UIColor(red: rgba.r, green: rgba.g, blue: rgba.b, alpha: rgba.a)
-        }
-        
-        return nil
-    }
-}
-
-extension String {
-    
-    var localized:String{
-        return self
-//        return NSLocalizedString(self, comment: self)
-    }
-}
-
-
-extension String {
-    var doubleValue: Double? {
-        Double(self)
-    }
-    
-    var localNumber: String {
-        if let value = Int(self), let numberString = value.localNumber {
-            return numberString
-        }
-        return self
-    }
-    
-    var md5:String {
-        let data = Data(self.utf8)
-        var digest = [UInt8](repeating: 0, count: Int(CC_MD5_DIGEST_LENGTH))
-        data.withUnsafeBytes {
-            _ = CC_MD5($0.baseAddress, CC_LONG(data.count), &digest)
-        }
-        return digest.map { String(format: "%02x", $0) }.joined()
-    }
-}
-
-
-extension String {
-    // 移除逗号
-    func deleteDotSymbol() -> String {
-        // 超过1000的数字,格式化成文本后会带 ','(en)/'٬'(ar)
-        return replacingOccurrences(of: ",", with: "").replacingOccurrences(of: "٬", with: "")
-    }
-    
-}
-
-
-
-
-extension String {
-    /// 根据字符串动态创建类实例
-    /// - Parameters:
-    ///   - type: 要创建的类类型(泛型)
-    ///   - bundle: 模块的命名空间(默认为 `nil`,即当前模块)
-    /// - Returns: 创建的实例或 `nil`
-    func toInstance<T:NSObject>(of type: T.Type, bundle: String? = nil) -> T? {
-        // 获取完整的类名
-        let namespace = bundle ?? Bundle.main.infoDictionary?["CFBundleName"] as? String ?? ""
-        let className = "\(namespace).\(self)"
-        
-        // 通过类名获取类型
-        guard let targetClass = NSClassFromString(className) as? T.Type else {
-            return nil
-        }
-        
-        // 创建实例
-        return targetClass.init()
-        
-    }
-    
-    
-    func toClass(bundle: String? = nil) -> AnyClass? {
-        // 获取完整的类名
-        let namespace = bundle ?? Bundle.main.infoDictionary?["CFBundleName"] as? String ?? ""
-        let className = "\(namespace).\(self)"
-        
-        // 通过类名获取类型
-        guard let targetClass = NSClassFromString(className) else {
-            return nil
-        }
-        
-        // 创建实例
-        return targetClass
-    }
-}
-
-
-
-
-extension String {
-    
-
-    func boundingRect(ofAttributes attributes: [NSAttributedString.Key: Any], size: CGSize) -> CGRect {
-        let boundingBox = boundingRect(
-            with: size,
-            options: [.usesLineFragmentOrigin, .usesFontLeading],
-            attributes: attributes,
-            context: nil
-        )
-        return boundingBox
-    }
-    
-    func size(ofAttributes attributes: [NSAttributedString.Key: Any], maxWidth: CGFloat, maxHeight: CGFloat) -> CGSize {
-        boundingRect(ofAttributes: attributes, size: .init(width: maxWidth, height: maxHeight)).size
-    }
-    
-    func size(ofFont font: UIFont, maxWidth: CGFloat, maxHeight: CGFloat) -> CGSize {
-        let constraintRect = CGSize(width: maxWidth, height: maxHeight)
-        let boundingBox = boundingRect(
-            with: constraintRect,
-            options: [.usesLineFragmentOrigin, .usesFontLeading],
-            attributes: [.font: font],
-            context: nil
-        )
-        return boundingBox.size
-    }
-    
-    func width(ofSize size: CGFloat, maxHeight: CGFloat) -> CGFloat {
-        width(
-            ofFont: UIFont.systemFont(ofSize: size),
-            maxHeight: maxHeight
-        )
-    }
-    
-    func width(ofFont font: UIFont, maxHeight: CGFloat) -> CGFloat {
-        size(
-            ofAttributes: [NSAttributedString.Key.font: font],
-            maxWidth: CGFloat(MAXFLOAT),
-            maxHeight: maxHeight
-        ).width
-    }
-    
-    func height(ofSize size: CGFloat, maxWidth: CGFloat) -> CGFloat {
-        height(
-            ofFont: UIFont.systemFont(ofSize: size),
-            maxWidth: maxWidth
-        )
-    }
-    
-    func height(ofFont font: UIFont, maxWidth: CGFloat) -> CGFloat {
-        size(
-            ofAttributes: [NSAttributedString.Key.font: font],
-            maxWidth: maxWidth,
-            maxHeight: CGFloat(MAXFLOAT)
-        ).height
-    }
-    
-    subscript(_ indexs: ClosedRange<Int>) -> String {
-            let beginIndex = index(startIndex, offsetBy: indexs.lowerBound)
-            let endIndex = index(startIndex, offsetBy: indexs.upperBound)
-            return String(self[beginIndex...endIndex])
-        }
-        
-    subscript(_ indexs: Range<Int>) -> String {
-        let beginIndex = index(startIndex, offsetBy: indexs.lowerBound)
-        let endIndex = index(startIndex, offsetBy: indexs.upperBound)
-        return String(self[beginIndex..<endIndex])
-    }
-    
-    subscript(_ indexs: PartialRangeThrough<Int>) -> String {
-        let endIndex = index(startIndex, offsetBy: indexs.upperBound)
-        return String(self[startIndex...endIndex])
-    }
-    
-    subscript(_ indexs: PartialRangeFrom<Int>) -> String {
-        let beginIndex = index(startIndex, offsetBy: indexs.lowerBound)
-        return String(self[beginIndex..<endIndex])
-    }
-    
-    subscript(_ indexs: PartialRangeUpTo<Int>) -> String {
-        let endIndex = index(startIndex, offsetBy: indexs.upperBound)
-        return String(self[startIndex..<endIndex])
-    }
-    
-    var assetFormat: String? {
-        let lowercased = lowercased()
-        if lowercased.hasSuffix("heic") {
-            return "heic"
-        }
-        if lowercased.hasSuffix("jpg") || lowercased.hasSuffix("jpeg") {
-            return "jpeg"
-        }
-        if lowercased.hasSuffix("png") {
-            return "png"
-        }
-        if lowercased.hasSuffix("gif") {
-            return "gif"
-        }
-        return nil
-    }
-}

+ 0 - 47
AIEmoji/Common/Ex/SwiftUI/Color+Ex.swift

@@ -1,47 +0,0 @@
-//
-//  Color+Ex.swift
-//  TSLiveWallpaper
-//
-//  Created by 100Years on 2025/1/14.
-//
-
-import SwiftUI
-
-extension Color {
-    static func hex(_ hex: String) -> Color {
-        let hex = hex.trimmingCharacters(in: CharacterSet.alphanumerics.inverted)
-        var int: UInt64 = 0
-        Scanner(string: hex).scanHexInt64(&int)
-
-        let a, r, g, b: UInt64
-        switch hex.count {
-        case 3: // RGB (12-bit)
-            (a, r, g, b) = (255, (int >> 8) * 17, (int >> 4 & 0xF) * 17, (int & 0xF) * 17)
-        case 6: // RGB (24-bit)
-            (a, r, g, b) = (255, int >> 16, int >> 8 & 0xFF, int & 0xFF)
-        case 8: // ARGB (32-bit)
-            (a, r, g, b) = (int >> 24, int >> 16 & 0xFF, int >> 8 & 0xFF, int & 0xFF)
-        default:
-            (a, r, g, b) = (255, 0, 0, 0)
-        }
-
-        return Self(
-            .sRGB,
-            red: Double(r) / 255,
-            green: Double(g) / 255,
-            blue: Double(b) / 255,
-            opacity: Double(a) / 255
-        )
-    }
-
-    // 随机生成一个颜色
-    static var randomColor: Color {
-        // 随机生成 R, G, B 和 alpha(透明度)值
-        let red = Double.random(in: 0 ... 1)
-        let green = Double.random(in: 0 ... 1)
-        let blue = Double.random(in: 0 ... 1)
-        let alpha = Double.random(in: 0.5 ... 1) // 可选,透明度的范围
-
-        return Color(red: red, green: green, blue: blue, opacity: alpha)
-    }
-}

+ 0 - 16
AIEmoji/Common/Ex/SwiftUI/Font+Ex.swift

@@ -1,16 +0,0 @@
-//
-//  Font+Ex.swift
-//  TSLiveWallpaper
-//
-//  Created by 100Years on 2025/1/14.
-//
-
-
-import SwiftUI
-extension Font {
-    static func font(name: FontName = .PingFangSC, size: CGFloat, weight: UIFont.Weight = .regular) -> Font {
-        let uiFont =  UIFont.font(name: name,size: size,weight: weight)
-        return Font(uiFont as CTFont)
-    }
-}
-

+ 0 - 12
AIEmoji/Common/Ex/UIApplication+Ex.swift

@@ -1,12 +0,0 @@
-//
-//  UIApplication+Ex.swift
-//  AIEmoji
-//
-//  Created by 100Years on 2025/1/22.
-//
-
-import UIKit
-
-extension UIApplication {
-
-}

+ 0 - 123
AIEmoji/Common/Ex/UIButton+Ex.swift

@@ -1,123 +0,0 @@
-//
-//  UIButton+Ex.swift
-//  TSLiveWallpaper
-//
-//  Created by 100Years on 2024/12/20.
-//
-
-extension UIButton {
-    
-    private struct AssociatedKeys {
-        static var actionKey = "UIButtonActionKey"
-    }
-
-    // 存储回调闭包
-    private var actionClosure: (() -> Void)? {
-        get {
-            return objc_getAssociatedObject(self, &AssociatedKeys.actionKey) as? (() -> Void)
-        }
-        set {
-            objc_setAssociatedObject(self, &AssociatedKeys.actionKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
-        }
-    }
-    
-    
-    
-    /// 快速创建 UIButton
-    /// - Parameters:
-    ///   - title: 按钮的标题
-    ///   - image: 按钮的图标
-    ///   - backgroundImage: 按钮的背景图
-    ///   - backgroundColor: 按钮的背景色
-    ///   - font: 按钮的字体
-    ///   - titleColor: 按钮的字体颜色
-    ///   - action: 按钮点击事件的回调
-    static func createButton(title: String? = nil,
-                             image: UIImage? = nil,
-                             backgroundImage: UIImage? = nil,
-                             backgroundColor: UIColor? = nil,
-                             font: UIFont? = nil,
-                             titleColor: UIColor? = nil,
-                             corner:CGFloat = 0,
-                             action: (() -> Void)? = nil) -> UIButton {
-        let button = UIButton(type: .custom)
-        button.setUpButton(title: title,
-                           image: image,
-                           backgroundImage: backgroundImage,
-                           backgroundColor: backgroundColor,
-                           font: font,
-                           titleColor: titleColor,
-                           corner:corner,
-                           action: action)
-        return button
-    }
-
-    func setUpButton(title: String? = nil,
-                             image: UIImage? = nil,
-                             backgroundImage: UIImage? = nil,
-                             backgroundColor: UIColor? = nil,
-                             font: UIFont? = nil,
-                             titleColor: UIColor? = nil,
-                             corner:CGFloat = 0,
-                             action: (() -> Void)? = nil){
-        let button = self
-        button.showsTouchWhenHighlighted = false
-        button.adjustsImageWhenHighlighted = false
-        // 设置标题
-        if let title = title {
-            button.setTitle(title, for: .normal)
-        }
-        
-        // 设置图片
-        if let image = image {
-            button.setImage(image, for: .normal)
-        }
-        
-        // 设置背景图片
-        if let backgroundImage = backgroundImage {
-            button.setBackgroundImage(backgroundImage, for: .normal)
-        }
-        
-        // 设置背景色
-        if let backgroundColor = backgroundColor {
-            button.backgroundColor = backgroundColor
-        }
-        
-        // 设置字体
-        if let font = font {
-            button.titleLabel?.font = font
-        }
-        
-        // 设置字体颜色
-        if let titleColor = titleColor {
-            button.setTitleColor(titleColor, for: .normal)
-        }
-        
-        if corner > 0 {
-            button.cornerRadius = corner
-        }
-
-        if let action = action {
-            button.actionClosure = action
-            button.addTarget(button, action: #selector(buttonTapped), for: .touchUpInside)
-        }
-
-    }
-    
-    // 按钮点击事件
-    @objc private func buttonTapped() {
-        actionClosure?()
-    }
-}
-
-
-class UIExpandedTouchButton: UIButton {
-    override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
-        let buttonBounds = self.bounds
-        let widthDelta = self.width * 0.5 // 增加点击区域的比例,这里增加了50%
-        let heightDelta = self.height * 0.5
-        let expandedBounds = buttonBounds.insetBy(dx: -widthDelta, dy: -heightDelta)
-        return expandedBounds.contains(point)
-    }
-}
-

+ 0 - 139
AIEmoji/Common/Ex/UICollectionView+Ex.swift

@@ -1,139 +0,0 @@
-//
-//  UICollectionView+Ex.swift
-//  TSLiveWallpaper
-//
-//  Created by 100Years on 2024/12/20.
-//
-
-import UIKit
-import MJRefresh
-
-private var isMJRefreshKey = "isMJRefreshKey"
-private var pageNumKey = "pageNumKey"
-private var pageSizeKey = "pageSizeKey"
-private var dataArrayKey = "dataArrayKey"
-
-private let PAGESIZE = 10
-private let PAGENUM = 1
-
-extension UICollectionView {
-    static func createCommon(delegate: UICollectionViewDelegate & UICollectionViewDataSource, cellReuseIds: [String]) -> UICollectionView {
-        let layout = UICollectionViewFlowLayout()
-        layout.scrollDirection = .vertical
-        
-        let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
-        collectionView.delegate = delegate
-        collectionView.dataSource = delegate
-        collectionView.showsVerticalScrollIndicator = false
-        collectionView.showsHorizontalScrollIndicator = false
-        collectionView.backgroundColor = .clear
-        
-        if #available(iOS 11.0, *) {
-            collectionView.contentInsetAdjustmentBehavior = .never
-        }
-        
-        for cellReuseId in cellReuseIds {
-            collectionView.register(cellReuseId.toClass(), forCellWithReuseIdentifier: cellReuseId)
-        }
-        
-        collectionView.dataArray = []
-        collectionView.pageNum = PAGENUM
-        collectionView.pageSize = PAGESIZE
-        
-        return collectionView
-    }
-    
-    func myReloadData() {
-        reloadData()
-    }
-    
-    func addFooterWithRefreshingBlock(_ block: @escaping () -> Void) {
-        isUseMJRefresh = true
-        mj_footer = MJRefreshAutoNormalFooter(refreshingBlock: { [weak self] in
-            self?.pageNum += 1
-            block()
-        })
-        (mj_footer as? MJRefreshAutoNormalFooter)?.stateLabel?.isHidden = true
-    }
-    
-    func addHeaderWithRefreshingBlock(_ block: @escaping () -> Void) {
-        isUseMJRefresh = true
-        mj_header = MJRefreshNormalHeader(refreshingBlock: { [weak self] in
-            self?.pageNum = PAGENUM
-            block()
-        })
-    }
-    
-    func handleDataArray(_ networkArray: [Any], noMore: Bool) {
-        let count = networkArray.count
-        
-        if count > 0 {
-            if pageNum <= PAGENUM {
-                dataArray.removeAll()
-            }
-            dataArray.append(contentsOf: networkArray)
-            myReloadData()
-        } else if pageNum <= PAGENUM {
-            dataArray.removeAll()
-            myReloadData()
-        }
-        
-        if isUseMJRefresh {
-            if !noMore {
-                mj_footer?.resetNoMoreData()
-            } else {
-                mj_footer?.endRefreshingWithNoMoreData()
-            }
-            
-            if pageNum <= PAGENUM {
-                mj_header?.endRefreshing()
-            }
-        }
-    }
-    
-    func handleDataArray(_ networkArray: [Any]) {
-        handleDataArray(networkArray, noMore: networkArray.count < pageSize)
-    }
-    
-    func handleMJRefreshWithCount(_ count: Int) {
-        if count >= pageSize {
-            mj_footer?.resetNoMoreData()
-        } else {
-            mj_footer?.endRefreshingWithNoMoreData()
-        }
-        
-        if pageNum <= PAGENUM {
-            mj_header?.endRefreshing()
-        }
-    }
-    
-    func handleMJRefreshWithError(_ error: String) {
-        if pageNum <= PAGENUM {
-            mj_header?.endRefreshing()
-        } else {
-            mj_footer?.endRefreshing()
-        }
-    }
-    
-    // MARK: - Properties
-    
-    var isUseMJRefresh: Bool {
-        get { (objc_getAssociatedObject(self, &isMJRefreshKey) as? Bool) ?? false }
-        set { objc_setAssociatedObject(self, &isMJRefreshKey, newValue, .OBJC_ASSOCIATION_ASSIGN) }
-    }
-    
-    var pageNum: Int {
-        get { (objc_getAssociatedObject(self, &pageNumKey) as? Int) ?? PAGENUM }
-        set { objc_setAssociatedObject(self, &pageNumKey, newValue, .OBJC_ASSOCIATION_ASSIGN) }
-    }
-    
-    var pageSize: Int {
-        get { (objc_getAssociatedObject(self, &pageSizeKey) as? Int) ?? PAGESIZE }
-        set { objc_setAssociatedObject(self, &pageSizeKey, newValue, .OBJC_ASSOCIATION_ASSIGN) }
-    }
-    
-    var dataArray: [Any] {
-        get { (objc_getAssociatedObject(self, &dataArrayKey) as? [Any]) ?? [] }
-        set { objc_setAssociatedObject(self, &dataArrayKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) }
-    }
-}

+ 0 - 49
AIEmoji/Common/Ex/UIColor+Ex.swift

@@ -1,49 +0,0 @@
-//
-//  UIColor+Ex.swift
-//  TSLiveWallpaper
-//
-//  Created by 100Years on 2024/12/20.
-//
-
-import UIKit
-import SwiftUI
-extension UIColor {
-    /// 返回一个随机颜色
-    static var random: UIColor {
-        return UIColor(
-            red: CGFloat.random(in: 0...1),
-            green: CGFloat.random(in: 0...1),
-            blue: CGFloat.random(in: 0...1),
-            alpha: 1.0
-        )
-    }
-    
-    static func fromHex(_ hex: String, alpha: CGFloat = 1.0) -> UIColor {
-        var cleanedHex = hex.trimmingCharacters(in: .whitespacesAndNewlines).uppercased()
-        
-        // Remove leading "#" if present
-        if cleanedHex.hasPrefix("#") {
-            cleanedHex.removeFirst()
-        }
-        
-        // Ensure valid hex length
-        guard cleanedHex.count == 6 else {
-            return UIColor.clear // Return clear color for invalid input
-        }
-        
-        // Extract RGB components
-        var rgbValue: UInt64 = 0
-        Scanner(string: cleanedHex).scanHexInt64(&rgbValue)
-        
-        let red = CGFloat((rgbValue & 0xFF0000) >> 16) / 255.0
-        let green = CGFloat((rgbValue & 0x00FF00) >> 8) / 255.0
-        let blue = CGFloat(rgbValue & 0x0000FF) / 255.0
-        
-        return UIColor(red: red, green: green, blue: blue, alpha: alpha)
-    }
-    
-    var color: Color {
-        return Color(self)
-    }
-
-}

+ 0 - 110
AIEmoji/Common/Ex/UIDevice+Extension.swift

@@ -1,110 +0,0 @@
-//
-//  UIDevice+Extension.swift
-//  Example
-//
-//  Created by Slience on 2021/1/13.
-//
-
-import UIKit
-
-extension UIDevice {
-    class var isPortrait: Bool {
-        if isPad {
-            return true
-        }
-        if  statusBarOrientation == .landscapeLeft ||
-                statusBarOrientation == .landscapeRight {
-            return false
-        }
-        return true
-    }
-    class var statusBarOrientation: UIInterfaceOrientation {
-        UIApplication.shared.statusBarOrientation
-    }
-    class var navigationBarHeight: CGFloat {
-        if isPad {
-            if #available(iOS 12, *) {
-                return statusBarHeight + 50
-            }
-        }
-        return statusBarHeight + 44
-    }
-    class var generalStatusBarHeight: CGFloat {
-        isAllIPhoneX ? 44 : 20
-    }
-    class var statusBarHeight: CGFloat {
-        let statusBarHeight: CGFloat
-        let window = UIApplication.shared.windows.first
-        if #available(iOS 13.0, *),
-           let height = window?.windowScene?.statusBarManager?.statusBarFrame.size.height {
-            statusBarHeight = height
-        } else {
-            statusBarHeight = UIApplication.shared.statusBarFrame.size.height
-        }
-        return statusBarHeight
-    }
-    class var topMargin: CGFloat {
-        if isAllIPhoneX {
-            return statusBarHeight
-        }
-        return safeAreaInsets.top
-    }
-    class var leftMargin: CGFloat {
-        safeAreaInsets.left
-    }
-    class var rightMargin: CGFloat {
-        safeAreaInsets.right
-    }
-    class var bottomMargin: CGFloat {
-        safeAreaInsets.bottom
-    }
-    class var isPad: Bool {
-        current.userInterfaceIdiom == .pad
-    }
-    class var isAllIPhoneX: Bool {
-        let safeArea = safeAreaInsets
-        let margin: CGFloat
-        if isPortrait {
-            margin = safeArea.bottom
-        }else {
-            margin = safeArea.left
-        }
-        return margin != 0
-    }
-    
-    class var safeAreaInsets: UIEdgeInsets {
-        if #available(iOS 11.0, *) {
-            return UIApplication._keyWindow?.safeAreaInsets ?? .zero
-        }
-        return .zero
-    }
-    
-    class var screenSize: CGSize {
-        if #available(iOS 14.0, *), ProcessInfo.processInfo.isiOSAppOnMac {
-            return UIApplication._keyWindow?.frame.size ?? UIScreen.main.bounds.size
-        }
-        return UIScreen.main.bounds.size
-    }
-}
-
-extension UIApplication {
-    class var _keyWindow: UIWindow? {
-        var window: UIWindow?
-        if #available(iOS 13.0, *) {
-            window = shared.windows.filter({ $0.isKeyWindow }).last
-        } else {
-            window = shared.delegate?.window ?? shared.keyWindow
-        }
-        return window
-    }
-}
-
-
-extension UIDevice {
-    
-    
-    class func copyImage(image:UIImage) {
-        UIPasteboard.general.image = image
-    }
-    
-}

+ 0 - 66
AIEmoji/Common/Ex/UIFont+Ex.swift

@@ -1,66 +0,0 @@
-//
-//  UIFont+Ex.swift
-//  TSLiveWallpaper
-//
-//  Created by 100Years on 2024/12/20.
-//
-
-typealias FontName = String
-
-extension FontName {
-    static let PingFangSC           = "PingFangSC"
-}
-
-
-extension UIFont {
-    class func font(name: FontName = .PingFangSC, size: CGFloat, weight: UIFont.Weight = .regular) -> UIFont {
-        guard !name.isEmpty,
-                let _ = UIFont(name: name, size: size) else {
-            return UIFont.systemFont(ofSize: size, weight: weight)
-        }
-        var finalFontName = name
-        
-        let fontNames = UIFont.fontNames(forFamilyName: name)
-        switch weight {
-        case .light://细体 300
-            if let aName = fontNames.first(where: { $0.lowercased().hasSuffix("-light") || $0.lowercased().hasSuffix("_light") }) {
-                finalFontName = aName
-            }
-        case .medium://中黑体 500
-            if let aName = fontNames.first(where: { $0.lowercased().hasSuffix("-medium") || $0.lowercased().hasSuffix("_medium") }) {
-                finalFontName = aName
-            }
-        case .bold:// 粗体 700
-            if let aName = fontNames.first(where: { $0.lowercased().hasSuffix("-bold") || $0.lowercased().hasSuffix("_bold") }) {
-                finalFontName = aName
-            }
-        case .semibold://半粗体 600
-            if let aName = fontNames.first(where: { $0.lowercased().hasSuffix("-semibold") || $0.lowercased().hasSuffix("_semibold") }) {
-                finalFontName = aName
-            }
-        case .heavy: //粗黑体 800
-            if let aName = fontNames.first(where: { $0.lowercased().hasSuffix("-heavy") || $0.lowercased().hasSuffix("_heavy") }) {
-                finalFontName = aName
-            }
-        case .black: // 黑体 900
-            if let aName = fontNames.first(where: { $0.lowercased().hasSuffix("-black") || $0.lowercased().hasSuffix("_black") }) {
-                finalFontName = aName
-            }
-        default:
-            break
-        }
-        
-        return UIFont(name: finalFontName, size: size)!
-    }
-}
-extension UIFont {
-    
-    /// 返回该字体下,对应字符的宽度
-    /// - Parameter word: 字符
-    /// - Returns: 宽度
-    func widthForWord(_ word: String) -> CGFloat {
-        
-        let sizeWidth = (word as NSString).size(withAttributes: [.font: self]).width
-        return sizeWidth//.rounded(.up)
-    }
-}

+ 0 - 130
AIEmoji/Common/Ex/UIImage+Ex.swift

@@ -1,130 +0,0 @@
-//
-//  UIImage+Ex.swift
-//  TSLiveWallpaper
-//
-//  Created by 100Years on 2024/12/23.
-//
-
-
-extension UIImage {
-    
-    var width: CGFloat { size.width }
-    var height: CGFloat { size.height }
-    
-    func normalizedImage() -> UIImage? {
-        if imageOrientation == .up {
-            return self
-        }
-        return repaintImage()
-    }
-    func repaintImage() -> UIImage? {
-        let format = UIGraphicsImageRendererFormat()
-        format.opaque = false
-        format.scale = scale
-        let renderer = UIGraphicsImageRenderer(size: size, format: format)
-        let image = renderer.image { context in
-            draw(in: CGRect(x: 0, y: 0, width: size.width, height: size.height))
-        }
-        return image
-    }
-
-    func scaleToFillSize(size: CGSize, mode: UIView.ContentMode = .scaleToFill, scale: CGFloat = 0) -> UIImage? {
-        if __CGSizeEqualToSize(self.size, size) {
-            return self
-        }
-        let rect: CGRect
-        let rendererSize: CGSize
-        if mode == .scaleToFill {
-            let isEqualRatio = size.width / size.height == width / height
-            if isEqualRatio {
-                rendererSize = size
-                rect = CGRect(origin: .zero, size: size)
-            }else {
-                let scale = size.width / width
-                var scaleHeight = scale * height
-                var scaleWidth = size.width
-                if scaleHeight < size.height {
-                    scaleWidth = size.height / scaleHeight * size.width
-                    scaleHeight = size.height
-                }
-                rendererSize = .init(width: scaleWidth, height: scaleHeight)
-                rect = .init(origin: .zero, size: rendererSize)
-            }
-        }else {
-            rendererSize = size
-            if mode == .scaleAspectFit {
-                rect = CGRect(origin: .zero, size: size)
-            }else {
-                var x: CGFloat = 0
-                var y: CGFloat = 0
-                let scale = size.width / width
-                var scaleWidth = size.width
-                var scaleHeight = scale * height
-                if scaleHeight < size.height {
-                    scaleWidth = size.height / scaleHeight * scaleWidth
-                    scaleHeight = size.height
-                }
-                if scaleWidth < size.width {
-                    scaleHeight = size.width / scaleWidth * scaleHeight
-                    scaleWidth = size.width
-                }
-                x = -(scaleWidth - size.width) / 2
-                y = -(scaleHeight - size.height) / 2
-                rect = CGRect(
-                    x: x,
-                    y: y,
-                    width: scaleWidth,
-                    height: scaleHeight
-                )
-            }
-        }
-        let format = UIGraphicsImageRendererFormat()
-        format.opaque = false
-        format.scale = scale == 0 ? self.scale : scale
-        let renderer = UIGraphicsImageRenderer(size: rendererSize, format: format)
-        let image = renderer.image { context in
-            draw(in: rect)
-        }
-        return image
-    }
-    
-    
-    var pngImage:UIImage?{
-        // 将 UIImage 转为 PNG Data
-        guard let pngData = self.pngData() else {
-            print("Failed to convert WebP image to PNG data.")
-            return nil
-        }
-        
-        // 使用 PNG Data 创建新的 UIImage
-        return UIImage(data: pngData)
-    }
-}
-
-
-extension UIImage {
-    /// 将颜色转换为 UIImage
-    /// - Parameters:
-    ///   - color: 目标颜色
-    ///   - size: 图片尺寸(默认 1x1)
-    /// - Returns: 转换后的 UIImage
-    static func colorFrom(color: UIColor, size: CGSize = CGSize(width: 1, height: 1)) -> UIImage? {
-        // 创建一个矩形
-        let rect = CGRect(origin: .zero, size: size)
-        
-        // 开始图形上下文
-        UIGraphicsBeginImageContextWithOptions(size, false, 0)
-        
-        // 设置颜色填充
-        color.setFill()
-        UIRectFill(rect)
-        
-        // 获取生成的图片
-        let image = UIGraphicsGetImageFromCurrentImageContext()
-        
-        // 结束图形上下文
-        UIGraphicsEndImageContext()
-        
-        return image
-    }
-}

+ 0 - 124
AIEmoji/Common/Ex/UIImageView+Ex.swift

@@ -1,124 +0,0 @@
-//
-//  UIImageView+Ex.swift
-//  TSLiveWallpaper
-//
-//  Created by 100Years on 2024/12/20.
-//
-import Kingfisher
-extension UIImageView {
-
-    /// 创建并配置 UIImageView
-    /// - Parameters:
-    ///   - imageName: 图片名称
-    ///   - contentMode: 内容模式,默认为 `.scaleAspectFit`
-    ///   - backgroundColor: 背景颜色,默认为透明
-    /// - Returns: 配置完成的 UIImageView 实例
-    static func createImageView(imageName: String,
-                                contentMode: UIView.ContentMode = .scaleAspectFit,
-                                backgroundColor: UIColor = .clear,
-                                corner: CGFloat = 0.0) -> UIImageView {
-        let imageView = UIImageView()
-        imageView.image = UIImage(named: imageName)
-        imageView.contentMode = contentMode
-        imageView.backgroundColor = backgroundColor
-        imageView.cornerRadius = corner
-        return imageView
-    }
-    
-    /// 异步创建并加载图片的 UIImageView
-    /// - Parameters:
-    ///   - imageName: 本地占位图片名称
-    ///   - urlString: 图片的 URL 字符串
-    ///   - contentMode: 内容模式,默认为 `.scaleAspectFit`
-    ///   - backgroundColor: 背景颜色,默认为透明
-    ///   - showLoading: 是否显示加载动画,默认为 `true`
-    ///   - completion: 图片加载成功后的回调
-    static func createAsyncImageView(urlString: String?,
-                                     placeholder:UIImage?,
-                                     contentMode: UIView.ContentMode = .scaleAspectFit,
-                                     backgroundColor: UIColor = .clear,
-                                     showLoading: Bool = false,
-                                     completion: ((UIImage?) -> Void)? = nil) -> UIImageView {
-        let imageView = UIImageView()
-        imageView.setAsyncImage(urlString: urlString,
-                                placeholder:placeholder,
-                                contentMode:contentMode,
-                                backgroundColor:backgroundColor,
-                                showLoading:showLoading,
-                                completion:completion)
-        return imageView
-    }
-
-    
-    
-    func setAsyncImage(urlString: String?,
-                     placeholder: UIImage? = nil,
-                     contentMode: UIView.ContentMode = .scaleAspectFit,
-                 backgroundColor: UIColor = .clear,
-                       showLoading: Bool = false,
-                      completion: ((UIImage?) -> Void)? = nil){
-        let imageView = self
-        imageView.contentMode = contentMode
-        imageView.backgroundColor = backgroundColor
-        
-        guard let urlString = urlString, let url = URL(string: urlString) else {
-            completion?(nil)
-            return
-        }
-        
-
-        if urlString.contains("http") {
-            kf.indicatorType = showLoading ? .activity : .none
-            imageView.kf.setImage(with: url,
-                 placeholder: placeholder,
-                     options: nil,
-               progressBlock: nil) { result in
-                
-                if let image = try? result.get().image {
-                    kDelayMainShort {
-                        completion?(image)
-                    }
-                }else{
-                    completion?(nil)
-                }
-            }
-            
-        }else if urlString.contains("/") {
-            imageView.image = placeholder
-            imageView.image = UIImage(contentsOfFile: urlString.fillCachePath)
-        }else {
-            imageView.image = placeholder
-            if let image = UIImage(named: urlString) {
-                imageView.image = image
-            }
-        }
-    }
-
-}
-
-extension UIImageView {
-    
-    static func createRightArrow() -> UIImageView {
-        let imageView = UIImageView()
-        imageView.image = UIImage(named: "white_right_arrow")
-        return imageView
-    }
-}
-
-extension UIImageView {
-    func setImage(_ image: UIImage?, duration: CFTimeInterval = 0.2, animated: Bool = true) {
-        if let image = image {
-            if animated {
-                UIView.transition(
-                    with: self,
-                    duration: duration,
-                    options: [.transitionCrossDissolve, .curveEaseInOut, .allowUserInteraction]
-                ) {
-                    self.image = image
-                }
-            }else {
-                self.image = image
-            }
-        }
-    }
-}

+ 0 - 88
AIEmoji/Common/Ex/UILabel+Ex.swift

@@ -1,88 +0,0 @@
-//
-//  UILabel+Ex.swift
-//  TSLiveWallpaper
-//
-//  Created by 100Years on 2024/12/20.
-//
-
-extension UILabel {
-    /// 快速创建 UILabel
-    /// - Parameters:
-    ///   - text: 文本内容
-    ///   - font: 字体
-    ///   - textColor: 文本颜色
-    ///   - textAlignment: 文本对齐方式
-    ///   - numberOfLines: 行数,默认 1
-    ///   - backgroundColor: 背景颜色
-    ///   - adjustsFontSizeToFitWidth: 是否自适应宽度,默认 false
-    ///   - cornerRadius: 圆角,默认 0
-    /// - Returns: 配置好的 UILabel 实例
-    static func createLabel(text: String? = nil,
-                            font: UIFont? = nil,
-                            textColor: UIColor? = nil,
-                            textAlignment: NSTextAlignment = .left,
-                            numberOfLines: Int = 1,
-                            backgroundColor: UIColor? = nil,
-                            adjustsFontSizeToFitWidth: Bool = false,
-                            cornerRadius: CGFloat = 0) -> UILabel {
-        let label = UILabel()
-        
-        // 设置文本内容
-        label.text = text
-        
-        // 设置字体
-        if let font = font {
-            label.font = font
-        }
-        
-        // 设置文本颜色
-        if let textColor = textColor {
-            label.textColor = textColor
-        }
-        
-        // 设置文本对齐方式
-        label.textAlignment = textAlignment
-        
-        // 设置行数
-        label.numberOfLines = numberOfLines
-        
-        // 设置背景颜色
-        if let backgroundColor = backgroundColor {
-            label.backgroundColor = backgroundColor
-        }
-        
-        // 设置是否自适应宽度
-        label.adjustsFontSizeToFitWidth = adjustsFontSizeToFitWidth
-        
-        // 设置圆角
-        if cornerRadius > 0 {
-            label.layer.cornerRadius = cornerRadius
-            label.layer.masksToBounds = true
-        }
-        
-        return label
-    }
-}
-
-
-
-extension UILabel {
-    var textHeight: CGFloat {
-        if let textHeight = text?.height(ofFont: font, maxWidth: width > 0 ? width : .max) {
-            return textHeight
-        }
-        return 0
-    }
-    var textWidth: CGFloat {
-        if let textWidth = text?.width(ofFont: font, maxHeight: height > 0 ? height : .max) {
-            return textWidth
-        }
-        return 0
-    }
-    var textSize: CGSize {
-        if let textSize = text?.size(ofFont: font, maxWidth: .max, maxHeight: .max) {
-            return textSize
-        }
-        return .zero
-    }
-}

+ 0 - 43
AIEmoji/Common/Ex/UIScreen.swift

@@ -1,43 +0,0 @@
-//
-//  UIScreen.swift
-//  TSLiveWallpaper
-//
-//  Created by 100Years on 2024/12/23.
-//
-
-extension UIScreen {
-    
-    static var _scale: CGFloat {
-        if #available(iOS 13.0, *), Thread.isMainThread,
-           let scale = UIApplication._keyWindow?.windowScene?.screen.scale {
-            return scale
-        }
-        return main.scale
-    }
-    
-    static var _width: CGFloat {
-        if #available(iOS 13.0, *), Thread.isMainThread,
-           let width = UIApplication._keyWindow?.windowScene?.screen.bounds.width {
-            return width
-        }
-        return main.bounds.width
-    }
-    
-    static var _height: CGFloat {
-        if #available(iOS 13.0, *), Thread.isMainThread,
-           let height = UIApplication._keyWindow?.windowScene?.screen.bounds.height {
-            return height
-        }
-        return main.bounds.height
-    }
-    
-    static var _size: CGSize {
-        if #available(iOS 13.0, *), Thread.isMainThread,
-           let size = UIApplication._keyWindow?.windowScene?.screen.bounds.size {
-            return size
-        }
-        return main.bounds.size
-    }
-    
-}
-

+ 0 - 195
AIEmoji/Common/Ex/UITableView+Ex.swift

@@ -1,195 +0,0 @@
-//
-//  UITableView+Ex.swift
-//  TSLiveWallpaper
-//
-//  Created by 100Years on 2024/12/20.
-//
-
-import UIKit
-import MJRefresh
-
-private var isMJRefreshKey = "isMJRefreshKey"
-private var pageNumKey = "pageNumKey"
-private var pageSizeKey = "pageSizeKey"
-private var nullDataImageViewKey = "nullDataImageViewKey"
-private var dataArrayKey = "dataArrayKey"
-
-private let PAGESIZE = 10
-private let PAGENUM = 1
-
-extension UITableView {
-    // MARK: - Properties
-    
-    var isUseMJRefresh: Bool {
-        get { objc_getAssociatedObject(self, &isMJRefreshKey) as? Bool ?? false }
-        set { objc_setAssociatedObject(self, &isMJRefreshKey, newValue, .OBJC_ASSOCIATION_ASSIGN) }
-    }
-
-    var pageNum: Int {
-        get { objc_getAssociatedObject(self, &pageNumKey) as? Int ?? PAGENUM }
-        set { objc_setAssociatedObject(self, &pageNumKey, newValue, .OBJC_ASSOCIATION_ASSIGN) }
-    }
-
-    var pageSize: Int {
-        get { objc_getAssociatedObject(self, &pageSizeKey) as? Int ?? PAGESIZE }
-        set { objc_setAssociatedObject(self, &pageSizeKey, newValue, .OBJC_ASSOCIATION_ASSIGN) }
-    }
-
-    var nullDataImageView: UIImageView? {
-        get { objc_getAssociatedObject(self, &nullDataImageViewKey) as? UIImageView }
-        set { objc_setAssociatedObject(self, &nullDataImageViewKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) }
-    }
-
-    var dataArray: [Any] {
-        get { objc_getAssociatedObject(self, &dataArrayKey) as? [Any] ?? [] }
-        set { objc_setAssociatedObject(self, &dataArrayKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) }
-    }
-
-    // MARK: - Methods
-    
-    func myReloadData() {
-        reloadData()
-        guard let dataSource = dataSource else { return }
-        var isEmpty = true
-        let sections = (dataSource.responds(to: #selector(UITableViewDataSource.numberOfSections(in:))) ? dataSource.numberOfSections?(in: self) : 1) ?? 1
-
-        for section in 0..<sections {
-            if dataSource.tableView(self, numberOfRowsInSection: section) > 0 {
-                isEmpty = false
-                break
-            }
-        }
-
-        if isEmpty {
-            if nullDataImageView == nil {
-                let nullImage = UIImage(named: "nullDataImageView") ?? UIImage()
-                let w = nullImage.size.width
-                let h = nullImage.size.height
-                nullDataImageView = UIImageView(frame: CGRect(x: (bounds.width - w) / 2, y: (bounds.height - h) / 2, width: w, height: h))
-                nullDataImageView?.image = nullImage
-                if let nullDataImageView = nullDataImageView {
-                    addSubview(nullDataImageView)
-                }
-            }
-        } else {
-            nullDataImageView?.removeFromSuperview()
-            nullDataImageView = nil
-        }
-    }
-
-    func handleDataArray(_ networkArray: [Any]) {
-        let count = networkArray.count
-
-        if count > 0 {
-            if pageNum <= PAGENUM {
-                dataArray.removeAll()
-            }
-            dataArray.append(contentsOf: networkArray)
-            myReloadData()
-        } else if pageNum <= PAGENUM {
-            dataArray.removeAll()
-            myReloadData()
-        }
-
-        if isUseMJRefresh {
-            handleMJRefresh(count: count)
-        }
-    }
-
-    func addFooter(refreshingBlock: @escaping () -> Void) {
-        isUseMJRefresh = true
-        mj_footer = MJRefreshAutoNormalFooter(refreshingBlock: { [weak self] in
-            self?.pageNum += 1
-            refreshingBlock()
-        })
-    }
-
-    func addHeader(refreshingBlock: @escaping () -> Void) {
-        isUseMJRefresh = true
-        mj_header = MJRefreshNormalHeader(refreshingBlock: { [weak self] in
-            self?.pageNum = PAGENUM
-            refreshingBlock()
-        })
-    }
-
-    func handleMJRefresh(count: Int) {
-        if count >= pageSize {
-            mj_footer?.resetNoMoreData()
-        } else {
-            mj_footer?.endRefreshingWithNoMoreData()
-        }
-
-        if pageNum <= PAGENUM {
-            mj_header?.endRefreshing()
-        } else {
-            mj_footer?.endRefreshing()
-        }
-    }
-
-    func handleMJRefreshWithError(_ error: String?) {
-        if pageNum <= PAGENUM {
-            mj_header?.endRefreshing()
-        } else {
-            mj_footer?.endRefreshing()
-        }
-    }
-
-    func initBaseTableView(reuseXib cellIds: [String], isUseMJRefresh: Bool, delegate: UITableViewDelegate & UITableViewDataSource) {
-        setUpTableView()
-        self.isUseMJRefresh = isUseMJRefresh
-        self.delegate = delegate
-        self.dataSource = delegate
-
-        cellIds.forEach { cellId in
-            register(UINib(nibName: cellId, bundle: nil), forCellReuseIdentifier: cellId)
-        }
-    }
-
-    func initBaseTableView(reuseClass cellIds: [String], isUseMJRefresh: Bool, delegate: UITableViewDelegate & UITableViewDataSource) {
-        setUpTableView()
-        self.isUseMJRefresh = isUseMJRefresh
-        self.delegate = delegate
-        self.dataSource = delegate
-
-        registerCellClass(cellIds: cellIds)
-    }
-    
-    func registerCellClass(cellIds:[String]) {
-        cellIds.forEach { cellId in
-            if let cellClass = cellId.toClass() {
-                self.register(cellClass, forCellReuseIdentifier: cellId)
-            }
-        }
-    }
-
-    private func setUpTableView() {
-        if #available(iOS 11.0, *) {
-            contentInsetAdjustmentBehavior = .never
-        }
-
-        if #available(iOS 15.0, *) {
-            sectionHeaderTopPadding = 0
-        }
-
-        separatorStyle = .none
-        backgroundColor = .clear
-
-        pageNum = PAGENUM
-        pageSize = PAGESIZE
-        dataArray = []
-
-        estimatedRowHeight = 0
-        estimatedSectionHeaderHeight = 0
-        estimatedSectionFooterHeight = 0
-
-        showsVerticalScrollIndicator = false
-        showsHorizontalScrollIndicator = false
-        
-        
-        backgroundColor = .clear
-
-        if tableFooterView == nil {
-            tableFooterView = UIView(frame: CGRect(x: 0, y: 0, width: 0, height: CGFLOAT_MIN))
-        }
-    }
-}

+ 0 - 7
AIEmoji/Common/Ex/UITextView+Ex.swift

@@ -1,7 +0,0 @@
-//
-//  UITextView+Ex.swift
-//  AIEmoji
-//
-//  Created by 100Years on 2025/1/16.
-//
-

+ 0 - 319
AIEmoji/Common/Ex/UIView+Ex.swift

@@ -1,319 +0,0 @@
-//
-//  View+Ex.swift
-//  TSLiveWallpaper
-//
-//  Created by 100Years on 2024/12/20.
-//
-
-
-import UIKit
-
-extension UIView {
-    
-    @IBInspectable
-    var cornerRadius: CGFloat {
-        set {
-            clipsToBounds = true
-            layer.cornerRadius = newValue
-        }
-        get {
-            layer.cornerRadius
-        }
-    }
-    
-    @IBInspectable
-    var borderWidth: CGFloat {
-        set {
-            layer.borderWidth = newValue
-        }
-        get {
-            layer.borderWidth
-        }
-    }
-    
-    @IBInspectable
-    var borderColor: UIColor? {
-        set {
-            layer.borderColor = newValue?.cgColor
-        }
-        get {
-            if let cgColor = layer.borderColor {
-                return UIColor(cgColor: cgColor)
-            }
-            return nil
-        }
-    }
-    
-    
-    /// 增加渐变背景,需要先确定当前 view 的 frame
-    /// - Parameters:
-    ///   - colors: 渐变背景颜色数组
-    ///   - startPoint: 渐变启示位置
-    ///   - endPoint: 渐变结束位置
-    ///   - layerSize: 指定 layer 的 size,否则和自己当前一样大
-    func addGradientBg(colors: [CGColor],
-                       startPoint: CGPoint = .zero,
-                       endPoint: CGPoint = CGPoint(x: 1, y: 1),
-                       layerSize: CGSize? = nil) {
-        let gl = CAGradientLayer()
-        gl.colors = colors
-        gl.startPoint = startPoint
-        gl.endPoint = endPoint
-        gl.frame = CGRect(origin: .zero, size: layerSize ?? self.bounds.size)
-        layer.insertSublayer(gl, at: 0)
-    }
-    
-    /// 慎用
-    /// 给 view 增加圆角阴影,会改变视图结构,慎用,
-    /// 需add 且确定frame后再调用
-    /// > Note: 慎用
-    /// - Parameters:
-    ///   - cornerRadius: 视图圆角
-    ///   - shadowColor: 阴影颜色
-    ///   - shadowOffset: 阴影偏移量
-    ///   - shadowRadius: 阴影扩散距离
-    ///   - shadowOpacity: 阴影透明度
-    @discardableResult
-    func addCornerRadiusShadow(cornerRadius: CGFloat,
-                               shadowColor: CGColor?,
-                               shadowOffset: CGSize,
-                               shadowRadius: CGFloat,
-                               shadowOpacity: Float) -> UIView? {
-        guard let supView = superview else {
-            debugPrint("必须要先add,且确定了frame")
-            return nil
-        }
-        
-        let frame = self.frame
-        
-        let shadowView = UIView()
-        shadowView.frame = frame
-        shadowView.layer.shadowColor = shadowColor
-        shadowView.layer.shadowOffset = shadowOffset
-        shadowView.layer.shadowOpacity = shadowOpacity
-        shadowView.layer.shadowRadius = shadowRadius
-        
-        supView.insertSubview(shadowView, belowSubview: self)
-        
-        shadowView.addSubview(self)
-        self.frame = CGRect(origin: .zero, size: frame.size)
-        self.clipsToBounds = false
-        self.layer.masksToBounds = true
-        self.layer.cornerRadius = cornerRadius
-        
-        return shadowView
-        
-    }
-}
-
-
-
-public extension UIScreen {
-    static let size = {
-        UIScreen.main.bounds.size
-    }()
-    
-    static var width: CGFloat {
-        return size.width
-    }
-    
-    static var height: CGFloat {
-        return size.height
-    }
-}
-
-// Frame
-public extension UIView {
-    var x: CGFloat {
-        set {
-            frame.origin.x = newValue
-        }
-        get {
-            return frame.origin.x
-        }
-    }
-    
-    var y: CGFloat {
-        set {
-            frame.origin.y = newValue
-        }
-        get {
-            return frame.origin.y
-        }
-    }
-    
-    var width: CGFloat {
-        set {
-            frame.size.width = newValue
-        }
-        get {
-            return frame.size.width
-        }
-    }
-    
-    var height: CGFloat {
-        set {
-            frame.size.height = newValue
-        }
-        get {
-            return frame.size.height
-        }
-    }
-    
-    var size: CGSize {
-        get { frame.size }
-        set {
-            var rect = frame
-            rect.size = newValue
-            frame = rect
-        }
-    }
-    
-    var centerX: CGFloat {
-        set {
-            let newCenter = CGPoint(x: newValue, y: center.y)
-            center = newCenter
-        }
-        get {
-            return center.x
-        }
-    }
-    
-    var centerY: CGFloat {
-        set {
-            let newCenter = CGPoint(x: center.x, y: newValue)
-            center = newCenter
-        }
-        get {
-            return center.y
-        }
-    }
-    
-    var bottom: CGFloat {
-        get {
-            return frame.origin.y + frame.size.height
-        }
-    }
-    
-    var viewController: UIViewController? {
-        var next = superview
-        while next != nil {
-            let nextResponder = next?.next
-            if nextResponder is UINavigationController ||
-                nextResponder is UIViewController {
-                return nextResponder as? UIViewController
-            }
-            next = next?.superview
-        }
-        return nil
-    }
-    
-    func convertedToImage(rect: CGRect = .zero) -> UIImage? {
-        var size = bounds.size
-        var origin = bounds.origin
-        if !size.equalTo(rect.size) && !rect.isEmpty {
-            size = rect.size
-            origin = CGPoint(x: -rect.minX, y: -rect.minY)
-        }
-        let format = UIGraphicsImageRendererFormat()
-        format.opaque = false
-        format.scale = UIScreen._scale
-        let renderer = UIGraphicsImageRenderer(size: size, format: format)
-        let image = renderer.image { context in
-            drawHierarchy(in: CGRect(origin: origin, size: bounds.size), afterScreenUpdates: true)
-        }
-        return image
-    }
-
-    func toImage() -> UIImage? {
-        let renderer = UIGraphicsImageRenderer(bounds: self.bounds)
-        let image = renderer.image { context in
-            self.layer.render(in: context.cgContext)
-        }
-        return image
-    }
-    
-    func cornersRound(radius: CGFloat, corner: UIRectCorner) {
-        if #available(iOS 11.0, *) {
-            layer.cornerRadius = radius
-            layer.maskedCorners = corner.mask
-        } else {
-            let path = UIBezierPath(
-                roundedRect: bounds,
-                byRoundingCorners: corner,
-                cornerRadii: CGSize(width: radius, height: radius)
-            )
-            let mask = CAShapeLayer()
-            mask.path = path.cgPath
-            layer.mask = mask
-        }
-    }
-}
-
-extension UIRectCorner {
-    var mask: CACornerMask {
-        switch self {
-        case .allCorners:
-            return [.layerMinXMinYCorner, .layerMinXMaxYCorner, .layerMaxXMinYCorner, .layerMaxXMaxYCorner]
-        default:
-            return .init(rawValue: rawValue)
-        }
-    }
-}
-
-public extension UIView {
-    // 部分圆角(必须Frame已知)
-    func makeCorner(_ corners: UIRectCorner, radius: CGFloat) {
-        let path = UIBezierPath(roundedRect: bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
-        let maskLayer = CAShapeLayer()
-        maskLayer.frame = bounds
-        maskLayer.path = path.cgPath
-        layer.mask = maskLayer
-    }
-}
-
-extension UIView {
-    /// 为视图添加高斯模糊效果
-    /// - Parameters:
-    ///   - blurRadius: 模糊半径(默认 10.0)
-    ///   - fillColor: 填充颜色(可选,默认透明)
-    func applyGaussianBlur(blurRadius: CGFloat = 10.0, fillColor: UIColor? = nil) {
-        // 移除已有的模糊效果
-        self.removeBlurEffect()
-        
-        // 创建模糊效果
-        let blurEffect = UIBlurEffect(style: .light)
-        let blurView = UIVisualEffectView(effect: blurEffect)
-        blurView.frame = self.bounds
-        blurView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
-        
-        // 设置模糊强度
-        if blurRadius != 10.0 {
-            let blurAnimator = CABasicAnimation(keyPath: "inputRadius")
-            blurAnimator.fromValue = blurRadius
-            blurAnimator.toValue = blurRadius
-            blurAnimator.duration = 0
-            blurView.layer.add(blurAnimator, forKey: nil)
-        }
-        
-        // 如果指定了填充颜色,添加一个覆盖视图
-        if let color = fillColor {
-            let colorOverlay = UIView(frame: self.bounds)
-            colorOverlay.backgroundColor = color
-            colorOverlay.autoresizingMask = [.flexibleWidth, .flexibleHeight]
-            colorOverlay.isUserInteractionEnabled = false
-            blurView.contentView.addSubview(colorOverlay)
-        }
-        
-        self.addSubview(blurView)
-    }
-    
-    /// 移除模糊效果
-    func removeBlurEffect() {
-        for subview in subviews {
-            if subview is UIVisualEffectView {
-                subview.removeFromSuperview()
-            }
-        }
-    }
-}

+ 0 - 54
AIEmoji/Common/Ex/UIViewController+Ex.swift

@@ -1,54 +0,0 @@
-//
-//  UIViewController+Ex.swift
-//  TSLiveWallpaper
-//
-//  Created by 100Years on 2024/12/30.
-//
-
-extension UIViewController {
-    func showCustomAlert(
-        title: String? = "",
-        message: String?,
-        deleteHandler: (() -> Void)? = nil,
-        cancelHandler: (() -> Void)? = nil
-    ) {
-        let alert = UIAlertController(title: nil, message: nil, preferredStyle: .alert)
-        
-        // 自定义标题
-        if let title = title {
-            let titleAttributes: [NSAttributedString.Key: Any] = [
-                .font: UIFont.boldSystemFont(ofSize: 20),
-                .foregroundColor: UIColor.white
-            ]
-            let attributedTitle = NSAttributedString(string: title, attributes: titleAttributes)
-            alert.setValue(attributedTitle, forKey: "attributedTitle")
-        }
-        
-        // 自定义消息
-        if let message = message {
-            let messageAttributes: [NSAttributedString.Key: Any] = [
-                .font: UIFont.boldSystemFont(ofSize: 17),
-                .foregroundColor: UIColor.white
-            ]
-            let attributedMessage = NSAttributedString(string: message, attributes: messageAttributes)
-            alert.setValue(attributedMessage, forKey: "attributedMessage")
-        }
-        
-        // 添加按钮
-        let cancelAction = UIAlertAction(title: "Cancel".localized, style: .cancel) { _ in
-            cancelHandler?()
-        }
-        alert.addAction(cancelAction)
-        
-        let deleteAction = UIAlertAction(title: "Delete".localized, style: .destructive) { _ in
-            deleteHandler?()
-        }
-        alert.addAction(deleteAction)
-        
-        // 设置黑暗模式
-        alert.overrideUserInterfaceStyle = .dark
-        
-        // 显示弹窗
-        present(alert, animated: true, completion: nil)
-    }
-}

+ 0 - 30
AIEmoji/Common/Ex/UserDefault+Ex.swift

@@ -1,30 +0,0 @@
-//
-//  UserDefault+Ex.swift
-//  TSLiveWallpaper
-//
-//  Created by 100Years on 2024/12/30.
-//
-
-import Foundation
-
-@propertyWrapper
-struct UserDefault<T> {
-    let key: String
-    let defaultValue: T
-    let storage: UserDefaults
-
-    init(key: String, defaultValue: T, storage: UserDefaults = .standard) {
-        self.key = key
-        self.defaultValue = defaultValue
-        self.storage = storage
-    }
-
-    var wrappedValue: T {
-        get {
-            return storage.object(forKey: key) as? T ?? defaultValue
-        }
-        set {
-            storage.set(newValue, forKey: key)
-        }
-    }
-}

+ 12 - 3
AIEmoji/Common/GlobalImports/GlobalImports.swift

@@ -6,9 +6,9 @@
 //
 
 //@_exported import Foundation
-@_exported import UIKit
-@_exported import SnapKit
-
+//@_exported import UIKit
+//@_exported import SnapKit
+@_exported import TSSmalCoacopods
 import AVFoundation
 
 func k_Height_statusBar() -> CGFloat {
@@ -146,3 +146,12 @@ func kPushVC(target:UIViewController,modelVC:UIViewController){
     modelVC.hidesBottomBarWhenPushed = true
     target.navigationController?.pushViewController(modelVC, animated: true)
 }
+
+
+extension String {
+    
+    var localized:String {
+        return self
+    }
+    
+}

+ 0 - 302
AIEmoji/Common/View/UICollectionView+Component/CollectionViewComponent.swift

@@ -1,302 +0,0 @@
-//
-//  CollectionViewComponent.swift
-//  ClockWidget
-//
-//  Created by TSYH on 2023/7/18.
-//
-
-import UIKit
-
-
-
-let kIndexPath = "kIndexPath"
-
-public class CollectionView: UICollectionView {
-    lazy var reuseSubviews: [String: UIView] = [:]
-    
-    func cacheReuseView(_ view: UIView, reuseId: String?) {
-        guard let reuseId = reuseId, !reuseId.isEmpty else {
-            return
-        }
-        reuseSubviews[reuseId] = view
-    }
-    
-    func dequeueReuseSubviews(for reuseId: String?) -> UIView? {
-        guard let reuseId = reuseId, !reuseId.isEmpty else {
-            return nil
-        }
-        return reuseSubviews[reuseId]
-    }
-    
-    func clearReuseSubviews() {
-        reuseSubviews.removeAll()
-    }
-}
-
-public class CollectionViewComponent: NSObject {
-    
-    var sectionActionHandler: ((Any?, IndexPath) -> Void)?
-
-    var itemDidSelectedHandler: ((Any?, IndexPath) -> Void)?
-    var itemActionHandler: ((Any?, IndexPath) -> Void)?
-    
-    var itemWillDisplayHandler: ((UICollectionViewCell, Any?, IndexPath) -> Void)?
-    var itemDidEndDisplayingHandler: ((UICollectionViewCell, Any?, IndexPath) -> Void)?
-    
-    var didScrollHandler: ((UIScrollView) -> Void)?
-    var willBeginDraggingHandler: ((UIScrollView) -> Void)?
-    var didEndDraggingHandler: ((UIScrollView, Bool) -> Void)?
-    var didScrollToTopHandler: ((UIScrollView) -> Void)?
-    var willEndDraggingWithVelocityHandler: ((UIScrollView, CGPoint) -> Void)?
-    var didEndDeceleratingHandler: ((UIScrollView) -> Void)?
-    
-    var collectionView: CollectionView!
-    var attributes: [String: Any]?
-    
-    
-    
-    
-    
-    static let defaultCellID: String = "Component_Default_Cell_ID"
-    init(frame: CGRect, layout: UICollectionViewFlowLayout? = nil, attributes: [String: Any]? = nil) {
-        super.init()
-        
-        var clLayout = UICollectionViewFlowLayout()
-        if let direction = attributes?["direction"] as? UICollectionView.ScrollDirection {
-            clLayout.scrollDirection = direction
-        }
-        
-        if let layout = layout {
-            clLayout = layout
-        }
-        collectionView = CollectionView(frame: frame, collectionViewLayout: clLayout)
-        collectionView.delegate = self
-        collectionView.dataSource = self
-        collectionView.contentInsetAdjustmentBehavior = .never
-        collectionView.showsVerticalScrollIndicator = false
-        collectionView.showsHorizontalScrollIndicator = false
-        collectionView.backgroundColor = .clear
-        
-        self.attributes = attributes
-        if let showScrollIndicator = attributes?["showScrollIndicator"] as? Bool {
-            collectionView.showsHorizontalScrollIndicator = showScrollIndicator
-        }
-        
-        collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: Self.defaultCellID)
-    }
-    
-    lazy var dataSource = [Component]()
-    func clear() {
-        dataSource = []
-    }
-    
-    func reloadView(with components: [Component]) {
-        registerClass(components: components)
-        dataSource.append(contentsOf: components)
-        collectionView.clearReuseSubviews()
-        collectionView.reloadData()
-    }
-    
-    func reloadData() {
-        collectionView.clearReuseSubviews()
-        collectionView.reloadData()
-    }
-    
-    // 注册cell
-    private func registerClass(components: [Component]) {
-        for cp in components {
-            if let sectionCp = cp as? CollectionViewSectionComponent {
-                if let header = sectionCp.headerComponent {
-                    collectionView.register(header.viewClass, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: header.reuseIdentifier)
-                }
-                if let footer = sectionCp.footerComponent {
-                    collectionView.register(footer.viewClass, forSupplementaryViewOfKind: UICollectionView.elementKindSectionFooter, withReuseIdentifier: footer.reuseIdentifier)
-                }
-                for cellCp in sectionCp.cells {
-                    collectionView.register(cellCp.cellClass, forCellWithReuseIdentifier: cellCp.cellClass.description())
-                }
-            } else if let cellCp = cp as? CollectionViewCellComponent {
-                collectionView.register(cellCp.cellClass, forCellWithReuseIdentifier: cellCp.cellClass.description())
-            }
-        }
-    }
-}
-
-extension CollectionViewComponent {
-    private var isSectionFramework: Bool {
-        if dataSource.first is CollectionViewSectionComponent {
-            return true
-        }
-        return false
-    }
-    
-    func cellComponent(at indexPath: IndexPath) -> CollectionViewCellComponent? {
-        var cellCp: Component?
-        if isSectionFramework {
-            if indexPath.section < dataSource.count,
-                let sectionCp = dataSource[indexPath.section] as? CollectionViewSectionComponent,
-                indexPath.item < sectionCp.cells.count {
-                cellCp = sectionCp.cells[indexPath.item]
-            }
-        } else if indexPath.item < dataSource.count {
-            cellCp = dataSource[indexPath.item]
-        }
-        if let cellCp = cellCp as? CollectionViewCellComponent {
-            return cellCp
-        }
-        return nil
-    }
-}
-
-extension CollectionViewComponent: UICollectionViewDataSource {
-    
-    public func numberOfSections(in collectionView: UICollectionView) -> Int {
-        if isSectionFramework {
-            return dataSource.count
-        }
-        return 1
-    }
-    
-    public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
-        if isSectionFramework {
-            if section < dataSource.count {
-                return (dataSource[section] as? CollectionViewSectionComponent)?.cells.count ?? 0
-            }
-            return 0
-        }
-        return dataSource.count
-    }
-    
-    public func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
-        itemWillDisplayHandler?(cell, cellComponent(at: indexPath), indexPath)
-    }
-    
-    public func collectionView(_ collectionView: UICollectionView, didEndDisplaying cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
-        itemDidEndDisplayingHandler?(cell, cellComponent(at: indexPath), indexPath)
-    }
-    
-    public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
-        guard let cellCp = cellComponent(at: indexPath) else {
-            return collectionView.dequeueReusableCell(withReuseIdentifier: Self.defaultCellID, for: indexPath)
-        }
-        
-        let cellClass = cellCp.cellClass
-        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellClass.description(), for: indexPath)
-        if let cell = cell as? ComponentView {
-            var atts = attributes ?? [:]
-            atts[kIndexPath] = indexPath
-            cell.renderView(with: cellCp, component: self, attributes: atts)
-        }
-        return cell
-    }
-    
-    public func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
-        guard let sectionCp = dataSource[indexPath.section] as? CollectionViewSectionComponent else {
-            return UICollectionReusableView()
-        }
-        if kind == UICollectionView.elementKindSectionHeader {
-            if let headerCp = sectionCp.headerComponent {
-                let header = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: headerCp.reuseIdentifier, for: indexPath)
-                if let headerView = header as? ComponentView {
-                    var atts = attributes ?? [:]
-                    atts[kIndexPath] = indexPath
-                    headerView.renderView(with: headerCp, component: self, attributes: atts)
-                }
-                return header
-            }
-        } else if kind == UICollectionView.elementKindSectionFooter {
-            if let footerCp = sectionCp.headerComponent {
-                let footer = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: footerCp.reuseIdentifier, for: indexPath)
-                if let footerView = footer as? ComponentView {
-                    var atts = attributes ?? [:]
-                    atts[kIndexPath] = indexPath
-                    footerView.renderView(with: footerCp, component: self, attributes: atts)
-                }
-                return footer
-            }
-        }
-        return UICollectionReusableView()
-    }
-}
-
-extension CollectionViewComponent: UICollectionViewDelegateFlowLayout {
-    public func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
-        guard let cellCp = cellComponent(at: indexPath) else {
-            return .zero
-        }
-        return cellCp.cellSize(with: attributes)
-    }
-    
-    public func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
-        if isSectionFramework {
-            if section < dataSource.count {
-                return (dataSource[section] as? CollectionViewSectionComponent)?.sectionInset ?? .zero
-            }
-        }
-        return UIEdgeInsets(top: 10, left: 16, bottom: 10, right: 16)
-    }
-    
-    public func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
-        if section < dataSource.count {
-            return (dataSource[section] as? CollectionViewSectionComponent)?.lineSpacing ?? 12.0
-        }
-        return 12.0
-    }
-    
-    public func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
-        if section < dataSource.count {
-            return (dataSource[section] as? CollectionViewSectionComponent)?.itemSpacing ?? 12.0
-        }
-        return 12.0
-    }
-    
-    public func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForFooterInSection section: Int) -> CGSize {
-        if isSectionFramework {
-            if section < dataSource.count,
-                let sectionCp = dataSource[section] as? CollectionViewSectionComponent {
-                return sectionCp.footerComponent?.viewSize ?? .zero
-            }
-        }
-        return .zero
-    }
-    
-    public func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
-        if isSectionFramework {
-            if section < dataSource.count,
-                let sectionCp = dataSource[section] as? CollectionViewSectionComponent {
-                return sectionCp.headerComponent?.viewSize ?? .zero
-            }
-        }
-        return .zero
-    }
-}
-
-extension CollectionViewComponent: UICollectionViewDelegate {
-    public func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
-        itemDidSelectedHandler?(cellComponent(at: indexPath), indexPath)
-    }
-    
-    public func scrollViewDidScroll(_ scrollView: UIScrollView) {
-        didScrollHandler?(scrollView)
-    }
-    
-    public func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
-        willEndDraggingWithVelocityHandler?(scrollView, velocity)
-    }
-    
-    public func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
-        willBeginDraggingHandler?(scrollView)
-    }
-    
-    public func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
-        didEndDraggingHandler?(scrollView, decelerate)
-    }
-    
-    public func scrollViewDidScrollToTop(_ scrollView: UIScrollView) {
-        didScrollToTopHandler?(scrollView)
-    }
-    
-    public func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
-        didEndDeceleratingHandler?(scrollView)
-    }
-}

+ 0 - 63
AIEmoji/Common/View/UICollectionView+Component/CommonSectionComponent.swift

@@ -1,63 +0,0 @@
-//
-//  CommonSectionComponent.swift
-//  ClockWidget
-//
-//  Created by TSYH on 2023/10/17.
-//
-
-import UIKit
-
-class CommonSectionComponent: CollectionViewSectionComponent {
-    var cellComponents: [CollectionViewCellComponent]
-    var header: CollectionViewReuseViewComponent?
-    var footer: CollectionViewReuseViewComponent?
-    var inset: UIEdgeInsets
-    var rowSpacing: CGFloat
-    var columnSpacing: CGFloat
-    
-    init(cellComponents: [CollectionViewCellComponent],
-         header: CollectionViewReuseViewComponent? = nil,
-         footer: CollectionViewReuseViewComponent? = nil,
-         inset: UIEdgeInsets = .zero,
-         rowSpacing: CGFloat = 10.0,
-         columnSpacing: CGFloat = 10.0) {
-        self.cellComponents = cellComponents
-        self.header = header
-        self.footer = footer
-        self.inset = inset
-        self.rowSpacing = rowSpacing
-        self.columnSpacing = columnSpacing
-    }
-    
-    var cells: [CollectionViewCellComponent] {
-        return cellComponents
-    }
-    
-    var headerComponent: CollectionViewReuseViewComponent? {
-        return header
-    }
-    
-    var footerComponent: CollectionViewReuseViewComponent? {
-        return footer
-    }
-    
-    func clear() {
-        cellComponents.removeAll()
-    }
-    
-    func append(_ cellComponents: [CollectionViewCellComponent]) {
-        self.cellComponents.append(contentsOf: cellComponents)
-    }
-   
-    var sectionInset: UIEdgeInsets {
-        return inset
-    }
-    
-    var lineSpacing: CGFloat {
-        return rowSpacing
-    }
-    
-    var itemSpacing: CGFloat {
-        return columnSpacing
-    }
-}

+ 0 - 64
AIEmoji/Common/View/UICollectionView+Component/Component.swift

@@ -1,64 +0,0 @@
-//
-//  Component.swift
-//  ClockWidget
-//
-//  Created by TSYH on 2023/10/7.
-//
-
-import UIKit
-
-public protocol Component {}
-
-public protocol ComponentView {
-    // UI 渲染
-    func renderView(with object: Any?, component: CollectionViewComponent, attributes: [String: Any]?)
-}
-
-public protocol CollectionViewSectionComponent: Component {
-    var cells: [CollectionViewCellComponent] { get }
-    var headerComponent: CollectionViewReuseViewComponent? { get }
-    var footerComponent: CollectionViewReuseViewComponent? { get }
-    var sectionInset: UIEdgeInsets { get }
-    var lineSpacing: CGFloat { get }
-    var itemSpacing: CGFloat { get }
-}
-
-extension CollectionViewSectionComponent {
-    var headerComponent: CollectionViewReuseViewComponent? { return nil }
-    var footerComponent: CollectionViewReuseViewComponent? { return nil }
-    
-    var sectionInset: UIEdgeInsets {
-        return UIEdgeInsets(top: 10, left: 16, bottom: 10, right: 16)
-    }
-    
-    var lineSpacing: CGFloat {
-        return 12.0
-    }
-    
-    var itemSpacing: CGFloat {
-        return 12.0
-    }
-}
-
-public enum CollectionViewReuseViewType {
-    case header
-    case footer
-}
-
-public protocol CollectionViewReuseViewComponent: Component {
-    var viewClass: UICollectionReusableView.Type { get }
-    var viewType: CollectionViewReuseViewType { get }
-    var viewSize: CGSize { get }
-    var reuseIdentifier: String { get }
-}
-
-extension CollectionViewReuseViewComponent {
-    var reuseIdentifier: String{
-        return viewClass.description()
-    }
-}
-
-public protocol CollectionViewCellComponent: Component {
-    var cellClass: UICollectionViewCell.Type { get }
-    func cellSize(with attrubites: [String: Any]?) -> CGSize
-}

+ 0 - 164
AIEmoji/Common/View/UICollectionView+Component/UICollectionView+More.swift

@@ -1,164 +0,0 @@
-//
-//  UICollectionView+More.swift
-//  ClockWidget
-//
-//  Created by TSYH on 2023/10/7.
-//
-
-import UIKit
-import MJRefresh
-
-//extension UICollectionView {
-//    func addRefresh(handler: (() -> Void)?) {
-//        let header = MJRefreshNormalHeader {
-//            handler?()
-//        }
-//        header.lastUpdatedTimeLabel?.isHidden = true
-//        header.stateLabel?.isHidden = true
-//        header.setTitle("", for: .idle)
-//        mj_header = header
-//    }
-//    
-//    func addLoadMore(handler: (() -> Void)?) {
-//        let footer = MJRefreshAutoNormalFooter {
-//            handler?()
-//        }
-//        footer.isRefreshingTitleHidden = true
-//        footer.setTitle("", for: .idle)
-//        footer.height = 30
-//        mj_footer = footer
-//    }
-//    
-//    public override func endRefreshing(noMore: Bool = false) {
-//        mj_header?.endRefreshing()
-//        if noMore {
-//            mj_footer?.endRefreshingWithNoMoreData()
-//            (mj_footer as? MJRefreshAutoNormalFooter)?.stateLabel?.isHidden = true
-//            (mj_footer as? FeedBackRefreshFooter)?.shouldShowFeedback = true
-//        } else {
-//            mj_footer?.endRefreshing()
-//            (mj_footer as? MJRefreshAutoNormalFooter)?.stateLabel?.isHidden = false
-//            (mj_footer as? FeedBackRefreshFooter)?.shouldShowFeedback = false
-//        }
-//    }
-//}
-//
-//// Feedback footer
-//extension UICollectionView {
-//    func addFeedbackLoadMore(feedbackText: String?, handler: (() -> Void)?) {
-//        let footer = FeedBackRefreshFooter {
-//            handler?()
-//        }
-//        footer.feedbackText = feedbackText
-//        footer.isRefreshingTitleHidden = true
-//        footer.setTitle("", for: .idle)
-//        footer.height = 68
-//        mj_footer = footer
-//    }
-//}
-//
-//// Feedback footer
-//extension UITableView {
-//    func addFeedbackLoadMore(feedbackText: String?, handler: (() -> Void)?) {
-//        let footer = FeedBackRefreshFooter {
-//            handler?()
-//        }
-//        footer.feedbackText = feedbackText
-//        footer.isRefreshingTitleHidden = true
-//        footer.setTitle("", for: .idle)
-//        footer.height = 68
-//        mj_footer = footer
-//    }
-//}
-
-//class FeedBackRefreshFooter: MJRefreshAutoNormalFooter {
-////    lazy var feedbackView = FooterFeedBackView()
-//    
-//    var feedbackText: String? {
-//        didSet {
-//            feedbackView.feedbackText = feedbackText
-//        }
-//    }
-//    
-//    override init(frame: CGRect) {
-//        super.init(frame: frame)
-//        
-//        feedbackView.isHidden = true
-//        addSubview(feedbackView)
-//        feedbackView.snp.makeConstraints { make in
-//            make.leading.top.trailing.equalToSuperview()
-//            make.height.equalTo(68)
-//        }
-//    }
-//    
-//    required init?(coder: NSCoder) {
-//        fatalError("init(coder:) has not been implemented")
-//    }
-//    
-//    var shouldShowFeedback: Bool = false {
-//        didSet {
-//            feedbackView.isHidden = !shouldShowFeedback
-//        }
-//    }
-//}
-
-//class FooterFeedBackView: UIView {
-//    lazy var textLabel = UILabel()
-//    lazy var actionButton = UIButton()
-//    lazy var feedbackLabel = UILabel()
-//    lazy var arrowImageView = UIImageView()
-//    
-//    var feedbackText: String?
-//    
-//    override init(frame: CGRect) {
-//        super.init(frame: frame)
-//        
-//        backgroundColor = .clear
-//        addSubview(textLabel)
-//        addSubview(actionButton)
-//        actionButton.addSubview(feedbackLabel)
-//        actionButton.addSubview(arrowImageView)
-//        textLabel.snp.makeConstraints { make in
-//            make.centerX.equalToSuperview()
-//            make.centerY.equalToSuperview().offset(-14)
-//        }
-//        actionButton.snp.makeConstraints { make in
-//            make.centerX.equalToSuperview()
-//            make.centerY.equalToSuperview().offset(10)
-//            make.height.equalTo(20)
-//        }
-//        feedbackLabel.snp.makeConstraints { make in
-//            make.leading.equalTo(8)
-//            make.centerY.equalToSuperview()
-//        }
-//        arrowImageView.snp.makeConstraints { make in
-//            make.leading.equalTo(feedbackLabel.snp.trailing).offset(4)
-//            make.trailing.equalTo(-4)
-//            make.centerY.equalToSuperview()
-//            make.width.height.equalTo(12)
-//        }
-//        
-//        textLabel.text = "Didn't find liked?".localization()
-//        textLabel.textColor = UIColor.textDisable
-//        textLabel.font = UIFont.font(name: .Poppins, size: 12)
-//        
-//        feedbackLabel.isUserInteractionEnabled = false
-//        feedbackLabel.text = "Feedback".localization()
-//        feedbackLabel.textColor = UIColor.textAssist
-//        feedbackLabel.font = UIFont.font(name: .Poppins, size: 12)
-//        arrowImageView.image = UIImage(named: "c_arrow_right")?.mirrored()
-//        arrowImageView.isUserInteractionEnabled = false
-//        
-//        actionButton.backgroundColor = "#F3F4F7".toColor()
-//        actionButton.cornerRadius = 10
-//        actionButton.addTarget(self, action: #selector(buttonClick(_:)), for: .touchUpInside)
-//    }
-//    
-//    required init?(coder: NSCoder) {
-//        fatalError("init(coder:) has not been implemented")
-//    }
-//    
-//    @objc func buttonClick(_ sender: UIButton) {
-//        UIApplication.shared.openEmail(from: feedbackText ?? "Widget")
-//    }
-//}

+ 0 - 76
AIEmoji/Common/View/UITableView+TSItemModel/TSSimpleTableView.swift

@@ -1,76 +0,0 @@
-//
-//  TSTableView.swift
-//  TSLiveWallpaper
-//
-//  Created by 100Years on 2025/1/4.
-//
-
-
-
-class TSSimpleTableView : NSObject{
-
-    lazy var tableView:UITableView = {
-        let tableView = UITableView()
-        tableView.initBaseTableView(reuseClass: reuseClass, isUseMJRefresh: false, delegate: self)
-        return tableView
-    }()
-    
-    var reuseClass:[String] = [] {
-        didSet{
-            tableView.registerCellClass(cellIds: reuseClass)
-        }
-    }
-    
-    var dataArray:[TSBasicSectionModel] = [TSBasicSectionModel](){
-        didSet{
-            tableView.reloadData()
-        }
-    }
-
-}
-
-
-extension TSSimpleTableView : UITableViewDataSource, UITableViewDelegate {
-    
-    func numberOfSections(in tableView: UITableView) -> Int {
-        return dataArray.count
-    }
-    
-    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
-        if let sectionModel = dataArray.safeObj(At: section){
-            return sectionModel.itemsArray.count
-        }
-        return 0
-    }
-    
-    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
-        if let sectionModel = dataArray.safeObj(At: indexPath.section),let itemModel = sectionModel.itemsArray.safeObj(At: indexPath.row){
-            return itemModel.height
-        }
-        return 0
-    }
-    
-    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
-        let cell = tableView.dequeueReusableCell(withIdentifier: "TSMineCell")!
-        
-        if let cell = cell as? TSSimpleTableViewCell {
-            if let sectionModel = dataArray.safeObj(At: indexPath.section),let itemModel = sectionModel.itemsArray.safeObj(At: indexPath.row){
-                cell.itemModel = itemModel
-            }
-        }
-        
-        return cell
-    }
-    
-    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
-        if let sectionModel = dataArray.safeObj(At: indexPath.section),let itemModel = sectionModel.itemsArray.safeObj(At: indexPath.row){
-            itemModel.tapBlock?(itemModel,indexPath.row,nil)
-        }
-    }
-}
-
-
-class TSSimpleTableViewCell: TSBaseTabViewCell {
-    var itemModel:TSBasicItemModel = TSBasicItemModel()
- 
-}

+ 19 - 20
AIEmoji/DataManger/Config/TSConfig.swift

@@ -4,18 +4,18 @@
 //
 //  Created by 100Years on 2024/12/20.
 //
-class TSConfig: NSObject {
-    static let appLanguage: String = {
-        let systemLanguages = UserDefaults.standard.value(forKey: "AppleLanguages")
-        var currentLanguage: String?
-        if let arr = systemLanguages as? [String] {
-            currentLanguage = arr.first
-        }
-        else if let str = systemLanguages as? String {
-            currentLanguage = str
-        }
-        return currentLanguage ?? ""
-    }()
+//class TSConfig: NSObject {
+//    static let appLanguage: String = {
+//        let systemLanguages = UserDefaults.standard.value(forKey: "AppleLanguages")
+//        var currentLanguage: String?
+//        if let arr = systemLanguages as? [String] {
+//            currentLanguage = arr.first
+//        }
+//        else if let str = systemLanguages as? String {
+//            currentLanguage = str
+//        }
+//        return currentLanguage ?? ""
+//    }()
 //    
 //    static let appLanguageShort: String? = {
 //        let currentLanguage = Bundle.main.preferredLocalizations.first
@@ -54,18 +54,17 @@ class TSConfig: NSObject {
 //        let localeId = Locale.current.identifier
 //        return localeId.contains("_CN")
 //    }
-    
-    static let appid = "6740220736" 
-
-}
-
+//    
+//    static let appid = "6740220736" 
+//
+//}
 
 extension UIColor {
     /// 背景色
-    static let mainBg = "#07080C".color
+    static let mainBg = "#07080C".uiColor
     
     /// 主色调
-    static let themeColor = "#FECB34".color
+    static let themeColor = "#FECB34".uiColor
     
     static let naviMianBgColor = UIColor.clear
     static let naviMianTextColor = UIColor.white.withAlphaComponent(0.8)
@@ -91,7 +90,7 @@ extension UIColor {
     static let success = UIColor(named: "c_success")!
     
     /// 辅助色
-    static let assist = "#111111".color
+    static let assist = "#111111".uiColor
     
     /// 按钮色
     static let button = UIColor(named: "c_button")!

+ 1 - 1
Podfile

@@ -21,7 +21,7 @@ target 'AIEmoji' do
   pod 'SwiftyMarkdown'
   pod 'RealmSwift', '~>10'
   pod 'SwipeCellKit'
-#  pod 'TSSmalCoacopods', :path => '../TSSmalCoacopods'
+  pod 'TSSmalCoacopods', :path => '../TSSmalCoacopods'
 end
 
 

+ 12 - 1
Podfile.lock

@@ -57,6 +57,11 @@ PODS:
   - SVProgressHUD/Core (2.3.1)
   - SwiftyMarkdown (1.2.4)
   - SwipeCellKit (2.7.1)
+  - TSSmalCoacopods (0.1.0):
+    - Alamofire (= 5.6.4)
+    - Kingfisher (= 7.10.0)
+    - ObjectMapper (~> 4.2)
+    - SnapKit
 
 DEPENDENCIES:
   - Alamofire (= 5.6.4)
@@ -72,6 +77,7 @@ DEPENDENCIES:
   - SVProgressHUD
   - SwiftyMarkdown
   - SwipeCellKit
+  - TSSmalCoacopods (from `../TSSmalCoacopods`)
 
 SPEC REPOS:
   trunk:
@@ -97,6 +103,10 @@ SPEC REPOS:
     - SwiftyMarkdown
     - SwipeCellKit
 
+EXTERNAL SOURCES:
+  TSSmalCoacopods:
+    :path: "../TSSmalCoacopods"
+
 SPEC CHECKSUMS:
   Alamofire: 4e95d97098eacb88856099c4fc79b526a299e48c
   IQKeyboardCore: 28c8bf3bcd8ba5aa1570b318cbc4da94b861711e
@@ -119,7 +129,8 @@ SPEC CHECKSUMS:
   SVProgressHUD: 4837c74bdfe2e51e8821c397825996a8d7de6e22
   SwiftyMarkdown: 7cdec87c6ab5cd9ea0e22ced288e889960649ba5
   SwipeCellKit: 3972254a826da74609926daf59b08d6c72e619ea
+  TSSmalCoacopods: d143fb37412626673d129359e55eb263a7c7de1d
 
-PODFILE CHECKSUM: 2affa4be0aabb44f2aef33dbf27a56e7e3259a25
+PODFILE CHECKSUM: 4bfa06c906b32ca1142731b283277c078647da9c
 
 COCOAPODS: 1.16.2