From c15399568f494c25436ac2e51209561a139ae8e8 Mon Sep 17 00:00:00 2001 From: Ed Sanders Date: Thu, 2 Jul 2020 15:12:30 +0100 Subject: [PATCH] Wait for API response before updating suggestion list We can update the local filtered list before then, but then we would have to do two updates for each keystroke, one to do an instant local filter and another to back-fill the list when the remote results become available. Currently CompletionAction is not set up for this, and this might be confusing behaviour. Bug: T256974 Change-Id: I6194cdcd6459be17fb142e644d73c9ec4036ba08 --- .../dt-ve/dt.ui.UsernameCompletionAction.js | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/modules/dt-ve/dt.ui.UsernameCompletionAction.js b/modules/dt-ve/dt.ui.UsernameCompletionAction.js index a2d9d5fd8..eaf8160e7 100644 --- a/modules/dt-ve/dt.ui.UsernameCompletionAction.js +++ b/modules/dt-ve/dt.ui.UsernameCompletionAction.js @@ -60,18 +60,19 @@ MWUsernameCompletionAction.prototype.insertAndOpen = function () { }; MWUsernameCompletionAction.prototype.getSuggestions = function ( input ) { - var capitalizedInput = input.length > 0 && input[ 0 ].toUpperCase() + input.slice( 1 ), + var apiPromise, + capitalizedInput = input.length > 0 && input[ 0 ].toUpperCase() + input.slice( 1 ), action = this; this.api.abort(); // Abort all unfinished API requests if ( capitalizedInput && !this.searchedPrefixes[ capitalizedInput ] ) { - this.api.get( { + apiPromise = this.api.get( { action: 'query', list: 'allusers', // Prefix of list=allusers is case sensitive, and users are stored in the DB capitalized, so: auprefix: capitalizedInput, aulimit: this.limit - } ).done( function ( response ) { + } ).then( function ( response ) { var suggestions = response.query.allusers.map( function ( user ) { return user.name; } ).filter( function ( username ) { @@ -85,23 +86,25 @@ MWUsernameCompletionAction.prototype.getSuggestions = function ( input ) { action.searchedPrefixes[ capitalizedInput ] = true; } ); + } else { + apiPromise = ve.createDeferred().resolve().promise(); } - return ve.createDeferred().resolve( + return apiPromise.then( function () { // By concatenating on-thread authors and remote-fetched authors, both // sorted alphabetically, we'll get our suggestion popup sorted so all // on-thread matches come first. - this.filterSuggestionsForInput( - this.localUsers + return action.filterSuggestionsForInput( + action.localUsers // Show no remote users if no input provided - .concat( capitalizedInput ? this.remoteUsers : [] ), + .concat( capitalizedInput ? action.remoteUsers : [] ), // TODO: Consider showing IP users // * Change link to Special:Contributions/ (localised) // * Let users know that mentioning an IP will not create a notification? // .concat( this.ipUsers ) input - ) - ).promise(); + ); + } ); }; MWUsernameCompletionAction.prototype.insertCompletion = function ( word, range ) {