MUC: create references for nicks gathered from messages

This commit is contained in:
JC Brand 2020-02-21 12:30:37 +01:00
parent 2ac33c77b3
commit 3c9ec96350
3 changed files with 53 additions and 26 deletions

View File

@ -652,7 +652,7 @@
from="${msg_obj.get('from')}"
to="${_converse.connection.jid}"
type="groupchat">
<msg_body>${msg_obj.get('message')}</msg_body>
<body>${msg_obj.get('message')}</body>
<stanza-id xmlns="urn:xmpp:sid:0"
id="5f3dbc5e-e1d3-4077-a492-693f3769c7ad"
by="lounge@montague.lit"/>
@ -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(`
<message xmlns="jabber:client"
from="${muc_jid}/gh0st"
to="${_converse.connection.bare_jid}"
type="groupchat">
<body>Boo!</body>
</message>`);
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();
}));

View File

@ -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) {

View File

@ -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
*/