new song structure
This commit is contained in:
@@ -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";
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user