@@ -286,6 +286,41 @@ function inviteUser(event, roomId, userId) {
286
286
} ) ;
287
287
}
288
288
289
+ /**
290
+ * Returns a promise that resolves when a widget with the given
291
+ * ID has been added as a user widget (ie. the accountData event
292
+ * arrives) or rejects after a timeout
293
+ *
294
+ * @param {string } widgetId The ID of the widget to wait for
295
+ * @returns {Promise } that resolves when the widget is available
296
+ */
297
+ function waitForUserWidget ( widgetId ) {
298
+ return new Promise ( ( resolve , reject ) => {
299
+ const currentAccountDataEvent = MatrixClientPeg . get ( ) . getAccountData ( 'm.widgets' ) ;
300
+ if (
301
+ currentAccountDataEvent &&
302
+ currentAccountDataEvent . getContent ( ) &&
303
+ currentAccountDataEvent . getContent ( ) [ widgetId ] !== undefined
304
+ ) {
305
+ resolve ( ) ;
306
+ return ;
307
+ }
308
+
309
+ function onAccountData ( ev ) {
310
+ if ( ev . getType ( ) === 'm.widgets' && ev . getContent ( ) && ev . getContent ( ) [ widgetId ] !== undefined ) {
311
+ MatrixClientPeg . get ( ) . removeListener ( 'accountData' , onAccountData ) ;
312
+ clearTimeout ( timerId ) ;
313
+ resolve ( ) ;
314
+ }
315
+ }
316
+ const timerId = setTimeout ( ( ) => {
317
+ MatrixClientPeg . get ( ) . removeListener ( 'accountData' , onAccountData ) ;
318
+ reject ( new Error ( "Timed out waiting for widget ID " + widgetId + " to appear" ) ) ;
319
+ } , 10000 ) ;
320
+ MatrixClientPeg . get ( ) . on ( 'accountData' , onAccountData ) ;
321
+ } ) ;
322
+ }
323
+
289
324
function setWidget ( event , roomId ) {
290
325
const widgetId = event . data . widget_id ;
291
326
const widgetType = event . data . type ;
@@ -355,12 +390,20 @@ function setWidget(event, roomId) {
355
390
} ;
356
391
}
357
392
393
+ // This starts listening for when the echo comes back from the server
394
+ // since the widget won't appear added until this happens. If we don't
395
+ // wait for this, the action will complete but if the user is fast enough,
396
+ // the widget still won't actually be there.
358
397
client . setAccountData ( 'm.widgets' , userWidgets ) . then ( ( ) => {
398
+ return waitForUserWidget ( widgetId ) ;
399
+ } ) . then ( ( ) => {
359
400
sendResponse ( event , {
360
401
success : true ,
361
402
} ) ;
362
403
363
404
dis . dispatch ( { action : "user_widget_updated" } ) ;
405
+ } ) . catch ( ( e ) => {
406
+ sendError ( event , _t ( 'Unable to create widget.' ) , e ) ;
364
407
} ) ;
365
408
} else { // Room widget
366
409
if ( ! roomId ) {
@@ -373,6 +416,8 @@ function setWidget(event, roomId) {
373
416
// TODO - Room widgets need to be moved to 'm.widget' state events
374
417
// https://docs.google.com/document/d/1uPF7XWY_dXTKVKV7jZQ2KmsI19wn9-kFRgQ1tFQP7wQ/edit?usp=sharing
375
418
client . sendStateEvent ( roomId , "im.vector.modular.widgets" , content , widgetId ) . done ( ( ) => {
419
+ // XXX: We should probably wait for the echo of the state event to come back from the server,
420
+ // as we do with user widgets.
376
421
sendResponse ( event , {
377
422
success : true ,
378
423
} ) ;
0 commit comments