瀏覽代碼

Merge branch 'main' into 音频剪辑

* main:
  1.7(5)打包上架
  1.7(4)
  1.7(3)打包测试
  修复1.7(1)bug
  1.7(1)打包
  1.6(3)打包
  1.修复1.6(2)bug 2.解决通知 block 的循环引用 3.解决 cell 左滑删除代理循环引用问题
  修复 ai铃声首页高度适配问题

# Conflicts:
#	AIRingtone/Business/TSAIRintoneVC/TSAIRintoneVC/TSAIRintoneVC.swift
#	AIRingtone/Business/TSAIRintoneVC/TSAIRintoneVC/View/TSAIRintoneHistoryCell.swift
#	AIRingtone/Business/TSAIRintoneVC/TSGenerateHistoryVC/TSGenerateHistoryVC.swift
#	AIRingtone/Business/TSDiscoverVC/TSRingDownVC/TSRingDownVC.swift
#	AIRingtone/Business/TSThemeVC/TSThemeBrowseVC/TSThemeBrowseVC.swift
#	AIRingtone/Common/Tool/TSBandRingTool/TSBandRingTool.swift
100Years 2 周之前
父節點
當前提交
27ea8c2811
共有 52 個文件被更改,包括 248 次插入161 次删除
  1. 4 4
      AIRingtone.xcodeproj/project.pbxproj
  2. 9 0
      AIRingtone/AppDelegate.swift
  3. 22 0
      AIRingtone/Assets.xcassets/Discover/square_bottom_shadow.imageset/Contents.json
  4. 二進制
      AIRingtone/Assets.xcassets/Discover/square_bottom_shadow.imageset/discovercell_shadow@2x.png
  5. 二進制
      AIRingtone/Assets.xcassets/Discover/square_bottom_shadow.imageset/discovercell_shadow@3x.png
  6. 22 0
      AIRingtone/Assets.xcassets/Discover/square_top_shadow.imageset/Contents.json
  7. 二進制
      AIRingtone/Assets.xcassets/Discover/square_top_shadow.imageset/square_top_shadow@2x.png
  8. 二進制
      AIRingtone/Assets.xcassets/Discover/square_top_shadow.imageset/square_top_shadow@3x.png
  9. 二進制
      AIRingtone/Assets.xcassets/Launch/bootPage_0.imageset/bootPage_0@2x.png
  10. 二進制
      AIRingtone/Assets.xcassets/Launch/bootPage_0.imageset/bootPage_0@3x.png
  11. 二進制
      AIRingtone/Assets.xcassets/Launch/bootPage_1.imageset/bootPage_1@2x.png
  12. 二進制
      AIRingtone/Assets.xcassets/Launch/bootPage_1.imageset/bootPage_1@3x.png
  13. 2 2
      AIRingtone/Assets.xcassets/Launch/bootPage_2.imageset/Contents.json
  14. 二進制
      AIRingtone/Assets.xcassets/Launch/bootPage_2.imageset/bootPage_1@2x.png
  15. 二進制
      AIRingtone/Assets.xcassets/Launch/bootPage_2.imageset/bootPage_1@3x.png
  16. 二進制
      AIRingtone/Assets.xcassets/Launch/bootPage_2.imageset/bootPage_2@2x.png
  17. 二進制
      AIRingtone/Assets.xcassets/Launch/bootPage_2.imageset/bootPage_2@3x.png
  18. 二進制
      AIRingtone/Assets.xcassets/Tabbar/tabbar_select_discover.imageset/tabbar_select_discover@2x.png
  19. 二進制
      AIRingtone/Assets.xcassets/Tabbar/tabbar_select_discover.imageset/tabbar_select_discover@3x.png
  20. 二進制
      AIRingtone/Assets.xcassets/Tabbar/tabbar_unSelect_discover.imageset/tabbar_unSelect_discover@2x.png
  21. 二進制
      AIRingtone/Assets.xcassets/Tabbar/tabbar_unSelect_discover.imageset/tabbar_unSelect_discover@3x.png
  22. 二進制
      AIRingtone/Assets.xcassets/VIP/listIcon/vip_ads.imageset/vip_ads@2x.png
  23. 二進制
      AIRingtone/Assets.xcassets/VIP/listIcon/vip_ads.imageset/vip_ads@3x.png
  24. 二進制
      AIRingtone/Assets.xcassets/VIP/listIcon/vip_photo.imageset/vip_photo@2x.png
  25. 二進制
      AIRingtone/Assets.xcassets/VIP/listIcon/vip_photo.imageset/vip_photo@3x.png
  26. 二進制
      AIRingtone/Assets.xcassets/VIP/listIcon/vip_pic.imageset/vip_pic@2x.png
  27. 二進制
      AIRingtone/Assets.xcassets/VIP/listIcon/vip_pic.imageset/vip_pic@3x.png
  28. 二進制
      AIRingtone/Assets.xcassets/VIP/listIcon/vip_ringtone.imageset/vip_ringtone@2x.png
  29. 二進制
      AIRingtone/Assets.xcassets/VIP/listIcon/vip_ringtone.imageset/vip_ringtone@3x.png
  30. 二進制
      AIRingtone/Assets.xcassets/VIP/upvote_black.imageset/upvote_black@2x.png
  31. 二進制
      AIRingtone/Assets.xcassets/VIP/upvote_black.imageset/upvote_black@3x.png
  32. 2 70
      AIRingtone/Business/LaunchVC/TSBootPageVC.swift
  33. 2 1
      AIRingtone/Business/TSAIPhotoVC/TSAIPhotoChildVC/TSAIPhotoChildVC.swift
  34. 2 1
      AIRingtone/Business/TSAIPhotoVC/TSAIPhotoVC.swift
  35. 13 3
      AIRingtone/Business/TSAIPhotoVC/TSTextGeneralPicVC/View/TSPromptStyleView.swift
  36. 16 7
      AIRingtone/Business/TSAIRintoneVC/TSAIRintoneVC/TSAIRintoneVC.swift
  37. 0 1
      AIRingtone/Business/TSAIRintoneVC/TSAIRintoneVC/View/TSAIRintoneHistoryCell.swift
  38. 18 16
      AIRingtone/Business/TSAIRintoneVC/TSGeneralRintoneVC/TSGeneralRintoneVC+Event.swift
  39. 14 6
      AIRingtone/Business/TSAIRintoneVC/TSGeneralRintoneVC/TSGeneralRintoneVC.swift
  40. 9 6
      AIRingtone/Business/TSAIRintoneVC/TSGenerateHistoryVC/TSGenerateHistoryVC.swift
  41. 11 8
      AIRingtone/Business/TSAIRintoneVC/TSTextGeneralRintoneVC/TSTextGeneralRintoneVC.swift
  42. 14 2
      AIRingtone/Business/TSDiscoverVC/TSDiscoverVC/View/TSDiscoverCell.swift
  43. 54 20
      AIRingtone/Business/TSPurchaseMembershipVC/TSPurchaseVC.swift
  44. 1 1
      AIRingtone/Business/TSSetingVC/SetingVC/TSSetingModel.swift
  45. 8 3
      AIRingtone/Business/TSSetingVC/SetingVC/TSSetingVC.swift
  46. 2 2
      AIRingtone/Business/TSTabBarController/TSTabBarController.swift
  47. 0 1
      AIRingtone/Business/TSThemeVC/TSThemeBrowseVC/TSThemeBrowseVC.swift
  48. 1 1
      AIRingtone/Business/VIewTool/TSRingLoadingView.swift
  49. 2 1
      AIRingtone/Business/VIewTool/TSRingToneCellView.swift
  50. 2 1
      AIRingtone/Common/Purchase/TSPurchaseManager/TSPurchaseTool.swift
  51. 6 0
      AIRingtone/Common/Tool/OperationQueue/TSGenerateBaseOperation/TSGenerateRintoneOperation.swift
  52. 12 4
      AIRingtone/Common/Tool/TSBandRingTool/TSBandRingTool.swift

+ 4 - 4
AIRingtone.xcodeproj/project.pbxproj

@@ -1371,7 +1371,7 @@
 				ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
 				CLANG_ENABLE_MODULES = YES;
 				CODE_SIGN_STYLE = Automatic;
-				CURRENT_PROJECT_VERSION = 2;
+				CURRENT_PROJECT_VERSION = 5;
 				DEVELOPMENT_TEAM = 65UD255J84;
 				GENERATE_INFOPLIST_FILE = YES;
 				INFOPLIST_FILE = AIRingtone/Info.plist;
@@ -1390,7 +1390,7 @@
 					"$(inherited)",
 					"$(PROJECT_DIR)/AIRingtone/Common/Tool/TSBandRingTool/libmp3",
 				);
-				MARKETING_VERSION = 1.6;
+				MARKETING_VERSION = 1.7;
 				PRODUCT_BUNDLE_IDENTIFIER = ai.ringtones.com;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
@@ -1413,7 +1413,7 @@
 				ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
 				CLANG_ENABLE_MODULES = YES;
 				CODE_SIGN_STYLE = Automatic;
-				CURRENT_PROJECT_VERSION = 2;
+				CURRENT_PROJECT_VERSION = 5;
 				DEVELOPMENT_TEAM = 65UD255J84;
 				GENERATE_INFOPLIST_FILE = YES;
 				INFOPLIST_FILE = AIRingtone/Info.plist;
@@ -1432,7 +1432,7 @@
 					"$(inherited)",
 					"$(PROJECT_DIR)/AIRingtone/Common/Tool/TSBandRingTool/libmp3",
 				);
-				MARKETING_VERSION = 1.6;
+				MARKETING_VERSION = 1.7;
 				PRODUCT_BUNDLE_IDENTIFIER = ai.ringtones.com;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";

+ 9 - 0
AIRingtone/AppDelegate.swift

@@ -148,6 +148,15 @@ extension AppDelegate {
         }
     }
     
+    
+    static func setsTopDayPopPurchase() {
+        let currentDate = Date()
+        let dateFormatter = DateFormatter()
+        dateFormatter.dateFormat = "yyyyMMdd"
+        let currentDateString = dateFormatter.string(from: currentDate)
+        UserDefaults.standard.set(currentDateString, forKey: "kEveryDayPopPurchase")
+    }
+    
     func checkAppConfig(){
         _ = TSNetworkShared.get(urlType: .config) { data,error in
             

+ 22 - 0
AIRingtone/Assets.xcassets/Discover/square_bottom_shadow.imageset/Contents.json

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

二進制
AIRingtone/Assets.xcassets/Discover/square_bottom_shadow.imageset/discovercell_shadow@2x.png


二進制
AIRingtone/Assets.xcassets/Discover/square_bottom_shadow.imageset/discovercell_shadow@3x.png


+ 22 - 0
AIRingtone/Assets.xcassets/Discover/square_top_shadow.imageset/Contents.json

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

二進制
AIRingtone/Assets.xcassets/Discover/square_top_shadow.imageset/square_top_shadow@2x.png


二進制
AIRingtone/Assets.xcassets/Discover/square_top_shadow.imageset/square_top_shadow@3x.png


二進制
AIRingtone/Assets.xcassets/Launch/bootPage_0.imageset/bootPage_0@2x.png


二進制
AIRingtone/Assets.xcassets/Launch/bootPage_0.imageset/bootPage_0@3x.png


二進制
AIRingtone/Assets.xcassets/Launch/bootPage_1.imageset/bootPage_1@2x.png


二進制
AIRingtone/Assets.xcassets/Launch/bootPage_1.imageset/bootPage_1@3x.png


+ 2 - 2
AIRingtone/Assets.xcassets/Launch/bootPage_2.imageset/Contents.json

@@ -5,12 +5,12 @@
       "scale" : "1x"
     },
     {
-      "filename" : "bootPage_2@2x.png",
+      "filename" : "bootPage_1@2x.png",
       "idiom" : "universal",
       "scale" : "2x"
     },
     {
-      "filename" : "bootPage_2@3x.png",
+      "filename" : "bootPage_1@3x.png",
       "idiom" : "universal",
       "scale" : "3x"
     }

二進制
AIRingtone/Assets.xcassets/Launch/bootPage_2.imageset/bootPage_1@2x.png


二進制
AIRingtone/Assets.xcassets/Launch/bootPage_2.imageset/bootPage_1@3x.png


二進制
AIRingtone/Assets.xcassets/Launch/bootPage_2.imageset/bootPage_2@2x.png


二進制
AIRingtone/Assets.xcassets/Launch/bootPage_2.imageset/bootPage_2@3x.png


二進制
AIRingtone/Assets.xcassets/Tabbar/tabbar_select_discover.imageset/tabbar_select_discover@2x.png


二進制
AIRingtone/Assets.xcassets/Tabbar/tabbar_select_discover.imageset/tabbar_select_discover@3x.png


二進制
AIRingtone/Assets.xcassets/Tabbar/tabbar_unSelect_discover.imageset/tabbar_unSelect_discover@2x.png


二進制
AIRingtone/Assets.xcassets/Tabbar/tabbar_unSelect_discover.imageset/tabbar_unSelect_discover@3x.png


二進制
AIRingtone/Assets.xcassets/VIP/listIcon/vip_ads.imageset/vip_ads@2x.png


二進制
AIRingtone/Assets.xcassets/VIP/listIcon/vip_ads.imageset/vip_ads@3x.png


二進制
AIRingtone/Assets.xcassets/VIP/listIcon/vip_photo.imageset/vip_photo@2x.png


二進制
AIRingtone/Assets.xcassets/VIP/listIcon/vip_photo.imageset/vip_photo@3x.png


二進制
AIRingtone/Assets.xcassets/VIP/listIcon/vip_pic.imageset/vip_pic@2x.png


二進制
AIRingtone/Assets.xcassets/VIP/listIcon/vip_pic.imageset/vip_pic@3x.png


二進制
AIRingtone/Assets.xcassets/VIP/listIcon/vip_ringtone.imageset/vip_ringtone@2x.png


二進制
AIRingtone/Assets.xcassets/VIP/listIcon/vip_ringtone.imageset/vip_ringtone@3x.png


二進制
AIRingtone/Assets.xcassets/VIP/upvote_black.imageset/upvote_black@2x.png


二進制
AIRingtone/Assets.xcassets/VIP/upvote_black.imageset/upvote_black@3x.png


+ 2 - 70
AIRingtone/Business/LaunchVC/TSBootPageVC.swift

@@ -18,7 +18,7 @@ class TSBootPageVC: TSBaseVC {
         fatalError("init(coder:) has not been implemented")
     }
     var index:Int = 0
-    let titleStrings = ["Create Ringtones with AI".localized,"Thousands of Ringtones".localized,"Calling Theme Surprise You".localized]
+    let titleStrings = ["Hot TikTok Ringtones".localized,"Create Ringtones with AI".localized,"Discover 100,000+ Ringtones".localized]
     let imageStrings = ["bootPage_0","bootPage_1","bootPage_2"]
     
     
@@ -45,75 +45,6 @@ class TSBootPageVC: TSBaseVC {
         return continueBtn
     }()
     
-//    lazy var scrollView: UIScrollView = {
-//        let scrollView = UIScrollView()
-//        scrollView.isScrollEnabled = false
-//        scrollView.frame = self.view.bounds
-//
-//        let imageView0 = UIImageView.createImageView(imageName: "bootPage_0",contentMode: .scaleAspectFill)
-//        imageView0.frame = CGRectMake(0, 0, k_ScreenWidth, k_ScreenHeight)
-//        scrollView.addSubview(imageView0)
-//        
-//        let imageView1 = UIImageView.createImageView(imageName: "bootPage_1",contentMode: .scaleAspectFill)
-//        imageView1.frame = CGRectMake(k_ScreenWidth, 0, k_ScreenWidth, k_ScreenHeight)
-//        scrollView.addSubview(imageView1)
-//        
-//        let imageView2 = UIImageView.createImageView(imageName: "bootPage_2",contentMode: .scaleAspectFill)
-//        imageView2.frame = CGRectMake(k_ScreenWidth*2, 0, k_ScreenWidth, k_ScreenHeight)
-//        scrollView.addSubview(imageView2)
-//        
-//        let btnH = k_ScreenHeight/5
-//        let btnTop = btnH*4
-//        
-//        let button0 = UIButton(frame: CGRectMake(0, btnTop, k_ScreenWidth, btnH))
-//        button0.tag = 1
-//        button0.addTarget(self, action: #selector(clickBtn(_:)), for: .touchUpInside)
-//        scrollView.addSubview(button0)
-//        
-//        let button1 = UIButton(frame: CGRectMake(k_ScreenWidth, btnTop, k_ScreenWidth, btnH))
-//        button1.tag = 2
-//        button1.addTarget(self, action: #selector(clickBtn(_:)), for: .touchUpInside)
-//        scrollView.addSubview(button1)
-//        
-//        let button2 = UIButton(frame: CGRectMake(k_ScreenWidth*2, btnTop, k_ScreenWidth, btnH))
-//        button2.tag = 3
-//        button2.addTarget(self, action: #selector(clickBtn(_:)), for: .touchUpInside)
-//        scrollView.addSubview(button2)
-//        
-//        scrollView.addSubview(titleLabel)
-//        scrollView.addSubview(continueBtn)
-//        continueBtn.snp.makeConstraints { make in
-//            make.width.equalTo(continueBtn.width)
-//            make.height.equalTo(continueBtn.height)
-//            make.bottom.equalTo(-61)
-//            make.centerY.equalToSuperview()
-//        }
-//        
-//        titleLabel.snp.makeConstraints { make in
-//            make.leading.equalTo(16)
-//            make.trailing.equalTo(-16)
-//            make.bottom.equalTo(continueBtn.snp.top).offset(-36)
-//        }
-//        return scrollView
-//    }()
-//    
-//    override func createView() {
-//        setNavBarViewHidden(true)
-//        self.view.backgroundColor = .black
-//        self.view.addSubview(scrollView)
-//        titleLabel.text = titleStrings.safeString(At: index)
-//    }
-    
-    
-//    @objc func clickBtn(_ btn:UIButton){
-//        if btn.tag <= 2{
-//            scrollView.contentOffset = CGPointMake(k_ScreenWidth*CGFloat(btn.tag), 0)
-//        }else{
-//            onComplete()
-//            self.navBarClickLeftAction()
-//        }
-//    }
-    
     @objc func clickBtn(_ btn:UIButton){
         if btn.tag <= 2{
             scrollView.contentOffset = CGPointMake(k_ScreenWidth*CGFloat(btn.tag), 0)
@@ -179,6 +110,7 @@ class TSBootPageVC: TSBaseVC {
                 onComplete()
             }
             self.navigationController?.pushViewController(vc, animated: true)
+            AppDelegate.setsTopDayPopPurchase()
         }
         
     }

+ 2 - 1
AIRingtone/Business/TSAIPhotoVC/TSAIPhotoChildVC/TSAIPhotoChildVC.swift

@@ -88,7 +88,8 @@ class TSAIPhotoChildVC: TSBaseVC {
     
     override func dealThings() {
         reloadView()
-        NotificationCenter.default.addObserver(forName: .kReloadUIData, object: nil, queue: nil) { notification in
+        NotificationCenter.default.addObserver(forName: .kReloadUIData, object: nil, queue: nil) { [weak self] notification in
+            guard let self = self else { return }
             if let userInfo = notification.userInfo as? [String: TSGennerateType], let myEnum = userInfo["TSGennerateType"] {
                 if myEnum == self.style {
                     self.vm.setRecentData()

+ 2 - 1
AIRingtone/Business/TSAIPhotoVC/TSAIPhotoVC.swift

@@ -141,7 +141,8 @@ class TSAIPhotoVC: TSBaseVC {
     
     
     override func dealThings() {
-        NotificationCenter.default.addObserver(forName: .kReloadUIData, object: nil, queue: nil) { notification in
+        NotificationCenter.default.addObserver(forName: .kReloadUIData, object: nil, queue: nil) { [weak self] notification in
+            guard let self = self else { return }
             if let userInfo = notification.userInfo as? [String: TSGennerateType], let myEnum = userInfo["TSGennerateType"] {
                 self.segmentedView.selectItemAt(index: myEnum.rawValue)
             }

+ 13 - 3
AIRingtone/Business/TSAIPhotoVC/TSTextGeneralPicVC/View/TSPromptStyleView.swift

@@ -130,10 +130,14 @@ class TSPTPSelectStyleCCell: TSBaseCollectionCell {
     
     lazy var imageView: UIImageView = {
         let imageView = UIImageView()
-        imageView.cornerRadius = 16.0
         return imageView
     }()
     
+    lazy var shadowImageView: UIImageView = {
+        let shadowImageView = UIImageView.createImageView(imageName: "square_bottom_shadow",contentMode: .scaleAspectFill)
+        return shadowImageView
+    }()
+    
     lazy var boardImageView: UIImageView = {
         let boardImageView = UIImageView.createImageView(imageName: "ptp_selected_border")
         boardImageView.isHidden = true
@@ -142,17 +146,23 @@ class TSPTPSelectStyleCCell: TSBaseCollectionCell {
 
     lazy var textLabel: UILabel = {
         let textLabel = UILabel.createLabel(font: .font(size: 14),textColor: .white,textAlignment: .center,numberOfLines: 0)
-        textLabel.addShadow(shadowColor: UIColor.black.cgColor, shadowOffset: CGSize(width: 0, height: 2), shadowRadius: 2, shadowOpacity: 0.3)
+        textLabel.addShadow(shadowColor: UIColor.black.cgColor, shadowOffset: CGSize(width: 0, height: 2), shadowRadius: 2, shadowOpacity: 0.6)
         return textLabel
     }()
     
     override func creatUI() {
-        
+        bgContentView.cornerRadius = 16.0
         bgContentView.addSubview(imageView)
         imageView.snp.makeConstraints { make in
             make.top.bottom.leading.trailing.equalTo(0)
         }
         
+        bgContentView.addSubview(shadowImageView)
+        shadowImageView.snp.makeConstraints { make in
+            make.bottom.leading.trailing.equalTo(0)
+            make.height.equalTo(41.0)
+        }
+        
         bgContentView.addSubview(boardImageView)
         boardImageView.snp.makeConstraints { make in
             make.top.bottom.leading.trailing.equalTo(0)

+ 16 - 7
AIRingtone/Business/TSAIRintoneVC/TSAIRintoneVC/TSAIRintoneVC.swift

@@ -87,21 +87,29 @@ class TSAIRintoneVC: TSBaseVC {
             make.edges.equalToSuperview()
         }
         
-        
-        let vcViewH = generalRintoneVC.viewH
-        collectionView.addSubview(generalRintoneVC.view)
-        generalRintoneVC.view.snp.makeConstraints { make in
+        self.collectionView.addSubview(self.generalRintoneVC.view)
+        setUpGeneralRintoneVCFrame()
+        kDelayMainShort {
+            self.setUpGeneralRintoneVCFrame()
+        }
+    }
+
+    
+    func setUpGeneralRintoneVCFrame(){
+        let vcViewH = self.generalRintoneVC.viewH
+        self.generalRintoneVC.view.snp.remakeConstraints { make in
             make.top.equalTo(-vcViewH)
             make.leading.trailing.equalTo(0)
             make.height.equalTo(vcViewH)
         }
         
-        collectionView.contentInset = UIEdgeInsets(top: vcViewH, left: 0, bottom: 20, right: 0)
-
+        self.collectionView.contentInset = UIEdgeInsets(top: vcViewH, left: 0, bottom: 20, right: 0)
     }
 
     override func viewWillAppear(_ animated: Bool) {
         super.viewWillAppear(animated)
+        viewModel.updateRecentData()
+        updateListView()
     }
     
     override func viewWillDisappear(_ animated: Bool) {
@@ -116,7 +124,8 @@ class TSAIRintoneVC: TSBaseVC {
             collectionView.reloadData()
         }
         
-        NotificationCenter.default.addObserver(forName: .kGenerateRintoneOperationChanged, object: nil, queue: nil) { notification in
+        NotificationCenter.default.addObserver(forName: .kGenerateRintoneOperationChanged, object: nil, queue: nil) { [weak self] notification in
+            guard let self = self else { return }
             if let userInfo = notification.userInfo as? [String: Any], let uuid = userInfo["uuid"] as? String,let state = userInfo["state"] as? TSProgressState {
                 dePrint("TSBaseOperation stateDatauPblished 收到 = \(state)")
                 switch state {

+ 0 - 1
AIRingtone/Business/TSAIRintoneVC/TSAIRintoneVC/View/TSAIRintoneHistoryCell.swift

@@ -134,7 +134,6 @@ class TSAIRintoneHistoryCell: SwipeCollectionViewCell  {
         if let vc = targetVC as? any SwipeCollectionViewCellDelegate {
           self.delegate = vc
         }
-
     }
     
     func dealThings(){

+ 18 - 16
AIRingtone/Business/TSAIRintoneVC/TSGeneralRintoneVC/TSGeneralRintoneVC+Event.swift

@@ -6,16 +6,16 @@
 //
 
 extension UIViewController {
-    func findFirstTransitionView() -> UIView? {
-        var currentView = self.view
-        while currentView != nil {// 判断当前视图是否是 UITransitionView
-            if String(describing: type(of: currentView!)) == "UITransitionView" {
-                return currentView
-            }
-            currentView = currentView?.superview
-        }
-        return nil // 如果没有找到,返回 nil
-    }
+//    func findFirstTransitionView() -> UIView? {
+//        var currentView = self.view
+//        while currentView != nil {// 判断当前视图是否是 UITransitionView
+//            if String(describing: type(of: currentView!)) == "UITransitionView" {
+//                return currentView
+//            }
+//            currentView = currentView?.superview
+//        }
+//        return nil // 如果没有找到,返回 nil
+//    }
 }
 extension TSGeneralRintoneVC {
     
@@ -31,10 +31,10 @@ extension TSGeneralRintoneVC {
         }
     }
     
-    func hiddenSelfVC(hidden:Bool){
-        self.view.isHidden = hidden
-        findFirstTransitionView()?.isHidden = hidden
-    }
+//    func hiddenSelfVC(hidden:Bool){
+//        self.view.isHidden = hidden
+//        findFirstTransitionView()?.isHidden = hidden
+//    }
 
 }
 extension TSGeneralRintoneVC {
@@ -42,10 +42,12 @@ extension TSGeneralRintoneVC {
         updateInfoModel(model: model)
         switch state {
             case .failed(let errorStr):
-                hiddenSelfVC(hidden: false)
+                audioPlayer.stop()
+//                hiddenSelfVC(hidden: false)
                 showError(text: errorStr)
             case .success:
-                hiddenSelfVC(hidden: false)
+                audioPlayer.stop()
+//                hiddenSelfVC(hidden: false)
                 if let model = model {
                     showSuccess(model: model)
                 }else{

+ 14 - 6
AIRingtone/Business/TSAIRintoneVC/TSGeneralRintoneVC/TSGeneralRintoneVC.swift

@@ -12,9 +12,11 @@ class TSGeneralRintoneVC: TSBottomAlertVC {
     
     var prompt:String
     var promptSort:String
-    init(prompt: String,promptSort: String,complete:@escaping ((TSActionInfoModel)->Void)) {
+    var showInfoModel:TSActionInfoModel?
+    init(prompt: String,promptSort: String,showInfoModel:TSActionInfoModel? = nil,complete:@escaping ((TSActionInfoModel)->Void)) {
         self.prompt = prompt
         self.promptSort = promptSort
+        self.showInfoModel = showInfoModel
         self.complete = complete
         super.init()
     }
@@ -85,8 +87,8 @@ class TSGeneralRintoneVC: TSBottomAlertVC {
     
     @objc func clickBackstageBtn() {
 //        viewModel.cancelAllRequest()
-//        self.dismiss(animated: true, completion: nil)
-        hiddenSelfVC(hidden: true)
+        self.dismiss(animated: true, completion: nil)
+//        hiddenSelfVC(hidden: true)
 
     }
     
@@ -148,7 +150,13 @@ class TSGeneralRintoneVC: TSBottomAlertVC {
 //            guard let self = self else { return }
 //            self.upDateView(state: state, model: model)
 //        }.store(in: &cancellable)
-        creatRintone()
+        
+        if let showInfoModel = showInfoModel {
+            showSuccess(model: showInfoModel)
+            updateInfoModel(model: showInfoModel)
+        }else {
+            creatRintone()
+        }
         ringView.monitorPlayStateDefaultHandle()
     }
     
@@ -160,8 +168,8 @@ class TSGeneralRintoneVC: TSBottomAlertVC {
             guard let self = self else { return }
             self.upDateView(state: state, model: model)
         }.store(in: &cancellable)
-        operation.creatRintone(oldModel: self.infoModel, prompt: prompt, promptSort: promptSort)
-
+        operation.creatRintone(oldModel: nil, prompt: prompt, promptSort: promptSort)
+//        operation.creatRintone(oldModel: self.infoModel, prompt: prompt, promptSort: promptSort)
     }
 }
 

+ 9 - 6
AIRingtone/Business/TSAIRintoneVC/TSGenerateHistoryVC/TSGenerateHistoryVC.swift

@@ -74,7 +74,8 @@ class TSGenerateHistoryVC: TSBaseVC {
     override func dealThings() {
         updateListView()
         
-        NotificationCenter.default.addObserver(forName: .kGenerateRintoneOperationChanged, object: nil, queue: nil) { notification in
+        NotificationCenter.default.addObserver(forName: .kGenerateRintoneOperationChanged, object: nil, queue: nil) {[weak self] notification in
+            guard let self = self else { return }
             if let userInfo = notification.userInfo as? [String: Any],let state = userInfo["state"] as? TSProgressState {
                 switch state {
                 case .start, .success(_),.failed(_),.none:
@@ -90,10 +91,11 @@ class TSGenerateHistoryVC: TSBaseVC {
         collectionView.reloadData()
     }
     
-    override func navBarClickLeftAction() {
-        super.navBarClickLeftAction()
-        self.reloadUIBlock?()
-    }
+//    override func navBarClickLeftAction() {
+//        super.navBarClickLeftAction()
+//        self.reloadUIBlock?()
+//    }
+
 }
 
 extension TSGenerateHistoryVC: UICollectionViewDataSource ,UICollectionViewDelegate,UICollectionViewDelegateFlowLayout {
@@ -178,7 +180,8 @@ extension TSGenerateHistoryVC: SwipeCollectionViewCellDelegate {
         // 删除操作
         let deleteAction = SwipeAction(style: .destructive, title: nil) {[weak self] action, indexPath in
             guard let self = self else { return }
-            showCustomAlert(message: "Are you sure to delete".localized, deleteHandler:  {
+            showCustomAlert(message: "Are you sure to delete".localized, deleteHandler:  { [weak self]  in
+                guard let self = self else { return }
                 if let sectionModel = self.viewModel.modelList.safeObj(At: indexPath.section),
                 let model = sectionModel.list.safeObj(At: indexPath.item){
                     if let model = model as? TSActionInfoModel {

+ 11 - 8
AIRingtone/Business/TSAIRintoneVC/TSTextGeneralRintoneVC/TSTextGeneralRintoneVC.swift

@@ -11,9 +11,9 @@ class TSTextGeneralRintoneVC: TSBaseVC {
     var viewH:CGFloat{
         get {
             if cusStackView.viewH > 0{
-                return cusStackView.viewH
+                return cusStackView.viewH + cusStackView.y
             }
-            return 400.0
+            return 140*kDesignScale + 260.0 + cusStackView.y //400.0
         }
     }
     
@@ -121,12 +121,15 @@ extension TSTextGeneralRintoneVC {
             reloadUIBlock?()
         }
         
-        //        kPresentModalVC(target: self, modelVC: gennerateVC,transitionStyle: .crossDissolve)
-        if let rootVC = WindowHelper.getRootViewController() {
-            gennerateVC.modalPresentationStyle = .overFullScreen
-            gennerateVC.modalTransitionStyle = .crossDissolve
-            rootVC.present(gennerateVC, animated: true)
-        }
+        kPresentModalVC(target: self, modelVC: gennerateVC,transitionStyle: .crossDissolve)
+        
+//        if let rootVC = WindowHelper.getRootViewController() {
+//            gennerateVC.modalPresentationStyle = .overFullScreen
+//            gennerateVC.modalTransitionStyle = .crossDissolve
+//            rootVC.present(gennerateVC, animated: true)
+////            gennerateVC.hidesBottomBarWhenPushed = true
+////            rootVC.navigationController?.pushViewController(gennerateVC, animated: true)
+//        }
     }
 
     func setCreatBtnEnabled() {

+ 14 - 2
AIRingtone/Business/TSDiscoverVC/TSDiscoverVC/View/TSDiscoverCell.swift

@@ -21,9 +21,15 @@ class TSDiscoverCell: TSBaseCollectionCell {
         return imageView
     }()
     
+    lazy var shadowImageView: UIImageView = {
+        let shadowImageView = UIImageView.createImageView(imageName: "square_top_shadow",contentMode: .scaleAspectFill)
+        return shadowImageView
+    }()
+
+    
     lazy var textLabel: UILabel = {
-        let textLabel = UILabel.createLabel(font: .font(size: 14),textColor: .white,textAlignment: .center,numberOfLines: 0)
-        textLabel.addShadow(shadowColor: UIColor.black.cgColor, shadowOffset: CGSize(width: 0, height: 2), shadowRadius: 2, shadowOpacity: 0.3)
+        let textLabel = UILabel.createLabel(font: .font(size: 18,weight: .medium),textColor: .white,textAlignment: .center,numberOfLines: 0)
+        textLabel.addShadow(shadowColor: UIColor.black.cgColor, shadowOffset: CGSize(width: 0, height: 2), shadowRadius: 2, shadowOpacity: 0.6)
         return textLabel
     }()
     
@@ -34,6 +40,12 @@ class TSDiscoverCell: TSBaseCollectionCell {
             make.top.bottom.leading.trailing.equalTo(0)
         }
         
+        bgContentView.addSubview(shadowImageView)
+        shadowImageView.snp.makeConstraints { make in
+            make.top.leading.trailing.equalTo(0)
+            make.height.equalTo(41.0)
+        }
+        
         bgContentView.addSubview(textLabel)
         textLabel.snp.makeConstraints { make in
             make.leading.equalTo(6)

+ 54 - 20
AIRingtone/Business/TSPurchaseMembershipVC/TSPurchaseVC.swift

@@ -10,7 +10,7 @@ import SwiftUI
 import SwiftUIX
 class PurchaseViewModel : ObservableObject{
     
-    @Published var selectedType: PremiumPeriod = .month
+    @Published var selectedType: PremiumPeriod = .year
     
     /// 订阅publisher
     let buyPublisher  = PassthroughSubject<Bool,Never>()
@@ -41,15 +41,32 @@ class TSPurchaseVC: TSBaseVC {
         return vc
     }()
     
+    lazy var closeBtn: UIButton = {
+        let closeBtn = UIButton.createButton(image: UIImage(named: "close_gray")){ [weak self]  in
+            guard let self = self else { return }
+            closePage()
+        }
+        return closeBtn
+    }()
     override func createView() {
-        addNormalNavBarView()
-        _ = setNavigationItem("", imageName: "close_gray", direction: .left, action: #selector(closePage))
+//        addNormalNavBarView()
+//        _ = setNavigationItem("", imageName: "close_gray", direction: .left, action: #selector(closePage))
+        
+        setNavBarViewHidden(true)
         setViewBgImageNamed(named: "purchase_bj")
 
         contentView.addSubview(hostVc.view)
         hostVc.view.snp.makeConstraints { make in
             make.leading.trailing.bottom.top.equalToSuperview()
         }
+        
+        contentView.addSubview(closeBtn)
+        closeBtn.snp.makeConstraints { make in
+            make.leading.equalTo(10)
+            make.top.equalTo(k_Height_StatusBar + 4)
+            make.width.height.equalTo(36)
+        }
+        
     }
     
     override func dealThings() {
@@ -212,7 +229,7 @@ struct PurchaseView :View {
     
     var body: some View {
         ScrollView {
-//            Spacer().frame(height: 44)
+            Spacer().frame(height:k_Height_StatusBar + 6)
             
             VStack {
                 Image("vip_big_icon").resizable().frame(width: 163, height: 163)
@@ -230,24 +247,25 @@ struct PurchaseView :View {
                 
                 ZStack {
                     VStack(alignment: .leading,spacing: 20) {
-                        
+                        let w = 28.0
+                        let h = 28.0
                         HStack(spacing: 16) {
-                            Image("vip_ringtone").resizable().frame(width: 32, height: 32)
+                            Image("vip_ringtone").resizable().frame(width: w, height: h)
                             Text("Unlimited ringtones generation")
                         }
                         
                         HStack(spacing: 16) {
-                            Image("vip_pic").resizable().frame(width: 32, height: 32)
+                            Image("vip_pic").resizable().frame(width: w, height: h)
                             Text("Generate unlimited contact poster&photo")
                         }
                         
                         HStack(spacing: 16) {
-                            Image("vip_photo").resizable().frame(width: 32, height: 32)
+                            Image("vip_photo").resizable().frame(width: w, height: h)
                             Text("Unlock all premium calling theme")
                         }
                         
                         HStack(spacing: 16) {
-                            Image("vip_ads").resizable().frame(width: 32, height: 32)
+                            Image("vip_ads").resizable().frame(width: w, height: h)
                             Text("100% No Ads").multilineTextAlignment(.leading)
                         }
                         
@@ -256,19 +274,26 @@ struct PurchaseView :View {
          
             }
             
-            Spacer().frame(height: 48)
+            Spacer().frame(height: 22)
             
             
             VStack(spacing: 12) {
                 
+                ZStack(alignment: .topTrailing) {
+                    PurchaseItemView(title: "One Year", type: .year, selectedType: $viewModel.selectedType).onTapGesture {
+                        viewModel.selectedType = .year
+                    }
+                    
+                    TSVipRecView().offset(y:-14)
+                }
+          
                 ZStack(alignment: .topTrailing) {
                     PurchaseItemView(title: "One Month", type: .month, selectedType: $viewModel.selectedType).onTapGesture {
                         viewModel.selectedType = .month
                     }
-//                    TSVipRecView()
-//                        .offset(y:-14)
+
                 }
-          
+               
 //                HStack {
 //                    PurchaseItemView(title: "One Year", type: .year, selectedType: $viewModel.selectedType).onTapGesture {
 //                        viewModel.selectedType = .year
@@ -334,27 +359,36 @@ struct PurchaseItemView: View {
     @Binding var selectedType: PremiumPeriod
 
     var body: some View {
+        let themeColor = Color.hex("#E661F6")
+        let fontColor = type == selectedType ? UIColor.mainText.color : UIColor.textAssist.color
+        
         ZStack {
-            Color.clear
+            if type == selectedType {
+                themeColor.opacity(0.1)
+            }else{
+                Color.white.opacity(0.1)
+            }
+            
             HStack {
                 VStack(alignment: .leading, spacing: 8) {
-                    Text(title).font(.font(size: 14)).foregroundColor(UIColor.textAssist.color)
-                    Text(kPurchaseDefault.price(for: type) ?? "--").font(.font(size: 18,weight: .medium)).foregroundColor(UIColor.mainText.color)
+                    Text(title).font(.font(size: 14)).foregroundColor(fontColor)
+                    Text(kPurchaseDefault.price(for: type) ?? "--").font(.font(size: 18,weight: .medium)).foregroundColor(fontColor)
                 }
                 Spacer()
                 if type == selectedType {
                     Image(.radioboxSelected)
                 }
             }.padding(.horizontal)
+
         }
         .frame(height: 74) // 设置高度
         .cornerRadius(16.0) // 圆角
        
         .overlay(
             RoundedRectangle(cornerRadius: 16)
-                .stroke(Color.hex("#E661F6"), lineWidth: type == selectedType ? 1 : 0) // 边框
+                .stroke(themeColor, lineWidth: type == selectedType ? 1 : 0) // 边框
         )
-        .shadow(color: Color.hex("#E661F6"), radius: 4, x: 0, y: 1)
+        .shadow(color: type == selectedType ? themeColor : Color.clear, radius: 4, x: 0, y: 1)
     }
 }
 
@@ -364,10 +398,10 @@ struct TSVipRecView: View {
         
         HStack(spacing: 4) {
             Image("upvote_black").resizable().frame(width: 16, height: 16)
-            Text("80% Choose").font(.font(size: 12,weight: .medium)).foregroundColor(.hex("#111111"))
+            Text("Save 60%").font(.font(size: 12,weight: .medium)).foregroundColor(.white)
         }
         .padding(EdgeInsets(top: 6, leading: 6, bottom: 6, trailing: 6))
-        .background(Color.hex("#FECB34"))
+        .background(Color.hex("#E661F6"))
         .frame(height: 28) // 设置高度
         .cornerRadius([.topLeading, .topTrailing, .bottomLeading], 16.0)
     }

+ 1 - 1
AIRingtone/Business/TSSetingVC/SetingVC/TSSetingModel.swift

@@ -7,7 +7,7 @@
 
 enum SettingType: String, CaseIterable {
     case tutorial = "Tutorial"
-    case update = "Update"
+    case update = "Update Version"
     case rateus = "Rate us"
     case shareus = "Share us"
     case privacy = "Privacy Policy"

+ 8 - 3
AIRingtone/Business/TSSetingVC/SetingVC/TSSetingVC.swift

@@ -104,9 +104,14 @@ class TSSetingVC: TSBaseVC {
     }
     
     @objc func refreshView() {
-        if let newVerison = Float(kAppNewVerison),
-           let oldVerison = Float(appShortVersion()){
-            self.viewModel.isHaveNewVersion = newVerison > oldVerison
+        
+        if UIApplication.compareAppVersions(newVersion1: kAppNewVerison, oldVersion: appShortVersion()) == .newer {
+            self.viewModel.isHaveNewVersion = true
         }
+        
+//        if let newVerison = Float(kAppNewVerison),
+//           let oldVerison = Float(appShortVersion()){
+//            self.viewModel.isHaveNewVersion = newVerison > oldVerison
+//        }
     }
 }

+ 2 - 2
AIRingtone/Business/TSTabBarController/TSTabBarController.swift

@@ -24,8 +24,8 @@ class TSTabBarController: UITabBarController {
     }
 
     @objc private func setUpData() {
-        viewControllerArray = ["TSAIRintoneVC","TSDiscoverVC","TSThemeVC","TSSetingVC"]
-        titleArray = ["AI","Discover","Contact","Setting"]
+        viewControllerArray = ["TSDiscoverVC","TSAIRintoneVC","TSThemeVC","TSSetingVC"]
+        titleArray = ["Rintone","AI","Contact","Setting"]
         
         selectedImageArray = [
             "tabbar_select_rintone",

+ 0 - 1
AIRingtone/Business/TSThemeVC/TSThemeBrowseVC/TSThemeBrowseVC.swift

@@ -189,7 +189,6 @@ extension TSThemeBrowseVC {
     
     func setUpRingtone() {
         if let ringtone = currentModel?.ringtone {
-            
             _ = TSDownloadManager.downloadFile(urlString: ringtone,missingEx: "mp3") {[weak self] url, error in
                 guard let self = self else { return }
                 if let path = url {

+ 1 - 1
AIRingtone/Business/VIewTool/TSRingLoadingView.swift

@@ -40,7 +40,7 @@ class TSRingLoadingView: TSBaseView {
     }()
     
     lazy var textLabel: UILabel = {
-        let textLabel = UILabel.createLabel(text:"loading...".localized, font: .font(size: 12),textColor: .fromHex("#FFFFFF").withAlphaComponent(0.8) ,textAlignment: .center)
+        let textLabel = UILabel.createLabel(text:"Loading...".localized, font: .font(size: 12),textColor: .fromHex("#FFFFFF").withAlphaComponent(0.8) ,textAlignment: .center)
         return textLabel
     }()
     

+ 2 - 1
AIRingtone/Business/VIewTool/TSRingToneCellView.swift

@@ -158,6 +158,7 @@ class TSRingToneCellView: TSBaseView {
 extension TSRingToneCellView {
     
     func monitorPlayStateDefaultHandle(){
+        TSBusinessAudioPlayer.shared.stop()
         TSBusinessAudioPlayer.shared.stateChangedHandle = { [weak self] state  in
             guard let self = self else { return }
             DispatchQueue.main.async {
@@ -274,7 +275,7 @@ class TSRingToneGenerateView:TSBaseView {
         generateProgressView.isHidden = false
         refreshBtn.isHidden = true
         let progressInt = Int(progress*100)
-        infoLabel.text = "Working On Your Ringtone \(progressInt)%..."
+        infoLabel.text = "Working on your ringtone \(progressInt)%..."
     }
     
     func setFail(){

+ 2 - 1
AIRingtone/Common/Purchase/TSPurchaseManager/TSPurchaseTool.swift

@@ -104,7 +104,8 @@ extension TSPurchaseTool{
     func luanchuPrchase() {
         kPurchaseDefault.AppleSharedKey = "4ed5151881304025bfee0295ee459422"
         kPurchaseDefault.purchaseProducts = [
-            PurchaseProduct(productId: "01", period:.month)
+            PurchaseProduct(productId: "01", period:.month),
+            PurchaseProduct(productId: "02", period:.year)
         ]
         kPurchaseDefault.requestProducts()
         

+ 6 - 0
AIRingtone/Common/Tool/OperationQueue/TSGenerateBaseOperation/TSGenerateRintoneOperation.swift

@@ -55,6 +55,12 @@ class TSGenerateRintoneOperation: TSGenerateBaseOperation , @unchecked Sendable{
     
     override func handleGenerateSuccess() {
         kPurchaseToolShared.useOnceForFree(type: .ringtones)
+        let gennerateVC = TSGeneralRintoneVC(prompt:"",promptSort: "",showInfoModel: currentActionInfoModel){ model in }
+        if let rootVC = WindowHelper.getCurrentViewController() {
+            gennerateVC.modalPresentationStyle = .overFullScreen
+            gennerateVC.modalTransitionStyle = .crossDissolve
+            rootVC.present(gennerateVC, animated: true)
+        }
     }
     
 

+ 12 - 4
AIRingtone/Common/Tool/TSBandRingTool/TSBandRingTool.swift

@@ -15,6 +15,7 @@ class TSBandRingTool:NSObject {
     
     lazy var ringLoadingView: TSRingLoadingView = {
         let ringLoadingView = TSRingLoadingView(frame: CGRectMake(0, 0, k_ScreenWidth, k_ScreenHeight))
+//        ringLoadingView.backgroundColor = .blue
         return ringLoadingView
     }()
     weak var targetVC:UIViewController?
@@ -58,14 +59,12 @@ class TSBandRingTool:NSObject {
                      fileURL: URL,
                    fileName:String?,
                    completion: ((Bool) -> Void)? = nil) {
-        
         self.targetVC = vc
-        
+
         if checkGarageBandInstallation() == false {
             completion?(false)
             return
         }
-        
         if TSFileManagerTool.fileExists(at: fileURL) == false{
             completion?(false)
             return
@@ -165,6 +164,14 @@ class TSBandRingTool:NSObject {
                 self.tryStartPictureInPicture()
             })
             
+            // 延迟检查是否真正弹出
+            DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
+                if self.targetVC?.presentedViewController != vc {
+                    dePrint("⚠️ present 失败:系统未正确响应")
+                    // 这里可以触发回调或通知
+                    self.playContentView.removeFromSuperview()
+                }
+            }
         }
     }
     
@@ -206,11 +213,12 @@ extension TSBandRingTool : AVPlayerViewControllerDelegate, AVPictureInPictureCon
             tutorialPlayer?.replaceCurrentItem(with: playerItem)
         }
         tutorialPlayer?.allowsExternalPlayback = true
-        
+//        playContentView.backgroundColor = .black.withAlphaComponent(0.1)
         targetVC?.view.addSubview(playContentView)
         
         let layer = AVPlayerLayer(player: tutorialPlayer)
         layer.frame = CGRect(x: 0, y: 0, width: 1, height: 1)
+//        layer.backgroundColor = UIColor.yellow.cgColor
         playContentView.layer.addSublayer(layer)
 
         let pictureVC = AVPictureInPictureController(playerLayer: layer)