| author | Stephen Paul Weber
<singpolyma@singpolyma.net> 2023-11-09 05:39:04 UTC |
| committer | Stephen Paul Weber
<singpolyma@singpolyma.net> 2023-11-09 05:39:04 UTC |
| parent | 405302bf9ac7ab48de0d643136d591b1113aea63 |
| xmpp/Chat.hx | +11 | -15 |
| xmpp/Client.hx | +26 | -1 |
| xmpp/queries/VcardTempGet.hx | +52 | -0 |
diff --git a/xmpp/Chat.hx b/xmpp/Chat.hx index 71f02f7..c70009f 100644 --- a/xmpp/Chat.hx +++ b/xmpp/Chat.hx @@ -75,7 +75,17 @@ abstract class Chat { } public function getPhoto(callback:(String)->Void) { - callback(Color.defaultPhoto(chatId, getDisplayName().charAt(0))); + if (avatarSha1 != null) { + persistence.getMediaUri("sha-1", avatarSha1, (uri) -> { + if (uri != null) { + callback(uri); + } else { + callback(Color.defaultPhoto(chatId, getDisplayName().charAt(0))); + } + }); + } else { + callback(Color.defaultPhoto(chatId, getDisplayName().charAt(0))); + } } public function readUpTo() { @@ -333,20 +343,6 @@ class DirectChat extends Chat { persistence.storeChat(client.accountId(), this); client.trigger("chats/update", [this]); } - - override public function getPhoto(callback:(String)->Void) { - if (avatarSha1 != null) { - persistence.getMediaUri("sha-1", avatarSha1, (uri) -> { - if (uri != null) { - callback(uri); - } else { - callback(Color.defaultPhoto(chatId, getDisplayName().charAt(0))); - } - }); - } else { - super.getPhoto(callback); - } - } } @:expose diff --git a/xmpp/Client.hx b/xmpp/Client.hx index 09b6e98..a56c89d 100644 --- a/xmpp/Client.hx +++ b/xmpp/Client.hx @@ -18,6 +18,7 @@ import xmpp.queries.JabberIqGatewayGet; import xmpp.queries.PubsubGet; import xmpp.queries.Push2Enable; import xmpp.queries.RosterGet; +import xmpp.queries.VcardTempGet; using Lambda; @:expose @@ -249,7 +250,8 @@ class Client extends xmpp.EventEmitter { final stanza:Stanza = event.stanza; final c = stanza.getChild("c", "http://jabber.org/protocol/caps"); if (stanza.attr.get("from") != null && stanza.attr.get("type") == null) { - final chat = getChat(JID.parse(stanza.attr.get("from")).asBare().asString()); + final from = JID.parse(stanza.attr.get("from")); + final chat = getChat(from.asBare().asString()); if (chat == null) { trace("Presence for unknown JID: " + stanza.attr.get("from")); return EventUnhandled; @@ -276,6 +278,29 @@ class Client extends xmpp.EventEmitter { } }); } + if (from.isBare()) { + final avatarSha1Hex = stanza.findText("{vcard-temp:x:update}x/photo#"); + if (avatarSha1Hex != null) { + final avatarSha1 = Bytes.ofHex(avatarSha1Hex).getData(); + chat.setAvatarSha1(avatarSha1); + persistence.storeChat(accountId(), chat); + persistence.getMediaUri("sha-1", avatarSha1, (uri) -> { + if (uri == null) { + final vcardGet = new VcardTempGet(from); + vcardGet.onFinished(() -> { + final vcard = vcardGet.getResult(); + if (vcard.photo == null) return; + persistence.storeMedia(vcard.photo.mime, vcard.photo.data.getData(), () -> { + this.trigger("chats/update", [chat]); + }); + }); + sendQuery(vcardGet); + } else { + this.trigger("chats/update", [chat]); + } + }); + } + } return EventHandled; } diff --git a/xmpp/queries/VcardTempGet.hx b/xmpp/queries/VcardTempGet.hx new file mode 100644 index 0000000..ed8df0c --- /dev/null +++ b/xmpp/queries/VcardTempGet.hx @@ -0,0 +1,52 @@ +package xmpp.queries; + +import haxe.DynamicAccess; +import haxe.Exception; +import haxe.crypto.Base64; +import haxe.io.Bytes; + +import xmpp.ID; +import xmpp.ResultSet; +import xmpp.Stanza; +import xmpp.Stream; +import xmpp.queries.GenericQuery; + +class VcardTempGet extends GenericQuery { + public var xmlns(default, null) = "vcard-temp"; + public var queryId:String = null; + public var ver:String = null; + private var responseStanza:Stanza; + private var result: {photo:Null<{mime:String, data:Bytes}>}; + + public function new(to: JID) { + /* Build basic query */ + queryId = ID.short(); + queryStanza = new Stanza("iq", { to: to.asString(), type: "get", id: queryId }); + queryStanza.tag("vCard", { xmlns: xmlns }).up(); + } + + public function handleResponse(stanza:Stanza) { + responseStanza = stanza; + finish(); + } + + public function getResult() { + if (responseStanza == null) { + return {photo: null}; + } + if(result == null) { + final vcard = responseStanza.getChild("vCard", xmlns); + if(vcard == null) { + return {photo: null}; + } + final photoMime = vcard.findText("PHOTO/TYPE#"); + final photoBinval = vcard.findText("PHOTO/BINVAL#"); + if (photoMime != null && photoBinval != null) { + result = {photo: { mime: photoMime, data: Base64.decode(StringTools.replace(photoBinval, "\n", "")) } }; + } else { + result = {photo: null}; + } + } + return result; + } +}