Skip to content

Commit

Permalink
getting-started: add welcome page checkbox preference (#12750)
Browse files Browse the repository at this point in the history
The pull-request includes a preference and checkbox to toggle the visibility of the welcome-page on startup.

Signed-off-by: Vlad Arama <vlad.arama@ericsson.com>
  • Loading branch information
vladarama authored Aug 4, 2023
1 parent a9ffaa4 commit 79653f3
Show file tree
Hide file tree
Showing 5 changed files with 163 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -38,6 +38,9 @@ export class GettingStartedContribution extends AbstractViewContribution<Getting
@inject(WorkspaceService)
protected readonly workspaceService: WorkspaceService;

@inject(PreferenceService)
protected readonly preferenceService: PreferenceService;

constructor() {
super({
widgetId: GettingStartedWidget.ID,
Expand All @@ -49,11 +52,17 @@ export class GettingStartedContribution extends AbstractViewContribution<Getting
}

async onStart(app: FrontendApplication): Promise<void> {
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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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) => {
Expand All @@ -29,4 +29,5 @@ export default new ContainerModule((bind: interfaces.Bind) => {
id: GettingStartedWidget.ID,
createWidget: () => context.container.get<GettingStartedWidget>(GettingStartedWidget),
})).inSingletonScope();
bindGettingStartedPreferences(bind);
});
Original file line number Diff line number Diff line change
@@ -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<GettingStartedConfiguration>;

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>(PreferenceService);
const contribution = ctx.container.get<PreferenceContribution>(GettingStartedPreferenceContribution);
return createGettingStartedPreferences(preferences, contribution.schema);
}).inSingletonScope();
bind(GettingStartedPreferenceContribution).toConstantValue({ schema: GettingStartedPreferenceSchema });
bind(PreferenceContribution).toService(GettingStartedPreferenceContribution);
}
97 changes: 73 additions & 24 deletions packages/getting-started/src/browser/getting-started-widget.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -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.
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -126,34 +129,39 @@ export class GettingStartedWidget extends ReactWidget {
* Render the content of the widget.
*/
protected render(): React.ReactNode {
return <div className='gs-container'>
{this.renderHeader()}
<hr className='gs-hr' />
<div className='flex-grid'>
<div className='col'>
{this.renderOpen()}
return <div>
<div className='gs-container'>
{this.renderHeader()}
<hr className='gs-hr' />
<div className='flex-grid'>
<div className='col'>
{this.renderOpen()}
</div>
</div>
</div>
<div className='flex-grid'>
<div className='col'>
{this.renderRecentWorkspaces()}
<div className='flex-grid'>
<div className='col'>
{this.renderRecentWorkspaces()}
</div>
</div>
</div>
<div className='flex-grid'>
<div className='col'>
{this.renderSettings()}
<div className='flex-grid'>
<div className='col'>
{this.renderSettings()}
</div>
</div>
</div>
<div className='flex-grid'>
<div className='col'>
{this.renderHelp()}
<div className='flex-grid'>
<div className='col'>
{this.renderHelp()}
</div>
</div>
</div>
<div className='flex-grid'>
<div className='col'>
{this.renderVersion()}
<div className='flex-grid'>
<div className='col'>
{this.renderVersion()}
</div>
</div>
</div>
<div className='gs-preference-container'>
{this.renderPreferences()}
</div>
</div>;
}

Expand Down Expand Up @@ -364,6 +372,10 @@ export class GettingStartedWidget extends ReactWidget {
</div>;
}

protected renderPreferences(): React.ReactNode {
return <WelcomePreferences preferenceService={this.preferenceService}></WelcomePreferences>;
}

/**
* Build the list of workspace paths.
* @param workspaces {string[]} the list of workspaces.
Expand Down Expand Up @@ -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<boolean>(
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<HTMLInputElement>) => {
const newChecked = e.target.checked;
props.preferenceService.updateValue('welcome.alwaysShowWelcomePage', newChecked);
};
return (
<div className='gs-preference'>
<input
type="checkbox"
className="theia-input"
id="alwaysShowWelcomePage"
onChange={handleChange}
checked={alwaysShowWelcomePage}
/>
<label htmlFor="alwaysShowWelcomePage">
{nls.localizeByDefault('Show welcome page on startup')}
</label>
</div>
);
}
15 changes: 15 additions & 0 deletions packages/getting-started/src/browser/style/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

0 comments on commit 79653f3

Please sign in to comment.