git » sdk » commit 18967ab

Include what happened to a message when notifying UI

author Stephen Paul Weber
2024-11-13 15:50:10 UTC
committer Stephen Paul Weber
2024-11-13 15:50:10 UTC
parent 54ea84fe64f82dc0f01d86f80b0b459bca47ecdf

Include what happened to a message when notifying UI

So they can tell if it was eg a corretion or reaction and not notify
about it as if new, or similar.

Makefile +2 -0
npm/index.ts +3 -2
snikket/Chat.hx +8 -8
snikket/Client.hx +22 -9
snikket/jingle/Session.hx +6 -6

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<String>,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)