.
This commit is contained in:
@@ -5,7 +5,7 @@ import { useEffect } from 'react';
|
||||
const ThemeProvider = ({ children }: { children: JSX.Element }) => {
|
||||
const colorScheme = useColorScheme();
|
||||
const lightGlassmorphism = {
|
||||
50: 'rgba(255,255,255,0.05)',
|
||||
50: 'rgba(255,255,255,0.9)',
|
||||
100: 'rgba(255,255,255,0.1)',
|
||||
200: 'rgba(255,255,255,0.2)',
|
||||
300: 'rgba(255,255,255,0.3)',
|
||||
@@ -18,7 +18,7 @@ const ThemeProvider = ({ children }: { children: JSX.Element }) => {
|
||||
1000: 'rgba(255,255,255,1)',
|
||||
};
|
||||
const darkGlassmorphism = {
|
||||
50: 'rgba(16,16,20,0.05)',
|
||||
50: 'rgba(16,16,20,0.9)',
|
||||
100: 'rgba(16,16,20,0.1)',
|
||||
200: 'rgba(16,16,20,0.2)',
|
||||
300: 'rgba(16,16,20,0.3)',
|
||||
|
||||
@@ -10,7 +10,7 @@ export type ButtonType = 'filled' | 'outlined' | 'menu';
|
||||
interface ButtonProps {
|
||||
title?: string;
|
||||
style?: StyleProp<ViewStyle>;
|
||||
onPress?: () => Promise<void>;
|
||||
onPress?: () => void | Promise<void>;
|
||||
isDisabled?: boolean;
|
||||
icon?: Icon;
|
||||
iconVariant?: 'Bold' | 'Outline';
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
/* eslint-disable react/prop-types */
|
||||
import React, { useMemo, memo } from 'react';
|
||||
import { StyleSheet } from 'react-native';
|
||||
import { StyleSheet, ViewStyle, Image } from 'react-native';
|
||||
import { Column, HStack, Row, Stack, Text, useBreakpointValue, useTheme } from 'native-base';
|
||||
import { HeartAdd, HeartRemove, Play } from 'iconsax-react-native';
|
||||
import { Image } from 'react-native';
|
||||
import IconButton from './IconButton';
|
||||
import Spacer from '../../components/UI/Spacer';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@@ -33,6 +32,9 @@ export interface MusicItemType {
|
||||
/** Indicates whether the song is liked/favorited by the user. */
|
||||
liked: boolean;
|
||||
|
||||
/** Custom style for the container. */
|
||||
style?: ViewStyle | ViewStyle[];
|
||||
|
||||
/** Callback function triggered when the like button is pressed. */
|
||||
onLike: () => void;
|
||||
|
||||
@@ -144,7 +146,7 @@ function MusicItemComponent(props: MusicItemType) {
|
||||
const formattedBestScore = useMemo(() => formatNumber(props.bestScore), [props.bestScore]);
|
||||
|
||||
return (
|
||||
<HStack space={screenSize === 'xl' ? 2 : 1} style={styles.container}>
|
||||
<HStack space={screenSize === 'xl' ? 2 : 1} style={[styles.container, props.style]}>
|
||||
<Stack style={{ position: 'relative', overflow: 'hidden' }}>
|
||||
<IconButton
|
||||
containerStyle={styles.playButtonContainer}
|
||||
|
||||
135
front/components/UI/MusicList copy.tsx
Normal file
135
front/components/UI/MusicList copy.tsx
Normal file
@@ -0,0 +1,135 @@
|
||||
import { FlatList, HStack, View, useBreakpointValue, useTheme, Text, Row } from "native-base";
|
||||
import MusicItem, { MusicItemType } from "./MusicItem";
|
||||
import React, { useState } from "react";
|
||||
import { ActivityIndicator } from "react-native";
|
||||
import { ArrowDown2, ArrowRotateLeft, Chart2, Cup, Icon } from "iconsax-react-native";
|
||||
import { StyleSheet } from 'react-native';
|
||||
import ButtonBase from "./ButtonBase";
|
||||
import useColorScheme from "../../hooks/colorScheme";
|
||||
|
||||
interface MusicItemTitleProps {
|
||||
text: string;
|
||||
icon: Icon;
|
||||
isBigScreen: boolean;
|
||||
}
|
||||
|
||||
const MusicItemTitle = (props: MusicItemTitleProps) => {
|
||||
const colorScheme = useColorScheme();
|
||||
|
||||
return (
|
||||
<Row
|
||||
style={{
|
||||
display: 'flex',
|
||||
flex: 1,
|
||||
maxWidth: props.isBigScreen ? 150 : 50,
|
||||
height: '100%',
|
||||
alignItems: 'center',
|
||||
justifyContent: props.isBigScreen ? 'flex-end' : 'center',
|
||||
}}
|
||||
>
|
||||
{props.isBigScreen && (
|
||||
<Text fontSize="lg" style={{ paddingRight: 8 }}>
|
||||
{props.text}
|
||||
</Text>
|
||||
)}
|
||||
<props.icon
|
||||
size={18}
|
||||
color={colorScheme === 'light' ? 'rgba(0,0,0,0.7)' : 'rgba(255,255,255,0.7)'}
|
||||
/>
|
||||
</Row>
|
||||
);
|
||||
};
|
||||
|
||||
type MusicListProps = {
|
||||
initialMusics: MusicItemType[];
|
||||
loadMoreMusics: (page: number) => Promise<MusicItemType[]>; // fonction pour charger plus de musiques
|
||||
};
|
||||
|
||||
const MusicList: React.FC<MusicListProps> = ({initialMusics}) => {
|
||||
const [musicData, setMusicData] = useState<MusicItemType[]>(initialMusics);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const { colors } = useTheme();
|
||||
const screenSize = useBreakpointValue({ base: 'small', md: 'md', xl: 'xl' });
|
||||
const isSmallScreen = screenSize === 'small';
|
||||
const isBigScreen = screenSize === 'xl';
|
||||
|
||||
const loadMoreMusicItems = () => {
|
||||
if (!loading) {
|
||||
setLoading(true);
|
||||
setTimeout(() => {
|
||||
const moreItems: MusicItemType[] = [
|
||||
];
|
||||
setMusicData((currentItems) => [...currentItems, ...moreItems]);
|
||||
setLoading(false);
|
||||
}, 2000); // Simule un appel réseau avec un délai de 2 secondes.
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<View>
|
||||
<View style={styles.container}>
|
||||
<HStack
|
||||
space={isSmallScreen ? 1 : 2}
|
||||
style={{
|
||||
backgroundColor: colors.coolGray[500],
|
||||
paddingHorizontal: isSmallScreen ? 8 : 16,
|
||||
paddingVertical: 12,
|
||||
}}
|
||||
>
|
||||
<Text
|
||||
fontSize="lg"
|
||||
style={{ flex: 4, width: '100%', justifyContent: 'center', paddingRight: 60 }}
|
||||
>
|
||||
Song
|
||||
</Text>
|
||||
{[
|
||||
{ text: 'level', icon: Chart2 },
|
||||
{ text: 'lastScore', icon: ArrowRotateLeft },
|
||||
{ text: 'BastScore', icon: Cup },
|
||||
].map((value) => (
|
||||
<MusicItemTitle
|
||||
key={value.text + 'key'}
|
||||
text={value.text}
|
||||
icon={value.icon}
|
||||
isBigScreen={isBigScreen}
|
||||
/>
|
||||
))}
|
||||
</HStack>
|
||||
<FlatList
|
||||
data={musicData}
|
||||
renderItem={({ item }) => <MusicItem style={{marginBottom: 2}} {...item} />}
|
||||
keyExtractor={(item) => item.artist + item.song}
|
||||
/>
|
||||
</View>
|
||||
<View style={styles.footerContainer}>
|
||||
{loading ? (
|
||||
<ActivityIndicator
|
||||
color={colors.primary[300]}
|
||||
/>
|
||||
) : (
|
||||
<ButtonBase
|
||||
style={{borderRadius: 999}}
|
||||
onPress={loadMoreMusicItems}
|
||||
icon={ArrowDown2}
|
||||
/>
|
||||
)}
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
gap: 2,
|
||||
borderRadius: 10,
|
||||
overflow: 'hidden',
|
||||
},
|
||||
footerContainer : {
|
||||
height: 60,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
}
|
||||
});
|
||||
|
||||
export default MusicList;
|
||||
@@ -1,26 +1,63 @@
|
||||
import { FlatList, View } from "native-base";
|
||||
import { FlatList, HStack, View, useBreakpointValue, useTheme, Text, Row } from "native-base";
|
||||
import MusicItem, { MusicItemType } from "./MusicItem";
|
||||
import IconButton from "./IconButton";
|
||||
import React, { useState } from "react";
|
||||
import { ActivityIndicator } from "react-native";
|
||||
import { ArrowCircleDown, ArrowDown } from "iconsax-react-native";
|
||||
import { ArrowDown2, ArrowRotateLeft, Chart2, Cup, Icon } from "iconsax-react-native";
|
||||
import { StyleSheet } from 'react-native';
|
||||
import ButtonBase from "./ButtonBase";
|
||||
import useColorScheme from "../../hooks/colorScheme";
|
||||
|
||||
type MusicListProps = {
|
||||
musics: MusicItemType[];
|
||||
interface MusicItemTitleProps {
|
||||
text: string;
|
||||
icon: Icon;
|
||||
isBigScreen: boolean;
|
||||
}
|
||||
|
||||
const MusicList: React.FC<MusicListProps> = ({musics}) => {
|
||||
const [musicData, setMusicData] = useState<MusicItemType[]>(musics);
|
||||
const MusicItemTitle = (props: MusicItemTitleProps) => {
|
||||
const colorScheme = useColorScheme();
|
||||
|
||||
return (
|
||||
<Row
|
||||
style={{
|
||||
display: 'flex',
|
||||
flex: 1,
|
||||
maxWidth: props.isBigScreen ? 150 : 50,
|
||||
height: '100%',
|
||||
alignItems: 'center',
|
||||
justifyContent: props.isBigScreen ? 'flex-end' : 'center',
|
||||
}}
|
||||
>
|
||||
{props.isBigScreen && (
|
||||
<Text fontSize="lg" style={{ paddingRight: 8 }}>
|
||||
{props.text}
|
||||
</Text>
|
||||
)}
|
||||
<props.icon
|
||||
size={18}
|
||||
color={colorScheme === 'light' ? 'rgba(0,0,0,0.7)' : 'rgba(255,255,255,0.7)'}
|
||||
/>
|
||||
</Row>
|
||||
);
|
||||
};
|
||||
|
||||
type MusicListProps = {
|
||||
initialMusics: MusicItemType[];
|
||||
loadMoreMusics: (page: number) => Promise<MusicItemType[]>; // fonction pour charger plus de musiques
|
||||
};
|
||||
|
||||
const MusicList: React.FC<MusicListProps> = ({initialMusics}) => {
|
||||
const [musicData, setMusicData] = useState<MusicItemType[]>(initialMusics);
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
// Supposons que vous ayez une fonction pour charger plus de données (simulée ici avec un setTimeout).
|
||||
const { colors } = useTheme();
|
||||
const screenSize = useBreakpointValue({ base: 'small', md: 'md', xl: 'xl' });
|
||||
const isSmallScreen = screenSize === 'small';
|
||||
const isBigScreen = screenSize === 'xl';
|
||||
|
||||
const loadMoreMusicItems = () => {
|
||||
if (!loading) {
|
||||
setLoading(true);
|
||||
setTimeout(() => {
|
||||
const moreItems: MusicItemType[] = [
|
||||
// ... ajoutez de nouveaux éléments ici
|
||||
];
|
||||
setMusicData((currentItems) => [...currentItems, ...moreItems]);
|
||||
setLoading(false);
|
||||
@@ -29,41 +66,70 @@ const MusicList: React.FC<MusicListProps> = ({musics}) => {
|
||||
};
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<FlatList
|
||||
data={musicData}
|
||||
renderItem={({ item }) => (
|
||||
<MusicItem
|
||||
image={item.image}
|
||||
liked={item.liked}
|
||||
onLike={item.onLike}
|
||||
onPlay={item.onPlay}
|
||||
level={item.level}
|
||||
lastScore={item.lastScore}
|
||||
bestScore={item.bestScore}
|
||||
artist={item.artist}
|
||||
song={item.song}
|
||||
/>
|
||||
<View>
|
||||
<View style={styles.container}>
|
||||
<HStack
|
||||
space={isSmallScreen ? 1 : 2}
|
||||
style={{
|
||||
backgroundColor: colors.coolGray[500],
|
||||
paddingHorizontal: isSmallScreen ? 8 : 16,
|
||||
paddingVertical: 12,
|
||||
}}
|
||||
>
|
||||
<Text
|
||||
fontSize="lg"
|
||||
style={{ flex: 4, width: '100%', justifyContent: 'center', paddingRight: 60 }}
|
||||
>
|
||||
Song
|
||||
</Text>
|
||||
{[
|
||||
{ text: 'level', icon: Chart2 },
|
||||
{ text: 'lastScore', icon: ArrowRotateLeft },
|
||||
{ text: 'BastScore', icon: Cup },
|
||||
].map((value) => (
|
||||
<MusicItemTitle
|
||||
key={value.text + 'key'}
|
||||
text={value.text}
|
||||
icon={value.icon}
|
||||
isBigScreen={isBigScreen}
|
||||
/>
|
||||
))}
|
||||
</HStack>
|
||||
<FlatList
|
||||
data={musicData}
|
||||
renderItem={({ item }) => <MusicItem style={{marginBottom: 2}} {...item} />}
|
||||
keyExtractor={(item) => item.artist + item.song}
|
||||
/>
|
||||
</View>
|
||||
<View style={styles.footerContainer}>
|
||||
{loading ? (
|
||||
<ActivityIndicator
|
||||
color={colors.primary[300]}
|
||||
/>
|
||||
) : (
|
||||
<ButtonBase
|
||||
style={{borderRadius: 999}}
|
||||
onPress={loadMoreMusicItems}
|
||||
icon={ArrowDown2}
|
||||
/>
|
||||
)}
|
||||
keyExtractor={(item) => item.artist + item.song}
|
||||
ListFooterComponent={() => (
|
||||
loading ? <ActivityIndicator size="large" color="#0000ff" /> : null
|
||||
)}
|
||||
/>
|
||||
<IconButton
|
||||
onPress={loadMoreMusicItems}
|
||||
color={"#000"}
|
||||
icon={ArrowCircleDown}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
gap: 2,
|
||||
borderRadius: 10,
|
||||
overflow: 'hidden',
|
||||
},
|
||||
// Ajoutez d'autres styles si nécessaire.
|
||||
});
|
||||
|
||||
export default MusicList;
|
||||
footerContainer : {
|
||||
height: 60,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
}
|
||||
});
|
||||
|
||||
export default MusicList;
|
||||
@@ -36,13 +36,12 @@ const ScaffoldMobileCC = (props: ScaffoldMobileCCProps) => {
|
||||
flex: 1,
|
||||
maxHeight: '100%',
|
||||
flexDirection: 'column',
|
||||
backgroundColor: '#f00',
|
||||
flexShrink: 0,
|
||||
padding: props.widthPadding ? 8 : 0,
|
||||
}}
|
||||
contentContainerStyle={{ flex: 1 }}
|
||||
>
|
||||
<View style={{ flex: 1 }}>{props.children}</View>
|
||||
<View>{props.children}</View>
|
||||
<Spacer />
|
||||
</ScrollView>
|
||||
<View style={{ padding: 8, paddingTop: 0 }}>
|
||||
|
||||
@@ -24,42 +24,9 @@ import useColorScheme from '../hooks/colorScheme';
|
||||
import { RouteProps } from '../Navigation';
|
||||
import { translate } from '../i18n/i18n';
|
||||
import ScaffoldCC from '../components/UI/ScaffoldCC';
|
||||
import MusicItem from '../components/UI/MusicItem';
|
||||
import MusicItem, { MusicItemType } from '../components/UI/MusicItem';
|
||||
import MusicList from '../components/UI/MusicList';
|
||||
|
||||
interface MusicItemTitleProps {
|
||||
text: string;
|
||||
icon: Icon;
|
||||
isBigScreen: boolean;
|
||||
}
|
||||
|
||||
const MusicItemTitle = (props: MusicItemTitleProps) => {
|
||||
const colorScheme = useColorScheme();
|
||||
|
||||
return (
|
||||
<Row
|
||||
style={{
|
||||
display: 'flex',
|
||||
flex: 1,
|
||||
maxWidth: props.isBigScreen ? 150 : 50,
|
||||
height: '100%',
|
||||
alignItems: 'center',
|
||||
justifyContent: props.isBigScreen ? 'flex-end' : 'center',
|
||||
}}
|
||||
>
|
||||
{props.isBigScreen && (
|
||||
<Text fontSize="lg" style={{ paddingRight: 8 }}>
|
||||
{props.text}
|
||||
</Text>
|
||||
)}
|
||||
<props.icon
|
||||
size={18}
|
||||
color={colorScheme === 'light' ? 'rgba(0,0,0,0.7)' : 'rgba(255,255,255,0.7)'}
|
||||
/>
|
||||
</Row>
|
||||
);
|
||||
};
|
||||
|
||||
// Fichier de données fictives, par exemple MusicData.ts
|
||||
export const fakeMusicData = [
|
||||
{
|
||||
@@ -208,35 +175,14 @@ export const FavoritesMusic = () => {
|
||||
const isBigScreen = screenSize === 'xl';
|
||||
|
||||
return (
|
||||
<Stack style={{ gap: 2, borderRadius: 10, overflow: 'hidden' }}>
|
||||
<HStack
|
||||
space={isSmallScreen ? 1 : 2}
|
||||
style={{
|
||||
backgroundColor: colors.coolGray[500],
|
||||
paddingHorizontal: isSmallScreen ? 8 : 16,
|
||||
paddingVertical: 12,
|
||||
<>
|
||||
<MusicList
|
||||
initialMusics={fakeMusicData}
|
||||
loadMoreMusics={async (page: number) => {
|
||||
console.log(page, 'Function not implemented.');
|
||||
return [];
|
||||
}}
|
||||
>
|
||||
<Text
|
||||
fontSize="lg"
|
||||
style={{ flex: 4, width: '100%', justifyContent: 'center', paddingRight: 60 }}
|
||||
>
|
||||
Song
|
||||
</Text>
|
||||
{[
|
||||
{ text: 'level', icon: Chart2 },
|
||||
{ text: 'lastScore', icon: ArrowRotateLeft },
|
||||
{ text: 'BastScore', icon: Cup },
|
||||
].map((value) => (
|
||||
<MusicItemTitle
|
||||
key={value.text + 'key'}
|
||||
text={value.text}
|
||||
icon={value.icon}
|
||||
isBigScreen={isBigScreen}
|
||||
/>
|
||||
))}
|
||||
</HStack>
|
||||
<MusicList musics={fakeMusicData}/>
|
||||
/>
|
||||
{/* <MusicItem
|
||||
image={
|
||||
'https://static.vecteezy.com/system/resources/previews/016/552/335/non_2x/luffy-kawai-chibi-cute-onepiece-anime-design-and-doodle-art-for-icon-logo-collection-and-others-free-vector.jpg'
|
||||
@@ -265,7 +211,7 @@ export const FavoritesMusic = () => {
|
||||
artist={'Ludwig van Beethoven'}
|
||||
song={'Sonata for Piano no. 20 in G major, op. 49 no. 2'}
|
||||
/> */}
|
||||
</Stack>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user