This commit is contained in:
Philip Cesar Garay
2025-08-08 21:01:38 +08:00
parent 5a4d36e1bc
commit 7bcc2e9779
28 changed files with 1065 additions and 269 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 577 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 454 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 552 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 508 KiB

+14
View File
@@ -165,23 +165,37 @@ export const mockups = {
import writingBG from "./UI/writingBG.png";
import studioBG from "./UI/studioBG.png";
import studioBG2 from "./UI/studioBG2.png";
import productionBG from "./UI/productionBG.png";
import productionBG2 from "./UI/productionBG2.png";
import playbackBG from "./UI/playbackBG.png";
import playbackBG2 from "./UI/playbackBG2.png";
export const background = {
writingBG,
studioBG,
studioBG2,
productionBG,
productionBG2,
playbackBG,
playbackBG2,
};
import nathalie from "./UI/nathalie.png";
import theo from "./UI/theo.png";
import bena from "./UI/bena.png";
import john from "./UI/john.png";
export const ai = {
nathalie,
theo,
bena,
john,
};
import placeholder from "./UI/placeholder.jpg";
import placeholder2 from "./UI/placeholder2.jpg";
export const img = {
placeholder,
placeholder2,
};
+137
View File
@@ -0,0 +1,137 @@
import { View, Text, ScrollView, StyleSheet, Dimensions } from "react-native";
import React, { useState } from "react";
import Animated, {
runOnJS,
useAnimatedGestureHandler,
useAnimatedStyle,
useSharedValue,
withSpring,
} from "react-native-reanimated";
import { PanGestureHandler } from "react-native-gesture-handler";
const { width } = Dimensions.get("window");
const DragDropTest = () => {
const [leftItems, setLeftItems] = useState([
"fortnite",
"apex",
"callofduty",
]);
const [rightItems, setRightItems] = useState([]);
const draggingItem = useSharedValue(null);
const translateX = useSharedValue(0);
const translateY = useSharedValue(0);
const moveItem = (item) => {
setLeftItems((items) => items.filter((i) => i !== item));
setRightItems((items) => [...items, item]);
};
const gestureHandler = useAnimatedGestureHandler({
onStart: (_, ctx) => {
ctx.startX = translateX.value;
ctx.startY = translateY.value;
},
onActive: (event, ctx) => {
translateX.value = ctx.startX + event.translationX;
translateY.value = ctx.startY + event.translationY;
},
onEnd: () => {
if (translateX.value > width / 2) {
runOnJS(moveItem)(draggingItem.value);
}
translateX.value = withSpring(0);
translateY.value = withSpring(0);
draggingItem.value = null;
},
});
const renderDraggable = (item) => {
const style = useAnimatedStyle(() => ({
transform: [
{ translateX: draggingItem.value === item ? translateX.value : 0 },
{ translateY: draggingItem.value === item ? translateY.value : 0 },
],
zIndex: draggingItem.value === item ? 10 : 0,
}));
return (
<PanGestureHandler
key={item}
onGestureEvent={gestureHandler}
onHandlerStateChange={() => {
draggingItem.value = item;
}}
>
<Animated.View style={[styles.item, style]}>
<Text style={styles.text}>{item}</Text>
</Animated.View>
</PanGestureHandler>
);
};
return (
<View style={styles.scrollWrapper}>
<ScrollView
style={{
...styles.scroll,
zIndex: 2,
}}
>
<Text style={styles.title}>Left</Text>
{leftItems.map(renderDraggable)}
</ScrollView>
<ScrollView
style={{
...styles.scroll,
zIndex: -1,
}}
>
<Text style={styles.title}>Right</Text>
{rightItems.map((item) => (
<View key={item} style={[styles.item, { backgroundColor: "#bdf" }]}>
<Text style={styles.text}>{item}</Text>
</View>
))}
</ScrollView>
</View>
);
};
export default DragDropTest;
const styles = StyleSheet.create({
container: {
flex: 1,
paddingTop: 50,
},
scrollWrapper: {
flexDirection: "row",
justifyContent: "space-around",
},
scroll: {
width: width / 2.2,
height: "90%",
backgroundColor: "#f0f0f0",
borderRadius: 10,
margin: 5,
padding: 10,
},
title: {
fontWeight: "bold",
fontSize: 16,
marginBottom: 10,
},
item: {
backgroundColor: "#aaf",
padding: 15,
marginVertical: 5,
borderRadius: 10,
},
text: {
color: "#333",
textAlign: "center",
},
});
+405 -40
View File
@@ -33,6 +33,186 @@ export const EMOTION_CONVEY = [
"déclare une frustration, ressentiment, énergie tournée vers la révolte.",
color: ["#FF0000", "#99999900"],
},
{
title: "La Peur",
description:
"suggère lanxiété, incertitude, perception du monde comme dangereux, tendance à l’évitement.",
color: ["#0900FF", "#99999900"],
},
{
title: "Lhumour",
description:
"insinue par allusions, sous-entendus, voire absurdité et jeux de mots. Plaisante sur le contexte.",
color: ["#FFFFFF", "#99999900"],
},
{
title: "Le Courage",
description:
"invoque la force et la capacité davancer malgré la peur. Volonté daffronté la vie, ouverture au changement positif.",
color: ["#FF441E", "#99999900"],
},
{
title: "Lllumination",
description:
"évoque la conscience pure, unité avec le tout, symbole de pureté et sagesse ultime.",
color: ["#CBD074", "#99999900"],
},
{
title: "La Paix",
description:
"suggére la paix intérieure inébranlable, la sérénite, la tranquilité profonde.",
color: ["#6CF0FF", "#99999900"],
},
{
title: "La Raison",
description:
"expose l'utilisation optimale de la logique, discernement, prise de décisions objectives et détachées. Clarté mentale.",
color: ["#4437A9", "#99999900"],
},
{
title: "LAcceptation",
description:
"laisse entendre l'arrêt de la résistance, l'équilibre obtenu, la capacité à changer ou à d'accepter ce qui ne peut lʼêtre.",
color: ["#80D475", "#99999900"],
},
{
title: "La Volonté",
description:
"déclare ma motivation à agir, l'énergie, l'autodiscipline, la recherche dʼamélioration et dʼefficacité.",
color: ["#FF9E1E", "#99999900"],
},
{
title: "Le Désir",
description:
"laisse entendre un attachement à lacquisition, la passion, la dépendance à des besoins, des personnes ou des objets extérieurs.",
color: ["#8C3F2C", "#99999900"],
},
{
title: "La Neutralité",
description:
"mentionne lacceptation de la vie telle quelle est, détachement émotionnel, labsence de jugement.",
color: ["#AFAFAF", "#99999900"],
},
{
title: "La Fierté",
description:
"expose un sentiment de supériorité, un besoin de reconnaissance externe.",
color: ["#D0BE00", "#99999900"],
},
{
title: "Le Chagrin",
description:
"exprime la tristesse profonde, perte, état de deuil ou de dépression, la mélancolie.",
color: ["#53519F", "#99999900"],
},
{
title: "LApathie",
description:
"laisse entendre labsence d’émotion, le désespoir, absence d’énergie, neutralité des réactions, résignation face à la vie.",
color: ["#565656", "#99999900"],
},
{
title: "La Culpabilité",
description:
"sous-entends lauto-blâme, lincapacité à se pardonner, excuses répétées, des justifications alambiquées.",
color: ["#7B1B1B", "#99999900"],
},
{
title: "La Honte",
description:
"insinue un sentiment dhumiliation profonde, perte destime de soi, tendance à lauto-dépréciation.",
color: ["#8E4746", "#99999900"],
},
];
export const SONG_STYLE = [
{
title: "Upbeat",
description: "Pour une ambiance joyeuse et rythmée",
},
{
title: "Grandios(e)",
description: "Pour un sentiment de grandeur",
},
{
title: "Chill",
description: "Pour une ambiance détendue ou apaisante, relax",
},
{
title: "Epic",
description: "Pour un sentiment grandiose et héroïque",
},
{
title: "Dramatic",
description: "Utilisé pour des effets théâtraux ou intenses",
},
{
title: "Comedic",
description: "Pour un ton humoristique",
},
{
title: "Theatrical",
description: "Pour un style musical qui évoque le théâtre",
},
{
title: "Flamboyant",
description: "Pour un style exubérant ",
},
{
title: "Melancholic",
description: "ambiance mélancolique",
},
{
title: "Introspective",
description: "Pour un caractère introspectif",
},
{
title: "Urban Tragedy",
description: "Pour une ambiance de tragédie urbaine",
},
{
title: "Eerie",
description: "Pour une ambiance étrange ou inquiétante",
},
{
title: "Mysterious",
description: "Pour un sentiment de mystère",
},
{
title: "Melancholic",
description: "ambiance mélancolique",
},
];
export const CUSTOM_SONG_STRUCTURE = [
"Introduction instrumentale courte.",
"Introduction instrumentale longue.",
"Ajoute un pré-refrain intrumental.",
"Utilisé pour une section contrastant avec les couplets et refrains.",
"Indique une section avec un solo Guitare.",
"Indique une section avec un solo Guitare électrique.",
"Indique une section avec un solo Batterie.",
"Indique une section avec un solo Saxo.",
"Indique une section avec un solo Violon.",
"Indique un moment de pause ou de changement.",
"Indique un interlude.",
"Indique un interlude mélodique.",
"Désigne une grande finition, un apogée.",
"Indique un arrêt net de la musique.",
"Permet de terminer la chanson en baissant le volume progressivement.",
"Indique une transition douce vers le silence.",
];
export const SONG_STRUCTURE = [
"1 couplet, 1 refrain, 1 couplet, 1 refrain",
"1 couplet, 1 refrain, 1 couplet, 2 refrains",
"1 couplet, 1 refrain, 2 couplets, 1 refrain",
"2 couplets, 1 refrain, 2 couplets, 1 refrain",
"2 couplets, 1 refrain, 2 couplets, 2 refrains",
"2 couplets, 1 refrain, 2 couplets, 1 refrain, 2 couplets, 1 refrain",
"2 couplets, 1 refrain, 2 couplets, 1 refrain, 2 couplets, 2 refrains",
"3 couplets, 2 refrains (metal)",
"Pas de couplet pas de refrain, juste un texte",
];
export const CHOOSE_GENRE = [
@@ -55,49 +235,234 @@ export const CHOOSE_GENRE = [
title: "Blues",
description: "Structure simple, thèmes sur les épreuves de la vie.",
},
{
title: "Folk",
description:
"Instruments acoustiques, narration, ancrage dans la tradition populaire.",
},
{
title: "Punk",
description:
"Énergie brute, textes contestataires, structures simples. Mouvement contre-culturel majeur.musique rebelle aux influences sociales et politiques fortes.",
},
{
title: "Dance",
description:
"Musique rythmée, conçue pour la danse, souvent électronique ou pop.",
},
{
title: "Grunge",
description:
"Sous-genre du rock, sons sales, textes introspectifs, popularisé par Nirvana.",
},
{
title: "EDM",
description:
"Musique électronique dynamique orientée clubs et festivals.Style Tomorrowland.",
},
{
title: "Trap",
description:
"Sous-genre du rap caractérisé par ses beats lourds et son attitude street. Popularisé à Atlanta, il domine le rap mainstream actuel.",
},
{
title: "Latino",
description:
"Reggaeton, salsa, bachata et autres styles hispaniques, rythmes dansants et festifs.",
},
{
title: "Dancehall",
description:
"Style jamaïcain rythmé dérivé du reggae, apprécié pour son énergie festive et sensuelle.",
},
{
title: "Latin Pop",
description:
"Musique pop Caribbean, Salsa, Merengue, rythmes latinos festifs et dansants.",
},
{
title: "Raggaeton",
description:
"Mélange latino de reggae, rap et dancehall aux rythmes entraînants. sons latinos modernes.",
},
{
title: "Rock",
description:
"Genre énergique dérivé du rock'n'roll, porté par guitares électriques et batterie puissante.",
},
{
title: "Rock progressif",
description:
"Rock complexe, longues compositions, virtuosité instrumentale.",
},
{
title: "Hard Rock",
description: "Rock énergique, guitares puissantes, voix souvent rauques.",
},
{
title: "Metal",
description:
"Dérivé extrême du rock avec des guitares saturées, une batterie énergique et des thèmes souvent sombres.",
},
{
title: "R&B",
description: "Genre doux et mélodieux issu du blues, jazz et gospel.",
},
{
title: "Phonk",
description:
"Samples funk, des voix rap vintage de Memphis, production hachées et vissées, combine à des éléments de jazz. atmosphère sombre et rythmes hypnotiques.",
},
{
title: "House",
description:
"Style électronique entraînant, rythmiques régulières et grooves dansants. Ambiance clubs, radio et festivals occidentaux.",
},
{
title: "Alternative",
description:
"Version expérimentale et variée du rock traditionnel, populaire en festivals indé. Caractérisé par attitude anti-mainstream.",
},
{
title: "Indie",
description:
"Musique indépendante variée, mettant en avant créativité et originalité.",
},
{
title: "Country",
description: "Musique traditionnelle américaine d'origine rurale.",
},
{
title: "Synthwave",
description:
"Musique électronique inspirée de l'esthétique années 80, nostalgique et futuriste. son revival esthétique.",
},
{
title: "Afrobeat",
description:
"Mélange de musique traditionnelle nigériane, de jazz, du highlife ghanéen, de funk et de chant, accompagné de percussions et de styles vocaux.",
},
{
title: "K-Pop",
description:
"Genre musical originaire de Corée du Sud qui combine divers styles comme la pop, le hip-hop, le R&B et l'électro. Mélodies accrocheuses.",
},
{
title: "Techno",
description:
"Musique électronique répétitive originaire de Détroit, tempo rapide, underground. Ambiance club.",
},
{
title: "Funk",
description:
"Musique rythmique marquée par des basses puissantes et grooves entraînants. pop moderne.",
},
{
title: "Disco",
description:
"Genre dance festif des années 70 caractérisé par des rythmes répétitifs et entraînants. Vit un revival puissant avec des références pop moderne.",
},
{
title: "New wave",
description:
"Fusion de punk, pop et électronique, esthétique expérimentale des années 80.",
},
{
title: "Jazz",
description:
"Genre basé sur limprovisation et lexpression musicale complexe.",
},
{
title: "Lo-Fi",
description:
"Musique relaxante à basse qualité sonore, souvent instrumentale et appréciée pour l'étude ou la détente.",
},
{
title: "Bedroom Pop",
description:
"Pop intimiste. sonorités douces, dream pop, avec une prédominance d'instruments acoustiques, de synthétiseurs et de voix feutrées.",
},
{
title: "Ambient",
description:
"Musique atmosphérique et immersive privilégiant textures sonores et ambiances relaxantes. recherche de calme.",
},
{
title: "Dream Pop",
description:
"Pop éthérée aux mélodies oniriques, souvent caractérisée par des effets de guitares et synthés. Adorée pour son esthétique mélancolique dans l'indie occidental.",
},
{
title: "Grime",
description:
"Genre électronique urbain britannique aux paroles incisives et flow rapide.",
},
{
title: "Hyperpop",
description:
"Musique expérimentale maximaliste combinant pop, EDM et distorsions vocales exagérées. Gen-Z.",
},
{
title: "Gospel",
description:
"Musique religieuse afro-américaine, chœurs puissants, influence sur soul et R&B.",
},
];
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.",
{
title: "base",
data: [
"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.",
],
},
{
title: "Sensibilité",
data: [
"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.",
],
},
{
title: "Technique",
data: [
"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 = [
+10
View File
@@ -30,6 +30,8 @@ import PouchReady from "../screens/Studio/PouchReady";
import PhotoCover from "../screens/Studio/PhotoCover";
import AddPhotoCover from "../screens/Studio/AddPhotoCover";
import FinishCompose from "../screens/Studio/FinishCompose";
import Production from "../screens/Production/Production";
import ProductionOnboarding from "../screens/Production/ProductionOnboarding";
const screenOptions = {
headerShown: false,
@@ -133,6 +135,14 @@ const screens = [
name: Routes.FinishCompose,
component: FinishCompose,
},
{
name: Routes.ProductionOnboarding,
component: ProductionOnboarding,
},
{
name: Routes.Production,
component: Production,
},
];
export default function Main() {
+3
View File
@@ -39,4 +39,7 @@ export const Routes = {
PhotoCover: "PhotoCover",
AddPhotoCover: "AddPhotoCover",
FinishCompose: "FinishCompose",
ProductionOnboarding: "ProductionOnboarding",
Production: "Production",
};
+1
View File
@@ -17,6 +17,7 @@ export default ({ navigation }) => {
>
<Button text="WRITING" onPress={() => navigate(Routes.Writing)} />
<Button text="STUDIO" onPress={() => navigate(Routes.Studio)} />
<Button text="PRODUCTION" onPress={() => navigate(Routes.ProductionOnboarding)} />
</View>
);
};
+12
View File
@@ -0,0 +1,12 @@
import { View, Text } from "react-native";
import React from "react";
const DownloadSongs = () => {
return (
<View>
<Text>DownloadSongs</Text>
</View>
);
};
export default DownloadSongs;
+37
View File
@@ -0,0 +1,37 @@
import { View } from "react-native";
import React from "react";
import Page from "../../layouts/Page";
import { background } from "../../assets";
import { gutters } from "../../styles";
import GradientButton from "../../components/GradientButton";
import MusicLandHeader from "../../components/MusicLandHeader";
import { goBack } from "../../navigation/NavigationService";
import BorderGradientButton from "../../components/BorderGradientButton";
const Production = () => {
return (
<Page headerType="NONE" backgroundImg={background.productionBG}>
<MusicLandHeader onPressBack={goBack} progress={9} />
<View
style={{
flex: 1,
paddingBottom: gutters * 2,
justifyContent: "flex-end",
gap: 37,
}}
>
<BorderGradientButton title="Je télécharge ma chanson" />
<View style={{ gap: 12 }}>
<GradientButton title="Je veux devenir Playbacker" />
<BorderGradientButton title="Voir exemples" />
</View>
<View style={{ gap: 12 }}>
<GradientButton title="Je veux créer un Clip" />
<BorderGradientButton title="Voir exemples" />
</View>
</View>
</Page>
);
};
export default Production;
@@ -0,0 +1,29 @@
import { View, Text } from "react-native";
import React from "react";
import Page from "../../layouts/Page";
import { background } from "../../assets";
import { gutters } from "../../styles";
import GradientButton from "../../components/GradientButton";
import { navigate } from "../../navigation/NavigationService";
import { Routes } from "../../navigation";
const ProductionOnboarding = () => {
return (
<Page headerType="NONE" backgroundImg={background.productionBG}>
<View
style={{
flex: 1,
paddingBottom: gutters * 2,
justifyContent: "flex-end",
}}
>
<GradientButton
title="Commence"
onPress={() => navigate(Routes.Production)}
/>
</View>
</Page>
);
};
export default ProductionOnboarding;
+59 -57
View File
@@ -1,76 +1,78 @@
import { View, Text, StyleSheet, FlatList } from "react-native";
import React from "react";
import { View, Text, FlatList } from "react-native";
import React, { useState } from "react";
import CreateLyricsHeader from "../Writing/components/CreateLyricsHeader";
import { responsiveHeight } from "react-native-responsive-dimensions";
import { BlurView } from "expo-blur";
import { FONT_FAMILY } from "../../styles/Fonts";
import { Palette } from "../../styles";
import { CHOOSE_GENRE } from "../../data/data";
import ItemContainer from "../../components/ItemContainer/ItemContainer";
const ChooseGenre = () => {
const [containerLayout, setContainerLayout] = useState(null);
const [selected, setSelected] = useState(null);
const onPressSelect = (item) => {
if (selected === item) {
setSelected(null);
} else {
setSelected(item);
}
};
return (
<View style={{ flex: 1, gap: 10, paddingTop: 16 }}>
<CreateLyricsHeader
title="Choisis un genre"
subTitle="Tu peux choisir jusqu’à 2 genres différents"
/>
<ItemContainer height={responsiveHeight(55)}>
<FlatList
data={CHOOSE_GENRE}
contentContainerStyle={{
gap: 16,
flexGrow: 1,
zIndex: 2,
}}
renderItem={({ item, index }) => (
<View style={{ borderRadius: 14, overflow: "hidden" }}>
<BlurView
intensity={30}
style={{ paddingVertical: 14, paddingHorizontal: 12 }}
>
<Text
style={{
fontSize: 16,
color: Palette.white,
fontFamily: FONT_FAMILY.InterRegular,
}}
>
<Text style={{ fontFamily: FONT_FAMILY.InterBold }}>
{item.title}
</Text>{" "}
: {item.description}
</Text>
</BlurView>
</View>
)}
/>
</ItemContainer>
<View
style={{ flex: 1 }}
onLayout={(event) => setContainerLayout(event.nativeEvent.layout)}
>
<ItemContainer height={containerLayout?.height}>
<FlatList
data={CHOOSE_GENRE}
contentContainerStyle={{
gap: 16,
flexGrow: 1,
zIndex: 2,
paddingTop: 5,
}}
renderItem={({ item, index }) => {
const selectedItem = selected === item.title;
return (
<View style={{ paddingHorizontal: 5 }}>
<CreateLyricsHeader
colors={
selectedItem
? ["#FFFFFF00", "#FFFFFF"]
: [Palette.tran, Palette.tran]
}
tint={selectedItem ? "default" : "dark"}
onPress={() => onPressSelect(item.title)}
>
<Text
style={{
fontSize: 16,
color: Palette.white,
fontFamily: FONT_FAMILY.InterRegular,
}}
>
<Text style={{ fontFamily: FONT_FAMILY.InterBold }}>
{item.title}
</Text>{" "}
: {item.description}
</Text>
</CreateLyricsHeader>
</View>
);
}}
/>
</ItemContainer>
</View>
</View>
);
};
export default ChooseGenre;
const styles = StyleSheet.create({
borderGradientStyle: {
borderWidth: 1,
borderRadius: 20,
shadowColor: "#000",
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.25,
shadowRadius: 3.84,
elevation: 100,
position: "absolute",
width: "100%",
},
blurContainer: {
borderRadius: 20,
overflow: "hidden",
zIndex: 1,
maxHeight: responsiveHeight(55),
},
});
+34 -13
View File
@@ -9,6 +9,15 @@ import { INSTRUMENTS } from "../../data/data";
const ChooseInstruments = () => {
const [containerLayout, setContainerLayout] = useState(null);
const [selected, setSelected] = useState(null);
const onPressSelect = (item) => {
if (selected === item) {
setSelected(null);
} else {
setSelected(item);
}
};
return (
<View style={{ flex: 1, gap: 10, paddingTop: 16 }}>
@@ -25,21 +34,33 @@ const ChooseInstruments = () => {
data={INSTRUMENTS}
showsVerticalScrollIndicator={false}
contentContainerStyle={styles.contentContainer}
renderItem={({ item }) => (
<View style={styles.itemContainer}>
<BlurView
intensity={30}
style={{
flex: 1,
backgroundColor: Palette.glass,
paddingHorizontal: 12,
justifyContent: "center",
renderItem={({ item }) => {
const selectedItem = selected === item;
return (
<CreateLyricsHeader
onPress={() => onPressSelect(item)}
tint={selectedItem ? "default" : "dark"}
colors={
selectedItem
? ["#FFFFFF00", "#FFFFFF"]
: [Palette.tran, Palette.tran]
}
containerStyle={{
...styles.itemContainer,
}}
>
<Text style={styles.itemText}>{item}</Text>
</BlurView>
</View>
)}
<View
style={{
height: 40,
justifyContent: "center",
}}
>
<Text style={styles.itemText}>{item}</Text>
</View>
</CreateLyricsHeader>
);
}}
/>
</ItemContainer>
</View>
+36 -14
View File
@@ -1,5 +1,5 @@
import { View, Text, FlatList, StyleSheet } from "react-native";
import React from "react";
import React, { useState } from "react";
import CreateLyricsHeader from "../Writing/components/CreateLyricsHeader";
import ItemContainer from "../../components/ItemContainer/ItemContainer";
import { BlurView } from "expo-blur";
@@ -8,6 +8,16 @@ import { FONT_FAMILY } from "../../styles/Fonts";
import { RHYTHM } from "../../data/data";
const ChooseRhythm = () => {
const [selected, setSelected] = useState(null);
const onPressSelect = (item) => {
if (selected === item) {
setSelected(null);
} else {
setSelected(item);
}
};
return (
<View style={{ flex: 1, gap: 10, paddingTop: 16 }}>
<CreateLyricsHeader title="Choisis un rythme" />
@@ -17,21 +27,33 @@ const ChooseRhythm = () => {
data={RHYTHM}
showsVerticalScrollIndicator={false}
contentContainerStyle={styles.contentContainer}
renderItem={({ item }) => (
<View style={styles.itemContainer}>
<BlurView
intensity={30}
style={{
flex: 1,
backgroundColor: Palette.glass,
paddingHorizontal: 12,
justifyContent: "center",
renderItem={({ item }) => {
const selectedItem = selected === item;
return (
<CreateLyricsHeader
onPress={() => onPressSelect(item)}
tint={selectedItem ? "default" : "dark"}
colors={
selectedItem
? ["#FFFFFF00", "#FFFFFF"]
: [Palette.tran, Palette.tran]
}
containerStyle={{
...styles.itemContainer,
}}
>
<Text style={styles.itemText}>{item}</Text>
</BlurView>
</View>
)}
<View
style={{
height: 40,
justifyContent: "center",
}}
>
<Text style={styles.itemText}>{item}</Text>
</View>
</CreateLyricsHeader>
);
}}
/>
</ItemContainer>
</View>
+47 -26
View File
@@ -1,4 +1,4 @@
import { View, Text, FlatList, StyleSheet } from "react-native";
import { View, Text, FlatList, StyleSheet, SectionList } from "react-native";
import React, { useState } from "react";
import CreateLyricsHeader from "../Writing/components/CreateLyricsHeader";
import ItemContainer from "../../components/ItemContainer/ItemContainer";
@@ -9,6 +9,15 @@ import { VOICE } from "../../data/data";
const CustomizeVoice = () => {
const [containerLayout, setContainerLayout] = useState(null);
const [selected, setSelected] = useState(null);
const onPressSelect = (item) => {
if (selected === item) {
setSelected(null);
} else {
setSelected(item);
}
};
return (
<View style={{ flex: 1, gap: 10, paddingTop: 16 }}>
@@ -22,35 +31,47 @@ const CustomizeVoice = () => {
>
<ItemContainer height={containerLayout?.height}>
<View style={{ flex: 1, gap: 10 }}>
<Text
style={{
fontSize: 16,
color: Palette.white,
fontFamily: FONT_FAMILY.InterBold,
left: 16,
marginTop: 5,
}}
>
Base
</Text>
<FlatList
data={VOICE}
<SectionList
sections={VOICE}
showsVerticalScrollIndicator={false}
contentContainerStyle={styles.contentContainer}
renderItem={({ item }) => (
<View style={styles.itemContainer}>
<BlurView
intensity={30}
style={{
flex: 1,
backgroundColor: Palette.glass,
paddingHorizontal: 12,
paddingVertical: 14,
renderItem={({ item }) => {
const selectedItem = selected === item;
return (
<CreateLyricsHeader
onPress={() => onPressSelect(item)}
tint={selectedItem ? "default" : "dark"}
colors={
selectedItem
? ["#FFFFFF00", "#FFFFFF"]
: [Palette.tran, Palette.tran]
}
containerStyle={{
...styles.itemContainer,
}}
>
<Text style={styles.itemText}>{item}</Text>
</BlurView>
</View>
<View
style={{
paddingVertical: 6,
}}
>
<Text style={styles.itemText}>{item}</Text>
</View>
</CreateLyricsHeader>
);
}}
renderSectionHeader={({ section: { title } }) => (
<Text
style={{
fontSize: 16,
color: Palette.white,
fontFamily: FONT_FAMILY.InterBold,
left: 10,
}}
>
{title}
</Text>
)}
/>
</View>
+1
View File
@@ -68,6 +68,7 @@ const CreatingLyrics = ({ active }) => {
>
<BlurView
intensity={40}
tint="dark"
style={{ flex: 1, padding: 10, paddingBottom: 20 }}
>
<Pressable
+15 -10
View File
@@ -5,6 +5,8 @@ import { BlurView } from "expo-blur";
import { Palette } from "../../styles";
import { FONT_FAMILY } from "../../styles/Fonts";
import ItemContainer from "../../components/ItemContainer/ItemContainer";
import { CUSTOM_SONG_STRUCTURE } from "../../data/data";
import DragDropTest from "../../components/DragDropTest";
const CustomizeSongStructure = () => {
const [containerLayout, setContainerLayout] = useState(null);
@@ -15,7 +17,7 @@ const CustomizeSongStructure = () => {
title="Personnalise la structure de ta chanson"
subTitle="Intègre en Drag and drop"
/>
<View style={{ flex: 1, gap: 10 }}>
{/* <View style={{ flex: 1, gap: 10 }}>
<View
style={{ flex: 1 }}
onLayout={(e) => {
@@ -24,18 +26,20 @@ const CustomizeSongStructure = () => {
>
<ItemContainer height={containerLayout?.height}>
<ScrollView contentContainerStyle={{ gap: 10, paddingBottom: 20 }}>
{Array.from({ length: 10 }).map((_, index) => (
<View key={index} style={styles.dropzoneContainer}>
<Text style={styles.dropzone}>Couplet</Text>
</View>
))}
{["Couplet", "Refrain", "Couplet", "Refrain"].map(
(item, index) => (
<View key={index} style={styles.dropzoneContainer}>
<Text style={styles.dropzone}>{item}</Text>
</View>
)
)}
</ScrollView>
</ItemContainer>
</View>
<View style={{ flex: 1 }}>
<ItemContainer height={containerLayout?.height}>
<ScrollView contentContainerStyle={{ gap: 10, paddingBottom: 20 }}>
{Array.from({ length: 10 }).map((_, index) => (
{CUSTOM_SONG_STRUCTURE.map((item, index) => (
<View key={index} style={styles.itemContainer}>
<BlurView
intensity={30}
@@ -46,15 +50,16 @@ const CustomizeSongStructure = () => {
paddingHorizontal: 12,
}}
>
<Text style={styles.dropzone}>
Introduction instrumentale longue.
</Text>
<Text style={styles.dropzone}>{item}</Text>
</BlurView>
</View>
))}
</ScrollView>
</ItemContainer>
</View>
</View> */}
<View style={{ flex: 1 }}>
<DragDropTest />
</View>
</View>
);
+54 -30
View File
@@ -1,5 +1,5 @@
import { View, Text, FlatList } from "react-native";
import React from "react";
import React, { useState } from "react";
import CreateLyricsHeader from "./components/CreateLyricsHeader";
import { responsiveHeight } from "react-native-responsive-dimensions";
import { Palette } from "../../styles";
@@ -8,6 +8,17 @@ import { EMOTION_CONVEY } from "../../data/data";
import ItemContainer from "../../components/ItemContainer/ItemContainer";
const EmotionConvey = () => {
const [containerLayout, setContainerLayout] = useState(null);
const [selected, setSelected] = useState(null);
const onPressSelect = (item) => {
if (selected === item) {
setSelected(null);
} else {
setSelected(item);
}
};
return (
<View style={{ flex: 1, gap: 10, marginTop: 16 }}>
<CreateLyricsHeader
@@ -15,35 +26,48 @@ const EmotionConvey = () => {
subTitle="Sélectionne tes intentions émotionnelles. (2 max)"
/>
<ItemContainer height={responsiveHeight(50)}>
<FlatList
data={EMOTION_CONVEY}
contentContainerStyle={{
gap: 16,
flexGrow: 1,
zIndex: 2,
paddingTop: 5,
}}
renderItem={({ item, index }) => (
<View style={{ paddingHorizontal: 5 }}>
<CreateLyricsHeader colors={item.color} intensity={30} >
<Text
style={{
fontSize: 16,
color: Palette.white,
fontFamily: FONT_FAMILY.InterRegular,
}}
>
<Text style={{ fontFamily: FONT_FAMILY.InterBold }}>
{item.title}
</Text>{" "}
: {item.description}
</Text>
</CreateLyricsHeader>
</View>
)}
/>
</ItemContainer>
<View
style={{ flex: 1 }}
onLayout={(event) => setContainerLayout(event.nativeEvent.layout)}
>
<ItemContainer height={containerLayout?.height}>
<FlatList
data={EMOTION_CONVEY}
contentContainerStyle={{
gap: 16,
flexGrow: 1,
zIndex: 2,
paddingTop: 5,
}}
renderItem={({ item, index }) => {
const selectedItem = selected === item.title;
return (
<View style={{ paddingHorizontal: 5 }}>
<CreateLyricsHeader
colors={item.color}
tint={selectedItem ? "default" : "dark"}
onPress={() => onPressSelect(item.title)}
>
<Text
style={{
fontSize: 16,
color: Palette.white,
fontFamily: FONT_FAMILY.InterRegular,
}}
>
<Text style={{ fontFamily: FONT_FAMILY.InterBold }}>
{item.title}
</Text>{" "}
: {item.description}
</Text>
</CreateLyricsHeader>
</View>
);
}}
/>
</ItemContainer>
</View>
</View>
);
};
+36 -18
View File
@@ -1,14 +1,23 @@
import { View, Text, FlatList, StyleSheet, Pressable } from "react-native";
import React from "react";
import React, { useState } from "react";
import CreateLyricsHeader from "./components/CreateLyricsHeader";
import { Palette, Style } from "../../styles";
import { BlurView } from "expo-blur";
import { GOALS } from "../../data/data";
import { FONT_FAMILY } from "../../styles/Fonts";
import CustomInput from "./components/CustomInput";
import ItemContainer from "../../components/ItemContainer/ItemContainer";
const Goals = () => {
const [selected, setSelected] = useState(null);
const onPressSelect = (item) => {
if (selected === item) {
setSelected(null);
} else {
setSelected(item);
}
};
return (
<View style={{ flex: 1, gap: 16, marginTop: 16 }}>
<View style={{ gap: 10 }}>
@@ -18,21 +27,33 @@ const Goals = () => {
data={GOALS}
showsVerticalScrollIndicator={false}
contentContainerStyle={styles.contentContainer}
renderItem={({ item }) => (
<Pressable style={styles.itemContainer}>
<BlurView
intensity={30}
style={{
flex: 1,
backgroundColor: Palette.glass,
paddingHorizontal: 12,
...Style.containerCenter,
renderItem={({ item }) => {
const selectedItem = selected === item;
return (
<CreateLyricsHeader
onPress={() => onPressSelect(item)}
tint={selectedItem ? "default" : "dark"}
colors={
selectedItem
? ["#FFFFFF00", "#FFFFFF"]
: [Palette.tran, Palette.tran]
}
containerStyle={{
...styles.itemContainer,
}}
>
<Text style={styles.itemText}>{item}</Text>
</BlurView>
</Pressable>
)}
<View
style={{
height: 40,
...Style.containerCenter,
}}
>
<Text style={styles.itemText}>{item}</Text>
</View>
</CreateLyricsHeader>
);
}}
/>
</ItemContainer>
</View>
@@ -55,10 +76,7 @@ const styles = StyleSheet.create({
paddingBottom: 50,
},
itemContainer: {
height: 54,
backgroundColor: Palette.glass,
borderRadius: 14,
overflow: "hidden",
shadowColor: "#00000040",
shadowOffset: {
width: 0,
+44 -19
View File
@@ -1,34 +1,58 @@
import { View, Text, StyleSheet } from "react-native";
import React from "react";
import React, { useState } from "react";
import CreateLyricsHeader from "./components/CreateLyricsHeader";
import { BlurView } from "expo-blur";
import { Palette } from "../../styles";
import { Palette, Style } from "../../styles";
import { FONT_FAMILY } from "../../styles/Fonts";
import ItemContainer from "../../components/ItemContainer/ItemContainer";
const Rhymes = () => {
const [selected, setSelected] = useState(null);
const onPressSelect = (item) => {
if (selected === item) {
setSelected(null);
} else {
setSelected(item);
}
};
return (
<View style={{ flex: 1, gap: 10, marginTop: 16 }}>
<CreateLyricsHeader title="Avec ou sans rimes" />
<ItemContainer height={200}>
<View style={{ gap: 10 }}>
{Array.from({ length: 3 }).map((_, index) => (
<View key={index} style={styles.itemContainer}>
<BlurView
intensity={30}
style={{
flex: 1,
backgroundColor: Palette.glass,
justifyContent: "center",
paddingHorizontal: 12,
}}
>
<Text style={styles.dropzone}>
Introduction instrumentale longue.
</Text>
</BlurView>
</View>
))}
{["Avec rimes", "Sans rimes", "Mélange des deux"].map(
(item, index) => {
const selectedItem = selected === item;
return (
<CreateLyricsHeader
key={index}
onPress={() => onPressSelect(item)}
tint={selectedItem ? "default" : "dark"}
colors={
selectedItem
? ["#FFFFFF00", "#FFFFFF"]
: [Palette.tran, Palette.tran]
}
containerStyle={{
...styles.itemContainer,
}}
>
<View
style={{
height: 40,
...Style.containerCenter,
paddingHorizontal: 14,
}}
>
<Text style={styles.dropzone}>{item}</Text>
</View>
</CreateLyricsHeader>
);
}
)}
</View>
</ItemContainer>
</View>
@@ -56,5 +80,6 @@ const styles = StyleSheet.create({
fontSize: 16,
color: Palette.white,
fontFamily: FONT_FAMILY.InterRegular,
textAlign: "center",
},
});
+39 -17
View File
@@ -1,13 +1,23 @@
import { View, Text, StyleSheet, FlatList, Pressable } from "react-native";
import React from "react";
import React, { useState } from "react";
import CreateLyricsHeader from "./components/CreateLyricsHeader";
import { BlurView } from "expo-blur";
import { GOALS } from "../../data/data";
import { GOALS, SONG_STRUCTURE } from "../../data/data";
import { Palette, Style } from "../../styles";
import { FONT_FAMILY } from "../../styles/Fonts";
import ItemContainer from "../../components/ItemContainer/ItemContainer";
const SongStructure = () => {
const [selected, setSelected] = useState(null);
const onPressSelect = (item) => {
if (selected === item) {
setSelected(null);
} else {
setSelected(item);
}
};
return (
<View style={{ flex: 1, gap: 10, marginTop: 16 }}>
<CreateLyricsHeader
@@ -16,23 +26,37 @@ const SongStructure = () => {
/>
<ItemContainer>
<FlatList
data={GOALS}
data={SONG_STRUCTURE}
showsVerticalScrollIndicator={false}
contentContainerStyle={styles.contentContainer}
renderItem={({ item }) => (
<Pressable style={styles.itemContainer}>
<BlurView
intensity={30}
style={{
flex: 1,
backgroundColor: Palette.glass,
...Style.containerCenter,
renderItem={({ item }) => {
const selectedItem = selected === item;
return (
<CreateLyricsHeader
onPress={() => onPressSelect(item)}
tint={selectedItem ? "default" : "dark"}
colors={
selectedItem
? ["#FFFFFF00", "#FFFFFF"]
: [Palette.tran, Palette.tran]
}
containerStyle={{
...styles.itemContainer,
}}
>
<Text style={styles.itemText}>{item}</Text>
</BlurView>
</Pressable>
)}
<View
style={{
height: 40,
paddingHorizontal: 14,
justifyContent: "center",
}}
>
<Text style={styles.itemText}>{item}</Text>
</View>
</CreateLyricsHeader>
);
}}
/>
</ItemContainer>
</View>
@@ -51,9 +75,7 @@ const styles = StyleSheet.create({
},
itemContainer: {
height: 54,
backgroundColor: Palette.glass,
borderRadius: 14,
overflow: "hidden",
shadowColor: "#00000040",
shadowOffset: {
width: 0,
+44 -19
View File
@@ -1,14 +1,24 @@
import { View, Text, FlatList, Pressable, StyleSheet } from "react-native";
import React from "react";
import React, { useState } from "react";
import CreateLyricsHeader from "./components/CreateLyricsHeader";
import { BlurView } from "expo-blur";
import { GOALS } from "../../data/data";
import { GOALS, SONG_STYLE } from "../../data/data";
import { Palette, Style } from "../../styles";
import CustomInput from "./components/CustomInput";
import { FONT_FAMILY } from "../../styles/Fonts";
import ItemContainer from "../../components/ItemContainer/ItemContainer";
const SongStyle = () => {
const [selected, setSelected] = useState(null);
const onPressSelect = (item) => {
if (selected === item) {
setSelected(null);
} else {
setSelected(item);
}
};
return (
<View style={{ flex: 1, gap: 16, marginTop: 16 }}>
<View style={{ gap: 10 }}>
@@ -18,24 +28,42 @@ const SongStyle = () => {
/>
<ItemContainer>
<FlatList
data={GOALS}
data={SONG_STYLE}
showsVerticalScrollIndicator={false}
contentContainerStyle={styles.contentContainer}
renderItem={({ item }) => (
<Pressable style={styles.itemContainer}>
<BlurView
intensity={30}
style={{
flex: 1,
backgroundColor: Palette.glass,
paddingHorizontal: 14,
...Style.containerCenter,
renderItem={({ item }) => {
const selectedItem = selected === item.title;
return (
<CreateLyricsHeader
colors={
selectedItem
? ["#FFFFFF00", "#FFFFFF"]
: [Palette.tran, Palette.tran]
}
tint={selectedItem ? "default" : "dark"}
onPress={() => onPressSelect(item.title)}
containerStyle={{
...styles.itemContainer,
}}
>
<Text style={styles.itemText}>{item}</Text>
</BlurView>
</Pressable>
)}
<View style={{ paddingVertical: 6 }}>
<Text
style={{
fontSize: 16,
color: Palette.white,
fontFamily: FONT_FAMILY.InterRegular,
}}
>
<Text style={{ fontFamily: FONT_FAMILY.InterBold }}>
{item.title}
</Text>{" "}
: {item.description}
</Text>
</View>
</CreateLyricsHeader>
);
}}
/>
</ItemContainer>
</View>
@@ -58,10 +86,7 @@ const styles = StyleSheet.create({
paddingBottom: 50,
},
itemContainer: {
height: 54,
backgroundColor: Palette.glass,
borderRadius: 14,
overflow: "hidden",
shadowColor: "#00000040",
shadowOffset: {
width: 0,
@@ -14,12 +14,14 @@ const CreateLyricsHeader = ({
gradientProps,
intensity = 40,
tint = "dark",
containerStyle = {},
onPress,
}) => {
const [onLayout, setOnLayout] = useState(null);
const { isWeb } = useLayoutType();
return (
<View>
<Pressable onPress={onPress}>
<BorderGradient
gradientProps={{
colors: colors,
@@ -33,21 +35,21 @@ const CreateLyricsHeader = ({
top: isWeb ? -1 : 0,
right: isWeb ? -1 : 0,
borderWidth: 1,
borderRadius: 18,
borderRadius: containerStyle?.borderRadius ?? 18,
position: "absolute",
width: "100%",
}}
/>
<Pressable
<View
style={{
backgroundColor: Palette.glass,
borderRadius: 18,
overflow: "hidden",
...containerStyle,
}}
onLayout={(event) => {
setOnLayout(event.nativeEvent.layout);
}}
onPress={() => console.log("PRESSED")}
>
<BlurView
intensity={intensity}
@@ -82,8 +84,8 @@ const CreateLyricsHeader = ({
)}
{children}
</BlurView>
</Pressable>
</View>
</View>
</Pressable>
);
};