| author | Stephen Paul Weber
<singpolyma@singpolyma.net> 2023-11-30 06:36:10 UTC |
| committer | Stephen Paul Weber
<singpolyma@singpolyma.net> 2023-12-11 15:59:52 UTC |
| parent | 0e0c9c02496bb6f988cb2e68d5c9aae8d4989c7b |
| xmpp/Chat.hx | +45 | -4 |
| xmpp/ChatMessage.hx | +1 | -0 |
| xmpp/Client.hx | +9 | -13 |
| xmpp/persistence/browser.js | +2 | -1 |
diff --git a/xmpp/Chat.hx b/xmpp/Chat.hx index ffadede..10cc2da 100644 --- a/xmpp/Chat.hx +++ b/xmpp/Chat.hx @@ -46,6 +46,8 @@ abstract class Chat { abstract public function prepareIncomingMessage(message:ChatMessage, stanza:Stanza):ChatMessage; + abstract public function correctMessage(localId:String, message:ChatMessage):Void; + abstract public function sendMessage(message:ChatMessage):Void; abstract public function getMessages(beforeId:Null<String>, beforeTime:Null<String>, handler:(Array<ChatMessage>)->Void):Void; @@ -276,14 +278,35 @@ class DirectChat extends Chat { return message; } - public function sendMessage(message:ChatMessage):Void { - client.chatActivity(this); + private function prepareOutgoingMessage(message:ChatMessage) { message.timestamp = message.timestamp ?? Date.format(std.Date.now()); message.direction = MessageSent; message.from = client.jid; message.sender = message.from.asBare(); message.replyTo = [message.sender]; message.recipients = getParticipants().map((p) -> JID.parse(p)); + return message; + } + + public function correctMessage(localId:String, message:ChatMessage) { + message = prepareOutgoingMessage(message); + persistence.correctMessage(client.accountId(), localId, message, (corrected) -> { + message.versions = corrected.versions; + for (recipient in message.recipients) { + message.to = recipient; + client.sendStanza(message.asStanza()); + } + if (localId == lastMessage?.localId) { + setLastMessage(corrected); + client.trigger("chats/update", [this]); + } + client.notifyMessageHandlers(corrected); + }); + } + + public function sendMessage(message:ChatMessage):Void { + client.chatActivity(this); + message = prepareOutgoingMessage(message); persistence.storeMessage(client.accountId(), message); for (recipient in message.recipients) { message.to = recipient; @@ -534,8 +557,7 @@ class Channel extends Chat { return message; } - public function sendMessage(message:ChatMessage):Void { - client.chatActivity(this); + private function prepareOutgoingMessage(message:ChatMessage) { message.timestamp = message.timestamp ?? Date.format(std.Date.now()); message.direction = MessageSent; message.from = client.jid; @@ -543,6 +565,25 @@ class Channel extends Chat { message.replyTo = [message.sender]; message.to = JID.parse(chatId); message.recipients = [message.to]; + return message; + } + + public function correctMessage(localId:String, message:ChatMessage) { + message = prepareOutgoingMessage(message); + persistence.correctMessage(client.accountId(), localId, message, (corrected) -> { + message.versions = corrected.versions; + client.sendStanza(message.asStanza("groupchat")); + if (localId == lastMessage?.localId) { + setLastMessage(corrected); + client.trigger("chats/update", [this]); + } + client.notifyMessageHandlers(corrected); + }); + } + + public function sendMessage(message:ChatMessage):Void { + client.chatActivity(this); + message = prepareOutgoingMessage(message); persistence.storeMessage(client.accountId(), message); client.sendStanza(message.asStanza("groupchat")); setLastMessage(message); diff --git a/xmpp/ChatMessage.hx b/xmpp/ChatMessage.hx index b38c847..3f2267f 100644 --- a/xmpp/ChatMessage.hx +++ b/xmpp/ChatMessage.hx @@ -276,6 +276,7 @@ class ChatMessage { if (to != null) attrs.set("to", to.asString()); if (localId != null) attrs.set("id", localId); var stanza = new Stanza("message", attrs); + if (versions.length > 0) stanza.tag("replace", { xmlns: "urn:xmpp:message-correct:0", id: versions[versions.length-1].localId }).up(); if (threadId != null) stanza.textTag("thread", threadId); if (recipients.length > 1) { final addresses = stanza.tag("addresses", { xmlns: "http://jabber.org/protocol/address" }); diff --git a/xmpp/Client.hx b/xmpp/Client.hx index 4ed1fdd..1c0cf16 100644 --- a/xmpp/Client.hx +++ b/xmpp/Client.hx @@ -76,11 +76,7 @@ class Client extends xmpp.EventEmitter { accountId(), data.id, MessageDeliveredToServer, - (chatMessage) -> { - for (handler in chatMessageHandlers) { - handler(chatMessage); - } - } + notifyMessageHandlers ); return EventHandled; }); @@ -90,11 +86,7 @@ class Client extends xmpp.EventEmitter { accountId(), data.id, MessageFailedToSend, - (chatMessage) -> { - for (handler in chatMessageHandlers) { - handler(chatMessage); - } - } + notifyMessageHandlers ); return EventHandled; }); @@ -158,9 +150,7 @@ class Client extends xmpp.EventEmitter { if (chatMessage.versions.length < 1) chat.setUnreadCount(chatMessage.isIncoming() ? chat.unreadCount() + 1 : 0); chatActivity(chat); } - for (handler in chatMessageHandlers) { - handler(chatMessage); - } + notifyMessageHandlers(chatMessage); }; chatMessage = chat.prepareIncomingMessage(chatMessage, stanza); final replace = stanza.getChild("replace", "urn:xmpp:message-correct:0"); @@ -732,6 +722,12 @@ class Client extends xmpp.EventEmitter { sendQuery(itemsGet); } + public function notifyMessageHandlers(message: ChatMessage) { + for (handler in chatMessageHandlers) { + handler(message); + } + } + private function rosterGet() { var rosterGet = new RosterGet(); rosterGet.onFinished(() -> { diff --git a/xmpp/persistence/browser.js b/xmpp/persistence/browser.js index 755e334..4f6c922 100644 --- a/xmpp/persistence/browser.js +++ b/xmpp/persistence/browser.js @@ -273,11 +273,12 @@ exports.xmpp.persistence = { const store = tx.objectStore("messages"); promisifyRequest(store.index("localId").openCursor(IDBKeyRange.only([account, localId, message.chatId()]))).then((result) => { if (result?.value && result.value.sender == message.senderId()) { - // Note, this strategy loses the ids of the replacement messages + // NOTE: this strategy loses the ids and timestamp of the replacement messages const withAnnotation = serializeMessage(account, message); withAnnotation.serverIdBy = result.value.serverIdBy; withAnnotation.serverId = result.value.serverId; withAnnotation.localId = result.value.localId; + withAnnotation.timestamp = result.value.timestamp; // Edited version is not newer withAnnotation.versions = [{ ...result.value, versions: [] }].concat(result.value.versions || []) result.update(withAnnotation); callback(hydrateMessage(withAnnotation));