From 40e10d16924ff221a426adb7dc8ea40cc3419d89 Mon Sep 17 00:00:00 2001 From: leon-morival Date: Wed, 22 Oct 2025 16:32:58 +0200 Subject: [PATCH] fix structure --- functions/src/lyrics.js | 20 ++-- src/screens/Library/MusicDetails.js | 26 +++++- src/screens/Library/MusicDetails.web.js | 8 +- src/utils/songStructure.js | 119 +++++++++--------------- 4 files changed, 74 insertions(+), 99 deletions(-) diff --git a/functions/src/lyrics.js b/functions/src/lyrics.js index 07cd241..b0288e6 100644 --- a/functions/src/lyrics.js +++ b/functions/src/lyrics.js @@ -15,7 +15,6 @@ const STRUCTURE_PROMPT_LABELS = { refrain: "refrain", short_intro: "introduction instrumentale courte", long_intro: "introduction instrumentale longue", - pre_chorus: "pré-refrain", pre_refrain_instrumental: "pré-refrain instrumental", pont: "pont", solo_de_guitare: "solo de guitare", @@ -39,11 +38,12 @@ const STRUCTURE_ALIASES = { "long intro": "long_intro", "introduction instrumentale longue": "long_intro", "intro instrumentale longue": "long_intro", - "pré-refrain": "pre_chorus", - "pre-refrain": "pre_chorus", - "pre chorus": "pre_chorus", - "pre-chorus": "pre_chorus", - prechorus: "pre_chorus", + "pré-refrain": "pre_refrain_instrumental", + "pre-refrain": "pre_refrain_instrumental", + "pre_refrain": "pre_refrain_instrumental", + "pre chorus": "pre_refrain_instrumental", + "pre-chorus": "pre_refrain_instrumental", + prechorus: "pre_refrain_instrumental", "pré-refrain instrumental": "pre_refrain_instrumental", "pre-refrain instrumental": "pre_refrain_instrumental", "instrumental pre-chorus": "pre_refrain_instrumental", @@ -85,14 +85,8 @@ const sanitizeStructureEntries = (structure = []) => { output.push(normalized); return; } - if (normalized === "pre_chorus") { - if (!output.includes("pre_chorus")) output.push("pre_chorus"); - return; - } if (normalized === "pre_refrain_instrumental") { - if (!output.includes("pre_refrain_instrumental")) { - output.push("pre_refrain_instrumental"); - } + output.push("pre_refrain_instrumental"); return; } if ( diff --git a/src/screens/Library/MusicDetails.js b/src/screens/Library/MusicDetails.js index a4f3250..34ee177 100644 --- a/src/screens/Library/MusicDetails.js +++ b/src/screens/Library/MusicDetails.js @@ -31,6 +31,12 @@ import { Palette } from "../../styles"; import { FONT_FAMILY } from "../../styles/Fonts"; import Style, { gutters, size } from "../../styles/Style"; import { getArtistDisplayName } from "../../utils/artistName"; +import { + formatStructureLabel, + getPromptLabelForStructure, + getSegmentMeta, + normalizeStructureType, +} from "../../utils/songStructure"; // 20 secondes const timeBeforeIncrement = 20000; @@ -363,6 +369,14 @@ const MusicDetails = ({ route }) => { let type = "section"; if (lower.includes("refrain") || lower.includes("chorus")) type = "refrain"; else if (lower.includes("couplet") || lower.includes("verse")) type = "couplet"; + else if ( + lower.includes("pré") || + lower.includes("prechorus") || + lower.includes("pre-chorus") || + lower.includes("pre chorus") || + lower.includes("pre-refrain") + ) + type = "pre_refrain_instrumental"; else if (lower.includes("pont") || lower.includes("bridge")) type = "pont"; else if (lower.includes("intro")) type = "intro"; const indexMatch = label.match(/(\d+)/); @@ -371,10 +385,14 @@ const MusicDetails = ({ route }) => { }; const formatSectionLabel = (type, index, fallback) => { if (fallback) return fallback; - if (type === "refrain") return index > 1 ? `Refrain ${index}` : "Refrain"; - if (type === "couplet") return index > 1 ? `Couplet ${index}` : "Couplet"; - if (type === "pont") return index > 1 ? `Pont ${index}` : "Pont"; - if (type === "intro") return "Intro"; + const normalized = normalizeStructureType(type); + const meta = getSegmentMeta(normalized); + if (meta) { + const label = formatStructureLabel(normalized, index); + if (label) return label; + } + const prompt = getPromptLabelForStructure(normalized); + if (prompt) return prompt; return index > 1 ? `Section ${index}` : "Section"; }; diff --git a/src/screens/Library/MusicDetails.web.js b/src/screens/Library/MusicDetails.web.js index 7ee8e38..920017a 100644 --- a/src/screens/Library/MusicDetails.web.js +++ b/src/screens/Library/MusicDetails.web.js @@ -444,7 +444,7 @@ const MusicDetails = ({ route }) => { lower.includes("pre chorus") || lower.includes("pre-refrain") ) - type = "pre_chorus"; + type = "pre_refrain_instrumental"; else if (lower.includes("pont") || lower.includes("bridge")) type = "pont"; else if (lower.includes("intro")) { if (lower.includes("long")) type = "long_intro"; @@ -464,12 +464,6 @@ const MusicDetails = ({ route }) => { } const prompt = getPromptLabelForStructure(normalized); if (prompt) return prompt; - if (normalized === "refrain") - return index > 1 ? `Refrain ${index}` : "Refrain"; - if (normalized === "couplet") - return index > 1 ? `Couplet ${index}` : "Couplet"; - if (type === "pont") return index > 1 ? `Pont ${index}` : "Pont"; - if (type === "intro") return index > 1 ? `Intro ${index}` : "Intro"; return index > 1 ? `Section ${index}` : "Section"; }; diff --git a/src/utils/songStructure.js b/src/utils/songStructure.js index 55439f8..f97bca0 100644 --- a/src/utils/songStructure.js +++ b/src/utils/songStructure.js @@ -65,26 +65,6 @@ export const STRUCTURE_SEGMENTS = { "intro instrumentale longue", ], }, - // pre_chorus: { - // label: "Pré-refrain", - // promptLabel: "Pré-refrain", - // showIndex: false, - pre_chorus: { - label: "Pré-refrain", - promptLabel: "Pré-refrain", - showIndex: false, - allowMultiple: false, - optional: true, - inputHeight: 150, - requiresLyrics: true, - aliases: [ - "pré-refrain", - "pre-refrain", - "prechorus", - "pre chorus", - "pré chorus", - ], - }, pre_refrain_instrumental: { label: "Pré-refrain instrumental", promptLabel: "Pré-refrain instrumental", @@ -94,7 +74,7 @@ export const STRUCTURE_SEGMENTS = { inputHeight: 150, exclusiveGroup: "pre_chorus", requiresLyrics: false, - aliases: ["instrumental_pre_chorus"], + aliases: [], }, pont: { label: "Pont", @@ -103,8 +83,8 @@ export const STRUCTURE_SEGMENTS = { allowMultiple: true, optional: true, inputHeight: 225, - requiresLyrics: true, - aliases: ["bridge"], + requiresLyrics: false, + aliases: [], }, solo_de_guitare: { label: "Solo de guitare", @@ -114,7 +94,7 @@ export const STRUCTURE_SEGMENTS = { optional: true, inputHeight: 150, requiresLyrics: false, - aliases: ["guitar_solo", "solo_guitare"], + aliases: [], }, solo_de_guitare_electrique: { label: "Solo de guitare électrique", @@ -124,7 +104,7 @@ export const STRUCTURE_SEGMENTS = { optional: true, inputHeight: 150, requiresLyrics: false, - aliases: ["electric_guitar_solo", "solo_guitare_electrique"], + aliases: [], }, solo_de_batterie: { label: "Solo de batterie", @@ -134,7 +114,7 @@ export const STRUCTURE_SEGMENTS = { optional: true, inputHeight: 150, requiresLyrics: false, - aliases: ["drum_solo", "solo_batterie"], + aliases: [], }, solo_de_saxophone: { label: "Solo de saxophone", @@ -144,7 +124,7 @@ export const STRUCTURE_SEGMENTS = { optional: true, inputHeight: 150, requiresLyrics: false, - aliases: ["sax_solo", "solo_saxo"], + aliases: [], }, solo_de_violon: { label: "Solo de violon", @@ -154,7 +134,7 @@ export const STRUCTURE_SEGMENTS = { optional: true, inputHeight: 150, requiresLyrics: false, - aliases: ["violin_solo", "solo_violon"], + aliases: [], }, break: { label: "Break", @@ -184,7 +164,7 @@ export const STRUCTURE_SEGMENTS = { optional: true, inputHeight: 150, requiresLyrics: false, - aliases: ["melodic_interlude"], + aliases: [], }, final_apogee: { label: "Final apogée", @@ -195,7 +175,7 @@ export const STRUCTURE_SEGMENTS = { inputHeight: 170, exclusiveGroup: "outro", requiresLyrics: false, - aliases: ["grand_finale"], + aliases: [], }, arret_net: { label: "Arrêt net", @@ -206,7 +186,7 @@ export const STRUCTURE_SEGMENTS = { inputHeight: 150, exclusiveGroup: "outro", requiresLyrics: false, - aliases: ["sudden_stop"], + aliases: [], }, fade_out: { label: "Fade out", @@ -228,7 +208,7 @@ export const STRUCTURE_SEGMENTS = { inputHeight: 150, exclusiveGroup: "outro", requiresLyrics: false, - aliases: ["soft_transition"], + aliases: [], }, }; @@ -243,6 +223,32 @@ const ALIAS_TO_KEY = Object.entries(STRUCTURE_SEGMENTS).reduce( {} ); +const LEGACY_STRUCTURE_ALIASES = { + pre_chorus: "pre_refrain_instrumental", + "pré-refrain": "pre_refrain_instrumental", + "pre-refrain": "pre_refrain_instrumental", + "pre_refrain": "pre_refrain_instrumental", + prechorus: "pre_refrain_instrumental", + "pre chorus": "pre_refrain_instrumental", + "pre-chorus": "pre_refrain_instrumental", + instrumental_pre_chorus: "pre_refrain_instrumental", + bridge: "pont", + guitar_solo: "solo_de_guitare", + electric_guitar_solo: "solo_de_guitare_electrique", + drum_solo: "solo_de_batterie", + sax_solo: "solo_de_saxophone", + violin_solo: "solo_de_violon", + melodic_interlude: "interlude_melodique", + grand_finale: "final_apogee", + sudden_stop: "arret_net", + soft_transition: "transition_douce", +}; + +Object.entries(LEGACY_STRUCTURE_ALIASES).forEach(([alias, target]) => { + const key = String(alias).toLowerCase(); + ALIAS_TO_KEY[key] = target; +}); + const sanitizeToken = (value) => String(value || "") .trim() @@ -281,7 +287,6 @@ export const normalizeStructureType = (value) => { export const sanitizeStructureList = (structure = []) => { if (!Array.isArray(structure)) return []; const output = []; - let shouldInjectPreChorus = false; let shouldInjectInstrumentalPreChorus = false; structure.forEach((segment) => { @@ -306,10 +311,6 @@ export const sanitizeStructureList = (structure = []) => { } } - if (type === "pre_chorus") { - shouldInjectPreChorus = true; - return; - } if (type === "pre_refrain_instrumental") { shouldInjectInstrumentalPreChorus = true; return; @@ -320,54 +321,22 @@ export const sanitizeStructureList = (structure = []) => { let result = output; - if (shouldInjectPreChorus) { - const baseWithoutPre = result.filter((item) => item !== "pre_chorus"); - const hasRefrain = baseWithoutPre.some((item) => item === "refrain"); + if (shouldInjectInstrumentalPreChorus) { const expanded = []; + let hasRefrain = false; - baseWithoutPre.forEach((item, idx) => { + result.forEach((item) => { if (item === "refrain") { + hasRefrain = true; const previous = expanded[expanded.length - 1]; - if (previous !== "pre_chorus") { - expanded.push("pre_chorus"); + if (previous !== "pre_refrain_instrumental") { + expanded.push("pre_refrain_instrumental"); } } expanded.push(item); }); if (!hasRefrain) { - expanded.push("pre_chorus"); - } - - result = expanded; - } - - if (shouldInjectInstrumentalPreChorus) { - const baseWithoutInstrumental = result.filter( - (item) => item !== "pre_refrain_instrumental" - ); - const expanded = []; - - baseWithoutInstrumental.forEach((item) => { - if (item === "pre_chorus") { - const previous = expanded[expanded.length - 1]; - if (previous !== "pre_refrain_instrumental") { - expanded.push("pre_refrain_instrumental"); - } - } - if (item === "refrain") { - const previous = expanded[expanded.length - 1]; - if ( - previous !== "pre_refrain_instrumental" && - previous !== "pre_chorus" - ) { - expanded.push("pre_refrain_instrumental"); - } - } - expanded.push(item); - }); - - if (!expanded.includes("pre_refrain_instrumental")) { expanded.push("pre_refrain_instrumental"); }