1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00

Revert "Allow to customize terminal theme (#4666)" (#4682)

This reverts commit a5e89b79d6.
This commit is contained in:
Roman 2022-01-13 11:54:54 +01:00 committed by GitHub
parent a5e89b79d6
commit 0be1ab4ce0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 65 additions and 106 deletions

View File

@ -83,15 +83,6 @@ const colorTheme: PreferenceDescription<string> = {
}, },
}; };
const terminalTheme: PreferenceDescription<string | undefined> = {
fromStore(val) {
return val || "";
},
toStore(val) {
return val || undefined;
},
};
const localeTimezone: PreferenceDescription<string> = { const localeTimezone: PreferenceDescription<string> = {
fromStore(val) { fromStore(val) {
return val || moment.tz.guess(true) || "UTC"; return val || moment.tz.guess(true) || "UTC";
@ -360,7 +351,6 @@ export const DESCRIPTORS = {
httpsProxy, httpsProxy,
shell, shell,
colorTheme, colorTheme,
terminalTheme,
localeTimezone, localeTimezone,
allowUntrustedCAs, allowUntrustedCAs,
allowTelemetry, allowTelemetry,

View File

@ -67,7 +67,6 @@ export class UserStore extends BaseStore<UserStoreModel> /* implements UserStore
@observable allowErrorReporting: boolean; @observable allowErrorReporting: boolean;
@observable allowUntrustedCAs: boolean; @observable allowUntrustedCAs: boolean;
@observable colorTheme: string; @observable colorTheme: string;
@observable terminalTheme: string;
@observable localeTimezone: string; @observable localeTimezone: string;
@observable downloadMirror: string; @observable downloadMirror: string;
@observable httpsProxy?: string; @observable httpsProxy?: string;
@ -189,7 +188,6 @@ export class UserStore extends BaseStore<UserStoreModel> /* implements UserStore
this.httpsProxy = DESCRIPTORS.httpsProxy.fromStore(preferences?.httpsProxy); this.httpsProxy = DESCRIPTORS.httpsProxy.fromStore(preferences?.httpsProxy);
this.shell = DESCRIPTORS.shell.fromStore(preferences?.shell); this.shell = DESCRIPTORS.shell.fromStore(preferences?.shell);
this.colorTheme = DESCRIPTORS.colorTheme.fromStore(preferences?.colorTheme); this.colorTheme = DESCRIPTORS.colorTheme.fromStore(preferences?.colorTheme);
this.terminalTheme = DESCRIPTORS.terminalTheme.fromStore(preferences?.terminalTheme);
this.localeTimezone = DESCRIPTORS.localeTimezone.fromStore(preferences?.localeTimezone); this.localeTimezone = DESCRIPTORS.localeTimezone.fromStore(preferences?.localeTimezone);
this.allowUntrustedCAs = DESCRIPTORS.allowUntrustedCAs.fromStore(preferences?.allowUntrustedCAs); this.allowUntrustedCAs = DESCRIPTORS.allowUntrustedCAs.fromStore(preferences?.allowUntrustedCAs);
this.allowTelemetry = DESCRIPTORS.allowTelemetry.fromStore(preferences?.allowTelemetry); this.allowTelemetry = DESCRIPTORS.allowTelemetry.fromStore(preferences?.allowTelemetry);
@ -214,7 +212,6 @@ export class UserStore extends BaseStore<UserStoreModel> /* implements UserStore
httpsProxy: DESCRIPTORS.httpsProxy.toStore(this.httpsProxy), httpsProxy: DESCRIPTORS.httpsProxy.toStore(this.httpsProxy),
shell: DESCRIPTORS.shell.toStore(this.shell), shell: DESCRIPTORS.shell.toStore(this.shell),
colorTheme: DESCRIPTORS.colorTheme.toStore(this.colorTheme), colorTheme: DESCRIPTORS.colorTheme.toStore(this.colorTheme),
terminalTheme: DESCRIPTORS.terminalTheme.toStore(this.terminalTheme),
localeTimezone: DESCRIPTORS.localeTimezone.toStore(this.localeTimezone), localeTimezone: DESCRIPTORS.localeTimezone.toStore(this.localeTimezone),
allowUntrustedCAs: DESCRIPTORS.allowUntrustedCAs.toStore(this.allowUntrustedCAs), allowUntrustedCAs: DESCRIPTORS.allowUntrustedCAs.toStore(this.allowUntrustedCAs),
allowTelemetry: DESCRIPTORS.allowTelemetry.toStore(this.allowTelemetry), allowTelemetry: DESCRIPTORS.allowTelemetry.toStore(this.allowTelemetry),

View File

@ -57,38 +57,24 @@ export const Application = observer(() => {
const [customUrl, setCustomUrl] = React.useState(userStore.extensionRegistryUrl.customUrl || ""); const [customUrl, setCustomUrl] = React.useState(userStore.extensionRegistryUrl.customUrl || "");
const [shell, setShell] = React.useState(userStore.shell || ""); const [shell, setShell] = React.useState(userStore.shell || "");
const extensionSettings = AppPreferenceRegistry.getInstance().getItems().filter((preference) => preference.showInPreferencesTab === "application"); const extensionSettings = AppPreferenceRegistry.getInstance().getItems().filter((preference) => preference.showInPreferencesTab === "application");
const themeStore = ThemeStore.getInstance();
return ( return (
<section id="application"> <section id="application">
<h2 data-testid="application-header">Application</h2> <h2 data-testid="application-header">Application</h2>
<section id="appearance"> <section id="appearance">
<SubTitle title="Theme" /> <SubTitle title="Theme"/>
<Select <Select
options={themeStore.themeOptions} options={ThemeStore.getInstance().themeOptions}
value={userStore.colorTheme} value={userStore.colorTheme}
onChange={({ value }) => userStore.colorTheme = value} onChange={({ value }) => userStore.colorTheme = value}
themeName="lens" themeName="lens"
/> />
</section> </section>
<hr /> <hr/>
<section id="terminalTheme">
<SubTitle title="Terminal theme" />
<Select
themeName="lens"
options={[
{ label: "Match theme", value: "" },
...themeStore.themeOptions,
]}
value={userStore.terminalTheme}
onChange={({ value }) => userStore.terminalTheme = value}
/>
</section>
<section id="shell"> <section id="shell">
<SubTitle title="Terminal Shell Path" /> <SubTitle title="Terminal Shell Path"/>
<Input <Input
theme="round-black" theme="round-black"
placeholder={defaultShell} placeholder={defaultShell}
@ -108,7 +94,7 @@ export const Application = observer(() => {
</Switch> </Switch>
</section> </section>
<hr /> <hr/>
<section id="extensionRegistryUrl"> <section id="extensionRegistryUrl">
<SubTitle title="Extension Install Registry" /> <SubTitle title="Extension Install Registry" />

View File

@ -76,14 +76,11 @@
.tab-content { .tab-content {
position: relative; position: relative;
background: var(--terminalBackground);
flex: 1; flex: 1;
overflow: hidden; overflow: hidden;
transition: flex-basis 25ms ease-in; transition: flex-basis 25ms ease-in;
&.terminal {
background: var(--terminalBackground);
}
> *:not(.Spinner) { > *:not(.Spinner) {
position: absolute; position: absolute;
left: 0; left: 0;

View File

@ -105,7 +105,7 @@ export class Dock extends React.Component<Props> {
if (!isOpen || !selectedTab) return null; if (!isOpen || !selectedTab) return null;
return ( return (
<div className={`tab-content ${selectedTab.kind}`} style={{ flexBasis: height }}> <div className="tab-content" style={{ flexBasis: height }}>
{this.renderTab(selectedTab)} {this.renderTab(selectedTab)}
</div> </div>
); );

View File

@ -26,9 +26,9 @@ import { FitAddon } from "xterm-addon-fit";
import { dockStore, TabId } from "./dock.store"; import { dockStore, TabId } from "./dock.store";
import { TerminalApi, TerminalChannels } from "../../api/terminal-api"; import { TerminalApi, TerminalChannels } from "../../api/terminal-api";
import { ThemeStore } from "../../theme.store"; import { ThemeStore } from "../../theme.store";
import { disposer } from "../../utils"; import { boundMethod, disposer } from "../../utils";
import { isMac } from "../../../common/vars"; import { isMac } from "../../../common/vars";
import { once } from "lodash"; import { camelCase, once } from "lodash";
import { UserStore } from "../../../common/user-store"; import { UserStore } from "../../../common/user-store";
import { clipboard } from "electron"; import { clipboard } from "electron";
import logger from "../../../common/logger"; import logger from "../../../common/logger";
@ -56,6 +56,23 @@ export class Terminal {
private scrollPos = 0; private scrollPos = 0;
private disposer = disposer(); private disposer = disposer();
@boundMethod
protected setTheme(colors: Record<string, string>) {
if (!this.xterm) {
return;
}
// Replacing keys stored in styles to format accepted by terminal
// E.g. terminalBrightBlack -> brightBlack
const colorPrefix = "terminal";
const terminalColorEntries = Object.entries(colors)
.filter(([name]) => name.startsWith(colorPrefix))
.map(([name, color]) => [camelCase(name.slice(colorPrefix.length)), color]);
const terminalColors = Object.fromEntries(terminalColorEntries);
this.xterm.setOption("theme", terminalColors);
}
get elem() { get elem() {
return this.xterm?.element; return this.xterm?.element;
} }
@ -104,9 +121,7 @@ export class Terminal {
window.addEventListener("resize", this.onResize); window.addEventListener("resize", this.onResize);
this.disposer.push( this.disposer.push(
reaction(() => ThemeStore.getInstance().xtermColors, colors => { reaction(() => ThemeStore.getInstance().activeTheme.colors, this.setTheme, {
this.xterm?.setOption("theme", colors);
}, {
fireImmediately: true, fireImmediately: true,
}), }),
dockStore.onResize(this.onResize), dockStore.onResize(this.onResize),

View File

@ -19,7 +19,7 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
import { comparer, computed, makeObservable, observable, reaction } from "mobx"; import { computed, makeObservable, observable, reaction } from "mobx";
import { autoBind, Singleton } from "./utils"; import { autoBind, Singleton } from "./utils";
import { UserStore } from "../common/user-store"; import { UserStore } from "../common/user-store";
import logger from "../main/logger"; import logger from "../main/logger";
@ -28,7 +28,6 @@ import lensLightThemeJson from "./themes/lens-light.json";
import type { SelectOption } from "./components/select"; import type { SelectOption } from "./components/select";
import type { MonacoEditorProps } from "./components/monaco-editor"; import type { MonacoEditorProps } from "./components/monaco-editor";
import { defaultTheme } from "../common/vars"; import { defaultTheme } from "../common/vars";
import { camelCase } from "lodash";
export type ThemeId = string; export type ThemeId = string;
@ -42,7 +41,7 @@ export interface Theme {
} }
export class ThemeStore extends Singleton { export class ThemeStore extends Singleton {
private terminalColorPrefix = "terminal"; protected styles: HTMLStyleElement;
// bundled themes from `themes/${themeId}.json` // bundled themes from `themes/${themeId}.json`
private themes = observable.map<ThemeId, Theme>({ private themes = observable.map<ThemeId, Theme>({
@ -50,37 +49,14 @@ export class ThemeStore extends Singleton {
"lens-light": lensLightThemeJson as Theme, "lens-light": lensLightThemeJson as Theme,
}); });
@computed get activeThemeId(): ThemeId { @computed get activeThemeId(): string {
return UserStore.getInstance().colorTheme; return UserStore.getInstance().colorTheme;
} }
@computed get terminalThemeId(): ThemeId {
return UserStore.getInstance().terminalTheme;
}
@computed get activeTheme(): Theme { @computed get activeTheme(): Theme {
return this.themes.get(this.activeThemeId) ?? this.themes.get(defaultTheme); return this.themes.get(this.activeThemeId) ?? this.themes.get(defaultTheme);
} }
@computed get terminalColors(): [string, string][] {
const theme = this.themes.get(this.terminalThemeId) ?? this.activeTheme;
return Object
.entries(theme.colors)
.filter(([name]) => name.startsWith(this.terminalColorPrefix));
}
// Replacing keys stored in styles to format accepted by terminal
// E.g. terminalBrightBlack -> brightBlack
@computed get xtermColors(): Record<string, string> {
return Object.fromEntries(
this.terminalColors.map(([name, color]) => [
camelCase(name.replace(this.terminalColorPrefix, "")),
color,
]),
);
}
@computed get themeOptions(): SelectOption<string>[] { @computed get themeOptions(): SelectOption<string>[] {
return Array.from(this.themes).map(([themeId, theme]) => ({ return Array.from(this.themes).map(([themeId, theme]) => ({
label: theme.name, label: theme.name,
@ -95,19 +71,15 @@ export class ThemeStore extends Singleton {
autoBind(this); autoBind(this);
// auto-apply active theme // auto-apply active theme
reaction(() => ({ reaction(() => this.activeThemeId, themeId => {
themeId: this.activeThemeId,
terminalThemeId: this.terminalThemeId,
}), ({ themeId }) => {
try { try {
this.applyTheme(themeId); this.applyTheme(this.getThemeById(themeId));
} catch (err) { } catch (err) {
logger.error(err); logger.error(err);
UserStore.getInstance().resetTheme(); UserStore.getInstance().resetTheme();
} }
}, { }, {
fireImmediately: true, fireImmediately: true,
equals: comparer.shallow,
}); });
} }
@ -115,18 +87,20 @@ export class ThemeStore extends Singleton {
return this.themes.get(themeId); return this.themes.get(themeId);
} }
protected applyTheme(themeId: ThemeId) { protected applyTheme(theme: Theme) {
const theme = this.getThemeById(themeId); if (!this.styles) {
const colors = Object.entries({ this.styles = document.createElement("style");
...theme.colors, this.styles.id = "lens-theme";
...Object.fromEntries(this.terminalColors), document.head.append(this.styles);
}); }
const cssVars = Object.entries(theme.colors).map(([cssName, color]) => {
colors.forEach(([name, value]) => { return `--${cssName}: ${color};`;
document.documentElement.style.setProperty(`--${name}`, value);
}); });
this.styles.textContent = `:root {\n${cssVars.join("\n")}}`;
// Adding universal theme flag which can be used in component styles // Adding universal theme flag which can be used in component styles
document.body.classList.toggle("theme-light", theme.type === "light"); const body = document.querySelector("body");
body.classList.toggle("theme-light", theme.type === "light");
} }
} }

View File

@ -1,5 +1,5 @@
{ {
"name": "Dark", "name": "Dark (Lens)",
"type": "dark", "type": "dark",
"description": "Original Lens dark theme", "description": "Original Lens dark theme",
"author": "Mirantis", "author": "Mirantis",

View File

@ -1,5 +1,5 @@
{ {
"name": "Light", "name": "Light (Lens)",
"type": "light", "type": "light",
"description": "Original Lens light theme", "description": "Original Lens light theme",
"author": "Mirantis", "author": "Mirantis",
@ -76,26 +76,26 @@
"logsBackground": "#24292e", "logsBackground": "#24292e",
"logsForeground": "#ffffff", "logsForeground": "#ffffff",
"logRowHoverBackground": "#35373a", "logRowHoverBackground": "#35373a",
"terminalBackground": "#ffffff", "terminalBackground": "#24292e",
"terminalForeground": "#2d2d2d", "terminalForeground": "#ffffff",
"terminalCursor": "#2d2d2d", "terminalCursor": "#ffffff",
"terminalCursorAccent": "#ffffff", "terminalCursorAccent": "#000000",
"terminalSelection": "#bfbfbf", "terminalSelection": "#ffffff77",
"terminalBlack": "#2d2d2d", "terminalBlack": "#2e3436",
"terminalRed": "#cd3734 ", "terminalRed": "#cc0000",
"terminalGreen": "#18cf12", "terminalGreen": "#4e9a06",
"terminalYellow": "#acb300", "terminalYellow": "#c4a000",
"terminalBlue": "#3d90ce", "terminalBlue": "#3465a4",
"terminalMagenta": "#c100cd", "terminalMagenta": "#75507b",
"terminalCyan": "#07c4b9", "terminalCyan": "#06989a",
"terminalWhite": "#d3d7cf", "terminalWhite": "#d3d7cf",
"terminalBrightBlack": "#a8a8a8", "terminalBrightBlack": "#555753",
"terminalBrightRed": "#ff6259", "terminalBrightRed": "#ef2929",
"terminalBrightGreen": "#5cdb59", "terminalBrightGreen": "#8ae234",
"terminalBrightYellow": "#f8c000", "terminalBrightYellow": "#fce94f",
"terminalBrightBlue": "#008db6", "terminalBrightBlue": "#729fcf",
"terminalBrightMagenta": "#ee55f8", "terminalBrightMagenta": "#ad7fa8",
"terminalBrightCyan": "#50e8df", "terminalBrightCyan": "#34e2e2",
"terminalBrightWhite": "#eeeeec", "terminalBrightWhite": "#eeeeec",
"dialogTextColor": "#87909c", "dialogTextColor": "#87909c",
"dialogBackground": "#ffffff", "dialogBackground": "#ffffff",