This commit is contained in:
Philip Cesar Garay
2025-08-11 21:10:08 +08:00
parent 7bcc2e9779
commit 643e8054ac
27 changed files with 912 additions and 23 deletions
+3
View File
@@ -58,6 +58,9 @@ const App = () => {
InterSemiBold: Inter_600SemiBold,
InterBold: Inter_700Bold,
InterRegularItalic: Inter_400Regular_Italic,
HelveticaNeueRegular: require("./src/assets/fonts/HelveticaNeueRegular.ttf"),
HelveticaNeueMedium: require("./src/assets/fonts/HelveticaNeueMedium.ttf"),
HelveticaNeueBold: require("./src/assets/fonts/HelveticaNeueBold.ttf"),
});
useEffect(() => {
+1
View File
@@ -1,6 +1,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
+9 -1
View File
@@ -97,7 +97,15 @@
"iCloudContainerEnvironment": "Production"
}
],
"expo-font"
"expo-font",
[
"expo-camera",
{
"cameraPermission": "Allow $(PRODUCT_NAME) to access your camera",
"microphonePermission": "Allow $(PRODUCT_NAME) to access your microphone",
"recordAudioAndroid": true
}
]
],
"extra": {
"eas": {
@@ -29,6 +29,7 @@
</constraints>
<color key="backgroundColor" name="SplashScreenBackground"/>
<color key="backgroundColor" name="SplashScreenBackground"/>
<color key="backgroundColor" name="SplashScreenBackground"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="EXPO-PLACEHOLDER-1" userLabel="First Responder" sceneMemberID="firstResponder"/>
@@ -44,5 +45,8 @@
<namedColor name="SplashScreenBackground">
<color alpha="1.000" blue="0.0784313725490196" green="0.0470588235294118" red="0.0588235294117647" customColorSpace="sRGB" colorSpace="custom"/>
</namedColor>
<namedColor name="SplashScreenBackground">
<color alpha="1.000" blue="0.0784313725490196" green="0.0470588235294118" red="0.0588235294117647" customColorSpace="sRGB" colorSpace="custom"/>
</namedColor>
</resources>
</document>
+1
View File
@@ -42,6 +42,7 @@
"expo-av": "~15.0.1",
"expo-blur": "~14.0.1",
"expo-build-properties": "~0.13.1",
"expo-camera": "~16.0.18",
"expo-constants": "~17.0.3",
"expo-dev-client": "~5.0.5",
"expo-document-picker": "~13.0.1",
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.
Binary file not shown.
Binary file not shown.
+2
View File
@@ -194,8 +194,10 @@ export const ai = {
import placeholder from "./UI/placeholder.jpg";
import placeholder2 from "./UI/placeholder2.jpg";
import placeholder3 from "./UI/placeholder3.png";
export const img = {
placeholder,
placeholder2,
placeholder3,
};
+50
View File
@@ -32,6 +32,16 @@ import AddPhotoCover from "../screens/Studio/AddPhotoCover";
import FinishCompose from "../screens/Studio/FinishCompose";
import Production from "../screens/Production/Production";
import ProductionOnboarding from "../screens/Production/ProductionOnboarding";
import DownloadSongs from "../screens/Production/DownloadSongs";
import DownloadPrices from "../screens/Production/DownloadPrices";
import SongDownloaded from "../screens/Production/SongDownloaded";
import StreamSong from "../screens/Production/StreamSong";
import SongRelease from "../screens/Production/SongRelease";
import PlaybackExample from "../screens/Production/PlaybackExample";
import PlaybackOnboarding from "../screens/Playback/PlaybackOnboarding";
import Playback from "../screens/Playback/Playback";
import RecordPlayback from "../screens/Playback/RecordPlayback";
import RecordedPlayback from "../screens/Playback/RecordedPlayback";
const screenOptions = {
headerShown: false,
@@ -143,6 +153,46 @@ const screens = [
name: Routes.Production,
component: Production,
},
{
name: Routes.DownloadSongs,
component: DownloadSongs,
},
{
name: Routes.DownloadPrices,
component: DownloadPrices,
},
{
name: Routes.SongDownloaded,
component: SongDownloaded,
},
{
name: Routes.StreamSong,
component: StreamSong,
},
{
name: Routes.SongRelease,
component: SongRelease,
},
{
name: Routes.PlaybackExample,
component: PlaybackExample,
},
{
name: Routes.PlaybackOnboarding,
component: PlaybackOnboarding,
},
{
name: Routes.Playback,
component: Playback,
},
{
name: Routes.RecordPlayback,
component: RecordPlayback,
},
{
name: Routes.RecordedPlayback,
component: RecordedPlayback,
},
];
export default function Main() {
+11
View File
@@ -42,4 +42,15 @@ export const Routes = {
ProductionOnboarding: "ProductionOnboarding",
Production: "Production",
DownloadSongs: "DownloadSongs",
DownloadPrices: "DownloadPrices",
SongDownloaded: "SongDownloaded",
StreamSong: "StreamSong",
SongRelease: "SongRelease",
PlaybackExample: "PlaybackExample",
PlaybackOnboarding: "PlaybackOnboarding",
Playback: "Playback",
RecordPlayback: "RecordPlayback",
RecordedPlayback: "RecordedPlayback",
};
+46
View File
@@ -0,0 +1,46 @@
import { View, Text, StyleSheet, Image } from "react-native";
import React from "react";
import { ai, background } from "../../assets";
import MusicLandHeader from "../../components/MusicLandHeader";
import { goBack, navigate } from "../../navigation/NavigationService";
import { gutters } from "../../styles";
import Page from "../../layouts/Page";
import BorderGradientButton from "../../components/BorderGradientButton";
import GradientButton from "../../components/GradientButton";
import { Routes } from "../../navigation";
const Playback = () => {
return (
<Page headerType="NONE" backgroundImg={background.playbackBG2}>
<Image source={ai.john} style={styles.img} resizeMode="contain" />
<MusicLandHeader onPressBack={goBack} progress={25} />
<View
style={{
flex: 1,
paddingBottom: gutters * 2,
justifyContent: "flex-end",
}}
>
<View style={{ width: "80%", alignSelf: "center", gap: 12 }}>
<BorderGradientButton title="Guide du Playbacker" />
<BorderGradientButton title="Importer une vidéo" />
<GradientButton
title="Enregistrer mon Playback"
onPress={() => navigate(Routes.RecordPlayback)}
/>
</View>
</View>
</Page>
);
};
export default Playback;
const styles = StyleSheet.create({
img: {
width: "100%",
height: "70%",
position: "absolute",
bottom: -40,
},
});
@@ -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 PlaybackOnboarding = () => {
return (
<Page backgroundImg={background.playbackBG} headerType="NONE">
<View
style={{
flex: 1,
paddingBottom: gutters * 2,
justifyContent: "flex-end",
}}
>
<GradientButton
title="Commence"
onPress={() => navigate(Routes.Playback)}
/>
</View>
</Page>
);
};
export default PlaybackOnboarding;
+56
View File
@@ -0,0 +1,56 @@
import { Text, View } from "react-native";
import React from "react";
import { CameraView } from "expo-camera";
import { gutters, Palette } from "../../styles";
import MusicLandHeader from "../../components/MusicLandHeader";
import { goBack, navigate } from "../../navigation/NavigationService";
import { useSafeAreaInsets } from "react-native-safe-area-context";
import CreateLyricsHeader from "../Writing/components/CreateLyricsHeader";
import { FONT_FAMILY } from "../../styles/Fonts";
import GradientButton from "../../components/GradientButton";
import { Routes } from "../../navigation";
const RecordPlayback = () => {
const { top } = useSafeAreaInsets();
return (
<View style={{ flex: 1 }}>
<CameraView style={{ flex: 1 }} facing="front">
<View
style={{
paddingHorizontal: gutters,
paddingTop: top,
flex: 1,
paddingBottom: gutters * 2,
}}
>
<MusicLandHeader progress={9} onPressBack={goBack} />
<View style={{ flex: 1, marginTop: 11 }}>
<CreateLyricsHeader>
<Text
style={{
fontSize: 16,
color: Palette.white,
fontFamily: FONT_FAMILY.InterMedium,
}}
>
L'enregistrement de ta vidéo commencera lorsque tu lanceras ta
musique, et s'arrêtera à la fin du morceau.
</Text>
</CreateLyricsHeader>
</View>
<GradientButton
title="Lancer ma musique"
containerStyle={{
width: "80%",
alignSelf: "center",
}}
onPress={() => navigate(Routes.RecordedPlayback)}
/>
</View>
</CameraView>
</View>
);
};
export default RecordPlayback;
+48
View File
@@ -0,0 +1,48 @@
import { View, Text, Image } from "react-native";
import React from "react";
import Page from "../../layouts/Page";
import { background, img } from "../../assets";
import MusicLandHeader from "../../components/MusicLandHeader";
import { goBack, navigate } from "../../navigation/NavigationService";
import { gutters } from "../../styles";
import Slider from "../../components/Slider";
import GradientButton from "../../components/GradientButton";
import { Routes } from "../../navigation";
import BorderGradientButton from "../../components/BorderGradientButton";
const RecordedPlayback = () => {
return (
<Page backgroundImg={background.playbackBG2} headerType="NONE">
<MusicLandHeader progress={19} onPressBack={goBack} />
<View
style={{ flex: 1, paddingTop: 12, gap: 14, paddingBottom: gutters * 2 }}
>
<View style={{ flex: 1, gap: 22 }}>
<Image
source={img.placeholder3}
style={{
width: "80%",
flex: 1,
alignSelf: "center",
borderRadius: 16,
}}
/>
<Slider value="0:00" maxValue="2:00" />
</View>
<View
style={{ width: "80%", alignSelf: "center", marginTop: 4, gap: 12 }}
>
<GradientButton
title="Je veux devenir Playbacker"
containerStyle={{}}
onPress={() => navigate(Routes.PlaybackOnboarding)}
/>
<BorderGradientButton title="Je change de décor" />
<BorderGradientButton title="Recommencer" />
</View>
</View>
</Page>
);
};
export default RecordedPlayback;
+146
View File
@@ -0,0 +1,146 @@
import { View, Text, Image } from "react-native";
import React, { useState } from "react";
import Page from "../../layouts/Page";
import { background, img } from "../../assets";
import MusicLandHeader from "../../components/MusicLandHeader";
import { goBack, navigate } from "../../navigation/NavigationService";
import { responsiveHeight } from "react-native-responsive-dimensions";
import CreateLyricsHeader from "../Writing/components/CreateLyricsHeader";
import Style, { size } from "../../styles/Style";
import { Palette } from "../../styles";
import { FONT_FAMILY } from "../../styles/Fonts";
import { Routes } from "../../navigation";
const PRICES = [
{
title: "Je télécharge ma chanson",
description: "Ce morceau uniquement",
price: "6,99€",
},
{
title: "3 chansons",
description: "Ce morceau et les 2 prochains que tu crées",
price: "12,99€",
},
{
title: "5 chansons",
description: "Ce morceau et les 4 prochains que tu crées",
price: "19,99€",
recommended: true,
},
];
const DownloadPrices = () => {
const [selectedIndex, setSelectedIndex] = useState(null);
return (
<Page backgroundImg={background.productionBG2} headerType="NONE">
<MusicLandHeader onPressBack={goBack} progress={75} />
<View style={{ flex: 1, paddingTop: responsiveHeight(10) }}>
<CreateLyricsHeader
gradientProps={{
start: { x: 0, y: 0 },
end: { x: 0, y: 1 },
}}
>
<Image
source={img.placeholder2}
style={{
...size({ size: 158 }),
borderRadius: 13,
alignSelf: "center",
}}
/>
<View style={{ gap: 12, marginTop: 10 }}>
<Text
style={{
fontSize: 22,
color: Palette.white,
fontFamily: FONT_FAMILY.InterSemiBold,
textAlign: "center",
}}
>
Tarifs
</Text>
<View style={{ gap: 10 }}>
{PRICES.map((item, index) => (
<CreateLyricsHeader
key={index}
colors={
selectedIndex === index
? ["#F94697", "#7023F7"]
: [Palette.tran, Palette.tran]
}
tint={!item.recommended ? "dark" : "light"}
onPress={() => {
setSelectedIndex(index);
navigate(Routes.SongDownloaded);
}}
>
<View style={{ paddingTop: 5 }}>
<Text
style={{
fontSize: 16,
color: Palette.white,
fontFamily: FONT_FAMILY.HelveticaNeueBold,
}}
>
{item.title}
</Text>
<Text
style={{
fontSize: 12,
color: Palette.white,
fontFamily: FONT_FAMILY.InterRegular,
}}
>
{item.description}
</Text>
</View>
<View style={{ alignSelf: "flex-end", marginTop: 14 }}>
<Text
style={{
fontSize: 12,
color: Palette.white,
fontFamily: FONT_FAMILY.InterRegular,
}}
>
{item.price}
</Text>
</View>
{item.recommended && (
<View
style={{
paddingHorizontal: 10,
height: 26,
...Style.containerCenter,
borderRadius: 100,
position: "absolute",
backgroundColor: "#FFFFFF33",
bottom: 8,
left: 10,
}}
>
<Text
style={{
fontSize: 14,
color: Palette.white,
fontFamily: FONT_FAMILY.HelveticaNeueRegular,
bottom: -1,
}}
>
Recommandé
</Text>
</View>
)}
</CreateLyricsHeader>
))}
</View>
</View>
</CreateLyricsHeader>
</View>
</Page>
);
};
export default DownloadPrices;
+98 -4
View File
@@ -1,12 +1,106 @@
import { View, Text } from "react-native";
import { View, Text, StyleSheet, Image, Pressable } from "react-native";
import React from "react";
import Page from "../../layouts/Page";
import { background, img } from "../../assets";
import MusicLandHeader from "../../components/MusicLandHeader";
import { goBack, navigate } from "../../navigation/NavigationService";
import { Palette } from "../../styles";
import { FONT_FAMILY } from "../../styles/Fonts";
import CreateLyricsHeader from "../Writing/components/CreateLyricsHeader";
import { size } from "../../styles/Style";
import { BlurView } from "expo-blur";
import { responsiveHeight } from "react-native-responsive-dimensions";
import { Routes } from "../../navigation";
const DownloadSongs = () => {
return (
<View>
<Text>DownloadSongs</Text>
</View>
<Page backgroundImg={background.productionBG2} headerType="NONE">
<MusicLandHeader onPressBack={goBack} progress={50} />
<View style={{ flex: 1, paddingTop: responsiveHeight(15) }}>
<CreateLyricsHeader
gradientProps={{
start: { x: 0, y: 0 },
end: { x: 0, y: 1 },
}}
>
<Image
source={img.placeholder2}
style={{
...size({ size: 158 }),
borderRadius: 13,
alignSelf: "center",
}}
/>
<View style={{ gap: 12, paddingVertical: 12 }}>
<Text style={styles.title}>Prêt à télécharger ta chanson ?</Text>
<View style={{ gap: 10 }}>
<Pressable
style={styles.itemContainer}
onPress={() => navigate(Routes.DownloadPrices)}
>
<BlurView style={styles.blurView} intensity={40} tint="dark">
<Text style={styles.label}>Télécharger ma chanson</Text>
<Text style={styles.description}>Pour moi uniquement</Text>
</BlurView>
</Pressable>
<Pressable
style={styles.itemContainer}
onPress={() => navigate(Routes.StreamSong)}
>
<BlurView style={styles.blurView} intensity={40} tint="dark">
<Text style={styles.label}>
Diffuser ma chanson sur la plateforme de MusicLand (+
réseaux sociaux) et participer au concours
</Text>
<Text style={styles.description}>
Top 3: 1er 15% du CA ML - 2ème 10% du CA ML - 3ème 5% du CA
ML (catégorie chanson)
</Text>
</BlurView>
</Pressable>
</View>
</View>
</CreateLyricsHeader>
</View>
</Page>
);
};
export default DownloadSongs;
const styles = StyleSheet.create({
title: {
fontSize: 22,
color: Palette.white,
fontFamily: FONT_FAMILY.InterSemiBold,
},
label: {
fontSize: 16,
color: Palette.white,
fontFamily: FONT_FAMILY.HelveticaNeueBold,
},
description: {
fontSize: 12,
color: Palette.white,
fontFamily: FONT_FAMILY.InterRegular,
},
blurView: {
paddingHorizontal: 10,
paddingBottom: 8,
paddingTop: 10,
},
itemContainer: {
borderRadius: 12,
overflow: "hidden",
backgroundColor: "#FFFFFF03",
shadowColor: "#0000001A",
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.25,
shadowRadius: 3.84,
elevation: 5,
},
});
+47
View File
@@ -0,0 +1,47 @@
import { View, Text, Image } from "react-native";
import React from "react";
import Page from "../../layouts/Page";
import { background, img } from "../../assets";
import MusicLandHeader from "../../components/MusicLandHeader";
import { goBack, navigate } from "../../navigation/NavigationService";
import CreateLyricsHeader from "../Writing/components/CreateLyricsHeader";
import Slider from "../../components/Slider";
import { gutters } from "../../styles";
import GradientButton from "../../components/GradientButton";
import { Routes } from "../../navigation";
const PlaybackExample = () => {
return (
<Page backgroundImg={background.productionBG} headerType="NONE">
<MusicLandHeader progress={50} onPressBack={goBack} />
<View
style={{ flex: 1, paddingTop: 12, gap: 14, paddingBottom: gutters * 2 }}
>
<CreateLyricsHeader title="Exemple" subTitle="Exemple de Playback" />
<View style={{ flex: 1, gap: 22 }}>
<Image
source={img.placeholder3}
style={{
width: "80%",
flex: 1,
alignSelf: "center",
borderRadius: 16,
}}
/>
<Slider value="0:00" maxValue="2:00" />
</View>
<GradientButton
title="Je veux devenir Playbacker"
containerStyle={{
width: "80%",
alignSelf: "center",
marginTop: 4,
}}
onPress={() => navigate(Routes.PlaybackOnboarding)}
/>
</View>
</Page>
);
};
export default PlaybackExample;
+24 -6
View File
@@ -1,17 +1,19 @@
import { View } from "react-native";
import { Image, StyleSheet, View } from "react-native";
import React from "react";
import Page from "../../layouts/Page";
import { background } from "../../assets";
import { ai, background } from "../../assets";
import { gutters } from "../../styles";
import GradientButton from "../../components/GradientButton";
import MusicLandHeader from "../../components/MusicLandHeader";
import { goBack } from "../../navigation/NavigationService";
import { goBack, navigate } from "../../navigation/NavigationService";
import BorderGradientButton from "../../components/BorderGradientButton";
import { Routes } from "../../navigation";
const Production = () => {
return (
<Page headerType="NONE" backgroundImg={background.productionBG}>
<MusicLandHeader onPressBack={goBack} progress={9} />
<Image source={ai.bena} style={styles.img} resizeMode="contain" />
<MusicLandHeader onPressBack={goBack} progress={25} />
<View
style={{
flex: 1,
@@ -20,10 +22,16 @@ const Production = () => {
gap: 37,
}}
>
<BorderGradientButton title="Je télécharge ma chanson" />
<BorderGradientButton
title="Je télécharge ma chanson"
onPress={() => navigate(Routes.DownloadSongs)}
/>
<View style={{ gap: 12 }}>
<GradientButton title="Je veux devenir Playbacker" />
<BorderGradientButton title="Voir exemples" />
<BorderGradientButton
title="Voir exemples"
onPress={() => navigate(Routes.PlaybackExample)}
/>
</View>
<View style={{ gap: 12 }}>
<GradientButton title="Je veux créer un Clip" />
@@ -35,3 +43,13 @@ const Production = () => {
};
export default Production;
const styles = StyleSheet.create({
img: {
width: "100%",
height: "70%",
position: "absolute",
bottom: -40,
right: -30,
},
});
+81
View File
@@ -0,0 +1,81 @@
import { View, Text, Image } from "react-native";
import React from "react";
import Page from "../../layouts/Page";
import { background, img } from "../../assets";
import { goBack, navigate } from "../../navigation/NavigationService";
import MusicLandHeader from "../../components/MusicLandHeader";
import CreateLyricsHeader from "../Writing/components/CreateLyricsHeader";
import { size } from "../../styles/Style";
import BorderGradientButton from "../../components/BorderGradientButton";
import GradientButton from "../../components/GradientButton";
import { responsiveHeight } from "react-native-responsive-dimensions";
import { Palette } from "../../styles";
import { FONT_FAMILY } from "../../styles/Fonts";
import { Routes } from "../../navigation";
const SongDownloaded = () => {
return (
<Page backgroundImg={background.productionBG2} headerType="NONE">
<MusicLandHeader onPressBack={goBack} progress={100} />
<View style={{ flex: 1, paddingTop: responsiveHeight(15) }}>
<CreateLyricsHeader
gradientProps={{
start: { x: 0, y: 0 },
end: { x: 0, y: 1 },
}}
>
<Image
source={img.placeholder2}
style={{
...size({ size: 158 }),
borderRadius: 13,
alignSelf: "center",
}}
/>
<View style={{ gap: 2, marginTop: 12 }}>
<Text
style={{
fontSize: 22,
color: Palette.white,
fontFamily: FONT_FAMILY.InterSemiBold,
textAlign: "center",
}}
>
Chanson téléchargée !
</Text>
<Text
style={{
fontSize: 16,
color: Palette.white,
fontFamily: FONT_FAMILY.InterMedium,
}}
>
Ta chanson est désormais téléchargée dans tes fichiers. Nhésite
pas à la partager avec tes proches.
</Text>
</View>
<View
style={{
marginTop: 26,
gap: 12,
paddingBottom: 12,
width: "80%",
alignSelf: "center",
}}
>
<BorderGradientButton
title="Partager"
onPress={() => navigate(Routes.Production)}
/>
<GradientButton
title="Page d'accueil"
onPress={() => navigate(Routes.Production)}
/>
</View>
</CreateLyricsHeader>
</View>
</Page>
);
};
export default SongDownloaded;
+82
View File
@@ -0,0 +1,82 @@
import { View, Text, Image } from "react-native";
import React from "react";
import MusicLandHeader from "../../components/MusicLandHeader";
import Page from "../../layouts/Page";
import { background, img } from "../../assets";
import { goBack, navigate } from "../../navigation/NavigationService";
import { responsiveHeight } from "react-native-responsive-dimensions";
import CreateLyricsHeader from "../Writing/components/CreateLyricsHeader";
import { size } from "../../styles/Style";
import { Palette } from "../../styles";
import { FONT_FAMILY } from "../../styles/Fonts";
import BorderGradientButton from "../../components/BorderGradientButton";
import GradientButton from "../../components/GradientButton";
import { Routes } from "../../navigation";
const SongRelease = () => {
return (
<Page backgroundImg={background.productionBG2} headerType="NONE">
<MusicLandHeader onPressBack={goBack} progress={100} />
<View style={{ flex: 1, paddingTop: responsiveHeight(15) }}>
<CreateLyricsHeader
gradientProps={{
start: { x: 0, y: 0 },
end: { x: 0, y: 1 },
}}
>
<Image
source={img.placeholder2}
style={{
...size({ size: 158 }),
borderRadius: 13,
alignSelf: "center",
}}
/>
<View style={{ gap: 2, marginTop: 12 }}>
<Text
style={{
fontSize: 22,
color: Palette.white,
fontFamily: FONT_FAMILY.InterSemiBold,
textAlign: "center",
}}
>
Chanson publiée!
</Text>
<Text
style={{
fontSize: 16,
color: Palette.white,
fontFamily: FONT_FAMILY.InterMedium,
}}
>
Ta chanson est désormais accessible sur lapplication et les
réseaux sociaux de MusicLand. Nhésite pas à la partager avec tes
proches.
</Text>
</View>
<View
style={{
marginTop: 26,
gap: 12,
paddingBottom: 12,
width: "80%",
alignSelf: "center",
}}
>
<BorderGradientButton
title="Partager"
onPress={() => navigate(Routes.Production)}
/>
<GradientButton
title="Page d'accueil"
onPress={() => navigate(Routes.Production)}
/>
</View>
</CreateLyricsHeader>
</View>
</Page>
);
};
export default SongRelease;
+162
View File
@@ -0,0 +1,162 @@
import { View, Text, Image } from "react-native";
import React, { useState } from "react";
import Page from "../../layouts/Page";
import MusicLandHeader from "../../components/MusicLandHeader";
import { background, img } from "../../assets";
import { goBack, navigate } from "../../navigation/NavigationService";
import CreateLyricsHeader from "../Writing/components/CreateLyricsHeader";
import { responsiveHeight } from "react-native-responsive-dimensions";
import Style, { size } from "../../styles/Style";
import { Palette } from "../../styles";
import { FONT_FAMILY } from "../../styles/Fonts";
import { Routes } from "../../navigation";
const STREAM_PRICES = [
{
title: "Je diffuse ma chanson",
description: "Ce morceau uniquement",
price: "1,99€ / mois",
},
{
title: "Je diffuse 3 chansons",
description: "Ce morceau et les 2 prochains que tu crées",
price: "3,99€ / mois",
},
{
title: "Illimité",
price: "14,99€ / mois",
recommended: true,
},
];
const StreamSong = () => {
const [selectedIndex, setSelectedIndex] = useState(null);
return (
<Page backgroundImg={background.productionBG2} headerType="NONE">
<MusicLandHeader onPressBack={goBack} progress={75} />
<View style={{ flex: 1, paddingTop: responsiveHeight(5) }}>
<CreateLyricsHeader
gradientProps={{
start: { x: 0, y: 0 },
end: { x: 0, y: 1 },
}}
>
<Image
source={img.placeholder2}
style={{
...size({ size: 158 }),
borderRadius: 13,
alignSelf: "center",
}}
/>
<View style={{ gap: 12 }}>
<View style={{ gap: 2, marginTop: 12 }}>
<Text
style={{
fontSize: 22,
color: Palette.white,
fontFamily: FONT_FAMILY.InterSemiBold,
textAlign: "center",
}}
>
Diffuser ta chanson{"\n"}
Tarifs
</Text>
<Text
style={{
fontSize: 16,
color: Palette.white,
fontFamily: FONT_FAMILY.InterMedium,
textAlign: "center",
}}
>
Si tu désires diffuser ta chanson ou tes chansons sur la
plateforme de MusicLand et participer au concours et être dans
le top 3 voici le tarif.
</Text>
</View>
<View style={{ gap: 10 }}>
{STREAM_PRICES.map((item, index) => (
<CreateLyricsHeader
key={index}
colors={
selectedIndex === index
? ["#F94697", "#7023F7"]
: [Palette.tran, Palette.tran]
}
tint={!item.recommended ? "dark" : "light"}
onPress={() => {
setSelectedIndex(index);
navigate(Routes.SongRelease);
}}
>
<View style={{ paddingTop: 5 }}>
<Text
style={{
fontSize: 16,
color: Palette.white,
fontFamily: FONT_FAMILY.HelveticaNeueBold,
}}
>
{item.title}
</Text>
{item.description && (
<Text
style={{
fontSize: 12,
color: Palette.white,
fontFamily: FONT_FAMILY.InterRegular,
}}
>
{item.description}
</Text>
)}
</View>
<View style={{ alignSelf: "flex-end", marginTop: 5 }}>
<Text
style={{
fontSize: 12,
color: Palette.white,
fontFamily: FONT_FAMILY.InterRegular,
}}
>
{item.price}
</Text>
</View>
{item.recommended && (
<View
style={{
paddingHorizontal: 10,
height: 26,
...Style.containerCenter,
borderRadius: 100,
position: "absolute",
backgroundColor: "#FFFFFF33",
bottom: 8,
left: 10,
}}
>
<Text
style={{
fontSize: 14,
color: Palette.white,
fontFamily: FONT_FAMILY.HelveticaNeueRegular,
bottom: -1,
}}
>
Recommandé
</Text>
</View>
)}
</CreateLyricsHeader>
))}
</View>
</View>
</CreateLyricsHeader>
</View>
</Page>
);
};
export default StreamSong;
-10
View File
@@ -113,13 +113,3 @@ const ComposeSong = () => {
};
export default ComposeSong;
const styles = StyleSheet.create({
img: {
width: "100%",
height: "70%",
position: "absolute",
bottom: -40,
right: -30,
},
});
@@ -28,7 +28,7 @@ const CreateLyricsHeader = ({
locations: [0.2, 1],
start: { x: 0, y: 0 },
end: { x: 1, y: 0 },
...{ gradientProps },
...gradientProps,
}}
style={{
height: isWeb ? onLayout?.height + 2 : onLayout?.height,
+3
View File
@@ -36,6 +36,9 @@ export const FONT_FAMILY = {
InterSemiBold: "InterSemiBold",
InterBold: "InterBold",
InterRegularItalic: "InterRegularItalic",
HelveticaNeueRegular: "HelveticaNeueRegular",
HelveticaNeueMedium: "HelveticaNeueMedium",
HelveticaNeueBold: "HelveticaNeueBold",
};
const Fonts = ({
+7
View File
@@ -4180,6 +4180,13 @@ expo-build-properties@~0.13.1:
ajv "^8.11.0"
semver "^7.6.0"
expo-camera@~16.0.18:
version "16.0.18"
resolved "https://registry.yarnpkg.com/expo-camera/-/expo-camera-16.0.18.tgz#5b54dc1a929c12732c585b137b04cef2b01dee3b"
integrity sha512-NP5u2yyc+wZc9GdUXH+jcEytyXZwBnHxItMwXoZQQxi4wgltwvs4XfSWjBtRZe1LngnhpBfPyPJV0aShjWlLDg==
dependencies:
invariant "^2.2.4"
expo-constants@~17.0.0, expo-constants@~17.0.3:
version "17.0.3"
resolved "https://registry.yarnpkg.com/expo-constants/-/expo-constants-17.0.3.tgz#a05b38e0417d59759ece1642b4d483889e04dbda"