diff --git a/CHANGELOG.md b/CHANGELOG.md index 1fa961bbf9..cf78b54f94 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,7 +31,6 @@ - メニューのスイッチの動作を改善 - 絵文字ピッカーの検索の表示件数を100件に増加 - 投稿フォームのプレビューの表示状態を記憶するように -- ノート詳細ページ読み込み時のパフォーマンスを改善 - AiScriptからMisskeyサーバーAPIを呼び出す際の制限を撤廃 - Playで直接投稿フォームを埋め込めるように(`Ui:C:postForm`) - Enhance: ユーザーメニューでスイッチでユーザーリストに追加・削除できるように @@ -43,6 +42,9 @@ - Enhance: Renoteを管理者権限で削除可能に - `$[rainbow ]`記法が、動きのあるMFMが無効になっていても使用できるようになりました - Playの操作を行うAPI TokenをAPIコンソールから発行できるように +- リアクションの表示サイズをより大きくできるように +- ノート詳細ページ読み込み時のパフォーマンスを改善 +- タイムラインでリスト/アンテナ選択時のパフォーマンスを改善 - Fix: サーバー情報画面(`/instance-info/{domain}`)でブロックができないのを修正 - Fix: 未読のお知らせの「わかった」をクリック・タップしてもその場で「わかった」が消えない問題を修正 - Fix: iOSで画面を回転させるとテキストサイズが変わる問題を修正 diff --git a/locales/index.d.ts b/locales/index.d.ts index 858736be6a..771d5cf872 100644 --- a/locales/index.d.ts +++ b/locales/index.d.ts @@ -1026,7 +1026,7 @@ export interface Locale { "enableChartsForRemoteUser": string; "enableChartsForFederatedInstances": string; "showClipButtonInNoteFooter": string; - "largeNoteReactions": string; + "reactionsDisplaySize": string; "noteIdOrUrl": string; "video": string; "videos": string; diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index 7e625b9ac8..2b2cad8d73 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -1023,7 +1023,7 @@ retryAllQueuesConfirmText: "一時的にサーバーの負荷が増大するこ enableChartsForRemoteUser: "リモートユーザーのチャートを生成" enableChartsForFederatedInstances: "リモートサーバーのチャートを生成" showClipButtonInNoteFooter: "ノートのアクションにクリップを追加" -largeNoteReactions: "ノートのリアクションを大きく表示" +reactionsDisplaySize: "リアクションの表示サイズ" noteIdOrUrl: "ノートIDまたはURL" video: "動画" videos: "動画" diff --git a/packages/frontend/src/components/MkReactionsViewer.reaction.vue b/packages/frontend/src/components/MkReactionsViewer.reaction.vue index 2bc88907a8..7da5790122 100644 --- a/packages/frontend/src/components/MkReactionsViewer.reaction.vue +++ b/packages/frontend/src/components/MkReactionsViewer.reaction.vue @@ -8,7 +8,7 @@ SPDX-License-Identifier: AGPL-3.0-only ref="buttonEl" v-ripple="canToggle" class="_button" - :class="[$style.root, { [$style.reacted]: note.myReaction == reaction, [$style.canToggle]: canToggle, [$style.large]: defaultStore.state.largeNoteReactions }]" + :class="[$style.root, { [$style.reacted]: note.myReaction == reaction, [$style.canToggle]: canToggle, [$style.small]: defaultStore.state.reactionsDisplaySize === 'small', [$style.large]: defaultStore.state.reactionsDisplaySize === 'large' }]" @click="toggleReaction()" > @@ -115,10 +115,11 @@ useTooltip(buttonEl, async (showing) => { diff --git a/packages/frontend/src/local-storage.ts b/packages/frontend/src/local-storage.ts index d9dce28599..f4c11d6130 100644 --- a/packages/frontend/src/local-storage.ts +++ b/packages/frontend/src/local-storage.ts @@ -30,6 +30,8 @@ type Keys = 'message_drafts' | 'scratchpad' | 'debug' | + 'userListsCache' | + 'antennasCache' | `miux:${string}` | `ui:folder:${string}` | `themes:${string}` | @@ -41,4 +43,12 @@ export const miLocalStorage = { getItem: (key: Keys): string | null => window.localStorage.getItem(key), setItem: (key: Keys, value: string): void => window.localStorage.setItem(key, value), removeItem: (key: Keys): void => window.localStorage.removeItem(key), + getItemAsJson: (key: Keys): any | undefined => { + const item = miLocalStorage.getItem(key); + if (item === null) { + return undefined; + } + return JSON.parse(item); + }, + setItemAsJson: (key: Keys, value: any): void => window.localStorage.setItem(key, JSON.stringify(value)), }; diff --git a/packages/frontend/src/pages/settings/general.vue b/packages/frontend/src/pages/settings/general.vue index 3b39a5c00a..85a3a2e2e3 100644 --- a/packages/frontend/src/pages/settings/general.vue +++ b/packages/frontend/src/pages/settings/general.vue @@ -40,13 +40,18 @@ SPDX-License-Identifier: AGPL-3.0-only
{{ i18n.ts.showNoteActionsOnlyHover }} {{ i18n.ts.showClipButtonInNoteFooter }} - {{ i18n.ts.largeNoteReactions }} {{ i18n.ts.collapseRenotes }} {{ i18n.ts.enableAdvancedMfm }} {{ i18n.ts.enableAnimatedMfm }} {{ i18n.ts.showGapBetweenNotesInTimeline }} {{ i18n.ts.loadRawImages }} {{ i18n.ts.useReactionPickerForContextMenu }} + + + + + +
@@ -204,7 +209,7 @@ const overridedDeviceKind = computed(defaultStore.makeGetterSetter('overridedDev const serverDisconnectedBehavior = computed(defaultStore.makeGetterSetter('serverDisconnectedBehavior')); const showNoteActionsOnlyHover = computed(defaultStore.makeGetterSetter('showNoteActionsOnlyHover')); const showClipButtonInNoteFooter = computed(defaultStore.makeGetterSetter('showClipButtonInNoteFooter')); -const largeNoteReactions = computed(defaultStore.makeGetterSetter('largeNoteReactions')); +const reactionsDisplaySize = computed(defaultStore.makeGetterSetter('reactionsDisplaySize')); const collapseRenotes = computed(defaultStore.makeGetterSetter('collapseRenotes')); const reduceAnimation = computed(defaultStore.makeGetterSetter('animation', v => !v, v => !v)); const useBlurEffectForModal = computed(defaultStore.makeGetterSetter('useBlurEffectForModal')); @@ -264,6 +269,7 @@ watch([ instanceTicker, overridedDeviceKind, mediaListWithOneImageAppearance, + reactionsDisplaySize, ], async () => { await reloadAsk(); }); diff --git a/packages/frontend/src/pages/timeline.vue b/packages/frontend/src/pages/timeline.vue index f5fadb3899..3ec4a6788c 100644 --- a/packages/frontend/src/pages/timeline.vue +++ b/packages/frontend/src/pages/timeline.vue @@ -38,6 +38,7 @@ import { i18n } from '@/i18n'; import { instance } from '@/instance'; import { $i } from '@/account'; import { definePageMetadata } from '@/scripts/page-metadata'; +import { miLocalStorage } from '@/local-storage'; provide('shouldOmitHeaderTitle', true); @@ -67,17 +68,24 @@ function top(): void { } async function chooseList(ev: MouseEvent): Promise { - const lists = await os.api('users/lists/list'); + const cachedLists = miLocalStorage.getItemAsJson('userListsCache'); + const lists = cachedLists ?? await os.api('users/lists/list'); const items = lists.map(list => ({ type: 'link' as const, text: list.name, to: `/timeline/list/${list.id}`, })); os.popupMenu(items, ev.currentTarget ?? ev.target); + if (cachedLists == null) { + miLocalStorage.setItemAsJson('userListsCache', lists); + } else { + miLocalStorage.setItemAsJson('userListsCache', await os.api('users/lists/list')); + } } async function chooseAntenna(ev: MouseEvent): Promise { - const antennas = await os.api('antennas/list'); + const cachedAntennas = miLocalStorage.getItemAsJson('antennasCache'); + const antennas = cachedAntennas ?? await os.api('antennas/list'); const items = antennas.map(antenna => ({ type: 'link' as const, text: antenna.name, @@ -85,6 +93,11 @@ async function chooseAntenna(ev: MouseEvent): Promise { to: `/timeline/antenna/${antenna.id}`, })); os.popupMenu(items, ev.currentTarget ?? ev.target); + if (cachedAntennas == null) { + miLocalStorage.setItemAsJson('antennasCache', antennas); + } else { + miLocalStorage.setItemAsJson('antennasCache', await os.api('antennas/list')); + } } async function chooseChannel(ev: MouseEvent): Promise { diff --git a/packages/frontend/src/store.ts b/packages/frontend/src/store.ts index 2b7a16b6bb..787a584f83 100644 --- a/packages/frontend/src/store.ts +++ b/packages/frontend/src/store.ts @@ -316,9 +316,9 @@ export const defaultStore = markRaw(new Storage('base', { where: 'device', default: false, }, - largeNoteReactions: { + reactionsDisplaySize: { where: 'device', - default: false, + default: 'medium' as 'small' | 'medium' | 'large', }, forceShowAds: { where: 'device',