Browse Source

add dark mode

dev
xmcp 6 years ago
parent
commit
29a921cf26
  1. 23
      src/App.js
  2. 21
      src/Common.css
  3. 11
      src/Common.js
  4. 39
      src/Flows.css
  5. 3
      src/Flows.js
  6. 18
      src/Sidebar.css
  7. 20
      src/Title.css
  8. 9
      src/color_picker.js
  9. 16
      src/index.css

23
src/App.js

@ -21,6 +21,7 @@ class App extends Component {
search_text: null, search_text: null,
flow_render_key: +new Date(), flow_render_key: +new Date(),
token: localStorage['TOKEN']||null, token: localStorage['TOKEN']||null,
darkmode: window.matchMedia('(prefers-color-scheme: dark)').matches,
}; };
this.show_sidebar_bound=this.show_sidebar.bind(this); this.show_sidebar_bound=this.show_sidebar.bind(this);
this.set_mode_bound=this.set_mode.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; 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() { on_pressure() {
if(this.state.sidebar_title!==null) if(this.state.sidebar_title!==null)
this.setState((prevState)=>({ this.setState((prevState)=>({

21
src/Common.css

@ -7,6 +7,10 @@
height: 100%; height: 100%;
} }
.root-dark-mode .bg-img {
opacity: .6;
}
.black-outline { .black-outline {
text-shadow: /* also change .flow-item-row-with-prompt:hover::before */ text-shadow: /* also change .flow-item-row-with-prompt:hover::before */
-1px -1px 0 rgba(0,0,0,.6), -1px -1px 0 rgba(0,0,0,.6),
@ -22,6 +26,23 @@
font-weight: bold; font-weight: bold;
} }
.root-dark-mode .search-query-highlight {
border-bottom: 1px solid white;
}
.url-pid-link { .url-pid-link {
opacity: .6; 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);
}

11
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; return txt ? new RegExp(`(${txt.split(split).filter((x)=>!!x).map(escape_regex).join('|')})`,'g') : /^$/g;
} }
function ColoredSpan(props) {
return (
<span className="colored-span" style={{
'--coloredspan-bgcolor-light': props.colors[0],
'--coloredspan-bgcolor-dark': props.colors[1],
}}>{props.children}</span>
)
}
export class HighlightedText extends PureComponent { export class HighlightedText extends PureComponent {
render() { render() {
function normalize_url(url) { function normalize_url(url) {
@ -31,7 +40,7 @@ export class HighlightedText extends PureComponent {
rule==='url_pid' ? <span className="url-pid-link" title={p}>/hole/##</span> : rule==='url_pid' ? <span className="url-pid-link" title={p}>/hole/##</span> :
rule==='url' ? <a href={normalize_url(p)} target="_blank" rel="noopener">{p}</a> : rule==='url' ? <a href={normalize_url(p)} target="_blank" rel="noopener">{p}</a> :
rule==='pid' ? <a href={'##'+p} onClick={(e)=>{e.preventDefault(); this.props.show_pid(p);}}>{p}</a> : rule==='pid' ? <a href={'##'+p} onClick={(e)=>{e.preventDefault(); this.props.show_pid(p);}}>{p}</a> :
rule==='nickname' ? <span style={{backgroundColor: this.props.color_picker.get(p)}}>{p}</span> : rule==='nickname' ? <ColoredSpan colors={this.props.color_picker.get(p)}>{p}</ColoredSpan> :
rule==='search' ? <span className="search-query-highlight">{p}</span> : rule==='search' ? <span className="search-query-highlight">{p}</span> :
p p
}</span> }</span>

39
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 { .box {
background-color: hsl(0,0%,97%); background-color: var(--box-bgcolor-light);
color: black;
border-radius: 5px; border-radius: 5px;
margin: 1em 0; margin: 1em 0;
padding: .5em; padding: .5em;
box-shadow: 0 2px 5px rgba(0,0,0,.4); 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 { .box-tip {
min-width: 100px; min-width: 100px;
z-index: 1; z-index: 1;
@ -18,6 +34,11 @@
text-shadow: 0 0 3px black; text-shadow: 0 0 3px black;
} }
.root-dark-mode .box-danger {
background-color: #d44;
color: var(--foreground-dark);
}
.left-container .flow-item { .left-container .flow-item {
display: inline-block; display: inline-block;
width: 600px; width: 600px;
@ -139,6 +160,10 @@
max-height: 80vh; max-height: 80vh;
} }
.root-dark-mode .flow-item-row p.img img {
filter: brightness(.8);
}
.box-header-badge { .box-header-badge {
float: right; float: right;
margin: 0 .5em; margin: 0 .5em;
@ -157,6 +182,10 @@
display: none; display: none;
} }
.root-dark-mode .flow-item-dot {
background-color: #eebb66;
}
.left-container .flow-item-dot { .left-container .flow-item-dot {
display: block; display: block;
} }
@ -174,6 +203,10 @@
color: #666666; color: #666666;
} }
.root-dark-mode .box-id {
color: #bbbbbb;
}
.box-id a:hover::before { .box-id a:hover::before {
content: "复制全文"; content: "复制全文";
position: relative; position: relative;
@ -225,3 +258,7 @@
margin-right: .25em; margin-right: .25em;
padding: 0 .25em; padding: 0 .25em;
} }
.root-dark-mode .box-header-tag {
background-color: #00a;
}

3
src/Flows.js

@ -80,7 +80,8 @@ class Reply extends PureComponent {
]); ]);
return ( return (
<div className={'flow-reply box'} style={this.props.info._display_color ? { <div className={'flow-reply box'} style={this.props.info._display_color ? {
backgroundColor: this.props.info._display_color, '--box-bgcolor-light': this.props.info._display_color[0],
'--box-bgcolor-dark': this.props.info._display_color[1],
} : null}> } : null}>
<div className="box-header"> <div className="box-header">
<code className="box-id">#{this.props.info.cid}</code> <code className="box-id">#{this.props.info.cid}</code>

18
src/Sidebar.css

@ -20,6 +20,13 @@
transition: unset; transition: unset;
} }
.root-dark-mode .sidebar-on .sidebar-shadow {
opacity: .5;
}
.root-dark-mode .sidebar-on .sidebar-shadow:active {
opacity: .3;
}
.sidebar { .sidebar {
user-select: text; user-select: text;
position: fixed; position: fixed;
@ -32,6 +39,10 @@
backdrop-filter: blur(10px); backdrop-filter: blur(10px);
} }
.root-dark-mode .sidebar {
background-color: hsla(0,0%,5%,.7);
}
.sidebar, .sidebar-title { .sidebar, .sidebar-title {
will-change: left; will-change: left;
left: 100%; left: 100%;
@ -56,6 +67,13 @@
backdrop-filter: blur(10px); backdrop-filter: blur(10px);
box-shadow: 0 3px 5px rgba(0,0,0,.2); 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 { .sidebar-title a {
pointer-events: initial; pointer-events: initial;
} }

20
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 { .title-bar {
z-index: 10; z-index: 10;
position: sticky; position: sticky;
@ -11,6 +19,10 @@
backdrop-filter: blur(10px); backdrop-filter: blur(10px);
} }
.root-dark-mode .title-bar {
background-color: hsla(0,0%,80%,.7);
}
.control-bar { .control-bar {
display: flex; display: flex;
margin-top: .5em; margin-top: .5em;
@ -36,13 +48,17 @@
.control-search { .control-search {
flex: auto; flex: auto;
color: black; color: black;
background-color: rgba(255,255,255,.3); background-color: rgba(255,255,255,.3) !important;
margin: 0 .5em; margin: 0 .5em;
min-width: 8em; min-width: 8em;
} }
.control-search:focus { .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 { .list-menu {

9
src/color_picker.js

@ -11,14 +11,17 @@ export class ColorPicker {
get(name) { get(name) {
name=name.toLowerCase(); name=name.toLowerCase();
if(name==='洞主') if(name==='洞主')
return 'hsl(0,0%,97%)'; return ['hsl(0,0%,97%)','hsl(0,0%,25%)'];
if(!window.config.color_picker) if(!window.config.color_picker)
return 'hsl(0,0%,87%)'; return ['hsl(0,0%,87%)','hsl(0,0%,13%)'];
if(!this.names[name]) { if(!this.names[name]) {
this.current_h+=golden_ratio_conjugate; this.current_h+=golden_ratio_conjugate;
this.current_h%=1; 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]; return this.names[name];
} }

16
src/index.css

@ -4,6 +4,10 @@ body {
background-color: #333; background-color: #333;
} }
body.root-dark-mode {
background-color: black;
}
html::-webkit-scrollbar { html::-webkit-scrollbar {
display: none; display: none;
} }
@ -15,6 +19,10 @@ a {
color: #00c; color: #00c;
} }
.root-dark-mode .left-container a, .root-dark-mode .sidebar a, .root-dark-mode .sidebar-title a {
color: #9bf;
}
input, textarea { input, textarea {
border-radius: 5px; border-radius: 5px;
border: 1px solid black; border: 1px solid black;
@ -39,6 +47,10 @@ button, .button {
margin: 0 .5rem; margin: 0 .5rem;
} }
.root-dark-mode button, .root-dark-mode .button {
background-color: rgba(255,255,255,.6);
}
button:hover, .button:hover { button:hover, .button:hover {
background-color: rgba(255,255,255,.7); background-color: rgba(255,255,255,.7);
} }
@ -46,3 +58,7 @@ button:hover, .button:hover {
button:disabled, .button:disabled { button:disabled, .button:disabled {
background-color: rgba(128,128,128,.5); background-color: rgba(128,128,128,.5);
} }
.root-dark-mode input:not([type=file]), .root-dark-mode textarea {
background-color: hsl(0,0%,80%);
}
Loading…
Cancel
Save