|
@@ -24,7 +24,7 @@ class TSMessageContentCell: MessageCollectionViewCell {
|
|
|
|
|
|
/// The `MessageCellDelegate` for the cell.
|
|
|
weak var delegate: MessageCellDelegate?
|
|
|
-
|
|
|
+ var cellTapType:TSChatMsgViewTapType?
|
|
|
/// 顶部内容
|
|
|
var topContainerView: UIView = {
|
|
|
let containerView = UIView()
|
|
@@ -39,6 +39,7 @@ class TSMessageContentCell: MessageCollectionViewCell {
|
|
|
// containerView.backgroundColor = .yellow
|
|
|
return containerView
|
|
|
}()
|
|
|
+
|
|
|
|
|
|
/// 底部内容
|
|
|
var bottomContainerView: UIView = {
|
|
@@ -48,12 +49,30 @@ class TSMessageContentCell: MessageCollectionViewCell {
|
|
|
}()
|
|
|
|
|
|
|
|
|
+
|
|
|
+
|
|
|
/// 消息内容容器.frame由 子视图自动布局撑起大小
|
|
|
var messageContainerView: UIView = {
|
|
|
let containerView = UIView()
|
|
|
containerView.cornerRadius = 16
|
|
|
return containerView
|
|
|
}()
|
|
|
+
|
|
|
+ var messageTopContainerView: UIView = {
|
|
|
+ let containerView = UIView()
|
|
|
+// containerView.backgroundColor = .orange
|
|
|
+ return containerView
|
|
|
+ }()
|
|
|
+ var messageCenterContainerView: UIView = {
|
|
|
+ let containerView = UIView()
|
|
|
+ return containerView
|
|
|
+ }()
|
|
|
+ var messageBottomContainerView: UIView = {
|
|
|
+ let containerView = UIView()
|
|
|
+// containerView.backgroundColor = .purple
|
|
|
+ return containerView
|
|
|
+ }()
|
|
|
+
|
|
|
|
|
|
// 左头像
|
|
|
var leadingAvatarImageView: UIImageView = {
|
|
@@ -70,6 +89,20 @@ class TSMessageContentCell: MessageCollectionViewCell {
|
|
|
}()
|
|
|
|
|
|
|
|
|
+ //工具栏,复制,copy 等
|
|
|
+ lazy var msgToolView: TSChatMsgToolView = {
|
|
|
+ let msgToolView = TSChatMsgToolView()
|
|
|
+ msgToolView.didTapCustomViewBlock = {[weak self] tapType in
|
|
|
+ guard let self = self else { return }
|
|
|
+ if let delegate = delegate{
|
|
|
+ cellTapType = tapType
|
|
|
+ delegate.didTapBackground(in: self)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return msgToolView
|
|
|
+ }()
|
|
|
+
|
|
|
+
|
|
|
//初始化 cell
|
|
|
func setupSubviews() {
|
|
|
contentView.addSubview(topContainerView)
|
|
@@ -93,10 +126,9 @@ class TSMessageContentCell: MessageCollectionViewCell {
|
|
|
setUpBottomContainerView()
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
+
|
|
|
func setUpTopContainerView() {
|
|
|
+
|
|
|
}
|
|
|
|
|
|
func setUpCenterContainerView() {
|
|
@@ -104,7 +136,6 @@ class TSMessageContentCell: MessageCollectionViewCell {
|
|
|
centerContainerView.addSubview(messageContainerView)
|
|
|
centerContainerView.addSubview(trailingAvatarImageView)
|
|
|
|
|
|
-
|
|
|
let leadingAvatarEdge = TSLayoutSizeCalculator.leadingAvatarEdge
|
|
|
let leadingAvatarSize = TSLayoutSizeCalculator.leadingAvatarSize
|
|
|
leadingAvatarImageView.snp.makeConstraints { make in
|
|
@@ -130,6 +161,35 @@ class TSMessageContentCell: MessageCollectionViewCell {
|
|
|
make.bottom.equalTo(-cellMessageContainerEdge.bottom)
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+ setUpMessageContainerView()
|
|
|
+ }
|
|
|
+
|
|
|
+ func setUpMessageContainerView(){
|
|
|
+ messageContainerView.addSubview(messageTopContainerView)
|
|
|
+ messageContainerView.addSubview(messageCenterContainerView)
|
|
|
+ messageContainerView.addSubview(messageBottomContainerView)
|
|
|
+
|
|
|
+
|
|
|
+ messageTopContainerView.snp.makeConstraints { make in
|
|
|
+ make.leading.top.trailing.equalTo(0)
|
|
|
+ }
|
|
|
+ messageCenterContainerView.snp.makeConstraints { make in
|
|
|
+ make.top.equalTo(messageTopContainerView.snp.bottom)
|
|
|
+ make.leading.trailing.equalTo(0)
|
|
|
+ }
|
|
|
+
|
|
|
+ messageBottomContainerView.snp.makeConstraints { make in
|
|
|
+ make.top.equalTo(messageCenterContainerView.snp.bottom)
|
|
|
+ make.leading.trailing.bottom.equalTo(0)
|
|
|
+ }
|
|
|
+
|
|
|
+ //添加工具栏
|
|
|
+ messageBottomContainerView.addSubview(msgToolView)
|
|
|
+ msgToolView.snp.makeConstraints { make in
|
|
|
+ make.leading.trailing.top.bottom.equalTo(0)
|
|
|
+ }
|
|
|
+
|
|
|
}
|
|
|
|
|
|
func setUpBottomContainerView() {
|
|
@@ -141,19 +201,18 @@ class TSMessageContentCell: MessageCollectionViewCell {
|
|
|
|
|
|
// 点击触发事件
|
|
|
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)
|
|
|
+// 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)
|
|
|
- }
|
|
|
+// default:
|
|
|
+// delegate?.didTapBackground(in: self)
|
|
|
+// }
|
|
|
}
|
|
|
|
|
|
/// Handle long press gesture, return true when gestureRecognizer's touch point in `messageContainerView`'s frame
|
|
@@ -174,7 +233,7 @@ class TSMessageContentCell: MessageCollectionViewCell {
|
|
|
guard let displayDelegate = messagesCollectionView.messagesDisplayDelegate else {
|
|
|
return
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
//是否是当前用户发送的消息
|
|
|
let fromCurrentSender = dataSource.isFromCurrentSender(message: message)
|
|
|
if fromCurrentSender {
|
|
@@ -198,26 +257,97 @@ class TSMessageContentCell: MessageCollectionViewCell {
|
|
|
}
|
|
|
|
|
|
messageContainerView.backgroundColor = displayDelegate.backgroundColor(for: message,at: indexPath,in: messagesCollectionView)
|
|
|
- handleTopContainerViewChanged(message: message)
|
|
|
+ handleTopContainerViewChanged(message: message,messagesCollectionView: messagesCollectionView,dataSource: dataSource)
|
|
|
}
|
|
|
|
|
|
- func handleTopContainerViewChanged(message: MessageType) {
|
|
|
+ func handleTopContainerViewChanged(
|
|
|
+ message: MessageType,
|
|
|
+ messagesCollectionView: MessagesCollectionView,
|
|
|
+ dataSource: MessagesDataSource
|
|
|
+ ) {
|
|
|
topContainerView.removeAllSubviews()
|
|
|
+ delegate = messagesCollectionView.messageCellDelegate
|
|
|
+
|
|
|
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
|
|
|
+ if let uiBaseModel = msgModel.appendDict[.topView] as? TSChatMessageUIBaseModel {
|
|
|
+ let modelView = uiBaseModel.view
|
|
|
+ topContainerView.addSubview(modelView)
|
|
|
+ modelView.snp.makeConstraints { make in
|
|
|
make.leading.trailing.top.bottom.equalTo(0)
|
|
|
make.height.equalTo(uiBaseModel.height)
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+
|
|
|
+ handelMsgToolView(message: message, dataSource: dataSource)
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ func handelMsgToolView(message: MessageType,dataSource: MessagesDataSource){
|
|
|
+ if let msgModel = message as? TSChatMessage,let chatVC = dataSource as? TSChatViewController{
|
|
|
+
|
|
|
+ var isSuccess = msgModel.sendState.reslutSuccess
|
|
|
+ let isLast = isLast(message: message, dataSource: dataSource)
|
|
|
+
|
|
|
+ //重试只在显示在最后一个 cell,所以cell 是失败了,只要不是最后一个 cell,都要显示成功
|
|
|
+ //历史记录中,不能显示重试
|
|
|
+ if isLast == false || chatVC.viewModel.uiStyle == .history {
|
|
|
+ isSuccess = true
|
|
|
+ }
|
|
|
+ //成功显示复制,失败显示重试
|
|
|
+ msgToolView.isSuccess = isSuccess
|
|
|
+
|
|
|
+ var isHidden = true
|
|
|
+ if msgModel.messageType == TSChatMessageMsgType.aiRobotResponse,
|
|
|
+ msgModel.sendState.isResult{
|
|
|
+ //是机器人的回答,且回答已经结束,就可以显示工具栏了
|
|
|
+ isHidden = false
|
|
|
+ }
|
|
|
+
|
|
|
+ self.msgToolView.setHidden(isHidden: isHidden)
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+
|
|
|
/// Handle `ContentView`'s tap gesture, return false when `ContentView` doesn't needs to handle gesture
|
|
|
func cellContentView(canHandle _: CGPoint) -> Bool {
|
|
|
false
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+extension TSMessageContentCell {
|
|
|
+
|
|
|
+ func isLastCell(in collectionView: UICollectionView) -> Bool {
|
|
|
+ if let indexPath = collectionView.indexPath(for: self),
|
|
|
+ let dataSource = collectionView.dataSource {
|
|
|
+ let itemCount = dataSource.collectionView(collectionView, numberOfItemsInSection: indexPath.section)
|
|
|
+ return indexPath.item == itemCount - 1
|
|
|
+ }
|
|
|
+ return false
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ func isLast(message: MessageType,dataSource: MessagesDataSource)->Bool{
|
|
|
+ if let chatVC = dataSource as? TSChatViewController,
|
|
|
+ let msg = message as? TSChatMessage
|
|
|
+ {
|
|
|
+ let array = chatVC.messageList
|
|
|
+ // 判断对象是否在数组中是最后一个元素
|
|
|
+ if let index = array.firstIndex(where: { $0 === msg }), index == array.count - 1 {
|
|
|
+ return true
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return false
|
|
|
+ }
|
|
|
+}
|