mirror of
https://github.com/flarum/core.git
synced 2025-07-25 10:41:24 +02:00
Stop mentions dropdown from jumping around (#48)
Cache the order in which users are returned by the API to stop the mentions list from jumping around Only ping the api when 2 or more characters are entered
This commit is contained in:
committed by
GitHub
parent
13e79e5457
commit
68163d462a
@@ -25,6 +25,12 @@ export default function addComposerAutocomplete() {
|
|||||||
let typed;
|
let typed;
|
||||||
let searchTimeout;
|
let searchTimeout;
|
||||||
|
|
||||||
|
// We store users returned from an API here to preserve order in which they are returned
|
||||||
|
// This prevents the user list jumping around while users are returned.
|
||||||
|
// We also use a hashset for user IDs to provide O(1) lookup for the users already in the list.
|
||||||
|
const returnedUsers = Array.from(app.store.all('users'));
|
||||||
|
const returnedUserIds = new Set(returnedUsers.map(u => u.id()));
|
||||||
|
|
||||||
const applySuggestion = function(replacement) {
|
const applySuggestion = function(replacement) {
|
||||||
const insert = replacement + ' ';
|
const insert = replacement + ' ';
|
||||||
|
|
||||||
@@ -112,7 +118,7 @@ export default function addComposerAutocomplete() {
|
|||||||
// If the user has started to type a username, then suggest users
|
// If the user has started to type a username, then suggest users
|
||||||
// matching that username.
|
// matching that username.
|
||||||
if (typed) {
|
if (typed) {
|
||||||
app.store.all('users').forEach(user => {
|
returnedUsers.forEach(user => {
|
||||||
if (!userMatches(user)) return;
|
if (!userMatches(user)) return;
|
||||||
|
|
||||||
suggestions.push(
|
suggestions.push(
|
||||||
@@ -140,7 +146,7 @@ export default function addComposerAutocomplete() {
|
|||||||
const user = post.user();
|
const user = post.user();
|
||||||
suggestions.push(
|
suggestions.push(
|
||||||
makeSuggestion(user, '@' + user.username() + '#' + post.id(), [
|
makeSuggestion(user, '@' + user.username() + '#' + post.id(), [
|
||||||
app.translator.trans('flarum-mentions.forum.composer.reply_to_post_text', {number: post.number()}), ' — ',
|
app.translator.trans('flarum-mentions.forum.composer.reply_to_post_text', { number: post.number() }), ' — ',
|
||||||
truncate(post.contentPlain(), 200)
|
truncate(post.contentPlain(), 200)
|
||||||
], 'MentionsDropdown-post')
|
], 'MentionsDropdown-post')
|
||||||
);
|
);
|
||||||
@@ -179,11 +185,19 @@ export default function addComposerAutocomplete() {
|
|||||||
dropdown.$().scrollTop(0);
|
dropdown.$().scrollTop(0);
|
||||||
|
|
||||||
clearTimeout(searchTimeout);
|
clearTimeout(searchTimeout);
|
||||||
if (typed) {
|
// Don't send API calls searching for users until at least 2 characters have been typed.
|
||||||
|
// This focuses the mention results on users and posts in the discussion.
|
||||||
|
if (typed.length > 1) {
|
||||||
searchTimeout = setTimeout(function() {
|
searchTimeout = setTimeout(function() {
|
||||||
const typedLower = typed.toLowerCase();
|
const typedLower = typed.toLowerCase();
|
||||||
if (searched.indexOf(typedLower) === -1) {
|
if (searched.indexOf(typedLower) === -1) {
|
||||||
app.store.find('users', {filter: {q: typed}, page: {limit: 5}}).then(() => {
|
app.store.find('users', { filter: { q: typed }, page: { limit: 5 } }).then(results => {
|
||||||
|
results.forEach(u => {
|
||||||
|
if (!returnedUserIds.has(u.id())) {
|
||||||
|
returnedUserIds.add(u.id());
|
||||||
|
returnedUsers.push(u);
|
||||||
|
}
|
||||||
|
})
|
||||||
if (dropdown.active) buildSuggestions();
|
if (dropdown.active) buildSuggestions();
|
||||||
});
|
});
|
||||||
searched.push(typedLower);
|
searched.push(typedLower);
|
||||||
|
Reference in New Issue
Block a user