2021-03-28 11:06:49 +02:00
|
|
|
import { CANCELLED_STATUS } from "discourse/lib/autocomplete";
|
2020-12-22 14:01:29 +01:00
|
|
|
import { debounce } from "@ember/runloop";
|
2021-03-28 11:06:49 +02:00
|
|
|
import getUrl from "discourse-common/lib/get-url";
|
2022-03-16 14:09:23 +01:00
|
|
|
import { Promise } from "rsvp";
|
2017-11-23 10:03:19 +01:00
|
|
|
|
2021-04-12 08:26:22 +02:00
|
|
|
let cache = {},
|
2021-03-28 11:06:49 +02:00
|
|
|
cacheTopicId,
|
|
|
|
cacheTime,
|
|
|
|
currentTerm,
|
|
|
|
oldSearch;
|
|
|
|
|
|
|
|
function performSearch(
|
|
|
|
term,
|
|
|
|
topicId,
|
|
|
|
includeGroups,
|
|
|
|
includeMentionableGroups,
|
|
|
|
includeMessageableGroups,
|
|
|
|
allowedUsers,
|
|
|
|
group,
|
|
|
|
resultsFn
|
|
|
|
) {
|
2021-04-12 08:26:22 +02:00
|
|
|
let cached = cache[term];
|
2017-11-23 10:03:19 +01:00
|
|
|
if (cached) {
|
|
|
|
resultsFn(cached);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// need to be able to cancel this
|
2021-03-28 11:06:49 +02:00
|
|
|
oldSearch = $.ajax(getUrl("/u/search/users"), {
|
|
|
|
data: {
|
2021-10-27 16:05:09 +02:00
|
|
|
term,
|
2021-03-28 11:06:49 +02:00
|
|
|
topic_id: topicId,
|
|
|
|
include_groups: includeGroups,
|
|
|
|
include_mentionable_groups: includeMentionableGroups,
|
|
|
|
include_messageable_groups: includeMessageableGroups,
|
2021-10-27 16:05:09 +02:00
|
|
|
group,
|
2021-03-28 11:06:49 +02:00
|
|
|
topic_allowed_users: allowedUsers,
|
|
|
|
},
|
2017-11-23 10:03:19 +01:00
|
|
|
});
|
|
|
|
|
2021-04-12 08:26:22 +02:00
|
|
|
let returnVal = CANCELLED_STATUS;
|
2017-11-23 10:03:19 +01:00
|
|
|
|
2021-03-28 11:06:49 +02:00
|
|
|
oldSearch
|
|
|
|
.then(function (r) {
|
|
|
|
cache[term] = r;
|
|
|
|
cacheTime = new Date();
|
|
|
|
// If there is a newer search term, return null
|
|
|
|
if (term === currentTerm) {
|
|
|
|
returnVal = r;
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.always(function () {
|
|
|
|
oldSearch = null;
|
|
|
|
resultsFn(returnVal);
|
|
|
|
});
|
2017-11-23 10:03:19 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
function organizeResults(r, options) {
|
2021-03-28 11:06:49 +02:00
|
|
|
if (r === CANCELLED_STATUS) {
|
|
|
|
return r;
|
|
|
|
}
|
2017-11-23 10:03:19 +01:00
|
|
|
|
2021-04-12 08:26:22 +02:00
|
|
|
let exclude = options.exclude || [],
|
2021-03-28 11:06:49 +02:00
|
|
|
limit = options.limit || 5,
|
|
|
|
users = [],
|
|
|
|
emails = [],
|
|
|
|
groups = [],
|
|
|
|
results = [];
|
2017-11-23 10:03:19 +01:00
|
|
|
|
|
|
|
if (r.users) {
|
2021-03-28 11:06:49 +02:00
|
|
|
r.users.every(function (u) {
|
2017-11-23 10:03:19 +01:00
|
|
|
if (exclude.indexOf(u.username) === -1) {
|
|
|
|
users.push(u);
|
|
|
|
results.push(u);
|
|
|
|
}
|
|
|
|
return results.length <= limit;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
if (options.term.match(/@/)) {
|
|
|
|
let e = { username: options.term };
|
2021-03-28 11:06:49 +02:00
|
|
|
emails = [e];
|
2017-11-23 10:03:19 +01:00
|
|
|
results.push(e);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (r.groups) {
|
2021-03-28 11:06:49 +02:00
|
|
|
r.groups.every(function (g) {
|
|
|
|
if (
|
|
|
|
results.length > limit &&
|
|
|
|
options.term.toLowerCase() !== g.name.toLowerCase()
|
2021-04-12 08:26:22 +02:00
|
|
|
) {
|
2021-03-28 11:06:49 +02:00
|
|
|
return false;
|
2021-04-12 08:26:22 +02:00
|
|
|
}
|
2017-11-23 10:03:19 +01:00
|
|
|
if (exclude.indexOf(g.name) === -1) {
|
|
|
|
groups.push(g);
|
|
|
|
results.push(g);
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
results.users = users;
|
|
|
|
results.emails = emails;
|
|
|
|
results.groups = groups;
|
|
|
|
return results;
|
|
|
|
}
|
|
|
|
|
|
|
|
export default function userSearch(options) {
|
2021-04-12 08:26:22 +02:00
|
|
|
let term = options.term || "",
|
2021-03-28 11:06:49 +02:00
|
|
|
includeGroups = options.includeGroups,
|
|
|
|
includeMentionableGroups = options.includeMentionableGroups,
|
|
|
|
includeMessageableGroups = options.includeMessageableGroups,
|
|
|
|
allowedUsers = options.allowedUsers,
|
|
|
|
topicId = options.topicId,
|
|
|
|
group = options.group;
|
2017-11-23 10:03:19 +01:00
|
|
|
|
|
|
|
if (oldSearch) {
|
|
|
|
oldSearch.abort();
|
|
|
|
oldSearch = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
currentTerm = term;
|
|
|
|
|
2022-03-16 14:09:23 +01:00
|
|
|
return new Promise(function (resolve) {
|
2017-11-23 10:03:19 +01:00
|
|
|
// TODO site setting for allowed regex in username
|
|
|
|
if (term.match(/[^\w_\-\.@\+]/)) {
|
|
|
|
resolve([]);
|
|
|
|
return;
|
|
|
|
}
|
2021-03-28 11:06:49 +02:00
|
|
|
if (new Date() - cacheTime > 30000 || cacheTopicId !== topicId) {
|
2017-11-23 10:03:19 +01:00
|
|
|
cache = {};
|
|
|
|
}
|
|
|
|
|
|
|
|
cacheTopicId = topicId;
|
|
|
|
|
2021-04-12 08:26:22 +02:00
|
|
|
let clearPromise = setTimeout(function () {
|
2017-11-23 10:03:19 +01:00
|
|
|
resolve(CANCELLED_STATUS);
|
|
|
|
}, 5000);
|
|
|
|
|
2021-01-04 07:22:43 +01:00
|
|
|
// TODO: Use discouseDebounce after it is available on stable.
|
|
|
|
debounce(
|
2020-12-22 14:01:29 +01:00
|
|
|
this,
|
2021-03-28 11:06:49 +02:00
|
|
|
function () {
|
2020-12-22 14:01:29 +01:00
|
|
|
performSearch(
|
|
|
|
term,
|
|
|
|
topicId,
|
|
|
|
includeGroups,
|
|
|
|
includeMentionableGroups,
|
|
|
|
includeMessageableGroups,
|
|
|
|
allowedUsers,
|
|
|
|
group,
|
2021-03-28 11:06:49 +02:00
|
|
|
function (r) {
|
2020-12-22 14:01:29 +01:00
|
|
|
clearTimeout(clearPromise);
|
|
|
|
resolve(organizeResults(r, options));
|
|
|
|
}
|
2021-03-28 11:06:49 +02:00
|
|
|
);
|
2020-12-22 14:01:29 +01:00
|
|
|
},
|
|
|
|
300
|
2021-03-28 11:06:49 +02:00
|
|
|
);
|
2021-01-04 07:22:43 +01:00
|
|
|
});
|
2017-11-23 10:03:19 +01:00
|
|
|
}
|