Compare commits

...

4 commits

Author SHA1 Message Date
S Kopper
0beb523cd9 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
2024-04-03 16:03:32 +00:00
Marie
8c955fcce5 merge: use correct note design in favorites page - fixes #483 (!481)
View MR for information: https://activitypub.software/TransFem-org/Sharkey/-/merge_requests/481

Closes #483

Approved-by: Amelia Yukii <amelia.yukii@shourai.de>
Approved-by: Marie <marie@kaifa.ch>
2024-04-03 09:28:01 +00:00
dakkar
bd7c4f66f3 use correct note design in favorites page - fixes #483 2024-03-27 16:03:35 +00:00
ShittyKopper
e74ff698c9 feat: sort replies to self before other replies 2024-02-19 12:23:16 +03:00
5 changed files with 31 additions and 5 deletions

View file

@ -55,8 +55,6 @@ import { i18n } from '@/i18n.js';
import { infoImageUrl } from '@/instance.js'; import { infoImageUrl } from '@/instance.js';
import { defaultStore } from '@/store.js'; import { defaultStore } from '@/store.js';
console.log(defaultStore.state.noteDesign, defaultStore.state.noteDesign === 'sharkey');
const props = defineProps<{ const props = defineProps<{
pagination: Paging; pagination: Paging;
noGap?: boolean; noGap?: boolean;

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

@ -16,9 +16,14 @@ SPDX-License-Identifier: AGPL-3.0-only
</template> </template>
<template #default="{ items }"> <template #default="{ items }">
<MkDateSeparatedList v-slot="{ item }" :items="items" :direction="'down'" :noGap="false" :ad="false"> <MkDateSeparatedList v-if="defaultStore.state.noteDesign === 'misskey'"
v-slot="{ item }" :items="items" :direction="'down'" :noGap="false" :ad="false">
<MkNote :key="item.id" :note="item.note" :class="$style.note"/> <MkNote :key="item.id" :note="item.note" :class="$style.note"/>
</MkDateSeparatedList> </MkDateSeparatedList>
<MkDateSeparatedList v-if="defaultStore.state.noteDesign === 'sharkey'"
v-slot="{ item }" :items="items" :direction="'down'" :noGap="false" :ad="false">
<SkNote :key="item.id" :note="item.note" :class="$style.note"/>
</MkDateSeparatedList>
</template> </template>
</MkPagination> </MkPagination>
</MkSpacer> </MkSpacer>
@ -28,10 +33,12 @@ SPDX-License-Identifier: AGPL-3.0-only
<script lang="ts" setup> <script lang="ts" setup>
import MkPagination from '@/components/MkPagination.vue'; import MkPagination from '@/components/MkPagination.vue';
import MkNote from '@/components/MkNote.vue'; import MkNote from '@/components/MkNote.vue';
import SkNote from '@/components/SkNote.vue';
import MkDateSeparatedList from '@/components/MkDateSeparatedList.vue'; import MkDateSeparatedList from '@/components/MkDateSeparatedList.vue';
import { i18n } from '@/i18n.js'; import { i18n } from '@/i18n.js';
import { definePageMetadata } from '@/scripts/page-metadata.js'; import { definePageMetadata } from '@/scripts/page-metadata.js';
import { infoImageUrl } from '@/instance.js'; import { infoImageUrl } from '@/instance.js';
import { defaultStore } from '@/store.js';
const pagination = { const pagination = {
endpoint: 'i/favorites' as const, endpoint: 'i/favorites' as const,

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