|
import { generateLocaleDict, initLocale, saveLangToCookies } from './lang' |
|
import { createContext, useContext, useEffect, useState } from 'react' |
|
import { useRouter } from 'next/router' |
|
import { THEMES, initDarkMode, saveDarkModeToCookies } from '@/themes/theme' |
|
import { APPEARANCE, LANG, THEME } from 'blog.config' |
|
const GlobalContext = createContext() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export function GlobalContextProvider(props) { |
|
const { post, children, siteInfo, categoryOptions, tagOptions, NOTION_CONFIG } = props |
|
const [lang, updateLang] = useState(NOTION_CONFIG?.LANG || LANG) |
|
const [locale, updateLocale] = useState(generateLocaleDict(NOTION_CONFIG?.LANG || LANG)) |
|
const [theme, setTheme] = useState(NOTION_CONFIG?.THEME || THEME) |
|
const [isDarkMode, updateDarkMode] = useState(NOTION_CONFIG?.APPEARANCE || APPEARANCE === 'dark') |
|
const [onLoading, setOnLoading] = useState(false) |
|
const router = useRouter() |
|
|
|
|
|
const fullWidth = post?.fullWidth ?? false |
|
|
|
|
|
function switchTheme() { |
|
const query = router.query |
|
const currentTheme = query.theme || theme |
|
const currentIndex = THEMES.indexOf(currentTheme) |
|
const newIndex = currentIndex < THEMES.length - 1 ? currentIndex + 1 : 0 |
|
const newTheme = THEMES[newIndex] |
|
query.theme = newTheme |
|
router.push({ pathname: router.pathname, query }) |
|
return newTheme |
|
} |
|
|
|
|
|
const toggleDarkMode = () => { |
|
const newStatus = !isDarkMode |
|
saveDarkModeToCookies(newStatus) |
|
updateDarkMode(newStatus) |
|
const htmlElement = document.getElementsByTagName('html')[0] |
|
htmlElement.classList?.remove(newStatus ? 'light' : 'dark') |
|
htmlElement.classList?.add(newStatus ? 'dark' : 'light') |
|
} |
|
|
|
|
|
|
|
|
|
function changeLang(lang) { |
|
if (lang) { |
|
saveLangToCookies(lang) |
|
updateLang(lang) |
|
updateLocale(generateLocaleDict(lang)) |
|
} |
|
} |
|
|
|
useEffect(() => { |
|
initDarkMode(updateDarkMode) |
|
initLocale(lang, locale, updateLang, updateLocale) |
|
}, []) |
|
|
|
|
|
useEffect(() => { |
|
const handleStart = (url) => { |
|
const { theme } = router.query |
|
if (theme && !url.includes(`theme=${theme}`)) { |
|
const newUrl = `${url}${url.includes('?') ? '&' : '?'}theme=${theme}` |
|
router.push(newUrl) |
|
} |
|
setOnLoading(true) |
|
} |
|
const handleStop = () => { |
|
setOnLoading(false) |
|
} |
|
|
|
router.events.on('routeChangeStart', handleStart) |
|
router.events.on('routeChangeError', handleStop) |
|
router.events.on('routeChangeComplete', handleStop) |
|
return () => { |
|
router.events.off('routeChangeStart', handleStart) |
|
router.events.off('routeChangeComplete', handleStop) |
|
router.events.off('routeChangeError', handleStop) |
|
} |
|
}, [router]) |
|
|
|
return ( |
|
<GlobalContext.Provider value={{ |
|
fullWidth, |
|
NOTION_CONFIG, |
|
toggleDarkMode, |
|
onLoading, |
|
setOnLoading, |
|
lang, |
|
changeLang, |
|
locale, |
|
updateLocale, |
|
isDarkMode, |
|
updateDarkMode, |
|
theme, |
|
setTheme, |
|
switchTheme, |
|
siteInfo, |
|
categoryOptions, |
|
tagOptions |
|
}}> |
|
{children} |
|
</GlobalContext.Provider> |
|
) |
|
} |
|
|
|
export const useGlobal = () => useContext(GlobalContext) |
|
|