dark-mode needs to block block
This commit is contained in:
parent
8d8e2859dd
commit
aea8948c45
|
@ -1,5 +1,54 @@
|
||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
import { getTheme, listenForThemeChange, setTheme } from '../public/bs-dark'
|
|
||||||
|
const handleThemeChange = (dark) => {
|
||||||
|
const root = window.document.documentElement
|
||||||
|
root.setAttribute('data-bs-theme', dark ? 'dark' : 'light')
|
||||||
|
}
|
||||||
|
|
||||||
|
const STORAGE_KEY = 'darkMode'
|
||||||
|
const PREFER_DARK_QUERY = '(prefers-color-scheme: dark)'
|
||||||
|
|
||||||
|
const getTheme = () => {
|
||||||
|
const mql = window.matchMedia(PREFER_DARK_QUERY)
|
||||||
|
const supportsColorSchemeQuery = mql.media === PREFER_DARK_QUERY
|
||||||
|
let localStorageTheme = null
|
||||||
|
try {
|
||||||
|
localStorageTheme = window.localStorage.getItem(STORAGE_KEY)
|
||||||
|
} catch (err) {}
|
||||||
|
const localStorageExists = localStorageTheme !== null
|
||||||
|
if (localStorageExists) {
|
||||||
|
localStorageTheme = JSON.parse(localStorageTheme)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (localStorageExists) {
|
||||||
|
return { user: true, dark: localStorageTheme }
|
||||||
|
} else if (supportsColorSchemeQuery) {
|
||||||
|
return { user: false, dark: mql.matches }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const setTheme = (dark) => {
|
||||||
|
window.localStorage.setItem(STORAGE_KEY, JSON.stringify(dark))
|
||||||
|
handleThemeChange(dark)
|
||||||
|
}
|
||||||
|
|
||||||
|
const listenForThemeChange = (onChange) => {
|
||||||
|
const mql = window.matchMedia(PREFER_DARK_QUERY)
|
||||||
|
mql.onchange = mql => {
|
||||||
|
const { user, dark } = getTheme()
|
||||||
|
if (!user) {
|
||||||
|
handleThemeChange(dark)
|
||||||
|
onChange({ user, dark })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
window.onstorage = e => {
|
||||||
|
if (e.key === STORAGE_KEY) {
|
||||||
|
const dark = JSON.parse(e.newValue)
|
||||||
|
setTheme(dark)
|
||||||
|
onChange({ user: true, dark })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export default function useDarkMode () {
|
export default function useDarkMode () {
|
||||||
const [dark, setDark] = useState()
|
const [dark, setDark] = useState()
|
||||||
|
|
|
@ -41,7 +41,7 @@ module.exports = withPlausibleProxy()({
|
||||||
headers: corsHeaders
|
headers: corsHeaders
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
source: '/bs-dark.js',
|
source: '/dark-mode.js',
|
||||||
headers: [
|
headers: [
|
||||||
...corsHeaders
|
...corsHeaders
|
||||||
]
|
]
|
||||||
|
|
|
@ -5,6 +5,7 @@ class MyDocument extends Document {
|
||||||
return (
|
return (
|
||||||
<Html lang='en'>
|
<Html lang='en'>
|
||||||
<Head>
|
<Head>
|
||||||
|
<script src={`${process.env.NEXT_PUBLIC_ASSET_PREFIX}/dark-mode.js`} crossOrigin='' />
|
||||||
<link rel='manifest' href='/site.webmanifest' />
|
<link rel='manifest' href='/site.webmanifest' />
|
||||||
<link rel='preload' href={`${process.env.NEXT_PUBLIC_ASSET_PREFIX}/Lightningvolt-xoqm.woff2`} as='font' type='font/woff2' crossOrigin='' />
|
<link rel='preload' href={`${process.env.NEXT_PUBLIC_ASSET_PREFIX}/Lightningvolt-xoqm.woff2`} as='font' type='font/woff2' crossOrigin='' />
|
||||||
<link rel='preload' href={`${process.env.NEXT_PUBLIC_ASSET_PREFIX}/Lightningvolt-xoqm.woff`} as='font' type='font/woff' crossOrigin='' />
|
<link rel='preload' href={`${process.env.NEXT_PUBLIC_ASSET_PREFIX}/Lightningvolt-xoqm.woff`} as='font' type='font/woff' crossOrigin='' />
|
||||||
|
@ -58,7 +59,6 @@ class MyDocument extends Document {
|
||||||
<link rel='apple-touch-startup-image' media='screen and (device-width: 810px) and (device-height: 1080px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)' href='/splash/10.2__iPad_portrait.png' />
|
<link rel='apple-touch-startup-image' media='screen and (device-width: 810px) and (device-height: 1080px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)' href='/splash/10.2__iPad_portrait.png' />
|
||||||
<link rel='apple-touch-startup-image' media='screen and (device-width: 768px) and (device-height: 1024px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)' href='/splash/9.7__iPad_Pro__7.9__iPad_mini__9.7__iPad_Air__9.7__iPad_portrait.png' />
|
<link rel='apple-touch-startup-image' media='screen and (device-width: 768px) and (device-height: 1024px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)' href='/splash/9.7__iPad_Pro__7.9__iPad_mini__9.7__iPad_Air__9.7__iPad_portrait.png' />
|
||||||
<link rel='apple-touch-startup-image' media='screen and (device-width: 744px) and (device-height: 1133px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)' href='/splash/8.3__iPad_Mini_portrait.png' />
|
<link rel='apple-touch-startup-image' media='screen and (device-width: 744px) and (device-height: 1133px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)' href='/splash/8.3__iPad_Mini_portrait.png' />
|
||||||
<script src={`${process.env.NEXT_PUBLIC_ASSET_PREFIX}/bs-dark.js`} crossOrigin='' type='module' />
|
|
||||||
</Head>
|
</Head>
|
||||||
<body>
|
<body>
|
||||||
<Main />
|
<Main />
|
||||||
|
|
|
@ -6,7 +6,7 @@ const handleThemeChange = (dark) => {
|
||||||
const STORAGE_KEY = 'darkMode'
|
const STORAGE_KEY = 'darkMode'
|
||||||
const PREFER_DARK_QUERY = '(prefers-color-scheme: dark)'
|
const PREFER_DARK_QUERY = '(prefers-color-scheme: dark)'
|
||||||
|
|
||||||
export const getTheme = () => {
|
const getTheme = () => {
|
||||||
const mql = window.matchMedia(PREFER_DARK_QUERY)
|
const mql = window.matchMedia(PREFER_DARK_QUERY)
|
||||||
const supportsColorSchemeQuery = mql.media === PREFER_DARK_QUERY
|
const supportsColorSchemeQuery = mql.media === PREFER_DARK_QUERY
|
||||||
let localStorageTheme = null
|
let localStorageTheme = null
|
||||||
|
@ -25,29 +25,6 @@ export const getTheme = () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const setTheme = (dark) => {
|
|
||||||
window.localStorage.setItem(STORAGE_KEY, JSON.stringify(dark))
|
|
||||||
handleThemeChange(dark)
|
|
||||||
}
|
|
||||||
|
|
||||||
export const listenForThemeChange = (onChange) => {
|
|
||||||
const mql = window.matchMedia(PREFER_DARK_QUERY)
|
|
||||||
mql.onchange = mql => {
|
|
||||||
const { user, dark } = getTheme()
|
|
||||||
if (!user) {
|
|
||||||
handleThemeChange(dark)
|
|
||||||
onChange({ user, dark })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
window.onstorage = e => {
|
|
||||||
if (e.key === STORAGE_KEY) {
|
|
||||||
const dark = JSON.parse(e.newValue)
|
|
||||||
setTheme(dark)
|
|
||||||
onChange({ user: true, dark })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof window !== 'undefined') {
|
if (typeof window !== 'undefined') {
|
||||||
(function () {
|
(function () {
|
||||||
const { dark } = getTheme()
|
const { dark } = getTheme()
|
112
public/dark.js
112
public/dark.js
|
@ -1,112 +0,0 @@
|
||||||
const COLORS = {
|
|
||||||
light: {
|
|
||||||
body: '#f5f5f7',
|
|
||||||
color: '#212529',
|
|
||||||
navbarVariant: 'light',
|
|
||||||
navLink: 'rgba(0, 0, 0, 0.55)',
|
|
||||||
navLinkFocus: 'rgba(0, 0, 0, 0.7)',
|
|
||||||
navLinkActive: 'rgba(0, 0, 0, 0.9)',
|
|
||||||
borderColor: '#ced4da',
|
|
||||||
inputBg: '#ffffff',
|
|
||||||
inputDisabledBg: '#e9ecef',
|
|
||||||
dropdownItemColor: 'rgba(0, 0, 0, 0.7)',
|
|
||||||
dropdownItemColorHover: 'rgba(0, 0, 0, 0.9)',
|
|
||||||
commentBg: 'rgba(0, 0, 0, 0.03)',
|
|
||||||
clickToContextColor: 'rgba(0, 0, 0, 0.07)',
|
|
||||||
brandColor: 'rgba(0, 0, 0, 0.9)',
|
|
||||||
grey: '#707070',
|
|
||||||
link: '#007cbe',
|
|
||||||
toolbarActive: 'rgba(0, 0, 0, 0.10)',
|
|
||||||
toolbarHover: 'rgba(0, 0, 0, 0.20)',
|
|
||||||
toolbar: '#ffffff',
|
|
||||||
quoteBar: 'rgb(206, 208, 212)',
|
|
||||||
quoteColor: 'rgb(101, 103, 107)',
|
|
||||||
linkHover: '#004a72',
|
|
||||||
linkVisited: '#537587'
|
|
||||||
},
|
|
||||||
dark: {
|
|
||||||
body: '#000000',
|
|
||||||
inputBg: '#000000',
|
|
||||||
inputDisabledBg: '#000000',
|
|
||||||
navLink: 'rgba(255, 255, 255, 0.55)',
|
|
||||||
navLinkFocus: 'rgba(255, 255, 255, 0.75)',
|
|
||||||
navLinkActive: 'rgba(255, 255, 255, 0.9)',
|
|
||||||
borderColor: 'rgba(255, 255, 255, 0.5)',
|
|
||||||
dropdownItemColor: 'rgba(255, 255, 255, 0.7)',
|
|
||||||
dropdownItemColorHover: 'rgba(255, 255, 255, 0.9)',
|
|
||||||
commentBg: 'rgba(255, 255, 255, 0.04)',
|
|
||||||
clickToContextColor: 'rgba(255, 255, 255, 0.2)',
|
|
||||||
color: '#f8f9fa',
|
|
||||||
brandColor: 'var(--bs-primary)',
|
|
||||||
grey: '#969696',
|
|
||||||
link: '#2e99d1',
|
|
||||||
toolbarActive: 'rgba(255, 255, 255, 0.10)',
|
|
||||||
toolbarHover: 'rgba(255, 255, 255, 0.20)',
|
|
||||||
toolbar: '#3e3f3f',
|
|
||||||
quoteBar: 'rgb(158, 159, 163)',
|
|
||||||
quoteColor: 'rgb(141, 144, 150)',
|
|
||||||
linkHover: '#007cbe',
|
|
||||||
linkVisited: '#56798E'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleThemeChange = (dark) => {
|
|
||||||
const root = window.document.documentElement
|
|
||||||
const colors = COLORS[dark ? 'dark' : 'light']
|
|
||||||
Object.entries(colors).forEach(([varName, value]) => {
|
|
||||||
const cssVarName = `--theme-${varName}`
|
|
||||||
root.style.setProperty(cssVarName, value)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const STORAGE_KEY = 'darkMode'
|
|
||||||
const PREFER_DARK_QUERY = '(prefers-color-scheme: dark)'
|
|
||||||
|
|
||||||
export const getTheme = () => {
|
|
||||||
const mql = window.matchMedia(PREFER_DARK_QUERY)
|
|
||||||
const supportsColorSchemeQuery = mql.media === PREFER_DARK_QUERY
|
|
||||||
let localStorageTheme = null
|
|
||||||
try {
|
|
||||||
localStorageTheme = window.localStorage.getItem(STORAGE_KEY)
|
|
||||||
} catch (err) {}
|
|
||||||
const localStorageExists = localStorageTheme !== null
|
|
||||||
if (localStorageExists) {
|
|
||||||
localStorageTheme = JSON.parse(localStorageTheme)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (localStorageExists) {
|
|
||||||
return { user: true, dark: localStorageTheme }
|
|
||||||
} else if (supportsColorSchemeQuery) {
|
|
||||||
return { user: false, dark: mql.matches }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const setTheme = (dark) => {
|
|
||||||
window.localStorage.setItem(STORAGE_KEY, JSON.stringify(dark))
|
|
||||||
handleThemeChange(dark)
|
|
||||||
}
|
|
||||||
|
|
||||||
export const listenForThemeChange = (onChange) => {
|
|
||||||
const mql = window.matchMedia(PREFER_DARK_QUERY)
|
|
||||||
mql.onchange = mql => {
|
|
||||||
const { user, dark } = getTheme()
|
|
||||||
if (!user) {
|
|
||||||
handleThemeChange(dark)
|
|
||||||
onChange({ user, dark })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
window.onstorage = e => {
|
|
||||||
if (e.key === STORAGE_KEY) {
|
|
||||||
const dark = JSON.parse(e.newValue)
|
|
||||||
setTheme(dark)
|
|
||||||
onChange({ user: true, dark })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof window !== 'undefined') {
|
|
||||||
(function () {
|
|
||||||
const { dark } = getTheme()
|
|
||||||
handleThemeChange(dark)
|
|
||||||
})()
|
|
||||||
}
|
|
|
@ -32,7 +32,7 @@ function generatePrecacheManifest () {
|
||||||
|
|
||||||
const staticDir = join(__dirname, '../public')
|
const staticDir = join(__dirname, '../public')
|
||||||
const staticFiles = walkSync(staticDir)
|
const staticFiles = walkSync(staticDir)
|
||||||
const staticMatch = f => [/\.(gif|jpe?g|ico|png|ttf|woff|woff2|webmanifest)$/, /bs-dark\.js$/].some(m => m.test(f))
|
const staticMatch = f => [/\.(gif|jpe?g|ico|png|ttf|woff|woff2|webmanifest)$/, /dark-mode\.js$/].some(m => m.test(f))
|
||||||
staticFiles.filter(staticMatch).forEach(file => {
|
staticFiles.filter(staticMatch).forEach(file => {
|
||||||
const stats = statSync(file)
|
const stats = statSync(file)
|
||||||
addToManifest(file, file.slice(staticDir.length), stats.size)
|
addToManifest(file, file.slice(staticDir.length), stats.size)
|
||||||
|
|
Loading…
Reference in New Issue