diff --git a/src/routes/_components/compose/ComposeAutosuggest.html b/src/routes/_components/compose/ComposeAutosuggest.html index c4bd69c..f84b2a8 100644 --- a/src/routes/_components/compose/ComposeAutosuggest.html +++ b/src/routes/_components/compose/ComposeAutosuggest.html @@ -74,6 +74,7 @@ } }).then(() => { this.set({ shown: shouldBeShown }) + this.store.setForCurrentAutosuggest({ autosuggestSelecting: false }) }) }) }, @@ -81,6 +82,8 @@ observe, once, onClick (item) { + /* autosuggestSelecting prevents a flash of searched content */ + this.store.setForCurrentAutosuggest({ autosuggestSelecting: true }) this.fire('autosuggestItemSelected') selectAutosuggestItem(item) } diff --git a/src/routes/_components/compose/ComposeInput.html b/src/routes/_components/compose/ComposeInput.html index ac2ae17..ca08ca9 100644 --- a/src/routes/_components/compose/ComposeInput.html +++ b/src/routes/_components/compose/ComposeInput.html @@ -127,7 +127,7 @@ stop('autosize.destroy()') }, onBlur () { - scheduleIdleTask(() => { + requestAnimationFrame(() => { this.store.setForCurrentAutosuggest({ composeFocused: false }) }) }, @@ -177,14 +177,22 @@ if (!autosuggestShown) { return false } - let { realm } = this.get() - if (autosuggestType === 'account') { - /* no await */ clickSelectedAutosuggestionUsername(realm) - } else { // emoji - /* no await */ clickSelectedAutosuggestionEmoji(realm) - } event.preventDefault() event.stopPropagation() + + const clickAutosuggestedItem = async () => { + let { realm } = this.get() + /* autosuggestSelecting prevents a flash of searched content */ + this.store.setForCurrentAutosuggest({ autosuggestSelecting: true }) + if (autosuggestType === 'account') { + await clickSelectedAutosuggestionUsername(realm) + } else { // emoji + await clickSelectedAutosuggestionEmoji(realm) + } + this.store.setForCurrentAutosuggest({ autosuggestSelecting: false }) + } + + /* no await */ clickAutosuggestedItem() return true }, incrementAutosuggestSelected (increment, event) { diff --git a/src/routes/_store/mixins/autosuggestMixins.js b/src/routes/_store/mixins/autosuggestMixins.js index 19823bd..7ab43b0 100644 --- a/src/routes/_store/mixins/autosuggestMixins.js +++ b/src/routes/_store/mixins/autosuggestMixins.js @@ -1,3 +1,5 @@ +import { get } from '../../_utils/lodash-lite' + export function autosuggestMixins (Store) { Store.prototype.setForAutosuggest = function (instanceName, realm, obj) { let valuesToSet = {} @@ -16,4 +18,9 @@ export function autosuggestMixins (Store) { let { currentInstance, currentComposeRealm } = this.get() this.setForAutosuggest(currentInstance, currentComposeRealm, obj) } + + Store.prototype.getForCurrentAutosuggest = function (key) { + let { currentInstance, currentComposeRealm } = this.get() + return get(this.get()[`autosuggestData_${key}`], [currentInstance, currentComposeRealm]) + } } diff --git a/src/routes/_store/observers/autosuggestObservers.js b/src/routes/_store/observers/autosuggestObservers.js index 79ff757..c0277ed 100644 --- a/src/routes/_store/observers/autosuggestObservers.js +++ b/src/routes/_store/observers/autosuggestObservers.js @@ -10,6 +10,19 @@ export function autosuggestObservers () { if (!composeFocused || !autosuggestSearchText) { return } + /* autosuggestSelecting indicates that the user has pressed Enter or clicked on an item + and the results are being processed. Returning early avoids a flash of searched content. + We can also cancel any inflight XHRs here. + */ + let autosuggestSelecting = store.getForCurrentAutosuggest('autosuggestSelecting') + if (autosuggestSelecting) { + if (lastSearch) { + lastSearch.cancel() + lastSearch = null + } + return + } + let autosuggestType = autosuggestSearchText.startsWith('@') ? 'account' : 'emoji' if (lastSearch) {