diff --git a/public/static/css/white.css b/public/static/css/white.css index 60b63da..96afe3f 100644 --- a/public/static/css/white.css +++ b/public/static/css/white.css @@ -371,7 +371,7 @@ color: #16a085; } .theme-default a:hover { - color: cc#2ecc71; + color: #2ecc71; } .theme-default input:focus { opacity: 0.8; diff --git a/src/client/web/src/components/__test__/pane_settings.test.tsx b/src/client/web/src/components/__test__/pane_settings.test.tsx index ae3f213..d3fd5ff 100644 --- a/src/client/web/src/components/__test__/pane_settings.test.tsx +++ b/src/client/web/src/components/__test__/pane_settings.test.tsx @@ -34,6 +34,7 @@ describe("PaneSettings", () => { const paneSettings = new PaneSettings({ msg: coreState.msg, login: coreState.login, + ui: coreState.ui, update: (updater: (prevState: ICoreState) => ICoreState) => {}, }); diff --git a/src/client/web/src/components/dialog_settings.tsx b/src/client/web/src/components/dialog_settings.tsx index b832e0e..5c58279 100644 --- a/src/client/web/src/components/dialog_settings.tsx +++ b/src/client/web/src/components/dialog_settings.tsx @@ -62,6 +62,7 @@ export class SettingsDialog extends React.Component { diff --git a/src/client/web/src/components/pane_admin.tsx b/src/client/web/src/components/pane_admin.tsx index 3109382..9666a30 100644 --- a/src/client/web/src/components/pane_admin.tsx +++ b/src/client/web/src/components/pane_admin.tsx @@ -576,20 +576,7 @@ export class AdminPane extends React.Component { return (
- {this.props.msg.pkg.get("siteSettings")}, - , - ])} - childrenStyles={List([{}, { justifyContent: "flex-end" }])} - /> - - - - - { } } -interface BgProps { +interface SiteCfgProps { msg: MsgProps; ui: UIProps; update?: (updater: (prevState: ICoreState) => ICoreState) => void; } -interface BgState { } -export class BgCfg extends React.Component { +interface SiteCfgState {} +export class SiteCfg extends React.Component { onChangeSiteName = (ev: React.ChangeEvent) => { - updater().setClientCfg({ ...this.props.ui.clientCfg, siteName: ev.target.value }); + updater().setClientCfg({ + ...this.props.ui.clientCfg, + siteName: ev.target.value, + }); this.props.update(updater().updateUI); }; onChangeSiteDesc = (ev: React.ChangeEvent) => { - updater().setClientCfg({ ...this.props.ui.clientCfg, siteDesc: ev.target.value }); + updater().setClientCfg({ + ...this.props.ui.clientCfg, + siteDesc: ev.target.value, + }); this.props.update(updater().updateUI); }; onChangeAllowSetBg = (enabled: boolean) => { @@ -782,7 +775,7 @@ export class BgCfg extends React.Component { this.props.update(updater().updateUI); }; - constructor(p: BgProps) { + constructor(p: SiteCfgProps) { super(p); } @@ -870,7 +863,9 @@ export class BgCfg extends React.Component {
{this.props.msg.pkg.get("cfg.bg")}, +
+ {this.props.msg.pkg.get("siteSettings")} +
, @@ -926,19 +927,29 @@ export class BgCfg extends React.Component { onClick={() => { this.onChangeAllowSetBg(false); }} - className="button-default inline-block margin-r-m" + className={`${ + this.props.ui.clientCfg.allowSetBg + ? "button-default" + : "white-font focus-bg" + } inline-block margin-r-m`} > {this.props.msg.pkg.get("term.disabled")}
+
+
{this.props.msg.pkg.get("autoTheme")}
@@ -946,7 +957,11 @@ export class BgCfg extends React.Component { onClick={() => { this.onChangeAutoTheme(false); }} - className="button-default inline-block margin-r-m" + className={`${ + this.props.ui.clientCfg.autoTheme + ? "button-default" + : "white-font focus-bg" + } inline-block margin-r-m`} > {this.props.msg.pkg.get("term.disabled")} @@ -1017,7 +1032,7 @@ export class BgCfg extends React.Component { />
- + ); } } diff --git a/src/client/web/src/components/pane_settings.tsx b/src/client/web/src/components/pane_settings.tsx index d6b5cdc..0e91940 100644 --- a/src/client/web/src/components/pane_settings.tsx +++ b/src/client/web/src/components/pane_settings.tsx @@ -15,6 +15,7 @@ import { loadingCtrl, ctrlOn, ctrlOff } from "../common/controls"; export interface Props { login: LoginProps; msg: MsgProps; + ui: UIProps; update?: (updater: (prevState: ICoreState) => ICoreState) => void; } @@ -211,6 +212,86 @@ export class PaneSettings extends React.Component { render() { const errRows = this.prepareErrorRows(); + const bgConfigPane = this.props.ui.clientCfg.allowSetBg ? ( + + {this.props.msg.pkg.get("cfg.bg")}, + + , + ])} + childrenStyles={List([{}, { justifyContent: "flex-end" }])} + /> + +
+ +
+
+
{this.props.msg.pkg.get("cfg.bg.url")}
+ +
+ +
+
+ {this.props.msg.pkg.get("cfg.bg.repeat")} +
+ +
+ +
+
{this.props.msg.pkg.get("cfg.bg.pos")}
+ +
+ +
+
+ {this.props.msg.pkg.get("cfg.bg.align")} +
+ +
+ +
+
+ {this.props.msg.pkg.get("cfg.bg.bgColor")} +
+ +
+
+
+ ) : null; + const errorReportPane = errRows.size > 0 ? ( @@ -361,7 +442,11 @@ export class PaneSettings extends React.Component { onClick={() => { this.setLan("en_US"); }} - className="button-default inline-block margin-r-m" + className={`${ + this.props.login.preferences.lan === "en_US" + ? "focus-bg white-font" + : "button-default" + } inline-block margin-r-m`} > {this.props.msg.pkg.get("enUS")} @@ -369,7 +454,11 @@ export class PaneSettings extends React.Component { onClick={() => { this.setLan("zh_CN"); }} - className="button-default inline-block margin-r-m" + className={`${ + this.props.login.preferences.lan === "zh_CN" + ? "focus-bg white-font" + : "button-default" + } inline-block margin-r-m`} > {this.props.msg.pkg.get("zhCN")} @@ -391,7 +480,11 @@ export class PaneSettings extends React.Component { onClick={() => { this.setTheme("light"); }} - className="button-default inline-block margin-r-m" + className={`${ + this.props.login.preferences.theme === "light" + ? "focus-bg white-font" + : "button-default" + } inline-block margin-r-m`} > {this.props.msg.pkg.get("theme.light")} @@ -399,7 +492,11 @@ export class PaneSettings extends React.Component { onClick={() => { this.setTheme("dark"); }} - className="button-default inline-block margin-r-m" + className={`${ + this.props.login.preferences.theme === "dark" + ? "focus-bg white-font" + : "button-default" + } inline-block margin-r-m`} > {this.props.msg.pkg.get("theme.dark")} @@ -443,88 +540,7 @@ export class PaneSettings extends React.Component { */} - - {this.props.msg.pkg.get("cfg.bg")}, - - , - ])} - childrenStyles={List([{}, { justifyContent: "flex-end" }])} - /> - -
- -
-
-
- {this.props.msg.pkg.get("cfg.bg.url")} -
- -
- -
-
- {this.props.msg.pkg.get("cfg.bg.repeat")} -
- -
- -
-
- {this.props.msg.pkg.get("cfg.bg.pos")} -
- -
- -
-
- {this.props.msg.pkg.get("cfg.bg.align")} -
- -
- -
-
- {this.props.msg.pkg.get("cfg.bg.bgColor")} -
- -
-
-
- + {bgConfigPane} {errorReportPane} {/*
diff --git a/src/client/web/src/components/root_frame.tsx b/src/client/web/src/components/root_frame.tsx index befaaa0..58c71b7 100644 --- a/src/client/web/src/components/root_frame.tsx +++ b/src/client/web/src/components/root_frame.tsx @@ -11,6 +11,8 @@ import { LoginProps } from "./pane_login"; import { Layers } from "./layers"; import { AdminProps } from "./pane_admin"; import { TopBar } from "./topbar"; +import { CronTable } from "../common/cron"; +import { updater } from "./state_updater"; export const controlName = "panelTabs"; export interface Props { @@ -30,6 +32,18 @@ export class RootFrame extends React.Component { super(p); } + componentDidMount(): void { + CronTable().setInterval("autoSwitchTheme", { + func: updater().autoSwitchTheme, + args: [], + delay: 60 * 1000, + }); + } + + componentWillUnmount() { + CronTable().clearInterval("autoSwitchTheme"); + } + makeBgStyle = (): Object => { if ( this.props.login.preferences != null && diff --git a/src/client/web/src/components/state_updater.ts b/src/client/web/src/components/state_updater.ts index ea4430a..a1794b8 100644 --- a/src/client/web/src/components/state_updater.ts +++ b/src/client/web/src/components/state_updater.ts @@ -562,8 +562,6 @@ export class Updater { return initClientCfgStatus; } - console.log(this.props.ui.control.controls.toJSON()); - this.initControls(paramMap); this.initUITree(); @@ -791,6 +789,22 @@ export class Updater { this.props.login.preferences.theme = theme; }; + autoSwitchTheme = () => { + if (!this.props.ui.clientCfg.autoTheme) { + return; + } + + const date = new Date(); + if ( + (date.getHours() >= 18 && date.getHours() <= 23) || + (date.getHours() >= 0 && date.getHours() <= 6) + ) { + this.setTheme("dark"); + } else { + this.setTheme("light"); + } + }; + setControlOption = (controlName: string, option: string): boolean => { const controlExists = this.props.ui.control.controls.has(controlName); const optionsExists = this.props.ui.control.options.has(controlName);