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;
+}
+