163 lines
5.8 KiB
JavaScript
163 lines
5.8 KiB
JavaScript
import React, { useMemo, useState } from "react";
|
|
import { Pressable, ScrollView, Text, View } from "react-native";
|
|
import { responsiveHeight } from "react-native-responsive-dimensions";
|
|
import { background } from "../../assets";
|
|
import alert from "../../components/Alert";
|
|
import GradientButton from "../../components/GradientButton";
|
|
import Page from "../../layouts/Page";
|
|
import { Routes } from "../../navigation";
|
|
import { navigate } from "../../navigation/NavigationService";
|
|
import { useUser } from "../../providers/UserDataProvider";
|
|
import { gutters } from "../../styles";
|
|
|
|
const Studio = () => {
|
|
const [selectedProjectId, setSelectedProjectId] = useState(null);
|
|
|
|
const { userProjects: projects, selectProject } = useUser();
|
|
|
|
const selectedProject = useMemo(() => {
|
|
if (!Array.isArray(projects) || !projects.length) return null;
|
|
return projects.find((p) => p?.id === selectedProjectId) ?? null;
|
|
}, [projects, selectedProjectId]);
|
|
|
|
return (
|
|
<Page
|
|
headerType="NONE"
|
|
backgroundImg={background.studioBG}
|
|
containerStyle={{ paddingHorizontal: 0 }}
|
|
contentContainerStyle={{
|
|
padding: gutters * 2,
|
|
}}
|
|
>
|
|
<View style={{ flex: 1 }}>
|
|
{projects?.length > 0 && (
|
|
<View style={{ marginBottom: gutters * 2 }}>
|
|
<Text
|
|
style={{
|
|
color: "#fff",
|
|
fontSize: 18,
|
|
marginBottom: 12,
|
|
fontWeight: "600",
|
|
}}
|
|
>
|
|
Derniers projets générés
|
|
</Text>
|
|
<ScrollView contentContainerStyle={{ gap: 10, paddingRight: 6 }}>
|
|
{projects.map((p) => {
|
|
const couplet = p?.lyrics?.couplet || "";
|
|
const preview = couplet.split("\n").slice(0, 2).join(" ");
|
|
const isSelected = selectedProjectId === p?.id;
|
|
const createdAt = p?.createdAt?.toDate
|
|
? p.createdAt.toDate()
|
|
: p?.createdAt
|
|
? new Date(p.createdAt)
|
|
: null;
|
|
const createdLabel =
|
|
createdAt && !Number.isNaN(createdAt.getTime())
|
|
? `${createdAt.toLocaleDateString("fr-FR")} • ${createdAt.toLocaleTimeString("fr-FR", { hour: "2-digit", minute: "2-digit" })}`
|
|
: "";
|
|
return (
|
|
<Pressable
|
|
key={p.id}
|
|
onPress={() => setSelectedProjectId(p?.id ?? null)}
|
|
style={{
|
|
backgroundColor: isSelected
|
|
? "rgba(15, 12, 25, 0.75)"
|
|
: "rgba(15, 12, 25, 0.2)",
|
|
borderRadius: 12,
|
|
padding: 12,
|
|
borderWidth: isSelected ? 2 : 0,
|
|
borderColor: isSelected ? "#F94697" : "transparent",
|
|
shadowColor: "rgba(0, 0, 0, 0.55)",
|
|
shadowOpacity: isSelected ? 0.6 : 0.35,
|
|
shadowRadius: isSelected ? 8 : 4,
|
|
shadowOffset: { width: 0, height: 4 },
|
|
elevation: isSelected ? 6 : 1,
|
|
}}
|
|
>
|
|
<Text
|
|
style={{ color: "#fff", fontSize: 16, fontWeight: "600" }}
|
|
>
|
|
{p?.title || "Sans titre"}
|
|
</Text>
|
|
{!!createdLabel && (
|
|
<Text
|
|
style={{ color: "#bbb", marginTop: 4, fontSize: 12 }}
|
|
>
|
|
{createdLabel}
|
|
</Text>
|
|
)}
|
|
{!!preview && (
|
|
<Text
|
|
style={{ color: "#ddd", marginTop: 6 }}
|
|
numberOfLines={2}
|
|
>
|
|
{preview}
|
|
</Text>
|
|
)}
|
|
{p?.config?.style && (
|
|
<Text
|
|
style={{ color: "#aaa", marginTop: 6, fontSize: 12 }}
|
|
>
|
|
Style: {String(p.config.style)}
|
|
</Text>
|
|
)}
|
|
</Pressable>
|
|
);
|
|
})}
|
|
</ScrollView>
|
|
</View>
|
|
)}
|
|
</View>
|
|
<View style={{ justifyContent: "flex-end" }}>
|
|
<GradientButton
|
|
title="Commencer"
|
|
disabled={!selectedProject}
|
|
onPress={() => {
|
|
if (selectedProject?.musicStatus === "GENERATING") {
|
|
alert(
|
|
"Attention",
|
|
"La chanson est en cours de génération. Veuillez patienter."
|
|
);
|
|
} else {
|
|
if (!selectedProject?.id) return;
|
|
selectProject(selectedProject.id);
|
|
navigate(Routes.Compose);
|
|
}
|
|
}}
|
|
/>
|
|
{selectedProject?.musicUrls?.length > 0 && (
|
|
<>
|
|
<GradientButton
|
|
title="Ecouter les audios"
|
|
containerStyle={{
|
|
marginTop: responsiveHeight(2),
|
|
}}
|
|
onPress={() => {
|
|
if (!selectedProject?.id) return;
|
|
selectProject(selectedProject.id);
|
|
navigate(Routes.SongReady);
|
|
}}
|
|
/>
|
|
{!selectedProject?.coverUrl && (
|
|
<GradientButton
|
|
title="Générer une pochette"
|
|
containerStyle={{
|
|
marginTop: responsiveHeight(2),
|
|
}}
|
|
onPress={() => {
|
|
if (!selectedProject?.id) return;
|
|
selectProject(selectedProject.id);
|
|
navigate(Routes.PouchReady);
|
|
}}
|
|
/>
|
|
)}
|
|
</>
|
|
)}
|
|
</View>
|
|
</Page>
|
|
);
|
|
};
|
|
|
|
export default Studio;
|