diff options
| author | syuilo <4439005+syuilo@users.noreply.github.com> | 2025-04-03 15:34:13 +0900 |
|---|---|---|
| committer | syuilo <4439005+syuilo@users.noreply.github.com> | 2025-04-03 15:34:13 +0900 |
| commit | 8b7cba1edeee88695bacefb726f8a5a009c4eeac (patch) | |
| tree | 57324fcddb012faf1b38e6931cbe2226dd888418 /packages | |
| parent | fix: チャット周りの修正 (#15741) (diff) | |
| download | sharkey-8b7cba1edeee88695bacefb726f8a5a009c4eeac.tar.gz sharkey-8b7cba1edeee88695bacefb726f8a5a009c4eeac.tar.bz2 sharkey-8b7cba1edeee88695bacefb726f8a5a009c4eeac.zip | |
🎨
Diffstat (limited to 'packages')
| -rw-r--r-- | packages/frontend/src/pages/chat/room.vue | 25 | ||||
| -rw-r--r-- | packages/frontend/src/utility/timeline-date-separate.ts | 63 |
2 files changed, 87 insertions, 1 deletions
diff --git a/packages/frontend/src/pages/chat/room.vue b/packages/frontend/src/pages/chat/room.vue index dcce70ae89..9942dbeee9 100644 --- a/packages/frontend/src/pages/chat/room.vue +++ b/packages/frontend/src/pages/chat/room.vue @@ -38,7 +38,14 @@ SPDX-License-Identifier: AGPL-3.0-only :moveClass="prefer.s.animation ? $style.transition_x_move : ''" tag="div" class="_gaps" > - <XMessage v-for="message in messages.toReversed()" :key="message.id" :message="message"/> + <template v-for="item in timeline.toReversed()" :key="item.id"> + <XMessage v-if="item.type === 'item'" :message="item.data"/> + <div v-else-if="item.type === 'date'" :class="$style.dateDivider"> + <span><i class="ti ti-chevron-up"></i> {{ item.nextText }}</span> + <span style="height: 1em; width: 1px; background: var(--MI_THEME-divider);"></span> + <span>{{ item.prevText }} <i class="ti ti-chevron-down"></i></span> + </div> + </template> </TransitionGroup> </div> @@ -101,6 +108,7 @@ import MkButton from '@/components/MkButton.vue'; import { useRouter } from '@/router.js'; import { useMutationObserver } from '@/use/use-mutation-observer.js'; import MkInfo from '@/components/MkInfo.vue'; +import { makeDateSeparatedTimelineComputedRef } from '@/utility/timeline-date-separate.js'; const $i = ensureSignin(); const router = useRouter(); @@ -126,6 +134,7 @@ const room = ref<Misskey.entities.ChatRoom | null>(null); const connection = ref<Misskey.IChannelConnection<Misskey.Channels['chatUser']> | Misskey.IChannelConnection<Misskey.Channels['chatRoom']> | null>(null); const showIndicator = ref(false); const timelineEl = useTemplateRef('timelineEl'); +const timeline = makeDateSeparatedTimelineComputedRef(messages); const SCROLL_HEAD_THRESHOLD = 200; @@ -489,4 +498,18 @@ definePage(computed(() => { transition: opacity 0.5s; opacity: 0; } + +.dateDivider { + display: flex; + font-size: 85%; + align-items: center; + justify-content: center; + gap: 0.5em; + opacity: 0.75; + border: solid 0.5px var(--MI_THEME-divider); + border-radius: 999px; + width: fit-content; + padding: 0.5em 1em; + margin: 0 auto; +} </style> diff --git a/packages/frontend/src/utility/timeline-date-separate.ts b/packages/frontend/src/utility/timeline-date-separate.ts new file mode 100644 index 0000000000..f9876a20ff --- /dev/null +++ b/packages/frontend/src/utility/timeline-date-separate.ts @@ -0,0 +1,63 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { computed } from 'vue'; +import type { Ref } from 'vue'; + +function getDateText(dateInstance: Date) { + const date = dateInstance.getDate(); + const month = dateInstance.getMonth() + 1; + return `${month.toString()}/${date.toString()}`; +} + +export type DateSeparetedTimelineItem<T> = { + id: string; + type: 'item'; + data: T; +} | { + id: string; + type: 'date'; + prev: Date; + prevText: string; + next: Date; + nextText: string; +}; + +export function makeDateSeparatedTimelineComputedRef<T extends { id: string; createdAt: string; }>(items: Ref<T[]>) { + return computed<DateSeparetedTimelineItem<T>[]>(() => { + const tl: DateSeparetedTimelineItem<T>[] = []; + for (let i = 0; i < items.value.length; i++) { + const item = items.value[i]; + + const date = new Date(item.createdAt); + const nextDate = items.value[i + 1] ? new Date(items.value[i + 1].createdAt) : null; + + tl.push({ + id: item.id, + type: 'item', + data: item, + }); + + if ( + i !== items.value.length - 1 && + nextDate != null && ( + date.getFullYear() !== nextDate.getFullYear() || + date.getMonth() !== nextDate.getMonth() || + date.getDate() !== nextDate.getDate() + ) + ) { + tl.push({ + id: `date-${item.id}`, + type: 'date', + prev: date, + prevText: getDateText(date), + next: nextDate, + nextText: getDateText(nextDate), + }); + } + } + return tl; + }); +} |