message-timestamp.vue 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. <template>
  2. <div
  3. v-if="timestampShowFlag"
  4. class="message-timestamp"
  5. >
  6. {{ timestampShowContent }}
  7. </div>
  8. </template>
  9. <script setup lang="ts">
  10. import { toRefs, ref, watch } from '../../../../adapter-vue';
  11. import { TUITranslateService } from '@tencentcloud/chat-uikit-engine';
  12. const props = defineProps({
  13. currTime: {
  14. type: Number,
  15. default: 0,
  16. },
  17. prevTime: {
  18. type: Number,
  19. default: 0,
  20. },
  21. });
  22. const { currTime, prevTime } = toRefs(props);
  23. const timestampShowFlag = ref(false);
  24. const timestampShowContent = ref('');
  25. const handleItemTime = (currTime: number, prevTime: number) => {
  26. timestampShowFlag.value = false;
  27. if (currTime <= 0) {
  28. return '';
  29. } else if (!prevTime || prevTime <= 0) {
  30. timestampShowFlag.value = true;
  31. return calculateTimestamp(currTime * 1000);
  32. } else {
  33. const minDiffToShow = 10 * 60; // 10min 10*60s
  34. const diff = currTime - prevTime; // s
  35. if (diff >= minDiffToShow) {
  36. timestampShowFlag.value = true;
  37. return calculateTimestamp(currTime * 1000);
  38. }
  39. }
  40. return '';
  41. };
  42. watch(
  43. () => [currTime.value, prevTime.value],
  44. (newVal: any, oldVal: any) => {
  45. if (newVal?.toString() === oldVal?.toString()) {
  46. return;
  47. } else {
  48. timestampShowContent.value = handleItemTime(
  49. currTime.value,
  50. prevTime.value,
  51. );
  52. }
  53. },
  54. {
  55. immediate: true,
  56. },
  57. );
  58. // 计算时间戳函数
  59. // calculate timestamp
  60. function calculateTimestamp(timestamp: number): string {
  61. const todayZero = new Date().setHours(0, 0, 0, 0);
  62. const thisYear = new Date(
  63. new Date().getFullYear(),
  64. 0,
  65. 1,
  66. 0,
  67. 0,
  68. 0,
  69. 0,
  70. ).getTime();
  71. const target = new Date(timestamp);
  72. const oneDay = 24 * 60 * 60 * 1000;
  73. const oneWeek = 7 * oneDay;
  74. const diff = todayZero - target.getTime();
  75. function formatNum(num: number): string {
  76. return num < 10 ? '0' + num : num.toString();
  77. }
  78. if (diff <= 0) {
  79. // today, only display hour:minute
  80. return `${formatNum(target.getHours())}:${formatNum(target.getMinutes())}`;
  81. } else if (diff <= oneDay) {
  82. // yesterday, display yesterday:hour:minute
  83. return `${TUITranslateService.t('time.昨天')} ${formatNum(
  84. target.getHours(),
  85. )}:${formatNum(target.getMinutes())}`;
  86. } else if (diff <= oneWeek - oneDay) {
  87. // Within a week, display weekday hour:minute
  88. const weekdays = [
  89. '星期日',
  90. '星期一',
  91. '星期二',
  92. '星期三',
  93. '星期四',
  94. '星期五',
  95. '星期六',
  96. ];
  97. const weekday = weekdays[target.getDay()];
  98. return `${TUITranslateService.t('time.' + weekday)} ${formatNum(
  99. target.getHours(),
  100. )}:${formatNum(target.getMinutes())}`;
  101. } else if (target.getTime() >= thisYear) {
  102. // Over a week, within this year, display mouth/day hour:minute
  103. return `${target.getMonth() + 1}/${target.getDate()} ${formatNum(
  104. target.getHours(),
  105. )}:${formatNum(target.getMinutes())}`;
  106. } else {
  107. // Not within this year, display year/mouth/day hour:minute
  108. return `${target.getFullYear()}/${
  109. target.getMonth() + 1
  110. }/${target.getDate()} ${formatNum(target.getHours())}:${formatNum(
  111. target.getMinutes(),
  112. )}`;
  113. }
  114. }
  115. </script>
  116. <style lang="scss" scoped>
  117. @import "../../../../assets/styles/common";
  118. .message-timestamp {
  119. margin: 0 auto;
  120. color: #999;
  121. font-size: 12px;
  122. overflow-wrap: anywhere;
  123. display: flex;
  124. place-content: center center;
  125. align-items: center;
  126. text-align: center;
  127. padding: 0 20px 30px;
  128. }
  129. </style>