Front: First Pass on translations + remove unused setting tabs

This commit is contained in:
Arthur Jamet
2023-12-14 16:11:27 +01:00
committed by Clément Le Bihan
parent 00d097f643
commit d3994ff26e
13 changed files with 37 additions and 280 deletions

View File

@@ -20,6 +20,7 @@ import {
} from './ElementTypes';
import { ArrowDown2 } from 'iconsax-react-native';
import { useWindowDimensions } from 'react-native';
import Translate from '../Translate';
type RawElementProps = {
element: ElementProps;
@@ -149,7 +150,7 @@ export const RawElement = ({ element }: RawElementProps) => {
/>
);
default:
return <Text>Unknown type</Text>;
return <Translate translationKey='unknownError'/>
}
})()}
</Row>

View File

@@ -3,6 +3,7 @@ import { Slider, Text, View, IconButton, Icon } from 'native-base';
import { MaterialCommunityIcons } from '@expo/vector-icons';
import { Audio } from 'expo-av';
import { VolumeHigh, VolumeSlash } from 'iconsax-react-native';
import { Translate } from '../i18n/i18n';
export const MetronomeControls = ({ paused = false, bpm }: { paused?: boolean; bpm: number }) => {
const audio = useRef<Audio.Sound | null>(null);
@@ -43,7 +44,7 @@ export const MetronomeControls = ({ paused = false, bpm }: { paused?: boolean; b
justifyContent: 'space-between',
}}
>
<Text>Metronome</Text>
<Translate translationKey="metronome" />
<Icon as={<MaterialCommunityIcons name="metronome" size={24} color="white" />} />
</View>
<View

View File

@@ -1,5 +1,5 @@
import React from 'react';
import { translate } from '../i18n/i18n';
import { Translate, translate } from '../i18n/i18n';
import { Box, Text, VStack, Progress, Stack } from 'native-base';
import { useNavigation } from '../Navigation';
import Card from '../components/Card';
@@ -18,13 +18,14 @@ const ProgressBar = ({ xp }: { xp: number }) => {
<Stack padding={4} space={2} direction="row" alignItems="center">
<UserAvatar />
<VStack alignItems={'center'} flexGrow={1} space={2}>
<Text>{`${translate('level')} ${level}`}</Text>
<Translate translationKey="level" format={(e) => `${e} ${level}`} />
<Box w="100%">
<Progress value={progessValue} mx="4" />
</Box>
<Text>
{xp} / {nextLevelThreshold} {translate('levelProgress')}
</Text>
<Translate
translationKey="levelProgress"
format={(e) => `${xp} / ${nextLevelThreshold} ${e}`}
/>
</VStack>
</Stack>
</Card>

View File

@@ -13,7 +13,7 @@ import {
import { SafeAreaView } from 'react-native';
import { SearchContext } from '../views/SearchView';
import { useQuery } from '../Queries';
import { translate } from '../i18n/i18n';
import { Translate, translate } from '../i18n/i18n';
import API from '../API';
import LoadingComponent, { LoadingView } from './Loading';
import ArtistCard from './ArtistCard';
@@ -115,7 +115,7 @@ const SongsSearchComponent = (props: SongsSearchComponentProps) => {
/>
))
) : (
<Text>{translate('errNoResults')}</Text>
<Translate translationKey="errNoResults" />
)}
</Box>
</ScrollView>
@@ -151,7 +151,7 @@ const ArtistSearchComponent = (props: ItemSearchComponentProps) => {
cardComponent={ArtistCard}
/>
) : (
<Text>{translate('errNoResults')}</Text>
<Translate translationKey="errNoResults" />
)}
</Box>
);
@@ -180,7 +180,7 @@ const GenreSearchComponent = (props: ItemSearchComponentProps) => {
cardComponent={GenreCard}
/>
) : (
<Text>{translate('errNoResults')}</Text>
<Translate translationKey="errNoResults" />
)}
</Box>
);
@@ -268,7 +268,7 @@ const FilterSwitch = () => {
case 'favorites':
return <FavoritesComponent />;
default:
return <Text>Something very bad happened: {currentFilter}</Text>;
return <Translate translationKey='unknownError' format={(e) => `${e}: ${currentFilter}`}/>;
}
};

View File

@@ -226,9 +226,6 @@ export const en = {
SettingsPreferencesTabLanguageSectionDescription: 'Set the language of your application',
SettingsPreferencesTabDifficultySectionTitle: 'Difficulty',
SettingsPreferencesTabDifficultySectionDescription: 'The precision of the tempo increases',
SettingsPreferencesTabColorblindModeSectionTitle: 'Colorblind Mode',
SettingsPreferencesTabColorblindModeSectionDescription: 'Increases contrast',
SettingsPreferencesTabMicVolumeSectionTitle: 'Mic Volume',
SettingsPreferencesTabMicVolumeSectionDescription:
'Adjust the volume of your microphone according to your preference',
// Notifications Tab
@@ -277,7 +274,6 @@ export const en = {
SettingsPreferencesTheme: 'Theme',
SettingsPreferencesLanguage: 'Language',
SettingsPreferencesDifficulty: 'Difficulty',
SettingsPreferencesColorblindMode: 'Colorblind mode',
SettingsPreferencesMicVolume: 'Mic volume',
SettingsPreferencesDevice: 'Device',
@@ -308,6 +304,10 @@ export const en = {
leaderBoardHeadingFull:
'The players having the best scores, thanks to their exceptional accuracy, are highlighted here.',
emptySelection: 'None,',
gamesPlayed: 'Games Played',
metronome: 'Metronome',
loading: "Loading... Please Wait",
emailCheckFailed: 'Email verification failed. The token has expired or is invalid.'
};
export const fr: typeof en = {
@@ -371,7 +371,7 @@ export const fr: typeof en = {
menuLeaderBoard: 'Classement',
menuSettings: 'Paramètres',
menuRecentlyPlayed: 'Récemment jouée',
menuRecentlyPlayed: 'Récemment joués',
menuNoSongsPlayedYet: "Aucune chanson jouée pour l'instant",
//signup
@@ -389,7 +389,7 @@ export const fr: typeof en = {
//music
musicTabFavorites: 'Favoris',
musicTabRecentlyPlayed: 'Récemment joué',
musicTabStepUp: 'Recommandation',
musicTabStepUp: 'Recommandations',
//search
allFilter: 'Tout',
@@ -538,9 +538,6 @@ export const fr: typeof en = {
SettingsPreferencesTabDifficultySectionTitle: 'Difficulté',
SettingsPreferencesTabDifficultySectionDescription:
'La précision du tempo est de plus en plus élevée',
SettingsPreferencesTabColorblindModeSectionTitle: 'Mode daltonien',
SettingsPreferencesTabColorblindModeSectionDescription: 'Augmente le contraste',
SettingsPreferencesTabMicVolumeSectionTitle: 'Volume du micro',
SettingsPreferencesTabMicVolumeSectionDescription:
'Réglez le volume de votre micro selon vos préférences',
// Notifications Tab
@@ -582,8 +579,6 @@ export const fr: typeof en = {
SettingsNotificationsPushNotifications: 'Notifications push',
SettingsNotificationsReleaseAlert: 'Alertes de nouvelles Sorties',
SettingsNotificationsTrainingReminder: "Rappel d'entrainement",
SettingsPreferencesColorblindMode: 'Mode daltonien',
SettingsPreferencesDevice: 'Appareil',
SettingsPreferencesDifficulty: 'Difficulté',
SettingsPreferencesLanguage: 'Langue',
@@ -621,6 +616,10 @@ export const fr: typeof en = {
leaderBoardHeadingFull:
'Les joueurs présentant les meilleurs scores, grâce à leur précision exceptionnelle, sont mis en lumière ici.',
emptySelection: 'Aucun',
gamesPlayed: 'Parties Jouées',
metronome: 'Métronome',
loading: "Chargement en cours... Veuillez Patienter",
emailCheckFailed: 'Email verification failed. The token has expired or is invalid.'
};
export const sp: typeof en = {
@@ -854,9 +853,6 @@ export const sp: typeof en = {
SettingsPreferencesTabLanguageSectionDescription: 'Establece el idioma de tu aplicación',
SettingsPreferencesTabDifficultySectionTitle: 'Dificultad',
SettingsPreferencesTabDifficultySectionDescription: 'La precisión del tempo aumenta',
SettingsPreferencesTabColorblindModeSectionTitle: 'Modo para daltónicos',
SettingsPreferencesTabColorblindModeSectionDescription: 'Aumenta el contraste',
SettingsPreferencesTabMicVolumeSectionTitle: 'Volumen del micrófono',
SettingsPreferencesTabMicVolumeSectionDescription:
'Ajusta el volumen de tu micrófono según tus preferencias',
// Notifications Tab
@@ -900,7 +896,6 @@ export const sp: typeof en = {
SettingsNotificationsReleaseAlert: 'Alertas de nuevas Sorties',
SettingsNotificationsTrainingReminder: 'Recordatorio de entrenamiento',
SettingsPreferencesColorblindMode: 'Modo daltoniano',
SettingsPreferencesDevice: 'Dispositivo',
SettingsPreferencesDifficulty: 'Dificultad',
SettingsPreferencesLanguage: 'Idioma',

View File

@@ -5,6 +5,7 @@ import { setAccessToken } from '../state/UserSlice';
import { Text } from 'native-base';
import { useRoute } from '@react-navigation/native';
import { AccessTokenResponseHandler } from '../models/AccessTokenResponse';
import { Translate } from '../i18n/i18n';
const GoogleView = () => {
const dispatch = useDispatch();
@@ -25,7 +26,7 @@ const GoogleView = () => {
run();
}, []);
return <Text>Loading please wait</Text>;
return <Translate translate={'loading'} />
};
export default GoogleView;

View File

@@ -12,7 +12,7 @@ import {
import { Heart, Clock, StatusUp, FolderCross } from 'iconsax-react-native';
import { Scene } from 'react-native-tab-view/lib/typescript/src/types';
import { RouteProps, useNavigation } from '../Navigation';
import { TranslationKey, translate } from '../i18n/i18n';
import { Translate, TranslationKey, translate } from '../i18n/i18n';
import ScaffoldCC from '../components/UI/ScaffoldCC';
import MusicList from '../components/UI/MusicList';
import { useQuery } from '../Queries';
@@ -98,7 +98,7 @@ export const FavoritesMusic = () => {
export const RecentlyPlayedMusic = () => {
return (
<Center style={{ flex: 1 }}>
<Text>RecentlyPlayedMusic</Text>
<Translate translationKey='recentlyPlayed' />
</Center>
);
};
@@ -106,7 +106,7 @@ export const RecentlyPlayedMusic = () => {
export const StepUpMusic = () => {
return (
<Center style={{ flex: 1 }}>
<Text>StepUpMusic</Text>
<Translate translationKey='musicTabStepUp'/>
</Center>
);
};

View File

@@ -7,7 +7,7 @@ import { LoadingView } from '../components/Loading';
import { useQuery } from '../Queries';
import API from '../API';
import ButtonBase from '../components/UI/ButtonBase';
import { translate } from '../i18n/i18n';
import { Translate, translate } from '../i18n/i18n';
import ScoreGraph from '../components/ScoreGraph';
import ScaffoldCC from '../components/UI/ScaffoldCC';
@@ -99,7 +99,7 @@ const ProfileView = (props: RouteProps<{}>) => {
<Text style={{ paddingRight: 20 }}>
Your client ID is {userQuery.data.id}
</Text>
<Text>{userQuery.data.data.gamesPlayed} Games played</Text>
<Translate translationKey="gamesPlayed" format={(e) => `${userQuery.data.data.gamesPlayed} ${e}`} />
</Flex>
</Column>
</View>

View File

@@ -1,8 +1,8 @@
import { useEffect, useState } from 'react';
import API from '../API';
import { Text } from 'native-base';
import { useNavigation } from '../Navigation';
import { useRoute } from '@react-navigation/native';
import { Translate } from '../i18n/i18n';
const VerifiedView = () => {
const navigation = useNavigation();
@@ -26,9 +26,9 @@ const VerifiedView = () => {
}, []);
return failed ? (
<Text>Email verification failed. The token has expired or is invalid.</Text>
<Translate translationKey={'emailCheckFailed'} />
) : (
<Text>Loading please wait</Text>
<Translate translationKey={'loading'} />
);
};

View File

@@ -1,95 +0,0 @@
import React from 'react';
import { translate } from '../../i18n/i18n';
import ElementList from '../../components/GtkUI/ElementList';
import useUserSettings from '../../hooks/userSettings';
import { LoadingView } from '../../components/Loading';
import { Calendar1, MonitorMobbile, Send2, Warning2 } from 'iconsax-react-native';
const NotificationsSettings = () => {
const { settings, updateSettings } = useUserSettings();
if (!settings.data) {
return <LoadingView />;
}
return (
<ElementList
style={{ width: '100%' }}
elements={[
{
type: 'toggle',
icon: MonitorMobbile,
title: translate('SettingsNotificationsTabPushNotificationsSectionTitle'),
description: translate(
'SettingsNotificationsTabPushNotificationsSectionDescription'
),
data: {
value: settings.data.notifications.pushNotif,
onToggle: () => {
updateSettings({
notifications: {
pushNotif: !settings.data.notifications.pushNotif,
},
});
},
},
},
{
type: 'toggle',
icon: Send2,
title: translate('SettingsNotificationsTabEmailNotificationsSectionTitle'),
description: translate(
'SettingsNotificationsTabEmailNotificationsSectionDescription'
),
data: {
value: settings.data.notifications.emailNotif,
onToggle: () => {
updateSettings({
notifications: {
emailNotif: !settings.data.notifications.emailNotif,
},
});
},
},
},
{
type: 'toggle',
icon: Calendar1,
title: translate('SettingsNotificationsTabTrainingReminderSectionTitle'),
description: translate(
'SettingsNotificationsTabTrainingReminderSectionDescription'
),
data: {
value: settings.data.notifications.trainNotif,
onToggle: () => {
updateSettings({
notifications: {
trainNotif: !settings.data.notifications.trainNotif,
},
});
},
},
},
{
type: 'toggle',
icon: Warning2,
title: translate('SettingsNotificationsTabReleaseAlertSectionTitle'),
description: translate(
'SettingsNotificationsTabReleaseAlertSectionDescription'
),
data: {
value: settings.data.notifications.newSongNotif,
onToggle: () => {
updateSettings({
notifications: {
newSongNotif: !settings.data.notifications.newSongNotif,
},
});
},
},
},
]}
/>
);
};
export default NotificationsSettings;

View File

@@ -7,7 +7,7 @@ import { useSelector } from '../../state/Store';
import { updateSettings } from '../../state/SettingsSlice';
import ElementList from '../../components/GtkUI/ElementList';
import LocalSettings from '../../models/LocalSettings';
import { Brush2, Colorfilter, LanguageSquare, Rank, Sound } from 'iconsax-react-native';
import { Brush2, LanguageSquare, Rank } from 'iconsax-react-native';
const PreferencesSettings = () => {
const dispatch = useDispatch();
@@ -84,59 +84,6 @@ const PreferencesSettings = () => {
},
]}
/>
<ElementList
elements={[
{
icon: Colorfilter,
type: 'toggle',
title: translate('SettingsPreferencesTabColorblindModeSectionTitle'),
description: translate(
'SettingsPreferencesTabColorblindModeSectionDescription'
),
data: {
value: settings.colorBlind,
onToggle: () => {
dispatch(updateSettings({ colorBlind: !settings.colorBlind }));
},
},
},
]}
/>
<ElementList
elements={[
{
icon: Sound,
type: 'range',
title: translate('SettingsPreferencesTabMicVolumeSectionTitle'),
description: translate('SettingsPreferencesTabMicVolumeSectionDescription'),
data: {
value: settings.micVolume,
min: 0,
max: 1000,
step: 10,
onChange: (value) => {
dispatch(updateSettings({ micVolume: value }));
},
},
},
/*{
type: "dropdown",
title: translate("SettingsPreferencesDevice"),
data: {
value: settings.preferedInputName || "0",
defaultValue: "0",
onSelect: (itemValue: string) => {
dispatch(updateSettings({ preferedInputName: itemValue }));
},
options: [
{ label: "Mic_0", value: "0" },
{ label: "Mic_1", value: "1" },
{ label: "Mic_2", value: "2" },
],
},
},*/
]}
/>
</Column>
);
};

View File

@@ -1,69 +0,0 @@
import API from '../../API';
import React from 'react';
import { LoadingView } from '../../components/Loading';
import ElementList from '../../components/GtkUI/ElementList';
import { translate } from '../../i18n/i18n';
import { useQuery } from '../../Queries';
import { Designtools, Magicpen, Star1 } from 'iconsax-react-native';
// Too painful to infer the settings-only, typed navigator. Gave up
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const PremiumSettings = () => {
const userQuery = useQuery(API.getUserInfo);
if (!userQuery.data || userQuery.isLoading) {
return <LoadingView />;
}
const user = userQuery.data;
return (
<ElementList
style={{ width: '100%' }}
elements={[
{
icon: Star1,
type: 'text',
title: translate('settingsPremiumTabPremiumAccountSectionTitle'),
description: translate('settingsPremiumTabPremiumAccountSectionDescription'),
data: {
text: translate(user.premium ? 'yes' : 'no'),
},
},
{
icon: Magicpen,
type: 'toggle',
title: translate('settingsPremiumTabPianoMagiqueSectionTitle'),
description: translate('settingsPremiumTabPianoMagiqueSectionDescription'),
helperText: translate('settingsPremiumTabPianoMagiqueSectionHelper'),
disabled: true,
data: {
value: false,
onToggle: () => {},
},
},
{
icon: Designtools,
type: 'dropdown',
title: translate('settingsPremiumTabThemePianoSectionTitle'),
description: translate('settingsPremiumTabThemePianoSectionDescription'),
disabled: true,
data: {
value: 'default',
onSelect: () => {},
options: [
{
label: 'Default',
value: 'default',
},
{
label: 'Catpuccino',
value: 'catpuccino',
},
],
},
},
]}
/>
);
};
export default PremiumSettings;

View File

@@ -1,7 +1,6 @@
import React from 'react';
import { Center, Text, useBreakpointValue, useTheme } from 'native-base';
import { Text, useBreakpointValue, useTheme } from 'native-base';
import ProfileSettings from './SettingsProfile';
import NotificationsSettings from './NotificationsSettings';
import PrivacySettings from './PrivacySettings';
import PreferencesSettings from './PreferencesSettings';
import { useWindowDimensions } from 'react-native';
@@ -15,50 +14,32 @@ import {
} from 'react-native-tab-view';
import {
HeartEdit,
Star1,
UserEdit,
Notification,
SecurityUser,
Music,
FolderCross,
} from 'iconsax-react-native';
import { Scene } from 'react-native-tab-view/lib/typescript/src/types';
import PremiumSettings from './SettingsPremium';
import { RouteProps } from '../../Navigation';
import ScaffoldCC from '../../components/UI/ScaffoldCC';
import { translate } from '../../i18n/i18n';
export const PianoSettings = () => {
return (
<Center style={{ flex: 1 }}>
<Text>Global settings for the virtual piano</Text>
</Center>
);
};
const renderScene = SceneMap({
profile: ProfileSettings,
premium: PremiumSettings,
preferences: PreferencesSettings,
notifications: NotificationsSettings,
privacy: PrivacySettings,
piano: PianoSettings,
});
const getTabData = (key: string) => {
switch (key) {
case 'profile':
return { index: 0, icon: UserEdit };
case 'premium':
return { index: 1, icon: Star1 };
case 'preferences':
return { index: 2, icon: HeartEdit };
case 'notifications':
return { index: 3, icon: Notification };
case 'privacy':
return { index: 4, icon: SecurityUser };
case 'piano':
return { index: 5, icon: Music };
default:
return { index: 6, icon: FolderCross };
}
@@ -71,11 +52,8 @@ const SettingsTab = (props: RouteProps<{}>) => {
const { colors } = useTheme();
const routes = [
{ key: 'profile', title: 'settingsTabProfile' },
{ key: 'premium', title: 'settingsTabPremium' },
{ key: 'preferences', title: 'settingsTabPreferences' },
{ key: 'notifications', title: 'settingsTabNotifications' },
{ key: 'privacy', title: 'settingsTabPrivacy' },
{ key: 'piano', title: 'settingsTabPiano' },
];
const screenSize = useBreakpointValue({ base: 'small', md: 'big' });
const isSmallScreen = screenSize === 'small';
@@ -113,11 +91,8 @@ const SettingsTab = (props: RouteProps<{}>) => {
{translate(
route.title as
| 'settingsTabProfile'
| 'settingsTabPremium'
| 'settingsTabPreferences'
| 'settingsTabNotifications'
| 'settingsTabPrivacy'
| 'settingsTabPiano'
)}
</Text>
)