Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(check-language): add info bubble and store language in localStorage #526

Merged
merged 6 commits into from
Aug 27, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions i18n/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
"showcaseMode": "Show Case Modus",
"play": "Abspielen",
"language": "Sprache wechseln",
"detectedLanguage": "Deutsche Sprache erkannt",
"changeLanguage": "Sprache ändern",
"keepLanguage": "Behalten",
"modes": "Modi",
"offline": "Desktop Version",
"download": "Anwendung herunterladen",
Expand Down
3 changes: 3 additions & 0 deletions i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
"showcaseMode": "Showcase Mode",
"play": "Play",
"language": "Change language",
"detectedLanguage": "English language detected",
"changeLanguage": "Change language",
"keepLanguage": "Keep",
"modes": "Modes",
"offline": "Standalone Version",
"download": "Download App",
Expand Down
3 changes: 3 additions & 0 deletions i18n/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
"showcaseMode": "Modo escaparate",
"play": "Reproducir",
"language": "Cambiar idioma",
"detectedLanguage": "Spanish language detected",
"changeLanguage": "Change language",
"keepLanguage": "Keep",
"modes": "Modos",
"offline": "Versión de escritorio",
"download": "Descargar app",
Expand Down
3 changes: 3 additions & 0 deletions i18n/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
"showcaseMode": "Showcase Mode",
"play": "Play",
"language": "Change language",
"detectedLanguage": "French language detected",
"changeLanguage": "Change language",
"keepLanguage": "Keep",
"modes": "Modes",
"offline": "Offline Mode",
"download": "Download App",
Expand Down
3 changes: 3 additions & 0 deletions i18n/nl.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
"showcaseMode": "Showcase mode",
"play": "Afspelen",
"language": "Wijzig taal",
"detectedLanguage": "Dutch language detected",
"changeLanguage": "Change language",
"keepLanguage": "Keep",
"modes": "Modes",
"offline": "Offline mode",
"download": "App downloaden",
Expand Down
14 changes: 12 additions & 2 deletions src/scripts/components/main/app/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import translations from '../../../i18n';

import styles from './app.styl';
import {useStoryMarkers} from '../../../hooks/use-story-markers';
import {Language} from '../../../types/language';

// create redux store
const store = createReduxStore();
Expand All @@ -36,12 +37,21 @@ const App: FunctionComponent = () => (
);

const TranslatedApp: FunctionComponent = () => {
const language = useSelector(languageSelector);
const markers = useStoryMarkers();
const language = useSelector(languageSelector);

const getLanguage = () => {
if (localStorage.getItem('language')) {
return localStorage.getItem('language') as Language;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We already retrieve the browser language in the language reducer. This would be a good place to also check for the localStorage language. It also has the benefit that it is only evaluated once on app start and not on every render like here.

Also we have to check if the language in the storage is actually one of the available languages similar to the getBrowserLanguage function.

}
return language;
};

return (
<Router>
<IntlProvider locale={language} messages={translations[language]}>
<IntlProvider
locale={getLanguage()}
messages={translations[getLanguage()]}>
<Switch>
<Route
path={[
Expand Down
46 changes: 46 additions & 0 deletions src/scripts/components/main/info-bubble/info-bubble.styl
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
@require '../../../../variables.styl'

.infoBubble
position: absolute
top: emCalc(50px)
right: emCalc(-16px)
display: flex
flex-direction: column
padding: emCalc(16px)
width: fit-content
height: fit-content
border-radius: 4px
background-color: $darkGrey4
box-shadow: 0px 2px 4px rgba(0, 0, 0, 0.14), 0px 3px 4px rgba(0, 0, 0, 0.12), 0px 1px 5px rgba(0, 0, 0, 0.2)

.infoBubble:before
position: absolute
right: emCalc(20px)
bottom: 100%
border-top-color: inherit
border-right: 8px solid transparent
border-bottom: 10px solid $darkGrey4
border-left: 8px solid transparent
content: ''

.language
margin: 0
color: $textWhite
font-size: emCalc(16px)
font-family: Arial

.buttons
display: flex
flex-direction: row
justify-content: space-between
padding-top: emCalc(16px)

.keepLanguage, .changeLanguage
color: $textColor
text-align: left
text-transform: uppercase
font-size: emCalc(11px)
font-family: NotesEsaBold

.changeLanguage
color: $textDefault
33 changes: 33 additions & 0 deletions src/scripts/components/main/info-bubble/info-bubble.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import React, {FunctionComponent} from 'react';
import {FormattedMessage} from 'react-intl';

import Button from '../button/button';

import styles from './info-bubble.styl';

interface Props {
onClose: () => void;
onMenuOpen: () => void;
}

const InfoBubble: FunctionComponent<Props> = ({onClose, onMenuOpen}) => (
<div className={styles.infoBubble}>
<p className={styles.language}>
<FormattedMessage id={'detectedLanguage'} />
</p>
<div className={styles.buttons}>
<Button
className={styles.changeLanguage}
label="changeLanguage"
onClick={() => onMenuOpen()}
/>
<Button
className={styles.keepLanguage}
label="keepLanguage"
onClick={() => onClose()}
/>
</div>
</div>
);

export default InfoBubble;
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,14 @@ const LanguageSelector: FunctionComponent<Props> = ({className = ''}) => {
const selectedLanguage = useSelector(languageSelector);
const dispatch = useDispatch();

const setLanguage = (language: Language) => {
localStorage.setItem('language', language);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be cool if the saving to localStorage and the dispatch would be combined so that we don't have to handle the saving manually in multiple places. We could just always save the language to local storage when dispatching the setLanguageAction action in the actions/set-language.ts file


if (localStorage.getItem('language')) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is this check for? if you set the item first and then check if it's there it should be always true

dispatch(setLanguageAction(language));
}
};

return (
<ul className={styles.language}>
{languages.map(language => {
Expand All @@ -34,7 +42,7 @@ const LanguageSelector: FunctionComponent<Props> = ({className = ''}) => {
<Button
className={buttonClasses}
key={language}
onClick={() => dispatch(setLanguageAction(language))}
onClick={() => setLanguage(language)}
label={`language.${language}`}
/>
</li>
Expand Down
18 changes: 17 additions & 1 deletion src/scripts/components/main/navigation/navigation.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, {FunctionComponent, useState} from 'react';
import {useDispatch} from 'react-redux';
import {useDispatch, useSelector} from 'react-redux';

import Button from '../button/button';
import Overlay from '../overlay/overlay';
Expand All @@ -11,10 +11,20 @@ import Share from '../share/share';
import {MenuIcon} from '../icons/menu-icon';

import styles from './navigation.styl';
import InfoBubble from '../info-bubble/info-bubble';
import {languageSelector} from '../../../selectors/language';

const Navigation: FunctionComponent = () => {
const dispatch = useDispatch();
const [showMenu, setShowMenu] = useState(false);
const [showInfoBubble, setshowInfoBubble] = useState(true);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't want to show the bubble if there is already a language in local storage right?
Something like that?

const savedLanguage = localStorage.getItem('language');
const [showInfoBubble, setshowInfoBubble] = useState(!Boolean(savedLanguage));

const language = useSelector(languageSelector);
const savedLanguage = localStorage.getItem('language');

const onSaveLanguage = () => {
localStorage.setItem('language', language);
setshowInfoBubble(false);
};

return (
<div className={styles.navigation}>
Expand All @@ -39,6 +49,12 @@ const Navigation: FunctionComponent = () => {
onClick={() => setShowMenu(true)}
hideLabelOnMobile
/>
{showInfoBubble && !savedLanguage && (
<InfoBubble
onMenuOpen={() => setShowMenu(true)}
onClose={() => onSaveLanguage()}
/>
)}
{showMenu && (
<Overlay onClose={() => setShowMenu(false)}>
<Menu />
Expand Down