fix dark mode

This commit is contained in:
keyan 2023-08-04 19:21:51 -05:00
parent 23257d8c63
commit 8d8e2859dd
14 changed files with 143 additions and 35 deletions

View File

@ -89,7 +89,7 @@ export function WhenAreaChart ({ data }) {
tick={{ fill: 'var(--theme-grey)' }} tick={{ fill: 'var(--theme-grey)' }}
/> />
<YAxis tickFormatter={abbrNum} tick={{ fill: 'var(--theme-grey)' }} /> <YAxis tickFormatter={abbrNum} tick={{ fill: 'var(--theme-grey)' }} />
<Tooltip labelFormatter={dateFormatter(when)} contentStyle={{ color: 'var(--theme-color)', backgroundColor: 'var(--theme-body)' }} /> <Tooltip labelFormatter={dateFormatter(when)} contentStyle={{ color: 'var(--bs-body-color)', backgroundColor: 'var(--bs-body-bg)' }} />
<Legend /> <Legend />
{Object.keys(data[0]).filter(v => v !== 'time' && v !== '__typename').map((v, i) => {Object.keys(data[0]).filter(v => v !== 'time' && v !== '__typename').map((v, i) =>
<Area key={v} type='monotone' dataKey={v} name={v} stackId='1' stroke={COLORS[i]} fill={COLORS[i]} />)} <Area key={v} type='monotone' dataKey={v} name={v} stackId='1' stroke={COLORS[i]} fill={COLORS[i]} />)}
@ -124,7 +124,7 @@ export function WhenLineChart ({ data }) {
tick={{ fill: 'var(--theme-grey)' }} tick={{ fill: 'var(--theme-grey)' }}
/> />
<YAxis tickFormatter={abbrNum} tick={{ fill: 'var(--theme-grey)' }} /> <YAxis tickFormatter={abbrNum} tick={{ fill: 'var(--theme-grey)' }} />
<Tooltip labelFormatter={dateFormatter(when)} contentStyle={{ color: 'var(--theme-color)', backgroundColor: 'var(--theme-body)' }} /> <Tooltip labelFormatter={dateFormatter(when)} contentStyle={{ color: 'var(--bs-body-color)', backgroundColor: 'var(--bs-body-bg)' }} />
<Legend /> <Legend />
{Object.keys(data[0]).filter(v => v !== 'time' && v !== '__typename').map((v, i) => {Object.keys(data[0]).filter(v => v !== 'time' && v !== '__typename').map((v, i) =>
<Line key={v} type='monotone' dataKey={v} name={v} stroke={COLORS[i]} fill={COLORS[i]} />)} <Line key={v} type='monotone' dataKey={v} name={v} stroke={COLORS[i]} fill={COLORS[i]} />)}
@ -160,7 +160,7 @@ export function WhenComposedChart ({ data, lineNames, areaNames, barNames }) {
/> />
<YAxis yAxisId='left' orientation='left' allowDecimals={false} stroke='var(--theme-grey)' tickFormatter={abbrNum} tick={{ fill: 'var(--theme-grey)' }} /> <YAxis yAxisId='left' orientation='left' allowDecimals={false} stroke='var(--theme-grey)' tickFormatter={abbrNum} tick={{ fill: 'var(--theme-grey)' }} />
<YAxis yAxisId='right' orientation='right' allowDecimals={false} stroke='var(--theme-grey)' tickFormatter={abbrNum} tick={{ fill: 'var(--theme-grey)' }} /> <YAxis yAxisId='right' orientation='right' allowDecimals={false} stroke='var(--theme-grey)' tickFormatter={abbrNum} tick={{ fill: 'var(--theme-grey)' }} />
<Tooltip labelFormatter={dateFormatter(when)} contentStyle={{ color: 'var(--theme-color)', backgroundColor: 'var(--theme-body)' }} /> <Tooltip labelFormatter={dateFormatter(when)} contentStyle={{ color: 'var(--bs-body-color)', backgroundColor: 'var(--bs-body-bg)' }} />
<Legend /> <Legend />
{barNames?.map((v, i) => {barNames?.map((v, i) =>
<Bar yAxisId='right' key={v} type='monotone' dataKey={v} name={v} stroke='var(--bs-info)' fill='var(--bs-info)' />)} <Bar yAxisId='right' key={v} type='monotone' dataKey={v} name={v} stroke='var(--bs-info)' fill='var(--bs-info)' />)}

View File

@ -1,5 +1,5 @@
import { useEffect, useState } from 'react' import { useEffect, useState } from 'react'
import { getTheme, listenForThemeChange, setTheme } from '../public/dark' import { getTheme, listenForThemeChange, setTheme } from '../public/bs-dark'
export default function useDarkMode () { export default function useDarkMode () {
const [dark, setDark] = useState() const [dark, setDark] = useState()

View File

@ -9,7 +9,7 @@
.receipt td { .receipt td {
padding: .25rem .1rem; padding: .25rem .1rem;
background-color: var(--theme-inputBg); background-color: var(--theme-inputBg);
color: var(--theme-color); color: var(--bs-body-color);
} }
.receipt tfoot { .receipt tfoot {

View File

@ -11,13 +11,13 @@
} }
.contrastLink { .contrastLink {
color: var(--theme-color); color: var(--bs-body-color);
} }
.contrastLink:hover { .contrastLink:hover {
color: var(--theme-color); color: var(--bs-body-color);
} }
.contrastLink svg { .contrastLink svg {
fill: var(--theme-color); fill: var(--bs-body-color);
} }
.version { .version {

View File

@ -38,7 +38,7 @@
background-color: var(--bs-primary); background-color: var(--bs-primary);
top: 3px; top: 3px;
right: 0px; right: 0px;
border: 1px solid var(--theme-body); border: 1px solid var(--bs-body-bg);
} }
.notification { .notification {
@ -47,7 +47,7 @@
background-color: var(--bs-danger); background-color: var(--bs-danger);
top: 1px; top: 1px;
right: 8px; right: 8px;
border: 1px solid var(--theme-body); border: 1px solid var(--bs-body-bg);
} }
.navbarNav { .navbarNav {

View File

@ -16,7 +16,7 @@
.searchSection.solid { .searchSection.solid {
pointer-events: auto; pointer-events: auto;
background: var(--theme-body); background: var(--bs-body-bg);
box-shadow: 0 -4px 12px hsl(0deg 0% 59% / 10%); box-shadow: 0 -4px 12px hsl(0deg 0% 59% / 10%);
} }

View File

@ -27,7 +27,7 @@
} }
.cover { .cover {
background: var(--theme-body); background: var(--bs-body-bg);
width: 100%; width: 100%;
overflow: hidden; overflow: hidden;
mix-blend-mode: color; mix-blend-mode: color;

View File

@ -41,7 +41,7 @@ module.exports = withPlausibleProxy()({
headers: corsHeaders headers: corsHeaders
}, },
{ {
source: '/dark.js', source: '/bs-dark.js',
headers: [ headers: [
...corsHeaders ...corsHeaders
] ]

View File

@ -58,7 +58,7 @@ 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}/dark.js`} crossOrigin='' type='module' /> <script src={`${process.env.NEXT_PUBLIC_ASSET_PREFIX}/bs-dark.js`} crossOrigin='' type='module' />
</Head> </Head>
<body> <body>
<Main /> <Main />

View File

@ -37,7 +37,7 @@ function Ots ({ item }) {
: ( : (
<pre <pre
className='mb-2 p-2 rounded' className='mb-2 p-2 rounded'
style={{ whiteSpace: 'pre-wrap', wordWrap: 'break-word', border: '1px solid var(--theme-borderColor)', color: 'var(--theme-color)' }} style={{ whiteSpace: 'pre-wrap', wordWrap: 'break-word', border: '1px solid var(--theme-borderColor)', color: 'var(--bs-body-color)' }}
>{itemString} >{itemString}
</pre>)} </pre>)}
<Button href={`/api/ots/preimage/${item.id}`} className='mt-1' variant='grey-medium'>download preimage</Button> <Button href={`/api/ots/preimage/${item.id}`} className='mt-1' variant='grey-medium'>download preimage</Button>

View File

@ -245,7 +245,7 @@ export default function Settings ({ ssrData }) {
name='greeterMode' name='greeterMode'
/> />
<AccordianItem <AccordianItem
headerColor='var(--theme-color)' headerColor='var(--bs-body-color)'
show={settings?.nostrPubkey} show={settings?.nostrPubkey}
header={<h4 className='text-left'>nostr <small><a href='https://github.com/nostr-protocol/nips/blob/master/05.md' target='_blank' rel='noreferrer'>NIP-05</a></small></h4>} header={<h4 className='text-left'>nostr <small><a href='https://github.com/nostr-protocol/nips/blob/master/05.md' target='_blank' rel='noreferrer'>NIP-05</a></small></h4>}
body={ body={

56
public/bs-dark.js Normal file
View File

@ -0,0 +1,56 @@
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)'
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)
})()
}

View File

@ -23,7 +23,10 @@ $theme-colors: (
"grey-darkmode": #8c8c8c, "grey-darkmode": #8c8c8c,
); );
$body-bg: #f5f5f7; $body-bg: #fcfcff;
$body-bg-dark: #121214;
$body-color: #212529;
$body-color-dark: #f0f0f0;
$border-radius: .4rem; $border-radius: .4rem;
$enable-transitions: false; $enable-transitions: false;
$enable-gradients: false; $enable-gradients: false;
@ -41,6 +44,10 @@ $btn-font-weight: bold;
$btn-focus-width: 0; $btn-focus-width: 0;
$btn-border-width: 0; $btn-border-width: 0;
$btn-focus-box-shadow: none; $btn-focus-box-shadow: none;
$form-invalid-border-color: #c03221;
$form-invalid-border-color-dark: #c03221;
$form-invalid-color: #c03221;
$form-invalid-color-dark: #c03221;
$alert-border-width: 0; $alert-border-width: 0;
$close-text-shadow: none; $close-text-shadow: none;
$close-color: inherit; $close-color: inherit;
@ -69,11 +76,12 @@ $nav-tabs-link-hover-border-color: transparent;
$nav-tabs-link-active-border-color: #ced4da #ced4da $nav-tabs-link-active-bg; $nav-tabs-link-active-border-color: #ced4da #ced4da $nav-tabs-link-active-bg;
$form-check-input-checked-color: var(--bs-primary); $form-check-input-checked-color: var(--bs-primary);
$form-check-input-checked-bg-color: var(--bs-primary); $form-check-input-checked-bg-color: var(--bs-primary);
$popover-bg: var(--theme-body); $popover-bg: var(--bs-body-bg);
$form-check-input-checked-color: #000; $form-check-input-checked-color: #000;
$tooltip-bg: #5c8001; $tooltip-bg: #5c8001;
$form-select-indicator-color: #808080; $form-select-indicator-color: #808080;
$form-select-indicator: url("data:image/svg+xml, %3Csvg fill='#{$form-select-indicator-color}' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 15.0006L7.75732 10.758L9.17154 9.34375L12 12.1722L14.8284 9.34375L16.2426 10.758L12 15.0006Z'%3E%3C/path%3E%3C/svg%3E%0A"); $form-select-indicator: url("data:image/svg+xml, %3Csvg fill='#{$form-select-indicator-color}' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 15.0006L7.75732 10.758L9.17154 9.34375L12 12.1722L14.8284 9.34375L16.2426 10.758L12 15.0006Z'%3E%3C/path%3E%3C/svg%3E%0A");
$form-select-indicator-dark: url("data:image/svg+xml, %3Csvg fill='#{$form-select-indicator-color}' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 15.0006L7.75732 10.758L9.17154 9.34375L12 12.1722L14.8284 9.34375L16.2426 10.758L12 15.0006Z'%3E%3C/path%3E%3C/svg%3E%0A");
$form-select-bg-position: right .25rem center; $form-select-bg-position: right .25rem center;
$form-select-bg-size: 1.5rem; $form-select-bg-size: 1.5rem;
$popover-body-padding-y: .5rem; $popover-body-padding-y: .5rem;
@ -81,6 +89,49 @@ $popover-max-width: 320px !default;
$popover-border-color: var(--theme-borderColor); $popover-border-color: var(--theme-borderColor);
$grid-gutter-width: 2rem; $grid-gutter-width: 2rem;
:root, [data-bs-theme=light] {
--theme-navLink: rgba(0, 0, 0, 0.55);
--theme-navLinkFocus: rgba(0, 0, 0, 0.7);
--theme-navLinkActive: rgba(0, 0, 0, 0.9);
--theme-borderColor: #ced4da;
--theme-inputBg: #ffffff;
--theme-inputDisabledBg: #e9ecef;
--theme-dropdownItemColor: rgba(0, 0, 0, 0.7);
--theme-dropdownItemColorHover: rgba(0, 0, 0, 0.9);
--theme-commentBg: rgba(0, 0, 0, 0.03);
--theme-clickToContextColor: rgba(0, 0, 0, 0.07);
--theme-brandColor: rgba(0, 0, 0, 0.9);
--theme-grey: #707070;
--theme-link: #007cbe;
--theme-quoteBar: rgb(206, 208, 212);
--theme-linkHover: #004a72;
--theme-linkVisited: #53758;
}
[data-bs-theme=dark] {
color-scheme: dark;
--theme-inputBg: #121211;
--theme-inputDisabledBg: #121211;
--theme-navLink: rgba(255, 255, 255, 0.55);
--theme-navLinkFocus: rgba(255, 255, 255, 0.75);
--theme-navLinkActive: rgba(255, 255, 255, 0.9);
--theme-borderColor: rgba(255, 255, 255, 0.5);
--theme-dropdownItemColor: rgba(255, 255, 255, 0.7);
--theme-dropdownItemColorHover: rgba(255, 255, 255, 0.9);
--theme-commentBg: rgba(255, 255, 255, 0.025);
--theme-clickToContextColor: rgba(255, 255, 255, 0.1);
--theme-brandColor: var(--bs-primary);
--theme-grey: #969696;
--theme-link: #2e99d1;
--theme-toolbarActive: rgba(255, 255, 255, 0.10);
--theme-toolbarHover: rgba(255, 255, 255, 0.20);
--theme-toolbar: #3e3f3f;
--theme-quoteBar: rgb(158, 159, 163);
--theme-quoteColor: rgb(141, 144, 150);
--theme-linkHover: #007cbe;
--theme-linkVisited: #56798E;
}
@import '../node_modules/bootstrap/scss/bootstrap.scss'; @import '../node_modules/bootstrap/scss/bootstrap.scss';
@media screen and (min-width: 899px) { @media screen and (min-width: 899px) {
@ -154,7 +205,7 @@ dl {
mark { mark {
background-color: #fada5e5e; background-color: #fada5e5e;
padding: 0 0.2rem; padding: 0 0.2rem;
color: var(--theme-color); color: var(--bs-body-color);
} }
.table-sm th, .table-sm th,
@ -181,8 +232,8 @@ mark {
} }
.table { .table {
color: var(--theme-color); color: var(--bs-body-color);
background-color: var(--theme-body); background-color: var(--bs-body-bg);
} }
.table th, .table th,
@ -192,13 +243,13 @@ mark {
} }
.table-hover tbody tr:hover { .table-hover tbody tr:hover {
color: var(--theme-color); color: var(--bs-body-color);
background-color: var(--theme-clickToContextColor); background-color: var(--theme-clickToContextColor);
} }
html, body { html, body {
background: var(--theme-body) !important; background: var(--bs-body-bg) !important;
color: var(--theme-color) !important; color: var(--bs-body-color) !important;
min-height: 100vh; min-height: 100vh;
min-height: 100svh; min-height: 100svh;
} }
@ -223,7 +274,7 @@ select,
div[contenteditable], div[contenteditable],
.form-control { .form-control {
background-color: var(--theme-inputBg); background-color: var(--theme-inputBg);
color: var(--theme-color); color: var(--bs-body-color);
border-color: var(--theme-borderColor); border-color: var(--theme-borderColor);
} }
@ -265,7 +316,7 @@ select:focus {
div[contenteditable]:focus, div[contenteditable]:focus,
.form-control:focus { .form-control:focus {
background-color: var(--theme-inputBg); background-color: var(--theme-inputBg);
color: var(--theme-color); color: var(--bs-body-color);
outline: 0; outline: 0;
box-shadow: 0 0 0 0.2rem rgb(250 218 94 / 25%); box-shadow: 0 0 0 0.2rem rgb(250 218 94 / 25%);
} }
@ -415,7 +466,7 @@ footer {
.input-group-text { .input-group-text {
background-color: var(--theme-clickToContextColor); background-color: var(--theme-clickToContextColor);
border-color: var(--theme-borderColor); border-color: var(--theme-borderColor);
color: var(--theme-color); color: var(--bs-body-color);
} }
textarea.form-control, textarea.form-control,
@ -454,8 +505,8 @@ div[contenteditable] {
} }
.popover { .popover {
color: var(--theme-color); color: var(--bs-body-color);
background-color: var(--theme-body); background-color: var(--bs-body-bg);
border-color: var(--theme-borderColor); border-color: var(--theme-borderColor);
} }
@ -464,7 +515,7 @@ div[contenteditable] {
} }
.popover .arrow::after { .popover .arrow::after {
border-top-color: var(--theme-body); border-top-color: var(--bs-body-bg);
} }
@ -575,7 +626,7 @@ div[contenteditable]:focus,
} }
.fill-theme-color { .fill-theme-color {
fill: var(--theme-color); fill: var(--bs-body-color);
} }
.fill-warning { .fill-warning {
@ -704,14 +755,15 @@ div[contenteditable]:focus,
.tooltip-inner { .tooltip-inner {
padding: 0.1rem 0.3rem; padding: 0.1rem 0.3rem;
color: #fff;
} }
.popover { .popover {
.popover-header { .popover-header {
background-color: var(--theme-body); background-color: var(--bs-body-bg);
color: var(--theme-color); color: var(--bs-body-color);
} }
.popover-body { .popover-body {
color: var(--theme-color); color: var(--bs-body-color);
} }
} }

View File

@ -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)$/, /dark\.js$/].some(m => m.test(f)) const staticMatch = f => [/\.(gif|jpe?g|ico|png|ttf|woff|woff2|webmanifest)$/, /bs-dark\.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)