Skip to content

Commit 2e19646

Browse files
author
Akos Kitta
committed
feat: removed the non official themes from the UI
Closes #1283 Ref eclipse-theia/theia#11151 Signed-off-by: Akos Kitta <a.kitta@arduino.cc>
1 parent 1db7ec8 commit 2e19646

File tree

6 files changed

+441
-30
lines changed

6 files changed

+441
-30
lines changed

Diff for: arduino-ide-extension/src/browser/arduino-ide-frontend-module.ts

+17-6
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,6 @@ import {
238238
UploadFirmwareDialog,
239239
UploadFirmwareDialogProps,
240240
} from './dialogs/firmware-uploader/firmware-uploader-dialog';
241-
242241
import { UploadCertificate } from './contributions/upload-certificate';
243242
import {
244243
ArduinoFirmwareUploader,
@@ -328,9 +327,13 @@ import { NewCloudSketch } from './contributions/new-cloud-sketch';
328327
import { SketchbookCompositeWidget } from './widgets/sketchbook/sketchbook-composite-widget';
329328
import { WindowTitleUpdater } from './theia/core/window-title-updater';
330329
import { WindowTitleUpdater as TheiaWindowTitleUpdater } from '@theia/core/lib/browser/window/window-title-updater';
331-
import { ThemeServiceWithDB } from './theia/core/theming';
332-
import { ThemeServiceWithDB as TheiaThemeServiceWithDB } from '@theia/monaco/lib/browser/monaco-indexed-db';
333-
import { MonacoThemingService } from './theia/monaco/monaco-theming-service';
330+
import {
331+
MonacoThemingService,
332+
CleanupObsoleteThemes,
333+
ThemesRegistrationSummary,
334+
MonacoThemeRegistry,
335+
} from './theia/monaco/monaco-theming-service';
336+
import { MonacoThemeRegistry as TheiaMonacoThemeRegistry } from '@theia/monaco/lib/browser/textmate/monaco-theme-registry';
334337
import { MonacoThemingService as TheiaMonacoThemingService } from '@theia/monaco/lib/browser/monaco-theming-service';
335338
import { TypeHierarchyServiceProvider } from './theia/typehierarchy/type-hierarchy-service';
336339
import { TypeHierarchyServiceProvider as TheiaTypeHierarchyServiceProvider } from '@theia/typehierarchy/lib/browser/typehierarchy-service';
@@ -981,11 +984,19 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
981984
rebind(TheiaWindowTitleUpdater).toService(WindowTitleUpdater);
982985

983986
// register Arduino themes
984-
bind(ThemeServiceWithDB).toSelf().inSingletonScope();
985-
rebind(TheiaThemeServiceWithDB).toService(ThemeServiceWithDB);
986987
bind(MonacoThemingService).toSelf().inSingletonScope();
987988
rebind(TheiaMonacoThemingService).toService(MonacoThemingService);
988989

990+
// workaround for themes cannot be removed after registration
991+
// https://github.com/eclipse-theia/theia/issues/11151
992+
bind(CleanupObsoleteThemes).toSelf().inSingletonScope();
993+
bind(FrontendApplicationContribution).toService(
994+
CleanupObsoleteThemes
995+
);
996+
bind(ThemesRegistrationSummary).toSelf().inSingletonScope();
997+
bind(MonacoThemeRegistry).toSelf().inSingletonScope();
998+
rebind(TheiaMonacoThemeRegistry).toService(MonacoThemeRegistry);
999+
9891000
// disable type-hierarchy support
9901001
// https://github.com/eclipse-theia/theia/commit/16c88a584bac37f5cf3cc5eb92ffdaa541bda5be
9911002
bind(TypeHierarchyServiceProvider).toSelf().inSingletonScope();

Diff for: arduino-ide-extension/src/browser/dialogs/settings/settings-component.tsx

+22-4
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ import {
2424
} from '@theia/core/lib/common/i18n/localization';
2525
import SettingsStepInput from './settings-step-input';
2626
import { InterfaceScale } from '../../contributions/interface-scale';
27+
import {
28+
userConfigurableThemes,
29+
themeLabelForSettings,
30+
} from '../../theia/core/theming';
2731

2832
const maxScale = InterfaceScale.ZoomLevel.toPercentage(
2933
InterfaceScale.ZoomLevel.MAX
@@ -218,11 +222,11 @@ export class SettingsComponent extends React.Component<
218222
<div className="flex-line">
219223
<select
220224
className="theia-select"
221-
value={this.props.themeService.getCurrentTheme().label}
225+
value={this.currentThemeLabel}
222226
onChange={this.themeDidChange}
223227
>
224-
{this.props.themeService.getThemes().map(({ id, label }) => (
225-
<option key={id} value={label}>
228+
{this.themeSelectOptions.map(({ key, label }) => (
229+
<option key={key} value={label}>
226230
{label}
227231
</option>
228232
))}
@@ -333,6 +337,18 @@ export class SettingsComponent extends React.Component<
333337
);
334338
}
335339

340+
private get currentThemeLabel(): string {
341+
const currentTheme = this.props.themeService.getCurrentTheme();
342+
return themeLabelForSettings(currentTheme);
343+
}
344+
345+
private get themeSelectOptions(): { key: string; label: string }[] {
346+
return userConfigurableThemes(this.props.themeService).map((theme) => ({
347+
key: theme.id,
348+
label: themeLabelForSettings(theme),
349+
}));
350+
}
351+
336352
private toSelectOptions(language: string | LanguageInfo): JSX.Element {
337353
const plain = typeof language === 'string';
338354
const key = plain ? language : language.languageId;
@@ -610,7 +626,9 @@ export class SettingsComponent extends React.Component<
610626
event: React.ChangeEvent<HTMLSelectElement>
611627
): void => {
612628
const { selectedIndex } = event.target.options;
613-
const theme = this.props.themeService.getThemes()[selectedIndex];
629+
const theme = userConfigurableThemes(this.props.themeService)[
630+
selectedIndex
631+
];
614632
if (theme) {
615633
this.setState({ themeId: theme.id });
616634
if (this.props.themeService.getCurrentTheme().id !== theme.id) {
+96-10
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,112 @@
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';
47

58
export namespace ArduinoThemes {
6-
export const Light: Theme = {
9+
export const light: Theme = {
710
id: 'arduino-theme',
811
type: 'light',
912
label: 'Light (Arduino)',
1013
editorTheme: 'arduino-theme',
1114
};
12-
export const Dark: Theme = {
15+
export const dark: Theme = {
1316
id: 'arduino-theme-dark',
1417
type: 'dark',
1518
label: 'Dark (Arduino)',
1619
editorTheme: 'arduino-theme-dark',
1720
};
1821
}
1922

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+
}
2567
}
2668
}
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

Comments
 (0)