From e9e8434d5e2cd643bb3586be118e56869a94663e Mon Sep 17 00:00:00 2001 From: sevenc-nanashi Date: Tue, 12 Sep 2023 20:58:31 +0900 Subject: [PATCH 1/8] =?UTF-8?q?Add:=20=E8=A4=87=E6=95=B0=E9=81=B8=E6=8A=9E?= =?UTF-8?q?=E3=81=A7=E3=82=AD=E3=83=A3=E3=83=A9=E3=82=AF=E3=82=BF=E3=83=BC?= =?UTF-8?q?=E3=82=92=E5=A4=89=E6=9B=B4=E3=81=A7=E3=81=8D=E3=82=8B=E3=82=88?= =?UTF-8?q?=E3=81=86=E3=81=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/AudioCell.vue | 10 +- src/components/CharacterPortrait.vue | 5 +- src/store/audio.ts | 179 ++++++++++++++------------- src/store/type.ts | 18 +-- tests/unit/store/Vuex.spec.ts | 1 + 5 files changed, 115 insertions(+), 98 deletions(-) diff --git a/src/components/AudioCell.vue b/src/components/AudioCell.vue index 0d6bcfc03f..342d1ab82e 100644 --- a/src/components/AudioCell.vue +++ b/src/components/AudioCell.vue @@ -150,8 +150,8 @@ const userOrderedCharacterInfos = computed(() => { throw new Error("USER_ORDERED_CHARACTER_INFOS == undefined"); return infos; }); -const isInitializingSpeaker = computed( - () => store.state.audioKeyInitializingSpeaker === props.audioKey +const isInitializingSpeaker = computed(() => + store.state.audioKeysInitializingSpeaker.includes(props.audioKey) ); const audioItem = computed(() => store.state.audioItems[props.audioKey]); @@ -262,8 +262,10 @@ const selectedVoice = computed({ }, set(voice: Voice | undefined) { if (voice == undefined) return; - store.dispatch("COMMAND_CHANGE_VOICE", { - audioKey: props.audioKey, + store.dispatch("COMMAND_CHANGE_VOICES", { + audioKeys: isMultiSelectEnabled.value + ? store.getters.SELECTED_AUDIO_KEYS + : [props.audioKey], voice, }); }, diff --git a/src/components/CharacterPortrait.vue b/src/components/CharacterPortrait.vue index 2be47a8c29..0a6c29a165 100644 --- a/src/components/CharacterPortrait.vue +++ b/src/components/CharacterPortrait.vue @@ -82,7 +82,10 @@ const portraitPath = computed( const isInitializingSpeaker = computed(() => { const activeAudioKey = store.getters.ACTIVE_AUDIO_KEY; - return store.state.audioKeyInitializingSpeaker === activeAudioKey; + return ( + activeAudioKey && + store.state.audioKeysInitializingSpeaker.includes(activeAudioKey) + ); }); const isMultipleEngine = computed(() => store.state.engineIds.length > 1); diff --git a/src/store/audio.ts b/src/store/audio.ts index 423ecf4070..4192c3ca7d 100644 --- a/src/store/audio.ts +++ b/src/store/audio.ts @@ -257,6 +257,7 @@ const getAudioElement = (() => { export const audioStoreState: AudioStoreState = { characterInfos: {}, + audioKeysInitializingSpeaker: [], morphableTargetsInfo: {}, audioItems: {}, audioKeys: [], @@ -507,30 +508,30 @@ export const audioStore = createPartialStore({ /** * AudioItemに設定される話者(スタイルID)に対してエンジン側の初期化を行い、即座に音声合成ができるようにする。 */ - async action({ commit, dispatch }, { engineId, audioKey, styleId }) { + async action({ commit, dispatch }, { engineId, audioKeys, styleId }) { const isInitialized = await dispatch("IS_INITIALIZED_ENGINE_SPEAKER", { engineId, styleId, }); if (isInitialized) return; - commit("SET_AUDIO_KEY_INITIALIZING_SPEAKER", { - audioKey, + commit("SET_AUDIO_KEYS_INITIALIZING_SPEAKER", { + audioKeys, }); await dispatch("INITIALIZE_ENGINE_SPEAKER", { engineId, styleId, }).finally(() => { - commit("SET_AUDIO_KEY_INITIALIZING_SPEAKER", { - audioKey: undefined, + commit("SET_AUDIO_KEYS_INITIALIZING_SPEAKER", { + audioKeys: [], }); }); }, }, - SET_AUDIO_KEY_INITIALIZING_SPEAKER: { - mutation(state, { audioKey }: { audioKey?: AudioKey }) { - state.audioKeyInitializingSpeaker = audioKey; + SET_AUDIO_KEYS_INITIALIZING_SPEAKER: { + mutation(state, { audioKeys }: { audioKeys: AudioKey[] }) { + state.audioKeysInitializingSpeaker = audioKeys; }, }, @@ -963,9 +964,14 @@ export const audioStore = createPartialStore({ }, }, - SET_AUDIO_VOICE: { - mutation(state, { audioKey, voice }: { audioKey: AudioKey; voice: Voice }) { - state.audioItems[audioKey].voice = voice; + SET_AUDIOS_VOICE: { + mutation( + state, + { audioKeys, voice }: { audioKeys: AudioKey[]; voice: Voice } + ) { + for (const audioKey of audioKeys) { + state.audioItems[audioKey].voice = voice; + } }, }, @@ -2076,10 +2082,10 @@ export const audioCommandStore = transformCommandStore( }, }, - COMMAND_CHANGE_VOICE: { + COMMAND_CHANGE_VOICES: { mutation( draft, - payload: { audioKey: AudioKey; voice: Voice } & ( + payload: { audioKeys: AudioKey[]; voice: Voice } & ( | { update: "RollbackStyleId" } | { update: "AccentPhrases"; @@ -2091,94 +2097,99 @@ export const audioCommandStore = transformCommandStore( } ) ) { - audioStore.mutations.SET_AUDIO_VOICE(draft, { - audioKey: payload.audioKey, + audioStore.mutations.SET_AUDIOS_VOICE(draft, { + audioKeys: payload.audioKeys, voice: payload.voice, }); if (payload.update === "RollbackStyleId") return; - const presetKey = draft.audioItems[payload.audioKey].presetKey; - - const { nextPresetKey, shouldApplyPreset } = determineNextPresetKey( - draft, - payload.voice, - presetKey, - "changeVoice" - ); - - audioStore.mutations.SET_AUDIO_PRESET_KEY(draft, { - audioKey: payload.audioKey, - presetKey: nextPresetKey, - }); + for (const audioKey of payload.audioKeys) { + const presetKey = draft.audioItems[audioKey].presetKey; - if (payload.update == "AccentPhrases") { - audioStore.mutations.SET_ACCENT_PHRASES(draft, { - audioKey: payload.audioKey, - accentPhrases: payload.accentPhrases, - }); - } else if (payload.update == "AudioQuery") { - audioStore.mutations.SET_AUDIO_QUERY(draft, { - audioKey: payload.audioKey, - audioQuery: payload.query, - }); - } + const { nextPresetKey, shouldApplyPreset } = determineNextPresetKey( + draft, + payload.voice, + presetKey, + "changeVoice" + ); - if (shouldApplyPreset) { - audioStore.mutations.APPLY_AUDIO_PRESET(draft, { - audioKey: payload.audioKey, + audioStore.mutations.SET_AUDIO_PRESET_KEY(draft, { + audioKey, + presetKey: nextPresetKey, }); - } - }, - async action( - { state, dispatch, commit }, - { audioKey, voice }: { audioKey: AudioKey; voice: Voice } - ) { - const query = state.audioItems[audioKey].query; - const engineId = voice.engineId; - const styleId = voice.styleId; - try { - await dispatch("SETUP_SPEAKER", { audioKey, engineId, styleId }); - if (query !== undefined) { - const accentPhrases = query.accentPhrases; - const newAccentPhrases: AccentPhrase[] = await dispatch( - "FETCH_MORA_DATA", - { - accentPhrases, - engineId, - styleId, - } - ); - commit("COMMAND_CHANGE_VOICE", { + if (payload.update == "AccentPhrases") { + audioStore.mutations.SET_ACCENT_PHRASES(draft, { audioKey, - voice, - update: "AccentPhrases", - accentPhrases: newAccentPhrases, + accentPhrases: payload.accentPhrases, }); - } else { - const text = state.audioItems[audioKey].text; - const query: AudioQuery = await dispatch("FETCH_AUDIO_QUERY", { - text: text, - engineId, - styleId, + } else if (payload.update == "AudioQuery") { + audioStore.mutations.SET_AUDIO_QUERY(draft, { + audioKey, + audioQuery: payload.query, }); - commit("COMMAND_CHANGE_VOICE", { + } + + if (shouldApplyPreset) { + audioStore.mutations.APPLY_AUDIO_PRESET(draft, { audioKey, - voice, - update: "AudioQuery", - query, }); } - } catch (error) { - commit("COMMAND_CHANGE_VOICE", { - audioKey, - voice, - update: "RollbackStyleId", - }); - throw error; } }, + async action( + { dispatch, commit, state }, + { audioKeys, voice }: { audioKeys: AudioKey[]; voice: Voice } + ) { + const engineId = voice.engineId; + const styleId = voice.styleId; + await dispatch("SETUP_SPEAKER", { audioKeys, engineId, styleId }); + await Promise.all( + audioKeys.map(async (audioKey) => { + try { + const query = state.audioItems[audioKey].query; + if (query !== undefined) { + const accentPhrases = query.accentPhrases; + const newAccentPhrases: AccentPhrase[] = await dispatch( + "FETCH_MORA_DATA", + { + accentPhrases, + engineId, + styleId, + } + ); + commit("COMMAND_CHANGE_VOICES", { + audioKeys, + voice, + update: "AccentPhrases", + accentPhrases: newAccentPhrases, + }); + } else { + const text = state.audioItems[audioKey].text; + const query: AudioQuery = await dispatch("FETCH_AUDIO_QUERY", { + text: text, + engineId, + styleId, + }); + commit("COMMAND_CHANGE_VOICES", { + audioKeys, + voice, + update: "AudioQuery", + query, + }); + } + } catch (error) { + commit("COMMAND_CHANGE_VOICES", { + audioKeys, + voice, + update: "RollbackStyleId", + }); + throw error; + } + }) + ); + }, }, COMMAND_CHANGE_ACCENT: { diff --git a/src/store/type.ts b/src/store/type.ts index 32f1d0aa9d..fc54e5bf6a 100644 --- a/src/store/type.ts +++ b/src/store/type.ts @@ -124,7 +124,7 @@ export type StoreType = { export type AudioStoreState = { characterInfos: Record; morphableTargetsInfo: Record; - audioKeyInitializingSpeaker?: string; + audioKeysInitializingSpeaker: AudioKey[]; audioItems: Record; audioKeys: AudioKey[]; audioStates: Record; @@ -186,14 +186,14 @@ export type AudioStoreTypes = { SETUP_SPEAKER: { action(payload: { - audioKey: AudioKey; + audioKeys: AudioKey[]; engineId: EngineId; styleId: StyleId; }): void; }; - SET_AUDIO_KEY_INITIALIZING_SPEAKER: { - mutation: { audioKey?: AudioKey }; + SET_AUDIO_KEYS_INITIALIZING_SPEAKER: { + mutation: { audioKeys: AudioKey[] }; }; SET_ACTIVE_AUDIO_KEY: { @@ -345,8 +345,8 @@ export type AudioStoreTypes = { }): Promise; }; - SET_AUDIO_VOICE: { - mutation: { audioKey: AudioKey; voice: Voice }; + SET_AUDIOS_VOICE: { + mutation: { audioKeys: AudioKey[]; voice: Voice }; }; SET_ACCENT_PHRASES: { @@ -525,8 +525,8 @@ export type AudioCommandStoreTypes = { action(payload: { audioKey: AudioKey; text: string }): void; }; - COMMAND_CHANGE_VOICE: { - mutation: { audioKey: AudioKey; voice: Voice } & ( + COMMAND_CHANGE_VOICES: { + mutation: { audioKeys: AudioKey[]; voice: Voice } & ( | { update: "RollbackStyleId" } | { update: "AccentPhrases"; @@ -537,7 +537,7 @@ export type AudioCommandStoreTypes = { query: AudioQuery; } ); - action(payload: { audioKey: AudioKey; voice: Voice }): void; + action(payload: { audioKeys: AudioKey[]; voice: Voice }): void; }; COMMAND_CHANGE_ACCENT: { diff --git a/tests/unit/store/Vuex.spec.ts b/tests/unit/store/Vuex.spec.ts index a50f59ceca..5f86a981ff 100644 --- a/tests/unit/store/Vuex.spec.ts +++ b/tests/unit/store/Vuex.spec.ts @@ -27,6 +27,7 @@ describe("store/vuex.js test", () => { engineSupportedDevices: {}, altPortInfos: {}, characterInfos: {}, + audioKeysInitializingSpeaker: [], morphableTargetsInfo: {}, defaultStyleIds: [], userCharacterOrder: [], From 1753addaeff922acb2fe4de8b5ff9c7ae32dd549 Mon Sep 17 00:00:00 2001 From: sevenc-nanashi Date: Tue, 12 Sep 2023 22:02:06 +0900 Subject: [PATCH 2/8] =?UTF-8?q?Add:=20=E3=83=86=E3=82=B9=E3=83=88=E3=82=92?= =?UTF-8?q?=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common.ts" | 10 +++ .../\346\223\215\344\275\234.spec.ts" | 62 +++++++++++++++++++ .../\351\201\270\346\212\236.spec.ts" | 12 +--- 3 files changed, 74 insertions(+), 10 deletions(-) create mode 100644 "tests/e2e/browser/\350\244\207\346\225\260\351\201\270\346\212\236/common.ts" create mode 100644 "tests/e2e/browser/\350\244\207\346\225\260\351\201\270\346\212\236/\346\223\215\344\275\234.spec.ts" rename "tests/e2e/browser/\350\244\207\346\225\260\351\201\270\346\212\236.spec.ts" => "tests/e2e/browser/\350\244\207\346\225\260\351\201\270\346\212\236/\351\201\270\346\212\236.spec.ts" (95%) diff --git "a/tests/e2e/browser/\350\244\207\346\225\260\351\201\270\346\212\236/common.ts" "b/tests/e2e/browser/\350\244\207\346\225\260\351\201\270\346\212\236/common.ts" new file mode 100644 index 0000000000..f3d3783019 --- /dev/null +++ "b/tests/e2e/browser/\350\244\207\346\225\260\351\201\270\346\212\236/common.ts" @@ -0,0 +1,10 @@ +import { Page } from "@playwright/test"; + +export async function addAudioCells(page: Page, count: number) { + for (let i = 0; i < count; i++) { + await page.getByRole("button", { name: "テキストを追加" }).click(); + await page.waitForTimeout(100); + } +} + +export const ctrlLike = process.platform === "darwin" ? "Meta" : "Control"; diff --git "a/tests/e2e/browser/\350\244\207\346\225\260\351\201\270\346\212\236/\346\223\215\344\275\234.spec.ts" "b/tests/e2e/browser/\350\244\207\346\225\260\351\201\270\346\212\236/\346\223\215\344\275\234.spec.ts" new file mode 100644 index 0000000000..9b48d031da --- /dev/null +++ "b/tests/e2e/browser/\350\244\207\346\225\260\351\201\270\346\212\236/\346\223\215\344\275\234.spec.ts" @@ -0,0 +1,62 @@ +import { test, expect, Page } from "@playwright/test"; +import { toggleSetting, navigateToMain } from "../../navigators"; +import { addAudioCells } from "./common"; + +/* + * 全てのAudioCellのキャラクター+スタイル名を取得する。 + * キャラクター+スタイル名はalt属性から取得する。 + * + * @returns キャラクター名の配列 + */ +async function getSelectedCharacters(page: Page): Promise { + const characterNames = await page.evaluate(() => { + const audioCells = [...document.querySelectorAll(".audio-cell")]; + const characterNames: string[] = []; + for (const audioCell of audioCells) { + const character = audioCell.querySelector(".icon-container > img"); + if (character) { + const alt = character.getAttribute("alt"); + if (!alt) { + throw new Error("alt属性がありません"); + } + + characterNames.push(alt); + } + } + return characterNames; + }); + return characterNames; +} + +test.beforeEach(async ({ page }) => { + const BASE_URL = "http://localhost:5173/#/home"; + await page.setViewportSize({ width: 800, height: 600 }); + await page.goto(BASE_URL); + + await navigateToMain(page); + await page.waitForTimeout(100); + await toggleSetting(page, "複数選択"); + + await addAudioCells(page, 3); +}); + +test("複数選択:キャラクター選択", async ({ page }) => { + await page.locator(".audio-cell:nth-child(2)").click(); + await page.keyboard.down("Shift"); + await page.keyboard.press("ArrowDown"); + await page.keyboard.press("ArrowDown"); + await page.keyboard.up("Shift"); + await page.waitForTimeout(100); + + await page.locator(".audio-cell:nth-child(2) .character-button").click(); + await page.waitForTimeout(100); + + await page.locator(".character-item-container .q-item:nth-child(2)").click(); + await page.waitForTimeout(100); + + const characterNames = await getSelectedCharacters(page); + + expect(characterNames[0]).not.toEqual(characterNames[1]); + expect(characterNames[1]).toEqual(characterNames[2]); + expect(characterNames[1]).toEqual(characterNames[3]); +}); diff --git "a/tests/e2e/browser/\350\244\207\346\225\260\351\201\270\346\212\236.spec.ts" "b/tests/e2e/browser/\350\244\207\346\225\260\351\201\270\346\212\236/\351\201\270\346\212\236.spec.ts" similarity index 95% rename from "tests/e2e/browser/\350\244\207\346\225\260\351\201\270\346\212\236.spec.ts" rename to "tests/e2e/browser/\350\244\207\346\225\260\351\201\270\346\212\236/\351\201\270\346\212\236.spec.ts" index 4918969730..c1b949c7e1 100644 --- "a/tests/e2e/browser/\350\244\207\346\225\260\351\201\270\346\212\236.spec.ts" +++ "b/tests/e2e/browser/\350\244\207\346\225\260\351\201\270\346\212\236/\351\201\270\346\212\236.spec.ts" @@ -1,5 +1,6 @@ import { test, expect, Page } from "@playwright/test"; -import { toggleSetting, navigateToMain } from "../navigators"; +import { toggleSetting, navigateToMain } from "../../navigators"; +import { ctrlLike, addAudioCells } from "./common"; test.beforeEach(async ({ page }) => { const BASE_URL = "http://localhost:5173/#/home"; @@ -13,8 +14,6 @@ test.beforeEach(async ({ page }) => { await addAudioCells(page, 3); }); -const ctrlLike = process.platform === "darwin" ? "Meta" : "Control"; - type SelectedStatus = { active: number; selected: number[]; @@ -46,13 +45,6 @@ async function getSelectedStatus(page: Page): Promise { return selectedAudioKeys; } -async function addAudioCells(page: Page, count: number) { - for (let i = 0; i < count; i++) { - await page.getByRole("button", { name: "テキストを追加" }).click(); - await page.waitForTimeout(100); - } -} - test("複数選択:マウス周り", async ({ page }) => { let selectedStatus: SelectedStatus; From 7c021b807812145922b5d12f2d9f12aa63f68117 Mon Sep 17 00:00:00 2001 From: sevenc-nanashi Date: Fri, 15 Sep 2023 00:50:24 +0900 Subject: [PATCH 3/8] Change: common.ts -> utils.ts --- .../\350\244\207\346\225\260\351\201\270\346\212\236/utils.ts" | 0 .../\345\200\244\345\244\211\346\233\264.spec.ts" | 2 +- .../\351\201\270\346\212\236.spec.ts" | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename "tests/e2e/browser/\350\244\207\346\225\260\351\201\270\346\212\236/common.ts" => "tests/e2e/browser/\350\244\207\346\225\260\351\201\270\346\212\236/utils.ts" (100%) rename "tests/e2e/browser/\350\244\207\346\225\260\351\201\270\346\212\236/\346\223\215\344\275\234.spec.ts" => "tests/e2e/browser/\350\244\207\346\225\260\351\201\270\346\212\236/\345\200\244\345\244\211\346\233\264.spec.ts" (97%) diff --git "a/tests/e2e/browser/\350\244\207\346\225\260\351\201\270\346\212\236/common.ts" "b/tests/e2e/browser/\350\244\207\346\225\260\351\201\270\346\212\236/utils.ts" similarity index 100% rename from "tests/e2e/browser/\350\244\207\346\225\260\351\201\270\346\212\236/common.ts" rename to "tests/e2e/browser/\350\244\207\346\225\260\351\201\270\346\212\236/utils.ts" diff --git "a/tests/e2e/browser/\350\244\207\346\225\260\351\201\270\346\212\236/\346\223\215\344\275\234.spec.ts" "b/tests/e2e/browser/\350\244\207\346\225\260\351\201\270\346\212\236/\345\200\244\345\244\211\346\233\264.spec.ts" similarity index 97% rename from "tests/e2e/browser/\350\244\207\346\225\260\351\201\270\346\212\236/\346\223\215\344\275\234.spec.ts" rename to "tests/e2e/browser/\350\244\207\346\225\260\351\201\270\346\212\236/\345\200\244\345\244\211\346\233\264.spec.ts" index 9b48d031da..5fe3ad1050 100644 --- "a/tests/e2e/browser/\350\244\207\346\225\260\351\201\270\346\212\236/\346\223\215\344\275\234.spec.ts" +++ "b/tests/e2e/browser/\350\244\207\346\225\260\351\201\270\346\212\236/\345\200\244\345\244\211\346\233\264.spec.ts" @@ -1,6 +1,6 @@ import { test, expect, Page } from "@playwright/test"; import { toggleSetting, navigateToMain } from "../../navigators"; -import { addAudioCells } from "./common"; +import { addAudioCells } from "./utils"; /* * 全てのAudioCellのキャラクター+スタイル名を取得する。 diff --git "a/tests/e2e/browser/\350\244\207\346\225\260\351\201\270\346\212\236/\351\201\270\346\212\236.spec.ts" "b/tests/e2e/browser/\350\244\207\346\225\260\351\201\270\346\212\236/\351\201\270\346\212\236.spec.ts" index c1b949c7e1..a47c5c07e1 100644 --- "a/tests/e2e/browser/\350\244\207\346\225\260\351\201\270\346\212\236/\351\201\270\346\212\236.spec.ts" +++ "b/tests/e2e/browser/\350\244\207\346\225\260\351\201\270\346\212\236/\351\201\270\346\212\236.spec.ts" @@ -1,6 +1,6 @@ import { test, expect, Page } from "@playwright/test"; import { toggleSetting, navigateToMain } from "../../navigators"; -import { ctrlLike, addAudioCells } from "./common"; +import { ctrlLike, addAudioCells } from "./utils"; test.beforeEach(async ({ page }) => { const BASE_URL = "http://localhost:5173/#/home"; From b82162bd2c1996d1d3c8add837760f1ef35133ea Mon Sep 17 00:00:00 2001 From: sevenc-nanashi Date: Fri, 15 Sep 2023 00:51:17 +0900 Subject: [PATCH 4/8] Change: CHANGE_VOICES -> MULTI_CHANGE_VOICE --- src/components/AudioCell.vue | 2 +- src/store/audio.ts | 8 ++++---- src/store/type.ts | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/components/AudioCell.vue b/src/components/AudioCell.vue index 342d1ab82e..e73007857e 100644 --- a/src/components/AudioCell.vue +++ b/src/components/AudioCell.vue @@ -262,7 +262,7 @@ const selectedVoice = computed({ }, set(voice: Voice | undefined) { if (voice == undefined) return; - store.dispatch("COMMAND_CHANGE_VOICES", { + store.dispatch("COMMAND_MULTI_CHANGE_VOICE", { audioKeys: isMultiSelectEnabled.value ? store.getters.SELECTED_AUDIO_KEYS : [props.audioKey], diff --git a/src/store/audio.ts b/src/store/audio.ts index 4192c3ca7d..7d03ab5c97 100644 --- a/src/store/audio.ts +++ b/src/store/audio.ts @@ -2082,7 +2082,7 @@ export const audioCommandStore = transformCommandStore( }, }, - COMMAND_CHANGE_VOICES: { + COMMAND_MULTI_CHANGE_VOICE: { mutation( draft, payload: { audioKeys: AudioKey[]; voice: Voice } & ( @@ -2159,7 +2159,7 @@ export const audioCommandStore = transformCommandStore( styleId, } ); - commit("COMMAND_CHANGE_VOICES", { + commit("COMMAND_MULTI_CHANGE_VOICE", { audioKeys, voice, update: "AccentPhrases", @@ -2172,7 +2172,7 @@ export const audioCommandStore = transformCommandStore( engineId, styleId, }); - commit("COMMAND_CHANGE_VOICES", { + commit("COMMAND_MULTI_CHANGE_VOICE", { audioKeys, voice, update: "AudioQuery", @@ -2180,7 +2180,7 @@ export const audioCommandStore = transformCommandStore( }); } } catch (error) { - commit("COMMAND_CHANGE_VOICES", { + commit("COMMAND_MULTI_CHANGE_VOICE", { audioKeys, voice, update: "RollbackStyleId", diff --git a/src/store/type.ts b/src/store/type.ts index fc54e5bf6a..b45a5e0856 100644 --- a/src/store/type.ts +++ b/src/store/type.ts @@ -525,7 +525,7 @@ export type AudioCommandStoreTypes = { action(payload: { audioKey: AudioKey; text: string }): void; }; - COMMAND_CHANGE_VOICES: { + COMMAND_MULTI_CHANGE_VOICE: { mutation: { audioKeys: AudioKey[]; voice: Voice } & ( | { update: "RollbackStyleId" } | { From b651e6e9ec1f35f51e4377c64527ced4d5128389 Mon Sep 17 00:00:00 2001 From: sevenc-nanashi Date: Sun, 17 Sep 2023 17:33:55 +0900 Subject: [PATCH 5/8] Change: audioKeysInitializingSpeaker -> audioKeysWithInitializingSpeaker --- src/components/AudioCell.vue | 2 +- src/components/CharacterPortrait.vue | 2 +- src/store/audio.ts | 10 +++++----- src/store/type.ts | 4 ++-- tests/unit/store/Vuex.spec.ts | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/components/AudioCell.vue b/src/components/AudioCell.vue index e73007857e..13f323f310 100644 --- a/src/components/AudioCell.vue +++ b/src/components/AudioCell.vue @@ -151,7 +151,7 @@ const userOrderedCharacterInfos = computed(() => { return infos; }); const isInitializingSpeaker = computed(() => - store.state.audioKeysInitializingSpeaker.includes(props.audioKey) + store.state.audioKeysWithInitializingSpeaker.includes(props.audioKey) ); const audioItem = computed(() => store.state.audioItems[props.audioKey]); diff --git a/src/components/CharacterPortrait.vue b/src/components/CharacterPortrait.vue index 0a6c29a165..334035ee4c 100644 --- a/src/components/CharacterPortrait.vue +++ b/src/components/CharacterPortrait.vue @@ -84,7 +84,7 @@ const isInitializingSpeaker = computed(() => { const activeAudioKey = store.getters.ACTIVE_AUDIO_KEY; return ( activeAudioKey && - store.state.audioKeysInitializingSpeaker.includes(activeAudioKey) + store.state.audioKeysWithInitializingSpeaker.includes(activeAudioKey) ); }); diff --git a/src/store/audio.ts b/src/store/audio.ts index 7d03ab5c97..4005f6440c 100644 --- a/src/store/audio.ts +++ b/src/store/audio.ts @@ -257,7 +257,7 @@ const getAudioElement = (() => { export const audioStoreState: AudioStoreState = { characterInfos: {}, - audioKeysInitializingSpeaker: [], + audioKeysWithInitializingSpeaker: [], morphableTargetsInfo: {}, audioItems: {}, audioKeys: [], @@ -515,23 +515,23 @@ export const audioStore = createPartialStore({ }); if (isInitialized) return; - commit("SET_AUDIO_KEYS_INITIALIZING_SPEAKER", { + commit("SET_AUDIO_KEYS_WITH_INITIALIZING_SPEAKER", { audioKeys, }); await dispatch("INITIALIZE_ENGINE_SPEAKER", { engineId, styleId, }).finally(() => { - commit("SET_AUDIO_KEYS_INITIALIZING_SPEAKER", { + commit("SET_AUDIO_KEYS_WITH_INITIALIZING_SPEAKER", { audioKeys: [], }); }); }, }, - SET_AUDIO_KEYS_INITIALIZING_SPEAKER: { + SET_AUDIO_KEYS_WITH_INITIALIZING_SPEAKER: { mutation(state, { audioKeys }: { audioKeys: AudioKey[] }) { - state.audioKeysInitializingSpeaker = audioKeys; + state.audioKeysWithInitializingSpeaker = audioKeys; }, }, diff --git a/src/store/type.ts b/src/store/type.ts index b45a5e0856..872921d133 100644 --- a/src/store/type.ts +++ b/src/store/type.ts @@ -124,7 +124,7 @@ export type StoreType = { export type AudioStoreState = { characterInfos: Record; morphableTargetsInfo: Record; - audioKeysInitializingSpeaker: AudioKey[]; + audioKeysWithInitializingSpeaker: AudioKey[]; audioItems: Record; audioKeys: AudioKey[]; audioStates: Record; @@ -192,7 +192,7 @@ export type AudioStoreTypes = { }): void; }; - SET_AUDIO_KEYS_INITIALIZING_SPEAKER: { + SET_AUDIO_KEYS_WITH_INITIALIZING_SPEAKER: { mutation: { audioKeys: AudioKey[] }; }; diff --git a/tests/unit/store/Vuex.spec.ts b/tests/unit/store/Vuex.spec.ts index 5f86a981ff..dbb8a654e9 100644 --- a/tests/unit/store/Vuex.spec.ts +++ b/tests/unit/store/Vuex.spec.ts @@ -27,7 +27,7 @@ describe("store/vuex.js test", () => { engineSupportedDevices: {}, altPortInfos: {}, characterInfos: {}, - audioKeysInitializingSpeaker: [], + audioKeysWithInitializingSpeaker: [], morphableTargetsInfo: {}, defaultStyleIds: [], userCharacterOrder: [], From 4ff5be5f80bea3853e984660c10015f9a663b7dd Mon Sep 17 00:00:00 2001 From: sevenc-nanashi Date: Sun, 17 Sep 2023 17:50:36 +0900 Subject: [PATCH 6/8] Change: SET_AUDIOS_VOICE -> SET_AUDIO_VOICE --- src/components/SettingDialog.vue | 2 +- src/store/audio.ts | 21 +++++++++------------ src/store/type.ts | 4 ++-- 3 files changed, 12 insertions(+), 15 deletions(-) diff --git a/src/components/SettingDialog.vue b/src/components/SettingDialog.vue index 3e58e07020..2c24e1b7c6 100644 --- a/src/components/SettingDialog.vue +++ b/src/components/SettingDialog.vue @@ -1089,7 +1089,7 @@ const updateAudioOutputDevices = async () => { return { label: device.label, key: device.deviceId }; }); }; -navigator.mediaDevices.addEventListener( +navigator.mediaDevices?.addEventListener( "devicechange", updateAudioOutputDevices ); diff --git a/src/store/audio.ts b/src/store/audio.ts index 4005f6440c..a6d6758bea 100644 --- a/src/store/audio.ts +++ b/src/store/audio.ts @@ -964,14 +964,9 @@ export const audioStore = createPartialStore({ }, }, - SET_AUDIOS_VOICE: { - mutation( - state, - { audioKeys, voice }: { audioKeys: AudioKey[]; voice: Voice } - ) { - for (const audioKey of audioKeys) { - state.audioItems[audioKey].voice = voice; - } + SET_AUDIO_VOICE: { + mutation(state, { audioKey, voice }: { audioKey: AudioKey; voice: Voice }) { + state.audioItems[audioKey].voice = voice; }, }, @@ -2097,10 +2092,12 @@ export const audioCommandStore = transformCommandStore( } ) ) { - audioStore.mutations.SET_AUDIOS_VOICE(draft, { - audioKeys: payload.audioKeys, - voice: payload.voice, - }); + for (const audioKey of payload.audioKeys) { + audioStore.mutations.SET_AUDIO_VOICE(draft, { + audioKey, + voice: payload.voice, + }); + } if (payload.update === "RollbackStyleId") return; diff --git a/src/store/type.ts b/src/store/type.ts index 872921d133..62080ed37d 100644 --- a/src/store/type.ts +++ b/src/store/type.ts @@ -345,8 +345,8 @@ export type AudioStoreTypes = { }): Promise; }; - SET_AUDIOS_VOICE: { - mutation: { audioKeys: AudioKey[]; voice: Voice }; + SET_AUDIO_VOICE: { + mutation: { audioKey: AudioKey; voice: Voice }; }; SET_ACCENT_PHRASES: { From 23e58f493fa19748dcb74757d8e34c1c168bf65c Mon Sep 17 00:00:00 2001 From: sevenc-nanashi Date: Sun, 17 Sep 2023 18:15:27 +0900 Subject: [PATCH 7/8] =?UTF-8?q?Revert:=20=E4=B8=8D=E8=A6=81=E3=81=AA?= =?UTF-8?q?=E5=A4=89=E6=9B=B4=E3=82=92Revert?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/store/audio.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/store/audio.ts b/src/store/audio.ts index a6d6758bea..ae2027f636 100644 --- a/src/store/audio.ts +++ b/src/store/audio.ts @@ -2136,7 +2136,7 @@ export const audioCommandStore = transformCommandStore( } }, async action( - { dispatch, commit, state }, + { state, dispatch, commit }, { audioKeys, voice }: { audioKeys: AudioKey[]; voice: Voice } ) { const engineId = voice.engineId; From d0166ea288747058b8d2dfa753eb6e90134d1d5f Mon Sep 17 00:00:00 2001 From: sevenc-nanashi Date: Tue, 19 Sep 2023 17:55:38 +0900 Subject: [PATCH 8/8] =?UTF-8?q?Fix:=20Vue=E3=81=AE=E5=9E=8B=E3=82=A8?= =?UTF-8?q?=E3=83=A9=E3=83=BC=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/EditorHome.vue | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/views/EditorHome.vue b/src/views/EditorHome.vue index a0a61c47b5..7b4a025a9a 100644 --- a/src/views/EditorHome.vue +++ b/src/views/EditorHome.vue @@ -526,7 +526,10 @@ watch(userOrderedCharacterInfos, (userOrderedCharacterInfos) => { }; // FIXME: UNDOができてしまうのでできれば直したい - store.dispatch("COMMAND_CHANGE_VOICE", { audioKey: first, voice: voice }); + store.dispatch("COMMAND_MULTI_CHANGE_VOICE", { + audioKeys: [first], + voice: voice, + }); } }); @@ -574,7 +577,7 @@ onMounted(async () => { // 最初の話者を初期化 store.dispatch("SETUP_SPEAKER", { - audioKey: newAudioKey, + audioKeys: [newAudioKey], engineId: audioItem.voice.engineId, styleId: audioItem.voice.styleId, });