6
6
import 'vs/css!./media/welcomeWidget' ;
7
7
import { Disposable } from 'vs/base/common/lifecycle' ;
8
8
import { ICodeEditor , IOverlayWidget , IOverlayWidgetPosition , OverlayWidgetPositionPreference } from 'vs/editor/browser/editorBrowser' ;
9
- import { $ , append , hide } from 'vs/base/browser/dom' ; import { RunOnceScheduler } from 'vs/base/common/async' ;
9
+ import { $ , append , hide } from 'vs/base/browser/dom' ;
10
10
import { MarkdownString } from 'vs/base/common/htmlContent' ;
11
11
import { MarkdownRenderer } from 'vs/editor/contrib/markdownRenderer/browser/markdownRenderer' ;
12
12
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation' ;
13
13
import { ButtonBar } from 'vs/base/browser/ui/button/button' ;
14
14
import { mnemonicButtonLabel } from 'vs/base/common/labels' ;
15
15
import { ICommandService } from 'vs/platform/commands/common/commands' ;
16
- import { defaultButtonStyles , defaultDialogStyles } from 'vs/platform/theme/browser/defaultStyles' ;
16
+ import { defaultButtonStyles } from 'vs/platform/theme/browser/defaultStyles' ;
17
17
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry' ;
18
18
import { Action , WorkbenchActionExecutedClassification , WorkbenchActionExecutedEvent } from 'vs/base/common/actions' ;
19
19
import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar' ;
@@ -25,16 +25,12 @@ import { Link } from 'vs/platform/opener/browser/link';
25
25
import { renderLabelWithIcons } from 'vs/base/browser/ui/iconLabel/iconLabels' ;
26
26
import { renderFormattedText } from 'vs/base/browser/formattedTextRenderer' ;
27
27
import { IOpenerService } from 'vs/platform/opener/common/opener' ;
28
- import { generateUuid } from 'vs/base/common/uuid' ;
29
- import { GettingStartedDetailsRenderer } from 'vs/workbench/contrib/welcomeGettingStarted/browser/gettingStartedDetailsRenderer' ;
30
- import { FileAccess } from 'vs/base/common/network' ;
31
- import { IWebviewService } from 'vs/workbench/contrib/webview/browser/webview' ;
28
+ import { registerThemingParticipant } from 'vs/platform/theme/common/themeService' ;
29
+ import { Color } from 'vs/base/common/color' ;
30
+ import { contrastBorder , editorWidgetBackground , editorWidgetForeground , widgetBorder , widgetShadow } from 'vs/platform/theme/common/colorRegistry' ;
32
31
33
32
export class WelcomeWidget extends Disposable implements IOverlayWidget {
34
33
35
- private static readonly WIDGET_TIMEOUT : number = 15000 ;
36
- private static readonly WELCOME_MEDIA_PATH = 'vs/workbench/contrib/welcomeGettingStarted/common/media/' ;
37
-
38
34
private readonly _rootDomNode : HTMLElement ;
39
35
private readonly element : HTMLElement ;
40
36
private readonly messageContainer : HTMLElement ;
@@ -45,9 +41,7 @@ export class WelcomeWidget extends Disposable implements IOverlayWidget {
45
41
private readonly instantiationService : IInstantiationService ,
46
42
private readonly commandService : ICommandService ,
47
43
private readonly telemetryService : ITelemetryService ,
48
- private readonly openerService : IOpenerService ,
49
- private readonly webviewService : IWebviewService ,
50
- private readonly detailsRenderer : GettingStartedDetailsRenderer
44
+ private readonly openerService : IOpenerService
51
45
) {
52
46
super ( ) ;
53
47
this . _rootDomNode = document . createElement ( 'div' ) ;
@@ -64,7 +58,6 @@ export class WelcomeWidget extends Disposable implements IOverlayWidget {
64
58
async executeCommand ( commandId : string , ...args : string [ ] ) {
65
59
try {
66
60
await this . commandService . executeCommand ( commandId , ...args ) ;
67
- this . _hide ( false ) ;
68
61
this . telemetryService . publicLog2 < WorkbenchActionExecutedEvent , WorkbenchActionExecutedClassification > ( 'workbenchActionExecuted' , {
69
62
id : commandId ,
70
63
from : 'welcomeWidget'
@@ -74,41 +67,38 @@ export class WelcomeWidget extends Disposable implements IOverlayWidget {
74
67
}
75
68
}
76
69
77
- public async render ( title : string , message : string , buttonText : string , buttonAction : string , media : { altText : string ; path : string } ) {
70
+ public async render ( title : string , message : string , buttonText : string , buttonAction : string ) {
78
71
if ( ! this . _editor . _getViewModel ( ) ) {
79
72
return ;
80
73
}
81
74
82
- await this . buildWidgetContent ( title , message , buttonText , buttonAction , media ) ;
75
+ await this . buildWidgetContent ( title , message , buttonText , buttonAction ) ;
83
76
this . _editor . addOverlayWidget ( this ) ;
84
- this . _revealTemporarily ( ) ;
77
+ this . _show ( ) ;
85
78
this . telemetryService . publicLog2 < WorkbenchActionExecutedEvent , WorkbenchActionExecutedClassification > ( 'workbenchActionExecuted' , {
86
79
id : 'welcomeWidgetRendered' ,
87
80
from : 'welcomeWidget'
88
81
} ) ;
89
82
}
90
83
91
- private async buildWidgetContent ( title : string , message : string , buttonText : string , buttonAction : string , media : { altText : string ; path : string } ) {
84
+ private async buildWidgetContent ( title : string , message : string , buttonText : string , buttonAction : string ) {
92
85
93
86
const actionBar = this . _register ( new ActionBar ( this . element , { } ) ) ;
94
87
95
88
const action = this . _register ( new Action ( 'dialog.close' , localize ( 'dialogClose' , "Close Dialog" ) , ThemeIcon . asClassName ( Codicon . dialogClose ) , true , async ( ) => {
96
- this . _hide ( true ) ;
89
+ this . _hide ( ) ;
97
90
} ) ) ;
98
91
actionBar . push ( action , { icon : true , label : false } ) ;
99
92
100
- if ( media ) {
101
- await this . buildSVGMediaComponent ( media . path ) ;
102
- }
103
-
104
- const renderBody = ( message : string ) : MarkdownString => {
105
- const mds = new MarkdownString ( undefined , { supportHtml : true } ) ;
93
+ const renderBody = ( message : string , icon : string ) : MarkdownString => {
94
+ const mds = new MarkdownString ( undefined , { supportThemeIcons : true , supportHtml : true } ) ;
95
+ mds . appendMarkdown ( `<a class="copilot">$(${ icon } )</a>` ) ;
106
96
mds . appendMarkdown ( message ) ;
107
97
return mds ;
108
98
} ;
109
99
110
100
const titleElement = this . messageContainer . appendChild ( $ ( '#monaco-dialog-message-detail.dialog-message-detail-title' ) ) ;
111
- const titleElementMdt = this . markdownRenderer . render ( renderBody ( title ) ) ;
101
+ const titleElementMdt = this . markdownRenderer . render ( renderBody ( title , 'zap' ) ) ;
112
102
titleElement . appendChild ( titleElementMdt . element ) ;
113
103
114
104
this . buildStepMarkdownDescription ( this . messageContainer , message . split ( '\n' ) . filter ( x => x ) . map ( text => parseLinkedText ( text ) ) ) ;
@@ -125,7 +115,6 @@ export class WelcomeWidget extends Disposable implements IOverlayWidget {
125
115
} ) ) ;
126
116
127
117
buttonBar . buttons [ 0 ] . focus ( ) ;
128
- this . applyStyles ( ) ;
129
118
}
130
119
131
120
private buildStepMarkdownDescription ( container : HTMLElement , text : LinkedText [ ] ) {
@@ -158,18 +147,6 @@ export class WelcomeWidget extends Disposable implements IOverlayWidget {
158
147
return container ;
159
148
}
160
149
161
- private async buildSVGMediaComponent ( path : string ) {
162
-
163
- const mediaContainer = this . messageContainer . appendChild ( $ ( '.dialog-image-container' ) ) ;
164
- mediaContainer . id = generateUuid ( ) ;
165
-
166
- const webview = this . _register ( this . webviewService . createWebviewElement ( { title : undefined , options : { } , contentOptions : { } , extension : undefined } ) ) ;
167
- webview . mountTo ( mediaContainer ) ;
168
-
169
- const body = await this . detailsRenderer . renderSVG ( FileAccess . asFileUri ( `${ WelcomeWidget . WELCOME_MEDIA_PATH } ${ path } ` ) ) ;
170
- webview . setHtml ( body ) ;
171
- }
172
-
173
150
getId ( ) : string {
174
151
return 'editor.contrib.welcomeWidget' ;
175
152
}
@@ -184,14 +161,8 @@ export class WelcomeWidget extends Disposable implements IOverlayWidget {
184
161
} ;
185
162
}
186
163
187
- private _hideSoon = this . _register ( new RunOnceScheduler ( ( ) => this . _hide ( false ) , WelcomeWidget . WIDGET_TIMEOUT ) ) ;
188
164
private _isVisible : boolean = false ;
189
165
190
- private _revealTemporarily ( ) : void {
191
- this . _show ( ) ;
192
- this . _hideSoon . schedule ( ) ;
193
- }
194
-
195
166
private _show ( ) : void {
196
167
if ( this . _isVisible ) {
197
168
return ;
@@ -200,32 +171,48 @@ export class WelcomeWidget extends Disposable implements IOverlayWidget {
200
171
this . _rootDomNode . style . display = 'block' ;
201
172
}
202
173
203
- private _hide ( isUserDismissed : boolean ) : void {
174
+ private _hide ( ) : void {
204
175
if ( ! this . _isVisible ) {
205
176
return ;
206
177
}
207
178
208
- this . _isVisible = false ;
179
+ this . _isVisible = true ;
209
180
this . _rootDomNode . style . display = 'none' ;
210
181
this . _editor . removeOverlayWidget ( this ) ;
211
182
this . telemetryService . publicLog2 < WorkbenchActionExecutedEvent , WorkbenchActionExecutedClassification > ( 'workbenchActionExecuted' , {
212
- id : isUserDismissed ? 'welcomeWidgetDismissed' : 'welcomeWidgetHidden ',
183
+ id : 'welcomeWidgetDismissed' ,
213
184
from : 'welcomeWidget'
214
185
} ) ;
215
186
}
187
+ }
188
+
189
+ registerThemingParticipant ( ( theme , collector ) => {
190
+ const addBackgroundColorRule = ( selector : string , color : Color | undefined ) : void => {
191
+ if ( color ) {
192
+ collector . addRule ( `.monaco-editor ${ selector } { background-color: ${ color } ; }` ) ;
193
+ }
194
+ } ;
216
195
217
- private applyStyles ( ) : void {
218
- const style = defaultDialogStyles ;
196
+ const widgetBackground = theme . getColor ( editorWidgetBackground ) ;
197
+ addBackgroundColorRule ( '.welcome-widget' , widgetBackground ) ;
219
198
220
- const fgColor = style . dialogForeground ;
221
- const bgColor = style . dialogBackground ;
222
- const shadowColor = style . dialogShadow ? `0 0px 8px ${ style . dialogShadow } ` : '' ;
223
- const border = style . dialogBorder ? `1px solid ${ style . dialogBorder } ` : '' ;
199
+ const widgetShadowColor = theme . getColor ( widgetShadow ) ;
200
+ if ( widgetShadowColor ) {
201
+ collector . addRule ( `.welcome-widget { box-shadow: 0 0 8px 2px ${ widgetShadowColor } ; }` ) ;
202
+ }
224
203
225
- this . _rootDomNode . style . boxShadow = shadowColor ;
204
+ const widgetBorderColor = theme . getColor ( widgetBorder ) ;
205
+ if ( widgetBorderColor ) {
206
+ collector . addRule ( `.welcome-widget { border-left: 1px solid ${ widgetBorderColor } ; border-right: 1px solid ${ widgetBorderColor } ; border-bottom: 1px solid ${ widgetBorderColor } ; }` ) ;
207
+ }
226
208
227
- this . _rootDomNode . style . color = fgColor ?? '' ;
228
- this . _rootDomNode . style . backgroundColor = bgColor ?? '' ;
229
- this . _rootDomNode . style . border = border ;
209
+ const hcBorder = theme . getColor ( contrastBorder ) ;
210
+ if ( hcBorder ) {
211
+ collector . addRule ( `.welcome-widget { border: 1px solid ${ hcBorder } ; }` ) ;
230
212
}
231
- }
213
+
214
+ const foreground = theme . getColor ( editorWidgetForeground ) ;
215
+ if ( foreground ) {
216
+ collector . addRule ( `.welcome-widget { color: ${ foreground } ; }` ) ;
217
+ }
218
+ } ) ;
0 commit comments