File size: 4,535 Bytes
1b72d7e |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 |
import cookie from 'react-cookies'
import BLOG from '@/blog.config'
import { getQueryParam, getQueryVariable, isBrowser } from '../lib/utils'
import dynamic from 'next/dynamic'
import getConfig from 'next/config'
import * as ThemeComponents from '@theme-components'
// 所有主题在next.config.js中扫描
export const { THEMES = [] } = getConfig().publicRuntimeConfig
/**
* 加载全局布局
* 如果是
* @param {*} themeQuery
* @returns
*/
export const getGlobalLayoutByTheme = (themeQuery) => {
const layout = getLayoutNameByPath(-1)
if (themeQuery !== BLOG.THEME) {
return dynamic(() => import(`@/themes/${themeQuery}`).then(m => m[layout]), { ssr: true })
} else {
return ThemeComponents[layout]
}
}
/**
* 加载主题文件
* 如果是
* @param {*} router
* @returns
*/
export const getLayoutByTheme = ({ router, theme }) => {
const themeQuery = getQueryParam(router.asPath, 'theme') || theme
const layoutName = getLayoutNameByPath(router.pathname)
if (themeQuery !== BLOG.THEME) {
return dynamic(() => import(`@/themes/${themeQuery}`).then(m => {
setTimeout(() => {
checkThemeDOM()
}, 500);
return m[layoutName]
}), { ssr: true })
} else {
setTimeout(() => {
checkThemeDOM()
}, 100);
return ThemeComponents[layoutName]
}
}
/**
* 切换主题时的特殊处理
*/
const checkThemeDOM = () => {
if (isBrowser) {
const elements = document.querySelectorAll('[id^="theme-"]')
if (elements?.length > 1) {
elements[elements.length - 1].scrollIntoView()
// 删除前面的元素,只保留最后一个元素
for (let i = 0; i < elements.length - 1; i++) {
elements[i].parentNode.removeChild(elements[i])
}
}
}
}
/**
* 根据路径 获取对应的layout
* @param {*} path
* @returns
*/
export const getLayoutNameByPath = (path) => {
switch (path) {
case -1:
return 'LayoutBase'
case '/':
return 'LayoutIndex'
case '/archive':
return 'LayoutArchive'
case '/page/[page]':
case '/category/[category]':
case '/category/[category]/page/[page]':
case '/tag/[tag]':
case '/tag/[tag]/page/[page]':
return 'LayoutPostList'
case '/search':
case '/search/[keyword]':
case '/search/[keyword]/page/[page]':
return 'LayoutSearch'
case '/404':
return 'Layout404'
case '/tag':
return 'LayoutTagIndex'
case '/category':
return 'LayoutCategoryIndex'
default:
return 'LayoutSlug'
}
}
/**
* 初始化主题 , 优先级 query > cookies > systemPrefer
* @param isDarkMode
* @param updateDarkMode 更改主题ChangeState函数
* @description 读取cookie中存的用户主题
*/
export const initDarkMode = (updateDarkMode) => {
// 查看用户设备浏览器是否深色模型
let newDarkMode = isPreferDark()
// 查看cookie中是否用户强制设置深色模式
const cookieDarkMode = loadDarkModeFromCookies()
if (cookieDarkMode) {
newDarkMode = JSON.parse(cookieDarkMode)
}
// url查询条件中是否深色模式
const queryMode = getQueryVariable('mode')
if (queryMode) {
newDarkMode = queryMode === 'dark'
}
updateDarkMode(newDarkMode)
saveDarkModeToCookies(newDarkMode)
document.getElementsByTagName('html')[0].setAttribute('class', newDarkMode ? 'dark' : 'light')
}
/**
* 是否优先深色模式, 根据系统深色模式以及当前时间判断
* @returns {*}
*/
export function isPreferDark() {
if (BLOG.APPEARANCE === 'dark') {
return true
}
if (BLOG.APPEARANCE === 'auto') {
// 系统深色模式或时间是夜间时,强行置为夜间模式
const date = new Date()
const prefersDarkMode = window.matchMedia('(prefers-color-scheme: dark)').matches
return prefersDarkMode || (BLOG.APPEARANCE_DARK_TIME && (date.getHours() >= BLOG.APPEARANCE_DARK_TIME[0] || date.getHours() < BLOG.APPEARANCE_DARK_TIME[1]))
}
return false
}
/**
* 读取深色模式
* @returns {*}
*/
export const loadDarkModeFromCookies = () => {
return cookie.load('darkMode')
}
/**
* 保存深色模式
* @param newTheme
*/
export const saveDarkModeToCookies = (newTheme) => {
cookie.save('darkMode', newTheme, { path: '/' })
}
/**
* 读取默认主题
* @returns {*}
*/
export const loadThemeFromCookies = () => {
return cookie.load('theme')
}
/**
* 保存默认主题
* @param newTheme
*/
export const saveThemeToCookies = (newTheme) => {
cookie.save('theme', newTheme, { path: '/' })
}
|