merge: feat: sort replies to self before other replies (attempt 2) (!424)

View MR for information: https://activitypub.software/TransFem-org/Sharkey/-/merge_requests/424
This commit is contained in:
S Kopper 2024-04-03 16:03:32 +00:00
commit 0beb523cd9
3 changed files with 23 additions and 2 deletions

View file

@ -178,7 +178,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<div v-if="!repliesLoaded" style="padding: 16px"> <div v-if="!repliesLoaded" style="padding: 16px">
<MkButton style="margin: 0 auto;" primary rounded @click="loadReplies">{{ i18n.ts.loadReplies }}</MkButton> <MkButton style="margin: 0 auto;" primary rounded @click="loadReplies">{{ i18n.ts.loadReplies }}</MkButton>
</div> </div>
<SkNoteSub v-for="note in replies" :key="note.id" :note="note" :class="$style.reply" :detail="true" :expandAllCws="props.expandAllCws" :onDeleteCallback="removeReply" :isReply="true"/> <SkNoteSub v-for="note in sortedReplies" :key="note.id" :note="note" :class="$style.reply" :detail="true" :expandAllCws="props.expandAllCws" :onDeleteCallback="removeReply" :isReply="true"/>
</div> </div>
<div v-else-if="tab === 'renotes'" :class="$style.tab_renotes"> <div v-else-if="tab === 'renotes'" :class="$style.tab_renotes">
<MkPagination :pagination="renotesPagination" :disableAutoLoad="true"> <MkPagination :pagination="renotesPagination" :disableAutoLoad="true">
@ -266,6 +266,7 @@ import MkPagination, { type Paging } from '@/components/MkPagination.vue';
import MkReactionIcon from '@/components/MkReactionIcon.vue'; import MkReactionIcon from '@/components/MkReactionIcon.vue';
import MkButton from '@/components/MkButton.vue'; import MkButton from '@/components/MkButton.vue';
import { boostMenuItems, type Visibility } from '@/scripts/boost-quote.js'; import { boostMenuItems, type Visibility } from '@/scripts/boost-quote.js';
import { sortReplies } from '@/scripts/reply-sorting.js';
const props = defineProps<{ const props = defineProps<{
note: Misskey.entities.Note; 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 showTicker = (defaultStore.state.instanceTicker === 'always') || (defaultStore.state.instanceTicker === 'remote' && appearNote.value.user.instance);
const conversation = ref<Misskey.entities.Note[]>([]); const conversation = ref<Misskey.entities.Note[]>([]);
const replies = ref<Misskey.entities.Note[]>([]); const replies = ref<Misskey.entities.Note[]>([]);
const sortedReplies = computed(() => sortReplies(props.note, replies.value));
const quotes = ref<Misskey.entities.Note[]>([]); const quotes = ref<Misskey.entities.Note[]>([]);
const canRenote = computed(() => ['public', 'home'].includes(appearNote.value.visibility) || (appearNote.value.visibility === 'followers' && appearNote.value.userId === $i?.id)); 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); const defaultLike = computed(() => defaultStore.state.like ? defaultStore.state.like : null);

View file

@ -73,7 +73,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</div> </div>
</div> </div>
<template v-if="depth < numberOfReplies"> <template v-if="depth < numberOfReplies">
<SkNoteSub v-for="reply in replies" :key="reply.id" :note="reply" :class="[$style.reply, { [$style.single]: replies.length === 1 }]" :detail="true" :depth="depth + 1" :expandAllCws="props.expandAllCws" :onDeleteCallback="removeReply" :isReply="props.isReply"/> <SkNoteSub v-for="reply in sortedReplies" :key="reply.id" :note="reply" :class="[$style.reply, { [$style.single]: replies.length === 1 }]" :detail="true" :depth="depth + 1" :expandAllCws="props.expandAllCws" :onDeleteCallback="removeReply" :isReply="props.isReply"/>
</template> </template>
<div v-else :class="$style.more"> <div v-else :class="$style.more">
<MkA class="_link" :to="notePage(note)">{{ i18n.ts.continueThread }} <i class="ph-caret-double-right ph-bold ph-lg"></i></MkA> <MkA class="_link" :to="notePage(note)">{{ i18n.ts.continueThread }} <i class="ph-caret-double-right ph-bold ph-lg"></i></MkA>
@ -114,6 +114,7 @@ import { claimAchievement } from '@/scripts/achievements.js';
import { getNoteMenu } from '@/scripts/get-note-menu.js'; import { getNoteMenu } from '@/scripts/get-note-menu.js';
import { useNoteCapture } from '@/scripts/use-note-capture.js'; import { useNoteCapture } from '@/scripts/use-note-capture.js';
import { boostMenuItems, type Visibility } from '@/scripts/boost-quote.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 canRenote = computed(() => ['public', 'home'].includes(props.note.visibility) || props.note.userId === $i.id);
const hideLine = computed(() => { return props.detail ? true : false; }); const hideLine = computed(() => { return props.detail ? true : false; });
@ -151,6 +152,7 @@ const likeButton = shallowRef<HTMLElement>();
let appearNote = computed(() => isRenote ? props.note.renote as Misskey.entities.Note : props.note); let appearNote = computed(() => isRenote ? props.note.renote as Misskey.entities.Note : props.note);
const defaultLike = computed(() => defaultStore.state.like ? defaultStore.state.like : null); const defaultLike = computed(() => defaultStore.state.like ? defaultStore.state.like : null);
const replies = ref<Misskey.entities.Note[]>([]); const replies = ref<Misskey.entities.Note[]>([]);
const sortedReplies = computed(() => sortReplies(props.note, replies.value));
const isRenote = ( const isRenote = (
props.note.renote != null && props.note.renote != null &&

View file

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