Skip to content

Commit

Permalink
Merge branch 'main' into feature/VOICEVOX#2011
Browse files Browse the repository at this point in the history
  • Loading branch information
jdkfx authored Dec 13, 2024
2 parents a86855a + 1bb22e1 commit 8a9a8e5
Show file tree
Hide file tree
Showing 41 changed files with 180 additions and 103 deletions.
13 changes: 10 additions & 3 deletions docs/UX・UIデザインの方針.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,16 @@
- それ以外はトーストで通知(`SHOW_NOTIFY_`系)
- 例: 音声を書き出しました。
- 例: エンジンが異常終了しました。エンジンの再起動が必要です。
- ダイアログの warning と confirm の使い分け
- 続行することが望まれそうな場合は confirm
- キャンセルすることが望まれそうな場合は warning
- ダイアログに関して
- warning と confirm の使い分け
- 続行することが望まれそうな場合は confirm
- キャンセルすることが望まれそうな場合は warning
- ダイアログの文面
- タイトルは疑問文「~しますか?」
- 本文は簡潔にし、「よろしいですか?」などを避ける
- ボタンの色
- 肯定的で、そちらを選ぶ可能性が高いボタンはPrimary色にする
- 破壊的で、状態を戻すのに手間がかかる操作を行うボタンはWarningn色にする

## 文章など

Expand Down
Binary file modified public/draw-cursor.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions public/howtouse.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,8 @@ GPU をお持ちの方は、音声の生成がずっと速い GPU モードを
- 読み上げの抑揚を変更できます。数値が小さいほど棒読みに近くなります。
- 音量
- 音声の音量を変更できます。数値が大きいほど音が大きくなります。
- 間の長さ
- 文中の無音の長さを変更できます。数値が大きいほど無音時間が長くなります。
- 開始無音・終了無音
- 音声の先頭や末尾の無音の長さを変更できます。数値が大きいほど無音時間が長くなります。

Expand Down
2 changes: 1 addition & 1 deletion src/components/App.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>
<ErrorBoundary>
<TooltipProvider disableHoverableContent>
<TooltipProvider disableHoverableContent :delayDuration="500">
<MenuBar
v-if="openedEditor != undefined"
:fileSubMenuData="subMenuData.fileSubMenuData.value"
Expand Down
41 changes: 34 additions & 7 deletions src/components/Dialog/Dialog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { withProgress } from "@/store/ui";
type MediaType = "audio" | "text";

export type TextDialogResult = "OK" | "CANCEL";
export type AlertDialogOptions = {
export type MessageDialogOptions = {
type?: DialogType;
title: string;
message: string;
Expand All @@ -26,21 +26,23 @@ export type ConfirmDialogOptions = {
type?: DialogType;
title: string;
message: string;
actionName: string;
actionName: string; // ボタンテキスト
isPrimaryColorButton?: boolean; // ボタンをPrimary色にするか
cancel?: string;
};
export type WarningDialogOptions = {
type?: DialogType;
title: string;
message: string;
actionName: string;
actionName: string; // ボタンテキスト
isWarningColorButton?: boolean; // ボタンをWarning色にするか
cancel?: string;
};
export type QuestionDialogOptions = {
type?: DialogType;
title: string;
message: string;
buttons: string[];
buttons: (string | { text: string; color: string })[];
cancel: number;
default?: number;
};
Expand All @@ -55,7 +57,9 @@ export type NotifyAndNotShowAgainButtonOption = {
export type LoadingScreenOption = { message: string };

// 汎用ダイアログを表示
export const showAlertDialog = async (options: AlertDialogOptions) => {

/** メッセージを知らせるダイアログ */
export const showMessageDialog = async (options: MessageDialogOptions) => {
options.ok ??= "閉じる";

const { promise, resolve } = Promise.withResolvers<void>();
Expand All @@ -74,6 +78,17 @@ export const showAlertDialog = async (options: AlertDialogOptions) => {
return "OK" as const;
};

/** エラーが起こったことを知らせるダイアログ */
export const showAlertDialog = async (
options: Omit<MessageDialogOptions, "type">,
) => {
return await showMessageDialog({
...options,
type: "error",
});
};

/** 続行することが望まれそうな場合の質問ダイアログ */
export const showConfirmDialog = async (options: ConfirmDialogOptions) => {
options.cancel ??= "キャンセル";

Expand All @@ -84,7 +99,12 @@ export const showConfirmDialog = async (options: ConfirmDialogOptions) => {
type: options.type ?? "question",
title: options.title,
message: options.message,
buttons: [options.cancel, options.actionName],
buttons: [
options.cancel,
options.isPrimaryColorButton
? { text: options.actionName, color: "primary" }
: options.actionName,
],
default: 1,
},
}).onOk(({ index }: { index: number }) => resolve(index));
Expand All @@ -94,6 +114,7 @@ export const showConfirmDialog = async (options: ConfirmDialogOptions) => {
return index === 1 ? "OK" : "CANCEL";
};

/** キャンセルすることが望まれそうな場合の質問ダイアログ */
export const showWarningDialog = async (options: WarningDialogOptions) => {
options.cancel ??= "キャンセル";

Expand All @@ -104,7 +125,12 @@ export const showWarningDialog = async (options: WarningDialogOptions) => {
type: options.type ?? "warning",
title: options.title,
message: options.message,
buttons: [options.cancel, options.actionName],
buttons: [
options.cancel,
options.isWarningColorButton
? { text: options.actionName, color: "warning" }
: options.actionName,
],
default: 0,
},
}).onOk(({ index }: { index: number }) => resolve(index));
Expand All @@ -114,6 +140,7 @@ export const showWarningDialog = async (options: WarningDialogOptions) => {
return index === 1 ? "OK" : "CANCEL";
};

/** キャンセル以外に複数の選択肢がある質問ダイアログ */
export const showQuestionDialog = async (options: QuestionDialogOptions) => {
const { promise, resolve } = Promise.withResolvers<number>();
Dialog.create({
Expand Down
10 changes: 6 additions & 4 deletions src/components/Dialog/DictionaryManageDialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -599,9 +599,10 @@ const saveWord = async () => {
};
const deleteWord = async () => {
const result = await store.actions.SHOW_WARNING_DIALOG({
title: "登録された単語を削除しますか",
title: "単語を削除しますか",
message: "削除された単語は元に戻せません。",
actionName: "削除",
actionName: "削除する",
isWarningColorButton: true,
});
if (result === "OK") {
try {
Expand All @@ -625,7 +626,7 @@ const resetWord = async (id: string) => {
const result = await store.actions.SHOW_WARNING_DIALOG({
title: "単語の変更をリセットしますか?",
message: "単語の変更は破棄されてリセットされます。",
actionName: "リセット",
actionName: "リセットする",
});
if (result === "OK") {
selectedId.value = id;
Expand All @@ -640,7 +641,8 @@ const discardOrNotDialog = async (okCallback: () => void) => {
const result = await store.actions.SHOW_WARNING_DIALOG({
title: "単語の追加・変更を破棄しますか?",
message: "破棄すると、単語の追加・変更はリセットされます。",
actionName: "破棄",
actionName: "破棄する",
isWarningColorButton: true,
});
if (result === "OK") {
okCallback();
Expand Down
30 changes: 15 additions & 15 deletions src/components/Dialog/EngineManageDialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -409,10 +409,10 @@ const getEngineDirValidationMessage = (result: EngineDirValidationResult) => {
const addEngine = async () => {
const result = await store.actions.SHOW_WARNING_DIALOG({
title: "エンジン追加の確認",
title: "エンジンを追加しますか?",
message:
"この操作はコンピュータに損害を与える可能性があります。エンジンの配布元が信頼できない場合は追加しないでください。",
actionName: "追加",
actionName: "追加する",
});
if (result === "OK") {
if (engineLoaderType.value === "dir") {
Expand All @@ -424,7 +424,7 @@ const addEngine = async () => {
);
void requireReload(
"エンジンを追加しました。反映には再読み込みが必要です。今すぐ再読み込みしますか?",
"エンジンを追加しました。反映には再読み込みが必要です。",
);
} else {
const success = await lockUi(
Expand All @@ -433,7 +433,7 @@ const addEngine = async () => {
);
if (success) {
void requireReload(
"エンジンを追加しました。反映には再読み込みが必要です。今すぐ再読み込みしますか?",
"エンジンを追加しました。反映には再読み込みが必要です。",
);
}
}
Expand All @@ -450,10 +450,11 @@ const deleteEngine = async () => {
throw new Error("default engine cannot be deleted");
}
const result = await store.actions.SHOW_CONFIRM_DIALOG({
title: "エンジン削除の確認",
message: "選択中のエンジンを削除します。よろしいですか?",
actionName: "削除",
const result = await store.actions.SHOW_WARNING_DIALOG({
title: "エンジンを削除しますか?",
message: "選択中のエンジンを削除します。",
actionName: "削除する",
isWarningColorButton: true,
});
if (result === "OK") {
switch (engineInfo.type) {
Expand All @@ -468,7 +469,7 @@ const deleteEngine = async () => {
}),
);
void requireReload(
"エンジンを削除しました。反映には再読み込みが必要です。今すぐ再読み込みしますか?",
"エンジンを削除しました。反映には再読み込みが必要です。",
);
break;
}
Expand All @@ -478,9 +479,7 @@ const deleteEngine = async () => {
store.actions.UNINSTALL_VVPP_ENGINE(engineId),
);
if (success) {
void requireReload(
"エンジンの削除には再読み込みが必要です。今すぐ再読み込みしますか?",
);
void requireReload("エンジンの削除には再読み込みが必要です。");
}
break;
}
Expand Down Expand Up @@ -509,11 +508,12 @@ const restartSelectedEngine = () => {
};
const requireReload = async (message: string) => {
const result = await store.actions.SHOW_WARNING_DIALOG({
title: "再読み込みが必要です",
const result = await store.actions.SHOW_CONFIRM_DIALOG({
title: "再読み込みしますか?",
message: message,
actionName: "再読み込み",
actionName: "再読み込みする",
cancel: "後で",
isPrimaryColorButton: true,
});
toInitialState();
if (result === "OK") {
Expand Down
5 changes: 2 additions & 3 deletions src/components/Dialog/HotkeySettingDialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -242,10 +242,9 @@ const isDefaultCombination = (action: string) => {
const resetHotkey = async (action: string) => {
const result = await store.actions.SHOW_CONFIRM_DIALOG({
title: "ショートカットキーをデフォルトに戻します",
message: `${action}のショートカットキーをデフォルトに戻します。\n本当に戻しますか?`,
title: "デフォルトに戻しますか?",
message: `${action}のショートカットキーをデフォルトに戻します。`,
actionName: "デフォルトに戻す",
cancel: "デフォルトに戻さない",
});
if (result !== "OK") return;
Expand Down
9 changes: 5 additions & 4 deletions src/components/Dialog/PresetManageDialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -103,10 +103,11 @@ const reorderPreset = (featurePresetList: (Preset & { key: PresetKey })[]) => {
};
const deletePreset = async (key: PresetKey) => {
const result = await store.actions.SHOW_CONFIRM_DIALOG({
title: "プリセット削除の確認",
message: `プリセット "${presetItems.value[key].name}" を削除してもよろしいですか?`,
actionName: "削除",
const result = await store.actions.SHOW_WARNING_DIALOG({
title: "プリセットを削除しますか?",
message: `プリセット "${presetItems.value[key].name}" を削除します。`,
actionName: "削除する",
isWarningColorButton: true,
});
if (result === "OK") {
await store.actions.DELETE_PRESET({
Expand Down
5 changes: 2 additions & 3 deletions src/components/Dialog/SettingDialog/SettingDialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -767,11 +767,10 @@ const outputSamplingRate = computed({
set: async (outputSamplingRate: SamplingRateOption) => {
if (outputSamplingRate !== "engineDefault") {
const result = await store.actions.SHOW_CONFIRM_DIALOG({
title: "出力サンプリングレートを変更します",
title: "出力サンプリングレートを変更しますか?",
message:
"出力サンプリングレートを変更しても、音質は変化しません。また、音声の生成処理に若干時間がかかる場合があります。\n変更しますか?",
"出力サンプリングレートを変更しても、音質は変化しません。また、音声の生成処理に若干時間がかかる場合があります。",
actionName: "変更する",
cancel: "変更しない",
});
if (result !== "OK") {
return;
Expand Down
18 changes: 12 additions & 6 deletions src/components/Dialog/TextDialog/MessageDialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,26 @@
<QCard class="q-py-sm q-px-md dialog-card">
<QCardSection class="title">
<QIcon
v-if="props.type !== 'none'"
:name="iconName"
class="text-h5 q-mr-sm"
v-if="props.type !== 'info'"
:name="`sym_o_${iconName}`"
size="2rem"
class="q-mr-sm"
:color
/>
<div class="text-h5" :class="[`text-${color}`]">{{ props.title }}</div>
<div class="text-h5">{{ props.title }}</div>
</QCardSection>

<QCardSection class="q-py-none message">
<QSeparator />

<QCardSection class="message">
{{ props.message }}
</QCardSection>

<QSeparator />

<QCardActions align="right">
<QBtn
unelevated
outline
:label="props.ok"
color="toolbar-button"
textColor="toolbar-button-display"
Expand Down
14 changes: 13 additions & 1 deletion src/components/Dialog/TextDialog/QuestionDialog.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,23 @@ export const Opened: Story = {
export const OpenedMultiline: Story = {
name: "開いている:複数行",
args: {
modelValue: true,
...Opened.args,
message: "メッセージ\n複数行",
},
};

export const OpenedButtonColor: Story = {
name: "開いている:ボタン色を変える",
args: {
...Opened.args,
buttons: [
{ text: "primary", color: "primary" },
{ text: "warning", color: "warning" },
"default",
],
},
};

export const Close: Story = {
name: "Aを押す",
args: { ...Opened.args },
Expand Down
Loading

0 comments on commit 8a9a8e5

Please sign in to comment.