Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
eac25b6
fix(dialog): ダイアログのキャンセル処理を修正
Hiroshiba Aug 16, 2025
d45361a
refactor(toolbar): ダイアログ関連の音声生成処理をリファクタリング
Hiroshiba Aug 16, 2025
2855feb
stash
Hiroshiba Sep 2, 2025
4d45ac9
立ち絵を表示できるようにしたけど縦幅の範囲がなんかおかしい
Hiroshiba Sep 7, 2025
22a8bdc
feat(dialog): キャラクターポリシーダイアログのポリシー表示をマークダウン対応に変更
Hiroshiba Sep 14, 2025
ee0b62d
Merge remote-tracking branch 'upstream/main' into 3つの関数を1つに共通化する
Hiroshiba Sep 20, 2025
cd724de
chore(plan): 利用規約同意機能の実装計画ファイルを削除
Hiroshiba Sep 20, 2025
54b7f1f
feat(dialog): ライブラリ利用規約ダイアログを実装
Hiroshiba Sep 20, 2025
e52d030
feat(dialog): 利用規約ダイアログのポリシーにリンクを追加
Hiroshiba Sep 20, 2025
5d1fbba
refactor(dialog): "accepted" を "confirmed" に変更
Hiroshiba Sep 20, 2025
7e5c3ea
feat(dialog): 音声ライブラリ利用規約ダイアログを実装
Hiroshiba Sep 20, 2025
9f4195b
refactor(dialog): "accepted" を "confirmed" に変更
Hiroshiba Sep 20, 2025
81f7ad3
refactor(ui): 利用規約ダイアログの名前を変更
Hiroshiba Sep 20, 2025
0caf990
refactor(dialog): 音声ライブラリの確認済みキーに関するリファクタリング
Hiroshiba Sep 20, 2025
fcc2e06
宣言場所を変更
Hiroshiba Sep 27, 2025
d174741
refactor(dialog): 音声ライブラリ関連の変数名を利用規約に基づく名称に変更
Hiroshiba Sep 27, 2025
ec33ee1
Merge remote-tracking branch 'upstream/main' into 3つの関数を1つに共通化する
Hiroshiba Sep 27, 2025
56cde12
refactor: 音声書き出し時のダイアログ表示部分を共通化
Hiroshiba Sep 27, 2025
2b7455e
Merge branch 'refactor--音声書き出し時のダイアログ表示部分を共通化' into 3つの関数を1つに共通化する
Hiroshiba Sep 27, 2025
2f6f85e
refactor(dialog): テストキャラクターのIDを動的に生成するように変更
Hiroshiba Sep 27, 2025
60d3fa2
test: e2eテスト書いた。
Hiroshiba Sep 27, 2025
fa0453c
Merge branch 'main' into 3つの関数を1つに共通化する
Hiroshiba Sep 28, 2025
9f35c1e
Merge branch 'main' into 3つの関数を1つに共通化する
Hiroshiba Oct 4, 2025
b9c0f33
feat(dialog): 音声ライブラリポリシーダイアログに確認済みキャラクターIDを追加
Hiroshiba Oct 4, 2025
eaa14e4
refactor(dialog): 利用規約確認済みキャラクターIDの保存処理をリファクタリング
Hiroshiba Oct 4, 2025
9aadae4
feat(dialog): キャラクターポリシーリストに役割属性を追加
Hiroshiba Oct 4, 2025
65fef8a
feat(tests): 音声ライブラリ利用規約確認のテストを追加
Hiroshiba Oct 4, 2025
7c35f05
style(utils): コメントの表現を修正
Hiroshiba Oct 4, 2025
dde269f
feat(tests): 設定マイグレーションのスナップショットに termConfirmedCharacterIds を追加
Hiroshiba Oct 4, 2025
469cdb5
feat(tests): 音声ライブラリ利用規約確認ダイアログの処理を追加
Hiroshiba Oct 4, 2025
e9d97de
refactor(tests): 利用規約確認ダイアログの処理をリファクタリング
Hiroshiba Oct 4, 2025
25c9f62
[update snapshots]
Hiroshiba Oct 4, 2025
8ca04fb
(スナップショットを更新)
github-actions[bot] Oct 4, 2025
e2996d4
chore(tests): スナップショットを更新
Hiroshiba Oct 5, 2025
819cdc4
Merge remote-tracking branch 'upstream/main' into 3つの関数を1つに共通化する
Hiroshiba Oct 11, 2025
5ed4c69
Merge remote-tracking branch 'upstream/main' into 3つの関数を1つに共通化する
Hiroshiba Oct 18, 2025
3dee0c7
feat(dialog): 音声ライブラリ利用規約ダイアログの表示機能を追加
Hiroshiba Oct 18, 2025
fb8e4f7
feat(ui): 音声ライブラリ利用規約確認アクションを追加
Hiroshiba Oct 18, 2025
ec74738
feat(ui): 利用規約確認アクションの戻り値を変更し、TermConfirmedAudioKeyの配列を返すように修正
Hiroshiba Oct 18, 2025
517251b
[update snapshots]
Hiroshiba Oct 18, 2025
87ff470
(スナップショットを更新)
github-actions[bot] Oct 18, 2025
cfd6a17
feat(store): 利用規約確認ダイアログ表示機能を追加し、未確認キャラクターの処理を実装
Hiroshiba Oct 18, 2025
3512d21
Update src/store/audio.ts
Hiroshiba Oct 18, 2025
a28fac5
fix(ui): トーク音声書き出し完了通知の取得方法を修正
Hiroshiba Oct 18, 2025
d5ae1f5
Apply suggestion from @Hiroshiba
Hiroshiba Oct 18, 2025
539c7cf
Merge remote-tracking branch 'origin/3つの関数を1つに共通化する' into 3つの関数を1つに共通化する
Hiroshiba Oct 20, 2025
e0578a0
test: 極端に長いURLを表示するストーリーを追加 [update snapshots]
Hiroshiba Oct 20, 2025
a6ca0ff
(スナップショットを更新)
github-actions[bot] Oct 20, 2025
d111ec1
fix: 極端に長いURLが折り返されるようにする [update snapshots]
Hiroshiba Oct 20, 2025
430a43e
(スナップショットを更新)
github-actions[bot] Oct 20, 2025
715e527
Merge branch 'main' into 3つの関数を1つに共通化する
Hiroshiba Nov 1, 2025
85abe09
feat: sevenc-nanashiさんのレビューコメントに対応
Hiroshiba Nov 1, 2025
680a498
[update snapshots]
Hiroshiba Nov 4, 2025
656a2e1
(スナップショットを更新)
github-actions[bot] Nov 4, 2025
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
62 changes: 53 additions & 9 deletions src/components/Dialog/Dialog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@ import { Dialog, Notify, Loading } from "quasar";
import SaveAllResultDialog from "./SaveAllResultDialog.vue";
import QuestionDialog from "./TextDialog/QuestionDialog.vue";
import MessageDialog from "./TextDialog/MessageDialog.vue";
import VoiceLibraryPolicyDialog from "./VoiceLibraryPolicyDialog.vue";
import { DialogType } from "./TextDialog/common";
import { AudioKey, ConfirmedTips } from "@/type/preload";
import { ConfirmedTips, CharacterInfo, SpeakerId } from "@/type/preload";
import {
AllActions,
SaveResultObject,
SaveResult,
ErrorTypeForSaveAllResultDialog,
TermConfirmedAudioKey,
} from "@/store/type";
import { DotNotationDispatch } from "@/store/vuex";
import { withProgress } from "@/store/ui";
Expand Down Expand Up @@ -171,47 +173,46 @@ export const showQuestionDialog = async (options: QuestionDialogOptions) => {
};

export async function generateAndSaveOneAudioWithDialog({
audioKey,
termConfirmedAudioKey,
actions,
filePath,
disableNotifyOnGenerate,
}: {
audioKey: AudioKey;
termConfirmedAudioKey: TermConfirmedAudioKey;
actions: DotNotationDispatch<AllActions>;
filePath?: string;
disableNotifyOnGenerate: boolean;
}): Promise<void> {
const result: SaveResultObject = await withProgress(
actions.GENERATE_AND_SAVE_AUDIO({
audioKey,
termConfirmedAudioKey,
filePath,
}),
actions,
);

if (result == undefined) return;
notifyResult(result, "audio", actions, disableNotifyOnGenerate);
}

export async function multiGenerateAndSaveAudioWithDialog({
audioKeys,
termConfirmedAudioKeys,
actions,
dirPath,
disableNotifyOnGenerate,
}: {
audioKeys: AudioKey[];
termConfirmedAudioKeys: TermConfirmedAudioKey[];
actions: DotNotationDispatch<AllActions>;
dirPath?: string;
disableNotifyOnGenerate: boolean;
}): Promise<void> {
const result = await withProgress(
actions.MULTI_GENERATE_AND_SAVE_AUDIO({
audioKeys,
termConfirmedAudioKeys,
dirPath,
callback: (finishedCount) =>
actions.SET_PROGRESS_FROM_COUNT({
finishedCount,
totalCount: audioKeys.length,
totalCount: termConfirmedAudioKeys.length,
}),
}),
actions,
Expand Down Expand Up @@ -262,16 +263,19 @@ export async function multiGenerateAndSaveAudioWithDialog({
}

export async function generateAndConnectAndSaveAudioWithDialog({
termConfirmedAudioKeys,
actions,
filePath,
disableNotifyOnGenerate,
}: {
termConfirmedAudioKeys: TermConfirmedAudioKey[];
actions: DotNotationDispatch<AllActions>;
filePath?: string;
disableNotifyOnGenerate: boolean;
}): Promise<void> {
const result = await withProgress(
actions.GENERATE_AND_CONNECT_AND_SAVE_AUDIO({
termConfirmedAudioKeys,
filePath,
callback: (finishedCount, totalCount) =>
actions.SET_PROGRESS_FROM_COUNT({ finishedCount, totalCount }),
Expand All @@ -298,6 +302,46 @@ export async function connectAndExportTextWithDialog({
notifyResult(result, "text", actions, disableNotifyOnGenerate);
}

/**
* 音声ライブラリ利用規約ダイアログを表示する。
* 確認ボタンを押された場合は確認状況を保存する。
*/
export async function showVoiceLibraryPolicyDialog({
unconfirmedCharacterInfos,
currentConfirmedCharacterIds,
actions,
}: {
unconfirmedCharacterInfos: CharacterInfo[];
currentConfirmedCharacterIds: SpeakerId[];
actions: DotNotationDispatch<AllActions>;
}): Promise<"confirmed" | "canceled"> {
const { promise, resolve } = Promise.withResolvers<
"confirmed" | "canceled"
>();

Dialog.create({
component: VoiceLibraryPolicyDialog,
componentProps: {
characterPolicyInfos: unconfirmedCharacterInfos.map((info) => ({
id: info.metas.speakerUuid,
name: info.metas.speakerName,
policy: info.metas.policy,
portraitPath: info.portraitPath,
})),
},
})
.onOk((confirmedIds: SpeakerId[]) => {
void actions.SET_ROOT_MISC_SETTING({
key: "termConfirmedCharacterIds",
value: [...currentConfirmedCharacterIds, ...confirmedIds],
});
resolve("confirmed");
})
.onCancel(() => resolve("canceled"));

return promise;
}

// 書き出し成功時の通知を表示
const showWriteSuccessNotify = ({
mediaType,
Expand Down
97 changes: 97 additions & 0 deletions src/components/Dialog/VoiceLibraryPolicyDialog.stories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import { userEvent, within, expect, fn } from "storybook/test";

import { Meta, StoryObj } from "@storybook/vue3-vite";
import VoiceLibraryPolicyDialog from "./VoiceLibraryPolicyDialog.vue";
import { SpeakerId as toSpeakerId } from "@/type/preload";
import { getPortraitUrl } from "@/mock/engineMock/characterResourceMock";
import { uuid4 } from "@/helpers/random";

const testCharacterAId = toSpeakerId(uuid4());
const testCharacterBId = toSpeakerId(uuid4());
const testCharacterCId = toSpeakerId(uuid4());

const meta: Meta<typeof VoiceLibraryPolicyDialog> = {
component: VoiceLibraryPolicyDialog,
args: {
modelValue: false,
characterPolicyInfos: [
{
id: testCharacterAId,
name: "テストキャラクターA",
policy:
"markdownテスト。**太字**。\\\n改行。\\\n[リンク](https://example.com)",
portraitPath: getPortraitUrl(0),
},
{
id: testCharacterBId,
name: "テストキャラクターB",
policy: Array(50).fill("長いテキスト").join(""),
portraitPath: getPortraitUrl(1),
},
],
onOk: fn(),
onHide: fn(),
"onUpdate:modelValue": fn(),
},
tags: ["!autodocs"], // ダイアログ系はautodocsのプレビューが正しく表示されないので無効化
};

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

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

export const LongUrl: Story = {
name: "極端に長いURL",
args: {
modelValue: true,
characterPolicyInfos: [
{
id: testCharacterCId,
name: "テストキャラクターC",
policy:
"極端に長いURLのテスト。https://example.com/very/long/path/to/some/policy/document/that/has/many/nested/directories/and/a/very/long/filename/with/query/parameters?param1=value1&param2=value2&param3=value3&param4=value4&param5=value5&param6=value6&param7=value7&param8=value8&param9=value9&param10=value10",
portraitPath: getPortraitUrl(2),
},
],
},
};

export const Ok: Story = {
name: "確認ボタンを押す",
args: { ...Opened.args },
play: async ({ args }) => {
const canvas = within(document.body); // ダイアログなので例外的にdocument.bodyを使う

const button = canvas.getByRole("button", { name: /確認して続行/ });
await userEvent.click(button);

await expect(args["onOk"]).toBeCalledWith([
testCharacterAId,
testCharacterBId,
]);
},
};

export const Cancel: Story = {
name: "キャンセルボタンを押す",
args: { ...Opened.args },
play: async ({ args }) => {
const canvas = within(document.body); // ダイアログなので例外的にdocument.bodyを使う

const button = canvas.getByRole("button", { name: /キャンセル/ });
await userEvent.click(button);

await expect(args["onHide"]).toBeCalledWith();
},
};

export const Closed: Story = {
name: "閉じている",
tags: ["skip-screenshot"],
};
Loading
Loading