From d27ce442eab9ae8e2f4ddff1e8ca0d0412e73046 Mon Sep 17 00:00:00 2001 From: dakkar Date: Thu, 23 May 2024 21:56:28 +0000 Subject: more timeline filters - #228 --- packages/frontend/src/components/MkTimeline.vue | 4 +++ packages/frontend/src/pages/channel.vue | 35 +++++++++++++++++++-- packages/frontend/src/pages/user-list-timeline.vue | 36 +++++++++++++++++++++- packages/frontend/src/ui/deck/channel-column.vue | 26 ++++++++++++++-- packages/frontend/src/ui/deck/list-column.vue | 14 ++++++++- 5 files changed, 109 insertions(+), 6 deletions(-) (limited to 'packages/frontend/src') diff --git a/packages/frontend/src/components/MkTimeline.vue b/packages/frontend/src/components/MkTimeline.vue index 1c14174a37..0f7eb3b86c 100644 --- a/packages/frontend/src/components/MkTimeline.vue +++ b/packages/frontend/src/components/MkTimeline.vue @@ -154,6 +154,8 @@ function connectChannel() { } else if (props.src === 'channel') { if (props.channel == null) return; connection = stream.useChannel('channel', { + withRenotes: props.withRenotes, + withFiles: props.onlyFiles ? true : undefined, channelId: props.channel, }); } else if (props.src === 'role') { @@ -234,6 +236,8 @@ function updatePaginationQuery() { } else if (props.src === 'channel') { endpoint = 'channels/timeline'; query = { + withRenotes: props.withRenotes, + withFiles: props.onlyFiles ? true : undefined, channelId: props.channel, }; } else if (props.src === 'role') { diff --git a/packages/frontend/src/pages/channel.vue b/packages/frontend/src/pages/channel.vue index 881acd0197..ee081d07ee 100644 --- a/packages/frontend/src/pages/channel.vue +++ b/packages/frontend/src/pages/channel.vue @@ -39,7 +39,7 @@ SPDX-License-Identifier: AGPL-3.0-only - +
@@ -95,6 +95,7 @@ import { isSupportShare } from '@/scripts/navigator.js'; import copyToClipboard from '@/scripts/copy-to-clipboard.js'; import { miLocalStorage } from '@/local-storage.js'; import { useRouter } from '@/router/supplier.js'; +import { deepMerge } from '@/scripts/merge.js'; const router = useRouter(); @@ -116,6 +117,15 @@ const featuredPagination = computed(() => ({ channelId: props.channelId, }, })); +const withRenotes = computed({ + get: () => defaultStore.reactiveState.tl.value.filter.withRenotes, + set: (x) => saveTlFilter('withRenotes', x), +}); + +const onlyFiles = computed({ + get: () => defaultStore.reactiveState.tl.value.filter.onlyFiles, + set: (x) => saveTlFilter('onlyFiles', x), +}); watch(() => props.channelId, async () => { channel.value = await misskeyApi('channels/show', { @@ -136,6 +146,13 @@ watch(() => props.channelId, async () => { } }, { immediate: true }); +function saveTlFilter(key: keyof typeof defaultStore.state.tl.filter, newValue: boolean) { + if (key !== 'withReplies' || $i) { + const out = deepMerge({ filter: { [key]: newValue } }, defaultStore.state.tl); + defaultStore.set('tl', out); + } +} + function edit() { router.push(`/channels/${channel.value?.id}/edit`); } @@ -192,7 +209,21 @@ async function search() { const headerActions = computed(() => { if (channel.value && channel.value.userId) { - const headerItems: PageHeaderItem[] = []; + const headerItems: PageHeaderItem[] = [{ + icon: 'ph-dots-three ph-bold ph-lg', + text: i18n.ts.options, + handler: (ev) => { + os.popupMenu([{ + type: 'switch', + text: i18n.ts.showRenotes, + ref: withRenotes, + }, { + type: 'switch', + text: i18n.ts.fileAttachedOnly, + ref: onlyFiles, + }], ev.currentTarget ?? ev.target); + }, + }]; headerItems.push({ icon: 'ph-share-network ph-bold ph-lg', diff --git a/packages/frontend/src/pages/user-list-timeline.vue b/packages/frontend/src/pages/user-list-timeline.vue index dd0b7fb675..b2d52b013c 100644 --- a/packages/frontend/src/pages/user-list-timeline.vue +++ b/packages/frontend/src/pages/user-list-timeline.vue @@ -11,10 +11,12 @@ SPDX-License-Identifier: AGPL-3.0-only
@@ -32,6 +34,9 @@ import { misskeyApi } from '@/scripts/misskey-api.js'; import { definePageMetadata } from '@/scripts/page-metadata.js'; import { i18n } from '@/i18n.js'; import { useRouter } from '@/router/supplier.js'; +import { defaultStore } from '@/store.js'; +import { deepMerge } from '@/scripts/merge.js'; +import * as os from '@/os.js'; const router = useRouter(); @@ -43,6 +48,21 @@ const list = ref(null); const queue = ref(0); const tlEl = shallowRef>(); const rootEl = shallowRef(); +const withRenotes = computed({ + get: () => defaultStore.reactiveState.tl.value.filter.withRenotes, + set: (x) => saveTlFilter('withRenotes', x), +}); +const onlyFiles = computed({ + get: () => defaultStore.reactiveState.tl.value.filter.onlyFiles, + set: (x) => saveTlFilter('onlyFiles', x), +}); + +function saveTlFilter(key: keyof typeof defaultStore.state.tl.filter, newValue: boolean) { + if (key !== 'withReplies' || $i) { + const out = deepMerge({ filter: { [key]: newValue } }, defaultStore.state.tl); + defaultStore.set('tl', out); + } +} watch(() => props.listId, async () => { list.value = await misskeyApi('users/lists/show', { @@ -63,6 +83,20 @@ function settings() { } const headerActions = computed(() => list.value ? [{ + icon: 'ph-dots-three ph-bold ph-lg', + text: i18n.ts.options, + handler: (ev) => { + os.popupMenu([{ + type: 'switch', + text: i18n.ts.showRenotes, + ref: withRenotes, + }, { + type: 'switch', + text: i18n.ts.fileAttachedOnly, + ref: onlyFiles, + }], ev.currentTarget ?? ev.target); + }, +}, { icon: 'ph-gear ph-bold ph-lg', text: i18n.ts.settings, handler: settings, diff --git a/packages/frontend/src/ui/deck/channel-column.vue b/packages/frontend/src/ui/deck/channel-column.vue index 984de82c3f..993be46910 100644 --- a/packages/frontend/src/ui/deck/channel-column.vue +++ b/packages/frontend/src/ui/deck/channel-column.vue @@ -13,13 +13,13 @@ SPDX-License-Identifier: AGPL-3.0-only
- + diff --git a/packages/frontend/src/ui/deck/list-column.vue b/packages/frontend/src/ui/deck/list-column.vue index 128562823b..f7988ed1b7 100644 --- a/packages/frontend/src/ui/deck/list-column.vue +++ b/packages/frontend/src/ui/deck/list-column.vue @@ -9,7 +9,7 @@ SPDX-License-Identifier: AGPL-3.0-only {{ column.name }} - + @@ -29,6 +29,7 @@ const props = defineProps<{ const timeline = shallowRef>(); const withRenotes = ref(props.column.withRenotes ?? true); +const onlyFiles = ref(props.column.onlyFiles ?? false); if (props.column.listId == null) { setList(); @@ -40,6 +41,12 @@ watch(withRenotes, v => { }); }); +watch(onlyFiles, v => { + updateColumn(props.column.id, { + onlyFiles: v, + }); +}); + async function setList() { const lists = await misskeyApi('users/lists/list'); const { canceled, result: list } = await os.select({ @@ -75,5 +82,10 @@ const menu = [ text: i18n.ts.showRenotes, ref: withRenotes, }, + { + type: 'switch', + text: i18n.ts.fileAttachedOnly, + ref: onlyFiles, + }, ]; -- cgit v1.2.3-freya