diff --git a/spec/muc_messages.js b/spec/muc_messages.js
index 86f33a5bc..475f53bd3 100644
--- a/spec/muc_messages.js
+++ b/spec/muc_messages.js
@@ -652,7 +652,7 @@
from="${msg_obj.get('from')}"
to="${_converse.connection.jid}"
type="groupchat">
- ${msg_obj.get('message')}
+
${msg_obj.get('message')}
@@ -878,6 +878,17 @@
})));
});
+ // Also check that nicks from received messages, (but for which
+ // we don't have occupant objects) can be mentioned.
+ const stanza = u.toStanza(`
+
+ Boo!
+ `);
+ await view.model.onMessage(stanza);
+
// Run a few unit tests for the parseTextForReferences method
let [text, references] = view.model.parseTextForReferences('hello z3r0')
expect(references.length).toBe(0);
@@ -935,6 +946,12 @@
expect(references.length).toBe(0);
expect(JSON.stringify(references))
.toBe('[]');
+
+ [text, references] = view.model.parseTextForReferences('@gh0st where are you?')
+ expect(text).toBe('gh0st where are you?');
+ expect(references.length).toBe(1);
+ expect(JSON.stringify(references))
+ .toBe('[{"begin":0,"end":5,"value":"gh0st","type":"mention","uri":"xmpp:lounge@montague.lit/gh0st"}]');
done();
}));
diff --git a/src/converse-muc-views.js b/src/converse-muc-views.js
index 4849754d7..e3a66f02c 100644
--- a/src/converse-muc-views.js
+++ b/src/converse-muc-views.js
@@ -845,12 +845,7 @@ converse.plugins.add('converse-muc-views', {
},
getAutoCompleteList () {
- // Create an array of unique nicknames based on the occupants and messages.
- const nicks = [...new Set([
- ...this.model.occupants.map(o => o.get('nick')),
- ...this.model.messages.map(m => m.get('nick'))
- ])].filter(n => n);
- return nicks.map(nick => ({'label': nick, 'value': `@${nick}`}));
+ return this.model.getAllKnownNicknames().map(nick => ({'label': nick, 'value': `@${nick}`}));
},
getAutoCompleteListItem(text, input) {
diff --git a/src/headless/converse-muc.js b/src/headless/converse-muc.js
index 437b93a69..98a3b5507 100644
--- a/src/headless/converse-muc.js
+++ b/src/headless/converse-muc.js
@@ -829,11 +829,22 @@ converse.plugins.add('converse-muc', {
_converse.connection.sendPresence(presence);
},
+ /**
+ * Return an array of unique nicknames based on all occupants and messages in this MUC.
+ * @private
+ * @method _converse.ChatRoom#getAllKnownNicknames
+ * @returns { String[] }
+ */
+ getAllKnownNicknames () {
+ return [...new Set([
+ ...this.occupants.map(o => o.get('nick')),
+ ...this.messages.map(m => m.get('nick'))
+ ])].filter(n => n);
+ },
+
getReferenceForMention (mention, index) {
- const longest_match = u.getLongestSubstring(
- mention,
- this.occupants.map(o => o.getDisplayName())
- );
+ const nicknames = this.getAllKnownNicknames();
+ const longest_match = u.getLongestSubstring(mention, nicknames);
if (!longest_match) {
return null;
}
@@ -843,22 +854,26 @@ converse.plugins.add('converse-muc', {
// match.
return null;
}
+
+ let uri;
const occupant = this.occupants.findOccupant({'nick': longest_match}) ||
- this.occupants.findOccupant({'jid': longest_match});
- if (!occupant) {
- return null;
+ u.isValidJID(longest_match) && this.occupants.findOccupant({'jid': longest_match});
+
+ if (occupant) {
+ uri = occupant.get('jid') || `${this.get('jid')}/${occupant.get('nick')}`;
+ } else if (nicknames.includes(longest_match)) {
+ // TODO: show a warning to the user that the person is not currently in the chat
+ uri = `${this.get('jid')}/${longest_match}`;
+ } else {
+ return;
}
const obj = {
'begin': index,
'end': index + longest_match.length,
'value': longest_match,
- 'type': 'mention'
+ 'type': 'mention',
+ 'uri': encodeURI(`xmpp:${uri}`)
};
- if (occupant.get('jid')) {
- obj.uri = encodeURI(`xmpp:${occupant.get('jid')}`);
- } else {
- obj.uri = encodeURI(`xmpp:${this.get('jid')}/${occupant.get('nick')}`);
- }
return obj;
},
@@ -898,16 +913,16 @@ converse.plugins.add('converse-muc', {
const origin_id = u.getUniqueId();
return {
+ is_spoiler,
+ origin_id,
+ references,
'id': origin_id,
'msgid': origin_id,
- 'origin_id': origin_id,
'from': `${this.get('jid')}/${this.get('nick')}`,
'fullname': this.get('nick'),
'is_only_emojis': text ? u.isOnlyEmojis(text) : false,
- 'is_spoiler': is_spoiler,
'message': text ? u.httpToGeoUri(u.shortnameToUnicode(text), _converse) : undefined,
'nick': this.get('nick'),
- 'references': references,
'sender': 'me',
'spoiler_hint': is_spoiler ? spoiler_hint : undefined,
'type': 'groupchat'
@@ -915,9 +930,9 @@ converse.plugins.add('converse-muc', {
},
/**
- * Utility method to construct the JID for the current user
- * as occupant of the groupchat.
- *
+ * Utility method to construct the JID for the current user as occupant of the groupchat.
+ * @private
+ * @method _converse.ChatRoom#getRoomJIDAndNick
* @returns {string} - The groupchat JID with the user's nickname added at the end.
* @example groupchat@conference.example.org/nickname
*/