V2TIMMessage+Extension.swift 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. //
  2. // V2TIMMessage+Extension.swift
  3. // Lanu
  4. //
  5. // Created by OneeChan on 2025/12/14.
  6. //
  7. import Foundation
  8. extension V2TIMMessage {
  9. var displayString: String? {
  10. let hasRisk = hasRiskContent
  11. let isRevoked = status == .MSG_STATUS_LOCAL_REVOKED
  12. if hasRisk, !isRevoked {
  13. return TIMLocalizedText.shared.commonText("TUIKitMessageDisplayRiskContent")
  14. }
  15. if isRevoked {
  16. return revokeDisplayString
  17. }
  18. return displayStringForMessageElement
  19. }
  20. private var revokeDisplayString: String? {
  21. var revoker = sender
  22. if let revokerInfo {
  23. revoker = revokerInfo.userID
  24. }
  25. var content = TIMLocalizedText.shared.commonText("TUIKitMessageTipsNormalRecallMessage")
  26. if revoker == sender {
  27. if isSelf {
  28. content = TIMLocalizedText.shared.commonText("TUIKitMessageTipsYouRecallMessage")
  29. } else {
  30. if userID?.isEmpty == false {
  31. content = TIMLocalizedText.shared.commonText("TUIKitMessageTipsOthersRecallMessage")
  32. } else if groupID?.isEmpty == false {
  33. content = String(format: TIMLocalizedText.shared.commonText("TUIKitMessageTipsRecallMessageFormat"), showName)
  34. } else { }
  35. }
  36. } else {
  37. var userName = showName
  38. if let revokerInfo {
  39. userName = revokerInfo.nickName ?? ""
  40. }
  41. content = String(format: TIMLocalizedText.shared.commonText("TUIKitMessageTipsRecallMessageFormat"), userName)
  42. }
  43. return content
  44. }
  45. private var displayStringForMessageElement: String? {
  46. switch elemType {
  47. case .ELEM_TYPE_TEXT: textElem?.text?.getEmojiDescContent
  48. case .ELEM_TYPE_IMAGE: TIMLocalizedText.shared.commonText("TUIkitMessageTypeImage")
  49. case .ELEM_TYPE_SOUND: TIMLocalizedText.shared.commonText("TUIKitMessageTypeVoice")
  50. case .ELEM_TYPE_VIDEO: TIMLocalizedText.shared.commonText("TUIkitMessageTypeVideo")
  51. case .ELEM_TYPE_FILE: TIMLocalizedText.shared.commonText("TUIkitMessageTypeFile")
  52. case .ELEM_TYPE_FACE: TIMLocalizedText.shared.commonText("TUIKitMessageTypeAnimateEmoji")
  53. case .ELEM_TYPE_MERGER: String(format: "[%@]", TIMLocalizedText.shared.commonText("TUIKitRelayChatHistory"))
  54. case .ELEM_TYPE_GROUP_TIPS: groupTipsDisplayString
  55. case .ELEM_TYPE_CUSTOM: TIMLocalizedText.shared.commonText("TUIKitMessageTipsUnsupportCustomMessage")
  56. default: TIMLocalizedText.shared.commonText("TUIKitMessageTipsUnsupportCustomMessage")
  57. }
  58. }
  59. private var groupTipsDisplayString: String? {
  60. guard let tips = groupTipsElem else { return nil }
  61. let opUser = groupOpMemberShowName(info: tips.opMember)
  62. let userList = groupUserNameList
  63. var str = ""
  64. switch tips.type {
  65. case .GROUP_TIPS_TYPE_JOIN:
  66. if !opUser.isEmpty {
  67. if userList.isEmpty
  68. || (userList.count == 1
  69. && opUser == userList.first) {
  70. str = String(format: TIMLocalizedText.shared.commonText("TUIKitMessageTipsJoinGroupFormat"), opUser)
  71. } else {
  72. let users = userList.joined(separator: "、")
  73. str = String(format: TIMLocalizedText.shared.commonText("TUIKitMessageTipsInviteJoinGroupFormat"), opUser, users)
  74. }
  75. }
  76. case .GROUP_TIPS_TYPE_INVITE:
  77. if !userList.isEmpty {
  78. let users = userList.joined(separator: "、")
  79. str = String(format: TIMLocalizedText.shared.commonText("TUIKitMessageTipsInviteJoinGroupFormat"), opUser, users)
  80. }
  81. case .GROUP_TIPS_TYPE_QUIT:
  82. if !opUser.isEmpty {
  83. str = String(format: TIMLocalizedText.shared.commonText("TUIKitMessageTipsLeaveGroupFormat"), opUser)
  84. }
  85. case .GROUP_TIPS_TYPE_KICKED:
  86. if !userList.isEmpty {
  87. let users = userList.joined(separator: "、")
  88. str = String(format: TIMLocalizedText.shared.commonText("TUIKitMessageTipsKickoffGroupFormat"), opUser, users)
  89. }
  90. case .GROUP_TIPS_TYPE_SET_ADMIN:
  91. if !userList.isEmpty {
  92. let users = userList.joined(separator: "、")
  93. str = String(format: TIMLocalizedText.shared.commonText("TUIKitMessageTipsSettAdminFormat"), users)
  94. }
  95. case .GROUP_TIPS_TYPE_CANCEL_ADMIN:
  96. if !userList.isEmpty {
  97. let users = userList.joined(separator: "、")
  98. str = String(format: TIMLocalizedText.shared.commonText("TUIKitMessageTipsCancelAdminFormat"), users)
  99. }
  100. case .GROUP_TIPS_TYPE_GROUP_INFO_CHANGE:
  101. str = opGroupInfoChangedFormatStr(opUser: opUser, userList: userList, tips: tips)
  102. case .GROUP_TIPS_TYPE_MEMBER_INFO_CHANGE:
  103. tips.memberChangeInfoList.forEach { info in
  104. let userId = info.userID
  105. let muteTime = info.muteTime
  106. let showName = if let user = tips.memberList.first(where: { $0.userID == userId }) {
  107. groupOpMemberShowName(info: user)
  108. } else {
  109. ""
  110. }
  111. str = String(format: "%@ %@", userId?.isMyUid == true ? TIMLocalizedText.shared.commonText("You") : showName, muteTime == 0 ? TIMLocalizedText.shared.commonText("TUIKitMessageTipsUnmute") : TIMLocalizedText.shared.commonText("TUIKitMessageTipsMute"))
  112. }
  113. case .GROUP_TIPS_TYPE_PINNED_MESSAGE_ADDED:
  114. if !opUser.isEmpty {
  115. str = String(format: TIMLocalizedText.shared.commonText("TUIKitMessageTipsGroupPinMessage"), opUser)
  116. }
  117. case .GROUP_TIPS_TYPE_PINNED_MESSAGE_DELETED:
  118. if !opUser.isEmpty {
  119. str = String(format: TIMLocalizedText.shared.commonText("TUIKitMessageTipsGroupUnPinMessage"), opUser)
  120. }
  121. default:
  122. break
  123. }
  124. return str
  125. }
  126. private var showName: String {
  127. if let nameCard, !nameCard.isEmpty {
  128. nameCard
  129. } else if let friendRemark, !friendRemark.isEmpty {
  130. friendRemark
  131. } else if let nickName, !nickName.isEmpty {
  132. nickName
  133. } else {
  134. sender ?? ""
  135. }
  136. }
  137. private func groupOpMemberShowName(info: V2TIMGroupMemberInfo) -> String {
  138. if let nameCard = info.nameCard, !nameCard.isEmpty {
  139. nameCard
  140. } else if let nickName = info.nickName, !nickName.isEmpty {
  141. nickName
  142. } else {
  143. info.userID ?? ""
  144. }
  145. }
  146. private var groupUserNameList: [String] {
  147. groupTipsElem?.memberList.compactMap {
  148. groupOpMemberShowName(info: $0)
  149. } ?? []
  150. }
  151. private func opGroupInfoChangedFormatStr(opUser: String, userList: [String], tips: V2TIMGroupTipsElem) -> String {
  152. var str = String(format: "%@", opUser)
  153. for info in tips.groupChangeInfoList {
  154. switch info.type {
  155. case .GROUP_INFO_CHANGE_TYPE_NAME:
  156. str = String(format: TIMLocalizedText.shared.commonText("TUIkitMessageTipsEditGroupNameFormat"), str, info.value ?? "")
  157. case .GROUP_INFO_CHANGE_TYPE_INTRODUCTION:
  158. str = String(format: TIMLocalizedText.shared.commonText("TUIKitMessageTipsEditGroupIntroFormat"), str, info.value ?? "")
  159. case .GROUP_INFO_CHANGE_TYPE_NOTIFICATION:
  160. if let value = info.value, !value.isEmpty {
  161. str = String(format: TIMLocalizedText.shared.commonText("TUIKitMessageTipsEditGroupAnnounceFormat"), str, value)
  162. } else {
  163. str = String(format: TIMLocalizedText.shared.commonText("TUIKitMessageTipsDeleteGroupAnnounceFormat"), str)
  164. }
  165. case .GROUP_INFO_CHANGE_TYPE_FACE:
  166. str = String(format: TIMLocalizedText.shared.commonText("TUIKitMessageTipsEditGroupAvatarFormat"), str)
  167. case .GROUP_INFO_CHANGE_TYPE_OWNER:
  168. if !userList.isEmpty {
  169. str = String(format: TIMLocalizedText.shared.commonText("TUIKitMessageTipsEditGroupOwnerFormat"), str, userList.first!)
  170. } else {
  171. str = String(format: TIMLocalizedText.shared.commonText("TUIKitMessageTipsEditGroupOwnerFormat"), str, info.value ?? "")
  172. }
  173. case .GROUP_INFO_CHANGE_TYPE_SHUT_UP_ALL:
  174. if info.boolValue {
  175. str = String(format: TIMLocalizedText.shared.commonText("TUIKitSetShutupAllFormat"), opUser)
  176. } else {
  177. str = String(format: TIMLocalizedText.shared.commonText("TUIKitCancelShutupAllFormat"), opUser)
  178. }
  179. case .GROUP_INFO_CHANGE_TYPE_GROUP_ADD_OPT:
  180. let addOpt = info.intValue
  181. var addOptDesc = "unknown"
  182. if addOpt == V2TIMGroupAddOpt.GROUP_ADD_FORBID.rawValue {
  183. addOptDesc = TIMLocalizedText.shared.commonText("TUIKitGroupProfileJoinDisable")
  184. } else if addOpt == V2TIMGroupAddOpt.GROUP_ADD_AUTH.rawValue {
  185. addOptDesc = TIMLocalizedText.shared.commonText("TUIKitGroupProfileAdminApprove")
  186. } else if addOpt == V2TIMGroupAddOpt.GROUP_ADD_ANY.rawValue {
  187. addOptDesc = TIMLocalizedText.shared.commonText("TUIKitGroupProfileAutoApproval")
  188. }
  189. str = String(format: TIMLocalizedText.shared.commonText("TUIKitMessageTipsEditGroupAddOptFormat"), str, addOptDesc)
  190. case .GROUP_INFO_CHANGE_TYPE_GROUP_APPROVE_OPT:
  191. let addOpt = info.intValue
  192. var addOptDesc = "unknown"
  193. if addOpt == V2TIMGroupAddOpt.GROUP_ADD_FORBID.rawValue {
  194. addOptDesc = TIMLocalizedText.shared.commonText("TUIKitGroupProfileInviteDisable")
  195. } else if addOpt == V2TIMGroupAddOpt.GROUP_ADD_AUTH.rawValue {
  196. addOptDesc = TIMLocalizedText.shared.commonText("TUIKitGroupProfileAdminApprove")
  197. } else if addOpt == V2TIMGroupAddOpt.GROUP_ADD_ANY.rawValue {
  198. addOptDesc = TIMLocalizedText.shared.commonText("TUIKitGroupProfileAutoApproval")
  199. }
  200. str = String(format: TIMLocalizedText.shared.commonText("TUIKitMessageTipsEditGroupInviteOptFormat"), str, addOptDesc)
  201. default:
  202. break
  203. }
  204. }
  205. return str
  206. }
  207. }