@jsxc/jsxc
Version:
Real-time XMPP chat application with video calls, file transfer and encrypted communication
143 lines (113 loc) • 4.52 kB
text/typescript
import Log from '../../../../util/Log';
import JID from '../../../../JID';
import Message from '../../../../Message';
import Translation from '../../../../util/Translation';
import MultiUserContact from '../../../../MultiUserContact';
import AbstractHandler from '../../AbstractHandler';
import { MessageMark } from '@src/Message.interface';
import MultiUserStatusCodeHandler from './StatusCodeHandler';
// body.replace(/^\/me /, '<i title="/me">' + Utils.removeHTML(this.sender.getName()) + '</i> ');
export default class extends AbstractHandler {
public processStanza(stanza: Element) {
let messageElement = $(stanza);
let from = new JID(stanza.getAttribute('from'));
let subjectElement = messageElement.find('subject');
let bodyElement = messageElement.find('>body:first');
let originId = messageElement.find('origin-id[xmlns="urn:xmpp:sid:0"]').attr('id');
let stanzaId = messageElement.find('stanza-id[xmlns="urn:xmpp:sid:0"]').attr('id');
let attrId = messageElement.attr('id');
let body = bodyElement.text();
let nickname = from.resource;
let contact = <MultiUserContact>this.account.getContact(from);
if (typeof contact === 'undefined') {
Log.info('Sender is not in our contact list');
return this.PRESERVE_HANDLER;
}
if (contact.getType() !== 'groupchat') {
Log.info('This groupchat message is not intended for a MultiUserContact');
return this.PRESERVE_HANDLER;
}
if (subjectElement.length === 1 && bodyElement.length === 0) {
let subject = subjectElement.text();
let oldSubject = contact.getSubject();
if (subject === oldSubject) {
return this.PRESERVE_HANDLER;
}
contact.setSubject(subject);
let translatedMessage = Translation.t('changed_subject_to', {
nickname,
subject,
});
contact.addSystemMessage(':page_with_curl: ' + translatedMessage);
return this.PRESERVE_HANDLER;
}
if (!nickname) {
const codes = $(stanza)
.find('x[xmlns="http://jabber.org/protocol/muc#user"]')
.find('status')
.map((index, element) => element.getAttribute('code'))
.get();
MultiUserStatusCodeHandler.processCodes(codes, contact);
}
if (body === '') {
return this.PRESERVE_HANDLER;
}
let delay = messageElement.find('delay[xmlns="urn:xmpp:delay"]');
let sendDate = delay.length > 0 ? new Date(delay.attr('stamp')) : new Date();
let afterJoin = sendDate > contact.getJoinDate();
let direction = afterJoin ? Message.DIRECTION.IN : Message.DIRECTION.PROBABLY_IN;
let transcript = contact.getTranscript();
if (!afterJoin) {
if (Message.exists(originId) || Message.exists(stanzaId)) {
return this.PRESERVE_HANDLER;
}
for (let message of transcript.getGenerator()) {
if (message.getAttrId() === attrId && message.getPlaintextMessage() === body) {
return this.PRESERVE_HANDLER;
}
}
}
let member = contact.getMember(nickname);
let uid = stanzaId || originId;
let unread = afterJoin;
let sender = {
name: nickname,
jid: member && member.jid,
};
if (contact.getNickname() === nickname) {
if (afterJoin) {
if (Message.exists(originId)) {
let message = new Message(originId);
message.received();
return this.PRESERVE_HANDLER;
}
direction = Message.DIRECTION.OUT;
uid = originId;
unread = false;
sender = undefined;
} else {
direction = Message.DIRECTION.PROBABLY_OUT;
}
}
let message = new Message({
uid,
attrId,
peer: from,
direction,
plaintextMessage: body,
// htmlMessage: htmlBody.html(),
stamp: sendDate.getTime(),
sender,
unread,
mark: MessageMark.transferred,
});
if (direction === Message.DIRECTION.OUT) {
message.received();
}
let pipe = this.account.getPipe('afterReceiveGroupMessage');
pipe.run(contact, message, messageElement.get(0)).then(([contact, message]) => {
contact.getTranscript().pushMessage(message);
});
return this.PRESERVE_HANDLER;
}
}