diff --git a/packages/frontend/src/os.ts b/packages/frontend/src/os.ts index 5e332533ef..88cbcd24e9 100644 --- a/packages/frontend/src/os.ts +++ b/packages/frontend/src/os.ts @@ -170,13 +170,33 @@ type EmitsExtractor = { [K in keyof T as K extends `onVnode${string}` ? never : K extends `on${infer E}` ? Uncapitalize : K extends string ? never : K]: T[K]; }; +type PopupOptions = { + /** @default false */ + allowMultiple?: boolean; +}; + export function popup( component: T, props: ComponentProps, events: ComponentEmit = {} as ComponentEmit, + options: PopupOptions = {}, ): { dispose: () => void } { markRaw(component); + const _options: Required = Object.assign({ + allowMultiple: false, + }, options); + + if ( + _options.allowMultiple === false && + popups.value.some(popup => popup.component === component) + ) { + if (_DEV_) console.warn('Popup already exists'); + return { + dispose: () => { }, + }; + } + const id = ++popupIdCount; const dispose = () => { // このsetTimeoutが無いと挙動がおかしくなる(autocompleteが閉じなくなる)。Vueのバグ? @@ -203,6 +223,8 @@ export function pageWindow(path: string) { initialPath: path, }, { closed: () => dispose(), + }, { + allowMultiple: true, }); } @@ -211,6 +233,8 @@ export function toast(message: string) { message, }, { closed: () => dispose(), + }, { + allowMultiple: true, }); } diff --git a/packages/frontend/src/scripts/hotkey.ts b/packages/frontend/src/scripts/hotkey.ts index ff3cbe98ac..04fb235694 100644 --- a/packages/frontend/src/scripts/hotkey.ts +++ b/packages/frontend/src/scripts/hotkey.ts @@ -114,6 +114,7 @@ const matchPatterns = (ev: KeyboardEvent, action: Action) => { const key = ev.key.toLowerCase(); return patterns.some(({ which, ctrl, shift, alt }) => { if ( + options.allowRepeat === false && latestHotkey != null && latestHotkey.which.includes(key) && latestHotkey.ctrl === ctrl &&