Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/jsxc/jsxc.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsualko <klaus@jsxc.org>2019-05-24 16:16:57 +0300
committersualko <klaus@jsxc.org>2019-05-24 16:16:57 +0300
commitc211ff6b85b73d72715ef366f6c0c767d1fb1beb (patch)
tree89d64c207798159f86fbe15d9a7649a659115ccb
parent60fdc20b6cb1348f47a4cbef8a0dc6ba31eadfeb (diff)
fix: mam archive selectionrefactoring
-rw-r--r--src/Contact.interface.ts4
-rw-r--r--src/Contact.ts8
-rw-r--r--src/connection/AbstractConnection.ts11
-rw-r--r--src/connection/Connection.interface.ts2
-rw-r--r--src/plugin/PluginAPI.interface.ts5
-rw-r--r--src/plugin/PluginAPI.ts8
-rw-r--r--src/plugins/mam/Archive.ts42
-rw-r--r--src/plugins/mam/Plugin.ts113
8 files changed, 130 insertions, 63 deletions
diff --git a/src/Contact.interface.ts b/src/Contact.interface.ts
index 2be8797f..d601ccaf 100644
--- a/src/Contact.interface.ts
+++ b/src/Contact.interface.ts
@@ -63,6 +63,10 @@ export interface IContact {
getType(): ContactType;
+ isGroupChat(): boolean;
+
+ isChat(): boolean;
+
getNumberOfUnreadMessages(): number;
hasName(): boolean;
diff --git a/src/Contact.ts b/src/Contact.ts
index f6675d91..c9b9c315 100644
--- a/src/Contact.ts
+++ b/src/Contact.ts
@@ -220,6 +220,14 @@ export default class Contact implements IIdentifiable, IContact {
return this.data.get('type');
}
+ public isGroupChat() {
+ return this.getType() === ContactType.GROUPCHAT;
+ }
+
+ public isChat() {
+ return this.getType() === ContactType.CHAT;
+ }
+
public getNumberOfUnreadMessages(): number {
return this.transcript.getNumberOfUnreadMessages();
}
diff --git a/src/connection/AbstractConnection.ts b/src/connection/AbstractConnection.ts
index e3f847be..ba68c494 100644
--- a/src/connection/AbstractConnection.ts
+++ b/src/connection/AbstractConnection.ts
@@ -184,13 +184,14 @@ abstract class AbstractConnection {
this.send(presenceStanza);
}
- public queryArchive(archive: JID, queryId: string, beforeResultId?: string, end?: Date): Promise<Element> {
+ public queryArchive(archive: JID, version: string, contact: JID, queryId: string, beforeResultId?: string, end?: Date): Promise<Element> {
let iq = $iq({
- type: 'set'
+ type: 'set',
+ to: archive.bare,
});
iq.c('query', {
- xmlns: NS.get('MAM'),
+ xmlns: version,
queryid: queryId
});
@@ -202,11 +203,11 @@ abstract class AbstractConnection {
iq.c('field', {
var: 'FORM_TYPE',
type: 'hidden'
- }).c('value').t(NS.get('MAM')).up().up();
+ }).c('value').t(version).up().up();
iq.c('field', {
var: 'with'
- }).c('value').t(archive.bare).up().up();
+ }).c('value').t(contact.bare).up().up();
if (end) {
iq.c('field', {
diff --git a/src/connection/Connection.interface.ts b/src/connection/Connection.interface.ts
index 66abdd87..96860681 100644
--- a/src/connection/Connection.interface.ts
+++ b/src/connection/Connection.interface.ts
@@ -36,7 +36,7 @@ export interface IConnection {
sendPresence(presence?: Presence)
- queryArchive(archive: IJID, queryId: string, beforeResultId?: string, end?: Date): Promise<Element>
+ queryArchive(archive: IJID, version: string, contact: IJID, queryId: string, beforeResultId?: string, end?: Date): Promise<Element>
close()
}
diff --git a/src/plugin/PluginAPI.interface.ts b/src/plugin/PluginAPI.interface.ts
index ec46b3f9..a474daef 100644
--- a/src/plugin/PluginAPI.interface.ts
+++ b/src/plugin/PluginAPI.interface.ts
@@ -8,6 +8,7 @@ import ChatWindow from '@ui/ChatWindow';
import ContactManager from '@src/ContactManager';
import ContactProvider from '@src/ContactProvider';
import { IAvatar } from '@src/Avatar.interface';
+import Pipe from '@util/Pipe';
export interface IPluginAPI {
@@ -57,4 +58,8 @@ export interface IPluginAPI {
registerContactProvider(source: ContactProvider)
getContactManager(): ContactManager
+
+ getAfterReceiveGroupMessagePipe(): Pipe
+
+ getAfterReceiveMessagePipe(): Pipe
}
diff --git a/src/plugin/PluginAPI.ts b/src/plugin/PluginAPI.ts
index bc242ccf..c851065d 100644
--- a/src/plugin/PluginAPI.ts
+++ b/src/plugin/PluginAPI.ts
@@ -142,4 +142,12 @@ export default class PluginAPI implements IPluginAPI {
public getContactManager(): ContactManager {
return this.account.getContactManager();
}
+
+ public getAfterReceiveGroupMessagePipe() {
+ return this.account.getPipe('afterReceiveGroupMessage');
+ }
+
+ public getAfterReceiveMessagePipe() {
+ return this.account.getPipe('afterReceiveMessage');
+ }
}
diff --git a/src/plugins/mam/Archive.ts b/src/plugins/mam/Archive.ts
index 9696819e..0318fc41 100644
--- a/src/plugins/mam/Archive.ts
+++ b/src/plugins/mam/Archive.ts
@@ -8,14 +8,19 @@ import Log from '../../util/Log'
import Translation from '../../util/Translation'
import * as Namespace from '../../connection/xmpp/namespace'
import { IMessage } from '@src/Message.interface';
+import { IJID } from '@src/JID.interface';
+import MultiUserContact from '@src/MultiUserContact';
export default class Archive {
private previousMessage: IMessage;
private lastMessageId: string;
private connected: boolean;
+ private archiveJid: IJID;
constructor(private plugin: MessageArchiveManagementPlugin, private contact: Contact) {
+ let jid = contact.isGroupChat() ? contact.getJid() : plugin.getConnection().getJID();
+ this.archiveJid = new JID(jid.bare);
}
public clear() {
@@ -73,8 +78,13 @@ export default class Archive {
}
let connection = this.plugin.getConnection();
- connection.queryArchive(this.contact.getJid(), queryId, firstResultId, endDate)
- .then(this.onComplete)
+ this.plugin.determineServerSupport(this.archiveJid).then(version => {
+ if (!version) {
+ throw new Error(`Archive JID ${this.archiveJid.full} has no support for MAM.`);
+ }
+
+ return connection.queryArchive(this.archiveJid, <string> version, this.contact.getJid(), queryId, firstResultId, endDate);
+ }).then(this.onComplete)
.catch((stanza) => {
Log.warn('Error while requesting archive', stanza);
});
@@ -88,11 +98,10 @@ export default class Archive {
return;
}
- let ownJid = this.plugin.getConnection().getJID();
let from = new JID(messageElement.attr('from'));
let to = new JID(messageElement.attr('to'));
- if (ownJid.bare !== from.bare && ownJid.bare !== to.bare) {
+ if (this.archiveJid.bare !== from.bare && this.archiveJid.bare !== to.bare) {
return;
}
@@ -117,7 +126,7 @@ export default class Archive {
if (Message.exists(uid)) {
message = new Message(uid);
} else {
- message = new Message({
+ let messageProperties = {
uid,
attrId: messageId,
peer: this.contact.getJid(),
@@ -126,7 +135,26 @@ export default class Archive {
htmlMessage: htmlBody.html(),
stamp: stamp.getTime(),
unread: false,
- });
+ sender: undefined,
+ };
+
+ if (this.contact.isGroupChat()) {
+ messageProperties.sender = {
+ name: from.resource,
+ };
+
+ let contact = <MultiUserContact> this.contact;
+
+ messageProperties.direction = contact.getNickname() === from.resource ? Message.DIRECTION.OUT : Message.DIRECTION.IN;
+ }
+
+ message = new Message(messageProperties);
+
+ if (this.contact.isChat()) {
+ this.plugin.runAfterReceiveMessagePipe(this.contact, message, messageElement);
+ } else if (this.contact.isGroupChat()) {
+ this.plugin.runAfterReceiveGroupMessagePipe(this.contact, message);
+ }
}
if (this.previousMessage) {
@@ -142,7 +170,7 @@ export default class Archive {
public onComplete = (stanza) => {
let stanzaElement = $(stanza);
- let finElement = stanzaElement.find(`fin` + Namespace.getFilter('MAM'));
+ let finElement = stanzaElement.find(`fin[xmlns^="urn:xmpp:mam:"]`);
if (finElement.length !== 1) {
Log.warn('No fin element found');
diff --git a/src/plugins/mam/Plugin.ts b/src/plugins/mam/Plugin.ts
index 55c5222e..4d584577 100644
--- a/src/plugins/mam/Plugin.ts
+++ b/src/plugins/mam/Plugin.ts
@@ -6,11 +6,10 @@ import JID from '../../JID'
import { IJID } from '../../JID.interface'
import * as Namespace from '../../connection/xmpp/namespace'
import Archive from './Archive'
-import DiscoInfo from '../../DiscoInfo'
-import { Status } from '../../vendor/Strophe'
import Contact from '@src/Contact';
import PluginAPI from '@src/plugin/PluginAPI';
import { IContact } from '@src/Contact.interface';
+import { IMessage } from '@src/Message.interface';
/**
* XEP-0313: Message Archive Management
@@ -25,6 +24,9 @@ const MAX_VERSION = '4.0.0';
const MAM1 = 'urn:xmpp:mam:1';
const MAM2 = 'urn:xmpp:mam:2';
+Namespace.register('MAM1', MAM1);
+Namespace.register('MAM2', MAM2);
+
export default class MessageArchiveManagementPlugin extends AbstractPlugin {
public static getName(): string {
return 'Message Archive Management';
@@ -34,9 +36,9 @@ export default class MessageArchiveManagementPlugin extends AbstractPlugin {
return Translation.t('setting-mam-enable');
}
- private enabled = false;
private archives: {[key: string]: Archive} = {};
private queryContactRelation: PersistentMap;
+ private supportCache: {[archiveJid: string]: string | boolean} = {};
constructor(pluginAPI: PluginAPI) {
super(MIN_VERSION, MAX_VERSION, pluginAPI);
@@ -48,16 +50,14 @@ export default class MessageArchiveManagementPlugin extends AbstractPlugin {
});
pluginAPI.registerChatWindowClearedHook((chatWindow: ChatWindow, contact: Contact) => {
- if (this.enabled) {
+ let archiveJid = this.getArchiveJid(contact);
+
+ if (this.supportCache[archiveJid.bare]) {
this.getArchive(contact.getJid()).clear();
}
});
- pluginAPI.registerConnectionHook((status, condition) => {
- if (status === Status.CONNECTED || status === Status.ATTACHED) {
- this.determineServerSupport();
- }
- });
+ this.pluginAPI.getConnection().registerHandler(this.onMamMessage, null, 'message', null);
}
public getStorage() {
@@ -68,6 +68,22 @@ export default class MessageArchiveManagementPlugin extends AbstractPlugin {
return this.pluginAPI.getConnection();
}
+ public runAfterReceiveMessagePipe(contact: IContact, message: IMessage, messageElement) {
+ let pipe = this.pluginAPI.getAfterReceiveMessagePipe();
+
+ pipe.run(contact, message, messageElement.get(0)).then(([contact, message]) => {
+ return message;
+ });
+ }
+
+ public runAfterReceiveGroupMessagePipe(contact: IContact, message: IMessage) {
+ let pipe = this.pluginAPI.getAfterReceiveGroupMessagePipe();
+
+ return pipe.run(contact, message).then(([contact, message]) => {
+ return message;
+ });
+ }
+
public addQueryContactRelation(queryId: string, contact: IContact) {
this.queryContactRelation.set(queryId, contact.getJid().bare);
}
@@ -76,54 +92,51 @@ export default class MessageArchiveManagementPlugin extends AbstractPlugin {
this.queryContactRelation.remove(queryId);
}
- private determineServerSupport() {
- let connection = this.pluginAPI.getConnection();
- let discoInfoRepository = this.pluginAPI.getDiscoInfoRepository();
- let domain = connection.getJID().domain;
-
- if (!domain) {
- this.pluginAPI.Log.debug('Could not get connected JID for MAM');
- return;
+ public async determineServerSupport(archivingJid: IJID) {
+ if (typeof this.supportCache[archivingJid.bare] !== 'undefined') {
+ return this.supportCache[archivingJid.bare];
}
- let serverJid = new JID('', domain, '') //@REVIEW
-
- discoInfoRepository.getCapabilities(serverJid).then((discoInfo: DiscoInfo) => {
- if (discoInfo.hasFeature(MAM2)) {
- Namespace.register('MAM', MAM2);
- return true;
- } else if (discoInfo.hasFeature(MAM1)) {
- Namespace.register('MAM', MAM1);
- return true;
- }
- return false;
- }).then((hasSupport) => {
- if (hasSupport) {
- this.pluginAPI.Log.debug('Server supports ' + Namespace.get('MAM'));
- this.enabled = true;
+ let discoInfoRepository = this.pluginAPI.getDiscoInfoRepository();
+
+ let version: string | boolean = false;
+ try {
+ let discoInfo = await discoInfoRepository.getCapabilities(archivingJid);
- this.pluginAPI.getConnection().registerHandler(this.onMamMessage, null, 'message', null);
+ if (discoInfo && discoInfo.hasFeature(MAM2)) {
+ version = MAM2;
+ } else if (discoInfo && discoInfo.hasFeature(MAM1)) {
+ version = MAM1;
}
- }).catch((err) => {
+ } catch (err) {
this.pluginAPI.Log.warn('Could not determine MAM server support:', err);
- });
- }
+ }
- private addLoadButtonIfEnabled(chatWindow: ChatWindow, contact: Contact) {
- if (!this.enabled) {
- let self = this;
-
- //@REVIEW event based?
- setTimeout(function check() {
- if (self.enabled) {
- self.addLoadButton(chatWindow.getDom(), contact);
- } else {
- setTimeout(check, 200);
- }
- }, 200);
+ if (version) {
+ this.pluginAPI.Log.debug(archivingJid.bare + ' supports ' + version);
} else {
- this.addLoadButton(chatWindow.getDom(), contact);
+ this.pluginAPI.Log.debug(archivingJid.bare + ' has no support for MAM');
}
+
+ this.supportCache[archivingJid.bare] = version;
+
+ return version;
+ }
+
+ private getArchiveJid(contact: Contact) {
+ let jid = contact.isGroupChat() ? contact.getJid() : this.getConnection().getJID();
+
+ return new JID(jid.bare);
+ }
+
+ private addLoadButtonIfEnabled(chatWindow: ChatWindow, contact: Contact) {
+ let archivingJid = this.getArchiveJid(contact);
+
+ this.determineServerSupport(archivingJid).then((version) => {
+ if (version) {
+ this.addLoadButton(chatWindow.getDom(), contact);
+ }
+ });
}
private addLoadButton(chatWindowElement: JQuery<HTMLElement>, contact: Contact) {
@@ -169,7 +182,7 @@ export default class MessageArchiveManagementPlugin extends AbstractPlugin {
private onMamMessage = (stanza: string): boolean => {
let stanzaElement = $(stanza);
- let resultElement = stanzaElement.find('result' + Namespace.getFilter('MAM'));
+ let resultElement = stanzaElement.find(`result[xmlns^="urn:xmpp:mam:"]`);
let queryId = resultElement.attr('queryid');
if (resultElement.length !== 1 || !queryId) {