mirror of
https://github.com/wavetermdev/waveterm.git
synced 2025-01-02 18:39:05 +01:00
use themes coming from backend
This commit is contained in:
parent
b10910d229
commit
6b5d2833eb
@ -1,27 +0,0 @@
|
||||
/* Copyright 2024, Command Line Inc.
|
||||
SPDX-License-Identifier: Apache-2.0 */
|
||||
|
||||
.main-content {
|
||||
--term-black: #757575;
|
||||
--term-red: #cc685c;
|
||||
--term-green: #76c266;
|
||||
--term-yellow: #cbca9b;
|
||||
--term-blue: #85aacb;
|
||||
--term-magenta: #cc72ca;
|
||||
--term-cyan: #74a7cb;
|
||||
--term-white: #c1c1c1;
|
||||
|
||||
--term-bright-black: #727272;
|
||||
--term-bright-red: #cc9d97;
|
||||
--term-bright-green: #a3dd97;
|
||||
--term-bright-yellow: #cbcaaa;
|
||||
--term-bright-blue: #9ab6cb;
|
||||
--term-bright-magenta: #cc8ecb;
|
||||
--term-bright-cyan: #b7b8cb;
|
||||
--term-bright-white: #f0f0f0;
|
||||
|
||||
--term-gray: #8b918a;
|
||||
--term-cmdtext: #f0f0f0;
|
||||
--term-foreground: red;
|
||||
--term-background: #00000000;
|
||||
}
|
@ -82,7 +82,6 @@ class ClientSettingsView extends React.Component<{ model: RemotesModel }, { hove
|
||||
if (currTheme == theme) {
|
||||
return;
|
||||
}
|
||||
|
||||
const prtn = GlobalCommandRunner.setMainTermTheme(theme, false);
|
||||
commandRtnHandler(prtn, this.errorMessage);
|
||||
}
|
||||
@ -207,7 +206,7 @@ class ClientSettingsView extends React.Component<{ model: RemotesModel }, { hove
|
||||
const curFontSize = GlobalModel.getTermFontSize();
|
||||
const curFontFamily = GlobalModel.getTermFontFamily();
|
||||
const curTheme = GlobalModel.getThemeSource();
|
||||
const termThemes = getTermThemes(GlobalModel.termThemes, "Wave Default");
|
||||
const termThemes = getTermThemes(GlobalModel.termThemeOptions.get(), "Wave Default");
|
||||
const currTermTheme = GlobalModel.getTermTheme()["main"] ?? termThemes[0].label;
|
||||
|
||||
return (
|
||||
|
@ -3,7 +3,6 @@
|
||||
|
||||
import * as React from "react";
|
||||
import * as mobxReact from "mobx-react";
|
||||
import * as mobx from "mobx";
|
||||
import { GlobalModel } from "@/models";
|
||||
|
||||
const VALID_CSS_VARIABLES = [
|
||||
@ -36,8 +35,9 @@ class TermStyleBlock extends React.Component<{
|
||||
themeName: string;
|
||||
selector: string;
|
||||
}> {
|
||||
styleRules: OV<string> = mobx.observable.box("", { name: "StyleBlock-styleRules" });
|
||||
injectedStyleElement: HTMLStyleElement | null = null;
|
||||
componentDidUpdate(): void {
|
||||
GlobalModel.bumpTermRenderVersion();
|
||||
}
|
||||
|
||||
isValidCSSColor(color) {
|
||||
const element = document.createElement("div");
|
||||
@ -45,7 +45,7 @@ class TermStyleBlock extends React.Component<{
|
||||
return element.style.color !== "";
|
||||
}
|
||||
|
||||
isValidTermCSSVariable(key, value) {
|
||||
isValidTermCSSVariable(key) {
|
||||
const cssVarName = `--term-${key}`;
|
||||
return VALID_CSS_VARIABLES.includes(cssVarName);
|
||||
}
|
||||
@ -54,50 +54,34 @@ class TermStyleBlock extends React.Component<{
|
||||
return str.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
|
||||
}
|
||||
|
||||
removeInjectedStyle() {
|
||||
if (this.injectedStyleElement) {
|
||||
document.head.removeChild(this.injectedStyleElement);
|
||||
this.injectedStyleElement = null;
|
||||
getStyleRules() {
|
||||
const { selector, themeName } = this.props;
|
||||
const termThemeOptions = GlobalModel.getTermThemeOptions();
|
||||
if (!termThemeOptions) {
|
||||
return null;
|
||||
}
|
||||
const theme = termThemeOptions[themeName];
|
||||
if (!theme) {
|
||||
return null;
|
||||
}
|
||||
|
||||
loadThemeStyles(selector: string, theme: string) {
|
||||
// Inject new style element
|
||||
GlobalModel.getTermThemeJson(theme)
|
||||
.then((termThemeJson) => {
|
||||
if (termThemeJson && typeof termThemeJson === "object") {
|
||||
const styleProperties = Object.entries(termThemeJson)
|
||||
.filter(([key, value]) => {
|
||||
const cssVarName = `--term-${this.camelCaseToKebabCase(key)}`;
|
||||
return VALID_CSS_VARIABLES.includes(cssVarName) && this.isValidCSSColor(value);
|
||||
})
|
||||
const styleProperties = Object.entries(theme)
|
||||
// .filter(([key, value]) => {
|
||||
// const cssVarName = `--term-${this.camelCaseToKebabCase(key)}`;
|
||||
// return this.isValidTermCSSVariable(cssVarName) && this.isValidCSSColor(value);
|
||||
// })
|
||||
.map(([key, value]) => `--term-${key}: ${value};`)
|
||||
.join(" ");
|
||||
|
||||
const styleRules = `${selector} { ${styleProperties} }`;
|
||||
|
||||
mobx.action(() => {
|
||||
this.styleRules.set(styleRules);
|
||||
})();
|
||||
|
||||
console.log("loaded theme styles:", this.styleRules.get());
|
||||
} else {
|
||||
console.error("termThemeJson is not an object:", termThemeJson);
|
||||
if (!styleProperties) {
|
||||
return null;
|
||||
}
|
||||
})
|
||||
.then(() => {
|
||||
GlobalModel.bumpTermRenderVersion();
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("error loading theme styles:", error);
|
||||
});
|
||||
return `${selector} { ${styleProperties} }`;
|
||||
}
|
||||
|
||||
render() {
|
||||
const { themeName, selector } = this.props;
|
||||
console.log("themeName:", themeName, "selector:", selector);
|
||||
const styleRules = this.getStyleRules();
|
||||
|
||||
return this.styleRules.get() ? <style>{this.styleRules.get()}</style> : null;
|
||||
return styleRules ? <style>{styleRules}</style> : null;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -99,7 +99,7 @@ class SessionSettingsModal extends React.Component<{}, {}> {
|
||||
if (this.session == null) {
|
||||
return null;
|
||||
}
|
||||
const termThemes = getTermThemes(GlobalModel.termThemes);
|
||||
const termThemes = getTermThemes(GlobalModel.termThemeOptions.get());
|
||||
const currTermTheme = GlobalModel.getTermTheme()[this.sessionId] ?? termThemes[0].label;
|
||||
|
||||
return (
|
||||
|
@ -153,7 +153,7 @@ class TabSettings extends React.Component<{ screen: Screen }, {}> {
|
||||
render() {
|
||||
const { screen } = this.props;
|
||||
const rptr = screen.curRemote.get();
|
||||
const termThemes = getTermThemes(GlobalModel.termThemes);
|
||||
const termThemes = getTermThemes(GlobalModel.termThemeOptions.get());
|
||||
const currTermTheme = GlobalModel.getTermTheme()[screen.screenId] ?? termThemes[0].label;
|
||||
return (
|
||||
<div className="newtab-container">
|
||||
|
@ -135,11 +135,10 @@ class Model {
|
||||
renderVersion: OV<number> = mobx.observable.box(0, {
|
||||
name: "renderVersion",
|
||||
});
|
||||
|
||||
appUpdateStatus = mobx.observable.box(getApi().getAppUpdateStatus(), {
|
||||
name: "appUpdateStatus",
|
||||
});
|
||||
termThemes: OMap<string, OMap<string, string>> = mobx.observable.array([], {
|
||||
termThemeOptions: OV<TermThemeOptionsType> = mobx.observable.box(null, {
|
||||
name: "terminalThemes",
|
||||
deep: false,
|
||||
});
|
||||
@ -159,7 +158,6 @@ class Model {
|
||||
this.ws.reconnect();
|
||||
this.keybindManager = new KeybindManager(this);
|
||||
this.readConfigKeybindings();
|
||||
this.fetchTerminalThemes();
|
||||
this.initSystemKeybindings();
|
||||
this.initAppKeybindings();
|
||||
this.inputModel = new InputModel(this);
|
||||
@ -231,35 +229,6 @@ class Model {
|
||||
}
|
||||
}
|
||||
|
||||
fetchTerminalThemes() {
|
||||
const url = new URL(this.getBaseHostPort() + "/config/terminal-themes");
|
||||
fetch(url, { method: "get", body: null, headers: this.getFetchHeaders() })
|
||||
.then((resp) => {
|
||||
if (resp.status == 404) {
|
||||
return [];
|
||||
} else if (!resp.ok) {
|
||||
util.handleNotOkResp(resp, url);
|
||||
}
|
||||
return resp.json();
|
||||
})
|
||||
.then((themes) => {
|
||||
const tt = themes.map((theme) => theme.name.split(".")[0]);
|
||||
this.termThemes.replace(tt);
|
||||
});
|
||||
}
|
||||
|
||||
getTermThemeJson(themeFileName: string) {
|
||||
const url = new URL(this.getBaseHostPort() + `/config/terminal-themes/${themeFileName}.json`);
|
||||
return fetch(url, { method: "get", body: null, headers: this.getFetchHeaders() })
|
||||
.then((resp) => resp.json())
|
||||
.then((themeVars: TermThemeType) => {
|
||||
return themeVars;
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error(`error applying theme: ${themeFileName}`, error);
|
||||
});
|
||||
}
|
||||
|
||||
bumpTermRenderVersion() {
|
||||
mobx.action(() => {
|
||||
this.termRenderVersion.set(this.termRenderVersion.get() + 1);
|
||||
@ -914,6 +883,16 @@ class Model {
|
||||
}
|
||||
}
|
||||
|
||||
setTermThemeOptions(termThemeOptions: TermThemeOptionsType) {
|
||||
mobx.action(() => {
|
||||
this.termThemeOptions.set(termThemeOptions);
|
||||
})();
|
||||
}
|
||||
|
||||
getTermThemeOptions(): TermThemeOptionsType {
|
||||
return this.termThemeOptions.get();
|
||||
}
|
||||
|
||||
updateScreenStatusIndicators(screenStatusIndicators: ScreenStatusIndicatorUpdateType[]) {
|
||||
for (const update of screenStatusIndicators) {
|
||||
this.getScreenById_single(update.screenid)?.setStatusIndicator(update.status);
|
||||
@ -1034,6 +1013,9 @@ class Model {
|
||||
} else if (update.userinputrequest != null) {
|
||||
const userInputRequest: UserInputRequest = update.userinputrequest;
|
||||
this.modalsModel.pushModal(appconst.USER_INPUT, userInputRequest);
|
||||
} else if (update.termthemeoptions != null) {
|
||||
console.log("got termthemeoptions==============", update.termthemeoptions);
|
||||
this.setTermThemeOptions(update.termthemeoptions);
|
||||
} else if (update.sessiontombstone != null || update.screentombstone != null) {
|
||||
// nothing (ignore)
|
||||
} else {
|
||||
|
9
src/types/custom.d.ts
vendored
9
src/types/custom.d.ts
vendored
@ -379,6 +379,13 @@ declare global {
|
||||
userinputrequest?: UserInputRequest;
|
||||
screentombstone?: any;
|
||||
sessiontombstone?: any;
|
||||
termthemeoptions?: TermThemeOptionsType;
|
||||
};
|
||||
|
||||
type TermThemeOptionsType = {
|
||||
[key: string]: {
|
||||
[innerKey: string]: string;
|
||||
};
|
||||
};
|
||||
|
||||
type HistoryViewDataType = {
|
||||
@ -582,7 +589,7 @@ declare global {
|
||||
termfontsize: number;
|
||||
termfontfamily: string;
|
||||
theme: NativeThemeSource;
|
||||
termtheme: TermThemeType;
|
||||
termthemeconfig: TermThemeType;
|
||||
};
|
||||
|
||||
type ConfirmFlagsType = {
|
||||
|
@ -1,10 +1,13 @@
|
||||
function getTermThemes(termThemes: string[], noneLabel = "Inherit"): DropdownItem[] {
|
||||
function getTermThemes(termThemeOptions: string[], noneLabel = "Inherit"): DropdownItem[] {
|
||||
if (!termThemeOptions) {
|
||||
return [];
|
||||
}
|
||||
const tt: DropdownItem[] = [];
|
||||
tt.push({
|
||||
label: noneLabel,
|
||||
value: null,
|
||||
});
|
||||
for (const themeName of termThemes) {
|
||||
for (const themeName of Object.keys(termThemeOptions)) {
|
||||
tt.push({
|
||||
label: themeName,
|
||||
value: themeName,
|
||||
|
@ -16,7 +16,7 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
TermThemesTypeStr = "termthemes"
|
||||
TermThemesTypeStr = "termthemeoptions"
|
||||
TermThemeDir = "config/terminal-themes/"
|
||||
)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user