diff --git a/locales/en-US.yml b/locales/en-US.yml index 6a8227511e..b9017317ed 100644 --- a/locales/en-US.yml +++ b/locales/en-US.yml @@ -944,6 +944,8 @@ approvalStatus: "Approval Status" document: "Documentation" numberOfPageCache: "Number of cached pages" numberOfPageCacheDescription: "Increasing this number will improve convenience for but cause more load as more memory usage on the user's device." +numberOfReplies: "Number of replies in a thread" +numberOfRepliesDescription: "Increasing this number will display more replies. Setting this too high can cause replies to be cramped and unreadable." logoutConfirm: "Really log out?" lastActiveDate: "Last used at" statusbar: "Status bar" diff --git a/locales/index.d.ts b/locales/index.d.ts index 98ab44dd41..6181e08b56 100644 --- a/locales/index.d.ts +++ b/locales/index.d.ts @@ -947,6 +947,8 @@ export interface Locale { "document": string; "numberOfPageCache": string; "numberOfPageCacheDescription": string; + "numberOfReplies": string; + "numberOfRepliesDescription": string; "logoutConfirm": string; "lastActiveDate": string; "statusbar": string; diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index 0af37e041f..6006487a9c 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -944,6 +944,8 @@ approvalStatus: "承認状況" document: "ドキュメント" numberOfPageCache: "ページキャッシュ数" numberOfPageCacheDescription: "多くすると利便性が向上しますが、負荷とメモリ使用量が増えます。" +numberOfReplies: "スレッド内の返信数" +numberOfRepliesDescription: "この数値を大きくすると、より多くの返信が表示されます。この値を大きくしすぎると、返信が窮屈になり、読めなくなることがあります。" logoutConfirm: "ログアウトしますか?" lastActiveDate: "最終利用日時" statusbar: "ステータスバー" diff --git a/packages/frontend/src/components/MkNoteSub.vue b/packages/frontend/src/components/MkNoteSub.vue index 384a85e546..5b1e1af308 100644 --- a/packages/frontend/src/components/MkNoteSub.vue +++ b/packages/frontend/src/components/MkNoteSub.vue @@ -64,7 +64,7 @@ SPDX-License-Identifier: AGPL-3.0-only </footer> </div> </div> - <template v-if="depth < 5"> + <template v-if="depth < numberOfReplies"> <MkNoteSub v-for="reply in replies" :key="reply.id" :note="reply" :class="$style.reply" :detail="true" :depth="depth + 1" :expandAllCws="props.expandAllCws"/> </template> <div v-else :class="$style.more"> @@ -124,6 +124,7 @@ const translation = ref<any>(null); const translating = ref(false); const isDeleted = ref(false); const renoted = ref(false); +const numberOfReplies = ref(defaultStore.state.numberOfReplies); const reactButton = shallowRef<HTMLElement>(); const renoteButton = shallowRef<HTMLElement>(); const quoteButton = shallowRef<HTMLElement>(); @@ -390,7 +391,7 @@ function menu(viaKeyboard = false): void { if (props.detail) { os.api('notes/children', { noteId: props.note.id, - limit: 5, + limit: numberOfReplies.value, showQuotes: false, }).then(res => { replies = res; diff --git a/packages/frontend/src/components/SkNoteSub.vue b/packages/frontend/src/components/SkNoteSub.vue index 64c71efd4e..dd4abe8f58 100644 --- a/packages/frontend/src/components/SkNoteSub.vue +++ b/packages/frontend/src/components/SkNoteSub.vue @@ -72,7 +72,7 @@ SPDX-License-Identifier: AGPL-3.0-only </footer> </div> </div> - <template v-if="depth < 5"> + <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"/> </template> <div v-else :class="$style.more"> @@ -133,6 +133,7 @@ const translation = ref<any>(null); const translating = ref(false); const isDeleted = ref(false); const renoted = ref(false); +const numberOfReplies = ref(defaultStore.state.numberOfReplies); const reactButton = shallowRef<HTMLElement>(); const renoteButton = shallowRef<HTMLElement>(); const quoteButton = shallowRef<HTMLElement>(); @@ -399,7 +400,7 @@ function menu(viaKeyboard = false): void { if (props.detail) { os.api('notes/children', { noteId: props.note.id, - limit: 5, + limit: numberOfReplies.value, showQuotes: false, }).then(res => { replies = res; diff --git a/packages/frontend/src/pages/settings/general.vue b/packages/frontend/src/pages/settings/general.vue index 38a1b5c2a7..419ea13713 100644 --- a/packages/frontend/src/pages/settings/general.vue +++ b/packages/frontend/src/pages/settings/general.vue @@ -89,6 +89,11 @@ SPDX-License-Identifier: AGPL-3.0-only <option value="1_1">{{ i18n.t('limitTo', { x: '1:1' }) }}</option> <option value="2_3">{{ i18n.t('limitTo', { x: '2:3' }) }}</option> </MkRadios> + + <MkRange v-model="numberOfReplies" :min="2" :max="20" :step="1" easing> + <template #label>{{ i18n.ts.numberOfReplies }}</template> + <template #caption>{{ i18n.ts.numberOfRepliesDescription }}</template> + </MkRange> </div> </FormSection> @@ -268,6 +273,7 @@ const nsfw = computed(defaultStore.makeGetterSetter('nsfw')); const showFixedPostForm = computed(defaultStore.makeGetterSetter('showFixedPostForm')); const showFixedPostFormInChannel = computed(defaultStore.makeGetterSetter('showFixedPostFormInChannel')); const numberOfPageCache = computed(defaultStore.makeGetterSetter('numberOfPageCache')); +const numberOfReplies = computed(defaultStore.makeGetterSetter('numberOfReplies')); const instanceTicker = computed(defaultStore.makeGetterSetter('instanceTicker')); const enableInfiniteScroll = computed(defaultStore.makeGetterSetter('enableInfiniteScroll')); const useReactionPickerForContextMenu = computed(defaultStore.makeGetterSetter('useReactionPickerForContextMenu')); diff --git a/packages/frontend/src/pages/settings/preferences-backups.vue b/packages/frontend/src/pages/settings/preferences-backups.vue index 3f038f8293..f7768ebe5c 100644 --- a/packages/frontend/src/pages/settings/preferences-backups.vue +++ b/packages/frontend/src/pages/settings/preferences-backups.vue @@ -90,6 +90,7 @@ const defaultStoreSaveKeys: (keyof typeof defaultStore['state'])[] = [ 'reportError', 'squareAvatars', 'numberOfPageCache', + 'numberOfReplies', 'aiChanMode', 'mediaListWithOneImageAppearance', ]; diff --git a/packages/frontend/src/store.ts b/packages/frontend/src/store.ts index eb16222968..a53336b5f7 100644 --- a/packages/frontend/src/store.ts +++ b/packages/frontend/src/store.ts @@ -346,6 +346,10 @@ export const defaultStore = markRaw(new Storage('base', { where: 'device', default: 3, }, + numberOfReplies: { + where: 'device', + default: 5, + }, showNoteActionsOnlyHover: { where: 'device', default: false,