-
Notifications
You must be signed in to change notification settings - Fork 3
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
Changes from 1 commit
150e095
fa16dd0
1446a2d
d6b6f47
7a2c045
acd09a6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
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 |
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 |
---|---|---|
|
@@ -21,6 +21,14 @@ const LanguageSelector: FunctionComponent<Props> = ({className = ''}) => { | |
const selectedLanguage = useSelector(languageSelector); | ||
const dispatch = useDispatch(); | ||
|
||
const setLanguage = (language: Language) => { | ||
localStorage.setItem('language', language); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 |
||
|
||
if (localStorage.getItem('language')) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 => { | ||
|
@@ -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> | ||
|
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'; | ||
|
@@ -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); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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? 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}> | ||
|
@@ -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 /> | ||
|
There was a problem hiding this comment.
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.