nodebb-plugin-mentions 4.4.4 → 4.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/library.js +23 -6
- package/package.json +1 -1
- package/static/autofill.js +41 -14
package/library.js
CHANGED
|
@@ -12,6 +12,7 @@ const winston = require.main.require('winston');
|
|
|
12
12
|
const db = require.main.require('./src/database');
|
|
13
13
|
const api = require.main.require('./src/api');
|
|
14
14
|
const meta = require.main.require('./src/meta');
|
|
15
|
+
const categories = require.main.require('./src/categories');
|
|
15
16
|
const Topics = require.main.require('./src/topics');
|
|
16
17
|
const posts = require.main.require('./src/posts');
|
|
17
18
|
const User = require.main.require('./src/user');
|
|
@@ -393,18 +394,34 @@ Mentions.parseRaw = async (content) => {
|
|
|
393
394
|
const slug = slugify(match.slice(1));
|
|
394
395
|
match = removePunctuationSuffix(match);
|
|
395
396
|
const uid = await User.getUidByUserslug(slug);
|
|
396
|
-
const
|
|
397
|
+
const cid = await categories.getCidByHandle(slug);
|
|
398
|
+
const { groupExists, user, category } = await utils.promiseParallel({
|
|
397
399
|
groupExists: Groups.existsBySlug(slug),
|
|
398
400
|
user: User.getUserFields(uid, ['uid', 'username', 'fullname', 'url']),
|
|
401
|
+
category: categories.getCategoryFields(cid, ['slug']),
|
|
399
402
|
});
|
|
400
403
|
|
|
401
|
-
if (
|
|
404
|
+
if (uid || groupExists || cid) {
|
|
402
405
|
let url;
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
406
|
+
|
|
407
|
+
switch (true) {
|
|
408
|
+
case !!uid: {
|
|
409
|
+
url = utils.isNumber(user.uid) ? `${nconf.get('url')}/uid/${user.uid}` : (user.url || user.uid);
|
|
410
|
+
break;
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
case !!cid: {
|
|
414
|
+
url = `${nconf.get('url')}/category/${category.slug}`;
|
|
415
|
+
console.log('setting url', url);
|
|
416
|
+
break;
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
case !!groupExists: {
|
|
420
|
+
url = `${nconf.get('url')}/groups/${slug}`;
|
|
421
|
+
break;
|
|
422
|
+
}
|
|
407
423
|
}
|
|
424
|
+
|
|
408
425
|
const regex = isLatinMention.test(match) ?
|
|
409
426
|
RegExp(`${parts.before}${match}${parts.after}`, 'gu') :
|
|
410
427
|
RegExp(`${parts.before}${match}`, 'gu');
|
package/package.json
CHANGED
package/static/autofill.js
CHANGED
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
|
|
4
4
|
$(document).ready(function () {
|
|
5
5
|
let groupList = [];
|
|
6
|
+
let categoryList;
|
|
7
|
+
const categorySlugMap = new Map();
|
|
6
8
|
let localUserList = [];
|
|
7
9
|
|
|
8
10
|
$(window).on('composer:autocomplete:init chat:autocomplete:init', function (ev, data) {
|
|
@@ -12,6 +14,10 @@ $(document).ready(function () {
|
|
|
12
14
|
loadGroupList();
|
|
13
15
|
}
|
|
14
16
|
|
|
17
|
+
if (!categoryList) {
|
|
18
|
+
loadCategoryList();
|
|
19
|
+
}
|
|
20
|
+
|
|
15
21
|
let slugify;
|
|
16
22
|
const strategy = {
|
|
17
23
|
match: /\B@([^\s\n]*)?$/,
|
|
@@ -20,7 +26,7 @@ $(document).ready(function () {
|
|
|
20
26
|
slugify = _slugify;
|
|
21
27
|
let mentions = [];
|
|
22
28
|
if (!term) {
|
|
23
|
-
mentions =
|
|
29
|
+
mentions = entriesToMentions(sortEntries(localUserList), helpers);
|
|
24
30
|
return callback(mentions);
|
|
25
31
|
}
|
|
26
32
|
|
|
@@ -37,10 +43,12 @@ $(document).ready(function () {
|
|
|
37
43
|
const localMatches = localUserList.filter(
|
|
38
44
|
u => u.username.toLocaleLowerCase().startsWith(termLowerCase)
|
|
39
45
|
);
|
|
46
|
+
const categoryMatches = categoryList.filter(c => c.handle.startsWith(termLowerCase));
|
|
40
47
|
|
|
41
|
-
// remove local matches from search results
|
|
48
|
+
// remove local matches from search results, add category matches
|
|
42
49
|
users = users.filter(u => !localMatches.find(lu => lu.uid === u.uid));
|
|
43
|
-
|
|
50
|
+
users = sortEntries(localMatches).concat(sortEntries([...users, ...categoryMatches]));
|
|
51
|
+
mentions = entriesToMentions(users, helpers);
|
|
44
52
|
|
|
45
53
|
// Add groups that start with the search term
|
|
46
54
|
const groupMentions = groupList.filter(function (groupName) {
|
|
@@ -62,7 +70,14 @@ $(document).ready(function () {
|
|
|
62
70
|
mention = $('<div/>').html(mention);
|
|
63
71
|
// Strip letter avatar
|
|
64
72
|
mention.find('span').remove();
|
|
65
|
-
|
|
73
|
+
|
|
74
|
+
const text = mention.text().trim();
|
|
75
|
+
const categoryHandle = categorySlugMap.get(text.toLowerCase());
|
|
76
|
+
if (categoryHandle) {
|
|
77
|
+
return `@${categoryHandle}`;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return '@' + slugify(text, true) + ' ';
|
|
66
81
|
},
|
|
67
82
|
cache: true,
|
|
68
83
|
};
|
|
@@ -75,23 +90,25 @@ $(document).ready(function () {
|
|
|
75
90
|
composer.attr('data-mentions', '1');
|
|
76
91
|
});
|
|
77
92
|
|
|
78
|
-
function
|
|
79
|
-
return
|
|
80
|
-
|
|
93
|
+
function sortEntries(entries) {
|
|
94
|
+
return entries.sort(function (entry1, entry2) {
|
|
95
|
+
const comparator1 = entry1.username || entry1.name;
|
|
96
|
+
const comparator2 = entry2.username || entry2.name;
|
|
97
|
+
return comparator1.toLocaleLowerCase() > comparator2.toLocaleLowerCase() ? 1 : -1;
|
|
81
98
|
});
|
|
82
99
|
}
|
|
83
100
|
|
|
84
|
-
function
|
|
85
|
-
return
|
|
101
|
+
function entriesToMentions(entries, helpers) {
|
|
102
|
+
return entries.reduce(function (carry, entry) {
|
|
86
103
|
// Don't add current user to suggestions
|
|
87
|
-
if (app.user.username && app.user.username ===
|
|
104
|
+
if (app.user.username && app.user.username === entry.username) {
|
|
88
105
|
return carry;
|
|
89
106
|
}
|
|
90
107
|
|
|
91
|
-
// Format suggestions as 'avatar username (fullname)'
|
|
92
|
-
const avatar = helpers.buildAvatar(
|
|
93
|
-
const fullname =
|
|
94
|
-
carry.push(`${avatar} ${
|
|
108
|
+
// Format suggestions as 'avatar username/name (fullname)'
|
|
109
|
+
const avatar = entry.uid ? helpers.buildAvatar(entry, '24px', true) : '';
|
|
110
|
+
const fullname = entry.fullname ? `(${entry.fullname})` : '';
|
|
111
|
+
carry.push(`${avatar} ${entry.username || entry.name} ${helpers.escape(fullname)}`);
|
|
95
112
|
|
|
96
113
|
return carry;
|
|
97
114
|
}, []);
|
|
@@ -141,4 +158,14 @@ $(document).ready(function () {
|
|
|
141
158
|
groupList = groupNames;
|
|
142
159
|
});
|
|
143
160
|
}
|
|
161
|
+
|
|
162
|
+
function loadCategoryList() {
|
|
163
|
+
require(['api'], async (api) => {
|
|
164
|
+
const { categories } = await api.get('/categories');
|
|
165
|
+
categoryList = categories;
|
|
166
|
+
categories.forEach((category) => {
|
|
167
|
+
categorySlugMap.set(category.name.toLowerCase(), category.handle);
|
|
168
|
+
});
|
|
169
|
+
});
|
|
170
|
+
}
|
|
144
171
|
});
|