accounts-frontend/packages/app/components/languageSwitcher/LanguageSwitcher.tsx

182 lines
5.9 KiB
TypeScript
Raw Normal View History

2019-12-07 16:58:52 +05:30
import React from 'react';
import { FormattedMessage as Message, injectIntl, IntlShape } from 'react-intl';
2019-12-08 01:13:08 +05:30
import clsx from 'clsx';
import { connect } from 'react-redux';
import { changeLang } from 'app/components/user/actions';
import LANGS from 'app/i18n';
import formStyles from 'app/components/ui/form/form.scss';
import popupStyles from 'app/components/ui/popup/popup.scss';
import icons from 'app/components/ui/icons.scss';
import styles from './languageSwitcher.scss';
import LanguageList from './LanguageList';
import { RootState } from 'app/reducers';
const translateUrl = 'http://ely.by/translate';
export interface LocaleData {
2020-05-24 04:38:24 +05:30
code: string;
name: string;
englishName: string;
progress: number;
isReleased: boolean;
}
export type LocalesMap = Record<string, LocaleData>;
2019-12-07 16:58:52 +05:30
type OwnProps = {
2020-05-24 04:38:24 +05:30
onClose: () => void;
langs: LocalesMap;
emptyCaptions: Array<{
src: string;
caption: string;
}>;
};
2019-12-07 16:58:52 +05:30
interface Props extends OwnProps {
2020-05-24 04:38:24 +05:30
intl: IntlShape;
selectedLocale: string;
changeLang: (lang: string) => void;
2019-12-07 16:58:52 +05:30
}
class LanguageSwitcher extends React.Component<
2020-05-24 04:38:24 +05:30
Props,
{
filter: string;
filteredLangs: LocalesMap;
}
> {
2020-05-24 04:38:24 +05:30
state = {
filter: '',
filteredLangs: this.props.langs,
};
2020-05-24 04:38:24 +05:30
static defaultProps = {
langs: LANGS,
onClose() {},
};
render() {
const { selectedLocale, onClose, intl } = this.props;
const { filteredLangs } = this.state;
return (
<div
className={styles.languageSwitcher}
data-testid="language-switcher"
data-e2e-active-locale={selectedLocale}
>
<div className={popupStyles.popup}>
<div className={popupStyles.header}>
<h2 className={popupStyles.headerTitle}>
<Message key="siteLanguage" defaultMessage="Site language" />
2020-05-24 04:38:24 +05:30
</h2>
<span className={clsx(icons.close, popupStyles.close)} onClick={onClose} />
</div>
<div className={styles.languageSwitcherBody}>
<div className={styles.searchBox}>
<input
className={clsx(formStyles.lightTextField, formStyles.greenTextField)}
placeholder={intl.formatMessage({
key: 'startTyping',
defaultMessage: 'Start typing…',
})}
2020-05-24 04:38:24 +05:30
onChange={this.onFilterUpdate}
onKeyPress={this.onFilterKeyPress()}
autoFocus
/>
<span className={styles.searchIcon} />
</div>
<LanguageList
selectedLocale={selectedLocale}
langs={filteredLangs}
onChangeLang={this.onChangeLang}
/>
<div className={styles.improveTranslates}>
<div className={styles.improveTranslatesIcon} />
<div className={styles.improveTranslatesContent}>
<div className={styles.improveTranslatesTitle}>
<Message key="improveTranslates" defaultMessage="Improve Ely.by translation" />
2020-05-24 04:38:24 +05:30
</div>
<div className={styles.improveTranslatesText}>
<Message
key="improveTranslatesDescription"
defaultMessage="Ely.bys localization is a community effort. If you want to improve the translation of Ely.by, we'd love your help."
/>{' '}
2020-05-24 04:38:24 +05:30
<a href={translateUrl} target="_blank">
<Message
key="improveTranslatesParticipate"
defaultMessage="Click here to participate."
/>
2020-05-24 04:38:24 +05:30
</a>
</div>
</div>
</div>
</div>
</div>
</div>
2020-05-24 04:38:24 +05:30
);
}
2020-05-24 04:38:24 +05:30
onChangeLang = this.changeLang.bind(this);
2020-05-24 04:38:24 +05:30
changeLang(lang: string) {
this.props.changeLang(lang);
2020-05-24 04:38:24 +05:30
setTimeout(this.props.onClose, 300);
}
2020-05-24 04:38:24 +05:30
onFilterUpdate = (event: React.ChangeEvent<HTMLInputElement>) => {
const filter = event.currentTarget.value.trim().toLowerCase();
const { langs } = this.props;
2020-05-24 04:38:24 +05:30
const result = Object.keys(langs).reduce((previous, key) => {
if (
langs[key].englishName.toLowerCase().indexOf(filter) === -1 &&
langs[key].name.toLowerCase().indexOf(filter) === -1
) {
return previous;
}
2020-05-24 04:38:24 +05:30
previous[key] = langs[key];
2020-05-24 04:38:24 +05:30
return previous;
}, {} as typeof langs);
2020-05-24 04:38:24 +05:30
this.setState({
filter,
filteredLangs: result,
});
};
2020-05-24 04:38:24 +05:30
onFilterKeyPress() {
return (event: React.KeyboardEvent<HTMLInputElement>) => {
if (event.key !== 'Enter' || this.state.filter === '') {
return;
}
2020-05-24 04:38:24 +05:30
const locales = Object.keys(this.state.filteredLangs);
2020-05-24 04:38:24 +05:30
if (locales.length === 0) {
return;
}
2020-05-24 04:38:24 +05:30
this.changeLang(locales[0]);
};
}
}
2019-11-11 14:10:05 +05:30
export default injectIntl(
2020-05-24 04:38:24 +05:30
connect(
(state: RootState) => ({
selectedLocale: state.i18n.locale,
}),
{
changeLang,
},
)(LanguageSwitcher),
2019-11-11 14:10:05 +05:30
);