Skip to content

Commit 4b9f2a0

Browse files
committed
Merge pull request #2166 from SofianHn/master
Remove static welcome page and move welcome experience to the website
2 parents 463db9e + bb6e460 commit 4b9f2a0

File tree

10 files changed

+178
-70
lines changed

10 files changed

+178
-70
lines changed

product.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,6 @@
33
"nameLong": "Code [OSS Build]",
44
"win32MutexName": "vscodeoss",
55
"licenseUrl": "https://github.com/Microsoft/vscode/blob/master/LICENSE.txt",
6-
"darwinBundleIdentifier": "com.visualstudio.code.oss"
6+
"darwinBundleIdentifier": "com.visualstudio.code.oss",
7+
"welcomePage": "http://go.microsoft.com/fwlink/?LinkId=723048"
78
}

src/vs/workbench/electron-main/menus.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -576,10 +576,9 @@ export class VSCodeMenu {
576576
});
577577

578578
arrays.coalesce([
579-
env.product.welcomePage ? this.createMenuItem(nls.localize('miShowWelcome', "&&Show Welcome"), 'workbench.action.markdown.showWelcome') : null,
580579
env.product.documentationUrl ? new MenuItem({ label: mnemonicLabel(nls.localize('miDocumentation', "&&Documentation")), click: () => openUrl(env.product.documentationUrl, 'openDocumentationUrl') }) : null,
581580
env.product.releaseNotesUrl ? new MenuItem({ label: mnemonicLabel(nls.localize('miReleaseNotes', "&&Release Notes")), click: () => openUrl(env.product.releaseNotesUrl, 'openReleaseNotesUrl') }) : null,,
582-
(env.product.welcomePage || env.product.documentationUrl || env.product.releaseNotesUrl) ? __separator__() : null,
581+
(env.product.documentationUrl || env.product.releaseNotesUrl) ? __separator__() : null,
583582
env.product.twitterUrl ? new MenuItem({ label: mnemonicLabel(nls.localize('miTwitter', "&&Join us on Twitter")), click: () => openUrl(env.product.twitterUrl, 'openTwitterUrl') }) : null,
584583
env.product.requestFeatureUrl ? new MenuItem({ label: mnemonicLabel(nls.localize('miUserVoice', "&&Request Features")), click: () => openUrl(env.product.requestFeatureUrl, 'openUserVoiceUrl') }) : null,
585584
env.product.reportIssueUrl ? new MenuItem({ label: mnemonicLabel(nls.localize('miReportIssues', "Report &&Issues")), click: () => openUrl(env.product.reportIssueUrl, 'openReportIssues') }) : null,
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
'use strict';
6+
7+
import {IWorkbenchContribution} from 'vs/workbench/common/contributions';
8+
import {IWorkspaceContextService} from 'vs/workbench/services/workspace/common/contextService';
9+
import {IStorageService, StorageScope, StorageEvent, StorageEventType} from 'vs/platform/storage/common/storage';
10+
import {ITelemetryService, ITelemetryInfo} from 'vs/platform/telemetry/common/telemetry';
11+
12+
/**
13+
* This extensions handles the first launch expereince for new users
14+
*/
15+
export abstract class AbstractGettingStarted implements IWorkbenchContribution {
16+
protected static hideWelcomeSettingskey = 'workbench.hide.welcome';
17+
18+
protected welcomePageURL: string;
19+
protected appName: string;
20+
21+
constructor(
22+
@IStorageService private storageService: IStorageService,
23+
@IWorkspaceContextService private contextService: IWorkspaceContextService,
24+
@ITelemetryService private telemetryService: ITelemetryService
25+
) {
26+
const env = contextService.getConfiguration().env;
27+
this.appName = env.appName;
28+
29+
if (env.welcomePage) {
30+
this.welcomePageURL = env.welcomePage;
31+
this.handleWelcome();
32+
}
33+
}
34+
35+
private handleWelcome(): void {
36+
let firstStartup = !this.storageService.get(AbstractGettingStarted.hideWelcomeSettingskey);
37+
38+
if (firstStartup && this.welcomePageURL) {
39+
this.telemetryService.getTelemetryInfo().then(info=>{
40+
let url = this.getUrl(info);
41+
this.openExternal(url);
42+
this.storageService.store(AbstractGettingStarted.hideWelcomeSettingskey, true);
43+
});
44+
}
45+
46+
}
47+
48+
private getUrl(telemetryInfo: ITelemetryInfo): string {
49+
return `${this.welcomePageURL}&&from=${this.appName}&&id=${telemetryInfo.machineId}`;
50+
}
51+
52+
protected openExternal(url: string) {
53+
throw new Error('implement me');
54+
}
55+
56+
public getId(): string {
57+
return 'vs.gettingstarted';
58+
}
59+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
'use strict';
6+
7+
import {Registry} from 'vs/platform/platform';
8+
import {ElectronGettingStarted} from 'vs/workbench/parts/gettingStarted/electron-browser/electronGettingStarted';
9+
import {IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions} from 'vs/workbench/common/contributions';
10+
11+
(<IWorkbenchContributionsRegistry>Registry.as(WorkbenchExtensions.Workbench)).registerWorkbenchContribution(
12+
ElectronGettingStarted
13+
);
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
'use strict';
6+
7+
import {IWorkbenchContribution} from 'vs/workbench/common/contributions';
8+
import {AbstractGettingStarted} from 'vs/workbench/parts/gettingStarted/common/abstractGettingStarted';
9+
10+
import { shell } from 'electron';
11+
12+
export class ElectronGettingStarted extends AbstractGettingStarted implements IWorkbenchContribution {
13+
14+
protected openExternal(url: string) {
15+
shell.openExternal(url);
16+
}
17+
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
'use strict';
7+
8+
import * as assert from 'assert';
9+
import {AbstractGettingStarted} from 'vs/workbench/parts/gettingStarted/common/abstractGettingStarted';
10+
import {IInstantiationService} from 'vs/platform/instantiation/common/instantiation';
11+
import {create} from 'vs/platform/instantiation/common/instantiationService';
12+
import {Promise} from 'vs/base/common/winjs.base';
13+
14+
class TestGettingStarted extends AbstractGettingStarted {
15+
public lastUrl: string;
16+
17+
protected openExternal(url: string) {
18+
this.lastUrl = url;
19+
}
20+
}
21+
22+
suite('Workbench - GettingStarted', () => {
23+
let instantiation: IInstantiationService = null;
24+
let welcomePageEnvConfig: string = null;
25+
let hideWelcomeSettingsValue: string = null;
26+
let machineId: string = null;
27+
let appName: string = null;
28+
29+
suiteSetup(() => {
30+
instantiation = create({
31+
contextService: {
32+
getConfiguration: () => {
33+
return {
34+
env: {
35+
welcomePage: welcomePageEnvConfig,
36+
appName: appName
37+
}
38+
}
39+
}
40+
},
41+
telemetryService: {
42+
getTelemetryInfo: () => Promise.as({ machineId: machineId })
43+
},
44+
storageService: {
45+
get: () => hideWelcomeSettingsValue,
46+
store: (value) => hideWelcomeSettingsValue = value
47+
}
48+
});
49+
});
50+
51+
suiteTeardown(() => {
52+
instantiation = null;
53+
});
54+
55+
setup(() => {
56+
welcomePageEnvConfig = null;
57+
hideWelcomeSettingsValue = null;
58+
appName = null;
59+
});
60+
61+
test('disabled by default', function() {
62+
let gettingStarted = instantiation.createInstance(TestGettingStarted);
63+
assert(gettingStarted.lastUrl === undefined, 'no page is opened when welcomePage is not configured');
64+
});
65+
66+
test('base case', function() {
67+
welcomePageEnvConfig = 'base url';
68+
appName = 'some app';
69+
machineId = '123';
70+
let gettingStarted = instantiation.createInstance(TestGettingStarted);
71+
assert(gettingStarted.lastUrl === `${welcomePageEnvConfig}&&from=${appName}&&id=${machineId}`, 'a page is opened when welcomePage is configured && first run');
72+
assert(hideWelcomeSettingsValue !== null, 'a flag is set to hide welcome page');
73+
});
74+
75+
test('dont show after initial run', function() {
76+
welcomePageEnvConfig = 'url';
77+
hideWelcomeSettingsValue = 'true';
78+
let gettingStarted = instantiation.createInstance(TestGettingStarted);
79+
assert(gettingStarted.lastUrl === undefined, 'no page is opened after initial run');
80+
assert(hideWelcomeSettingsValue !== null, 'a flag is set to hide welcome page');
81+
});
82+
});

src/vs/workbench/parts/markdown/browser/markdownActions.contribution.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import {FileEditorInputActionContributor} from 'vs/workbench/parts/files/browser
1414
import {asFileResource} from 'vs/workbench/parts/files/common/files';
1515
import strings = require('vs/base/common/strings');
1616
import {IEditorInputActionContext, IEditorInputAction} from 'vs/workbench/browser/parts/editor/baseEditor';
17-
import {ShowWelcomeAction, OpenPreviewToSideAction, GlobalTogglePreviewMarkdownAction, PreviewMarkdownEditorInputAction, PreviewMarkdownAction} from 'vs/workbench/parts/markdown/browser/markdownActions';
17+
import {OpenPreviewToSideAction, GlobalTogglePreviewMarkdownAction, PreviewMarkdownEditorInputAction, PreviewMarkdownAction} from 'vs/workbench/parts/markdown/browser/markdownActions';
1818
import {MARKDOWN_MIME, MARKDOWN_FILES} from 'vs/workbench/parts/markdown/common/markdown';
1919
import {IWorkbenchActionRegistry, Extensions as ActionExtensions} from 'vs/workbench/common/actionRegistry';
2020
import {IInstantiationService} from 'vs/platform/instantiation/common/instantiation';
@@ -80,5 +80,4 @@ let category = nls.localize('markdown', "Markdown");
8080

8181
let workbenchActionsRegistry = <IWorkbenchActionRegistry>Registry.as(ActionExtensions.WorkbenchActions);
8282
workbenchActionsRegistry.registerWorkbenchAction(new SyncActionDescriptor(GlobalTogglePreviewMarkdownAction, GlobalTogglePreviewMarkdownAction.ID, GlobalTogglePreviewMarkdownAction.LABEL, { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_V }), category);
83-
workbenchActionsRegistry.registerWorkbenchAction(new SyncActionDescriptor(OpenPreviewToSideAction, OpenPreviewToSideAction.ID, OpenPreviewToSideAction.LABEL, { primary: KeyMod.chord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyCode.KEY_V) }), category);
84-
workbenchActionsRegistry.registerWorkbenchAction(new SyncActionDescriptor(ShowWelcomeAction, ShowWelcomeAction.ID, ShowWelcomeAction.LABEL));
83+
workbenchActionsRegistry.registerWorkbenchAction(new SyncActionDescriptor(OpenPreviewToSideAction, OpenPreviewToSideAction.ID, OpenPreviewToSideAction.LABEL, { primary: KeyMod.chord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyCode.KEY_V) }), category);

src/vs/workbench/parts/markdown/browser/markdownActions.ts

Lines changed: 0 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -155,50 +155,4 @@ export class PreviewMarkdownEditorInputAction extends EditorInputAction {
155155

156156
return this.editorService.openEditor(markdownInput, null, sideBySide);
157157
}
158-
}
159-
160-
export class ShowWelcomeAction extends Action {
161-
162-
public static ID = 'workbench.action.markdown.showWelcome';
163-
public static LABEL = nls.localize('showWelcome', "Show Welcome");
164-
165-
private preserveFocus: boolean;
166-
private welcomePageResource: URI;
167-
168-
constructor(
169-
id: string,
170-
label: string,
171-
@IInstantiationService private instantiationService: IInstantiationService,
172-
@IWorkbenchEditorService private editorService: IWorkbenchEditorService,
173-
@IPartService private partService: IPartService,
174-
@IWorkspaceContextService private contextService: IWorkspaceContextService
175-
) {
176-
super(id, label);
177-
178-
this.preserveFocus = false;
179-
180-
const env = contextService.getConfiguration().env;
181-
if (env.welcomePage) {
182-
this.welcomePageResource = URI.file(paths.join(env.appRoot, env.welcomePage));
183-
}
184-
185-
this.enabled = !!this.welcomePageResource;
186-
}
187-
188-
public setPreserveFocus(preserveFocus: boolean) {
189-
this.preserveFocus = preserveFocus;
190-
}
191-
192-
public run(): Promise {
193-
return this.partService.joinCreation().then(() => {
194-
let editorCount = this.editorService.getVisibleEditors().length;
195-
196-
let markdownInput = this.instantiationService.createInstance(MarkdownEditorInput, this.welcomePageResource, nls.localize('welcome', "Welcome"), nls.localize('vscode', "Getting Started"));
197-
198-
let options = new EditorOptions();
199-
options.preserveFocus = this.preserveFocus;
200-
201-
return this.editorService.openEditor(markdownInput, options, editorCount !== 0 && editorCount !== 3);
202-
});
203-
}
204158
}

src/vs/workbench/parts/markdown/browser/markdownExtension.ts

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ import themes = require('vs/platform/theme/common/themes');
1616
import {IWorkbenchContribution} from 'vs/workbench/common/contributions';
1717
import {IFrameEditor} from 'vs/workbench/browser/parts/editor/iframeEditor';
1818
import {MarkdownEditorInput} from 'vs/workbench/parts/markdown/common/markdownEditorInput';
19-
import {ShowWelcomeAction} from 'vs/workbench/parts/markdown/browser/markdownActions';
2019
import {EditorEvent, EventType as WorkbenchEventType} from 'vs/workbench/common/events';
2120
import {IWorkbenchEditorService} from 'vs/workbench/services/editor/common/editorService';
2221
import {IWorkspaceContextService} from 'vs/workbench/services/workspace/common/contextService';
@@ -36,7 +35,6 @@ interface ILanguageConfiguration {
3635
// This extension tracks markdown files for changes to update markdown editors and inputs accordingly.
3736
export class MarkdownFileTracker implements IWorkbenchContribution {
3837

39-
private static hideWelcomeSettingskey = 'workbench.hide.welcome';
4038
private static RELOAD_MARKDOWN_DELAY = 300; // delay before reloading markdown preview after user typing
4139

4240
private fileChangeListener: () => void;
@@ -64,7 +62,6 @@ export class MarkdownFileTracker implements IWorkbenchContribution {
6462
this.configureMode(this.storageService.get(Preferences.THEME, StorageScope.GLOBAL));
6563

6664
this.registerListeners();
67-
this.handleWelcome();
6865
}
6966

7067
private registerListeners(): void {
@@ -126,21 +123,6 @@ export class MarkdownFileTracker implements IWorkbenchContribution {
126123
}
127124
}
128125

129-
private handleWelcome(): void {
130-
let firstStartup = !this.storageService.get(MarkdownFileTracker.hideWelcomeSettingskey);
131-
let emptyWorkbench = !this.contextService.getWorkspace() && (!this.contextService.getOptions().filesToOpen || this.contextService.getOptions().filesToOpen.length === 0) && (!this.contextService.getOptions().filesToCreate || this.contextService.getOptions().filesToCreate.length === 0);
132-
133-
if (firstStartup && emptyWorkbench) {
134-
this.storageService.store(MarkdownFileTracker.hideWelcomeSettingskey, true); // only once
135-
136-
let action = this.instantiationService.createInstance(ShowWelcomeAction, ShowWelcomeAction.ID, ShowWelcomeAction.LABEL);
137-
if (action.enabled) {
138-
action.setPreserveFocus(true);
139-
action.run().done(() => action.dispose(), errors.onUnexpectedError);
140-
}
141-
}
142-
}
143-
144126
private configureMode(theme: string): void {
145127
if (theme) {
146128
let baseTheme = themes.getBaseThemeId(theme);

src/vs/workbench/workbench.main.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ define([
7474

7575
'vs/workbench/parts/feedback/electron-browser/feedback.contribution',
7676

77+
'vs/workbench/parts/gettingStarted/electron-browser/electronGettingStarted.contribution',
78+
7779
'vs/workbench/electron-browser/main.contribution',
7880
'vs/workbench/electron-browser/main'
7981

0 commit comments

Comments
 (0)