Skip to content

Commit 649985a

Browse files
feat: customize getting started page (#5707)
* feat: add getting-started patch This modifies the text on the Getting Started page to promote coder/coder. * feat: add --disable-getting-started-override This adds a new CLI flag to code-server called `--disable-getting-started` which will be used in Code to not use Coder's custom Getting Started text. * refactor: conditionally show coder getting started This modifies the getting started patch changes to work with the new `--disable-getting-started-override`. The flag is false by default meaning the Coder getting started is shown. By passing the flag to code-server, it will not be shown. * docs: update faq for getting started override * docs: update getting-started patch description * fixup!: update patch * fixup!: unit test * feat: add more tests * fixup!: use correct env var in tests Co-authored-by: repo-ranger[bot] <39074581+repo-ranger[bot]@users.noreply.github.com>
1 parent ca182b9 commit 649985a

File tree

5 files changed

+221
-0
lines changed

5 files changed

+221
-0
lines changed

docs/FAQ.md

+5
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
- [Does code-server have any security login validation?](#does-code-server-have-any-security-login-validation)
3333
- [Are there community projects involving code-server?](#are-there-community-projects-involving-code-server)
3434
- [How do I change the port?](#how-do-i-change-the-port)
35+
- [How do I hide the coder/coder promotion?](#how-do-i-hide-the-codercoder-promotion)
3536

3637
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
3738
<!-- prettier-ignore-end -->
@@ -418,3 +419,7 @@ There are two ways to change the port on which code-server runs:
418419

419420
1. with an environment variable e.g. `PORT=3000 code-server`
420421
2. using the flag `--bind-addr` e.g. `code-server --bind-addr localhost:3000`
422+
423+
## How do I hide the coder/coder promotion?
424+
425+
You can pass the flag `--disable-getting-started-override` to `code-server`.

patches/getting-started.diff

+178
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
Modify Help: Getting Started
2+
3+
This modifies some text on the Getting Started page and adds text about using
4+
code-server on a team.
5+
6+
It is enabled by default but can be overriden using the cli flag
7+
`--disable-getting-started-override`.
8+
9+
Index: code-server/lib/vscode/src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted.ts
10+
===================================================================
11+
--- code-server.orig/lib/vscode/src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted.ts
12+
+++ code-server/lib/vscode/src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted.ts
13+
@@ -62,7 +62,7 @@ import { GettingStartedIndexList } from
14+
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
15+
import { KeyCode } from 'vs/base/common/keyCodes';
16+
import { getTelemetryLevel } from 'vs/platform/telemetry/common/telemetryUtils';
17+
-import { WorkbenchStateContext } from 'vs/workbench/common/contextkeys';
18+
+import { IsEnabledCoderGettingStarted, WorkbenchStateContext } from 'vs/workbench/common/contextkeys';
19+
import { OpenFolderViaWorkspaceAction } from 'vs/workbench/browser/actions/workspaceActions';
20+
import { OpenRecentAction } from 'vs/workbench/browser/actions/windowActions';
21+
import { Toggle } from 'vs/base/browser/ui/toggle/toggle';
22+
@@ -753,11 +753,24 @@ export class GettingStartedPage extends
23+
onShowOnStartupChanged();
24+
}));
25+
26+
- const header = $('.header', {},
27+
+ let header = $('.header', {},
28+
$('h1.product-name.caption', {}, this.productService.nameLong),
29+
$('p.subtitle.description', {}, localize({ key: 'gettingStarted.editingEvolved', comment: ['Shown as subtitle on the Welcome page.'] }, "Editing evolved"))
30+
);
31+
32+
+ if (this.contextService.contextMatchesRules(IsEnabledCoderGettingStarted)) {
33+
+ header = $('.header', {},
34+
+ $('h1.product-name.caption', {}, this.productService.nameLong),
35+
+ $('p.subtitle.description.coder', {},
36+
+ "Using code-server on a team?",
37+
+ ),
38+
+ $('p.subtitle.description.coder-coder', {},
39+
+ "Check out: ",
40+
+ $('a', { href: "https://github.com/coder/coder" }, "coder/coder")
41+
+ ),
42+
+ );
43+
+ }
44+
+
45+
46+
const leftColumn = $('.categories-column.categories-column-left', {},);
47+
const rightColumn = $('.categories-column.categories-column-right', {},);
48+
Index: code-server/lib/vscode/src/vs/workbench/contrib/welcomeGettingStarted/browser/media/gettingStarted.css
49+
===================================================================
50+
--- code-server.orig/lib/vscode/src/vs/workbench/contrib/welcomeGettingStarted/browser/media/gettingStarted.css
51+
+++ code-server/lib/vscode/src/vs/workbench/contrib/welcomeGettingStarted/browser/media/gettingStarted.css
52+
@@ -60,6 +60,15 @@
53+
display: block;
54+
}
55+
56+
+.monaco-workbench .part.editor > .content .gettingStartedContainer .coder {
57+
+ margin-bottom: 0.2em;
58+
+}
59+
+
60+
+.monaco-workbench .part.editor>.content .gettingStartedContainer .coder-coder {
61+
+ font-size: 1em;
62+
+ margin-top: 0.2em;
63+
+}
64+
+
65+
.monaco-workbench.hc-black .part.editor>.content .gettingStartedContainer .subtitle,
66+
.monaco-workbench.hc-light .part.editor>.content .gettingStartedContainer .subtitle {
67+
font-weight: 200;
68+
Index: code-server/lib/vscode/src/vs/workbench/browser/web.api.ts
69+
===================================================================
70+
--- code-server.orig/lib/vscode/src/vs/workbench/browser/web.api.ts
71+
+++ code-server/lib/vscode/src/vs/workbench/browser/web.api.ts
72+
@@ -276,6 +276,11 @@ export interface IWorkbenchConstructionO
73+
*/
74+
readonly isEnabledFileDownloads?: boolean
75+
76+
+ /**
77+
+ * Whether to use Coder's custom Getting Started text.
78+
+ */
79+
+ readonly isEnabledCoderGettingStarted?: boolean
80+
+
81+
//#endregion
82+
83+
84+
Index: code-server/lib/vscode/src/vs/workbench/services/environment/browser/environmentService.ts
85+
===================================================================
86+
--- code-server.orig/lib/vscode/src/vs/workbench/services/environment/browser/environmentService.ts
87+
+++ code-server/lib/vscode/src/vs/workbench/services/environment/browser/environmentService.ts
88+
@@ -36,6 +36,11 @@ export interface IBrowserWorkbenchEnviro
89+
* Enable downloading files via menu actions.
90+
*/
91+
readonly isEnabledFileDownloads?: boolean;
92+
+
93+
+ /**
94+
+ * Enable Coder's custom getting started text.
95+
+ */
96+
+ readonly isEnabledCoderGettingStarted?: boolean;
97+
}
98+
99+
export class BrowserWorkbenchEnvironmentService implements IBrowserWorkbenchEnvironmentService {
100+
@@ -74,6 +79,13 @@ export class BrowserWorkbenchEnvironment
101+
return this.options.isEnabledFileDownloads;
102+
}
103+
104+
+ get isEnabledCoderGettingStarted(): boolean {
105+
+ if (typeof this.options.isEnabledCoderGettingStarted === "undefined") {
106+
+ throw new Error('isEnabledCoderGettingStarted was not provided to the browser');
107+
+ }
108+
+ return this.options.isEnabledCoderGettingStarted;
109+
+ }
110+
+
111+
@memoize
112+
get argvResource(): URI { return joinPath(this.userRoamingDataHome, 'argv.json'); }
113+
114+
Index: code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
115+
===================================================================
116+
--- code-server.orig/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
117+
+++ code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
118+
@@ -16,6 +16,7 @@ export const serverOptions: OptionDescri
119+
'auth': { type: 'string' },
120+
'disable-file-downloads': { type: 'boolean' },
121+
'locale': { type: 'string' },
122+
+ 'disable-getting-started-override': { type: 'boolean' },
123+
124+
/* ----- server setup ----- */
125+
126+
@@ -98,6 +99,7 @@ export interface ServerParsedArgs {
127+
'auth'?: string
128+
'disable-file-downloads'?: boolean;
129+
'locale'?: string
130+
+ 'disable-getting-started-override'?: boolean;
131+
132+
/* ----- server setup ----- */
133+
134+
Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
135+
===================================================================
136+
--- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts
137+
+++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts
138+
@@ -308,6 +308,7 @@ export class WebClientServer {
139+
webviewEndpoint: vscodeBase + this._staticRoute + '/out/vs/workbench/contrib/webview/browser/pre',
140+
userDataPath: this._environmentService.userDataPath,
141+
isEnabledFileDownloads: !this._environmentService.args['disable-file-downloads'],
142+
+ isEnabledCoderGettingStarted: !this._environmentService.args['disable-getting-started-override'],
143+
_wrapWebWorkerExtHostInIframe,
144+
developmentOptions: { enableSmokeTestDriver: this._environmentService.args['enable-smoke-test-driver'] ? true : undefined, logLevel: this._logService.getLevel() },
145+
settingsSyncOptions: !this._environmentService.isBuilt && this._environmentService.args['enable-sync'] ? { enabled: true } : undefined,
146+
Index: code-server/lib/vscode/src/vs/workbench/browser/contextkeys.ts
147+
===================================================================
148+
--- code-server.orig/lib/vscode/src/vs/workbench/browser/contextkeys.ts
149+
+++ code-server/lib/vscode/src/vs/workbench/browser/contextkeys.ts
150+
@@ -7,7 +7,7 @@ import { Event } from 'vs/base/common/ev
151+
import { Disposable } from 'vs/base/common/lifecycle';
152+
import { IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey';
153+
import { InputFocusedContext, IsMacContext, IsLinuxContext, IsWindowsContext, IsWebContext, IsMacNativeContext, IsDevelopmentContext, IsIOSContext, ProductQualityContext, IsMobileContext } from 'vs/platform/contextkey/common/contextkeys';
154+
-import { SplitEditorsVertically, InEditorZenModeContext, ActiveEditorCanRevertContext, ActiveEditorGroupLockedContext, ActiveEditorCanSplitInGroupContext, SideBySideEditorActiveContext, AuxiliaryBarVisibleContext, SideBarVisibleContext, PanelAlignmentContext, PanelMaximizedContext, PanelVisibleContext, ActiveEditorContext, EditorsVisibleContext, TextCompareEditorVisibleContext, TextCompareEditorActiveContext, ActiveEditorGroupEmptyContext, MultipleEditorGroupsContext, EditorTabsVisibleContext, IsCenteredLayoutContext, ActiveEditorGroupIndexContext, ActiveEditorGroupLastContext, ActiveEditorReadonlyContext, EditorAreaVisibleContext, ActiveEditorAvailableEditorIdsContext, DirtyWorkingCopiesContext, EmptyWorkspaceSupportContext, EnterMultiRootWorkspaceSupportContext, HasWebFileSystemAccess, IsFullscreenContext, OpenFolderWorkspaceSupportContext, RemoteNameContext, VirtualWorkspaceContext, WorkbenchStateContext, WorkspaceFolderCountContext, PanelPositionContext, TemporaryWorkspaceContext, IsEnabledFileDownloads } from 'vs/workbench/common/contextkeys';
155+
+import { SplitEditorsVertically, InEditorZenModeContext, ActiveEditorCanRevertContext, ActiveEditorGroupLockedContext, ActiveEditorCanSplitInGroupContext, SideBySideEditorActiveContext, AuxiliaryBarVisibleContext, SideBarVisibleContext, PanelAlignmentContext, PanelMaximizedContext, PanelVisibleContext, ActiveEditorContext, EditorsVisibleContext, TextCompareEditorVisibleContext, TextCompareEditorActiveContext, ActiveEditorGroupEmptyContext, MultipleEditorGroupsContext, EditorTabsVisibleContext, IsCenteredLayoutContext, ActiveEditorGroupIndexContext, ActiveEditorGroupLastContext, ActiveEditorReadonlyContext, EditorAreaVisibleContext, ActiveEditorAvailableEditorIdsContext, DirtyWorkingCopiesContext, EmptyWorkspaceSupportContext, EnterMultiRootWorkspaceSupportContext, HasWebFileSystemAccess, IsFullscreenContext, OpenFolderWorkspaceSupportContext, RemoteNameContext, VirtualWorkspaceContext, WorkbenchStateContext, WorkspaceFolderCountContext, PanelPositionContext, TemporaryWorkspaceContext, IsEnabledFileDownloads, IsEnabledCoderGettingStarted } from 'vs/workbench/common/contextkeys';
156+
import { TEXT_DIFF_EDITOR_ID, EditorInputCapabilities, SIDE_BY_SIDE_EDITOR_ID, DEFAULT_EDITOR_ASSOCIATION } from 'vs/workbench/common/editor';
157+
import { trackFocus, addDisposableListener, EventType } from 'vs/base/browser/dom';
158+
import { preferredSideBySideGroupDirection, GroupDirection, IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
159+
@@ -204,6 +204,7 @@ export class WorkbenchContextKeysHandler
160+
161+
// code-server
162+
IsEnabledFileDownloads.bindTo(this.contextKeyService).set(this.environmentService.isEnabledFileDownloads ?? true)
163+
+ IsEnabledCoderGettingStarted.bindTo(this.contextKeyService).set(this.environmentService.isEnabledCoderGettingStarted ?? true)
164+
165+
this.registerListeners();
166+
}
167+
Index: code-server/lib/vscode/src/vs/workbench/common/contextkeys.ts
168+
===================================================================
169+
--- code-server.orig/lib/vscode/src/vs/workbench/common/contextkeys.ts
170+
+++ code-server/lib/vscode/src/vs/workbench/common/contextkeys.ts
171+
@@ -33,6 +33,7 @@ export const IsFullscreenContext = new R
172+
export const HasWebFileSystemAccess = new RawContextKey<boolean>('hasWebFileSystemAccess', false, true); // Support for FileSystemAccess web APIs (https://wicg.github.io/file-system-access)
173+
174+
export const IsEnabledFileDownloads = new RawContextKey<boolean>('isEnabledFileDownloads', true, true);
175+
+export const IsEnabledCoderGettingStarted = new RawContextKey<boolean>('isEnabledCoderGettingStarted', true, true);
176+
177+
//#endregion
178+

patches/series

+1
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,4 @@ telemetry.diff
1919
display-language.diff
2020
cli-window-open.diff
2121
exec-argv.diff
22+
getting-started.diff

src/node/cli.ts

+9
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ export interface UserProvidedCodeArgs {
5151
"disable-update-check"?: boolean
5252
"disable-file-downloads"?: boolean
5353
"disable-workspace-trust"?: boolean
54+
"disable-getting-started-override"?: boolean
5455
}
5556

5657
/**
@@ -170,6 +171,10 @@ export const options: Options<Required<UserProvidedArgs>> = {
170171
type: "boolean",
171172
description: "Disable Workspace Trust feature. This switch only affects the current session.",
172173
},
174+
"disable-getting-started-override": {
175+
type: "boolean",
176+
description: "Disable the coder/coder override in the Help: Getting Started page.",
177+
},
173178
// --enable can be used to enable experimental features. These features
174179
// provide no guarantees.
175180
enable: { type: "string[]" },
@@ -563,6 +568,10 @@ export async function setDefaults(cliArgs: UserProvidedArgs, configArgs?: Config
563568
args["disable-file-downloads"] = true
564569
}
565570

571+
if (process.env.CS_DISABLE_GETTING_STARTED_OVERRIDE?.match(/^(1|true)$/)) {
572+
args["disable-getting-started-override"] = true
573+
}
574+
566575
const usingEnvHashedPassword = !!process.env.HASHED_PASSWORD
567576
if (process.env.HASHED_PASSWORD) {
568577
args["hashed-password"] = process.env.HASHED_PASSWORD

test/unit/node/cli.test.ts

+28
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ describe("parser", () => {
4343
delete process.env.LOG_LEVEL
4444
delete process.env.PASSWORD
4545
delete process.env.CS_DISABLE_FILE_DOWNLOADS
46+
delete process.env.CS_DISABLE_GETTING_STARTED_OVERRIDE
4647
console.log = jest.fn()
4748
})
4849

@@ -97,6 +98,8 @@ describe("parser", () => {
9798

9899
"--disable-file-downloads",
99100

101+
"--disable-getting-started-override",
102+
100103
["--host", "0.0.0.0"],
101104
"4",
102105
"--",
@@ -114,6 +117,7 @@ describe("parser", () => {
114117
value: path.resolve("path/to/cert"),
115118
},
116119
"disable-file-downloads": true,
120+
"disable-getting-started-override": true,
117121
enable: ["feature1", "feature2"],
118122
help: true,
119123
host: "0.0.0.0",
@@ -378,6 +382,30 @@ describe("parser", () => {
378382
})
379383
})
380384

385+
it("should use env var CS_DISABLE_GETTING_STARTED_OVERRIDE", async () => {
386+
process.env.CS_DISABLE_GETTING_STARTED_OVERRIDE = "1"
387+
const args = parse([])
388+
expect(args).toEqual({})
389+
390+
const defaultArgs = await setDefaults(args)
391+
expect(defaultArgs).toEqual({
392+
...defaults,
393+
"disable-getting-started-override": true,
394+
})
395+
})
396+
397+
it("should use env var CS_DISABLE_GETTING_STARTED_OVERRIDE set to true", async () => {
398+
process.env.CS_DISABLE_GETTING_STARTED_OVERRIDE = "true"
399+
const args = parse([])
400+
expect(args).toEqual({})
401+
402+
const defaultArgs = await setDefaults(args)
403+
expect(defaultArgs).toEqual({
404+
...defaults,
405+
"disable-getting-started-override": true,
406+
})
407+
})
408+
381409
it("should error if password passed in", () => {
382410
expect(() => parse(["--password", "supersecret123"])).toThrowError(
383411
"--password can only be set in the config file or passed in via $PASSWORD",

0 commit comments

Comments
 (0)