added language toggle feature

This commit is contained in:
Kim, Jimin 2021-05-19 13:38:10 +09:00
parent 255d3939e3
commit 6c1de6bbbd
3 changed files with 131 additions and 65 deletions

View file

@ -5,7 +5,7 @@ import storage from "local-storage-fallback"
import { useState, useEffect } from "react" import { useState, useEffect } from "react"
import theme from "styled-theming" import theme from "styled-theming"
import Spinner from "./components/Spinner" import Spinner from "./components/Spinner"
import LanguageContext from "./LanguageContext"
import theming from "./theming" import theming from "./theming"
import Navbar from "./components/Navbar" import Navbar from "./components/Navbar"
@ -125,16 +125,9 @@ blockquote {
` `
function App() { function App() {
const [currentTheme, _setTheme] = useState(() => { /**
const savedTheme = storage.getItem("theme") * Loading
return savedTheme ? JSON.parse(savedTheme) : { mode: "dark" } */
})
// save theme when theme is changed
useEffect(() => {
storage.setItem("theme", JSON.stringify(currentTheme))
}, [currentTheme])
const [isLoading, setLoading] = useState(true) const [isLoading, setLoading] = useState(true)
// show loading screen until all fonts are loaded. // show loading screen until all fonts are loaded.
@ -151,6 +144,42 @@ function App() {
} }
}, []) }, [])
/**
* Theme
*/
const [currentTheme, _setTheme] = useState(() => {
const savedTheme = storage.getItem("theme")
return savedTheme ? JSON.parse(savedTheme) : { mode: "dark" }
})
// save theme when it is changed
useEffect(() => {
storage.setItem("theme", JSON.stringify(currentTheme))
}, [currentTheme])
/**
* Language
*/
const [currentLanguage, _setLanguage] = useState(
storage.getItem("lang") || "en" // get language from storage and set to "en" if not set already
)
// save language when it is changed
useEffect(() => {
storage.setItem("lang", currentLanguage)
}, [currentLanguage])
const languageState = {
language: currentLanguage,
toggleLanguage: () => {
// cycle through languages
let setLanguageTo = "en"
if (currentLanguage == "en") setLanguageTo = "kr"
_setLanguage(setLanguageTo)
},
}
return ( return (
<HelmetProvider> <HelmetProvider>
<ThemeProvider <ThemeProvider
@ -160,6 +189,7 @@ function App() {
setTheme: ({ setTheme, ...theme }) => _setTheme(theme), // make setTheme function available in other components setTheme: ({ setTheme, ...theme }) => _setTheme(theme), // make setTheme function available in other components
}} }}
> >
<LanguageContext.Provider value={languageState}>
<GlobalStyle /> <GlobalStyle />
<Router> <Router>
<Navbar /> <Navbar />
@ -185,20 +215,31 @@ function App() {
<Route <Route
exact exact
path="/archives" path="/archives"
component={() => <Home title="Archives" />} component={() => (
<Home title="Archives" />
)}
/> />
<Route <Route
exact exact
path="/portfolio" path="/portfolio"
component={Portfolio} component={Portfolio}
/> />
<Route exact path="/404" component={NotFound} /> <Route
<Route exact path="/:path*" component={Page} /> exact
path="/404"
component={NotFound}
/>
<Route
exact
path="/:path*"
component={Page}
/>
</Switch> </Switch>
)} )}
</div> </div>
<Footer /> <Footer />
</Router> </Router>
</LanguageContext.Provider>
</ThemeProvider> </ThemeProvider>
</HelmetProvider> </HelmetProvider>
) )

View file

@ -0,0 +1,11 @@
/**
* go to App.tsx and search for `languageState` to see the actual values
*/
import { createContext } from "react"
export default createContext({
language: "",
// eslint-disable-next-line @typescript-eslint/no-empty-function
toggleLanguage: () => {},
})

View file

@ -1,34 +1,48 @@
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome" import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
import { faLanguage } from "@fortawesome/free-solid-svg-icons" import { faLanguage } from "@fortawesome/free-solid-svg-icons"
import styled from "styled-components" import styled from "styled-components"
import theme from "styled-theming"
import ReactTooltip from "react-tooltip" import ReactTooltip from "react-tooltip"
import LanguageContext from "../LanguageContext"
import theming from "../theming" import theming from "../theming"
const StyledThemeButton = styled.div` const StyledThemeButton = styled.div<{ language: string }>`
${theming.styles.navbarButtonStyle} ${theming.styles.navbarButtonStyle}
transition: transform 0.2s linear; transition: transform 0.2s linear;
/* ${theme("mode", { ${(props) =>
light: "", props.language == "en"
dark: "transform: scaleX(-1);\ ? ""
: "transform: scaleX(-1);\
-moz-transform: scaleX(-1);\ -moz-transform: scaleX(-1);\
-webkit-transform: scaleX(-1);\ -webkit-transform: scaleX(-1);\
-ms-transform: scaleX(-1);", -ms-transform: scaleX(-1);"};
})}; */
` `
function LanguageToggleButton() { function LanguageToggleButton() {
function languageName(language) {
let name = "English"
if (language == "kr") name = "Korean"
return name
}
return ( return (
<LanguageContext.Consumer>
{({ language, toggleLanguage }) => (
<> <>
<StyledThemeButton data-tip data-for="language"> <StyledThemeButton
data-tip
data-for="language"
onClick={toggleLanguage}
language={language}
>
<FontAwesomeIcon icon={faLanguage} /> <FontAwesomeIcon icon={faLanguage} />
</StyledThemeButton> </StyledThemeButton>
<ReactTooltip id="language" type="dark" effect="solid"> <ReactTooltip id="language" type="dark" effect="solid">
<span>Change to Korean/English</span> <span>Using {languageName(language)} language</span>
</ReactTooltip> </ReactTooltip>
</> </>
)}
</LanguageContext.Consumer>
) )
} }