[ADD] SettingsView: translation, Menu: collapsed mode && translation
This commit is contained in:
@@ -24,12 +24,13 @@ const handleSubmit = async (username: string, password: string, email: string) =
|
||||
};
|
||||
|
||||
type LogoutButtonCCProps = {
|
||||
collapse?: boolean;
|
||||
isGuest?: boolean;
|
||||
style: any;
|
||||
buttonType: ButtonType
|
||||
};
|
||||
|
||||
const LogoutButtonCC = ({isGuest = false, buttonType = 'menu', style}: LogoutButtonCCProps) => {
|
||||
const LogoutButtonCC = ({collapse = false, isGuest = false, buttonType = 'menu', style}: LogoutButtonCCProps) => {
|
||||
const dispatch = useDispatch();
|
||||
const [isVisible, setIsVisible] = useState(false);
|
||||
|
||||
@@ -38,7 +39,7 @@ const LogoutButtonCC = ({isGuest = false, buttonType = 'menu', style}: LogoutBut
|
||||
<ButtonBase
|
||||
style={style}
|
||||
icon={LogoutCurve}
|
||||
title={translate('signOutBtn')}
|
||||
title={collapse ? translate('signOutBtn') : undefined}
|
||||
type={buttonType}
|
||||
onPress={async () => {isGuest ? setIsVisible(true) : dispatch(unsetAccessToken());}}
|
||||
/>
|
||||
@@ -50,7 +51,7 @@ const LogoutButtonCC = ({isGuest = false, buttonType = 'menu', style}: LogoutBut
|
||||
>
|
||||
<SignUpForm onSubmit={handleSubmit} />
|
||||
<ButtonBase
|
||||
style={{width: '100%'}}
|
||||
style={!collapse ? { width: '100%' } : {}}
|
||||
type="outlined"
|
||||
icon={LogoutCurve}
|
||||
title={translate('signOutBtn')}
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
import { View, Image } from 'react-native';
|
||||
import { Divider, Text, ScrollView, Flex, Row, Popover, Heading, Button, useBreakpointValue } from 'native-base';
|
||||
import { Flex, useBreakpointValue } from 'native-base';
|
||||
import useColorScheme from '../../hooks/colorScheme';
|
||||
import { useQuery, useQueries } from '../../Queries';
|
||||
import { useQuery } from '../../Queries';
|
||||
import API from '../../API';
|
||||
import Song from '../../models/Song';
|
||||
import { LinearGradient } from 'expo-linear-gradient';
|
||||
import ButtonBase from './ButtonBase';
|
||||
import {
|
||||
Cup,
|
||||
Discover,
|
||||
@@ -15,12 +12,7 @@ import {
|
||||
Setting2,
|
||||
User,
|
||||
} from 'iconsax-react-native';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { LoadingView } from '../Loading';
|
||||
import { translate } from '../../i18n/i18n';
|
||||
import { unsetAccessToken } from '../../state/UserSlice';
|
||||
import { useNavigation } from '../../Navigation';
|
||||
import Spacer from './Spacer';
|
||||
import ScaffoldDesktopCC from './ScaffoldDesktopCC';
|
||||
import ScaffoldMobileCC from './ScaffoldMobileCC';
|
||||
|
||||
@@ -30,12 +22,12 @@ const menu: {
|
||||
icon: Icon;
|
||||
link: string;
|
||||
}[] = [
|
||||
{ type: "main", title: 'Discovery', icon: Discover, link: 'HomeNew' },
|
||||
{ type: "main", title: 'Profile', icon: User, link: 'User' },
|
||||
{ type: "main", title: 'Music', icon: Music, link: 'Home' },
|
||||
{ type: "main", title: 'Search', icon: SearchNormal1, link: 'Search' },
|
||||
{ type: "main", title: 'LeaderBoard', icon: Cup, link: 'Score' },
|
||||
{ type: "sub", title: 'Settings', icon: Setting2, link: 'Settings' },
|
||||
{ type: "main", title: 'menuDiscovery', icon: Discover, link: 'HomeNew' },
|
||||
{ type: "main", title: 'menuProfile', icon: User, link: 'User' },
|
||||
{ type: "main", title: 'menuMusic', icon: Music, link: 'Home' },
|
||||
{ type: "main", title: 'menuSearch', icon: SearchNormal1, link: 'Search' },
|
||||
{ type: "main", title: 'menuLeaderBoard', icon: Cup, link: 'Score' },
|
||||
{ type: "sub", title: 'menuSettings', icon: Setting2, link: 'Settings' },
|
||||
];
|
||||
|
||||
type ScaffoldCCProps = {
|
||||
|
||||
@@ -30,61 +30,95 @@ type ScaffoldDesktopCCProps = {
|
||||
}[]
|
||||
};
|
||||
|
||||
const ScaffoldDesktopCC = (props: ScaffoldDesktopCCProps) => {
|
||||
const navigation = useNavigation();
|
||||
const userQuery = useQuery(API.getUserInfo);
|
||||
const [isSmallScreen] = useMediaQuery({ maxWidth: 400 });
|
||||
const layout = useWindowDimensions();
|
||||
const colorScheme = useColorScheme();
|
||||
|
||||
if (!userQuery.data || userQuery.isLoading) {
|
||||
return <LoadingView />;
|
||||
}
|
||||
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: 300,
|
||||
width: !isSmallScreen ? 300 : undefined,
|
||||
padding: 20,
|
||||
flexDirection: 'column',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'flex-start',
|
||||
alignItems: isSmallScreen ? 'center' : 'flex-start',
|
||||
flexShrink: 0,
|
||||
}}
|
||||
>
|
||||
<View style={{ width: '100%' }}>
|
||||
<Row space={2} flex={1}>
|
||||
<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',
|
||||
}}
|
||||
/>
|
||||
{layout.width > 650 &&
|
||||
{!isSmallScreen &&
|
||||
<Text fontSize={'xl'} selectable={false}>
|
||||
Chromacase
|
||||
</Text>
|
||||
}
|
||||
</Row>
|
||||
<Spacer height="lg" />
|
||||
<View style={{ width: '100%' }}>
|
||||
<View>
|
||||
{props.menu.map((value) => (
|
||||
value.type === "main" &&
|
||||
<View key={'key-menu-link-' + value.title}>
|
||||
<ButtonBase
|
||||
style={{ width: '100%' }}
|
||||
style={!isSmallScreen ? { width: '100%' } : {}}
|
||||
type="menu"
|
||||
icon={value.icon}
|
||||
title={value.title}
|
||||
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'
|
||||
@@ -98,61 +132,35 @@ const ScaffoldDesktopCC = (props: ScaffoldDesktopCCProps) => {
|
||||
))}
|
||||
</View>
|
||||
</View>
|
||||
<View style={{ width: '100%' }}>
|
||||
<Divider my="2" _light={{bg: colors.black[500]}} _dark={{bg:'#FFF'}}/>
|
||||
<Spacer height='xs'/>
|
||||
<Text
|
||||
bold
|
||||
style={{
|
||||
paddingHorizontal: 16,
|
||||
paddingVertical: 10,
|
||||
fontSize: 20,
|
||||
}}
|
||||
>
|
||||
Recently played
|
||||
</Text>
|
||||
{songHistory.length === 0 && (
|
||||
{!isSmallScreen &&
|
||||
<View>
|
||||
<Divider my="2" _light={{bg: colors.black[500]}} _dark={{bg:'#FFF'}}/>
|
||||
<Spacer height='xs'/>
|
||||
<Text
|
||||
bold
|
||||
style={{
|
||||
paddingHorizontal: 16,
|
||||
paddingVertical: 10,
|
||||
paddingBottom: 10,
|
||||
fontSize: 20,
|
||||
}}
|
||||
>
|
||||
No songs played yet
|
||||
{translate('menuRecentlyPlayed')}
|
||||
</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, 4)
|
||||
.map((histoItem, index) => (
|
||||
<View
|
||||
key={'tab-navigation-other-' + index}
|
||||
style={{
|
||||
paddingHorizontal: 16,
|
||||
paddingVertical: 10,
|
||||
}}
|
||||
>
|
||||
<Text numberOfLines={1}>{histoItem.name}</Text>
|
||||
</View>
|
||||
))}
|
||||
</View>
|
||||
<SongHistory quantity={3}/>
|
||||
</View>
|
||||
}
|
||||
<Spacer height='xs'/>
|
||||
<View style={{ width: '100%' }}>
|
||||
<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={{ width: '100%' }}
|
||||
style={!isSmallScreen ? { width: '100%' } : {}}
|
||||
type="menu"
|
||||
icon={value.icon}
|
||||
title={!isSmallScreen ? value.title : undefined}
|
||||
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'
|
||||
@@ -163,7 +171,7 @@ const ScaffoldDesktopCC = (props: ScaffoldDesktopCCProps) => {
|
||||
/>
|
||||
))}
|
||||
<Spacer height='xs'/>
|
||||
<LogoutButtonCC isGuest={props.user.isGuest} style={{with: '100%'}} buttonType={'menu'}/>
|
||||
<LogoutButtonCC collapse={!isSmallScreen} isGuest={props.user.isGuest} style={!isSmallScreen ? { width: '100%' } : {}} buttonType={'menu'}/>
|
||||
</View>
|
||||
</View>
|
||||
<ScrollView
|
||||
@@ -176,6 +184,7 @@ const ScaffoldDesktopCC = (props: ScaffoldDesktopCCProps) => {
|
||||
flex: 1,
|
||||
margin: 8,
|
||||
marginBottom: 0,
|
||||
marginLeft: 0,
|
||||
padding: props.widthPadding ? 20 : 0,
|
||||
borderRadius: 12,
|
||||
minHeight: 'fit-content',
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { View, useWindowDimensions } from 'react-native';
|
||||
import { ScrollView, Flex, useBreakpointValue, useMediaQuery, useTheme } from 'native-base';
|
||||
import { LinearGradient } from 'expo-linear-gradient';
|
||||
import { View } from 'react-native';
|
||||
import { ScrollView, Flex, useMediaQuery, useTheme } from 'native-base';
|
||||
import ButtonBase from './ButtonBase';
|
||||
import { Icon } from 'iconsax-react-native';
|
||||
import { useNavigation } from '../../Navigation';
|
||||
import Spacer from './Spacer';
|
||||
import User from '../../models/User';
|
||||
import { translate } from '../../i18n/i18n';
|
||||
|
||||
type ScaffoldMobileCCProps = {
|
||||
children?: React.ReactNode;
|
||||
@@ -61,7 +61,7 @@ const ScaffoldMobileCC = (props: ScaffoldMobileCCProps) => {
|
||||
key={'key-menu-link-' + value.title}
|
||||
type="menu"
|
||||
icon={value.icon}
|
||||
title={props.routeName === value.link && !isSmallScreen ? value.title : undefined}
|
||||
title={props.routeName === value.link && !isSmallScreen ? translate(value.title as 'menuDiscovery' | 'menuProfile' | 'menuMusic' | 'menuSearch' | 'menuLeaderBoard' | 'menuSettings') : undefined}
|
||||
isDisabled={props.routeName === value.link}
|
||||
iconVariant={
|
||||
props.routeName === value.link ? 'Bold' : 'Outline'
|
||||
|
||||
Reference in New Issue
Block a user