mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Introduce reactive way to get theme from operating system
Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com> Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>
This commit is contained in:
parent
c7dba52cd0
commit
32bc853279
@ -0,0 +1,18 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import nativeThemeInjectable from "./native-theme.injectable";
|
||||
|
||||
const getElectronThemeInjectable = getInjectable({
|
||||
id: "get-electron-theme",
|
||||
|
||||
instantiate: (di) => {
|
||||
const nativeTheme = di.inject(nativeThemeInjectable);
|
||||
|
||||
return () => nativeTheme.shouldUseDarkColors ? "dark" : "light";
|
||||
},
|
||||
});
|
||||
|
||||
export default getElectronThemeInjectable;
|
||||
14
src/main/electron-app/features/native-theme.injectable.ts
Normal file
14
src/main/electron-app/features/native-theme.injectable.ts
Normal file
@ -0,0 +1,14 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { nativeTheme } from "electron";
|
||||
|
||||
const nativeThemeInjectable = getInjectable({
|
||||
id: "native-theme",
|
||||
instantiate: () => nativeTheme,
|
||||
causesSideEffects: true,
|
||||
});
|
||||
|
||||
export default nativeThemeInjectable;
|
||||
@ -0,0 +1,35 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { getStartableStoppable } from "../../../common/utils/get-startable-stoppable";
|
||||
import currentOperatingSystemThemeStateInjectable from "../../theme/current-operating-system-theme-state.injectable";
|
||||
import nativeThemeInjectable from "./native-theme.injectable";
|
||||
import getElectronThemeInjectable from "./get-electron-theme.injectable";
|
||||
|
||||
const syncThemeFromOperatingSystemInjectable = getInjectable({
|
||||
id: "sync-theme-from-operating-system",
|
||||
|
||||
instantiate: (di) => {
|
||||
const currentThemeState = di.inject(currentOperatingSystemThemeStateInjectable);
|
||||
const nativeTheme = di.inject(nativeThemeInjectable);
|
||||
const getElectronTheme = di.inject(getElectronThemeInjectable);
|
||||
|
||||
return getStartableStoppable("sync-theme-from-operating-system", () => {
|
||||
const updateThemeState = () => {
|
||||
const newTheme = getElectronTheme();
|
||||
|
||||
currentThemeState.set(newTheme);
|
||||
};
|
||||
|
||||
nativeTheme.on("updated", updateThemeState);
|
||||
|
||||
return () => {
|
||||
nativeTheme.off("updated", updateThemeState);
|
||||
};
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
export default syncThemeFromOperatingSystemInjectable;
|
||||
@ -1,24 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { broadcastNativeThemeOnUpdate } from "../../native-theme";
|
||||
import { whenApplicationIsLoadingInjectionToken } from "../../start-main-application/runnable-tokens/when-application-is-loading-injection-token";
|
||||
|
||||
const setupOsThemeUpdatesInjectable = getInjectable({
|
||||
id: "setup-os-theme-updates",
|
||||
|
||||
instantiate: () => ({
|
||||
run: () => {
|
||||
broadcastNativeThemeOnUpdate();
|
||||
},
|
||||
}),
|
||||
|
||||
// Todo: remove explicit usage of IPC to get rid of this.
|
||||
causesSideEffects: true,
|
||||
|
||||
injectionToken: whenApplicationIsLoadingInjectionToken,
|
||||
});
|
||||
|
||||
export default setupOsThemeUpdatesInjectable;
|
||||
@ -47,7 +47,6 @@ import catalogCategoryRegistryInjectable from "../common/catalog/catalog-categor
|
||||
import setupIpcMainHandlersInjectable from "./electron-app/runnables/setup-ipc-main-handlers/setup-ipc-main-handlers.injectable";
|
||||
import setupLensProxyInjectable from "./start-main-application/runnables/setup-lens-proxy.injectable";
|
||||
import setupRunnablesForAfterRootFrameIsReadyInjectable from "./start-main-application/runnables/setup-runnables-for-after-root-frame-is-ready.injectable";
|
||||
import setupOsThemeUpdatesInjectable from "./electron-app/runnables/setup-os-theme-updates.injectable";
|
||||
import setupSentryInjectable from "./start-main-application/runnables/setup-sentry.injectable";
|
||||
import setupShellInjectable from "./start-main-application/runnables/setup-shell.injectable";
|
||||
import setupSyncingOfWeblinksInjectable from "./start-main-application/runnables/setup-syncing-of-weblinks.injectable";
|
||||
@ -79,6 +78,8 @@ import createElectronWindowForInjectable from "./start-main-application/lens-win
|
||||
import setupRunnablesAfterWindowIsOpenedInjectable from "./electron-app/runnables/setup-runnables-after-window-is-opened.injectable";
|
||||
import sendToChannelInElectronBrowserWindowInjectable from "./start-main-application/lens-window/application-window/send-to-channel-in-electron-browser-window.injectable";
|
||||
import broadcastMessageInjectable from "../common/ipc/broadcast-message.injectable";
|
||||
import getElectronThemeInjectable from "./electron-app/features/get-electron-theme.injectable";
|
||||
import syncThemeFromOperatingSystemInjectable from "./electron-app/features/sync-theme-from-operating-system.injectable";
|
||||
|
||||
export const getDiForUnitTesting = (
|
||||
{ doGeneralOverrides } = { doGeneralOverrides: false },
|
||||
@ -136,8 +137,8 @@ export const getDiForUnitTesting = (
|
||||
di.override(registerChannelInjectable, () => () => undefined);
|
||||
di.override(directoryForBundledBinariesInjectable, () => "some-bin-directory");
|
||||
|
||||
di.override(broadcastMessageInjectable, () => {
|
||||
throw new Error("Tried to broadcast message over IPC without explicit override.");
|
||||
di.override(broadcastMessageInjectable, () => (channel) => {
|
||||
throw new Error(`Tried to broadcast message to channel "${channel}" over IPC without explicit override.`);
|
||||
});
|
||||
|
||||
di.override(spawnInjectable, () => () => {
|
||||
@ -184,7 +185,6 @@ const overrideRunnablesHavingSideEffects = (di: DiContainer) => {
|
||||
setupIpcMainHandlersInjectable,
|
||||
setupLensProxyInjectable,
|
||||
setupRunnablesForAfterRootFrameIsReadyInjectable,
|
||||
setupOsThemeUpdatesInjectable,
|
||||
setupSentryInjectable,
|
||||
setupShellInjectable,
|
||||
setupSyncingOfWeblinksInjectable,
|
||||
@ -224,6 +224,8 @@ const overrideElectronFeatures = (di: DiContainer) => {
|
||||
di.override(showMessagePopupInjectable, () => () => {});
|
||||
di.override(waitForElectronToBeReadyInjectable, () => () => Promise.resolve());
|
||||
di.override(ipcMainInjectable, () => ({}));
|
||||
di.override(getElectronThemeInjectable, () => () => "dark");
|
||||
di.override(syncThemeFromOperatingSystemInjectable, () => ({ start: () => {}, stop: () => {} }));
|
||||
|
||||
di.override(createElectronWindowForInjectable, () => () => async () => ({
|
||||
show: () => {},
|
||||
|
||||
@ -0,0 +1,27 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { reaction } from "mobx";
|
||||
import { getStartableStoppable } from "../../../common/utils/get-startable-stoppable";
|
||||
import { setNativeThemeChannel } from "../../../common/ipc/native-theme";
|
||||
import currentOperatingSystemThemeInjectable from "../current-operating-system-theme.injectable";
|
||||
import broadcastMessageInjectable from "../../../common/ipc/broadcast-message.injectable";
|
||||
|
||||
const broadcastThemeChangeInjectable = getInjectable({
|
||||
id: "broadcast-theme-change",
|
||||
|
||||
instantiate: (di) => {
|
||||
const currentTheme = di.inject(currentOperatingSystemThemeInjectable);
|
||||
const broadcastMessage = di.inject(broadcastMessageInjectable);
|
||||
|
||||
return getStartableStoppable("broadcast-theme-change", () =>
|
||||
reaction(() => currentTheme.get(), (theme) => {
|
||||
broadcastMessage(setNativeThemeChannel, theme);
|
||||
}),
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
export default broadcastThemeChangeInjectable;
|
||||
@ -0,0 +1,25 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { whenApplicationIsLoadingInjectionToken } from "../../start-main-application/runnable-tokens/when-application-is-loading-injection-token";
|
||||
import broadcastThemeChangeInjectable from "./broadcast-theme-change.injectable";
|
||||
|
||||
const startBroadcastingThemeChangeInjectable = getInjectable({
|
||||
id: "start-broadcasting-theme-change",
|
||||
|
||||
instantiate: (di) => {
|
||||
const broadcastThemeChange = di.inject(broadcastThemeChangeInjectable);
|
||||
|
||||
return {
|
||||
run: async () => {
|
||||
await broadcastThemeChange.start();
|
||||
},
|
||||
};
|
||||
},
|
||||
|
||||
injectionToken: whenApplicationIsLoadingInjectionToken,
|
||||
});
|
||||
|
||||
export default startBroadcastingThemeChangeInjectable;
|
||||
@ -0,0 +1,25 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import broadcastThemeChangeInjectable from "./broadcast-theme-change.injectable";
|
||||
import { beforeQuitOfBackEndInjectionToken } from "../../start-main-application/runnable-tokens/before-quit-of-back-end-injection-token";
|
||||
|
||||
const stopBroadcastingThemeChangeInjectable = getInjectable({
|
||||
id: "stop-broadcasting-theme-change",
|
||||
|
||||
instantiate: (di) => {
|
||||
const broadcastThemeChange = di.inject(broadcastThemeChangeInjectable);
|
||||
|
||||
return {
|
||||
run: async () => {
|
||||
await broadcastThemeChange.stop();
|
||||
},
|
||||
};
|
||||
},
|
||||
|
||||
injectionToken: beforeQuitOfBackEndInjectionToken,
|
||||
});
|
||||
|
||||
export default stopBroadcastingThemeChangeInjectable;
|
||||
@ -0,0 +1,24 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { observable } from "mobx";
|
||||
import getElectronThemeInjectable from "../electron-app/features/get-electron-theme.injectable";
|
||||
|
||||
export type Theme = "dark" | "light";
|
||||
|
||||
const currentOperatingSystemThemeStateInjectable = getInjectable({
|
||||
id: "current-operating-system-theme-state",
|
||||
|
||||
instantiate: (di) => {
|
||||
const getElectronTheme = di.inject(getElectronThemeInjectable);
|
||||
const defaultTheme = getElectronTheme();
|
||||
|
||||
return observable.box<Theme>(
|
||||
defaultTheme,
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
export default currentOperatingSystemThemeStateInjectable;
|
||||
19
src/main/theme/current-operating-system-theme.injectable.ts
Normal file
19
src/main/theme/current-operating-system-theme.injectable.ts
Normal file
@ -0,0 +1,19 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { computed } from "mobx";
|
||||
import currentOperatingSystemThemeStateInjectable from "./current-operating-system-theme-state.injectable";
|
||||
|
||||
const currentOperatingSystemThemeInjectable = getInjectable({
|
||||
id: "current-operating-system-theme",
|
||||
|
||||
instantiate: (di) => {
|
||||
const currentThemeState = di.inject(currentOperatingSystemThemeStateInjectable);
|
||||
|
||||
return computed(() => currentThemeState.get());
|
||||
},
|
||||
});
|
||||
|
||||
export default currentOperatingSystemThemeInjectable;
|
||||
@ -0,0 +1,25 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import syncThemeFromOperatingSystemInjectable from "../../electron-app/features/sync-theme-from-operating-system.injectable";
|
||||
import { whenApplicationIsLoadingInjectionToken } from "../../start-main-application/runnable-tokens/when-application-is-loading-injection-token";
|
||||
|
||||
const startSyncingThemeFromOperatingSystemInjectable = getInjectable({
|
||||
id: "start-syncing-theme-from-operating-system",
|
||||
|
||||
instantiate: (di) => {
|
||||
const syncTheme = di.inject(syncThemeFromOperatingSystemInjectable);
|
||||
|
||||
return {
|
||||
run: async () => {
|
||||
await syncTheme.start();
|
||||
},
|
||||
};
|
||||
},
|
||||
|
||||
injectionToken: whenApplicationIsLoadingInjectionToken,
|
||||
});
|
||||
|
||||
export default startSyncingThemeFromOperatingSystemInjectable;
|
||||
@ -0,0 +1,25 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import syncThemeFromOperatingSystemInjectable from "../../electron-app/features/sync-theme-from-operating-system.injectable";
|
||||
import { beforeQuitOfBackEndInjectionToken } from "../../start-main-application/runnable-tokens/before-quit-of-back-end-injection-token";
|
||||
|
||||
const stopSyncingThemeFromOperatingSystemInjectable = getInjectable({
|
||||
id: "stop-syncing-theme-from-operating-system",
|
||||
|
||||
instantiate: (di) => {
|
||||
const syncTheme = di.inject(syncThemeFromOperatingSystemInjectable);
|
||||
|
||||
return {
|
||||
run: async () => {
|
||||
await syncTheme.stop();
|
||||
},
|
||||
};
|
||||
},
|
||||
|
||||
injectionToken: beforeQuitOfBackEndInjectionToken,
|
||||
});
|
||||
|
||||
export default stopSyncingThemeFromOperatingSystemInjectable;
|
||||
Loading…
Reference in New Issue
Block a user