添加登录和后端校验
完成后端设计(未在本仓库体现),通过安全的手段完成了登录鉴权
This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
import { createContext, useContext, useState, useCallback, useEffect } from 'react'
|
||||
import Taro, { useDidShow } from '@tarojs/taro'
|
||||
import { getTheme, setTheme as saveTheme, resolveTheme, type ThemeMode } from '../utils/store'
|
||||
import { applyPageBackground } from '../utils/themeBackground'
|
||||
|
||||
interface ThemeContextValue {
|
||||
theme: ThemeMode
|
||||
resolvedTheme: 'light' | 'dark'
|
||||
toggleTheme: () => void
|
||||
setTheme: (t: ThemeMode) => void
|
||||
}
|
||||
|
||||
const ThemeContext = createContext<ThemeContextValue>({
|
||||
theme: 'auto',
|
||||
resolvedTheme: 'light',
|
||||
toggleTheme: () => {},
|
||||
setTheme: () => {}
|
||||
})
|
||||
|
||||
export { ThemeContext }
|
||||
|
||||
type ThemeChangeListener = (result: { theme?: string }) => void
|
||||
|
||||
type ThemeChangeApi = {
|
||||
onThemeChange?: (listener: ThemeChangeListener) => void
|
||||
offThemeChange?: (listener: ThemeChangeListener) => void
|
||||
}
|
||||
|
||||
/** 主题广播事件名:自定义 tabBar 等无法继承 React Context 的独立组件通过它同步主题 */
|
||||
export const THEME_CHANGE_EVENT = 'themeChange'
|
||||
|
||||
export function ThemeProvider({ children }: { children: React.ReactNode }) {
|
||||
const [theme, set] = useState<ThemeMode>(getTheme())
|
||||
const [resolvedTheme, setResolved] = useState<'light' | 'dark'>(resolveTheme(getTheme()))
|
||||
|
||||
const updateResolved = useCallback((mode: ThemeMode) => {
|
||||
setResolved(resolveTheme(mode))
|
||||
}, [])
|
||||
|
||||
const setTheme = useCallback((t: ThemeMode) => {
|
||||
saveTheme(t)
|
||||
set(t)
|
||||
updateResolved(t)
|
||||
}, [updateResolved])
|
||||
|
||||
const toggleTheme = useCallback(() => {
|
||||
const next = resolvedTheme === 'light' ? 'dark' : 'light'
|
||||
setTheme(next)
|
||||
}, [resolvedTheme, setTheme])
|
||||
|
||||
// 广播实际生效主题,供 custom-tab-bar 等独立组件订阅
|
||||
useEffect(() => {
|
||||
Taro.eventCenter.trigger(THEME_CHANGE_EVENT, resolvedTheme)
|
||||
}, [resolvedTheme])
|
||||
|
||||
// App 启动时立即同步页面背景(自定义导航区在 iOS 上由 backgroundColorTop 控制),
|
||||
// 避免首屏/切换 tab 时顶部导航区先显示白色再变主题色
|
||||
useEffect(() => {
|
||||
applyPageBackground(resolvedTheme)
|
||||
}, [resolvedTheme])
|
||||
|
||||
// 页面每次显示时(从小程序后台切回前台)重新检测系统主题
|
||||
useDidShow(() => {
|
||||
if (theme === 'auto') {
|
||||
setResolved(resolveTheme('auto'))
|
||||
}
|
||||
})
|
||||
|
||||
// auto模式下监听系统主题变化
|
||||
useEffect(() => {
|
||||
if (theme === 'auto') {
|
||||
// 先同步一次当前系统主题
|
||||
setResolved(resolveTheme('auto'))
|
||||
const listener: ThemeChangeListener = (res) => {
|
||||
setResolved(res.theme === 'dark' ? 'dark' : 'light')
|
||||
}
|
||||
const themeApi = Taro as typeof Taro & ThemeChangeApi
|
||||
themeApi.onThemeChange?.(listener)
|
||||
return () => {
|
||||
themeApi.offThemeChange?.(listener)
|
||||
}
|
||||
} else {
|
||||
updateResolved(theme)
|
||||
}
|
||||
}, [theme, updateResolved])
|
||||
|
||||
return (
|
||||
<ThemeContext.Provider value={{ theme, resolvedTheme, toggleTheme, setTheme }}>
|
||||
{children}
|
||||
</ThemeContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
export function useThemeContext(): ThemeContextValue {
|
||||
return useContext(ThemeContext)
|
||||
}
|
||||
Reference in New Issue
Block a user