diff options
| author | かっこかり <67428053+kakkokari-gtyih@users.noreply.github.com> | 2023-09-11 14:31:50 +0900 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-09-11 14:31:50 +0900 |
| commit | cd6428715e6780d51e8f6edf93fe7e32bd8f937b (patch) | |
| tree | 3a1ac5a3f7d01f4fa1fbcb29af7c5bd9df0d6581 /packages/frontend/src | |
| parent | fix (diff) | |
| download | misskey-cd6428715e6780d51e8f6edf93fe7e32bd8f937b.tar.gz misskey-cd6428715e6780d51e8f6edf93fe7e32bd8f937b.tar.bz2 misskey-cd6428715e6780d51e8f6edf93fe7e32bd8f937b.zip | |
feat: テスト通知を送信できるようにする (#11810)
* (add) Notification test
* Update Changelog
* (add) backend, frontend impl
* globalEventの名前を明確にする
* Run API Extractor
Diffstat (limited to 'packages/frontend/src')
5 files changed, 53 insertions, 2 deletions
diff --git a/packages/frontend/src/components/MkNotification.vue b/packages/frontend/src/components/MkNotification.vue index d46e8de553..ea2b6c1d4b 100644 --- a/packages/frontend/src/components/MkNotification.vue +++ b/packages/frontend/src/components/MkNotification.vue @@ -8,6 +8,7 @@ SPDX-License-Identifier: AGPL-3.0-only <div :class="$style.head"> <MkAvatar v-if="notification.type === 'pollEnded'" :class="$style.icon" :user="notification.note.user" link preview/> <MkAvatar v-else-if="notification.type === 'achievementEarned'" :class="$style.icon" :user="$i" link preview/> + <img v-else-if="notification.type === 'test'" :class="$style.icon" :src="infoImageUrl"/> <MkAvatar v-else-if="notification.user" :class="$style.icon" :user="notification.user" link preview/> <img v-else-if="notification.icon" :class="$style.icon" :src="notification.icon" alt=""/> <div @@ -47,6 +48,7 @@ SPDX-License-Identifier: AGPL-3.0-only <header :class="$style.header"> <span v-if="notification.type === 'pollEnded'">{{ i18n.ts._notification.pollEnded }}</span> <span v-else-if="notification.type === 'achievementEarned'">{{ i18n.ts._notification.achievementEarned }}</span> + <span v-else-if="notification.type === 'test'">{{ i18n.ts._notification.testNotification }}</span> <MkA v-else-if="notification.user" v-user-preview="notification.user.id" :class="$style.headerName" :to="userPage(notification.user)"><MkUserName :user="notification.user"/></MkA> <span v-else>{{ notification.header }}</span> <MkTime v-if="withTime" :time="notification.createdAt" :class="$style.headerTime"/> @@ -91,6 +93,7 @@ SPDX-License-Identifier: AGPL-3.0-only <MkButton :class="$style.followRequestCommandButton" rounded danger @click="rejectFollowRequest()"><i class="ti ti-x"/> {{ i18n.ts.reject }}</MkButton> </div> </template> + <span v-else-if="notification.type === 'test'" :class="$style.text">{{ i18n.ts._notification.notificationWillBeDisplayedLikeThis }}</span> <span v-else-if="notification.type === 'app'" :class="$style.text"> <Mfm :text="notification.body" :nowrap="false"/> </span> @@ -113,6 +116,7 @@ import { i18n } from '@/i18n'; import * as os from '@/os'; import { useTooltip } from '@/scripts/use-tooltip'; import { $i } from '@/account'; +import { infoImageUrl } from '@/instance'; const props = withDefaults(defineProps<{ notification: Misskey.entities.Notification; diff --git a/packages/frontend/src/pages/settings/general.vue b/packages/frontend/src/pages/settings/general.vue index 85a3a2e2e3..31d5dd93ec 100644 --- a/packages/frontend/src/pages/settings/general.vue +++ b/packages/frontend/src/pages/settings/general.vue @@ -95,6 +95,8 @@ SPDX-License-Identifier: AGPL-3.0-only <option value="vertical"><i class="ti ti-carousel-vertical"></i> {{ i18n.ts.vertical }}</option> <option value="horizontal"><i class="ti ti-carousel-horizontal"></i> {{ i18n.ts.horizontal }}</option> </MkRadios> + + <MkButton @click="testNotification('client')">{{ i18n.ts._notification.checkNotificationBehavior }}</MkButton> </div> </FormSection> @@ -190,6 +192,7 @@ import { unisonReload } from '@/scripts/unison-reload'; import { i18n } from '@/i18n'; import { definePageMetadata } from '@/scripts/page-metadata'; import { miLocalStorage } from '@/local-storage'; +import { testNotification } from '@/scripts/test-notification'; const lang = ref(miLocalStorage.getItem('lang')); const fontSize = ref(miLocalStorage.getItem('fontSize')); diff --git a/packages/frontend/src/pages/settings/notifications.vue b/packages/frontend/src/pages/settings/notifications.vue index b9e4c58f79..b20add724c 100644 --- a/packages/frontend/src/pages/settings/notifications.vue +++ b/packages/frontend/src/pages/settings/notifications.vue @@ -13,6 +13,11 @@ SPDX-License-Identifier: AGPL-3.0-only </div> </FormSection> <FormSection> + <div class="_gaps_m"> + <FormLink @click="testNotification('server')">{{ i18n.ts._notification.sendTestNotification }}</FormLink> + </div> + </FormSection> + <FormSection> <template #label>{{ i18n.ts.pushNotification }}</template> <div class="_gaps_m"> @@ -41,6 +46,7 @@ import { i18n } from '@/i18n'; import { definePageMetadata } from '@/scripts/page-metadata'; import MkPushNotificationAllowButton from '@/components/MkPushNotificationAllowButton.vue'; import { notificationTypes } from '@/const'; +import { testNotification } from '@/scripts/test-notification'; let allowButton = $shallowRef<InstanceType<typeof MkPushNotificationAllowButton>>(); let pushRegistrationInServer = $computed(() => allowButton?.pushRegistrationInServer); diff --git a/packages/frontend/src/scripts/test-notification.ts b/packages/frontend/src/scripts/test-notification.ts new file mode 100644 index 0000000000..0e8289e19e --- /dev/null +++ b/packages/frontend/src/scripts/test-notification.ts @@ -0,0 +1,34 @@ +/* + * SPDX-FileCopyrightText: syuilo and other misskey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import * as Misskey from 'misskey-js'; +import * as os from '@/os'; +import { globalEvents } from '@/events'; + +/** + * テスト通知を送信 + * + * - `client` … 通知ポップアップのみを表示 + * - `server` … サーバー側から通知を送信 + * + * @param type 通知タイプを指定 + */ +export function testNotification(type: 'client' | 'server'): void { + const notification: Misskey.entities.Notification = { + id: Math.random().toString(), + createdAt: new Date().toUTCString(), + isRead: false, + type: 'test', + }; + + switch (type) { + case 'server': + os.api('notifications/test-notification'); + break; + case 'client': + globalEvents.emit('clientNotification', notification); + break; + } +} diff --git a/packages/frontend/src/ui/_common_/common.vue b/packages/frontend/src/ui/_common_/common.vue index 61fcb0b171..65c5dbb384 100644 --- a/packages/frontend/src/ui/_common_/common.vue +++ b/packages/frontend/src/ui/_common_/common.vue @@ -56,6 +56,7 @@ import { $i } from '@/account'; import { useStream } from '@/stream'; import { i18n } from '@/i18n'; import { defaultStore } from '@/store'; +import { globalEvents } from '@/events'; const XStreamIndicator = defineAsyncComponent(() => import('./stream-indicator.vue')); const XUpload = defineAsyncComponent(() => import('./upload.vue')); @@ -64,11 +65,13 @@ const dev = _DEV_; let notifications = $ref<Misskey.entities.Notification[]>([]); -function onNotification(notification) { +function onNotification(notification: Misskey.entities.Notification, isClient: boolean = false) { if ($i.mutingNotificationTypes.includes(notification.type)) return; if (document.visibilityState === 'visible') { - useStream().send('readNotification'); + if (!isClient) { + useStream().send('readNotification'); + } notifications.unshift(notification); window.setTimeout(() => { @@ -86,6 +89,7 @@ function onNotification(notification) { if ($i) { const connection = useStream().useChannel('main', null, 'UI'); connection.on('notification', onNotification); + globalEvents.on('clientNotification', notification => onNotification(notification, true)); //#region Listen message from SW if ('serviceWorker' in navigator) { |