diff --git a/Makefile b/Makefile index 783bd52..d3cdf18 100644 --- a/Makefile +++ b/Makefile @@ -15,6 +15,7 @@ npm/snikket-browser.js: sed -i 's/snikket\.MessageDirection/enums.MessageDirection/g' npm/snikket-browser.d.ts sed -i 's/snikket\.MessageType/enums.MessageType/g' npm/snikket-browser.d.ts sed -i 's/snikket\.UserState/enums.UserState/g' npm/snikket-browser.d.ts + sed -i 's/snikket\.ChatMessageEvent/enums.ChatMessageEvent/g' npm/snikket-browser.d.ts sed -i 's/_Push.Push_Fields_/Push/g' npm/snikket-browser.d.ts sed -i '1ivar exports = {};' npm/snikket-browser.js echo "export const snikket = exports.snikket;" >> npm/snikket-browser.js @@ -27,6 +28,7 @@ npm/snikket.js: sed -i 's/snikket\.MessageDirection/enums.MessageDirection/g' npm/snikket.d.ts sed -i 's/snikket\.MessageType/enums.MessageType/g' npm/snikket.d.ts sed -i 's/snikket\.UserState/enums.UserState/g' npm/snikket.d.ts + sed -i 's/snikket\.ChatMessageEvent/enums.ChatMessageEvent/g' npm/snikket.d.ts sed -i 's/_Push.Push_Fields_/Push/g' npm/snikket.d.ts sed -i '1iimport { createRequire } from "module";' npm/snikket.js sed -i '1iglobal.require = createRequire(import.meta.url);' npm/snikket.js diff --git a/npm/index.ts b/npm/index.ts index a22ae51..582518f 100644 --- a/npm/index.ts +++ b/npm/index.ts @@ -22,10 +22,11 @@ export import SerializedChat = snikket.SerializedChat; export import jingle = snikket.jingle; export const VERSION = snikket.Version.HUMAN; -export import UiState = enums.UiState; -export import MessageStatus = enums.MessageStatus; +export import ChatMessageEvent = enums.ChatMessageEvent; export import MessageDirection = enums.MessageDirection; +export import MessageStatus = enums.MessageStatus; export import MessageType = enums.MessageType; +export import UiState = enums.UiState; export import UserState = enums.UserState; export namespace persistence { diff --git a/snikket/Chat.hx b/snikket/Chat.hx index 3f2d67f..88c7a48 100644 --- a/snikket/Chat.hx +++ b/snikket/Chat.hx @@ -723,7 +723,7 @@ class DirectChat extends Chat { setLastMessage(corrected); client.trigger("chats/update", [this]); } - client.notifyMessageHandlers(corrected); + client.notifyMessageHandlers(corrected, CorrectionEvent); }); } @@ -748,7 +748,7 @@ class DirectChat extends Chat { } setLastMessage(message); client.trigger("chats/update", [this]); - client.notifyMessageHandlers(stored); + client.notifyMessageHandlers(stored, stored.versions.length > 1 ? CorrectionEvent : DeliveryEvent); }); case ReactionUpdateStanza(update): persistence.storeReaction(client.accountId(), update, (stored) -> { @@ -756,7 +756,7 @@ class DirectChat extends Chat { message.to = recipient; client.sendStanza(message.asStanza()); } - if (stored != null) client.notifyMessageHandlers(stored); + if (stored != null) client.notifyMessageHandlers(stored, ReactionEvent); }); default: trace("Invalid message", fromStanza); @@ -778,7 +778,7 @@ class DirectChat extends Chat { stanza.attr.set("to", recipient); client.sendStanza(stanza); } - if (stored != null) client.notifyMessageHandlers(stored); + if (stored != null) client.notifyMessageHandlers(stored, ReactionEvent); }); } @@ -1152,7 +1152,7 @@ class Channel extends Chat { setLastMessage(corrected); client.trigger("chats/update", [this]); } - client.notifyMessageHandlers(corrected); + client.notifyMessageHandlers(corrected, CorrectionEvent); }); } @@ -1177,12 +1177,12 @@ class Channel extends Chat { client.sendStanza(stanza); setLastMessage(stored); client.trigger("chats/update", [this]); - client.notifyMessageHandlers(stored); + client.notifyMessageHandlers(stored, stored.versions.length > 1 ? CorrectionEvent : DeliveryEvent); }); case ReactionUpdateStanza(update): persistence.storeReaction(client.accountId(), update, (stored) -> { client.sendStanza(stanza); - if (stored != null) client.notifyMessageHandlers(stored); + if (stored != null) client.notifyMessageHandlers(stored, ReactionEvent); }); default: trace("Invalid message", fromStanza); @@ -1202,7 +1202,7 @@ class Channel extends Chat { final stanza = update.asStanza(); stanza.attr.set("to", chatId); client.sendStanza(stanza); - if (stored != null) client.notifyMessageHandlers(stored); + if (stored != null) client.notifyMessageHandlers(stored, ReactionEvent); }); } diff --git a/snikket/Client.hx b/snikket/Client.hx index 52360bd..766a88e 100644 --- a/snikket/Client.hx +++ b/snikket/Client.hx @@ -34,6 +34,13 @@ using Lambda; import HaxeCBridge; #end +enum abstract ChatMessageEvent(Int) { + var DeliveryEvent; + var CorrectionEvent; + var ReactionEvent; + var StatusEvent; +} + @:expose #if cpp @:build(HaxeCBridge.expose()) @@ -45,7 +52,7 @@ class Client extends EventEmitter { **/ public var sendAvailable(null, default): Bool = true; private var stream:GenericStream; - private var chatMessageHandlers: Array<(ChatMessage)->Void> = []; + private var chatMessageHandlers: Array<(ChatMessage, ChatMessageEvent)->Void> = []; private var chatStateHandlers: Array<(String,String,Null,UserState)->Void> = []; @:allow(snikket) private var jid(default,null):JID; @@ -111,7 +118,7 @@ class Client extends EventEmitter { accountId(), data.id, MessageDeliveredToServer, - notifyMessageHandlers + (m) -> notifyMessageHandlers(m, StatusEvent) ); return EventHandled; }); @@ -121,7 +128,7 @@ class Client extends EventEmitter { accountId(), data.id, MessageFailedToSend, - notifyMessageHandlers + (m) -> notifyMessageHandlers(m, StatusEvent) ); return EventHandled; }); @@ -155,7 +162,7 @@ class Client extends EventEmitter { if (chat == null && stanza.attr.get("type") != "groupchat") chat = getDirectChat(chatMessage.chatId()); if (chat != null) { final updateChat = (chatMessage) -> { - notifyMessageHandlers(chatMessage); + notifyMessageHandlers(chatMessage, chatMessage.versions.length > 1 ? CorrectionEvent : DeliveryEvent); if (chatMessage.versions.length < 1 || chat.lastMessageId() == chatMessage.serverId || chat.lastMessageId() == chatMessage.localId) { chat.setLastMessage(chatMessage); if (chatMessage.versions.length < 1) chat.setUnreadCount(chatMessage.isIncoming() ? chat.unreadCount() + 1 : 0); @@ -173,7 +180,7 @@ class Client extends EventEmitter { for (hash in update.inlineHashReferences()) { fetchMediaByHash([hash], [from]); } - persistence.storeReaction(accountId(), update, (stored) -> if (stored != null) notifyMessageHandlers(stored)); + persistence.storeReaction(accountId(), update, (stored) -> if (stored != null) notifyMessageHandlers(stored, ReactionEvent)); default: // ignore } @@ -975,10 +982,16 @@ class Client extends EventEmitter { Also fires when status of a ChatMessage changes, when a ChatMessage is edited, or when a reaction is added - @param handler takes one argument, the ChatMessage + @param handler takes two arguments, the ChatMessage and ChatMessageEvent enum describing what happened **/ - public function addChatMessageListener(handler:ChatMessage->Void):Void { + #if cpp + // HaxeCBridge doesn't support "secondary" enums yet + public function addChatMessageListener(handler:(ChatMessage, Int)->Void):Void { + chatMessageHandlers.push((m, e) -> handler(m, cast e)); + #else + public function addChatMessageListener(handler:(ChatMessage, ChatMessageEvent)->Void):Void { chatMessageHandlers.push(handler); + #end } /** @@ -1198,11 +1211,11 @@ class Client extends EventEmitter { } @:allow(snikket) - private function notifyMessageHandlers(message: ChatMessage) { + private function notifyMessageHandlers(message: ChatMessage, event: ChatMessageEvent) { final chat = getChat(message.chatId()); if (chat != null && chat.isBlocked) return; // Don't notify blocked chats for (handler in chatMessageHandlers) { - handler(message); + handler(message, event); } } diff --git a/snikket/jingle/Session.hx b/snikket/jingle/Session.hx index fcbc4ac..7d0cc0c 100644 --- a/snikket/jingle/Session.hx +++ b/snikket/jingle/Session.hx @@ -76,7 +76,7 @@ class IncomingProposedSession implements Session { final event = new Stanza("ringing", { xmlns: "urn:xmpp:jingle-message:0", id: sid }); final msg = mkCallMessage(from, client.jid, event); client.storeMessage(msg, (stored) -> { - client.notifyMessageHandlers(stored); + client.notifyMessageHandlers(stored, CorrectionEvent); }); client.trigger("call/ring", { chatId: from.asBare().asString(), session: this }); } @@ -88,7 +88,7 @@ class IncomingProposedSession implements Session { final event = new Stanza("reject", { xmlns: "urn:xmpp:jingle-message:0", id: sid }); final msg = mkCallMessage(from, client.jid, event); client.storeMessage(msg, (stored) -> { - client.notifyMessageHandlers(stored); + client.notifyMessageHandlers(stored, CorrectionEvent); }); client.getDirectChat(from.asBare().asString(), false).jingleSessions.remove(sid); } @@ -122,7 +122,7 @@ class IncomingProposedSession implements Session { final event = new Stanza("proceed", { xmlns: "urn:xmpp:jingle-message:0", id: sid }); final msg = mkCallMessage(from, client.jid, event); client.storeMessage(msg, (stored) -> { - client.notifyMessageHandlers(stored); + client.notifyMessageHandlers(stored, CorrectionEvent); client.sendStanza( new Stanza("message", { to: from.asString(), type: "chat", id: msg.versions[0].localId }) .addChild(event) @@ -191,7 +191,7 @@ class OutgoingProposedSession implements Session { .addChild(event) .tag("store", { xmlns: "urn:xmpp:hints" }); client.sendStanza(stanza); - client.notifyMessageHandlers(stored); + client.notifyMessageHandlers(stored, DeliveryEvent); client.trigger("call/ringing", { chatId: to.asBare().asString() }); }); } @@ -209,7 +209,7 @@ class OutgoingProposedSession implements Session { .addChild(event) .tag("store", { xmlns: "urn:xmpp:hints" }) ); - client.notifyMessageHandlers(stored); + client.notifyMessageHandlers(stored, CorrectionEvent); }); client.getDirectChat(to.asBare().asString(), false).jingleSessions.remove(sid); } @@ -368,7 +368,7 @@ class InitiatedSession implements Session { final event = new Stanza("finish", { xmlns: "urn:xmpp:jingle-message:0", id: sid }); final msg = mkCallMessage(counterpart, client.jid, event); client.storeMessage(msg, (stored) -> { - client.notifyMessageHandlers(stored); + client.notifyMessageHandlers(stored, CorrectionEvent); client.sendStanza( new Stanza("message", { to: counterpart.asString(), type: "chat", id: msg.versions[0].localId }) .addChild(event)