This commit is contained in:
Philip Cesar Garay
2025-08-07 21:02:22 +08:00
parent 40e877774b
commit 5a4d36e1bc
34 changed files with 902 additions and 137 deletions
+10 -2
View File
@@ -1,11 +1,16 @@
import { View, Text, Pressable } from "react-native"; import { View, Text, Pressable, Image } from "react-native";
import React from "react"; import React from "react";
import BorderGradient from "./BorderGradient/BorderGradient"; import BorderGradient from "./BorderGradient/BorderGradient";
import { Palette, Style } from "../styles"; import { Palette, Style } from "../styles";
import { BlurView } from "expo-blur"; import { BlurView } from "expo-blur";
import { FONT_FAMILY } from "../styles/Fonts"; import { FONT_FAMILY } from "../styles/Fonts";
import { size } from "../styles/Style";
const BorderGradientButton = ({ title = "Jai déjà mes paroles", onPress }) => { const BorderGradientButton = ({
title = "Jai déjà mes paroles",
onPress,
icon,
}) => {
return ( return (
<Pressable onPress={onPress}> <Pressable onPress={onPress}>
<BorderGradient <BorderGradient
@@ -38,9 +43,12 @@ const BorderGradientButton = ({ title = "Jai déjà mes paroles", onPress })
width: "100%", width: "100%",
height: "100%", height: "100%",
...Style.containerCenter, ...Style.containerCenter,
...Style.containerRow,
borderRadius: 14, borderRadius: 14,
gap: 11,
}} }}
> >
{icon && <Image source={icon} style={size({ size: 16 })} />}
<Text <Text
style={{ style={{
fontSize: 15, fontSize: 15,
+6 -1
View File
@@ -1,8 +1,9 @@
import { View, Text, Pressable } from "react-native"; import { View, Text, Pressable, Image } from "react-native";
import React from "react"; import React from "react";
import { LinearGradient } from "./LinearGradient/LinearGradient"; import { LinearGradient } from "./LinearGradient/LinearGradient";
import { Palette, Style } from "../styles"; import { Palette, Style } from "../styles";
import { FONT_FAMILY } from "../styles/Fonts"; import { FONT_FAMILY } from "../styles/Fonts";
import { size } from "../styles/Style";
const GradientButton = ({ const GradientButton = ({
title = "", title = "",
@@ -10,6 +11,7 @@ const GradientButton = ({
onPress, onPress,
props, props,
containerStyle = {}, containerStyle = {},
icon,
}) => { }) => {
return ( return (
<Pressable onPress={onPress} style={{ ...containerStyle }}> <Pressable onPress={onPress} style={{ ...containerStyle }}>
@@ -17,13 +19,16 @@ const GradientButton = ({
colors={colors} colors={colors}
style={{ style={{
...Style.containerCenter, ...Style.containerCenter,
...Style.containerRow,
height: 50, height: 50,
borderRadius: 14, borderRadius: 14,
gap: 10,
}} }}
start={{ x: 0, y: 0 }} start={{ x: 0, y: 0 }}
end={{ x: 1, y: 0 }} end={{ x: 1, y: 0 }}
{...props} {...props}
> >
{icon && <Image source={icon} style={size({ size: 16 })} />}
<Text <Text
style={{ style={{
fontSize: 15, fontSize: 15,
@@ -18,7 +18,7 @@ const ItemContainer = ({ height = responsiveHeight(40), children }) => {
}} }}
> >
<View style={styles.blurContainer}> <View style={styles.blurContainer}>
<BlurView intensity={40} style={{ flex: 1, padding: 6 }}> <BlurView intensity={40} tint="dark" style={{ flex: 1, padding: 6 }}>
{children} {children}
</BlurView> </BlurView>
</View> </View>
@@ -40,6 +40,7 @@ const ItemContainer = ({ height = responsiveHeight(40), children }) => {
> >
<BlurView <BlurView
intensity={40} intensity={40}
tint="dark"
style={{ style={{
padding: 6, padding: 6,
zIndex: 2, zIndex: 2,
+102 -11
View File
@@ -1,16 +1,107 @@
import Slider from "@react-native-community/slider"; import { useState } from "react";
import { StyleSheet, Text, View } from "react-native";
import { Gesture, GestureDetector } from "react-native-gesture-handler";
import Animated, {
useAnimatedStyle,
useSharedValue,
} from "react-native-reanimated";
import { LinearGradient } from "./LinearGradient/LinearGradient";
import { Palette, Style } from "../styles";
import { FONT_FAMILY } from "../styles/Fonts";
import { Palette } from "../styles"; const INITIAL_BOX_SIZE = 6;
export default ({ value, maxValue }) => {
const offset = useSharedValue(0);
const boxWidth = useSharedValue(INITIAL_BOX_SIZE);
const [layout, setLayout] = useState(null);
const SLIDER_WIDTH = layout?.width;
const MAX_VALUE = SLIDER_WIDTH - INITIAL_BOX_SIZE;
const pan = Gesture.Pan().onChange((event) => {
offset.value =
Math.abs(offset.value) <= MAX_VALUE
? offset.value + event.changeX <= 0
? 0
: offset.value + event.changeX >= MAX_VALUE
? MAX_VALUE
: offset.value + event.changeX
: offset.value;
const newWidth = INITIAL_BOX_SIZE + offset.value;
boxWidth.value = newWidth;
});
const boxStyle = useAnimatedStyle(() => {
return {
width: INITIAL_BOX_SIZE + offset.value,
};
});
const sliderStyle = useAnimatedStyle(() => {
return {
transform: [{ translateX: offset.value }],
};
});
export default (props) => {
return ( return (
<Slider <View onLayout={(e) => setLayout(e.nativeEvent.layout)}>
style={{ width: "100%", height: 100 }} <View style={{ ...styles.sliderTrack, width: SLIDER_WIDTH }}>
minimumTrackTintColor={Palette.primary} <Animated.View style={[styles.box, boxStyle]}>
maximumTrackTintColor={Palette.lightPurple} <LinearGradient
thumbTintColor={Palette.primary} colors={["#F94697", "#7023F7"]}
tapToSeek start={{ x: 0, y: 0 }}
{...props} end={{ x: 1, y: 0 }}
/> style={{ flex: 1, borderRadius: 20 }}
/>
</Animated.View>
<GestureDetector gesture={pan}>
<Animated.View style={[styles.sliderHandle, sliderStyle]} />
</GestureDetector>
</View>
<View style={{ ...Style.containerSpaceBetween, marginTop: 10 }}>
<Text style={styles.time}>{value}</Text>
<Text style={styles.time}>{maxValue}</Text>
</View>
</View>
); );
}; };
const styles = StyleSheet.create({
box: {
height: INITIAL_BOX_SIZE,
borderRadius: 20,
position: "absolute",
zIndex: 1,
},
sliderHandle: {
width: 20,
height: 20,
backgroundColor: "#f8f9ff",
borderRadius: 25,
position: "absolute",
zIndex: 2,
borderWidth: 4,
borderColor: "#9B4DFF",
shadowColor: "#8951FC",
shadowOffset: {
width: 0,
height: 3,
},
shadowOpacity: 0.17,
shadowRadius: 3.05,
elevation: 4,
},
sliderTrack: {
height: 6,
backgroundColor: "#0F0C19",
borderRadius: 25,
justifyContent: "center",
},
time: {
fontSize: 14,
color: Palette.white,
fontFamily: FONT_FAMILY.InterRegular,
},
});
+81
View File
@@ -0,0 +1,81 @@
import { View, Text, Modal } from "react-native";
import React from "react";
import { gutters, Palette } from "../../styles";
import { BlurView } from "expo-blur";
import CreateLyricsHeader from "../../screens/Writing/components/CreateLyricsHeader";
import BorderGradientButton from "../BorderGradientButton";
import GradientButton from "../GradientButton";
import { FONT_FAMILY } from "../../styles/Fonts";
const ValidateModal = ({ visible, onClose, onPressValidate }) => {
return (
<Modal
animationType="slide"
visible={visible}
transparent={true}
onRequestClose={onClose}
>
<View
style={{
flex: 1,
justifyContent: "flex-end",
paddingBottom: gutters * 1.5,
paddingHorizontal: gutters,
}}
>
<CreateLyricsHeader>
<View style={{ gap: 30 }}>
<View style={{ gap: 15 }}>
<View
style={{ paddingHorizontal: 15, gap: 2, alignItems: "center" }}
>
<Text
style={{
fontSize: 22,
color: Palette.white,
fontFamily: FONT_FAMILY.InterSemiBold,
textAlign: "center",
}}
>
Attention !
</Text>
<Text
style={{
fontSize: 16,
color: Palette.white,
fontFamily: FONT_FAMILY.InterRegular,
}}
>
Lorsque tu clique sur valider, tu ne pourra plus changer ni le
texte ni la mélodie.{" "}
</Text>
</View>
<Text
style={{
fontSize: 16,
color: Palette.white,
fontFamily: FONT_FAMILY.InterRegular,
textAlign: "center",
}}
>
Valider
</Text>
</View>
<View style={{ width: "85%", alignSelf: "center", gap: 15 }}>
<BorderGradientButton title="Retour" onPress={onClose} />
<GradientButton
title="Valider"
onPress={() => {
onClose();
onPressValidate?.();
}}
/>
</View>
</View>
</CreateLyricsHeader>
</View>
</Modal>
);
};
export default ValidateModal;
+72
View File
@@ -56,3 +56,75 @@ export const CHOOSE_GENRE = [
description: "Structure simple, thèmes sur les épreuves de la vie.", description: "Structure simple, thèmes sur les épreuves de la vie.",
}, },
]; ];
export const VOICE = [
"Une voix féminine interpretra ta chanson.",
"Une voix masculine interpretera ta chanson.",
"Deux voix pour interpreter ta chanson.",
"Solo vocal puissant et dramatique.",
"Un chœur gospel pour (dimension spirituelle ou émotionnelle).",
"Un cri brut et puissant (émotion intense).",
"Un couplet interprété en rap.",
"Voix qui raconte une histoire, souvent sans chanter.",
"Paroles déclamées plutôt que chantées, souvent dans un style poétique ou de slam.",
"Technique vocale entre parler et chanter, typique de la musique expressionniste.",
"Sensibilité ",
"Voix séduisante et sensuelle.",
"Voix profonde et résonnante.",
"Voix légère et aérienne.",
"Voix relaxante et sophistiquée.",
"Voix synthétique.",
"Voix découpées pour un style EDM ou future bass.",
"Effet de distorsion (rendu + agressif).",
"Slam (Chant parlé).",
"Rap moderne.",
"Technique",
"Chant chargé d'émotion.",
"Technique vocale rugueuse pour le métal ou le rock.",
"Voix robotisée ou mécanique, genres électro ou futuristes.",
"Voix étrange (atmosphère de science-fiction ou de mystère).",
"Voix grave et intimidante (effet dramatique).",
"Voix pure et céleste, évoquant la tranquillité ou le divin.",
"Voix douce et aérienne, avec une touche d'intimité.",
"Voix chantée dans une tonalité plus aiguë que la normale.",
"Voix d'enfant (+ d'innocence).",
"Chant en murmure (+ intime).",
"Multiples voix superposées (effet harmonique riche).",
"Voix légère et innocente.",
"Voix soprano puissante (style opéra).",
"Chant puissant (styles pop et Broadway).",
"Mélange subtil de chuchotements et dharmoniques.",
"Voix rauque et granuleuse, utilisée dans le blues ou le rock.",
"Chœur avec une tonalité légère et céleste.",
"Inspiration et expiration sonores (effets dramatiques).",
"Changements de volume ou de tonalité dans une même phrase.",
];
export const INSTRUMENTS = [
"Piano classique",
"Piano éléctrique",
"Synthétiseur",
"Guitare acoustique",
"Guitare électrique",
"Banjo",
"Violon",
"Saxophone",
"Saxophone alto",
"Trompette",
"Flûte",
"Clarinette",
"Clarinette basse",
"Djembe",
"Bongos",
"Congas",
"Harmonica",
"Handpan",
"Harpe",
"Xylophone",
"Mandoline",
"Accordéon",
"Orgue",
"Electronique ",
];
export const RHYTHM = ["Très rapide", "Rapide", "Normal", "Lent", "Très lent"];
+25
View File
@@ -25,6 +25,11 @@ import ComposeSong from "../screens/Studio/ComposeSong";
import Compose from "../screens/Studio/Compose"; import Compose from "../screens/Studio/Compose";
import CustomizeVoice from "../screens/Studio/CustomizeVoice"; import CustomizeVoice from "../screens/Studio/CustomizeVoice";
import SongReady from "../screens/Studio/SongReady"; import SongReady from "../screens/Studio/SongReady";
import Regenerate from "../screens/Studio/Regenerate";
import PouchReady from "../screens/Studio/PouchReady";
import PhotoCover from "../screens/Studio/PhotoCover";
import AddPhotoCover from "../screens/Studio/AddPhotoCover";
import FinishCompose from "../screens/Studio/FinishCompose";
const screenOptions = { const screenOptions = {
headerShown: false, headerShown: false,
@@ -108,6 +113,26 @@ const screens = [
name: Routes.SongReady, name: Routes.SongReady,
component: SongReady, component: SongReady,
}, },
{
name: Routes.Regenerate,
component: Regenerate,
},
{
name: Routes.PouchReady,
component: PouchReady,
},
{
name: Routes.PhotoCover,
component: PhotoCover,
},
{
name: Routes.AddPhotoCover,
component: AddPhotoCover,
},
{
name: Routes.FinishCompose,
component: FinishCompose,
},
]; ];
export default function Main() { export default function Main() {
+5
View File
@@ -34,4 +34,9 @@ export const Routes = {
ComposeSong: "ComposeSong", ComposeSong: "ComposeSong",
CustomizeVoice: "CustomizeVoice", CustomizeVoice: "CustomizeVoice",
SongReady: "SongReady", SongReady: "SongReady",
Regenerate: "Regenerate",
PouchReady: "PouchReady",
PhotoCover: "PhotoCover",
AddPhotoCover: "AddPhotoCover",
FinishCompose: "FinishCompose",
}; };
+123
View File
@@ -0,0 +1,123 @@
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.FinishCompose)}
/>
</View>
</Page>
);
};
export default AddPhotoCover;
+1 -1
View File
@@ -10,7 +10,7 @@ import ItemContainer from "../../components/ItemContainer/ItemContainer";
const ChooseGenre = () => { const ChooseGenre = () => {
return ( return (
<View style={{ flex: 1, gap: 10 }}> <View style={{ flex: 1, gap: 10, paddingTop: 16 }}>
<CreateLyricsHeader <CreateLyricsHeader
title="Choisis un genre" title="Choisis un genre"
subTitle="Tu peux choisir jusqu’à 2 genres différents" subTitle="Tu peux choisir jusqu’à 2 genres différents"
+5 -4
View File
@@ -5,12 +5,13 @@ import ItemContainer from "../../components/ItemContainer/ItemContainer";
import { Palette } from "../../styles"; import { Palette } from "../../styles";
import { FONT_FAMILY } from "../../styles/Fonts"; import { FONT_FAMILY } from "../../styles/Fonts";
import { BlurView } from "expo-blur"; import { BlurView } from "expo-blur";
import { INSTRUMENTS } from "../../data/data";
const ChooseInstruments = () => { const ChooseInstruments = () => {
const [containerLayout, setContainerLayout] = useState(null); const [containerLayout, setContainerLayout] = useState(null);
return ( return (
<View style={{ flex: 1, gap: 10 }}> <View style={{ flex: 1, gap: 10, paddingTop: 16 }}>
<CreateLyricsHeader <CreateLyricsHeader
title="Choisis des instruments" title="Choisis des instruments"
subTitle="Tu peux choisir jusqu’à 5 instruments différents" subTitle="Tu peux choisir jusqu’à 5 instruments différents"
@@ -21,10 +22,10 @@ const ChooseInstruments = () => {
> >
<ItemContainer height={containerLayout?.height}> <ItemContainer height={containerLayout?.height}>
<FlatList <FlatList
data={Array.from({ length: 10 })} data={INSTRUMENTS}
showsVerticalScrollIndicator={false} showsVerticalScrollIndicator={false}
contentContainerStyle={styles.contentContainer} contentContainerStyle={styles.contentContainer}
renderItem={() => ( renderItem={({ item }) => (
<View style={styles.itemContainer}> <View style={styles.itemContainer}>
<BlurView <BlurView
intensity={30} intensity={30}
@@ -35,7 +36,7 @@ const ChooseInstruments = () => {
justifyContent: "center", justifyContent: "center",
}} }}
> >
<Text style={styles.itemText}>Piano classique</Text> <Text style={styles.itemText}>{item}</Text>
</BlurView> </BlurView>
</View> </View>
)} )}
+5 -4
View File
@@ -5,18 +5,19 @@ import ItemContainer from "../../components/ItemContainer/ItemContainer";
import { BlurView } from "expo-blur"; import { BlurView } from "expo-blur";
import { Palette } from "../../styles"; import { Palette } from "../../styles";
import { FONT_FAMILY } from "../../styles/Fonts"; import { FONT_FAMILY } from "../../styles/Fonts";
import { RHYTHM } from "../../data/data";
const ChooseRhythm = () => { const ChooseRhythm = () => {
return ( return (
<View style={{ flex: 1, gap: 10 }}> <View style={{ flex: 1, gap: 10, paddingTop: 16 }}>
<CreateLyricsHeader title="Choisis un rythme" /> <CreateLyricsHeader title="Choisis un rythme" />
<View style={{ flex: 1 }}> <View style={{ flex: 1 }}>
<ItemContainer height={340}> <ItemContainer height={340}>
<FlatList <FlatList
data={Array.from({ length: 5 })} data={RHYTHM}
showsVerticalScrollIndicator={false} showsVerticalScrollIndicator={false}
contentContainerStyle={styles.contentContainer} contentContainerStyle={styles.contentContainer}
renderItem={() => ( renderItem={({ item }) => (
<View style={styles.itemContainer}> <View style={styles.itemContainer}>
<BlurView <BlurView
intensity={30} intensity={30}
@@ -27,7 +28,7 @@ const ChooseRhythm = () => {
justifyContent: "center", justifyContent: "center",
}} }}
> >
<Text style={styles.itemText}>Très rapide</Text> <Text style={styles.itemText}>{item}</Text>
</BlurView> </BlurView>
</View> </View>
)} )}
+1 -1
View File
@@ -12,7 +12,7 @@ const Compose = () => {
return ( return (
<Page backgroundImg={background.studioBG2} headerType="NONE"> <Page backgroundImg={background.studioBG2} headerType="NONE">
<Image source={ai.theo} style={styles.img} resizeMode="contain" /> <Image source={ai.theo} style={styles.img} resizeMode="contain" />
<MusicLandHeader showSkip onPressBack={goBack} progress={7.1} /> <MusicLandHeader showSkip onPressBack={goBack} progress={9} />
<View <View
style={{ flex: 1, position: "relative", justifyContent: "flex-end" }} style={{ flex: 1, position: "relative", justifyContent: "flex-end" }}
> >
+4 -6
View File
@@ -19,13 +19,12 @@ const { width } = Dimensions.get("window");
const ComposeSong = () => { const ComposeSong = () => {
const scrollRef = useRef(null); const scrollRef = useRef(null);
const [selectedIndex, setSelectedIndex] = useState(0); const [selectedIndex, setSelectedIndex] = useState(0);
const [progress, setProgress] = useState(14.2); const [progress, setProgress] = useState(18);
const [containerLayout, setContainerLayout] = useState(null); const [containerLayout, setContainerLayout] = useState(null);
console.log("progress: ", progress);
const onPressNext = () => { const onPressNext = () => {
setSelectedIndex(selectedIndex + 1); setSelectedIndex(selectedIndex + 1);
setProgress(progress + 7.1); setProgress(progress + 9);
scrollRef.current.scrollToIndex({ scrollRef.current.scrollToIndex({
index: selectedIndex + 1, index: selectedIndex + 1,
animated: true, animated: true,
@@ -35,7 +34,7 @@ const ComposeSong = () => {
const onPressBack = () => { const onPressBack = () => {
if (selectedIndex > 0) { if (selectedIndex > 0) {
setSelectedIndex(selectedIndex - 1); setSelectedIndex(selectedIndex - 1);
setProgress(progress - 7.1); setProgress(progress - 9);
scrollRef.current.scrollToIndex({ scrollRef.current.scrollToIndex({
index: selectedIndex - 1, index: selectedIndex - 1,
animated: true, animated: true,
@@ -47,9 +46,8 @@ const ComposeSong = () => {
return ( return (
<Page backgroundImg={background.studioBG2} headerType="NONE"> <Page backgroundImg={background.studioBG2} headerType="NONE">
<Image source={ai.theo} style={styles.img} resizeMode="contain" />
<MusicLandHeader onPressBack={onPressBack} progress={progress} /> <MusicLandHeader onPressBack={onPressBack} progress={progress} />
<View style={{ flex: 1, marginTop: 16, paddingBottom: gutters, gap: 48 }}> <View style={{ flex: 1, paddingBottom: gutters, gap: 48 }}>
<View <View
style={{ flex: 1 }} style={{ flex: 1 }}
onLayout={(event) => setContainerLayout(event.nativeEvent.layout)} onLayout={(event) => setContainerLayout(event.nativeEvent.layout)}
+5 -3
View File
@@ -6,7 +6,7 @@ import Style, { size } from "../../styles/Style";
import { Palette } from "../../styles"; import { Palette } from "../../styles";
import { FONT_FAMILY } from "../../styles/Fonts"; import { FONT_FAMILY } from "../../styles/Fonts";
import ProgressBar from "../../components/ProgressBar"; import ProgressBar from "../../components/ProgressBar";
import { navigate } from "../../navigation/NavigationService"; import { goBack, navigate } from "../../navigation/NavigationService";
import { Routes } from "../../navigation"; import { Routes } from "../../navigation";
import GradientButton from "../../components/GradientButton"; import GradientButton from "../../components/GradientButton";
@@ -19,7 +19,7 @@ const CreatingSong = ({ active }) => {
setProgress((prevProgress) => { setProgress((prevProgress) => {
if (prevProgress >= 100) { if (prevProgress >= 100) {
clearInterval(interval); clearInterval(interval);
navigate(Routes.SongReady)
return 100; return 100;
} }
return prevProgress + 1; return prevProgress + 1;
@@ -34,6 +34,7 @@ const CreatingSong = ({ active }) => {
<View <View
style={{ style={{
flex: 1, flex: 1,
paddingTop: 16,
...Style.containerCenter, ...Style.containerCenter,
}} }}
> >
@@ -69,6 +70,7 @@ const CreatingSong = ({ active }) => {
> >
<BlurView <BlurView
intensity={40} intensity={40}
tint="dark"
style={{ flex: 1, padding: 10, paddingBottom: 20 }} style={{ flex: 1, padding: 10, paddingBottom: 20 }}
> >
<Pressable <Pressable
@@ -80,7 +82,7 @@ const CreatingSong = ({ active }) => {
left: 10, left: 10,
zIndex: 3, zIndex: 3,
}} }}
onPress={() => console.log("Pressed")} onPress={goBack}
> >
<Image source={icons.close} style={size({ size: 11 })} /> <Image source={icons.close} style={size({ size: 11 })} />
</Pressable> </Pressable>
+6 -6
View File
@@ -5,12 +5,13 @@ import ItemContainer from "../../components/ItemContainer/ItemContainer";
import { Palette, Style } from "../../styles"; import { Palette, Style } from "../../styles";
import { FONT_FAMILY } from "../../styles/Fonts"; import { FONT_FAMILY } from "../../styles/Fonts";
import { BlurView } from "expo-blur"; import { BlurView } from "expo-blur";
import { VOICE } from "../../data/data";
const CustomizeVoice = () => { const CustomizeVoice = () => {
const [containerLayout, setContainerLayout] = useState(null); const [containerLayout, setContainerLayout] = useState(null);
return ( return (
<View style={{ flex: 1, gap: 10 }}> <View style={{ flex: 1, gap: 10, paddingTop: 16 }}>
<CreateLyricsHeader <CreateLyricsHeader
title="Personnalise la voix que tu veux pour ta chanson" title="Personnalise la voix que tu veux pour ta chanson"
subTitle="Choisis maximum 1 option par catégorie." subTitle="Choisis maximum 1 option par catégorie."
@@ -33,10 +34,10 @@ const CustomizeVoice = () => {
Base Base
</Text> </Text>
<FlatList <FlatList
data={Array.from({ length: 10 })} data={VOICE}
showsVerticalScrollIndicator={false} showsVerticalScrollIndicator={false}
contentContainerStyle={styles.contentContainer} contentContainerStyle={styles.contentContainer}
renderItem={() => ( renderItem={({ item }) => (
<View style={styles.itemContainer}> <View style={styles.itemContainer}>
<BlurView <BlurView
intensity={30} intensity={30}
@@ -44,10 +45,10 @@ const CustomizeVoice = () => {
flex: 1, flex: 1,
backgroundColor: Palette.glass, backgroundColor: Palette.glass,
paddingHorizontal: 12, paddingHorizontal: 12,
justifyContent: "center", paddingVertical: 14,
}} }}
> >
<Text style={styles.itemText}>Une voix féminine interpretra ta chanson.</Text> <Text style={styles.itemText}>{item}</Text>
</BlurView> </BlurView>
</View> </View>
)} )}
@@ -70,7 +71,6 @@ const styles = StyleSheet.create({
paddingBottom: 50, paddingBottom: 50,
}, },
itemContainer: { itemContainer: {
height: 54,
backgroundColor: Palette.glass, backgroundColor: Palette.glass,
borderRadius: 14, borderRadius: 14,
overflow: "hidden", overflow: "hidden",
+52
View File
@@ -0,0 +1,52 @@
import { View, Text, 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.Onboarding)}
/>
<GradientButton
title="Continuer la création"
onPress={() => navigate(Routes.Onboarding)}
/>
</View>
</View>
</Page>
);
};
export default FinishCompose;
const styles = StyleSheet.create({
img: {
width: "100%",
height: "70%",
position: "absolute",
bottom: -40,
right: -30,
},
});
+93
View File
@@ -0,0 +1,93 @@
import { View, Text, Image } from "react-native";
import React 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 { Routes } from "../../navigation";
import GradientButton from "../../components/GradientButton";
const PhotoCover = () => {
return (
<Page backgroundImg={background.studioBG2} headerType="NONE">
<MusicLandHeader onPressBack={goBack} progress={81} />
<View style={{ flex: 1, marginTop: 16 }}>
<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"
/>
</View>
</View>
</View>
</View>
<View
style={{
paddingBottom: gutters * 2,
width: "80%",
alignSelf: "center",
gap: 12,
}}
>
<BorderGradientButton title="Non, laisser la pochette telle quelle" />
<GradientButton
title="Oui"
onPress={() => navigate(Routes.AddPhotoCover)}
/>
</View>
</Page>
);
};
export default PhotoCover;
+104
View File
@@ -0,0 +1,104 @@
import { View, Text, Image } from "react-native";
import React from "react";
import Page from "../../layouts/Page";
import { background, icons, img } from "../../assets";
import MusicLandHeader from "../../components/MusicLandHeader";
import { goBack, navigate } from "../../navigation/NavigationService";
import CreateLyricsHeader from "../Writing/components/CreateLyricsHeader";
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";
const PouchReady = () => {
return (
<Page backgroundImg={background.studioBG2} headerType="NONE">
<MusicLandHeader onPressBack={goBack} progress={72} />
<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",
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="Regénérer"
icon={icons.stars}
onPress={() =>
navigate(Routes.Regenerate, {
progress: 72,
})
}
/>
<GradientButton
title="Valider"
onPress={() => navigate(Routes.PhotoCover)}
/>
</View>
</Page>
);
};
export default PouchReady;
+74
View File
@@ -0,0 +1,74 @@
import { View, Text } from "react-native";
import React from "react";
import Page from "../../layouts/Page";
import { background, icons } from "../../assets";
import CreateLyricsHeader from "../Writing/components/CreateLyricsHeader";
import MusicLandHeader from "../../components/MusicLandHeader";
import { goBack } from "../../navigation/NavigationService";
import { gutters, Palette } from "../../styles";
import { FONT_FAMILY } from "../../styles/Fonts";
import GradientButton from "../../components/GradientButton";
import { useRoute } from "@react-navigation/core";
const Regenerate = () => {
const params = useRoute().params;
return (
<Page
backgroundImg={background.studioBG2}
headerType="NONE"
containerStyle={{ paddingBottom: gutters * 2 }}
>
<MusicLandHeader onPressBack={goBack} progress={params?.progress} />
<View style={{ flex: 1, marginTop: 16 }}>
<CreateLyricsHeader
title="Regénérer"
subTitle="Veux-tu changer tes choix ?"
/>
<View style={{ gap: 27, marginTop: 30 }}>
<CreateLyricsHeader title="Genre">
<Text
style={{
fontSize: 16,
color: Palette.white,
fontFamily: FONT_FAMILY.InterRegular,
}}
>
<Text style={{ fontFamily: FONT_FAMILY.InterBold }}>
Hip Hop/Rap
</Text>{" "}
: Musique commerciale destinée au grand public, accrocheuse et
mélodique. Domine les charts internationaux avec des artistes
ultra-médiatisés.
</Text>
</CreateLyricsHeader>
<CreateLyricsHeader
title="Voix"
subTitle="Une voix masculine interpretera ta chanson."
/>
<CreateLyricsHeader title="Instruments">
<Text
style={{
fontSize: 16,
color: Palette.gray,
fontFamily: FONT_FAMILY.InterRegular,
}}
>
Banjo{"\n"}Violon{"\n"}
Saxophone{"\n"}
Piano classique{"\n"}
</Text>
</CreateLyricsHeader>
</View>
</View>
<GradientButton
title="Regénérer"
containerStyle={{ width: "80%", alignSelf: "center" }}
icon={icons.stars}
onPress={goBack}
/>
</Page>
);
};
export default Regenerate;
+73 -30
View File
@@ -1,45 +1,88 @@
import { View, Text } from "react-native"; import React, { useState } from "react";
import React from "react";
import Page from "../../layouts/Page"; import Page from "../../layouts/Page";
import { background } from "../../assets"; import { background, icons } from "../../assets";
import MusicLandHeader from "../../components/MusicLandHeader"; import MusicLandHeader from "../../components/MusicLandHeader";
import { goBack } from "../../navigation/NavigationService"; import { goBack, navigate } from "../../navigation/NavigationService";
import { LinearGradient } from "../../components/LinearGradient/LinearGradient";
import Slider from "../../components/Slider"; import Slider from "../../components/Slider";
import { Image, Pressable, View } from "react-native";
import CreateLyricsHeader from "../Writing/components/CreateLyricsHeader";
import { BlurView } from "expo-blur";
import { Style } from "../../styles";
import { responsiveWidth } from "react-native-responsive-dimensions";
import { gutters, size } from "../../styles/Style";
import BorderGradientButton from "../../components/BorderGradientButton";
import GradientButton from "../../components/GradientButton";
import { Routes } from "../../navigation";
import ValidateModal from "../../components/modal/ValidateModal";
const SongReady = () => { const SongReady = () => {
const [showValidateModal, setShowValidateModal] = useState(false);
return ( return (
<Page headerType="NONE" backgroundImg={background.studioBG2}> <Page headerType="NONE" backgroundImg={background.studioBG2}>
<MusicLandHeader onPressBack={goBack} progress={49.7} /> <MusicLandHeader onPressBack={goBack} progress={63} />
<View style={{ flex: 1, marginTop: 16 }}>
<View> <CreateLyricsHeader
<LinearGradient title="Ta chanson est prête !"
colors={["#FF0000", "#FFFF00", "#0000FF"]} // Red to Yellow to Blue gradient subTitle="Quen penses-tu ?"
start={{ x: 0, y: 0.5 }} />
end={{ x: 1, y: 0.5 }} <View
style={{ style={{
width: "100%", ...size({ size: responsiveWidth(80) }),
height: 40, alignSelf: "center",
borderRadius: 20, // Optional: for rounded corners borderRadius: 1000,
overflow: "hidden",
marginTop: 16,
}} }}
> >
<Slider <BlurView
style={{ height: 40, width: "100%" }} intensity={40}
minimumValue={0} tint="dark"
maximumValue={100} style={{ ...Style.containerCenter, flex: 1 }}
minimumTrackTintColor="transparent" >
maximumTrackTintColor="red" <Image source={icons.disk} />
thumbTintColor="#FFFFFF" </BlurView>
/> </View>
</LinearGradient> <View style={{ marginTop: 49 }}>
<Slider <Slider value="0" maxValue="2:11" />
minimumValue={0} <Pressable
maximumValue={100} style={{
minimumTrackTintColor="transparent" alignSelf: "center",
maximumTrackTintColor="red" ...size({ size: 48 }),
thumbTintColor="#FFFFFF" ...Style.containerCenter,
}}
>
<Image source={icons.play} />
</Pressable>
</View>
</View>
<View
style={{
paddingBottom: gutters * 2,
width: "80%",
alignSelf: "center",
gap: 12,
}}
>
<BorderGradientButton
title="Regénérer"
icon={icons.stars}
onPress={() =>
navigate(Routes.Regenerate, {
progress: 63,
})
}
/>
<GradientButton
title="Valider"
onPress={() => setShowValidateModal(true)}
/> />
</View> </View>
<ValidateModal
visible={showValidateModal}
onClose={() => setShowValidateModal(false)}
onPressValidate={() => navigate(Routes.PouchReady)}
/>
</Page> </Page>
); );
}; };
@@ -57,7 +57,6 @@ const CreateLyricsWithAi = () => {
<View <View
style={{ style={{
flex: 1, flex: 1,
marginTop: 16,
paddingBottom: gutters, paddingBottom: gutters,
gap: responsiveHeight(5), gap: responsiveHeight(5),
}} }}
+2 -3
View File
@@ -7,7 +7,7 @@ import { size } from "../../styles/Style";
import ProgressBar from "../../components/ProgressBar"; import ProgressBar from "../../components/ProgressBar";
import { FONT_FAMILY } from "../../styles/Fonts"; import { FONT_FAMILY } from "../../styles/Fonts";
import GradientButton from "../../components/GradientButton"; import GradientButton from "../../components/GradientButton";
import { navigate } from "../../navigation/NavigationService"; import { goBack, navigate } from "../../navigation/NavigationService";
import { Routes } from "../../navigation"; import { Routes } from "../../navigation";
const CreatingLyrics = ({ active }) => { const CreatingLyrics = ({ active }) => {
@@ -19,7 +19,6 @@ const CreatingLyrics = ({ active }) => {
setProgress((prevProgress) => { setProgress((prevProgress) => {
if (prevProgress >= 100) { if (prevProgress >= 100) {
clearInterval(interval); clearInterval(interval);
navigate(Routes.Lyrics)
return 100; return 100;
} }
return prevProgress + 1; return prevProgress + 1;
@@ -80,7 +79,7 @@ const CreatingLyrics = ({ active }) => {
left: 10, left: 10,
zIndex: 3, zIndex: 3,
}} }}
onPress={() => console.log("Pressed")} onPress={goBack}
> >
<Image source={icons.close} style={size({ size: 11 })} /> <Image source={icons.close} style={size({ size: 11 })} />
</Pressable> </Pressable>
@@ -10,7 +10,7 @@ const CustomizeSongStructure = () => {
const [containerLayout, setContainerLayout] = useState(null); const [containerLayout, setContainerLayout] = useState(null);
return ( return (
<View style={{ flex: 1, gap: 10 }}> <View style={{ flex: 1, gap: 10, marginTop: 16 }}>
<CreateLyricsHeader <CreateLyricsHeader
title="Personnalise la structure de ta chanson" title="Personnalise la structure de ta chanson"
subTitle="Intègre en Drag and drop" subTitle="Intègre en Drag and drop"
+17 -43
View File
@@ -1,19 +1,15 @@
import { View, Text, FlatList } from "react-native"; import { View, Text, FlatList } from "react-native";
import React, { useState } from "react"; import React from "react";
import CreateLyricsHeader from "./components/CreateLyricsHeader"; import CreateLyricsHeader from "./components/CreateLyricsHeader";
import BorderGradient from "../../components/BorderGradient/BorderGradient";
import { responsiveHeight } from "react-native-responsive-dimensions"; import { responsiveHeight } from "react-native-responsive-dimensions";
import { BlurView } from "expo-blur";
import { Palette } from "../../styles"; import { Palette } from "../../styles";
import { FONT_FAMILY } from "../../styles/Fonts"; import { FONT_FAMILY } from "../../styles/Fonts";
import { EMOTION_CONVEY } from "../../data/data"; import { EMOTION_CONVEY } from "../../data/data";
import ItemContainer from "../../components/ItemContainer/ItemContainer"; import ItemContainer from "../../components/ItemContainer/ItemContainer";
const EmotionConvey = () => { const EmotionConvey = () => {
const [itemLayout, setItemLayout] = useState([]);
return ( return (
<View style={{ flex: 1, gap: 10 }}> <View style={{ flex: 1, gap: 10, marginTop: 16 }}>
<CreateLyricsHeader <CreateLyricsHeader
title={`Quel émotion veux-tu\ntransmettre ?`} title={`Quel émotion veux-tu\ntransmettre ?`}
subTitle="Sélectionne tes intentions émotionnelles. (2 max)" subTitle="Sélectionne tes intentions émotionnelles. (2 max)"
@@ -26,46 +22,24 @@ const EmotionConvey = () => {
gap: 16, gap: 16,
flexGrow: 1, flexGrow: 1,
zIndex: 2, zIndex: 2,
paddingTop: 5,
}} }}
renderItem={({ item, index }) => ( renderItem={({ item, index }) => (
<View> <View style={{ paddingHorizontal: 5 }}>
<BorderGradient <CreateLyricsHeader colors={item.color} intensity={30} >
gradientProps={{ <Text
colors: item.color, style={{
}} fontSize: 16,
style={{ color: Palette.white,
borderWidth: 1, fontFamily: FONT_FAMILY.InterRegular,
height: itemLayout[index]?.height, }}
borderRadius: 14,
position: "absolute",
width: "100%",
}}
/>
<View
style={{ borderRadius: 14, overflow: "hidden" }}
onLayout={(e) => {
e.persist();
setItemLayout((prev) => [...prev, e.nativeEvent.layout]);
}}
>
<BlurView
intensity={30}
style={{ paddingVertical: 14, paddingHorizontal: 12 }}
> >
<Text <Text style={{ fontFamily: FONT_FAMILY.InterBold }}>
style={{ {item.title}
fontSize: 16, </Text>{" "}
color: Palette.white, : {item.description}
fontFamily: FONT_FAMILY.InterRegular, </Text>
}} </CreateLyricsHeader>
>
<Text style={{ fontFamily: FONT_FAMILY.InterBold }}>
{item.title}
</Text>{" "}
: {item.description}
</Text>
</BlurView>
</View>
</View> </View>
)} )}
/> />
+1 -1
View File
@@ -10,7 +10,7 @@ import ItemContainer from "../../components/ItemContainer/ItemContainer";
const Goals = () => { const Goals = () => {
return ( return (
<View style={{ flex: 1, gap: 16 }}> <View style={{ flex: 1, gap: 16, marginTop: 16 }}>
<View style={{ gap: 10 }}> <View style={{ gap: 10 }}>
<CreateLyricsHeader title="Quels sont tes objectifs ?" /> <CreateLyricsHeader title="Quels sont tes objectifs ?" />
<ItemContainer> <ItemContainer>
+1 -1
View File
@@ -8,7 +8,7 @@ import ItemContainer from "../../components/ItemContainer/ItemContainer";
const Rhymes = () => { const Rhymes = () => {
return ( return (
<View style={{ flex: 1, gap: 10 }}> <View style={{ flex: 1, gap: 10, marginTop: 16 }}>
<CreateLyricsHeader title="Avec ou sans rimes" /> <CreateLyricsHeader title="Avec ou sans rimes" />
<ItemContainer height={200}> <ItemContainer height={200}>
<View style={{ gap: 10 }}> <View style={{ gap: 10 }}>
+1 -1
View File
@@ -9,7 +9,7 @@ import ItemContainer from "../../components/ItemContainer/ItemContainer";
const SongStructure = () => { const SongStructure = () => {
return ( return (
<View style={{ flex: 1, gap: 10 }}> <View style={{ flex: 1, gap: 10, marginTop: 16 }}>
<CreateLyricsHeader <CreateLyricsHeader
title="Comment veux-tu structurer ta chanson ?" title="Comment veux-tu structurer ta chanson ?"
subTitle="Sélectionne une structure." subTitle="Sélectionne une structure."
+1 -1
View File
@@ -10,7 +10,7 @@ import ItemContainer from "../../components/ItemContainer/ItemContainer";
const SongStyle = () => { const SongStyle = () => {
return ( return (
<View style={{ flex: 1, gap: 16 }}> <View style={{ flex: 1, gap: 16, marginTop: 16 }}>
<View style={{ gap: 10 }}> <View style={{ gap: 10 }}>
<CreateLyricsHeader <CreateLyricsHeader
title={`Quel est le style de ta chanson ?`} title={`Quel est le style de ta chanson ?`}
+1 -1
View File
@@ -5,7 +5,7 @@ import CustomInput from "./components/CustomInput";
const SongTo = () => { const SongTo = () => {
return ( return (
<View style={{ flex: 1, gap: 10 }}> <View style={{ flex: 1, gap: 10, marginTop: 16 }}>
<CreateLyricsHeader title="À qui sadresse ta chanson ?" /> <CreateLyricsHeader title="À qui sadresse ta chanson ?" />
<CustomInput placeholder="Ecrire mon contexte" height={283} /> <CustomInput placeholder="Ecrire mon contexte" height={283} />
</View> </View>
+1 -1
View File
@@ -5,7 +5,7 @@ import CustomInput from "./components/CustomInput";
const SpecificityContext = () => { const SpecificityContext = () => {
return ( return (
<View style={{ flex: 1, gap: 10 }}> <View style={{ flex: 1, gap: 10, marginTop: 16 }}>
<CreateLyricsHeader <CreateLyricsHeader
title="Spécificité du contexte" title="Spécificité du contexte"
subTitle="Dis-nous en un peu plus pour quon puisse mieux taider." subTitle="Dis-nous en un peu plus pour quon puisse mieux taider."
@@ -6,18 +6,27 @@ import { Palette } from "../../../styles";
import { FONT_FAMILY } from "../../../styles/Fonts"; import { FONT_FAMILY } from "../../../styles/Fonts";
import useLayoutType from "../../../hooks/useLayoutType"; import useLayoutType from "../../../hooks/useLayoutType";
const CreateLyricsHeader = ({ title = "", subTitle = "", height = 45 }) => { const CreateLyricsHeader = ({
title = "",
subTitle = "",
children,
colors = ["#FFFFFF00", "#FFFFFF"],
gradientProps,
intensity = 40,
tint = "dark",
}) => {
const [onLayout, setOnLayout] = useState(null); const [onLayout, setOnLayout] = useState(null);
const { isWeb } = useLayoutType(); const { isWeb } = useLayoutType();
return ( return (
<View style={{ paddingTop: isWeb ? 10 : 0 }}> <View>
<BorderGradient <BorderGradient
gradientProps={{ gradientProps={{
colors: ["#FFFFFF00", "#FFFFFF"], colors: colors,
locations: [0.2, 1], locations: [0.2, 1],
start: { x: 0, y: 0 }, start: { x: 0, y: 0 },
end: { x: 1, y: 0 }, end: { x: 1, y: 0 },
...{ gradientProps },
}} }}
style={{ style={{
height: isWeb ? onLayout?.height + 2 : onLayout?.height, height: isWeb ? onLayout?.height + 2 : onLayout?.height,
@@ -41,22 +50,25 @@ const CreateLyricsHeader = ({ title = "", subTitle = "", height = 45 }) => {
onPress={() => console.log("PRESSED")} onPress={() => console.log("PRESSED")}
> >
<BlurView <BlurView
intensity={20} intensity={intensity}
tint={tint}
style={{ style={{
paddingHorizontal: 12, paddingHorizontal: 12,
paddingVertical: 8, paddingVertical: 8,
gap: 4, gap: 4,
}} }}
> >
<Text {title && (
style={{ <Text
fontSize: 22, style={{
color: Palette.white, fontSize: 22,
fontFamily: FONT_FAMILY.InterSemiBold, color: Palette.white,
}} fontFamily: FONT_FAMILY.InterSemiBold,
> }}
{title} >
</Text> {title}
</Text>
)}
{subTitle && ( {subTitle && (
<Text <Text
style={{ style={{
@@ -68,6 +80,7 @@ const CreateLyricsHeader = ({ title = "", subTitle = "", height = 45 }) => {
{subTitle} {subTitle}
</Text> </Text>
)} )}
{children}
</BlurView> </BlurView>
</Pressable> </Pressable>
</View> </View>
+1
View File
@@ -35,6 +35,7 @@ const Palette = {
glass: "#73737324", glass: "#73737324",
grayMid: "#8C8C8C", grayMid: "#8C8C8C",
gray: "#E5E5E5",
}; };
export default Palette; export default Palette;