Add method to determine references from message text
This commit is contained in:
parent
e10d9b074e
commit
f2b017ec89
|
@ -13,7 +13,7 @@
|
|||
const Strophe = converse.env.Strophe;
|
||||
const u = converse.env.utils;
|
||||
|
||||
return describe("A groupchat textarea", function () {
|
||||
describe("The nickname autocomplete feature", function () {
|
||||
|
||||
it("shows all autocompletion options when the user presses @",
|
||||
mock.initConverseWithPromises(
|
||||
|
@ -146,7 +146,7 @@
|
|||
'stopPropagation': _.noop,
|
||||
'keyCode': 13 // Enter
|
||||
});
|
||||
expect(textarea.value).toBe('hello s some2 ');
|
||||
expect(textarea.value).toBe('hello s @some2 ');
|
||||
|
||||
// Test that pressing tab twice selects
|
||||
presence = $pres({
|
||||
|
@ -166,7 +166,7 @@
|
|||
|
||||
view.keyPressed(tab_event);
|
||||
view.keyUp(tab_event);
|
||||
expect(textarea.value).toBe('hello z3r0 ');
|
||||
expect(textarea.value).toBe('hello @z3r0 ');
|
||||
|
||||
done();
|
||||
}).catch(_.partial(console.error, _));
|
||||
|
|
|
@ -1202,6 +1202,60 @@
|
|||
});
|
||||
}));
|
||||
|
||||
describe("in which someone is mentioned", function () {
|
||||
|
||||
it("includes XEP-0372 references to that person",
|
||||
mock.initConverseWithPromises(
|
||||
null, ['rosterGroupsFetched'], {},
|
||||
function (done, _converse) {
|
||||
|
||||
test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'tom')
|
||||
.then(() => {
|
||||
const view = _converse.chatboxviews.get('lounge@localhost');
|
||||
['z3r0', 'mr.robot', 'gibson', 'sw0rdf1sh'].forEach((nick) => {
|
||||
_converse.connection._dataRecv(test_utils.createRequest(
|
||||
$pres({
|
||||
'to': 'tom@localhost/resource',
|
||||
'from': `lounge@localhost/${nick}`
|
||||
})
|
||||
.c('x', {xmlns: Strophe.NS.MUC_USER})
|
||||
.c('item', {
|
||||
'affiliation': 'none',
|
||||
'jid': `${nick}@localhost/resource`,
|
||||
'role': 'participant'
|
||||
})));
|
||||
});
|
||||
|
||||
let [text, references] = view.model.parseForReferences('hello z3r0')
|
||||
expect(references.length).toBe(0);
|
||||
expect(text).toBe('hello z3r0');
|
||||
|
||||
[text, references] = view.model.parseForReferences('hello @z3r0')
|
||||
expect(references.length).toBe(1);
|
||||
expect(text).toBe('hello z3r0');
|
||||
expect(JSON.stringify(references))
|
||||
.toBe('[{"begin":6,"end":10,"type":"mention","uri":"xmpp:z3r0@localhost"}]');
|
||||
|
||||
[text, references] = view.model.parseForReferences('hello @some1 @z3r0 @gibson @mr.robot, how are you?')
|
||||
expect(text).toBe('hello @some1 z3r0 gibson mr.robot, how are you?');
|
||||
expect(JSON.stringify(references))
|
||||
.toBe('[{"begin":13,"end":17,"type":"mention","uri":"xmpp:z3r0@localhost"},'+
|
||||
'{"begin":18,"end":24,"type":"mention","uri":"xmpp:gibson@localhost"},'+
|
||||
'{"begin":25,"end":33,"type":"mention","uri":"xmpp:mr.robot@localhost"}]');
|
||||
|
||||
[text, references] = view.model.parseForReferences('yo @gib')
|
||||
expect(text).toBe('yo @gib');
|
||||
expect(references.length).toBe(0);
|
||||
|
||||
[text, references] = view.model.parseForReferences('yo @gibsonian')
|
||||
expect(text).toBe('yo @gibsonian');
|
||||
expect(references.length).toBe(0);
|
||||
done();
|
||||
}).catch(_.partial(console.error, _));
|
||||
}));
|
||||
});
|
||||
|
||||
|
||||
describe("when received from someone else", function () {
|
||||
|
||||
it("will open a chatbox and be displayed inside it",
|
||||
|
|
|
@ -237,7 +237,6 @@
|
|||
} else {
|
||||
selected = this.ul.children[this.index];
|
||||
}
|
||||
|
||||
if (selected) {
|
||||
const suggestion = this.suggestions[this.index];
|
||||
this.insertValue(suggestion);
|
||||
|
|
|
@ -617,7 +617,7 @@
|
|||
'min_chars': 1,
|
||||
'match_current_word': true,
|
||||
'match_on_tab': true,
|
||||
'list': () => this.model.occupants.map(o => ({'label': o.get('nick'), 'value': o.get('nick')})),
|
||||
'list': () => this.model.occupants.map(o => ({'label': o.get('nick'), 'value': `@${o.get('nick')}`})),
|
||||
'filter': _converse.FILTER_STARTSWITH,
|
||||
'trigger_on_at': true
|
||||
});
|
||||
|
|
|
@ -308,14 +308,75 @@
|
|||
_converse.connection.sendPresence(presence);
|
||||
},
|
||||
|
||||
getReferenceForMention (mention, index) {
|
||||
const longest_match = u.getLongestSubstring(mention, this.occupants.map(o => o.get('nick')));
|
||||
if (!longest_match) {
|
||||
return null;
|
||||
}
|
||||
if ((mention[longest_match.length] || '').match(/[A-Za-zäëïöüâêîôûáéíóúàèìòùÄËÏÖÜÂÊÎÔÛÁÉÍÓÚÀÈÌÒÙ]/i)) {
|
||||
// avoid false positives, i.e. mentions that have
|
||||
// further alphabetical characters than our longest
|
||||
// match.
|
||||
return null;
|
||||
}
|
||||
const occupant = this.occupants.findOccupant({'nick': longest_match});
|
||||
if (!occupant) {
|
||||
return null;
|
||||
}
|
||||
const obj = {
|
||||
'begin': index,
|
||||
'end': index + longest_match.length,
|
||||
'type': 'mention'
|
||||
};
|
||||
if (occupant.get('jid')) {
|
||||
obj.uri = `xmpp:${occupant.get('jid')}`
|
||||
}
|
||||
return obj;
|
||||
},
|
||||
|
||||
extractReference (text, index) {
|
||||
for (let i=index; i<text.length; i++) {
|
||||
if (text[i] !== '@') {
|
||||
continue
|
||||
} else {
|
||||
const match = text.slice(i+1),
|
||||
ref = this.getReferenceForMention(match, i)
|
||||
if (ref) {
|
||||
return [text.slice(0, i) + match, ref, i]
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
},
|
||||
|
||||
parseForReferences (text) {
|
||||
const refs = [];
|
||||
let index = 0;
|
||||
while (index < (text || '').length) {
|
||||
const result = this.extractReference(text, index);
|
||||
if (result) {
|
||||
text = result[0]; // @ gets filtered out
|
||||
refs.push(result[1]);
|
||||
index = result[2];
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return [text, refs];
|
||||
},
|
||||
|
||||
getOutgoingMessageAttributes (text, spoiler_hint) {
|
||||
const is_spoiler = this.get('composing_spoiler');
|
||||
var references;
|
||||
[text, references] = this.parseForReferences(text);
|
||||
|
||||
return {
|
||||
'nick': this.get('nick'),
|
||||
'from': `${this.get('jid')}/${this.get('nick')}`,
|
||||
'fullname': this.get('nick'),
|
||||
'is_spoiler': is_spoiler,
|
||||
'message': text ? u.httpToGeoUri(emojione.shortnameToUnicode(text), _converse) : undefined,
|
||||
'nick': this.get('nick'),
|
||||
'references': references,
|
||||
'sender': 'me',
|
||||
'spoiler_hint': is_spoiler ? spoiler_hint : undefined,
|
||||
'type': 'groupchat'
|
||||
|
|
|
@ -98,6 +98,21 @@
|
|||
|
||||
var u = {};
|
||||
|
||||
u.getLongestSubstring = function (string, candidates) {
|
||||
function reducer (accumulator, current_value) {
|
||||
if (string.startsWith(current_value)) {
|
||||
if (current_value.length > accumulator.length) {
|
||||
return current_value;
|
||||
} else {
|
||||
return accumulator;
|
||||
}
|
||||
} else {
|
||||
return accumulator;
|
||||
}
|
||||
}
|
||||
return candidates.reduce(reducer, '');
|
||||
}
|
||||
|
||||
u.getNextElement = function (el, selector='*') {
|
||||
let next_el = el.nextElementSibling;
|
||||
while (!_.isNull(next_el) && !sizzle.matchesSelector(next_el, selector)) {
|
||||
|
|
Loading…
Reference in New Issue
Block a user