From c2dde1ae88a12cafecdb8b37afd2a959ad0ddf8f Mon Sep 17 00:00:00 2001 From: Robin Ward Date: Thu, 11 Jun 2015 15:12:16 -0400 Subject: [PATCH] PERF: Debounce mention lookup, enforce minimum username --- .../discourse/lib/link-mentions.js.es6 | 53 +++++++------------ .../discourse/views/composer.js.es6 | 14 ++++- 2 files changed, 32 insertions(+), 35 deletions(-) diff --git a/app/assets/javascripts/discourse/lib/link-mentions.js.es6 b/app/assets/javascripts/discourse/lib/link-mentions.js.es6 index 084564291f7..c1aeb354147 100644 --- a/app/assets/javascripts/discourse/lib/link-mentions.js.es6 +++ b/app/assets/javascripts/discourse/lib/link-mentions.js.es6 @@ -14,43 +14,30 @@ function updateFound($mentions, usernames) { const username = usernames[i]; if (found.indexOf(username) !== -1) { replaceSpan($e, username); - } else { - $e.removeClass('mention-loading').addClass('mention-tested'); + } else if (checked.indexOf(username) !== -1) { + $e.addClass('mention-tested'); } }); }); } +export function linkSeenMentions($elem, siteSettings) { + const $mentions = $('span.mention:not(.mention-tested)', $elem); + if ($mentions.length) { + const usernames = $mentions.map((_, e) => $(e).text().substr(1).toLowerCase()); + const unseen = _.uniq(usernames).filter((u) => { + return u.length >= siteSettings.min_username_length && checked.indexOf(u) === -1; + }); + updateFound($mentions, usernames); + return unseen; + } -let linking = false; -export default function linkMentions($elem) { - if (linking) { return Ember.RSVP.Promise.resolve(); } - linking = true; - - return new Ember.RSVP.Promise(function(resolve) { - const $mentions = $('span.mention:not(.mention-tested):not(.mention-loading)', $elem); - if ($mentions.length) { - const usernames = $mentions.map((_, e) => $(e).text().substr(1).toLowerCase()); - - if (usernames.length) { - $mentions.addClass('mention-loading'); - const uncached = _.uniq(usernames).filter((u) => { return checked.indexOf(u) === -1; }); - - if (uncached.length) { - return Discourse.ajax("/users/is_local_username", { - data: { usernames: uncached} - }).then(function(r) { - found.push.apply(found, r.valid); - checked.push.apply(checked, uncached); - updateFound($mentions, usernames); - resolve(); - }); - } else { - updateFound($mentions, usernames); - } - } - } - - resolve(); - }).finally(() => { linking = false }); + return []; +} + +export function fetchUnseenMentions($elem, usernames) { + return Discourse.ajax("/users/is_local_username", { data: { usernames } }).then(function(r) { + found.push.apply(found, r.valid); + checked.push.apply(checked, usernames); + }); } diff --git a/app/assets/javascripts/discourse/views/composer.js.es6 b/app/assets/javascripts/discourse/views/composer.js.es6 index 03b5c50eb60..462f65a1499 100644 --- a/app/assets/javascripts/discourse/views/composer.js.es6 +++ b/app/assets/javascripts/discourse/views/composer.js.es6 @@ -3,7 +3,7 @@ import afterTransition from 'discourse/lib/after-transition'; import loadScript from 'discourse/lib/load-script'; import avatarTemplate from 'discourse/lib/avatar-template'; import positioningWorkaround from 'discourse/lib/safari-hacks'; -import linkMentions from 'discourse/lib/link-mentions'; +import { linkSeenMentions, fetchUnseenMentions } from 'discourse/lib/link-mentions'; const ComposerView = Discourse.View.extend(Ember.Evented, { _lastKeyTimeout: null, @@ -177,7 +177,17 @@ const ComposerView = Discourse.View.extend(Ember.Evented, { Discourse.Onebox.load(e, refresh); }); - linkMentions($wmdPreview).then(() => { + const unseen = linkSeenMentions($wmdPreview, this.siteSettings); + if (unseen.length) { + Ember.run.debounce(this, this._renderUnseen, $wmdPreview, unseen, 500); + } + + this.trigger('previewRefreshed', $wmdPreview); + }, + + _renderUnseen: function($wmdPreview, unseen) { + fetchUnseenMentions($wmdPreview, unseen, this.siteSettings).then(() => { + linkSeenMentions($wmdPreview, this.siteSettings); this.trigger('previewRefreshed', $wmdPreview); }); },