diff --git a/src/App.js b/src/App.js index 50778b5..0043513 100644 --- a/src/App.js +++ b/src/App.js @@ -21,6 +21,7 @@ class App extends Component { search_text: null, flow_render_key: +new Date(), token: localStorage['TOKEN']||null, + darkmode: window.matchMedia('(prefers-color-scheme: dark)').matches, }; this.show_sidebar_bound=this.show_sidebar.bind(this); this.set_mode_bound=this.set_mode.bind(this); @@ -30,6 +31,28 @@ class App extends Component { this.inpku_flag=window[atob('ZG9jdW1lbnQ')][atob('Y29va2ll')].indexOf(atob('cGt1X2lwX2ZsYWc9eWVz'))!==-1; } + componentDidMount() { + this.update_color_scheme(); + window.matchMedia('(prefers-color-scheme: dark)').addListener((e)=>{ + this.setState({ + darkmode: e.matches, + }); + }); + } + + componentDidUpdate(prevProps,prevState) { + if(this.state.darkmode!==prevState.darkmode) + this.update_color_scheme(); + } + + update_color_scheme() { + if(this.state.darkmode) + document.body.classList.add('root-dark-mode'); + else + document.body.classList.remove('root-dark-mode'); + } + + on_pressure() { if(this.state.sidebar_title!==null) this.setState((prevState)=>({ diff --git a/src/Common.css b/src/Common.css index b1ca4eb..2448f61 100644 --- a/src/Common.css +++ b/src/Common.css @@ -7,6 +7,10 @@ height: 100%; } +.root-dark-mode .bg-img { + opacity: .6; +} + .black-outline { text-shadow: /* also change .flow-item-row-with-prompt:hover::before */ -1px -1px 0 rgba(0,0,0,.6), @@ -22,6 +26,23 @@ font-weight: bold; } +.root-dark-mode .search-query-highlight { + border-bottom: 1px solid white; +} + .url-pid-link { opacity: .6; +} + +:root { + --coloredspan-bgcolor-light: white; + --coloredspan-bgcolor-dark: black; +} + +.colored-span { + background-color: var(--coloredspan-bgcolor-light); +} + +.root-dark-mode .colored-span { + background-color: var(--coloredspan-bgcolor-dark); } \ No newline at end of file diff --git a/src/Common.js b/src/Common.js index 0c01710..fe53dac 100644 --- a/src/Common.js +++ b/src/Common.js @@ -17,6 +17,15 @@ export function build_highlight_re(txt,split) { return txt ? new RegExp(`(${txt.split(split).filter((x)=>!!x).map(escape_regex).join('|')})`,'g') : /^$/g; } +function ColoredSpan(props) { + return ( + {props.children} + ) +} + export class HighlightedText extends PureComponent { render() { function normalize_url(url) { @@ -31,7 +40,7 @@ export class HighlightedText extends PureComponent { rule==='url_pid' ? /hole/## : rule==='url' ? {p} : rule==='pid' ? {e.preventDefault(); this.props.show_pid(p);}}>{p} : - rule==='nickname' ? {p} : + rule==='nickname' ? {p} : rule==='search' ? {p} : p } diff --git a/src/Flows.css b/src/Flows.css index 9de99fb..c8f7908 100644 --- a/src/Flows.css +++ b/src/Flows.css @@ -1,11 +1,27 @@ +:root { + --box-bgcolor-light: hsl(0,0%,97%); + --box-bgcolor-dark: hsl(0,0%,20%); + --foreground-dark: hsl(0,0%,93%) +} + .box { - background-color: hsl(0,0%,97%); + background-color: var(--box-bgcolor-light); + color: black; border-radius: 5px; margin: 1em 0; padding: .5em; box-shadow: 0 2px 5px rgba(0,0,0,.4); } +.root-dark-mode .box { + background-color: var(--box-bgcolor-dark); + color: var(--foreground-dark); +} + +.root-dark-mode .sidebar .box { + --box-bgcolor-dark: hsl(0,0%,25%); +} + .box-tip { min-width: 100px; z-index: 1; @@ -18,6 +34,11 @@ text-shadow: 0 0 3px black; } +.root-dark-mode .box-danger { + background-color: #d44; + color: var(--foreground-dark); +} + .left-container .flow-item { display: inline-block; width: 600px; @@ -139,6 +160,10 @@ max-height: 80vh; } +.root-dark-mode .flow-item-row p.img img { + filter: brightness(.8); +} + .box-header-badge { float: right; margin: 0 .5em; @@ -157,6 +182,10 @@ display: none; } +.root-dark-mode .flow-item-dot { + background-color: #eebb66; +} + .left-container .flow-item-dot { display: block; } @@ -174,6 +203,10 @@ color: #666666; } +.root-dark-mode .box-id { + color: #bbbbbb; +} + .box-id a:hover::before { content: "复制全文"; position: relative; @@ -224,4 +257,8 @@ border-radius: 3px; margin-right: .25em; padding: 0 .25em; +} + +.root-dark-mode .box-header-tag { + background-color: #00a; } \ No newline at end of file diff --git a/src/Flows.js b/src/Flows.js index ed4341f..0fe639e 100644 --- a/src/Flows.js +++ b/src/Flows.js @@ -80,7 +80,8 @@ class Reply extends PureComponent { ]); return (
#{this.props.info.cid} diff --git a/src/Sidebar.css b/src/Sidebar.css index 017dd8d..40b1cba 100644 --- a/src/Sidebar.css +++ b/src/Sidebar.css @@ -20,6 +20,13 @@ transition: unset; } +.root-dark-mode .sidebar-on .sidebar-shadow { + opacity: .5; +} +.root-dark-mode .sidebar-on .sidebar-shadow:active { + opacity: .3; +} + .sidebar { user-select: text; position: fixed; @@ -32,6 +39,10 @@ backdrop-filter: blur(10px); } +.root-dark-mode .sidebar { + background-color: hsla(0,0%,5%,.7); +} + .sidebar, .sidebar-title { will-change: left; left: 100%; @@ -56,6 +67,13 @@ backdrop-filter: blur(10px); box-shadow: 0 3px 5px rgba(0,0,0,.2); } + +.root-dark-mode .sidebar-title { + background-color: hsla(0,0%,20%,.6); + color: var(--foreground-dark); + text-shadow: 0 0 3px black; +} + .sidebar-title a { pointer-events: initial; } diff --git a/src/Title.css b/src/Title.css index 31c7335..5e8f926 100644 --- a/src/Title.css +++ b/src/Title.css @@ -1,3 +1,11 @@ +/* overriding infrastructure/widget.css */ +.root-dark-mode .title-line { + color: var(--foreground-dark); +} +.root-dark-mode .title-line::before, .root-dark-mode .title-line::after { + background-color: var(--foreground-dark); +} + .title-bar { z-index: 10; position: sticky; @@ -11,6 +19,10 @@ backdrop-filter: blur(10px); } +.root-dark-mode .title-bar { + background-color: hsla(0,0%,80%,.7); +} + .control-bar { display: flex; margin-top: .5em; @@ -36,13 +48,17 @@ .control-search { flex: auto; color: black; - background-color: rgba(255,255,255,.3); + background-color: rgba(255,255,255,.3) !important; margin: 0 .5em; min-width: 8em; } .control-search:focus { - background-color: white; + background-color: white !important; +} + +.root-dark-mode .control-search:focus { + background-color: hsl(0,0%,90%) !important; } .list-menu { diff --git a/src/color_picker.js b/src/color_picker.js index ca4f2e9..cff6ead 100644 --- a/src/color_picker.js +++ b/src/color_picker.js @@ -11,14 +11,17 @@ export class ColorPicker { get(name) { name=name.toLowerCase(); if(name==='洞主') - return 'hsl(0,0%,97%)'; + return ['hsl(0,0%,97%)','hsl(0,0%,25%)']; if(!window.config.color_picker) - return 'hsl(0,0%,87%)'; + return ['hsl(0,0%,87%)','hsl(0,0%,13%)']; if(!this.names[name]) { this.current_h+=golden_ratio_conjugate; this.current_h%=1; - this.names[name]=`hsl(${this.current_h*360}, 50%, 90%)`; + this.names[name]=[ + `hsl(${this.current_h*360}, 50%, 90%)`, + `hsl(${this.current_h*360}, 60%, 25%)`, + ]; } return this.names[name]; } diff --git a/src/index.css b/src/index.css index 0335be4..ffdd16c 100644 --- a/src/index.css +++ b/src/index.css @@ -4,6 +4,10 @@ body { background-color: #333; } +body.root-dark-mode { + background-color: black; +} + html::-webkit-scrollbar { display: none; } @@ -15,6 +19,10 @@ a { color: #00c; } +.root-dark-mode .left-container a, .root-dark-mode .sidebar a, .root-dark-mode .sidebar-title a { + color: #9bf; +} + input, textarea { border-radius: 5px; border: 1px solid black; @@ -39,6 +47,10 @@ button, .button { margin: 0 .5rem; } +.root-dark-mode button, .root-dark-mode .button { + background-color: rgba(255,255,255,.6); +} + button:hover, .button:hover { background-color: rgba(255,255,255,.7); } @@ -46,3 +58,7 @@ button:hover, .button:hover { button:disabled, .button:disabled { background-color: rgba(128,128,128,.5); } + +.root-dark-mode input:not([type=file]), .root-dark-mode textarea { + background-color: hsl(0,0%,80%); +} \ No newline at end of file