Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
vscode
提交
2f8ddbe3
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,发现更多精彩内容 >>
提交
2f8ddbe3
编写于
2月 27, 2020
作者:
B
Benjamin Pasero
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
notifications - revised progress indication for hidden notifications (fix #91469)
上级
1b352f2f
变更
8
隐藏空白更改
内联
并排
Showing
8 changed file
with
135 addition
and
43 deletion
+135
-43
src/vs/platform/notification/common/notification.ts
src/vs/platform/notification/common/notification.ts
+7
-0
src/vs/workbench/browser/parts/notifications/notificationsActions.ts
...bench/browser/parts/notifications/notificationsActions.ts
+5
-15
src/vs/workbench/browser/parts/notifications/notificationsCenter.ts
...kbench/browser/parts/notifications/notificationsCenter.ts
+14
-6
src/vs/workbench/browser/parts/notifications/notificationsCommands.ts
...ench/browser/parts/notifications/notificationsCommands.ts
+2
-0
src/vs/workbench/browser/parts/notifications/notificationsToasts.ts
...kbench/browser/parts/notifications/notificationsToasts.ts
+22
-17
src/vs/workbench/common/notifications.ts
src/vs/workbench/common/notifications.ts
+23
-0
src/vs/workbench/services/progress/browser/progressService.ts
...vs/workbench/services/progress/browser/progressService.ts
+51
-5
src/vs/workbench/test/common/notifications.test.ts
src/vs/workbench/test/common/notifications.test.ts
+11
-0
未找到文件。
src/vs/platform/notification/common/notification.ts
浏览文件 @
2f8ddbe3
...
...
@@ -173,6 +173,13 @@ export interface INotificationHandle {
*/
readonly
onDidClose
:
Event
<
void
>
;
/**
* Will be fired whenever the visibility of the notification changes.
* A notification can either be visible as toast or inside the notification
* center if it is visible.
*/
readonly
onDidChangeVisibility
:
Event
<
boolean
>
;
/**
* Allows to indicate progress on the notification even after the
* notification is already visible.
...
...
src/vs/workbench/browser/parts/notifications/notificationsActions.ts
浏览文件 @
2f8ddbe3
...
...
@@ -26,10 +26,8 @@ export class ClearNotificationAction extends Action {
super
(
id
,
label
,
'
codicon-close
'
);
}
run
(
notification
:
INotificationViewItem
):
Promise
<
any
>
{
async
run
(
notification
:
INotificationViewItem
):
Promise
<
any
>
{
this
.
commandService
.
executeCommand
(
CLEAR_NOTIFICATION
,
notification
);
return
Promise
.
resolve
();
}
}
...
...
@@ -46,10 +44,8 @@ export class ClearAllNotificationsAction extends Action {
super
(
id
,
label
,
'
codicon-clear-all
'
);
}
run
(
notification
:
INotificationViewItem
):
Promise
<
any
>
{
async
run
(
notification
:
INotificationViewItem
):
Promise
<
any
>
{
this
.
commandService
.
executeCommand
(
CLEAR_ALL_NOTIFICATIONS
);
return
Promise
.
resolve
();
}
}
...
...
@@ -66,10 +62,8 @@ export class HideNotificationsCenterAction extends Action {
super
(
id
,
label
,
'
codicon-chevron-down
'
);
}
run
(
notification
:
INotificationViewItem
):
Promise
<
any
>
{
async
run
(
notification
:
INotificationViewItem
):
Promise
<
any
>
{
this
.
commandService
.
executeCommand
(
HIDE_NOTIFICATIONS_CENTER
);
return
Promise
.
resolve
();
}
}
...
...
@@ -86,10 +80,8 @@ export class ExpandNotificationAction extends Action {
super
(
id
,
label
,
'
codicon-chevron-up
'
);
}
run
(
notification
:
INotificationViewItem
):
Promise
<
any
>
{
async
run
(
notification
:
INotificationViewItem
):
Promise
<
any
>
{
this
.
commandService
.
executeCommand
(
EXPAND_NOTIFICATION
,
notification
);
return
Promise
.
resolve
();
}
}
...
...
@@ -106,10 +98,8 @@ export class CollapseNotificationAction extends Action {
super
(
id
,
label
,
'
codicon-chevron-down
'
);
}
run
(
notification
:
INotificationViewItem
):
Promise
<
any
>
{
async
run
(
notification
:
INotificationViewItem
):
Promise
<
any
>
{
this
.
commandService
.
executeCommand
(
COLLAPSE_NOTIFICATION
,
notification
);
return
Promise
.
resolve
();
}
}
...
...
src/vs/workbench/browser/parts/notifications/notificationsCenter.ts
浏览文件 @
2f8ddbe3
...
...
@@ -100,6 +100,9 @@ export class NotificationsCenter extends Themable implements INotificationsCente
// Theming
this
.
updateStyles
();
// Mark as visible
this
.
model
.
notifications
.
forEach
(
notification
=>
notification
.
updateVisibility
(
true
));
// Context Key
this
.
notificationsCenterVisibleContextKey
.
set
(
true
);
...
...
@@ -115,7 +118,7 @@ export class NotificationsCenter extends Themable implements INotificationsCente
clearAllAction
.
enabled
=
false
;
}
else
{
notificationsCenterTitle
.
textContent
=
localize
(
'
notifications
'
,
"
Notifications
"
);
clearAllAction
.
enabled
=
t
rue
;
clearAllAction
.
enabled
=
t
his
.
model
.
notifications
.
some
(
notification
=>
!
notification
.
hasProgress
)
;
}
}
...
...
@@ -172,20 +175,22 @@ export class NotificationsCenter extends Themable implements INotificationsCente
return
;
// only if visible
}
let
focus
Group
=
false
;
let
focus
Editor
=
false
;
// Update notifications list based on event
const
[
notificationsList
,
notificationsCenterContainer
]
=
assertAllDefined
(
this
.
notificationsList
,
this
.
notificationsCenterContainer
);
switch
(
e
.
kind
)
{
case
NotificationChangeType
.
ADD
:
notificationsList
.
updateNotificationsList
(
e
.
index
,
0
,
[
e
.
item
]);
e
.
item
.
updateVisibility
(
true
);
break
;
case
NotificationChangeType
.
CHANGE
:
notificationsList
.
updateNotificationsList
(
e
.
index
,
1
,
[
e
.
item
]);
break
;
case
NotificationChangeType
.
REMOVE
:
focus
Group
=
isAncestor
(
document
.
activeElement
,
notificationsCenterContainer
);
focus
Editor
=
isAncestor
(
document
.
activeElement
,
notificationsCenterContainer
);
notificationsList
.
updateNotificationsList
(
e
.
index
,
1
);
e
.
item
.
updateVisibility
(
false
);
break
;
}
...
...
@@ -197,7 +202,7 @@ export class NotificationsCenter extends Themable implements INotificationsCente
this
.
hide
();
// Restore focus to editor group if we had focus
if
(
focus
Group
)
{
if
(
focus
Editor
)
{
this
.
editorGroupService
.
activeGroup
.
focus
();
}
}
...
...
@@ -208,13 +213,16 @@ export class NotificationsCenter extends Themable implements INotificationsCente
return
;
// already hidden
}
const
focus
Group
=
isAncestor
(
document
.
activeElement
,
this
.
notificationsCenterContainer
);
const
focus
Editor
=
isAncestor
(
document
.
activeElement
,
this
.
notificationsCenterContainer
);
// Hide
this
.
_isVisible
=
false
;
removeClass
(
this
.
notificationsCenterContainer
,
'
visible
'
);
this
.
notificationsList
.
hide
();
// Mark as hidden
this
.
model
.
notifications
.
forEach
(
notification
=>
notification
.
updateVisibility
(
false
));
// Context Key
this
.
notificationsCenterVisibleContextKey
.
set
(
false
);
...
...
@@ -222,7 +230,7 @@ export class NotificationsCenter extends Themable implements INotificationsCente
this
.
_onDidChangeVisibility
.
fire
();
// Restore focus to editor group if we had focus
if
(
focus
Group
)
{
if
(
focus
Editor
)
{
this
.
editorGroupService
.
activeGroup
.
focus
();
}
}
...
...
src/vs/workbench/browser/parts/notifications/notificationsCommands.ts
浏览文件 @
2f8ddbe3
...
...
@@ -75,6 +75,7 @@ export function registerNotificationCommands(center: INotificationsCenterControl
// Show Notifications Cneter
CommandsRegistry
.
registerCommand
(
SHOW_NOTIFICATIONS_CENTER
,
()
=>
{
toasts
.
hide
();
center
.
show
();
});
...
...
@@ -92,6 +93,7 @@ export function registerNotificationCommands(center: INotificationsCenterControl
if
(
center
.
isVisible
)
{
center
.
hide
();
}
else
{
toasts
.
hide
();
center
.
show
();
}
});
...
...
src/vs/workbench/browser/parts/notifications/notificationsToasts.ts
浏览文件 @
2f8ddbe3
...
...
@@ -179,11 +179,8 @@ export class NotificationsToasts extends Themable implements INotificationsToast
const
toast
:
INotificationToast
=
{
item
,
list
:
notificationList
,
container
:
notificationToastContainer
,
toast
:
notificationToast
,
toDispose
:
itemDisposables
};
this
.
mapNotificationToToast
.
set
(
item
,
toast
);
itemDisposables
.
add
(
toDisposable
(()
=>
{
if
(
this
.
isToastVisible
(
toast
)
&&
notificationsToastsContainer
)
{
notificationsToastsContainer
.
removeChild
(
toast
.
container
);
}
}));
// When disposed, remove as visible
itemDisposables
.
add
(
toDisposable
(()
=>
this
.
updateToastVisibility
(
toast
,
false
)));
// Make visible
notificationList
.
show
();
...
...
@@ -236,6 +233,9 @@ export class NotificationsToasts extends Themable implements INotificationsToast
addClass
(
notificationToast
,
'
notification-fade-in-done
'
);
}));
// Mark as visible
item
.
updateVisibility
(
true
);
// Events
if
(
!
this
.
_isVisible
)
{
this
.
_isVisible
=
true
;
...
...
@@ -292,12 +292,13 @@ export class NotificationsToasts extends Themable implements INotificationsToast
}
private
removeToast
(
item
:
INotificationViewItem
):
void
{
let
focusEditor
=
false
;
const
notificationToast
=
this
.
mapNotificationToToast
.
get
(
item
);
let
focusGroup
=
false
;
if
(
notificationToast
)
{
const
toastHasDOMFocus
=
isAncestor
(
document
.
activeElement
,
notificationToast
.
container
);
if
(
toastHasDOMFocus
)
{
focus
Group
=
!
(
this
.
focusNext
()
||
this
.
focusPrevious
());
// focus next if any, otherwise focus editor
focus
Editor
=
!
(
this
.
focusNext
()
||
this
.
focusPrevious
());
// focus next if any, otherwise focus editor
}
// Listeners
...
...
@@ -317,7 +318,7 @@ export class NotificationsToasts extends Themable implements INotificationsToast
this
.
doHide
();
// Move focus back to editor group as needed
if
(
focus
Group
)
{
if
(
focus
Editor
)
{
this
.
editorGroupService
.
activeGroup
.
focus
();
}
}
...
...
@@ -346,11 +347,11 @@ export class NotificationsToasts extends Themable implements INotificationsToast
}
hide
():
void
{
const
focus
Group
=
this
.
notificationsToastsContainer
?
isAncestor
(
document
.
activeElement
,
this
.
notificationsToastsContainer
)
:
false
;
const
focus
Editor
=
this
.
notificationsToastsContainer
?
isAncestor
(
document
.
activeElement
,
this
.
notificationsToastsContainer
)
:
false
;
this
.
removeToasts
();
if
(
focus
Group
)
{
if
(
focus
Editor
)
{
this
.
editorGroupService
.
activeGroup
.
focus
();
}
}
...
...
@@ -459,12 +460,12 @@ export class NotificationsToasts extends Themable implements INotificationsToast
notificationToasts
.
push
(
toast
);
break
;
case
ToastVisibility
.
HIDDEN
:
if
(
!
this
.
isToast
Visible
(
toast
))
{
if
(
!
this
.
isToast
InDOM
(
toast
))
{
notificationToasts
.
push
(
toast
);
}
break
;
case
ToastVisibility
.
VISIBLE
:
if
(
this
.
isToast
Visible
(
toast
))
{
if
(
this
.
isToast
InDOM
(
toast
))
{
notificationToasts
.
push
(
toast
);
}
break
;
...
...
@@ -530,7 +531,7 @@ export class NotificationsToasts extends Themable implements INotificationsToast
// In order to measure the client height, the element cannot have display: none
toast
.
container
.
style
.
opacity
=
'
0
'
;
this
.
se
tVisibility
(
toast
,
true
);
this
.
updateToas
tVisibility
(
toast
,
true
);
heightToGive
-=
toast
.
container
.
offsetHeight
;
...
...
@@ -542,7 +543,7 @@ export class NotificationsToasts extends Themable implements INotificationsToast
}
// Hide or show toast based on context
this
.
se
tVisibility
(
toast
,
makeVisible
);
this
.
updateToas
tVisibility
(
toast
,
makeVisible
);
toast
.
container
.
style
.
opacity
=
''
;
if
(
makeVisible
)
{
...
...
@@ -551,20 +552,24 @@ export class NotificationsToasts extends Themable implements INotificationsToast
});
}
private
se
tVisibility
(
toast
:
INotificationToast
,
visible
:
boolean
):
void
{
if
(
this
.
isToast
Visible
(
toast
)
===
visible
)
{
private
updateToas
tVisibility
(
toast
:
INotificationToast
,
visible
:
boolean
):
void
{
if
(
this
.
isToast
InDOM
(
toast
)
===
visible
)
{
return
;
}
// Update visibility in DOM
const
notificationsToastsContainer
=
assertIsDefined
(
this
.
notificationsToastsContainer
);
if
(
visible
)
{
notificationsToastsContainer
.
appendChild
(
toast
.
container
);
}
else
{
notificationsToastsContainer
.
removeChild
(
toast
.
container
);
}
// Update visibility in model
toast
.
item
.
updateVisibility
(
visible
);
}
private
isToast
Visible
(
toast
:
INotificationToast
):
boolean
{
private
isToast
InDOM
(
toast
:
INotificationToast
):
boolean
{
return
!!
toast
.
container
.
parentElement
;
}
}
src/vs/workbench/common/notifications.ts
浏览文件 @
2f8ddbe3
...
...
@@ -92,6 +92,9 @@ export class NotificationHandle extends Disposable implements INotificationHandl
private
readonly
_onDidClose
=
this
.
_register
(
new
Emitter
<
void
>
());
readonly
onDidClose
=
this
.
_onDidClose
.
event
;
private
readonly
_onDidChangeVisibility
=
this
.
_register
(
new
Emitter
<
boolean
>
());
readonly
onDidChangeVisibility
=
this
.
_onDidChangeVisibility
.
event
;
constructor
(
private
readonly
item
:
INotificationViewItem
,
private
readonly
onClose
:
(
item
:
INotificationViewItem
)
=>
void
)
{
super
();
...
...
@@ -99,6 +102,11 @@ export class NotificationHandle extends Disposable implements INotificationHandl
}
private
registerListeners
():
void
{
// Visibility
this
.
_register
(
this
.
item
.
onDidChangeVisibility
(
visible
=>
this
.
_onDidChangeVisibility
.
fire
(
visible
)));
// Closing
Event
.
once
(
this
.
item
.
onDidClose
)(()
=>
{
this
.
_onDidClose
.
fire
();
...
...
@@ -265,6 +273,7 @@ export interface INotificationViewItem {
readonly
onDidChangeExpansion
:
Event
<
void
>
;
readonly
onDidClose
:
Event
<
void
>
;
readonly
onDidChangeVisibility
:
Event
<
boolean
>
;
readonly
onDidChangeLabel
:
Event
<
INotificationViewItemLabelChangeEvent
>
;
expand
():
void
;
...
...
@@ -275,6 +284,8 @@ export interface INotificationViewItem {
updateMessage
(
message
:
NotificationMessage
):
void
;
updateActions
(
actions
?:
INotificationActions
):
void
;
updateVisibility
(
visible
:
boolean
):
void
;
close
():
void
;
equals
(
item
:
INotificationViewItem
):
boolean
;
...
...
@@ -398,6 +409,7 @@ export class NotificationViewItem extends Disposable implements INotificationVie
private
static
readonly
MAX_MESSAGE_LENGTH
=
1000
;
private
_expanded
:
boolean
|
undefined
;
private
_visible
:
boolean
=
false
;
private
_actions
:
INotificationActions
|
undefined
;
private
_progress
:
NotificationViewItemProgress
|
undefined
;
...
...
@@ -411,6 +423,9 @@ export class NotificationViewItem extends Disposable implements INotificationVie
private
readonly
_onDidChangeLabel
=
this
.
_register
(
new
Emitter
<
INotificationViewItemLabelChangeEvent
>
());
readonly
onDidChangeLabel
=
this
.
_onDidChangeLabel
.
event
;
private
readonly
_onDidChangeVisibility
=
this
.
_register
(
new
Emitter
<
boolean
>
());
readonly
onDidChangeVisibility
=
this
.
_onDidChangeVisibility
.
event
;
static
create
(
notification
:
INotification
,
filter
:
NotificationsFilter
=
NotificationsFilter
.
OFF
):
INotificationViewItem
|
undefined
{
if
(
!
notification
||
!
notification
.
message
||
isPromiseCanceledError
(
notification
.
message
))
{
return
undefined
;
// we need a message to show
...
...
@@ -600,6 +615,14 @@ export class NotificationViewItem extends Disposable implements INotificationVie
this
.
_onDidChangeLabel
.
fire
({
kind
:
NotificationViewItemLabelKind
.
ACTIONS
});
}
updateVisibility
(
visible
:
boolean
):
void
{
if
(
this
.
_visible
!==
visible
)
{
this
.
_visible
=
visible
;
this
.
_onDidChangeVisibility
.
fire
(
visible
);
}
}
expand
():
void
{
if
(
this
.
_expanded
||
!
this
.
canCollapse
)
{
return
;
...
...
src/vs/workbench/services/progress/browser/progressService.ts
浏览文件 @
2f8ddbe3
...
...
@@ -6,7 +6,7 @@
import
'
vs/css!./media/progressService
'
;
import
{
localize
}
from
'
vs/nls
'
;
import
{
IDisposable
,
dispose
,
DisposableStore
,
MutableDisposable
,
Disposable
}
from
'
vs/base/common/lifecycle
'
;
import
{
IDisposable
,
dispose
,
DisposableStore
,
MutableDisposable
,
Disposable
,
toDisposable
}
from
'
vs/base/common/lifecycle
'
;
import
{
IProgressService
,
IProgressOptions
,
IProgressStep
,
ProgressLocation
,
IProgress
,
Progress
,
IProgressCompositeOptions
,
IProgressNotificationOptions
,
IProgressRunner
,
IProgressIndicator
,
IProgressWindowOptions
}
from
'
vs/platform/progress/common/progress
'
;
import
{
IViewletService
}
from
'
vs/workbench/services/viewlet/browser/viewlet
'
;
import
{
StatusbarAlignment
,
IStatusbarService
}
from
'
vs/workbench/services/statusbar/common/statusbar
'
;
...
...
@@ -191,6 +191,38 @@ export class ProgressService extends Disposable implements IProgressService {
}
};
const
createWindowProgress
=
()
=>
{
// Create a promise that we can resolve as needed
// when the outside calls dispose on us
let
promiseResolve
:
()
=>
void
;
const
promise
=
new
Promise
<
R
>
(
resolve
=>
promiseResolve
=
resolve
);
this
.
withWindowProgress
<
R
>
({
location
:
ProgressLocation
.
Window
,
title
:
options
.
title
,
command
:
'
notifications.showList
'
},
progress
=>
{
// Apply any progress that was made already
if
(
progressStateModel
.
step
)
{
progress
.
report
(
progressStateModel
.
step
);
}
// Continue to report progress as it happens
const
onDidReportListener
=
progressStateModel
.
onDidReport
(
step
=>
progress
.
report
(
step
));
promise
.
finally
(()
=>
onDidReportListener
.
dispose
());
// When the progress model gets disposed, we are done as well
Event
.
once
(
progressStateModel
.
onDispose
)(()
=>
promiseResolve
());
return
promise
;
});
// Dispose means completing our promise
return
toDisposable
(()
=>
promiseResolve
());
};
const
createNotification
=
(
message
:
string
,
increment
?:
number
):
INotificationHandle
=>
{
const
notificationDisposables
=
new
DisposableStore
();
...
...
@@ -229,7 +261,7 @@ export class ProgressService extends Disposable implements IProgressService {
primaryActions
.
push
(
cancelAction
);
}
const
handle
=
this
.
notificationService
.
notify
({
const
notification
=
this
.
notificationService
.
notify
({
severity
:
Severity
.
Info
,
message
,
source
:
options
.
source
,
...
...
@@ -237,12 +269,26 @@ export class ProgressService extends Disposable implements IProgressService {
progress
:
typeof
increment
===
'
number
'
&&
increment
>=
0
?
{
total
:
100
,
worked
:
increment
}
:
{
infinite
:
true
}
});
updateProgress
(
handle
,
increment
);
// Switch to window based progress once the notification
// changes visibility to hidden and is still ongoing.
// Remove that window based progress once the notification
// shows again.
let
windowProgressDisposable
:
IDisposable
|
undefined
=
undefined
;
notificationDisposables
.
add
(
notification
.
onDidChangeVisibility
(
visible
=>
{
// Clear any previous running window progress
dispose
(
windowProgressDisposable
);
// Create new window progress if notification got hidden
if
(
!
visible
&&
!
progressStateModel
.
done
)
{
windowProgressDisposable
=
createWindowProgress
();
}
}));
// Clear upon dispose
Event
.
once
(
handle
.
onDidClose
)(()
=>
notificationDisposables
.
dispose
());
Event
.
once
(
notification
.
onDidClose
)(()
=>
notificationDisposables
.
dispose
());
return
handle
;
return
notification
;
};
const
updateProgress
=
(
notification
:
INotificationHandle
,
increment
?:
number
):
void
=>
{
...
...
src/vs/workbench/test/common/notifications.test.ts
浏览文件 @
2f8ddbe3
...
...
@@ -98,6 +98,17 @@ suite('Notifications', () => {
assert
.
equal
(
called
,
1
);
called
=
0
;
item1
.
onDidChangeVisibility
(
e
=>
{
called
++
;
});
item1
.
updateVisibility
(
true
);
item1
.
updateVisibility
(
false
);
item1
.
updateVisibility
(
false
);
assert
.
equal
(
called
,
2
);
called
=
0
;
item1
.
onDidClose
(()
=>
{
called
++
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录