summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorHank <hank@mullvad.net>2022-10-10 16:08:45 +0200
committerHank <hank@mullvad.net>2022-10-10 16:08:45 +0200
commit46e8823158b6e857c8f24b1e7cecf51612f48efd (patch)
tree15d9721bd552fea9c4a198a5b136625803a33228
parent27470f46a55c478abe994dfa86646fad5dc3847e (diff)
parentd4331d23acc52b1b0f5f2635d8450c4622ac6b9b (diff)
downloadmullvadvpn-46e8823158b6e857c8f24b1e7cecf51612f48efd.tar.xz
mullvadvpn-46e8823158b6e857c8f24b1e7cecf51612f48efd.zip
Merge branch 'select-language-component'
-rw-r--r--gui/src/renderer/app.tsx4
-rw-r--r--gui/src/renderer/components/AppRouter.tsx4
-rw-r--r--gui/src/renderer/components/SelectLanguage.tsx151
-rw-r--r--gui/src/renderer/containers/SelectLanguagePage.tsx27
4 files changed, 78 insertions, 108 deletions
diff --git a/gui/src/renderer/app.tsx b/gui/src/renderer/app.tsx
index 7991453240..c991e07104 100644
--- a/gui/src/renderer/app.tsx
+++ b/gui/src/renderer/app.tsx
@@ -491,7 +491,7 @@ export default class AppRenderer {
];
}
- public async setPreferredLocale(preferredLocale: string): Promise<void> {
+ public setPreferredLocale = async (preferredLocale: string): Promise<void> => {
const translations = await IpcRendererEventChannel.guiSettings.setPreferredLocale(
preferredLocale,
);
@@ -502,7 +502,7 @@ export default class AppRenderer {
// load translations for new locale
loadTranslations(messages, translations.locale, translations.messages);
loadTranslations(relayLocations, translations.locale, translations.relayLocations);
- }
+ };
public getPreferredLocaleDisplayName = (localeCode: string): string => {
const preferredLocale = this.getPreferredLocaleList().find((item) => item.code === localeCode);
diff --git a/gui/src/renderer/components/AppRouter.tsx b/gui/src/renderer/components/AppRouter.tsx
index 05f3658605..dbc6f538e6 100644
--- a/gui/src/renderer/components/AppRouter.tsx
+++ b/gui/src/renderer/components/AppRouter.tsx
@@ -5,7 +5,6 @@ import { Route, Switch } from 'react-router';
import AccountPage from '../containers/AccountPage';
import LoginPage from '../containers/LoginPage';
import ProblemReportPage from '../containers/ProblemReportPage';
-import SelectLanguagePage from '../containers/SelectLanguagePage';
import SelectLocationPage from '../containers/SelectLocationPage';
import withAppContext, { IAppContext } from '../context';
import { IHistoryProps, ITransitionSpecification, transitions, withHistory } from '../lib/history';
@@ -22,6 +21,7 @@ import Focus, { IFocusHandle } from './Focus';
import Launch from './Launch';
import MainView from './MainView';
import OpenVpnSettings from './OpenVpnSettings';
+import SelectLanguage from './SelectLanguage';
import Settings from './Settings';
import SplitTunnelingSettings from './SplitTunnelingSettings';
import Support from './Support';
@@ -88,7 +88,7 @@ class AppRouter extends React.Component<IHistoryProps & IAppContext, IAppRoutesS
<Route exact path={RoutePath.timeAdded} component={TimeAdded} />
<Route exact path={RoutePath.setupFinished} component={SetupFinished} />
<Route exact path={RoutePath.settings} component={Settings} />
- <Route exact path={RoutePath.selectLanguage} component={SelectLanguagePage} />
+ <Route exact path={RoutePath.selectLanguage} component={SelectLanguage} />
<Route exact path={RoutePath.accountSettings} component={AccountPage} />
<Route
exact
diff --git a/gui/src/renderer/components/SelectLanguage.tsx b/gui/src/renderer/components/SelectLanguage.tsx
index 2b11f0a924..b97243a456 100644
--- a/gui/src/renderer/components/SelectLanguage.tsx
+++ b/gui/src/renderer/components/SelectLanguage.tsx
@@ -1,7 +1,10 @@
-import * as React from 'react';
+import { useCallback, useEffect, useMemo, useRef } from 'react';
import styled from 'styled-components';
+import { useAppContext } from '../../renderer/context';
import { messages } from '../../shared/gettext';
+import { useHistory } from '../lib/history';
+import { useSelector } from '../redux/store';
import { AriaInputGroup } from './AriaGroup';
import Selector, { SelectorItem } from './cell/Selector';
import { CustomScrollbarsRef } from './CustomScrollbars';
@@ -16,91 +19,85 @@ import {
} from './NavigationBar';
import SettingsHeader, { HeaderTitle } from './SettingsHeader';
-interface IProps {
- preferredLocale: string;
- preferredLocalesList: Array<{ name: string; code: string }>;
- setPreferredLocale: (locale: string) => void;
- onClose: () => void;
-}
-
-interface IState {
- source: Array<SelectorItem<string>>;
-}
-
-const StyledNavigationScrollbars = styled(NavigationScrollbars)({
- flex: 1,
-});
-
const StyledSelector = styled(Selector)({
marginBottom: 0,
}) as typeof Selector;
-export default class SelectLanguage extends React.Component<IProps, IState> {
- private scrollView = React.createRef<CustomScrollbarsRef>();
- private selectedCellRef = React.createRef<HTMLButtonElement>();
+export default function SelectLanguage() {
+ const history = useHistory();
+ const { preferredLocale, preferredLocalesList, setPreferredLocale } = usePreferredLocale();
+ const scrollView = useRef<CustomScrollbarsRef>(null);
+ const selectedCellRef = useRef<HTMLButtonElement>(null);
+
+ const selectLocale = useCallback(
+ async (locale: string) => {
+ await setPreferredLocale(locale);
+ history.pop();
+ },
+ [history.pop],
+ );
+
+ const scrollToSelectedCell = () => {
+ const ref = selectedCellRef.current;
+ const view = scrollView.current;
+ if (view && ref) {
+ if (ref instanceof HTMLElement) {
+ view.scrollToElement(ref, 'middle');
+ }
+ }
+ };
- constructor(props: IProps) {
- super(props);
+ useEffect(() => {
+ scrollToSelectedCell();
+ }, []);
- this.state = {
- source: [
- ...this.props.preferredLocalesList.map((item) => ({ label: item.name, value: item.code })),
- ],
- };
- }
+ return (
+ <BackAction action={history.pop}>
+ <Layout>
+ <SettingsContainer>
+ <NavigationContainer>
+ <NavigationBar>
+ <NavigationItems>
+ <TitleBarItem>
+ {
+ // TRANSLATORS: Title label in navigation bar
+ messages.pgettext('select-language-nav', 'Select language')
+ }
+ </TitleBarItem>
+ </NavigationItems>
+ </NavigationBar>
- public componentDidMount() {
- this.scrollToSelectedCell();
- }
+ <NavigationScrollbars ref={scrollView}>
+ <SettingsHeader>
+ <HeaderTitle>
+ {messages.pgettext('select-language-nav', 'Select language')}
+ </HeaderTitle>
+ </SettingsHeader>
+ <AriaInputGroup>
+ <StyledSelector
+ title=""
+ value={preferredLocale}
+ items={preferredLocalesList}
+ onSelect={selectLocale}
+ selectedCellRef={selectedCellRef}
+ />
+ </AriaInputGroup>
+ </NavigationScrollbars>
+ </NavigationContainer>
+ </SettingsContainer>
+ </Layout>
+ </BackAction>
+ );
+}
- public render() {
- return (
- <BackAction action={this.props.onClose}>
- <Layout>
- <SettingsContainer>
- <NavigationContainer>
- <NavigationBar>
- <NavigationItems>
- <TitleBarItem>
- {
- // TRANSLATORS: Title label in navigation bar
- messages.pgettext('select-language-nav', 'Select language')
- }
- </TitleBarItem>
- </NavigationItems>
- </NavigationBar>
+function usePreferredLocale() {
+ const preferredLocale = useSelector((state) => state.settings.guiSettings.preferredLocale);
- <StyledNavigationScrollbars ref={this.scrollView}>
- <SettingsHeader>
- <HeaderTitle>
- {messages.pgettext('select-language-nav', 'Select language')}
- </HeaderTitle>
- </SettingsHeader>
- <AriaInputGroup>
- <StyledSelector
- title=""
- items={this.state.source}
- value={this.props.preferredLocale}
- onSelect={this.props.setPreferredLocale}
- selectedCellRef={this.selectedCellRef}
- />
- </AriaInputGroup>
- </StyledNavigationScrollbars>
- </NavigationContainer>
- </SettingsContainer>
- </Layout>
- </BackAction>
- );
- }
+ const { getPreferredLocaleList, setPreferredLocale } = useAppContext();
- private scrollToSelectedCell() {
- const ref = this.selectedCellRef.current;
- const scrollView = this.scrollView.current;
+ const preferredLocalesList: SelectorItem<string>[] = useMemo(() => {
+ return [...getPreferredLocaleList().map(({ name, code }) => ({ label: name, value: code }))];
+ }, []);
- if (scrollView && ref) {
- if (ref instanceof HTMLElement) {
- scrollView.scrollToElement(ref, 'middle');
- }
- }
- }
+ return { preferredLocale, preferredLocalesList, setPreferredLocale };
}
diff --git a/gui/src/renderer/containers/SelectLanguagePage.tsx b/gui/src/renderer/containers/SelectLanguagePage.tsx
deleted file mode 100644
index 5a0f2f9d29..0000000000
--- a/gui/src/renderer/containers/SelectLanguagePage.tsx
+++ /dev/null
@@ -1,27 +0,0 @@
-import { connect } from 'react-redux';
-
-import SelectLanguage from '../components/SelectLanguage';
-import withAppContext, { IAppContext } from '../context';
-import { IHistoryProps, withHistory } from '../lib/history';
-import { IReduxState, ReduxDispatch } from '../redux/store';
-
-const mapStateToProps = (state: IReduxState) => ({
- preferredLocale: state.settings.guiSettings.preferredLocale,
-});
-
-const mapDispatchToProps = (_dispatch: ReduxDispatch, props: IHistoryProps & IAppContext) => {
- return {
- preferredLocalesList: props.app.getPreferredLocaleList(),
- async setPreferredLocale(locale: string) {
- await props.app.setPreferredLocale(locale);
- props.history.pop();
- },
- onClose() {
- props.history.pop();
- },
- };
-};
-
-export default withAppContext(
- withHistory(connect(mapStateToProps, mapDispatchToProps)(SelectLanguage)),
-);