new song structure

This commit is contained in:
2025-10-21 11:38:48 +02:00
parent 59328aaaed
commit 3a5d449424
11 changed files with 807 additions and 175 deletions
+32 -6
View File
@@ -37,6 +37,11 @@ import Page from "../../layouts/Page";
import { Palette } from "../../styles";
import { FONT_FAMILY } from "../../styles/Fonts";
import Style, { gutters, size } from "../../styles/Style";
import {
formatStructureLabel,
getSegmentMeta,
normalizeStructureType,
} from "../../utils/songStructure";
// 20 secondes
const timeBeforeIncrement = 20000;
@@ -325,12 +330,14 @@ const MusicDetails = ({ route }) => {
const description = useMemo(() => {
// Build a readable text from lyrics with section labels
if (Array.isArray(project?.lyrics)) {
const counts = {};
return project.lyrics
.map((s) => {
const body = (s?.lyrics || "").trim();
if (!body) return null;
const t = (s?.type || "").toLowerCase();
const label = t === "refrain" ? "Refrain" : "Couplet";
const type = normalizeStructureType(s?.type);
counts[type] = (counts[type] || 0) + 1;
const label = formatStructureLabel(type, counts[type]);
return `[${label}]\n${body}`;
})
.filter(Boolean)
@@ -370,22 +377,41 @@ const MusicDetails = ({ route }) => {
if (!match) return null;
const label = match[1]?.trim() || "";
const lower = label.toLowerCase();
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_chorus";
else if (lower.includes("bridge")) type = "bridge";
else if (lower.includes("intro")) type = "intro";
else if (lower.includes("intro")) {
if (lower.includes("long")) type = "long_intro";
else type = "short_intro";
}
const indexMatch = label.match(/(\d+)/);
const index = indexMatch ? Number(indexMatch[1]) : undefined;
return { label, type, index };
};
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";
const normalized = normalizeStructureType(type);
const meta = getSegmentMeta(normalized);
if (meta) {
return formatStructureLabel(normalized, index);
}
if (normalized === "refrain")
return index > 1 ? `Refrain ${index}` : "Refrain";
if (normalized === "couplet")
return index > 1 ? `Couplet ${index}` : "Couplet";
if (type === "bridge") return index > 1 ? `Pont ${index}` : "Pont";
if (type === "intro") return "Intro";
if (type === "intro") return index > 1 ? `Intro ${index}` : "Intro";
return index > 1 ? `Section ${index}` : "Section";
};