From 299c9c41188df46b64b04ba53cbded7a89998b6c Mon Sep 17 00:00:00 2001 From: syuilo Date: Tue, 19 Sep 2023 10:58:42 +0900 Subject: [PATCH] =?UTF-8?q?feat(frontend):=20=E4=BB=BB=E6=84=8F=E3=81=AE?= =?UTF-8?q?=E3=83=A6=E3=83=BC=E3=82=B6=E3=83=BC=E3=83=AA=E3=82=B9=E3=83=88?= =?UTF-8?q?=E3=82=92=E3=82=BF=E3=82=A4=E3=83=A0=E3=83=A9=E3=82=A4=E3=83=B3?= =?UTF-8?q?=E3=83=9A=E3=83=BC=E3=82=B8=E3=81=AB=E3=83=94=E3=83=B3=E7=95=99?= =?UTF-8?q?=E3=82=81=E3=81=A7=E3=81=8D=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 2 ++ locales/index.d.ts | 1 + locales/ja-JP.yml | 1 + .../frontend/src/pages/settings/general.vue | 23 +++++++++++++++++++ packages/frontend/src/pages/timeline.vue | 19 +++++++++++---- packages/frontend/src/store.ts | 10 +++++--- 6 files changed, 49 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 56c2552145..683c0a85a5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,8 @@ - ローカリゼーションの更新 ### Client +- 任意のユーザーリストをタイムラインページにピン留めできるように + - 設定->クライアント設定->全般 から設定可能です - ノート詳細ページを改修 - 読み込み時のパフォーマンスが向上しました - リノート一覧、リアクション一覧がタブとして追加されました diff --git a/locales/index.d.ts b/locales/index.d.ts index ac714258e2..bf7aff75df 100644 --- a/locales/index.d.ts +++ b/locales/index.d.ts @@ -1114,6 +1114,7 @@ export interface Locale { "renotes": string; "loadReplies": string; "loadConversation": string; + "pinnedList": string; "_announcement": { "forExistingUsers": string; "forExistingUsersDescription": string; diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index d97b09f63c..2f88128c98 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -1111,6 +1111,7 @@ replies: "返信" renotes: "リノート" loadReplies: "返信を見る" loadConversation: "会話を見る" +pinnedList: "ピン留めされたリスト" _announcement: forExistingUsers: "既存ユーザーのみ" diff --git a/packages/frontend/src/pages/settings/general.vue b/packages/frontend/src/pages/settings/general.vue index b486e6d80f..ff498e4164 100644 --- a/packages/frontend/src/pages/settings/general.vue +++ b/packages/frontend/src/pages/settings/general.vue @@ -30,6 +30,12 @@ SPDX-License-Identifier: AGPL-3.0-only {{ i18n.ts.showFixedPostForm }} {{ i18n.ts.showFixedPostFormInChannel }} {{ i18n.ts.flagShowTimelineReplies }} + + + + {{ i18n.ts.add }} + {{ i18n.ts.remove }} + @@ -307,6 +313,23 @@ function removeEmojiIndex(lang: string) { os.promiseDialog(main()); } +async function setPinnedList() { + const lists = await os.api('users/lists/list'); + const { canceled, result: list } = await os.select({ + title: i18n.ts.selectList, + items: lists.map(x => ({ + value: x, text: x.name, + })), + }); + if (canceled) return; + + defaultStore.set('pinnedUserLists', [list]); +} + +function removePinnedList() { + defaultStore.set('pinnedUserLists', []); +} + let smashCount = 0; let smashTimer: number | null = null; function testNotification(): void { diff --git a/packages/frontend/src/pages/timeline.vue b/packages/frontend/src/pages/timeline.vue index 307d77882b..c0b1f03ff0 100644 --- a/packages/frontend/src/pages/timeline.vue +++ b/packages/frontend/src/pages/timeline.vue @@ -16,7 +16,8 @@ SPDX-License-Identifier: AGPL-3.0-only @@ -102,10 +103,15 @@ async function chooseChannel(ev: MouseEvent): Promise { os.popupMenu(items, ev.currentTarget ?? ev.target); } -function saveSrc(newSrc: 'home' | 'local' | 'social' | 'global'): void { +function saveSrc(newSrc: 'home' | 'local' | 'social' | 'global' | `list:${string}`): void { + let userList = null; + if (newSrc.startsWith('userList:')) { + const id = newSrc.substring('userList:'.length); + userList = defaultStore.reactiveState.pinnedUserLists.value.find(l => l.id === id); + } defaultStore.set('tl', { - ...defaultStore.state.tl, src: newSrc, + userList, }); srcWhenNotSignin = newSrc; } @@ -125,7 +131,12 @@ function focus(): void { const headerActions = $computed(() => []); -const headerTabs = $computed(() => [{ +const headerTabs = $computed(() => [...(defaultStore.reactiveState.pinnedUserLists.value.map(l => ({ + key: 'list:' + l.id, + title: l.name, + icon: 'ti ti-star', + iconOnly: true, +}))), { key: 'home', title: i18n.ts._timelines.home, icon: 'ti ti-home', diff --git a/packages/frontend/src/store.ts b/packages/frontend/src/store.ts index 787a584f83..4b8001bfb4 100644 --- a/packages/frontend/src/store.ts +++ b/packages/frontend/src/store.ts @@ -4,7 +4,7 @@ */ import { markRaw, ref } from 'vue'; -import misskey from 'misskey-js'; +import * as Misskey from 'misskey-js'; import { Storage } from './pizzax'; interface PostFormAction { @@ -163,10 +163,14 @@ export const defaultStore = markRaw(new Storage('base', { tl: { where: 'deviceAccount', default: { - src: 'home' as 'home' | 'local' | 'social' | 'global', - arg: null, + src: 'home' as 'home' | 'local' | 'social' | 'global' | `list:${string}`, + userList: null as Misskey.entities.UserList | null, }, }, + pinnedUserLists: { + where: 'deviceAccount', + default: [] as Misskey.entities.UserList[], + }, overridedDeviceKind: { where: 'device',