utils.ts 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. import TUIChatEngine, { TUITranslateService, TUIStore, StoreName, IMessageModel } from '@tencentcloud/chat-uikit-engine';
  2. export function deepCopy(data: any, hash = new WeakMap()) {
  3. if (typeof data !== 'object' || data === null || data === undefined) {
  4. return data;
  5. }
  6. if (hash.has(data)) {
  7. return hash.get(data);
  8. }
  9. const newData: any = Object.create(Object.getPrototypeOf(data));
  10. const dataKeys = Object.keys(data);
  11. dataKeys.forEach((value) => {
  12. const currentDataValue = data[value];
  13. if (typeof currentDataValue !== 'object' || currentDataValue === null) {
  14. newData[value] = currentDataValue;
  15. } else if (Array.isArray(currentDataValue)) {
  16. newData[value] = [...currentDataValue];
  17. } else if (currentDataValue instanceof Set) {
  18. newData[value] = new Set([...currentDataValue]);
  19. } else if (currentDataValue instanceof Map) {
  20. newData[value] = new Map([...currentDataValue]);
  21. } else {
  22. hash.set(data, data);
  23. newData[value] = deepCopy(currentDataValue, hash);
  24. }
  25. });
  26. return newData;
  27. }
  28. export const handleSkeletonSize = (
  29. width: number,
  30. height: number,
  31. maxWidth: number,
  32. maxHeight: number,
  33. ): { width: number; height: number } => {
  34. const widthToHeight = width / height;
  35. const maxWidthToHeight = maxWidth / maxHeight;
  36. if (width <= maxWidth && height <= maxHeight) {
  37. return { width, height };
  38. }
  39. if (
  40. (width <= maxWidth && height > maxHeight)
  41. || (width > maxWidth && height > maxHeight && widthToHeight <= maxWidthToHeight)
  42. ) {
  43. return { width: width * (maxHeight / height), height: maxHeight };
  44. }
  45. return { width: maxWidth, height: height * (maxWidth / width) };
  46. };
  47. // Image loading complete
  48. export function getImgLoad(container: any, className: string, callback: any) {
  49. const images = container?.querySelectorAll(`.${className}`) || [];
  50. const promiseList = Array.prototype.slice.call(images).map((node: any) => {
  51. return new Promise((resolve: any) => {
  52. node.onload = () => {
  53. resolve(node);
  54. };
  55. node.onloadeddata = () => {
  56. resolve(node);
  57. };
  58. node.onprogress = () => {
  59. resolve(node);
  60. };
  61. if (node.complete) {
  62. resolve(node);
  63. }
  64. });
  65. });
  66. return Promise.all(promiseList)
  67. .then(() => {
  68. callback && callback();
  69. })
  70. .catch((e) => {
  71. console.error('网络异常', e);
  72. });
  73. }
  74. export const isCreateGroupCustomMessage = (message: IMessageModel) => {
  75. return (
  76. message.type === TUIChatEngine.TYPES.MSG_CUSTOM
  77. && message?.getMessageContent()?.businessID === 'group_create'
  78. );
  79. };
  80. /**
  81. * displayMessageReadReceipt: User-level control to display message read status
  82. * After turning off, the messages you send and receive will not have message read status
  83. * You will not be able to see whether the other party has read their messages, and they will also not be able to see whether you have read the messages they sent
  84. *
  85. * enabledMessageReadReceipt: App-level setting to enable read receipts
  86. * @return {boolean} - Returns a boolean value indicating if the message read receipt is enabled globally.
  87. */
  88. export function isEnabledMessageReadReceiptGlobal(): boolean {
  89. return TUIStore.getData(StoreName.USER, 'displayMessageReadReceipt')
  90. && TUIStore.getData(StoreName.APP, 'enabledMessageReadReceipt');
  91. }
  92. export function shallowCopyMessage(message: IMessageModel) {
  93. return Object.assign({}, message);
  94. }
  95. // calculate timestamp
  96. export function calculateTimestamp(timestamp: number): string {
  97. const todayZero = new Date().setHours(0, 0, 0, 0);
  98. const thisYear = new Date(
  99. new Date().getFullYear(),
  100. 0,
  101. 1,
  102. 0,
  103. 0,
  104. 0,
  105. 0,
  106. ).getTime();
  107. const target = new Date(timestamp);
  108. const oneDay = 24 * 60 * 60 * 1000;
  109. const oneWeek = 7 * oneDay;
  110. const diff = todayZero - target.getTime();
  111. function formatNum(num: number): string {
  112. return num < 10 ? '0' + num : num.toString();
  113. }
  114. if (diff <= 0) {
  115. // today, only display hour:minute
  116. return `${formatNum(target.getHours())}:${formatNum(target.getMinutes())}`;
  117. } else if (diff <= oneDay) {
  118. // yesterday, display yesterday:hour:minute
  119. return `${TUITranslateService.t('time.昨天')} ${formatNum(
  120. target.getHours(),
  121. )}:${formatNum(target.getMinutes())}`;
  122. } else if (diff <= oneWeek - oneDay) {
  123. // Within a week, display weekday hour:minute
  124. const weekdays = [
  125. '星期日',
  126. '星期一',
  127. '星期二',
  128. '星期三',
  129. '星期四',
  130. '星期五',
  131. '星期六',
  132. ];
  133. const weekday = weekdays[target.getDay()];
  134. return `${TUITranslateService.t('time.' + weekday)} ${formatNum(
  135. target.getHours(),
  136. )}:${formatNum(target.getMinutes())}`;
  137. } else if (target.getTime() >= thisYear) {
  138. // Over a week, within this year, display mouth/day hour:minute
  139. return `${target.getMonth() + 1}/${target.getDate()} ${formatNum(
  140. target.getHours(),
  141. )}:${formatNum(target.getMinutes())}`;
  142. } else {
  143. // Not within this year, display year/mouth/day hour:minute
  144. return `${target.getFullYear()}/${
  145. target.getMonth() + 1
  146. }/${target.getDate()} ${formatNum(target.getHours())}:${formatNum(
  147. target.getMinutes(),
  148. )}`;
  149. }
  150. }