|
1 |
| -import type { Theme } from '@theia/core/lib/common/theme'; |
2 |
| -import { injectable } from '@theia/core/shared/inversify'; |
3 |
| -import { ThemeServiceWithDB as TheiaThemeServiceWithDB } from '@theia/monaco/lib/browser/monaco-indexed-db'; |
| 1 | +import { |
| 2 | + BuiltinThemeProvider, |
| 3 | + ThemeService, |
| 4 | +} from '@theia/core/lib/browser/theming'; |
| 5 | +import { nls } from '@theia/core/lib/common/nls'; |
| 6 | +import type { Theme, ThemeType } from '@theia/core/lib/common/theme'; |
4 | 7 |
|
5 | 8 | export namespace ArduinoThemes {
|
6 |
| - export const Light: Theme = { |
| 9 | + export const light: Theme = { |
7 | 10 | id: 'arduino-theme',
|
8 | 11 | type: 'light',
|
9 | 12 | label: 'Light (Arduino)',
|
10 | 13 | editorTheme: 'arduino-theme',
|
11 | 14 | };
|
12 |
| - export const Dark: Theme = { |
| 15 | + export const dark: Theme = { |
13 | 16 | id: 'arduino-theme-dark',
|
14 | 17 | type: 'dark',
|
15 | 18 | label: 'Dark (Arduino)',
|
16 | 19 | editorTheme: 'arduino-theme-dark',
|
17 | 20 | };
|
18 | 21 | }
|
19 | 22 |
|
20 |
| -@injectable() |
21 |
| -export class ThemeServiceWithDB extends TheiaThemeServiceWithDB { |
22 |
| - protected override init(): void { |
23 |
| - this.register(ArduinoThemes.Light, ArduinoThemes.Dark); |
24 |
| - super.init(); |
| 23 | +const officialThemeIds = new Set( |
| 24 | + [ |
| 25 | + ArduinoThemes.light, |
| 26 | + ArduinoThemes.dark, |
| 27 | + BuiltinThemeProvider.hcTheme, |
| 28 | + // TODO: add the HC light theme after Theia 1.36 |
| 29 | + ].map(({ id }) => id) |
| 30 | +); |
| 31 | +export function isOfficialTheme(theme: Theme | string): boolean { |
| 32 | + const themeId = typeof theme === 'string' ? theme : theme.id; |
| 33 | + return officialThemeIds.has(themeId); |
| 34 | +} |
| 35 | + |
| 36 | +export function themeLabelForSettings(theme: Theme): string { |
| 37 | + switch (theme.id) { |
| 38 | + case ArduinoThemes.light.id: |
| 39 | + return nls.localize('arduino/theme/light', 'Light'); |
| 40 | + case ArduinoThemes.dark.id: |
| 41 | + return nls.localize('arduino/theme/dark', 'Dark'); |
| 42 | + case BuiltinThemeProvider.hcTheme.id: |
| 43 | + return nls.localize('arduino/theme/hc', 'High Contrast'); |
| 44 | + default: |
| 45 | + return nls.localize( |
| 46 | + 'arduino/theme/unofficialTheme', |
| 47 | + 'Unofficial - {0}', |
| 48 | + theme.label |
| 49 | + ); |
| 50 | + } |
| 51 | +} |
| 52 | + |
| 53 | +export function compatibleBuiltInTheme(theme: Theme): Theme { |
| 54 | + switch (theme.type) { |
| 55 | + case 'light': |
| 56 | + return ArduinoThemes.light; |
| 57 | + case 'dark': |
| 58 | + return ArduinoThemes.dark; |
| 59 | + case 'hc': |
| 60 | + return BuiltinThemeProvider.hcTheme; |
| 61 | + default: { |
| 62 | + console.warn( |
| 63 | + `Unhandled theme type: ${theme.type}. Theme ID: ${theme.id}, label: ${theme.label}` |
| 64 | + ); |
| 65 | + return ArduinoThemes.light; |
| 66 | + } |
25 | 67 | }
|
26 | 68 | }
|
| 69 | + |
| 70 | +// For tests without DI |
| 71 | +interface ThemeProvider { |
| 72 | + themes(): Theme[]; |
| 73 | + currentTheme(): Theme; |
| 74 | +} |
| 75 | + |
| 76 | +/** |
| 77 | + * Returns with a list of built-in themes officially supported by IDE2 (https://github.com/arduino/arduino-ide/issues/1283). |
| 78 | + * If the `currentTheme` is not a built-in one, it will be appended to the array. Built-in themes come first (in light, dark, HC dark order), followed by any contributed one. |
| 79 | + */ |
| 80 | +export function userConfigurableThemes(service: ThemeService): Theme[]; |
| 81 | +export function userConfigurableThemes(provider: ThemeProvider): Theme[]; |
| 82 | +export function userConfigurableThemes( |
| 83 | + serviceOrProvider: ThemeService | ThemeProvider |
| 84 | +): Theme[] { |
| 85 | + const provider = |
| 86 | + serviceOrProvider instanceof ThemeService |
| 87 | + ? { |
| 88 | + currentTheme: () => serviceOrProvider.getCurrentTheme(), |
| 89 | + themes: () => serviceOrProvider.getThemes(), |
| 90 | + } |
| 91 | + : serviceOrProvider; |
| 92 | + const currentTheme = provider.currentTheme(); |
| 93 | + return provider |
| 94 | + .themes() |
| 95 | + .filter((theme) => isOfficialTheme(theme) || currentTheme.id === theme.id) |
| 96 | + .sort((left, right) => { |
| 97 | + const leftBuiltIn = isOfficialTheme(left); |
| 98 | + const rightBuiltIn = isOfficialTheme(right); |
| 99 | + if (leftBuiltIn === rightBuiltIn) { |
| 100 | + return themeTypeComparator(left, right); |
| 101 | + } |
| 102 | + return leftBuiltIn ? -1 : 1; |
| 103 | + }); |
| 104 | +} |
| 105 | + |
| 106 | +const themeTypeOrder: Record<ThemeType, number> = { |
| 107 | + light: 0, |
| 108 | + dark: 1, |
| 109 | + hc: 2, |
| 110 | +}; |
| 111 | +const themeTypeComparator = (left: Theme, right: Theme) => |
| 112 | + themeTypeOrder[left.type] - themeTypeOrder[right.type]; |
0 commit comments