update
@@ -61,6 +61,9 @@ const App = () => {
|
||||
HelveticaNeueRegular: require("./src/assets/fonts/HelveticaNeueRegular.ttf"),
|
||||
HelveticaNeueMedium: require("./src/assets/fonts/HelveticaNeueMedium.ttf"),
|
||||
HelveticaNeueBold: require("./src/assets/fonts/HelveticaNeueBold.ttf"),
|
||||
OwnersRegular: require("./src/assets/fonts/OwnersRegular.ttf"),
|
||||
OwnersMedium: require("./src/assets/fonts/OwnersMedium.ttf"),
|
||||
OwnersBold: require("./src/assets/fonts/OwnersBold.ttf"),
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
@@ -76,7 +76,7 @@
|
||||
"react-native-linear-gradient": "^2.8.3",
|
||||
"react-native-minuit": "^1.3.52",
|
||||
"react-native-reanimated": "~3.16.1",
|
||||
"react-native-reanimated-carousel": "^4.0.0-alpha.8",
|
||||
"react-native-reanimated-carousel": "^4.0.3",
|
||||
"react-native-responsive-dimensions": "^3.1.1",
|
||||
"react-native-safe-area-context": "4.12.0",
|
||||
"react-native-store-review": "^0.3.0",
|
||||
|
||||
|
After Width: | Height: | Size: 558 KiB |
|
Before Width: | Height: | Size: 783 B After Width: | Height: | Size: 329 B |
|
After Width: | Height: | Size: 231 B |
|
After Width: | Height: | Size: 290 B |
|
After Width: | Height: | Size: 532 B |
|
After Width: | Height: | Size: 600 B |
|
After Width: | Height: | Size: 892 B |
|
After Width: | Height: | Size: 796 B |
|
After Width: | Height: | Size: 336 B |
|
After Width: | Height: | Size: 160 B |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 6.3 KiB |
@@ -4,6 +4,11 @@ import chat from "./UI/tabs/chat.png";
|
||||
import design from "./UI/tabs/design.png";
|
||||
import quotes from "./UI/tabs/quotes.png";
|
||||
import settings from "./UI/tabs/settings.png";
|
||||
import addTab from "./UI/tabs/add.png";
|
||||
import albums from "./UI/tabs/albums.png";
|
||||
import ribbon from "./UI/tabs/ribbon.png";
|
||||
import mic from "./UI/tabs/mic.png";
|
||||
import person from "./UI/tabs/person.png";
|
||||
|
||||
export const tabs = {
|
||||
home,
|
||||
@@ -12,6 +17,11 @@ export const tabs = {
|
||||
quotes,
|
||||
chat,
|
||||
design,
|
||||
addTab,
|
||||
albums,
|
||||
ribbon,
|
||||
mic,
|
||||
person,
|
||||
};
|
||||
|
||||
import bell from "./UI/bell.png";
|
||||
@@ -66,6 +76,9 @@ import disk from "./icons/disk.png";
|
||||
import stars from "./icons/stars.png";
|
||||
import musicLandLogo from "./icons/musicLandLogo.png";
|
||||
import close from "./icons/close.png";
|
||||
import heart from "./icons/heart.png";
|
||||
import heartOutline from "./icons/heartOutline.png";
|
||||
import more from "./icons/more.png";
|
||||
|
||||
export const icons = {
|
||||
bell,
|
||||
@@ -119,6 +132,9 @@ export const icons = {
|
||||
stars,
|
||||
musicLandLogo,
|
||||
close,
|
||||
heart,
|
||||
heartOutline,
|
||||
more,
|
||||
};
|
||||
|
||||
import triangle from "./art/triangle.png";
|
||||
@@ -169,6 +185,7 @@ import productionBG from "./UI/productionBG.png";
|
||||
import productionBG2 from "./UI/productionBG2.png";
|
||||
import playbackBG from "./UI/playbackBG.png";
|
||||
import playbackBG2 from "./UI/playbackBG2.png";
|
||||
import libraryBG from "./UI/libraryBG.png";
|
||||
|
||||
export const background = {
|
||||
writingBG,
|
||||
@@ -178,6 +195,7 @@ export const background = {
|
||||
productionBG2,
|
||||
playbackBG,
|
||||
playbackBG2,
|
||||
libraryBG,
|
||||
};
|
||||
|
||||
import nathalie from "./UI/nathalie.png";
|
||||
|
||||
@@ -4,17 +4,24 @@ import BorderGradient from "../BorderGradient/BorderGradient";
|
||||
import { BlurView } from "expo-blur";
|
||||
import { responsiveHeight } from "react-native-responsive-dimensions";
|
||||
|
||||
const ItemContainer = ({ height = responsiveHeight(40), children }) => {
|
||||
const ItemContainer = ({
|
||||
height = responsiveHeight(40),
|
||||
children,
|
||||
gradientProps,
|
||||
style,
|
||||
}) => {
|
||||
return (
|
||||
<BorderGradient
|
||||
gradientProps={{
|
||||
colors: ["#FFFFFF00", "#FFFFFF"],
|
||||
start: { x: 0.3, y: 0 },
|
||||
end: { x: 1, y: 1 },
|
||||
...gradientProps,
|
||||
}}
|
||||
style={{
|
||||
...styles.borderGradientStyle,
|
||||
height,
|
||||
...style,
|
||||
}}
|
||||
>
|
||||
<View style={styles.blurContainer}>
|
||||
|
||||
@@ -5,7 +5,12 @@ import { responsiveHeight } from "react-native-responsive-dimensions";
|
||||
import { BlurView } from "expo-blur";
|
||||
import { Style } from "../../styles";
|
||||
|
||||
const ItemContainer = ({ height = responsiveHeight(40), children }) => {
|
||||
const ItemContainer = ({
|
||||
height = responsiveHeight(40),
|
||||
children,
|
||||
gradientProps,
|
||||
style,
|
||||
}) => {
|
||||
const [containerLayout, setContainerLayout] = useState(null);
|
||||
|
||||
return (
|
||||
@@ -20,10 +25,12 @@ const ItemContainer = ({ height = responsiveHeight(40), children }) => {
|
||||
start: { x: 0.3, y: 0 },
|
||||
end: { x: 1, y: 1 },
|
||||
locations: [0, 1],
|
||||
...gradientProps,
|
||||
}}
|
||||
style={{
|
||||
...styles.borderGradientStyle,
|
||||
height: containerLayout?.height,
|
||||
...style,
|
||||
}}
|
||||
/>
|
||||
<View
|
||||
|
||||
@@ -13,7 +13,10 @@ const MusicLandHeader = ({
|
||||
}) => {
|
||||
return (
|
||||
<View style={{ alignItems: "center", gap: 16 }}>
|
||||
<Image source={icons.musicLandLogo} />
|
||||
<Image
|
||||
source={icons.musicLandLogo}
|
||||
|
||||
/>
|
||||
<View style={{ width: "100%", ...Style.containerRow, gap: 16 }}>
|
||||
<Pressable
|
||||
style={{ width: 24, height: 24, ...Style.containerCenter }}
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
import { View, Text, TextInput, Image } from "react-native";
|
||||
import React from "react";
|
||||
import { BlurView } from "expo-blur";
|
||||
import { icons } from "../assets";
|
||||
import Style, { size } from "../styles/Style";
|
||||
import { Palette } from "../styles";
|
||||
import { FONT_FAMILY } from "../styles/Fonts";
|
||||
|
||||
const SearchBar = ({ placeholder = "Que souhaites-tu écouter?" }) => {
|
||||
return (
|
||||
<View style={{ borderRadius: 12, overflow: "hidden" }}>
|
||||
<BlurView
|
||||
intensity={10}
|
||||
style={{
|
||||
height: 40,
|
||||
paddingHorizontal: 8,
|
||||
gap: 10,
|
||||
...Style.containerRow,
|
||||
}}
|
||||
>
|
||||
<Image source={icons.search} />
|
||||
<TextInput
|
||||
placeholder={placeholder}
|
||||
placeholderTextColor={Palette.gray}
|
||||
style={{
|
||||
fontSize: 12,
|
||||
color: Palette.white,
|
||||
fontFamily: FONT_FAMILY.HelveticaNeueRegular,
|
||||
flex: 1,
|
||||
}}
|
||||
/>
|
||||
</BlurView>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
export default SearchBar;
|
||||
@@ -493,3 +493,12 @@ export const INSTRUMENTS = [
|
||||
];
|
||||
|
||||
export const RHYTHM = ["Très rapide", "Rapide", "Normal", "Lent", "Très lent"];
|
||||
|
||||
export const CHOOSE_DECOR = [
|
||||
"Plage",
|
||||
"Café",
|
||||
"Montagne",
|
||||
"Rue",
|
||||
"Jardin",
|
||||
"Neige",
|
||||
];
|
||||
|
||||
@@ -17,6 +17,7 @@ import TabBar from "./TabBar";
|
||||
import HomeStack from "./HomeStack";
|
||||
import ChatStack from "./ChatStack";
|
||||
import SettingsStack from "./SettingsStack";
|
||||
import Library from "../screens/Library/Library.js";
|
||||
|
||||
const bottomTabStyles = StyleSheet.create({
|
||||
icon: {
|
||||
@@ -33,13 +34,13 @@ export const BottomTabScreen = () => {
|
||||
<Motion.Image
|
||||
resizeMode={"contain"}
|
||||
animate={{
|
||||
tintColor: focused ? Palette.primary : Palette.white,
|
||||
tintColor: focused ? Palette.white : "#8B8883",
|
||||
}}
|
||||
style={[
|
||||
bottomTabStyles.icon,
|
||||
{
|
||||
width: "55%",
|
||||
height: "55%",
|
||||
width: 24,
|
||||
height: 24,
|
||||
},
|
||||
]}
|
||||
source={icon}
|
||||
@@ -49,30 +50,53 @@ export const BottomTabScreen = () => {
|
||||
return (
|
||||
<BottomTab.Navigator tabBar={(props) => <TabBar {...props} />}>
|
||||
<BottomTab.Screen
|
||||
name={Routes.HomeStack}
|
||||
name={Routes.Create}
|
||||
component={HomeStack}
|
||||
options={{
|
||||
tabBarLabel: "Créer",
|
||||
headerShown: false,
|
||||
tabBarShowLabel: true,
|
||||
tabBarIcon: ({ focused }) => renderIcon(tabs.home, focused),
|
||||
tabBarIcon: ({ focused }) => renderIcon(tabs.addTab, focused),
|
||||
}}
|
||||
/>
|
||||
<BottomTab.Screen
|
||||
name={Routes.ChatStack}
|
||||
name={Routes.HitParade}
|
||||
component={ChatStack}
|
||||
options={{
|
||||
tabBarLabel: "Hit Parade",
|
||||
headerShown: false,
|
||||
tabBarShowLabel: true,
|
||||
tabBarIcon: ({ focused }) => renderIcon(tabs.chat, focused),
|
||||
tabBarIcon: ({ focused }) => renderIcon(tabs.ribbon, focused),
|
||||
}}
|
||||
/>
|
||||
<BottomTab.Screen
|
||||
name={Routes.SettingsStack}
|
||||
name={Routes.Playbacks}
|
||||
component={SettingsStack}
|
||||
options={{
|
||||
tabBarLabel: "Playbacks",
|
||||
headerShown: false,
|
||||
tabBarShowLabel: true,
|
||||
tabBarIcon: ({ focused }) => renderIcon(tabs.settings, focused),
|
||||
tabBarIcon: ({ focused }) => renderIcon(tabs.mic, focused),
|
||||
}}
|
||||
/>
|
||||
<BottomTab.Screen
|
||||
name={Routes.Library}
|
||||
component={Library}
|
||||
options={{
|
||||
tabBarLabel: "Librairie",
|
||||
headerShown: false,
|
||||
tabBarShowLabel: true,
|
||||
tabBarIcon: ({ focused }) => renderIcon(tabs.albums, focused),
|
||||
}}
|
||||
/>
|
||||
<BottomTab.Screen
|
||||
name={Routes.Profile}
|
||||
component={SettingsStack}
|
||||
options={{
|
||||
tabBarLabel: "Profil",
|
||||
headerShown: false,
|
||||
tabBarShowLabel: true,
|
||||
tabBarIcon: ({ focused }) => renderIcon(tabs.person, focused),
|
||||
}}
|
||||
/>
|
||||
</BottomTab.Navigator>
|
||||
|
||||
@@ -42,6 +42,9 @@ import PlaybackOnboarding from "../screens/Playback/PlaybackOnboarding";
|
||||
import Playback from "../screens/Playback/Playback";
|
||||
import RecordPlayback from "../screens/Playback/RecordPlayback";
|
||||
import RecordedPlayback from "../screens/Playback/RecordedPlayback";
|
||||
import ChooseDecor from "../screens/Playback/ChooseDecor";
|
||||
import CreatingDecor from "../screens/Playback/CreatingDecor";
|
||||
import VideoFinalize from "../screens/Playback/VideoFinalize";
|
||||
|
||||
const screenOptions = {
|
||||
headerShown: false,
|
||||
@@ -193,6 +196,18 @@ const screens = [
|
||||
name: Routes.RecordedPlayback,
|
||||
component: RecordedPlayback,
|
||||
},
|
||||
{
|
||||
name: Routes.ChooseDecor,
|
||||
component: ChooseDecor,
|
||||
},
|
||||
{
|
||||
name: Routes.CreatingDecor,
|
||||
component: CreatingDecor,
|
||||
},
|
||||
{
|
||||
name: Routes.VideoFinalize,
|
||||
component: VideoFinalize,
|
||||
},
|
||||
];
|
||||
|
||||
export default function Main() {
|
||||
|
||||
@@ -53,4 +53,13 @@ export const Routes = {
|
||||
Playback: "Playback",
|
||||
RecordPlayback: "RecordPlayback",
|
||||
RecordedPlayback: "RecordedPlayback",
|
||||
ChooseDecor: "ChooseDecor",
|
||||
CreatingDecor: "CreatingDecor",
|
||||
VideoFinalize: "VideoFinalize",
|
||||
|
||||
Create: "Create",
|
||||
HitParade: "HitParade",
|
||||
Playbacks: "Playbacks",
|
||||
Library: "Library",
|
||||
Profile: "Profile",
|
||||
};
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
import React from "react";
|
||||
import { View, TouchableOpacity } from "react-native";
|
||||
import { View, TouchableOpacity, Text } from "react-native";
|
||||
import * as Haptics from "expo-haptics";
|
||||
|
||||
import { gutters, Palette, Style } from "../styles";
|
||||
import useLayoutType from "../hooks/useLayoutType";
|
||||
import BorderGradient from "../components/BorderGradient/BorderGradient";
|
||||
import { colors } from "react-native-swiper-flatlist/src/themes";
|
||||
import { BlurView } from "expo-blur";
|
||||
import ItemContainer from "../components/ItemContainer/ItemContainer";
|
||||
import { FONT_FAMILY } from "../styles/Fonts";
|
||||
|
||||
const TabBar = ({ state = {}, descriptors = {}, navigation = {} }) => {
|
||||
const { isDesktop, windowWidth, mediumDesktopBreakpoint, isWeb } =
|
||||
@@ -14,70 +19,98 @@ const TabBar = ({ state = {}, descriptors = {}, navigation = {} }) => {
|
||||
style={{
|
||||
position: "absolute",
|
||||
bottom: gutters * 2,
|
||||
borderRadius: 500,
|
||||
flexDirection: "row",
|
||||
height: 60,
|
||||
width: "60%",
|
||||
width: "90%",
|
||||
alignSelf: "center",
|
||||
maxWidth: isDesktop ? 200 : 220,
|
||||
borderColor: Palette.ultraLightWhite,
|
||||
borderWidth: 3,
|
||||
paddingHorizontal: 1.2 * gutters,
|
||||
backgroundColor: Palette.darkPurple,
|
||||
...Style.containerSpaceBetween,
|
||||
...Style.defaultShadows,
|
||||
zIndex: 1,
|
||||
justifyContent: "center",
|
||||
}}
|
||||
>
|
||||
{state?.routes?.map((route, index) => {
|
||||
const { options } = descriptors[route.key];
|
||||
const isFocused = state?.index === index;
|
||||
<ItemContainer
|
||||
height={64}
|
||||
gradientProps={{
|
||||
start: { x: 0, y: 0 },
|
||||
end: { x: 1, y: 0 },
|
||||
}}
|
||||
style={{
|
||||
height: 65,
|
||||
}}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
...Style.containerSpaceBetween,
|
||||
paddingHorizontal: 4,
|
||||
flex: 1,
|
||||
}}
|
||||
>
|
||||
{state?.routes?.map((route, index) => {
|
||||
const { options } = descriptors[route.key];
|
||||
const isFocused = state?.index === index;
|
||||
|
||||
const _onPressTabBar = () => {
|
||||
if (!isWeb) {
|
||||
Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light);
|
||||
}
|
||||
const label =
|
||||
options.tabBarLabel !== undefined
|
||||
? options.tabBarLabel
|
||||
: options.title !== undefined
|
||||
? options.title
|
||||
: route.name;
|
||||
|
||||
const event = navigation.emit({
|
||||
type: "tabPress",
|
||||
target: route.key,
|
||||
canPreventDefault: true,
|
||||
});
|
||||
const _onPressTabBar = () => {
|
||||
if (!isWeb) {
|
||||
Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light);
|
||||
}
|
||||
|
||||
if (!isFocused && !event.defaultPrevented) {
|
||||
// The `merge: true` option makes sure that the params inside the tab screen are preserved
|
||||
navigation.navigate({ name: route.name, merge: true });
|
||||
}
|
||||
};
|
||||
const event = navigation.emit({
|
||||
type: "tabPress",
|
||||
target: route.key,
|
||||
canPreventDefault: true,
|
||||
});
|
||||
|
||||
const onLongPress = () => {
|
||||
navigation.emit({
|
||||
type: "tabLongPress",
|
||||
target: route.key,
|
||||
});
|
||||
};
|
||||
if (!isFocused && !event.defaultPrevented) {
|
||||
// The `merge: true` option makes sure that the params inside the tab screen are preserved
|
||||
navigation.navigate({ name: route.name, merge: true });
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
!options?.hide && (
|
||||
<TouchableOpacity
|
||||
key={route.key}
|
||||
style={{
|
||||
alignSelf: "center",
|
||||
width: `${100 / state?.routes?.length}%`,
|
||||
height: 40,
|
||||
...Style.containerCenter,
|
||||
}}
|
||||
accessibilityRole="button"
|
||||
accessibilityState={isFocused ? { selected: true } : {}}
|
||||
accessibilityLabel={options.tabBarAccessibilityLabel}
|
||||
testID={options.tabBarTestID}
|
||||
onPress={_onPressTabBar}
|
||||
onLongPress={onLongPress}
|
||||
>
|
||||
{options?.tabBarIcon({ focused: isFocused })}
|
||||
</TouchableOpacity>
|
||||
)
|
||||
);
|
||||
})}
|
||||
const onLongPress = () => {
|
||||
navigation.emit({
|
||||
type: "tabLongPress",
|
||||
target: route.key,
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
!options?.hide && (
|
||||
<TouchableOpacity
|
||||
key={route.key}
|
||||
style={{
|
||||
alignSelf: "center",
|
||||
width: `${100 / state?.routes?.length}%`,
|
||||
height: "100%",
|
||||
...Style.containerCenter,
|
||||
}}
|
||||
accessibilityRole="button"
|
||||
accessibilityState={isFocused ? { selected: true } : {}}
|
||||
accessibilityLabel={options.tabBarAccessibilityLabel}
|
||||
testID={options.tabBarTestID}
|
||||
onPress={_onPressTabBar}
|
||||
onLongPress={onLongPress}
|
||||
>
|
||||
{options?.tabBarIcon({ focused: isFocused })}
|
||||
<Text
|
||||
style={{
|
||||
fontSize: 10,
|
||||
color: isFocused ? Palette.white : "#8B8883",
|
||||
fontFamily: FONT_FAMILY.HelveticaNeueRegular,
|
||||
marginTop: 2,
|
||||
}}
|
||||
>
|
||||
{label}
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
)
|
||||
);
|
||||
})}
|
||||
</View>
|
||||
</ItemContainer>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
import { View, Image, ScrollView } from "react-native";
|
||||
import React from "react";
|
||||
import Page from "../../layouts/Page";
|
||||
import { background, icons } from "../../assets";
|
||||
import SearchBar from "../../components/SearchBar";
|
||||
import MyMusic from "./components/MyMusic";
|
||||
import BackTracks from "./components/BackTracks";
|
||||
import MyClips from "./components/MyClips";
|
||||
import LikedMusic from "./components/LikedMusic";
|
||||
import LikedPlayback from "./components/LikedPlayback";
|
||||
import LikedClips from "./components/LikedClips";
|
||||
import { responsiveHeight } from "react-native-responsive-dimensions";
|
||||
import MyPlaylist from "./components/MyPlaylist";
|
||||
|
||||
const Library = () => {
|
||||
return (
|
||||
<Page backgroundImg={background.libraryBG} headerType="NONE">
|
||||
<View style={{ gap: 17, paddingBottom: 20 }}>
|
||||
<Image source={icons.musicLandLogo} style={{ alignSelf: "center" }} />
|
||||
<SearchBar />
|
||||
</View>
|
||||
<View style={{ flex: 1 }}>
|
||||
<ScrollView
|
||||
contentContainerStyle={{
|
||||
flexGrow: 1,
|
||||
gap: 20,
|
||||
paddingBottom: responsiveHeight(20),
|
||||
}}
|
||||
showsVerticalScrollIndicator={false}
|
||||
>
|
||||
<MyMusic />
|
||||
<BackTracks />
|
||||
<LikedMusic />
|
||||
<MyClips />
|
||||
<MyPlaylist />
|
||||
<LikedPlayback />
|
||||
<LikedClips />
|
||||
</ScrollView>
|
||||
</View>
|
||||
</Page>
|
||||
);
|
||||
};
|
||||
|
||||
export default Library;
|
||||
@@ -0,0 +1,24 @@
|
||||
import { View, Text, Image } from "react-native";
|
||||
import React from "react";
|
||||
import { img } from "../../../assets";
|
||||
import { Style } from "../../../styles";
|
||||
import CardContainer from "./CardContainer";
|
||||
|
||||
const BackTracks = () => {
|
||||
return (
|
||||
<CardContainer label="Mes Playbacks">
|
||||
<View style={{ ...Style.containerRow, gap: 6 }}>
|
||||
{Array.from({ length: 3 }).map((_, index) => (
|
||||
<View style={{ flex: 1 }} key={index}>
|
||||
<Image
|
||||
source={img.placeholder3}
|
||||
style={{ width: "100%", height: 172, borderRadius: 10 }}
|
||||
/>
|
||||
</View>
|
||||
))}
|
||||
</View>
|
||||
</CardContainer>
|
||||
);
|
||||
};
|
||||
|
||||
export default BackTracks;
|
||||
@@ -0,0 +1,33 @@
|
||||
import { View, Text, StyleSheet, Pressable } from "react-native";
|
||||
import React from "react";
|
||||
import { Palette, Style } from "../../../styles";
|
||||
import { FONT_FAMILY } from "../../../styles/Fonts";
|
||||
|
||||
const CardContainer = ({ children, label = "" }) => {
|
||||
return (
|
||||
<View style={{ gap: 12 }}>
|
||||
<View style={{ ...Style.containerSpaceBetween }}>
|
||||
<Text style={styles.label}>{label}</Text>
|
||||
<Pressable>
|
||||
<Text style={styles.seeAll}>Voir tout</Text>
|
||||
</Pressable>
|
||||
</View>
|
||||
{children}
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
export default CardContainer;
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
label: {
|
||||
fontSize: 22,
|
||||
color: Palette.white,
|
||||
fontFamily: FONT_FAMILY.InterSemiBold,
|
||||
},
|
||||
seeAll: {
|
||||
fontSize: 12,
|
||||
color: Palette.gray,
|
||||
fontFamily: FONT_FAMILY.InterRegular,
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,24 @@
|
||||
import { View, Text, Image } from "react-native";
|
||||
import React from "react";
|
||||
import CardContainer from "./CardContainer";
|
||||
import { Style } from "../../../styles";
|
||||
import { img } from "../../../assets";
|
||||
|
||||
const LikedClips = () => {
|
||||
return (
|
||||
<CardContainer label="Clips likés">
|
||||
<View style={{ ...Style.containerRow, gap: 6 }}>
|
||||
{Array.from({ length: 3 }).map((_, index) => (
|
||||
<View style={{ flex: 1 }} key={index}>
|
||||
<Image
|
||||
source={img.placeholder3}
|
||||
style={{ width: "100%", height: 172, borderRadius: 10 }}
|
||||
/>
|
||||
</View>
|
||||
))}
|
||||
</View>
|
||||
</CardContainer>
|
||||
);
|
||||
};
|
||||
|
||||
export default LikedClips;
|
||||
@@ -0,0 +1,29 @@
|
||||
import { View, Text, Image, FlatList } from "react-native";
|
||||
import React from "react";
|
||||
import CardContainer from "./CardContainer";
|
||||
import { Style } from "../../../styles";
|
||||
import { img } from "../../../assets";
|
||||
|
||||
const LikedMusic = () => {
|
||||
return (
|
||||
<CardContainer label="Musiques likées">
|
||||
<FlatList
|
||||
scrollEnabled={false}
|
||||
data={Array.from({ length: 6 })}
|
||||
numColumns={3}
|
||||
contentContainerStyle={{ gap: 10 }}
|
||||
columnWrapperStyle={{ gap: 6 }}
|
||||
renderItem={() => (
|
||||
<View style={{ flex: 1 }}>
|
||||
<Image
|
||||
source={img.placeholder3}
|
||||
style={{ width: "100%", height: 172, borderRadius: 10 }}
|
||||
/>
|
||||
</View>
|
||||
)}
|
||||
/>
|
||||
</CardContainer>
|
||||
);
|
||||
};
|
||||
|
||||
export default LikedMusic;
|
||||
@@ -0,0 +1,24 @@
|
||||
import { View, Text, Image } from "react-native";
|
||||
import React from "react";
|
||||
import CardContainer from "./CardContainer";
|
||||
import { Style } from "../../../styles";
|
||||
import { img } from "../../../assets";
|
||||
|
||||
const LikedPlayback = () => {
|
||||
return (
|
||||
<CardContainer label="Playbacks likés">
|
||||
<View style={{ ...Style.containerRow, gap: 6 }}>
|
||||
{Array.from({ length: 3 }).map((_, index) => (
|
||||
<View style={{ flex: 1 }} key={index}>
|
||||
<Image
|
||||
source={img.placeholder3}
|
||||
style={{ width: "100%", height: 172, borderRadius: 10 }}
|
||||
/>
|
||||
</View>
|
||||
))}
|
||||
</View>
|
||||
</CardContainer>
|
||||
);
|
||||
};
|
||||
|
||||
export default LikedPlayback;
|
||||
@@ -0,0 +1,78 @@
|
||||
import { View, Text, Image, Pressable, StyleSheet } from "react-native";
|
||||
import React, { useState } from "react";
|
||||
import { Palette, Style } from "../../../styles";
|
||||
import { icons, img } from "../../../assets";
|
||||
import { size } from "../../../styles/Style";
|
||||
import { BlurView } from "expo-blur";
|
||||
import { FONT_FAMILY } from "../../../styles/Fonts";
|
||||
|
||||
const MusicCard = () => {
|
||||
const [selected, setSelected] = useState(false);
|
||||
|
||||
return (
|
||||
<View
|
||||
style={{
|
||||
...Style.containerRow,
|
||||
gap: 6,
|
||||
}}
|
||||
>
|
||||
<Image
|
||||
source={img.placeholder2}
|
||||
style={{ ...size({ size: 60 }), borderRadius: 12 }}
|
||||
/>
|
||||
<View style={styles.blurContainer}>
|
||||
<BlurView
|
||||
intensity={20}
|
||||
style={{
|
||||
flex: 1,
|
||||
...Style.containerSpaceBetween,
|
||||
paddingHorizontal: 8,
|
||||
}}
|
||||
>
|
||||
<View>
|
||||
<Text style={styles.title}>Alors on danse</Text>
|
||||
<Text style={styles.subTitle}>Stromae</Text>
|
||||
</View>
|
||||
<View
|
||||
style={{
|
||||
...Style.containerRow,
|
||||
gap: 12,
|
||||
}}
|
||||
>
|
||||
<Pressable onPress={() => setSelected(!selected)}>
|
||||
<Image
|
||||
source={selected ? icons.heart : icons.heartOutline}
|
||||
style={size({ size: 24 })}
|
||||
resizeMode="contain"
|
||||
/>
|
||||
</Pressable>
|
||||
<Pressable>
|
||||
<Image source={icons.more} />
|
||||
</Pressable>
|
||||
</View>
|
||||
</BlurView>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
export default MusicCard;
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
blurContainer: {
|
||||
borderRadius: 12,
|
||||
overflow: "hidden",
|
||||
flex: 1,
|
||||
height: "100%",
|
||||
},
|
||||
title: {
|
||||
fontSize: 16,
|
||||
color: Palette.white,
|
||||
fontFamily: FONT_FAMILY.OwnersRegular,
|
||||
},
|
||||
subTitle: {
|
||||
fontSize: 12,
|
||||
color: Palette.white,
|
||||
fontFamily: FONT_FAMILY.InterRegular,
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,24 @@
|
||||
import { View, Text, Image } from "react-native";
|
||||
import React from "react";
|
||||
import CardContainer from "./CardContainer";
|
||||
import { Style } from "../../../styles";
|
||||
import { img } from "../../../assets";
|
||||
|
||||
const MyClips = () => {
|
||||
return (
|
||||
<CardContainer label="Mes Clips">
|
||||
<View style={{ ...Style.containerRow, gap: 6 }}>
|
||||
{Array.from({ length: 3 }).map((_, index) => (
|
||||
<View style={{ flex: 1 }} key={index}>
|
||||
<Image
|
||||
source={img.placeholder3}
|
||||
style={{ width: "100%", height: 172, borderRadius: 10 }}
|
||||
/>
|
||||
</View>
|
||||
))}
|
||||
</View>
|
||||
</CardContainer>
|
||||
);
|
||||
};
|
||||
|
||||
export default MyClips;
|
||||
@@ -0,0 +1,18 @@
|
||||
import { View } from "react-native";
|
||||
import React from "react";
|
||||
import CardContainer from "./CardContainer";
|
||||
import MusicCard from "./MusicCard";
|
||||
|
||||
const MyMusic = () => {
|
||||
return (
|
||||
<CardContainer label="Mes musiques">
|
||||
<View style={{ gap: 10 }}>
|
||||
{Array.from({ length: 3 }).map((_, index) => (
|
||||
<MusicCard key={index} />
|
||||
))}
|
||||
</View>
|
||||
</CardContainer>
|
||||
);
|
||||
};
|
||||
|
||||
export default MyMusic;
|
||||
@@ -0,0 +1,51 @@
|
||||
import { View, Text, Pressable, Image } from "react-native";
|
||||
import React from "react";
|
||||
import CardContainer from "./CardContainer";
|
||||
import { BlurView } from "expo-blur";
|
||||
import { icons } from "../../../assets";
|
||||
import Style, { size } from "../../../styles/Style";
|
||||
import { Palette } from "../../../styles";
|
||||
import { FONT_FAMILY } from "../../../styles/Fonts";
|
||||
|
||||
const MyPlaylist = () => {
|
||||
return (
|
||||
<CardContainer label="Mes Playlists">
|
||||
<View style={{ gap: 8 }}>
|
||||
{["Musiques de lover", "Musiques triste"].map((item, index) => (
|
||||
<View style={{ borderRadius: 12, overflow: "hidden" }} key={index}>
|
||||
<BlurView
|
||||
intensity={20}
|
||||
style={{
|
||||
...Style.containerSpaceBetween,
|
||||
height: 59,
|
||||
paddingHorizontal: 10,
|
||||
}}
|
||||
>
|
||||
<Text
|
||||
style={{
|
||||
fontSize: 16,
|
||||
color: Palette.white,
|
||||
fontFamily: FONT_FAMILY.InterRegular,
|
||||
}}
|
||||
>
|
||||
{item}
|
||||
</Text>
|
||||
<Pressable>
|
||||
<Image
|
||||
source={icons.chevronDown}
|
||||
style={{
|
||||
...size({ size: 15 }),
|
||||
transform: [{ rotate: "-90deg" }],
|
||||
}}
|
||||
resizeMode="contain"
|
||||
/>
|
||||
</Pressable>
|
||||
</BlurView>
|
||||
</View>
|
||||
))}
|
||||
</View>
|
||||
</CardContainer>
|
||||
);
|
||||
};
|
||||
|
||||
export default MyPlaylist;
|
||||
@@ -29,6 +29,7 @@ import {
|
||||
|
||||
import useLayoutType from "../hooks/useLayoutType.js";
|
||||
import { capitalize } from "../helpers/index.js";
|
||||
import { navigate } from "../navigation/NavigationService.js";
|
||||
|
||||
export default ({ navigation }) => {
|
||||
console.log("LOGINSCREEN");
|
||||
@@ -292,7 +293,7 @@ export default ({ navigation }) => {
|
||||
|
||||
<Button
|
||||
{...(mode === "LOGIN"
|
||||
? { text: "Connexion", onPress: onLogin }
|
||||
? { text: "Connexion", onPress: () => navigate(Routes.BottomTab) }
|
||||
: {
|
||||
text: "Inscription",
|
||||
onPress: onSignup,
|
||||
|
||||
@@ -4,6 +4,8 @@ import Button from "../components/Button";
|
||||
import { gutters } from "../styles";
|
||||
import { navigate } from "../navigation/NavigationService";
|
||||
import { Routes } from "../navigation";
|
||||
import { LinearGradient } from "../components/LinearGradient/LinearGradient";
|
||||
import GradientButton from "../components/GradientButton";
|
||||
|
||||
export default ({ navigation }) => {
|
||||
return (
|
||||
@@ -13,11 +15,20 @@ export default ({ navigation }) => {
|
||||
justifyContent: "flex-end",
|
||||
padding: gutters,
|
||||
paddingBottom: gutters * 2,
|
||||
backgroundColor: "#0A0D12",
|
||||
gap: 10,
|
||||
}}
|
||||
>
|
||||
<Button text="WRITING" onPress={() => navigate(Routes.Writing)} />
|
||||
<Button text="STUDIO" onPress={() => navigate(Routes.Studio)} />
|
||||
<Button text="PRODUCTION" onPress={() => navigate(Routes.ProductionOnboarding)} />
|
||||
<GradientButton title="LOGIN" onPress={() => navigate(Routes.Login)} />
|
||||
<GradientButton
|
||||
title="WRITING"
|
||||
onPress={() => navigate(Routes.Writing)}
|
||||
/>
|
||||
<GradientButton title="STUDIO" onPress={() => navigate(Routes.Studio)} />
|
||||
<GradientButton
|
||||
title="PRODUCTION"
|
||||
onPress={() => navigate(Routes.ProductionOnboarding)}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
import { View, Text } from "react-native";
|
||||
import React, { useState } from "react";
|
||||
import Page from "../../layouts/Page";
|
||||
import { background } from "../../assets";
|
||||
import MusicLandHeader from "../../components/MusicLandHeader";
|
||||
import { goBack, navigate } from "../../navigation/NavigationService";
|
||||
import CreateLyricsHeader from "../Writing/components/CreateLyricsHeader";
|
||||
import ItemContainer from "../../components/ItemContainer/ItemContainer";
|
||||
import GradientButton from "../../components/GradientButton";
|
||||
import { CHOOSE_DECOR } from "../../data/data";
|
||||
import { Palette } from "../../styles";
|
||||
import { FONT_FAMILY } from "../../styles/Fonts";
|
||||
import { Routes } from "../../navigation";
|
||||
|
||||
const ChooseDecor = () => {
|
||||
const [selected, setSelected] = useState("");
|
||||
|
||||
return (
|
||||
<Page headerType="NONE" backgroundImg={background.playbackBG2}>
|
||||
<MusicLandHeader progress={20} onPressBack={goBack} />
|
||||
<View style={{ flex: 1, marginTop: 12, gap: 34 }}>
|
||||
<View style={{ gap: 10 }}>
|
||||
<CreateLyricsHeader
|
||||
title="Choisis ton décor"
|
||||
subTitle="Il sera généré derrière toi lors de ton Playback."
|
||||
/>
|
||||
<ItemContainer height={402}>
|
||||
<View style={{ gap: 10, marginTop: 5, paddingHorizontal: 5 }}>
|
||||
{CHOOSE_DECOR.map((item, index) => {
|
||||
const selectedItem = selected === item;
|
||||
|
||||
return (
|
||||
<CreateLyricsHeader
|
||||
key={index}
|
||||
gradientProps={{
|
||||
locations: [0, 1],
|
||||
}}
|
||||
containerStyle={{
|
||||
borderRadius: 14,
|
||||
}}
|
||||
onPress={() => setSelected(item)}
|
||||
colors={
|
||||
selectedItem
|
||||
? ["#99999900", "#FFFFFF"]
|
||||
: [Palette.tran, Palette.tran]
|
||||
}
|
||||
tint={selectedItem ? "default" : "dark"}
|
||||
>
|
||||
<View style={{ paddingVertical: 6 }}>
|
||||
<Text
|
||||
style={{
|
||||
fontSize: 16,
|
||||
color: Palette.white,
|
||||
fontFamily: FONT_FAMILY.InterRegular,
|
||||
}}
|
||||
>
|
||||
{item}
|
||||
</Text>
|
||||
</View>
|
||||
</CreateLyricsHeader>
|
||||
);
|
||||
})}
|
||||
</View>
|
||||
</ItemContainer>
|
||||
</View>
|
||||
<GradientButton
|
||||
title="Suivant"
|
||||
onPress={() => navigate(Routes.CreatingDecor)}
|
||||
/>
|
||||
</View>
|
||||
</Page>
|
||||
);
|
||||
};
|
||||
|
||||
export default ChooseDecor;
|
||||
@@ -0,0 +1,129 @@
|
||||
import { View, Text, Image } from "react-native";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import Page from "../../layouts/Page";
|
||||
import { ai, background } from "../../assets";
|
||||
import MusicLandHeader from "../../components/MusicLandHeader";
|
||||
import { goBack, navigate } from "../../navigation/NavigationService";
|
||||
import { Palette, Style } from "../../styles";
|
||||
import { BlurView } from "expo-blur";
|
||||
import { FONT_FAMILY } from "../../styles/Fonts";
|
||||
import ProgressBar from "../../components/ProgressBar";
|
||||
import { Routes } from "../../navigation";
|
||||
import GradientButton from "../../components/GradientButton";
|
||||
|
||||
const CreatingDecor = () => {
|
||||
const [progress, setProgress] = useState(0);
|
||||
|
||||
useEffect(() => {
|
||||
const interval = setInterval(() => {
|
||||
setProgress((prevProgress) => {
|
||||
if (prevProgress >= 100) {
|
||||
clearInterval(interval);
|
||||
|
||||
return 100;
|
||||
}
|
||||
return prevProgress + 1;
|
||||
});
|
||||
}, 100);
|
||||
|
||||
return () => clearInterval(interval);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Page backgroundImg={background.playbackBG2} headerType="NONE">
|
||||
<MusicLandHeader progress={20} onPressBack={goBack} />
|
||||
<View
|
||||
style={{
|
||||
flex: 1,
|
||||
paddingTop: 16,
|
||||
...Style.containerCenter,
|
||||
}}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
width: "100%",
|
||||
height: "50%",
|
||||
}}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
zIndex: 1,
|
||||
position: "absolute",
|
||||
top: -150,
|
||||
width: "50%",
|
||||
height: "80%",
|
||||
alignSelf: "center",
|
||||
}}
|
||||
>
|
||||
<Image
|
||||
source={ai.john}
|
||||
style={{ width: "100%", height: "100%", right: -10 }}
|
||||
resizeMode="contain"
|
||||
/>
|
||||
</View>
|
||||
<View
|
||||
style={{
|
||||
flex: 1,
|
||||
borderRadius: 20,
|
||||
overflow: "hidden",
|
||||
backgroundColor: "#0F0C1933",
|
||||
}}
|
||||
>
|
||||
<BlurView
|
||||
intensity={40}
|
||||
tint="dark"
|
||||
style={{ flex: 1, padding: 10, paddingBottom: 20 }}
|
||||
>
|
||||
<View style={{ flex: 1, justifyContent: "flex-end", gap: 20 }}>
|
||||
<View>
|
||||
<Text
|
||||
style={{
|
||||
fontSize: 22,
|
||||
color: Palette.white,
|
||||
fontFamily: FONT_FAMILY.InterSemiBold,
|
||||
textAlign: "center",
|
||||
}}
|
||||
>
|
||||
Ton décor est en cours de{"\n"}création
|
||||
</Text>
|
||||
<Text
|
||||
style={{
|
||||
fontSize: 14,
|
||||
color: Palette.gray,
|
||||
fontFamily: FONT_FAMILY.InterRegular,
|
||||
textAlign: "center",
|
||||
}}
|
||||
>
|
||||
Veuillez patienter
|
||||
</Text>
|
||||
</View>
|
||||
<View style={{ alignItems: "center", gap: 16 }}>
|
||||
<ProgressBar gradient progress={progress} />
|
||||
<Text
|
||||
style={{
|
||||
fontSize: 14,
|
||||
color: Palette.white,
|
||||
fontFamily: FONT_FAMILY.InterRegular,
|
||||
}}
|
||||
>
|
||||
{progress}%
|
||||
</Text>
|
||||
</View>
|
||||
<GradientButton
|
||||
title="Découvrir mon Playback"
|
||||
containerStyle={{
|
||||
width: "80%",
|
||||
alignSelf: "center",
|
||||
}}
|
||||
onPress={() => navigate(Routes.VideoFinalize)}
|
||||
/>
|
||||
</View>
|
||||
</BlurView>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</Page>
|
||||
);
|
||||
};
|
||||
|
||||
export default CreatingDecor;
|
||||
@@ -33,11 +33,12 @@ const RecordedPlayback = () => {
|
||||
style={{ width: "80%", alignSelf: "center", marginTop: 4, gap: 12 }}
|
||||
>
|
||||
<GradientButton
|
||||
title="Je veux devenir Playbacker"
|
||||
containerStyle={{}}
|
||||
onPress={() => navigate(Routes.PlaybackOnboarding)}
|
||||
title="Je valide"
|
||||
/>
|
||||
<BorderGradientButton
|
||||
title="Je change de décor"
|
||||
onPress={() => navigate(Routes.ChooseDecor)}
|
||||
/>
|
||||
<BorderGradientButton title="Je change de décor" />
|
||||
<BorderGradientButton title="Recommencer" />
|
||||
</View>
|
||||
</View>
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
import { View, Text, Image } from "react-native";
|
||||
import React from "react";
|
||||
import MusicLandHeader from "../../components/MusicLandHeader";
|
||||
import Page from "../../layouts/Page";
|
||||
import { background, icons, img } from "../../assets";
|
||||
import { goBack, navigate } from "../../navigation/NavigationService";
|
||||
import Slider from "../../components/Slider";
|
||||
import GradientButton from "../../components/GradientButton";
|
||||
import BorderGradientButton from "../../components/BorderGradientButton";
|
||||
import { gutters } from "../../styles";
|
||||
import { Routes } from "../../navigation";
|
||||
|
||||
const VideoFinalize = () => {
|
||||
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 }}
|
||||
>
|
||||
<BorderGradientButton
|
||||
icon={icons.stars}
|
||||
title="Regénérer"
|
||||
onPress={goBack}
|
||||
/>
|
||||
<GradientButton
|
||||
title="Valider"
|
||||
onPress={() =>
|
||||
navigate(Routes.DownloadSongs, {
|
||||
action: "playback",
|
||||
})
|
||||
}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
</Page>
|
||||
);
|
||||
};
|
||||
|
||||
export default VideoFinalize;
|
||||
@@ -10,31 +10,47 @@ 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,
|
||||
},
|
||||
];
|
||||
import { useRoute } from "@react-navigation/core";
|
||||
|
||||
const DownloadPrices = () => {
|
||||
const params = useRoute().params;
|
||||
const action = params?.action;
|
||||
const [selectedIndex, setSelectedIndex] = useState(null);
|
||||
|
||||
const PRICES = [
|
||||
{
|
||||
title: action === "playback" ? "1 Playback" : "Je télécharge ma chanson",
|
||||
description: `Ce ${
|
||||
action === "playback" ? "Playback" : "morceau"
|
||||
} uniquement`,
|
||||
price: "6,99€",
|
||||
},
|
||||
{
|
||||
title: `3 ${action === "playback" ? "Playbacks" : "chansons"}`,
|
||||
description: `Ce ${
|
||||
action === "playback" ? "Playback" : "morceau"
|
||||
} et les 2 prochains que tu crées`,
|
||||
price: "12,99€",
|
||||
},
|
||||
{
|
||||
title: `5 ${action === "playback" ? "Playbacks" : "chansons"}`,
|
||||
description: `Ce ${
|
||||
action === "playback" ? "Playback" : "morceau"
|
||||
} et les 4 prochains que tu crées`,
|
||||
price: "19,99€",
|
||||
recommended: true,
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<Page backgroundImg={background.productionBG2} headerType="NONE">
|
||||
<Page
|
||||
backgroundImg={
|
||||
action === "playback"
|
||||
? background.playbackBG2
|
||||
: background.productionBG2
|
||||
}
|
||||
headerType="NONE"
|
||||
>
|
||||
<MusicLandHeader onPressBack={goBack} progress={75} />
|
||||
<View style={{ flex: 1, paddingTop: responsiveHeight(10) }}>
|
||||
<CreateLyricsHeader
|
||||
@@ -74,7 +90,9 @@ const DownloadPrices = () => {
|
||||
tint={!item.recommended ? "dark" : "light"}
|
||||
onPress={() => {
|
||||
setSelectedIndex(index);
|
||||
navigate(Routes.SongDownloaded);
|
||||
navigate(Routes.SongDownloaded, {
|
||||
action,
|
||||
});
|
||||
}}
|
||||
>
|
||||
<View style={{ paddingTop: 5 }}>
|
||||
|
||||
@@ -11,10 +11,21 @@ import { size } from "../../styles/Style";
|
||||
import { BlurView } from "expo-blur";
|
||||
import { responsiveHeight } from "react-native-responsive-dimensions";
|
||||
import { Routes } from "../../navigation";
|
||||
import { useRoute } from "@react-navigation/core";
|
||||
|
||||
const DownloadSongs = () => {
|
||||
const params = useRoute().params;
|
||||
const action = params?.action;
|
||||
|
||||
return (
|
||||
<Page backgroundImg={background.productionBG2} headerType="NONE">
|
||||
<Page
|
||||
backgroundImg={
|
||||
action === "playback"
|
||||
? background.playbackBG2
|
||||
: background.productionBG2
|
||||
}
|
||||
headerType="NONE"
|
||||
>
|
||||
<MusicLandHeader onPressBack={goBack} progress={50} />
|
||||
<View style={{ flex: 1, paddingTop: responsiveHeight(15) }}>
|
||||
<CreateLyricsHeader
|
||||
@@ -32,29 +43,37 @@ const DownloadSongs = () => {
|
||||
}}
|
||||
/>
|
||||
<View style={{ gap: 12, paddingVertical: 12 }}>
|
||||
<Text style={styles.title}>Prêt à télécharger ta chanson ?</Text>
|
||||
<Text style={styles.title}>Prêt à télécharger {action === "playback" ? "ton Playback" : "ta chanson"} ?</Text>
|
||||
<View style={{ gap: 10 }}>
|
||||
<Pressable
|
||||
style={styles.itemContainer}
|
||||
onPress={() => navigate(Routes.DownloadPrices)}
|
||||
onPress={() =>
|
||||
navigate(Routes.DownloadPrices, {
|
||||
action,
|
||||
})
|
||||
}
|
||||
>
|
||||
<BlurView style={styles.blurView} intensity={40} tint="dark">
|
||||
<Text style={styles.label}>Télécharger ma chanson</Text>
|
||||
<Text style={styles.label}>Télécharger {action === "playback" ? "mon Playback" : "ma chanson"}</Text>
|
||||
<Text style={styles.description}>Pour moi uniquement</Text>
|
||||
</BlurView>
|
||||
</Pressable>
|
||||
<Pressable
|
||||
style={styles.itemContainer}
|
||||
onPress={() => navigate(Routes.StreamSong)}
|
||||
onPress={() =>
|
||||
navigate(Routes.StreamSong, {
|
||||
action,
|
||||
})
|
||||
}
|
||||
>
|
||||
<BlurView style={styles.blurView} intensity={40} tint="dark">
|
||||
<Text style={styles.label}>
|
||||
Diffuser ma chanson sur la plateforme de MusicLand (+
|
||||
Diffuser {action === "playback" ? "mon Playback" : "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)
|
||||
ML (catégorie {action === "playback" ? "Playback" : "chanson"})
|
||||
</Text>
|
||||
</BlurView>
|
||||
</Pressable>
|
||||
|
||||
@@ -12,10 +12,21 @@ import { responsiveHeight } from "react-native-responsive-dimensions";
|
||||
import { Palette } from "../../styles";
|
||||
import { FONT_FAMILY } from "../../styles/Fonts";
|
||||
import { Routes } from "../../navigation";
|
||||
import { useRoute } from "@react-navigation/core";
|
||||
|
||||
const SongDownloaded = () => {
|
||||
const params = useRoute().params;
|
||||
const action = params?.action;
|
||||
|
||||
return (
|
||||
<Page backgroundImg={background.productionBG2} headerType="NONE">
|
||||
<Page
|
||||
backgroundImg={
|
||||
action === "playback"
|
||||
? background.playbackBG2
|
||||
: background.productionBG2
|
||||
}
|
||||
headerType="NONE"
|
||||
>
|
||||
<MusicLandHeader onPressBack={goBack} progress={100} />
|
||||
<View style={{ flex: 1, paddingTop: responsiveHeight(15) }}>
|
||||
<CreateLyricsHeader
|
||||
@@ -41,7 +52,7 @@ const SongDownloaded = () => {
|
||||
textAlign: "center",
|
||||
}}
|
||||
>
|
||||
Chanson téléchargée !
|
||||
{action === "playback" ? "Playback" : "Chanson"} téléchargée !
|
||||
</Text>
|
||||
<Text
|
||||
style={{
|
||||
@@ -50,8 +61,9 @@ const SongDownloaded = () => {
|
||||
fontFamily: FONT_FAMILY.InterMedium,
|
||||
}}
|
||||
>
|
||||
Ta chanson est désormais téléchargée dans tes fichiers. N’hésite
|
||||
pas à la partager avec tes proches.
|
||||
{action === "playback" ? "Ton Playback" : "Ta Chanson"} est
|
||||
désormais téléchargée dans tes fichiers. N’hésite pas à la
|
||||
partager avec tes proches.
|
||||
</Text>
|
||||
</View>
|
||||
<View
|
||||
|
||||
@@ -12,10 +12,21 @@ import { FONT_FAMILY } from "../../styles/Fonts";
|
||||
import BorderGradientButton from "../../components/BorderGradientButton";
|
||||
import GradientButton from "../../components/GradientButton";
|
||||
import { Routes } from "../../navigation";
|
||||
import { useRoute } from "@react-navigation/core";
|
||||
|
||||
const SongRelease = () => {
|
||||
const params = useRoute().params;
|
||||
const action = params?.action;
|
||||
|
||||
return (
|
||||
<Page backgroundImg={background.productionBG2} headerType="NONE">
|
||||
<Page
|
||||
backgroundImg={
|
||||
action === "playback"
|
||||
? background.playbackBG2
|
||||
: background.productionBG2
|
||||
}
|
||||
headerType="NONE"
|
||||
>
|
||||
<MusicLandHeader onPressBack={goBack} progress={100} />
|
||||
<View style={{ flex: 1, paddingTop: responsiveHeight(15) }}>
|
||||
<CreateLyricsHeader
|
||||
@@ -41,7 +52,7 @@ const SongRelease = () => {
|
||||
textAlign: "center",
|
||||
}}
|
||||
>
|
||||
Chanson publiée!
|
||||
{action === "playback" ? "Playback" : "Chanson"} publiée !
|
||||
</Text>
|
||||
<Text
|
||||
style={{
|
||||
@@ -50,9 +61,9 @@ const SongRelease = () => {
|
||||
fontFamily: FONT_FAMILY.InterMedium,
|
||||
}}
|
||||
>
|
||||
Ta chanson est désormais accessible sur l’application et les
|
||||
réseaux sociaux de MusicLand. N’hésite pas à la partager avec tes
|
||||
proches.
|
||||
{action === "playback" ? "Ton Playback" : "Ta Chanson"} est
|
||||
désormais accessible sur l’application et les réseaux sociaux de
|
||||
MusicLand. N’hésite pas à la partager avec tes proches.
|
||||
</Text>
|
||||
</View>
|
||||
<View
|
||||
|
||||
@@ -10,6 +10,7 @@ import Style, { size } from "../../styles/Style";
|
||||
import { Palette } from "../../styles";
|
||||
import { FONT_FAMILY } from "../../styles/Fonts";
|
||||
import { Routes } from "../../navigation";
|
||||
import { useRoute } from "@react-navigation/core";
|
||||
|
||||
const STREAM_PRICES = [
|
||||
{
|
||||
@@ -29,11 +30,40 @@ const STREAM_PRICES = [
|
||||
},
|
||||
];
|
||||
|
||||
const PLAYBACK_STREAM_PRICES = [
|
||||
{
|
||||
title: "Je créer et diffuse mon Playback",
|
||||
description: "Ce morceau uniquement",
|
||||
price: "6,99€ / mois",
|
||||
},
|
||||
{
|
||||
title: "3 Playbacks",
|
||||
description: "Ce morceau et les 2 prochains que tu crées",
|
||||
price: "12,99€ / mois",
|
||||
},
|
||||
{
|
||||
title: "Illimité",
|
||||
price: "20€ / mois",
|
||||
recommended: true,
|
||||
},
|
||||
];
|
||||
|
||||
const StreamSong = () => {
|
||||
const params = useRoute().params;
|
||||
const action = params?.action;
|
||||
const [selectedIndex, setSelectedIndex] = useState(null);
|
||||
|
||||
const DATA = action === "playback" ? PLAYBACK_STREAM_PRICES : STREAM_PRICES;
|
||||
|
||||
return (
|
||||
<Page backgroundImg={background.productionBG2} headerType="NONE">
|
||||
<Page
|
||||
backgroundImg={
|
||||
action === "playback"
|
||||
? background.playbackBG2
|
||||
: background.productionBG2
|
||||
}
|
||||
headerType="NONE"
|
||||
>
|
||||
<MusicLandHeader onPressBack={goBack} progress={75} />
|
||||
<View style={{ flex: 1, paddingTop: responsiveHeight(5) }}>
|
||||
<CreateLyricsHeader
|
||||
@@ -77,7 +107,7 @@ const StreamSong = () => {
|
||||
</Text>
|
||||
</View>
|
||||
<View style={{ gap: 10 }}>
|
||||
{STREAM_PRICES.map((item, index) => (
|
||||
{DATA.map((item, index) => (
|
||||
<CreateLyricsHeader
|
||||
key={index}
|
||||
colors={
|
||||
@@ -88,7 +118,9 @@ const StreamSong = () => {
|
||||
tint={!item.recommended ? "dark" : "light"}
|
||||
onPress={() => {
|
||||
setSelectedIndex(index);
|
||||
navigate(Routes.SongRelease);
|
||||
navigate(Routes.SongRelease, {
|
||||
action,
|
||||
});
|
||||
}}
|
||||
>
|
||||
<View style={{ paddingTop: 5 }}>
|
||||
|
||||
@@ -39,6 +39,9 @@ export const FONT_FAMILY = {
|
||||
HelveticaNeueRegular: "HelveticaNeueRegular",
|
||||
HelveticaNeueMedium: "HelveticaNeueMedium",
|
||||
HelveticaNeueBold: "HelveticaNeueBold",
|
||||
OwnersRegular: "OwnersRegular",
|
||||
OwnersMedium: "OwnersMedium",
|
||||
OwnersBold: "OwnersBold",
|
||||
};
|
||||
|
||||
const Fonts = ({
|
||||
|
||||
@@ -7402,10 +7402,10 @@ react-native-modalbox@^2.0.2:
|
||||
dependencies:
|
||||
prop-types "^15.5.10"
|
||||
|
||||
react-native-reanimated-carousel@^4.0.0-alpha.8:
|
||||
version "4.0.0-canary.22"
|
||||
resolved "https://registry.yarnpkg.com/react-native-reanimated-carousel/-/react-native-reanimated-carousel-4.0.0-canary.22.tgz#4fa530548bf330184b252eabd2d95dc02eb31f28"
|
||||
integrity sha512-GOTSXVuoV08ZUxGPuzQ1Kl1YOOOrKWb18uRlPsa759bFyiqFWpjjLrCUdfgBgF9ZqUHUbb1jj+UffFf2eGDz+A==
|
||||
react-native-reanimated-carousel@^4.0.3:
|
||||
version "4.0.3"
|
||||
resolved "https://registry.yarnpkg.com/react-native-reanimated-carousel/-/react-native-reanimated-carousel-4.0.3.tgz#975f4ff3f5da5bb3790fe60850a46ad8119612bc"
|
||||
integrity sha512-YZXlvZNghR5shFcI9hTA7h7bEhh97pfUSLZvLBAshpbkuYwJDKmQXejO/199T6hqGq0wCRwR0CWf2P4Vs6A4Fw==
|
||||
|
||||
react-native-reanimated@~3.16.1:
|
||||
version "3.16.3"
|
||||
|
||||