From 58e83f8e4f634bfd95a3afc847a875413120c301 Mon Sep 17 00:00:00 2001 From: syuilo Date: Sat, 25 Jun 2022 18:26:31 +0900 Subject: feat: allow GET for some endpoints Resolve #8263 --- packages/client/src/widgets/activity.vue | 10 +++++----- packages/client/src/widgets/federation.vue | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) (limited to 'packages/client/src/widgets') diff --git a/packages/client/src/widgets/activity.vue b/packages/client/src/widgets/activity.vue index 7fb9f5894c..265bde4a3b 100644 --- a/packages/client/src/widgets/activity.vue +++ b/packages/client/src/widgets/activity.vue @@ -15,12 +15,12 @@ diff --git a/packages/client/src/components/mini-chart.vue b/packages/client/src/components/mini-chart.vue index 5e842b1975..c64ce163f9 100644 --- a/packages/client/src/components/mini-chart.vue +++ b/packages/client/src/components/mini-chart.vue @@ -29,6 +29,7 @@ import { onUnmounted, watch } from 'vue'; import { v4 as uuid } from 'uuid'; import tinycolor from 'tinycolor2'; +import { useInterval } from '@/scripts/use-interval'; const props = defineProps<{ src: number[]; @@ -65,9 +66,8 @@ function draw(): void { watch(() => props.src, draw, { immediate: true }); // Vueが何故かWatchを発動させない場合があるので -clock = window.setInterval(draw, 1000); - -onUnmounted(() => { - window.clearInterval(clock); +useInterval(draw, 1000, { + immediate: false, + afterMounted: true, }); diff --git a/packages/client/src/components/notification.vue b/packages/client/src/components/notification.vue index cbfd809f37..26fbeecb68 100644 --- a/packages/client/src/components/notification.vue +++ b/packages/client/src/components/notification.vue @@ -112,9 +112,12 @@ export default defineComponent({ const elRef = ref(null); const reactionRef = ref(null); + let readObserver: IntersectionObserver | undefined; + let connection; + onMounted(() => { if (!props.notification.isRead) { - const readObserver = new IntersectionObserver((entries, observer) => { + readObserver = new IntersectionObserver((entries, observer) => { if (!entries.some(entry => entry.isIntersecting)) return; stream.send('readNotification', { id: props.notification.id, @@ -124,19 +127,19 @@ export default defineComponent({ readObserver.observe(elRef.value); - const connection = stream.useChannel('main'); + connection = stream.useChannel('main'); connection.on('readAllNotifications', () => readObserver.disconnect()); watch(props.notification.isRead, () => { readObserver.disconnect(); }); - - onUnmounted(() => { - readObserver.disconnect(); - connection.dispose(); - }); } }); + + onUnmounted(() => { + if (readObserver) readObserver.disconnect(); + if (connection) connection.dispose(); + }); const followRequestDone = ref(false); const groupInviteDone = ref(false); diff --git a/packages/client/src/components/notifications.vue b/packages/client/src/components/notifications.vue index 8eb569c369..eb19ad488c 100644 --- a/packages/client/src/components/notifications.vue +++ b/packages/client/src/components/notifications.vue @@ -60,8 +60,10 @@ const onNotification = (notification) => { } }; +let connection; + onMounted(() => { - const connection = stream.useChannel('main'); + connection = stream.useChannel('main'); connection.on('notification', onNotification); connection.on('readAllNotifications', () => { if (pagingComponent.value) { @@ -87,10 +89,10 @@ onMounted(() => { } } }); +}); - onUnmounted(() => { - connection.dispose(); - }); +onUnmounted(() => { + if (connection) connection.dispose(); }); diff --git a/packages/client/src/components/poll.vue b/packages/client/src/components/poll.vue index d9ef5970cb..35f87325d8 100644 --- a/packages/client/src/components/poll.vue +++ b/packages/client/src/components/poll.vue @@ -27,18 +27,19 @@ import { sum } from '@/scripts/array'; import { pleaseLogin } from '@/scripts/please-login'; import * as os from '@/os'; import { i18n } from '@/i18n'; +import { useInterval } from '@/scripts/use-interval'; export default defineComponent({ props: { note: { type: Object, - required: true + required: true, }, readOnly: { type: Boolean, required: false, default: false, - } + }, }, setup(props) { @@ -54,7 +55,7 @@ export default defineComponent({ s: Math.floor(remaining.value % 60), m: Math.floor(remaining.value / 60) % 60, h: Math.floor(remaining.value / 3600) % 24, - d: Math.floor(remaining.value / 86400) + d: Math.floor(remaining.value / 86400), })); const showResult = ref(props.readOnly || isVoted.value); @@ -68,10 +69,9 @@ export default defineComponent({ } }; - tick(); - const intevalId = window.setInterval(tick, 3000); - onUnmounted(() => { - window.clearInterval(intevalId); + useInterval(tick, 3000, { + immediate: true, + afterMounted: false, }); } diff --git a/packages/client/src/components/sparkle.vue b/packages/client/src/components/sparkle.vue index f52e5a3f9b..b52dbe31c4 100644 --- a/packages/client/src/components/sparkle.vue +++ b/packages/client/src/components/sparkle.vue @@ -33,7 +33,8 @@ --> - { - const ro = new ResizeObserver((entries, observer) => { + ro = new ResizeObserver((entries, observer) => { width.value = el.value?.offsetWidth + 64; height.value = el.value?.offsetHeight + 64; }); ro.observe(el.value); - let stop = false; const add = () => { if (stop) return; const x = (Math.random() * (width.value - 64)); @@ -104,10 +106,11 @@ export default defineComponent({ }, 500 + (Math.random() * 500)); }; add(); - onUnmounted(() => { - ro.disconnect(); - stop = true; - }); + }); + + onUnmounted(() => { + if (ro) ro.disconnect(); + stop = true; }); return { diff --git a/packages/client/src/pages/admin/overview.federation.vue b/packages/client/src/pages/admin/overview.federation.vue index 6da1fa4e98..6c99cad33c 100644 --- a/packages/client/src/pages/admin/overview.federation.vue +++ b/packages/client/src/pages/admin/overview.federation.vue @@ -18,6 +18,7 @@ import { onMounted, onUnmounted, ref } from 'vue'; import MkMiniChart from '@/components/mini-chart.vue'; import * as os from '@/os'; +import { useInterval } from '@/scripts/use-interval'; const instances = ref([]); const charts = ref([]); @@ -34,15 +35,9 @@ const fetch = async () => { fetching.value = false; }; -let intervalId; - -onMounted(() => { - fetch(); - intervalId = window.setInterval(fetch, 1000 * 60); -}); - -onUnmounted(() => { - window.clearInterval(intervalId); +useInterval(fetch, 1000 * 60, { + immediate: true, + afterMounted: true, }); diff --git a/packages/client/src/scripts/use-interval.ts b/packages/client/src/scripts/use-interval.ts new file mode 100644 index 0000000000..eb6e44338d --- /dev/null +++ b/packages/client/src/scripts/use-interval.ts @@ -0,0 +1,22 @@ +import { onMounted, onUnmounted } from 'vue'; + +export function useInterval(fn: () => void, interval: number, options: { + immediate: boolean; + afterMounted: boolean; +}): void { + let intervalId: number | null = null; + + if (options.afterMounted) { + onMounted(() => { + if (options.immediate) fn(); + intervalId = window.setInterval(fn, interval); + }); + } else { + if (options.immediate) fn(); + intervalId = window.setInterval(fn, interval); + } + + onUnmounted(() => { + if (intervalId) window.clearInterval(intervalId); + }); +} diff --git a/packages/client/src/widgets/aichan.vue b/packages/client/src/widgets/aichan.vue index cdd367cc84..828490fd9c 100644 --- a/packages/client/src/widgets/aichan.vue +++ b/packages/client/src/widgets/aichan.vue @@ -6,8 +6,8 @@
- + -
{{ $t('aboutX', { x: instanceName }) }}
+
{{ $ts.instanceInfo }}
@@ -34,13 +34,14 @@ diff --git a/packages/client/src/pages/about.federation.vue b/packages/client/src/pages/about.federation.vue new file mode 100644 index 0000000000..00ca44eec8 --- /dev/null +++ b/packages/client/src/pages/about.federation.vue @@ -0,0 +1,106 @@ + + + + + diff --git a/packages/client/src/pages/about.vue b/packages/client/src/pages/about.vue index c0226bdb6c..bacfab771f 100644 --- a/packages/client/src/pages/about.vue +++ b/packages/client/src/pages/about.vue @@ -67,6 +67,12 @@
+ + + + + + @@ -75,6 +81,8 @@ - - diff --git a/packages/client/src/pages/emojis.vue b/packages/client/src/pages/emojis.vue deleted file mode 100644 index 1592995844..0000000000 --- a/packages/client/src/pages/emojis.vue +++ /dev/null @@ -1,60 +0,0 @@ - - - - - diff --git a/packages/client/src/pages/federation.vue b/packages/client/src/pages/federation.vue deleted file mode 100644 index 07c5a32bdb..0000000000 --- a/packages/client/src/pages/federation.vue +++ /dev/null @@ -1,122 +0,0 @@ - - - - - diff --git a/packages/client/src/pages/mentions.vue b/packages/client/src/pages/mentions.vue deleted file mode 100644 index 0835f1f019..0000000000 --- a/packages/client/src/pages/mentions.vue +++ /dev/null @@ -1,27 +0,0 @@ - - - diff --git a/packages/client/src/pages/messages.vue b/packages/client/src/pages/messages.vue deleted file mode 100644 index e443b5c461..0000000000 --- a/packages/client/src/pages/messages.vue +++ /dev/null @@ -1,30 +0,0 @@ - - - diff --git a/packages/client/src/pages/notifications.vue b/packages/client/src/pages/notifications.vue index 52cb298fa3..3df1a3f17f 100644 --- a/packages/client/src/pages/notifications.vue +++ b/packages/client/src/pages/notifications.vue @@ -2,8 +2,14 @@ -
- +
+ +
+
+ +
+
+
@@ -13,12 +19,27 @@ import { computed } from 'vue'; import { notificationTypes } from 'misskey-js'; import XNotifications from '@/components/notifications.vue'; +import XNotes from '@/components/notes.vue'; import * as os from '@/os'; import { i18n } from '@/i18n'; import { definePageMetadata } from '@/scripts/page-metadata'; let tab = $ref('all'); let includeTypes = $ref(null); +let unreadOnly = $computed(() => tab === 'unread'); + +const mentionsPagination = { + endpoint: 'notes/mentions' as const, + limit: 10, +}; + +const directNotesPagination = { + endpoint: 'notes/mentions' as const, + limit: 10, + params: { + visibility: 'specified', + }, +}; function setFilter(ev) { const typeItems = notificationTypes.map(t => ({ @@ -38,18 +59,18 @@ function setFilter(ev) { os.popupMenu(items, ev.currentTarget ?? ev.target); } -const headerActions = $computed(() => [{ +const headerActions = $computed(() => [tab === 'all' ? { text: i18n.ts.filter, icon: 'fas fa-filter', highlighted: includeTypes != null, handler: setFilter, -}, { +} : undefined, tab === 'all' ? { text: i18n.ts.markAllAsRead, icon: 'fas fa-check', handler: () => { os.apiWithDialog('notifications/mark-all-as-read'); }, -}]); +} : undefined].filter(x => x !== undefined)); const headerTabs = $computed(() => [{ key: 'all', @@ -57,6 +78,14 @@ const headerTabs = $computed(() => [{ }, { key: 'unread', title: i18n.ts.unread, +}, { + key: 'mentions', + title: i18n.ts.mentions, + icon: 'fas fa-at', +}, { + key: 'directNotes', + title: i18n.ts.directNotes, + icon: 'fas fa-envelope', }]); definePageMetadata(computed(() => ({ @@ -65,8 +94,3 @@ definePageMetadata(computed(() => ({ bg: 'var(--bg)', }))); - - diff --git a/packages/client/src/pages/user/index.activity.vue b/packages/client/src/pages/user/index.activity.vue index aecd25d6b0..8a7a86e0f1 100644 --- a/packages/client/src/pages/user/index.activity.vue +++ b/packages/client/src/pages/user/index.activity.vue @@ -1,6 +1,6 @@