Files
Chromacase/front/components/UI/ScaffoldDesktopCC.tsx
Arthur Jamet 7067fb9708 Front: Pretty
2023-10-28 08:09:21 +02:00

230 lines
6.2 KiB
TypeScript

import { View, Image, useWindowDimensions } from 'react-native';
import { Divider, Text, ScrollView, Flex, Row, useMediaQuery, useTheme } from 'native-base';
import { useQuery, useQueries } from '../../Queries';
import API from '../../API';
import Song from '../../models/Song';
import { LinearGradient } from 'expo-linear-gradient';
import ButtonBase from './ButtonBase';
import { Icon } from 'iconsax-react-native';
import { LoadingView } from '../Loading';
import { translate } from '../../i18n/i18n';
import { useNavigation } from '../../Navigation';
import Spacer from './Spacer';
import User from '../../models/User';
import LogoutButtonCC from './LogoutButtonCC';
import GlassmorphismCC from './Glassmorphism';
import { ColorSchemeProvider } from '../../Theme';
import useColorScheme from '../../hooks/colorScheme';
type ScaffoldDesktopCCProps = {
widthPadding: boolean;
children?: React.ReactNode;
user: User;
logo: string;
routeName: string;
menu: {
type: 'main' | 'sub';
title: string;
icon: Icon;
link: string;
}[];
};
const SongHistory = (props: { quantity: number }) => {
const playHistoryQuery = useQuery(API.getUserPlayHistory);
const songHistory = useQueries(
playHistoryQuery.data?.map(({ songID }) => API.getSong(songID)) ?? []
);
if (!playHistoryQuery.data || playHistoryQuery.isLoading) {
return <LoadingView />;
}
return (
<View>
{songHistory.length === 0 ? (
<Text style={{ paddingHorizontal: 16 }}>{translate('menuNoSongsPlayedYet')}</Text>
) : (
songHistory
.map((h) => h.data)
.filter((data): data is Song => data !== undefined)
.filter(
(song, i, array) =>
array.map((s) => s.id).findIndex((id) => id == song.id) == i
)
.slice(0, props.quantity + 1)
.map((histoItem, index) => (
<View
key={'tab-navigation-other-' + index}
style={{
paddingHorizontal: 16,
paddingVertical: 10,
}}
>
<Text numberOfLines={1}>{histoItem.name}</Text>
</View>
))
)}
</View>
);
};
const ScaffoldDesktopCC = (props: ScaffoldDesktopCCProps) => {
const navigation = useNavigation();
const userQuery = useQuery(API.getUserInfo);
const [isSmallScreen] = useMediaQuery({ maxWidth: 1100 });
const { colors } = useTheme();
if (!userQuery.data || userQuery.isLoading) {
return <LoadingView />;
}
return (
<View style={{ height: '100%', flexDirection: 'row', overflow: 'hidden' }}>
<View
style={{
display: 'flex',
width: !isSmallScreen ? 300 : undefined,
padding: 20,
flexDirection: 'column',
justifyContent: 'space-between',
alignItems: isSmallScreen ? 'center' : 'flex-start',
flexShrink: 0,
}}
>
<View style={!isSmallScreen ? { width: '100%' } : {}}>
<Row space={2} flex={1} style={{ justifyContent: 'center' }}>
<Image
source={{ uri: props.logo }}
style={{
aspectRatio: 1,
width: 32,
height: 32,
alignItems: isSmallScreen ? 'center' : 'flex-start',
}}
/>
{!isSmallScreen && (
<Text fontSize={'xl'} selectable={false}>
Chromacase
</Text>
)}
</Row>
<Spacer height="lg" />
<View>
{props.menu.map(
(value) =>
value.type === 'main' && (
<View key={'key-menu-link-' + value.title}>
<ButtonBase
style={!isSmallScreen ? { width: '100%' } : {}}
type="menu"
icon={value.icon}
title={
!isSmallScreen
? translate(
value.title as
| 'menuDiscovery'
| 'menuProfile'
| 'menuMusic'
| 'menuSearch'
| 'menuLeaderBoard'
| 'menuSettings'
)
: undefined
}
isDisabled={props.routeName === value.link}
iconVariant={
props.routeName === value.link ? 'Bold' : 'Outline'
}
onPress={async () =>
navigation.navigate(value.link as never)
}
/>
<Spacer height="xs" />
</View>
)
)}
</View>
</View>
{!isSmallScreen && (
<View>
<Divider my="2" _light={{ bg: colors.black[500] }} _dark={{ bg: '#FFF' }} />
<Spacer height="xs" />
<Text
bold
style={{
paddingHorizontal: 16,
paddingBottom: 10,
fontSize: 20,
}}
>
{translate('menuRecentlyPlayed')}
</Text>
<SongHistory quantity={3} />
</View>
)}
<Spacer height="xs" />
<View style={!isSmallScreen ? { width: '100%' } : {}}>
<Divider my="2" _light={{ bg: colors.black[500] }} _dark={{ bg: '#FFF' }} />
<Spacer height="xs" />
{props.menu.map(
(value) =>
value.type === 'sub' && (
<ButtonBase
key={'key-menu-link-' + value.title}
style={!isSmallScreen ? { width: '100%' } : {}}
type="menu"
icon={value.icon}
title={
!isSmallScreen
? translate(
value.title as
| 'menuDiscovery'
| 'menuProfile'
| 'menuMusic'
| 'menuSearch'
| 'menuLeaderBoard'
| 'menuSettings'
)
: undefined
}
isDisabled={props.routeName === value.link}
iconVariant={
props.routeName === value.link ? 'Bold' : 'Outline'
}
onPress={async () => navigation.navigate(value.link as never)}
/>
)
)}
<Spacer height="xs" />
<LogoutButtonCC
collapse={!isSmallScreen}
isGuest={props.user.isGuest}
style={!isSmallScreen ? { width: '100%' } : {}}
buttonType={'menu'}
/>
</View>
</View>
<ScrollView style={{ flex: 1, maxHeight: '100vh' }} contentContainerStyle={{ flex: 1 }}>
<GlassmorphismCC
style={{
backgroundColor: colors.coolGray[500],
flex: 1,
margin: 8,
marginBottom: 0,
marginLeft: 0,
padding: props.widthPadding ? 20 : 0,
borderRadius: 12,
minHeight: 'fit-content',
}}
>
{props.children}
</GlassmorphismCC>
<Spacer height="xs" />
</ScrollView>
</View>
);
};
export default ScaffoldDesktopCC;