mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
- Add auto-update and pre-release update user settings - Add settings in user preferences for auto-updating (default false) and for allowing pre-release versions (default false) - Use in-Lens notifications instead of OS notifications as those were found to be flaky - Add rudimentary main->renderer notification system. - Remove options, always confirm, never auto prelease - Changed "yes later" to "yes on quit" - move register IpcHandlers - use moment instead of dateformat - moved formatting notification buttons to renderer - move to RenderButtons as function component - explicitly only send notifications to main view - move delay to utils, always retry even if check failed - fix notification rendering and disabled the auto-updater for integration tests - update integration runner to output logs on failure - pin minikube version Signed-off-by: Sebastian Malton <sebastian@malton.name>
99 lines
2.7 KiB
TypeScript
99 lines
2.7 KiB
TypeScript
import { computed, observable, reaction } from "mobx";
|
|
import { autobind } from "./utils/autobind";
|
|
import { userStore } from "../common/user-store";
|
|
import logger from "../main/logger";
|
|
|
|
export type ThemeId = string;
|
|
|
|
export enum ThemeType {
|
|
DARK = "dark",
|
|
LIGHT = "light",
|
|
}
|
|
|
|
export interface Theme {
|
|
id: ThemeId; // filename without .json-extension
|
|
type: ThemeType;
|
|
name?: string;
|
|
colors?: Record<string, string>;
|
|
description?: string;
|
|
author?: string;
|
|
}
|
|
|
|
@autobind()
|
|
export class ThemeStore {
|
|
protected styles: HTMLStyleElement;
|
|
|
|
// bundled themes from `themes/${themeId}.json`
|
|
@observable themes: Theme[] = [
|
|
{ id: "kontena-dark", type: ThemeType.DARK },
|
|
{ id: "kontena-light", type: ThemeType.LIGHT },
|
|
];
|
|
|
|
@computed get activeTheme(): Theme {
|
|
const activeTheme = this.themes.find(theme => theme.id === userStore.preferences.colorTheme) || this.themes[0];
|
|
return {
|
|
colors: {},
|
|
...activeTheme,
|
|
}
|
|
}
|
|
|
|
constructor() {
|
|
// auto-apply active theme
|
|
reaction(() => this.activeTheme, async ({ id }) => {
|
|
try {
|
|
await this.loadTheme(id);
|
|
this.applyTheme();
|
|
} catch (err) {
|
|
userStore.resetTheme();
|
|
}
|
|
}, {
|
|
fireImmediately: true,
|
|
})
|
|
}
|
|
|
|
async init() {
|
|
// preload all themes
|
|
await Promise.all(
|
|
this.themes.map(theme => this.loadTheme(theme.id))
|
|
);
|
|
}
|
|
|
|
getThemeById(themeId: ThemeId): Theme {
|
|
return this.themes.find(theme => theme.id === themeId)
|
|
}
|
|
|
|
protected async loadTheme(themeId: ThemeId): Promise<Theme> {
|
|
try {
|
|
// todo: figure out why await import() doesn't work
|
|
const theme = require( // eslint-disable-line @typescript-eslint/no-var-requires
|
|
/* webpackChunkName: "themes/[name]" */
|
|
`./themes/${themeId}.json`
|
|
);
|
|
const existingTheme = this.getThemeById(themeId);
|
|
if (existingTheme) {
|
|
Object.assign(existingTheme, theme); // merge
|
|
}
|
|
return existingTheme;
|
|
} catch (err) {
|
|
logger.error(`Can't load theme "${themeId}": ${err}`);
|
|
}
|
|
}
|
|
|
|
protected applyTheme(theme = this.activeTheme) {
|
|
if (!this.styles) {
|
|
this.styles = document.createElement("style");
|
|
this.styles.id = "lens-theme"
|
|
document.head.prepend(this.styles);
|
|
}
|
|
const cssVars = Object.entries(theme.colors).map(([cssName, color]) => {
|
|
return `--${cssName}: ${color} !important;`
|
|
});
|
|
this.styles.textContent = `:root {\n${cssVars.join("\n")}}`;
|
|
// Adding universal theme flag which can be used in component styles
|
|
const body = document.querySelector("body");
|
|
body.classList.toggle("theme-light", theme.type === ThemeType.LIGHT);
|
|
}
|
|
}
|
|
|
|
export const themeStore = new ThemeStore();
|