diff --git a/packages/frontend/src/components/SkNoteDetailed.vue b/packages/frontend/src/components/SkNoteDetailed.vue index ced7e7a17..e20101ba4 100644 --- a/packages/frontend/src/components/SkNoteDetailed.vue +++ b/packages/frontend/src/components/SkNoteDetailed.vue @@ -178,7 +178,7 @@ SPDX-License-Identifier: AGPL-3.0-only
{{ i18n.ts.loadReplies }}
- +
@@ -266,6 +266,7 @@ import MkPagination, { type Paging } from '@/components/MkPagination.vue'; import MkReactionIcon from '@/components/MkReactionIcon.vue'; import MkButton from '@/components/MkButton.vue'; import { boostMenuItems, type Visibility } from '@/scripts/boost-quote.js'; +import { sortReplies } from '@/scripts/reply-sorting.js'; const props = defineProps<{ note: Misskey.entities.Note; @@ -327,6 +328,7 @@ const allowAnim = ref(defaultStore.state.advancedMfm && defaultStore.state.anima const showTicker = (defaultStore.state.instanceTicker === 'always') || (defaultStore.state.instanceTicker === 'remote' && appearNote.value.user.instance); const conversation = ref([]); const replies = ref([]); +const sortedReplies = computed(() => sortReplies(props.note, replies.value)); const quotes = ref([]); const canRenote = computed(() => ['public', 'home'].includes(appearNote.value.visibility) || (appearNote.value.visibility === 'followers' && appearNote.value.userId === $i?.id)); const defaultLike = computed(() => defaultStore.state.like ? defaultStore.state.like : null); diff --git a/packages/frontend/src/components/SkNoteSub.vue b/packages/frontend/src/components/SkNoteSub.vue index 1cffd8dd6..e04c66ff8 100644 --- a/packages/frontend/src/components/SkNoteSub.vue +++ b/packages/frontend/src/components/SkNoteSub.vue @@ -73,7 +73,7 @@ SPDX-License-Identifier: AGPL-3.0-only
{{ i18n.ts.continueThread }} @@ -114,6 +114,7 @@ import { claimAchievement } from '@/scripts/achievements.js'; import { getNoteMenu } from '@/scripts/get-note-menu.js'; import { useNoteCapture } from '@/scripts/use-note-capture.js'; import { boostMenuItems, type Visibility } from '@/scripts/boost-quote.js'; +import { sortReplies } from '@/scripts/reply-sorting.js'; const canRenote = computed(() => ['public', 'home'].includes(props.note.visibility) || props.note.userId === $i.id); const hideLine = computed(() => { return props.detail ? true : false; }); @@ -151,6 +152,7 @@ const likeButton = shallowRef(); let appearNote = computed(() => isRenote ? props.note.renote as Misskey.entities.Note : props.note); const defaultLike = computed(() => defaultStore.state.like ? defaultStore.state.like : null); const replies = ref([]); +const sortedReplies = computed(() => sortReplies(props.note, replies.value)); const isRenote = ( props.note.renote != null && diff --git a/packages/frontend/src/scripts/reply-sorting.ts b/packages/frontend/src/scripts/reply-sorting.ts new file mode 100644 index 000000000..43485ee19 --- /dev/null +++ b/packages/frontend/src/scripts/reply-sorting.ts @@ -0,0 +1,17 @@ +import * as Misskey from 'misskey-js'; + +// sorts replies to self before other replies to make threads easier to read +export function sortReplies(root: Misskey.entities.Note, replies: Misskey.entities.Note[]): Misskey.entities.Note[] { + const result: Misskey.entities.Note[] = []; + + for (const reply of replies) { + if (root.userId === reply.userId) { + result.unshift(reply); + } else { + result.push(reply); + } + } + + return result; +} +