feat(frontend): 任意のユーザーリストをタイムラインページにピン留めできるように
This commit is contained in:
parent
bec338aa00
commit
299c9c4118
6 changed files with 49 additions and 7 deletions
|
@ -32,6 +32,8 @@
|
|||
- ローカリゼーションの更新
|
||||
|
||||
### Client
|
||||
- 任意のユーザーリストをタイムラインページにピン留めできるように
|
||||
- 設定->クライアント設定->全般 から設定可能です
|
||||
- ノート詳細ページを改修
|
||||
- 読み込み時のパフォーマンスが向上しました
|
||||
- リノート一覧、リアクション一覧がタブとして追加されました
|
||||
|
|
1
locales/index.d.ts
vendored
1
locales/index.d.ts
vendored
|
@ -1114,6 +1114,7 @@ export interface Locale {
|
|||
"renotes": string;
|
||||
"loadReplies": string;
|
||||
"loadConversation": string;
|
||||
"pinnedList": string;
|
||||
"_announcement": {
|
||||
"forExistingUsers": string;
|
||||
"forExistingUsersDescription": string;
|
||||
|
|
|
@ -1111,6 +1111,7 @@ replies: "返信"
|
|||
renotes: "リノート"
|
||||
loadReplies: "返信を見る"
|
||||
loadConversation: "会話を見る"
|
||||
pinnedList: "ピン留めされたリスト"
|
||||
|
||||
_announcement:
|
||||
forExistingUsers: "既存ユーザーのみ"
|
||||
|
|
|
@ -30,6 +30,12 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<MkSwitch v-model="showFixedPostForm">{{ i18n.ts.showFixedPostForm }}</MkSwitch>
|
||||
<MkSwitch v-model="showFixedPostFormInChannel">{{ i18n.ts.showFixedPostFormInChannel }}</MkSwitch>
|
||||
<MkSwitch v-model="showTimelineReplies">{{ i18n.ts.flagShowTimelineReplies }}<template #caption>{{ i18n.ts.flagShowTimelineRepliesDescription }} {{ i18n.ts.reflectMayTakeTime }}</template></MkSwitch>
|
||||
<MkFolder>
|
||||
<template #label>{{ i18n.ts.pinnedList }}</template>
|
||||
<!-- 複数ピン止め管理できるようにしたいけどめんどいので一旦ひとつのみ -->
|
||||
<MkButton v-if="defaultStore.reactiveState.pinnedUserLists.value.length === 0" @click="setPinnedList()">{{ i18n.ts.add }}</MkButton>
|
||||
<MkButton v-else danger @click="removePinnedList()"><i class="ti ti-trash"></i> {{ i18n.ts.remove }}</MkButton>
|
||||
</MkFolder>
|
||||
</div>
|
||||
</FormSection>
|
||||
|
||||
|
@ -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 {
|
||||
|
|
|
@ -16,7 +16,8 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<MkTimeline
|
||||
ref="tlComponent"
|
||||
:key="src"
|
||||
:src="src"
|
||||
:src="src.split(':')[0]"
|
||||
:list="src.split(':')[1]"
|
||||
:sound="true"
|
||||
@queue="queueUpdated"
|
||||
/>
|
||||
|
@ -102,10 +103,15 @@ async function chooseChannel(ev: MouseEvent): Promise<void> {
|
|||
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',
|
||||
|
|
|
@ -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',
|
||||
|
|
Loading…
Reference in a new issue