diff --git a/CHANGELOG.md b/CHANGELOG.md index 3f821fc0e16a0..9e252ea0291b4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ ## v1.41.0 - - [application-package] Quit Electron app when back end fails to start [#12778](https://github.com/eclipse-theia/theia/pull/12778) - Contributed on behalf of STMicroelectronics. +[Breaking Changes:](#breaking_changes_1.41.0) + +- [preferences] removed the `welcome.alwaysShowWelcomePage` preference in favor of `workbench.startupEditor`: [#12813](https://github.com/eclipse-theia/theia/pull/12813) + ## v1.40.0 - 07/27/2023 - [application-package] bumped the default supported VS Code API from `1.78.0` to `1.79.0` [#12764](https://github.com/eclipse-theia/theia/pull/12764) - Contributed on behalf of STMicroelectronics. diff --git a/packages/getting-started/package.json b/packages/getting-started/package.json index 89c48b9f8f318..b568750714cdc 100644 --- a/packages/getting-started/package.json +++ b/packages/getting-started/package.json @@ -4,7 +4,10 @@ "description": "Theia - GettingStarted Extension", "dependencies": { "@theia/core": "1.40.0", + "@theia/editor": "1.40.0", + "@theia/filesystem": "1.40.0", "@theia/keymaps": "1.40.0", + "@theia/preview": "1.40.0", "@theia/workspace": "1.40.0" }, "publishConfig": { diff --git a/packages/getting-started/src/browser/getting-started-contribution.ts b/packages/getting-started/src/browser/getting-started-contribution.ts index 6f3d70cf1eb4f..b31de3b3bc2c6 100644 --- a/packages/getting-started/src/browser/getting-started-contribution.ts +++ b/packages/getting-started/src/browser/getting-started-contribution.ts @@ -15,10 +15,13 @@ // ***************************************************************************** import { injectable, inject } from '@theia/core/shared/inversify'; -import { CommandRegistry, MenuModelRegistry } from '@theia/core/lib/common'; -import { CommonMenus, AbstractViewContribution, FrontendApplicationContribution, FrontendApplication, NavigatableWidget, PreferenceService } from '@theia/core/lib/browser'; +import { ArrayUtils, CommandRegistry, MenuModelRegistry } from '@theia/core/lib/common'; +import { CommonCommands, CommonMenus, AbstractViewContribution, FrontendApplicationContribution, FrontendApplication, PreferenceService } from '@theia/core/lib/browser'; +import { EditorManager } from '@theia/editor/lib/browser/editor-manager'; import { GettingStartedWidget } from './getting-started-widget'; +import { FileService } from '@theia/filesystem/lib/browser/file-service'; import { FrontendApplicationStateService } from '@theia/core/lib/browser/frontend-application-state'; +import { PreviewContribution } from '@theia/preview/lib/browser/preview-contribution'; import { WorkspaceService } from '@theia/workspace/lib/browser'; /** @@ -32,15 +35,27 @@ export const GettingStartedCommand = { @injectable() export class GettingStartedContribution extends AbstractViewContribution implements FrontendApplicationContribution { + @inject(CommandRegistry) + protected readonly commandRegistry: CommandRegistry; + + @inject(EditorManager) + protected readonly editorManager: EditorManager; + + @inject(FileService) + protected readonly fileService: FileService; + + @inject(PreferenceService) + protected readonly preferenceService: PreferenceService; + + @inject(PreviewContribution) + protected readonly previewContribution: PreviewContribution; + @inject(FrontendApplicationStateService) protected readonly stateService: FrontendApplicationStateService; @inject(WorkspaceService) protected readonly workspaceService: WorkspaceService; - @inject(PreferenceService) - protected readonly preferenceService: PreferenceService; - constructor() { super({ widgetId: GettingStartedWidget.ID, @@ -52,19 +67,49 @@ export class GettingStartedContribution extends AbstractViewContribution { - this.stateService.reachedState('ready').then(() => { - const editors = this.shell.widgets.filter((widget): widget is NavigatableWidget => NavigatableWidget.is(widget)); - if (editors.length === 0) { - this.preferenceService.ready.then(() => { - const showWelcomePage: boolean = this.preferenceService.get('welcome.alwaysShowWelcomePage', true); - if (showWelcomePage) { + this.stateService.reachedState('ready').then(async () => { + if (this.editorManager.all.length === 0) { + await this.preferenceService.ready; + const startupEditor = this.preferenceService.get('workbench.startupEditor'); + switch (startupEditor) { + case 'welcomePage': this.openView({ reveal: true, activate: true }); - } - }); + break; + case 'welcomePageInEmptyWorkbench': + if (!this.workspaceService.opened) { + this.openView({ reveal: true, activate: true }); + } + break; + case 'newUntitledFile': + this.commandRegistry.executeCommand(CommonCommands.NEW_UNTITLED_TEXT_FILE.id); + break; + case 'readme': + await this.openReadme(); + break; + } } }); } + protected async openReadme(): Promise { + const roots = await this.workspaceService.roots; + const readmes = await Promise.all(roots.map(async folder => { + const folderStat = await this.fileService.resolve(folder.resource); + const fileArr = folderStat?.children?.sort((a, b) => a.name.localeCompare(b.name)) || []; + const filePath = fileArr.find(file => file.name.toLowerCase() === 'readme.md') || fileArr.find(file => file.name.toLowerCase().startsWith('readme')); + return filePath?.resource; + })); + const validReadmes = ArrayUtils.coalesce(readmes); + if (validReadmes.length) { + for (const readme of validReadmes) { + await this.previewContribution.open(readme); + } + } else { + // If no readme is found, show the welcome page. + this.openView({ reveal: true, activate: true }); + } + } + override registerCommands(registry: CommandRegistry): void { registry.registerCommand(GettingStartedCommand, { execute: () => this.openView({ reveal: true, activate: true }), diff --git a/packages/getting-started/src/browser/getting-started-preferences.ts b/packages/getting-started/src/browser/getting-started-preferences.ts index 18d1cc64e2cc3..2621402d1756f 100644 --- a/packages/getting-started/src/browser/getting-started-preferences.ts +++ b/packages/getting-started/src/browser/getting-started-preferences.ts @@ -22,21 +22,32 @@ import { PreferenceSchema, PreferenceContribution } from '@theia/core/lib/browser/preferences'; +import { FrontendApplicationConfigProvider } from '@theia/core/lib/browser/frontend-application-config-provider'; import { nls } from '@theia/core/lib/common/nls'; export const GettingStartedPreferenceSchema: PreferenceSchema = { 'type': 'object', properties: { - 'welcome.alwaysShowWelcomePage': { - type: 'boolean', - description: nls.localizeByDefault('Show welcome page on startup'), - default: true - } + 'workbench.startupEditor': { + type: 'string', + enum: ['none', 'welcomePage', 'readme', 'newUntitledFile', 'welcomePageInEmptyWorkbench'], + enumDescriptions: [ + nls.localizeByDefault('Start without an editor.'), + nls.localize('theia/getting-started/startup-editor/welcomePage', 'Open the Welcome page, with content to aid in getting started with {0} and extensions.', + FrontendApplicationConfigProvider.get().applicationName), + nls.localizeByDefault(`Open the README when opening a folder that contains one, fallback to \'welcomePage\' otherwise. + Note: This is only observed as a global configuration, it will be ignored if set in a workspace or folder configuration.`), + nls.localizeByDefault('Open a new untitled text file (only applies when opening an empty window).'), + nls.localizeByDefault('Open the Welcome page when opening an empty workbench.'), + ], + default: 'welcomePage', + description: nls.localizeByDefault('Controls which editor is shown at startup, if none are restored from the previous session.') + }, } }; export interface GettingStartedConfiguration { - 'welcome.alwaysShowWelcomePage': boolean; + 'workbench.startupEditor': string; } export const GettingStartedPreferenceContribution = Symbol('GettingStartedPreferenceContribution'); diff --git a/packages/getting-started/src/browser/getting-started-widget.tsx b/packages/getting-started/src/browser/getting-started-widget.tsx index 4da274562f0e8..72053273f2fd9 100644 --- a/packages/getting-started/src/browser/getting-started-widget.tsx +++ b/packages/getting-started/src/browser/getting-started-widget.tsx @@ -496,32 +496,32 @@ export interface PreferencesProps { } function WelcomePreferences(props: PreferencesProps): JSX.Element { - const [alwaysShowWelcomePage, setAlwaysShowWelcomePage] = React.useState( - props.preferenceService.get('welcome.alwaysShowWelcomePage', true) + const [startupEditor, setStartupEditor] = React.useState( + props.preferenceService.get('workbench.startupEditor', 'welcomePage') ); React.useEffect(() => { const prefListener = props.preferenceService.onPreferenceChanged(change => { - if (change.preferenceName === 'welcome.alwaysShowWelcomePage') { + if (change.preferenceName === 'workbench.startupEditor') { const prefValue = change.newValue; - setAlwaysShowWelcomePage(prefValue); + setStartupEditor(prefValue); } }); return () => prefListener.dispose(); }, [props.preferenceService]); const handleChange = (e: React.ChangeEvent) => { - const newChecked = e.target.checked; - props.preferenceService.updateValue('welcome.alwaysShowWelcomePage', newChecked); + const newValue = e.target.checked ? 'welcomePage' : 'none'; + props.preferenceService.updateValue('workbench.startupEditor', newValue); }; return (
-
diff --git a/packages/getting-started/tsconfig.json b/packages/getting-started/tsconfig.json index ba31f57815a43..26df745bdd0c6 100644 --- a/packages/getting-started/tsconfig.json +++ b/packages/getting-started/tsconfig.json @@ -12,9 +12,18 @@ { "path": "../core" }, + { + "path": "../editor" + }, + { + "path": "../filesystem" + }, { "path": "../keymaps" }, + { + "path": "../preview" + }, { "path": "../workspace" }