end of cover flow. Todo: fix combine pictures and save path in storage

This commit is contained in:
Thomas Demirdjian
2025-09-04 14:53:19 +02:00
parent c30b87b565
commit ce786d4750
17 changed files with 1104 additions and 850 deletions
+105 -82
View File
@@ -1,6 +1,14 @@
import { View, Text, Image, ActivityIndicator } from "react-native";
import {
View,
Text,
Image,
ActivityIndicator,
Alert,
setTimeout,
} from "react-native";
import { Image as ExpoImage } from "expo-image";
import React, { useEffect, useState } from "react";
import React, { useEffect } from "react";
import { useIsFocused } from "@react-navigation/native";
import Page from "../../layouts/Page";
import { background, icons, img } from "../../assets";
import MusicLandHeader from "../../components/MusicLandHeader";
@@ -10,35 +18,20 @@ import { gutters, Palette, Style } from "../../styles";
import BorderGradientButton from "../../components/BorderGradientButton";
import GradientButton from "../../components/GradientButton";
import { Routes } from "../../navigation";
import { FONT_FAMILY } from "../../styles/Fonts";
import firebase, { tasksRef } from "../../config/firebase";
import { useUser } from "../../providers/UserDataProvider";
import useMinuit from "react-native-minuit/src/hooks/useMinuit.js";
const PouchReady = () => {
const { selectedProjectId, selectedProject, updateProjectData } = useUser();
const [coverUrl, setCoverUrl] = useState(null);
const [loading, setLoading] = useState(false);
const [title, setTitle] = useState("");
const [coverStatus, setCoverStatus] = useState(null);
const isGenerating = coverStatus === "GENERATING";
useEffect(() => {
const d = selectedProject || {};
setTitle(d?.title || "");
setCoverUrl(d?.coverUrl || null);
setCoverStatus(d?.coverStatus || null);
}, [
selectedProject?.title,
selectedProject?.coverUrl,
selectedProject?.coverStatus,
]);
const { setIsLoading } = useMinuit();
const isGenerating = selectedProject?.coverStatus === "GENERATING";
const isFocused = useIsFocused();
const generateCover = async () => {
if (!selectedProjectId) return;
try {
setLoading(true);
await updateProjectData({ coverStatus: "GENERATING" });
await setIsLoading(true);
await tasksRef.add({
type: "cover",
projectId: selectedProjectId,
@@ -48,16 +41,44 @@ const PouchReady = () => {
} catch (e) {
console.log("Cover task error", e?.message);
} finally {
setLoading(false);
setIsLoading(false);
}
};
useEffect(() => {
if (!selectedProjectId) return;
if (!coverUrl && !isGenerating && !loading) {
generateCover();
async function validateCover() {
try {
await setIsLoading(true);
await updateProjectData({
cover: {
...selectedProject.cover,
result: selectedProject.cover.generatedBackground,
},
});
navigate(Routes.PhotoCover);
} catch (e) {
console.log(e);
} finally {
await setIsLoading(false);
}
}, [selectedProjectId, coverUrl, isGenerating]);
}
useEffect(() => {
if (
isFocused &&
!selectedProject?.cover?.generatedBackground &&
selectedProject?.coverStatus !== "GENERATING"
) {
Alert.alert("Attention", "Générer une pochette ?", [
{
text: "Oui",
onPress: generateCover,
},
{
text: "Non",
},
]);
}
}, [selectedProject, isFocused]);
return (
<Page backgroundImg={background.studioBG2} headerType="NONE">
@@ -65,15 +86,17 @@ const PouchReady = () => {
<View style={{ flex: 1, marginTop: 16 }}>
<CreateLyricsHeader
title={
coverUrl ? "Ta pochette est prête!" : "Génération de la pochette"
selectedProject?.cover?.backgroundGenerated
? "Ta pochette est prête!"
: "Génération de la pochette"
}
subTitle="Quen penses-tu ?"
// subTitle="Quen penses-tu ?"
/>
<View style={{ flex: 1, ...Style.containerCenter }}>
<View style={{ width: "80%", position: "relative" }}>
{coverUrl ? (
{selectedProject?.cover?.generatedBackground && !isGenerating ? (
<ExpoImage
source={{ uri: coverUrl }}
source={{ uri: selectedProject?.cover?.generatedBackground }}
cachePolicy="memory-disk"
priority="high"
contentFit="cover"
@@ -90,57 +113,57 @@ const PouchReady = () => {
...Style.containerCenter,
}}
>
{isGenerating || loading ? (
<ActivityIndicator color={Palette.white} />
) : (
<Image
source={img.placeholder}
style={{ width: 120, height: 120, opacity: 0.5 }}
/>
{isGenerating && (
<View style={{ alignItems: "center", gap: 8 }}>
<ActivityIndicator color={Palette.white} />
<Text style={{ color: Palette.white, marginTop: 6 }}>
Génération en cours.
</Text>
</View>
)}
</View>
)}
<View
style={{
position: "absolute",
alignSelf: "center",
alignItems: "center",
top: 10,
}}
>
<Text
style={{
fontSize: 22,
color: Palette.white,
fontFamily: FONT_FAMILY.InterSemiBold,
}}
>
{title || "Titre"}
</Text>
<Text
style={{
fontSize: 14,
color: Palette.gray,
fontFamily: FONT_FAMILY.InterRegular,
}}
>
MusicLand
</Text>
</View>
<View
style={{
position: "absolute",
alignItems: "center",
bottom: 10,
width: "100%",
}}
>
<Image
source={icons.musicLandLogo}
style={{ width: "100%", height: 30 }}
resizeMode="contain"
/>
</View>
{/*<View*/}
{/* style={{*/}
{/* position: "absolute",*/}
{/* alignSelf: "center",*/}
{/* alignItems: "center",*/}
{/* top: 10,*/}
{/* }}*/}
{/*>*/}
{/* <Text*/}
{/* style={{*/}
{/* fontSize: 22,*/}
{/* color: Palette.white,*/}
{/* fontFamily: FONT_FAMILY.InterSemiBold,*/}
{/* }}*/}
{/* >*/}
{/* {title || "Titre"}*/}
{/* </Text>*/}
{/* <Text*/}
{/* style={{*/}
{/* fontSize: 14,*/}
{/* color: Palette.gray,*/}
{/* fontFamily: FONT_FAMILY.InterRegular,*/}
{/* }}*/}
{/* >*/}
{/* MusicLand*/}
{/* </Text>*/}
{/*</View>*/}
{/*<View*/}
{/* style={{*/}
{/* position: "absolute",*/}
{/* alignItems: "center",*/}
{/* bottom: 10,*/}
{/* width: "100%",*/}
{/* }}*/}
{/*>*/}
{/* <Image*/}
{/* source={icons.musicLandLogo}*/}
{/* style={{ width: "100%", height: 30 }}*/}
{/* resizeMode="contain"*/}
{/* />*/}
{/*</View>*/}
</View>
</View>
</View>
@@ -160,8 +183,8 @@ const PouchReady = () => {
/>
<GradientButton
title={isGenerating ? "Veuillez patienter..." : "Valider"}
disabled={isGenerating || !coverUrl}
onPress={() => navigate(Routes.PhotoCover)}
disabled={isGenerating}
onPress={() => validateCover()}
/>
</View>
</Page>