diff --git a/CHANGELOG.md b/CHANGELOG.md index d51369f4b..940a4309b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ - Enhance: 開発者モードでメニューからファイルIDをコピー出来るように `#15441' - Enhance: ノートに埋め込まれたメディアのコンテキストメニューから管理者用のファイル管理画面を開けるように ( #15440 ) - Enhance: リアクションする際に確認ダイアログを表示できるように +- Enhance: コントロールパネルのユーザ検索で入力された情報をページ遷移で損なわないように `#15437` - Enhance: CWの注釈で入力済みの文字数を表示 - Fix: ノートページで、クリップ一覧が表示されないことがある問題を修正 - Fix: コンディショナルロールを手動で割り当てできる導線を削除 `#13529` diff --git a/packages/frontend/src/account.ts b/packages/frontend/src/account.ts index 9006150bc..17d690cd3 100644 --- a/packages/frontend/src/account.ts +++ b/packages/frontend/src/account.ts @@ -7,6 +7,7 @@ import { defineAsyncComponent, reactive, ref } from 'vue'; import * as Misskey from 'misskey-js'; import { apiUrl } from '@@/js/config.js'; import type { MenuItem, MenuButton } from '@/types/menu.js'; +import { defaultMemoryStorage } from '@/memory-storage'; import { showSuspendedDialog } from '@/scripts/show-suspended-dialog.js'; import { i18n } from '@/i18n.js'; import { miLocalStorage } from '@/local-storage.js'; @@ -40,6 +41,8 @@ export function incNotesCount() { export async function signout() { if (!$i) return; + defaultMemoryStorage.clear(); + waiting(); document.cookie.split(';').forEach((cookie) => { const cookieName = cookie.split('=')[0].trim(); @@ -107,7 +110,7 @@ export async function removeAccount(idOrToken: Account['id']) { } function fetchAccount(token: string, id?: string, forceShowDialog?: boolean): Promise { - document.cookie = "token=; path=/; max-age=0"; + document.cookie = 'token=; path=/; max-age=0'; document.cookie = `token=${token}; path=/queue; max-age=86400; SameSite=Strict; Secure`; // bull dashboardの認証とかで使う return new Promise((done, fail) => { diff --git a/packages/frontend/src/memory-storage.ts b/packages/frontend/src/memory-storage.ts new file mode 100644 index 000000000..df0dc1308 --- /dev/null +++ b/packages/frontend/src/memory-storage.ts @@ -0,0 +1,57 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +export type MemoryStorage = { + has: (key: string) => boolean; + getItem: (key: string) => T | null; + setItem: (key: string, value: unknown) => void; + removeItem: (key: string) => void; + clear: () => void; + size: number; +}; + +class MemoryStorageImpl implements MemoryStorage { + private readonly storage: Map; + + constructor() { + this.storage = new Map(); + } + + has(key: string): boolean { + return this.storage.has(key); + } + + getItem(key: string): T | null { + return this.storage.has(key) ? this.storage.get(key) as T : null; + } + + setItem(key: string, value: unknown): void { + this.storage.set(key, value); + } + + removeItem(key: string): void { + this.storage.delete(key); + } + + clear(): void { + this.storage.clear(); + } + + get size(): number { + return this.storage.size; + } +} + +export function createMemoryStorage(): MemoryStorage { + return new MemoryStorageImpl(); +} + +/** + * SessionStorageよりも更に短い期間でクリアされるストレージです + * - ブラウザの再読み込みやタブの閉じると内容が揮発します + * - このストレージは他のタブと共有されません + * - アカウント切り替えやログアウトを行うと内容が揮発します + */ +export const defaultMemoryStorage: MemoryStorage = createMemoryStorage(); diff --git a/packages/frontend/src/pages/admin/users.vue b/packages/frontend/src/pages/admin/users.vue index 870c3ce88..91104b676 100644 --- a/packages/frontend/src/pages/admin/users.vue +++ b/packages/frontend/src/pages/admin/users.vue @@ -9,6 +9,9 @@ SPDX-License-Identifier: AGPL-3.0-only
+
+ {{ i18n.ts.reset }} +
@@ -57,8 +60,10 @@ SPDX-License-Identifier: AGPL-3.0-only