@@ -14,7 +14,11 @@ const CLASS_ALIGN_START = 'mdc-snackbar--align-start';
14
14
* It can also be used to subscribe to action clicks.
15
15
*/
16
16
export class MdcSnackbarRef {
17
- constructor ( private _action : Subject < void > ) { }
17
+ constructor (
18
+ private _action : Subject < void > ,
19
+ private _show : Subject < void > ,
20
+ private _hide : Subject < void >
21
+ ) { }
18
22
19
23
/**
20
24
* Subscribe to this observable to be informed when a user clicks the action
@@ -24,6 +28,24 @@ export class MdcSnackbarRef {
24
28
action ( ) : Observable < void > {
25
29
return this . _action . asObservable ( ) ;
26
30
}
31
+
32
+ /**
33
+ * Subscribe to this observable to be informed when the message is displayed.
34
+ * Note that the observable will complete when the snackbar disappears from screen,
35
+ * so there is no need to unsubscribe.
36
+ */
37
+ afterShow ( ) : Observable < void > {
38
+ return this . _show . asObservable ( ) ;
39
+ }
40
+
41
+ /**
42
+ * Subscribe to this observable to be informed when the message is displayed.
43
+ * Note that the observable will complete when the snackbar disappears from screen,
44
+ * so there is no need to unsubscribe.
45
+ */
46
+ afterHide ( ) : Observable < void > {
47
+ return this . _hide . asObservable ( ) ;
48
+ }
27
49
}
28
50
29
51
/**
@@ -38,6 +60,7 @@ export class MdcSnackbarService {
38
60
private lastActivated = - 1 ;
39
61
private lastDismissed = - 1 ;
40
62
63
+ private openMessage : Subject < number > = new Subject < number > ( ) ;
41
64
private closeMessage : Subject < number > = new Subject < number > ( ) ;
42
65
43
66
constructor ( ) {
@@ -69,16 +92,8 @@ export class MdcSnackbarService {
69
92
const textEl = root . querySelector ( '.mdc-snackbar__text' ) ;
70
93
const buttonEl = < HTMLElement > root . querySelector ( '.mdc-snackbar__action-button' ) ;
71
94
const adapter : MdcSnackbarAdapter = {
72
- addClass : ( className ) => {
73
- if ( className === CLASS_ACTIVE )
74
- this . activateNext ( ) ;
75
- root . classList . add ( className ) ;
76
- } ,
77
- removeClass : ( className ) => {
78
- if ( className === 'mdc-snackbar--active' )
79
- this . deactivateLast ( ) ;
80
- root . classList . remove ( className ) ;
81
- } ,
95
+ addClass : ( className ) => { root . classList . add ( className ) ; } ,
96
+ removeClass : ( className ) => { root . classList . remove ( className ) ; } ,
82
97
setAriaHidden : ( ) => root . setAttribute ( 'aria-hidden' , 'true' ) ,
83
98
unsetAriaHidden : ( ) => root . removeAttribute ( 'aria-hidden' ) ,
84
99
setActionAriaHidden : ( ) => buttonEl . setAttribute ( 'aria-hidden' , 'true' ) ,
@@ -96,7 +111,9 @@ export class MdcSnackbarService {
96
111
registerActionClickHandler : ( handler ) => buttonEl . addEventListener ( 'click' , handler ) ,
97
112
deregisterActionClickHandler : ( handler ) => buttonEl . removeEventListener ( 'click' , handler ) ,
98
113
registerTransitionEndHandler : ( handler ) => root . addEventListener ( getCorrectEventName ( window , 'transitionend' ) , handler ) ,
99
- deregisterTransitionEndHandler : ( handler ) => root . removeEventListener ( getCorrectEventName ( window , 'transitionend' ) , handler )
114
+ deregisterTransitionEndHandler : ( handler ) => root . removeEventListener ( getCorrectEventName ( window , 'transitionend' ) , handler ) ,
115
+ notifyShow : ( ) => { this . activateNext ( ) ; } ,
116
+ notifyHide : ( ) => { this . deactivateLast ( ) ; }
100
117
}
101
118
return new MDCSnackbarFoundation ( adapter ) ;
102
119
}
@@ -105,7 +122,7 @@ export class MdcSnackbarService {
105
122
while ( this . lastDismissed < this . lastActivated )
106
123
// since this activates a new message, all messages before will logically be closed:
107
124
this . closeMessage . next ( ++ this . lastDismissed ) ;
108
- ++ this . lastActivated ;
125
+ this . openMessage . next ( ++ this . lastActivated ) ;
109
126
this . isActive = true ;
110
127
}
111
128
@@ -144,21 +161,33 @@ export class MdcSnackbarService {
144
161
145
162
// provide a means to subscribe to an action click:
146
163
let action = new Subject < void > ( ) ;
164
+ let show = new Subject < void > ( ) ;
165
+ let hide = new Subject < void > ( ) ;
147
166
if ( message . actionText )
148
- data . actionHandler = function ( ) { action . next ( ) ; } ;
149
- // make sure the action Subject will complete after the snackbar is removed from screen,
150
- // so that callers never have to unsubscribe:
167
+ data . actionHandler = function ( ) { action . next ( ) ; } ;
168
+
169
+ // manage the show subscription
170
+ this . openMessage . asObservable ( ) . pipe (
171
+ filter ( nr => nr === messageNr ) ,
172
+ take ( 1 )
173
+ ) . subscribe ( nr => { show . next ( ) ; } ) ;
174
+ // manage the hide subscription, and close complete all observables when the
175
+ // message is removed:
151
176
this . closeMessage . asObservable ( ) . pipe (
152
177
filter ( nr => nr === messageNr ) ,
153
178
take ( 1 )
154
179
) . subscribe ( nr => {
180
+ hide . next ( ) ;
181
+ show . complete ( ) ;
182
+ hide . complete ( ) ;
155
183
action . complete ( ) ;
156
184
} ) ;
157
185
158
- // show the actual snackbar:
159
- this . snackbar . show ( data ) ;
186
+ // show the actual snackbar, using setTimeout to give callers
187
+ // a chance to subscribe to all events:
188
+ setTimeout ( ( ) => { this . snackbar . show ( data ) ; } ) ;
160
189
161
- return new MdcSnackbarRef ( action ) ;
190
+ return new MdcSnackbarRef ( action , show , hide ) ;
162
191
}
163
192
164
193
/**
0 commit comments