Skip to content

Commit

Permalink
Merge pull request #289 from adrianxx321/ImplementLanguageSwitching
Browse files Browse the repository at this point in the history
Implement language switching
  • Loading branch information
PierreBresson authored Aug 7, 2021
2 parents 0ea649b + 318fcb6 commit ff5d2ad
Show file tree
Hide file tree
Showing 40 changed files with 599 additions and 76 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
exports[`userPreferences actions should export expected actions 1`] = `
Object {
"acceptTermsOfUse": [Function],
"changeLanguage": [Function],
"toggleNotifications": [Function],
"updateLocation": [Function],
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { ElectricityType } from "carbon-footprint";

import { currentLanguage } from "utils";

import userPreferences from "../";

describe("userPreferences reducer should", () => {
Expand All @@ -10,6 +12,7 @@ describe("userPreferences reducer should", () => {
acceptedTermsOfUseVersion: 0,
activatedNotifications: false,
location: ElectricityType.world,
language: currentLanguage,
});
});

Expand All @@ -25,6 +28,7 @@ describe("userPreferences reducer should", () => {
acceptedTermsOfUseVersion: 2,
activatedNotifications: false,
location: ElectricityType.world,
language: currentLanguage,
});
});

Expand All @@ -38,6 +42,7 @@ describe("userPreferences reducer should", () => {
acceptedTermsOfUseVersion: 0,
activatedNotifications: false,
location: ElectricityType.belgium,
language: currentLanguage,
});
});

Expand All @@ -51,6 +56,21 @@ describe("userPreferences reducer should", () => {
acceptedTermsOfUseVersion: 0,
activatedNotifications: true,
location: ElectricityType.world,
language: currentLanguage,
});
});

it("handle language change", () => {
const expectedAction = {
type: userPreferences.actions.changeLanguage.toString(),
payload: "fr",
};

expect(userPreferences.reducer(undefined, expectedAction)).toEqual({
acceptedTermsOfUseVersion: 0,
activatedNotifications: false,
location: ElectricityType.world,
language: "fr",
});
});
});
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { ElectricityType } from "carbon-footprint";

import { supportedLanguages } from "utils";

import userPreferences from "../";

let state;
Expand All @@ -8,6 +10,7 @@ const initialState = {
acceptedTermsOfUseVersion: 3,
activatedNotifications: false,
location: ElectricityType.world,
language: supportedLanguages.en,
};

describe("userPreferences selector should", () => {
Expand All @@ -29,4 +32,7 @@ describe("userPreferences selector should", () => {
expect(userPreferences.selectors.getActivateNotifications(state)).toEqual(
initialState.activatedNotifications
));

test("return current language", () =>
expect(userPreferences.selectors.getLanguage(state)).toEqual(initialState.language));
});
5 changes: 5 additions & 0 deletions app/ducks/userPreferences/userPreferences.selectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
import { pathOr } from "ramda";
import { ElectricityType } from "carbon-footprint";

import { currentLanguage } from "utils";

import { namespace } from "./userPreferences.slice";

const getAcceptedTermsOfUseVersion = (state) =>
Expand All @@ -12,8 +14,11 @@ const getLocation = (state) => pathOr(ElectricityType.world, [namespace, "locati
const getActivateNotifications = (state) =>
pathOr(false, [namespace, "activatedNotifications"], state);

const getLanguage = (state) => pathOr(currentLanguage, [namespace, "language"], state);

export default {
getAcceptedTermsOfUseVersion,
getActivateNotifications,
getLocation,
getLanguage,
};
14 changes: 13 additions & 1 deletion app/ducks/userPreferences/userPreferences.slice.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
import { ElectricityType } from "carbon-footprint";

import { currentLanguage } from "utils";

const initialState = {
acceptedTermsOfUseVersion: 0,
activatedNotifications: false,
location: ElectricityType.world,
language: currentLanguage,
};

const userPreferences = createSlice({
Expand All @@ -20,15 +23,24 @@ const userPreferences = createSlice({
updateLocation(state, action: PayloadAction<ElectricityType>) {
state.location = action.payload;
},
changeLanguage(state, action: PayloadAction<string>) {
state.language = action.payload;
},
},
});

const { acceptTermsOfUse, updateLocation, toggleNotifications } = userPreferences.actions;
const {
acceptTermsOfUse,
updateLocation,
toggleNotifications,
changeLanguage,
} = userPreferences.actions;

export const actions = {
acceptTermsOfUse,
updateLocation,
toggleNotifications,
changeLanguage,
};

export const namespace = userPreferences.name;
Expand Down
6 changes: 6 additions & 0 deletions app/navigation/Navigator/BottomTab/SettingsNavigator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import MyLocationScreen from "../../../screens/MyLocation";
import NotificationsScreen from "../../../screens/Notifications";
import MyData from "../../../screens/MyData";
import StorybookScreen from "../../../../storybook";
import LanguagesScreen from "../../../screens/Languages/LanguagesScreen";

const Stack = createStackNavigator();

Expand Down Expand Up @@ -36,6 +37,11 @@ const SettingsNavigator = (): React.ReactElement => (
/>
<Stack.Screen name="MyData" options={MyData.navigationOptions} component={MyData} />
<Stack.Screen name="Storybook" component={StorybookScreen} />
<Stack.Screen
name="Languages"
options={LanguagesScreen.navigationOptions}
component={LanguagesScreen}
/>
</Stack.Navigator>
);

Expand Down
5 changes: 5 additions & 0 deletions app/navigation/navigate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@ const openMonthlyEmissions = (navigation) => (props = {}) => {
navigation.push("MonthlyEmissions", props);
};

const openLanguages = (navigation) => (props = {}) => {
navigation.push("Languages", props);
};

const navigate = (navigation) => ({
goBack: navigation.goBack,
openMonthlyEmissions: navigateOneTime(openMonthlyEmissions(navigation)),
Expand All @@ -90,6 +94,7 @@ const navigate = (navigation) => ({
openNotifications: navigateOneTime(openNotifications(navigation)),
openSupportUs: navigateOneTime(openSupportUs(navigation)),
openStorybook: navigateOneTime(openStorybook(navigation)),
openLanguages: navigateOneTime(openLanguages(navigation)),
});

export default navigate;
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ exports[`EmissionsScreen renders correctly 1`] = `
]
}
>
Friday
Wednesday
</Text.Primary>
<Text.Primary
darkGray={true}
Expand All @@ -121,7 +121,7 @@ exports[`EmissionsScreen renders correctly 1`] = `
}
}
>
6th August 2021
7th August 2021
</Text.Primary>
</View>
<Button.Primary
Expand Down
18 changes: 18 additions & 0 deletions app/screens/Languages/LanguagesScreen.navigationOptions.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import React from "react";
import { StackNavigationOptions } from "@react-navigation/stack";

import { Text } from "components";
import { t } from "utils";
import { Colors, ComponentsStyle } from "style";

const navigationOptions = (): StackNavigationOptions => ({
...ComponentsStyle.transitionBetweenScreenPresets,
headerStyle: {
...ComponentsStyle.header,
},
headerBackTitleVisible: false,
headerTintColor: Colors.grey100,
headerTitle: () => <Text.H1>{t("LANGUAGES_SCREEN_TITLE")}</Text.H1>,
});

export default navigationOptions;
11 changes: 11 additions & 0 deletions app/screens/Languages/LanguagesScreen.styles.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { StyleSheet } from "react-native";

import { Layout } from "style";

const styles = StyleSheet.create({
container: {
...Layout.containerWithPadding,
},
});

export default styles;
60 changes: 60 additions & 0 deletions app/screens/Languages/LanguagesScreen.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import React, { useCallback, useContext } from "react";
import { View, ScrollView } from "react-native";
import { useDispatch } from "react-redux";

import { SelectableListItem } from "components";
import { userPreferences } from "ducks";
import { LocalizationContext, supportedLanguages } from "utils";

import navigationOptions from "./LanguagesScreen.navigationOptions";
import styles from "./LanguagesScreen.styles";

const Language: React.FC<{
selectedLanguage: string;
language: string;
onSelectLanguage: (language: string) => void;
}> = ({ language, onSelectLanguage, selectedLanguage }) => {
const onClickLanguage = useCallback(() => {
onSelectLanguage?.(language);
}, [language, onSelectLanguage]);

return (
<SelectableListItem
key={language}
selected={selectedLanguage === language}
title={supportedLanguages[language]}
onPress={onClickLanguage}
/>
);
};

const LanguagesScreen = () => {
const dispatch = useDispatch();
const { language, setLanguage } = useContext(LocalizationContext);
const onPress = useCallback(
(lang: string) => {
dispatch(userPreferences.actions.changeLanguage(lang));
setLanguage(lang);
},
[dispatch, setLanguage]
);

return (
<View style={styles.container}>
<ScrollView>
{Object.keys(supportedLanguages).map((lang: string) => (
<Language
key={lang}
selectedLanguage={language}
language={lang}
onSelectLanguage={onPress}
/>
))}
</ScrollView>
</View>
);
};

LanguagesScreen.navigationOptions = navigationOptions;

export default LanguagesScreen;
11 changes: 11 additions & 0 deletions app/screens/Languages/__tests__/LanguagesScreen.tests.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import React from "react";
import { create } from "react-test-renderer";

import LanguagesScreen from "../LanguagesScreen";

// jest.unmock("../");

it("LanguageScreen renders correctly", () => {
const tree = create(<LanguagesScreen />).toJSON();
expect(tree).toMatchSnapshot();
});
Loading

0 comments on commit ff5d2ad

Please sign in to comment.