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:
Diffstat (limited to 'src/plugins/LastMessageCorrectionPlugin.ts')
-rw-r--r--src/plugins/LastMessageCorrectionPlugin.ts185
1 files changed, 185 insertions, 0 deletions
diff --git a/src/plugins/LastMessageCorrectionPlugin.ts b/src/plugins/LastMessageCorrectionPlugin.ts
new file mode 100644
index 00000000..c3db4c46
--- /dev/null
+++ b/src/plugins/LastMessageCorrectionPlugin.ts
@@ -0,0 +1,185 @@
+import { AbstractPlugin, IMetaData } from '../plugin/AbstractPlugin';
+import PluginAPI from '../plugin/PluginAPI';
+import Translation from '@util/Translation';
+import * as Namespace from '@connection/xmpp/namespace';
+import { IContact } from '@src/Contact.interface';
+import { IMessage } from '@src/Message.interface';
+import Message from '@src/Message';
+
+/**
+ * XEP-0308: Last Message Correction
+ *
+ * @version: 1.2.0
+ * @see: https://xmpp.org/extensions/xep-0308.html
+ *
+ */
+
+const CORRECTION_CMD = '/fix';
+const LMC = 'urn:xmpp:message-correct:0';
+
+const MIN_VERSION = '4.3.0';
+const MAX_VERSION = '99.0.0';
+
+Namespace.register('LAST_MSG_CORRECTION', LMC);
+
+export default class LastMessageCorrectionPlugin extends AbstractPlugin {
+ public static getId(): string {
+ return 'lmc';
+ }
+
+ public static getName(): string {
+ return 'Last Message Correction';
+ }
+
+ public static getMetaData(): IMetaData {
+ return {
+ description: Translation.t('setting-lmc-enable'),
+ xeps: [
+ {
+ id: 'XEP-0308',
+ name: 'Last Message Correction',
+ version: '1.2.0',
+ },
+ ],
+ };
+ }
+
+ private correctionRequests: { [contactUid: string]: IMessage } = {};
+
+ constructor(pluginAPI: PluginAPI) {
+ super(MIN_VERSION, MAX_VERSION, pluginAPI);
+
+ pluginAPI.registerCommand(CORRECTION_CMD, this.commandHandler, 'cmd_correction');
+
+ pluginAPI.addPreSendMessageStanzaProcessor(this.addReplaceElementToStanza, 90);
+
+ pluginAPI.addAfterReceiveMessageProcessor(this.checkMessageCorrection, 90);
+
+ pluginAPI.registerChatMessageMenuItem({
+ generate: this.generateCorrectMessageMenuItem,
+ });
+ }
+
+ private commandHandler = async (args: string[], contact: IContact, messageString: string) => {
+ const originalMessage = contact.getTranscript().getFirstOutgoingMessage();
+
+ this.correctionRequests[contact.getUid()] = originalMessage;
+
+ if (!originalMessage || !contact.isChat()) {
+ return false;
+ }
+
+ const chatWindow = contact.getChatWindow();
+ const message = new Message({
+ peer: contact.getJid(),
+ direction: Message.DIRECTION.OUT,
+ type: contact.getType(),
+ plaintextMessage: messageString.replace(/^\/fix /, ''),
+ attachment: chatWindow.getAttachment(),
+ unread: false,
+ original: originalMessage.getUid(),
+ });
+
+ contact.getTranscript().pushMessage(message);
+
+ chatWindow.clearAttachment();
+
+ let pipe = contact.getAccount().getPipe('preSendMessage');
+
+ return pipe
+ .run(contact, message)
+ .then(([contact, message]) => {
+ originalMessage.getLastVersion().setReplacedBy(message);
+
+ contact.getAccount().getConnection().sendMessage(message);
+
+ return true;
+ })
+ .catch(err => {
+ this.pluginAPI.Log.warn('Error during preSendMessage pipe', err);
+
+ return false;
+ });
+ };
+
+ private addReplaceElementToStanza = async (
+ message: IMessage,
+ xmlMsg: Strophe.Builder
+ ): Promise<[IMessage, Strophe.Builder]> => {
+ const contact = this.pluginAPI.getContact(message.getPeer());
+ const originalMessage = this.correctionRequests[contact.getUid()];
+
+ if (!originalMessage || originalMessage.getLastVersion().getUid() !== message.getUid()) {
+ return [message, xmlMsg];
+ }
+
+ delete this.correctionRequests[contact.getUid()];
+
+ xmlMsg
+ .c('replace', {
+ xmlns: LMC,
+ id: originalMessage.getAttrId(),
+ })
+ .up();
+
+ return [message, xmlMsg];
+ };
+
+ private checkMessageCorrection = async (
+ contact: IContact,
+ message: IMessage,
+ stanza: Element
+ ): Promise<[IContact, IMessage, Element]> => {
+ const replaceElement = $(stanza).find(`>replace[xmlns="${LMC}"]`);
+
+ if (replaceElement.length === 0) {
+ return [contact, message, stanza];
+ }
+
+ const attrIdToBeReplaced = replaceElement.attr('id');
+
+ if (!attrIdToBeReplaced) {
+ return [contact, message, stanza];
+ }
+
+ const firstIncomingMessage = contact.getTranscript().getFirstIncomingMessage();
+
+ if (firstIncomingMessage && firstIncomingMessage.getAttrId() === attrIdToBeReplaced) {
+ message.setOriginal(firstIncomingMessage);
+
+ firstIncomingMessage.getLastVersion().setReplacedBy(message);
+ }
+
+ return [contact, message, stanza];
+ };
+
+ private generateCorrectMessageMenuItem = (contact: IContact, message: IMessage) => {
+ if (message.isOutgoing()) {
+ const lastOutgoingMessage = contact.getTranscript().getFirstOutgoingMessage().getLastVersion();
+
+ if (lastOutgoingMessage.getUid() === message.getUid()) {
+ const chatWindow = contact.getChatWindow();
+
+ return {
+ id: 'lmc-edit',
+ label: '',
+ icon: 'edit',
+ handler: () => {
+ let plaintextMessage = message.getPlaintextMessage();
+
+ if (message.hasAttachment()) {
+ const attachment = message.getAttachment();
+
+ chatWindow.setAttachment(attachment);
+ plaintextMessage = plaintextMessage.replace(attachment.getData() + '\n', '');
+ }
+
+ chatWindow.setInput(CORRECTION_CMD + ' ' + plaintextMessage);
+ },
+ };
+ }
+ }
+
+ return false;
+ };
+}