Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x | import { getGlobalPluginsPath } from "lib/pluginManager/globalPlugins"; import darkTheme from "ui/theme/darkTheme"; import darkThemeWin from "ui/theme/darkThemeWin"; import lightTheme from "ui/theme/lightTheme"; import lightThemeWin from "ui/theme/lightThemeWin"; import { ThemeInterface } from "ui/theme/ThemeInterface"; import glob from "glob"; import { promisify } from "util"; import { join, relative } from "path"; import { readJSON } from "fs-extra"; import { merge, cloneDeep } from "lodash"; const globAsync = promisify(glob); const themeIds = ["dark", "light"] as const; export type ThemeId = typeof themeIds[number]; const themes: Record<ThemeId, ThemeInterface> = { light: lightTheme, dark: darkTheme, }; const windowsThemes: Record<ThemeId, ThemeInterface> = { light: lightThemeWin, dark: darkThemeWin, }; export interface ThemePlugin { id: string; name: string; theme: JSON; } export const loadThemePlugin = async ( path: string ): Promise<(JSON & { name: string; type: unknown }) | null> => { try { const theme = await readJSON(path); Iif (!theme.name) { throw new Error("Theme is missing name"); } return theme; } catch (e) { console.error("Unable to load theme", e); } return null; }; export class ThemeManager { systemThemes: Record<ThemeId, ThemeInterface>; pluginThemes: Record<string, ThemeInterface>; constructor(platform: string) { this.systemThemes = platform === "darwin" ? themes : windowsThemes; this.pluginThemes = {}; } async loadPluginThemes() { this.pluginThemes = {}; const globalPluginsPath = getGlobalPluginsPath(); const pluginPaths = await globAsync( join(globalPluginsPath, "**/theme.json") ); for (const path of pluginPaths) { const theme = await loadThemePlugin(path); Iif (theme) { const id = relative(globalPluginsPath, path); const baseTheme = theme.type === "dark" ? this.systemThemes.dark : this.systemThemes.light; const mergedTheme = merge(cloneDeep(baseTheme), theme); this.pluginThemes[id] = mergedTheme; } } } async loadPluginTheme(path: string) { const globalPluginsPath = getGlobalPluginsPath(); const theme = await loadThemePlugin(path); Iif (theme) { const id = relative(globalPluginsPath, path); const baseTheme = theme.type === "dark" ? this.systemThemes.dark : this.systemThemes.light; const mergedTheme = merge(cloneDeep(baseTheme), theme); this.pluginThemes[id] = mergedTheme; return mergedTheme; } } getTheme(themeId: string, systemShouldUseDarkColors: boolean) { // Use plugin theme if available const pluginTheme = this.pluginThemes[themeId]; Iif (pluginTheme) { return pluginTheme; } // If light/dark set manually if (themeId === "light") { return this.systemThemes[themeId]; } else Iif (themeId === "dark") { return this.systemThemes[themeId]; } // Fallback to system theme Iif (systemShouldUseDarkColors) { return this.systemThemes["dark"]; } return this.systemThemes["light"]; } getPluginThemes() { return Object.entries(this.pluginThemes).map(([id, theme]) => { return { id, name: theme.name, }; }); } } |