Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
vscode
提交
63efefb8
V
vscode
项目概览
xxadev
/
vscode
与 Fork 源项目一致
从无法访问的项目Fork
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
V
vscode
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
63efefb8
编写于
11月 24, 2020
作者:
S
Sandeep Somavarapu
提交者:
GitHub
11月 24, 2020
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #111182 from microsoft/sandy081/notifications/dropdown
Implement split action with dropdown in notifications
上级
875ad7bd
1ff7e577
变更
9
隐藏空白更改
内联
并排
Showing
9 changed file
with
233 addition
and
82 deletion
+233
-82
src/vs/base/browser/ui/button/button.css
src/vs/base/browser/ui/button/button.css
+13
-2
src/vs/base/browser/ui/button/button.ts
src/vs/base/browser/ui/button/button.ts
+124
-36
src/vs/base/browser/ui/dialog/dialog.ts
src/vs/base/browser/ui/dialog/dialog.ts
+10
-9
src/vs/base/common/actions.ts
src/vs/base/common/actions.ts
+11
-0
src/vs/platform/notification/common/notification.ts
src/vs/platform/notification/common/notification.ts
+25
-7
src/vs/workbench/browser/parts/notifications/media/notificationsList.css
...h/browser/parts/notifications/media/notificationsList.css
+9
-4
src/vs/workbench/browser/parts/notifications/notificationsViewer.ts
...kbench/browser/parts/notifications/notificationsViewer.ts
+28
-15
src/vs/workbench/common/notifications.ts
src/vs/workbench/common/notifications.ts
+7
-1
src/vs/workbench/contrib/extensions/browser/extensionRecommendationNotificationService.ts
...ons/browser/extensionRecommendationNotificationService.ts
+6
-8
未找到文件。
src/vs/base/browser/ui/button/button.css
浏览文件 @
63efefb8
...
...
@@ -10,11 +10,14 @@
padding
:
4px
;
text-align
:
center
;
cursor
:
pointer
;
outline-offset
:
2px
!important
;
justify-content
:
center
;
align-items
:
center
;
}
.monaco-button
{
outline-offset
:
2px
!important
;
}
.monaco-text-button
:hover
{
text-decoration
:
none
!important
;
}
...
...
@@ -24,7 +27,15 @@
cursor
:
default
;
}
.monaco-button
>
.codicon
{
.monaco-
text-
button
>
.codicon
{
margin
:
0
0.2em
;
color
:
inherit
!important
;
}
.monaco-button-dropdown
{
display
:
flex
;
}
.monaco-button-dropdown
>
.monaco-dropdown-button
{
margin-left
:
1px
;
}
src/vs/base/browser/ui/button/button.ts
浏览文件 @
63efefb8
...
...
@@ -9,10 +9,12 @@ import { KeyCode } from 'vs/base/common/keyCodes';
import
{
Color
}
from
'
vs/base/common/color
'
;
import
{
mixin
}
from
'
vs/base/common/objects
'
;
import
{
Event
as
BaseEvent
,
Emitter
}
from
'
vs/base/common/event
'
;
import
{
Disposable
}
from
'
vs/base/common/lifecycle
'
;
import
{
Disposable
,
IDisposable
}
from
'
vs/base/common/lifecycle
'
;
import
{
Gesture
,
EventType
as
TouchEventType
}
from
'
vs/base/browser/touch
'
;
import
{
renderCodicons
}
from
'
vs/base/browser/codicons
'
;
import
{
addDisposableListener
,
IFocusTracker
,
EventType
,
EventHelper
,
trackFocus
,
reset
,
removeTabIndexAndUpdateFocus
}
from
'
vs/base/browser/dom
'
;
import
{
IContextMenuProvider
}
from
'
vs/base/browser/contextmenu
'
;
import
{
IAction
}
from
'
vs/base/common/actions
'
;
export
interface
IButtonOptions
extends
IButtonStyles
{
readonly
title
?:
boolean
|
string
;
...
...
@@ -36,7 +38,18 @@ const defaultOptions: IButtonStyles = {
buttonForeground
:
Color
.
white
};
export
class
Button
extends
Disposable
{
export
interface
IButton
extends
IDisposable
{
readonly
element
:
HTMLElement
;
readonly
onDidClick
:
BaseEvent
<
Event
>
;
label
:
string
;
icon
:
string
;
enabled
:
boolean
;
style
(
styles
:
IButtonStyles
):
void
;
focus
():
void
;
hasFocus
():
boolean
;
}
export
class
Button
extends
Disposable
implements
IButton
{
private
_element
:
HTMLElement
;
private
options
:
IButtonOptions
;
...
...
@@ -189,7 +202,7 @@ export class Button extends Disposable {
}
set
icon
(
iconClassName
:
string
)
{
this
.
_element
.
classList
.
add
(
iconClassName
);
this
.
_element
.
classList
.
add
(
...
iconClassName
.
split
(
'
'
)
);
}
set
enabled
(
value
:
boolean
)
{
...
...
@@ -217,47 +230,122 @@ export class Button extends Disposable {
}
}
export
class
ButtonGroup
extends
Disposable
{
private
_buttons
:
Button
[]
=
[];
export
interface
IButtonWithDropdownOptions
extends
IButtonOptions
{
readonly
contextMenuProvider
:
IContextMenuProvider
;
readonly
actions
:
IAction
[];
}
export
class
ButtonWithDropdown
extends
Disposable
implements
IButton
{
private
readonly
button
:
Button
;
private
readonly
dropdownButton
:
Button
;
readonly
element
:
HTMLElement
;
readonly
onDidClick
:
BaseEvent
<
Event
>
;
constructor
(
container
:
HTMLElement
,
count
:
number
,
options
?:
IButto
nOptions
)
{
constructor
(
container
:
HTMLElement
,
options
:
IButtonWithDropdow
nOptions
)
{
super
();
this
.
create
(
container
,
count
,
options
);
this
.
element
=
document
.
createElement
(
'
div
'
);
this
.
element
.
classList
.
add
(
'
monaco-button-dropdown
'
);
container
.
appendChild
(
this
.
element
);
this
.
button
=
this
.
_register
(
new
Button
(
this
.
element
,
options
));
this
.
onDidClick
=
this
.
button
.
onDidClick
;
this
.
dropdownButton
=
this
.
_register
(
new
Button
(
this
.
element
,
{
...
options
,
title
:
false
,
supportCodicons
:
true
}));
this
.
dropdownButton
.
element
.
classList
.
add
(
'
monaco-dropdown-button
'
);
this
.
dropdownButton
.
icon
=
'
codicon codicon-chevron-down
'
;
this
.
_register
(
this
.
dropdownButton
.
onDidClick
(()
=>
{
options
.
contextMenuProvider
.
showContextMenu
({
getAnchor
:
()
=>
this
.
dropdownButton
.
element
,
getActions
:
()
=>
options
.
actions
,
onHide
:
()
=>
this
.
dropdownButton
.
element
.
setAttribute
(
'
aria-expanded
'
,
'
false
'
)
});
this
.
dropdownButton
.
element
.
setAttribute
(
'
aria-expanded
'
,
'
true
'
);
}));
}
set
label
(
value
:
string
)
{
this
.
button
.
label
=
value
;
}
set
icon
(
iconClassName
:
string
)
{
this
.
button
.
icon
=
iconClassName
;
}
set
enabled
(
enabled
:
boolean
)
{
this
.
button
.
enabled
=
enabled
;
this
.
dropdownButton
.
enabled
=
enabled
;
}
get
enabled
():
boolean
{
return
this
.
button
.
enabled
;
}
style
(
styles
:
IButtonStyles
):
void
{
this
.
button
.
style
(
styles
);
this
.
dropdownButton
.
style
(
styles
);
}
focus
():
void
{
this
.
button
.
focus
();
}
hasFocus
():
boolean
{
return
this
.
button
.
hasFocus
()
||
this
.
dropdownButton
.
hasFocus
();
}
}
export
class
ButtonBar
extends
Disposable
{
private
_buttons
:
IButton
[]
=
[];
constructor
(
private
readonly
container
:
HTMLElement
)
{
super
();
}
get
buttons
():
Button
[]
{
get
buttons
():
I
Button
[]
{
return
this
.
_buttons
;
}
private
create
(
container
:
HTMLElement
,
count
:
number
,
options
?:
IButtonOptions
):
void
{
for
(
let
index
=
0
;
index
<
count
;
index
++
)
{
const
button
=
this
.
_register
(
new
Button
(
container
,
options
));
this
.
_buttons
.
push
(
button
);
// Implement keyboard access in buttons if there are multiple
if
(
count
>
1
)
{
this
.
_register
(
addDisposableListener
(
button
.
element
,
EventType
.
KEY_DOWN
,
e
=>
{
const
event
=
new
StandardKeyboardEvent
(
e
);
let
eventHandled
=
true
;
// Next / Previous Button
let
buttonIndexToFocus
:
number
|
undefined
;
if
(
event
.
equals
(
KeyCode
.
LeftArrow
))
{
buttonIndexToFocus
=
index
>
0
?
index
-
1
:
this
.
_buttons
.
length
-
1
;
}
else
if
(
event
.
equals
(
KeyCode
.
RightArrow
))
{
buttonIndexToFocus
=
index
===
this
.
_buttons
.
length
-
1
?
0
:
index
+
1
;
}
else
{
eventHandled
=
false
;
}
if
(
eventHandled
&&
typeof
buttonIndexToFocus
===
'
number
'
)
{
this
.
_buttons
[
buttonIndexToFocus
].
focus
();
EventHelper
.
stop
(
e
,
true
);
}
}));
addButton
(
options
?:
IButtonOptions
):
IButton
{
const
button
=
this
.
_register
(
new
Button
(
this
.
container
,
options
));
this
.
pushButton
(
button
);
return
button
;
}
addButtonWithDropdown
(
options
:
IButtonWithDropdownOptions
):
IButton
{
const
button
=
this
.
_register
(
new
ButtonWithDropdown
(
this
.
container
,
options
));
this
.
pushButton
(
button
);
return
button
;
}
private
pushButton
(
button
:
IButton
):
void
{
this
.
_buttons
.
push
(
button
);
const
index
=
this
.
_buttons
.
length
-
1
;
this
.
_register
(
addDisposableListener
(
button
.
element
,
EventType
.
KEY_DOWN
,
e
=>
{
const
event
=
new
StandardKeyboardEvent
(
e
);
let
eventHandled
=
true
;
// Next / Previous Button
let
buttonIndexToFocus
:
number
|
undefined
;
if
(
event
.
equals
(
KeyCode
.
LeftArrow
))
{
buttonIndexToFocus
=
index
>
0
?
index
-
1
:
this
.
_buttons
.
length
-
1
;
}
else
if
(
event
.
equals
(
KeyCode
.
RightArrow
))
{
buttonIndexToFocus
=
index
===
this
.
_buttons
.
length
-
1
?
0
:
index
+
1
;
}
else
{
eventHandled
=
false
;
}
}
if
(
eventHandled
&&
typeof
buttonIndexToFocus
===
'
number
'
)
{
this
.
_buttons
[
buttonIndexToFocus
].
focus
();
EventHelper
.
stop
(
e
,
true
);
}
}));
}
}
src/vs/base/browser/ui/dialog/dialog.ts
浏览文件 @
63efefb8
...
...
@@ -11,7 +11,7 @@ import { domEvent } from 'vs/base/browser/event';
import
{
StandardKeyboardEvent
}
from
'
vs/base/browser/keyboardEvent
'
;
import
{
KeyCode
,
KeyMod
}
from
'
vs/base/common/keyCodes
'
;
import
{
Color
}
from
'
vs/base/common/color
'
;
import
{
Button
Group
,
IButtonStyles
}
from
'
vs/base/browser/ui/button/button
'
;
import
{
Button
Bar
,
IButtonStyles
}
from
'
vs/base/browser/ui/button/button
'
;
import
{
ActionBar
}
from
'
vs/base/browser/ui/actionbar/actionbar
'
;
import
{
Action
}
from
'
vs/base/common/actions
'
;
import
{
mnemonicButtonLabel
}
from
'
vs/base/common/labels
'
;
...
...
@@ -74,7 +74,7 @@ export class Dialog extends Disposable {
private
readonly
iconElement
:
HTMLElement
;
private
readonly
checkbox
:
SimpleCheckbox
|
undefined
;
private
readonly
toolbarContainer
:
HTMLElement
;
private
button
Group
:
ButtonGroup
|
undefined
;
private
button
Bar
:
ButtonBar
|
undefined
;
private
styles
:
IDialogStyles
|
undefined
;
private
focusToReturn
:
HTMLElement
|
undefined
;
private
readonly
inputs
:
InputBox
[];
...
...
@@ -173,11 +173,12 @@ export class Dialog extends Disposable {
return
new
Promise
<
IDialogResult
>
((
resolve
)
=>
{
clearNode
(
this
.
buttonsContainer
);
const
button
Group
=
this
.
buttonGroup
=
this
.
_register
(
new
ButtonGroup
(
this
.
buttonsContainer
,
this
.
buttons
.
length
,
{
title
:
true
}
));
const
button
Bar
=
this
.
buttonBar
=
this
.
_register
(
new
ButtonBar
(
this
.
buttonsContainer
));
const
buttonMap
=
this
.
rearrangeButtons
(
this
.
buttons
,
this
.
options
.
cancelId
);
// Handle button clicks
buttonGroup
.
buttons
.
forEach
((
button
,
index
)
=>
{
buttonMap
.
forEach
((
entry
,
index
)
=>
{
const
button
=
this
.
_register
(
buttonBar
.
addButton
({
title
:
true
}));
button
.
label
=
mnemonicButtonLabel
(
buttonMap
[
index
].
label
,
true
);
this
.
_register
(
button
.
onDidClick
(
e
=>
{
...
...
@@ -237,8 +238,8 @@ export class Dialog extends Disposable {
}
}
if
(
this
.
button
Group
)
{
for
(
const
button
of
this
.
button
Group
.
buttons
)
{
if
(
this
.
button
Bar
)
{
for
(
const
button
of
this
.
button
Bar
.
buttons
)
{
focusableElements
.
push
(
button
);
if
(
button
.
hasFocus
())
{
focusedIndex
=
focusableElements
.
length
-
1
;
...
...
@@ -349,7 +350,7 @@ export class Dialog extends Disposable {
}
else
{
buttonMap
.
forEach
((
value
,
index
)
=>
{
if
(
value
.
index
===
0
)
{
button
Group
.
buttons
[
index
].
focus
();
button
Bar
.
buttons
[
index
].
focus
();
}
});
}
...
...
@@ -371,8 +372,8 @@ export class Dialog extends Disposable {
this
.
element
.
style
.
backgroundColor
=
bgColor
?.
toString
()
??
''
;
this
.
element
.
style
.
border
=
border
;
if
(
this
.
button
Group
)
{
this
.
button
Group
.
buttons
.
forEach
(
button
=>
button
.
style
(
style
));
if
(
this
.
button
Bar
)
{
this
.
button
Bar
.
buttons
.
forEach
(
button
=>
button
.
style
(
style
));
}
if
(
this
.
checkbox
)
{
...
...
src/vs/base/common/actions.ts
浏览文件 @
63efefb8
...
...
@@ -235,6 +235,17 @@ export class Separator extends Action {
}
}
export
class
ActionWithMenuAction
extends
Action
{
get
actions
():
IAction
[]
{
return
this
.
_actions
;
}
constructor
(
id
:
string
,
private
_actions
:
IAction
[],
label
?:
string
,
cssClass
?:
string
,
enabled
?:
boolean
,
actionCallback
?:
(
event
?:
any
)
=>
Promise
<
any
>
)
{
super
(
id
,
label
,
cssClass
,
enabled
,
actionCallback
);
}
}
export
class
SubmenuAction
extends
Action
{
get
actions
():
IAction
[]
{
...
...
src/vs/platform/notification/common/notification.ts
浏览文件 @
63efefb8
...
...
@@ -114,6 +114,8 @@ export interface INotificationActions {
/**
* Primary actions show up as buttons as part of the message and will close
* the notification once clicked.
*
* Pass `ActionWithMenuAction` for an action that has additional menu actions.
*/
readonly
primary
?:
ReadonlyArray
<
IAction
>
;
...
...
@@ -209,29 +211,45 @@ export interface INotificationHandle {
close
():
void
;
}
export
interface
I
PromptChoice
{
interface
IBase
PromptChoice
{
/**
* Label to show for the choice to the user.
*/
readonly
label
:
string
;
/**
* Whether to keep the notification open after the choice was selected
* by the user. By default, will close the notification upon click.
*/
readonly
keepOpen
?:
boolean
;
/**
* Triggered when the user selects the choice.
*/
run
:
()
=>
void
;
}
export
interface
IPromptChoice
extends
IBasePromptChoice
{
/**
* Primary choices show up as buttons in the notification below the message.
* Secondary choices show up under the gear icon in the header of the notification.
*/
readonly
isSecondary
?:
boolean
;
}
export
interface
IPromptChoiceWithMenu
extends
IPromptChoice
{
/**
* Whether to keep the notification open after the choice was selected
* by the user. By default, will close the notification upon click.
* Additional choices those will be shown in the dropdown menu for this choice.
*/
readonly
keepOpen
?:
boolean
;
readonly
menu
:
IBasePromptChoice
[]
;
/**
*
Triggered when the user selects the choice.
*
Menu is not supported on secondary choices
*/
r
un
:
()
=>
voi
d
;
r
eadonly
isSecondary
:
false
|
undefine
d
;
}
export
interface
IPromptOptions
extends
INotificationProperties
{
...
...
@@ -327,7 +345,7 @@ export interface INotificationService {
*
* @returns a handle on the notification to e.g. hide it or update message, buttons, etc.
*/
prompt
(
severity
:
Severity
,
message
:
string
,
choices
:
IPromptChoice
[],
options
?:
IPromptOptions
):
INotificationHandle
;
prompt
(
severity
:
Severity
,
message
:
string
,
choices
:
(
IPromptChoice
|
IPromptChoiceWithMenu
)
[],
options
?:
IPromptOptions
):
INotificationHandle
;
/**
* Shows a status message in the status area with the provided text.
...
...
src/vs/workbench/browser/parts/notifications/media/notificationsList.css
浏览文件 @
63efefb8
...
...
@@ -105,18 +105,23 @@
overflow
:
hidden
;
}
.monaco-workbench
.notifications-list-container
.notification-list-item
.notification-list-item-buttons-container
.monaco-button
{
.monaco-workbench
.notifications-list-container
.notification-list-item
.notification-list-item-buttons-container
>
.monaco-button-dropdown
,
.monaco-workbench
.notifications-list-container
.notification-list-item
.notification-list-item-buttons-container
>
.monaco-button
{
margin
:
4px
5px
;
/* allows button focus outline to be visible */
}
.monaco-workbench
.notifications-list-container
.notification-list-item
.notification-list-item-buttons-container
.monaco-text-button
{
width
:
fit-content
;
width
:
-moz-fit-content
;
padding
:
5px
10px
;
margin
:
4px
5px
;
/* allows button focus outline to be visible
*/
display
:
inline-block
;
/* to enable ellipsis in text overflow
*/
font-size
:
12px
;
overflow
:
hidden
;
text-overflow
:
ellipsis
;
}
.monaco-workbench
.notifications-list-container
.notification-list-item
.notification-list-item-buttons-container
.monaco-
text
-button
{
display
:
inline-block
;
/* to enable ellipsis in text overflow */
.monaco-workbench
.notifications-list-container
.notification-list-item
.notification-list-item-buttons-container
.monaco-
dropdown
-button
{
padding
:
5px
}
/** Notification: Progress */
...
...
src/vs/workbench/browser/parts/notifications/notificationsViewer.ts
浏览文件 @
63efefb8
...
...
@@ -8,11 +8,11 @@ import { clearNode, addDisposableListener, EventType, EventHelper, $ } from 'vs/
import
{
IOpenerService
}
from
'
vs/platform/opener/common/opener
'
;
import
{
URI
}
from
'
vs/base/common/uri
'
;
import
{
localize
}
from
'
vs/nls
'
;
import
{
Button
Group
}
from
'
vs/base/browser/ui/button/button
'
;
import
{
Button
Bar
}
from
'
vs/base/browser/ui/button/button
'
;
import
{
attachButtonStyler
,
attachProgressBarStyler
}
from
'
vs/platform/theme/common/styler
'
;
import
{
IThemeService
}
from
'
vs/platform/theme/common/themeService
'
;
import
{
ActionBar
}
from
'
vs/base/browser/ui/actionbar/actionbar
'
;
import
{
IAction
,
IActionRunner
}
from
'
vs/base/common/actions
'
;
import
{
ActionRunner
,
ActionWithMenuAction
,
IAction
,
IActionRunner
}
from
'
vs/base/common/actions
'
;
import
{
IInstantiationService
}
from
'
vs/platform/instantiation/common/instantiation
'
;
import
{
dispose
,
DisposableStore
,
Disposable
}
from
'
vs/base/common/lifecycle
'
;
import
{
IContextMenuService
}
from
'
vs/platform/contextview/browser/contextView
'
;
...
...
@@ -285,7 +285,8 @@ export class NotificationTemplateRenderer extends Disposable {
@
IOpenerService
private
readonly
openerService
:
IOpenerService
,
@
IInstantiationService
private
readonly
instantiationService
:
IInstantiationService
,
@
IThemeService
private
readonly
themeService
:
IThemeService
,
@
IKeybindingService
private
readonly
keybindingService
:
IKeybindingService
@
IKeybindingService
private
readonly
keybindingService
:
IKeybindingService
,
@
IContextMenuService
private
readonly
contextMenuService
:
IContextMenuService
,
)
{
super
();
...
...
@@ -441,27 +442,39 @@ export class NotificationTemplateRenderer extends Disposable {
const
primaryActions
=
notification
.
actions
?
notification
.
actions
.
primary
:
undefined
;
if
(
notification
.
expanded
&&
isNonEmptyArray
(
primaryActions
))
{
const
buttonGroup
=
new
ButtonGroup
(
this
.
template
.
buttonsContainer
,
primaryActions
.
length
,
{
title
:
true
/* assign titles to buttons in case they overflow */
});
buttonGroup
.
buttons
.
forEach
((
button
,
index
)
=>
{
const
action
=
primaryActions
[
index
];
button
.
label
=
action
.
label
;
this
.
inputDisposables
.
add
(
button
.
onDidClick
(
e
=>
{
EventHelper
.
stop
(
e
,
true
);
const
that
=
this
;
const
actionRunner
:
IActionRunner
=
new
class
extends
ActionRunner
{
protected
async
runAction
(
action
:
IAction
):
Promise
<
void
>
{
// Run action
th
is
.
actionRunner
.
run
(
action
,
notification
);
th
at
.
actionRunner
.
run
(
action
,
notification
);
// Hide notification (unless explicitly prevented)
if
(
!
(
action
instanceof
ChoiceAction
)
||
!
action
.
keepOpen
)
{
notification
.
close
();
}
}
}();
const
buttonToolbar
=
this
.
inputDisposables
.
add
(
new
ButtonBar
(
this
.
template
.
buttonsContainer
));
for
(
const
action
of
primaryActions
)
{
const
buttonOptions
=
{
title
:
true
,
/* assign titles to buttons in case they overflow */
};
const
dropdownActions
=
action
instanceof
ChoiceAction
?
action
.
menu
:
action
instanceof
ActionWithMenuAction
?
action
.
actions
:
undefined
;
const
button
=
this
.
inputDisposables
.
add
(
dropdownActions
?
buttonToolbar
.
addButtonWithDropdown
({
...
buttonOptions
,
contextMenuProvider
:
this
.
contextMenuService
,
actions
:
dropdownActions
,
})
:
buttonToolbar
.
addButton
(
buttonOptions
));
button
.
label
=
action
.
label
;
this
.
inputDisposables
.
add
(
button
.
onDidClick
(
e
=>
{
EventHelper
.
stop
(
e
,
true
);
actionRunner
.
run
(
action
);
}));
this
.
inputDisposables
.
add
(
attachButtonStyler
(
button
,
this
.
themeService
));
});
this
.
inputDisposables
.
add
(
buttonGroup
);
}
}
}
...
...
src/vs/workbench/common/notifications.ts
浏览文件 @
63efefb8
...
...
@@ -3,7 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import
{
INotification
,
INotificationHandle
,
INotificationActions
,
INotificationProgress
,
NoOpNotification
,
Severity
,
NotificationMessage
,
IPromptChoice
,
IStatusMessageOptions
,
NotificationsFilter
,
INotificationProgressProperties
}
from
'
vs/platform/notification/common/notification
'
;
import
{
INotification
,
INotificationHandle
,
INotificationActions
,
INotificationProgress
,
NoOpNotification
,
Severity
,
NotificationMessage
,
IPromptChoice
,
IStatusMessageOptions
,
NotificationsFilter
,
INotificationProgressProperties
,
IPromptChoiceWithMenu
}
from
'
vs/platform/notification/common/notification
'
;
import
{
toErrorMessage
}
from
'
vs/base/common/errorMessage
'
;
import
{
Event
,
Emitter
}
from
'
vs/base/common/event
'
;
import
{
Disposable
,
IDisposable
,
toDisposable
}
from
'
vs/base/common/lifecycle
'
;
...
...
@@ -695,6 +695,7 @@ export class ChoiceAction extends Action {
readonly
onDidRun
=
this
.
_onDidRun
.
event
;
private
readonly
_keepOpen
:
boolean
;
private
readonly
_menu
:
ChoiceAction
[]
|
undefined
;
constructor
(
id
:
string
,
choice
:
IPromptChoice
)
{
super
(
id
,
choice
.
label
,
undefined
,
true
,
async
()
=>
{
...
...
@@ -707,6 +708,11 @@ export class ChoiceAction extends Action {
});
this
.
_keepOpen
=
!!
choice
.
keepOpen
;
this
.
_menu
=
!
choice
.
isSecondary
&&
(
<
IPromptChoiceWithMenu
>
choice
).
menu
?
(
<
IPromptChoiceWithMenu
>
choice
).
menu
.
map
((
c
,
index
)
=>
new
ChoiceAction
(
`
${
id
}
.
${
index
}
`
,
c
))
:
undefined
;
}
get
menu
():
ChoiceAction
[]
|
undefined
{
return
this
.
_menu
;
}
get
keepOpen
():
boolean
{
...
...
src/vs/workbench/contrib/extensions/browser/extensionRecommendationNotificationService.ts
浏览文件 @
63efefb8
...
...
@@ -15,7 +15,7 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur
import
{
areSameExtensions
}
from
'
vs/platform/extensionManagement/common/extensionManagementUtil
'
;
import
{
IExtensionRecommendationNotificationService
,
RecommendationsNotificationResult
,
RecommendationSource
}
from
'
vs/platform/extensionRecommendations/common/extensionRecommendations
'
;
import
{
IInstantiationService
,
optional
}
from
'
vs/platform/instantiation/common/instantiation
'
;
import
{
INotificationHandle
,
INotificationService
,
IPromptChoice
,
Severity
}
from
'
vs/platform/notification/common/notification
'
;
import
{
INotificationHandle
,
INotificationService
,
IPromptChoice
,
IPromptChoiceWithMenu
,
Severity
}
from
'
vs/platform/notification/common/notification
'
;
import
{
IStorageService
,
StorageScope
,
StorageTarget
}
from
'
vs/platform/storage/common/storage
'
;
import
{
ITelemetryService
}
from
'
vs/platform/telemetry/common/telemetry
'
;
import
{
IUserDataAutoSyncEnablementService
,
IUserDataSyncResourceEnablementService
,
SyncResource
}
from
'
vs/platform/userDataSync/common/userDataSync
'
;
...
...
@@ -241,7 +241,7 @@ export class ExtensionRecommendationNotificationService implements IExtensionRec
{
onDidInstallRecommendedExtensions
,
onDidShowRecommendedExtensions
,
onDidCancelRecommendedExtensions
,
onDidNeverShowRecommendedExtensionsAgain
}:
RecommendationsNotificationActions
):
CancelablePromise
<
RecommendationsNotificationResult
>
{
return
createCancelablePromise
<
RecommendationsNotificationResult
>
(
async
token
=>
{
let
accepted
=
false
;
const
choices
:
IPromptChoice
[]
=
[];
const
choices
:
(
IPromptChoice
|
IPromptChoiceWithMenu
)
[]
=
[];
const
installExtensions
=
async
(
isMachineScoped
?:
boolean
)
=>
{
this
.
runAction
(
this
.
instantiationService
.
createInstance
(
SearchExtensionsAction
,
searchValue
));
onDidInstallRecommendedExtensions
(
extensions
);
...
...
@@ -252,14 +252,12 @@ export class ExtensionRecommendationNotificationService implements IExtensionRec
};
choices
.
push
({
label
:
localize
(
'
install
'
,
"
Install
"
),
run
:
()
=>
installExtensions
()
});
if
(
this
.
userDataAutoSyncEnablementService
.
isEnabled
()
&&
this
.
userDataSyncResourceEnablementService
.
isResourceEnabled
(
SyncResource
.
Extensions
))
{
choices
.
push
({
run
:
()
=>
installExtensions
(),
menu
:
this
.
userDataAutoSyncEnablementService
.
isEnabled
()
&&
this
.
userDataSyncResourceEnablementService
.
isResourceEnabled
(
SyncResource
.
Extensions
)
?
[{
label
:
localize
(
'
install and do no sync
'
,
"
Install (Do not sync)
"
),
run
:
()
=>
installExtensions
(
true
)
}
);
}
}
]
:
undefined
,
}
);
choices
.
push
(...[{
label
:
localize
(
'
show recommendations
'
,
"
Show Recommendations
"
),
run
:
async
()
=>
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录