Browse Source

ai 机器人开发完毕

100Years 1 month ago
parent
commit
df8ae06f90

+ 17 - 5
AIEmoji.xcodeproj/project.pbxproj

@@ -45,7 +45,8 @@
 		A85E479B2D6808C40018D62D /* TSBigIconBrowseVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A85E479A2D6808C30018D62D /* TSBigIconBrowseVC.swift */; };
 		A85E479D2D6809DC0018D62D /* TSBigIconBrowseCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A85E479C2D6809DA0018D62D /* TSBigIconBrowseCell.swift */; };
 		A85E479F2D6859FA0018D62D /* TSRandomTextPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = A85E479E2D6859F80018D62D /* TSRandomTextPicker.swift */; };
-		A85E47BC2D68800D0018D62D /* TSMessageContentCell+Ex.swift in Sources */ = {isa = PBXBuildFile; fileRef = A85E47BB2D6880060018D62D /* TSMessageContentCell+Ex.swift */; };
+		A85E47C02D6961BB0018D62D /* TSChatMessageUIModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A85E47BF2D6961B90018D62D /* TSChatMessageUIModel.swift */; };
+		A85E47C32D6964A50018D62D /* TSMSGAIDefaultHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A85E47C22D69646D0018D62D /* TSMSGAIDefaultHeaderView.swift */; };
 		A89EA64B2D59A588000EB181 /* MessageKit in Frameworks */ = {isa = PBXBuildFile; productRef = A89EA64A2D59A588000EB181 /* MessageKit */; };
 		A89EA6542D59A9F4000EB181 /* TSTextLayoutSizeCalculator.swift in Sources */ = {isa = PBXBuildFile; fileRef = A89EA64F2D59A9F4000EB181 /* TSTextLayoutSizeCalculator.swift */; };
 		A89EA6552D59A9F4000EB181 /* TSChatMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = A89EA6502D59A9F4000EB181 /* TSChatMessage.swift */; };
@@ -173,7 +174,8 @@
 		A85E479A2D6808C30018D62D /* TSBigIconBrowseVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSBigIconBrowseVC.swift; sourceTree = "<group>"; };
 		A85E479C2D6809DA0018D62D /* TSBigIconBrowseCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSBigIconBrowseCell.swift; sourceTree = "<group>"; };
 		A85E479E2D6859F80018D62D /* TSRandomTextPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSRandomTextPicker.swift; sourceTree = "<group>"; };
-		A85E47BB2D6880060018D62D /* TSMessageContentCell+Ex.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TSMessageContentCell+Ex.swift"; sourceTree = "<group>"; };
+		A85E47BF2D6961B90018D62D /* TSChatMessageUIModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSChatMessageUIModel.swift; sourceTree = "<group>"; };
+		A85E47C22D69646D0018D62D /* TSMSGAIDefaultHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSMSGAIDefaultHeaderView.swift; sourceTree = "<group>"; };
 		A89EA64C2D59A9F4000EB181 /* CustomMessageFlowLayout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomMessageFlowLayout.swift; sourceTree = "<group>"; };
 		A89EA64E2D59A9F4000EB181 /* TSLayoutSizeCalculator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSLayoutSizeCalculator.swift; sourceTree = "<group>"; };
 		A89EA64F2D59A9F4000EB181 /* TSTextLayoutSizeCalculator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSTextLayoutSizeCalculator.swift; sourceTree = "<group>"; };
@@ -491,6 +493,14 @@
 			path = TSBigIconBrowseVC;
 			sourceTree = "<group>";
 		};
+		A85E47C12D6964500018D62D /* TSCellView */ = {
+			isa = PBXGroup;
+			children = (
+				A85E47C22D69646D0018D62D /* TSMSGAIDefaultHeaderView.swift */,
+			);
+			path = TSCellView;
+			sourceTree = "<group>";
+		};
 		A89EA64D2D59A9F4000EB181 /* Layout */ = {
 			isa = PBXGroup;
 			children = (
@@ -507,6 +517,7 @@
 				A89EA64E2D59A9F4000EB181 /* TSLayoutSizeCalculator.swift */,
 				A89EA64F2D59A9F4000EB181 /* TSTextLayoutSizeCalculator.swift */,
 				A89EA6502D59A9F4000EB181 /* TSChatMessage.swift */,
+				A85E47BF2D6961B90018D62D /* TSChatMessageUIModel.swift */,
 				A89EA6522D59A9F4000EB181 /* TSChatUser.swift */,
 			);
 			path = Models;
@@ -515,10 +526,10 @@
 		A89EA6682D59AA31000EB181 /* Views */ = {
 			isa = PBXGroup;
 			children = (
+				A85E47C12D6964500018D62D /* TSCellView */,
 				A89EA6632D59AA31000EB181 /* CameraInputBarAccessoryView.swift */,
-				A89EA6652D59AA31000EB181 /* TSMessageContentCell.swift */,
-				A85E47BB2D6880060018D62D /* TSMessageContentCell+Ex.swift */,
 				A89EA6662D59AA31000EB181 /* TSTextMessageContentCell.swift */,
+				A89EA6652D59AA31000EB181 /* TSMessageContentCell.swift */,
 				A89EA6672D59AA31000EB181 /* TableViewCells.swift */,
 			);
 			path = Views;
@@ -1161,6 +1172,7 @@
 				A80E726F2D40DE2B00C64288 /* TSWallpaperPreviewVC.swift in Sources */,
 				A8F775492D3935D600AA6E93 /* TSBusinessWebVC.swift in Sources */,
 				A8F776392D3B38E600AA6E93 /* TSGenmojiGennerateVC.swift in Sources */,
+				A85E47C02D6961BB0018D62D /* TSChatMessageUIModel.swift in Sources */,
 				A8F774E02D38EA8C00AA6E93 /* TSCommonTool.swift in Sources */,
 				A89EA6BF2D5E03D6000EB181 /* Notification+Ex.swift in Sources */,
 				A8F774E12D38EA8C00AA6E93 /* TSFileManagerTool.swift in Sources */,
@@ -1198,6 +1210,7 @@
 				A80E72202D3F3A8600C64288 /* DiyElementBaseView.swift in Sources */,
 				A8F776212D3A3F0200AA6E93 /* TSEmojisChildVC.swift in Sources */,
 				A80E72222D3F3A9200C64288 /* DiyStickerElement.swift in Sources */,
+				A85E47C32D6964A50018D62D /* TSMSGAIDefaultHeaderView.swift in Sources */,
 				A8F775002D38EA8C00AA6E93 /* WindowHelper.swift in Sources */,
 				A8F7764B2D3E008500AA6E93 /* TSEmojisChildColViewModel.swift in Sources */,
 				A80E72772D41EFF900C64288 /* TSEmojisTutorialsVC.swift in Sources */,
@@ -1231,7 +1244,6 @@
 				A80E72382D3F473B00C64288 /* DiyPaperProtocol.swift in Sources */,
 				A8F775382D390C3C00AA6E93 /* TSNetworkManager.swift in Sources */,
 				A85E47982D672AE70018D62D /* TSTextPicGennerateVM.swift in Sources */,
-				A85E47BC2D68800D0018D62D /* TSMessageContentCell+Ex.swift in Sources */,
 				A89EA65F2D59AA11000EB181 /* TSChatViewController.swift in Sources */,
 				A89EA6C62D5F5C22000EB181 /* TSChatInputFullScreenVC.swift in Sources */,
 				A89EA6CA2D642C0A000EB181 /* TSChatViewController+SendMsg.swift in Sources */,

+ 1 - 1
AIEmoji.xcodeproj/xcshareddata/xcschemes/AIEmoji.xcscheme

@@ -31,7 +31,7 @@
       shouldAutocreateTestPlan = "YES">
    </TestAction>
    <LaunchAction
-      buildConfiguration = "Release"
+      buildConfiguration = "Debug"
       selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
       selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
       launchStyle = "0"

+ 1 - 7
AIEmoji/Business/AIChat/TSChatViewController/Layout/CustomMessageFlowLayout.swift

@@ -29,14 +29,7 @@ open class CustomMessagesFlowLayout: MessagesCollectionViewFlowLayout {
   lazy var customMessageSizeCalculator = TSTextLayoutSizeCalculator(layout: self)
 
   open override func cellSizeCalculatorForItem(at indexPath: IndexPath) -> CellSizeCalculator {
-//    if isSectionReservedForTypingIndicator(indexPath.section) {
-//      return typingIndicatorSizeCalculator
-//    }
-//    let message = messagesDataSource.messageForItem(at: indexPath, in: messagesCollectionView)
-//    if case .custom = message.kind {
       return customMessageSizeCalculator
-//    }
-//    return super.cellSizeCalculatorForItem(at: indexPath)
   }
 
   open override func messageSizeCalculators() -> [MessageSizeCalculator] {
@@ -44,4 +37,5 @@ open class CustomMessagesFlowLayout: MessagesCollectionViewFlowLayout {
     superCalculators.append(customMessageSizeCalculator)
     return superCalculators
   }
+
 }

+ 5 - 3
AIEmoji/Business/AIChat/TSChatViewController/Models/TSChatMessage.swift

@@ -59,8 +59,10 @@ internal class TSChatMessage: MessageType {
         user
     }
     var sendState: TSProgressState = .none
-    var appendDict:[String:Any] = [:]
+    var appendDict:[TSChatMessageAppendDictKey:Any] = [:]
 }
 
-//AI对话默认头View
-let kCMAppendkey_AIDefaultHeader = "kCMAppendkey_AIDefaultHeader"
+// 定义一个枚举作为字典的键
+enum TSChatMessageAppendDictKey: String {
+    case AIDefaultHeader
+}

+ 12 - 0
AIEmoji/Business/AIChat/TSChatViewController/Models/TSChatMessageUIModel.swift

@@ -0,0 +1,12 @@
+//
+//  TSChatMessageUIModel.swift
+//  AIEmoji
+//
+//  Created by 100Years on 2025/2/21.
+//
+
+class TSChatMessageUIBaseModel: TSBaseModel {
+    var text:String = ""
+    var height:CGFloat = 0.0
+    var view:UIView = UIView()
+}

+ 11 - 1
AIEmoji/Business/AIChat/TSChatViewController/Models/TSLayoutSizeCalculator.swift

@@ -73,7 +73,17 @@ class TSLayoutSizeCalculator: MessageSizeCalculator {//CellSizeCalculator {
     
     //消息容器的高度
     func cellContentHeight(for message: MessageType,at indexPath: IndexPath,fromCurrentSender: Bool)-> CGFloat {
-        return Self.cellMessageContainerMinSize.height
+       
+        var height = 0.0
+        
+        if let msgModel = message as? TSChatMessage {
+            //有ai机器人头部imageview
+            if let uiBaseModel = msgModel.appendDict[.AIDefaultHeader] as? TSChatMessageUIBaseModel {
+                height+=uiBaseModel.height
+            }
+        }
+
+        return height
     }
     
 }

+ 9 - 5
AIEmoji/Business/AIChat/TSChatViewController/Models/TSTextLayoutSizeCalculator.swift

@@ -36,13 +36,17 @@ class TSTextLayoutSizeCalculator: TSLayoutSizeCalculator {
     //消息容器的高度
     override func cellContentHeight(for message: MessageType,at indexPath: IndexPath, fromCurrentSender: Bool)-> CGFloat {
         let superH = super.cellContentHeight(for: message, at: indexPath, fromCurrentSender: fromCurrentSender)
+        
+        var height = superH
         let size = messageLabelSize(for: message, at: indexPath, fromCurrentSender: fromCurrentSender)
-        var height = size.height + Self.cellMessagelabelEdge.top + Self.cellMessagelabelEdge.bottom
-
-        if height < superH {
-            height = superH
+        let messagecontainerH = size.height + Self.cellMessagelabelEdge.top + Self.cellMessagelabelEdge.bottom
+        
+        height = height + messagecontainerH
+        let minHeight = Self.cellMessageContainerMinSize.height
+        if height < minHeight {
+            height = minHeight
         }
-
+        
         return height
     }
     

+ 0 - 1
AIEmoji/Business/AIChat/TSChatViewController/TSChatViewController/TSChatViewController.swift

@@ -108,7 +108,6 @@ class TSChatViewController: MessagesViewController, MessagesDataSource {
         //设置自定义FlowLayout,itemsize等,都在这里控制
         let flowLayout = CustomMessagesFlowLayout()
         flowLayout.sectionInset = UIEdgeInsets(top: 4, left: 0, bottom: 4, right: 0)
-        flowLayout.estimatedItemSize = UICollectionViewFlowLayout.automaticSize
         messagesCollectionView.collectionViewLayout = flowLayout
         messagesCollectionView.backgroundColor = .clear
         messagesCollectionView.register(TSTextMessageContentCell.self)

+ 6 - 1
AIEmoji/Business/AIChat/TSChatViewController/ViewModel/TSAIChatVM.swift

@@ -99,7 +99,12 @@ extension TSAIChatVM {
         }else {
             let aiString = "I can tackle your questions, my skillset includes, but is not limited to:\n\n📧 Composing high-quality emails\n\n🇺🇸 Facilitating language learning\n\n📑 Assisting in your studies\n\n💡Brainstorming ideas\n\nand much more!"
             let msg = TSChatMessage(kind: .attributedText(kMDAttributedString(text: aiString)), user: kAIUser, messageId: "", date: Date())
-            msg.appendDict = [kCMAppendkey_AIDefaultHeader:"Greetings! Curious about what I can do?".localized]
+
+            let model = TSChatMessageUIBaseModel()
+            model.height = 52.0
+            model.view = TSMSGAIDefaultHeaderView(text: "Greetings! Curious about\nwhat I can do?".localized)
+
+            msg.appendDict = [.AIDefaultHeader:model]
             return [msg]
         }
     }

+ 25 - 10
AIEmoji/Business/AIChat/TSChatViewController/Views/TSMessageContentCell+Ex.swift → AIEmoji/Business/AIChat/TSChatViewController/Views/TSCellView/TSMSGAIDefaultHeaderView.swift

@@ -1,12 +1,30 @@
 //
-//  TSMessageContentCell+Ex.swift
+//  TSMSGAIDefaultHeaderView.swift
 //  AIEmoji
 //
 //  Created by 100Years on 2025/2/21.
 //
 
-extension TSMessageContentCell {
+class TSMSGAIDefaultHeaderView: TSBaseView {
+    
+    var text:String
+    init(text:String) {
+        self.text = text
+        super.init(frame: .zero)
+    }
+    
+    @MainActor required init?(coder: NSCoder) {
+        fatalError("init(coder:) has not been implemented")
+    }
 
+    override func creatUI() {
+        let view = creatAIDefaultHeaderView(text: text)
+        addSubview(view)
+        view.snp.makeConstraints { make in
+            make.edges.equalToSuperview()
+        }
+    }
+    
     func creatAIDefaultHeaderView(text:String) -> UIView {
         let view = UIView()
         view.clipsToBounds = true
@@ -22,20 +40,17 @@ extension TSMessageContentCell {
         let textLabel = UILabel.createLabel(
             text: text,
             font: .font(size: 16,weight: .medium),
-            textColor: .white
+            textColor: .white,
+            numberOfLines: 0
         )
         view.addSubview(textLabel)
         textLabel.snp.makeConstraints { make in
-            make.leading.equalTo(88)
-            make.trailing.equalTo(-40)
+            make.leading.equalTo(imageView.snp.trailing).offset(8)
+            make.trailing.lessThanOrEqualTo(-40)
             make.top.equalTo(0)
             make.bottom.equalTo(-8)
         }
         return view
     }
-    
-    
-    
-    
-    
+        
 }

+ 20 - 13
AIEmoji/Business/AIChat/TSChatViewController/Views/TSMessageContentCell.swift

@@ -29,18 +29,21 @@ class TSMessageContentCell: MessageCollectionViewCell {
     var topContainerView: UIView = {
         let containerView = UIView()
         containerView.clipsToBounds = true
+//        containerView.backgroundColor = .red
         return containerView
     }()
     
-    /// 部内容
+    /// 部内容
     var centerContainerView: UIView = {
         let containerView = UIView()
+//        containerView.backgroundColor = .yellow
         return containerView
     }()
     
     /// 底部内容
     var bottomContainerView: UIView = {
         let containerView = UIView()
+//        containerView.backgroundColor = .blue
         return containerView
     }()
     
@@ -85,7 +88,7 @@ class TSMessageContentCell: MessageCollectionViewCell {
             make.leading.trailing.bottom.equalTo(0)
         }
         
-//        setUpTopContainerView()
+        setUpTopContainerView()
         setUpCenterContainerView()
         setUpBottomContainerView()
     }
@@ -194,19 +197,23 @@ class TSMessageContentCell: MessageCollectionViewCell {
         }
         
         messageContainerView.backgroundColor = displayDelegate.backgroundColor(for: message,at: indexPath,in: messagesCollectionView)
+        handleTopContainerViewChanged(message: message)
     }
     
-//    
-//    func handleTopContainerViewChanged(<#parameters#>) -> <#return type#> {
-//        topContainerView.removeFromSuperview()
-//        if let msgModel = message as? TSChatMessage {
-//            
-//            //有ai机器人头部imageview
-//            if let text = msgModel.appendDict[kCMAppendkey_AIDefaultHeader] {
-//                topContainerView
-//            }
-//        }
-//    }
+    func handleTopContainerViewChanged(message: MessageType) {
+        topContainerView.removeAllSubviews()
+        if let msgModel = message as? TSChatMessage {
+            //有ai机器人头部imageview
+            if let uiBaseModel = msgModel.appendDict[.AIDefaultHeader] as? TSChatMessageUIBaseModel {
+                let aiDefaultHeaderView = uiBaseModel.view
+                topContainerView.addSubview(aiDefaultHeaderView)
+                aiDefaultHeaderView.snp.makeConstraints { make in
+                    make.leading.trailing.top.bottom.equalTo(0)
+                    make.height.equalTo(uiBaseModel.height)
+                }
+            }
+        }
+    }
     
     /// Handle `ContentView`'s tap gesture, return false when `ContentView` doesn't needs to handle gesture
     func cellContentView(canHandle _: CGPoint) -> Bool {

+ 1 - 1
AIEmoji/Common/Purchase/TSPurchaseManager.swift

@@ -140,7 +140,7 @@ public class PurchaseManager: NSObject {
 
     @objc public var isVip: Bool {
         #if DEBUG
-//        return true
+        return true
         #endif
         guard let expiresDate = expiredDate else {
             return false