1
1
import * as path from 'vs/base/common/path' ;
2
- import { URI } from 'vs/base/common/uri' ;
3
2
import { Options } from 'vs/ipc' ;
4
3
import { localize } from 'vs/nls' ;
4
+ import { MenuId , MenuRegistry } from 'vs/platform/actions/common/actions' ;
5
+ import { CommandsRegistry } from 'vs/platform/commands/common/commands' ;
5
6
import { Extensions , IConfigurationRegistry } from 'vs/platform/configuration/common/configurationRegistry' ;
7
+ import { ContextKeyExpr , IContextKeyService } from 'vs/platform/contextkey/common/contextkey' ;
6
8
import { registerSingleton } from 'vs/platform/instantiation/common/extensions' ;
7
9
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection' ;
8
10
import { ILogService } from 'vs/platform/log/common/log' ;
@@ -11,10 +13,18 @@ import { Registry } from 'vs/platform/registry/common/platform';
11
13
import { IStorageService , StorageScope , StorageTarget } from 'vs/platform/storage/common/storage' ;
12
14
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry' ;
13
15
import { TelemetryChannelClient } from 'vs/server/common/telemetry' ;
16
+ import { getOptions } from 'vs/server/common/util' ;
14
17
import 'vs/workbench/contrib/localizations/browser/localizations.contribution' ;
15
18
import 'vs/workbench/services/localizations/browser/localizationsService' ;
16
19
import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService' ;
17
20
21
+ /**
22
+ * All client-side customization to VS Code should live in this file when
23
+ * possible.
24
+ */
25
+
26
+ const options = getOptions < Options > ( ) ;
27
+
18
28
class TelemetryService extends TelemetryChannelClient {
19
29
public constructor (
20
30
@IRemoteAgentService remoteAgentService : IRemoteAgentService ,
@@ -23,26 +33,6 @@ class TelemetryService extends TelemetryChannelClient {
23
33
}
24
34
}
25
35
26
- /**
27
- * Remove extra slashes in a URL.
28
- */
29
- export const normalize = ( url : string , keepTrailing = false ) : string => {
30
- return url . replace ( / \/ \/ + / g, '/' ) . replace ( / \/ + $ / , keepTrailing ? '/' : '' ) ;
31
- } ;
32
-
33
- /**
34
- * Get options embedded in the HTML.
35
- */
36
- export const getOptions = < T extends Options > ( ) : T => {
37
- try {
38
- return JSON . parse ( document . getElementById ( 'coder-options' ) ! . getAttribute ( 'data-settings' ) ! ) ;
39
- } catch ( error ) {
40
- return { } as T ;
41
- }
42
- } ;
43
-
44
- const options = getOptions ( ) ;
45
-
46
36
const TELEMETRY_SECTION_ID = 'telemetry' ;
47
37
Registry . as < IConfigurationRegistry > ( Extensions . Configuration ) . registerConfiguration ( {
48
38
'id' : TELEMETRY_SECTION_ID ,
@@ -173,38 +163,36 @@ export const initialize = async (services: ServiceCollection): Promise<void> =>
173
163
if ( theme ) {
174
164
localStorage . setItem ( 'colorThemeData' , theme ) ;
175
165
}
176
- } ;
177
166
178
- export interface Query {
179
- [ key : string ] : string | undefined ;
180
- }
181
-
182
- /**
183
- * Split a string up to the delimiter. If the delimiter doesn't exist the first
184
- * item will have all the text and the second item will be an empty string.
185
- */
186
- export const split = ( str : string , delimiter : string ) : [ string , string ] => {
187
- const index = str . indexOf ( delimiter ) ;
188
- return index !== - 1 ? [ str . substring ( 0 , index ) . trim ( ) , str . substring ( index + 1 ) ] : [ str , '' ] ;
189
- } ;
167
+ // Use to show or hide logout commands and menu options.
168
+ const contextKeyService = ( services . get ( IContextKeyService ) as IContextKeyService ) ;
169
+ contextKeyService . createKey ( 'code-server.authed' , options . authed ) ;
170
+
171
+ // Add a logout command.
172
+ const logoutEndpoint = path . join ( options . base , '/logout' ) + `?base=${ options . base } ` ;
173
+ const LOGOUT_COMMAND_ID = 'code-server.logout' ;
174
+ CommandsRegistry . registerCommand (
175
+ LOGOUT_COMMAND_ID ,
176
+ ( ) => {
177
+ window . location . href = logoutEndpoint ;
178
+ } ,
179
+ ) ;
180
+
181
+ // Add logout to command palette.
182
+ MenuRegistry . appendMenuItem ( MenuId . CommandPalette , {
183
+ command : {
184
+ id : LOGOUT_COMMAND_ID ,
185
+ title : localize ( 'logout' , "Log out" )
186
+ } ,
187
+ when : ContextKeyExpr . has ( 'code-server.authed' )
188
+ } ) ;
190
189
191
- /**
192
- * Return the URL modified with the specified query variables. It's pretty
193
- * stupid so it probably doesn't cover any edge cases. Undefined values will
194
- * unset existing values. Doesn't allow duplicates.
195
- */
196
- export const withQuery = ( url : string , replace : Query ) : string => {
197
- const uri = URI . parse ( url ) ;
198
- const query = { ...replace } ;
199
- uri . query . split ( '&' ) . forEach ( ( kv ) => {
200
- const [ key , value ] = split ( kv , '=' ) ;
201
- if ( ! ( key in query ) ) {
202
- query [ key ] = value ;
203
- }
190
+ // Add logout to the (web-only) home menu.
191
+ MenuRegistry . appendMenuItem ( MenuId . MenubarHomeMenu , {
192
+ command : {
193
+ id : LOGOUT_COMMAND_ID ,
194
+ title : localize ( 'logout' , "Log out" )
195
+ } ,
196
+ when : ContextKeyExpr . has ( 'code-server.authed' )
204
197
} ) ;
205
- return uri . with ( {
206
- query : Object . keys ( query )
207
- . filter ( ( k ) => typeof query [ k ] !== 'undefined' )
208
- . map ( ( k ) => `${ k } =${ query [ k ] } ` ) . join ( '&' ) ,
209
- } ) . toString ( true ) ;
210
198
} ;
0 commit comments