big refacto change all flows
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import React, { useEffect, useRef, useState } from "react";
|
||||
import { Image, Platform, Text, View } from "react-native";
|
||||
import React, { useEffect, useMemo, useRef, useState } from "react";
|
||||
import { Alert, Image, Platform, Text, View } from "react-native";
|
||||
import Page from "../../layouts/Page";
|
||||
import { ai, background } from "../../assets";
|
||||
import MusicLandHeader from "../../components/MusicLandHeader";
|
||||
@@ -15,24 +15,22 @@ import useMinuit from "react-native-minuit/src/hooks/useMinuit.js";
|
||||
import moment from "moment";
|
||||
import { responsiveHeight } from "react-native-responsive-dimensions";
|
||||
import { FONT_FAMILY } from "../../styles/Fonts";
|
||||
import useDataFromRef from "../../hooks/useDataFromRef";
|
||||
import { useUser } from "../../providers/UserDataProvider";
|
||||
import { useIsFocused } from "@react-navigation/native";
|
||||
|
||||
const GeneratingSong = ({ route }) => {
|
||||
const { config, projectId } = route.params;
|
||||
const GeneratingSong = () => {
|
||||
const { selectedProjectId, selectedProject } = useUser();
|
||||
const [progress, setProgress] = useState(0);
|
||||
const { setIsLoading } = useMinuit();
|
||||
const progressTimerRef = useRef(null);
|
||||
const navigatedRef = useRef(false);
|
||||
const isFocused = useIsFocused();
|
||||
const lastConfigKeyRef = useRef(null);
|
||||
const askedRef = useRef(false);
|
||||
|
||||
const { data: project } = useDataFromRef({
|
||||
ref: projectId ? projectsRef.doc(projectId) : null,
|
||||
simpleRef: true,
|
||||
listener: true,
|
||||
condition: !!projectId,
|
||||
refreshArray: [projectId],
|
||||
});
|
||||
// project loaded from provider
|
||||
|
||||
// Progress based on 8 minutes cap or until status changes
|
||||
// Progress based on 8 minutes cap or until status becomes GENERATED
|
||||
useEffect(() => {
|
||||
const totalMs = 8 * 60 * 1000;
|
||||
const clearTimer = () => {
|
||||
@@ -41,15 +39,15 @@ const GeneratingSong = ({ route }) => {
|
||||
progressTimerRef.current = null;
|
||||
}
|
||||
};
|
||||
if (project?.musicStatus !== "GENERATING") {
|
||||
if (selectedProject?.musicStatus === "GENERATED") {
|
||||
setProgress(100);
|
||||
clearTimer();
|
||||
return () => clearTimer();
|
||||
}
|
||||
const update = () => {
|
||||
const startDate = project?.generationStartAt?.toDate
|
||||
? project.generationStartAt.toDate()
|
||||
: new Date(project?.generationStartAt || Date.now());
|
||||
const startDate = selectedProject?.generationStartAt?.toDate
|
||||
? selectedProject.generationStartAt.toDate()
|
||||
: new Date(selectedProject?.generationStartAt || Date.now());
|
||||
const elapsed = moment().diff(moment(startDate));
|
||||
const raw = Math.floor((elapsed / totalMs) * 100);
|
||||
// While status is GENERATING, block visual progress at 99%
|
||||
@@ -60,16 +58,29 @@ const GeneratingSong = ({ route }) => {
|
||||
clearTimer();
|
||||
progressTimerRef.current = setInterval(update, 1000);
|
||||
return () => clearTimer();
|
||||
}, [project?.musicStatus]);
|
||||
}, [selectedProject?.musicStatus]);
|
||||
|
||||
// Auto navigate to SongReady when generation completed
|
||||
useEffect(() => {
|
||||
if (!config?.projectId) return;
|
||||
if (project?.musicStatus !== "GENERATING" && !navigatedRef.current) {
|
||||
if (!selectedProjectId) return;
|
||||
if (selectedProject?.musicStatus === "GENERATED" && !navigatedRef.current) {
|
||||
navigatedRef.current = true;
|
||||
navigate(Routes.SongReady, { projectId: config.projectId });
|
||||
navigate(Routes.SongReady);
|
||||
}
|
||||
}, [project?.musicStatus, config?.projectId]);
|
||||
}, [selectedProject?.musicStatus, selectedProjectId]);
|
||||
|
||||
const effectiveConfig = useMemo(() => {
|
||||
// Use selectedProject.musicConfig only
|
||||
const cfg = selectedProject?.musicConfig || {};
|
||||
return {
|
||||
title: cfg?.title || "",
|
||||
lyrics: Array.isArray(cfg?.lyrics) ? cfg.lyrics : [],
|
||||
genres: Array.isArray(cfg?.genres) ? cfg.genres : [],
|
||||
voice: cfg?.voice || "",
|
||||
instruments: Array.isArray(cfg?.instruments) ? cfg.instruments : [],
|
||||
tempo: cfg?.tempo || "",
|
||||
};
|
||||
}, [selectedProject?.musicConfig]);
|
||||
|
||||
async function startMusicGeneration() {
|
||||
try {
|
||||
@@ -78,39 +89,39 @@ const GeneratingSong = ({ route }) => {
|
||||
const callable = firebase
|
||||
.functions()
|
||||
.httpsCallable("music-generateMusic");
|
||||
const cfg = effectiveConfig || {};
|
||||
const { data } = await callable({
|
||||
title: config?.title,
|
||||
lyrics: config?.lyrics,
|
||||
genres: config?.genres,
|
||||
voice: config?.voice,
|
||||
instruments: config?.instruments,
|
||||
tempo: config?.tempo,
|
||||
projectId: config?.projectId,
|
||||
title: cfg?.title,
|
||||
lyrics: cfg?.lyrics,
|
||||
genres: cfg?.genres,
|
||||
voice: cfg?.voice,
|
||||
instruments: cfg?.instruments,
|
||||
tempo: cfg?.tempo,
|
||||
});
|
||||
const taskId =
|
||||
data?.response?.data?.taskId || data?.response?.data?.task_id;
|
||||
if (config?.projectId && taskId) {
|
||||
if (selectedProjectId && taskId) {
|
||||
const baseUpdate = {
|
||||
sunoTaskId: taskId,
|
||||
musicStatus: "GENERATING",
|
||||
generationStartAt: firebase.firestore.FieldValue.serverTimestamp(),
|
||||
updatedAt: firebase.firestore.FieldValue.serverTimestamp(),
|
||||
};
|
||||
const updatePayload = project?.musicConfig
|
||||
const updatePayload = selectedProject?.musicConfig
|
||||
? baseUpdate
|
||||
: {
|
||||
...baseUpdate,
|
||||
musicConfig: {
|
||||
title: config?.title || "",
|
||||
lyrics: config?.lyrics || [],
|
||||
genres: config?.genres || [],
|
||||
voice: config?.voice || "",
|
||||
instruments: config?.instruments || [],
|
||||
tempo: config?.tempo || "",
|
||||
title: effectiveConfig?.title || "",
|
||||
lyrics: effectiveConfig?.lyrics || [],
|
||||
genres: effectiveConfig?.genres || [],
|
||||
voice: effectiveConfig?.voice || "",
|
||||
instruments: effectiveConfig?.instruments || [],
|
||||
tempo: effectiveConfig?.tempo || "",
|
||||
},
|
||||
};
|
||||
await projectsRef
|
||||
.doc(config.projectId)
|
||||
.doc(selectedProjectId)
|
||||
.set(updatePayload, { merge: true });
|
||||
}
|
||||
} catch (e) {
|
||||
@@ -120,16 +131,44 @@ const GeneratingSong = ({ route }) => {
|
||||
}
|
||||
}
|
||||
|
||||
// Trigger generation only if not already GENERATING
|
||||
// Trigger generation only when focused; ask once per config
|
||||
useEffect(() => {
|
||||
if (!!project?.title && project?.musicStatus !== "GENERATING") {
|
||||
startMusicGeneration();
|
||||
if (!isFocused) return;
|
||||
|
||||
const key = JSON.stringify(effectiveConfig || {});
|
||||
if (lastConfigKeyRef.current !== key) {
|
||||
lastConfigKeyRef.current = key;
|
||||
askedRef.current = false;
|
||||
}
|
||||
}, [project]);
|
||||
|
||||
const canAsk =
|
||||
!!selectedProject?.title && selectedProject?.musicStatus !== "GENERATING";
|
||||
|
||||
if (canAsk && !askedRef.current) {
|
||||
askedRef.current = true;
|
||||
Alert.alert(
|
||||
"Attention",
|
||||
"Une génération va être lancée. Continuer ?",
|
||||
[
|
||||
{
|
||||
text: "Non",
|
||||
style: "cancel",
|
||||
},
|
||||
{
|
||||
text: "Oui",
|
||||
onPress: () => startMusicGeneration(),
|
||||
},
|
||||
],
|
||||
);
|
||||
}
|
||||
}, [isFocused, selectedProject?.title, selectedProject?.musicStatus, effectiveConfig]);
|
||||
|
||||
return (
|
||||
<Page headerType="NONE" backgroundImg={background.studioBG2}>
|
||||
<MusicLandHeader onPressBack={goBack} progress={63} />
|
||||
<MusicLandHeader
|
||||
onPressBack={() => navigate(Routes.FlowSelection)}
|
||||
progress={63}
|
||||
/>
|
||||
<View style={{ flex: 1, marginTop: 16 }}>
|
||||
<CreateLyricsHeader
|
||||
title="Ta musique est en cours de création !"
|
||||
@@ -206,14 +245,14 @@ const GeneratingSong = ({ route }) => {
|
||||
</Text>
|
||||
</View>
|
||||
<GradientButton
|
||||
title={"Création en cours..."}
|
||||
disabled={project?.musicStatus === "GENERATING"}
|
||||
containerStyle={{ width: "80%", alignSelf: "center" }}
|
||||
onPress={() =>
|
||||
navigate(Routes.SongReady, {
|
||||
projectId: config?.projectId,
|
||||
})
|
||||
title={
|
||||
selectedProject?.musicStatus === "GENERATED"
|
||||
? "Découvrir ma musique"
|
||||
: "Création en cours..."
|
||||
}
|
||||
disabled={selectedProject?.musicStatus !== "GENERATED"}
|
||||
containerStyle={{ width: "80%", alignSelf: "center" }}
|
||||
onPress={() => navigate(Routes.SongReady)}
|
||||
/>
|
||||
</View>
|
||||
</BlurView>
|
||||
|
||||
Reference in New Issue
Block a user