diff --git a/CHANGELOG.md b/CHANGELOG.md index 03c93f70df..1cc6b3f0d4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,7 @@ - センシティブチャンネルのノートはユーザープロフィールに表示されません - 二要素認証のバックアップコードが生成されるようになりました ref. https://github.com/MisskeyIO/misskey/pull/121 - 二要素認証でパスキーをサポートするようになりました +- 通知をテストできるようになりました ### Client - プロフィールにその人が作ったPlayの一覧出せるように @@ -33,7 +34,6 @@ - 投稿フォームのプレビューの表示状態を記憶するように - AiScriptからMisskeyサーバーAPIを呼び出す際の制限を撤廃 - Playで直接投稿フォームを埋め込めるように(`Ui:C:postForm`) -- 通知をテストできるように - Enhance: ユーザーメニューでスイッチでユーザーリストに追加・削除できるように - Enhance: 自分が押したリアクションのデザインを改善 - Enhance: ノート検索にローカルのみ検索可能なオプションの追加 @@ -46,6 +46,7 @@ - リアクションの表示サイズをより大きくできるように - ノート詳細ページ読み込み時のパフォーマンスを改善 - タイムラインでリスト/アンテナ選択時のパフォーマンスを改善 +- 新しい実績を追加 - Fix: サーバー情報画面(`/instance-info/{domain}`)でブロックができないのを修正 - Fix: 未読のお知らせの「わかった」をクリック・タップしてもその場で「わかった」が消えない問題を修正 - Fix: iOSで画面を回転させるとテキストサイズが変わる問題を修正 diff --git a/locales/index.d.ts b/locales/index.d.ts index 36897285c4..746c51c991 100644 --- a/locales/index.d.ts +++ b/locales/index.d.ts @@ -1467,6 +1467,10 @@ export interface Locale { "description": string; "flavor": string; }; + "_smashTestNotificationButton": { + "title": string; + "description": string; + }; }; }; "_role": { diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index f9427e13ec..3cde23ca91 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -1391,6 +1391,9 @@ _achievements: title: "Brain Diver" description: "Brain Diverへのリンクを投稿した" flavor: "Misskey-Misskey La-Tu-Ma" + _smashTestNotificationButton: + title: "テスト過剰" + description: "通知のテストをごく短時間のうちに連続して行った" _role: new: "ロールの作成" diff --git a/packages/backend/src/core/AchievementService.ts b/packages/backend/src/core/AchievementService.ts index aa810015ed..a35acd3680 100644 --- a/packages/backend/src/core/AchievementService.ts +++ b/packages/backend/src/core/AchievementService.ts @@ -85,6 +85,7 @@ export const ACHIEVEMENT_TYPES = [ 'setNameToSyuilo', 'cookieClicked', 'brainDiver', + 'smashTestNotificationButton', ] as const; @Injectable() diff --git a/packages/frontend/src/pages/settings/general.vue b/packages/frontend/src/pages/settings/general.vue index 31d5dd93ec..b486e6d80f 100644 --- a/packages/frontend/src/pages/settings/general.vue +++ b/packages/frontend/src/pages/settings/general.vue @@ -96,7 +96,7 @@ SPDX-License-Identifier: AGPL-3.0-only <option value="horizontal"><i class="ti ti-carousel-horizontal"></i> {{ i18n.ts.horizontal }}</option> </MkRadios> - <MkButton @click="testNotification('client')">{{ i18n.ts._notification.checkNotificationBehavior }}</MkButton> + <MkButton @click="testNotification">{{ i18n.ts._notification.checkNotificationBehavior }}</MkButton> </div> </FormSection> @@ -176,6 +176,7 @@ SPDX-License-Identifier: AGPL-3.0-only <script lang="ts" setup> import { computed, ref, watch } from 'vue'; +import * as Misskey from 'misskey-js'; import MkSwitch from '@/components/MkSwitch.vue'; import MkSelect from '@/components/MkSelect.vue'; import MkRadios from '@/components/MkRadios.vue'; @@ -192,7 +193,8 @@ 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'; +import { globalEvents } from '@/events'; +import { claimAchievement } from '@/scripts/achievements'; const lang = ref(miLocalStorage.getItem('lang')); const fontSize = ref(miLocalStorage.getItem('fontSize')); @@ -305,6 +307,32 @@ function removeEmojiIndex(lang: string) { os.promiseDialog(main()); } +let smashCount = 0; +let smashTimer: number | null = null; +function testNotification(): void { + const notification: Misskey.entities.Notification = { + id: Math.random().toString(), + createdAt: new Date().toUTCString(), + isRead: false, + type: 'test', + }; + + globalEvents.emit('clientNotification', notification); + + // セルフ通知破壊 実績関連 + smashCount++; + if (smashCount >= 10) { + claimAchievement('smashTestNotificationButton'); + smashCount = 0; + } + if (smashTimer) { + clearTimeout(smashTimer); + } + smashTimer = window.setTimeout(() => { + smashCount = 0; + }, 300); +} + const headerActions = $computed(() => []); const headerTabs = $computed(() => []); diff --git a/packages/frontend/src/pages/settings/notifications.vue b/packages/frontend/src/pages/settings/notifications.vue index b20add724c..193795cdec 100644 --- a/packages/frontend/src/pages/settings/notifications.vue +++ b/packages/frontend/src/pages/settings/notifications.vue @@ -14,7 +14,7 @@ SPDX-License-Identifier: AGPL-3.0-only </FormSection> <FormSection> <div class="_gaps_m"> - <FormLink @click="testNotification('server')">{{ i18n.ts._notification.sendTestNotification }}</FormLink> + <FormLink @click="testNotification">{{ i18n.ts._notification.sendTestNotification }}</FormLink> </div> </FormSection> <FormSection> @@ -46,7 +46,6 @@ 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); @@ -89,6 +88,10 @@ function onChangeSendReadMessage(v: boolean) { }); } +function testNotification(): void { + os.api('notifications/test-notification'); +} + const headerActions = $computed(() => []); const headerTabs = $computed(() => []); diff --git a/packages/frontend/src/scripts/achievements.ts b/packages/frontend/src/scripts/achievements.ts index 8b3a518830..54242b330d 100644 --- a/packages/frontend/src/scripts/achievements.ts +++ b/packages/frontend/src/scripts/achievements.ts @@ -81,6 +81,7 @@ export const ACHIEVEMENT_TYPES = [ 'setNameToSyuilo', 'cookieClicked', 'brainDiver', + 'smashTestNotificationButton', ] as const; export const ACHIEVEMENT_BADGES = { @@ -454,6 +455,11 @@ export const ACHIEVEMENT_BADGES = { bg: 'linear-gradient(0deg, rgb(144, 224, 255), rgb(255, 168, 252))', frame: 'bronze', }, + 'smashTestNotificationButton': { + img: '/fluent-emoji/1f514.png', + bg: 'linear-gradient(0deg, rgb(187 183 59), rgb(255 143 77))', + frame: 'bronze', + }, /* @see <https://github.com/misskey-dev/misskey/pull/10365#discussion_r1155511107> } as const satisfies Record<typeof ACHIEVEMENT_TYPES[number], { img: string; diff --git a/packages/frontend/src/scripts/test-notification.ts b/packages/frontend/src/scripts/test-notification.ts deleted file mode 100644 index 0e8289e19e..0000000000 --- a/packages/frontend/src/scripts/test-notification.ts +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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; - } -}