instrumental introduction

This commit is contained in:
2025-10-21 13:34:16 +02:00
parent 3a5d449424
commit 837a634997
6 changed files with 226 additions and 92 deletions
+72 -14
View File
@@ -17,9 +17,11 @@ import { Palette, gutters } from "../../styles";
import { FONT_FAMILY } from "../../styles/Fonts";
import {
formatStructureLabel,
getPromptLabelForStructure,
getSegmentMeta,
normalizeStructureType,
sanitizeStructureList,
segmentRequiresLyrics,
} from "../../utils/songStructure";
import CustomInput from "./components/CustomInput";
@@ -52,21 +54,42 @@ const Lyrics = ({ navigation }) => {
? sanitizeStructureList(projectConfig.structure)
: null;
if (normalizedSections.length) {
return {
title,
sections: normalizedSections,
};
const structureToUse =
targetStructure && targetStructure.length
? targetStructure
: normalizedSections.map((s) => s.type);
if (!structureToUse.length && normalizedSections.length) {
return { title, sections: normalizedSections };
}
if (targetStructure && targetStructure.length) {
return {
title,
sections: targetStructure.map((t) => ({ type: t, lyrics: "" })),
};
}
const remaining = [...normalizedSections];
const takeMatching = (type) => {
const index = remaining.findIndex((s) => s.type === type);
if (index !== -1) {
return remaining.splice(index, 1)[0];
}
return remaining.shift() || null;
};
return { title, sections: [] };
const sections = structureToUse.map((segmentType) => {
const normalizedType = normalizeStructureType(segmentType);
if (!segmentRequiresLyrics(normalizedType)) {
return { type: normalizedType, lyrics: "" };
}
const matched = takeMatching(normalizedType);
return {
type: normalizedType,
lyrics: matched?.lyrics || "",
};
});
const remainingTextual = remaining.filter((item) =>
segmentRequiresLyrics(item.type)
);
sections.push(...remainingTextual);
return { title, sections };
}, [projectTitle, projectLyrics, projectConfig]);
const [titleValue, setTitleValue] = useState(initial.title || "");
@@ -131,7 +154,11 @@ const Lyrics = ({ navigation }) => {
alertMessage("Titre manquant", "Veuillez renseigner un titre.");
return;
}
const invalid = (sections || []).some((s) => !(s?.lyrics || "").trim());
const invalid = (sections || []).some((s) => {
const type = normalizeStructureType(s?.type);
if (!segmentRequiresLyrics(type)) return false;
return !(s?.lyrics || "").trim();
});
if (invalid) {
alertMessage(
"Champs incomplets",
@@ -141,7 +168,9 @@ const Lyrics = ({ navigation }) => {
}
const normalizedNewLyrics = (sections || []).map((s) => ({
type: normalizeStructureType(s?.type),
lyrics: (s?.lyrics || "").trim(),
lyrics: segmentRequiresLyrics(normalizeStructureType(s?.type))
? (s?.lyrics || "").trim()
: "",
}));
const normalizedOldLyrics = Array.isArray(projectLyrics)
? projectLyrics.map((s) => ({
@@ -349,6 +378,18 @@ const Lyrics = ({ navigation }) => {
? 170
: 225;
const placeholder = meta?.label || label;
const requiresLyrics = segmentRequiresLyrics(key);
if (!requiresLyrics) {
return (
<View key={idx} style={styles.instrumentalBlock}>
<Text style={styles.instrumentalTitle}>{label}</Text>
<Text style={styles.instrumentalText}>
{getPromptLabelForStructure(key)} section instrumentale
sans paroles.
</Text>
</View>
);
}
return (
<CustomInput
key={idx}
@@ -417,4 +458,21 @@ const styles = StyleSheet.create({
instructionsHighlight: {
fontFamily: FONT_FAMILY.InterSemiBold,
},
instrumentalBlock: {
padding: 16,
borderRadius: 12,
backgroundColor: Palette.ultraLightWhite,
gap: 6,
},
instrumentalTitle: {
fontFamily: FONT_FAMILY.InterSemiBold,
fontSize: 16,
color: Palette.white,
},
instrumentalText: {
fontFamily: FONT_FAMILY.InterRegular,
fontSize: 14,
color: Palette.white,
opacity: 0.8,
},
});