diff --git a/packages/getting-started/src/browser/getting-started-contribution.ts b/packages/getting-started/src/browser/getting-started-contribution.ts index f3a21ca099347..6f3d70cf1eb4f 100644 --- a/packages/getting-started/src/browser/getting-started-contribution.ts +++ b/packages/getting-started/src/browser/getting-started-contribution.ts @@ -16,7 +16,7 @@ import { injectable, inject } from '@theia/core/shared/inversify'; import { CommandRegistry, MenuModelRegistry } from '@theia/core/lib/common'; -import { CommonMenus, AbstractViewContribution, FrontendApplicationContribution, FrontendApplication } from '@theia/core/lib/browser'; +import { CommonMenus, AbstractViewContribution, FrontendApplicationContribution, FrontendApplication, NavigatableWidget, PreferenceService } from '@theia/core/lib/browser'; import { GettingStartedWidget } from './getting-started-widget'; import { FrontendApplicationStateService } from '@theia/core/lib/browser/frontend-application-state'; import { WorkspaceService } from '@theia/workspace/lib/browser'; @@ -38,6 +38,9 @@ export class GettingStartedContribution extends AbstractViewContribution { - if (!this.workspaceService.opened) { - this.stateService.reachedState('ready').then( - () => this.openView({ reveal: true, activate: true }) - ); - } + 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.openView({ reveal: true, activate: true }); + } + }); + } + }); } override registerCommands(registry: CommandRegistry): void { diff --git a/packages/getting-started/src/browser/getting-started-frontend-module.ts b/packages/getting-started/src/browser/getting-started-frontend-module.ts index a51e8b627f19c..fbcc828646f02 100644 --- a/packages/getting-started/src/browser/getting-started-frontend-module.ts +++ b/packages/getting-started/src/browser/getting-started-frontend-module.ts @@ -18,7 +18,7 @@ import { GettingStartedContribution } from './getting-started-contribution'; import { ContainerModule, interfaces } from '@theia/core/shared/inversify'; import { GettingStartedWidget } from './getting-started-widget'; import { WidgetFactory, FrontendApplicationContribution, bindViewContribution } from '@theia/core/lib/browser'; - +import { bindGettingStartedPreferences } from './getting-started-preferences'; import '../../src/browser/style/index.css'; export default new ContainerModule((bind: interfaces.Bind) => { @@ -29,4 +29,5 @@ export default new ContainerModule((bind: interfaces.Bind) => { id: GettingStartedWidget.ID, createWidget: () => context.container.get(GettingStartedWidget), })).inSingletonScope(); + bindGettingStartedPreferences(bind); }); diff --git a/packages/getting-started/src/browser/getting-started-preferences.ts b/packages/getting-started/src/browser/getting-started-preferences.ts new file mode 100644 index 0000000000000..18d1cc64e2cc3 --- /dev/null +++ b/packages/getting-started/src/browser/getting-started-preferences.ts @@ -0,0 +1,58 @@ +// ***************************************************************************** +// Copyright (C) 2023 Ericsson and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0. +// +// This Source Code may also be made available under the following Secondary +// Licenses when the conditions for such availability set forth in the Eclipse +// Public License v. 2.0 are satisfied: GNU General Public License, version 2 +// with the GNU Classpath Exception which is available at +// https://www.gnu.org/software/classpath/license.html. +// +// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 +// ***************************************************************************** + +import { interfaces } from '@theia/core/shared/inversify'; +import { + createPreferenceProxy, + PreferenceProxy, + PreferenceService, + PreferenceSchema, + PreferenceContribution +} from '@theia/core/lib/browser/preferences'; +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 + } + } +}; + +export interface GettingStartedConfiguration { + 'welcome.alwaysShowWelcomePage': boolean; +} + +export const GettingStartedPreferenceContribution = Symbol('GettingStartedPreferenceContribution'); +export const GettingStartedPreferences = Symbol('GettingStartedPreferences'); +export type GettingStartedPreferences = PreferenceProxy; + +export function createGettingStartedPreferences(preferences: PreferenceService, schema: PreferenceSchema = GettingStartedPreferenceSchema): GettingStartedPreferences { + return createPreferenceProxy(preferences, schema); +} + +export function bindGettingStartedPreferences(bind: interfaces.Bind): void { + bind(GettingStartedPreferences).toDynamicValue(ctx => { + const preferences = ctx.container.get(PreferenceService); + const contribution = ctx.container.get(GettingStartedPreferenceContribution); + return createGettingStartedPreferences(preferences, contribution.schema); + }).inSingletonScope(); + bind(GettingStartedPreferenceContribution).toConstantValue({ schema: GettingStartedPreferenceSchema }); + bind(PreferenceContribution).toService(GettingStartedPreferenceContribution); +} diff --git a/packages/getting-started/src/browser/getting-started-widget.tsx b/packages/getting-started/src/browser/getting-started-widget.tsx index d468240e7db2e..c833471122e8e 100644 --- a/packages/getting-started/src/browser/getting-started-widget.tsx +++ b/packages/getting-started/src/browser/getting-started-widget.tsx @@ -20,7 +20,7 @@ import { injectable, inject, postConstruct } from '@theia/core/shared/inversify' import { CommandRegistry, isOSX, environment, Path } from '@theia/core/lib/common'; import { WorkspaceCommands, WorkspaceService } from '@theia/workspace/lib/browser'; import { KeymapsCommands } from '@theia/keymaps/lib/browser'; -import { Message, ReactWidget, CommonCommands, LabelProvider, Key, KeyCode, codicon } from '@theia/core/lib/browser'; +import { Message, ReactWidget, CommonCommands, LabelProvider, Key, KeyCode, codicon, PreferenceService } from '@theia/core/lib/browser'; import { ApplicationInfo, ApplicationServer } from '@theia/core/lib/common/application-protocol'; import { FrontendApplicationConfigProvider } from '@theia/core/lib/browser/frontend-application-config-provider'; import { EnvVariablesServer } from '@theia/core/lib/common/env-variables'; @@ -47,7 +47,7 @@ export class GettingStartedWidget extends ReactWidget { /** * The widget `label` which is used for display purposes. */ - static readonly LABEL = nls.localizeByDefault('Get Started'); + static readonly LABEL = nls.localizeByDefault('Welcome'); /** * The `ApplicationInfo` for the application if available. @@ -97,6 +97,9 @@ export class GettingStartedWidget extends ReactWidget { @inject(WorkspaceService) protected readonly workspaceService: WorkspaceService; + @inject(PreferenceService) + protected readonly preferenceService: PreferenceService; + @postConstruct() protected init(): void { this.doInit(); @@ -126,34 +129,39 @@ export class GettingStartedWidget extends ReactWidget { * Render the content of the widget. */ protected render(): React.ReactNode { - return
- {this.renderHeader()} -
-
-
- {this.renderOpen()} + return
+
+ {this.renderHeader()} +
+
+
+ {this.renderOpen()} +
-
-
-
- {this.renderRecentWorkspaces()} +
+
+ {this.renderRecentWorkspaces()} +
-
-
-
- {this.renderSettings()} +
+
+ {this.renderSettings()} +
-
-
-
- {this.renderHelp()} +
+
+ {this.renderHelp()} +
-
-
-
- {this.renderVersion()} +
+
+ {this.renderVersion()} +
+
+ {this.renderPreferences()} +
; } @@ -364,6 +372,10 @@ export class GettingStartedWidget extends ReactWidget {
; } + protected renderPreferences(): React.ReactNode { + return ; + } + /** * Build the list of workspace paths. * @param workspaces {string[]} the list of workspaces. @@ -478,3 +490,40 @@ export class GettingStartedWidget extends ReactWidget { return Key.ENTER.keyCode === KeyCode.createKeyCode(e.nativeEvent).key?.keyCode; } } + +export interface PreferencesProps { + preferenceService: PreferenceService; +} + +function WelcomePreferences(props: PreferencesProps): JSX.Element { + const [alwaysShowWelcomePage, setAlwaysShowWelcomePage] = React.useState( + props.preferenceService.get('welcome.alwaysShowWelcomePage', true) + ); + React.useEffect(() => { + const prefListener = props.preferenceService.onPreferenceChanged(change => { + if (change.preferenceName === 'welcome.alwaysShowWelcomePage') { + const prefValue = change.newValue; + setAlwaysShowWelcomePage(prefValue); + } + }); + return () => prefListener.dispose(); + }, [props.preferenceService]); + const handleChange = (e: React.ChangeEvent) => { + const newChecked = e.target.checked; + props.preferenceService.updateValue('welcome.alwaysShowWelcomePage', newChecked); + }; + return ( +
+ + +
+ ); +} diff --git a/packages/getting-started/src/browser/style/index.css b/packages/getting-started/src/browser/style/index.css index 2a23b097fdd32..ba828730c4c0a 100644 --- a/packages/getting-started/src/browser/style/index.css +++ b/packages/getting-started/src/browser/style/index.css @@ -89,3 +89,18 @@ body { text-transform: capitalize; font-weight: 400; } + +.gs-preference-container { + display: flex; + position: absolute; + bottom: 0; + width: 100%; + justify-content: center; +} + +.gs-preference { + margin-top: 20px; + margin-bottom: 20px; + display: flex; + align-items: center; +}