diff --git a/components/DarkModeButton.js b/components/DarkModeButton.js
index 9e433a81..362c99ef 100644
--- a/components/DarkModeButton.js
+++ b/components/DarkModeButton.js
@@ -1,16 +1,17 @@
-import { useTheme } from '@/lib/theme'
-import localStorage from 'localStorage'
+import { loadUserThemeFromCookies, saveTheme, useTheme } from '@/lib/theme'
const DarkModeButton = () => {
- const { theme, changeTheme } = useTheme()
+ const { changeTheme } = useTheme()
+ const userTheme = loadUserThemeFromCookies()
// 用户手动设置主题
const handleChangeDarkMode = () => {
- const newTheme = (theme === 'light' ? 'dark' : 'light')
- localStorage.setItem('theme', newTheme)
+ const newTheme = (userTheme === 'light' ? 'dark' : 'light')
+ saveTheme(newTheme)
changeTheme(newTheme)
}
return
-
+
}
export default DarkModeButton
diff --git a/lib/theme.js b/lib/theme.js
index 308cc825..430728f5 100644
--- a/lib/theme.js
+++ b/lib/theme.js
@@ -1,5 +1,5 @@
-import { useContext, createContext, useState, useEffect } from 'react'
-import localStorage from 'localStorage'
+import { useContext, createContext, useState, useEffect, useRef } from 'react'
+import cookie from 'react-cookies'
const ThemeContext = createContext()
@@ -10,21 +10,38 @@ const ThemeContext = createContext()
* @constructor
*/
export function ThemeProvider ({ children }) {
- // 用户自定义主题设置在变量中
- const userTheme = localStorage.getItem('theme')
- const [theme, changeTheme] = useState(userTheme)
+ const [theme, changeTheme] = useState(loadUserThemeFromCookies())
+
+ // 由于Server采用服务端静态渲染,无法获取前端Cookie配置,故在渲染hooks中做初始化主题
useEffect(() => {
- const prefersDarkMode = window.matchMedia('(prefers-color-scheme: dark)').matches
- if (prefersDarkMode) {
- changeTheme('dark')
- localStorage.setItem('theme', 'dark')
- } else {
- changeTheme(userTheme)
+ // 若用户当前会话无指定主题,将根据深色偏好及访问时间决定默认主题
+ if (!theme) {
+ const date = new Date()
+ const prefersDarkMode = window.matchMedia('(prefers-color-scheme: dark)').matches
+ const useDark = prefersDarkMode || (date.getHours() >= 18 || date.getHours() < 6)
+ if (useDark) {
+ changeTheme('dark')
+ saveTheme('dark')
+ }
+ }
+
+ const baseLayoutClass = document.getElementById('wrapper').classList
+ if (!baseLayoutClass.contains(theme)) {
+ baseLayoutClass.add(theme)
}
})
+
return (
{children}
)
}
+export const loadUserThemeFromCookies = () => {
+ return cookie.load('theme')
+}
+
+export const saveTheme = (newTheme) => {
+ cookie.save('theme', newTheme, { path: '/' })
+}
+
export const useTheme = () => useContext(ThemeContext)
diff --git a/package.json b/package.json
index 0789c1f3..293b2bb3 100644
--- a/package.json
+++ b/package.json
@@ -34,6 +34,7 @@
"preact": "^10.5.13",
"qrcode.react": "^1.0.1",
"react": "17.0.2",
+ "react-cookies": "^0.1.1",
"react-cusdis": "^2.0.1",
"react-dom": "17.0.2",
"react-notion-x": "^4.6.5",
diff --git a/pages/_app.js b/pages/_app.js
index 9c235ba4..3387ac80 100644
--- a/pages/_app.js
+++ b/pages/_app.js
@@ -17,7 +17,7 @@ import { ThemeProvider } from '@/lib/theme'
const Ackee = dynamic(() => import('@/components/Ackee'), { ssr: false })
const Gtag = dynamic(() => import('@/components/Gtag'), { ssr: false })
-function MyApp ({ Component, pageProps }) {
+const MyApp = ({ Component, pageProps }) => {
return (
diff --git a/pages/index.js b/pages/index.js
index 585a278a..153b379c 100644
--- a/pages/index.js
+++ b/pages/index.js
@@ -25,7 +25,7 @@ export async function getStaticProps () {
}
}
-const index = ({ posts, tags, meta }) => {
+const Index = ({ posts, tags, meta }) => {
return (
@@ -36,4 +36,4 @@ const index = ({ posts, tags, meta }) => {
)
}
-export default index
+export default Index