Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
13 changes: 10 additions & 3 deletions static/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -123,10 +123,17 @@
<!-- Experimental automatic song-structure detection. Off makes the
pipeline skip the inference stage entirely; the backend reads
the setting once per job, so a change applies to the next import
without a restart. -->
<button class="stem-choice structure-toggle" type="button" id="autoSectionsBtn" aria-pressed="false" title="Experimental Song Structure Extraction" aria-label="Experimental Song Structure Extraction" data-i18n-title="structure.toggleTitle" data-i18n-aria-label="structure.toggleTitle">
without a restart.

It is named for the work it does at import time, not for the
sections bar. Called "Song structure" it read as the switch that
shows and hides that bar, so clicking it on an open track looked
broken: nothing moved, because nothing it controls belongs to a
track that has already been separated (#634). The bar has its
own control, "Sections" in the Collapse row. -->
<button class="stem-choice structure-toggle" type="button" id="autoSectionsBtn" aria-pressed="false" title="Experimental. Labels intro, verse and chorus while a track is imported. Applies to the next import, not to a track that is already open. To hide the sections bar, use Collapse > Sections." aria-label="Detect song structure on import (experimental)" data-i18n-title="structure.toggleTitle" data-i18n-aria-label="structure.toggleAria">
<span class="structure-toggle-main">
<span data-i18n="structure.toggle">Song structure</span>
<span data-i18n="structure.toggle">Detect structure</span>
</span>
<span class="structure-toggle-note" data-i18n="structure.experimental">Experimental</span>
</button>
Expand Down
50 changes: 30 additions & 20 deletions static/js/i18n.js
Original file line number Diff line number Diff line change
Expand Up @@ -231,8 +231,9 @@ const en = {
"sections.clear": "Clear",
"sections.clearAria": "Clear all sections",
"sections.clearConfirm": "Confirm?",
"structure.toggle": "Song structure",
"structure.toggleTitle": "Experimental Song Structure Extraction: automatically label intro, verse and chorus after a split",
"structure.toggle": "Detect structure",
"structure.toggleTitle": "Experimental. Labels intro, verse and chorus while a track is imported. Applies to the next import, not to a track that is already open. To hide the sections bar, use Collapse > Sections.",
"structure.toggleAria": "Detect song structure on import (experimental)",
"structure.experimental": "Experimental",
"doc.title": "StemDeck — split any track into stems",

Expand Down Expand Up @@ -848,8 +849,9 @@ const pl = {
"sections.clear": "Wyczyść",
"sections.clearAria": "Wyczyść wszystkie sekcje",
"sections.clearConfirm": "Potwierdzić?",
"structure.toggle": "Struktura utworu",
"structure.toggleTitle": "Eksperymentalne wykrywanie struktury utworu: automatycznie oznacza intro, zwrotkę i refren po podziale",
"structure.toggle": "Wykryj strukturę",
"structure.toggleTitle": "Eksperymentalne. Oznacza intro, zwrotkę i refren podczas importu utworu. Dotyczy następnego importu, a nie utworu już otwartego. Aby ukryć pasek sekcji, użyj Zwiń > Sekcje.",
"structure.toggleAria": "Wykryj strukturę utworu podczas importu (eksperymentalne)",
"structure.experimental": "Eksperymentalne",
"doc.title": "StemDeck — rozdziel dowolny utwór na ścieżki",

Expand Down Expand Up @@ -1455,8 +1457,9 @@ const ja = {
"sections.clear": "クリア",
"sections.clearAria": "すべてのセクションを削除",
"sections.clearConfirm": "確認?",
"structure.toggle": "曲の構成",
"structure.toggleTitle": "実験的な楽曲構造抽出: 分離後にイントロ、Aメロ、サビを自動でラベル付けします",
"structure.toggle": "構成を検出",
"structure.toggleTitle": "実験的機能です。読み込み時にイントロ、Aメロ、サビを自動でラベル付けします。次回の読み込みに適用され、すでに開いている曲には影響しません。セクションバーを隠すには「折りたたむ > セクション」を使ってください。",
"structure.toggleAria": "読み込み時に曲の構成を検出(実験的)",
"structure.experimental": "試験的",
"doc.title": "StemDeck — トラックをパートごとに分離",

Expand Down Expand Up @@ -2037,8 +2040,9 @@ const zhHans = {
"sections.clear": "清除",
"sections.clearAria": "清除所有段落",
"sections.clearConfirm": "确认?",
"structure.toggle": "歌曲结构",
"structure.toggleTitle": "实验性歌曲结构提取: 分离后自动标记前奏、主歌和副歌",
"structure.toggle": "检测结构",
"structure.toggleTitle": "实验性功能。在导入时标记前奏、主歌和副歌。仅对下次导入生效,不影响已经打开的歌曲。要隐藏段落栏,请使用“折叠 > 段落”。",
"structure.toggleAria": "导入时检测歌曲结构(实验性)",
"structure.experimental": "实验性",
"doc.title": "StemDeck — 将任意曲目分离为音轨",

Expand Down Expand Up @@ -2619,8 +2623,9 @@ const de = {
"sections.clear": "Löschen",
"sections.clearAria": "Alle Abschnitte löschen",
"sections.clearConfirm": "Sicher?",
"structure.toggle": "Songstruktur",
"structure.toggleTitle": "Experimentelle Songstruktur-Erkennung: beschriftet Intro, Strophe und Refrain nach dem Trennen automatisch",
"structure.toggle": "Struktur erkennen",
"structure.toggleTitle": "Experimentell. Beschriftet Intro, Strophe und Refrain beim Importieren. Gilt für den nächsten Import, nicht für einen bereits geöffneten Titel. Zum Ausblenden der Abschnittsleiste: Einklappen > Abschnitte.",
"structure.toggleAria": "Songstruktur beim Import erkennen (experimentell)",
"structure.experimental": "Experimentell",
"doc.title": "StemDeck — jeden Track in Stems zerlegen",

Expand Down Expand Up @@ -3212,8 +3217,9 @@ const pt = {
"sections.clear": "Limpar",
"sections.clearAria": "Limpar todas as seções",
"sections.clearConfirm": "Confirmar?",
"structure.toggle": "Estrutura da música",
"structure.toggleTitle": "Extração experimental da estrutura da música: marca intro, verso e refrão automaticamente após a separação",
"structure.toggle": "Detectar estrutura",
"structure.toggleTitle": "Experimental. Marca intro, verso e refrão durante a importação. Vale para a próxima importação, não para uma música já aberta. Para esconder a barra de seções, use Recolher > Seções.",
"structure.toggleAria": "Detectar a estrutura da música na importação (experimental)",
"structure.experimental": "Experimental",
"doc.title": "StemDeck — separe qualquer faixa em stems",

Expand Down Expand Up @@ -3807,8 +3813,9 @@ const id = {
"sections.clear": "Hapus",
"sections.clearAria": "Hapus semua bagian",
"sections.clearConfirm": "Yakin?",
"structure.toggle": "Struktur lagu",
"structure.toggleTitle": "Ekstraksi struktur lagu eksperimental: menandai intro, bait, dan refrein secara otomatis setelah pemisahan",
"structure.toggle": "Deteksi struktur",
"structure.toggleTitle": "Eksperimental. Menandai intro, bait, dan refrein saat lagu diimpor. Berlaku untuk impor berikutnya, bukan untuk lagu yang sudah terbuka. Untuk menyembunyikan bilah bagian, gunakan Ciutkan > Bagian.",
"structure.toggleAria": "Deteksi struktur lagu saat impor (eksperimental)",
"structure.experimental": "Eksperimental",
"doc.title": "StemDeck — pisahkan trek apa pun menjadi stem",

Expand Down Expand Up @@ -4389,8 +4396,9 @@ const fr = {
"sections.clear": "Effacer",
"sections.clearAria": "Effacer toutes les sections",
"sections.clearConfirm": "Confirmer ?",
"structure.toggle": "Structure du morceau",
"structure.toggleTitle": "Extraction expérimentale de la structure: étiquette automatiquement intro, couplet et refrain après la séparation",
"structure.toggle": "Détecter la structure",
"structure.toggleTitle": "Expérimental. Étiquette intro, couplet et refrain pendant l'import. S'applique au prochain import, pas à un morceau déjà ouvert. Pour masquer la barre des sections, utilisez Réduire > Sections.",
"structure.toggleAria": "Détecter la structure du morceau à l'import (expérimental)",
"structure.experimental": "Expérimental",
"doc.title": "StemDeck — séparez n'importe quel morceau en pistes",

Expand Down Expand Up @@ -5100,8 +5108,9 @@ const es = {
"sections.clear": "Borrar",
"sections.clearAria": "Borrar todas las secciones",
"sections.clearConfirm": "¿Confirmar?",
"structure.toggle": "Estructura de la canción",
"structure.toggleTitle": "Extracción experimental de la estructura: etiqueta automáticamente intro, verso y estribillo tras la separación",
"structure.toggle": "Detectar estructura",
"structure.toggleTitle": "Experimental. Etiqueta intro, verso y estribillo durante la importación. Se aplica a la próxima importación, no a una canción ya abierta. Para ocultar la barra de secciones, usa Contraer > Secciones.",
"structure.toggleAria": "Detectar la estructura de la canción al importar (experimental)",
"structure.experimental": "Experimental",
"doc.title": "StemDeck — separa cualquier pista en stems",

Expand Down Expand Up @@ -5716,8 +5725,9 @@ const ko = {
"sections.clear": "지우기",
"sections.clearAria": "모든 구간 지우기",
"sections.clearConfirm": "정말요?",
"structure.toggle": "곡 구조",
"structure.toggleTitle": "실험적 곡 구조 분석: 분리한 뒤 인트로, 벌스, 코러스를 자동으로 표시해요",
"structure.toggle": "구조 감지",
"structure.toggleTitle": "실험적 기능이에요. 가져오는 동안 인트로, 벌스, 코러스를 표시해요. 이미 열려 있는 곡이 아니라 다음에 가져오는 곡부터 적용돼요. 구간 막대를 숨기려면 접기 > 구간을 사용하세요.",
"structure.toggleAria": "가져올 때 곡 구조 감지 (실험적)",
"structure.experimental": "실험적",
"doc.title": "StemDeck, 어떤 곡이든 스템으로 분리",

Expand Down
39 changes: 39 additions & 0 deletions tests/e2e/song-structure-toggle.spec.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,43 @@ test.describe("song structure toggle", () => {
await expect(button(page)).toHaveAttribute("aria-pressed", "false");
await expect.poll(() => setting(page)).toBe(false);
});

// Two controls, one word between them. This one runs a pass at import time;
// the sections bar is shown and hidden by "Sections" in the Collapse row. A
// reporter read the first as the second, clicked it on an open track, and saw
// a button change colour while nothing else moved (#634).
test("it does not show or hide the sections bar, which has its own control", async ({ page }) => {
await openStudio(page, { tauri: true });
const app = page.locator(".app");
const ribbon = page.locator(".daw-section-ribbon");
const panelToggle = page.locator('.daw-panel-toggle[data-panel="sections"]');

await expect(ribbon).toBeVisible();

// Both directions: the bar is still there whether the toggle goes on or off.
await button(page).click();
await expect(button(page)).toHaveAttribute("aria-pressed", "true");
await expect(ribbon).toBeVisible();
await button(page).click();
await expect(button(page)).toHaveAttribute("aria-pressed", "false");
await expect(ribbon).toBeVisible();

// And the control that does own the bar still owns it.
await panelToggle.click();
await expect(app).toHaveClass(/panel-sections-off/);
await panelToggle.click();
await expect(app).not.toHaveClass(/panel-sections-off/);
await expect(ribbon).toBeVisible();
});

// The label is the fix for #634. Naming the work it does at import time is
// what stops it reading as the switch for the sections bar, so it is pinned
// rather than left to the next person tidying up wording.
test("the button names the import, not the sections bar", async ({ page }) => {
await openStudio(page, { tauri: true });

await expect(button(page)).toContainText(/detect/i);
await expect(button(page)).toHaveAttribute("aria-label", /import/i);
await expect(button(page)).toHaveAttribute("title", /next import/i);
});
});
Loading