Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ダイアログをQuasarのものに置き換える #2286

Merged
merged 32 commits into from
Oct 20, 2024
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
4159c46
Add: ブラウザ版にダイアログを追加
sevenc-nanashi Oct 8, 2024
77aab3a
Add: Storybookを追加
sevenc-nanashi Oct 8, 2024
524f454
Change: 既存のものを新しいダイアログを使う用にする
sevenc-nanashi Oct 9, 2024
cf487e2
Add: テストを追加
sevenc-nanashi Oct 9, 2024
bedeb98
Improve: テキストを良い感じにする
sevenc-nanashi Oct 9, 2024
564156b
Delete: 使われていないpropsを削除
sevenc-nanashi Oct 9, 2024
90e9c42
Fix: テストを修正
sevenc-nanashi Oct 9, 2024
4bb8647
Merge: main -> add/browser-dialog
sevenc-nanashi Oct 13, 2024
0a6687b
Fix: package-lock.jsonを再構築
sevenc-nanashi Oct 13, 2024
b6afa6b
Fix: テストが落ちてるのを修正
sevenc-nanashi Oct 13, 2024
e790b61
Add: 複数行できるように
sevenc-nanashi Oct 16, 2024
5792b2d
Merge: upstream/main -> add/browser-dialog
sevenc-nanashi Oct 16, 2024
29b9328
(CI用)
sevenc-nanashi Oct 16, 2024
67e10a7
(スナップショットを更新)
github-actions[bot] Oct 16, 2024
e6ee86f
Code: 空行を空ける
sevenc-nanashi Oct 16, 2024
80cb962
Code: 空行を空ける(その2)
sevenc-nanashi Oct 16, 2024
0b61d22
Code: TODOを追加
sevenc-nanashi Oct 16, 2024
1d0e534
Code: コメントを追加
sevenc-nanashi Oct 19, 2024
26e41b1
Delete: backendのアラート周りを爆破
sevenc-nanashi Oct 19, 2024
f7c53fa
Code: Lintのエラーを修正
sevenc-nanashi Oct 19, 2024
e217e92
Merge: upstream/main -> add/browser-dialog
sevenc-nanashi Oct 19, 2024
1d21395
Update: Storyを更新
sevenc-nanashi Oct 19, 2024
f76d481
Fix: イベント名を修正
sevenc-nanashi Oct 19, 2024
8ba6947
Fix: waitForを使う
sevenc-nanashi Oct 19, 2024
71e78c0
Fix: onUpdateを監視する
sevenc-nanashi Oct 19, 2024
f5db398
Revert: デフォルトを戻す
sevenc-nanashi Oct 19, 2024
d03ee90
Code: コメントを更新
sevenc-nanashi Oct 19, 2024
9d98019
Fix: 条件の反転を修正
sevenc-nanashi Oct 19, 2024
e21e618
Code: コメントを更新
sevenc-nanashi Oct 19, 2024
71b7273
Code: 型の名前を変更
sevenc-nanashi Oct 19, 2024
833d85e
Code: フォーマット
sevenc-nanashi Oct 19, 2024
5e6632d
Change: onHideを監視する
sevenc-nanashi Oct 19, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
281 changes: 147 additions & 134 deletions package-lock.json

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions package.json
Hiroshiba marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
"shlex": "2.1.2",
"systeminformation": "5.21.15",
"tree-kill": "1.2.2",
"vue": "3.4.26",
"vue": "3.5.11",
"vuedraggable": "4.1.0",
"vuex": "4.0.2",
"zod": "3.22.4"
Expand Down Expand Up @@ -96,7 +96,7 @@
"@typescript-eslint/parser": "7.15.0",
"@typescript-eslint/types": "7.15.0",
"@typescript-eslint/utils": "7.15.0",
"@vitejs/plugin-vue": "5.0.4",
"@vitejs/plugin-vue": "5.1.4",
"@voicevox/eslint-plugin": "file:./eslint-plugin",
"@vue/eslint-config-prettier": "9.0.0",
"@vue/eslint-config-typescript": "13.0.0",
Expand All @@ -123,12 +123,12 @@
"ts-node": "10.9.1",
"typescript": "5.5.2",
"vite": "5.3.2",
"vite-plugin-checker": "0.7.0",
"vite-plugin-checker": "0.8.0",
"vite-plugin-electron": "0.28.4",
"vite-plugin-node-polyfills": "0.21.0",
"vite-tsconfig-paths": "4.2.1",
"vitest": "1.5.0",
"vue-tsc": "2.0.24",
"vue-tsc": "2.1.6",
"yargs": "17.2.1"
}
}
45 changes: 33 additions & 12 deletions src/backend/browser/sandbox.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { Dialog } from "quasar";
import { defaultEngine } from "./contract";
import {
checkFileExistsImpl,
Expand All @@ -7,7 +8,6 @@ import {
writeFileImpl,
} from "./fileImpl";
import { getConfigManager } from "./browserConfig";

import { IpcSOData } from "@/type/ipc";
import {
defaultHotkeySettings,
Expand All @@ -29,6 +29,8 @@ import {
QAndATextFileName,
UpdateInfosJsonFileName,
} from "@/type/staticResources";
import MessageDialog from "@/components/Dialog/TextDialog/MessageDialog.vue";
import QuestionDialog from "@/components/Dialog/TextDialog/QuestionDialog.vue";

// TODO: base pathを設定できるようにするか、ビルド時埋め込みにする
const toStaticPath = (fileName: string) => `/${fileName}`;
Expand Down Expand Up @@ -167,29 +169,48 @@ 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<void>();
Dialog.create({
component: MessageDialog,
componentProps: {
type: obj.type,
title: obj.title,
message: obj.message,
},
}).onOk(() => resolve());

await promise;

// 誰も使ってないので適当な値を返している。型定義をPromise<void>に変えてもいいかも
sevenc-nanashi marked this conversation as resolved.
Show resolved Hide resolved
// 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;
buttons: string[];
cancelId?: number;
defaultId?: number;
}) {
// FIXME
// TODO: 例えば動的にdialog要素をDOMに生成して、それを表示させるみたいのはあるかもしれない
throw new Error(
`Not implemented: showQuestionDialog, request: ${JSON.stringify(obj)}`,
);
const { promise, resolve } = Promise.withResolvers<number>();

Dialog.create({
component: QuestionDialog,
componentProps: {
type: obj.type,
title: obj.title,
message: obj.message,
buttons: obj.buttons,
},
}).onOk((result: { index: number }) => resolve(result.index));

return await promise;
},
async showImportFileDialog(obj: {
name?: string;
Expand Down
120 changes: 47 additions & 73 deletions src/components/Dialog/Dialog.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { Dialog, DialogChainObject, Notify, Loading } from "quasar";
import { Dialog, Notify, Loading } from "quasar";
import SaveAllResultDialog from "./SaveAllResultDialog.vue";
import QuestionDialog from "./TextDialog/QuestionDialog.vue";
import MessageDialog from "./TextDialog/MessageDialog.vue";
import { AudioKey, ConfirmedTips } from "@/type/preload";
import {
AllActions,
Expand All @@ -22,7 +24,6 @@ export type CommonDialogOptions = {
confirm: {
title: string;
message: string;
html?: boolean;
actionName: string;
cancel?: string;
};
Expand All @@ -34,7 +35,6 @@ export type CommonDialogOptions = {
};
};
export type CommonDialogType = keyof CommonDialogOptions;
type CommonDialogCallback = (value: CommonDialogResult) => void;

export type NotifyAndNotShowAgainButtonOption = {
message: string;
Expand All @@ -51,20 +51,20 @@ export const showAlertDialog = async (
) => {
options.ok ??= "閉じる";

return new Promise((resolve: CommonDialogCallback) => {
setCommonDialogCallback(
Dialog.create({
title: options.title,
message: options.message,
ok: {
label: options.ok,
flat: true,
textColor: "display",
},
}),
resolve,
);
});
const { promise, resolve } = Promise.withResolvers<void>();
Dialog.create({
component: MessageDialog,
componentProps: {
type: "warning",
title: options.title,
message: options.message,
ok: options.ok,
},
}).onOk(() => resolve());

await promise;

return "OK" as const;
};

/**
Expand All @@ -76,69 +76,43 @@ export const showConfirmDialog = async (
) => {
options.cancel ??= "キャンセル";

return new Promise((resolve: CommonDialogCallback) => {
setCommonDialogCallback(
Dialog.create({
title: options.title,
message: options.message,
persistent: true, // ダイアログ外側押下時・Esc押下時にユーザが設定ができたと思い込むことを防止する
focus: "ok",
html: options.html,
ok: {
flat: true,
label: options.actionName,
textColor: "display",
},
cancel: {
flat: true,
label: options.cancel,
textColor: "display",
},
}),
resolve,
);
});
const { promise, resolve } = Promise.withResolvers<number>();
Dialog.create({
component: QuestionDialog,
componentProps: {
type: "question",
title: options.title,
message: options.message,
buttons: [options.actionName, options.cancel],
default: 0,
},
sevenc-nanashi marked this conversation as resolved.
Show resolved Hide resolved
sevenc-nanashi marked this conversation as resolved.
Show resolved Hide resolved
}).onOk(({ index }: { index: number }) => resolve(index));

const index = await promise;

return index === 0 ? "OK" : "CANCEL";
};

export const showWarningDialog = async (
options: CommonDialogOptions["warning"],
) => {
options.cancel ??= "キャンセル";

return new Promise((resolve: CommonDialogCallback) => {
setCommonDialogCallback(
Dialog.create({
title: options.title,
message: options.message,
persistent: true,
focus: "cancel",
ok: {
label: options.actionName,
flat: true,
textColor: "warning",
},
cancel: {
label: options.cancel,
flat: true,
textColor: "display",
},
}),
resolve,
);
});
};

const setCommonDialogCallback = (
dialog: DialogChainObject,
resolve: (result: CommonDialogResult) => void,
) => {
return dialog
.onOk(() => {
resolve("OK");
})
.onCancel(() => {
resolve("CANCEL");
});
const { promise, resolve } = Promise.withResolvers<number>();
Dialog.create({
component: QuestionDialog,
componentProps: {
type: "warning",
title: options.title,
message: options.message,
buttons: [options.actionName, options.cancel],
default: 1,
},
sevenc-nanashi marked this conversation as resolved.
Show resolved Hide resolved
}).onOk(({ index }: { index: number }) => resolve(index));

const index = await promise;

return index === 0 ? "OK" : "CANCEL";
};

export async function generateAndSaveOneAudioWithDialog({
Expand Down
3 changes: 1 addition & 2 deletions src/components/Dialog/HotkeySettingDialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -265,8 +265,7 @@ const setHotkeyDialogOpened = () => {
const resetHotkey = async (action: string) => {
const result = await store.dispatch("SHOW_CONFIRM_DIALOG", {
title: "ショートカットキーを初期値に戻します",
message: `${action}のショートカットキーを初期値に戻します。<br/>本当に戻しますか?`,
html: true,
message: `${action}のショートカットキーを初期値に戻します。\n本当に戻しますか?`,
actionName: "初期値に戻す",
cancel: "初期値に戻さない",
});
Expand Down
5 changes: 0 additions & 5 deletions src/components/Dialog/ImportSongProjectDialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -355,11 +355,6 @@ const handleCancel = () => {
</script>

<style scoped lang="scss">
.dialog-card {
width: 700px;
max-width: 80vw;
}

.scrollable-area {
overflow-y: auto;
max-height: calc(100vh - 100px - 295px);
Expand Down
3 changes: 1 addition & 2 deletions src/components/Dialog/SettingDialog/SettingDialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -872,8 +872,7 @@ const outputSamplingRate = computed({
const result = await store.dispatch("SHOW_CONFIRM_DIALOG", {
title: "出力サンプリングレートを変更します",
message:
"出力サンプリングレートを変更しても、音質は変化しません。また、音声の生成処理に若干時間がかかる場合があります。<br />変更しますか?",
html: true,
"出力サンプリングレートを変更しても、音質は変化しません。また、音声の生成処理に若干時間がかかる場合があります。\n変更しますか?",
actionName: "変更する",
cancel: "変更しない",
});
Expand Down
45 changes: 45 additions & 0 deletions src/components/Dialog/TextDialog/MessageDialog.stories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { userEvent, within, expect } from "@storybook/test";

import { Meta, StoryObj } from "@storybook/vue3";
import MessageDialog from "./MessageDialog.vue";

const meta: Meta<typeof MessageDialog> = {
component: MessageDialog,
args: {
type: "info",
modelValue: true,
title: "タイトル",
message: "メッセージ",
},
tags: ["!autodocs"],
};

export default meta;
type Story = StoryObj<typeof meta>;

export const Opened: Story = {
name: "開いている",
args: {
modelValue: true,
},
};

export const Close: Story = {
sevenc-nanashi marked this conversation as resolved.
Show resolved Hide resolved
name: "OKを押す",
args: { ...Opened.args },
play: async ({ args }) => {
const canvas = within(document.body); // ダイアログなので例外的にdocument.bodyを使う

const button = canvas.getByRole("button", { name: "OK" });
await userEvent.click(button);

await expect(args["onOk"]).toBeCalled();
},
};

export const Closed: Story = {
name: "閉じている",
args: {
modelValue: false,
},
};
Loading
Loading