diff --git a/functions/src/lyrics.js b/functions/src/lyrics.js
index 9001001..a268958 100644
--- a/functions/src/lyrics.js
+++ b/functions/src/lyrics.js
@@ -24,40 +24,59 @@ exports.generateLyrics = onCall({}, async ({ auth = {}, data = {} }) => {
console.log("Function generate lyrics start with data", data);
- const system =
- `
+ const system = `
Tu es un parolier expert en chanson française moderne et populaire.
-Tu écris des chansons marquantes, accessibles, sur des thématiques ` +
- `d'innovation, d'esprit d'équipe et de créativité digitale.
-Ton ` +
- `écriture doit toucher à la fois l'humain, le collectif et la ` +
- `passion d'entreprendre.
-Tu dois générer un titre accrocheur et ` +
- `mémorable pour la chanson en plus des paroles.
-Respecte ` +
- `précisément la structure demandée et fournis le résultat dans un ` +
- `format JSON clair, respectant strictement le schéma demandé.
+Tu écris des chansons marquantes, accessibles, sur des thématiques d'innovation, d'esprit d'équipe et de créativité digitale.
+Ton écriture doit toucher à la fois l'humain, le collectif et la passion d'entreprendre.
+Analyse attentivement les informations placées entre balises XML-like.
+Génère un titre accrocheur et mémorable en plus des paroles, tout en respectant strictement la structure demandée.
+Retourne uniquement un JSON conforme au schéma fourni, sans ajouter d'autres textes.
`.trim();
- // Construction du prompt utilisateur
- const prompt =
- `
-Objectif : ${objective}
-Contexte : ${context}
-Émotion : ${emotion}
-Style musical : ${style}
-Audience cible : ${audience}
-Structure de la chanson : ${structure.join(" => ")}
-Schéma de rimes : ${rhymes}
+ const structureTags = (Array.isArray(structure) ? structure : [])
+ .map((part, index) => {
+ const content = part || "";
+ return ` `;
+ })
+ .join("\n");
-Génère un titre accrocheur et les paroles de la chanson en suivant ` +
- `strictement cette structure.
-Le titre doit être court, ` +
- `mémorable et refléter l'esprit de la musique.
-Pour chaque ` +
- `partie ("couplet" ou "refrain"), écris 4 à 16 lignes adaptées, ` +
- `expressives et cohérentes avec le style et l'émotion souhaitée.
-`.trim();
+ const fallbackStructureTags = [
+ ' ',
+ ' ',
+ ].join("\n");
+
+ // Construction du prompt utilisateur avec des balises explicites
+ const prompt = `
+
+ ${objective || ""}
+ ${context || ""}
+ ${emotion || ""}
+ ${style || ""}
+ ${audience || ""}
+ ${rhymes || ""}
+
+
+
+${structureTags || fallbackStructureTags}
+
+
+
+
+ Génère un titre court, mémorable et aligné avec l'esprit de la musique.
+
+
+ Pour chaque section demandée, rédige entre 4 et 16 lignes expressives.
+ Respecte strictement l'ordre et le type de chaque section (couplet, refrain, etc.).
+
+
+
+ Retourne uniquement un objet JSON valide selon le schéma.
+ Utilise les retours à la ligne (\n) pour séparer les phrases afin de conserver le découpage.
+
+
+ `.trim();
// Définition du schéma zod/genkit pour la validation du retour
const lyricsSchema = z.object({
diff --git a/functions/src/thumbnail.js b/functions/src/thumbnail.js
index f55d812..6aa6327 100644
--- a/functions/src/thumbnail.js
+++ b/functions/src/thumbnail.js
@@ -29,7 +29,9 @@ exports.generateVideoThumbnail = onObjectFinalized(
if (/_thumb9x16\.jpg$/i.test(objectName)) return;
const bucket = admin.storage().bucket(bucketName);
- const playbackMatch = objectName.match(/^musics\/([^/]+)\/playback\.mp4$/i);
+ const playbackMatch = objectName.match(
+ /^users\/[^/]+\/projects\/([^/]+)\/playback\.mp4$/i,
+ );
const projectId = playbackMatch ? playbackMatch[1] : null;
// Use unique folder under /tmp to avoid name collisions
diff --git a/src/screens/Production/DownloadSongs.js b/src/screens/Production/DownloadSongs.js
index adebc85..fcf103f 100644
--- a/src/screens/Production/DownloadSongs.js
+++ b/src/screens/Production/DownloadSongs.js
@@ -1,5 +1,5 @@
-import { BlurView } from 'expo-blur';
-import React from 'react';
+import { BlurView } from "expo-blur";
+import React from "react";
import {
Image,
Platform,
@@ -7,38 +7,39 @@ import {
StyleSheet,
Text,
View,
-} from 'react-native';
-import useMinuit from 'react-native-minuit/src/hooks/useMinuit.js';
-import { responsiveHeight } from 'react-native-responsive-dimensions';
-import { background, img } from '../../assets';
-import MusicLandHeader from '../../components/MusicLandHeader';
-import { projectsRef, serverTimestamp } from '../../config/firebase';
-import { uploadFileToFirebase } from '../../helpers/uploadToFirebase';
-import Page from '../../layouts/Page';
-import { Routes } from '../../navigation';
-import { goBack, navigate } from '../../navigation/NavigationService';
-import { Palette } from '../../styles';
-import { FONT_FAMILY } from '../../styles/Fonts';
+} from "react-native";
+import useMinuit from "react-native-minuit/src/hooks/useMinuit.js";
+import { responsiveHeight } from "react-native-responsive-dimensions";
+import { background, img } from "../../assets";
+import MusicLandHeader from "../../components/MusicLandHeader";
+import { projectsRef, serverTimestamp } from "../../config/firebase";
+import { uploadFileToFirebase } from "../../helpers/uploadToFirebase";
+import Page from "../../layouts/Page";
+import { Routes } from "../../navigation";
+import { goBack, navigate } from "../../navigation/NavigationService";
+import { Palette } from "../../styles";
+import { FONT_FAMILY } from "../../styles/Fonts";
+import { size } from "../../styles/Style";
+import CreateLyricsHeader from "../Writing/components/CreateLyricsHeader";
+import { useUserData } from "../../providers/UserDataProvider";
-import { size } from '../../styles/Style';
-import CreateLyricsHeader from '../Writing/components/CreateLyricsHeader';
const DownloadSongs = ({ route }) => {
- // const params = useRoute().params;
+ const { currentUID } = useUserData();
const { action, uri, project } = route.params || {};
- console.log('project id', project?.id);
+ console.log("project id", project?.id);
const { setIsLoading, setTooltip } = useMinuit();
const handleDownloadUri = async () => {
- if (action === 'playback' && project?.id) {
+ if (action === "playback" && project?.id) {
// Publication du playback
- console.log('project id : ', project.id);
+ console.log("project id : ", project.id);
try {
setIsLoading(true);
const { resultURI = null } = await uploadFileToFirebase({
uri: uri,
- path: `musics/${project.id}/source.mp4`,
+ path: `users/${currentUID}/projects/${project.id}/playback.mp4`,
shouldCompress: true,
- fileType: 'VIDEO',
+ fileType: "VIDEO",
});
if (!resultURI) throw new Error("Téléversement de l'image impossible");
@@ -49,23 +50,23 @@ const DownloadSongs = ({ route }) => {
playbackUrl: resultURI,
updatedAt: serverTimestamp(),
},
- { merge: true }
+ { merge: true },
);
setTooltip({
- type: 'success',
- text: 'Vidéo uploadée, conversion HLS en cours…',
+ type: "success",
+ text: "Vidéo uploadée, conversion HLS en cours…",
});
} else {
setTooltip({
- type: 'error',
- text: 'Erreur lors de la publication du playback',
+ type: "error",
+ text: "Erreur lors de la publication du playback",
});
}
} catch (error) {
- console.log('error upload playback', error);
+ console.log("error upload playback", error);
setTooltip({
- type: 'error',
- text: 'Erreur lors de la publication du playback',
+ type: "error",
+ text: "Erreur lors de la publication du playback",
});
} finally {
setIsLoading(false);
@@ -78,37 +79,39 @@ const DownloadSongs = ({ route }) => {
return (
+ headerType="NONE"
+ >
+ }}
+ >
- Prêt à télécharger{' '}
- {action === 'playback' ? 'ton Playback' : 'ta chanson'} ?
+ Prêt à télécharger{" "}
+ {action === "playback" ? "ton Playback" : "ta chanson"} ?
{
- console.log('test');
+ console.log("test");
handleDownloadUri();
}
@@ -116,18 +119,19 @@ const DownloadSongs = ({ route }) => {
// action,
// uri,
// })
- }>
+ }
+ >
- Télécharger{' '}
- {action === 'playback' ? 'mon Playback' : 'ma chanson'}
+ Télécharger{" "}
+ {action === "playback" ? "mon Playback" : "ma chanson"}
Pour moi uniquement
@@ -138,25 +142,26 @@ const DownloadSongs = ({ route }) => {
navigate(Routes.StreamSong, {
action,
})
- }>
+ }
+ >
- Diffuser{' '}
- {action === 'playback' ? 'mon Playback' : 'ma chanson'} sur
+ Diffuser{" "}
+ {action === "playback" ? "mon Playback" : "ma chanson"} sur
la plateforme de MusicLand (+ réseaux sociaux) et participer
au concours
Top 3: 1er 15% du CA ML - 2ème 10% du CA ML - 3ème 5% du CA
- ML (catégorie{' '}
- {action === 'playback' ? 'Playback' : 'chanson'})
+ ML (catégorie{" "}
+ {action === "playback" ? "Playback" : "chanson"})
@@ -193,9 +198,9 @@ const styles = StyleSheet.create({
},
itemContainer: {
borderRadius: 12,
- overflow: 'hidden',
- backgroundColor: '#FFFFFF03',
- shadowColor: '#0000001A',
+ overflow: "hidden",
+ backgroundColor: "#FFFFFF03",
+ shadowColor: "#0000001A",
shadowOffset: {
width: 0,
height: 2,