From 4159c46232797964bd925c0e9b825976aa9db5e9 Mon Sep 17 00:00:00 2001 From: sevenc-nanashi Date: Tue, 8 Oct 2024 18:21:08 +0900 Subject: [PATCH 01/29] =?UTF-8?q?Add:=20=E3=83=96=E3=83=A9=E3=82=A6?= =?UTF-8?q?=E3=82=B6=E7=89=88=E3=81=AB=E3=83=80=E3=82=A4=E3=82=A2=E3=83=AD?= =?UTF-8?q?=E3=82=B0=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/backend/browser/sandbox.ts | 47 ++++++++++---- .../Dialog/Browser/MessageDialog.vue | 60 ++++++++++++++++++ .../Dialog/Browser/QuestionDialog.vue | 62 +++++++++++++++++++ src/components/Dialog/Browser/common.ts | 28 +++++++++ .../Dialog/ImportSongProjectDialog.vue | 5 -- src/styles/_index.scss | 18 ++++-- 6 files changed, 197 insertions(+), 23 deletions(-) create mode 100644 src/components/Dialog/Browser/MessageDialog.vue create mode 100644 src/components/Dialog/Browser/QuestionDialog.vue create mode 100644 src/components/Dialog/Browser/common.ts diff --git a/src/backend/browser/sandbox.ts b/src/backend/browser/sandbox.ts index d7ec97d6e7..0533f40ce9 100644 --- a/src/backend/browser/sandbox.ts +++ b/src/backend/browser/sandbox.ts @@ -1,3 +1,4 @@ +import { Dialog } from "quasar"; import { defaultEngine } from "./contract"; import { checkFileExistsImpl, @@ -7,7 +8,6 @@ import { writeFileImpl, } from "./fileImpl"; import { getConfigManager } from "./browserConfig"; - import { IpcSOData } from "@/type/ipc"; import { defaultHotkeySettings, @@ -29,6 +29,8 @@ import { QAndATextFileName, UpdateInfosJsonFileName, } from "@/type/staticResources"; +import MessageDialog from "@/components/Dialog/Browser/MessageDialog.vue"; +import QuestionDialog from "@/components/Dialog/Browser/QuestionDialog.vue"; // TODO: base pathを設定できるようにするか、ビルド時埋め込みにする const toStaticPath = (fileName: string) => `/${fileName}`; @@ -167,17 +169,28 @@ export const api: Sandbox = { ], }); }, - showMessageDialog(obj: { + async showMessageDialog(obj: { type: "none" | "info" | "error" | "question" | "warning"; title: string; message: string; }) { - window.alert(`${obj.title}\n${obj.message}`); - // NOTE: どの呼び出し元も、return valueを使用していないので雑に対応している - // eslint-disable-next-line @typescript-eslint/no-explicit-any - return Promise.resolve({} as any); + const { promise, resolve } = Promise.withResolvers(); + Dialog.create({ + component: MessageDialog, + componentProps: { + type: obj.type, + title: obj.title, + message: obj.message, + }, + }).onOk(() => resolve()); + + await promise; + + // 誰も使ってないので適当な値を返している。型定義をPromiseに変えてもいいかも + // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-return + return {} as any; }, - showQuestionDialog(obj: { + async showQuestionDialog(obj: { type: "none" | "info" | "error" | "question" | "warning"; title: string; message: string; @@ -185,11 +198,21 @@ export const api: Sandbox = { cancelId?: number; defaultId?: number; }) { - // FIXME - // TODO: 例えば動的にdialog要素をDOMに生成して、それを表示させるみたいのはあるかもしれない - throw new Error( - `Not implemented: showQuestionDialog, request: ${JSON.stringify(obj)}`, - ); + const { promise, resolve } = Promise.withResolvers(); + + Dialog.create({ + component: QuestionDialog, + componentProps: { + type: obj.type, + title: obj.title, + message: obj.message, + buttons: obj.buttons, + cancelId: obj.cancelId, + defaultId: obj.defaultId, + }, + }).onOk((result: { index: number }) => resolve(result.index)); + + return await promise; }, async showImportFileDialog(obj: { name?: string; diff --git a/src/components/Dialog/Browser/MessageDialog.vue b/src/components/Dialog/Browser/MessageDialog.vue new file mode 100644 index 0000000000..6e0b239b3c --- /dev/null +++ b/src/components/Dialog/Browser/MessageDialog.vue @@ -0,0 +1,60 @@ + + + + + diff --git a/src/components/Dialog/Browser/QuestionDialog.vue b/src/components/Dialog/Browser/QuestionDialog.vue new file mode 100644 index 0000000000..9e287d9e54 --- /dev/null +++ b/src/components/Dialog/Browser/QuestionDialog.vue @@ -0,0 +1,62 @@ + + + + diff --git a/src/components/Dialog/Browser/common.ts b/src/components/Dialog/Browser/common.ts new file mode 100644 index 0000000000..b9bb67a0f7 --- /dev/null +++ b/src/components/Dialog/Browser/common.ts @@ -0,0 +1,28 @@ +export const getIcon = (dialogType: string) => { + switch (dialogType) { + case "info": + return "info"; + case "error": + return "error"; + case "question": + return "help"; + case "warning": + return "warning"; + default: + return ""; + } +}; + +export const getColor = (dialogType: string) => { + switch (dialogType) { + case "error": + return "warning"; + case "warning": + // TODO:用意する + // fallthrough + case "question": + case "info": + default: + return "display"; + } +}; diff --git a/src/components/Dialog/ImportSongProjectDialog.vue b/src/components/Dialog/ImportSongProjectDialog.vue index cfc301db24..e565f657a2 100644 --- a/src/components/Dialog/ImportSongProjectDialog.vue +++ b/src/components/Dialog/ImportSongProjectDialog.vue @@ -355,11 +355,6 @@ const handleCancel = () => { diff --git a/src/components/Dialog/Browser/common.ts b/src/components/Dialog/TextDialog/common.ts similarity index 100% rename from src/components/Dialog/Browser/common.ts rename to src/components/Dialog/TextDialog/common.ts diff --git a/src/components/Dialog/ToolBarCustomDialog.vue b/src/components/Dialog/ToolBarCustomDialog.vue index 8a5763e6eb..f0ff907b0f 100644 --- a/src/components/Dialog/ToolBarCustomDialog.vue +++ b/src/components/Dialog/ToolBarCustomDialog.vue @@ -210,8 +210,7 @@ watch( const applyDefaultSetting = async () => { const result = await store.dispatch("SHOW_CONFIRM_DIALOG", { title: "ツールバーをデフォルトに戻します", - message: "ツールバーをデフォルトに戻します。
よろしいですか?", - html: true, + message: "ツールバーをデフォルトに戻します。\nよろしいですか?", actionName: "はい", cancel: "いいえ", }); diff --git a/src/components/Sing/SideBar/SideBar.vue b/src/components/Sing/SideBar/SideBar.vue index 92116b568c..1c47c1db9a 100644 --- a/src/components/Sing/SideBar/SideBar.vue +++ b/src/components/Sing/SideBar/SideBar.vue @@ -70,6 +70,7 @@ import { TrackId } from "@/type/preload"; // DraggableのコンテナにQListを使うための設定。 // https://github.com/SortableJS/vue.draggable.next/issues/211#issuecomment-1718863764 +// @ts-expect-error 型エラーが出るが、ちゃんと動くので無視。 Draggable.components = { ...Draggable.components, QList }; const itemKey = (trackId: TrackId) => trackId; From cf487e2c50c6840c1cd23475ac7d363b299381bd Mon Sep 17 00:00:00 2001 From: sevenc-nanashi Date: Wed, 9 Oct 2024 18:50:10 +0900 Subject: [PATCH 04/29] =?UTF-8?q?Add:=20=E3=83=86=E3=82=B9=E3=83=88?= =?UTF-8?q?=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../TextDialog/QuestionDialog.stories.ts | 24 ++++++++++ .../Dialog/TextDialog/QuestionDialog.vue | 48 ++++++++++++++++--- 2 files changed, 65 insertions(+), 7 deletions(-) diff --git a/src/components/Dialog/TextDialog/QuestionDialog.stories.ts b/src/components/Dialog/TextDialog/QuestionDialog.stories.ts index 4b200dc913..913bf3de12 100644 --- a/src/components/Dialog/TextDialog/QuestionDialog.stories.ts +++ b/src/components/Dialog/TextDialog/QuestionDialog.stories.ts @@ -2,6 +2,7 @@ import { userEvent, within, expect } from "@storybook/test"; import { Meta, StoryObj } from "@storybook/vue3"; import QuestionDialog from "./QuestionDialog.vue"; +import { UnreachableError } from "@/type/utility"; const meta: Meta = { component: QuestionDialog, @@ -37,6 +38,29 @@ export const Close: Story = { await expect(args["onOk"]).toBeCalledWith({ index: 0 }); }, }; +export const ClickBackdropWithoutCancel: Story = { + name: "Cancelなしで背景を押しても反応しない", + args: { ...Opened.args }, + play: async ({ args }) => { + const backdrop = document.body.querySelector(".q-dialog__backdrop"); + if (!backdrop) throw new UnreachableError(); + await userEvent.click(backdrop); + + await expect(args["onOk"]).not.toBeCalled(); + }, +}; + +export const ClickBackdropWithCancel: Story = { + name: "Cancelありで背景を押す", + args: { ...Opened.args, buttons: ["A", "キャンセル"], cancel: 1 }, + play: async ({ args }) => { + const backdrop = document.body.querySelector(".q-dialog__backdrop"); + if (!backdrop) throw new UnreachableError(); + await userEvent.click(backdrop); + + await expect(args["onOk"]).toBeCalledWith({ index: 1 }); + }, +}; export const Closed: Story = { name: "閉じている", diff --git a/src/components/Dialog/TextDialog/QuestionDialog.vue b/src/components/Dialog/TextDialog/QuestionDialog.vue index eb18c89e8a..eabce7c9da 100644 --- a/src/components/Dialog/TextDialog/QuestionDialog.vue +++ b/src/components/Dialog/TextDialog/QuestionDialog.vue @@ -4,7 +4,12 @@ 参照:https://quasar.dev/quasar-plugins/dialog -->