diff --git a/src/main/initializers/init-ipc-main-handlers/init-ipc-main-handlers.ts b/src/main/initializers/init-ipc-main-handlers/init-ipc-main-handlers.ts index 5a907f2449..0899052f00 100644 --- a/src/main/initializers/init-ipc-main-handlers/init-ipc-main-handlers.ts +++ b/src/main/initializers/init-ipc-main-handlers/init-ipc-main-handlers.ts @@ -3,7 +3,7 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ -import { BrowserWindow, IpcMainInvokeEvent, Menu, nativeTheme } from "electron"; +import { BrowserWindow, IpcMainInvokeEvent, Menu } from "electron"; import { clusterFrameMap } from "../../../common/cluster-frames"; import { clusterActivateHandler, clusterSetFrameIdHandler, clusterVisibilityHandler, clusterRefreshHandler, clusterDisconnectHandler, clusterKubectlApplyAllHandler, clusterKubectlDeleteAllHandler, clusterDeleteHandler, clusterSetDeletingHandler, clusterClearDeletingHandler } from "../../../common/ipc/cluster"; import type { ClusterId } from "../../../common/cluster-types"; diff --git a/src/renderer/theme.store.ts b/src/renderer/theme.store.ts index 19180285dd..d46c5af058 100644 --- a/src/renderer/theme.store.ts +++ b/src/renderer/theme.store.ts @@ -13,6 +13,8 @@ import type { SelectOption } from "./components/select"; import type { MonacoEditorProps } from "./components/monaco-editor"; import { defaultTheme } from "../common/vars"; import { camelCase } from "lodash"; +import { ipcRenderer } from "electron"; +import { getNativeThemeChannel, setNativeThemeChannel } from "../common/ipc/native-theme"; export type ThemeId = string; @@ -34,6 +36,8 @@ export class ThemeStore extends Singleton { "lens-light": lensLightThemeJson as Theme, }); + private osNativeTheme: "dark" | "light" | undefined; + @computed get activeThemeId(): ThemeId { return UserStore.getInstance().colorTheme; } @@ -43,7 +47,7 @@ export class ThemeStore extends Singleton { } @computed get activeTheme(): Theme { - return this.themes.get(this.activeThemeId) ?? this.themes.get(defaultTheme); + return this.systemTheme ?? this.themes.get(this.activeThemeId) ?? this.themes.get(defaultTheme); } @computed get terminalColors(): [string, string][] { @@ -66,10 +70,22 @@ export class ThemeStore extends Singleton { } @computed get themeOptions(): SelectOption[] { - return Array.from(this.themes).map(([themeId, theme]) => ({ + const options = Array.from(this.themes).map(([themeId, theme]) => ({ label: theme.name, value: themeId, })); + + options.unshift({ label: "System", value: "system" }); + + return options; + } + + @computed get systemTheme() { + if (this.activeThemeId == "system" && this.osNativeTheme) { + return this.themes.get(`lens-${this.osNativeTheme}`); + } + + return null; } constructor() { @@ -77,6 +93,8 @@ export class ThemeStore extends Singleton { makeObservable(this); autoBind(this); + this.setNativeTheme(); + this.bindNativeThemeUpdateEvent(); // auto-apply active theme reaction(() => ({ @@ -95,8 +113,21 @@ export class ThemeStore extends Singleton { }); } + bindNativeThemeUpdateEvent() { + ipcRenderer.on(setNativeThemeChannel, (event, theme: "dark" | "light") => { + this.osNativeTheme = theme; + this.applyTheme(theme); + }); + } + + async setNativeTheme() { + const theme: "dark" | "light" = await ipcRenderer.invoke(getNativeThemeChannel); + + this.osNativeTheme = theme; + } + getThemeById(themeId: ThemeId): Theme { - return this.themes.get(themeId); + return this.systemTheme ?? this.themes.get(themeId); } protected applyTheme(themeId: ThemeId) {