浏览代码

feat: 移除 IMSDK UI层逻辑

陈文艺 3 月之前
父节点
当前提交
71b237f9b0
共有 100 个文件被更改,包括 607 次插入10299 次删除
  1. 5 9
      Lanu.xcodeproj/project.pbxproj
  2. 6 0
      Lanu/Assets.xcassets/IM/FromTencent/Contents.json
  3. 22 0
      Lanu/Assets.xcassets/IM/FromTencent/msg_error_for_conv.imageset/Contents.json
  4. 0 0
      Lanu/Assets.xcassets/IM/FromTencent/msg_error_for_conv.imageset/msg_error_for_conv@2x.png
  5. 0 0
      Lanu/Assets.xcassets/IM/FromTencent/msg_error_for_conv.imageset/msg_error_for_conv@3x.png
  6. 22 0
      Lanu/Assets.xcassets/IM/FromTencent/msg_sending_for_conv.imageset/Contents.json
  7. 0 0
      Lanu/Assets.xcassets/IM/FromTencent/msg_sending_for_conv.imageset/msg_sending_for_conv@2x.png
  8. 0 0
      Lanu/Assets.xcassets/IM/FromTencent/msg_sending_for_conv.imageset/msg_sending_for_conv@3x.png
  9. 131 0
      Lanu/Common/Extension/Date+Extension.swift
  10. 12 57
      Lanu/Common/Extension/TimeInterval+Extension.swift
  11. 0 4
      Lanu/Lanu-Bridging-Header.h
  12. 7 0
      Lanu/Manager/GameMate/Network/LNGameMateResponse.swift
  13. 0 1
      Lanu/Manager/IM/LNIMManager.swift
  14. 1 1
      Lanu/Manager/IM/LNIMMessageData.swift
  15. 119 0
      Lanu/Manager/IM/V2TIMConversation+Extension.swift
  16. 223 0
      Lanu/Manager/IM/V2TIMMessage+Extension.swift
  17. 2 0
      Lanu/Views/Home/GameTab/LNHomeActivityTabItemView.swift
  18. 1 1
      Lanu/Views/Home/LNHomeGameMatePanel.swift
  19. 0 1
      Lanu/Views/Home/LNHomeViewController.swift
  20. 1 2
      Lanu/Views/IM/Chat/Cells/LNIMChatBaseMessageCell.swift
  21. 0 1
      Lanu/Views/IM/Chat/Cells/LNIMChatImageMessageCell.swift
  22. 0 1
      Lanu/Views/IM/Chat/Cells/LNIMChatSystemMessageCell.swift
  23. 0 1
      Lanu/Views/IM/Chat/Cells/LNIMChatTextMessageCell.swift
  24. 0 1
      Lanu/Views/IM/Chat/Cells/LNIMChatUnknownMessageCell.swift
  25. 0 1
      Lanu/Views/IM/Chat/Cells/LNIMChatVoiceMessageCell.swift
  26. 1 0
      Lanu/Views/IM/Chat/LNIMChatTopMenuView.swift
  27. 0 1
      Lanu/Views/IM/Chat/LNIMChatViewController.swift
  28. 4 1
      Lanu/Views/IM/Chat/ViewModel/LNIMChatViewModel.swift
  29. 2 15
      Lanu/Views/IM/ConversationList/LNIMConversationCell.swift
  30. 0 13
      Lanu/Views/IM/TUIConversationListDataProvider+Extension.swift
  31. 0 2
      Podfile
  32. 2 24
      Podfile.lock
  33. 0 249
      ThirdParty/TUIKit/TIMCommon/BaseCell/TUIMessageCell.h
  34. 0 680
      ThirdParty/TUIKit/TIMCommon/BaseCell/TUIMessageCell.m
  35. 0 20
      ThirdParty/TUIKit/TIMCommon/BaseCell/TUISecurityStrikeView.h
  36. 0 73
      ThirdParty/TUIKit/TIMCommon/BaseCell/TUISecurityStrikeView.m
  37. 0 30
      ThirdParty/TUIKit/TIMCommon/BaseCell/TUISystemMessageCell.h
  38. 0 107
      ThirdParty/TUIKit/TIMCommon/BaseCell/TUISystemMessageCell.m
  39. 0 30
      ThirdParty/TUIKit/TIMCommon/BaseCellData/TUIBubbleMessageCellData.h
  40. 0 15
      ThirdParty/TUIKit/TIMCommon/BaseCellData/TUIBubbleMessageCellData.m
  41. 0 280
      ThirdParty/TUIKit/TIMCommon/BaseCellData/TUIMessageCellData.h
  42. 0 151
      ThirdParty/TUIKit/TIMCommon/BaseCellData/TUIMessageCellData.m
  43. 0 110
      ThirdParty/TUIKit/TIMCommon/BaseCellData/TUIMessageCellLayout.h
  44. 0 160
      ThirdParty/TUIKit/TIMCommon/BaseCellData/TUIMessageCellLayout.m
  45. 0 24
      ThirdParty/TUIKit/TIMCommon/BaseCellData/TUIRelationUserModel.h
  46. 0 26
      ThirdParty/TUIKit/TIMCommon/BaseCellData/TUIRelationUserModel.m
  47. 0 73
      ThirdParty/TUIKit/TIMCommon/BaseCellData/TUISystemMessageCellData.h
  48. 0 97
      ThirdParty/TUIKit/TIMCommon/BaseCellData/TUISystemMessageCellData.m
  49. 0 17
      ThirdParty/TUIKit/TIMCommon/CommonModel/NSTimer+TUISafe.h
  50. 0 21
      ThirdParty/TUIKit/TIMCommon/CommonModel/NSTimer+TUISafe.m
  51. 0 458
      ThirdParty/TUIKit/TIMCommon/CommonModel/TIMCommonModel.h
  52. 46 1185
      ThirdParty/TUIKit/TIMCommon/CommonModel/TIMCommonModel.m
  53. 0 2
      ThirdParty/TUIKit/TIMCommon/CommonModel/TIMDefine.h
  54. 0 20
      ThirdParty/TUIKit/TIMCommon/CommonModel/TIMGroupInfo+TUIDataProvider.h
  55. 0 46
      ThirdParty/TUIKit/TIMCommon/CommonModel/TIMGroupInfo+TUIDataProvider.m
  56. 0 19
      ThirdParty/TUIKit/TIMCommon/CommonModel/TIMInputViewMoreActionProtocol.h
  57. 0 33
      ThirdParty/TUIKit/TIMCommon/CommonModel/TIMPopActionProtocol.h
  58. 0 661
      ThirdParty/TUIKit/TIMCommon/CommonModel/TUIAttributedLabel.h
  59. 0 1797
      ThirdParty/TUIKit/TIMCommon/CommonModel/TUIAttributedLabel.m
  60. 0 29
      ThirdParty/TUIKit/TIMCommon/CommonModel/TUIFitButton.h
  61. 0 66
      ThirdParty/TUIKit/TIMCommon/CommonModel/TUIFitButton.m
  62. 0 54
      ThirdParty/TUIKit/TIMCommon/CommonModel/TUIFloatViewController.h
  63. 0 283
      ThirdParty/TUIKit/TIMCommon/CommonModel/TUIFloatViewController.m
  64. 0 21
      ThirdParty/TUIKit/TIMCommon/CommonModel/TUIGroupAvatar+Helper.h
  65. 0 125
      ThirdParty/TUIKit/TIMCommon/CommonModel/TUIGroupAvatar+Helper.m
  66. 0 22
      ThirdParty/TUIKit/TIMCommon/CommonModel/TUISecondConfirm.h
  67. 0 105
      ThirdParty/TUIKit/TIMCommon/CommonModel/TUISecondConfirm.m
  68. 0 25
      ThirdParty/TUIKit/TIMCommon/CommonModel/TUITextView.h
  69. 0 65
      ThirdParty/TUIKit/TIMCommon/CommonModel/TUITextView.m
  70. 0 25
      ThirdParty/TUIKit/TIMCommon/CommonModel/TUIUserAuthorizationCenter.h
  71. 0 136
      ThirdParty/TUIKit/TIMCommon/CommonModel/TUIUserAuthorizationCenter.m
  72. 0 12
      ThirdParty/TUIKit/TIMCommon/Resources/TIMCommon_Minimalist.bundle/dark/manifest.plist
  73. 0 12
      ThirdParty/TUIKit/TIMCommon/Resources/TIMCommon_Minimalist.bundle/light/manifest.plist
  74. 0 12
      ThirdParty/TUIKit/TIMCommon/Resources/TIMCommon_Minimalist.bundle/lively/manifest.plist
  75. 0 12
      ThirdParty/TUIKit/TIMCommon/Resources/TIMCommon_Minimalist.bundle/serious/manifest.plist
  76. 0 2
      ThirdParty/TUIKit/TIMCommon/TIMCommon.podspec
  77. 0 96
      ThirdParty/TUIKit/TIMCommon/UI_Classic/TUIBubbleMessageCell.h
  78. 0 354
      ThirdParty/TUIKit/TIMCommon/UI_Classic/TUIBubbleMessageCell.m
  79. 0 37
      ThirdParty/TUIKit/TIMCommon/UI_Classic/TUICommonGroupInfoCellData.h
  80. 0 46
      ThirdParty/TUIKit/TIMCommon/UI_Classic/TUICommonGroupInfoCellData.m
  81. 0 34
      ThirdParty/TUIKit/TIMCommon/UI_Classic/TUIConfig_Classic.h
  82. 0 27
      ThirdParty/TUIKit/TIMCommon/UI_Classic/TUIConfig_Classic.m
  83. 0 102
      ThirdParty/TUIKit/TIMCommon/UI_Minimalist/TUIBubbleMessageCell_Minimalist.h
  84. 0 356
      ThirdParty/TUIKit/TIMCommon/UI_Minimalist/TUIBubbleMessageCell_Minimalist.m
  85. 0 41
      ThirdParty/TUIKit/TIMCommon/UI_Minimalist/TUICommonGroupInfoCellData_Minimalist.h
  86. 0 24
      ThirdParty/TUIKit/TIMCommon/UI_Minimalist/TUICommonGroupInfoCellData_Minimalist.m
  87. 0 28
      ThirdParty/TUIKit/TIMCommon/UI_Minimalist/TUIConfig_Minimalist.h
  88. 0 22
      ThirdParty/TUIKit/TIMCommon/UI_Minimalist/TUIConfig_Minimalist.m
  89. 0 21
      ThirdParty/TUIKit/TIMCommon/UI_Minimalist/TUIGroupButtonCell_Minimalist.h
  90. 0 168
      ThirdParty/TUIKit/TIMCommon/UI_Minimalist/TUIGroupButtonCell_Minimalist.m
  91. 0 33
      ThirdParty/TUIKit/TIMCommon/UI_Minimalist/TUIMessageCell_Minimalist.h
  92. 0 461
      ThirdParty/TUIKit/TIMCommon/UI_Minimalist/TUIMessageCell_Minimalist.m
  93. 0 17
      ThirdParty/TUIKit/TUIChat/BaseCell/TUIChatPopActionsView.h
  94. 0 28
      ThirdParty/TUIKit/TUIChat/BaseCell/TUIChatPopActionsView.m
  95. 0 56
      ThirdParty/TUIKit/TUIChat/BaseCell/TUIChatPopMenu.h
  96. 0 555
      ThirdParty/TUIKit/TUIChat/BaseCell/TUIChatPopMenu.m
  97. 0 18
      ThirdParty/TUIKit/TUIChat/BaseCell/TUIChatPopMenuDefine.h
  98. 0 41
      ThirdParty/TUIKit/TUIChat/BaseCell/TUIChatShortcutMenuView.h
  99. 0 182
      ThirdParty/TUIKit/TUIChat/BaseCell/TUIChatShortcutMenuView.m
  100. 0 25
      ThirdParty/TUIKit/TUIChat/BaseCell/TUIFaceSegementScrollView.h

+ 5 - 9
Lanu.xcodeproj/project.pbxproj

@@ -39,6 +39,7 @@
 				Common/Extension/AppUtils.swift,
 				"Common/Extension/Comparable+Extension.swift",
 				"Common/Extension/Data+Extension.swift",
+				"Common/Extension/Date+Extension.swift",
 				"Common/Extension/DispatchQueue+Extension.swift",
 				"Common/Extension/NSObject+Extension.swift",
 				"Common/Extension/String+Extension.swift",
@@ -94,6 +95,8 @@
 				Manager/IM/GenerateTestUserSig.m,
 				Manager/IM/LNIMManager.swift,
 				Manager/IM/LNIMMessageData.swift,
+				"Manager/IM/V2TIMConversation+Extension.swift",
+				"Manager/IM/V2TIMMessage+Extension.swift",
 				Manager/LNDelayTask.swift,
 				Manager/LNEventDeliver.swift,
 				Manager/Network/Download/LNFileDownloader.swift,
@@ -157,7 +160,6 @@
 				Views/IM/ConversationList/LNIMConversationListController.swift,
 				Views/IM/Notify/Cell/LNIMOfficialMessageCell.swift,
 				Views/IM/Notify/LNIMOfficialMessageViewController.swift,
-				"Views/IM/TUIConversationListDataProvider+Extension.swift",
 				Views/Login/LNLoginPanel.swift,
 				Views/Login/LNLoginViewController.swift,
 				Views/Login/LNPrivacyTextView.swift,
@@ -208,6 +210,8 @@
 		};
 		FBB67E232EC48B440070E686 /* ThirdParty */ = {
 			isa = PBXFileSystemSynchronizedRootGroup;
+			exceptions = (
+			);
 			path = ThirdParty;
 			sourceTree = "<group>";
 		};
@@ -358,14 +362,10 @@
 			inputFileListPaths = (
 				"${PODS_ROOT}/Target Support Files/Pods-Lanu/Pods-Lanu-resources-${CONFIGURATION}-input-files.xcfilelist",
 			);
-			inputPaths = (
-			);
 			name = "[CP] Copy Pods Resources";
 			outputFileListPaths = (
 				"${PODS_ROOT}/Target Support Files/Pods-Lanu/Pods-Lanu-resources-${CONFIGURATION}-output-files.xcfilelist",
 			);
-			outputPaths = (
-			);
 			runOnlyForDeploymentPostprocessing = 0;
 			shellPath = /bin/sh;
 			shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Lanu/Pods-Lanu-resources.sh\"\n";
@@ -401,14 +401,10 @@
 			inputFileListPaths = (
 				"${PODS_ROOT}/Target Support Files/Pods-Lanu/Pods-Lanu-frameworks-${CONFIGURATION}-input-files.xcfilelist",
 			);
-			inputPaths = (
-			);
 			name = "[CP] Embed Pods Frameworks";
 			outputFileListPaths = (
 				"${PODS_ROOT}/Target Support Files/Pods-Lanu/Pods-Lanu-frameworks-${CONFIGURATION}-output-files.xcfilelist",
 			);
-			outputPaths = (
-			);
 			runOnlyForDeploymentPostprocessing = 0;
 			shellPath = /bin/sh;
 			shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Lanu/Pods-Lanu-frameworks.sh\"\n";

+ 6 - 0
Lanu/Assets.xcassets/IM/FromTencent/Contents.json

@@ -0,0 +1,6 @@
+{
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

+ 22 - 0
Lanu/Assets.xcassets/IM/FromTencent/msg_error_for_conv.imageset/Contents.json

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

+ 0 - 0
ThirdParty/TUIKit/TUIConversation/Resources/TUIConversation.bundle/msg_error_for_conv@2x.png → Lanu/Assets.xcassets/IM/FromTencent/msg_error_for_conv.imageset/msg_error_for_conv@2x.png


+ 0 - 0
ThirdParty/TUIKit/TUIConversation/Resources/TUIConversation.bundle/msg_error_for_conv@3x.png → Lanu/Assets.xcassets/IM/FromTencent/msg_error_for_conv.imageset/msg_error_for_conv@3x.png


+ 22 - 0
Lanu/Assets.xcassets/IM/FromTencent/msg_sending_for_conv.imageset/Contents.json

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

+ 0 - 0
ThirdParty/TUIKit/TUIConversation/Resources/TUIConversation.bundle/msg_sending_for_conv@2x.png → Lanu/Assets.xcassets/IM/FromTencent/msg_sending_for_conv.imageset/msg_sending_for_conv@2x.png


+ 0 - 0
ThirdParty/TUIKit/TUIConversation/Resources/TUIConversation.bundle/msg_sending_for_conv@3x.png → Lanu/Assets.xcassets/IM/FromTencent/msg_sending_for_conv.imageset/msg_sending_for_conv@3x.png


+ 131 - 0
Lanu/Common/Extension/Date+Extension.swift

@@ -0,0 +1,131 @@
+//
+//  Date+Extension.swift
+//  Lanu
+//
+//  Created by OneeChan on 2025/12/14.
+//
+
+import Foundation
+
+
+extension Date {
+    // 辅助方法:格式化 "时:分"(补零,如 09:05)
+    func formattedTime() -> String {
+        let formatter = DateFormatter()
+        formatter.dateFormat = "HH:mm"
+        return formatter.string(from: self)
+    }
+    
+    // 辅助方法:格式化 "星期一"
+    func formattedWeek() -> String {
+        let formatter = DateFormatter()
+        formatter.locale = Locale.current
+        formatter.dateFormat = "EEEE"
+        return formatter.string(from: self)
+    }
+    
+    // 辅助方法:格式化 "星期 时:分"(如 星期一 09:30)
+    func formattedWeekWithTime() -> String {
+        let formatter = DateFormatter()
+        formatter.locale = Locale.current
+        formatter.dateFormat = "EEEE HH:mm"
+        return formatter.string(from: self)
+    }
+    
+    // 辅助方法:格式化 "月/日"(如 10/23)
+    func formattedDate(_ separator: String = "/") -> String {
+        let formatter = DateFormatter()
+        formatter.dateFormat = "MM\(separator)dd"
+        return formatter.string(from: self)
+    }
+    
+    // 辅助方法:格式化 "月/日 时:分"(如 10/23 14:30)
+    func formattedDateWithTime(_ separator: String = "/") -> String {
+        let formatter = DateFormatter()
+        formatter.dateFormat = "MM\(separator)dd HH:mm"
+        return formatter.string(from: self)
+    }
+    
+    // 辅助方法:格式化 "年/月/日"(如 2025/10/23)
+    func formattedFullDate(_ separator: String = "/") -> String {
+        let formatter = DateFormatter()
+        formatter.dateFormat = "yyyy\(separator)MM\(separator)dd"
+        return formatter.string(from: self)
+    }
+    
+    // 辅助方法:格式化 "年/月/日 时:分"(如 2025/10/23 14:30)
+    func formattedFullDateWithTime(_ separator: String = "/") -> String {
+        let formatter = DateFormatter()
+        formatter.dateFormat = "yyyy\(separator)MM\(separator)dd HH:mm"
+        return formatter.string(from: self)
+    }
+    
+    var imTimeDesc: String {
+        let now = Date()
+        
+        let calendar = Calendar.current
+        let components = calendar.dateComponents([.year, .month, .day, .hour, .minute], from: self, to: now)
+        
+        // 1. 小于等于15分钟,显示"现在"
+        let minutesDiff = (components.minute ?? 0) + (components.hour ?? 0) * 60 + (components.day ?? 0) * 1440
+        if minutesDiff <= 15 {
+            return .init(key: "Now")
+        }
+        
+        // 2. 计算时间差(秒)
+        let timeDiff = now.timeIntervalSince(self)
+        let oneDay: TimeInterval = 24 * 60 * 60
+        
+        // 3. 小于24小时且是今天
+        if timeDiff < oneDay, calendar.isDateInToday(self) {
+            return formattedTime()
+        }
+        
+        // 4. 处理日期显示逻辑(≥15分钟且≥24小时 或 小于24小时但不是今天)
+        let targetYear = calendar.component(.year, from: self)
+        let currentYear = calendar.component(.year, from: now)
+        
+        let formatter = DateFormatter()
+        // 跨年显示日月年,否则显示日月
+        if targetYear != currentYear {
+            formatter.dateFormat = "dd/MM/yyyy"
+        } else {
+            formatter.dateFormat = "dd/MM"
+        }
+        
+        return formatter.string(from: self)
+    }
+    
+    var tencentIMTimeDesc: String {
+        if self == Date.distantPast {
+            return ""
+        }
+        
+        let dateFmt = DateFormatter()
+        var calendar = Calendar.current
+        calendar.firstWeekday = 7
+        
+        let nowComponent: DateComponents = calendar.dateComponents([.day, .month, .year, .weekOfMonth], from: Date())
+        let dateComponent: DateComponents = calendar.dateComponents([.day, .month, .year, .weekOfMonth], from: self)
+        
+        if nowComponent.year == dateComponent.year {
+            if nowComponent.month == dateComponent.month {
+                if nowComponent.weekOfMonth == dateComponent.weekOfMonth {
+                    if nowComponent.day == dateComponent.day {
+                        dateFmt.dateFormat = "HH:mm";
+                    } else {
+                        dateFmt.dateFormat = "EEEE"
+                    }
+                } else {
+                    dateFmt.dateFormat = "MM/dd"
+                }
+            } else {
+                dateFmt.dateFormat = "MM/dd"
+            }
+        } else {
+            dateFmt.dateFormat = "yyyy/MM/dd"
+        }
+        
+        return dateFmt.string(from: self)
+    }
+}

+ 12 - 57
Lanu/Common/Extension/TimeInterval+Extension.swift

@@ -11,91 +11,46 @@ import Foundation
 extension TimeInterval {
     // 辅助方法:格式化 "时:分"(补零,如 09:05)
     func formattedTime() -> String {
-        let formatter = DateFormatter()
-        formatter.dateFormat = "HH:mm"
-        return formatter.string(from: Date(timeIntervalSince1970: self))
+        Date(timeIntervalSince1970: self).formattedTime()
     }
     
     // 辅助方法:格式化 "星期一"
     func formattedWeek() -> String {
-        let formatter = DateFormatter()
-        formatter.locale = Locale.current
-        formatter.dateFormat = "EEEE"
-        return formatter.string(from: Date(timeIntervalSince1970: self))
+        Date(timeIntervalSince1970: self).formattedWeek()
     }
     
     // 辅助方法:格式化 "星期 时:分"(如 星期一 09:30)
     func formattedWeekWithTime() -> String {
-        let formatter = DateFormatter()
-        formatter.locale = Locale.current
-        formatter.dateFormat = "EEEE HH:mm"
-        return formatter.string(from: Date(timeIntervalSince1970: self))
+        Date(timeIntervalSince1970: self).formattedWeekWithTime()
     }
     
     // 辅助方法:格式化 "月/日"(如 10/23)
     func formattedDate(_ separator: String = "/") -> String {
-        let formatter = DateFormatter()
-        formatter.dateFormat = "MM\(separator)dd"
-        return formatter.string(from: Date(timeIntervalSince1970: self))
+        Date(timeIntervalSince1970: self).formattedDate(separator)
     }
     
     // 辅助方法:格式化 "月/日 时:分"(如 10/23 14:30)
     func formattedDateWithTime(_ separator: String = "/") -> String {
-        let formatter = DateFormatter()
-        formatter.dateFormat = "MM\(separator)dd HH:mm"
-        return formatter.string(from: Date(timeIntervalSince1970: self))
+        Date(timeIntervalSince1970: self).formattedDateWithTime(separator)
     }
     
     // 辅助方法:格式化 "年/月/日"(如 2025/10/23)
     func formattedFullDate(_ separator: String = "/") -> String {
-        let formatter = DateFormatter()
-        formatter.dateFormat = "yyyy\(separator)MM\(separator)dd"
-        return formatter.string(from: Date(timeIntervalSince1970: self))
+        Date(timeIntervalSince1970: self).formattedFullDate(separator)
     }
     
     // 辅助方法:格式化 "年/月/日 时:分"(如 2025/10/23 14:30)
     func formattedFullDateWithTime(_ separator: String = "/") -> String {
-        let formatter = DateFormatter()
-        formatter.dateFormat = "yyyy\(separator)MM\(separator)dd HH:mm"
-        return formatter.string(from: Date(timeIntervalSince1970: self))
+        Date(timeIntervalSince1970: self).formattedFullDateWithTime(separator)
     }
 }
 
 extension TimeInterval {
     var imTimeDesc: String {
-        let now = Date()
-        
-        let targetDate = Date(timeIntervalSince1970: self)
-        let calendar = Calendar.current
-        let components = calendar.dateComponents([.year, .month, .day, .hour, .minute], from: targetDate, to: now)
-        
-        // 1. 小于等于15分钟,显示"现在"
-        let minutesDiff = (components.minute ?? 0) + (components.hour ?? 0) * 60 + (components.day ?? 0) * 1440
-        if minutesDiff <= 15 {
-            return .init(key: "Now")
-        }
-        
-        // 2. 计算时间差(秒)
-        let timeDiff = now.timeIntervalSince(targetDate)
-        let oneDay: TimeInterval = 24 * 60 * 60
-        
-        // 3. 小于24小时且是今天
-        if timeDiff < oneDay, calendar.isDateInToday(targetDate) {
-            return formattedTime()
-        }
-        
-        // 4. 处理日期显示逻辑(≥15分钟且≥24小时 或 小于24小时但不是今天)
-        let targetYear = calendar.component(.year, from: targetDate)
-        let currentYear = calendar.component(.year, from: now)
-        
-        let formatter = DateFormatter()
-        // 跨年显示日月年,否则显示日月
-        if targetYear != currentYear {
-            formatter.dateFormat = "dd/MM/yyyy"
-        } else {
-            formatter.dateFormat = "dd/MM"
-        }
-        
-        return formatter.string(from: targetDate)
+        Date(timeIntervalSince1970: self).imTimeDesc
+    }
+    
+    var tencentIMTimeDesc: String {
+        Date(timeIntervalSince1970: self).tencentIMTimeDesc
     }
 }

+ 0 - 4
Lanu/Lanu-Bridging-Header.h

@@ -9,9 +9,5 @@
 #import <TIMCommon/TIMDefine.h>
 #import <TUICore/TUICore.h>
 #import <TUICore/TUIThemeManager.h>
-#import "TUIConversationCell.h"
-#import "TUIConversationListDataProvider.h"
-#import "TUIFoldListViewController.h"
-#import "TUIConversationConfig.h"
 
 #import "GenerateTestUserSig.h"

+ 7 - 0
Lanu/Manager/GameMate/Network/LNGameMateResponse.swift

@@ -34,11 +34,17 @@ class LNGameMateListResponse: Decodable {
     var next: String = ""
 }
 
+enum LNGameCategoryType: Int, Decodable {
+    case normal = 0
+    case offline = 1
+}
+
 @AutoCodable
 class LNGameCategoryItemVO: Decodable {
     var code: String = ""
     var name: String = ""
     var icon: String = ""
+    var categoryType: LNGameCategoryType = .normal
 }
 
 @AutoCodable
@@ -46,6 +52,7 @@ class LNGameTypeItemVO: Decodable {
     var code: String = ""
     var name: String = ""
     var icon: String = ""
+    var categoryType: LNGameCategoryType = .normal
     var children: [LNGameCategoryItemVO] = []
 }
 

+ 0 - 1
Lanu/Manager/IM/LNIMManager.swift

@@ -6,7 +6,6 @@
 //
 
 import Foundation
-import TUIChat
 
 
 protocol LNIMManagerNotify {

+ 1 - 1
Lanu/Manager/IM/LNIMMessageData.swift

@@ -83,7 +83,7 @@ class LNIMMessageData: NSObject {
     static func buildDateMessage(date: Date) -> LNIMMessageData {
         let data = LNIMMessageData(imMessage: V2TIMMessage())
         data.type = .system
-        data.content = TUITool.convertDate(toStr: date)
+        data.content = date.timeIntervalSince1970.tencentIMTimeDesc
         
         return data
     }

+ 119 - 0
Lanu/Manager/IM/V2TIMConversation+Extension.swift

@@ -0,0 +1,119 @@
+//
+//  V2TIMConversation+Extension.swift
+//  Lanu
+//
+//  Created by OneeChan on 2025/12/14.
+//
+
+import Foundation
+
+
+func TIMCommonLocalizedString(_ key: String) -> String {
+    TUIGlobalization.getLocalizedString(forKey: key, bundle: TIMCommonLocalizableBundle)
+}
+
+extension V2TIMConversation {
+    var lastDisplayDate: Date? {
+        if draftText?.isEmpty == false {
+            draftTimestamp
+        } else if let lastMessage {
+            lastMessage.timestamp
+        } else {
+            Date.distantPast
+        }
+    }
+    
+    var lastDisplayString: NSMutableAttributedString? {
+        let atStr = groupAtTipString
+        let attrString = NSMutableAttributedString(string: atStr)
+        attrString.setAttributes([.foregroundColor: UIColor.systemRed], range: .init(location: 0, length: atStr.count))
+        
+        let hasRisk = lastMessage?.hasRiskContent == true
+        let isRevoked = lastMessage?.status == .MSG_STATUS_LOCAL_REVOKED
+        
+        if draftText?.count ?? 0 > 0 {
+            let draft = NSAttributedString(string: TIMCommonLocalizedString("TUIKitMessageTypeDraftFormat"), attributes: [.foregroundColor: UIColor(hex: "#FA5151")])
+            attrString.append(draft)
+            let draftContentStr = draftContent.getLocalizableStringWithFaceContent()
+            let draftContent = NSAttributedString(string: draftContentStr, attributes: [.foregroundColor: UIColor.systemGray])
+            attrString.append(draftContent)
+        } else {
+            if let lastMessage {
+                let lastMsgStr = lastMessage.displayString
+                guard let lastMsgStr else { return nil }
+                if hasRisk, !isRevoked {
+                    attrString.append(.init(string: lastMsgStr, attributes: [.foregroundColor: UIColor(hex: "#E94444")]))
+                } else {
+                    attrString.append(.init(string: lastMsgStr))
+                }
+            }
+        }
+        
+        if groupType == GroupType_Meeting,
+           recvOpt == .RECEIVE_NOT_NOTIFY_MESSAGE,
+           unreadCount > 0 {
+            let unreadStr = NSAttributedString(string: String(format: "[%d %@]", unreadCount, TIMCommonLocalizedString("TUIKitMessageTypeLastMsgCountFormat")))
+            attrString.insert(unreadStr, at: 0)
+        }
+        
+        if draftText == nil, let lastMessage,
+           lastMessage.status == .MSG_STATUS_SENDING
+            || lastMessage.status == .MSG_STATUS_SEND_FAIL
+            || hasRisk,
+           !isRevoked {
+            let font = UIFont.systemFont(ofSize: 14)
+            let spaceStr = NSAttributedString(string: " ", attributes: [.font: font])
+            attrString.insert(spaceStr, at: 0)
+            
+            let image: UIImage! = if lastMessage.status == .MSG_STATUS_SENDING {
+                .init(named: "msg_sending_for_conv")
+            } else {
+                .init(named: "msg_error_for_conv")
+            }
+            let attachment = NSTextAttachment(image: image)
+            attachment.bounds = .init(x: 0, y: -(font.lineHeight - font.pointSize) / 2, width: font.pointSize, height: font.pointSize)
+            let imageStr = NSAttributedString(attachment: attachment)
+            attrString.insert(imageStr, at: 0)
+        }
+        
+        return attrString
+    }
+}
+
+extension V2TIMConversation {
+    private var groupAtTipString: String {
+        var atMe = false
+        var atAll = false
+        self.groupAtInfolist?.forEach {
+            switch ($0.atType) {
+            case .AT_ME: atMe = true
+            case .AT_ALL: atAll = true
+            case .AT_ALL_AT_ME:
+                atMe = true
+                atAll = true
+            default:
+                break
+            }
+        }
+        var atTipsStr = ""
+        if atMe, !atAll {
+            atTipsStr = TIMCommonLocalizedString("TUIKitConversationTipsAtMe")
+        }
+        if !atMe, atAll {
+            atTipsStr = TIMCommonLocalizedString("TUIKitConversationTipsAtAll")
+        }
+        if atMe, atAll {
+            atTipsStr = TIMCommonLocalizedString("TUIKitConversationTipsAtMeAndAll")
+        }
+        
+        return atTipsStr
+    }
+    
+    private var draftContent: String {
+        guard let draftText, !draftText.isEmpty else { return "" }
+        guard let data = draftText.data(using: .utf8) else { return "" }
+        let jsonDic = try? JSONSerialization.jsonObject(with: data, options: .mutableLeaves) as? [String: String]
+        
+        return jsonDic?["content"] ?? ""
+    }
+}

+ 223 - 0
Lanu/Manager/IM/V2TIMMessage+Extension.swift

@@ -0,0 +1,223 @@
+//
+//  V2TIMMessage+Extension.swift
+//  Lanu
+//
+//  Created by OneeChan on 2025/12/14.
+//
+
+import Foundation
+
+
+extension V2TIMMessage {
+    var displayString: String? {
+        let hasRisk = hasRiskContent
+        let isRevoked = status == .MSG_STATUS_LOCAL_REVOKED
+        if hasRisk, !isRevoked {
+            return TIMCommonLocalizedString("TUIKitMessageDisplayRiskContent")
+        }
+        if isRevoked {
+            return revokeDisplayString
+        }
+        
+        return displayStringForMessageElement
+    }
+    
+    private var revokeDisplayString: String? {
+        var revoker = sender
+        if let revokerInfo {
+            revoker = revokerInfo.userID
+        }
+        var content = TIMCommonLocalizedString("TUIKitMessageTipsNormalRecallMessage")
+        if revoker == sender {
+            if isSelf {
+                content = TIMCommonLocalizedString("TUIKitMessageTipsYouRecallMessage")
+            } else {
+                if userID?.isEmpty == false {
+                    content = TIMCommonLocalizedString("TUIKitMessageTipsOthersRecallMessage")
+                } else if groupID?.isEmpty == false {
+                    content = String(format: TIMCommonLocalizedString("TUIKitMessageTipsRecallMessageFormat"), showName)
+                } else { }
+            }
+        } else {
+            var userName = showName
+            if let revokerInfo {
+                userName = revokerInfo.showName()
+            }
+            content = String(format: TIMCommonLocalizedString("TUIKitMessageTipsRecallMessageFormat"), userName)
+        }
+        return content
+    }
+    
+    private var displayStringForMessageElement: String? {
+        switch elemType {
+        case .ELEM_TYPE_TEXT: textElem?.text?.getLocalizableStringWithFaceContent()
+        case .ELEM_TYPE_IMAGE: TIMCommonLocalizedString("TUIkitMessageTypeImage")
+        case .ELEM_TYPE_SOUND: TIMCommonLocalizedString("TUIKitMessageTypeVoice")
+        case .ELEM_TYPE_VIDEO: TIMCommonLocalizedString("TUIkitMessageTypeVideo")
+        case .ELEM_TYPE_FILE: TIMCommonLocalizedString("TUIkitMessageTypeFile")
+        case .ELEM_TYPE_FACE: TIMCommonLocalizedString("TUIKitMessageTypeAnimateEmoji")
+        case .ELEM_TYPE_MERGER: String(format: "[%@]", TIMCommonLocalizedString("TUIKitRelayChatHistory"))
+        case .ELEM_TYPE_GROUP_TIPS: groupTipsDisplayString
+        case .ELEM_TYPE_CUSTOM: TIMCommonLocalizedString("TUIKitMessageTipsUnsupportCustomMessage")
+        default: TIMCommonLocalizedString("TUIKitMessageTipsUnsupportCustomMessage")
+        }
+    }
+    
+    private var groupTipsDisplayString: String? {
+        guard let tips = groupTipsElem else { return nil }
+        let opUser = groupOpMemberShowName(info: tips.opMember)
+        let userList = groupUserNameList
+        var str = ""
+        
+        switch tips.type {
+        case .GROUP_TIPS_TYPE_JOIN:
+            if !opUser.isEmpty {
+                if userList.isEmpty
+                    || (userList.count == 1
+                        && opUser == userList.first) {
+                    str = String(format: TIMCommonLocalizedString("TUIKitMessageTipsJoinGroupFormat"), opUser)
+                } else {
+                    let users = userList.joined(separator: "、")
+                    str = String(format: TIMCommonLocalizedString("TUIKitMessageTipsInviteJoinGroupFormat"), opUser, users)
+                }
+            }
+        case .GROUP_TIPS_TYPE_INVITE:
+            if !userList.isEmpty {
+                let users = userList.joined(separator: "、")
+                str = String(format: TIMCommonLocalizedString("TUIKitMessageTipsInviteJoinGroupFormat"), opUser, users)
+            }
+        case .GROUP_TIPS_TYPE_QUIT:
+            if !opUser.isEmpty {
+                str = String(format: TIMCommonLocalizedString("TUIKitMessageTipsLeaveGroupFormat"), opUser)
+            }
+        case .GROUP_TIPS_TYPE_KICKED:
+            if !userList.isEmpty {
+                let users = userList.joined(separator: "、")
+                str = String(format: TIMCommonLocalizedString("TUIKitMessageTipsKickoffGroupFormat"), opUser, users)
+            }
+        case .GROUP_TIPS_TYPE_SET_ADMIN:
+            if !userList.isEmpty {
+                let users = userList.joined(separator: "、")
+                str = String(format: TIMCommonLocalizedString("TUIKitMessageTipsSettAdminFormat"), users)
+            }
+        case .GROUP_TIPS_TYPE_CANCEL_ADMIN:
+            if !userList.isEmpty {
+                let users = userList.joined(separator: "、")
+                str = String(format: TIMCommonLocalizedString("TUIKitMessageTipsCancelAdminFormat"), users)
+            }
+        case .GROUP_TIPS_TYPE_GROUP_INFO_CHANGE:
+            str = opGroupInfoChangedFormatStr(opUser: opUser, userList: userList, tips: tips)
+        case .GROUP_TIPS_TYPE_MEMBER_INFO_CHANGE:
+            tips.memberChangeInfoList.forEach { info in
+                let userId = info.userID
+                let muteTime = info.muteTime
+                let showName = if let user = tips.memberList.first(where: { $0.userID == userId }) {
+                    groupOpMemberShowName(info: user)
+                } else {
+                    ""
+                }
+                str = String(format: "%@ %@", userId?.isMyUid == true ? TIMCommonLocalizedString("You") : showName, muteTime == 0 ? TIMCommonLocalizedString("TUIKitMessageTipsUnmute") : TIMCommonLocalizedString("TUIKitMessageTipsMute"))
+            }
+        case .GROUP_TIPS_TYPE_PINNED_MESSAGE_ADDED:
+            if !opUser.isEmpty {
+                str = String(format: TIMCommonLocalizedString("TUIKitMessageTipsGroupPinMessage"), opUser)
+            }
+        case .GROUP_TIPS_TYPE_PINNED_MESSAGE_DELETED:
+            if !opUser.isEmpty {
+                str = String(format: TIMCommonLocalizedString("TUIKitMessageTipsGroupUnPinMessage"), opUser)
+            }
+        default:
+            break
+        }
+        
+        return str
+    }
+    
+    private var showName: String {
+        if let nameCard, !nameCard.isEmpty {
+            nameCard
+        } else if let friendRemark, !friendRemark.isEmpty {
+            friendRemark
+        } else if let nickName, !nickName.isEmpty {
+            nickName
+        } else {
+            sender ?? ""
+        }
+    }
+    
+    private func groupOpMemberShowName(info: V2TIMGroupMemberInfo) -> String {
+        if let nameCard = info.nameCard, !nameCard.isEmpty {
+            nameCard
+        } else if let nickName = info.nickName, !nickName.isEmpty {
+            nickName
+        } else {
+            info.userID ?? ""
+        }
+    }
+    
+    private var groupUserNameList: [String] {
+        groupTipsElem?.memberList.compactMap {
+            groupOpMemberShowName(info: $0)
+        } ?? []
+    }
+    
+    private func opGroupInfoChangedFormatStr(opUser: String, userList: [String], tips: V2TIMGroupTipsElem) -> String {
+        var str = String(format: "%@", opUser)
+        for info in tips.groupChangeInfoList {
+            switch info.type {
+            case .GROUP_INFO_CHANGE_TYPE_NAME:
+                str = String(format: TIMCommonLocalizedString("TUIkitMessageTipsEditGroupNameFormat"), str, info.value ?? "")
+            case .GROUP_INFO_CHANGE_TYPE_INTRODUCTION:
+                str = String(format: TIMCommonLocalizedString("TUIKitMessageTipsEditGroupIntroFormat"), str, info.value ?? "")
+            case .GROUP_INFO_CHANGE_TYPE_NOTIFICATION:
+                if let value = info.value, !value.isEmpty {
+                    str = String(format: TIMCommonLocalizedString("TUIKitMessageTipsEditGroupAnnounceFormat"), str, value)
+                } else {
+                    str = String(format: TIMCommonLocalizedString("TUIKitMessageTipsDeleteGroupAnnounceFormat"), str)
+                }
+            case .GROUP_INFO_CHANGE_TYPE_FACE:
+                str = String(format: TIMCommonLocalizedString("TUIKitMessageTipsEditGroupAvatarFormat"), str)
+            case .GROUP_INFO_CHANGE_TYPE_OWNER:
+                if !userList.isEmpty {
+                    str = String(format: TIMCommonLocalizedString("TUIKitMessageTipsEditGroupOwnerFormat"), str, userList.first!)
+                } else {
+                    str = String(format: TIMCommonLocalizedString("TUIKitMessageTipsEditGroupOwnerFormat"), str, info.value ?? "")
+                }
+            case .GROUP_INFO_CHANGE_TYPE_SHUT_UP_ALL:
+                if info.boolValue {
+                    str = String(format: TIMCommonLocalizedString("TUIKitSetShutupAllFormat"), opUser)
+                } else {
+                    str = String(format: TIMCommonLocalizedString("TUIKitCancelShutupAllFormat"), opUser)
+                }
+            case .GROUP_INFO_CHANGE_TYPE_GROUP_ADD_OPT:
+                let addOpt = info.intValue
+                var addOptDesc = "unknown"
+                if addOpt == V2TIMGroupAddOpt.GROUP_ADD_FORBID.rawValue {
+                    addOptDesc = TIMCommonLocalizedString("TUIKitGroupProfileJoinDisable")
+                } else if addOpt == V2TIMGroupAddOpt.GROUP_ADD_AUTH.rawValue {
+                    addOptDesc = TIMCommonLocalizedString("TUIKitGroupProfileAdminApprove")
+                } else if addOpt == V2TIMGroupAddOpt.GROUP_ADD_ANY.rawValue {
+                    addOptDesc = TIMCommonLocalizedString("TUIKitGroupProfileAutoApproval")
+                }
+                    
+                str = String(format: TIMCommonLocalizedString("TUIKitMessageTipsEditGroupAddOptFormat"), str, addOptDesc)
+            case .GROUP_INFO_CHANGE_TYPE_GROUP_APPROVE_OPT:
+                let addOpt = info.intValue
+                var addOptDesc = "unknown"
+                if addOpt == V2TIMGroupAddOpt.GROUP_ADD_FORBID.rawValue {
+                    addOptDesc = TIMCommonLocalizedString("TUIKitGroupProfileInviteDisable")
+                } else if addOpt == V2TIMGroupAddOpt.GROUP_ADD_AUTH.rawValue {
+                    addOptDesc = TIMCommonLocalizedString("TUIKitGroupProfileAdminApprove")
+                } else if addOpt == V2TIMGroupAddOpt.GROUP_ADD_ANY.rawValue {
+                    addOptDesc = TIMCommonLocalizedString("TUIKitGroupProfileAutoApproval")
+                }
+                    
+                str = String(format: TIMCommonLocalizedString("TUIKitMessageTipsEditGroupInviteOptFormat"), str, addOptDesc)
+            default:
+                break
+            }
+        }
+        
+        return str
+    }
+}

+ 2 - 0
Lanu/Views/Home/GameTab/LNHomeActivityTabItemView.swift

@@ -40,6 +40,8 @@ class LNHomeActivityTabItemView: UIView {
         cover.image = .init(named: "ic_home_game_tab_more")
         cover.contentMode = .center
         nameLabel.text = .init(key: "More")
+        nameLabel.setContentHuggingPriority(.defaultHigh, for: .horizontal)
+        nameLabel.setContentCompressionResistancePriority(.defaultHigh, for: .horizontal)
     }
     
     required init?(coder: NSCoder) {

+ 1 - 1
Lanu/Views/Home/LNHomeGameMatePanel.swift

@@ -48,7 +48,7 @@ extension LNHomeGameMatePanel: LNHomeActivityTabViewDelegate {
 extension LNHomeGameMatePanel {
     private func setupViews(_ item: LNGameTypeItemVO) {
         let tabView: UIView
-        if item.code == "0005" {
+        if item.categoryType == .offline {
             let gameTab = LNHomeActivityTabView()
             gameTab.delegate = self
             addSubview(gameTab)

+ 0 - 1
Lanu/Views/Home/LNHomeViewController.swift

@@ -8,7 +8,6 @@
 import Foundation
 import UIKit
 import SnapKit
-import TUIConversation
 
 class LNHomeViewController: LNViewController {
     private let topTab = LNHomeTopTabView()

+ 1 - 2
Lanu/Views/IM/Chat/Cells/LNIMChatBaseMessageCell.swift

@@ -8,7 +8,6 @@
 import Foundation
 import UIKit
 import SnapKit
-import TUIChat
 
 
 class LNIMChatBaseMessageCell: UITableViewCell {
@@ -71,7 +70,7 @@ class LNIMChatBaseMessageCell: UITableViewCell {
         sendStateIc.isHidden = data.imMessage.isSelf != true || data.imMessage.status != .MSG_STATUS_SEND_FAIL
         
         if let time = data.imMessage.timestamp {
-            timeLabel.text = time.timeIntervalSince1970.imTimeDesc
+            timeLabel.text = time.imTimeDesc
         }
         curItem = data
         self.viewModel = viewModel

+ 0 - 1
Lanu/Views/IM/Chat/Cells/LNIMChatImageMessageCell.swift

@@ -8,7 +8,6 @@
 import Foundation
 import UIKit
 import SnapKit
-import TUIChat
 
 
 private extension LNIMMessageData {

+ 0 - 1
Lanu/Views/IM/Chat/Cells/LNIMChatSystemMessageCell.swift

@@ -8,7 +8,6 @@
 import Foundation
 import UIKit
 import SnapKit
-import TUIChat
 
 class LNIMChatSystemMessageCell: UITableViewCell {
     private let contentLabel = UILabel()

+ 0 - 1
Lanu/Views/IM/Chat/Cells/LNIMChatTextMessageCell.swift

@@ -8,7 +8,6 @@
 import Foundation
 import UIKit
 import SnapKit
-import TUIChat
 
 class LNIMChatTextMessageCell: LNIMChatBaseMessageCell {
     private let contextLabel = UILabel()

+ 0 - 1
Lanu/Views/IM/Chat/Cells/LNIMChatUnknownMessageCell.swift

@@ -8,7 +8,6 @@
 import Foundation
 import UIKit
 import SnapKit
-import TUIChat
 
 class LNIMChatUnknownMessageCell: UITableViewCell {
     private let contentLabel = UILabel()

+ 0 - 1
Lanu/Views/IM/Chat/Cells/LNIMChatVoiceMessageCell.swift

@@ -8,7 +8,6 @@
 import Foundation
 import UIKit
 import SnapKit
-import TUIChat
 
 class LNIMChatVoiceMessageCell: LNIMChatBaseMessageCell {
     private let voiceView = UIStackView()

+ 1 - 0
Lanu/Views/IM/Chat/LNIMChatTopMenuView.swift

@@ -43,6 +43,7 @@ extension LNIMChatTopMenuView {
         guard let uid = viewModel?.userId else { return }
         let unreadCount = LNIMManager.shared.conversationList.filter { $0.userID != uid }.reduce(0) { $0 + $1.unreadCount}
         unreadLabel.text = "\(unreadCount)"
+        unreadLabel.isHidden = unreadCount == 0
     }
     
     private func updateUserOnlineStatus() {

+ 0 - 1
Lanu/Views/IM/Chat/LNIMChatViewController.swift

@@ -8,7 +8,6 @@
 import Foundation
 import UIKit
 import SnapKit
-import TUIChat
 
 
 extension UIView {

+ 4 - 1
Lanu/Views/IM/Chat/ViewModel/LNIMChatViewModel.swift

@@ -49,7 +49,10 @@ class LNIMChatViewModel: NSObject {
 // MARK: 消息管理
 extension LNIMChatViewModel {
     func updateMessageOpt(opt: V2TIMReceiveMessageOpt) {
-        
+        V2TIMManager.sharedInstance().setC2CReceiveMessageOpt(userIDList: [userId], opt: opt) { [weak self] in
+            guard let self else { return }
+            messageOpt = opt
+        }
     }
     
     private func getMessageOpt() {

+ 2 - 15
Lanu/Views/IM/ConversationList/LNIMConversationCell.swift

@@ -10,19 +10,6 @@ import UIKit
 import SnapKit
 
 
-private extension V2TIMConversation {
-    var lastDisplayDate: Date? {
-        if draftText?.isEmpty == false {
-            draftTimestamp
-        } else if let lastMessage {
-            lastMessage.timestamp
-        } else {
-            Date.distantPast
-        }
-    }
-}
-
-
 class LNIMConversationCell: UITableViewCell {
     private let avatar = UIImageView()
     private let titleLabel = UILabel()
@@ -46,8 +33,8 @@ class LNIMConversationCell: UITableViewCell {
             titleLabel.text = item.showName
             titleLabel.textColor = .text_5
         }
-        messageLabel.attributedText = TUIConversationListDataProvider.shared.getLastDisplayString(item)
-        timeLabel.text = TUITool.convertDate(toStr: item.lastDisplayDate!)
+        messageLabel.attributedText = item.lastDisplayString
+        timeLabel.text = item.lastDisplayDate?.tencentIMTimeDesc ?? ""
         
         if item.unreadCount > 0 {
             if item.unreadCount > 99 {

+ 0 - 13
Lanu/Views/IM/TUIConversationListDataProvider+Extension.swift

@@ -1,13 +0,0 @@
-//
-//  TUIConversationListDataProvider+Extension.swift
-//  Lanu
-//
-//  Created by OneeChan on 2025/12/10.
-//
-
-import Foundation
-
-
-extension TUIConversationListDataProvider {
-    static let shared = TUIConversationListDataProvider()
-}

+ 0 - 2
Podfile

@@ -8,8 +8,6 @@ target 'Lanu' do
   use_frameworks!
 
   # # 腾讯IM
-  pod 'TUIChat', :path => "./ThirdParty/TUIKit/TUIChat"
-  pod 'TUIConversation', :path => "./ThirdParty/TUIKit/TUIConversation"
   pod 'TIMCommon', :path => "./ThirdParty/TUIKit/TIMCommon"
   pod 'TUICore', :path => "./ThirdParty/TUIKit/TUICore"
   

+ 2 - 24
Podfile.lock

@@ -18,27 +18,15 @@ PODS:
     - GCDWebServer/Core
   - GCDWebServer/WebUploader (3.5.4):
     - GCDWebServer/Core
-  - Masonry (1.1.0)
   - ReactiveObjC (3.1.1)
   - SDWebImage (5.21.3):
     - SDWebImage/Core (= 5.21.3)
   - SDWebImage/Core (5.21.3)
   - TIMCommon (1.0.0):
-    - Masonry
     - ReactiveObjC
-    - SDWebImage
     - TUICore
   - TIMPush (8.7.7201):
     - TXIMSDK_Plus_iOS_XCFramework (>= 8.7.7201)
-  - TUIChat (1.0.0):
-    - ReactiveObjC
-    - SDWebImage
-    - TIMCommon
-    - TUICore
-  - TUIConversation (1.0.0):
-    - ReactiveObjC
-    - TIMCommon
-    - TUICore
   - TUICore (1.0.0):
     - SDWebImage
     - TUICore/ImSDK_Plus (= 1.0.0)
@@ -54,8 +42,6 @@ DEPENDENCIES:
   - DoraemonKit
   - TIMCommon (from `./ThirdParty/TUIKit/TIMCommon`)
   - TIMPush
-  - TUIChat (from `./ThirdParty/TUIKit/TUIChat`)
-  - TUIConversation (from `./ThirdParty/TUIKit/TUIConversation`)
   - TUICore (from `./ThirdParty/TUIKit/TUICore`)
   - TXIMSDK_Plus_iOS_XCFramework
 
@@ -64,7 +50,6 @@ SPEC REPOS:
     - DoraemonKit
     - FMDB
     - GCDWebServer
-    - Masonry
     - ReactiveObjC
     - SDWebImage
     - TIMPush
@@ -73,10 +58,6 @@ SPEC REPOS:
 EXTERNAL SOURCES:
   TIMCommon:
     :path: "./ThirdParty/TUIKit/TIMCommon"
-  TUIChat:
-    :path: "./ThirdParty/TUIKit/TUIChat"
-  TUIConversation:
-    :path: "./ThirdParty/TUIKit/TUIConversation"
   TUICore:
     :path: "./ThirdParty/TUIKit/TUICore"
 
@@ -84,16 +65,13 @@ SPEC CHECKSUMS:
   DoraemonKit: 0b45c9dc6ab34bd426a2782ee1bf7ab13492a60b
   FMDB: 728731dd336af3936ce00f91d9d8495f5718a0e6
   GCDWebServer: 2c156a56c8226e2d5c0c3f208a3621ccffbe3ce4
-  Masonry: 678fab65091a9290e40e2832a55e7ab731aad201
   ReactiveObjC: 011caa393aa0383245f2dcf9bf02e86b80b36040
   SDWebImage: 16309af6d214ba3f77a7c6f6fdda888cb313a50a
-  TIMCommon: 5a716eda26c177556be02dd4932ea73a66efd6ba
+  TIMCommon: 6d2d9da7cd19efe5aabef4e237eb208df62235d7
   TIMPush: 4f4fa655697c4106309054d0b50a485e642b4f80
-  TUIChat: 74fc0a4bf0ccaa3998f69068ac31ac77238e4faa
-  TUIConversation: 7352e1f4835d24c09c302f756ad5b74d98bb1270
   TUICore: c1e480d7644ad9efb0db8c353e26ff39d7e4933b
   TXIMSDK_Plus_iOS_XCFramework: 3b435eae84c639f35ae8dc9c8b92c399a8b0a67f
 
-PODFILE CHECKSUM: e572b89b92959c73e2693d353cd3268923dc207d
+PODFILE CHECKSUM: 6159bb63027e2bf4fe49c25713af73bccb835746
 
 COCOAPODS: 1.16.2

+ 0 - 249
ThirdParty/TUIKit/TIMCommon/BaseCell/TUIMessageCell.h

@@ -1,249 +0,0 @@
-
-//  Created by Tencent on 2023/06/09.
-//  Copyright © 2023 Tencent. All rights reserved.
-/**
- *
- *
- *  This document declares the modules and components used to implement the message unit.
- *  The message unit (TUIMessageCell) is a general term for the bubble message/picture message/emoticon message/video message displayed in the chat view.
- *  The above messages are implemented by inheriting from this class or a subclass of this class. If you want to customize the message, you also need to
- * implement it by inheriting from this class or a subclass of this class. The XXXX message unit (TUIXXXXMessageCell) is mainly responsible for displaying on
- * the page and responding to user interaction events. For data processing and acquisition in the message unit, please refer to
- * TUIChat\CellData\TUIXXXXMessageCellData.h according to the specific message unit
- *
- *  The interaction callbacks provided by the TUIMessageCellDelegate protocol include: long press, resend, click on the message, click on the avatar, etc.
- *  The TUIMessageCell class stores message-related information, such as the sender's avatar, sender's nickname, and message content (supports various formats
- * such as text, pictures, and videos). At the same time, TUIMessageeCell, as a parent class, provides basic properties and behavior templates for subclass
- * messages.
- */
-
-#import <UIKit/UIKit.h>
-#import "TUIFitButton.h"
-#import "TUIMessageCellData.h"
-#import "TUISecurityStrikeView.h"
-
-
-@class TUIMessageCell;
-
-
-@protocol TUIMessageCellProtocol <NSObject>
-
-@required
-+ (CGFloat)getHeight:(TUIMessageCellData *)data withWidth:(CGFloat)width;
-+ (CGFloat)getEstimatedHeight:(TUIMessageCellData *)data;
-+ (CGSize)getContentSize:(TUIMessageCellData *)data;
-
-@end
-
-
-/////////////////////////////////////////////////////////////////////////////////
-//
-//                              TUIMessageCellDelegate
-//
-/////////////////////////////////////////////////////////////////////////////////
-
-@protocol TUIMessageCellDelegate <NSObject>
-
-/**
- *  Callback for long press message
- *  You can use this callback to implement secondary operations such as delete and recall (when the sender of the message long-presses his own message) on top
- * of the long-pressed message.
- */
-- (void)onLongPressMessage:(TUIMessageCell *)cell;
-
-/**
- *  Callback for clicking retryView
- *  You can use this callback to implement: resend the message.
- */
-- (void)onRetryMessage:(TUIMessageCell *)cell;
-
-/**
- *  Callback for clicking message cell
- *  Usually:
- *  - Clicking on the sound message means playing voice
- *  - Clicking on the file message means opening the file
- *  - Clicking on the picture message means showing the larger image
- *  - Clicking on the video message means playing the video.
- *  Usually, it only provides a reference for the function implementation, and you can implement the delegate function according to your needs.
- */
-- (void)onSelectMessage:(TUIMessageCell *)cell;
-
-/**
- *  Callback for clicking avatar view of the messageCell
- *  You can use this callback to implement: in response to the user's click, jump to the detailed information interface of the corresponding user.
- */
-- (void)onSelectMessageAvatar:(TUIMessageCell *)cell;
-
-/**
- *  Callback for long pressing avatar view of messageCell
- */
-- (void)onLongSelectMessageAvatar:(TUIMessageCell *)cell;
-
-/**
- *  Callback for clicking read receipt label
- */
-- (void)onSelectReadReceipt:(TUIMessageCellData *)cell;
-
-/**
- * Clicking the x-person reply button to jump to the multi-person reply details page
- */
-- (void)onJumpToRepliesDetailPage:(TUIMessageCellData *)data;
-
-
-- (void)onJumpToMessageInfoPage:(TUIMessageCellData *)data selectCell:(TUIMessageCell *)cell;
-
-@end
-
-/////////////////////////////////////////////////////////////////////////////////
-//
-//                              TUIMessageCell
-//
-/////////////////////////////////////////////////////////////////////////////////
-
-@interface TUIMessageCell : TUICommonTableViewCell <TUIMessageCellProtocol>
-
-/**
- * Icon that identifies the message selected
- * In the multi-selection scenario, it is used to identify whether the message is selected
- */
-@property(nonatomic, strong) UIImageView *selectedIcon;
-
-/**
- * Message selection view
- * When multiple selection is activated, the view will be overlaid on this cell, and clicking on the view will trigger the check/uncheck of the message
- */
-@property(nonatomic, strong) UIButton *selectedView;
-
-/**
- *  
- *  The icon view of displays user's avatar
- */
-@property(nonatomic, strong) UIImageView *avatarView;
-
-/**
- *  
- *  The label of displays user's displayname
- */
-@property(nonatomic, strong) UILabel *nameLabel;
-
-/**
- *  Container view
- *  It wraps various views of MesageCell as the "bottom" of MessageCell, which is convenient for view management and layout.
- */
-@property(nonatomic, strong) UIView *container;
-
-/**
- *  Activity indicator
- *  A circling icon is provided while the message is being sent to indicate that the message is being sent.
- */
-@property(nonatomic, strong) UIActivityIndicatorView *indicator;
-
-/**
- *  Retry view, displayed after sending failed, click on this view to trigger onRetryMessage: callback.
- */
-@property(nonatomic, strong) UIImageView *retryView;
-
-
-/**
- *  security Strike View
- */
-@property (nonatomic, strong) TUISecurityStrikeView * securityStrikeView;
-
-/**
- *  Message reply details button
- */
-@property(nonatomic, strong) TUIFitButton *messageModifyRepliesButton;
-
-/**
- * The message data class which stores the information required in the messageCell, including sender ID, sender avatar, message sending status, message bubble
- * icon, etc. For details of messageData, please refer to: TUIChat\Cell\CellData\TUIMessageCellData.h
- */
-@property(readonly) TUIMessageCellData *messageData;
-
-/**
- *  A control that identifies whether a message has been read
- */
-@property(nonatomic, strong) UILabel *readReceiptLabel;
-
-/**
- * The message time label control, which is not displayed by default, is located at the far right of the message cell
- * In the message forwarding scenario, open the forwarded message list, and the time of the current message will be displayed on the far right of the message.
- */
-@property(nonatomic, strong) UILabel *timeLabel;
-
-/**
- * Whether to disable the default selection behavior encapsulated in TUIKit, such as group live broadcast by default to create live room and other behaviors,
- * default: NO
- */
-@property(nonatomic, assign) BOOL disableDefaultSelectAction;
-
-@property(nonatomic, weak) id<TUIMessageCellDelegate> delegate;
-
-/**
- * 
- * Whether the highlight flashing animation is in progress
- */
-@property(nonatomic, assign) BOOL highlightAnimating;
-
-- (void)fillWithData:(TUICommonCellData *)data;
-
-/**
- * Set the highlighting effect after matching the keyword, mainly used for jumping after message search, subclass rewriting
- * The base class provides the default highlighting effect, and the subclass can implement it freely
- *
- * @param keyword  Highlight keywords
- */
-- (void)highlightWhenMatchKeyword:(NSString *)keyword;
-
-/**
- * Returns the view for highlighting
- */
-- (UIView *)highlightAnimateView;
-
-/**
- * Update the content of the read label
- */
-- (void)updateReadLabelText;
-
-/// Preset bottom container in cell, which can be added custom view/viewControllers.
-@property(nonatomic, strong) UIView *bottomContainer;
-
-/// When bottom container is layout ready, notify it to add custom extensions.
-- (void)notifyBottomContainerReadyOfData:(TUIMessageCellData *)cellData;
-
-/// Callback of SelectCell
-@property(nonatomic, copy) TUIValueCallbck pluginMsgSelectCallback;
-
-@end
-
-
-@interface TUIMessageCell (TUILayoutConfiguration)
-
-/**
- *  The color of the label that displays the recipient's nickname
- *  Used when the nickname needs to be displayed and the message direction is MsgDirectionIncoming
- */
-@property(nonatomic, class) UIColor *incommingNameColor;
-
-/**
- *
- *  The font of the label that displays the recipient's nickname
- *  Used when the nickname needs to be displayed and the message direction is MsgDirectionIncoming
- *
- */
-@property(nonatomic, class) UIFont *incommingNameFont;
-
-/**
- *  The color of the label showing the sender's nickname
- *  Used when the nickname needs to be displayed and the message direction is MsgDirectionOutgoing.
- */
-@property(nonatomic, class) UIColor *outgoingNameColor;
-
-/**
- *
- *  The font of the label that displays the sender's nickname
- *  Used when the nickname needs to be displayed and the message direction is MsgDirectionOutgoing.
- */
-@property(nonatomic, class) UIFont *outgoingNameFont;
-
-@end

+ 0 - 680
ThirdParty/TUIKit/TIMCommon/BaseCell/TUIMessageCell.m

@@ -1,680 +0,0 @@
-//
-//  TUIMessageCell.m
-//  UIKit
-//
-//  Created by kennethmiao on 2018/9/17.
-//  Copyright © 2018 Tencent. All rights reserved.
-//
-
-#import "TUIMessageCell.h"
-#import <TIMCommon/TIMDefine.h>
-#import <TUICore/TUIThemeManager.h>
-#import <TUICore/TUITool.h>
-#import "NSString+TUIEmoji.h"
-#import "TUISystemMessageCellData.h"
-#import <TUICore/TUICore.h>
-
-@interface TUIMessageCell () <CAAnimationDelegate>
-@property(nonatomic, strong) TUIMessageCellData *messageData;
-
-@end
-
-@implementation TUIMessageCell
-
-#pragma mark - Life cycle
-- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
-    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
-    if (self) {
-        [self setupSubViews];
-        [self setupRAC];
-    }
-    return self;
-}
-
-- (void)setupSubViews {
-    // head
-    _avatarView = [[UIImageView alloc] init];
-    _avatarView.contentMode = UIViewContentModeScaleAspectFit;
-    [self.contentView addSubview:_avatarView];
-    UITapGestureRecognizer *tap1 = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onSelectMessageAvatar:)];
-    [_avatarView addGestureRecognizer:tap1];
-    UILongPressGestureRecognizer *tap2 = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(onLongSelectMessageAvatar:)];
-    [_avatarView addGestureRecognizer:tap2];
-    [_avatarView setUserInteractionEnabled:YES];
-
-    // nameLabel
-    _nameLabel = [[UILabel alloc] init];
-    _nameLabel.font = [self fontWithSize:13];
-    _nameLabel.textColor = [UIColor d_systemGrayColor];
-    [self.contentView addSubview:_nameLabel];
-
-    // container
-    _container = [[UIView alloc] init];
-    _container.backgroundColor = [UIColor clearColor];
-    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onSelectMessage:)];
-    tap.cancelsTouchesInView = NO;
-    [_container addGestureRecognizer:tap];
-    UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(onLongPress:)];
-    [_container addGestureRecognizer:longPress];
-    [self.contentView addSubview:_container];
-
-    // indicator
-    _indicator = [[UIActivityIndicatorView alloc] init];
-    _indicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyleGray;
-    [_indicator sizeToFit];
-    [self.contentView addSubview:_indicator];
-
-    // error
-    _retryView = [[UIImageView alloc] init];
-    _retryView.userInteractionEnabled = YES;
-    UITapGestureRecognizer *resendTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onRetryMessage:)];
-    [_retryView addGestureRecognizer:resendTap];
-    [self.contentView addSubview:_retryView];
-
-    // messageModifyRepliesLabel
-    _messageModifyRepliesButton = [[TUIFitButton alloc] initWithFrame:CGRectMake(0, 0, 12, 12)];
-    _messageModifyRepliesButton.imageSize = CGSizeMake(12, 12);
-    [_messageModifyRepliesButton addTarget:self action:@selector(onJumpToRepliesDetailPage:) forControlEvents:UIControlEventTouchUpInside];
-    [_messageModifyRepliesButton.titleLabel setFont:[self fontWithSize:12]];
-    [_messageModifyRepliesButton setTitleColor:TIMCommonDynamicColor(@"chat_message_read_name_date_text_color", @"#999999") forState:UIControlStateNormal];
-    [_messageModifyRepliesButton setImage:TIMCommonBundleThemeImage(@"chat_messageReplyIcon_img", @"messageReplyIcon") forState:UIControlStateNormal];
-    [self.contentView addSubview:_messageModifyRepliesButton];
-
-    _readReceiptLabel = [[UILabel alloc] init];
-    _readReceiptLabel.hidden = YES;
-    _readReceiptLabel.font = [self fontWithSize:12];
-    _readReceiptLabel.textColor = TIMCommonDynamicColor(@"chat_message_read_status_text_gray_color", @"#BBBBBB");
-    _readReceiptLabel.lineBreakMode = NSLineBreakByCharWrapping;
-    UITapGestureRecognizer *showReadReceiptTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onSelectReadReceipt:)];
-    [_readReceiptLabel addGestureRecognizer:showReadReceiptTap];
-    _readReceiptLabel.userInteractionEnabled = YES;
-    [self.contentView addSubview:_readReceiptLabel];
-
-    // selectedIcon
-    _selectedIcon = [[UIImageView alloc] init];
-    [self.contentView addSubview:_selectedIcon];
-
-    // selectedView
-    _selectedView = [UIButton buttonWithType:UIButtonTypeCustom];
-    _selectedView.backgroundColor = [UIColor clearColor];
-    [_selectedView addTarget:self action:@selector(onSelectMessage:) forControlEvents:UIControlEventTouchUpInside];
-    [self.contentView addSubview:_selectedView];
-
-    // timeLabel
-    _timeLabel = [[UILabel alloc] init];
-    _timeLabel.textColor = [UIColor darkGrayColor];
-    _timeLabel.font = [self fontWithSize:11.0];
-    [self.contentView addSubview:_timeLabel];
-
-    self.selectionStyle = UITableViewCellSelectionStyleNone;
-    self.backgroundColor = UIColor.clearColor;
-    self.contentView.backgroundColor = UIColor.clearColor;
-    
-    [self makeConstraints];
-}
-
-- (void)makeConstraints {
-    
-    [self.nameLabel mas_makeConstraints:^(MASConstraintMaker *make) {
-        make.leading.mas_equalTo(_container.mas_leading).mas_offset(7);
-        make.top.mas_equalTo(self.avatarView.mas_top);
-        make.width.mas_equalTo(1);
-        make.height.mas_equalTo(20);
-    }];
-    
-    [self.selectedIcon mas_makeConstraints:^(MASConstraintMaker *make) {
-        make.leading.mas_equalTo(self.contentView.mas_leading).mas_offset(3);
-        make.top.mas_equalTo(self.avatarView.mas_centerY).mas_offset(-10);
-        make.width.mas_equalTo(20);
-        make.height.mas_equalTo(20);
-    }];
-
-    [self.timeLabel mas_makeConstraints:^(MASConstraintMaker *make) {
-        make.trailing.mas_equalTo(self.contentView.mas_trailing).mas_offset(-10);
-        make.top.mas_equalTo(self.avatarView);
-        make.width.mas_greaterThanOrEqualTo(10);
-        make.height.mas_equalTo(10);
-    }];
-    
-    [self.selectedView mas_makeConstraints:^(MASConstraintMaker *make) {
-        make.edges.mas_equalTo(self.contentView);
-    }];
-
-}
-
-+ (BOOL)requiresConstraintBasedLayout {
-    return YES;
-}
-
-// this is Apple's recommended place for adding/updating constraints
-- (void)updateConstraints {
-    TUIMessageCellLayout *cellLayout = self.messageData.cellLayout;
-    BOOL isInComing = (self.messageData.direction == MsgDirectionIncoming);
-
-    [self.nameLabel mas_remakeConstraints:^(MASConstraintMaker *make) {
-        if (isInComing) {
-            make.leading.mas_equalTo(_container.mas_leading).mas_offset(7);
-            make.trailing.mas_equalTo(self.contentView).mas_offset(-7);
-        } else {
-            make.leading.mas_equalTo(self.contentView).mas_offset(7);
-            make.trailing.mas_equalTo(self.container.mas_trailing);
-        }
-        if (self.messageData.showName) {
-            make.width.mas_greaterThanOrEqualTo(20);
-            make.height.mas_greaterThanOrEqualTo(20);
-        } else {
-            make.height.mas_equalTo(0);
-        }
-        make.top.mas_equalTo(self.avatarView.mas_top);
-    }];
-
-    [self.selectedIcon mas_updateConstraints:^(MASConstraintMaker *make) {
-        if (self.messageData.showCheckBox) {
-            make.width.mas_equalTo(20);
-            make.height.mas_equalTo(20);
-        } else {
-            make.size.mas_equalTo(CGSizeZero);
-        }
-    }];
-
-    [self.timeLabel sizeToFit];
-    [self.timeLabel mas_updateConstraints:^(MASConstraintMaker *make) {
-        if (self.messageData.showMessageTime) {
-            make.width.mas_equalTo(self.timeLabel.frame.size.width);
-            make.height.mas_equalTo(self.timeLabel.frame.size.height);
-        } else {
-            make.width.mas_equalTo(0);
-            make.height.mas_equalTo(0);
-        }
-    }];
-
-    CGSize csize = [self.class getContentSize:self.messageData];
-    CGFloat contentWidth = csize.width;
-    CGFloat contentHeight = csize.height;
-
-    if (!CGSizeEqualToSize(self.messageData.messageContainerAppendSize, CGSizeZero)) {
-        /**
-         * Taking the maximum width between the "emoji reply message" and the text content
-         */
-        contentWidth = MAX(self.messageData.messageContainerAppendSize.width, csize.width);
-        /**
-         * Limit the maximum width to Screen_Width *0.25 * 3
-         */
-        contentWidth = MIN(contentWidth, Screen_Width * 0.25 * 3);
-        contentHeight = csize.height + self.messageData.messageContainerAppendSize.height;
-    }
-    if (self.messageData.direction == MsgDirectionIncoming) {
-        self.avatarView.hidden = !self.messageData.showAvatar;
-        [self.avatarView mas_remakeConstraints:^(MASConstraintMaker *make) {
-          if (self.messageData.showCheckBox) {
-              make.leading.mas_equalTo(self.selectedIcon.mas_trailing).mas_offset(cellLayout.avatarInsets.left);
-          } else {
-              make.leading.mas_equalTo(self.contentView.mas_leading).mas_offset(cellLayout.avatarInsets.left);
-          }
-          make.top.mas_equalTo(cellLayout.avatarInsets.top);
-          make.size.mas_equalTo(cellLayout.avatarSize);
-        }];
-
-        [self.container mas_remakeConstraints:^(MASConstraintMaker *make) {
-          make.leading.mas_equalTo(self.avatarView.mas_trailing).mas_offset(cellLayout.messageInsets.left);
-          make.top.mas_equalTo(self.nameLabel.mas_bottom).mas_offset(cellLayout.messageInsets.top);
-          make.width.mas_equalTo(contentWidth);
-          make.height.mas_equalTo(contentHeight);
-        }];
-
-        CGRect indicatorFrame = self.indicator.frame;
-        [self.indicator mas_remakeConstraints:^(MASConstraintMaker *make) {
-          make.leading.mas_equalTo(self.container.mas_trailing).mas_offset(8);
-          make.centerY.mas_equalTo(self.container.mas_centerY);
-          make.size.mas_equalTo(indicatorFrame.size);
-        }];
-        self.retryView.frame = self.indicator.frame;
-        self.readReceiptLabel.hidden = YES;
-    } else {
-        if (!self.messageData.showAvatar) {
-            cellLayout.avatarSize = CGSizeZero;
-        } 
-        [self.avatarView mas_remakeConstraints:^(MASConstraintMaker *make) {
-          make.trailing.mas_equalTo(self.contentView.mas_trailing).mas_offset(-cellLayout.avatarInsets.right);
-          make.top.mas_equalTo(cellLayout.avatarInsets.top);
-          make.size.mas_equalTo(cellLayout.avatarSize);
-        }];
-        [self.container mas_remakeConstraints:^(MASConstraintMaker *make) {
-          make.trailing.mas_equalTo(self.avatarView.mas_leading).mas_offset(-cellLayout.messageInsets.right);
-          make.top.mas_equalTo(self.nameLabel.mas_bottom).mas_offset(cellLayout.messageInsets.top);
-          make.width.mas_equalTo(contentWidth);
-          make.height.mas_equalTo(contentHeight);
-        }];
-
-        CGRect indicatorFrame = self.indicator.frame;
-        [self.indicator mas_remakeConstraints:^(MASConstraintMaker *make) {
-          make.trailing.mas_equalTo(self.container.mas_leading).mas_offset(-8);
-          make.centerY.mas_equalTo(self.container.mas_centerY);
-          make.size.mas_equalTo(indicatorFrame.size);
-        }];
-
-        self.retryView.frame = self.indicator.frame;
-
-        [self.readReceiptLabel sizeToFit];
-        [self.readReceiptLabel mas_remakeConstraints:^(MASConstraintMaker *make) {
-          make.bottom.mas_equalTo(self.container.mas_bottom);
-          make.trailing.mas_equalTo(self.container.mas_leading).mas_offset(-8);
-          make.size.mas_equalTo(self.readReceiptLabel.frame.size);
-        }];
-    }
-
-    if (!self.messageModifyRepliesButton.isHidden) {
-        self.messageModifyRepliesButton.mm_sizeToFit();
-        CGFloat repliesBtnTextWidth = self.messageModifyRepliesButton.frame.size.width;
-        [self.messageModifyRepliesButton mas_remakeConstraints:^(MASConstraintMaker *make) {
-          if (isInComing) {
-              make.leading.mas_equalTo(self.container.mas_leading);
-          } else {
-              make.trailing.mas_equalTo(self.container.mas_trailing);
-          }
-          make.top.mas_equalTo(self.container.mas_bottom);
-          make.size.mas_equalTo(CGSizeMake(repliesBtnTextWidth + 10, 30));
-        }];
-    }
-
-
-    // according to apple super should be called at end of method
-    [super updateConstraints];
-}
-
-- (void)layoutSubviews {
-    [super layoutSubviews];
-}
-
-- (void)setupRAC {
-    @weakify(self);
-    [RACObserve(self, readReceiptLabel.text) subscribeNext:^(id _Nullable x) {
-      @strongify(self);
-      if ([self shouldHighlightReadReceiptLabel]) {
-          self.readReceiptLabel.textColor = TIMCommonDynamicColor(@"chat_message_read_status_text_color", @"#147AFF");
-      } else {
-          self.readReceiptLabel.textColor = TIMCommonDynamicColor(@"chat_message_read_status_text_gray_color", @"#BBBBBB");
-      }
-    }];
-}
-
-- (void)prepareForReuse {
-    [super prepareForReuse];
-    /**
-     * In the future, any UI problems caused by reuse can be solved by coding here.
-     */
-
-    /**
-     * Once the message is reused, it means that a new message is about to appear, and the label content is changed to empty string.
-     */
-    _readReceiptLabel.text = @"";
-    _readReceiptLabel.hidden = YES;
-}
-
-#pragma mark - Public
-- (void)fillWithData:(TUIMessageCellData *)data {
-    [super fillWithData:data];
-    self.messageData = data;
-
-    [self loadAvatar:data];
-
-    if (self.messageData.showName) {
-        _nameLabel.hidden = NO;
-    } else {
-        _nameLabel.hidden = YES;
-    }
-
-    if (self.messageData.showCheckBox) {
-        _selectedIcon.hidden = NO;
-        _selectedView.hidden = NO;
-    } else {
-        _selectedIcon.hidden = YES;
-        _selectedView.hidden = YES;
-    }
-
-    if ([TUIConfig defaultConfig].avatarType == TAvatarTypeRounded) {
-        self.avatarView.layer.masksToBounds = YES;
-        self.avatarView.layer.cornerRadius = data.cellLayout.avatarSize.height / 2;
-    } else if ([TUIConfig defaultConfig].avatarType == TAvatarTypeRadiusCorner) {
-        self.avatarView.layer.masksToBounds = YES;
-        self.avatarView.layer.cornerRadius = [TUIConfig defaultConfig].avatarCornerRadius;
-    }
-
-    self.nameLabel.text = data.senderName;
-    
-    if (data.direction == MsgDirectionIncoming) {
-        self.nameLabel.textColor = self.class.incommingNameColor;
-        self.nameLabel.font = self.class.incommingNameFont;
-    } else {
-        self.nameLabel.textColor = self.class.outgoingNameColor;
-        self.nameLabel.font = self.class.outgoingNameFont;
-    }
-
-
-    self.retryView.image = [UIImage imageNamed:TUIChatImagePath(@"msg_error")];
-
-    if (data.status == Msg_Status_Fail) {
-        [_indicator stopAnimating];
-        _readReceiptLabel.hidden = YES;
-        self.retryView.hidden = NO;
-    } else {
-        if (data.status == Msg_Status_Sending_2) {
-            [_indicator startAnimating];
-            _readReceiptLabel.hidden = YES;
-        } else if (data.status == Msg_Status_Succ) {
-            [_indicator stopAnimating];
-            /**
-             * The message is sent successfully, indicating that the indicator and error are no longer displayed on the label, and the read receipt label can be
-             * displayed.
-             */
-            if (self.messageData.showReadReceipt && self.messageData.direction == MsgDirectionOutgoing && self.messageData.innerMessage.needReadReceipt &&
-                (self.messageData.innerMessage.userID || self.messageData.innerMessage.groupID) &&
-                ![self.messageData isKindOfClass:TUISystemMessageCellData.class]) {
-                [self updateReadLabelText];
-                _readReceiptLabel.hidden = NO;
-            }
-        } else if (data.status == Msg_Status_Sending) {
-            [_indicator startAnimating];
-            _readReceiptLabel.hidden = YES;
-        }
-        self.retryView.hidden = YES;
-    }
-
-    self.messageModifyRepliesButton.hidden = !data.showMessageModifyReplies;
-    if (data.showMessageModifyReplies) {
-        NSString *title = [NSString stringWithFormat:@"%ld%@", data.messageModifyReplies.count, TIMCommonLocalizableString(TUIKitRepliesNum)];
-        [self.messageModifyRepliesButton setTitle:title forState:UIControlStateNormal];
-        [self.messageModifyRepliesButton sizeToFit];
-        [self.messageModifyRepliesButton setNeedsUpdateConstraints];
-        [self.messageModifyRepliesButton updateConstraintsIfNeeded];
-        [self.messageModifyRepliesButton layoutIfNeeded];
-    }
-
-    NSString *imageName = (data.showCheckBox && data.selected) ? TIMCommonImagePath(@"icon_select_selected") : TIMCommonImagePath(@"icon_select_normal");
-    self.selectedIcon.image = [UIImage imageNamed:imageName];
-
-    _timeLabel.text = [TUITool convertDateToStr:data.innerMessage.timestamp];
-    [_timeLabel sizeToFit];
-    _timeLabel.hidden = !data.showMessageTime;
-
-    /**
-     * Text highlighting - asynchronous operations are here to keep the order of execution consistent with subclasses
-     */
-    __weak typeof(self) weakSelf = self;
-    dispatch_async(dispatch_get_main_queue(), ^{
-      [weakSelf highlightWhenMatchKeyword:data.highlightKeyword];
-    });
-    
-    // tell constraints they need updating
-    [self setNeedsUpdateConstraints];
-
-    // update constraints now so we can animate the change
-    [self updateConstraintsIfNeeded];
-
-    [self layoutIfNeeded];
-
-}
-
-- (void)loadAvatar:(TUIMessageCellData *)data {
-    [self.avatarView setImage:DefaultAvatarImage];
-    @weakify(self);
-    [[[RACObserve(data, avatarUrl) takeUntil:self.rac_prepareForReuseSignal] ignore:nil] subscribeNext:^(NSURL *url) {
-      @strongify(self);
-      [self.avatarView sd_setImageWithURL:url placeholderImage:DefaultAvatarImage];
-    }];
-
-    if (data.isUseMsgReceiverAvatar) {
-        NSString *userId = @"";
-        if ([data.innerMessage.sender isEqualToString:V2TIMManager.sharedInstance.getLoginUser]) {
-            userId = data.innerMessage.userID;
-        } else {
-            userId = V2TIMManager.sharedInstance.getLoginUser;
-        }
-
-        [V2TIMManager.sharedInstance getUsersInfo:@[ userId?:@"" ]
-                                             succ:^(NSArray<V2TIMUserFullInfo *> *infoList) {
-                                               @strongify(self);
-                                               V2TIMUserFullInfo *info = infoList.firstObject;
-                                               if (info && [data isEqual:self.messageData]) {
-                                                   data.avatarUrl = [NSURL URLWithString:info.faceURL];
-                                                   [self.avatarView sd_setImageWithURL:data.avatarUrl placeholderImage:DefaultAvatarImage];
-                                               }
-                                             }
-                                             fail:^(int code, NSString *desc){
-
-                                             }];
-    }
-}
-
-- (void)highlightWhenMatchKeyword:(NSString *)keyword {
-    static NSString *const key = @"highlightAnimation";
-    if (keyword && keyword.length) {
-        if (self.highlightAnimating) {
-            return;
-        }
-        self.highlightAnimating = YES;
-        CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"backgroundColor"];
-        animation.repeatCount = 3;
-        animation.values = @[
-            (id)[[UIColor orangeColor] colorWithAlphaComponent:0.2].CGColor,
-            (id)[[UIColor orangeColor] colorWithAlphaComponent:0.5].CGColor,
-            (id)[[UIColor orangeColor] colorWithAlphaComponent:0.2].CGColor,
-        ];
-        animation.duration = 0.5;
-        animation.removedOnCompletion = YES;
-        animation.delegate = self;
-        [self.highlightAnimateView.layer addAnimation:animation forKey:key];
-    } else {
-        [self.highlightAnimateView.layer removeAnimationForKey:key];
-    }
-}
-
-- (void)updateReadLabelText {
-    if (self.messageData.innerMessage.groupID.length > 0) {
-        // group message
-        NSString *text = TIMCommonLocalizableString(Unread);
-        if (self.messageData.messageReceipt == nil) {
-            // haven't received the message receipt yet
-            return;
-        }
-        NSInteger readCount = self.messageData.messageReceipt.readCount;
-        NSInteger unreadCount = self.messageData.messageReceipt.unreadCount;
-        if (unreadCount == 0) {
-            // show "All read"
-            text = TIMCommonLocalizableString(TUIKitMessageReadAllRead);
-        } else if (readCount > 0) {
-            // show "x read"
-            text = [NSString stringWithFormat:@"%ld %@", (long)readCount, TIMCommonLocalizableString(TUIKitMessageReadPartRead)];
-        }
-        self.readReceiptLabel.text = text;
-    } else {
-        // c2c message
-        BOOL isPeerRead = self.messageData.messageReceipt.isPeerRead;
-        NSString *text = isPeerRead ? TIMCommonLocalizableString(TUIKitMessageReadC2CRead) : TIMCommonLocalizableString(TUIKitMessageReadC2CUnRead);
-        self.readReceiptLabel.text = text;
-    }
-    
-    [self.readReceiptLabel sizeToFit];
-    [self.readReceiptLabel mas_remakeConstraints:^(MASConstraintMaker *make) {
-      make.bottom.mas_equalTo(self.container.mas_bottom);
-      make.trailing.mas_equalTo(self.container.mas_leading).mas_offset(-8);
-      make.size.mas_equalTo(self.readReceiptLabel.frame.size);
-    }];
-    self.readReceiptLabel.textColor = [self shouldHighlightReadReceiptLabel] ? TIMCommonDynamicColor(@"chat_message_read_status_text_color", @"#147AFF")
-                                                                             : TIMCommonDynamicColor(@"chat_message_read_status_text_gray_color", @"#BBBBBB");
-}
-
-- (UIView *)highlightAnimateView {
-    return self.container;
-}
-
-#pragma mark - TUIMessageCellProtocol
-+ (CGFloat)getEstimatedHeight:(TUIMessageCellData *)data {
-    return 60.f;
-}
-
-+ (CGFloat)getHeight:(TUIMessageCellData *)data withWidth:(CGFloat)width {
-    CGFloat height = 0;
-    if (data.showName) height += kScale375(20);
-    if (data.showMessageModifyReplies) height += kScale375(22);
-    
-    if (data.messageContainerAppendSize.height > 0) {
-        height += data.messageContainerAppendSize.height;
-    }
-    
-    CGSize containerSize = [self getContentSize:data];
-    height += containerSize.height;
-    height += data.cellLayout.messageInsets.top;
-    height += data.cellLayout.messageInsets.bottom;
-    
-    if (height < 55) height = 55;
-    return height;
-}
-
-+ (CGSize)getContentSize:(TUIMessageCellData *)data {
-    return CGSizeZero;
-}
-
-#pragma mark - Private
-- (void)animationDidStart:(CAAnimation *)anim {
-    self.highlightAnimating = YES;
-}
-
-- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag {
-    self.highlightAnimating = NO;
-}
-
-#pragma mark-- Event
-- (void)onLongPress:(UIGestureRecognizer *)recognizer {
-    if ([recognizer isKindOfClass:[UILongPressGestureRecognizer class]] && recognizer.state == UIGestureRecognizerStateBegan) {
-        if (_delegate && [_delegate respondsToSelector:@selector(onLongPressMessage:)]) {
-            [_delegate onLongPressMessage:self];
-        }
-    }
-}
-
-- (void)onRetryMessage:(UIGestureRecognizer *)recognizer {
-    if (_messageData.status == Msg_Status_Fail)
-        if (_delegate && [_delegate respondsToSelector:@selector(onRetryMessage:)]) {
-            [_delegate onRetryMessage:self];
-        }
-}
-
-- (void)onSelectMessage:(UIGestureRecognizer *)recognizer {
-    if (_delegate && [_delegate respondsToSelector:@selector(onSelectMessage:)]) {
-        [_delegate onSelectMessage:self];
-    }
-}
-
-- (void)onSelectMessageAvatar:(UIGestureRecognizer *)recognizer {
-    if (_delegate && [_delegate respondsToSelector:@selector(onSelectMessageAvatar:)]) {
-        [_delegate onSelectMessageAvatar:self];
-    }
-}
-
-- (void)onLongSelectMessageAvatar:(UIGestureRecognizer *)recognizer {
-    if (_delegate && [_delegate respondsToSelector:@selector(onLongSelectMessageAvatar:)]) {
-        [_delegate onLongSelectMessageAvatar:self];
-    }
-}
-
-- (void)onSelectReadReceipt:(UITapGestureRecognizer *)gesture {
-    if (![self shouldHighlightReadReceiptLabel]) {
-        return;
-    }
-    if (_delegate && [_delegate respondsToSelector:@selector(onSelectReadReceipt:)]) {
-        [_delegate onSelectReadReceipt:self.messageData];
-    }
-}
-
-- (void)onJumpToRepliesDetailPage:(UIButton *)btn {
-    NSLog(@"click onJumpToRepliesDetailPage");
-    NSLog(@"%@", self.messageData.messageModifyReplies);
-
-    if (_delegate && [_delegate respondsToSelector:@selector(onJumpToRepliesDetailPage:)]) {
-        [_delegate onJumpToRepliesDetailPage:self.messageData];
-    }
-}
-- (BOOL)shouldHighlightReadReceiptLabel {
-    if (self.messageData.innerMessage.groupID.length == 0) {
-        return ![self.readReceiptLabel.text isEqualToString:TIMCommonLocalizableString(TUIKitMessageReadC2CRead)];
-    } else {
-        return ![self.readReceiptLabel.text isEqualToString:TIMCommonLocalizableString(TUIKitMessageReadAllRead)];
-    }
-}
-
-- (UIFont *)fontWithSize:(CGFloat)size {
-    static NSCache *fontCache;
-    if (fontCache == nil) {
-        fontCache = [[NSCache alloc] init];
-    }
-    UIFont *font = [fontCache objectForKey:@(size)];
-    if (font == nil) {
-        font = [UIFont systemFontOfSize:size];
-        [fontCache setObject:font forKey:@(size)];
-    }
-    return font;
-}
-
-- (void)notifyBottomContainerReadyOfData:(TUIMessageCellData *)cellData {
-    // Override by subclass.
-}
-
-@end
-
-
-@implementation TUIMessageCell (TUILayoutConfiguration)
-
-static UIColor *gOutgoingNameColor;
-
-+ (UIColor *)outgoingNameColor {
-    if (!gOutgoingNameColor) {
-        gOutgoingNameColor = [UIColor d_systemGrayColor];
-    }
-    return gOutgoingNameColor;
-}
-
-+ (void)setOutgoingNameColor:(UIColor *)outgoingNameColor {
-    gOutgoingNameColor = outgoingNameColor;
-}
-
-static UIFont *gOutgoingNameFont;
-
-+ (UIFont *)outgoingNameFont {
-    if (!gOutgoingNameFont) {
-        gOutgoingNameFont = [UIFont systemFontOfSize:14];
-    }
-    return gOutgoingNameFont;
-}
-
-+ (void)setOutgoingNameFont:(UIFont *)outgoingNameFont {
-    gOutgoingNameFont = outgoingNameFont;
-}
-
-static UIColor *gIncommingNameColor;
-
-+ (UIColor *)incommingNameColor {
-    if (!gIncommingNameColor) {
-        gIncommingNameColor = [UIColor d_systemGrayColor];
-    }
-    return gIncommingNameColor;
-}
-
-+ (void)setIncommingNameColor:(UIColor *)incommingNameColor {
-    gIncommingNameColor = incommingNameColor;
-}
-
-static UIFont *gIncommingNameFont;
-
-+ (UIFont *)incommingNameFont {
-    if (!gIncommingNameFont) {
-        gIncommingNameFont = [UIFont systemFontOfSize:14];
-    }
-    return gIncommingNameFont;
-}
-
-+ (void)setIncommingNameFont:(UIFont *)incommingNameFont {
-    gIncommingNameFont = incommingNameFont;
-}
-
-@end

+ 0 - 20
ThirdParty/TUIKit/TIMCommon/BaseCell/TUISecurityStrikeView.h

@@ -1,20 +0,0 @@
-//
-//  TUISecurityStrikeView.h
-//  TIMCommon
-//
-//  Created by wyl on 2023/10/11.
-//  Copyright © 2023 Tencent. All rights reserved.
-
-#import <UIKit/UIKit.h>
-
-NS_ASSUME_NONNULL_BEGIN
-#define  kTUISecurityStrikeViewTopLineMargin 14.5
-#define  kTUISecurityStrikeViewTopLineToBottom 28
-@interface TUISecurityStrikeView : UIView
-@property(nonatomic, strong) UIView * topLine;
-@property(nonatomic, strong) UILabel * textLabel;
-
-+ (UIImage *)changeImageColorWith:(UIColor *)color image:(UIImage *)image alpha:(CGFloat)alpha;
-@end
-
-NS_ASSUME_NONNULL_END

+ 0 - 73
ThirdParty/TUIKit/TIMCommon/BaseCell/TUISecurityStrikeView.m

@@ -1,73 +0,0 @@
-//
-//  TUISecurityStrikeView.m
-//  TIMCommon
-//
-//  Created by wyl on 2023/10/11.
-//  Copyright © 2023 Tencent. All rights reserved.
-
-#import "TUISecurityStrikeView.h"
-#import <TIMCommon/TIMDefine.h>
-
-@implementation TUISecurityStrikeView
-
-- (instancetype)initWithFrame:(CGRect)frame {
-    self = [super initWithFrame:frame];
-    if (self){
-        [self setupView];
-    }
-    return self;
-}
-+ (BOOL)requiresConstraintBasedLayout {
-    return YES;
-}
-
-- (void)setupView {
-    self.topLine = [[UIView alloc] initWithFrame:CGRectZero];
-    self.topLine.backgroundColor = TUIDynamicColor(@"", TUIThemeModuleTIMCommon, @"#E5C7C7");
-    [self addSubview:self.topLine];
-    
-    self.textLabel = [[UILabel alloc] initWithFrame:CGRectZero];
-    [self addSubview:self.textLabel];
-    self.textLabel.font = [UIFont systemFontOfSize:14];
-    self.textLabel.text = TIMCommonLocalizableString(TUIKitMessageTypeSecurityStrike);
-    self.textLabel.textColor = TUIDynamicColor(@"", TUIThemeModuleTIMCommon, @"#DA2222");
-    self.textLabel.numberOfLines = 0;
-    self.textLabel.textAlignment = isRTL()?NSTextAlignmentRight:NSTextAlignmentLeft;
-
-}
-// this is Apple's recommended place for adding/updating constraints
-- (void)updateConstraints {
-    [super updateConstraints];
-    [self.topLine mas_remakeConstraints:^(MASConstraintMaker *make) {
-        make.top.mas_equalTo(kTUISecurityStrikeViewTopLineMargin);
-        make.leading.mas_equalTo(10);
-        make.trailing.mas_equalTo(-10);
-        make.height.mas_equalTo(0.5);
-    }];
-    
-    [self.textLabel sizeToFit];
-    [self.textLabel mas_remakeConstraints:^(MASConstraintMaker *make) {
-        make.leading.mas_equalTo(10);
-        make.bottom.mas_equalTo(-11);
-        make.width.mas_equalTo(self);
-    }];
-
-}
-
-+ (UIImage *)changeImageColorWith:(UIColor *)color image:(UIImage *)image alpha:(CGFloat)alpha {
-    UIGraphicsBeginImageContextWithOptions(image.size, NO, image.scale);
-    CGContextRef context = UIGraphicsGetCurrentContext();
-    CGContextTranslateCTM(context, 0, image.size.height);
-    CGContextScaleCTM(context, 1.0, -1.0);
-    CGContextSetAlpha(context, alpha);
-    CGContextSetBlendMode(context, kCGBlendModeNormal);
-    CGRect rect = CGRectMake(0, 0, image.size.width, image.size.height);
-    CGContextClipToMask(context, rect, image.CGImage);
-    [color setFill];
-    CGContextFillRect(context, rect);
-    UIImage*newImage = UIGraphicsGetImageFromCurrentImageContext();
-    UIGraphicsEndImageContext();
-    return newImage;
-}
-@end
-

+ 0 - 30
ThirdParty/TUIKit/TIMCommon/BaseCell/TUISystemMessageCell.h

@@ -1,30 +0,0 @@
-
-//  Created by Tencent on 2023/06/09.
-//  Copyright © 2023 Tencent. All rights reserved.
-/**
- *
- *  This file declares the TUISystemMessageCell class, which is responsible for displaying system messages.
- *  The system message unit is responsible for displaying special messages from the system. Such messages are usually white on a gray background and centered.
- */
-#import "TUIMessageCell.h"
-#import "TUISystemMessageCellData.h"
-
-/**
- * 【Module name】 TUISystemMessageCell
- * 【Function description】System message unit
- *  - It is used to display the system messages. Common system messages include: recall-message, group-member-change-message, group-created and
- * group-diss-message, etc.
- *  - System messages are typically used to display notifications from apps that are sent by the system, not from any user.
- */
-@interface TUISystemMessageCell : TUIMessageCell
-
-/**
- *
- *  The label of display system message content, such as "You recalled a message.".
- */
-@property(readonly) UILabel *messageLabel;
-
-@property(readonly) TUISystemMessageCellData *systemData;
-
-- (void)fillWithData:(TUISystemMessageCellData *)data;
-@end

+ 0 - 107
ThirdParty/TUIKit/TIMCommon/BaseCell/TUISystemMessageCell.m

@@ -1,107 +0,0 @@
-//
-//  TUISystemMessageCell.m
-//  UIKit
-//
-//  Created by annidyfeng on 2019/5/30.
-//  Copyright © 2023 Tencent. All rights reserved.
-//
-
-#import "TUISystemMessageCell.h"
-#import <TIMCommon/TIMDefine.h>
-#import <TUICore/NSString+TUIUtil.h>
-
-@interface TUISystemMessageCell ()
-@property(nonatomic, strong) UILabel *messageLabel;
-@property TUISystemMessageCellData *systemData;
-@end
-
-@implementation TUISystemMessageCell
-
-- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
-    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
-    if (self) {
-        _messageLabel = [[UILabel alloc] init];
-        _messageLabel.textAlignment = NSTextAlignmentCenter;
-        _messageLabel.numberOfLines = 0;
-        _messageLabel.backgroundColor = [UIColor clearColor];
-        _messageLabel.layer.cornerRadius = 3;
-        [_messageLabel.layer setMasksToBounds:YES];
-        [self.container addSubview:_messageLabel];
-        self.backgroundColor = [UIColor clearColor];
-        self.contentView.backgroundColor = [UIColor clearColor];
-    }
-    return self;
-}
-
-+ (BOOL)requiresConstraintBasedLayout {
-    return YES;
-}
-
-// this is Apple's recommended place for adding/updating constraints
-- (void)updateConstraints {
-    [super updateConstraints];
-    
-    [self.container mas_remakeConstraints:^(MASConstraintMaker *make) {
-        make.center.mas_equalTo(self.contentView);
-        make.size.mas_equalTo(self.contentView);
-    }];
-    [self.messageLabel sizeToFit];
-    if(self.messageLabel.superview) {
-        [self.messageLabel mas_remakeConstraints:^(MASConstraintMaker *make) {
-            make.center.mas_equalTo(self.container);
-            make.leading.trailing.mas_equalTo(self.container);
-        }];
-    }
-}
-
-- (void)fillWithData:(TUISystemMessageCellData *)data;
-{
-    [super fillWithData:data];
-    self.systemData = data;
-    
-    self.messageLabel.textColor = TUISystemMessageCellData.textColor ? : data.contentColor;
-    self.messageLabel.font = TUISystemMessageCellData.textFont ? : data.contentFont;
-    self.messageLabel.backgroundColor = TUISystemMessageCellData.textBackgroundColor ? : [UIColor clearColor];
-    self.messageLabel.attributedText = data.attributedString;
-    
-    self.nameLabel.hidden = YES;
-    self.avatarView.hidden = YES;
-    self.retryView.hidden = YES;
-    [self.indicator stopAnimating];
-    
-    // tell constraints they need updating
-    [self setNeedsUpdateConstraints];
-    // update constraints now so we can animate the change
-    [self updateConstraintsIfNeeded];
-    [self layoutIfNeeded];
-}
-
-- (void)layoutSubviews {
-    [super layoutSubviews];
-}
-
-
-#pragma mark - TUIMessageCellProtocol
-+ (CGFloat)getEstimatedHeight:(TUIMessageCellData *)data {
-    return 42.f;
-}
-
-+ (CGFloat)getHeight:(TUIMessageCellData *)data withWidth:(CGFloat)width {
-    return [self getContentSize:data].height + kScale375(16);
-}
-
-+ (CGSize)getContentSize:(TUIMessageCellData *)data {
-    NSAssert([data isKindOfClass:TUISystemMessageCellData.class], @"data must be kind of TUISystemMessageCellData");
-    TUISystemMessageCellData *systemCellData = (TUISystemMessageCellData *)data;
-    
-    static CGSize maxSystemSize;
-    if (CGSizeEqualToSize(maxSystemSize, CGSizeZero)) {
-        maxSystemSize = CGSizeMake(Screen_Width, MAXFLOAT);
-    }
-    CGSize size = [systemCellData.attributedString.string textSizeIn:maxSystemSize font:systemCellData.contentFont];
-    size.height += 10;
-    size.width += 16;
-    return size;
-}
-
-@end

+ 0 - 30
ThirdParty/TUIKit/TIMCommon/BaseCellData/TUIBubbleMessageCellData.h

@@ -1,30 +0,0 @@
-
-//  Created by Tencent on 2023/06/09.
-//  Copyright © 2023 Tencent. All rights reserved.
-/**
- *
- *  - This file declares the TUIBubbleMessageCellData class.
- *  - This class inherits from TUIMessageCellData and is used to store a series of data and information required by the bubble message unit.
- *  - This class is used as the base class for the data source of the bubble message. When you want to implement a custom bubble message,
- *   you also need to make the data source of the corresponding message inherit from this class.
- *
- */
-#import "TUIMessageCellData.h"
-
-NS_ASSUME_NONNULL_BEGIN
-
-/**
- *
- * 【Module name】TUIBubbleMessageCellData
- * 【Function description】Bubble message data source.
- *  - Bubble messages, the most common type of messages that contain text and emoji characters, will be your most common type of message in most cases.
- *  - The Bubble Message data source (hereinafter referred to as the data source) is responsible for storing various information required to render the Bubble
- * Message UI.
- *  - The data source implements a series of business logic that can provide the required information to the Bubble Message UI.
- *  - Both TUIFileMessageCellData and TUIVoiceMessageCellData inherit from this class and implement the UI of bubble messages.
- */
-@interface TUIBubbleMessageCellData : TUIMessageCellData
-
-@end
-
-NS_ASSUME_NONNULL_END

+ 0 - 15
ThirdParty/TUIKit/TIMCommon/BaseCellData/TUIBubbleMessageCellData.m

@@ -1,15 +0,0 @@
-//
-//  TUIBubbleMessageCellData.m
-//  TXIMSDK_TUIKit_iOS
-//
-//  Created by annidyfeng on 2019/5/30.
-//  Copyright © 2023 Tencent. All rights reserved.
-//
-
-#import "TUIBubbleMessageCellData.h"
-#import <TIMCommon/TIMDefine.h>
-#import <TUICore/TUIThemeManager.h>
-
-@implementation TUIBubbleMessageCellData
-
-@end

+ 0 - 280
ThirdParty/TUIKit/TIMCommon/BaseCellData/TUIMessageCellData.h

@@ -1,280 +0,0 @@
-
-//  Created by Tencent on 2023/06/09.
-//  Copyright © 2023 Tencent. All rights reserved.
-/**
- *
- * This file declares the TUIMessageCellData class.
- * - The "message unit" data source, as the parent class of various detailed data sources, provides basic templates for the properties and behaviors of various
- * "message unit" data sources.
- * - The "data source class" in this document is the base class for all message data, and each type of data source inherits from this class or its subclasses.
- * - When you want to customize the message, you need to inherit the data source of the customized message from this class or a subclass of this class.
- */
-#import <TIMCommon/TIMCommonModel.h>
-#import <TIMCommon/TIMDefine.h>
-#import "TUIMessageCellLayout.h"
-@class TUIRelationUserModel;
-
-NS_ASSUME_NONNULL_BEGIN
-
-typedef void (^TDownloadProgress)(NSInteger curSize, NSInteger totalSize);
-typedef void (^TDownloadResponse)(int code, NSString *desc, NSString *path);
-
-/**
- *  The definition of message status
- */
-typedef NS_ENUM(NSUInteger, TMsgStatus) {
-    Msg_Status_Init,       //  message initial
-    Msg_Status_Sending,    //  message sending
-    Msg_Status_Sending_2,  //  message sending, recommended
-    Msg_Status_Succ,       //  message sent successfully
-    Msg_Status_Fail,       //  Failed to send message
-};
-
-/**
- *
- *  The definition of message direction
- *  Message direction affects UI styles such as bubble icons, bubble positions, etc.
- */
-typedef NS_ENUM(NSUInteger, TMsgDirection) {
-    MsgDirectionIncoming,
-    MsgDirectionOutgoing,
-};
-
-/**
- *
- *  The source of message
- *  Different display logic can be done according to the source of the message.
- */
-typedef NS_ENUM(NSUInteger, TMsgSource) {
-    Msg_Source_Unkown = 0,    // 未知
-    Msg_Source_OnlinePush,    // Messages actively pushed in the background
-    Msg_Source_GetHistory,    // SDK actively requests historical messages pulled from the background
-};
-
-/**
- * 【Module name】TUIMessageCellData
- * 【Function description】The data source of the chat message unit cooperates with the message controller to realize the business logic of message sending and
- * receiving.
- *  - It is used to store various data and information required for message management and logic implementation. Including a series of data such as message
- * status, message sender ID and avatar.
- *  - The chat information data unit integrates and calls the IM SDK, and can implement the business logic of the message through the interface provided by the
- * SDK.
- */
-@interface TUIMessageCellData : TUICommonCellData
-/**
- *  Getting cellData according to message
- */
-+ (TUIMessageCellData *)getCellData:(V2TIMMessage *)message;
-
-/**
- * Getting the display string according to the message
- */
-+ (NSString *)getDisplayString:(V2TIMMessage *)message;
-
-/**
- * Class to get the layout of the message reply custom reference and its data
- */
-- (Class)getReplyQuoteViewDataClass;
-- (Class)getReplyQuoteViewClass;
-
-/**
- *  Message unique id
- */
-@property(nonatomic, strong) NSString *msgID;
-
-/**
- *  Message sender ID
- */
-@property(nonatomic, strong) NSString *identifier;
-
-/**
- *  Message display sender name
- */
-@property(nonatomic, strong, readonly) NSString *senderName;
-
-/**
- *  Sender's avatar url
- */
-@property(nonatomic, strong) NSURL *__nullable avatarUrl;
-
-/**
- *  Sender's avatar
- */
-@property(nonatomic, strong) UIImage *__nullable avatarImage __attribute__((deprecated("not supported")));
-
-/**
- * Whether to use the receiver's avatar, default is NO
- */
-@property(nonatomic, assign) BOOL isUseMsgReceiverAvatar;
-
-/**
- *
- *  The flag of showing name
- *  - In 1 vs 1 chat, the nickname is not displayed in the message by default.
- *  - In group chat, the nickname is displayed for messages sent by other users in the group.
- *  - YES: showing nickname;  NO: hidden nickname
- */
-@property(nonatomic, assign) BOOL showName;
-
-/**
- *  Display user avatar
- */
-@property(nonatomic, assign) BOOL showAvatar;
-
-/**
- *  Whether the current message is the same as the sender of the next message
- */
-@property(nonatomic, assign) BOOL sameToNextMsgSender;
-
-/**
- *
- * The flag of showing message multiple selection
- * - In the message list, the selection button is not displayed by default. When you long press the message to pop up the multi-select button and click it, the
- * message list becomes multi-selectable.
- * - YES: Enable multiple selection, multiple selection views are displayed; NO: Disable multiple selection, the default view is displayed.
- */
-@property(nonatomic, assign) BOOL showCheckBox;
-
-/**
- * The flag of selected
- */
-@property(nonatomic, assign) BOOL selected;
-
-/**
- * The user list in at message
- */
-@property(nonatomic, strong) NSMutableArray<NSString *> *atUserList;
-
-/**
- * Message direction
- * - Message direction affects UI styles such as bubble icons, bubble positions, etc.
- */
-@property(nonatomic, assign) TMsgDirection direction;
-
-/**
- * Message status
- */
-@property(nonatomic, assign) TMsgStatus status;
-
-/**
- * Message source
- */
-@property(nonatomic, assign) TMsgSource source;
-
-/**
- * IMSDK message
- * The Message object provided by IM SDK. Contains various member functions for obtaining message information, including obtaining priority, obtaining element
- * index, obtaining offline message configuration information, etc. For details, please refer to
- * TXIMSDK__Plus_iOS\Frameworks\ImSDK_Plus.framework\Headers\V2TIMMessage.h
- */
-@property(nonatomic, strong) V2TIMMessage *innerMessage;
-
-/**
- *  Message unit layout
- *  It includes UI information such as message margins, bubble padding, avatar margins, and avatar size.
- *  For details, please refer to Section\Chat\CellLayout\TUIMessageCellLayout.h
- */
-@property(nonatomic, strong) TUIMessageCellLayout *cellLayout;
-
-/**
- * The flag of whether showing read receipts.
- */
-@property(nonatomic, assign) BOOL showReadReceipt;
-
-/**
- * The flag of  whether showing message time.
- */
-@property(nonatomic, assign) BOOL showMessageTime;
-
-/**
- * The flag of whether showing the button which indicated how many people modiffied.
- */
-@property(nonatomic, assign) BOOL showMessageModifyReplies;
-/**
- * Highlight keywords, when the keyword is not empty, it will be highlighted briefly, mainly used in message search scenarios.
- */
-@property(nonatomic, copy) NSString *__nullable highlightKeyword;
-
-/**
- * Message read receipt
- */
-@property(nonatomic, strong) V2TIMMessageReceipt *messageReceipt;
-
-/**
- * List of Reply Messages for the current message
- */
-@property(nonatomic, strong) NSArray *messageModifyReplies;
-
-@property(nonatomic, assign) CGSize messageContainerAppendSize;
-
-/// Size for bottom container.
-@property(nonatomic, assign) CGSize bottomContainerSize;
-
-/// Placeholder data, to be replaced after data preparation is completed.
-@property(nonatomic, strong) TUIMessageCellData* _Nullable placeHolderCellData;
-
-/// Video transcoding progress
-@property(nonatomic, assign) CGFloat videoTranscodingProgress;
-
-/// If cell content can be forwarded.
-- (BOOL)canForward;
-
-- (BOOL)canLongPress;
-
-- (BOOL)shouldHide;
-
-/// Custom cell refresh when message modified
-- (BOOL)customReloadCellWithNewMsg:(V2TIMMessage *)newMessage;
-
-/**
- *  Initialize the message unit according to the message direction (receive/sent)
- *  - In addition to the initialization of basic messages, it also includes setting direction variables, nickname fonts, etc. according to the direction.
- *  - Also provides inheritable behavior for subclasses.
- */
-- (instancetype)initWithDirection:(TMsgDirection)direction NS_DESIGNATED_INITIALIZER;
-
-- (instancetype)init NS_UNAVAILABLE;
-
-@property(nonatomic, assign) CGSize msgStatusSize;
-
-/**
- * TUIChat supports batch retrieval of user information except for the message sender's nickname.
- * You can override the requestForAdditionalUserInfo method in your custom TUIMessageCellData to return the user IDs which you want to retrieve, and directly use the additionalUserInfoResult property in your custom TUIMessageCell to render the UI as needed.
- * After TUIChat retrieves the information, it will assign it to the additionalUserInfoResult property and asynchronously refresh your cell.
- */
-- (NSArray<NSString *> *)requestForAdditionalUserInfo;
-@property(nonatomic, strong) NSDictionary<NSString *, TUIRelationUserModel *> *additionalUserInfoResult;
-
-@end
-
-NS_ASSUME_NONNULL_END
-
-/**
- * 【Module name】TUIMessageCellDataFileUploadProtocol
- * 【Function description】File type message, unified upload (send) progress field
- */
-@protocol TUIMessageCellDataFileUploadProtocol <NSObject>
-
-@required
-/**
- *  The progress of uploading (sending)
- */
-@property(nonatomic, assign) NSUInteger uploadProgress;
-
-@end
-
-@protocol TUIMessageCellDataFileDownloadProtocol <NSObject>
-
-@required
-/**
- *  The progress of downloading (receving)
- */
-@property(nonatomic, assign) NSUInteger downladProgress;
-
-/**
- *  The flag of whether is downloading
- *  YES: downloading; NO: not download
- */
-@property(nonatomic, assign) BOOL isDownloading;
-
-@end

+ 0 - 151
ThirdParty/TUIKit/TIMCommon/BaseCellData/TUIMessageCellData.m

@@ -1,151 +0,0 @@
-//
-//  TUIMessageCellData.m
-//  TXIMSDK_TUIKit_iOS
-//
-//  Created by annidyfeng on 2019/5/21.
-//  Copyright © 2023 Tencent. All rights reserved.
-//
-
-#import "TUIMessageCellData.h"
-#import <TIMCommon/TIMDefine.h>
-
-@interface TUIMessageCellData ()
-
-@end
-
-@implementation TUIMessageCellData
-{
-    NSString *_msgID;
-    NSString *_identifier;
-    NSURL *_avatarUrl;
-}
-
-+ (TUIMessageCellData *)getCellData:(V2TIMMessage *)message {
-    return nil;
-}
-
-+ (NSString *)getDisplayString:(V2TIMMessage *)message {
-    return nil;
-}
-
-- (Class)getReplyQuoteViewDataClass {
-    return nil;
-}
-
-- (Class)getReplyQuoteViewClass {
-    return nil;
-}
-
-- (instancetype)initWithDirection:(TMsgDirection)direction {
-    self = [super init];
-    if (self) {
-        _direction = direction;
-        _status = Msg_Status_Init;
-        _source = Msg_Source_Unkown;
-        _showReadReceipt = YES;
-        _sameToNextMsgSender = NO;
-        _showAvatar = YES;
-        _cellLayout = [self cellLayout:direction];
-        _additionalUserInfoResult = @{};
-    }
-    return self;
-}
-
-- (TUIMessageCellLayout *)cellLayout:(TMsgDirection)direction {
-    if (direction == MsgDirectionIncoming) {
-        return [TUIMessageCellLayout incommingMessageLayout];
-    } else {
-        return [TUIMessageCellLayout outgoingMessageLayout];
-    }
-}
-
-- (void)setMsgID:(NSString *)msgID {
-    _msgID = msgID;
-}
-
-- (NSString *)msgID {
-    if (_msgID) {
-        return _msgID;
-    }
-    if (self.innerMessage) {
-        return self.innerMessage.msgID;
-    }
-    return nil;
-}
-
-- (void)setIdentifier:(NSString *)identifier {
-    _identifier = identifier;
-}
-
-- (NSString *)identifier {
-    if (_identifier) {
-        return _identifier;
-    }
-    if (self.innerMessage) {
-        return self.innerMessage.sender;
-    }
-    return nil;
-}
-
-- (NSString *)senderName {
-    if (self.innerMessage) {
-        return self.innerMessage.nameCard ? : (self.innerMessage.friendRemark ? : (self.innerMessage.nickName ? : self.innerMessage.sender));
-    }
-    return nil;
-}
-
-- (void)setAvatarUrl:(NSURL *)avatarUrl {
-    _avatarUrl = avatarUrl;
-}
-
-- (NSURL *)avatarUrl {
-    if (_avatarUrl) {
-        return _avatarUrl;
-    }
-    if (self.innerMessage) {
-        return [NSURL URLWithString:self.innerMessage.faceURL];;
-    }
-    return nil;
-}
-
-- (BOOL)canForward {
-    return YES;
-}
-
-- (BOOL)canLongPress {
-    return YES;
-}
-
-- (BOOL)shouldHide {
-    return NO;
-}
-
-- (BOOL)customReloadCellWithNewMsg:(V2TIMMessage *)newMessage {
-    return NO;
-}
-
-- (CGSize)msgStatusSize {
-    if (self.showReadReceipt && self.innerMessage.needReadReceipt &&
-        (self.innerMessage.userID || self.innerMessage.groupID)) {
-        if (self.direction == MsgDirectionOutgoing) {
-            return CGSizeMake(54, 14);
-        } else {
-            return CGSizeMake(38, 14);
-        }
-    }
-    else {
-        //The community type does not require read receipt markers, only the time is needed.
-        return CGSizeMake(26, 14);
-    }
-
-}
-
-- (NSDictionary *)messageModifyUserInfos {
-  return self.additionalUserInfoResult;
-}
-
-- (NSArray<NSString *> *)requestForAdditionalUserInfo {
-  return @[];
-}
-
-@end

+ 0 - 110
ThirdParty/TUIKit/TIMCommon/BaseCellData/TUIMessageCellLayout.h

@@ -1,110 +0,0 @@
-
-//  Created by Tencent on 2023/06/09.
-//  Copyright © 2023 Tencent. All rights reserved.
-
-#import <Foundation/Foundation.h>
-@import UIKit;
-
-NS_ASSUME_NONNULL_BEGIN
-
-/**
- *【Module Name】TUIMessageCellLayout
- *【Function description】The layout of message unit
- * - UI layouts for implementing various message units (text, voice, video, images, emoticons, etc.).
- * - When you want to adjust the interface layout in TUIKit, you can modify the corresponding properties in this layout.
- */
-@interface TUIMessageCellLayout : NSObject
-
-/**
- * The insets of message
- */
-@property(nonatomic, assign) UIEdgeInsets messageInsets;
-
-/**
- * The insets of bubble content.
- */
-@property(nonatomic, assign) UIEdgeInsets bubbleInsets;
-
-/**
- * The insets of avatar
- */
-@property(nonatomic, assign) UIEdgeInsets avatarInsets;
-
-/**
- * The size of avatar
- */
-@property(nonatomic, assign) CGSize avatarSize;
-
-/////////////////////////////////////////////////////////////////////////////////
-//                      Text Message Layout
-/////////////////////////////////////////////////////////////////////////////////
-
-/**
- *  Getting text message (receive) layout
- */
-+ (TUIMessageCellLayout *)incommingTextMessageLayout;
-
-/**
- *  Getting text message (send) layout
- */
-+ (TUIMessageCellLayout *)outgoingTextMessageLayout;
-
-/////////////////////////////////////////////////////////////////////////////////
-//                      Voice Message Layout
-/////////////////////////////////////////////////////////////////////////////////
-/**
- *  Getting voice message (receive) layout
- */
-+ (TUIMessageCellLayout *)incommingVoiceMessageLayout;
-
-/**
- *  Getting voice message (send) layout
- */
-+ (TUIMessageCellLayout *)outgoingVoiceMessageLayout;
-
-/////////////////////////////////////////////////////////////////////////////////
-//                      System Message Layout
-/////////////////////////////////////////////////////////////////////////////////
-/**
- *  Getting system message layout
- */
-+ (TUIMessageCellLayout *)systemMessageLayout;
-
-/////////////////////////////////////////////////////////////////////////////////
-//                      Image Message Layout
-/////////////////////////////////////////////////////////////////////////////////
-
-/**
- *  Getting Image message layout
- */
-+ (TUIMessageCellLayout *)incommingImageMessageLayout;
-+ (TUIMessageCellLayout *)outgoingImageMessageLayout;
-
-/////////////////////////////////////////////////////////////////////////////////
-//                      Video Message Layout
-/////////////////////////////////////////////////////////////////////////////////
-
-/**
- *  Getting video message layout
- */
-+ (TUIMessageCellLayout *)incommingVideoMessageLayout;
-+ (TUIMessageCellLayout *)outgoingVideoMessageLayout;
-
-
-
-/////////////////////////////////////////////////////////////////////////////////
-//                     Other Message Layout
-/////////////////////////////////////////////////////////////////////////////////
-/**
- *  Getting receive message layout
- */
-+ (TUIMessageCellLayout *)incommingMessageLayout;
-
-/**
- *  Getting send message layout
- */
-+ (TUIMessageCellLayout *)outgoingMessageLayout;
-
-@end
-
-NS_ASSUME_NONNULL_END

+ 0 - 160
ThirdParty/TUIKit/TIMCommon/BaseCellData/TUIMessageCellLayout.m

@@ -1,160 +0,0 @@
-//
-//  TUIMessageCellLayout.m
-//  TXIMSDK_TUIKit_iOS
-//
-//  Created by annidyfeng on 2019/5/21.
-//  Copyright © 2023 Tencent. All rights reserved.
-//
-
-#import "TUIMessageCellLayout.h"
-#import <TIMCommon/TIMDefine.h>
-
-@implementation TUIMessageCellLayout
-
-- (instancetype)init:(BOOL)isIncomming {
-    self = [super init];
-    if (self) {
-        self.avatarSize = CGSizeMake(40, 40);
-        if (isIncomming) {
-            self.avatarInsets = (UIEdgeInsets){
-                .left = 8,
-                .top = 3,
-                .bottom = 1,
-            };
-            self.messageInsets = (UIEdgeInsets){
-                .top = 3,
-                .bottom = 17,
-                .left = 8,
-            };
-        } else {
-            self.avatarInsets = (UIEdgeInsets){
-                .right = 8,
-                .top = 3,
-                .bottom = 1,
-            };
-            self.messageInsets = (UIEdgeInsets){
-                .top = 3,
-                .bottom = 17,
-                .right = 8,
-            };
-        }
-    }
-    return self;
-}
-
-static TUIMessageCellLayout *gIncommingMessageLayout;
-
-+ (TUIMessageCellLayout *)incommingMessageLayout {
-    if (!gIncommingMessageLayout) {
-        gIncommingMessageLayout = [[TUIMessageCellLayout alloc] init:YES];
-    }
-    return gIncommingMessageLayout;
-}
-
-static TUIMessageCellLayout *gOutgoingMessageLayout;
-
-+ (TUIMessageCellLayout *)outgoingMessageLayout {
-    if (!gOutgoingMessageLayout) {
-        gOutgoingMessageLayout = [[TUIMessageCellLayout alloc] init:NO];
-    }
-    return gOutgoingMessageLayout;
-}
-
-#pragma Text CellLayout
-
-static TUIMessageCellLayout *gIncommingTextMessageLayout;
-
-+ (TUIMessageCellLayout *)incommingTextMessageLayout {
-    if (!gIncommingTextMessageLayout) {
-        gIncommingTextMessageLayout = [[TUIMessageCellLayout alloc] init:YES];
-        gIncommingTextMessageLayout.bubbleInsets = (UIEdgeInsets){.top = 10.5, .bottom = 10.5, .left = 16, .right = 16};
-    }
-    return gIncommingTextMessageLayout;
-}
-
-static TUIMessageCellLayout *gOutgingTextMessageLayout;
-
-+ (TUIMessageCellLayout *)outgoingTextMessageLayout {
-    if (!gOutgingTextMessageLayout) {
-        gOutgingTextMessageLayout = [[TUIMessageCellLayout alloc] init:NO];
-        gOutgingTextMessageLayout.bubbleInsets = (UIEdgeInsets){.top = 10.5, .bottom = 10.5, .left = 16, .right = 16};
-    }
-    return gOutgingTextMessageLayout;
-}
-
-#pragma Voice CellLayout
-
-static TUIMessageCellLayout *gIncommingVoiceMessageLayout;
-
-+ (TUIMessageCellLayout *)incommingVoiceMessageLayout {
-    if (!gIncommingVoiceMessageLayout) {
-        gIncommingVoiceMessageLayout = [[TUIMessageCellLayout alloc] init:YES];
-        gIncommingVoiceMessageLayout.bubbleInsets = (UIEdgeInsets){.top = 12, .bottom = 12, .left = 16, .right = 16};
-    }
-    return gIncommingVoiceMessageLayout;
-}
-
-static TUIMessageCellLayout *gOutgingVoiceMessageLayout;
-
-+ (TUIMessageCellLayout *)outgoingVoiceMessageLayout {
-    if (!gOutgingVoiceMessageLayout) {
-        gOutgingVoiceMessageLayout = [[TUIMessageCellLayout alloc] init:NO];
-        gOutgingVoiceMessageLayout.bubbleInsets = (UIEdgeInsets){.top = 14, .bottom = 20, .left = 22, .right = 20};
-    }
-    return gOutgingVoiceMessageLayout;
-}
-
-#pragma System CellLayout
-
-static TUIMessageCellLayout *gSystemMessageLayout;
-
-+ (TUIMessageCellLayout *)systemMessageLayout {
-    if (!gSystemMessageLayout) {
-        gSystemMessageLayout = [[TUIMessageCellLayout alloc] init:YES];
-        gSystemMessageLayout.messageInsets = (UIEdgeInsets){.top = 5, .bottom = 5};
-    }
-    return gSystemMessageLayout;
-}
-
-#pragma Image CellLayout
-
-static TUIMessageCellLayout *gIncommingImageMessageLayout;
-+ (TUIMessageCellLayout *)incommingImageMessageLayout {
-    if (!gIncommingImageMessageLayout) {
-        gIncommingImageMessageLayout = [[TUIMessageCellLayout alloc] init:YES];
-        gIncommingImageMessageLayout.bubbleInsets = (UIEdgeInsets){.top = 0, .bottom = 0, .left = 0 ,.right = 0};
-    }
-    return gIncommingImageMessageLayout;
-}
-
-static TUIMessageCellLayout *gOutgoingImageMessageLayout;
-+ (TUIMessageCellLayout *)outgoingImageMessageLayout {
-    if (!gOutgoingImageMessageLayout) {
-        gOutgoingImageMessageLayout = [[TUIMessageCellLayout alloc] init:NO];
-        gOutgoingImageMessageLayout.bubbleInsets = (UIEdgeInsets){.top = 0, .bottom = 0, .left = 0 ,.right = 0};
-    }
-    return gOutgoingImageMessageLayout;
-}
-
-#pragma Video CellLayout
-static TUIMessageCellLayout *gIncommingVideoMessageLayout;
-
-+ (TUIMessageCellLayout *)incommingVideoMessageLayout {
-    if (!gIncommingVideoMessageLayout) {
-        gIncommingVideoMessageLayout = [[TUIMessageCellLayout alloc] init:YES];
-        gIncommingVideoMessageLayout.bubbleInsets = (UIEdgeInsets){.top = 0, .bottom = 0, .left = 0 ,.right = 0};
-    }
-    return gIncommingVideoMessageLayout;
-}
-
-static TUIMessageCellLayout *gOutgoingVideoMessageLayout;
-
-+ (TUIMessageCellLayout *)outgoingVideoMessageLayout {
-    if (!gOutgoingVideoMessageLayout) {
-        gOutgoingVideoMessageLayout = [[TUIMessageCellLayout alloc] init:NO];
-        gOutgoingVideoMessageLayout.bubbleInsets = (UIEdgeInsets){.top = 0, .bottom = 0, .left = 0 ,.right = 0};
-    }
-    return gOutgoingVideoMessageLayout;
-}
-
-@end

+ 0 - 24
ThirdParty/TUIKit/TIMCommon/BaseCellData/TUIRelationUserModel.h

@@ -1,24 +0,0 @@
-//
-//  TUIRelationUserModel.h
-//  TIMCommon
-//
-//  Created by wyl on 2023/12/5.
-//  Copyright © 2023 Tencent. All rights reserved.
-//
-
-#import <Foundation/Foundation.h>
-
-NS_ASSUME_NONNULL_BEGIN
-
-@interface TUIRelationUserModel : NSObject
-@property(nonatomic, copy) NSString *userID;
-@property(nonatomic, copy) NSString *nickName;
-@property(nonatomic, copy) NSString *faceURL;
-@property(nonatomic, copy) NSString *friendRemark;
-@property(nonatomic, copy) NSString *nameCard;
-
-- (NSString *)getDisplayName;
-
-@end
-
-NS_ASSUME_NONNULL_END

+ 0 - 26
ThirdParty/TUIKit/TIMCommon/BaseCellData/TUIRelationUserModel.m

@@ -1,26 +0,0 @@
-//
-//  TUIRelationUserModel.m
-//  TIMCommon
-//
-//  Created by wyl on 2023/12/5.
-//  Copyright © 2023 Tencent. All rights reserved.
-//
-
-#import "TUIRelationUserModel.h"
-#import <TIMCommon/TIMDefine.h>
-
-@implementation TUIRelationUserModel
-
-- (NSString *)getDisplayName {
-    if (IS_NOT_EMPTY_NSSTRING(self.nameCard)) {
-        return self.nameCard;
-    } else if (IS_NOT_EMPTY_NSSTRING(self.friendRemark)) {
-        return self.friendRemark;
-    } else if (IS_NOT_EMPTY_NSSTRING(self.nickName)) {
-        return self.nickName;
-    } else {
-        return self.userID;
-    }
-    return @"";
-}
-@end

+ 0 - 73
ThirdParty/TUIKit/TIMCommon/BaseCellData/TUISystemMessageCellData.h

@@ -1,73 +0,0 @@
-
-//  Created by Tencent on 2023/06/09.
-//  Copyright © 2023 Tencent. All rights reserved.
-/**
- * This file declares the TUISystemMessageCellData class.
- * This class inherits from TUIMessageCellData and is used to store a series of data and information required by the system message unit.
- */
-#import "TUIMessageCellData.h"
-
-NS_ASSUME_NONNULL_BEGIN
-
-typedef NS_ENUM(NSInteger, TUISystemMessageType) {
-    TUISystemMessageTypeUnknown = 0,
-    TUISystemMessageTypeDate = 1,
-};
-
-/**
- * 【Module name】TUISystemMessageCellData
- * 【Function description】The datasource of system message unit.
- */
-@interface TUISystemMessageCellData : TUIMessageCellData
-
-/**
- *  The content of system message, such as "You recalled a message.".
- */
-@property(nonatomic, strong) NSString *content;
-
-/**
- *  The flag of whether supporting re-edit.
- */
-@property(nonatomic, assign) BOOL supportReEdit;
-
-/**
- *  Mutable string
- *  The recalled message can be re-edited within 2 minutes, which is displayed here based on attributedString.
- */
-@property(nonatomic, strong, nullable) NSMutableAttributedString *attributedString;
-
-/**
- *  The font of label which displays the system message content.
- */
-@property(nonatomic, strong, nullable) UIFont *contentFont;
-
-/**
- *  The color of label which displays the system message content.
- */
-@property(nonatomic, strong, nullable) UIColor *contentColor;
-
-/**
- * The type of system message type, default is TUISystemMessageTypeUnknown
- */
-@property(nonatomic, assign) TUISystemMessageType type;
-
-@property(nonatomic, strong) NSArray<NSString *> *replacedUserIDList;
-
-/**
- *  The font of label which displays the system message content.
- */
-@property(nonatomic, class) UIFont *textFont;
-
-/**
- *  The color of label which displays the system message content.
- */
-@property(nonatomic, class) UIColor *textColor;
-
-/**
- *  The background color of label which displays the system message content.
- */
-@property(nonatomic, class) UIColor *textBackgroundColor;
-
-@end
-
-NS_ASSUME_NONNULL_END

+ 0 - 97
ThirdParty/TUIKit/TIMCommon/BaseCellData/TUISystemMessageCellData.m

@@ -1,97 +0,0 @@
-//
-//  TUISystemMessageCellData.m
-//  TXIMSDK_TUIKit_iOS
-//
-//  Created by annidyfeng on 2019/5/21.
-//  Copyright © 2023 Tencent. All rights reserved.
-//
-
-#import "TUISystemMessageCellData.h"
-#import <TIMCommon/TIMDefine.h>
-#import "TUIRelationUserModel.h"
-
-
-@implementation TUISystemMessageCellData
-
-- (instancetype)initWithDirection:(TMsgDirection)direction {
-    self = [super initWithDirection:direction];
-    if (self) {
-        self.showAvatar = NO;
-        _contentFont = [UIFont systemFontOfSize:13];
-        _contentColor = [UIColor d_systemGrayColor];
-        self.cellLayout = [TUIMessageCellLayout systemMessageLayout];
-    }
-    return self;
-}
-
-- (NSMutableAttributedString *)attributedString {
-    __block BOOL forceRefresh = NO;
-    [self.additionalUserInfoResult enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, TUIRelationUserModel * _Nonnull obj, BOOL * _Nonnull stop) {
-      NSString *str = [NSString stringWithFormat:@"{%@}", key];
-      NSString *showName = obj.userID;
-      if (obj.nameCard.length > 0) {
-          showName = obj.nameCard;
-      } else if (obj.friendRemark.length > 0) {
-          showName = obj.friendRemark;
-      } else if (obj.nickName.length > 0) {
-          showName = obj.nickName;
-      }
-      if ([self.content containsString:str]) {
-        self.content = [self.content stringByReplacingOccurrencesOfString:str withString:showName];
-        forceRefresh = YES;
-      }
-    }];
-  
-    if (forceRefresh || (_attributedString == nil && self.content.length > 0)) {
-        NSMutableAttributedString *attributeString = [[NSMutableAttributedString alloc] initWithString:self.content];
-        NSDictionary *attributeDict = @{NSForegroundColorAttributeName : [UIColor d_systemGrayColor]};
-        [attributeString setAttributes:attributeDict range:NSMakeRange(0, attributeString.length)];
-        if (self.supportReEdit) {
-            NSString *reEditStr = TIMCommonLocalizableString(TUIKitMessageTipsReEditMessage);
-            [attributeString appendAttributedString:[[NSAttributedString alloc] initWithString:[NSString stringWithFormat:@" %@", reEditStr]]];
-            NSDictionary *attributeDict = @{NSForegroundColorAttributeName : [UIColor d_systemBlueColor]};
-            [attributeString setAttributes:attributeDict range:NSMakeRange(self.content.length + 1, reEditStr.length)];
-            [attributeString addAttribute:NSUnderlineStyleAttributeName
-                                    value:[NSNumber numberWithInteger:NSUnderlineStyleNone]
-                                    range:NSMakeRange(self.content.length + 1, reEditStr.length)];
-        }
-        _attributedString = attributeString;
-    }
-
-    return _attributedString;
-}
-
-- (NSArray<NSString *> *)requestForAdditionalUserInfo {
-  NSMutableArray *result = [NSMutableArray arrayWithArray:[super requestForAdditionalUserInfo]];
-  
-  if (self.replacedUserIDList) {
-    [result addObjectsFromArray:self.replacedUserIDList];
-  }
-  return result;
-}
-
-static UIFont *gTextFont;
-+ (void)setTextFont:(UIFont *)textFont {
-    gTextFont = textFont;
-}
-+ (UIFont *)textFont {
-    return gTextFont;
-}
-
-static UIColor *gTextColor;
-+ (void)setTextColor:(UIColor *)textColor {
-    gTextColor = textColor;
-}
-+ (UIColor *)textColor {
-    return gTextColor;
-}
-
-static UIColor *gTextBackgroundColor;
-+ (void)setTextBackgroundColor:(UIColor *)textBackgroundColor {
-    gTextBackgroundColor = textBackgroundColor;
-}
-+ (UIColor *)textBackgroundColor {
-    return gTextBackgroundColor;
-}
-
-@end

+ 0 - 17
ThirdParty/TUIKit/TIMCommon/CommonModel/NSTimer+TUISafe.h

@@ -1,17 +0,0 @@
-//
-//  NSTimer+TUISafe.h
-//  TUICore
-//
-//  Created by wyl on 2022/7/5.
-//  Copyright © 2023 Tencent. All rights reserved.
-//
-
-#import <Foundation/Foundation.h>
-
-NS_ASSUME_NONNULL_BEGIN
-
-@interface NSTimer (TUISafe)
-+ (NSTimer *)tui_scheduledTimerWithTimeInterval:(NSTimeInterval)interval repeats:(BOOL)repeats block:(void (^)(NSTimer *timer))block;
-@end
-
-NS_ASSUME_NONNULL_END

+ 0 - 21
ThirdParty/TUIKit/TIMCommon/CommonModel/NSTimer+TUISafe.m

@@ -1,21 +0,0 @@
-//
-//  NSTimer+TUISafe.m
-//  TUICore
-//
-//  Created by wyl on 2022/7/5.
-//  Copyright © 2023 Tencent. All rights reserved.
-//
-
-#import "NSTimer+TUISafe.h"
-
-@implementation NSTimer (TUISafe)
-+ (NSTimer *)tui_scheduledTimerWithTimeInterval:(NSTimeInterval)interval repeats:(BOOL)repeats block:(void (^)(NSTimer *timer))block {
-    return [self scheduledTimerWithTimeInterval:interval target:self selector:@selector(tui_callBlock:) userInfo:[block copy] repeats:repeats];
-}
-
-+ (void)tui_callBlock:(NSTimer *)timer {
-    void (^block)(NSTimer *timer) = timer.userInfo;
-    !block ?: block(timer);
-}
-
-@end

+ 0 - 458
ThirdParty/TUIKit/TIMCommon/CommonModel/TIMCommonModel.h

@@ -11,264 +11,6 @@
 #import "TIMDefine.h"
 
 NS_ASSUME_NONNULL_BEGIN
-////////////////////////////////////////////////////////////////////////////////
-//
-//                           TUIPopView
-//
-/////////////////////////////////////////////////////////////////////////////////
-@class TUIPopView;
-@protocol TUIPopViewDelegate <NSObject>
-- (void)popView:(TUIPopView *)popView didSelectRowAtIndex:(NSInteger)index;
-@end
-
-@interface TUIPopView : UIView
-@property(nonatomic, strong) UITableView *tableView;
-@property(nonatomic, assign) CGPoint arrowPoint;
-@property(nonatomic, weak) id<TUIPopViewDelegate> delegate;
-- (void)setData:(NSMutableArray *)data;
-- (void)showInWindow:(UIWindow *)window;
-@end
-
-@interface TUIPopCellData : NSObject
-@property(nonatomic, strong) UIImage *image;
-@property(nonatomic, strong) NSString *title;
-@end
-
-@interface TUIPopCell : UITableViewCell
-@property(nonatomic, strong) UIImageView *image;
-@property(nonatomic, strong) UILabel *title;
-+ (CGFloat)getHeight;
-- (void)setData:(TUIPopCellData *)data;
-@end
-
-/////////////////////////////////////////////////////////////////////////////////
-//
-//                           TUIModifyView
-//
-/////////////////////////////////////////////////////////////////////////////////
-@class TUIModifyView;
-@protocol TUIModifyViewDelegate <NSObject>
-- (void)modifyView:(TUIModifyView *)modifyView didModiyContent:(NSString *)content;
-@end
-
-@interface TUIModifyViewData : NSObject
-@property(nonatomic, strong) NSString *title;
-@property(nonatomic, strong) NSString *content;
-@property(nonatomic, strong) NSString *desc;
-@property(nonatomic, assign) BOOL enableNull;
-@end
-
-@interface TUIModifyView : UIView
-@property(nonatomic, strong) UIView *container;
-@property(nonatomic, strong) UILabel *title;
-@property(nonatomic, strong) UITextField *content;
-@property(nonatomic, strong) UILabel *descLabel;
-@property(nonatomic, strong) UIButton *confirm;
-@property(nonatomic, strong) UIView *hLine;
-@property(nonatomic, weak) id<TUIModifyViewDelegate> delegate;
-- (void)setData:(TUIModifyViewData *)data;
-- (void)showInWindow:(UIWindow *)window;
-@end
-
-/////////////////////////////////////////////////////////////////////////////////
-//
-//                           TUINaviBarIndicatorView
-//
-/////////////////////////////////////////////////////////////////////////////////
-@interface TUINaviBarIndicatorView : UIView
-
-@property(nonatomic, strong) UIActivityIndicatorView *indicator;
-
-@property(nonatomic, strong) UILabel *label;
-
-@property(nonatomic, assign) CGFloat maxLabelLength;
-
-- (void)setTitle:(NSString *)title;
-
-- (void)startAnimating;
-
-- (void)stopAnimating;
-
-@end
-
-/////////////////////////////////////////////////////////////////////////////////
-//
-//                           TUICommonCell & data
-//
-/////////////////////////////////////////////////////////////////////////////////
-
-@interface TUICommonCellData : NSObject
-@property(strong) NSString *reuseId;
-@property(nonatomic, assign) SEL cselector;
-@property(nonatomic, strong) NSDictionary *ext;
-- (CGFloat)heightOfWidth:(CGFloat)width;
-- (CGFloat)estimatedHeight;
-@end
-
-@interface TUICommonTableViewCell : UITableViewCell
-
-@property(readonly) TUICommonCellData *data;
-@property UIColor *colorWhenTouched;
-@property BOOL changeColorWhenTouched;
-
-- (void)fillWithData:(TUICommonCellData *)data;
-
-@end
-
-/////////////////////////////////////////////////////////////////////////////////
-//
-//                           TUICommonTextCell & data
-//
-/////////////////////////////////////////////////////////////////////////////////
-@interface TUICommonTextCellData : TUICommonCellData
-
-@property NSString *key;
-@property NSString *value;
-@property BOOL showAccessory;
-@property UIColor *keyColor;
-@property UIColor *valueColor;
-@property BOOL enableMultiLineValue;
-
-@property(nonatomic, assign) UIEdgeInsets keyEdgeInsets;
-
-@end
-
-@interface TUICommonTextCell : TUICommonTableViewCell
-@property UILabel *keyLabel;
-@property UILabel *valueLabel;
-@property(readonly) TUICommonTextCellData *textData;
-
-- (void)fillWithData:(TUICommonTextCellData *)data;
-
-@end
-
-/////////////////////////////////////////////////////////////////////////////////
-//
-//                           TUICommonSwitchCell & data
-//
-/////////////////////////////////////////////////////////////////////////////////
-@interface TUICommonSwitchCellData : TUICommonCellData
-
-@property NSString *title;
-@property NSString *desc;
-@property(getter=isOn) BOOL on;
-@property CGFloat margin;
-@property SEL cswitchSelector;
-
-@property(nonatomic, assign) BOOL displaySeparatorLine;
-
-@property(nonatomic, assign) BOOL disableChecked;
-
-@end
-
-@interface TUICommonSwitchCell : TUICommonTableViewCell
-@property UILabel *titleLabel;  // main title label
-@property UILabel *descLabel;   // detail title label below the main title label, used for explaining details
-@property UISwitch *switcher;
-
-@property(readonly) TUICommonSwitchCellData *switchData;
-
-- (void)fillWithData:(TUICommonSwitchCellData *)data;
-
-@end
-
-/////////////////////////////////////////////////////////////////////////////////
-//
-//                           TUIButtonCell & data
-//
-/////////////////////////////////////////////////////////////////////////////////
-typedef enum : NSUInteger {
-    ButtonGreen,
-    ButtonWhite,
-    ButtonRedText,
-    ButtonBule,
-} TUIButtonStyle;
-
-@interface TUIButtonCellData : TUICommonCellData
-@property(nonatomic, strong) NSString *title;
-@property SEL cbuttonSelector;
-@property TUIButtonStyle style;
-@property(nonatomic, strong) UIColor *textColor;
-@property(nonatomic, assign) BOOL hideSeparatorLine;
-@end
-
-@interface TUIButtonCell : TUICommonTableViewCell
-@property(nonatomic, strong) UIButton *button;
-@property TUIButtonCellData *buttonData;
-
-- (void)fillWithData:(TUIButtonCellData *)data;
-@end
-
-/////////////////////////////////////////////////////////////////////////////////
-//
-//                             TUIGroupPendencyCell & data
-//
-/////////////////////////////////////////////////////////////////////////////////
-#define TUIGroupPendencyCellData_onPendencyChanged @"TUIGroupPendencyCellData_onPendencyChanged"
-
-@interface TUIGroupPendencyCellData : TUICommonCellData
-
-@property(nonatomic, strong) NSString *groupId;
-
-@property(nonatomic, strong) NSString *fromUser;
-
-@property(nonatomic, strong) NSString *toUser;
-
-@property(readonly) V2TIMGroupApplication *pendencyItem;
-
-@property NSURL *avatarUrl;
-
-@property NSString *title;
-
-/**
- *  The joining group introduction of the requester. Such as "Xiao Ming applied to join the group".
- */
-@property NSString *requestMsg;
-
-/**
- *  Agree or Not
- *  YES: Agree;  NO: Indicates that the current request was not granted, but does not mean that the request has been denied.
- */
-@property BOOL isAccepted;
-
-/**
- *
- *  Refuse or Not
- *  YES: Refuse; NO: Indicates that the current request is not denied, but does not mean that the request has been granted.
- */
-@property BOOL isRejectd;
-@property SEL cbuttonSelector;
-
-- (instancetype)initWithPendency:(V2TIMGroupApplication *)args;
-
-typedef void (^TUIGroupPendencyCellDataSuccessCallback)(void);
-typedef void (^TUIGroupPendencyCellDataFailureCallback)(int code, NSString *msg);
-
-- (void)agreeWithSuccess:(TUIGroupPendencyCellDataSuccessCallback)success
-                 failure:(TUIGroupPendencyCellDataFailureCallback)failure;
-
-- (void)rejectWithSuccess:(TUIGroupPendencyCellDataSuccessCallback)success
-                  failure:(TUIGroupPendencyCellDataFailureCallback)failure;
-- (void)accept;
-- (void)reject;
-
-@end
-
-@interface TUIGroupPendencyCell : TUICommonTableViewCell
-
-@property UIImageView *avatarView;
-
-@property UILabel *titleLabel;
-
-@property UILabel *addWordingLabel;
-
-@property UIButton *agreeButton;
-
-@property TUIGroupPendencyCellData *pendencyData;
-
-- (void)fillWithData:(TUIGroupPendencyCellData *)pendencyData;
-
-@end
 
 /////////////////////////////////////////////////////////////////////////////////
 //
@@ -384,204 +126,4 @@ typedef void (^TUIGroupPendencyCellDataFailureCallback)(int code, NSString *msg)
 
 @end
 
-/////////////////////////////////////////////////////////////////////////////////
-//
-// TUIUnReadView
-//
-/////////////////////////////////////////////////////////////////////////////////
-@interface TUIUnReadView : UIView
-
-/**
- * The label of displaying unread message count
- */
-@property(nonatomic, strong) UILabel *unReadLabel;
-
-/**
- * Set the unread message count
- */
-- (void)setNum:(NSInteger)num;
-@end
-
-/////////////////////////////////////////////////////////////////////////////////
-//
-//                          TUIConversationPin
-//
-/////////////////////////////////////////////////////////////////////////////////
-extern NSString *kTopConversationListChangedNotification;
-
-@interface TUIConversationPin : NSObject
-
-+ (instancetype)sharedInstance;
-
-/**
- * 
- * Getting the list of pinned conversations
- */
-- (NSArray *)topConversationList;
-
-/**
- * 
- * Pin the conversation
- */
-- (void)addTopConversation:(NSString *)conv callback:(void (^__nullable)(BOOL success, NSString *__nullable errorMessage))callback;
-/**
- * 
- * Remove pinned conversations
- */
-- (void)removeTopConversation:(NSString *)conv callback:(void (^__nullable)(BOOL success, NSString *__nullable errorMessage))callback;
-@end
-
-/////////////////////////////////////////////////////////////////////////////////
-//
-//                          TUICommonContactSelectCellData
-//
-/////////////////////////////////////////////////////////////////////////////////
-@interface TUICommonContactSelectCellData : TUICommonCellData
-
-@property(nonatomic, strong) NSString *identifier;
-@property(nonatomic, strong) NSString *title;
-@property(nonatomic, strong) NSURL *avatarUrl;
-@property(nonatomic, strong) UIImage *avatarImage;
-
-@property(nonatomic, getter=isSelected) BOOL selected;
-@property(nonatomic, getter=isEnabled) BOOL enabled;
-
-@end
-
-/////////////////////////////////////////////////////////////////////////////////
-//
-//                          TUICommonContactListPickerCell
-//
-/////////////////////////////////////////////////////////////////////////////////
-@interface TUICommonContactListPickerCell : UICollectionViewCell
-
-@property UIImageView *avatar;
-
-@end
-
-/////////////////////////////////////////////////////////////////////////////////
-//
-//                          TUIContactListPickerOnCancel
-//
-/////////////////////////////////////////////////////////////////////////////////
-typedef void (^TUIContactListPickerOnCancel)(TUICommonContactSelectCellData *data);
-
-@interface TUIContactListPicker : UIControl
-
-@property(nonatomic, strong, readonly) UIButton *accessoryBtn;
-@property(nonatomic, strong) NSArray<TUICommonContactSelectCellData *> *selectArray;
-@property(nonatomic, copy) TUIContactListPickerOnCancel onCancel;
-
-@end
-
-/////////////////////////////////////////////////////////////////////////////////
-//
-//                             TUIProfileCardCell & vc
-//
-/////////////////////////////////////////////////////////////////////////////////
-@class TUIProfileCardCell;
-@protocol TUIProfileCardDelegate <NSObject>
-- (void)didTapOnAvatar:(TUIProfileCardCell *)cell;
-@end
-
-@interface TUIProfileCardCellData : TUICommonCellData
-@property(nonatomic, strong) UIImage *avatarImage;
-@property(nonatomic, strong) NSURL *avatarUrl;
-@property(nonatomic, strong) NSString *name;
-@property(nonatomic, strong) NSString *identifier;
-@property(nonatomic, strong) NSString *signature;
-@property(nonatomic, strong) UIImage *genderIconImage;
-@property(nonatomic, strong) NSString *genderString;
-@property BOOL showAccessory;
-@property BOOL showSignature;
-@end
-
-@interface TUIProfileCardCell : TUICommonTableViewCell
-@property(nonatomic, strong) UIImageView *avatar;
-@property(nonatomic, strong) UILabel *name;
-@property(nonatomic, strong) UILabel *identifier;
-@property(nonatomic, strong) UILabel *signature;
-@property(nonatomic, strong) UIImageView *genderIcon;
-@property(nonatomic, strong) TUIProfileCardCellData *cardData;
-@property(nonatomic, weak) id<TUIProfileCardDelegate> delegate;
-- (void)fillWithData:(TUIProfileCardCellData *)data;
-@end
-
-@interface TUIAvatarViewController : UIViewController
-
-@property(nonatomic, strong) TUIProfileCardCellData *avatarData;
-
-@end
-
-typedef NS_ENUM(NSUInteger, TUISelectAvatarType) {
-    TUISelectAvatarTypeUserAvatar,
-    TUISelectAvatarTypeGroupAvatar,
-    TUISelectAvatarTypeCover,
-    TUISelectAvatarTypeConversationBackGroundCover,
-};
-
-@interface TUISelectAvatarCardItem : NSObject
-@property(nonatomic, strong) NSString *posterUrlStr;
-@property(nonatomic, assign) BOOL isSelect;
-@property(nonatomic, copy) NSString *fullUrlStr;
-@property(nonatomic, assign) BOOL isDefaultBackgroundItem;
-@property(nonatomic, assign) BOOL isGroupGridAvatar;
-@property(nonatomic, copy) NSString *createGroupType;
-@property(nonatomic, strong) UIImage *cacheGroupGridAvatarImage;
-@end
-
-@interface TUISelectAvatarController : UIViewController
-@property(nonatomic, copy) void (^selectCallBack)(NSString *urlStr);
-@property(nonatomic, assign) TUISelectAvatarType selectAvatarType;
-@property(nonatomic, copy) NSString *profilFaceURL;
-@property(nonatomic, strong) UIImage *cacheGroupGridAvatarImage;
-@property(nonatomic, copy) NSString *createGroupType;
-@end
-
-/////////////////////////////////////////////////////////////////////////////////
-//
-//                             TUICommonAvatarCell & Data
-//
-/////////////////////////////////////////////////////////////////////////////////
-@interface TUICommonAvatarCellData : TUICommonCellData
-;
-@property(nonatomic, strong) NSString *key;
-@property(nonatomic, strong) NSString *value;
-@property BOOL showAccessory;
-@property(nonatomic, strong) UIImage *avatarImage;
-@property(nonatomic, strong) NSURL *avatarUrl;
-
-@end
-
-@interface TUICommonAvatarCell : TUICommonTableViewCell
-@property UILabel *keyLabel;
-@property UILabel *valueLabel;
-@property UIImageView *avatar;
-@property(readonly) TUICommonAvatarCellData *avatarData;
-
-- (void)fillWithData:(TUICommonAvatarCellData *)avatarData;
-
-@end
-
-/////////////////////////////////////////////////////////////////////////////////
-//
-//                             TUIConversationGroupItem
-//
-/////////////////////////////////////////////////////////////////////////////////
-extern NSUInteger kConversationMarkStarType;
-@interface TUIConversationGroupItem : NSObject
-@property(nonatomic, strong) NSString *groupName;
-@property(nonatomic, assign) NSInteger unreadCount;
-@property(nonatomic, assign) NSInteger groupIndex;
-@property(nonatomic, assign) BOOL isShow;
-@property(nonatomic, strong) UIButton *groupBtn;
-@end
-
-
-@interface TUISendMessageAppendParams : NSObject
-@property (nonatomic, assign) BOOL isSendPushInfo;
-@property (nonatomic, assign) BOOL isOnlineUserOnly;
-@property (nonatomic, assign) V2TIMMessagePriority priority;
-+ (instancetype)defaultConfig;
-@end
 NS_ASSUME_NONNULL_END

文件差异内容过多而无法显示
+ 46 - 1185
ThirdParty/TUIKit/TIMCommon/CommonModel/TIMCommonModel.m


+ 0 - 2
ThirdParty/TUIKit/TIMCommon/CommonModel/TIMDefine.h

@@ -11,10 +11,8 @@
 
 #import <ReactiveObjC/ReactiveObjC.h>
 #import <TUICore/TUIDefine.h>
-#import <Masonry/Masonry.h>
 #import "TIMConfig.h"
 #import "TIMCommonModel.h"
-#import "TIMRTLUtil.h"
 
 #define kEnableAllRotationOrientationNotification @"kEnableAllRotationOrientationNotification"
 #define kDisableAllRotationOrientationNotification @"kDisableAllRotationOrientationNotification"

+ 0 - 20
ThirdParty/TUIKit/TIMCommon/CommonModel/TIMGroupInfo+TUIDataProvider.h

@@ -1,20 +0,0 @@
-
-//  Created by Tencent on 2023/06/09.
-//  Copyright © 2023 Tencent. All rights reserved.
-#import <Foundation/Foundation.h>
-@import ImSDK_Plus;
-
-NS_ASSUME_NONNULL_BEGIN
-
-@interface V2TIMGroupInfo (TUIDataProvider)
-
-- (BOOL)isMeOwner;
-- (BOOL)isPrivate;
-- (BOOL)canInviteMember;
-- (BOOL)canRemoveMember;
-- (BOOL)canDismissGroup;
-- (BOOL)canSupportSetAdmain;
-
-@end
-
-NS_ASSUME_NONNULL_END

+ 0 - 46
ThirdParty/TUIKit/TIMCommon/CommonModel/TIMGroupInfo+TUIDataProvider.m

@@ -1,46 +0,0 @@
-
-//  Created by Tencent on 2023/06/09.
-//  Copyright © 2023 Tencent. All rights reserved.
-
-#import <TUICore/TUIGlobalization.h>
-#import "TIMGroupInfo+TUIDataProvider.h"
-
-@implementation V2TIMGroupInfo (TUIDataProvider)
-
-- (BOOL)isMeOwner {
-    return [self.owner isEqualToString:[[V2TIMManager sharedInstance] getLoginUser]] || (self.role == V2TIM_GROUP_MEMBER_ROLE_ADMIN);
-}
-
-- (BOOL)isPrivate {
-    return [self.groupType isEqualToString:@"Work"];
-}
-
-- (BOOL)canInviteMember {
-    return self.groupApproveOpt != V2TIM_GROUP_ADD_FORBID;
-}
-
-- (BOOL)canRemoveMember {
-    return [self isMeOwner] && (self.memberCount > 1);
-}
-
-- (BOOL)canDismissGroup {
-    if ([self isPrivate]) {
-        return NO;
-    } else {
-        if ([self.owner isEqualToString:[[V2TIMManager sharedInstance] getLoginUser]] || (self.role == V2TIM_GROUP_MEMBER_ROLE_SUPER)) {
-            return YES;
-        } else {
-            return NO;
-        }
-    }
-}
-
-- (BOOL)canSupportSetAdmain {
-    BOOL isMeSuper = [self.owner isEqualToString:[[V2TIMManager sharedInstance] getLoginUser]] || (self.role == V2TIM_GROUP_MEMBER_ROLE_SUPER);
-
-    BOOL isCurrentGroupTypeSupportSetAdmain = ([self.groupType isEqualToString:@"Public"] || [self.groupType isEqualToString:@"Meeting"] ||
-                                               [self.groupType isEqualToString:@"Community"] || [self.groupType isEqualToString:@"Private"]);
-
-    return isMeSuper && isCurrentGroupTypeSupportSetAdmain && (self.memberCount > 1);
-}
-@end

+ 0 - 19
ThirdParty/TUIKit/TIMCommon/CommonModel/TIMInputViewMoreActionProtocol.h

@@ -1,19 +0,0 @@
-//
-//  TIMInputViewMoreActionProtocol.h
-//  TIMCommon
-//
-//  Created by wyl on 2023/5/5.
-//  Copyright © 2023 Tencent. All rights reserved.
-//
-
-#import <Foundation/Foundation.h>
-
-NS_ASSUME_NONNULL_BEGIN
-
-@protocol TIMInputViewMoreActionProtocol <NSObject>
-
-- (void)sendMessage:(V2TIMMessage *)message;
-
-@end
-
-NS_ASSUME_NONNULL_END

+ 0 - 33
ThirdParty/TUIKit/TIMCommon/CommonModel/TIMPopActionProtocol.h

@@ -1,33 +0,0 @@
-//
-//  TIMPopActionProtocol.h
-//  TIMCommon
-//
-//  Created by wyl on 2023/4/3.
-//  Copyright © 2023 Tencent. All rights reserved.
-//
-
-#import <Foundation/Foundation.h>
-
-NS_ASSUME_NONNULL_BEGIN
-
-@protocol TIMPopActionProtocol <NSObject>
-
-- (void)onDelete:(id)sender;
-
-- (void)onCopyMsg:(id)sender;
-
-- (void)onRevoke:(id)sender;
-
-- (void)onReSend:(id)sender;
-
-- (void)onMulitSelect:(id)sender;
-
-- (void)onForward:(id)sender;
-
-- (void)onReply:(id)sender;
-
-- (void)onReference:(id)sender;
-
-@end
-
-NS_ASSUME_NONNULL_END

+ 0 - 661
ThirdParty/TUIKit/TIMCommon/CommonModel/TUIAttributedLabel.h

@@ -1,661 +0,0 @@
-
-//  Created by Tencent on 2023/06/09.
-//  Copyright © 2023 Tencent. All rights reserved.
-// TUIAttributedLabel.h
-
-#import <CoreText/CoreText.h>
-#import <UIKit/UIKit.h>
-
-//! Project version number for TUIAttributedLabel.
-FOUNDATION_EXPORT double TUIAttributedLabelVersionNumber;
-
-//! Project version string for TUIAttributedLabel.
-FOUNDATION_EXPORT const unsigned char TUIAttributedLabelVersionString[];
-
-@class TUIAttributedLabelLink;
-
-/**
- Vertical alignment for text in a label whose bounds are larger than its text bounds
- */
-typedef NS_ENUM(NSInteger, TUIAttributedLabelVerticalAlignment) {
-    TUIAttributedLabelVerticalAlignmentCenter = 0,
-    TUIAttributedLabelVerticalAlignmentTop = 1,
-    TUIAttributedLabelVerticalAlignmentBottom = 2,
-};
-
-/**
- Determines whether the text to which this attribute applies has a strikeout drawn through itself.
- */
-extern NSString *const kTUIStrikeOutAttributeName;
-
-/**
- The background fill color. Value must be a `CGColorRef`. Default value is `nil` (no fill).
- */
-extern NSString *const kTUIBackgroundFillColorAttributeName;
-
-/**
- The padding for the background fill. Value must be a `UIEdgeInsets`. Default value is `UIEdgeInsetsZero` (no padding).
- */
-extern NSString *const kTUIBackgroundFillPaddingAttributeName;
-
-/**
- The background stroke color. Value must be a `CGColorRef`. Default value is `nil` (no stroke).
- */
-extern NSString *const kTUIBackgroundStrokeColorAttributeName;
-
-/**
- The background stroke line width. Value must be an `NSNumber`. Default value is `1.0f`.
- */
-extern NSString *const kTUIBackgroundLineWidthAttributeName;
-
-/**
- The background corner radius. Value must be an `NSNumber`. Default value is `5.0f`.
- */
-extern NSString *const kTUIBackgroundCornerRadiusAttributeName;
-
-@protocol TUIAttributedLabelDelegate;
-
-// Override UILabel @property to accept both NSString and NSAttributedString
-@protocol TUIAttributedLabel <NSObject>
-@property(nonatomic, copy) IBInspectable id text;
-@end
-
-IB_DESIGNABLE
-
-/**
- `TUIAttributedLabel` is a drop-in replacement for `UILabel` that supports `NSAttributedString`, as well as automatically-detected and manually-added links to
- URLs, addresses, phone numbers, and dates.
-
- ## Differences Between `TUIAttributedLabel` and `UILabel`
-
- For the most part, `TUIAttributedLabel` behaves just like `UILabel`. The following are notable exceptions, in which `TUIAttributedLabel` may act differently:
-
- - `text` - This property now takes an `id` type argument, which can either be a kind of `NSString` or `NSAttributedString` (mutable or immutable in both cases)
- - `attributedText` - Do not set this property directly. Instead, pass an `NSAttributedString` to `text`.
- - `lineBreakMode` - This property displays only the first line when the value is `UILineBreakModeHeadTruncation`, `UILineBreakModeTailTruncation`, or
- `UILineBreakModeMiddleTruncation`
- - `adjustsFontsizeToFitWidth` - Supported in iOS 5 and greater, this property is effective for any value of `numberOfLines` greater than zero. In iOS 4,
- setting `numberOfLines` to a value greater than 1 with `adjustsFontSizeToFitWidth` set to `YES` may cause `sizeToFit` to execute indefinitely.
- - `baselineAdjustment` - This property has no affect.
- - `textAlignment` - This property does not support justified alignment.
- - `NSTextAttachment` - This string attribute is not supported.
-
- Any properties affecting text or paragraph styling, such as `firstLineIndent` will only apply when text is set with an `NSString`. If the text is set with an
- `NSAttributedString`, these properties will not apply.
-
- ### NSCoding
-
- `TUIAttributedLabel`, like `UILabel`, conforms to `NSCoding`. However, if the build target is set to less than iOS 6.0, `linkAttributes` and
- `activeLinkAttributes` will not be encoded or decoded. This is due to an runtime exception thrown when attempting to copy non-object CoreText values in
- dictionaries.
-
- @warning Any properties changed on the label after setting the text will not be reflected until a subsequent call to `setText:` or
- `setText:afterInheritingLabelAttributesAndConfiguringWithBlock:`. This is to say, order of operations matters in this case. For example, if the label text
- color is originally black when the text is set, changing the text color to red will have no effect on the display of the label until the text is set once
- again.
-
- @bug Setting `attributedText` directly is not recommended, as it may cause a crash when attempting to access any links previously set. Instead, call
- `setText:`, passing an `NSAttributedString`.
- */
-@interface TUIAttributedLabel : UILabel <TUIAttributedLabel, UIGestureRecognizerDelegate>
-
-/**
- * The designated initializers are @c initWithFrame: and @c initWithCoder:.
- * init will not properly initialize many required properties and other configuration.
- */
-- (instancetype)init NS_UNAVAILABLE;
-
-///-----------------------------
-/// @name Accessing the Delegate
-///-----------------------------
-
-/**
- The receiver's delegate.
-
- @discussion A `TUIAttributedLabel` delegate responds to messages sent by tapping on links in the label. You can use the delegate to respond to links
- referencing a URL, address, phone number, date, or date with a specified time zone and duration.
- */
-@property(nonatomic, unsafe_unretained) IBOutlet id<TUIAttributedLabelDelegate> delegate;
-
-///--------------------------------------------
-/// @name Detecting, Accessing, & Styling Links
-///--------------------------------------------
-
-/**
- A bitmask of `NSTextCheckingType` which are used to automatically detect links in the label text.
-
- @warning You must specify `enabledTextCheckingTypes` before setting the `text`, with either `setText:` or
- `setText:afterInheritingLabelAttributesAndConfiguringWithBlock:`.
- */
-@property(nonatomic, assign) NSTextCheckingTypes enabledTextCheckingTypes;
-
-/**
- An array of `NSTextCheckingResult` objects for links detected or manually added to the label text.
- */
-@property(readonly, nonatomic, strong) NSArray *links;
-
-/**
- A dictionary containing the default `NSAttributedString` attributes to be applied to links detected or manually added to the label text. The default link style
- is blue and underlined.
-
- @warning You must specify `linkAttributes` before setting autodecting or manually-adding links for these attributes to be applied.
- */
-@property(nonatomic, strong) NSDictionary *linkAttributes;
-
-/**
- A dictionary containing the default `NSAttributedString` attributes to be applied to links when they are in the active state. If `nil` or an empty
- `NSDictionary`, active links will not be styled. The default active link style is red and underlined.
- */
-@property(nonatomic, strong) NSDictionary *activeLinkAttributes;
-
-/**
- A dictionary containing the default `NSAttributedString` attributes to be applied to links when they are in the inactive state, which is triggered by a change
- in `tintColor` in iOS 7 and later. If `nil` or an empty `NSDictionary`, inactive links will not be styled. The default inactive link style is gray and
- unadorned.
- */
-@property(nonatomic, strong) NSDictionary *inactiveLinkAttributes;
-
-/**
- The edge inset for the background of a link. The default value is `{0, -1, 0, -1}`.
- */
-@property(nonatomic, assign) UIEdgeInsets linkBackgroundEdgeInset;
-
-/**
- Indicates if links will be detected within an extended area around the touch
- to emulate the link detection behaviour of WKWebView.
- Default value is NO. Enabling this may adversely impact performance.
- */
-@property(nonatomic, assign) BOOL extendsLinkTouchArea;
-
-///---------------------------------------
-/// @name Acccessing Text Style Attributes
-///---------------------------------------
-
-/**
- The shadow blur radius for the label. A value of 0 indicates no blur, while larger values produce correspondingly larger blurring. This value must not be
- negative. The default value is 0.
- */
-@property(nonatomic, assign) IBInspectable CGFloat shadowRadius;
-
-/**
- The shadow blur radius for the label when the label's `highlighted` property is `YES`. A value of 0 indicates no blur, while larger values produce
- correspondingly larger blurring. This value must not be negative. The default value is 0.
- */
-@property(nonatomic, assign) IBInspectable CGFloat highlightedShadowRadius;
-/**
- The shadow offset for the label when the label's `highlighted` property is `YES`. A size of {0, 0} indicates no offset, with positive values extending down and
- to the right. The default size is {0, 0}.
- */
-@property(nonatomic, assign) IBInspectable CGSize highlightedShadowOffset;
-/**
- The shadow color for the label when the label's `highlighted` property is `YES`. The default value is `nil` (no shadow color).
- */
-@property(nonatomic, strong) IBInspectable UIColor *highlightedShadowColor;
-
-/**
- The amount to kern the next character. Default is standard kerning. If this attribute is set to 0.0, no kerning is done at all.
- */
-@property(nonatomic, assign) IBInspectable CGFloat kern;
-
-///--------------------------------------------
-/// @name Acccessing Paragraph Style Attributes
-///--------------------------------------------
-
-/**
- The distance, in points, from the leading margin of a frame to the beginning of the
- paragraph's first line. This value is always nonnegative, and is 0.0 by default.
- This applies to the full text, rather than any specific paragraph metrics.
- */
-@property(nonatomic, assign) IBInspectable CGFloat firstLineIndent;
-
-/**
- The space in points added between lines within the paragraph. This value is always nonnegative and is 0.0 by default.
- */
-@property(nonatomic, assign) IBInspectable CGFloat lineSpacing;
-
-/**
- The minimum line height within the paragraph. If the value is 0.0, the minimum line height is set to the line height of the `font`. 0.0 by default.
- */
-@property(nonatomic, assign) IBInspectable CGFloat minimumLineHeight;
-
-/**
- The maximum line height within the paragraph. If the value is 0.0, the maximum line height is set to the line height of the `font`. 0.0 by default.
- */
-@property(nonatomic, assign) IBInspectable CGFloat maximumLineHeight;
-
-/**
- The line height multiple. This value is 1.0 by default.
- */
-@property(nonatomic, assign) IBInspectable CGFloat lineHeightMultiple;
-
-/**
- The distance, in points, from the margin to the text container. This value is `UIEdgeInsetsZero` by default.
- sizeThatFits: will have its returned size increased by these margins.
- drawTextInRect: will inset all drawn text by these margins.
- */
-@property(nonatomic, assign) IBInspectable UIEdgeInsets textInsets;
-
-/**
- The vertical text alignment for the label, for when the frame size is greater than the text rect size. The vertical alignment is
- `TUIAttributedLabelVerticalAlignmentCenter` by default.
- */
-@property(nonatomic, assign) TUIAttributedLabelVerticalAlignment verticalAlignment;
-
-///--------------------------------------------
-/// @name Accessing Truncation Token Appearance
-///--------------------------------------------
-
-/**
- The attributed string to apply to the truncation token at the end of a truncated line.
- */
-@property(nonatomic, strong) IBInspectable NSAttributedString *attributedTruncationToken;
-
-///--------------------------
-/// @name Long press gestures
-///--------------------------
-
-/**
- *  The long-press gesture recognizer used internally by the label.
- */
-@property(nonatomic, strong, readonly) UILongPressGestureRecognizer *longPressGestureRecognizer;
-
-///--------------------------------------------
-/// @name Calculating Size of Attributed String
-///--------------------------------------------
-
-/**
- Calculate and return the size that best fits an attributed string, given the specified constraints on size and number of lines.
-
- @param attributedString The attributed string.
- @param size The maximum dimensions used to calculate size.
- @param numberOfLines The maximum number of lines in the text to draw, if the constraining size cannot accomodate the full attributed string.
-
- @return The size that fits the attributed string within the specified constraints.
- */
-+ (CGSize)sizeThatFitsAttributedString:(NSAttributedString *)attributedString withConstraints:(CGSize)size limitedToNumberOfLines:(NSUInteger)numberOfLines;
-
-///----------------------------------
-/// @name Setting the Text Attributes
-///----------------------------------
-
-/**
- Sets the text displayed by the label.
-
- @param text An `NSString` or `NSAttributedString` object to be displayed by the label. If the specified text is an `NSString`, the label will display the text
- like a `UILabel`, inheriting the text styles of the label. If the specified text is an `NSAttributedString`, the label text styles will be overridden by the
- styles specified in the attributed string.
-
- @discussion This method overrides `UILabel -setText:` to accept both `NSString` and `NSAttributedString` objects. This string is `nil` by default.
- */
-- (void)setText:(id)text;
-
-/**
- Sets the text displayed by the label, after configuring an attributed string containing the text attributes inherited from the label in a block.
-
- @param text An `NSString` or `NSAttributedString` object to be displayed by the label.
- @param block A block object that returns an `NSMutableAttributedString` object and takes a single argument, which is an `NSMutableAttributedString` object with
- the text from the first parameter, and the text attributes inherited from the label text styles. For example, if you specified the `font` of the label to be
- `[UIFont boldSystemFontOfSize:14]` and `textColor` to be `[UIColor redColor]`, the `NSAttributedString` argument of the block would be contain the
- `NSAttributedString` attribute equivalents of those properties. In this block, you can set further attributes on particular ranges.
-
- @discussion This string is `nil` by default.
- */
-- (void)setText:(id)text
-    afterInheritingLabelAttributesAndConfiguringWithBlock:(NSMutableAttributedString * (^)(NSMutableAttributedString *mutableAttributedString))block;
-
-///------------------------------------
-/// @name Accessing the Text Attributes
-///------------------------------------
-
-/**
- A copy of the label's current attributedText. This returns `nil` if an attributed string has never been set on the label.
-
- @warning Do not set this property directly. Instead, set @c text to an @c NSAttributedString.
- */
-@property(readwrite, nonatomic, copy) NSAttributedString *attributedText;
-
-///-------------------
-/// @name Adding Links
-///-------------------
-
-/**
- Adds a link. You can customize an individual link's appearance and accessibility value by creating your own @c TUIAttributedLabelLink and passing it to this
- method. The other methods for adding links will use the label's default attributes.
-
- @warning Modifying the link's attribute dictionaries must be done before calling this method.
-
- @param link A @c TUIAttributedLabelLink object.
- */
-- (void)addLink:(TUIAttributedLabelLink *)link;
-
-/**
- Adds a link to an @c NSTextCheckingResult.
-
- @param result An @c NSTextCheckingResult representing the link's location and type.
-
- @return The newly added link object.
- */
-- (TUIAttributedLabelLink *)addLinkWithTextCheckingResult:(NSTextCheckingResult *)result;
-
-/**
- Adds a link to an @c NSTextCheckingResult.
-
- @param result An @c NSTextCheckingResult representing the link's location and type.
- @param attributes The attributes to be added to the text in the range of the specified link. If set, the label's @c activeAttributes and @c inactiveAttributes
- will be applied to the link. If `nil`, no attributes are added to the link.
-
- @return The newly added link object.
- */
-- (TUIAttributedLabelLink *)addLinkWithTextCheckingResult:(NSTextCheckingResult *)result attributes:(NSDictionary *)attributes;
-
-/**
- Adds a link to a URL for a specified range in the label text.
-
- @param url The url to be linked to
- @param range The range in the label text of the link. The range must not exceed the bounds of the receiver.
-
- @return The newly added link object.
- */
-- (TUIAttributedLabelLink *)addLinkToURL:(NSURL *)url withRange:(NSRange)range;
-
-/**
- Adds a link to an address for a specified range in the label text.
-
- @param addressComponents A dictionary of address components for the address to be linked to
- @param range The range in the label text of the link. The range must not exceed the bounds of the receiver.
-
- @discussion The address component dictionary keys are described in `NSTextCheckingResult`'s "Keys for Address Components."
-
- @return The newly added link object.
- */
-- (TUIAttributedLabelLink *)addLinkToAddress:(NSDictionary *)addressComponents withRange:(NSRange)range;
-
-/**
- Adds a link to a phone number for a specified range in the label text.
-
- @param phoneNumber The phone number to be linked to.
- @param range The range in the label text of the link. The range must not exceed the bounds of the receiver.
-
- @return The newly added link object.
- */
-- (TUIAttributedLabelLink *)addLinkToPhoneNumber:(NSString *)phoneNumber withRange:(NSRange)range;
-
-/**
- Adds a link to a date for a specified range in the label text.
-
- @param date The date to be linked to.
- @param range The range in the label text of the link. The range must not exceed the bounds of the receiver.
-
- @return The newly added link object.
- */
-- (TUIAttributedLabelLink *)addLinkToDate:(NSDate *)date withRange:(NSRange)range;
-
-/**
- Adds a link to a date with a particular time zone and duration for a specified range in the label text.
-
- @param date The date to be linked to.
- @param timeZone The time zone of the specified date.
- @param duration The duration, in seconds from the specified date.
- @param range The range in the label text of the link. The range must not exceed the bounds of the receiver.
-
- @return The newly added link object.
- */
-- (TUIAttributedLabelLink *)addLinkToDate:(NSDate *)date timeZone:(NSTimeZone *)timeZone duration:(NSTimeInterval)duration withRange:(NSRange)range;
-
-/**
- Adds a link to transit information for a specified range in the label text.
-
- @param components A dictionary containing the transit components. The currently supported keys are `NSTextCheckingAirlineKey` and `NSTextCheckingFlightKey`.
- @param range The range in the label text of the link. The range must not exceed the bounds of the receiver.
-
- @return The newly added link object.
- */
-- (TUIAttributedLabelLink *)addLinkToTransitInformation:(NSDictionary *)components withRange:(NSRange)range;
-
-/**
- Returns whether an @c NSTextCheckingResult is found at the give point.
-
- @discussion This can be used together with @c UITapGestureRecognizer to tap interactions with overlapping views.
-
- @param point The point inside the label.
- */
-- (BOOL)containslinkAtPoint:(CGPoint)point;
-
-/**
- Returns the @c TUIAttributedLabelLink at the give point if it exists.
-
- @discussion This can be used together with @c UIViewControllerPreviewingDelegate to peek into links.
-
- @param point The point inside the label.
- */
-- (TUIAttributedLabelLink *)linkAtPoint:(CGPoint)point;
-
-@end
-
-/**
- The `TUIAttributedLabelDelegate` protocol defines the messages sent to an attributed label delegate when links are tapped. All of the methods of this protocol
- are optional.
- */
-@protocol TUIAttributedLabelDelegate <NSObject>
-
-///-----------------------------------
-/// @name Responding to Link Selection
-///-----------------------------------
-@optional
-
-/**
- Tells the delegate that the user did select a link to a URL.
-
- @param label The label whose link was selected.
- @param url The URL for the selected link.
- */
-- (void)attributedLabel:(TUIAttributedLabel *)label didSelectLinkWithURL:(NSURL *)url;
-
-/**
- Tells the delegate that the user did select a link to an address.
-
- @param label The label whose link was selected.
- @param addressComponents The components of the address for the selected link.
- */
-- (void)attributedLabel:(TUIAttributedLabel *)label didSelectLinkWithAddress:(NSDictionary *)addressComponents;
-
-/**
- Tells the delegate that the user did select a link to a phone number.
-
- @param label The label whose link was selected.
- @param phoneNumber The phone number for the selected link.
- */
-- (void)attributedLabel:(TUIAttributedLabel *)label didSelectLinkWithPhoneNumber:(NSString *)phoneNumber;
-
-/**
- Tells the delegate that the user did select a link to a date.
-
- @param label The label whose link was selected.
- @param date The datefor the selected link.
- */
-- (void)attributedLabel:(TUIAttributedLabel *)label didSelectLinkWithDate:(NSDate *)date;
-
-/**
- Tells the delegate that the user did select a link to a date with a time zone and duration.
-
- @param label The label whose link was selected.
- @param date The date for the selected link.
- @param timeZone The time zone of the date for the selected link.
- @param duration The duration, in seconds from the date for the selected link.
- */
-- (void)attributedLabel:(TUIAttributedLabel *)label didSelectLinkWithDate:(NSDate *)date timeZone:(NSTimeZone *)timeZone duration:(NSTimeInterval)duration;
-
-/**
- Tells the delegate that the user did select a link to transit information
-
- @param label The label whose link was selected.
- @param components A dictionary containing the transit components. The currently supported keys are `NSTextCheckingAirlineKey` and `NSTextCheckingFlightKey`.
- */
-- (void)attributedLabel:(TUIAttributedLabel *)label didSelectLinkWithTransitInformation:(NSDictionary *)components;
-
-/**
- Tells the delegate that the user did select a link to a text checking result.
-
- @discussion This method is called if no other delegate method was called, which can occur by either now implementing the method in `TUIAttributedLabelDelegate`
- corresponding to a particular link, or the link was added by passing an instance of a custom `NSTextCheckingResult` subclass into
- `-addLinkWithTextCheckingResult:`.
-
- @param label The label whose link was selected.
- @param result The custom text checking result.
- */
-- (void)attributedLabel:(TUIAttributedLabel *)label didSelectLinkWithTextCheckingResult:(NSTextCheckingResult *)result;
-
-///---------------------------------
-/// @name Responding to Long Presses
-///---------------------------------
-
-/**
- *  Long-press delegate methods include the CGPoint tapped within the label's coordinate space.
- *  This may be useful on iPad to present a popover from a specific origin point.
- */
-
-/**
- Tells the delegate that the user long-pressed a link to a URL.
-
- @param label The label whose link was long pressed.
- @param url The URL for the link.
- @param point the point pressed, in the label's coordinate space
- */
-- (void)attributedLabel:(TUIAttributedLabel *)label didLongPressLinkWithURL:(NSURL *)url atPoint:(CGPoint)point;
-
-/**
- Tells the delegate that the user long-pressed a link to an address.
-
- @param label The label whose link was long pressed.
- @param addressComponents The components of the address for the link.
- @param point the point pressed, in the label's coordinate space
- */
-- (void)attributedLabel:(TUIAttributedLabel *)label didLongPressLinkWithAddress:(NSDictionary *)addressComponents atPoint:(CGPoint)point;
-
-/**
- Tells the delegate that the user long-pressed a link to a phone number.
-
- @param label The label whose link was long pressed.
- @param phoneNumber The phone number for the link.
- @param point the point pressed, in the label's coordinate space
- */
-- (void)attributedLabel:(TUIAttributedLabel *)label didLongPressLinkWithPhoneNumber:(NSString *)phoneNumber atPoint:(CGPoint)point;
-
-/**
- Tells the delegate that the user long-pressed a link to a date.
-
- @param label The label whose link was long pressed.
- @param date The date for the selected link.
- @param point the point pressed, in the label's coordinate space
- */
-- (void)attributedLabel:(TUIAttributedLabel *)label didLongPressLinkWithDate:(NSDate *)date atPoint:(CGPoint)point;
-
-/**
- Tells the delegate that the user long-pressed a link to a date with a time zone and duration.
-
- @param label The label whose link was long pressed.
- @param date The date for the link.
- @param timeZone The time zone of the date for the link.
- @param duration The duration, in seconds from the date for the link.
- @param point the point pressed, in the label's coordinate space
- */
-- (void)attributedLabel:(TUIAttributedLabel *)label
-    didLongPressLinkWithDate:(NSDate *)date
-                    timeZone:(NSTimeZone *)timeZone
-                    duration:(NSTimeInterval)duration
-                     atPoint:(CGPoint)point;
-
-/**
- Tells the delegate that the user long-pressed a link to transit information.
-
- @param label The label whose link was long pressed.
- @param components A dictionary containing the transit components. The currently supported keys are `NSTextCheckingAirlineKey` and `NSTextCheckingFlightKey`.
- @param point the point pressed, in the label's coordinate space
- */
-- (void)attributedLabel:(TUIAttributedLabel *)label didLongPressLinkWithTransitInformation:(NSDictionary *)components atPoint:(CGPoint)point;
-
-/**
- Tells the delegate that the user long-pressed a link to a text checking result.
-
- @discussion Similar to `-attributedLabel:didSelectLinkWithTextCheckingResult:`, this method is called if a link is long pressed and the delegate does not
- implement the method corresponding to this type of link.
-
- @param label The label whose link was long pressed.
- @param result The custom text checking result.
- @param point the point pressed, in the label's coordinate space
- */
-- (void)attributedLabel:(TUIAttributedLabel *)label didLongPressLinkWithTextCheckingResult:(NSTextCheckingResult *)result atPoint:(CGPoint)point;
-
-@end
-
-@interface TUIAttributedLabelLink : NSObject <NSCoding>
-
-typedef void (^TUIAttributedLabelLinkBlock)(TUIAttributedLabel *, TUIAttributedLabelLink *);
-
-/**
- An `NSTextCheckingResult` representing the link's location and type.
- */
-@property(readonly, nonatomic, strong) NSTextCheckingResult *result;
-
-/**
- A dictionary containing the @c NSAttributedString attributes to be applied to the link.
- */
-@property(readonly, nonatomic, copy) NSDictionary *attributes;
-
-/**
- A dictionary containing the @c NSAttributedString attributes to be applied to the link when it is in the active state.
- */
-@property(readonly, nonatomic, copy) NSDictionary *activeAttributes;
-
-/**
- A dictionary containing the @c NSAttributedString attributes to be applied to the link when it is in the inactive state, which is triggered by a change in
- `tintColor` in iOS 7 and later.
- */
-@property(readonly, nonatomic, copy) NSDictionary *inactiveAttributes;
-
-/**
- Additional information about a link for VoiceOver users. Has default values if the link's @c result is @c NSTextCheckingTypeLink, @c
- NSTextCheckingTypePhoneNumber, or @c NSTextCheckingTypeDate.
- */
-@property(nonatomic, copy) NSString *accessibilityValue;
-
-/**
- A block called when this link is tapped.
- If non-nil, tapping on this link will call this block instead of the
- @c TUIAttributedLabelDelegate tap methods, which will not be called for this link.
- */
-@property(nonatomic, copy) TUIAttributedLabelLinkBlock linkTapBlock;
-
-/**
- A block called when this link is long-pressed.
- If non-nil, long pressing on this link will call this block instead of the
- @c TUIAttributedLabelDelegate long press methods, which will not be called for this link.
- */
-@property(nonatomic, copy) TUIAttributedLabelLinkBlock linkLongPressBlock;
-
-/**
- Initializes a link using the attribute dictionaries specified.
-
- @param attributes         The @c attributes property for the link.
- @param activeAttributes   The @c activeAttributes property for the link.
- @param inactiveAttributes The @c inactiveAttributes property for the link.
- @param result             An @c NSTextCheckingResult representing the link's location and type.
-
- @return The initialized link object.
- */
-- (instancetype)initWithAttributes:(NSDictionary *)attributes
-                  activeAttributes:(NSDictionary *)activeAttributes
-                inactiveAttributes:(NSDictionary *)inactiveAttributes
-                textCheckingResult:(NSTextCheckingResult *)result;
-
-/**
- Initializes a link using the attribute dictionaries set on a specified label.
-
- @param label  The attributed label from which to inherit attribute dictionaries.
- @param result An @c NSTextCheckingResult representing the link's location and type.
-
- @return The initialized link object.
- */
-- (instancetype)initWithAttributesFromLabel:(TUIAttributedLabel *)label textCheckingResult:(NSTextCheckingResult *)result;
-
-@end

+ 0 - 1797
ThirdParty/TUIKit/TIMCommon/CommonModel/TUIAttributedLabel.m

@@ -1,1797 +0,0 @@
-
-//  Created by Tencent on 2023/06/09.
-//  Copyright © 2023 Tencent. All rights reserved.
-// TUIAttributedLabel.m
-
-#import "TUIAttributedLabel.h"
-
-#import <Availability.h>
-#import <QuartzCore/QuartzCore.h>
-#import <objc/runtime.h>
-
-#define kTUILineBreakWordWrapTextWidthScalingFactor (M_PI / M_E)
-
-static CGFloat const TUIFLOAT_MAX = 100000;
-
-NSString *const kTUIStrikeOutAttributeName = @"TUIStrikeOutAttribute";
-NSString *const kTUIBackgroundFillColorAttributeName = @"TUIBackgroundFillColor";
-NSString *const kTUIBackgroundFillPaddingAttributeName = @"TUIBackgroundFillPadding";
-NSString *const kTUIBackgroundStrokeColorAttributeName = @"TUIBackgroundStrokeColor";
-NSString *const kTUIBackgroundLineWidthAttributeName = @"TUIBackgroundLineWidth";
-NSString *const kTUIBackgroundCornerRadiusAttributeName = @"TUIBackgroundCornerRadius";
-
-const NSTextAlignment TUITextAlignmentLeft = NSTextAlignmentLeft;
-const NSTextAlignment TUITextAlignmentCenter = NSTextAlignmentCenter;
-const NSTextAlignment TUITextAlignmentRight = NSTextAlignmentRight;
-const NSTextAlignment TUITextAlignmentJustified = NSTextAlignmentJustified;
-const NSTextAlignment TUITextAlignmentNatural = NSTextAlignmentNatural;
-
-const NSLineBreakMode TUILineBreakByWordWrapping = NSLineBreakByWordWrapping;
-const NSLineBreakMode TUILineBreakByCharWrapping = NSLineBreakByCharWrapping;
-const NSLineBreakMode TUILineBreakByClipping = NSLineBreakByClipping;
-const NSLineBreakMode TUILineBreakByTruncatingHead = NSLineBreakByTruncatingHead;
-const NSLineBreakMode TUILineBreakByTruncatingMiddle = NSLineBreakByTruncatingMiddle;
-const NSLineBreakMode TUILineBreakByTruncatingTail = NSLineBreakByTruncatingTail;
-
-typedef NSTextAlignment TUITextAlignment;
-typedef NSLineBreakMode TUILineBreakMode;
-
-static inline CGFLOAT_TYPE formatCGFloatCeil(CGFLOAT_TYPE cgfloat) {
-#if CGFLOAT_IS_DOUBLE
-    return ceil(cgfloat);
-#else
-    return ceilf(cgfloat);
-#endif
-}
-
-static inline CGFLOAT_TYPE formatCGFloatFloor(CGFLOAT_TYPE cgfloat) {
-#if CGFLOAT_IS_DOUBLE
-    return floor(cgfloat);
-#else
-    return floorf(cgfloat);
-#endif
-}
-
-static inline CGFLOAT_TYPE formatCGFloatRound(CGFLOAT_TYPE cgfloat) {
-#if CGFLOAT_IS_DOUBLE
-    return round(cgfloat);
-#else
-    return roundf(cgfloat);
-#endif
-}
-
-static inline CGFLOAT_TYPE formatCGFloatSqrt(CGFLOAT_TYPE cgfloat) {
-#if CGFLOAT_IS_DOUBLE
-    return sqrt(cgfloat);
-#else
-    return sqrtf(cgfloat);
-#endif
-}
-
-static inline CGFloat flushFactorForTextAlignment(NSTextAlignment textAlignment) {
-    switch (textAlignment) {
-        case TUITextAlignmentCenter:
-            return 0.5f;
-        case TUITextAlignmentRight:
-            return 1.0f;
-        case TUITextAlignmentLeft:
-        default:
-            return 0.0f;
-    }
-}
-
-static inline NSDictionary *formatNSAttributedStringAttributesFromLabel(TUIAttributedLabel *label) {
-    NSMutableDictionary *mutableAttributes = [NSMutableDictionary dictionary];
-
-    [mutableAttributes setObject:label.font forKey:(NSString *)kCTFontAttributeName];
-    [mutableAttributes setObject:label.textColor forKey:(NSString *)kCTForegroundColorAttributeName];
-    [mutableAttributes setObject:@(label.kern) forKey:(NSString *)kCTKernAttributeName];
-
-    NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
-    paragraphStyle.alignment = label.textAlignment;
-    paragraphStyle.lineSpacing = label.lineSpacing;
-    paragraphStyle.minimumLineHeight = label.minimumLineHeight > 0 ? label.minimumLineHeight : label.font.lineHeight * label.lineHeightMultiple;
-    paragraphStyle.maximumLineHeight = label.maximumLineHeight > 0 ? label.maximumLineHeight : label.font.lineHeight * label.lineHeightMultiple;
-    paragraphStyle.lineHeightMultiple = label.lineHeightMultiple;
-    paragraphStyle.firstLineHeadIndent = label.firstLineIndent;
-
-    if (label.numberOfLines == 1) {
-        paragraphStyle.lineBreakMode = label.lineBreakMode;
-    } else {
-        paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping;
-    }
-
-    [mutableAttributes setObject:paragraphStyle forKey:(NSString *)kCTParagraphStyleAttributeName];
-
-    return [NSDictionary dictionaryWithDictionary:mutableAttributes];
-}
-
-static inline CGColorRef formatCGColorRefFromColor(id color);
-static inline NSDictionary *convertNSAttributedStringAttributesToCTAttributes(NSDictionary *attributes);
-
-static inline NSAttributedString *formatNSAttributedStringByScalingFontSize(NSAttributedString *attributedString, CGFloat scale) {
-    NSMutableAttributedString *mutableAttributedString = [attributedString mutableCopy];
-    [mutableAttributedString enumerateAttribute:(NSString *)kCTFontAttributeName
-                                        inRange:NSMakeRange(0, [mutableAttributedString length])
-                                        options:0
-                                     usingBlock:^(id value, NSRange range, BOOL *__unused stop) {
-                                       UIFont *font = (UIFont *)value;
-                                       if (font) {
-                                           NSString *fontName;
-                                           CGFloat pointSize;
-
-                                           if ([font isKindOfClass:[UIFont class]]) {
-                                               fontName = font.fontName;
-                                               pointSize = font.pointSize;
-                                           } else {
-                                               fontName = (NSString *)CFBridgingRelease(CTFontCopyName((__bridge CTFontRef)font, kCTFontPostScriptNameKey));
-                                               pointSize = CTFontGetSize((__bridge CTFontRef)font);
-                                           }
-
-                                           [mutableAttributedString removeAttribute:(NSString *)kCTFontAttributeName range:range];
-                                           CTFontRef fontRef =
-                                               CTFontCreateWithName((__bridge CFStringRef)fontName, formatCGFloatFloor(pointSize * scale), NULL);
-                                           [mutableAttributedString addAttribute:(NSString *)kCTFontAttributeName value:(__bridge id)fontRef range:range];
-                                           CFRelease(fontRef);
-                                       }
-                                     }];
-
-    return mutableAttributedString;
-}
-
-static inline NSAttributedString *formatNSAttributedStringBySettingColorFromContext(NSAttributedString *attributedString, UIColor *color) {
-    if (!color) {
-        return attributedString;
-    }
-
-    NSMutableAttributedString *mutableAttributedString = [attributedString mutableCopy];
-    [mutableAttributedString enumerateAttribute:(NSString *)kCTForegroundColorFromContextAttributeName
-                                        inRange:NSMakeRange(0, [mutableAttributedString length])
-                                        options:0
-                                     usingBlock:^(id value, NSRange range, __unused BOOL *stop) {
-                                       BOOL usesColorFromContext = (BOOL)value;
-                                       if (usesColorFromContext) {
-                                           [mutableAttributedString
-                                               setAttributes:[NSDictionary dictionaryWithObject:color forKey:(NSString *)kCTForegroundColorAttributeName]
-                                                       range:range];
-                                           [mutableAttributedString removeAttribute:(NSString *)kCTForegroundColorFromContextAttributeName range:range];
-                                       }
-                                     }];
-
-    return mutableAttributedString;
-}
-
-static inline CGSize formatCTFramesetterSuggestFrameSizeForAttributedStringWithConstraints(CTFramesetterRef framesetter, NSAttributedString *attributedString,
-                                                                                           CGSize size, NSUInteger numberOfLines) {
-    CFRange rangeToSize = CFRangeMake(0, (CFIndex)[attributedString length]);
-    CGSize constraints = CGSizeMake(size.width, TUIFLOAT_MAX);
-
-    if (numberOfLines == 1) {
-        // If there is one line, the size that fits is the full width of the line
-        constraints = CGSizeMake(TUIFLOAT_MAX, TUIFLOAT_MAX);
-    } else if (numberOfLines > 0) {
-        // If the line count of the label more than 1, limit the range to size to the number of lines that have been set
-        CGMutablePathRef path = CGPathCreateMutable();
-        CGPathAddRect(path, NULL, CGRectMake(0.0f, 0.0f, constraints.width, TUIFLOAT_MAX));
-        CTFrameRef frame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, 0), path, NULL);
-        CFArrayRef lines = CTFrameGetLines(frame);
-
-        if (CFArrayGetCount(lines) > 0) {
-            NSInteger lastVisibleLineIndex = MIN((CFIndex)numberOfLines, CFArrayGetCount(lines)) - 1;
-            CTLineRef lastVisibleLine = CFArrayGetValueAtIndex(lines, lastVisibleLineIndex);
-
-            CFRange rangeToLayout = CTLineGetStringRange(lastVisibleLine);
-            rangeToSize = CFRangeMake(0, rangeToLayout.location + rangeToLayout.length);
-        }
-
-        CFRelease(frame);
-        CGPathRelease(path);
-    }
-
-    CGSize suggestedSize = CTFramesetterSuggestFrameSizeWithConstraints(framesetter, rangeToSize, NULL, constraints, NULL);
-
-    return CGSizeMake(formatCGFloatCeil(suggestedSize.width), formatCGFloatCeil(suggestedSize.height));
-}
-
-@interface TUIAccessibilityElement : UIAccessibilityElement
-@property(nonatomic, weak) UIView *superview;
-@property(nonatomic, assign) CGRect boundingRect;
-@end
-
-@implementation TUIAccessibilityElement
-
-- (CGRect)accessibilityFrame {
-    return UIAccessibilityConvertFrameToScreenCoordinates(self.boundingRect, self.superview);
-}
-
-@end
-
-@interface TUIAttributedLabel ()
-@property(readwrite, nonatomic, copy) NSAttributedString *inactiveAttributedText;
-@property(readwrite, nonatomic, copy) NSAttributedString *renderedAttributedText;
-@property(readwrite, atomic, strong) NSDataDetector *dataDetector;
-@property(readwrite, nonatomic, strong) NSArray *linkModels;
-@property(readwrite, nonatomic, strong) TUIAttributedLabelLink *activeLink;
-@property(readwrite, nonatomic, strong) NSArray *accessibilityElements;
-
-- (void)longPressGestureDidFire:(UILongPressGestureRecognizer *)sender;
-@end
-
-@implementation TUIAttributedLabel {
-@private
-    BOOL _needsFramesetter;
-    CTFramesetterRef _framesetter;
-    CTFramesetterRef _highlightFramesetter;
-}
-
-@dynamic text;
-@synthesize attributedText = _attributedText;
-
-#ifndef kCFCoreFoundationVersionNumber_iOS_7_0
-#define kCFCoreFoundationVersionNumber_iOS_7_0 847.2
-#endif
-
-+ (void)load {
-    static dispatch_once_t onceToken;
-    dispatch_once(&onceToken, ^{
-      if (kCFCoreFoundationVersionNumber < kCFCoreFoundationVersionNumber_iOS_7_0) {
-          Class class = [self class];
-          Class superclass = class_getSuperclass(class);
-
-          NSArray *strings = @[
-              NSStringFromSelector(@selector(isAccessibilityElement)),
-              NSStringFromSelector(@selector(accessibilityElementCount)),
-              NSStringFromSelector(@selector(accessibilityElementAtIndex:)),
-              NSStringFromSelector(@selector(indexOfAccessibilityElement:)),
-          ];
-
-          for (NSString *string in strings) {
-              SEL selector = NSSelectorFromString(string);
-              IMP superImplementation = class_getMethodImplementation(superclass, selector);
-              Method method = class_getInstanceMethod(class, selector);
-              const char *types = method_getTypeEncoding(method);
-              class_replaceMethod(class, selector, superImplementation, types);
-          }
-      }
-    });
-}
-
-- (instancetype)initWithFrame:(CGRect)frame {
-    self = [super initWithFrame:frame];
-    if (!self) {
-        return nil;
-    }
-
-    [self commonInit];
-
-    return self;
-}
-
-- (void)commonInit {
-    self.userInteractionEnabled = YES;
-#if !TARGET_OS_TV
-    self.multipleTouchEnabled = NO;
-#endif
-
-    self.textInsets = UIEdgeInsetsZero;
-    self.lineHeightMultiple = 1.0f;
-
-    self.linkModels = [NSArray array];
-
-    self.linkBackgroundEdgeInset = UIEdgeInsetsMake(0.0f, -1.0f, 0.0f, -1.0f);
-
-    NSMutableDictionary *mutableLinkAttributes = [NSMutableDictionary dictionary];
-    [mutableLinkAttributes setObject:[NSNumber numberWithBool:YES] forKey:(NSString *)kCTUnderlineStyleAttributeName];
-
-    NSMutableDictionary *mutableActiveLinkAttributes = [NSMutableDictionary dictionary];
-    [mutableActiveLinkAttributes setObject:[NSNumber numberWithBool:NO] forKey:(NSString *)kCTUnderlineStyleAttributeName];
-
-    NSMutableDictionary *mutableInactiveLinkAttributes = [NSMutableDictionary dictionary];
-    [mutableInactiveLinkAttributes setObject:[NSNumber numberWithBool:NO] forKey:(NSString *)kCTUnderlineStyleAttributeName];
-
-    if ([NSMutableParagraphStyle class]) {
-        [mutableLinkAttributes setObject:[UIColor blueColor] forKey:(NSString *)kCTForegroundColorAttributeName];
-        [mutableActiveLinkAttributes setObject:[UIColor redColor] forKey:(NSString *)kCTForegroundColorAttributeName];
-        [mutableInactiveLinkAttributes setObject:[UIColor grayColor] forKey:(NSString *)kCTForegroundColorAttributeName];
-    } else {
-        [mutableLinkAttributes setObject:(__bridge id)[[UIColor blueColor] CGColor] forKey:(NSString *)kCTForegroundColorAttributeName];
-        [mutableActiveLinkAttributes setObject:(__bridge id)[[UIColor redColor] CGColor] forKey:(NSString *)kCTForegroundColorAttributeName];
-        [mutableInactiveLinkAttributes setObject:(__bridge id)[[UIColor grayColor] CGColor] forKey:(NSString *)kCTForegroundColorAttributeName];
-    }
-
-    self.linkAttributes = [NSDictionary dictionaryWithDictionary:mutableLinkAttributes];
-    self.activeLinkAttributes = [NSDictionary dictionaryWithDictionary:mutableActiveLinkAttributes];
-    self.inactiveLinkAttributes = [NSDictionary dictionaryWithDictionary:mutableInactiveLinkAttributes];
-    _extendsLinkTouchArea = NO;
-    _longPressGestureRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressGestureDidFire:)];
-    self.longPressGestureRecognizer.delegate = self;
-    [self addGestureRecognizer:self.longPressGestureRecognizer];
-}
-
-- (void)dealloc {
-    if (_framesetter) {
-        CFRelease(_framesetter);
-    }
-
-    if (_highlightFramesetter) {
-        CFRelease(_highlightFramesetter);
-    }
-
-    if (_longPressGestureRecognizer) {
-        [self removeGestureRecognizer:_longPressGestureRecognizer];
-    }
-}
-
-#pragma mark -
-
-+ (CGSize)sizeThatFitsAttributedString:(NSAttributedString *)attributedString withConstraints:(CGSize)size limitedToNumberOfLines:(NSUInteger)numberOfLines {
-    if (!attributedString || attributedString.length == 0) {
-        return CGSizeZero;
-    }
-
-    CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef)attributedString);
-
-    CGSize calculatedSize = formatCTFramesetterSuggestFrameSizeForAttributedStringWithConstraints(framesetter, attributedString, size, numberOfLines);
-
-    CFRelease(framesetter);
-
-    return calculatedSize;
-}
-
-#pragma mark -
-
-- (void)setAttributedText:(NSAttributedString *)text {
-    if ([text isEqualToAttributedString:_attributedText]) {
-        return;
-    }
-
-    _attributedText = [text copy];
-
-    [self setNeedsFramesetter];
-    [self setNeedsDisplay];
-
-    if ([self respondsToSelector:@selector(invalidateIntrinsicContentSize)]) {
-        [self invalidateIntrinsicContentSize];
-    }
-
-    [super setText:[self.attributedText string]];
-}
-
-- (NSAttributedString *)renderedAttributedText {
-    if (!_renderedAttributedText) {
-        NSMutableAttributedString *fullString = [[NSMutableAttributedString alloc] initWithAttributedString:self.attributedText];
-
-        if (self.attributedTruncationToken) {
-            [fullString appendAttributedString:self.attributedTruncationToken];
-        }
-
-        NSAttributedString *string = [[NSAttributedString alloc] initWithAttributedString:fullString];
-        self.renderedAttributedText = formatNSAttributedStringBySettingColorFromContext(string, self.textColor);
-    }
-
-    return _renderedAttributedText;
-}
-
-- (NSArray *)links {
-    return [_linkModels valueForKey:@"result"];
-}
-
-- (void)setLinkModels:(NSArray *)linkModels {
-    _linkModels = linkModels;
-
-    self.accessibilityElements = nil;
-}
-
-- (void)setNeedsFramesetter {
-    // Reset the rendered attributed text so it has a chance to regenerate
-    self.renderedAttributedText = nil;
-
-    _needsFramesetter = YES;
-}
-
-- (CTFramesetterRef)framesetter {
-    if (_needsFramesetter) {
-        @synchronized(self) {
-            CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef)self.renderedAttributedText);
-            [self setFramesetter:framesetter];
-            [self setHighlightFramesetter:nil];
-            _needsFramesetter = NO;
-
-            if (framesetter) {
-                CFRelease(framesetter);
-            }
-        }
-    }
-
-    return _framesetter;
-}
-
-- (void)setFramesetter:(CTFramesetterRef)framesetter {
-    if (framesetter) {
-        CFRetain(framesetter);
-    }
-
-    if (_framesetter) {
-        CFRelease(_framesetter);
-    }
-
-    _framesetter = framesetter;
-}
-
-- (CTFramesetterRef)highlightFramesetter {
-    return _highlightFramesetter;
-}
-
-- (void)setHighlightFramesetter:(CTFramesetterRef)highlightFramesetter {
-    if (highlightFramesetter) {
-        CFRetain(highlightFramesetter);
-    }
-
-    if (_highlightFramesetter) {
-        CFRelease(_highlightFramesetter);
-    }
-
-    _highlightFramesetter = highlightFramesetter;
-}
-
-#pragma mark -
-
-- (void)setEnabledTextCheckingTypes:(NSTextCheckingTypes)enabledTextCheckingTypes {
-    if (self.enabledTextCheckingTypes == enabledTextCheckingTypes) {
-        return;
-    }
-
-    _enabledTextCheckingTypes = enabledTextCheckingTypes;
-
-    // one detector instance per type (combination), fast reuse e.g. in cells
-    static NSMutableDictionary *dataDetectorsByType = nil;
-
-    if (!dataDetectorsByType) {
-        dataDetectorsByType = [NSMutableDictionary dictionary];
-    }
-
-    if (enabledTextCheckingTypes) {
-        if (![dataDetectorsByType objectForKey:@(enabledTextCheckingTypes)]) {
-            NSDataDetector *detector = [NSDataDetector dataDetectorWithTypes:enabledTextCheckingTypes error:nil];
-            if (detector) {
-                [dataDetectorsByType setObject:detector forKey:@(enabledTextCheckingTypes)];
-            }
-        }
-        self.dataDetector = [dataDetectorsByType objectForKey:@(enabledTextCheckingTypes)];
-    } else {
-        self.dataDetector = nil;
-    }
-}
-
-- (void)addLink:(TUIAttributedLabelLink *)link {
-    [self addLinks:@[ link ]];
-}
-
-- (void)addLinks:(NSArray *)links {
-    NSMutableArray *mutableLinkModels = [NSMutableArray arrayWithArray:self.linkModels];
-
-    NSMutableAttributedString *mutableAttributedString = [self.attributedText mutableCopy];
-
-    for (TUIAttributedLabelLink *link in links) {
-        if (link.attributes) {
-            [mutableAttributedString addAttributes:link.attributes range:link.result.range];
-        }
-    }
-
-    self.attributedText = mutableAttributedString;
-    [self setNeedsDisplay];
-
-    [mutableLinkModels addObjectsFromArray:links];
-
-    self.linkModels = [NSArray arrayWithArray:mutableLinkModels];
-}
-
-- (TUIAttributedLabelLink *)addLinkWithTextCheckingResult:(NSTextCheckingResult *)result attributes:(NSDictionary *)attributes {
-    return [self addLinksWithTextCheckingResults:@[ result ] attributes:attributes].firstObject;
-}
-
-- (NSArray *)addLinksWithTextCheckingResults:(NSArray *)results attributes:(NSDictionary *)attributes {
-    NSMutableArray *links = [NSMutableArray array];
-
-    for (NSTextCheckingResult *result in results) {
-        NSDictionary *activeAttributes = attributes ? self.activeLinkAttributes : nil;
-        NSDictionary *inactiveAttributes = attributes ? self.inactiveLinkAttributes : nil;
-
-        TUIAttributedLabelLink *link = [[TUIAttributedLabelLink alloc] initWithAttributes:attributes
-                                                                         activeAttributes:activeAttributes
-                                                                       inactiveAttributes:inactiveAttributes
-                                                                       textCheckingResult:result];
-
-        [links addObject:link];
-    }
-
-    [self addLinks:links];
-
-    return links;
-}
-
-- (TUIAttributedLabelLink *)addLinkWithTextCheckingResult:(NSTextCheckingResult *)result {
-    return [self addLinkWithTextCheckingResult:result attributes:self.linkAttributes];
-}
-
-- (TUIAttributedLabelLink *)addLinkToURL:(NSURL *)url withRange:(NSRange)range {
-    return [self addLinkWithTextCheckingResult:[NSTextCheckingResult linkCheckingResultWithRange:range URL:url]];
-}
-
-- (TUIAttributedLabelLink *)addLinkToAddress:(NSDictionary *)addressComponents withRange:(NSRange)range {
-    return [self addLinkWithTextCheckingResult:[NSTextCheckingResult addressCheckingResultWithRange:range components:addressComponents]];
-}
-
-- (TUIAttributedLabelLink *)addLinkToPhoneNumber:(NSString *)phoneNumber withRange:(NSRange)range {
-    return [self addLinkWithTextCheckingResult:[NSTextCheckingResult phoneNumberCheckingResultWithRange:range phoneNumber:phoneNumber]];
-}
-
-- (TUIAttributedLabelLink *)addLinkToDate:(NSDate *)date withRange:(NSRange)range {
-    return [self addLinkWithTextCheckingResult:[NSTextCheckingResult dateCheckingResultWithRange:range date:date]];
-}
-
-- (TUIAttributedLabelLink *)addLinkToDate:(NSDate *)date timeZone:(NSTimeZone *)timeZone duration:(NSTimeInterval)duration withRange:(NSRange)range {
-    return [self addLinkWithTextCheckingResult:[NSTextCheckingResult dateCheckingResultWithRange:range date:date timeZone:timeZone duration:duration]];
-}
-
-- (TUIAttributedLabelLink *)addLinkToTransitInformation:(NSDictionary *)components withRange:(NSRange)range {
-    return [self addLinkWithTextCheckingResult:[NSTextCheckingResult transitInformationCheckingResultWithRange:range components:components]];
-}
-
-#pragma mark -
-
-- (BOOL)containslinkAtPoint:(CGPoint)point {
-    return [self linkAtPoint:point] != nil;
-}
-
-- (TUIAttributedLabelLink *)linkAtPoint:(CGPoint)point {
-    // Stop quickly if none of the points to be tested are in the bounds.
-    if (!CGRectContainsPoint(CGRectInset(self.bounds, -15.f, -15.f), point) || self.links.count == 0) {
-        return nil;
-    }
-
-    TUIAttributedLabelLink *result = [self linkAtCharacterIndex:[self characterIndexAtPoint:point]];
-
-    if (!result && self.extendsLinkTouchArea) {
-        result = [self linkAtRadius:2.5f aroundPoint:point]
-              ?: [self linkAtRadius:5.f aroundPoint:point]
-              ?: [self linkAtRadius:7.5f aroundPoint:point]
-              ?: [self linkAtRadius:12.5f aroundPoint:point]
-              ?: [self linkAtRadius:15.f aroundPoint:point];
-    }
-
-    return result;
-}
-
-- (TUIAttributedLabelLink *)linkAtRadius:(const CGFloat)radius aroundPoint:(CGPoint)point {
-    const CGFloat diagonal = formatCGFloatSqrt(2 * radius * radius);
-    const CGPoint deltas[] = {
-        CGPointMake(0, -radius),           CGPointMake(0, radius),  // Above and below
-        CGPointMake(-radius, 0),           CGPointMake(radius, 0),  // Beside
-        CGPointMake(-diagonal, -diagonal), CGPointMake(-diagonal, diagonal), CGPointMake(diagonal, diagonal), CGPointMake(diagonal, -diagonal)  // Diagonal
-    };
-    const size_t count = sizeof(deltas) / sizeof(CGPoint);
-
-    TUIAttributedLabelLink *link = nil;
-
-    for (NSUInteger i = 0; i < count && link.result == nil; i++) {
-        CGPoint currentPoint = CGPointMake(point.x + deltas[i].x, point.y + deltas[i].y);
-        link = [self linkAtCharacterIndex:[self characterIndexAtPoint:currentPoint]];
-    }
-
-    return link;
-}
-
-- (TUIAttributedLabelLink *)linkAtCharacterIndex:(CFIndex)idx {
-    // Do not enumerate if the index is outside of the bounds of the text.
-    if (!NSLocationInRange((NSUInteger)idx, NSMakeRange(0, self.attributedText.length))) {
-        return nil;
-    }
-
-    NSEnumerator *enumerator = [self.linkModels reverseObjectEnumerator];
-    TUIAttributedLabelLink *link = nil;
-    while ((link = [enumerator nextObject])) {
-        if (NSLocationInRange((NSUInteger)idx, link.result.range)) {
-            return link;
-        }
-    }
-
-    return nil;
-}
-
-- (CFIndex)characterIndexAtPoint:(CGPoint)p {
-    if (!CGRectContainsPoint(self.bounds, p)) {
-        return NSNotFound;
-    }
-
-    CGRect textRect = [self textRectForBounds:self.bounds limitedToNumberOfLines:self.numberOfLines];
-    if (!CGRectContainsPoint(textRect, p)) {
-        return NSNotFound;
-    }
-
-    // Offset tap coordinates by textRect origin to make them relative to the origin of frame
-    p = CGPointMake(p.x - textRect.origin.x, p.y - textRect.origin.y);
-    // Convert tap coordinates (start at top left) to CT coordinates (start at bottom left)
-    p = CGPointMake(p.x, textRect.size.height - p.y);
-
-    CGMutablePathRef path = CGPathCreateMutable();
-    CGPathAddRect(path, NULL, textRect);
-    CTFrameRef frame = CTFramesetterCreateFrame([self framesetter], CFRangeMake(0, (CFIndex)[self.attributedText length]), path, NULL);
-    if (frame == NULL) {
-        CGPathRelease(path);
-        return NSNotFound;
-    }
-
-    CFArrayRef lines = CTFrameGetLines(frame);
-    NSInteger numberOfLines = self.numberOfLines > 0 ? MIN(self.numberOfLines, CFArrayGetCount(lines)) : CFArrayGetCount(lines);
-    if (numberOfLines == 0) {
-        CFRelease(frame);
-        CGPathRelease(path);
-        return NSNotFound;
-    }
-
-    CFIndex idx = NSNotFound;
-
-    CGPoint lineOrigins[numberOfLines];
-    CTFrameGetLineOrigins(frame, CFRangeMake(0, numberOfLines), lineOrigins);
-
-    for (CFIndex lineIndex = 0; lineIndex < numberOfLines; lineIndex++) {
-        CGPoint lineOrigin = lineOrigins[lineIndex];
-        CTLineRef line = CFArrayGetValueAtIndex(lines, lineIndex);
-
-        // Get bounding information of line
-        CGFloat ascent = 0.0f, descent = 0.0f, leading = 0.0f;
-        CGFloat width = (CGFloat)CTLineGetTypographicBounds(line, &ascent, &descent, &leading);
-        CGFloat yMin = (CGFloat)floor(lineOrigin.y - descent);
-        CGFloat yMax = (CGFloat)ceil(lineOrigin.y + ascent);
-
-        // Apply penOffset using flushFactor for horizontal alignment to set lineOrigin since this is the horizontal offset from drawFramesetter
-        CGFloat flushFactor = flushFactorForTextAlignment(self.textAlignment);
-        CGFloat penOffset = (CGFloat)CTLineGetPenOffsetForFlush(line, flushFactor, textRect.size.width);
-        lineOrigin.x = penOffset;
-
-        // Check if we've already passed the line
-        if (p.y > yMax) {
-            break;
-        }
-        // Check if the point is within this line vertically
-        if (p.y >= yMin) {
-            // Check if the point is within this line horizontally
-            if (p.x >= lineOrigin.x && p.x <= lineOrigin.x + width) {
-                // Convert CT coordinates to line-relative coordinates
-                CGPoint relativePoint = CGPointMake(p.x - lineOrigin.x, p.y - lineOrigin.y);
-                idx = CTLineGetStringIndexForPosition(line, relativePoint);
-                break;
-            }
-        }
-    }
-
-    CFRelease(frame);
-    CGPathRelease(path);
-
-    return idx;
-}
-
-- (CGRect)boundingRectForCharacterRange:(NSRange)range {
-    NSMutableAttributedString *mutableAttributedString = [self.attributedText mutableCopy];
-
-    NSTextStorage *textStorage = [[NSTextStorage alloc] initWithAttributedString:mutableAttributedString];
-
-    NSLayoutManager *layoutManager = [[NSLayoutManager alloc] init];
-    [textStorage addLayoutManager:layoutManager];
-
-    NSTextContainer *textContainer = [[NSTextContainer alloc] initWithSize:self.bounds.size];
-    [layoutManager addTextContainer:textContainer];
-
-    NSRange glyphRange;
-    [layoutManager characterRangeForGlyphRange:range actualGlyphRange:&glyphRange];
-
-    return [layoutManager boundingRectForGlyphRange:glyphRange inTextContainer:textContainer];
-}
-
-- (void)drawFramesetter:(CTFramesetterRef)framesetter
-       attributedString:(NSAttributedString *)attributedString
-              textRange:(CFRange)textRange
-                 inRect:(CGRect)rect
-                context:(CGContextRef)c {
-    CGMutablePathRef path = CGPathCreateMutable();
-    CGPathAddRect(path, NULL, rect);
-    CTFrameRef frame = CTFramesetterCreateFrame(framesetter, textRange, path, NULL);
-
-    [self drawBackground:frame inRect:rect context:c];
-
-    CFArrayRef lines = CTFrameGetLines(frame);
-    NSInteger numberOfLines = self.numberOfLines > 0 ? MIN(self.numberOfLines, CFArrayGetCount(lines)) : CFArrayGetCount(lines);
-    BOOL truncateLastLine = (self.lineBreakMode == TUILineBreakByTruncatingHead || self.lineBreakMode == TUILineBreakByTruncatingMiddle ||
-                             self.lineBreakMode == TUILineBreakByTruncatingTail);
-
-    CGPoint lineOrigins[numberOfLines];
-    CTFrameGetLineOrigins(frame, CFRangeMake(0, numberOfLines), lineOrigins);
-
-    for (CFIndex lineIndex = 0; lineIndex < numberOfLines; lineIndex++) {
-        CGPoint lineOrigin = lineOrigins[lineIndex];
-        CGContextSetTextPosition(c, lineOrigin.x, lineOrigin.y);
-        CTLineRef line = CFArrayGetValueAtIndex(lines, lineIndex);
-
-        CGFloat descent = 0.0f;
-        CTLineGetTypographicBounds((CTLineRef)line, NULL, &descent, NULL);
-
-        // Adjust pen offset for flush depending on text alignment
-        CGFloat flushFactor = flushFactorForTextAlignment(self.textAlignment);
-
-        if (lineIndex == numberOfLines - 1 && truncateLastLine) {
-            // Check if the range of text in the last line reaches the end of the full attributed string
-            CFRange lastLineRange = CTLineGetStringRange(line);
-
-            if (!(lastLineRange.length == 0 && lastLineRange.location == 0) &&
-                lastLineRange.location + lastLineRange.length < textRange.location + textRange.length) {
-                // Get correct truncationType and attribute position
-                CTLineTruncationType truncationType;
-                CFIndex truncationAttributePosition = lastLineRange.location;
-                TUILineBreakMode lineBreakMode = self.lineBreakMode;
-
-                // Multiple lines, only use UILineBreakModeTailTruncation
-                if (numberOfLines != 1) {
-                    lineBreakMode = TUILineBreakByTruncatingTail;
-                }
-
-                switch (lineBreakMode) {
-                    case TUILineBreakByTruncatingHead:
-                        truncationType = kCTLineTruncationStart;
-                        break;
-                    case TUILineBreakByTruncatingMiddle:
-                        truncationType = kCTLineTruncationMiddle;
-                        truncationAttributePosition += (lastLineRange.length / 2);
-                        break;
-                    case TUILineBreakByTruncatingTail:
-                    default:
-                        truncationType = kCTLineTruncationEnd;
-                        truncationAttributePosition += (lastLineRange.length - 1);
-                        break;
-                }
-
-                NSAttributedString *attributedTruncationString = self.attributedTruncationToken;
-                if (!attributedTruncationString) {
-                    NSString *truncationTokenString = @"\u2026";  // Unicode Character 'HORIZONTAL ELLIPSIS' (U+2026)
-
-                    NSDictionary *truncationTokenStringAttributes = truncationTokenStringAttributes =
-                        [attributedString attributesAtIndex:(NSUInteger)truncationAttributePosition effectiveRange:NULL];
-
-                    attributedTruncationString = [[NSAttributedString alloc] initWithString:truncationTokenString attributes:truncationTokenStringAttributes];
-                }
-                CTLineRef truncationToken = CTLineCreateWithAttributedString((__bridge CFAttributedStringRef)attributedTruncationString);
-
-                // Append truncationToken to the string
-                // because if string isn't too long, CT won't add the truncationToken on its own.
-                // There is no chance of a double truncationToken because CT only adds the
-                // token if it removes characters (and the one we add will go first)
-                NSMutableAttributedString *truncationString = [[NSMutableAttributedString alloc]
-                    initWithAttributedString:[attributedString attributedSubstringFromRange:NSMakeRange((NSUInteger)lastLineRange.location,
-                                                                                                        (NSUInteger)lastLineRange.length)]];
-                if (lastLineRange.length > 0) {
-                    // Remove any newline at the end (we don't want newline space between the text and the truncation token). There can only be one, because the
-                    // second would be on the next line.
-                    unichar lastCharacter = [[truncationString string] characterAtIndex:(NSUInteger)(lastLineRange.length - 1)];
-                    if ([[NSCharacterSet newlineCharacterSet] characterIsMember:lastCharacter]) {
-                        [truncationString deleteCharactersInRange:NSMakeRange((NSUInteger)(lastLineRange.length - 1), 1)];
-                    }
-                }
-                [truncationString appendAttributedString:attributedTruncationString];
-                CTLineRef truncationLine = CTLineCreateWithAttributedString((__bridge CFAttributedStringRef)truncationString);
-
-                // Truncate the line in case it is too long.
-                CTLineRef truncatedLine = CTLineCreateTruncatedLine(truncationLine, rect.size.width, truncationType, truncationToken);
-                if (!truncatedLine) {
-                    // If the line is not as wide as the truncationToken, truncatedLine is NULL
-                    truncatedLine = CFRetain(truncationToken);
-                }
-
-                CGFloat penOffset = (CGFloat)CTLineGetPenOffsetForFlush(truncatedLine, flushFactor, rect.size.width);
-                CGContextSetTextPosition(c, penOffset, lineOrigin.y - descent - self.font.descender);
-
-                CTLineDraw(truncatedLine, c);
-
-                NSRange linkRange;
-                if ([attributedTruncationString attribute:NSLinkAttributeName atIndex:0 effectiveRange:&linkRange]) {
-                    NSRange tokenRange = [truncationString.string rangeOfString:attributedTruncationString.string];
-                    NSRange tokenLinkRange =
-                        NSMakeRange((NSUInteger)(lastLineRange.location + lastLineRange.length) - tokenRange.length, (NSUInteger)tokenRange.length);
-
-                    [self addLinkToURL:[attributedTruncationString attribute:NSLinkAttributeName atIndex:0 effectiveRange:&linkRange] withRange:tokenLinkRange];
-                }
-
-                CFRelease(truncatedLine);
-                CFRelease(truncationLine);
-                CFRelease(truncationToken);
-            } else {
-                CGFloat penOffset = (CGFloat)CTLineGetPenOffsetForFlush(line, flushFactor, rect.size.width);
-                CGContextSetTextPosition(c, penOffset, lineOrigin.y - descent - self.font.descender);
-                CTLineDraw(line, c);
-            }
-        } else {
-            CGFloat penOffset = (CGFloat)CTLineGetPenOffsetForFlush(line, flushFactor, rect.size.width);
-            CGContextSetTextPosition(c, penOffset, lineOrigin.y - descent - self.font.descender);
-            CTLineDraw(line, c);
-        }
-    }
-
-    [self drawStrike:frame inRect:rect context:c];
-
-    CFRelease(frame);
-    CGPathRelease(path);
-}
-
-- (void)drawBackground:(CTFrameRef)frame inRect:(CGRect)rect context:(CGContextRef)c {
-    NSArray *lines = (__bridge NSArray *)CTFrameGetLines(frame);
-    CGPoint origins[[lines count]];
-    CTFrameGetLineOrigins(frame, CFRangeMake(0, 0), origins);
-
-    CFIndex lineIndex = 0;
-    for (id line in lines) {
-        CGFloat ascent = 0.0f, descent = 0.0f, leading = 0.0f;
-        CGFloat width = (CGFloat)CTLineGetTypographicBounds((__bridge CTLineRef)line, &ascent, &descent, &leading);
-
-        for (id glyphRun in (__bridge NSArray *)CTLineGetGlyphRuns((__bridge CTLineRef)line)) {
-            NSDictionary *attributes = (__bridge NSDictionary *)CTRunGetAttributes((__bridge CTRunRef)glyphRun);
-            CGColorRef strokeColor = formatCGColorRefFromColor([attributes objectForKey:kTUIBackgroundStrokeColorAttributeName]);
-            CGColorRef fillColor = formatCGColorRefFromColor([attributes objectForKey:kTUIBackgroundFillColorAttributeName]);
-            UIEdgeInsets fillPadding = [[attributes objectForKey:kTUIBackgroundFillPaddingAttributeName] UIEdgeInsetsValue];
-            CGFloat cornerRadius = [[attributes objectForKey:kTUIBackgroundCornerRadiusAttributeName] floatValue];
-            CGFloat lineWidth = [[attributes objectForKey:kTUIBackgroundLineWidthAttributeName] floatValue];
-
-            if (strokeColor || fillColor) {
-                CGRect runBounds = CGRectZero;
-                CGFloat runAscent = 0.0f;
-                CGFloat runDescent = 0.0f;
-
-                runBounds.size.width = (CGFloat)CTRunGetTypographicBounds((__bridge CTRunRef)glyphRun, CFRangeMake(0, 0), &runAscent, &runDescent, NULL) +
-                                       fillPadding.left + fillPadding.right;
-                runBounds.size.height = runAscent + runDescent + fillPadding.top + fillPadding.bottom;
-
-                CGFloat xOffset = 0.0f;
-                CFRange glyphRange = CTRunGetStringRange((__bridge CTRunRef)glyphRun);
-                switch (CTRunGetStatus((__bridge CTRunRef)glyphRun)) {
-                    case kCTRunStatusRightToLeft:
-                        xOffset = CTLineGetOffsetForStringIndex((__bridge CTLineRef)line, glyphRange.location + glyphRange.length, NULL);
-                        break;
-                    default:
-                        xOffset = CTLineGetOffsetForStringIndex((__bridge CTLineRef)line, glyphRange.location, NULL);
-                        break;
-                }
-
-                runBounds.origin.x = origins[lineIndex].x + rect.origin.x + xOffset - fillPadding.left - rect.origin.x;
-                runBounds.origin.y = origins[lineIndex].y + rect.origin.y - fillPadding.bottom - rect.origin.y;
-                runBounds.origin.y -= runDescent;
-
-                // Don't draw higlightedLinkBackground too far to the right
-                if (CGRectGetWidth(runBounds) > width) {
-                    runBounds.size.width = width;
-                }
-
-                CGPathRef path =
-                    [[UIBezierPath bezierPathWithRoundedRect:CGRectInset(UIEdgeInsetsInsetRect(runBounds, self.linkBackgroundEdgeInset), lineWidth, lineWidth)
-                                                cornerRadius:cornerRadius] CGPath];
-
-                CGContextSetLineJoin(c, kCGLineJoinRound);
-
-                if (fillColor) {
-                    CGContextSetFillColorWithColor(c, fillColor);
-                    CGContextAddPath(c, path);
-                    CGContextFillPath(c);
-                }
-
-                if (strokeColor) {
-                    CGContextSetStrokeColorWithColor(c, strokeColor);
-                    CGContextAddPath(c, path);
-                    CGContextStrokePath(c);
-                }
-            }
-        }
-
-        lineIndex++;
-    }
-}
-
-- (void)drawStrike:(CTFrameRef)frame inRect:(__unused CGRect)rect context:(CGContextRef)c {
-    NSArray *lines = (__bridge NSArray *)CTFrameGetLines(frame);
-    CGPoint origins[[lines count]];
-    CTFrameGetLineOrigins(frame, CFRangeMake(0, 0), origins);
-
-    CFIndex lineIndex = 0;
-    for (id line in lines) {
-        CGFloat ascent = 0.0f, descent = 0.0f, leading = 0.0f;
-        CGFloat width = (CGFloat)CTLineGetTypographicBounds((__bridge CTLineRef)line, &ascent, &descent, &leading);
-
-        for (id glyphRun in (__bridge NSArray *)CTLineGetGlyphRuns((__bridge CTLineRef)line)) {
-            NSDictionary *attributes = (__bridge NSDictionary *)CTRunGetAttributes((__bridge CTRunRef)glyphRun);
-            BOOL strikeOut = [[attributes objectForKey:kTUIStrikeOutAttributeName] boolValue];
-            NSInteger superscriptStyle = [[attributes objectForKey:(id)kCTSuperscriptAttributeName] integerValue];
-
-            if (strikeOut) {
-                CGRect runBounds = CGRectZero;
-                CGFloat runAscent = 0.0f;
-                CGFloat runDescent = 0.0f;
-
-                runBounds.size.width = (CGFloat)CTRunGetTypographicBounds((__bridge CTRunRef)glyphRun, CFRangeMake(0, 0), &runAscent, &runDescent, NULL);
-                runBounds.size.height = runAscent + runDescent;
-
-                CGFloat xOffset = 0.0f;
-                CFRange glyphRange = CTRunGetStringRange((__bridge CTRunRef)glyphRun);
-                switch (CTRunGetStatus((__bridge CTRunRef)glyphRun)) {
-                    case kCTRunStatusRightToLeft:
-                        xOffset = CTLineGetOffsetForStringIndex((__bridge CTLineRef)line, glyphRange.location + glyphRange.length, NULL);
-                        break;
-                    default:
-                        xOffset = CTLineGetOffsetForStringIndex((__bridge CTLineRef)line, glyphRange.location, NULL);
-                        break;
-                }
-                runBounds.origin.x = origins[lineIndex].x + xOffset;
-                runBounds.origin.y = origins[lineIndex].y;
-                runBounds.origin.y -= runDescent;
-
-                // Don't draw strikeout too far to the right
-                if (CGRectGetWidth(runBounds) > width) {
-                    runBounds.size.width = width;
-                }
-
-                switch (superscriptStyle) {
-                    case 1:
-                        runBounds.origin.y -= runAscent * 0.47f;
-                        break;
-                    case -1:
-                        runBounds.origin.y += runAscent * 0.25f;
-                        break;
-                    default:
-                        break;
-                }
-
-                // Use text color, or default to black
-                id color = [attributes objectForKey:(id)kCTForegroundColorAttributeName];
-                if (color) {
-                    CGContextSetStrokeColorWithColor(c, formatCGColorRefFromColor(color));
-                } else {
-                    CGContextSetGrayStrokeColor(c, 0.0f, 1.0);
-                }
-
-                CTFontRef font = CTFontCreateWithName((__bridge CFStringRef)self.font.fontName, self.font.pointSize, NULL);
-                CGContextSetLineWidth(c, CTFontGetUnderlineThickness(font));
-                CFRelease(font);
-
-                CGFloat y = formatCGFloatRound(runBounds.origin.y + runBounds.size.height / 2.0f);
-                CGContextMoveToPoint(c, runBounds.origin.x, y);
-                CGContextAddLineToPoint(c, runBounds.origin.x + runBounds.size.width, y);
-
-                CGContextStrokePath(c);
-            }
-        }
-
-        lineIndex++;
-    }
-}
-
-#pragma mark - TUIAttributedLabel
-
-- (void)setText:(id)text {
-    NSParameterAssert(!text || [text isKindOfClass:[NSAttributedString class]] || [text isKindOfClass:[NSString class]]);
-
-    if ([text isKindOfClass:[NSString class]]) {
-        [self setText:text afterInheritingLabelAttributesAndConfiguringWithBlock:nil];
-        return;
-    }
-
-    self.attributedText = text;
-    self.activeLink = nil;
-
-    self.linkModels = [NSArray array];
-    if (text && self.attributedText && self.enabledTextCheckingTypes) {
-        __weak __typeof(self) weakSelf = self;
-        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
-          __strong __typeof(weakSelf) strongSelf = weakSelf;
-
-          NSDataDetector *dataDetector = strongSelf.dataDetector;
-          if (dataDetector && [dataDetector respondsToSelector:@selector(matchesInString:options:range:)]) {
-              NSArray *results = [dataDetector matchesInString:[(NSAttributedString *)text string]
-                                                       options:0
-                                                         range:NSMakeRange(0, [(NSAttributedString *)text length])];
-              if ([results count] > 0) {
-                  dispatch_async(dispatch_get_main_queue(), ^{
-                    if ([[strongSelf.attributedText string] isEqualToString:[(NSAttributedString *)text string]]) {
-                        [strongSelf addLinksWithTextCheckingResults:results attributes:strongSelf.linkAttributes];
-                    }
-                  });
-              }
-          }
-        });
-    }
-
-    [self.attributedText enumerateAttribute:NSLinkAttributeName
-                                    inRange:NSMakeRange(0, self.attributedText.length)
-                                    options:0
-                                 usingBlock:^(id value, __unused NSRange range, __unused BOOL *stop) {
-                                   if (value) {
-                                       NSURL *URL = [value isKindOfClass:[NSString class]] ? [NSURL URLWithString:value] : value;
-                                       [self addLinkToURL:URL withRange:range];
-                                   }
-                                 }];
-}
-
-- (void)setText:(id)text
-    afterInheritingLabelAttributesAndConfiguringWithBlock:(NSMutableAttributedString * (^)(NSMutableAttributedString *mutableAttributedString))block {
-    NSMutableAttributedString *mutableAttributedString = nil;
-    if ([text isKindOfClass:[NSString class]]) {
-        mutableAttributedString = [[NSMutableAttributedString alloc] initWithString:text attributes:formatNSAttributedStringAttributesFromLabel(self)];
-    } else {
-        mutableAttributedString = [[NSMutableAttributedString alloc] initWithAttributedString:text];
-        [mutableAttributedString addAttributes:formatNSAttributedStringAttributesFromLabel(self) range:NSMakeRange(0, [mutableAttributedString length])];
-    }
-
-    if (block) {
-        mutableAttributedString = block(mutableAttributedString);
-    }
-
-    [self setText:mutableAttributedString];
-}
-
-- (void)setActiveLink:(TUIAttributedLabelLink *)activeLink {
-    _activeLink = activeLink;
-
-    NSDictionary *activeAttributes = activeLink.activeAttributes ?: self.activeLinkAttributes;
-
-    if (_activeLink && activeAttributes.count > 0) {
-        if (!self.inactiveAttributedText) {
-            self.inactiveAttributedText = [self.attributedText copy];
-        }
-
-        NSMutableAttributedString *mutableAttributedString = [self.inactiveAttributedText mutableCopy];
-        if (self.activeLink.result.range.length > 0 &&
-            NSLocationInRange(NSMaxRange(self.activeLink.result.range) - 1, NSMakeRange(0, [self.inactiveAttributedText length]))) {
-            [mutableAttributedString addAttributes:activeAttributes range:self.activeLink.result.range];
-        }
-
-        self.attributedText = mutableAttributedString;
-        [self setNeedsDisplay];
-
-        [CATransaction flush];
-    } else if (self.inactiveAttributedText) {
-        self.attributedText = self.inactiveAttributedText;
-        self.inactiveAttributedText = nil;
-
-        [self setNeedsDisplay];
-    }
-}
-
-- (void)setLinkAttributes:(NSDictionary *)linkAttributes {
-    _linkAttributes = convertNSAttributedStringAttributesToCTAttributes(linkAttributes);
-}
-
-- (void)setActiveLinkAttributes:(NSDictionary *)activeLinkAttributes {
-    _activeLinkAttributes = convertNSAttributedStringAttributesToCTAttributes(activeLinkAttributes);
-}
-
-- (void)setInactiveLinkAttributes:(NSDictionary *)inactiveLinkAttributes {
-    _inactiveLinkAttributes = convertNSAttributedStringAttributesToCTAttributes(inactiveLinkAttributes);
-}
-
-#pragma mark - UILabel
-
-- (void)setHighlighted:(BOOL)highlighted {
-    [super setHighlighted:highlighted];
-    [self setNeedsDisplay];
-}
-
-// Fixes crash when loading from a UIStoryboard
-- (UIColor *)textColor {
-    UIColor *color = [super textColor];
-    if (!color) {
-        color = [UIColor blackColor];
-    }
-
-    return color;
-}
-
-- (void)setTextColor:(UIColor *)textColor {
-    UIColor *oldTextColor = self.textColor;
-    [super setTextColor:textColor];
-
-    // Redraw to allow any ColorFromContext attributes a chance to update
-    if (textColor != oldTextColor) {
-        [self setNeedsFramesetter];
-        [self setNeedsDisplay];
-    }
-}
-
-- (CGRect)textRectForBounds:(CGRect)bounds limitedToNumberOfLines:(NSInteger)numberOfLines {
-    bounds = UIEdgeInsetsInsetRect(bounds, self.textInsets);
-    if (!self.attributedText) {
-        return [super textRectForBounds:bounds limitedToNumberOfLines:numberOfLines];
-    }
-
-    CGRect textRect = bounds;
-
-    // Calculate height with a minimum of double the font pointSize, to ensure that CTFramesetterSuggestFrameSizeWithConstraints doesn't return CGSizeZero, as
-    // it would if textRect height is insufficient.
-    textRect.size.height = MAX(self.font.lineHeight * MAX(2, numberOfLines), bounds.size.height);
-
-    // Adjust the text to be in the center vertically, if the text size is smaller than bounds
-    CGSize textSize =
-        CTFramesetterSuggestFrameSizeWithConstraints([self framesetter], CFRangeMake(0, (CFIndex)[self.attributedText length]), NULL, textRect.size, NULL);
-    textSize =
-        CGSizeMake(formatCGFloatCeil(textSize.width),
-                   formatCGFloatCeil(textSize.height));
-    // Fix for iOS 4, CTFramesetterSuggestFrameSizeWithConstraints sometimes returns fractional sizes
-
-    if (textSize.height < bounds.size.height) {
-        CGFloat yOffset = 0.0f;
-        switch (self.verticalAlignment) {
-            case TUIAttributedLabelVerticalAlignmentCenter:
-                yOffset = formatCGFloatFloor((bounds.size.height - textSize.height) / 2.0f);
-                break;
-            case TUIAttributedLabelVerticalAlignmentBottom:
-                yOffset = bounds.size.height - textSize.height;
-                break;
-            case TUIAttributedLabelVerticalAlignmentTop:
-            default:
-                break;
-        }
-
-        textRect.origin.y += yOffset;
-    }
-
-    return textRect;
-}
-
-- (void)drawTextInRect:(CGRect)rect {
-    CGRect insetRect = UIEdgeInsetsInsetRect(rect, self.textInsets);
-    if (!self.attributedText) {
-        [super drawTextInRect:insetRect];
-        return;
-    }
-
-    NSAttributedString *originalAttributedText = nil;
-
-    // Adjust the font size to fit width, if necessarry
-    if (self.adjustsFontSizeToFitWidth && self.numberOfLines > 0) {
-        // Framesetter could still be working with a resized version of the text;
-        // need to reset so we start from the original font size.
-        // See #393.
-        [self setNeedsFramesetter];
-        [self setNeedsDisplay];
-
-        if ([self respondsToSelector:@selector(invalidateIntrinsicContentSize)]) {
-            [self invalidateIntrinsicContentSize];
-        }
-
-        // Use infinite width to find the max width, which will be compared to availableWidth if needed.
-        CGSize maxSize = (self.numberOfLines > 1) ? CGSizeMake(TUIFLOAT_MAX, TUIFLOAT_MAX) : CGSizeZero;
-
-        CGFloat textWidth = [self sizeThatFits:maxSize].width;
-        CGFloat availableWidth = self.frame.size.width * self.numberOfLines;
-        if (self.numberOfLines > 1 && self.lineBreakMode == TUILineBreakByWordWrapping) {
-            textWidth *= kTUILineBreakWordWrapTextWidthScalingFactor;
-        }
-
-        if (textWidth > availableWidth && textWidth > 0.0f) {
-            originalAttributedText = [self.attributedText copy];
-
-            CGFloat scaleFactor = availableWidth / textWidth;
-            if ([self respondsToSelector:@selector(minimumScaleFactor)] && self.minimumScaleFactor > scaleFactor) {
-                scaleFactor = self.minimumScaleFactor;
-            }
-
-            self.attributedText = formatNSAttributedStringByScalingFontSize(self.attributedText, scaleFactor);
-        }
-    }
-
-    CGContextRef c = UIGraphicsGetCurrentContext();
-    CGContextSaveGState(c);
-    {
-        CGContextSetTextMatrix(c, CGAffineTransformIdentity);
-
-        // Inverts the CTM to match iOS coordinates (otherwise text draws upside-down; Mac OS's system is different)
-        CGContextTranslateCTM(c, 0.0f, insetRect.size.height);
-        CGContextScaleCTM(c, 1.0f, -1.0f);
-
-        CFRange textRange = CFRangeMake(0, (CFIndex)[self.attributedText length]);
-
-        // First, get the text rect (which takes vertical centering into account)
-        CGRect textRect = [self textRectForBounds:rect limitedToNumberOfLines:self.numberOfLines];
-
-        // CoreText draws its text aligned to the bottom, so we move the CTM here to take our vertical offsets into account
-        CGContextTranslateCTM(c, insetRect.origin.x, insetRect.size.height - textRect.origin.y - textRect.size.height);
-
-        // Second, trace the shadow before the actual text, if we have one
-        if (self.shadowColor && !self.highlighted) {
-            CGContextSetShadowWithColor(c, self.shadowOffset, self.shadowRadius, [self.shadowColor CGColor]);
-        } else if (self.highlightedShadowColor) {
-            CGContextSetShadowWithColor(c, self.highlightedShadowOffset, self.highlightedShadowRadius, [self.highlightedShadowColor CGColor]);
-        }
-
-        // Finally, draw the text or highlighted text itself (on top of the shadow, if there is one)
-        if (self.highlightedTextColor && self.highlighted) {
-            NSMutableAttributedString *highlightAttributedString = [self.renderedAttributedText mutableCopy];
-            [highlightAttributedString addAttribute:(__bridge NSString *)kCTForegroundColorAttributeName
-                                              value:(id)[self.highlightedTextColor CGColor]
-                                              range:NSMakeRange(0, highlightAttributedString.length)];
-
-            if (![self highlightFramesetter]) {
-                CTFramesetterRef highlightFramesetter = CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef)highlightAttributedString);
-                [self setHighlightFramesetter:highlightFramesetter];
-                CFRelease(highlightFramesetter);
-            }
-
-            [self drawFramesetter:[self highlightFramesetter] attributedString:highlightAttributedString textRange:textRange inRect:textRect context:c];
-        } else {
-            [self drawFramesetter:[self framesetter] attributedString:self.renderedAttributedText textRange:textRange inRect:textRect context:c];
-        }
-
-        // If we adjusted the font size, set it back to its original size
-        if (originalAttributedText) {
-            // Use ivar directly to avoid clearing out framesetter and renderedAttributedText
-            _attributedText = originalAttributedText;
-        }
-    }
-    CGContextRestoreGState(c);
-}
-
-#pragma mark - UIAccessibilityElement
-
-- (BOOL)isAccessibilityElement {
-    return NO;
-}
-
-- (NSInteger)accessibilityElementCount {
-    return (NSInteger)[[self accessibilityElements] count];
-}
-
-- (id)accessibilityElementAtIndex:(NSInteger)index {
-    return [[self accessibilityElements] objectAtIndex:(NSUInteger)index];
-}
-
-- (NSInteger)indexOfAccessibilityElement:(id)element {
-    return (NSInteger)[[self accessibilityElements] indexOfObject:element];
-}
-
-- (NSArray *)accessibilityElements {
-    if (!_accessibilityElements) {
-        @synchronized(self) {
-            NSMutableArray *mutableAccessibilityItems = [NSMutableArray array];
-
-            for (TUIAttributedLabelLink *link in self.linkModels) {
-                if (link.result.range.location == NSNotFound) {
-                    continue;
-                }
-
-                NSString *sourceText = [self.text isKindOfClass:[NSString class]] ? self.text : [(NSAttributedString *)self.text string];
-
-                NSString *accessibilityLabel = [sourceText substringWithRange:link.result.range];
-                NSString *accessibilityValue = link.accessibilityValue;
-
-                if (accessibilityLabel) {
-                    TUIAccessibilityElement *linkElement = [[TUIAccessibilityElement alloc] initWithAccessibilityContainer:self];
-                    linkElement.accessibilityTraits = UIAccessibilityTraitLink;
-                    linkElement.boundingRect = [self boundingRectForCharacterRange:link.result.range];
-                    linkElement.superview = self;
-                    linkElement.accessibilityLabel = accessibilityLabel;
-
-                    if (![accessibilityLabel isEqualToString:accessibilityValue]) {
-                        linkElement.accessibilityValue = accessibilityValue;
-                    }
-
-                    [mutableAccessibilityItems addObject:linkElement];
-                }
-            }
-
-            TUIAccessibilityElement *baseElement = [[TUIAccessibilityElement alloc] initWithAccessibilityContainer:self];
-            baseElement.accessibilityLabel = [super accessibilityLabel];
-            baseElement.accessibilityHint = [super accessibilityHint];
-            baseElement.accessibilityValue = [super accessibilityValue];
-            baseElement.boundingRect = self.bounds;
-            baseElement.superview = self;
-            baseElement.accessibilityTraits = [super accessibilityTraits];
-
-            [mutableAccessibilityItems addObject:baseElement];
-
-            self.accessibilityElements = [NSArray arrayWithArray:mutableAccessibilityItems];
-        }
-    }
-
-    return _accessibilityElements;
-}
-
-#pragma mark - UIView
-
-- (CGSize)sizeThatFits:(CGSize)size {
-    if (!self.attributedText) {
-        return [super sizeThatFits:size];
-    } else {
-        NSAttributedString *string = [self renderedAttributedText];
-
-        CGSize labelSize =
-            formatCTFramesetterSuggestFrameSizeForAttributedStringWithConstraints([self framesetter], string, size, (NSUInteger)self.numberOfLines);
-        labelSize.width += self.textInsets.left + self.textInsets.right;
-        labelSize.height += self.textInsets.top + self.textInsets.bottom;
-
-        return labelSize;
-    }
-}
-
-- (CGSize)intrinsicContentSize {
-    // There's an implicit width from the original UILabel implementation
-    return [self sizeThatFits:[super intrinsicContentSize]];
-}
-
-- (void)tintColorDidChange {
-    if (!self.inactiveLinkAttributes || [self.inactiveLinkAttributes count] == 0) {
-        return;
-    }
-
-    BOOL isInactive = (self.tintAdjustmentMode == UIViewTintAdjustmentModeDimmed);
-
-    NSMutableAttributedString *mutableAttributedString = [self.attributedText mutableCopy];
-    for (TUIAttributedLabelLink *link in self.linkModels) {
-        NSDictionary *attributesToRemove = isInactive ? link.attributes : link.inactiveAttributes;
-        NSDictionary *attributesToAdd = isInactive ? link.inactiveAttributes : link.attributes;
-
-        [attributesToRemove enumerateKeysAndObjectsUsingBlock:^(NSString *name, __unused id value, __unused BOOL *stop) {
-          if (NSMaxRange(link.result.range) <= mutableAttributedString.length) {
-              [mutableAttributedString removeAttribute:name range:link.result.range];
-          }
-        }];
-
-        if (attributesToAdd) {
-            if (NSMaxRange(link.result.range) <= mutableAttributedString.length) {
-                [mutableAttributedString addAttributes:attributesToAdd range:link.result.range];
-            }
-        }
-    }
-
-    self.attributedText = mutableAttributedString;
-
-    [self setNeedsDisplay];
-}
-
-- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
-    if (![self linkAtPoint:point] || !self.userInteractionEnabled || self.hidden || self.alpha < 0.01) {
-        return [super hitTest:point withEvent:event];
-    }
-
-    return self;
-}
-
-#pragma mark - UIResponder
-
-- (BOOL)canBecomeFirstResponder {
-    return YES;
-}
-
-- (BOOL)canPerformAction:(SEL)action withSender:(__unused id)sender {
-#if !TARGET_OS_TV
-    return (action == @selector(copy:));
-#else
-    return NO;
-#endif
-}
-
-- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
-    UITouch *touch = [touches anyObject];
-
-    self.activeLink = [self linkAtPoint:[touch locationInView:self]];
-
-    if (!self.activeLink) {
-        [super touchesBegan:touches withEvent:event];
-    }
-}
-
-- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
-    if (self.activeLink) {
-        UITouch *touch = [touches anyObject];
-
-        if (self.activeLink != [self linkAtPoint:[touch locationInView:self]]) {
-            self.activeLink = nil;
-        }
-    } else {
-        [super touchesMoved:touches withEvent:event];
-    }
-}
-
-- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
-    if (self.activeLink) {
-        if (self.activeLink.linkTapBlock) {
-            self.activeLink.linkTapBlock(self, self.activeLink);
-            self.activeLink = nil;
-            return;
-        }
-
-        NSTextCheckingResult *result = self.activeLink.result;
-        self.activeLink = nil;
-
-        switch (result.resultType) {
-            case NSTextCheckingTypeLink:
-                if ([self.delegate respondsToSelector:@selector(attributedLabel:didSelectLinkWithURL:)]) {
-                    [self.delegate attributedLabel:self didSelectLinkWithURL:result.URL];
-                    return;
-                }
-                break;
-            case NSTextCheckingTypeAddress:
-                if ([self.delegate respondsToSelector:@selector(attributedLabel:didSelectLinkWithAddress:)]) {
-                    [self.delegate attributedLabel:self didSelectLinkWithAddress:result.addressComponents];
-                    return;
-                }
-                break;
-            case NSTextCheckingTypePhoneNumber:
-                if ([self.delegate respondsToSelector:@selector(attributedLabel:didSelectLinkWithPhoneNumber:)]) {
-                    [self.delegate attributedLabel:self didSelectLinkWithPhoneNumber:result.phoneNumber];
-                    return;
-                }
-                break;
-            case NSTextCheckingTypeDate:
-                if (result.timeZone && [self.delegate respondsToSelector:@selector(attributedLabel:didSelectLinkWithDate:timeZone:duration:)]) {
-                    [self.delegate attributedLabel:self didSelectLinkWithDate:result.date timeZone:result.timeZone duration:result.duration];
-                    return;
-                } else if ([self.delegate respondsToSelector:@selector(attributedLabel:didSelectLinkWithDate:)]) {
-                    [self.delegate attributedLabel:self didSelectLinkWithDate:result.date];
-                    return;
-                }
-                break;
-            case NSTextCheckingTypeTransitInformation:
-                if ([self.delegate respondsToSelector:@selector(attributedLabel:didSelectLinkWithTransitInformation:)]) {
-                    [self.delegate attributedLabel:self didSelectLinkWithTransitInformation:result.components];
-                    return;
-                }
-            default:
-                break;
-        }
-
-        // Fallback to `attributedLabel:didSelectLinkWithTextCheckingResult:` if no other delegate method matched.
-        if ([self.delegate respondsToSelector:@selector(attributedLabel:didSelectLinkWithTextCheckingResult:)]) {
-            [self.delegate attributedLabel:self didSelectLinkWithTextCheckingResult:result];
-        }
-    } else {
-        [super touchesEnded:touches withEvent:event];
-    }
-}
-
-- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
-    if (self.activeLink) {
-        self.activeLink = nil;
-    } else {
-        [super touchesCancelled:touches withEvent:event];
-    }
-}
-
-#pragma mark - UIGestureRecognizerDelegate
-
-- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
-    return [self containslinkAtPoint:[touch locationInView:self]];
-}
-
-#pragma mark - UILongPressGestureRecognizer
-
-- (void)longPressGestureDidFire:(UILongPressGestureRecognizer *)sender {
-    switch (sender.state) {
-        case UIGestureRecognizerStateBegan: {
-            CGPoint touchPoint = [sender locationInView:self];
-            TUIAttributedLabelLink *link = [self linkAtPoint:touchPoint];
-
-            if (link) {
-                if (link.linkLongPressBlock) {
-                    link.linkLongPressBlock(self, link);
-                    return;
-                }
-
-                NSTextCheckingResult *result = link.result;
-
-                if (!result) {
-                    return;
-                }
-
-                switch (result.resultType) {
-                    case NSTextCheckingTypeLink:
-                        if ([self.delegate respondsToSelector:@selector(attributedLabel:didLongPressLinkWithURL:atPoint:)]) {
-                            [self.delegate attributedLabel:self didLongPressLinkWithURL:result.URL atPoint:touchPoint];
-                            return;
-                        }
-                        break;
-                    case NSTextCheckingTypeAddress:
-                        if ([self.delegate respondsToSelector:@selector(attributedLabel:didLongPressLinkWithAddress:atPoint:)]) {
-                            [self.delegate attributedLabel:self didLongPressLinkWithAddress:result.addressComponents atPoint:touchPoint];
-                            return;
-                        }
-                        break;
-                    case NSTextCheckingTypePhoneNumber:
-                        if ([self.delegate respondsToSelector:@selector(attributedLabel:didLongPressLinkWithPhoneNumber:atPoint:)]) {
-                            [self.delegate attributedLabel:self didLongPressLinkWithPhoneNumber:result.phoneNumber atPoint:touchPoint];
-                            return;
-                        }
-                        break;
-                    case NSTextCheckingTypeDate:
-                        if (result.timeZone && [self.delegate respondsToSelector:@selector(attributedLabel:
-                                                                                     didLongPressLinkWithDate:timeZone:duration:atPoint:)]) {
-                            [self.delegate attributedLabel:self
-                                  didLongPressLinkWithDate:result.date
-                                                  timeZone:result.timeZone
-                                                  duration:result.duration
-                                                   atPoint:touchPoint];
-                            return;
-                        } else if ([self.delegate respondsToSelector:@selector(attributedLabel:didLongPressLinkWithDate:atPoint:)]) {
-                            [self.delegate attributedLabel:self didLongPressLinkWithDate:result.date atPoint:touchPoint];
-                            return;
-                        }
-                        break;
-                    case NSTextCheckingTypeTransitInformation:
-                        if ([self.delegate respondsToSelector:@selector(attributedLabel:didLongPressLinkWithTransitInformation:atPoint:)]) {
-                            [self.delegate attributedLabel:self didLongPressLinkWithTransitInformation:result.components atPoint:touchPoint];
-                            return;
-                        }
-                    default:
-                        break;
-                }
-
-                // Fallback to `attributedLabel:didLongPressLinkWithTextCheckingResult:atPoint:` if no other delegate method matched.
-                if ([self.delegate respondsToSelector:@selector(attributedLabel:didLongPressLinkWithTextCheckingResult:atPoint:)]) {
-                    [self.delegate attributedLabel:self didLongPressLinkWithTextCheckingResult:result atPoint:touchPoint];
-                }
-            }
-            break;
-        }
-        default:
-            break;
-    }
-}
-
-#if !TARGET_OS_TV
-#pragma mark - UIResponderStandardEditActions
-
-- (void)copy:(__unused id)sender {
-    [[UIPasteboard generalPasteboard] setString:self.text];
-}
-#endif
-
-#pragma mark - NSCoding
-
-- (void)encodeWithCoder:(NSCoder *)coder {
-    [super encodeWithCoder:coder];
-
-    [coder encodeObject:@(self.enabledTextCheckingTypes) forKey:NSStringFromSelector(@selector(enabledTextCheckingTypes))];
-
-    [coder encodeObject:self.linkModels forKey:NSStringFromSelector(@selector(linkModels))];
-    if ([NSMutableParagraphStyle class]) {
-        [coder encodeObject:self.linkAttributes forKey:NSStringFromSelector(@selector(linkAttributes))];
-        [coder encodeObject:self.activeLinkAttributes forKey:NSStringFromSelector(@selector(activeLinkAttributes))];
-        [coder encodeObject:self.inactiveLinkAttributes forKey:NSStringFromSelector(@selector(inactiveLinkAttributes))];
-    }
-    [coder encodeObject:@(self.shadowRadius) forKey:NSStringFromSelector(@selector(shadowRadius))];
-    [coder encodeObject:@(self.highlightedShadowRadius) forKey:NSStringFromSelector(@selector(highlightedShadowRadius))];
-    [coder encodeCGSize:self.highlightedShadowOffset forKey:NSStringFromSelector(@selector(highlightedShadowOffset))];
-    [coder encodeObject:self.highlightedShadowColor forKey:NSStringFromSelector(@selector(highlightedShadowColor))];
-    [coder encodeObject:@(self.kern) forKey:NSStringFromSelector(@selector(kern))];
-    [coder encodeObject:@(self.firstLineIndent) forKey:NSStringFromSelector(@selector(firstLineIndent))];
-    [coder encodeObject:@(self.lineSpacing) forKey:NSStringFromSelector(@selector(lineSpacing))];
-    [coder encodeObject:@(self.lineHeightMultiple) forKey:NSStringFromSelector(@selector(lineHeightMultiple))];
-    [coder encodeUIEdgeInsets:self.textInsets forKey:NSStringFromSelector(@selector(textInsets))];
-    [coder encodeInteger:self.verticalAlignment forKey:NSStringFromSelector(@selector(verticalAlignment))];
-
-    [coder encodeObject:self.attributedTruncationToken forKey:NSStringFromSelector(@selector(attributedTruncationToken))];
-
-    [coder encodeObject:NSStringFromUIEdgeInsets(self.linkBackgroundEdgeInset) forKey:NSStringFromSelector(@selector(linkBackgroundEdgeInset))];
-    [coder encodeObject:self.attributedText forKey:NSStringFromSelector(@selector(attributedText))];
-    [coder encodeObject:self.text forKey:NSStringFromSelector(@selector(text))];
-}
-
-- (id)initWithCoder:(NSCoder *)coder {
-    self = [super initWithCoder:coder];
-    if (!self) {
-        return nil;
-    }
-
-    [self commonInit];
-
-    if ([coder containsValueForKey:NSStringFromSelector(@selector(enabledTextCheckingTypes))]) {
-        self.enabledTextCheckingTypes = [[coder decodeObjectForKey:NSStringFromSelector(@selector(enabledTextCheckingTypes))] unsignedLongLongValue];
-    }
-
-    if ([NSMutableParagraphStyle class]) {
-        if ([coder containsValueForKey:NSStringFromSelector(@selector(linkAttributes))]) {
-            self.linkAttributes = [coder decodeObjectForKey:NSStringFromSelector(@selector(linkAttributes))];
-        }
-
-        if ([coder containsValueForKey:NSStringFromSelector(@selector(activeLinkAttributes))]) {
-            self.activeLinkAttributes = [coder decodeObjectForKey:NSStringFromSelector(@selector(activeLinkAttributes))];
-        }
-
-        if ([coder containsValueForKey:NSStringFromSelector(@selector(inactiveLinkAttributes))]) {
-            self.inactiveLinkAttributes = [coder decodeObjectForKey:NSStringFromSelector(@selector(inactiveLinkAttributes))];
-        }
-    }
-
-    if ([coder containsValueForKey:NSStringFromSelector(@selector(links))]) {
-        NSArray *oldLinks = [coder decodeObjectForKey:NSStringFromSelector(@selector(links))];
-        [self addLinksWithTextCheckingResults:oldLinks attributes:nil];
-    }
-
-    if ([coder containsValueForKey:NSStringFromSelector(@selector(linkModels))]) {
-        self.linkModels = [coder decodeObjectForKey:NSStringFromSelector(@selector(linkModels))];
-    }
-
-    if ([coder containsValueForKey:NSStringFromSelector(@selector(shadowRadius))]) {
-        self.shadowRadius = [[coder decodeObjectForKey:NSStringFromSelector(@selector(shadowRadius))] floatValue];
-    }
-
-    if ([coder containsValueForKey:NSStringFromSelector(@selector(highlightedShadowRadius))]) {
-        self.highlightedShadowRadius = [[coder decodeObjectForKey:NSStringFromSelector(@selector(highlightedShadowRadius))] floatValue];
-    }
-
-    if ([coder containsValueForKey:NSStringFromSelector(@selector(highlightedShadowOffset))]) {
-        self.highlightedShadowOffset = [coder decodeCGSizeForKey:NSStringFromSelector(@selector(highlightedShadowOffset))];
-    }
-
-    if ([coder containsValueForKey:NSStringFromSelector(@selector(highlightedShadowColor))]) {
-        self.highlightedShadowColor = [coder decodeObjectForKey:NSStringFromSelector(@selector(highlightedShadowColor))];
-    }
-
-    if ([coder containsValueForKey:NSStringFromSelector(@selector(kern))]) {
-        self.kern = [[coder decodeObjectForKey:NSStringFromSelector(@selector(kern))] floatValue];
-    }
-
-    if ([coder containsValueForKey:NSStringFromSelector(@selector(firstLineIndent))]) {
-        self.firstLineIndent = [[coder decodeObjectForKey:NSStringFromSelector(@selector(firstLineIndent))] floatValue];
-    }
-
-    if ([coder containsValueForKey:NSStringFromSelector(@selector(lineSpacing))]) {
-        self.lineSpacing = [[coder decodeObjectForKey:NSStringFromSelector(@selector(lineSpacing))] floatValue];
-    }
-
-    if ([coder containsValueForKey:NSStringFromSelector(@selector(minimumLineHeight))]) {
-        self.minimumLineHeight = [[coder decodeObjectForKey:NSStringFromSelector(@selector(minimumLineHeight))] floatValue];
-    }
-
-    if ([coder containsValueForKey:NSStringFromSelector(@selector(maximumLineHeight))]) {
-        self.maximumLineHeight = [[coder decodeObjectForKey:NSStringFromSelector(@selector(maximumLineHeight))] floatValue];
-    }
-
-    if ([coder containsValueForKey:NSStringFromSelector(@selector(lineHeightMultiple))]) {
-        self.lineHeightMultiple = [[coder decodeObjectForKey:NSStringFromSelector(@selector(lineHeightMultiple))] floatValue];
-    }
-
-    if ([coder containsValueForKey:NSStringFromSelector(@selector(textInsets))]) {
-        self.textInsets = [coder decodeUIEdgeInsetsForKey:NSStringFromSelector(@selector(textInsets))];
-    }
-
-    if ([coder containsValueForKey:NSStringFromSelector(@selector(verticalAlignment))]) {
-        self.verticalAlignment = [coder decodeIntegerForKey:NSStringFromSelector(@selector(verticalAlignment))];
-    }
-
-    if ([coder containsValueForKey:NSStringFromSelector(@selector(attributedTruncationToken))]) {
-        self.attributedTruncationToken = [coder decodeObjectForKey:NSStringFromSelector(@selector(attributedTruncationToken))];
-    }
-
-    if ([coder containsValueForKey:NSStringFromSelector(@selector(linkBackgroundEdgeInset))]) {
-        self.linkBackgroundEdgeInset = UIEdgeInsetsFromString([coder decodeObjectForKey:NSStringFromSelector(@selector(linkBackgroundEdgeInset))]);
-    }
-
-    if ([coder containsValueForKey:NSStringFromSelector(@selector(attributedText))]) {
-        self.attributedText = [coder decodeObjectForKey:NSStringFromSelector(@selector(attributedText))];
-    } else {
-        self.text = super.text;
-    }
-
-    return self;
-}
-
-@end
-
-#pragma mark - TUIAttributedLabelLink
-
-@implementation TUIAttributedLabelLink
-
-- (instancetype)initWithAttributes:(NSDictionary *)attributes
-                  activeAttributes:(NSDictionary *)activeAttributes
-                inactiveAttributes:(NSDictionary *)inactiveAttributes
-                textCheckingResult:(NSTextCheckingResult *)result {
-    if ((self = [super init])) {
-        _result = result;
-        _attributes = [attributes copy];
-        _activeAttributes = [activeAttributes copy];
-        _inactiveAttributes = [inactiveAttributes copy];
-    }
-
-    return self;
-}
-
-- (instancetype)initWithAttributesFromLabel:(TUIAttributedLabel *)label textCheckingResult:(NSTextCheckingResult *)result {
-    return [self initWithAttributes:label.linkAttributes
-                   activeAttributes:label.activeLinkAttributes
-                 inactiveAttributes:label.inactiveLinkAttributes
-                 textCheckingResult:result];
-}
-
-#pragma mark - Accessibility
-
-- (NSString *)accessibilityValue {
-    if ([_accessibilityValue length] == 0) {
-        switch (self.result.resultType) {
-            case NSTextCheckingTypeLink:
-                _accessibilityValue = self.result.URL.absoluteString;
-                break;
-            case NSTextCheckingTypePhoneNumber:
-                _accessibilityValue = self.result.phoneNumber;
-                break;
-            case NSTextCheckingTypeDate:
-                _accessibilityValue = [NSDateFormatter localizedStringFromDate:self.result.date
-                                                                     dateStyle:NSDateFormatterLongStyle
-                                                                     timeStyle:NSDateFormatterLongStyle];
-                break;
-            default:
-                break;
-        }
-    }
-
-    return _accessibilityValue;
-}
-
-#pragma mark - NSCoding
-
-- (void)encodeWithCoder:(NSCoder *)aCoder {
-    [aCoder encodeObject:self.result forKey:NSStringFromSelector(@selector(result))];
-    [aCoder encodeObject:self.attributes forKey:NSStringFromSelector(@selector(attributes))];
-    [aCoder encodeObject:self.activeAttributes forKey:NSStringFromSelector(@selector(activeAttributes))];
-    [aCoder encodeObject:self.inactiveAttributes forKey:NSStringFromSelector(@selector(inactiveAttributes))];
-    [aCoder encodeObject:self.accessibilityValue forKey:NSStringFromSelector(@selector(accessibilityValue))];
-}
-
-- (id)initWithCoder:(NSCoder *)aDecoder {
-    if ((self = [super init])) {
-        _result = [aDecoder decodeObjectForKey:NSStringFromSelector(@selector(result))];
-        _attributes = [aDecoder decodeObjectForKey:NSStringFromSelector(@selector(attributes))];
-        _activeAttributes = [aDecoder decodeObjectForKey:NSStringFromSelector(@selector(activeAttributes))];
-        _inactiveAttributes = [aDecoder decodeObjectForKey:NSStringFromSelector(@selector(inactiveAttributes))];
-        self.accessibilityValue = [aDecoder decodeObjectForKey:NSStringFromSelector(@selector(accessibilityValue))];
-    }
-
-    return self;
-}
-
-@end
-
-#pragma mark -
-
-static inline CGColorRef formatCGColorRefFromColor(id color) { return [color isKindOfClass:[UIColor class]] ? [color CGColor] : (__bridge CGColorRef)color; }
-
-static inline CTFontRef formatCTFontRefFromUIFont(UIFont *font) {
-    CTFontRef ctfont = CTFontCreateWithName((__bridge CFStringRef)font.fontName, font.pointSize, NULL);
-    return CFAutorelease(ctfont);
-}
-
-static inline NSDictionary *convertNSAttributedStringAttributesToCTAttributes(NSDictionary *attributes) {
-    if (!attributes) return nil;
-
-    NSMutableDictionary *mutableAttributes = [NSMutableDictionary dictionary];
-
-    NSDictionary *convertMap = @{
-        NSFontAttributeName : (NSString *)kCTFontAttributeName,
-        NSBackgroundColorAttributeName : (NSString *)kTUIBackgroundFillColorAttributeName,
-        NSForegroundColorAttributeName : (NSString *)kCTForegroundColorAttributeName,
-        NSUnderlineColorAttributeName : (NSString *)kCTUnderlineColorAttributeName,
-        NSUnderlineStyleAttributeName : (NSString *)kCTUnderlineStyleAttributeName,
-        NSStrokeWidthAttributeName : (NSString *)kCTStrokeWidthAttributeName,
-        NSStrokeColorAttributeName : (NSString *)kCTStrokeWidthAttributeName,
-        NSKernAttributeName : (NSString *)kCTKernAttributeName,
-        NSLigatureAttributeName : (NSString *)kCTLigatureAttributeName
-    };
-
-    [attributes enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL *stop) {
-      key = [convertMap objectForKey:key] ?: key;
-
-      if (![NSMutableParagraphStyle class]) {
-          if ([value isKindOfClass:[UIFont class]]) {
-              value = (__bridge id)formatCTFontRefFromUIFont(value);
-          } else if ([value isKindOfClass:[UIColor class]]) {
-              value = (__bridge id)((UIColor *)value).CGColor;
-          }
-      }
-
-      [mutableAttributes setObject:value forKey:key];
-    }];
-
-    return [NSDictionary dictionaryWithDictionary:mutableAttributes];
-}

+ 0 - 29
ThirdParty/TUIKit/TIMCommon/CommonModel/TUIFitButton.h

@@ -1,29 +0,0 @@
-//
-//  TUIFitButton.h
-//  TUICore
-//
-//  Created by wyl on 2022/5/24.
-//  Copyright © 2023 Tencent. All rights reserved.
-//
-
-#import <UIKit/UIKit.h>
-
-NS_ASSUME_NONNULL_BEGIN
-
-@interface TUIFitButton : UIButton
-@property(nonatomic, assign) CGRect titleRect;
-@property(nonatomic, assign) CGRect imageRect;
-
-@property(nonatomic, assign) CGSize imageSize;
-@property(nonatomic, assign) CGSize titleSize;
-
-@property(nonatomic, strong) UIImage* hoverImage;
-@property(nonatomic, strong) UIImage* normalImage;
-
-@end
-
-@interface TUIBlockButton : TUIFitButton
-@property(nonatomic, copy) void (^clickCallBack)(id button);
-@end
-
-NS_ASSUME_NONNULL_END

+ 0 - 66
ThirdParty/TUIKit/TIMCommon/CommonModel/TUIFitButton.m

@@ -1,66 +0,0 @@
-//
-//  TUIFitButton.m
-//  TUICore
-//
-//  Created by wyl on 2022/5/24.
-//  Copyright © 2023 Tencent. All rights reserved.
-//
-
-#import "TUIFitButton.h"
-
-@implementation TUIFitButton
-
-- (CGRect)titleRectForContentRect:(CGRect)contentRect {
-    if (!CGRectEqualToRect(self.titleRect, CGRectZero)) {
-        return self.titleRect;
-    } else if (!CGSizeEqualToSize(self.titleSize, CGSizeZero)) {
-        CGRect oldrect = [super titleRectForContentRect:contentRect];
-        CGRect newrect = CGRectZero;
-        newrect.origin.x = oldrect.origin.x + (oldrect.size.width - self.titleSize.width) / 2;
-        newrect.origin.y = oldrect.origin.y + (oldrect.size.height - self.titleSize.height) / 2;
-        newrect.size.width = self.titleSize.width;
-        newrect.size.height = self.titleSize.height;
-
-        return newrect;
-    }
-    return [super titleRectForContentRect:contentRect];
-}
-- (CGRect)imageRectForContentRect:(CGRect)contentRect {
-    if (!CGRectEqualToRect(self.imageRect, CGRectZero)) {
-        return self.imageRect;
-    } else if (!CGSizeEqualToSize(self.imageSize, CGSizeZero)) {
-        CGRect oldrect = [super imageRectForContentRect:contentRect];
-        CGRect newrect = CGRectZero;
-        newrect.origin.x = oldrect.origin.x + (oldrect.size.width - self.imageSize.width) / 2;
-        newrect.origin.y = oldrect.origin.y + (oldrect.size.height - self.imageSize.height) / 2;
-        newrect.size.width = self.imageSize.width;
-        newrect.size.height = self.imageSize.height;
-
-        return newrect;
-    }
-    return [super imageRectForContentRect:contentRect];
-}
-
-- (void)setNormalImage:(UIImage *)normalImage {
-    _normalImage = normalImage;
-    [self setImage:normalImage forState:UIControlStateNormal];
-}
-@end
-
-@implementation TUIBlockButton
-
-- (instancetype)initWithFrame:(CGRect)frame {
-    if (self = [super initWithFrame:frame]) {
-        [self addTarget:self action:@selector(buttonTap:) forControlEvents:UIControlEventTouchUpInside];
-    }
-    return self;
-}
-
-- (void)buttonTap:(id)button {
-    if (self.clickCallBack) {
-        self.clickCallBack(self);
-    }
-}
-- (void)dealloc {
-}
-@end

+ 0 - 54
ThirdParty/TUIKit/TIMCommon/CommonModel/TUIFloatViewController.h

@@ -1,54 +0,0 @@
-//
-//  TUIFloatViewController.h
-//  TIMCommon
-//
-//  Created by wyl on 2023/1/16.
-//  Copyright © 2023 Tencent. All rights reserved.
-//
-
-#import <UIKit/UIKit.h>
-
-NS_ASSUME_NONNULL_BEGIN
-
-@protocol TUIFloatSubViewControllerProtocol <NSObject>
-
-@optional
-
-@property(nonatomic, copy) void (^floatDataSourceChanged)(NSArray *arr);
-
-- (void)floatControllerLeftButtonClick;
-
-- (void)floatControllerRightButtonClick;
-
-@end
-
-@interface TUIFloatTitleView : UIView
-
-@property(nonatomic, strong) UIButton *leftButton;
-@property(nonatomic, strong) UIButton *rightButton;
-@property(nonatomic, copy) void (^leftButtonClickCallback)(void);
-@property(nonatomic, copy) void (^rightButtonClickCallback)(void);
-@property(nonatomic, strong) UILabel *titleLabel;
-@property(nonatomic, strong) UILabel *subTitleLabel;
-
-- (void)setTitleText:(NSString *)mainText subTitleText:(NSString *)secondText leftBtnText:(NSString *)leftBtnText rightBtnText:(NSString *)rightBtnText;
-@end
-
-@interface TUIFloatViewController : UIViewController
-@property(nonatomic, strong) TUIFloatTitleView *topGestureView;
-@property(nonatomic, strong) UIImageView *topImgView;
-@property(nonatomic, strong) UIView *containerView;
-@property(nonatomic, strong) UIViewController<TUIFloatSubViewControllerProtocol> *childVC;
-
-- (void)updateSubContainerView;
-
-- (void)setnormalTop;
-
-- (void)setNormalBottom;
-
-- (void)appendChildViewController:(UIViewController<TUIFloatSubViewControllerProtocol> *)vc topMargin:(CGFloat)topMargin;
-
-- (void)floatDismissViewControllerAnimated:(BOOL)flag completion:(void (^)(void))completion;
-@end
-
-NS_ASSUME_NONNULL_END

+ 0 - 283
ThirdParty/TUIKit/TIMCommon/CommonModel/TUIFloatViewController.m

@@ -1,283 +0,0 @@
-//
-//  TUIFloatTitleView.m
-//  TUI
-//
-//  Created by wyl on 2023/1/16.
-//  Copyright © 2023 Tencent. All rights reserved.
-//
-
-#import "TUIFloatViewController.h"
-#import <TIMCommon/TIMDefine.h>
-
-typedef enum : NSUInteger {
-    FLEX_TOP,
-    FLEX_Bottom,
-} FLEX_Location;
-
-@interface TUIFloatTitleView ()
-
-@end
-
-@implementation TUIFloatTitleView
-
-- (instancetype)initWithFrame:(CGRect)frame {
-    self = [super initWithFrame:frame];
-    if (self) {
-        [self setupView];
-    }
-    return self;
-}
-
-- (void)setupView {
-    self.titleLabel = [[UILabel alloc] init];
-    self.titleLabel.text = @"";
-    self.titleLabel.font = [UIFont boldSystemFontOfSize:kScale390(20)];
-    [self addSubview:self.titleLabel];
-
-    self.subTitleLabel = [[UILabel alloc] init];
-    self.subTitleLabel.text = @"";
-    self.subTitleLabel.font = [UIFont systemFontOfSize:kScale390(12)];
-    self.subTitleLabel.tintColor = [UIColor grayColor];
-    [self addSubview:self.subTitleLabel];
-
-    self.leftButton = [UIButton buttonWithType:UIButtonTypeCustom];
-    [self addSubview:self.leftButton];
-    [self.leftButton setTitle:TIMCommonLocalizableString(TUIKitCreateCancel) forState:UIControlStateNormal];
-    self.leftButton.titleLabel.font = [UIFont systemFontOfSize:kScale390(16)];
-    [self.leftButton addTarget:self action:@selector(leftButtonClick) forControlEvents:UIControlEventTouchUpInside];
-    [self.leftButton setTitleColor:[UIColor tui_colorWithHex:@"#0365F9"] forState:UIControlStateNormal];
-
-    self.rightButton = [UIButton buttonWithType:UIButtonTypeCustom];
-    [self addSubview:self.rightButton];
-    [self.rightButton setTitle:TIMCommonLocalizableString(TUIKitCreateNext) forState:UIControlStateNormal];
-    self.rightButton.titleLabel.font = [UIFont systemFontOfSize:kScale390(16)];
-    [self.rightButton addTarget:self action:@selector(rightButtonClick) forControlEvents:UIControlEventTouchUpInside];
-    [self.rightButton setTitleColor:[UIColor tui_colorWithHex:@"#0365F9"] forState:UIControlStateNormal];
-}
-
-- (void)layoutSubviews {
-    [super layoutSubviews];
-
-    [self.titleLabel sizeToFit];
-    [self.subTitleLabel sizeToFit];
-
-    if (self.subTitleLabel.isHidden || self.subTitleLabel.text.length == 0) {
-        self.titleLabel.frame = CGRectMake((self.frame.size.width - self.titleLabel.frame.size.width) * 0.5, kScale390(23.5), self.titleLabel.frame.size.width,
-                                           self.titleLabel.frame.size.height);
-    } else {
-        self.titleLabel.frame = CGRectMake((self.frame.size.width - self.titleLabel.frame.size.width) * 0.5, kScale390(17.5), self.titleLabel.frame.size.width,
-                                           self.titleLabel.frame.size.height);
-
-        self.subTitleLabel.frame = CGRectMake((self.frame.size.width - self.subTitleLabel.frame.size.width) * 0.5,
-                                              self.titleLabel.frame.origin.y + self.titleLabel.frame.size.height + kScale390(1),
-                                              self.subTitleLabel.frame.size.width, self.subTitleLabel.frame.size.height);
-    }
-
-    [self.leftButton sizeToFit];
-    self.leftButton.frame = CGRectMake(kScale390(15), kScale390(23.5), self.leftButton.frame.size.width, self.leftButton.frame.size.height);
-
-    [self.rightButton sizeToFit];
-    self.rightButton.frame = CGRectMake(self.frame.size.width - self.rightButton.frame.size.width - kScale390(14), kScale390(23.5),
-                                        self.rightButton.frame.size.width, self.rightButton.frame.size.height);
-    if (isRTL()){
-        [self.leftButton resetFrameToFitRTL];
-        [self.rightButton resetFrameToFitRTL];
-    }
-}
-- (void)leftButtonClick {
-    if (self.leftButtonClickCallback) {
-        self.leftButtonClickCallback();
-    }
-}
-
-- (void)rightButtonClick {
-    if (self.rightButtonClickCallback) {
-        self.rightButtonClickCallback();
-    }
-}
-
-- (void)setTitleText:(NSString *)mainText subTitleText:(NSString *)secondText leftBtnText:(NSString *)leftBtnText rightBtnText:(NSString *)rightBtnText {
-    self.titleLabel.text = mainText;
-    self.subTitleLabel.text = secondText;
-    [self.leftButton setTitle:leftBtnText forState:UIControlStateNormal];
-    [self.rightButton setTitle:rightBtnText forState:UIControlStateNormal];
-}
-@end
-
-@interface TUIFloatViewController ()
-
-@property(nonatomic, assign) CGFloat topMargin;
-
-@property(nonatomic, assign) FLEX_Location currentLoaction;
-
-@property(nonatomic, strong) UIPanGestureRecognizer *panCover;
-
-@property(nonatomic, strong) UITapGestureRecognizer *singleTap;
-
-@end
-
-@implementation TUIFloatViewController
-
-- (void)appendChildViewController:(UIViewController<TUIFloatSubViewControllerProtocol> *)vc topMargin:(CGFloat)topMargin {
-    self.childVC = vc;
-    self.topMargin = topMargin;
-
-    [self addChildViewController:vc];
-    [self.containerView addSubview:vc.view];
-}
-
-- (void)viewDidLoad {
-    [super viewDidLoad];
-
-    self.view.backgroundColor = [UIColor tui_colorWithHex:@"#000000" alpha:0.6];
-    self.modalPresentationStyle = UIModalPresentationCustom;
-
-    self.containerView.backgroundColor = [UIColor whiteColor];
-
-    self.topImgView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:TIMCommonImagePath(@"icon_flex_arrow")]];
-    [self.topGestureView addSubview:self.topImgView];
-    self.topImgView.hidden = YES;
-
-    @weakify(self);
-    self.topGestureView.leftButtonClickCallback = ^{
-      @strongify(self);
-      if ([self.childVC respondsToSelector:@selector(floatControllerLeftButtonClick)]) {
-          [self.childVC performSelector:@selector(floatControllerLeftButtonClick)];
-      }
-    };
-    self.topGestureView.rightButtonClickCallback = ^{
-      @strongify(self);
-      if ([self.childVC respondsToSelector:@selector(floatControllerRightButtonClick)]) {
-          [self.childVC performSelector:@selector(floatControllerRightButtonClick)];
-      }
-    };
-    [self addSingleTapGesture];
-
-    if (!_currentLoaction) {
-        self.currentLoaction = FLEX_TOP;
-    }
-
-    [self updateSubContainerView];
-}
-
-- (void)addSingleTapGesture {
-    // When clicking on the shadow, the page disappears
-    self.view.userInteractionEnabled = YES;
-    UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(singleTap:)];
-    singleTap.cancelsTouchesInView = NO;
-    [self.view addGestureRecognizer:singleTap];
-}
-
-- (void)singleTap:(UITapGestureRecognizer *)tap {
-    CGPoint translation = [tap locationInView:self.containerView];
-
-    if (translation.x < 0 || translation.y < 0) {
-        [self dismissViewControllerAnimated:YES completion:nil];
-    } else if (translation.x > self.containerView.frame.size.width || translation.y > self.containerView.frame.size.height) {
-        [self dismissViewControllerAnimated:YES completion:nil];
-    }
-}
-
-- (void)setnormalTop {
-    self.currentLoaction = FLEX_TOP;
-}
-
-- (void)setNormalBottom {
-    self.currentLoaction = FLEX_Bottom;
-}
-
-- (void)setCurrentLoaction:(FLEX_Location)currentLoaction {
-    _currentLoaction = currentLoaction;
-    if (currentLoaction == FLEX_TOP) {
-        self.containerView.frame = CGRectMake(0, self.topMargin, self.view.frame.size.width, self.view.frame.size.height - self.topMargin);
-    } else if (currentLoaction == FLEX_Bottom) {
-        self.containerView.frame = CGRectMake(0, self.view.frame.size.height - kScale390(393), self.view.frame.size.width, kScale390(393));
-    }
-}
-
-- (void)floatDismissViewControllerAnimated:(BOOL)flag completion:(void (^)(void))completion {
-    [self dismissViewControllerAnimated:flag completion:completion];
-}
-#pragma mark - lazy
-
-- (UIView *)containerView {
-    if (_containerView == nil) {
-        _containerView = [[UIView alloc] init];
-        _containerView.layer.cornerRadius = kScale390(12);
-        [self.view addSubview:_containerView];
-    }
-    return _containerView;
-}
-
-- (UIView *)topGestureView {
-    if (_topGestureView == nil) {
-        _topGestureView = [[TUIFloatTitleView alloc] init];
-        //        [_topGestureView addGestureRecognizer:self.panCover];
-        [self.containerView addSubview:_topGestureView];
-    }
-    return _topGestureView;
-}
-
-- (UIPanGestureRecognizer *)panCover {
-    if (_panCover == nil) {
-        _panCover = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(onPanCover:)];
-    }
-    return _panCover;
-}
-
-- (void)onPanCover:(UIPanGestureRecognizer *)pan {
-    CGPoint translation = [pan translationInView:self.topGestureView];
-    CGFloat absX = fabs(translation.x);
-    CGFloat absY = fabs(translation.y);
-
-    if (MAX(absX, absY) < 2) return;
-    if (absX > absY) {
-        if (translation.x < 0) {
-            // scroll left
-        } else {
-            // scroll right
-        }
-    } else if (absY > absX) {
-        if (translation.y < 0) {
-            // scroll up
-            [self.topGestureView removeGestureRecognizer:self.panCover];
-            [UIView animateWithDuration:0.3
-                animations:^{
-                  self.currentLoaction = FLEX_TOP;
-                  [self.topGestureView addGestureRecognizer:self.panCover];
-                }
-                completion:^(BOOL finished) {
-                  if (finished) {
-                      [self updateSubContainerView];
-                  }
-                }];
-        } else {
-            // scroll down
-            if (self.currentLoaction == FLEX_Bottom) {
-                [self dismissViewControllerAnimated:YES completion:nil];
-            }
-            [self.topGestureView removeGestureRecognizer:self.panCover];
-            [UIView animateWithDuration:0.3
-                animations:^{
-                  self.currentLoaction = FLEX_Bottom;
-                  [self.topGestureView addGestureRecognizer:self.panCover];
-                }
-                completion:^(BOOL finished) {
-                  if (finished) {
-                      dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
-                        [self updateSubContainerView];
-                      });
-                  }
-                }];
-        }
-    }
-}
-
-- (void)updateSubContainerView {
-    self.topGestureView.frame = CGRectMake(0, 0, self.containerView.frame.size.width, kScale390(68.5));
-    self.topImgView.frame = CGRectMake((self.topGestureView.frame.size.width - kScale390(24)) * 0.5, kScale390(22), kScale390(24), kScale390(6));
-
-    self.childVC.view.frame = CGRectMake(0, self.topGestureView.frame.origin.y + self.topGestureView.frame.size.height, self.containerView.frame.size.width,
-                                         self.containerView.frame.size.height - self.topGestureView.frame.size.height);
-}
-@end

+ 0 - 21
ThirdParty/TUIKit/TIMCommon/CommonModel/TUIGroupAvatar+Helper.h

@@ -1,21 +0,0 @@
-//
-//  TUIGroupAvatar+Helper.h
-//  TIMCommon
-//
-//  Created by wyl on 2023/4/27.
-//  Copyright © 2023 Tencent. All rights reserved.
-//
-
-#import <TUICore/TUIDefine.h>
-
-NS_ASSUME_NONNULL_BEGIN
-
-@interface TUIGroupAvatar (Helper)
-
-+ (UIImage *)getNormalGroupCacheAvatar:(NSString *)groupID groupType:(NSString *)groupType;
-
-+ (void)configAvatarByParam:(NSDictionary *)param targetView:(UIImageView *)targetView;
-
-@end
-
-NS_ASSUME_NONNULL_END

+ 0 - 125
ThirdParty/TUIKit/TIMCommon/CommonModel/TUIGroupAvatar+Helper.m

@@ -1,125 +0,0 @@
-//
-//  TUIGroupAvatar+Helper.m
-//  TIMCommon
-//
-//  Created by wyl on 2023/4/27.
-//  Copyright © 2023 Tencent. All rights reserved.
-//
-
-#import <TUICore/TUIConfig.h>
-#import "TUIGroupAvatar+Helper.h"
-
-@implementation TUIGroupAvatar (Helper)
-
-+ (UIImage *)getNormalGroupCacheAvatar:(NSString *)groupID groupType:(NSString *)groupType {
-    /**
-     * 
-     * Setup default avatar
-     */
-    UIImage *avatarImage = nil;
-    if (groupID.length > 0) {
-        /**
-         * If it is a group, change the group default avatar to the last used avatar
-         */
-        UIImage *avatar = nil;
-        if (TUIConfig.defaultConfig.enableGroupGridAvatar) {
-            NSString *key = [NSString stringWithFormat:@"TUIConversationLastGroupMember_%@", groupID];
-            NSInteger member = [NSUserDefaults.standardUserDefaults integerForKey:key];
-            avatar = [TUIGroupAvatar getCacheAvatarForGroup:groupID number:(UInt32)member];
-        }
-        avatarImage = avatar ? avatar : DefaultGroupAvatarImageByGroupType(groupType);
-        ;
-        return avatarImage;
-    }
-    return avatarImage;
-}
-+ (void)configAvatarByParam:(NSDictionary *)param targetView:(UIImageView *)targetView {
-    NSString *groupID = param[@"groupID"];
-    NSString *faceUrl = param[@"faceUrl"];
-    NSString *groupType = param[@"groupType"];
-    UIImage *originAvatarImage = param[@"originAvatarImage"];
-    if (groupID.length > 0) {
-        /**
-         * 
-         * Group avatar
-         */
-        if (IS_NOT_EMPTY_NSSTRING(faceUrl)) {
-            /**
-             * 
-             * The group avatar has been manually set externally
-             */
-            [targetView sd_setImageWithURL:[NSURL URLWithString:faceUrl] placeholderImage:originAvatarImage];
-        } else {
-            /**
-             * The group avatar has not been set externally. If the synthetic avatar is allowed, the synthetic avatar will be used; otherwise, the default
-             * avatar will be used.
-             */
-            if (TUIConfig.defaultConfig.enableGroupGridAvatar) {
-                /**
-                 *
-                 * If the synthetic avatar is allowed, the synthetic avatar will be used
-                 * 1. Asynchronously obtain the cached synthetic avatar according to the number of group members
-                 * 2. If the cache is hit, use the cached synthetic avatar directly
-                 * 3. If the cache is not hit, recompose a new avatar
-                 *
-                 * Note:
-                 * 1. Since "asynchronously obtaining cached avatars" and "synthesizing avatars" take a long time, it is easy to cause cell reuse problems, so
-                 * it is necessary to confirm whether to assign values directly according to groupID.
-                 * 2. Use SDWebImage to implement placeholder, because SDWebImage has already dealt with the problem of cell reuse
-                 */
- 
-                // 1. Obtain group avatar from cache
-
-                // fix: The getCacheGroupAvatar needs to request the
-                // network. When the network is disconnected, since the headImageView is not set, the current conversation sends a message, the conversation is
-                // moved up, and the avatar of the first conversation is reused, resulting in confusion of the avatar.
-                [targetView sd_setImageWithURL:nil placeholderImage:originAvatarImage];
-                [TUIGroupAvatar getCacheGroupAvatar:groupID
-                                           callback:^(UIImage *avatar, NSString *groupID) {
-                                             if ([groupID isEqualToString:groupID]) {
-                                                 // 1.1 When the callback is invoked, the cell is not reused
-
-                                                 if (avatar != nil) {
-                                                     // 2. Hit the cache and assign directly
-                                                     [targetView sd_setImageWithURL:nil placeholderImage:avatar];
-                                                 } else {
-                                                     // 3. Synthesize new avatars asynchronously without hitting cache
-
-                                                     [targetView sd_setImageWithURL:nil placeholderImage:originAvatarImage];
-                                                     [TUIGroupAvatar
-                                                         fetchGroupAvatars:groupID
-                                                               placeholder:originAvatarImage
-                                                                  callback:^(BOOL success, UIImage *image, NSString *groupID) {
-                                                                    if ([groupID isEqualToString:groupID]) {
-                                                                        // When the callback is invoked, the cell is not reused
-                                                                        [targetView
-                                                                            sd_setImageWithURL:nil
-                                                                              placeholderImage:success ? image : DefaultGroupAvatarImageByGroupType(groupType)];
-                                                                    } else {
-                                                                        //  callback, When the callback is invoked, the cell has
-                                                                        // been reused to other groupIDs. Since a new callback will be triggered when the new
-                                                                        // groupID synthesizes new avatar, it is ignored here
-                                                                    }
-                                                                  }];
-                                                 }
-                                             } else {
-                                                 // 1.2 callback ,cell  groupID。 groupID 
-                                                 // callback, 1.2 When the callback is invoked, the cell has been reused to other groupIDs. Since a new
-                                                 // callback will be triggered when the new groupID gets the cache, it is ignored here
-                                             }
-                                           }];
-            } else {
-                /**
-                 * Synthetic avatars are not allowed, use the default avatar directly
-                 */
-                [targetView sd_setImageWithURL:nil placeholderImage:originAvatarImage];
-            }
-        }
-    } else {
-        /**
-         * Personal avatar
-         */
-        [targetView sd_setImageWithURL:[NSURL URLWithString:faceUrl] placeholderImage:originAvatarImage];
-    }
-}
-@end

+ 0 - 22
ThirdParty/TUIKit/TIMCommon/CommonModel/TUISecondConfirm.h

@@ -1,22 +0,0 @@
-//
-//  TUISecondConfirm.h
-//  TIMCommon
-//
-//  Created by xiangzhang on 2023/5/15.
-//  Copyright © 2023 Tencent. All rights reserved.
-//
-
-#import <UIKit/UIKit.h>
-
-NS_ASSUME_NONNULL_BEGIN
-typedef void (^TUISecondConfirmBtnClickCallback)(void);
-@interface TUISecondConfirmBtnInfo : NSObject
-@property(nonatomic, strong) NSString *tile;
-@property(nonatomic, copy) TUISecondConfirmBtnClickCallback click;
-@end
-
-@interface TUISecondConfirm : NSObject
-+ (void)show:(NSString *)title cancelBtnInfo:(TUISecondConfirmBtnInfo *)cancelBtnInfo confirmBtnInfo:(TUISecondConfirmBtnInfo *)confirmBtnInfo;
-@end
-
-NS_ASSUME_NONNULL_END

+ 0 - 105
ThirdParty/TUIKit/TIMCommon/CommonModel/TUISecondConfirm.m

@@ -1,105 +0,0 @@
-//
-//  TUISecondConfirm.m
-//  TIMCommon
-//
-//  Created by xiangzhang on 2023/5/15.
-//  Copyright © 2023 Tencent. All rights reserved.
-//
-
-#import "TUISecondConfirm.h"
-#import <TUICore/TUIDefine.h>
-#import <TUICore/UIView+TUILayout.h>
-
-@implementation TUISecondConfirmBtnInfo
-
-@end
-
-static UIWindow *gSecondWindow = nil;
-static TUISecondConfirmBtnInfo *gCancelBtnInfo = nil;
-static TUISecondConfirmBtnInfo *gConfirmBtnInfo = nil;
-
-@implementation TUISecondConfirm
-
-+ (void)show:(NSString *)title cancelBtnInfo:(TUISecondConfirmBtnInfo *)cancelBtnInfo confirmBtnInfo:(TUISecondConfirmBtnInfo *)confirmBtnInfo {
-    gCancelBtnInfo = cancelBtnInfo;
-    gConfirmBtnInfo = confirmBtnInfo;
-
-    gSecondWindow = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
-    gSecondWindow.windowLevel = UIWindowLevelAlert - 1;
-    gSecondWindow.backgroundColor = [UIColor clearColor];
-    gSecondWindow.hidden = NO;
-
-    if (@available(iOS 13.0, *)) {
-        for (UIWindowScene *windowScene in [UIApplication sharedApplication].connectedScenes) {
-            if (windowScene.activationState == UISceneActivationStateForegroundActive) {
-                gSecondWindow.windowScene = windowScene;
-                break;
-            }
-        }
-    }
-
-    UIView *backgroupView = [[UIView alloc] initWithFrame:gSecondWindow.bounds];
-    backgroupView.backgroundColor = RGBA(0, 0, 0, 0.4);
-    [gSecondWindow addSubview:backgroupView];
-
-    UIView *confimView = [[UIView alloc] init];
-    confimView.backgroundColor = TIMCommonDynamicColor(@"second_confirm_bg_color", @"#FFFFFF");
-    confimView.layer.cornerRadius = 13;
-    confimView.layer.masksToBounds = YES;
-    [gSecondWindow addSubview:confimView];
-    confimView.mm_width(gSecondWindow.mm_w - kScale375(32) * 2).mm_height(183).mm__centerX(gSecondWindow.mm_centerX).mm__centerY(gSecondWindow.mm_h / 2);
-
-    UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, confimView.mm_w, 123)];
-    titleLabel.text = title;
-    titleLabel.textColor = TIMCommonDynamicColor(@"second_confirm_title_color", @"#000000");
-    titleLabel.textAlignment = NSTextAlignmentCenter;
-    titleLabel.font = [UIFont systemFontOfSize:16];
-    titleLabel.numberOfLines = 0;
-    [confimView addSubview:titleLabel];
-
-    UIView *line1 = [[UIView alloc] initWithFrame:CGRectMake(0, titleLabel.mm_maxY, titleLabel.mm_w, 0.5)];
-    line1.backgroundColor = TIMCommonDynamicColor(@"second_confirm_line_color", @"#DDDDDD");
-    [confimView addSubview:line1];
-
-    UIButton *cancelBtn = [UIButton buttonWithType:UIButtonTypeCustom];
-    [cancelBtn setFrame:CGRectMake(0, line1.mm_maxY, line1.mm_w / 2, confimView.mm_h - line1.mm_maxY)];
-    [cancelBtn setTitle:gCancelBtnInfo.tile forState:UIControlStateNormal];
-    [cancelBtn.titleLabel setFont:[UIFont systemFontOfSize:16]];
-    [cancelBtn setTitleColor:TIMCommonDynamicColor(@"second_confirm_cancel_btn_title_color", @"#000000") forState:UIControlStateNormal];
-    [cancelBtn addTarget:self action:@selector(onCancelBtnClick) forControlEvents:UIControlEventTouchUpInside];
-    [confimView addSubview:cancelBtn];
-
-    UIView *line2 = [[UIView alloc] initWithFrame:CGRectMake(cancelBtn.mm_maxX, cancelBtn.mm_y, 0.5, cancelBtn.mm_h)];
-    line2.backgroundColor = TIMCommonDynamicColor(@"second_confirm_line_color", @"#DDDDDD");
-    [confimView addSubview:line2];
-
-    UIButton *confirmBtn = [UIButton buttonWithType:UIButtonTypeCustom];
-    [confirmBtn setFrame:CGRectMake(line2.mm_maxX, cancelBtn.mm_y, cancelBtn.mm_w, cancelBtn.mm_h)];
-    [confirmBtn setTitle:gConfirmBtnInfo.tile forState:UIControlStateNormal];
-    [confirmBtn.titleLabel setFont:[UIFont systemFontOfSize:16]];
-    [confirmBtn setTitleColor:TIMCommonDynamicColor(@"second_confirm_confirm_btn_title_color", @"#FF584C") forState:UIControlStateNormal];
-    [confirmBtn addTarget:self action:@selector(onConfirmBtnBtnClick) forControlEvents:UIControlEventTouchUpInside];
-    [confimView addSubview:confirmBtn];
-}
-
-+ (void)onCancelBtnClick {
-    if (gCancelBtnInfo && gCancelBtnInfo.click) {
-        gCancelBtnInfo.click();
-    }
-    [self dismiss];
-}
-
-+ (void)onConfirmBtnBtnClick {
-    if (gConfirmBtnInfo && gConfirmBtnInfo.click) {
-        gConfirmBtnInfo.click();
-    }
-    [self dismiss];
-}
-
-+ (void)dismiss {
-    gSecondWindow = nil;
-    gCancelBtnInfo = nil;
-    gConfirmBtnInfo = nil;
-}
-
-@end

+ 0 - 25
ThirdParty/TUIKit/TIMCommon/CommonModel/TUITextView.h

@@ -1,25 +0,0 @@
-//
-//  TUITextView.h
-//  Masonry
-//
-//  Created by xiangzhang on 2022/10/14.
-//  Copyright © 2023 Tencent. All rights reserved.
-//
-
-#import <UIKit/UIKit.h>
-
-NS_ASSUME_NONNULL_BEGIN
-
-@protocol TUITextViewDelegate <NSObject>
-- (void)onLongPressTextViewMessage:(UITextView *)textView;
-@end
-
-@interface TUITextView : UITextView
-@property (nonatomic, strong) UILongPressGestureRecognizer *longPressGesture;
-@property (nonatomic, weak) id<TUITextViewDelegate> tuiTextViewDelegate;
-
-- (void)disableHighlightLink;
-
-@end
-
-NS_ASSUME_NONNULL_END

+ 0 - 65
ThirdParty/TUIKit/TIMCommon/CommonModel/TUITextView.m

@@ -1,65 +0,0 @@
-//
-//  TUITextView.m
-//  Masonry
-//
-//  Created by xiangzhang on 2022/10/14.
-//  Copyright © 2023 Tencent. All rights reserved.
-//
-
-#import "TUITextView.h"
-#import <TUICore/TUIThemeManager.h>
-
-@implementation TUITextView
-
-- (instancetype)init {
-    self = [super init];
-    if (self) {
-        self.dataDetectorTypes = UIDataDetectorTypeLink | UIDataDetectorTypePhoneNumber;
-        [self setupLongPressGesture];
-        self.tintColor = TIMCommonDynamicColor(@"chat_highlight_link_color", @"#6495ED");
-    }
-    return self;
-}
-
-- (BOOL)canBecomeFirstResponder {
-    return YES;
-}
-
-- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
-    return NO;
-}
-
-- (void)buildMenuWithBuilder:(id<UIMenuBuilder>)builder API_AVAILABLE(ios(13.0)) {
-    if (@available(iOS 16.0, *)) {
-        [builder removeMenuForIdentifier:UIMenuLookup];
-    }
-    [super buildMenuWithBuilder:builder];
-}
-
-- (void)disableHighlightLink {
-    self.dataDetectorTypes = UIDataDetectorTypeNone;
-}
-
-- (void)setupLongPressGesture {
-    self.longPressGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongPress:)];
-    [self addGestureRecognizer:self.longPressGesture];
-}
-
-- (void)handleLongPress:(UILongPressGestureRecognizer *)gesture {
-    if ([gesture isKindOfClass:[UILongPressGestureRecognizer class]] && gesture.state == UIGestureRecognizerStateBegan) {
-        if (self.tuiTextViewDelegate && [self.tuiTextViewDelegate respondsToSelector:@selector(onLongPressTextViewMessage:)]) {
-            [self.tuiTextViewDelegate onLongPressTextViewMessage:self];
-        }
-    }
-}
-
-- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
-shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
-    if ([gestureRecognizer isKindOfClass:[UILongPressGestureRecognizer class]] &&
-        gestureRecognizer != self.longPressGesture) {
-        return NO;
-    }
-    return YES;
-}
-
-@end

+ 0 - 25
ThirdParty/TUIKit/TIMCommon/CommonModel/TUIUserAuthorizationCenter.h

@@ -1,25 +0,0 @@
-//
-//  TUIUserAuthorizationCenter.h
-//  TUIChat
-//
-//  Created by wyl on 2022/2/16.
-//  Copyright © 2023 Tencent. All rights reserved.
-//
-
-#import <Foundation/Foundation.h>
-
-typedef NS_OPTIONS(NSUInteger, TUIChatAuthControlType) {
-    TUIChatAuthControlTypeMicro = 1 << 0,
-    TUIChatAuthControlTypeCamera = 1 << 1,
-    TUIChatAuthControlTypePhoto = 1 << 2,
-};
-@interface TUIUserAuthorizationCenter : NSObject
-@property(nonatomic, assign, class, readonly) BOOL isEnableCameraAuthorization;
-@property(nonatomic, assign, class, readonly) BOOL isEnableMicroAuthorization;
-
-+ (void)cameraStateActionWithPopCompletion:(void (^)(void))completion API_AVAILABLE(ios(8.0));
-+ (void)microStateActionWithPopCompletion:(void (^)(void))completion API_AVAILABLE(ios(8.0));
-
-+ (void)openSettingPage;
-+ (void)showAlert:(TUIChatAuthControlType)type;
-@end

+ 0 - 136
ThirdParty/TUIKit/TIMCommon/CommonModel/TUIUserAuthorizationCenter.m

@@ -1,136 +0,0 @@
-//
-//  TUIUserAuthorizationCenter.m
-//  TUIChat
-//
-//  Created by wyl on 2022/2/16.
-//  Copyright © 2023 Tencent. All rights reserved.
-//
-
-#import "TUIUserAuthorizationCenter.h"
-#import <AVFoundation/AVCaptureDevice.h>
-#import <CoreLocation/CLLocationManager.h>
-#import <CoreMotion/CoreMotion.h>
-#import <EventKit/EventKit.h>
-#import <Photos/Photos.h>
-#import <Speech/Speech.h>
-#import <TIMCommon/TIMDefine.h>
-#import <UserNotifications/UserNotifications.h>
-
-#import <TUICore/TUIGlobalization.h>
-@implementation TUIUserAuthorizationCenter
-
-+ (BOOL)isEnableCameraAuthorization {
-    if (@available(iOS 7.0, *)) {
-        return [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo] == AVAuthorizationStatusAuthorized;
-    } else {
-        return YES;
-    }
-}
-
-+ (void)cameraStateActionWithPopCompletion:(void (^)(void))completion {
-    if ([AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo] == AVAuthorizationStatusNotDetermined) {
-        [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo
-                                 completionHandler:^(BOOL granted) {
-                                   if (granted && completion) {
-                                       completion();
-                                   }
-                                 }];
-    } else {
-        [self showAlert:TUIChatAuthControlTypeCamera];
-    }
-}
-
-+ (void)openSettingPage {
-    if (@available(iOS 8.0, *)) {
-        NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
-        if ([[UIApplication sharedApplication] canOpenURL:url]) {
-            if (@available(iOS 10.0, *)) {
-                [[UIApplication sharedApplication] openURL:url options:@{} completionHandler:nil];
-            } else {
-                [[UIApplication sharedApplication] openURL:url];
-            }
-        }
-    } else {
-        // Fallback on earlier versions
-    }
-}
-
-+ (BOOL)isEnableMicroAuthorization {
-    if (@available(iOS 7.0, *)) {
-        return [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeAudio] == AVAuthorizationStatusAuthorized;
-    } else {
-        return YES;
-    }
-}
-
-+ (void)microStateActionWithPopCompletion:(void (^)(void))completion {
-#if !TARGET_OS_MACCATALYST
-    if ([AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeAudio] == AVAuthorizationStatusNotDetermined) {
-        [AVCaptureDevice requestAccessForMediaType:AVMediaTypeAudio
-                                 completionHandler:^(BOOL granted) {
-                                   if (granted && completion) {
-                                       completion();
-                                   }
-                                 }];
-    } else {
-        [self showAlert:TUIChatAuthControlTypeMicro];
-    }
-#endif
-}
-
-+ (BOOL)isEnableLocationAuthorization {
-    CLAuthorizationStatus status = [CLLocationManager authorizationStatus];
-    if (@available(iOS 8.0, *)) {
-        return status == kCLAuthorizationStatusAuthorizedAlways || status == kCLAuthorizationStatusAuthorizedWhenInUse;
-    } else {
-        // Fallback on earlier versions
-        return YES;
-    }
-}
-
-+ (void)showAlert:(TUIChatAuthControlType)type {
-    NSString *title = @"";
-    NSString *message = @"";
-    NSString *laterMessage = @"";
-    NSString *openSettingMessage = @"";
-
-    if (TUIChatAuthControlTypeMicro == type) {
-        title = TIMCommonLocalizableString(TUIKitInputNoMicTitle);
-        message = TIMCommonLocalizableString(TUIKitInputNoMicTips);
-        laterMessage = TIMCommonLocalizableString(TUIKitInputNoMicOperateLater);
-        openSettingMessage = TIMCommonLocalizableString(TUIKitInputNoMicOperateEnable);
-    } else if (TUIChatAuthControlTypeCamera == type) {
-        title = TIMCommonLocalizableString(TUIKitInputNoCameraTitle);
-        message = TIMCommonLocalizableString(TUIKitInputNoCameraTips);
-        laterMessage = TIMCommonLocalizableString(TUIKitInputNoCameraOperateLater);
-        openSettingMessage = TIMCommonLocalizableString(TUIKitInputNoCameraOperateEnable);
-    } else if (TUIChatAuthControlTypePhoto == type) {
-        title = TIMCommonLocalizableString(TUIKitInputNoPhotoTitle);
-        message = TIMCommonLocalizableString(TUIKitInputNoPhotoTips);
-        laterMessage = TIMCommonLocalizableString(TUIKitInputNoPhotoOperateLater);
-        openSettingMessage = TIMCommonLocalizableString(TUIKitInputNoPhotoerateEnable);
-    } else {
-        return;
-    }
-    if (@available(iOS 8.0, *)) {
-        UIAlertController *ac = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert];
-        [ac tuitheme_addAction:[UIAlertAction actionWithTitle:laterMessage style:UIAlertActionStyleCancel handler:nil]];
-        [ac tuitheme_addAction:[UIAlertAction actionWithTitle:openSettingMessage
-                                                        style:UIAlertActionStyleDefault
-                                                      handler:^(UIAlertAction *_Nonnull action) {
-                                                        UIApplication *app = [UIApplication sharedApplication];
-                                                        NSURL *settingsURL = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
-                                                        if ([app canOpenURL:settingsURL]) {
-                                                            [app openURL:settingsURL];
-                                                        }
-                                                      }]];
-        dispatch_async(dispatch_get_main_queue(), ^{
-          [UIApplication.sharedApplication.keyWindow.rootViewController presentViewController:ac animated:YES completion:nil];
-          //        [self presentViewController:ac animated:YES completion:nil];
-        });
-    } else {
-        // Fallback on earlier versions
-    }
-}
-
-@end

+ 0 - 12
ThirdParty/TUIKit/TIMCommon/Resources/TIMCommon_Minimalist.bundle/dark/manifest.plist

@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
-	<key>id</key>
-	<string>dark</string>
-	<key>name</key>
-	<string>黑夜</string>
-	<key>name_en</key>
-	<string>Dark</string>
-</dict>
-</plist>

+ 0 - 12
ThirdParty/TUIKit/TIMCommon/Resources/TIMCommon_Minimalist.bundle/light/manifest.plist

@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
-	<key>id</key>
-	<string>light</string>
-	<key>name</key>
-	<string>轻量</string>
-	<key>name_en</key>
-	<string>Light</string>
-</dict>
-</plist>

+ 0 - 12
ThirdParty/TUIKit/TIMCommon/Resources/TIMCommon_Minimalist.bundle/lively/manifest.plist

@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
-	<key>id</key>
-	<string>lively</string>
-	<key>name</key>
-	<string>活泼</string>
-	<key>name_en</key>
-	<string>Lively</string>
-</dict>
-</plist>

+ 0 - 12
ThirdParty/TUIKit/TIMCommon/Resources/TIMCommon_Minimalist.bundle/serious/manifest.plist

@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
-	<key>id</key>
-	<string>serious</string>
-	<key>name</key>
-	<string>严肃</string>
-	<key>name_en</key>
-	<string>Business</string>
-</dict>
-</plist>

+ 0 - 2
ThirdParty/TUIKit/TIMCommon/TIMCommon.podspec

@@ -13,9 +13,7 @@ Pod::Spec.new do |spec|
   spec.authors      = 'tencent video cloud'
   spec.summary      = 'TIMCommon'
   spec.dependency 'TUICore'
-  spec.dependency 'SDWebImage'
   spec.dependency 'ReactiveObjC'
-  spec.dependency 'Masonry'
   spec.requires_arc = true
 
   spec.source = { :git => 'https://git.woa.com/lynxzhang/tui-components.git', :tag => spec.version}

+ 0 - 96
ThirdParty/TUIKit/TIMCommon/UI_Classic/TUIBubbleMessageCell.h

@@ -1,96 +0,0 @@
-
-//  Created by Tencent on 2023/06/09.
-//  Copyright © 2023 Tencent. All rights reserved.
-/**
- *  This document declares the TUIBubbleMessageCell class.
- *  Bubble messages, the most common type of messages that contain strings and emoticons.
- *  Both TUIFileMessageCell and TUIVoiceMessageCell inherit from this class and implement the userinterface of bubble messages.
- *  If developers want to customize the bubble message, they can also refer to the implementation methods of the above two message units to implement their own
- * bubble message unit.
- */
-#import "TUIBubbleMessageCellData.h"
-#import "TUIMessageCell.h"
-NS_ASSUME_NONNULL_BEGIN
-
-@interface TUIBubbleMessageCell : TUIMessageCell
-
-/**
- *  The bubble image view, the message's bubble icon, wraps the message's content on the UI as a background panel for the bubble.
- */
-@property(nonatomic, strong) UIImageView *bubbleView;
-
-@property TUIBubbleMessageCellData *bubbleData;
-
-- (void)fillWithData:(TUIBubbleMessageCellData *)data;
-
-+ (CGFloat)getBubbleTop:(TUIBubbleMessageCellData *)data;
-
-- (UIImage *)getBubble;
-
-- (UIImage *)getErrorBubble;
-
-@end
-
-
-#pragma mark - TUILayoutConfiguration
-
-@interface TUIBubbleMessageCell (TUILayoutConfiguration)
-
-/**
- *  Send bubble icon (normal state)
- *  - The send icon of the bubble, assigned to the @bubble when the bubble message was sent.
- */
-@property(nonatomic, class) UIImage *outgoingBubble;
-
-/**
- *  Send bubble icon (highlighted state)
- *  - The send icon (highlighted state) of the bubble, assigned to @highlightedBubble when the bubble message was sent.
- */
-@property(nonatomic, class) UIImage *outgoingHighlightedBubble;
-
-@property(nonatomic, class) UIImage *outgoingErrorBubble;
-
-/**
- * 
- * Send bubble icon (highlighted state)
- */
-@property(nonatomic, class) UIImage *outgoingAnimatedHighlightedAlpha20;
-@property(nonatomic, class) UIImage *outgoingAnimatedHighlightedAlpha50;
-
-/**
- *  Receive bubble icon (normal state)
- *  - The receive icon of the bubble, assigned to the @bubble when the bubble message was received.
- */
-@property(nonatomic, class) UIImage *incommingBubble;
-
-/**
- *  Receive bubble icon (highlighted state)
- *  - The receive icon of the bubble, assigned to @highlightedBubble when the bubble message was received.
- */
-@property(nonatomic, class) UIImage *incommingHighlightedBubble;
-
-@property(nonatomic, class) UIImage *incommingErrorBubble;
-
-/**
- * Receive bubble icon (highlighted state)
- */
-@property(nonatomic, class) UIImage *incommingAnimatedHighlightedAlpha20;
-@property(nonatomic, class) UIImage *incommingAnimatedHighlightedAlpha50;
-
-
-/**
- *  Spacing at the top of the send bubble
- *  - It is used to locate the top of the sent bubble, and is assigned to @bubbleTop when the bubble message was sent.
- */
-@property(nonatomic, class) CGFloat outgoingBubbleTop;
-
-/**
- *  Spacing at the top of the receiving bubble
- *  - It is used to locate the top of the receive bubble, and is assigned to @bubbleTop when the bubble message was
- * received.
- */
-@property(nonatomic, class) CGFloat incommingBubbleTop;
-
-@end
-
-NS_ASSUME_NONNULL_END

+ 0 - 354
ThirdParty/TUIKit/TIMCommon/UI_Classic/TUIBubbleMessageCell.m

@@ -1,354 +0,0 @@
-//
-//  TBubbleMessageCell.m
-//  TXIMSDK_TUIKit_iOS
-//
-//  Created by annidyfeng on 2019/5/22.
-//  Copyright © 2023 Tencent. All rights reserved.
-//
-
-#import "TUIBubbleMessageCell.h"
-#import <TIMCommon/TIMCommonModel.h>
-#import <TIMCommon/TIMDefine.h>
-#import <TUICore/TUICore.h>
-
-@implementation TUIBubbleMessageCell
-
-- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
-    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
-    if (self) {
-        _bubbleView = [[UIImageView alloc] initWithFrame:self.container.bounds];
-        _bubbleView.userInteractionEnabled = YES;
-        [self.container addSubview:_bubbleView];
-        _bubbleView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
-        self.securityStrikeView = [[TUISecurityStrikeView alloc] init];
-        [self.bubbleView addSubview:self.securityStrikeView];
-
-    }
-    return self;
-}
-
-- (void)fillWithData:(TUIBubbleMessageCellData *)data {
-    [super fillWithData:data];
-    self.bubbleData = data;
-    self.bubbleView.image = self.getBubble;
-    self.bubbleView.highlightedImage = self.getHighlightBubble;
-    self.securityStrikeView.hidden = YES;
-    BOOL hasRiskContent = self.messageData.innerMessage.hasRiskContent;
-    if (hasRiskContent) {
-        self.bubbleView.image =  [self getErrorBubble];
-        self.securityStrikeView.hidden = NO;
-    }
-    
-    [self prepareReactTagUI:self.container];
-    // tell constraints they need updating
-    [self setNeedsUpdateConstraints];
-
-    // update constraints now so we can animate the change
-    [self updateConstraintsIfNeeded];
-
-    [self layoutIfNeeded];
-
-}
-
-+ (BOOL)requiresConstraintBasedLayout {
-    return YES;
-}
-
-// this is Apple's recommended place for adding/updating constraints
-- (void)updateConstraints {
-
-    [super updateConstraints];
-    [self.bubbleView mas_remakeConstraints:^(MASConstraintMaker *make) {
-        make.leading.mas_equalTo(0);
-        make.size.mas_equalTo(self.container);
-        make.top.mas_equalTo(self.container);
-    }];
-    
-    CGPoint center = self.retryView.center;
-    center.y = self.bubbleView.center.y;
-    self.retryView.center = center;
-    
-}
-
-- (void)layoutSubviews {
-    [super layoutSubviews];
-}
-
-- (void)highlightWhenMatchKeyword:(NSString *)keyword {
-    /**
-     * The parent class implements the default highlighting effect - flickering
-     */
-    if (keyword) {
-        if (self.highlightAnimating) {
-            return;
-        }
-        [self animate:3];
-    }
-}
-
-- (void)animate:(int)times {
-    times--;
-    if (times < 0) {
-        self.bubbleView.image = self.getBubble;
-        self.highlightAnimating = NO;
-        return;
-    }
-    self.highlightAnimating = YES;
-    self.bubbleView.image = self.getAnimateHighlightBubble_alpha50;
-    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.25 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
-      self.bubbleView.image = self.getAnimateHighlightBubble_alpha20;
-      dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.25 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
-        if (!self.bubbleData.highlightKeyword) {
-            [self animate:0];
-            return;
-        }
-        [self animate:times];
-      });
-    });
-}
-
-- (CGFloat)getBubbleTop {
-    return [self.class getBubbleTop:self.bubbleData];
-}
-
-- (UIImage *)getBubble {
-    if (!TIMConfig.defaultConfig.enableMessageBubble) {
-        return nil;
-    }
-    if (self.bubbleData.direction == MsgDirectionIncoming) {
-        return self.class.incommingBubble;
-    } else {
-        return self.class.outgoingBubble;
-    }
-}
-
-- (UIImage *)getHighlightBubble {
-    if (!TIMConfig.defaultConfig.enableMessageBubble) {
-        return nil;
-    }
-    if (self.bubbleData.direction == MsgDirectionIncoming) {
-        return self.class.incommingHighlightedBubble;
-    } else {
-        return self.class.outgoingHighlightedBubble;
-    }
-}
-
-- (UIImage *)getErrorBubble {
-    if (self.bubbleData.direction == MsgDirectionIncoming) {
-        return self.class.incommingErrorBubble;
-    } else {
-        return self.class.outgoingErrorBubble;
-    }
-}
-
-- (UIImage *)getAnimateHighlightBubble_alpha50 {
-    if (!TIMConfig.defaultConfig.enableMessageBubble) {
-        return nil;
-    }
-    if (self.bubbleData.direction == MsgDirectionIncoming) {
-        return self.class.incommingAnimatedHighlightedAlpha50;
-    } else {
-        return self.class.outgoingAnimatedHighlightedAlpha50;
-    }
-}
-
-- (UIImage *)getAnimateHighlightBubble_alpha20 {
-    if (!TIMConfig.defaultConfig.enableMessageBubble) {
-        return nil;
-    }
-    if (self.bubbleData.direction == MsgDirectionIncoming) {
-        return self.class.incommingAnimatedHighlightedAlpha20;
-    } else {
-        return self.class.outgoingAnimatedHighlightedAlpha20;
-    }
-}
-
-- (void)prepareReactTagUI:(UIView *)containerView {
-    NSDictionary *param = @{TUICore_TUIChatExtension_ChatMessageReactPreview_Delegate: self};
-    [TUICore raiseExtension:TUICore_TUIChatExtension_ChatMessageReactPreview_ClassicExtensionID parentView:containerView param:param];
-}
-
-+ (CGFloat)getBubbleTop:(TUIBubbleMessageCellData *)data {
-    if (data.direction == MsgDirectionIncoming) {
-        return self.class.incommingBubbleTop;
-    } else {
-        return self.class.outgoingBubbleTop;
-    }
-}
-
-@end
-
-
-@implementation TUIBubbleMessageCell (TUILayoutConfiguration)
-
-+ (void)initialize {
-    [NSNotificationCenter.defaultCenter addObserver:self selector:@selector(onThemeChanged:) name:TUIDidApplyingThemeChangedNotfication object:nil];
-}
-
-
-#pragma mark - outgoing Bubble
-static UIImage *gOutgoingBubble;
-+ (UIImage *)outgoingBubble {
-    if (!gOutgoingBubble) {
-        UIImage *defaultImage = [[TUIImageCache sharedInstance] getResourceFromCache:TUIChatImagePath(@"SenderTextNodeBkg")];
-        [self setOutgoingBubble:TUIChatDynamicImage(@"chat_bubble_send_img", defaultImage)];
-    }
-    return gOutgoingBubble;
-}
-
-+ (void)setOutgoingBubble:(UIImage *)outgoingBubble {
-    gOutgoingBubble = [self stretchImage:outgoingBubble];
-}
-
-static UIImage *gOutgoingHighlightedBubble;
-+ (UIImage *)outgoingHighlightedBubble {
-    if (!gOutgoingHighlightedBubble) {
-        UIImage *defaultImage = [[TUIImageCache sharedInstance] getResourceFromCache:TUIChatImagePath(@"SenderTextNodeBkgHL")];
-        [self setOutgoingHighlightedBubble:TUIChatDynamicImage(@"chat_bubble_send_img", defaultImage)];
-    }
-    return gOutgoingHighlightedBubble;
-}
-
-+ (void)setOutgoingHighlightedBubble:(UIImage *)outgoingHighlightedBubble {
-    gOutgoingHighlightedBubble = [self stretchImage:outgoingHighlightedBubble];
-}
-
-static UIImage *gOutgoingAnimatedHighlightedAlpha50;
-+ (UIImage *)outgoingAnimatedHighlightedAlpha50 {
-    if (!gOutgoingAnimatedHighlightedAlpha50) {
-        UIImage *alpha50 = [[TUIImageCache sharedInstance] getResourceFromCache:TUIChatImagePath(@"SenderTextNodeBkg_alpha50")];
-        [self setOutgoingAnimatedHighlightedAlpha50:TUIChatDynamicImage(@"chat_bubble_send_alpha50_img", alpha50)];
-    }
-    return gOutgoingAnimatedHighlightedAlpha50;
-}
-
-+ (void)setOutgoingAnimatedHighlightedAlpha50:(UIImage *)outgoingAnimatedHighlightedAlpha50 {
-    gOutgoingAnimatedHighlightedAlpha50 = [self stretchImage:outgoingAnimatedHighlightedAlpha50];
-}
-
-static UIImage *gOutgoingAnimatedHighlightedAlpha20;
-+ (UIImage *)outgoingAnimatedHighlightedAlpha20 {
-    if (!gOutgoingAnimatedHighlightedAlpha20) {
-        UIImage *alpha20 = [[TUIImageCache sharedInstance] getResourceFromCache:TUIChatImagePath(@"SenderTextNodeBkg_alpha20")];
-        [self setOutgoingAnimatedHighlightedAlpha20:TUIChatDynamicImage(@"chat_bubble_send_alpha20_img", alpha20)];
-    }
-    return gOutgoingAnimatedHighlightedAlpha20;
-}
-
-+ (void)setOutgoingAnimatedHighlightedAlpha20:(UIImage *)outgoingAnimatedHighlightedAlpha20 {
-    gOutgoingAnimatedHighlightedAlpha20 = [self stretchImage:outgoingAnimatedHighlightedAlpha20];
-}
-
-static UIImage *gOutgoingErrorBubble;
-+ (UIImage *)outgoingErrorBubble {
-    if (!gOutgoingErrorBubble) {
-        UIImage *defaultImage = [[TUIImageCache sharedInstance] getResourceFromCache:TUIChatImagePath(@"SenderTextNodeBkg")];
-        UIImage *formatImage = TUIChatDynamicImage(@"chat_bubble_send_img", defaultImage);
-        formatImage = [TUISecurityStrikeView changeImageColorWith:[UIColor tui_colorWithHex:@"#FA5151" alpha:0.16] image:formatImage alpha:1];
-        gOutgoingErrorBubble = [self stretchImage:formatImage];
-    }
-    return gOutgoingErrorBubble;
-}
-
-#pragma mark - incomming Bubble
-static UIImage *gIncommingBubble;
-+ (UIImage *)incommingBubble {
-    if (!gIncommingBubble) {
-        UIImage *defaultImage = [[TUIImageCache sharedInstance] getResourceFromCache:TUIChatImagePath(@"ReceiverTextNodeBkg")];
-        [self setIncommingBubble:TUIChatDynamicImage(@"chat_bubble_receive_img", defaultImage)];
-    }
-    return gIncommingBubble;
-}
-
-+ (void)setIncommingBubble:(UIImage *)incommingBubble {
-    gIncommingBubble = [self stretchImage:incommingBubble];
-}
-
-static UIImage *gIncommingHighlightedBubble;
-+ (UIImage *)incommingHighlightedBubble {
-    if (!gIncommingHighlightedBubble) {
-        UIImage *defaultImage = [[TUIImageCache sharedInstance] getResourceFromCache:TUIChatImagePath(@"ReceiverTextNodeBkgHL")];
-        [self setIncommingHighlightedBubble:TUIChatDynamicImage(@"chat_bubble_receive_img", defaultImage)];
-    }
-    return gIncommingHighlightedBubble;
-}
-
-+ (void)setIncommingHighlightedBubble:(UIImage *)incommingHighlightedBubble {
-    gIncommingHighlightedBubble = [self stretchImage:incommingHighlightedBubble];
-}
-
-static UIImage *gIncommingAnimatedHighlightedAlpha50;
-+ (UIImage *)incommingAnimatedHighlightedAlpha50 {
-    if (!gIncommingAnimatedHighlightedAlpha50) {
-        UIImage *alpha50 = [[TUIImageCache sharedInstance] getResourceFromCache:TUIChatImagePath(@"ReceiverTextNodeBkg_alpha50")];
-        [self setIncommingAnimatedHighlightedAlpha50:TUIChatDynamicImage(@"chat_bubble_receive_alpha50_img", alpha50)];
-    }
-    return gIncommingAnimatedHighlightedAlpha50;
-}
-
-+ (void)setIncommingAnimatedHighlightedAlpha50:(UIImage *)incommingAnimatedHighlightedAlpha50 {
-    gIncommingAnimatedHighlightedAlpha50 = [self stretchImage:incommingAnimatedHighlightedAlpha50];
-}
-
-static UIImage *gIncommingAnimatedHighlightedAlpha20;
-+ (UIImage *)incommingAnimatedHighlightedAlpha20 {
-    if (!gIncommingAnimatedHighlightedAlpha20) {
-        UIImage *alpha20 = [[TUIImageCache sharedInstance] getResourceFromCache:TUIChatImagePath(@"ReceiverTextNodeBkg_alpha20")];
-        [self setIncommingAnimatedHighlightedAlpha20:TUIChatDynamicImage(@"chat_bubble_receive_alpha20_img", alpha20)];
-    }
-    return gIncommingAnimatedHighlightedAlpha20;
-}
-
-+ (void)setIncommingAnimatedHighlightedAlpha20:(UIImage *)incommingAnimatedHighlightedAlpha20 {
-    gIncommingAnimatedHighlightedAlpha20 = [self stretchImage:incommingAnimatedHighlightedAlpha20];
-}
-
-static UIImage *gIncommingErrorBubble;
-+ (UIImage *)incommingErrorBubble {
-    if (!gIncommingErrorBubble) {
-        UIImage *defaultImage = [[TUIImageCache sharedInstance] getResourceFromCache:TUIChatImagePath(@"ReceiverTextNodeBkg")];
-        UIImage *formatImage = TUIChatDynamicImage(@"chat_bubble_receive_img", defaultImage);
-        formatImage = [TUISecurityStrikeView changeImageColorWith:[UIColor tui_colorWithHex:@"#FA5151" alpha:0.16] image:formatImage alpha:1];
-        gIncommingErrorBubble = [self stretchImage:formatImage];
-    }
-    return gIncommingErrorBubble;
-}
-
-+ (UIImage *)stretchImage:(UIImage *)oldImage {
-    UIImage *image = [oldImage rtl_imageFlippedForRightToLeftLayoutDirection];
-    UIEdgeInsets insets = rtlEdgeInsetsWithInsets(UIEdgeInsetsFromString(@"{12,12,12,12}"));
-    return [image resizableImageWithCapInsets:insets resizingMode:UIImageResizingModeStretch];
-}
-
-static CGFloat gOutgoingBubbleTop = 0;
-+ (CGFloat)outgoingBubbleTop {
-    return gOutgoingBubbleTop;
-}
-
-+ (void)setOutgoingBubbleTop:(CGFloat)outgoingBubble {
-    gOutgoingBubbleTop = outgoingBubble;
-}
-
-static CGFloat gIncommingBubbleTop = 0;
-+ (CGFloat)incommingBubbleTop {
-    return gIncommingBubbleTop;
-}
-
-+ (void)setIncommingBubbleTop:(CGFloat)incommingBubbleTop {
-    gIncommingBubbleTop = incommingBubbleTop;
-}
-
-
-+ (void)onThemeChanged:(NSNotification *)notice {
-    gOutgoingBubble = nil;
-    gOutgoingHighlightedBubble = nil;
-    gOutgoingAnimatedHighlightedAlpha50 = nil;
-    gOutgoingAnimatedHighlightedAlpha20 = nil;
-
-    gIncommingBubble = nil;
-    gIncommingHighlightedBubble = nil;
-    gIncommingAnimatedHighlightedAlpha50 = nil;
-    gIncommingAnimatedHighlightedAlpha20 = nil;
-}
-
-@end

+ 0 - 37
ThirdParty/TUIKit/TIMCommon/UI_Classic/TUICommonGroupInfoCellData.h

@@ -1,37 +0,0 @@
-//
-//  TUICommonGroupInfoCellData.h
-//  TIMCommon
-//
-//  Created by yiliangwang on 2024/12/26.
-//  Copyright © 2024 Tencent. All rights reserved.
-
-#import <Foundation/Foundation.h>
-
-NS_ASSUME_NONNULL_BEGIN
-
-@interface TUIGroupMemberCellData : NSObject
-
-@property(nonatomic, strong) NSString *identifier;
-
-@property(nonatomic, strong) NSString *name;
-
-@property(nonatomic, strong) UIImage *avatarImage;
-
-@property(nonatomic, strong) NSString *avatarUrl;
-
-@property NSInteger tag;
-
-@end
-
-@interface TUIGroupMembersCellData : NSObject
-
-@property(nonatomic, strong) NSMutableArray *members;
-- (CGFloat)heightOfWidth:(CGFloat)width;
-
-@end
-
-@interface TUICommonGroupInfoCellData : NSObject
-
-@end
-
-NS_ASSUME_NONNULL_END

+ 0 - 46
ThirdParty/TUIKit/TIMCommon/UI_Classic/TUICommonGroupInfoCellData.m

@@ -1,46 +0,0 @@
-//
-//  TUICommonGroupInfoCellData.m
-//  TIMCommon
-//
-//  Created by yiliangwang on 2024/12/26.
-//  Copyright © 2024 Tencent. All rights reserved.
-
-#import "TUICommonGroupInfoCellData.h"
-#import <TIMCommon/TIMDefine.h>
-#import <TUICore/UIView+TUILayout.h>
-
-@implementation TUIGroupMemberCellData
-
-@end
-
-@implementation TUIGroupMembersCellData
-
-+ (CGSize)getSize {
-    CGSize headSize = TGroupMemberCell_Head_Size;
-    if (headSize.width * TGroupMembersCell_Column_Count + TGroupMembersCell_Margin * (TGroupMembersCell_Column_Count + 1) > Screen_Width) {
-        CGFloat wd = (Screen_Width - (TGroupMembersCell_Margin * (TGroupMembersCell_Column_Count + 1))) / TGroupMembersCell_Column_Count;
-        headSize = CGSizeMake(wd, wd);
-    }
-    return CGSizeMake(headSize.width, headSize.height + TGroupMemberCell_Name_Height + TGroupMemberCell_Margin);
-}
-
-+ (CGFloat)getHeight:(TUIGroupMembersCellData *)data {
-    NSInteger row = ceil(data.members.count * 1.0 / TGroupMembersCell_Column_Count);
-    if (row > TGroupMembersCell_Row_Count) {
-        row = TGroupMembersCell_Row_Count;
-    }
-    CGFloat height = row * [self getSize].height + (row + 1) * TGroupMembersCell_Margin;
-    return height;
-}
-
-
-- (CGFloat)heightOfWidth:(CGFloat)width {
-    return [self.class getHeight:self];
-}
-
-@end
-
-
-@implementation TUICommonGroupInfoCellData
-
-@end

+ 0 - 34
ThirdParty/TUIKit/TIMCommon/UI_Classic/TUIConfig_Classic.h

@@ -1,34 +0,0 @@
-//
-//  TUIConfig_Classic.h
-//  TIMCommon
-//
-//  Created by Tencent on 2024/7/16.
-//  Copyright © 2024 Tencent. All rights reserved.
-
-#import <Foundation/Foundation.h>
-
-NS_ASSUME_NONNULL_BEGIN
-
-@interface TUIConfig_Classic : NSObject
-/**
- *  Show the toast prompt built in TUIKit.
- *  The default value is YES.
- */
-+ (void)enableToast:(BOOL)enable;
-
-/**
- * Switch the language of TUIKit. 
- * The currently supported languages are "en", "zh-Hans", and "ar".
- */
-+ (void)switchLanguageToTarget:(NSString *)targetLanguage;
-
-/**
- * Switch the theme of TUIKit.
- * The currently supported languages are "system", "serious", "light", "lively", "dark"
- */
-+ (void)switchThemeToTarget:(NSString *)targetTheme;
-
-@end
-
-
-NS_ASSUME_NONNULL_END

+ 0 - 27
ThirdParty/TUIKit/TIMCommon/UI_Classic/TUIConfig_Classic.m

@@ -1,27 +0,0 @@
-//
-//  TUIConfig_Classic.m
-//  TIMCommon
-//
-//  Created by Tencent on 2024/7/16.
-//  Copyright © 2024 Tencent. All rights reserved.
-
-#import "TUIConfig_Classic.h"
-#import <TUICore/TUIConfig.h>
-#import <TUICore/TUIGlobalization.h>
-#import <TUICore/TUIThemeManager.h>
-
-@implementation TUIConfig_Classic
-
-+ (void)enableToast:(BOOL)enable {
-    [TUIConfig defaultConfig].enableToast = enable;
-}
-
-+ (void)switchLanguageToTarget:(NSString *)targetLanguage {
-    [TUIGlobalization setPreferredLanguage:targetLanguage];
-}
-
-+ (void)switchThemeToTarget:(NSString *)targetTheme {
-    [TUIThemeManager.shareManager applyTheme:targetTheme forModule:TUIThemeModuleAll];
-}
-
-@end

+ 0 - 102
ThirdParty/TUIKit/TIMCommon/UI_Minimalist/TUIBubbleMessageCell_Minimalist.h

@@ -1,102 +0,0 @@
-
-//  Created by Tencent on 2023/06/09.
-//  Copyright © 2023 Tencent. All rights reserved.
-/**
- *
- *
- *  This document declares the TUIBubbleMessageCell_Minimalist class.
- *  Bubble messages, the most common type of messages that contain strings and emoticons.
- *  Both TUIFileMessageCell_Minimalist and TUIVoiceMessageCell_Minimalist inherit from this class and implement the userinterface of bubble messages.
- *  If developers want to customize the bubble message, they can also refer to the implementation methods of the above two message units to implement their own
- * bubble message unit.
- */
-#import "TUIBubbleMessageCellData.h"
-#import "TUIMessageCell_Minimalist.h"
-
-NS_ASSUME_NONNULL_BEGIN
-
-@interface TUIBubbleMessageCell_Minimalist : TUIMessageCell_Minimalist
-
-/**
- *  The bubble image view, the message's bubble icon, wraps the message's content on the UI as a background panel for the bubble.
- */
-@property(nonatomic, strong) UIImageView *bubbleView;
-@property(nonatomic, strong) TUIBubbleMessageCellData *bubbleData;
-
-- (void)fillWithData:(TUIBubbleMessageCellData *)data;
-
-+ (CGFloat)getBubbleTop:(TUIBubbleMessageCellData *)data;
-
-@end
-
-#pragma mark - TUILayoutConfiguration
-
-@interface TUIBubbleMessageCell_Minimalist (TUILayoutConfiguration)
-
-/**
- *  Send bubble icon (normal state)
- *  - The send icon of the bubble, assigned to the @bubble when the bubble message was sent.
- */
-@property(nonatomic, class) UIImage *outgoingBubble;
-
-/**
- *  Send bubble icon (normal state)
- *  - The send icon of the bubble, assigned to the @bubble when the bubble message was sent.
- */
-@property(nonatomic, class) UIImage *outgoingSameBubble;
-
-/**
- *  Send bubble icon (highlighted state)
- *  - The send icon (highlighted state) of the bubble, assigned to @highlightedBubble when the bubble message was sent.
- */
-@property(nonatomic, class) UIImage *outgoingHighlightedBubble;
-
-/**
- * Send bubble icon (highlighted state)
- */
-@property(nonatomic, class) UIImage *outgoingAnimatedHighlightedAlpha20;
-@property(nonatomic, class) UIImage *outgoingAnimatedHighlightedAlpha50;
-
-/**
- *
- *  Receive bubble icon (normal state)
- *  - The receive icon of the bubble, assigned to the @bubble when the bubble message was received.
- */
-@property(nonatomic, class) UIImage *incommingBubble;
-
-/**
- *
- *  Receive bubble icon (normal state)
- *  - The receive icon of the bubble, assigned to the @bubble when the bubble message was received.
- */
-@property(nonatomic, class) UIImage *incommingSameBubble;
-
-/**
- *
- *  Receive bubble icon (highlighted state)
- *  - The receive icon of the bubble, assigned to @highlightedBubble when the bubble message was received.
- */
-@property(nonatomic, class) UIImage *incommingHighlightedBubble;
-
-/**
- * 
- * Receive bubble icon (highlighted state)
- */
-@property(nonatomic, class) UIImage *incommingAnimatedHighlightedAlpha20;
-@property(nonatomic, class) UIImage *incommingAnimatedHighlightedAlpha50;
-
-/**
- *  Spacing at the top of the send bubble
- *  - It is used to locate the top of the sent bubble, and is assigned to @bubbleTop when the bubble message was sent.
- */
-@property(nonatomic, class) CGFloat outgoingBubbleTop;
-
-/**
- *  Spacing at the top of the receiving bubble
- *  - It is used to locate the top of the receive bubble, and is assigned to @bubbleTop when the bubble message was received.
- */
-@property(nonatomic, class) CGFloat incommingBubbleTop;
-
-@end
-
-NS_ASSUME_NONNULL_END

+ 0 - 356
ThirdParty/TUIKit/TIMCommon/UI_Minimalist/TUIBubbleMessageCell_Minimalist.m

@@ -1,356 +0,0 @@
-//
-//  TUIBubbleMessageCell_Minimalist.m
-//  TXIMSDK_TUIKit_iOS
-//
-//  Created by annidyfeng on 2019/5/22.
-//  Copyright © 2023 Tencent. All rights reserved.
-//
-
-#import "TUIBubbleMessageCell_Minimalist.h"
-#import <TIMCommon/TIMCommonModel.h>
-#import <TIMCommon/TIMDefine.h>
-
-@implementation TUIBubbleMessageCell_Minimalist
-
-- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
-    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
-    if (self) {
-        _bubbleView = [[UIImageView alloc] initWithFrame:self.container.bounds];
-        _bubbleView.userInteractionEnabled = YES;
-        [self.container addSubview:_bubbleView];
-        _bubbleView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
-    }
-    return self;
-}
-
-- (void)fillWithData:(TUIBubbleMessageCellData *)data {
-    [super fillWithData:data];
-    _bubbleData = data;
-
-    if (self.bubbleData.sameToNextMsgSender) {
-        self.bubbleView.image = self.getSameMessageBubble;
-        self.bubbleView.highlightedImage = self.getHighlightSameMessageBubble;
-    } else {
-        self.bubbleView.image = self.getBubble;
-        self.bubbleView.highlightedImage = self.getHighlightBubble;
-    }
-    // tell constraints they need updating
-    [self setNeedsUpdateConstraints];
-
-    // update constraints now so we can animate the change
-    [self updateConstraintsIfNeeded];
-
-    [self layoutIfNeeded];
-}
-
-+ (BOOL)requiresConstraintBasedLayout {
-    return YES;
-}
-
-// this is Apple's recommended place for adding/updating constraints
-- (void)updateConstraints {
-     
-    [super updateConstraints];
-    [self.bubbleView mas_remakeConstraints:^(MASConstraintMaker *make) {
-        make.leading.mas_equalTo(0);
-        make.size.mas_equalTo(self.container);
-        make.top.mas_equalTo(self.container);
-    }];
-    
-    CGPoint center = self.retryView.center;
-    center.y = self.bubbleView.center.y;
-    self.retryView.center = center;
-    
-}
-
-- (void)layoutSubviews {
-    [super layoutSubviews];
-}
-
-- (void)highlightWhenMatchKeyword:(NSString *)keyword {
-    /**
-     * The parent class implements the default highlighting effect - flickering
-     */
-    if (keyword) {
-        if (self.highlightAnimating) {
-            return;
-        }
-        [self animate:3];
-    }
-}
-
-- (void)animate:(int)times {
-    times--;
-    if (times < 0) {
-        if (self.bubbleData.sameToNextMsgSender) {
-            self.bubbleView.image = self.getSameMessageBubble;
-        } else {
-            self.bubbleView.image = self.getBubble;
-        }
-        self.bubbleView.layer.cornerRadius = 0;
-        self.bubbleView.layer.masksToBounds = YES;
-        self.highlightAnimating = NO;
-        return;
-    }
-
-    self.bubbleView.image = self.getAnimateHighlightBubble_alpha50;
-    self.bubbleView.layer.cornerRadius = 12;
-    self.bubbleView.layer.masksToBounds = YES;
-    self.highlightAnimating = YES;
-    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.25 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
-      self.bubbleView.image = self.getAnimateHighlightBubble_alpha20;
-      dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.25 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
-        if (!self.bubbleData.highlightKeyword) {
-            [self animate:0];
-            return;
-        }
-        [self animate:times];
-      });
-    });
-}
-
-- (CGFloat)getBubbleTop {
-    return [self.class getBubbleTop:self.bubbleData];
-}
-
-- (UIImage *)getBubble {
-    if (!TIMConfig.defaultConfig.enableMessageBubble) {
-        return nil;
-    }
-    if (self.bubbleData.direction == MsgDirectionIncoming) {
-        return self.class.incommingBubble;
-    } else {
-        return self.class.outgoingBubble;
-    }
-}
-
-- (UIImage *)getHighlightBubble {
-    if (!TIMConfig.defaultConfig.enableMessageBubble) {
-        return nil;
-    }
-    if (self.bubbleData.direction == MsgDirectionIncoming) {
-        return self.class.incommingHighlightedBubble;
-    } else {
-        return self.class.outgoingHighlightedBubble;
-    }
-}
-
-- (UIImage *)getAnimateHighlightBubble_alpha50 {
-    if (!TIMConfig.defaultConfig.enableMessageBubble) {
-        return nil;
-    }
-    if (self.bubbleData.direction == MsgDirectionIncoming) {
-        return self.class.incommingAnimatedHighlightedAlpha50;
-    } else {
-        return self.class.outgoingAnimatedHighlightedAlpha50;
-    }
-}
-
-- (UIImage *)getAnimateHighlightBubble_alpha20 {
-    if (!TIMConfig.defaultConfig.enableMessageBubble) {
-        return nil;
-    }
-    if (self.bubbleData.direction == MsgDirectionIncoming) {
-        return self.class.incommingAnimatedHighlightedAlpha20;
-    } else {
-        return self.class.outgoingAnimatedHighlightedAlpha20;
-    }
-}
-
-- (UIImage *)getSameMessageBubble {
-    if (!TIMConfig.defaultConfig.enableMessageBubble) {
-        return nil;
-    }
-    return self.bubbleData.direction == MsgDirectionIncoming ? self.class.incommingSameBubble : self.class.outgoingSameBubble;
-}
-
-- (UIImage *)getHighlightSameMessageBubble {
-    if (!TIMConfig.defaultConfig.enableMessageBubble) {
-        return nil;
-    }
-    return self.getSameMessageBubble;
-}
-
-+ (CGFloat)getBubbleTop:(TUIBubbleMessageCellData *)data {
-    if (data.direction == MsgDirectionIncoming) {
-        return self.class.incommingBubbleTop;
-    } else {
-        return self.class.outgoingBubbleTop;
-    }
-}
-
-@end
-
-@implementation TUIBubbleMessageCell_Minimalist (TUILayoutConfiguration)
-
-+ (void)initialize {
-    [NSNotificationCenter.defaultCenter addObserver:self selector:@selector(onThemeChanged:) name:TUIDidApplyingThemeChangedNotfication object:nil];
-}
-
-#pragma mark - gOutgoingBubble
-static UIImage *gOutgoingBubble;
-+ (UIImage *)outgoingBubble {
-    if (!gOutgoingBubble) {
-        UIImage *defaultImage = [[TUIImageCache sharedInstance] getResourceFromCache:TUIChatImagePath_Minimalist(@"SenderTextNodeBkg")];
-        [self setOutgoingBubble:defaultImage];
-    }
-    return gOutgoingBubble;
-}
-+ (void)setOutgoingBubble:(UIImage *)outgoingBubble {
-    gOutgoingBubble = [self stretchImage:outgoingBubble];
-}
-
-#pragma mark - gOutgoingSameBubble
-static UIImage *gOutgoingSameBubble;
-+ (UIImage *)outgoingSameBubble {
-    if (!gOutgoingSameBubble) {
-        UIImage *defaultImage = [[TUIImageCache sharedInstance] getResourceFromCache:TUIChatImagePath_Minimalist(@"SenderTextNodeBkg_Same")];
-        [self setOutgoingSameBubble:defaultImage];
-    }
-    return gOutgoingSameBubble;
-}
-+ (void)setOutgoingSameBubble:(UIImage *)outgoingSameBubble {
-    gOutgoingSameBubble = [self stretchImage:outgoingSameBubble];
-}
-
-#pragma mark - gOutgoingHighlightedBubble
-static UIImage *gOutgoingHighlightedBubble;
-+ (UIImage *)outgoingHighlightedBubble {
-    if (!gOutgoingHighlightedBubble) {
-        UIImage *defaultImage = [[TUIImageCache sharedInstance] getResourceFromCache:TUIChatImagePath_Minimalist(@"SenderTextNodeBkg")];
-        [self setOutgoingHighlightedBubble:defaultImage];
-    }
-    return gOutgoingHighlightedBubble;
-}
-+ (void)setOutgoingHighlightedBubble:(UIImage *)outgoingHighlightedBubble {
-    gOutgoingHighlightedBubble = [self stretchImage:outgoingHighlightedBubble];
-}
-
-#pragma mark - gOutgoingAnimatedHighlightedAlpha20
-static UIImage *gOutgoingAnimatedHighlightedAlpha20;
-+ (UIImage *)outgoingAnimatedHighlightedAlpha20 {
-    if (!gOutgoingAnimatedHighlightedAlpha20) {
-        UIImage *alpha20 = [[TUIImageCache sharedInstance] getResourceFromCache:TUIChatImagePath(@"SenderTextNodeBkg_alpha20")];
-        [self setOutgoingAnimatedHighlightedAlpha20:TUIChatDynamicImage(@"chat_bubble_send_alpha20_img", alpha20)];
-    }
-    return gOutgoingAnimatedHighlightedAlpha20;
-}
-+ (void)setOutgoingAnimatedHighlightedAlpha20:(UIImage *)outgoingAnimatedHighlightedAlpha20 {
-    gOutgoingAnimatedHighlightedAlpha20 = [self stretchImage:outgoingAnimatedHighlightedAlpha20];
-}
-
-#pragma mark - gOutgoingAnimatedHighlightedAlpha50
-static UIImage *gOutgoingAnimatedHighlightedAlpha50;
-+ (UIImage *)outgoingAnimatedHighlightedAlpha50 {
-    if (!gOutgoingAnimatedHighlightedAlpha50) {
-        UIImage *alpha50 = [[TUIImageCache sharedInstance] getResourceFromCache:TUIChatImagePath(@"SenderTextNodeBkg_alpha50")];
-        [self setOutgoingAnimatedHighlightedAlpha50:TUIChatDynamicImage(@"chat_bubble_send_alpha50_img", alpha50)];
-    }
-    return gOutgoingAnimatedHighlightedAlpha50;
-}
-+ (void)setOutgoingAnimatedHighlightedAlpha50:(UIImage *)outgoingAnimatedHighlightedAlpha50 {
-    gOutgoingAnimatedHighlightedAlpha50 = [self stretchImage:outgoingAnimatedHighlightedAlpha50];
-}
-
-#pragma mark - gIncommingBubble
-static UIImage *gIncommingBubble;
-+ (UIImage *)incommingBubble {
-    if (!gIncommingBubble) {
-        UIImage *defaultImage = [[TUIImageCache sharedInstance] getResourceFromCache:TUIChatImagePath_Minimalist(@"ReceiverTextNodeBkg")];
-        [self setIncommingBubble:defaultImage];
-    }
-    return gIncommingBubble;
-}
-+ (void)setIncommingBubble:(UIImage *)incommingBubble {
-    gIncommingBubble = [self stretchImage:incommingBubble];
-}
-
-#pragma mark - gIncommingSameBubble
-static UIImage *gIncommingSameBubble;
-+ (UIImage *)incommingSameBubble {
-    if (!gIncommingSameBubble) {
-        UIImage *defaultImage = [[TUIImageCache sharedInstance] getResourceFromCache:TUIChatImagePath_Minimalist(@"ReceiverTextNodeBkg_Same")];
-        [self setIncommingSameBubble:defaultImage];
-    }
-    return gIncommingSameBubble;
-}
-+ (void)setIncommingSameBubble:(UIImage *)incommingSameBubble {
-    gIncommingSameBubble = [self stretchImage:incommingSameBubble];
-}
-
-#pragma mark - gIncommingHighlightedBubble
-static UIImage *gIncommingHighlightedBubble;
-+ (UIImage *)incommingHighlightedBubble {
-    if (!gIncommingHighlightedBubble) {
-        UIImage *defaultImage = [[TUIImageCache sharedInstance] getResourceFromCache:TUIChatImagePath_Minimalist(@"ReceiverTextNodeBkg")];
-        [self setIncommingHighlightedBubble:defaultImage];
-    }
-    return gIncommingHighlightedBubble;
-}
-+ (void)setIncommingHighlightedBubble:(UIImage *)incommingHighlightedBubble {
-    gIncommingHighlightedBubble = [self stretchImage:incommingHighlightedBubble];
-}
-
-#pragma mark - gIncommingAnimatedHighlightedAlpha20
-static UIImage *gIncommingAnimatedHighlightedAlpha20;
-+ (UIImage *)incommingAnimatedHighlightedAlpha20 {
-    if (!gIncommingAnimatedHighlightedAlpha20) {
-        UIImage *alpha20 = [[TUIImageCache sharedInstance] getResourceFromCache:TUIChatImagePath(@"ReceiverTextNodeBkg_alpha20")];
-        [self setIncommingAnimatedHighlightedAlpha20:TUIChatDynamicImage(@"chat_bubble_receive_alpha20_img", alpha20)];
-    }
-    return gIncommingAnimatedHighlightedAlpha20;
-}
-+ (void)setIncommingAnimatedHighlightedAlpha20:(UIImage *)incommingAnimatedHighlightedAlpha20 {
-    gIncommingAnimatedHighlightedAlpha20 = [self stretchImage:incommingAnimatedHighlightedAlpha20];
-}
-
-#pragma mark - gIncommingAnimatedHighlightedAlpha50
-static UIImage *gIncommingAnimatedHighlightedAlpha50;
-+ (UIImage *)incommingAnimatedHighlightedAlpha50 {
-    if (!gIncommingAnimatedHighlightedAlpha50) {
-        UIImage *alpha50 = [[TUIImageCache sharedInstance] getResourceFromCache:TUIChatImagePath(@"ReceiverTextNodeBkg_alpha50")];
-        [self setIncommingAnimatedHighlightedAlpha50:TUIChatDynamicImage(@"chat_bubble_receive_alpha50_img", alpha50)];
-    }
-    return gIncommingAnimatedHighlightedAlpha50;
-}
-+ (void)setIncommingAnimatedHighlightedAlpha50:(UIImage *)incommingAnimatedHighlightedAlpha50 {
-    gIncommingAnimatedHighlightedAlpha50 = [self stretchImage:incommingAnimatedHighlightedAlpha50];
-}
-
-+ (UIImage *)stretchImage:(UIImage *)oldImage {
-    UIImage *image = [oldImage rtl_imageFlippedForRightToLeftLayoutDirection];
-    UIEdgeInsets insets = rtlEdgeInsetsWithInsets(UIEdgeInsetsFromString(@"{12,12,12,12}"));
-    return [image resizableImageWithCapInsets:insets resizingMode:UIImageResizingModeStretch];
-}
-
-static CGFloat gOutgoingBubbleTop = 0;
-+ (CGFloat)outgoingBubbleTop {
-    return gOutgoingBubbleTop;
-}
-
-+ (void)setOutgoingBubbleTop:(CGFloat)outgoingBubble {
-    gOutgoingBubbleTop = outgoingBubble;
-}
-
-static CGFloat gIncommingBubbleTop = 0;
-+ (CGFloat)incommingBubbleTop {
-    return gIncommingBubbleTop;
-}
-
-+ (void)setIncommingBubbleTop:(CGFloat)incommingBubbleTop {
-    gIncommingBubbleTop = incommingBubbleTop;
-}
-
-+ (void)onThemeChanged:(NSNotification *)notice {
-    gOutgoingBubble = nil;
-    gOutgoingHighlightedBubble = nil;
-    gOutgoingAnimatedHighlightedAlpha50 = nil;
-    gOutgoingAnimatedHighlightedAlpha20 = nil;
-
-    gIncommingBubble = nil;
-    gIncommingHighlightedBubble = nil;
-    gIncommingAnimatedHighlightedAlpha50 = nil;
-    gIncommingAnimatedHighlightedAlpha20 = nil;
-}
-
-@end

+ 0 - 41
ThirdParty/TUIKit/TIMCommon/UI_Minimalist/TUICommonGroupInfoCellData_Minimalist.h

@@ -1,41 +0,0 @@
-//
-//  TUICommonGroupInfoCellData_Minimalist.h
-//  TIMCommon
-//
-//  Created by yiliangwang on 2024/12/26.
-//  Copyright © 2024 Tencent. All rights reserved.
-
-#import <Foundation/Foundation.h>
-#import <TIMCommon/TIMCommonModel.h>
-NS_ASSUME_NONNULL_BEGIN
-
-@interface TUIGroupButtonCellData_Minimalist : TUICommonCellData
-@property(nonatomic, strong) NSString *title;
-@property SEL cbuttonSelector;
-@property TUIButtonStyle style;
-@property(nonatomic, strong) UIColor *textColor;
-@property(nonatomic, assign) BOOL hideSeparatorLine;
-@property(nonatomic, assign) BOOL isInfoPageLeftButton;
-@end
-
-@interface TUIGroupMemberCellData_Minimalist : TUICommonCellData
-@property(nonatomic, strong) NSString *identifier;
-
-@property(nonatomic, strong) NSString *name;
-
-@property(nonatomic, strong) UIImage *avatarImage;
-
-@property(nonatomic, strong) NSString *avatarUrl;
-
-@property(nonatomic, assign) BOOL showAccessory;
-
-@property(nonatomic, copy) NSString *detailName;
-
-@property NSInteger tag;
-@end
-
-@interface TUICommonGroupInfoCellData_Minimalist : NSObject
-
-@end
-
-NS_ASSUME_NONNULL_END

+ 0 - 24
ThirdParty/TUIKit/TIMCommon/UI_Minimalist/TUICommonGroupInfoCellData_Minimalist.m

@@ -1,24 +0,0 @@
-//
-//  TUICommonGroupInfoCellData_Minimalist.m
-//  TIMCommon
-//
-//  Created by yiliangwang on 2024/12/26.
-//  Copyright © 2024 Tencent. All rights reserved.
-
-#import "TUICommonGroupInfoCellData_Minimalist.h"
-#import <TIMCommon/TIMDefine.h>
-#import <TUICore/TUIThemeManager.h>
-@implementation TUIGroupButtonCellData_Minimalist
-- (CGFloat)heightOfWidth:(CGFloat)width {
-    return 56;
-}
-@end
-
-@implementation TUIGroupMemberCellData_Minimalist
-- (CGFloat)heightOfWidth:(CGFloat)width {
-    return kScale390(48);
-}
-@end
-@implementation TUICommonGroupInfoCellData_Minimalist
-
-@end

+ 0 - 28
ThirdParty/TUIKit/TIMCommon/UI_Minimalist/TUIConfig_Minimalist.h

@@ -1,28 +0,0 @@
-//
-//  TUIConfig_Minimalist.h
-//  TIMCommon
-//
-//  Created by Tencent on 2024/7/16.
-//  Copyright © 2024 Tencent. All rights reserved.
-
-#import <Foundation/Foundation.h>
-
-NS_ASSUME_NONNULL_BEGIN
-
-@interface TUIConfig_Minimalist : NSObject
-/**
- *  Show the toast prompt built in TUIKit.
- *  The default value is YES.
- */
-+ (void)enableToast:(BOOL)enable;
-
-/**
- * Switch the language of TUIKit. 
- * The currently supported languages are "en", "zh-Hans", and "ar".
- */
-+ (void)switchLanguageToTarget:(NSString *)targetLanguage;
-
-@end
-
-
-NS_ASSUME_NONNULL_END

+ 0 - 22
ThirdParty/TUIKit/TIMCommon/UI_Minimalist/TUIConfig_Minimalist.m

@@ -1,22 +0,0 @@
-//
-//  TUIConfig_Minimalist.m
-//  TIMCommon
-//
-//  Created by Tencent on 2024/7/16.
-//  Copyright © 2024 Tencent. All rights reserved.
-
-#import "TUIConfig_Minimalist.h"
-#import <TUICore/TUIConfig.h>
-#import <TUICore/TUIGlobalization.h>
-
-@implementation TUIConfig_Minimalist
-
-+ (void)enableToast:(BOOL)enable {
-    [TUIConfig defaultConfig].enableToast = enable;
-}
-
-+ (void)switchLanguageToTarget:(NSString *)targetLanguage {
-    [TUIGlobalization setPreferredLanguage:targetLanguage];
-}
-
-@end

+ 0 - 21
ThirdParty/TUIKit/TIMCommon/UI_Minimalist/TUIGroupButtonCell_Minimalist.h

@@ -1,21 +0,0 @@
-//
-//  TUIGroupButtonCell_Minimalist.h
-//  TUIGroup
-//
-//  Created by wyl on 2023/1/4.
-//  Copyright © 2023 Tencent. All rights reserved.
-//
-
-#import <TIMCommon/TIMCommonModel.h>
-#import <TIMCommon/TUICommonGroupInfoCellData_Minimalist.h>
-NS_ASSUME_NONNULL_BEGIN
-
-@interface TUIGroupButtonCell_Minimalist : TUICommonTableViewCell
-@property(nonatomic, strong) UIButton *button;
-@property(nonatomic, strong) TUIGroupButtonCellData_Minimalist *buttonData;
-
-- (void)fillWithData:(TUIGroupButtonCellData_Minimalist *)data;
-
-@end
-
-NS_ASSUME_NONNULL_END

+ 0 - 168
ThirdParty/TUIKit/TIMCommon/UI_Minimalist/TUIGroupButtonCell_Minimalist.m

@@ -1,168 +0,0 @@
-//
-//  TUIGroupButtonCell_Minimalist.m
-//  TUIGroup
-//
-//  Created by wyl on 2023/1/4.
-//  Copyright © 2023 Tencent. All rights reserved.
-//
-
-#import "TUIGroupButtonCell_Minimalist.h"
-
-#import <TUICore/TUIThemeManager.h>
-
-@implementation TUIGroupButtonCell_Minimalist {
-    UIView *_line;
-}
-
-- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
-    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
-    if (self) {
-        [self setupViews];
-        self.changeColorWhenTouched = YES;
-    }
-    return self;
-}
-
-- (void)setupViews {
-    self.backgroundColor = [UIColor tui_colorWithHex:@"#f9f9f9"];
-    self.contentView.backgroundColor = [UIColor tui_colorWithHex:@"#f9f9f9"];
-
-    _button = [UIButton buttonWithType:UIButtonTypeCustom];
-    [_button.titleLabel setFont:[UIFont systemFontOfSize:16]];
-
-    [_button addTarget:self action:@selector(onClick:) forControlEvents:UIControlEventTouchUpInside];
-
-    [self.contentView addSubview:_button];
-
-    [self setSeparatorInset:UIEdgeInsetsMake(0, Screen_Width, 0, 0)];
-    [self setSelectionStyle:UITableViewCellSelectionStyleNone];
-    self.changeColorWhenTouched = YES;
-
-    _line = [[UIView alloc] initWithFrame:CGRectZero];
-    [self.contentView addSubview:_line];
-    _line.backgroundColor = [UIColor whiteColor];
-}
-
-- (void)fillWithData:(TUIGroupButtonCellData_Minimalist *)data {
-    [super fillWithData:data];
-    self.buttonData = data;
-    [_button setTitle:data.title forState:UIControlStateNormal];
-    if(isRTL()) {
-        _button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentRight;
-    }
-    else {
-        _button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
-    }
-    _button.titleEdgeInsets = UIEdgeInsetsMake(0, 0, 0, 0);
-    switch (data.style) {
-        case ButtonGreen: {
-            [_button setTitleColor:TIMCommonDynamicColor(@"form_green_button_text_color", @"#FFFFFF") forState:UIControlStateNormal];
-            _button.backgroundColor = TIMCommonDynamicColor(@"", @"#f9f9f9");
-            [_button setBackgroundImage:[self imageWithColor:TIMCommonDynamicColor(@"", @"#f9f9f9")] forState:UIControlStateHighlighted];
-        } break;
-        case ButtonWhite: {
-            [_button setTitleColor:TIMCommonDynamicColor(@"form_white_button_text_color", @"#000000") forState:UIControlStateNormal];
-            _button.backgroundColor = TIMCommonDynamicColor(@"", @"#f9f9f9");
-        } break;
-        case ButtonRedText: {
-            [_button setTitleColor:TIMCommonDynamicColor(@"form_redtext_button_text_color", @"#FF0000") forState:UIControlStateNormal];
-            _button.backgroundColor = TIMCommonDynamicColor(@"", @"#f9f9f9");
-
-            break;
-        }
-        case ButtonBule: {
-            if (data.isInfoPageLeftButton) {
-                [_button setTitleColor:TIMCommonDynamicColor(@"", @"#0365F9") forState:UIControlStateNormal];
-                _button.backgroundColor = TIMCommonDynamicColor(@"", @"#f9f9f9");
-            } else {
-                [_button.titleLabel setTextColor:[UIColor tui_colorWithHex:@"147AFF"]];
-                _button.backgroundColor = [UIColor tui_colorWithHex:@"#f9f9f9"];
-                _button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;
-                _button.layer.cornerRadius = kScale390(10);
-                _button.layer.masksToBounds = YES;
-                self.backgroundColor = [UIColor clearColor];
-                self.contentView.backgroundColor = [UIColor clearColor];
-            }
-        } break;
-        default:
-            break;
-    }
-
-    if (data.textColor) {
-        [_button setTitleColor:data.textColor forState:UIControlStateNormal];
-    }
-
-    _line.hidden = data.hideSeparatorLine;
-    
-    // tell constraints they need updating
-    [self setNeedsUpdateConstraints];
-
-    // update constraints now so we can animate the change
-    [self updateConstraintsIfNeeded];
-
-    [self layoutIfNeeded];
-    
-}
-
-+ (BOOL)requiresConstraintBasedLayout {
-    return YES;
-}
-
-// this is Apple's recommended place for adding/updating constraints
-- (void)updateConstraints {
-     
-    [super updateConstraints];
-    [self.button mas_remakeConstraints:^(MASConstraintMaker *make) {
-        make.leading.mas_equalTo(self.contentView.mas_leading).mas_offset(kScale390(20));
-        make.trailing.mas_equalTo(self.contentView.mas_trailing).mas_offset(- kScale390(20));
-        make.top.mas_equalTo(self.contentView);
-        make.bottom.mas_equalTo(self.contentView);
-    }];
-    
-    [_line mas_remakeConstraints:^(MASConstraintMaker *make) {
-        make.leading.mas_equalTo(self.contentView.mas_leading).mas_offset(20);
-        make.trailing.mas_equalTo(self.contentView.mas_trailing);
-        make.height.mas_equalTo(0.2);
-        make.bottom.mas_equalTo(self.contentView);
-    }];
-}
-
-- (void)layoutSubviews {
-    [super layoutSubviews];
-
-}
-
-- (void)onClick:(UIButton *)sender {
-    if (self.buttonData.cbuttonSelector) {
-        UIViewController *vc = self.mm_viewController;
-        if ([vc respondsToSelector:self.buttonData.cbuttonSelector]) {
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
-            [vc performSelector:self.buttonData.cbuttonSelector withObject:self];
-#pragma clang diagnostic pop
-        }
-    }
-}
-
-- (void)didAddSubview:(UIView *)subview {
-    [super didAddSubview:subview];
-    if (subview != self.contentView) {
-        [subview removeFromSuperview];
-    }
-}
-
-- (UIImage *)imageWithColor:(UIColor *)color {
-    CGRect rect = CGRectMake(0.0f, 0.0f, 1.0f, 1.0f);
-    UIGraphicsBeginImageContext(rect.size);
-    CGContextRef context = UIGraphicsGetCurrentContext();
-
-    CGContextSetFillColorWithColor(context, [color CGColor]);
-    CGContextFillRect(context, rect);
-
-    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
-    UIGraphicsEndImageContext();
-
-    return image;
-}
-
-@end

+ 0 - 33
ThirdParty/TUIKit/TIMCommon/UI_Minimalist/TUIMessageCell_Minimalist.h

@@ -1,33 +0,0 @@
-
-//  Created by Tencent on 2023/06/09.
-//  Copyright © 2023 Tencent. All rights reserved.
-/**
- *  This document declares the TUIBubbleMessageCell_Minimalist class.
- *  Bubble messages, the most common type of messages that contain strings and emoticons.
- *  Both TUIFileMessageCell_Minimalist and TUIVoiceMessageCell_Minimalist inherit from this class and implement the userinterface of bubble messages.
- *  If developers want to customize the bubble message, they can also refer to the implementation methods of the above two message units to implement their own
- * bubble message unit.
- */
-#import "TUIMessageCell.h"
-#import "TUIMessageCellData.h"
-
-NS_ASSUME_NONNULL_BEGIN
-
-typedef NS_ENUM(NSInteger, TUIMessageStatus) {
-    TUIMessageStatus_Unkown,
-    TUIMessageStatus_Sending,
-    TUIMessageStatus_Send_Succ,
-    TUIMessageStatus_Some_People_Read,
-    TUIMessageStatus_All_People_Read,
-};
-
-@interface TUIMessageCell_Minimalist : TUIMessageCell
-@property(nonatomic, strong) UIImageView *replyLineView;
-@property(nonatomic, strong) NSMutableArray *replyAvatarImageViews;
-@property(nonatomic, strong) UIImageView *msgStatusView;
-@property(nonatomic, strong) UILabel *msgTimeLabel;
-
-- (void)fillWithData:(TUIMessageCellData *)data;
-@end
-
-NS_ASSUME_NONNULL_END

+ 0 - 461
ThirdParty/TUIKit/TIMCommon/UI_Minimalist/TUIMessageCell_Minimalist.m

@@ -1,461 +0,0 @@
-//
-//  TUIMessageCell_Minimalist.m
-//  TXIMSDK_TUIKit_iOS
-//
-//  Created by annidyfeng on 2019/5/22.
-//  Copyright © 2023 Tencent. All rights reserved.
-//
-
-#import "TUIMessageCell_Minimalist.h"
-#import <TIMCommon/TIMCommonModel.h>
-#import <TIMCommon/TIMDefine.h>
-#import "NSString+TUIEmoji.h"
-#import <TUICore/TUICore.h>
-#import <TIMCommon/TUIRelationUserModel.h>
-
-@interface TUIMessageCell_Minimalist ()
-@property(nonatomic, assign) TUIMessageStatus status;
-@property(nonatomic, strong) NSMutableArray *animationImages;
-@end
-
-@implementation TUIMessageCell_Minimalist
-
-- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
-    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
-    if (self) {
-        _replyLineView = [[UIImageView alloc] initWithFrame:CGRectZero];
-        _replyLineView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
-        [self.contentView addSubview:_replyLineView];
-        [self.messageModifyRepliesButton.titleLabel setFont:[UIFont systemFontOfSize:12]];
-        if(isRTL()) {
-            self.messageModifyRepliesButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentRight;
-        }
-        else {
-            self.messageModifyRepliesButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
-        }
-        [self.messageModifyRepliesButton setTitleColor:RGBA(0, 95, 255, 1) forState:UIControlStateNormal];
-
-        _msgStatusView = [[UIImageView alloc] initWithFrame:CGRectZero];
-        _msgStatusView.contentMode = UIViewContentModeScaleAspectFit;
-        _msgStatusView.layer.zPosition = FLT_MAX;
-        UITapGestureRecognizer *tap2 = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onJumpToMessageInfoPage)];
-        [_msgStatusView addGestureRecognizer:tap2];
-        _msgStatusView.userInteractionEnabled = YES;
-        [self.container addSubview:_msgStatusView];
-
-        _msgTimeLabel = [[UILabel alloc] initWithFrame:CGRectZero];
-        _msgTimeLabel.textColor = RGB(102, 102, 102);
-        _msgTimeLabel.font = [UIFont systemFontOfSize:12];
-        _msgTimeLabel.rtlAlignment = TUITextRTLAlignmentTrailing;
-        _msgTimeLabel.layer.zPosition = FLT_MAX;
-        [self.container addSubview:_msgTimeLabel];
-
-        self.animationImages = [NSMutableArray array];
-        for (int i = 1; i <= 45; ++i) {
-            NSString *imageName = [NSString stringWithFormat:@"msg_status_sending_%d", i];
-            NSString *imagePath = TUIChatImagePath_Minimalist(imageName);
-            UIImage *image = [[TUIImageCache sharedInstance] getResourceFromCache:imagePath];
-            [self.animationImages addObject:image];
-        }
-        _replyAvatarImageViews = [NSMutableArray array];
-    }
-    return self;
-}
-
-- (void)prepareReactTagUI:(UIView *)containerView {
-    NSDictionary *param = @{TUICore_TUIChatExtension_ChatMessageReactPreview_Delegate: self};
-    [TUICore raiseExtension:TUICore_TUIChatExtension_ChatMessageReactPreview_MinimalistExtensionID parentView:containerView param:param];
-}
-
-
-- (void)onJumpToMessageInfoPage {
-    if (self.delegate && [self.delegate respondsToSelector:@selector(onJumpToMessageInfoPage:selectCell:)]) {
-        [self.delegate onJumpToMessageInfoPage:self.messageData selectCell:self];
-    }
-}
-
-+ (BOOL)requiresConstraintBasedLayout {
-    return YES;
-}
-
-// this is Apple's recommended place for adding/updating constraints
-- (void)updateConstraints {
-     
-    [super updateConstraints];
-    TUIMessageCellLayout *cellLayout = self.messageData.cellLayout;
-    BOOL isInComing = (self.messageData.direction == MsgDirectionIncoming);
-
-    [self.nameLabel mas_remakeConstraints:^(MASConstraintMaker *make) {
-        if (isInComing) {
-            make.leading.mas_equalTo(self.container.mas_leading).mas_offset(7);
-        } else {
-            make.trailing.mas_equalTo(self.container.mas_trailing);
-        }
-        if (self.messageData.showName) {
-            make.width.mas_greaterThanOrEqualTo(20);
-            make.height.mas_greaterThanOrEqualTo(20);
-        } else {
-            make.height.mas_equalTo(0);
-        }
-        make.top.mas_equalTo(self.avatarView.mas_top);
-    }];
-
-    [self.selectedIcon mas_remakeConstraints:^(MASConstraintMaker *make) {
-        make.leading.mas_equalTo(self.contentView.mas_leading).mas_offset(3);
-        make.centerY.mas_equalTo(self.container.mas_centerY);
-        if (self.messageData.showCheckBox) {
-            make.width.mas_equalTo(20);
-            make.height.mas_equalTo(20);
-        } else {
-            make.size.mas_equalTo(CGSizeZero);
-        }
-    }];
-
-    [self.timeLabel sizeToFit];
-    [self.timeLabel mas_updateConstraints:^(MASConstraintMaker *make) {
-        if (self.messageData.showMessageTime) {
-            make.width.mas_equalTo(self.timeLabel.frame.size.width);
-            make.height.mas_equalTo(self.timeLabel.frame.size.height);
-        } else {
-            make.width.mas_equalTo(0);
-            make.height.mas_equalTo(0);
-        }
-    }];
-
-    CGSize csize = [self.class getContentSize:self.messageData];
-    CGFloat contentWidth = csize.width;
-    CGFloat contentHeight = csize.height;
-
-    if (self.messageData.direction == MsgDirectionIncoming) {
-        self.avatarView.hidden = !self.messageData.showAvatar;
-        [self.avatarView mas_remakeConstraints:^(MASConstraintMaker *make) {
-          if (self.messageData.showCheckBox) {
-              make.leading.mas_equalTo(self.selectedIcon.mas_trailing).mas_offset(cellLayout.avatarInsets.left);
-          } else {
-              make.leading.mas_equalTo(self.contentView.mas_leading).mas_offset(cellLayout.avatarInsets.left);
-          }
-          make.top.mas_equalTo(cellLayout.avatarInsets.top);
-          make.size.mas_equalTo(cellLayout.avatarSize);
-        }];
-
-        [self.container mas_remakeConstraints:^(MASConstraintMaker *make) {
-          make.leading.mas_equalTo(self.avatarView.mas_trailing).mas_offset(cellLayout.messageInsets.left);
-          make.top.mas_equalTo(self.nameLabel.mas_bottom).mas_offset(cellLayout.messageInsets.top);
-          make.width.mas_equalTo(contentWidth);
-          make.height.mas_equalTo(contentHeight);
-        }];
-
-        CGRect indicatorFrame = self.indicator.frame;
-        [self.indicator mas_remakeConstraints:^(MASConstraintMaker *make) {
-          make.leading.mas_equalTo(self.container.mas_trailing).mas_offset(8);
-          make.centerY.mas_equalTo(self.container.mas_centerY);
-          make.size.mas_equalTo(indicatorFrame.size);
-        }];
-        self.retryView.frame = self.indicator.frame;
-        self.readReceiptLabel.hidden = YES;
-    } else {
-        if (!self.messageData.showAvatar) {
-            cellLayout.avatarSize = CGSizeZero;
-        } 
-        [self.avatarView mas_remakeConstraints:^(MASConstraintMaker *make) {
-          make.trailing.mas_equalTo(self.contentView.mas_trailing).mas_offset(-cellLayout.avatarInsets.right);
-          make.top.mas_equalTo(cellLayout.avatarInsets.top);
-          make.size.mas_equalTo(cellLayout.avatarSize);
-        }];
-        [self.container mas_remakeConstraints:^(MASConstraintMaker *make) {
-          make.trailing.mas_equalTo(self.avatarView.mas_leading).mas_offset(-cellLayout.messageInsets.right);
-          make.top.mas_equalTo(self.nameLabel.mas_bottom).mas_offset(cellLayout.messageInsets.top);
-          make.width.mas_equalTo(contentWidth);
-          make.height.mas_equalTo(contentHeight);
-        }];
-
-        CGRect indicatorFrame = self.indicator.frame;
-        [self.indicator mas_remakeConstraints:^(MASConstraintMaker *make) {
-          make.trailing.mas_equalTo(self.container.mas_leading).mas_offset(-8);
-          make.centerY.mas_equalTo(self.container.mas_centerY);
-          make.size.mas_equalTo(indicatorFrame.size);
-        }];
-
-        self.retryView.frame = self.indicator.frame;
-
-        [self.readReceiptLabel sizeToFit];
-        [self.readReceiptLabel mas_remakeConstraints:^(MASConstraintMaker *make) {
-          make.bottom.mas_equalTo(self.container.mas_bottom);
-          make.trailing.mas_equalTo(self.container.mas_leading).mas_offset(-8);
-          make.size.mas_equalTo(self.readReceiptLabel.frame.size);
-        }];
-    }
-
-    if (!self.messageModifyRepliesButton.isHidden) {
-        self.messageModifyRepliesButton.mm_sizeToFit();
-        CGFloat repliesBtnTextWidth = self.messageModifyRepliesButton.frame.size.width;
-        [self.messageModifyRepliesButton mas_remakeConstraints:^(MASConstraintMaker *make) {
-          if (isInComing) {
-              make.leading.mas_equalTo(self.container.mas_leading);
-          } else {
-              make.trailing.mas_equalTo(self.container.mas_trailing);
-          }
-          make.top.mas_equalTo(self.container.mas_bottom);
-          make.size.mas_equalTo(CGSizeMake(repliesBtnTextWidth + 10, 30));
-        }];
-    }
-    
-
-    if (self.messageData.showMessageModifyReplies && _replyAvatarImageViews.count > 0)  {
-        CGFloat lineViewW = 17;
-        CGFloat avatarSize = 16;
-        CGFloat repliesBtnW = kScale390(50);
-        CGFloat avatarY = self.contentView.mm_h - (self.messageData.sameToNextMsgSender ? avatarSize : avatarSize * 2);
-        if (self.messageData.direction == MsgDirectionIncoming)  {
-            UIImageView *preAvatarImageView = nil;
-            for (int i = 0; i < _replyAvatarImageViews.count; ++i) {
-                UIImageView *avatarView = _replyAvatarImageViews[i];
-                if (i == 0) {
-                    preAvatarImageView = nil;
-                }
-                else {
-                    preAvatarImageView = _replyAvatarImageViews[i-1];
-                }
-                [avatarView mas_remakeConstraints:^(MASConstraintMaker *make) {
-                    if (i == 0) {
-                        make.leading.mas_equalTo(_replyLineView.mas_trailing);
-                    }
-                    else {
-                        make.leading.mas_equalTo(preAvatarImageView.mas_centerX);
-                    }
-                    make.top.mas_equalTo(avatarY);
-                    make.width.height.mas_equalTo(avatarSize);
-                   
-                }];
-                avatarView.layer.masksToBounds = YES;
-                avatarView.layer.cornerRadius = avatarSize / 2.0;
-            }
-        }
-        else {
-            __block UIImageView *preAvatarImageView = nil;
-            NSInteger count = _replyAvatarImageViews.count;
-            for (NSInteger i = (count - 1); i >=0; i--) {
-                UIImageView *avatarView = _replyAvatarImageViews[i];
-                [avatarView mas_remakeConstraints:^(MASConstraintMaker *make) {
-                    if (!preAvatarImageView) {
-                        make.trailing.mas_equalTo(self.messageModifyRepliesButton.mas_leading);
-                    }
-                    else {
-                        make.trailing.mas_equalTo(preAvatarImageView.mas_centerX);
-                    }
-                    make.top.mas_equalTo(avatarY);
-                    make.width.height.mas_equalTo(avatarSize);
-                }];
-                avatarView.layer.masksToBounds = YES;
-                avatarView.layer.cornerRadius = avatarSize / 2.0;
-                preAvatarImageView = avatarView;
-            }
-        }
-
-        UIImageView *lastAvatarImageView = _replyAvatarImageViews.lastObject;
-
-        [self.messageModifyRepliesButton mas_remakeConstraints:^(MASConstraintMaker *make) {
-            if (self.messageData.direction == MsgDirectionIncoming)  {
-                make.leading.mas_equalTo(lastAvatarImageView.mas_trailing);
-            }
-            else {
-                make.trailing.mas_equalTo(_replyLineView.mas_leading);
-            }
-            
-            make.top.mas_equalTo(avatarY);
-            make.width.mas_equalTo(repliesBtnW);
-            make.height.mas_equalTo(avatarSize);
-        }];
-
-        [_replyLineView mas_remakeConstraints:^(MASConstraintMaker *make) {
-            if (self.messageData.direction == MsgDirectionIncoming) {
-                make.leading.mas_equalTo(self.container.mas_leading).mas_offset(- 1);
-            }
-            else {
-                make.trailing.mas_equalTo(self.container.mas_trailing);
-            }
-            make.top.mas_equalTo(CGRectGetMaxY(self.container.frame) - 14);
-            make.width.mas_equalTo(lineViewW);
-            make.bottom.mas_equalTo(self.messageModifyRepliesButton.mas_centerY);
-        }];
-    } else {
-        _replyLineView.frame = CGRectZero;
-        self.messageModifyRepliesButton.frame = CGRectZero;
-    }
-
-    [_msgTimeLabel mas_makeConstraints:^(MASConstraintMaker *make) {
-        make.width.mas_equalTo(38);
-        make.height.mas_equalTo(self.messageData.msgStatusSize.height);
-        make.bottom.mas_equalTo(self.container).mas_offset(-kScale390(9));
-        make.trailing.mas_equalTo(self.container).mas_offset(-kScale390(16));
-    }];
-    [_msgStatusView mas_makeConstraints:^(MASConstraintMaker *make) {
-        make.width.mas_equalTo(16);
-        make.height.mas_equalTo(self.messageData.msgStatusSize.height);
-        make.bottom.mas_equalTo(self.msgTimeLabel);
-        make.trailing.mas_equalTo(_msgTimeLabel.mas_leading);
-    }];
-    
-}
-
-- (void)fillWithData:(TUIMessageCellData *)data {
-    [super fillWithData:data];
-    self.readReceiptLabel.hidden = YES;
-    self.messageModifyRepliesButton.hidden = YES;
-    [self.messageModifyRepliesButton setImage:nil forState:UIControlStateNormal];
-    //react
-    [self prepareReactTagUI:self.contentView];
-    
-    if (_replyAvatarImageViews.count > 0) {
-        for (UIImageView *imageView in _replyAvatarImageViews) {
-            [imageView removeFromSuperview];
-        }
-        [_replyAvatarImageViews removeAllObjects];
-    }
-    _replyLineView.hidden = YES;
-    if (data.showMessageModifyReplies) {
-        _replyLineView.hidden = NO;
-        self.messageModifyRepliesButton.hidden = NO;
-
-        // line
-        UIImage *lineImage = nil;
-        if (self.messageData.direction == MsgDirectionIncoming) {
-            lineImage = [[TUIImageCache sharedInstance] getResourceFromCache:TUIChatImagePath_Minimalist(@"msg_reply_line_income")];
-        } else {
-            lineImage = [[TUIImageCache sharedInstance] getResourceFromCache:TUIChatImagePath_Minimalist(@"msg_reply_line_outcome")];
-        }
-        lineImage = [lineImage rtl_imageFlippedForRightToLeftLayoutDirection];
-        UIEdgeInsets ei = UIEdgeInsetsFromString(@"{10,0,20,0}");
-        ei = rtlEdgeInsetsWithInsets(ei);
-        _replyLineView.image = [lineImage resizableImageWithCapInsets:ei resizingMode:UIImageResizingModeStretch];
-
-        // avtar
-        NSInteger avatarCount = 0;
-        NSInteger avatarMaxCount = 4;
-        NSMutableDictionary *existSenderMap = [NSMutableDictionary dictionary];
-        for (NSDictionary *senderMap in self.messageData.messageModifyReplies) {
-            NSString *sender = senderMap[@"messageSender"];
-
-            TUIRelationUserModel *userModel = self.messageData.additionalUserInfoResult[sender];
-            NSURL *headUrl = [NSURL URLWithString:userModel.faceURL];
-
-            NSString *existSender = existSenderMap[@"messageSender"];
-            if (!sender || [sender isEqualToString:existSender]) {
-                //exist sender head not add again
-                continue;
-            }
-            UIImageView *avatarView = [[UIImageView alloc] init];
-            if (avatarCount < avatarMaxCount - 1) {
-                existSenderMap[@"messageSender"] = sender;
-                [avatarView sd_setImageWithURL:headUrl placeholderImage:DefaultAvatarImage];
-            } else {
-                [avatarView setImage:[[TUIImageCache sharedInstance] getResourceFromCache:TUIChatImagePath_Minimalist(@"msg_reply_more_icon")]];
-            }
-            [_replyAvatarImageViews addObject:avatarView];
-            [self.contentView addSubview:avatarView];
-
-            if (++avatarCount >= avatarMaxCount) {
-                break;
-            }
-        }
-    }
-
-    _msgTimeLabel.text = [TUITool convertDateToHMStr:self.messageData.innerMessage.timestamp];
-
-    self.indicator.hidden = YES;
-    _msgStatusView.hidden = YES;
-    self.readReceiptLabel.hidden = YES;
-    if (self.messageData.direction == MsgDirectionOutgoing) {
-        self.status = TUIMessageStatus_Unkown;
-        if (self.messageData.status == Msg_Status_Sending || self.messageData.status == Msg_Status_Sending_2) {
-            [self updateMessageStatus:TUIMessageStatus_Sending];
-        } else if (self.messageData.status == Msg_Status_Succ) {
-            [self updateMessageStatus:TUIMessageStatus_Send_Succ];
-        }
-        [self updateReadLabelText];
-    }
-    // tell constraints they need updating
-    [self setNeedsUpdateConstraints];
-
-    // update constraints now so we can animate the change
-    [self updateConstraintsIfNeeded];
-
-    [self layoutIfNeeded];
-
-}
-
-- (void)updateReadLabelText {
-    if (self.messageData.innerMessage.groupID.length > 0) {
-        // group message
-        if (self.messageData.messageReceipt == nil) {
-            // haven't received the message receipt yet
-            return;
-        }
-        NSInteger readCount = self.messageData.messageReceipt.readCount;
-        NSInteger unreadCount = self.messageData.messageReceipt.unreadCount;
-        if (unreadCount == 0) {
-            // All read
-            [self updateMessageStatus:TUIMessageStatus_All_People_Read];
-        } else if (readCount > 0) {
-            // Some read
-            [self updateMessageStatus:TUIMessageStatus_Some_People_Read];
-        }
-    } else {
-        // c2c message
-        BOOL isPeerRead = self.messageData.messageReceipt.isPeerRead;
-        if (isPeerRead) {
-            [self updateMessageStatus:TUIMessageStatus_All_People_Read];
-        }
-    }
-}
-
-- (void)updateMessageStatus:(TUIMessageStatus)status {
-    if (status <= self.status) {
-        return;
-    }
-    if (self.messageData.showReadReceipt && self.messageData.direction == MsgDirectionOutgoing && self.messageData.innerMessage.needReadReceipt &&
-        (self.messageData.innerMessage.userID || self.messageData.innerMessage.groupID)) {
-        _msgStatusView.hidden = NO;
-        _msgStatusView.image = nil;
-    }
-    if (_msgStatusView.isAnimating) {
-        [_msgStatusView stopAnimating];
-        _msgStatusView.animationImages = nil;
-    }
-    switch (status) {
-        case TUIMessageStatus_Sending: {
-            _msgStatusView.animationImages = self.animationImages;
-            [_msgStatusView startAnimating];
-        } break;
-        case TUIMessageStatus_Send_Succ: {
-            _msgStatusView.image = [[TUIImageCache sharedInstance] getResourceFromCache:TUIChatImagePath_Minimalist(@"msg_status_send_succ")];
-        } break;
-        case TUIMessageStatus_Some_People_Read: {
-            _msgStatusView.image = [[TUIImageCache sharedInstance] getResourceFromCache:TUIChatImagePath_Minimalist(@"msg_status_some_people_read")];
-        } break;
-        case TUIMessageStatus_All_People_Read: {
-            _msgStatusView.image = [[TUIImageCache sharedInstance] getResourceFromCache:TUIChatImagePath_Minimalist(@"msg_status_all_people_read")];
-        } break;
-
-        default:
-            break;
-    }
-    self.status = status;
-}
-
-- (void)layoutSubviews {
-    [super layoutSubviews];
-}
-
-#pragma mark - TUIMessageCellProtocol
-+ (CGFloat)getHeight:(TUIMessageCellData *)data withWidth:(CGFloat)width {
-    NSAssert([data isKindOfClass:TUIMessageCellData.class], @"data must be kind of TUIMessageCellData");
-    CGFloat height = [super getHeight:data withWidth:width];
-    if (data.sameToNextMsgSender) {
-        height -= kScale375(16);
-    }
-
-    return height;
-}
-
-@end

+ 0 - 17
ThirdParty/TUIKit/TUIChat/BaseCell/TUIChatPopActionsView.h

@@ -1,17 +0,0 @@
-//
-//  TUIChatPopActionsView.h
-//  TUIChat
-//
-//  Created by wyl on 2022/6/13.
-//  Copyright © 2023 Tencent. All rights reserved.
-//
-
-#import <UIKit/UIKit.h>
-
-NS_ASSUME_NONNULL_BEGIN
-
-@interface TUIChatPopActionsView : UIView
-
-@end
-
-NS_ASSUME_NONNULL_END

+ 0 - 28
ThirdParty/TUIKit/TUIChat/BaseCell/TUIChatPopActionsView.m

@@ -1,28 +0,0 @@
-//
-//  TUIChatPopActionsView.m
-//  TUIChat
-//
-//  Created by wyl on 2022/6/13.
-//  Copyright © 2023 Tencent. All rights reserved.
-//
-
-#import "TUIChatPopActionsView.h"
-
-@implementation TUIChatPopActionsView
-
-- (void)layoutSubviews {
-    [super layoutSubviews];
-
-    [self updateCorner];
-}
-- (void)updateCorner {
-    UIRectCorner corner = UIRectCornerBottomLeft | UIRectCornerBottomRight;
-    CGRect containerBounds = self.bounds;
-    CGRect bounds = CGRectMake(containerBounds.origin.x, containerBounds.origin.y - 1, containerBounds.size.width, containerBounds.size.height);
-    UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:bounds byRoundingCorners:corner cornerRadii:CGSizeMake(5, 5)];
-    CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
-    maskLayer.frame = self.bounds;
-    maskLayer.path = maskPath.CGPath;
-    self.layer.mask = maskLayer;
-}
-@end

+ 0 - 56
ThirdParty/TUIKit/TUIChat/BaseCell/TUIChatPopMenu.h

@@ -1,56 +0,0 @@
-//
-//  TUIChatPopMenu.h
-//  TUIChat
-//
-//  Created by harvy on 2021/11/30.
-//  Copyright © 2023 Tencent. All rights reserved.
-//
-
-#import <UIKit/UIKit.h>
-#import "TUIChatConfig.h"
-#import "TUIChatPopMenuDefine.h"
-#import <TIMCommon/TUIMessageCellData.h>
-#import <TIMCommon/TUIMessageCell.h>
-
-NS_ASSUME_NONNULL_BEGIN
-
-typedef void (^TUIChatPopMenuActionCallback)(void);
-
-@interface TUIChatPopMenuAction : NSObject
-
-@property(nonatomic, copy) NSString *title;
-@property(nonatomic, strong) UIImage *image;
-@property(nonatomic, copy) TUIChatPopMenuActionCallback callback;
-
-/**
- * The higher the weight, the more prominent it is: audioPlayback 11000 Copy 10000, Forward 9000, Multiple Choice 8000, Quote 7000, Reply 5000, Withdraw 4000, Delete 3000.
- */
-@property(nonatomic, assign) NSInteger weight;
-
-- (instancetype)initWithTitle:(NSString *)title image:(UIImage *)image weight:(NSInteger)weight callback:(TUIChatPopMenuActionCallback)callback;
-@end
-
-typedef void (^TUIChatPopMenuHideCallback)(void);
-@interface TUIChatPopMenu : UIView
-@property(nonatomic, copy) TUIChatPopMenuHideCallback hideCallback;
-@property(nonatomic, copy) void (^reactClickCallback)(NSString *faceName);
-@property(nonatomic, weak) TUIMessageCellData *targetCellData;
-@property(nonatomic, weak) TUIMessageCell *targetCell;
-/**
- * TUIChatPopMenu has no emojiView by default. If you need a chatPopMenu with emojiView, use this initializer.
- */
-- (instancetype)initWithEmojiView:(BOOL)hasEmojiView frame:(CGRect)frame;
-
-@property(nonatomic, strong, readonly) UIView *emojiContainerView;
-@property(nonatomic, strong, readonly) UIView *containerView;
-
-- (void)addAction:(TUIChatPopMenuAction *)action;
-- (void)removeAllAction;
-- (void)setArrawPosition:(CGPoint)point adjustHeight:(CGFloat)adjustHeight;
-- (void)showInView:(UIView *__nullable)window;
-- (void)layoutSubview;
-- (void)hideWithAnimation;
-
-@end
-
-NS_ASSUME_NONNULL_END

+ 0 - 555
ThirdParty/TUIKit/TUIChat/BaseCell/TUIChatPopMenu.m

@@ -1,555 +0,0 @@
-//
-//  TUIChatPopMenu.m
-//  TUIChat
-//
-//  Created by harvy on 2021/11/30.
-//  Copyright © 2023 Tencent. All rights reserved.
-//
-
-#import "TUIChatPopMenu.h"
-#import <TIMCommon/TIMDefine.h>
-#import <TUICore/TUIThemeManager.h>
-#import "TUIChatPopActionsView.h"
-#import <TIMCommon/TIMCommonMediator.h>
-#import <TIMCommon/TUIEmojiMeditorProtocol.h>
-#import <TUICore/TUICore.h>
-#import "TUIFaceView.h"
-
-#define maxColumns 5
-#define kContainerInsets UIEdgeInsetsMake(3, 0, 3, 0)
-#define kActionWidth 54
-#define kActionHeight 65
-#define kActionMargin 5
-#define kSepartorHeight 0.5
-#define kSepartorLRMargin 10
-#define kArrowSize CGSizeMake(15, 10)
-#define kEmojiHeight 44
-
-@implementation TUIChatPopMenuAction
-
-- (instancetype)initWithTitle:(NSString *)title image:(UIImage *)image weight:(NSInteger)weight callback:(TUIChatPopMenuActionCallback)callback {
-    if (self = [super init]) {
-        self.title = title;
-        self.image = image;
-        self.weight = weight;
-        self.callback = callback;
-    }
-    return self;
-}
-
-@end
-
-@interface TUIChatPopMenu () <UIGestureRecognizerDelegate,V2TIMAdvancedMsgListener>
-
-/**
- * emojiRecent view and emoji secondary page view
- */
-@property(nonatomic, strong) UIView *emojiContainerView;
-
-@property(nonatomic, strong) UIView *containerView;
-
-@property(nonatomic, strong) NSMutableArray *actions;
-
-@property(nonatomic, assign) CGPoint arrawPoint;
-
-@property(nonatomic, assign) CGFloat adjustHeight;
-
-@property(nonatomic, strong) NSMutableDictionary *actionCallback;
-
-@property(nonatomic, strong) CAShapeLayer *arrowLayer;
-
-@property(nonatomic, assign) CGFloat emojiHeight;
-
-@property(nonatomic, strong) TUIChatPopActionsView *actionsView;
-
-@property(nonatomic, assign) BOOL hasEmojiView;
-
-@end
-
-@implementation TUIChatPopMenu
-
-- (void)addAction:(TUIChatPopMenuAction *)action {
-    if (action) {
-        [self.actions addObject:action];
-    }
-}
-
-- (void)removeAllAction {
-    [self.actions removeAllObjects];
-}
-
-- (void)setArrawPosition:(CGPoint)point adjustHeight:(CGFloat)adjustHeight {
-    point = CGPointMake(point.x, point.y - NavBar_Height);
-    self.arrawPoint = point;
-    self.adjustHeight = adjustHeight;
-}
-
-- (instancetype)initWithEmojiView:(BOOL)hasEmojiView frame:(CGRect)frame {
-    self.hasEmojiView = hasEmojiView;
-    return [self initWithFrame:frame];
-}
-
-- (instancetype)initWithFrame:(CGRect)frame {
-    if (self = [super initWithFrame:frame]) {
-        UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(onTap:)];
-        UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onTap:)];
-        tap.delegate = self;
-        pan.delegate = self;
-        [self addGestureRecognizer:tap];
-        [self addGestureRecognizer:pan];
-        if ([self isAddEmojiView]) {
-            self.emojiHeight = kEmojiHeight;
-        }
-
-        [NSNotificationCenter.defaultCenter addObserver:self selector:@selector(hideWithAnimation) name:@"kTUIChatPopMenuWillHideNotification" object:nil];
-        [NSNotificationCenter.defaultCenter addObserver:self selector:@selector(hideWithAnimation) name:UIKeyboardWillChangeFrameNotification object:nil];
-        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onThemeChanged) name:TUIDidApplyingThemeChangedNotfication object:nil];
-        [[V2TIMManager sharedInstance] addAdvancedMsgListener:self];
-    }
-    return self;
-}
-
-- (BOOL)isAddEmojiView {
-    return self.hasEmojiView && [TUIChatConfig defaultConfig].enablePopMenuEmojiReactAction;
-}
-
-- (void)onTap:(UIGestureRecognizer *)tap {
-    [self hideWithAnimation];
-}
-
-- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
-    if ([touch.view isDescendantOfView:self.emojiContainerView]) {
-        return NO;
-    }
-    if ([touch.view isDescendantOfView:self.containerView]) {
-        return NO;
-    }
-
-    if (@available(iOS 17.0, *)) {
-        CGPoint touchPoint = [touch locationInView:touch.view.nextResponder];
-        CGRect frame = self.targetCell.frame;
-        if (CGRectContainsPoint(frame, touchPoint)) {
-            return NO;
-        }
-    }
-    return YES;
-}
-- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
-    if (@available(iOS 17.0, *)) {
-        CGPoint touchPoint = [self.superview convertPoint:point fromView:self];
-        CGRect frame = self.targetCell.frame;
-        CGRect containerFrame = [self.superview convertRect:self.targetCell.container.frame fromView:self.targetCell];
-//        CGRect popFrame1 =   [self.superview convertRect:self.emojiContainerView.frame fromView:self];
-        CGRect popFrame2 =  [self.superview convertRect:self.containerView.frame fromView:self];
-        if ( CGRectContainsPoint(popFrame2, touchPoint)) {
-            return  [super hitTest:point withEvent:event];
-        }
-        [self.superview convertRect:self.targetCell.container.frame fromView:self.targetCell];
-        
-        if (CGRectContainsPoint(frame, touchPoint)) {
-            if ([self.targetCell respondsToSelector:@selector(textView)]) {
-                UITextView *textView = [self.targetCell valueForKey:@"textView"];
-                if (CGRectContainsPoint(containerFrame,touchPoint)) {
-                    if (textView && [textView isKindOfClass:UITextView.class] && !textView.isSelectable) {
-                        [textView selectAll:self];
-                    }
-                    return textView;
-                }else {
-                    if (textView && [textView isKindOfClass:UITextView.class]) {
-                        [textView selectAll:nil];
-                        [self hideWithAnimation];
-                    }
-                }
-            } else {
-                [self hideWithAnimation];
-            }
-            return [super hitTest:point withEvent:event];
-        }
-        return [super hitTest:point withEvent:event];
-    }
-    else {
-        return [super hitTest:point withEvent:event];
-    }
-}
-- (void)hideWithAnimation {
-    [UIView animateWithDuration:0.3
-        animations:^{
-          self.alpha = 0;
-        }
-        completion:^(BOOL finished) {
-          if (finished) {
-              if (self.hideCallback) {
-                  self.hideCallback();
-              }
-              [self removeFromSuperview];
-          }
-        }];
-}
-
-- (void)hideByClickButton:(UIButton *)button callback:(void (^__nullable)(void))callback {
-    [UIView animateWithDuration:0.3
-        animations:^{
-          self.alpha = 0;
-        }
-        completion:^(BOOL finished) {
-          if (finished) {
-              if (callback) {
-                  callback();
-              }
-              if (self.hideCallback) {
-                  self.hideCallback();
-              }
-              [self removeFromSuperview];
-          }
-        }];
-}
-- (void)showInView:(UIView *)window {
-    if (window == nil) {
-        window = UIApplication.sharedApplication.keyWindow;
-    }
-
-    self.frame = window.bounds;
-    [window addSubview:self];
-
-    [self layoutSubview];
-}
-
-- (void)layoutSubview {
-    self.layer.shadowColor = [UIColor blackColor].CGColor;
-    self.layer.shadowRadius = 5;
-    self.layer.shadowOpacity = 0.5;
-
-    [self updateActionByRank];
-
-    if ([self isAddEmojiView]) {
-        [self prepareEmojiView];
-    }
-
-    [self prepareContainerView];
-
-    if ([self isAddEmojiView]) {
-        [self setupEmojiSubView];
-    }
-
-    [self setupContainerPosition];
-
-    [self updateLayout];
-    
-    if (isRTL()) {
-        [self fitRTLViews];
-    }
-    
-}
-- (void)fitRTLViews {    
-    if (self.actionsView) {
-        for (UIView *subview in self.actionsView.subviews) {
-            if ([subview respondsToSelector:@selector(resetFrameToFitRTL)]) {
-                [subview resetFrameToFitRTL];
-            }
-        }
-    }
-}
-- (void)updateActionByRank {
-    NSArray *ageSortResultArray = [self.actions sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
-      TUIChatPopMenuAction *per1 = obj1;
-      TUIChatPopMenuAction *per2 = obj2;
-      return per1.weight > per2.weight ? NSOrderedAscending : NSOrderedDescending;
-    }];
-    NSMutableArray *filterArray = [NSMutableArray arrayWithArray:ageSortResultArray];
-
-    self.actions = [NSMutableArray arrayWithArray:ageSortResultArray];
-}
-- (void)setupContainerPosition {
-    /**
-     * Calculate the coordinates and correct them, the default arrow points down
-     */
-    CGFloat minTopBottomMargin = (Is_IPhoneX ? (100) : (0.0));
-    CGFloat minLeftRightMargin = 50;
-    CGFloat containerW = self.containerView.bounds.size.width;
-    CGFloat containerH = self.containerView.bounds.size.height;
-    CGFloat upContainerY = self.arrawPoint.y + self.adjustHeight + kArrowSize.height;  // The containerY value when arrow points up
-
-    /**
-     * The default arrow points down
-     */
-    CGFloat containerX = self.arrawPoint.x - 0.5 * containerW;
-    CGFloat containerY = self.arrawPoint.y - kArrowSize.height - containerH - StatusBar_Height - self.emojiHeight;
-    BOOL top = NO;  // The direction of arrow, here is down
-    CGFloat arrawX = 0.5 * containerW;
-    CGFloat arrawY = kArrowSize.height + containerH - 1.5;
-
-    /**
-     * Corrected vertical coordinates
-     */
-    if (containerY < minTopBottomMargin) {
-        /**
-         * At this time, the container is too high, and it is planned to adjust the direction of the arrow to upward.
-         */
-        if (upContainerY + containerH + minTopBottomMargin > self.superview.bounds.size.height) {
-            /**
-             * After adjusting the upward arrow direction, it will cause the entire container to exceed the screen. At this time, the adjustment strategy is
-             * changed to: keep the arrow direction downward and move self.arrawPoint
-             */
-            top = NO;
-            self.arrawPoint = CGPointMake(self.arrawPoint.x, self.arrawPoint.y - containerY);
-            containerY = self.arrawPoint.y - kArrowSize.height - containerH;
-
-        } else {
-            /**
-             * Adjust the direction of the arrow to meet the requirements
-             */
-            top = YES;
-            self.arrawPoint = CGPointMake(self.arrawPoint.x, self.arrawPoint.y + self.adjustHeight - StatusBar_Height - 5);
-            arrawY = -kArrowSize.height;
-            containerY = self.arrawPoint.y + kArrowSize.height;
-        }
-    }
-
-    /**
-     * 
-     * Corrected horizontal coordinates
-     */
-    if (containerX < minLeftRightMargin) {
-        /**
-         * At this time, the container is too close to the left side of the screen and needs to move to the right
-         */
-        CGFloat offset = (minLeftRightMargin - containerX);
-        arrawX = arrawX - offset;
-        containerX = containerX + offset;
-        if (arrawX < 20) {
-            arrawX = 20;
-        }
-
-    } else if (containerX + containerW + minLeftRightMargin > self.bounds.size.width) {
-        /**
-         * At this time, the container is too close to the right side of the screen and needs to be moved to the left
-         */
-        CGFloat offset = containerX + containerW + minLeftRightMargin - self.bounds.size.width;
-        arrawX = arrawX + offset;
-        containerX = containerX - offset;
-        if (arrawX > containerW - 20) {
-            arrawX = containerW - 20;
-        }
-    }
-
-    self.emojiContainerView.frame = CGRectMake(containerX, containerY, containerW, MAX(self.emojiHeight + containerH, 200));
-    self.containerView.frame = CGRectMake(containerX, containerY + self.emojiHeight, containerW, containerH);
-
-    /**
-     * Drawing arrow
-     */
-    self.arrowLayer = [[CAShapeLayer alloc] init];
-    self.arrowLayer.path = [self arrawPath:CGPointMake(arrawX, arrawY) directionTop:top].CGPath;
-    self.arrowLayer.fillColor = TUIChatDynamicColor(@"chat_pop_menu_bg_color", @"#FFFFFF").CGColor;
-    if (top) {
-        if (self.emojiContainerView) {
-            [self.emojiContainerView.layer addSublayer:self.arrowLayer];
-        } else {
-            [self.containerView.layer addSublayer:self.arrowLayer];
-        }
-    } else {
-        [self.containerView.layer addSublayer:self.arrowLayer];
-    }
-}
-
-- (void)prepareEmojiView {
-    if (self.emojiContainerView) {
-        [self.emojiContainerView removeFromSuperview];
-        self.emojiContainerView = nil;
-    }
-
-    self.emojiContainerView = [[UIView alloc] init];
-    [self addSubview:self.emojiContainerView];
-}
-- (void)prepareContainerView {
-    if (self.containerView) {
-        [self.containerView removeFromSuperview];
-        self.containerView = nil;
-    }
-    self.containerView = [[UIView alloc] init];
-    [self addSubview:self.containerView];
-
-    self.actionsView = [[TUIChatPopActionsView alloc] init];
-    self.actionsView.backgroundColor = TUIChatDynamicColor(@"chat_pop_menu_bg_color", @"#FFFFFF");
-    [self.containerView addSubview:self.actionsView];
-
-    int i = 0;
-    for (TUIChatPopMenuAction *action in self.actions) {
-        UIButton *actionButton = [self buttonWithAction:action tag:[self.actions indexOfObject:action]];
-        [self.actionsView addSubview:actionButton];
-        i++;
-        if (i == maxColumns && i < self.actions.count) {
-            UIView *separtorView = [[UIView alloc] init];
-            separtorView.backgroundColor = TIMCommonDynamicColor(@"separator_color", @"#39393B");
-            separtorView.hidden = YES;
-            [self.actionsView addSubview:separtorView];
-            i = 0;
-        }
-    }
-
-    /**
-     * Calculating the size of container
-     */
-    int rows = (self.actions.count % maxColumns == 0) ? (int)self.actions.count / maxColumns : (int)(self.actions.count / maxColumns) + 1;
-    int columns = self.actions.count < maxColumns ? (int)self.actions.count : maxColumns;
-    if ([self isAddEmojiView]) {
-        columns = maxColumns;
-    }
-    CGFloat width = kActionWidth * columns + kActionMargin * (columns + 1) + kContainerInsets.left + kContainerInsets.right;
-    CGFloat height = kActionHeight * rows + (rows - 1) * kSepartorHeight + kContainerInsets.top + kContainerInsets.bottom;
-
-    self.emojiContainerView.frame = CGRectMake(0, 0, width, self.emojiHeight + height);
-    self.containerView.frame = CGRectMake(0, self.emojiHeight, width, height);
-}
-
-- (void)setupEmojiSubView {
-    [self setupEmojiRecentView];
-    [self setupEmojiAdvanceView];
-}
-- (void)setupEmojiRecentView {
-    NSDictionary *param = @{TUICore_TUIChatExtension_ChatPopMenuReactRecentView_Delegate : self};
-    BOOL isRaiseEmojiExtensionSuccess = [TUICore raiseExtension:TUICore_TUIChatExtension_ChatPopMenuReactRecentView_ClassicExtensionID
-                                                     parentView:self.emojiContainerView
-                                                          param:param];
-    if (!isRaiseEmojiExtensionSuccess) {
-        self.emojiHeight = 0;
-    }
-}
-- (void)setupEmojiAdvanceView {
-    NSDictionary *param = @{TUICore_TUIChatExtension_ChatPopMenuReactRecentView_Delegate : self};
-    [TUICore raiseExtension:TUICore_TUIChatExtension_ChatPopMenuReactDetailView_ClassicExtensionID parentView:self.emojiContainerView param:param];
-}
-
-- (void)updateLayout {
-    
-    self.actionsView.frame = CGRectMake(0, -0.5, self.containerView.frame.size.width, self.containerView.frame.size.height);
-
-    int columns = self.actions.count < maxColumns ? (int)self.actions.count : maxColumns;
-    CGFloat containerWidth = kActionWidth * columns + kActionMargin * (columns + 1) + kContainerInsets.left + kContainerInsets.right;
-
-    int i = 0;
-    int currentRow = 0;
-    int currentColumn = 0;
-    for (UIView *subView in self.actionsView.subviews) {
-        if ([subView isKindOfClass:UIButton.class]) {
-            currentRow = i / maxColumns;
-            currentColumn = i % maxColumns;
-
-            CGFloat x = kContainerInsets.left + (currentColumn + 1) * kActionMargin + currentColumn * kActionWidth;
-            CGFloat y = kContainerInsets.top + currentRow * kActionHeight + currentRow * kSepartorHeight;
-            subView.frame = CGRectMake(x, y, kActionWidth, kActionHeight);
-
-            i++;
-        } else {
-            CGFloat y = (currentRow + 1) * kActionHeight + kContainerInsets.top;
-            CGFloat width = containerWidth - 2 * kSepartorLRMargin - kContainerInsets.left - kContainerInsets.right;
-            subView.frame = CGRectMake(kSepartorLRMargin, y, width, kSepartorHeight);
-        }
-    }
-}
-
-- (UIBezierPath *)arrawPath:(CGPoint)point directionTop:(BOOL)top {
-    CGSize arrowSize = kArrowSize;
-    UIBezierPath *arrowPath = [[UIBezierPath alloc] init];
-    [arrowPath moveToPoint:point];
-    if (top) {
-        [arrowPath addLineToPoint:CGPointMake(point.x + arrowSize.width * 0.5, point.y + arrowSize.height)];
-        [arrowPath addLineToPoint:CGPointMake(point.x - arrowSize.width * 0.5, point.y + arrowSize.height)];
-    } else {
-        [arrowPath addLineToPoint:CGPointMake(point.x + arrowSize.width * 0.5, point.y - arrowSize.height)];
-        [arrowPath addLineToPoint:CGPointMake(point.x - arrowSize.width * 0.5, point.y - arrowSize.height)];
-    }
-    [arrowPath closePath];
-    return arrowPath;
-}
-
-- (UIButton *)buttonWithAction:(TUIChatPopMenuAction *)action tag:(NSInteger)tag {
-    UIButton *actionButton = [UIButton buttonWithType:UIButtonTypeCustom];
-    [actionButton setTitleColor:TUIChatDynamicColor(@"chat_pop_menu_text_color", @"#444444")
-                       forState:UIControlStateNormal];
-    actionButton.titleLabel.font = [UIFont systemFontOfSize:10.0];
-    actionButton.titleLabel.numberOfLines = 2;
-    actionButton.titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
-    [actionButton setTitle:action.title forState:UIControlStateNormal];
-    [actionButton setImage:action.image forState:UIControlStateNormal];
-    actionButton.contentMode = UIViewContentModeScaleAspectFit;
-
-    [actionButton addTarget:self action:@selector(buttonHighlightedEnter:) forControlEvents:UIControlEventTouchDown];
-    [actionButton addTarget:self action:@selector(buttonHighlightedEnter:) forControlEvents:UIControlEventTouchDragEnter];
-    [actionButton addTarget:self action:@selector(buttonHighlightedExit:) forControlEvents:UIControlEventTouchDragExit];
-    [actionButton addTarget:self action:@selector(onClick:) forControlEvents:UIControlEventTouchUpInside];
-
-    actionButton.tag = tag;
-
-    CGSize imageSize = CGSizeMake(20, 20);
-    CGSize titleSize = actionButton.titleLabel.frame.size;
-    CGSize textSize = [actionButton.titleLabel.text sizeWithAttributes:@{NSFontAttributeName : actionButton.titleLabel.font}];
-    CGSize frameSize = CGSizeMake(ceilf(textSize.width), ceilf(textSize.height));
-    if (titleSize.width + 0.5 < frameSize.width) {
-        titleSize.width = frameSize.width;
-    }
-    titleSize.width = MIN(titleSize.width, 48);
-    CGFloat totalHeight = (imageSize.height + titleSize.height + 8);
-    actionButton.imageEdgeInsets = UIEdgeInsetsMake(-(totalHeight - imageSize.height), 0.0, 0.0, -titleSize.width);
-    actionButton.titleEdgeInsets = UIEdgeInsetsMake(0, -imageSize.width, -(totalHeight - titleSize.height), 0);
-
-    [self.actionCallback setObject:action.callback forKey:@(tag)];
-
-    return actionButton;
-}
-
-- (void)buttonHighlightedEnter:(UIButton *)sender {
-    sender.backgroundColor = TUIChatDynamicColor(@"", @"#006EFF19");
-}
-- (void)buttonHighlightedExit:(UIButton *)sender {
-    sender.backgroundColor = [UIColor clearColor];
-}
-- (void)onClick:(UIButton *)button {
-    if (![self.actionCallback.allKeys containsObject:@(button.tag)]) {
-        [self hideWithAnimation];
-        return;
-    }
-
-    __weak typeof(self) weakSelf = self;
-    [self hideByClickButton:button
-                   callback:^() {
-                     __strong typeof(weakSelf) strongSelf = weakSelf;
-                     TUIChatPopMenuActionCallback callback = [strongSelf.actionCallback objectForKey:@(button.tag)];
-                     if (callback) {
-                         callback();
-                     }
-                   }];
-}
-
-- (NSMutableArray *)actions {
-    if (_actions == nil) {
-        _actions = [NSMutableArray array];
-    }
-    return _actions;
-}
-
-- (NSMutableDictionary *)actionCallback {
-    if (_actionCallback == nil) {
-        _actionCallback = [NSMutableDictionary dictionary];
-    }
-    return _actionCallback;
-}
-
-// MARK: V2TIMAdvancedMsgListener
-- (void)onRecvMessageRevoked:(NSString *)msgID operateUser:(V2TIMUserFullInfo *)operateUser reason:(NSString *)reason {
-    if ([msgID isEqualToString:self.targetCellData.msgID]) {
-        [self hideWithAnimation];
-    }
-}
-
-// MARK: ThemeChanged
-- (void)applyBorderTheme {
-    if (_arrowLayer) {
-        _arrowLayer.fillColor = TUIChatDynamicColor(@"chat_pop_menu_bg_color", @"#FFFFFF").CGColor;
-    }
-}
-
-- (void)onThemeChanged {
-    [self applyBorderTheme];
-}
-@end

+ 0 - 18
ThirdParty/TUIKit/TUIChat/BaseCell/TUIChatPopMenuDefine.h

@@ -1,18 +0,0 @@
-//
-//  TUIChatPopMenuDefine.h
-//  TUIChat
-//
-//  Created by cologne on 2023/11/22.
-//  Copyright © 2023 Tencent. All rights reserved.
-//
-
-#import <Foundation/Foundation.h>
-
-#define TChatEmojiView_Margin 10
-#define TChatEmojiView_MarginTopBottom 17
-
-#define TChatEmojiView_Padding 20
-#define TChatEmojiView_Page_Height 30
-#define TChatEmojiView_CollectionOffsetY 8
-#define TChatEmojiView_CollectionHeight 107
-

+ 0 - 41
ThirdParty/TUIKit/TUIChat/BaseCell/TUIChatShortcutMenuView.h

@@ -1,41 +0,0 @@
-//
-//  TUIChatShortcutMenuView.h
-//  TUIChat
-//
-//  Created by Tencent on 2023/6/29.
-//  Copyright © 2024 Tencent. All rights reserved.
-
-#import <UIKit/UIKit.h>
-
-NS_ASSUME_NONNULL_BEGIN
-
-@interface TUIChatShortcutMenuCellData : NSObject
-@property (nonatomic, strong) NSString *text;
-@property (nonatomic, assign) SEL cselector;
-@property (nonatomic, strong) id target;
-
-@property (nonatomic, strong) UIColor *textColor;
-@property (nonatomic, strong) UIColor *backgroundColor;
-@property (nonatomic, strong) UIFont *textFont;
-@property (nonatomic, strong) UIColor *borderColor;
-@property (nonatomic, assign) CGFloat borderWidth;
-@property (nonatomic, assign) CGFloat cornerRadius;
-
-- (CGSize)calcSize;
-@end
-
-
-@interface TUIChatShortcutMenuCell : UICollectionViewCell
-@property (nonatomic, strong) UIButton *button;
-@property (nonatomic, strong) TUIChatShortcutMenuCellData *cellData;
-@end
-
-
-@interface TUIChatShortcutMenuView : UIView
-@property (nonatomic, assign) CGFloat viewHeight;
-@property (nonatomic, assign) CGFloat itemHorizontalSpacing;
-- (instancetype)initWithDataSource:(NSArray *)source;
-- (void)updateFrame;
-@end
-
-NS_ASSUME_NONNULL_END

+ 0 - 182
ThirdParty/TUIKit/TUIChat/BaseCell/TUIChatShortcutMenuView.m

@@ -1,182 +0,0 @@
-//
-//  TUIChatShortcutMenuView.m
-//  TUIChat
-//
-//  Created by Tencent on 2023/6/29.
-//  Copyright © 2024 Tencent. All rights reserved.
-
-#import "TUIChatShortcutMenuView.h"
-#import <TUICore/TUICore.h>
-#import <TUICore/TUIDefine.h>
-#import <TIMCommon/TIMDefine.h>
-
-@implementation TUIChatShortcutMenuCellData
-
-- (instancetype)init {
-    self = [super init];
-    if (self) {
-        self.textColor = [UIColor tui_colorWithHex:@"#8F959E"];
-        self.textFont = [UIFont systemFontOfSize:14];
-        self.backgroundColor = [UIColor tui_colorWithHex:@"#F6F7F9"];
-        self.cornerRadius = 16;
-        self.borderColor = [UIColor tui_colorWithHex:@"#C5CBD4"];
-        self.borderWidth = 1.0;
-    }
-    return self;
-}
-
-- (CGSize)calcSize {
-    return [self calcMenuCellButtonSize:self.text];
-}
-
-- (CGSize)calcMenuCellButtonSize:(NSString *)title {
-    CGFloat margin = 28;
-    CGRect rect = [title boundingRectWithSize:CGSizeMake(MAXFLOAT, 32)
-                                      options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading
-                                   attributes:@{ NSFontAttributeName : self.textFont}
-                                      context:nil];
-    return CGSizeMake(rect.size.width + margin, 32);
-}
-
-@end
-
-
-@interface TUIChatShortcutMenuCell()
-
-@end
-
-@implementation TUIChatShortcutMenuCell
-
-- (instancetype)initWithFrame:(CGRect)frame {
-    self = [super initWithFrame:frame];
-    if (self) {
-        self.button = [UIButton new];
-        [self addSubview:self.button];
-    }
-    return self;
-}
-
-- (void)fillWithData:(TUIChatShortcutMenuCellData *)cellData {
-    self.cellData = cellData;
-    [self.button setTitle:cellData.text forState:UIControlStateNormal];
-    [self.button addTarget:cellData.target action:cellData.cselector forControlEvents:UIControlEventTouchUpInside];
-    
-    self.button.layer.cornerRadius = self.cellData.cornerRadius;
-    self.button.titleLabel.font = self.cellData.textFont;
-    self.button.backgroundColor = self.cellData.backgroundColor;
-    [self.button setTitleColor:self.cellData.textColor forState:UIControlStateNormal];
-    self.button.layer.borderWidth = self.cellData.borderWidth;
-    self.button.layer.borderColor = self.cellData.borderColor.CGColor;
-    
-    [self updateConstraints];
-    // tell constraints they need updating
-    [self setNeedsUpdateConstraints];
-    // update constraints now so we can animate the change
-    [self updateConstraintsIfNeeded];
-    [self layoutIfNeeded];
-}
-
-- (void)updateConstraints {
-    [super updateConstraints];
-    
-    CGSize size = [self.cellData calcSize];
-    [self.button mas_makeConstraints:^(MASConstraintMaker *make) {
-        make.leading.mas_equalTo(12);
-        make.centerY.mas_equalTo(self.mas_centerY);
-        make.width.mas_equalTo(size.width);
-        make.height.mas_equalTo(size.height);
-    }];
-}
-
-@end
-
-@interface TUIChatShortcutMenuView() <UICollectionViewDelegate, UICollectionViewDataSource>
-
-@property (nonatomic, strong) UICollectionView *collectionView;
-@property (nonatomic, strong) NSMutableArray *dataSource;
-
-@end
-
-@implementation TUIChatShortcutMenuView
-
-- (instancetype)initWithDataSource:(NSArray *)source {
-    self = [super init];
-    if (self) {
-        self.dataSource = [source mutableCopy];
-        self.backgroundColor = [UIColor tui_colorWithHex:@"#EBF0F6"];
-        [self addSubview:self.collectionView];
-    }
-    return self;
-}
-
-#pragma mark - Public
-- (void)updateFrame {
-    self.mm_left(0).mm_top(0).mm_width(Screen_Width).mm_height(self.viewHeight > 0 ? self.viewHeight : 46);
-    self.collectionView.mm_fill();
-}
-
-#pragma mark - Getter
-- (UICollectionView *)collectionView {
-    if (!_collectionView) {
-        UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
-        [layout setScrollDirection:UICollectionViewScrollDirectionHorizontal];
-        _collectionView = [[UICollectionView alloc] initWithFrame:self.bounds collectionViewLayout:layout];
-        _collectionView.delegate = self;
-        _collectionView.dataSource = self;
-        _collectionView.scrollEnabled = YES;
-        _collectionView.backgroundColor = [UIColor clearColor];
-        _collectionView.showsHorizontalScrollIndicator = NO;
-        [_collectionView registerClass:[TUIChatShortcutMenuCell class] forCellWithReuseIdentifier:@"menuCell"];
-    }
-    return _collectionView;
-}
-
-#pragma mark - UICollectionViewDataSource & Delegate
-- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
-    return 1;
-}
-
-- (NSInteger)collectionView:(UICollectionView *)collectionView 
-     numberOfItemsInSection:(NSInteger)section {
-    return self.dataSource.count;
-}
-
-- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView 
-                  cellForItemAtIndexPath:(NSIndexPath *)indexPath {
-    TUIChatShortcutMenuCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"menuCell" forIndexPath:indexPath];
-    TUIChatShortcutMenuCellData *cellData = self.dataSource[indexPath.row];
-    [cell fillWithData:cellData];
-    return cell;
-}
-
-- (CGSize)collectionView:(UICollectionView *)collectionView 
-                  layout:(UICollectionViewLayout *)collectionViewLayout
-  sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
-    TUIChatShortcutMenuCellData *cellData = self.dataSource[indexPath.row];
-    return CGSizeMake([cellData calcSize].width + 12, [cellData calcSize].height);
-}
-
-- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView 
-                        layout:(UICollectionViewLayout *)collectionViewLayout
-        insetForSectionAtIndex:(NSInteger)section {
-    return UIEdgeInsetsMake(0, 0, 0, 0);
-}
-
-- (CGFloat)collectionView:(UICollectionView *)collectionView 
-                   layout:(UICollectionViewLayout *)collectionViewLayout
-minimumInteritemSpacingForSectionAtIndex:(NSInteger)section {
-    return 0;
-}
-
-- (CGFloat)collectionView:(UICollectionView *)collectionView 
-                   layout:(UICollectionViewLayout*)collectionViewLayout
-minimumLineSpacingForSectionAtIndex:(NSInteger)section {
-    return 0;
-}
-
-- (BOOL)collectionView:(UICollectionView *)collectionView 
-shouldSelectItemAtIndexPath:(NSIndexPath *)indexPath {
-    return YES;
-}
-
-@end

+ 0 - 25
ThirdParty/TUIKit/TUIChat/BaseCell/TUIFaceSegementScrollView.h

@@ -1,25 +0,0 @@
-//
-//  TUIFaceSegementScrollView.h
-//  TUIEmojiPlugin
-//
-//  Created by wyl on 2023/11/15.
-//  Copyright © 2023 Tencent. All rights reserved.
-//
-
-#import <UIKit/UIKit.h>
-#import "TUIFaceView.h"
-#import "TUIFaceVerticalView.h"
-NS_ASSUME_NONNULL_BEGIN
-@class TUIFaceGroup;
-
-@interface TUIFaceSegementScrollView : UIView
-@property(nonatomic, copy) void(^onScrollCallback)(NSInteger indexPage);
-@property(strong, nonatomic) UIScrollView *pageScrollView;
-- (void)setItems:(NSArray<TUIFaceGroup *> *)items delegate:(id <TUIFaceVerticalViewDelegate>) delegate;
-- (void)updateContainerView;
-- (void)setPageIndex:(NSInteger)index;
-- (void)setAllFloatCtrlViewAllowSendSwitch:(BOOL)isAllow;
-- (void)updateRecentView;
-@end
-
-NS_ASSUME_NONNULL_END

部分文件因为文件数量过多而无法显示