@@ -18,7 +18,7 @@ limitations under the License.
18
18
import React from "react" ;
19
19
import ReactDOM from "react-dom" ;
20
20
import classNames from "classnames" ;
21
- import { defer , sleep } from "matrix-js-sdk/src/utils" ;
21
+ import { IDeferred , defer , sleep } from "matrix-js-sdk/src/utils" ;
22
22
import { TypedEventEmitter } from "matrix-js-sdk/src/matrix" ;
23
23
import { Glass } from "@vector-im/compound-web" ;
24
24
@@ -47,11 +47,12 @@ export interface IModal<C extends ComponentType> {
47
47
elem : React . ReactNode ;
48
48
className ?: string ;
49
49
beforeClosePromise ?: Promise < boolean > ;
50
- closeReason ?: string ;
51
- onBeforeClose ?( reason ?: string ) : Promise < boolean > ;
50
+ closeReason ?: ModalCloseReason ;
51
+ onBeforeClose ?( reason ?: ModalCloseReason ) : Promise < boolean > ;
52
52
onFinished : ComponentProps < C > [ "onFinished" ] ;
53
53
close ( ...args : Parameters < ComponentProps < C > [ "onFinished" ] > ) : void ;
54
54
hidden ?: boolean ;
55
+ deferred ?: IDeferred < Parameters < ComponentProps < C > [ "onFinished" ] > > ;
55
56
}
56
57
57
58
export interface IHandle < C extends ComponentType > {
@@ -73,6 +74,8 @@ type HandlerMap = {
73
74
[ ModalManagerEvent . Closed ] : ( ) => void ;
74
75
} ;
75
76
77
+ type ModalCloseReason = "backgroundClick" ;
78
+
76
79
export class ModalManager extends TypedEventEmitter < ModalManagerEvent , HandlerMap > {
77
80
private counter = 0 ;
78
81
// The modal to prioritise over all others. If this is set, only show
@@ -148,10 +151,14 @@ export class ModalManager extends TypedEventEmitter<ModalManagerEvent, HandlerMa
148
151
}
149
152
150
153
/**
154
+ * DEPRECATED.
155
+ * This is used only for tests. They should be using forceCloseAllModals but that
156
+ * caused a chunk of tests to fail, so for now they continue to use this.
157
+ *
151
158
* @param reason either "backgroundClick" or undefined
152
159
* @return whether a modal was closed
153
160
*/
154
- public closeCurrentModal ( reason ?: string ) : boolean {
161
+ public closeCurrentModal ( reason ?: ModalCloseReason ) : boolean {
155
162
const modal = this . getCurrentModal ( ) ;
156
163
if ( ! modal ) {
157
164
return false ;
@@ -161,6 +168,22 @@ export class ModalManager extends TypedEventEmitter<ModalManagerEvent, HandlerMa
161
168
return true ;
162
169
}
163
170
171
+ /**
172
+ * Forces closes all open modals. The modals onBeforeClose function will not be
173
+ * run and the modal will not have a chance to prevent closing. Intended for
174
+ * situations like the user logging out of the app.
175
+ */
176
+ public forceCloseAllModals ( ) : void {
177
+ for ( const modal of this . modals ) {
178
+ modal . deferred ?. resolve ( [ ] ) ;
179
+ if ( modal . onFinished ) modal . onFinished . apply ( null ) ;
180
+ this . emitClosed ( ) ;
181
+ }
182
+
183
+ this . modals = [ ] ;
184
+ this . reRender ( ) ;
185
+ }
186
+
164
187
private buildModal < C extends ComponentType > (
165
188
prom : Promise < C > ,
166
189
props ?: ComponentProps < C > ,
@@ -199,7 +222,7 @@ export class ModalManager extends TypedEventEmitter<ModalManagerEvent, HandlerMa
199
222
modal : IModal < C > ,
200
223
props ?: ComponentProps < C > ,
201
224
) : [ IHandle < C > [ "close" ] , IHandle < C > [ "finished" ] ] {
202
- const deferred = defer < Parameters < ComponentProps < C > [ "onFinished" ] > > ( ) ;
225
+ modal . deferred = defer < Parameters < ComponentProps < C > [ "onFinished" ] > > ( ) ;
203
226
return [
204
227
async ( ...args : Parameters < ComponentProps < C > [ "onFinished" ] > ) : Promise < void > => {
205
228
if ( modal . beforeClosePromise ) {
@@ -212,7 +235,7 @@ export class ModalManager extends TypedEventEmitter<ModalManagerEvent, HandlerMa
212
235
return ;
213
236
}
214
237
}
215
- deferred . resolve ( args ) ;
238
+ modal . deferred ? .resolve ( args ) ;
216
239
if ( props ?. onFinished ) props . onFinished . apply ( null , args ) ;
217
240
const i = this . modals . indexOf ( modal ) ;
218
241
if ( i >= 0 ) {
@@ -236,7 +259,7 @@ export class ModalManager extends TypedEventEmitter<ModalManagerEvent, HandlerMa
236
259
this . reRender ( ) ;
237
260
this . emitClosed ( ) ;
238
261
} ,
239
- deferred . promise ,
262
+ modal . deferred . promise ,
240
263
] ;
241
264
}
242
265
0 commit comments