diff --git a/src/components/AudioDetail.vue b/src/components/AudioDetail.vue
index ee8f80c465..02d200d147 100644
--- a/src/components/AudioDetail.vue
+++ b/src/components/AudioDetail.vue
@@ -69,6 +69,7 @@
]"
@click="setPlayAndStartPoint(accentPhraseIndex)"
>
+
@@ -278,6 +279,8 @@ import {
import ToolTip from "./ToolTip.vue";
import AudioAccent from "./AudioAccent.vue";
import AudioParameter from "./AudioParameter.vue";
+import ContextMenu from "./ContextMenu.vue";
+import { MenuItemButton } from "./MenuBar.vue";
import { useStore } from "@/store";
import {
AudioKey,
@@ -424,6 +427,22 @@ const setPlayAndStartPoint = (accentPhraseIndex: number) => {
}
};
+// accentPhraseIndexごとにcontext-menuの内容を用意する
+const accentPhraseMenudata = computed(() => (accentPhraseIndex: number): [
+ MenuItemButton
+] => {
+ return [
+ {
+ type: "button",
+ label: "削除",
+ onClick: async () => {
+ deleteAccentPhrase(accentPhraseIndex);
+ },
+ disableWhenUiLocked: true,
+ },
+ ];
+});
+
const lastPitches = ref([]);
watch(accentPhrases, async (newPhrases) => {
activePoint.value = startPoint.value;
@@ -457,6 +476,12 @@ const toggleAccentPhraseSplit = (
...(!isPause ? { isPause, moraIndex: moraIndex as number } : { isPause }),
});
};
+const deleteAccentPhrase = (phraseIndex: number) => {
+ store.dispatch("COMMAND_DELETE_ACCENT_PHRASE", {
+ audioKey: props.activeAudioKey,
+ accentPhraseIndex: phraseIndex,
+ });
+};
const maxPitch = 6.5;
const minPitch = 3;
diff --git a/src/store/audio.ts b/src/store/audio.ts
index cc3b2f4d0c..4e5af1bc1f 100644
--- a/src/store/audio.ts
+++ b/src/store/audio.ts
@@ -2387,6 +2387,35 @@ export const audioCommandStore = transformCommandStore(
},
},
+ COMMAND_DELETE_ACCENT_PHRASE: {
+ async action(
+ { state, commit },
+ {
+ audioKey,
+ accentPhraseIndex,
+ }: {
+ audioKey: AudioKey;
+ accentPhraseIndex: number;
+ }
+ ) {
+ const query = state.audioItems[audioKey].query;
+ if (query == undefined) throw new Error("query == undefined");
+
+ const originAccentPhrases = query.accentPhrases;
+
+ const newAccentPhrases = [
+ ...originAccentPhrases.slice(0, accentPhraseIndex),
+ ...originAccentPhrases.slice(accentPhraseIndex + 1),
+ ];
+
+ // 自動再調整は行わない
+ commit("COMMAND_CHANGE_SINGLE_ACCENT_PHRASE", {
+ audioKey,
+ accentPhrases: newAccentPhrases,
+ });
+ },
+ },
+
COMMAND_CHANGE_SINGLE_ACCENT_PHRASE: {
mutation(
draft,
diff --git a/src/store/type.ts b/src/store/type.ts
index 140409122a..4712bfb041 100644
--- a/src/store/type.ts
+++ b/src/store/type.ts
@@ -563,6 +563,10 @@ export type AudioCommandStoreTypes = {
): void;
};
+ COMMAND_DELETE_ACCENT_PHRASE: {
+ action(payload: { audioKey: AudioKey; accentPhraseIndex: number }): void;
+ };
+
COMMAND_CHANGE_SINGLE_ACCENT_PHRASE: {
mutation: { audioKey: AudioKey; accentPhrases: AccentPhrase[] };
action(payload: {
diff --git "a/tests/e2e/browser/\351\237\263\345\243\260\350\251\263\347\264\260.spec.ts" "b/tests/e2e/browser/\351\237\263\345\243\260\350\251\263\347\264\260.spec.ts"
new file mode 100644
index 0000000000..c7e4584a0a
--- /dev/null
+++ "b/tests/e2e/browser/\351\237\263\345\243\260\350\251\263\347\264\260.spec.ts"
@@ -0,0 +1,30 @@
+import { test, expect } from "@playwright/test";
+
+import { navigateToMain } from "../navigators";
+
+test.beforeEach(async ({ page }) => {
+ const BASE_URL = "http://localhost:5173/#/home";
+ await page.setViewportSize({ width: 800, height: 600 });
+ await page.goto(BASE_URL);
+});
+
+test("詳細調整欄のコンテキストメニュー", async ({ page }) => {
+ await navigateToMain(page);
+ await page.waitForTimeout(100);
+
+ // 削除
+ await page.getByRole("textbox", { name: "1行目" }).click();
+ await page.getByRole("textbox", { name: "1行目" }).fill("1234");
+ await page.getByRole("textbox", { name: "1行目" }).press("Enter");
+ await page.getByText("サンジュウ").click({
+ button: "right",
+ });
+ await page
+ .getByRole("listitem")
+ .filter({ has: page.getByText("削除") })
+ .click();
+ await page.waitForTimeout(100);
+ await expect(page.getByText("サンジュウ")).not.toBeVisible();
+ await expect(page.getByText("ニヒャク")).toBeVisible();
+ await expect(page.getByText("ヨン")).toBeVisible();
+});