utils.ts 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576
  1. import { formatTime } from "../../../utils/date";
  2. import { decodeText } from "./decodeText";
  3. import TIM from "../../../../TUICore/tim";
  4. import constant from "../../constant";
  5. import { Message } from "../interface";
  6. // Handling avatars
  7. export function handleAvatar(item: any) {
  8. let avatar = "";
  9. switch (item.type) {
  10. case TIM.TYPES.CONV_C2C:
  11. avatar = isUrl(item?.userProfile?.avatar) ? item?.userProfile?.avatar : "https://oss.dayaedu.com/news-info/07/1690787574969.png";
  12. break;
  13. case TIM.TYPES.CONV_GROUP:
  14. avatar = isUrl(item?.groupProfile?.avatar) ? item?.groupProfile?.avatar : "https://oss.dayaedu.com/news-info/07/1690775328089.png";
  15. break;
  16. case TIM.TYPES.CONV_SYSTEM:
  17. avatar = isUrl(item?.groupProfile?.avatar) ? item?.groupProfile?.avatar : "https://web.sdk.qcloud.com/component/TUIKit/assets/group_avatar.png";
  18. break;
  19. }
  20. return avatar;
  21. }
  22. // Handling names
  23. export function handleName(item: any) {
  24. const { t } = (window as any).TUIKitTUICore.config.i18n.useI18n();
  25. let name = "";
  26. switch (item.type) {
  27. case TIM.TYPES.CONV_C2C:
  28. name = item?.userProfile.nick || item?.userProfile?.userID || "";
  29. break;
  30. case TIM.TYPES.CONV_GROUP:
  31. name = item.groupProfile.name || item?.groupProfile?.groupID || "";
  32. break;
  33. case TIM.TYPES.CONV_SYSTEM:
  34. name = t("系统通知");
  35. break;
  36. }
  37. return name;
  38. }
  39. // Handle whether there is someone@
  40. export function handleAt(item: any) {
  41. const { t } = (window as any).TUIKitTUICore.config.i18n.useI18n();
  42. const List: any = [`[${t("TUIConversation.有人@我")}]`, `[${t("TUIConversation.@所有人")}]`, `[${t("TUIConversation.@所有人")}][${t("TUIConversation.有人@我")}]`];
  43. let showAtType = "";
  44. for (let index = 0; index < item.groupAtInfoList.length; index++) {
  45. if (item.groupAtInfoList[index].atTypeArray[0] && item.unreadCount > 0) {
  46. showAtType = List[item.groupAtInfoList[index].atTypeArray[0] - 1];
  47. }
  48. }
  49. return showAtType;
  50. }
  51. export function handleReferenceForShow(message: any) {
  52. const data = {
  53. referenceMessageForShow: "",
  54. referenceMessageType: 0,
  55. };
  56. if (!message || !message?.ID || !message?.type) return data;
  57. switch (message.type) {
  58. case TIM.TYPES.MSG_TEXT:
  59. data.referenceMessageForShow = message?.payload?.text;
  60. data.referenceMessageType = 1;
  61. break;
  62. case TIM.TYPES.MSG_CUSTOM:
  63. data.referenceMessageForShow = "[自定义消息]";
  64. data.referenceMessageType = 2;
  65. break;
  66. case TIM.TYPES.MSG_IMAGE:
  67. data.referenceMessageForShow = "[图片]";
  68. data.referenceMessageType = 3;
  69. break;
  70. case TIM.TYPES.MSG_AUDIO:
  71. data.referenceMessageForShow = "[语音]";
  72. data.referenceMessageType = 4;
  73. break;
  74. case TIM.TYPES.MSG_VIDEO:
  75. data.referenceMessageForShow = "[视频]";
  76. data.referenceMessageType = 5;
  77. break;
  78. case TIM.TYPES.MSG_FILE:
  79. data.referenceMessageForShow = "[文件]";
  80. data.referenceMessageType = 6;
  81. break;
  82. case TIM.TYPES.MSG_FACE:
  83. data.referenceMessageForShow = "[表情]";
  84. data.referenceMessageType = 8;
  85. break;
  86. }
  87. return data;
  88. }
  89. // Internal display of processing message box
  90. export function handleShowLastMessage(item: any) {
  91. const { t } = (window as any).TUIKitTUICore.config.i18n.useI18n();
  92. const { lastMessage } = item;
  93. const conversation = item;
  94. let showNick = "";
  95. let lastMessagePayload = "";
  96. // Judge the number of unread messages and display them only when the message is enabled without interruption.
  97. const showUnreadCount = conversation.unreadCount > 0 && conversation.messageRemindType === TIM.TYPES.MSG_REMIND_ACPT_NOT_NOTE ? `[${conversation.unreadCount > 99 ? "99+" : conversation.unreadCount}${t("TUIConversation.条")}] ` : "";
  98. // Determine the lastmessage sender of the group. Namecard / Nick / userid is displayed by priority
  99. if (conversation.type === TIM.TYPES.CONV_GROUP) {
  100. if (lastMessage?.fromAccount === conversation?.groupProfile.selfInfo.userID) {
  101. showNick = t("TUIConversation.我");
  102. } else {
  103. showNick = lastMessage?.nameCard || lastMessage?.nick || lastMessage?.fromAccount;
  104. }
  105. }
  106. // Display content of lastmessage message body
  107. if (lastMessage?.type === TIM.TYPES.MSG_TEXT) {
  108. lastMessagePayload = lastMessage?.payload.text;
  109. } else if (lastMessage?.type === TIM.TYPES.MSG_CUSTOM) {
  110. const data = JSONToObject(lastMessage?.payload?.data);
  111. if (data?.businessID === 1) {
  112. lastMessagePayload = extractCallingInfoFromMessage(lastMessage);
  113. return lastMessagePayload;
  114. } else if(data?.businessID === "TC_GROUP_NOTICE") {
  115. return '[群公告]'
  116. }
  117. lastMessagePayload = lastMessage?.messageForShow;
  118. } else {
  119. lastMessagePayload = lastMessage?.messageForShow;
  120. }
  121. if (lastMessage?.isRevoked) {
  122. lastMessagePayload = t("TUIChat.撤回了一条消息");
  123. }
  124. if (conversation.type === TIM.TYPES.CONV_GROUP && lastMessage?.type === TIM.TYPES.MSG_GRP_TIP) {
  125. return lastMessagePayload;
  126. }
  127. // Specific display content of message box
  128. return `${showUnreadCount}${showNick ? `${showNick}:` : ""}${lastMessagePayload}`;
  129. }
  130. // Handling system tip message display
  131. export function handleTipMessageShowContext(message: any) {
  132. const { t } = (window as any).TUIKitTUICore.config.i18n.useI18n();
  133. const options: any = {
  134. message,
  135. text: "",
  136. };
  137. let userName = message?.nick || message?.payload?.userIDList?.join(",");
  138. if (message?.payload?.memberList?.length > 0) {
  139. userName = "";
  140. message?.payload?.memberList?.map((user: any) => {
  141. userName += `${user?.nick || user?.userID},`;
  142. });
  143. userName = userName?.slice(0, -1);
  144. }
  145. if (message?.type === TIM?.TYPES?.MSG_GRP_TIP) {
  146. switch (message.payload.operationType) {
  147. case TIM.TYPES.GRP_TIP_MBR_JOIN:
  148. options.text = `${userName} ${t("message.tip.加入群组")}`;
  149. break;
  150. case TIM.TYPES.GRP_TIP_MBR_QUIT:
  151. options.text = `${t("message.tip.群成员")}:${userName} ${t("message.tip.退出群组")}`;
  152. break;
  153. case TIM.TYPES.GRP_TIP_MBR_KICKED_OUT:
  154. // ${t("message.tip.被")}${message.payload.operatorID}
  155. options.text = `${t("message.tip.群成员")}:${userName} ${t("message.tip.踢出群组")}`;
  156. break;
  157. case TIM.TYPES.GRP_TIP_MBR_SET_ADMIN:
  158. options.text = `${t("message.tip.群成员")}:${userName} ${t("message.tip.成为管理员")}`;
  159. break;
  160. case TIM.TYPES.GRP_TIP_MBR_CANCELED_ADMIN:
  161. options.text = `${t("message.tip.群成员")}:${userName} ${t("message.tip.被撤销管理员")}`;
  162. break;
  163. case TIM.TYPES.GRP_TIP_GRP_PROFILE_UPDATED:
  164. // options.text = `${userName} 修改群组资料`;
  165. options.text = handleTipGrpUpdated(message);
  166. break;
  167. case TIM.TYPES.GRP_TIP_MBR_PROFILE_UPDATED:
  168. for (const member of message.payload.memberList) {
  169. if (member.muteTime > 0) {
  170. options.text = `${t("message.tip.群成员")}:${member.userID}${t("message.tip.被禁言")}`;
  171. } else {
  172. options.text = `${t("message.tip.群成员")}:${member.userID}${t("message.tip.被取消禁言")}`;
  173. }
  174. }
  175. break;
  176. default:
  177. options.text = `[${t("message.tip.群提示消息")}]`;
  178. break;
  179. }
  180. } else if (JSONToObject(message?.payload?.data)?.businessID === "group_create") {
  181. const data = JSONToObject(message?.payload?.data);
  182. options.text = `"${data?.opUser}" ` + t(data?.content);
  183. } else {
  184. options.text = extractCallingInfoFromMessage(message);
  185. }
  186. return options;
  187. }
  188. function handleTipGrpUpdated(message: any) {
  189. const { t } = (window as any).TUIKitTUICore.config.i18n.useI18n();
  190. const { payload } = message;
  191. const { newGroupProfile } = payload;
  192. const { operatorID } = payload;
  193. let text = "";
  194. if ("muteAllMembers" in newGroupProfile) {
  195. if (newGroupProfile["muteAllMembers"]) {
  196. text = `${t("message.tip.管理员")} ${operatorID} ${t("message.tip.开启学生禁言")}`;
  197. } else {
  198. text = `${t("message.tip.管理员")} ${operatorID} ${t("message.tip.取消学生禁言")}`;
  199. }
  200. } else if ("ownerID" in newGroupProfile) {
  201. text = `${newGroupProfile["ownerID"]} ${t("message.tip.成为新的群主")}`;
  202. } else if ("groupName" in newGroupProfile) {
  203. text = `${operatorID} ${t("message.tip.修改群名为")} ${newGroupProfile["groupName"]}`;
  204. } else if ("notification" in newGroupProfile) {
  205. text = `${operatorID} ${t("message.tip.发布新公告")}`;
  206. }
  207. return text;
  208. }
  209. // Parsing and handling text message display
  210. export function handleTextMessageShowContext(item: any) {
  211. const options: any = {
  212. text: decodeText(item.payload),
  213. };
  214. return options;
  215. }
  216. // Parsing and handling face message display
  217. export function handleFaceMessageShowContext(item: any) {
  218. const face: any = {
  219. message: item,
  220. name: "",
  221. url: "",
  222. };
  223. face.name = item.payload.data;
  224. if (item.payload.data.indexOf("@2x") < 0) {
  225. face.name = `${face.name}@2x`;
  226. }
  227. face.url = `https://web.sdk.qcloud.com/im/assets/face-elem/${face.name}.png`;
  228. return face;
  229. }
  230. // Parsing and handling location message display
  231. export function handleLocationMessageShowContext(item: any) {
  232. const location: any = {
  233. lon: "",
  234. lat: "",
  235. href: "",
  236. url: "",
  237. description: "",
  238. message: item,
  239. };
  240. location.lon = item.payload.longitude.toFixed(6);
  241. location.lat = item.payload.latitude.toFixed(6);
  242. location.href = "https://map.qq.com/?type=marker&isopeninfowin=1&markertype=1&" + `pointx=${location.lon}&pointy=${location.lat}&name=${item.payload.description}`;
  243. location.url = "https://apis.map.qq.com/ws/staticmap/v2/?" + `center=${location.lat},${location.lon}&zoom=10&size=300*150&maptype=roadmap&` + `markers=size:large|color:0xFFCCFF|label:k|${location.lat},${location.lon}&` + "key=UBNBZ-PTP3P-TE7DB-LHRTI-Y4YLE-VWBBD";
  244. location.description = item.payload.description;
  245. return location;
  246. }
  247. // Parsing and handling image message display
  248. export function handleImageMessageShowContext(item: any) {
  249. return {
  250. progress: item?.status === "unSend" && item.progress,
  251. url: item.payload.imageInfoArray[1].url,
  252. width: item.payload.imageInfoArray[0].width,
  253. height: item.payload.imageInfoArray[0].height,
  254. message: item,
  255. };
  256. }
  257. // Parsing and handling video message display
  258. export function handleVideoMessageShowContext(item: any) {
  259. return {
  260. progress: item?.status === "unSend" && item?.progress,
  261. url: item?.payload?.videoUrl,
  262. snapshotUrl: item?.payload?.snapshotUrl,
  263. snapshotWidth: item?.payload?.snapshotWidth,
  264. snapshotHeight: item?.payload?.snapshotHeight,
  265. message: item,
  266. };
  267. }
  268. // Parsing and handling audio message display
  269. export function handleAudioMessageShowContext(item: any) {
  270. return {
  271. progress: item?.status === "unSend" && item.progress,
  272. url: item.payload.url,
  273. message: item,
  274. second: item.payload.second,
  275. };
  276. }
  277. // Parsing and handling file message display
  278. export function handleFileMessageShowContext(item: any) {
  279. let size = "";
  280. if (item.payload.fileSize >= 1024 * 1024) {
  281. size = `${(item.payload.fileSize / (1024 * 1024)).toFixed(2)} Mb`;
  282. } else if (item.payload.fileSize >= 1024) {
  283. size = `${(item.payload.fileSize / 1024).toFixed(2)} Kb`;
  284. } else {
  285. size = `${item.payload.fileSize.toFixed(2)}B`;
  286. }
  287. return {
  288. progress: item?.status === "unSend" && item.progress,
  289. url: item.payload.fileUrl,
  290. message: item,
  291. name: item.payload.fileName,
  292. size,
  293. };
  294. }
  295. // Parsing and handling merger message display
  296. export function handleMergerMessageShowContext(item: any) {
  297. return { message: item, ...item.payload };
  298. }
  299. // Parse audio and video call messages
  300. export function extractCallingInfoFromMessage(message: any) {
  301. const { t } = (window as any).TUIKitTUICore.config.i18n.useI18n();
  302. let callingMessage: any = {};
  303. let objectData: any = {};
  304. try {
  305. callingMessage = JSONToObject(message?.payload?.data);
  306. } catch (error) {
  307. callingMessage = {};
  308. }
  309. if (callingMessage.businessID !== 1) {
  310. return "";
  311. }
  312. try {
  313. objectData = JSONToObject(callingMessage.data);
  314. } catch (error) {
  315. objectData = {};
  316. }
  317. let inviteeList = "";
  318. callingMessage?.inviteeList?.forEach((userID: string, index: number) => {
  319. if (index < callingMessage?.inviteeList?.length - 1) {
  320. inviteeList += `"${userID}"、`;
  321. } else {
  322. inviteeList += `"${userID}" `;
  323. }
  324. });
  325. const inviter = `"${callingMessage?.inviter}" `;
  326. switch (callingMessage.actionType) {
  327. case 1: {
  328. if (objectData.call_end >= 0 && !callingMessage.groupID) {
  329. return `${t("message.custom.通话时长")}:${formatTime(objectData.call_end)}`;
  330. }
  331. if (callingMessage.groupID && callingMessage.timeout > 0) {
  332. return `${inviter}${t("message.custom.发起通话")}`;
  333. }
  334. if (callingMessage.groupID) {
  335. return `${t("message.custom.结束群聊")}`;
  336. }
  337. if (objectData.data && objectData.data.cmd === "switchToAudio") {
  338. return `${t("message.custom.切换语音通话")}`;
  339. }
  340. if (objectData.data && objectData.data.cmd === "switchToVideo") {
  341. return `${t("message.custom.切换视频通话")}`;
  342. }
  343. return `${t("message.custom.发起通话")}`;
  344. }
  345. case 2:
  346. return `${callingMessage.groupID ? inviter : ""}${t("message.custom.取消通话")}`;
  347. case 3:
  348. if (objectData.data && objectData.data.cmd === "switchToAudio") {
  349. return `${t("message.custom.切换语音通话")}`;
  350. }
  351. if (objectData.data && objectData.data.cmd === "switchToVideo") {
  352. return `${t("message.custom.切换视频通话")}`;
  353. }
  354. return `${callingMessage.groupID ? inviteeList : ""}${t("message.custom.已接听")}`;
  355. case 4:
  356. return `${callingMessage.groupID ? inviteeList : ""}${t("message.custom.拒绝通话")}`;
  357. case 5:
  358. if (objectData.data && objectData.data.cmd === "switchToAudio") {
  359. return `${t("message.custom.切换语音通话")}`;
  360. }
  361. if (objectData.data && objectData.data.cmd === "switchToVideo") {
  362. return `${t("message.custom.切换视频通话")}`;
  363. }
  364. return `${callingMessage.groupID ? inviteeList : ""}${t("message.custom.无应答")}`;
  365. default:
  366. return "";
  367. }
  368. }
  369. // Parsing and handling custom message display
  370. export function handleCustomMessageShowContext(item: any) {
  371. const { t } = (window as any).TUIKitTUICore.config.i18n.useI18n();
  372. const payloadObj = JSONToObject(item?.payload?.data);
  373. if (payloadObj?.businessID === constant.typeEvaluate) {
  374. if (!(payloadObj?.score > 0)) {
  375. payloadObj.score = 1;
  376. item.payload.data = JSON.stringify(payloadObj);
  377. }
  378. }
  379. return {
  380. message: item,
  381. custom: extractCallingInfoFromMessage(item) || `[${t("message.custom.自定义消息")}]`,
  382. };
  383. }
  384. // Parsing and handling system message display
  385. export function translateGroupSystemNotice(message: any) {
  386. const { t } = (window as any).TUIKitTUICore.config.i18n.useI18n();
  387. const groupName = message.payload.groupProfile.name || message.payload.groupProfile.groupID;
  388. switch (message.payload.operationType) {
  389. case 1:
  390. return `${message.payload.operatorID} ${t("message.tip.申请加入群组")}:${groupName}`;
  391. case 2:
  392. return `${t("message.tip.成功加入群组")}:${groupName}`;
  393. case 3:
  394. return `${t("message.tip.申请加入群组")}:${groupName} ${t("message.tip.被拒绝")}`;
  395. case 4:
  396. return `${t("message.tip.你被管理员")}${message.payload.operatorID} ${t("message.tip.踢出群组")}:${groupName}`;
  397. case 5:
  398. return `${t("message.tip.群")}:${groupName} ${t("message.tip.被")} ${message.payload.operatorID} ${t("message.tip.解散")}`;
  399. case 6:
  400. return `${message.payload.operatorID} ${t("message.tip.创建群")}:${groupName}`;
  401. case 7:
  402. return `${message.payload.operatorID} ${t("message.tip.邀请你加群")}:${groupName}`;
  403. case 8:
  404. return `${t("message.tip.你退出群组")}:${groupName}`;
  405. case 9:
  406. return `${t("message.tip.你被")}${message.payload.operatorID} ${t("message.tip.设置为群")}:${groupName} ${t("message.tip.的管理员")}`;
  407. case 10:
  408. return `${t("message.tip.你被")}${message.payload.operatorID} ${t("message.tip.撤销群")}:${groupName} ${t("message.tip.的管理员身份")}`;
  409. case 12:
  410. return `${message.payload.operatorID} ${t("message.tip.邀请你加群")}:${groupName}`;
  411. case 13:
  412. return `${message.payload.operatorID} ${t("message.tip.同意加群")}:${groupName}`;
  413. case 14:
  414. return `${message.payload.operatorID} ${t("message.tip.拒接加群")}:${groupName}`;
  415. case 255:
  416. return `${t("message.tip.自定义群系统通知")}: ${message.payload.userDefinedField}`;
  417. }
  418. }
  419. // Image loading complete
  420. export function getImgLoad(container: any, className: string, callback: any) {
  421. const images = container?.querySelectorAll(`.${className}`) || [];
  422. const promiseList = Array.prototype.slice.call(images).map((node: any) => {
  423. return new Promise((resolve: any, reject: any) => {
  424. node.onload = () => {
  425. resolve(node);
  426. };
  427. node.onloadeddata = () => {
  428. resolve(node);
  429. };
  430. node.onprogress = () => {
  431. resolve(node);
  432. };
  433. if (node.complete) {
  434. resolve(node);
  435. }
  436. });
  437. });
  438. return Promise.all(promiseList)
  439. .then(() => {
  440. callback && callback();
  441. })
  442. .catch((e) => {
  443. console.error("网络异常", e);
  444. });
  445. }
  446. // Determine whether it is url
  447. export function isUrl(url: string) {
  448. return /^(https?:\/\/(([a-zA-Z0-9]+-?)+[a-zA-Z0-9]+\.)+[a-zA-Z]+)(:\d+)?(\/.*)?(\?.*)?(#.*)?$/.test(url);
  449. }
  450. // Handling custom message options
  451. export function handleOptions(businessID: string, version: number, other: any) {
  452. return {
  453. businessID,
  454. version,
  455. ...other,
  456. };
  457. }
  458. // Determine if it is a JSON string
  459. export function isJSON(str: string) {
  460. // eslint-disable-next-line no-useless-escape
  461. if (typeof str === "string") {
  462. try {
  463. const data = JSON.parse(str);
  464. if (data) {
  465. return true;
  466. }
  467. return false;
  468. } catch (error) {
  469. return false;
  470. }
  471. }
  472. return false;
  473. }
  474. // Determine if it is a JSON string
  475. export function JSONToObject(str: string) {
  476. if (!str || !isJSON(str)) {
  477. return str;
  478. }
  479. return JSON.parse(str);
  480. }
  481. // Determine if it is a typing message
  482. export function isTypingMessage(item: any) {
  483. if (!item) return false;
  484. try {
  485. const { businessID }: any = JSONToObject(item?.payload?.data);
  486. if (businessID === constant.typeUserTyping) return true;
  487. } catch {
  488. return false;
  489. }
  490. return false;
  491. }
  492. export function deepCopy(data: any, hash = new WeakMap()) {
  493. if (typeof data !== "object" || data === null) {
  494. throw new TypeError("传入参数不是对象");
  495. }
  496. if (hash.has(data)) {
  497. return hash.get(data);
  498. }
  499. const newData: any = Object.create(Object.getPrototypeOf(data));
  500. const dataKeys = Object.keys(data);
  501. dataKeys.forEach((value) => {
  502. const currentDataValue = data[value];
  503. if (typeof currentDataValue !== "object" || currentDataValue === null) {
  504. newData[value] = currentDataValue;
  505. } else if (Array.isArray(currentDataValue)) {
  506. newData[value] = [...currentDataValue];
  507. } else if (currentDataValue instanceof Set) {
  508. newData[value] = new Set([...currentDataValue]);
  509. } else if (currentDataValue instanceof Map) {
  510. newData[value] = new Map([...currentDataValue]);
  511. } else {
  512. hash.set(data, data);
  513. newData[value] = deepCopy(currentDataValue, hash);
  514. }
  515. });
  516. return newData;
  517. }
  518. export const throttle = (fn: any): (() => void) => {
  519. let isRunning = false;
  520. return (...args) => {
  521. if (isRunning) return;
  522. setTimeout(() => {
  523. fn.apply(this, args);
  524. isRunning = false;
  525. }, 100);
  526. };
  527. };
  528. export const isMessageTip = (message: Message) => {
  529. if (
  530. message?.type === TIM?.TYPES?.MSG_GRP_TIP ||
  531. (message?.type === TIM?.TYPES?.MSG_CUSTOM && message?.conversationType === TIM?.TYPES?.CONV_GROUP && JSONToObject(message?.payload?.data)?.businessID === constant?.TYPE_CALL_MESSAGE) ||
  532. (message?.type === TIM?.TYPES?.MSG_CUSTOM && message?.conversationType === TIM?.TYPES?.CONV_GROUP && JSONToObject(message?.payload?.data)?.businessID === "group_create")
  533. ) {
  534. return true;
  535. }
  536. return false;
  537. };
  538. export const handleSkeletonSize = (width: number, height: number, maxWidth: number, maxHeight: number): { width: number; height: number } => {
  539. const widthToHeight = width / height;
  540. const maxWidthToHeight = maxWidth / maxHeight;
  541. if (width <= maxWidth && height <= maxHeight) {
  542. return { width, height };
  543. } else if ((width <= maxWidth && height > maxHeight) || (width > maxWidth && height > maxHeight && widthToHeight <= maxWidthToHeight)) {
  544. return { width: width * (maxHeight / height), height: maxHeight };
  545. } else {
  546. return { width: maxWidth, height: height * (maxWidth / width) };
  547. }
  548. };