Browse Source

Merge branch '开发机器人头部' into 文生图

* 开发机器人头部:
  ai 机器人开发完毕
  添加机器人头部 Imageview

# Conflicts:
#	AIEmoji.xcodeproj/project.pbxproj
100Years 1 month ago
parent
commit
bd5d2440a5

+ 17 - 1
AIEmoji.xcodeproj/project.pbxproj

@@ -46,6 +46,8 @@
 		A85E479D2D6809DC0018D62D /* TSBigIconBrowseCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A85E479C2D6809DA0018D62D /* TSBigIconBrowseCell.swift */; };
 		A85E479F2D6859FA0018D62D /* TSRandomTextPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = A85E479E2D6859F80018D62D /* TSRandomTextPicker.swift */; };
 		A85E47BE2D68999B0018D62D /* ShareActivityItemProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = A85E47BD2D68999B0018D62D /* ShareActivityItemProvider.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 */; };
@@ -174,6 +176,8 @@
 		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>"; };
 		A85E47BD2D68999B0018D62D /* ShareActivityItemProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareActivityItemProvider.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 +495,14 @@
 			path = TSBigIconBrowseVC;
 			sourceTree = "<group>";
 		};
+		A85E47C12D6964500018D62D /* TSCellView */ = {
+			isa = PBXGroup;
+			children = (
+				A85E47C22D69646D0018D62D /* TSMSGAIDefaultHeaderView.swift */,
+			);
+			path = TSCellView;
+			sourceTree = "<group>";
+		};
 		A89EA64D2D59A9F4000EB181 /* Layout */ = {
 			isa = PBXGroup;
 			children = (
@@ -507,6 +519,7 @@
 				A89EA64E2D59A9F4000EB181 /* TSLayoutSizeCalculator.swift */,
 				A89EA64F2D59A9F4000EB181 /* TSTextLayoutSizeCalculator.swift */,
 				A89EA6502D59A9F4000EB181 /* TSChatMessage.swift */,
+				A85E47BF2D6961B90018D62D /* TSChatMessageUIModel.swift */,
 				A89EA6522D59A9F4000EB181 /* TSChatUser.swift */,
 			);
 			path = Models;
@@ -515,9 +528,10 @@
 		A89EA6682D59AA31000EB181 /* Views */ = {
 			isa = PBXGroup;
 			children = (
+				A85E47C12D6964500018D62D /* TSCellView */,
 				A89EA6632D59AA31000EB181 /* CameraInputBarAccessoryView.swift */,
-				A89EA6652D59AA31000EB181 /* TSMessageContentCell.swift */,
 				A89EA6662D59AA31000EB181 /* TSTextMessageContentCell.swift */,
+				A89EA6652D59AA31000EB181 /* TSMessageContentCell.swift */,
 				A89EA6672D59AA31000EB181 /* TableViewCells.swift */,
 			);
 			path = Views;
@@ -1161,6 +1175,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 +1213,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 */,

+ 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 - 0
AIEmoji/Business/AIChat/TSChatViewController/ViewModel/TSAIChatVM.swift

@@ -99,6 +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())
+
+            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]
         }
     }

+ 56 - 0
AIEmoji/Business/AIChat/TSChatViewController/Views/TSCellView/TSMSGAIDefaultHeaderView.swift

@@ -0,0 +1,56 @@
+//
+//  TSMSGAIDefaultHeaderView.swift
+//  AIEmoji
+//
+//  Created by 100Years on 2025/2/21.
+//
+
+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
+        
+        let imageView = UIImageView.createImageView(imageName: "aichat_avatar")
+        view.addSubview(imageView)
+        imageView.snp.makeConstraints { make in
+            make.leading.equalTo(16)
+            make.top.equalTo(0)
+            make.width.height.equalTo(80)
+        }
+
+        let textLabel = UILabel.createLabel(
+            text: text,
+            font: .font(size: 16,weight: .medium),
+            textColor: .white,
+            numberOfLines: 0
+        )
+        view.addSubview(textLabel)
+        textLabel.snp.makeConstraints { make in
+            make.leading.equalTo(imageView.snp.trailing).offset(8)
+            make.trailing.lessThanOrEqualTo(-40)
+            make.top.equalTo(0)
+            make.bottom.equalTo(-8)
+        }
+        return view
+    }
+        
+}

+ 35 - 19
AIEmoji/Business/AIChat/TSChatViewController/Views/TSMessageContentCell.swift

@@ -28,18 +28,22 @@ 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
     }()
     
@@ -68,7 +72,6 @@ class TSMessageContentCell: MessageCollectionViewCell {
     
     //初始化 cell
     func setupSubviews() {
-        
         contentView.addSubview(topContainerView)
         contentView.addSubview(centerContainerView)
         contentView.addSubview(bottomContainerView)
@@ -85,6 +88,18 @@ class TSMessageContentCell: MessageCollectionViewCell {
             make.leading.trailing.bottom.equalTo(0)
         }
         
+        setUpTopContainerView()
+        setUpCenterContainerView()
+        setUpBottomContainerView()
+    }
+    
+    
+    
+    
+    func setUpTopContainerView() {
+    }
+    
+    func setUpCenterContainerView() {
         centerContainerView.addSubview(leadingAvatarImageView)
         centerContainerView.addSubview(messageContainerView)
         centerContainerView.addSubview(trailingAvatarImageView)
@@ -117,7 +132,8 @@ class TSMessageContentCell: MessageCollectionViewCell {
         
     }
     
-
+    func setUpBottomContainerView() {
+    }
     
     override func prepareForReuse() {
         super.prepareForReuse()
@@ -158,22 +174,6 @@ class TSMessageContentCell: MessageCollectionViewCell {
         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)
-        
-        
-        
 
         //是否是当前用户发送的消息
         let fromCurrentSender = dataSource.isFromCurrentSender(message: message)
@@ -198,6 +198,22 @@ class TSMessageContentCell: MessageCollectionViewCell {
         }
         
         messageContainerView.backgroundColor = displayDelegate.backgroundColor(for: message,at: indexPath,in: messagesCollectionView)
+        handleTopContainerViewChanged(message: message)
+    }
+    
+    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