Skip to content

Commit

Permalink
feat: removed the non official themes from the UI
Browse files Browse the repository at this point in the history
Closes #1283
Ref eclipse-theia/theia#11151

Signed-off-by: Akos Kitta <[email protected]>
  • Loading branch information
Akos Kitta committed Apr 4, 2023
1 parent 6eed3bd commit d3300ea
Show file tree
Hide file tree
Showing 6 changed files with 441 additions and 30 deletions.
23 changes: 17 additions & 6 deletions arduino-ide-extension/src/browser/arduino-ide-frontend-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,6 @@ import {
UploadFirmwareDialog,
UploadFirmwareDialogProps,
} from './dialogs/firmware-uploader/firmware-uploader-dialog';

import { UploadCertificate } from './contributions/upload-certificate';
import {
ArduinoFirmwareUploader,
Expand Down Expand Up @@ -328,9 +327,13 @@ import { NewCloudSketch } from './contributions/new-cloud-sketch';
import { SketchbookCompositeWidget } from './widgets/sketchbook/sketchbook-composite-widget';
import { WindowTitleUpdater } from './theia/core/window-title-updater';
import { WindowTitleUpdater as TheiaWindowTitleUpdater } from '@theia/core/lib/browser/window/window-title-updater';
import { ThemeServiceWithDB } from './theia/core/theming';
import { ThemeServiceWithDB as TheiaThemeServiceWithDB } from '@theia/monaco/lib/browser/monaco-indexed-db';
import { MonacoThemingService } from './theia/monaco/monaco-theming-service';
import {
MonacoThemingService,
CleanupObsoleteThemes,
ThemesRegistrationSummary,
MonacoThemeRegistry,
} from './theia/monaco/monaco-theming-service';
import { MonacoThemeRegistry as TheiaMonacoThemeRegistry } from '@theia/monaco/lib/browser/textmate/monaco-theme-registry';
import { MonacoThemingService as TheiaMonacoThemingService } from '@theia/monaco/lib/browser/monaco-theming-service';
import { TypeHierarchyServiceProvider } from './theia/typehierarchy/type-hierarchy-service';
import { TypeHierarchyServiceProvider as TheiaTypeHierarchyServiceProvider } from '@theia/typehierarchy/lib/browser/typehierarchy-service';
Expand Down Expand Up @@ -981,11 +984,19 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
rebind(TheiaWindowTitleUpdater).toService(WindowTitleUpdater);

// register Arduino themes
bind(ThemeServiceWithDB).toSelf().inSingletonScope();
rebind(TheiaThemeServiceWithDB).toService(ThemeServiceWithDB);
bind(MonacoThemingService).toSelf().inSingletonScope();
rebind(TheiaMonacoThemingService).toService(MonacoThemingService);

// workaround for themes cannot be removed after registration
// https://github.com/eclipse-theia/theia/issues/11151
bind(CleanupObsoleteThemes).toSelf().inSingletonScope();
bind(FrontendApplicationContribution).toService(
CleanupObsoleteThemes
);
bind(ThemesRegistrationSummary).toSelf().inSingletonScope();
bind(MonacoThemeRegistry).toSelf().inSingletonScope();
rebind(TheiaMonacoThemeRegistry).toService(MonacoThemeRegistry);

// disable type-hierarchy support
// https://github.com/eclipse-theia/theia/commit/16c88a584bac37f5cf3cc5eb92ffdaa541bda5be
bind(TypeHierarchyServiceProvider).toSelf().inSingletonScope();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ import {
} from '@theia/core/lib/common/i18n/localization';
import SettingsStepInput from './settings-step-input';
import { InterfaceScale } from '../../contributions/interface-scale';
import {
userConfigurableThemes,
themeLabelForSettings,
} from '../../theia/core/theming';

const maxScale = InterfaceScale.ZoomLevel.toPercentage(
InterfaceScale.ZoomLevel.MAX
Expand Down Expand Up @@ -218,11 +222,11 @@ export class SettingsComponent extends React.Component<
<div className="flex-line">
<select
className="theia-select"
value={this.props.themeService.getCurrentTheme().label}
value={this.currentThemeLabel}
onChange={this.themeDidChange}
>
{this.props.themeService.getThemes().map(({ id, label }) => (
<option key={id} value={label}>
{this.themeSelectOptions.map(({ key, label }) => (
<option key={key} value={label}>
{label}
</option>
))}
Expand Down Expand Up @@ -333,6 +337,18 @@ export class SettingsComponent extends React.Component<
);
}

private get currentThemeLabel(): string {
const currentTheme = this.props.themeService.getCurrentTheme();
return themeLabelForSettings(currentTheme);
}

private get themeSelectOptions(): { key: string; label: string }[] {
return userConfigurableThemes(this.props.themeService).map((theme) => ({
key: theme.id,
label: themeLabelForSettings(theme),
}));
}

private toSelectOptions(language: string | LanguageInfo): JSX.Element {
const plain = typeof language === 'string';
const key = plain ? language : language.languageId;
Expand Down Expand Up @@ -610,7 +626,9 @@ export class SettingsComponent extends React.Component<
event: React.ChangeEvent<HTMLSelectElement>
): void => {
const { selectedIndex } = event.target.options;
const theme = this.props.themeService.getThemes()[selectedIndex];
const theme = userConfigurableThemes(this.props.themeService)[
selectedIndex
];
if (theme) {
this.setState({ themeId: theme.id });
if (this.props.themeService.getCurrentTheme().id !== theme.id) {
Expand Down
106 changes: 96 additions & 10 deletions arduino-ide-extension/src/browser/theia/core/theming.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,112 @@
import type { Theme } from '@theia/core/lib/common/theme';
import { injectable } from '@theia/core/shared/inversify';
import { ThemeServiceWithDB as TheiaThemeServiceWithDB } from '@theia/monaco/lib/browser/monaco-indexed-db';
import {
BuiltinThemeProvider,
ThemeService,
} from '@theia/core/lib/browser/theming';
import { nls } from '@theia/core/lib/common/nls';
import type { Theme, ThemeType } from '@theia/core/lib/common/theme';

export namespace ArduinoThemes {
export const Light: Theme = {
export const light: Theme = {
id: 'arduino-theme',
type: 'light',
label: 'Light (Arduino)',
editorTheme: 'arduino-theme',
};
export const Dark: Theme = {
export const dark: Theme = {
id: 'arduino-theme-dark',
type: 'dark',
label: 'Dark (Arduino)',
editorTheme: 'arduino-theme-dark',
};
}

@injectable()
export class ThemeServiceWithDB extends TheiaThemeServiceWithDB {
protected override init(): void {
this.register(ArduinoThemes.Light, ArduinoThemes.Dark);
super.init();
const officialThemeIds = new Set(
[
ArduinoThemes.light,
ArduinoThemes.dark,
BuiltinThemeProvider.hcTheme,
// TODO: add the HC light theme after Theia 1.36
].map(({ id }) => id)
);
export function isOfficialTheme(theme: Theme | string): boolean {
const themeId = typeof theme === 'string' ? theme : theme.id;
return officialThemeIds.has(themeId);
}

export function themeLabelForSettings(theme: Theme): string {
switch (theme.id) {
case ArduinoThemes.light.id:
return nls.localize('arduino/theme/light', 'Light');
case ArduinoThemes.dark.id:
return nls.localize('arduino/theme/dark', 'Dark');
case BuiltinThemeProvider.hcTheme.id:
return nls.localize('arduino/theme/hc', 'High Contrast');
default:
return nls.localize(
'arduino/theme/unofficialTheme',
'Unofficial - {0}',
theme.label
);
}
}

export function compatibleBuiltInTheme(theme: Theme): Theme {
switch (theme.type) {
case 'light':
return ArduinoThemes.light;
case 'dark':
return ArduinoThemes.dark;
case 'hc':
return BuiltinThemeProvider.hcTheme;
default: {
console.warn(
`Unhandled theme type: ${theme.type}. Theme ID: ${theme.id}, label: ${theme.label}`
);
return ArduinoThemes.light;
}
}
}

// For tests without DI
interface ThemeProvider {
themes(): Theme[];
currentTheme(): Theme;
}

/**
* Returns with a list of built-in themes officially supported by IDE2 (https://github.com/arduino/arduino-ide/issues/1283).
* 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.
*/
export function userConfigurableThemes(service: ThemeService): Theme[];
export function userConfigurableThemes(provider: ThemeProvider): Theme[];
export function userConfigurableThemes(
serviceOrProvider: ThemeService | ThemeProvider
): Theme[] {
const provider =
serviceOrProvider instanceof ThemeService
? {
currentTheme: () => serviceOrProvider.getCurrentTheme(),
themes: () => serviceOrProvider.getThemes(),
}
: serviceOrProvider;
const currentTheme = provider.currentTheme();
return provider
.themes()
.filter((theme) => isOfficialTheme(theme) || currentTheme.id === theme.id)
.sort((left, right) => {
const leftBuiltIn = isOfficialTheme(left);
const rightBuiltIn = isOfficialTheme(right);
if (leftBuiltIn === rightBuiltIn) {
return themeTypeComparator(left, right);
}
return leftBuiltIn ? -1 : 1;
});
}

const themeTypeOrder: Record<ThemeType, number> = {
light: 0,
dark: 1,
hc: 2,
};
const themeTypeComparator = (left: Theme, right: Theme) =>
themeTypeOrder[left.type] - themeTypeOrder[right.type];
Loading

0 comments on commit d3300ea

Please sign in to comment.