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
+4 -14
View File
@@ -1,18 +1,13 @@
import React from "react";
import { createStackNavigator } from "@react-navigation/stack";
import { Palette } from "../styles";
import { Routes } from "./Routes";
import { BottomTabScreen } from "./BottomTab";
import Splash from "../screens/Splash";
import Onboarding from "../screens/Onboarding";
import Login from "../screens/Login";
import ForgotPassword from "../screens/ForgotPassword";
import Notifications from "../screens/Profile/Notifications";
import TermsOfUse from "../screens/TermsOfUse";
import PrivacyPolicy from "../screens/PrivacyPolicy";
import Writing from "../screens/Writing/Writing";
@@ -28,8 +23,6 @@ import SongReady from "../screens/Studio/SongReady";
import Regenerate from "../screens/Studio/Regenerate";
import PouchReady from "../screens/cover/PouchReady";
import PhotoCover from "../screens/cover/PhotoCover";
import AddPhotoCover from "../screens/cover/AddPhotoCover";
import FinishCompose from "../screens/cover/FinishCompose";
import Production from "../screens/Production/Production";
import ProductionOnboarding from "../screens/Production/ProductionOnboarding";
import DownloadSongs from "../screens/Production/DownloadSongs";
@@ -63,7 +56,8 @@ import NewMusicOptions from "../screens/NewMusicOptions";
import Register from "../screens/Register";
import CreatePassword from "../screens/CreatePassword";
import CreatePseudo from "../screens/CreatePseudo";
import ChooseCoverType from "../screens/cover/ChooseCoverType";
import { ChooseCoverType } from "../screens/cover/ChooseCoverType";
import ValidateCover from "../screens/cover/ValidateCover";
const screenOptions = {
headerShown: false,
@@ -155,12 +149,8 @@ const screens = [
component: PhotoCover,
},
{
name: Routes.AddPhotoCover,
component: AddPhotoCover,
},
{
name: Routes.FinishCompose,
component: FinishCompose,
name: Routes.ValidateCover,
component: ValidateCover,
},
{
name: Routes.ProductionOnboarding,
+1 -1
View File
@@ -38,7 +38,7 @@ export const Routes = {
Regenerate: "Regenerate",
PouchReady: "PouchReady",
PhotoCover: "PhotoCover",
AddPhotoCover: "AddPhotoCover",
ValidateCover: "ValidateCover",
FinishCompose: "FinishCompose",
ProductionOnboarding: "ProductionOnboarding",
+5 -1
View File
@@ -92,7 +92,11 @@ const NewMusicOptions = () => {
}
break;
case 2:
navigate(Routes.ChooseCoverType);
if (selectedProject?.coverUrl) {
navigate(Routes.ValidateCover);
} else {
navigate(Routes.ChooseCoverType);
}
break;
case 3:
console.log("test");
-123
View File
@@ -1,123 +0,0 @@
import { View, Text, Image } from "react-native";
import React, { useState } from "react";
import MusicLandHeader from "../../components/MusicLandHeader";
import { background, icons, img } from "../../assets";
import Page from "../../layouts/Page";
import { goBack, navigate } from "../../navigation/NavigationService";
import CreateLyricsHeader from "../Writing/components/CreateLyricsHeader";
import { gutters, Palette, Style } from "../../styles";
import { FONT_FAMILY } from "../../styles/Fonts";
import BorderGradientButton from "../../components/BorderGradientButton";
import GradientButton from "../../components/GradientButton";
import { launchImageLibraryAsync } from "expo-image-picker";
import { Routes } from "../../navigation";
const AddPhotoCover = () => {
const [image, setImage] = useState(null);
const onPressAddImage = async () => {
const result = await launchImageLibraryAsync({
mediaTypes: ["images"],
allowsEditing: true,
aspect: [4, 3],
quality: 1,
});
if (!result.canceled) {
setImage(result.assets[0]?.uri);
}
};
return (
<Page backgroundImg={background.studioBG2} headerType="NONE">
<MusicLandHeader onPressBack={goBack} progress={90} />
<View style={{ flex: 1, marginTop: 16 }}>
<CreateLyricsHeader
title="Ta pochette est prête!"
subTitle="Quen penses-tu ?"
/>
<View style={{ flex: 1, ...Style.containerCenter }}>
<View style={{ width: "80%", position: "relative" }}>
<Image
source={img.placeholder}
style={{
width: "100%",
height: 300,
borderRadius: 20,
transform: [{ rotateY: "180deg" }],
}}
/>
<View
style={{ position: "absolute", width: "100%", height: "100%" }}
>
<Image
source={{ uri: image }}
style={{ width: "100%", height: "100%", borderRadius: 20 }}
/>
</View>
<View
style={{
position: "absolute",
alignSelf: "center",
alignItems: "center",
top: 10,
}}
>
<Text
style={{
fontSize: 22,
color: Palette.white,
fontFamily: FONT_FAMILY.InterSemiBold,
}}
>
Lust for Life
</Text>
<Text
style={{
fontSize: 14,
color: Palette.gray,
fontFamily: FONT_FAMILY.InterRegular,
}}
>
Lana del Rey
</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>
<View
style={{
paddingBottom: gutters * 2,
width: "80%",
alignSelf: "center",
gap: 12,
}}
>
<BorderGradientButton
title="Ajouter une autre photo"
onPress={onPressAddImage}
/>
<GradientButton
title="Valider"
onPress={() => navigate(Routes.FlowSelection)}
/>
</View>
</Page>
);
};
export default AddPhotoCover;
+64 -16
View File
@@ -1,5 +1,6 @@
import { View, StyleSheet, Image } from "react-native";
import { View, Image } from "react-native";
import React, { useState } from "react";
import * as ImagePicker from "expo-image-picker";
import { ai, background } from "../../assets";
import Page from "../../layouts/Page";
import { goBack, navigate } from "../../navigation/NavigationService";
@@ -9,12 +10,68 @@ import GradientButton from "../../components/GradientButton";
import { gutters } from "../../styles";
import FullscreenIntroVideo from "../../components/FullscreenIntroVideo";
import BorderGradientButton from "../../components/BorderGradientButton";
import { useUserData } from "../../providers/UserDataProvider";
import { uploadFileToFirebase } from "../../helpers/uploadToFirebase";
import useMinuit from "react-native-minuit/src/hooks/useMinuit";
const ChooseCoverType = () => {
export const ChooseCoverType = () => {
const [showIntro, setShowIntro] = useState(true);
const { selectedProject, selectedProjectId, updateProjectData } =
useUserData();
const { setIsLoading } = useMinuit();
const onPickUserImage = async () => {
try {
await setIsLoading(true);
const result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ["images"],
allowsEditing: true,
aspect: [1, 1],
quality: 1,
});
const uri = result?.assets?.[0]?.uri || null;
if (!uri) return;
const projectId = selectedProject?.id || selectedProjectId;
const path = `musics/${projectId}/userSelectedCover.png`;
const { resultURI } = await uploadFileToFirebase({
uri,
path,
shouldCompress: true,
fileType: "IMAGE",
});
if (!resultURI) {
throw new Error("Erreur lors de l'upload");
}
await updateProjectData({
cover: {
result: resultURI,
},
});
navigate(Routes.ValidateCover);
} catch (e) {
console.log("onPickUserImage error", e?.message);
} finally {
await setIsLoading(false);
}
};
return (
<Page backgroundImg={background.productionBG2} headerType="NONE">
<Image source={ai.bena} style={styles.img} resizeMode="contain" />
<Image
source={ai.bena}
style={{
width: "100%",
height: "70%",
position: "absolute",
bottom: -40,
right: -30,
}}
resizeMode="contain"
/>
<MusicLandHeader onPressBack={goBack} progress={9} />
<View
style={{ flex: 1, position: "relative", justifyContent: "flex-end" }}
@@ -26,7 +83,10 @@ const ChooseCoverType = () => {
gap: 12,
}}
>
<BorderGradientButton title="Choisir une image" />
<BorderGradientButton
title="Choisir une image"
onPress={onPickUserImage}
/>
<GradientButton
title="Générer une pochette"
onPress={() => navigate(Routes.PouchReady)}
@@ -40,15 +100,3 @@ const ChooseCoverType = () => {
</Page>
);
};
export default ChooseCoverType;
const styles = StyleSheet.create({
img: {
width: "100%",
height: "70%",
position: "absolute",
bottom: -40,
right: -30,
},
});
-53
View File
@@ -1,53 +0,0 @@
import { View, Image, StyleSheet } from "react-native";
import React from "react";
import { ai, background } from "../../assets";
import Page from "../../layouts/Page";
import { goBack, navigate } from "../../navigation/NavigationService";
import MusicLandHeader from "../../components/MusicLandHeader";
import { gutters } from "../../styles";
import { Routes } from "../../navigation";
import GradientButton from "../../components/GradientButton";
import BorderGradientButton from "../../components/BorderGradientButton";
const FinishCompose = () => {
return (
<Page backgroundImg={background.studioBG2} headerType="NONE">
<Image source={ai.theo} style={styles.img} resizeMode="contain" />
<MusicLandHeader onPressBack={goBack} progress={100} />
<View
style={{ flex: 1, position: "relative", justifyContent: "flex-end" }}
>
<View
style={{
paddingBottom: gutters * 2,
width: "70%",
alignSelf: "center",
gap: 12,
}}
>
<BorderGradientButton
title="Continuer plus tard"
onPress={() => navigate(Routes.Home)}
/>
<GradientButton
title="Continuer la création"
onPress={() => navigate(Routes.Home)}
/>
</View>
</View>
</Page>
);
};
export default FinishCompose;
const styles = StyleSheet.create({
img: {
width: "100%",
height: "70%",
position: "absolute",
bottom: -40,
right: -30,
},
});
+92 -55
View File
@@ -1,17 +1,72 @@
import { View, Text, Image } from "react-native";
import { ActivityIndicator, Text, View } from "react-native";
import React from "react";
import MusicLandHeader from "../../components/MusicLandHeader";
import { background, icons, img } from "../../assets";
import { background } from "../../assets";
import Page from "../../layouts/Page";
import { goBack, navigate } from "../../navigation/NavigationService";
import CreateLyricsHeader from "../Writing/components/CreateLyricsHeader";
import { gutters, Palette, Style } from "../../styles";
import { FONT_FAMILY } from "../../styles/Fonts";
import BorderGradientButton from "../../components/BorderGradientButton";
import { Routes } from "../../navigation";
import GradientButton from "../../components/GradientButton";
import * as ImagePicker from "expo-image-picker";
import { uploadFileToFirebase } from "../../helpers/uploadToFirebase";
import { useUserData } from "../../providers/UserDataProvider";
import useMinuit from "react-native-minuit/src/hooks/useMinuit";
import firebase, { tasksRef } from "../../config/firebase";
import { Image as ExpoImage } from "expo-image";
const PhotoCover = () => {
const { selectedProject, selectedProjectId, updateProjectData } =
useUserData();
const { setIsLoading } = useMinuit();
const isGenerating = selectedProject?.coverStatus === "GENERATING";
const onChooseForegroundImage = async () => {
try {
await setIsLoading(true);
const result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ["images"],
allowsEditing: true,
aspect: [1, 1],
quality: 1,
});
const uri = result?.assets?.[0]?.uri || null;
if (!uri) return;
const projectId = selectedProject?.id || selectedProjectId;
const path = `musics/${projectId}/userForeground.png`;
const { resultURI } = await uploadFileToFirebase({
uri,
path,
shouldCompress: true,
fileType: "IMAGE",
});
if (!resultURI) {
throw new Error("Erreur lors de l'upload");
}
await updateProjectData({
cover: {
...selectedProject.cover,
userForeground: resultURI,
},
});
await tasksRef.add({
type: "combine",
projectId: selectedProjectId,
status: "PENDING",
createdAt: firebase.firestore.FieldValue.serverTimestamp(),
});
} catch (e) {
console.log("onPickUserImage error", e?.message);
} finally {
await setIsLoading(false);
}
};
return (
<Page backgroundImg={background.studioBG2} headerType="NONE">
<MusicLandHeader onPressBack={goBack} progress={81} />
@@ -19,56 +74,35 @@ const PhotoCover = () => {
<CreateLyricsHeader title="Souhaites-tu rajouter une photo de toi sur la pochette?" />
<View style={{ flex: 1, ...Style.containerCenter }}>
<View style={{ width: "80%", position: "relative" }}>
<Image
source={img.placeholder}
style={{
width: "100%",
height: 300,
borderRadius: 20,
transform: [{ rotateY: "180deg" }],
}}
/>
<View
style={{
position: "absolute",
alignSelf: "center",
alignItems: "center",
top: 10,
}}
>
<Text
style={{
fontSize: 22,
color: Palette.white,
fontFamily: FONT_FAMILY.InterSemiBold,
}}
>
Lust for Life
</Text>
<Text
style={{
fontSize: 14,
color: Palette.gray,
fontFamily: FONT_FAMILY.InterRegular,
}}
>
Lana del Rey
</Text>
</View>
<View
style={{
position: "absolute",
alignItems: "center",
bottom: 10,
width: "100%",
}}
>
<Image
source={icons.musicLandLogo}
style={{ width: "100%", height: 30 }}
resizeMode="contain"
{selectedProject?.cover?.result && !isGenerating ? (
<ExpoImage
source={{ uri: selectedProject?.cover?.result }}
cachePolicy="memory-disk"
priority="high"
contentFit="cover"
transition={120}
style={{ width: "100%", height: 300, borderRadius: 20 }}
/>
</View>
) : (
<View
style={{
width: "100%",
height: 300,
borderRadius: 20,
backgroundColor: "#00000040",
...Style.containerCenter,
}}
>
{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>
</View>
</View>
@@ -80,10 +114,13 @@ const PhotoCover = () => {
gap: 12,
}}
>
<BorderGradientButton title="Non, laisser la pochette telle quelle" />
<BorderGradientButton
onPress={() => navigate(Routes.ValidateCover)}
title="Non, valider la pochette"
/>
<GradientButton
title="Oui"
onPress={() => navigate(Routes.AddPhotoCover)}
title="Oui choisir une image"
onPress={() => onChooseForegroundImage()}
/>
</View>
</Page>
+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>
+139
View File
@@ -0,0 +1,139 @@
import { View, Image } from "react-native";
import React from "react";
import MusicLandHeader from "../../components/MusicLandHeader";
import { background, img } from "../../assets";
import Page from "../../layouts/Page";
import { goBack, navigate } from "../../navigation/NavigationService";
import CreateLyricsHeader from "../Writing/components/CreateLyricsHeader";
import { gutters, Style } from "../../styles";
import BorderGradientButton from "../../components/BorderGradientButton";
import GradientButton from "../../components/GradientButton";
import { Routes } from "../../navigation";
import { useUserData } from "../../providers/UserDataProvider";
import useMinuit from "react-native-minuit/src/hooks/useMinuit.js";
const ValidateCover = () => {
const { selectedProject, updateProjectData } = useUserData();
const { setIsLoading } = useMinuit();
async function onStartAgain() {
try {
await setIsLoading(true);
await updateProjectData({
cover: null,
coverUrl: null,
});
navigate(Routes.ChooseCoverType);
} catch (e) {
console.log(e);
} finally {
await setIsLoading(false);
}
}
async function onValidatePicture() {
try {
await setIsLoading(true);
await updateProjectData({
coverUrl: selectedProject?.cover?.result,
});
navigate(Routes.FlowSelection);
} catch (e) {
console.log(e);
} finally {
await setIsLoading(false);
}
}
return (
<Page backgroundImg={background.studioBG2} headerType="NONE">
<MusicLandHeader onPressBack={goBack} progress={90} />
<View style={{ flex: 1, marginTop: 16 }}>
<CreateLyricsHeader
title="Ta pochette est prête!"
subTitle="Quen penses-tu ?"
/>
<View style={{ flex: 1, ...Style.containerCenter }}>
<View style={{ width: "80%", position: "relative" }}>
<Image
source={img.placeholder}
style={{
width: "100%",
height: 300,
borderRadius: 20,
transform: [{ rotateY: "180deg" }],
}}
/>
<View
style={{ position: "absolute", width: "100%", height: "100%" }}
>
<Image
source={{ uri: selectedProject?.cover?.result }}
style={{ width: "100%", height: "100%", borderRadius: 20 }}
/>
</View>
{/*<View*/}
{/* style={{*/}
{/* position: "absolute",*/}
{/* alignSelf: "center",*/}
{/* alignItems: "center",*/}
{/* top: 10,*/}
{/* }}*/}
{/*>*/}
{/* <Text*/}
{/* style={{*/}
{/* fontSize: 22,*/}
{/* color: Palette.white,*/}
{/* fontFamily: FONT_FAMILY.InterSemiBold,*/}
{/* }}*/}
{/* >*/}
{/* Lust for Life*/}
{/* </Text>*/}
{/* <Text*/}
{/* style={{*/}
{/* fontSize: 14,*/}
{/* color: Palette.gray,*/}
{/* fontFamily: FONT_FAMILY.InterRegular,*/}
{/* }}*/}
{/* >*/}
{/* Lana del Rey*/}
{/* </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>
<View
style={{
paddingBottom: gutters * 2,
width: "80%",
alignSelf: "center",
gap: 12,
}}
>
<BorderGradientButton
title="Recommencer la création"
onPress={onStartAgain}
/>
<GradientButton
title="Valider la pochette"
onPress={onValidatePicture}
/>
</View>
</Page>
);
};
export default ValidateCover;