package borogove;
import borogove.Hash;
import borogove.MucUser;
import borogove.Role;
enum abstract ShowPresence(Int) to Int {
var Online;
var Idle;
var DoNotDisturb;
var Standby;
var Offline;
}
@:nullSafety(StrictThreaded)
@:forward(toString)
@:expose
abstract Presence(Stanza) from Stanza to Stanza {
public var capsNode(get, never): Null<String>;
public var ver(get, never): Null<String>;
public var mucUser(get, never): Null<MucUser>;
public var hats(get, never): Null<Array<Role>>;
public var avatarHash(get, never): Null<Hash>;
public var type(get, never): Null<String>;
public var show(get, never): ShowPresence;
public var priority(get, never): Int;
/**
Create a presence stanza wrapper from caps, MUC metadata, and avatar hash.
**/
public function new(caps: Null<Caps>, mucUser: Null<MucUser>, avatarHash: Null<Hash>): Presence {
final stanza = new Stanza("presence", { xmlns: "jabber:client" });
if (caps != null) caps.addC(stanza);
if (mucUser != null) stanza.addChild(mucUser);
if (avatarHash != null) {
stanza.tag("x", { xmlns: "vcard-temp:x:update" }).textTag("photo", avatarHash.toHex()).up();
}
this = stanza;
}
private inline function get_capsNode() {
final c = this.getChild("c", "http://jabber.org/protocol/caps");
return c?.attr?.get("node");
}
private inline function get_ver() {
final c = this.getChild("c", "http://jabber.org/protocol/caps");
return c?.attr?.get("ver");
}
private inline function get_mucUser() {
return this.getChild("x", "http://jabber.org/protocol/muc#user");
}
private inline function get_hats() {
return (this.getChild("hats", "urn:xmpp:hats:0")?.allTags("hat") ?? []).map(hat -> new Role(hat.attr.get("uri") ?? "", hat.attr.get("title") ?? ""));
}
private inline function get_avatarHash() {
final avatarSha1Hex = this.findText("{vcard-temp:x:update}x/photo#");
return avatarSha1Hex == null || avatarSha1Hex == "" ? null : Hash.fromHex("sha-1", avatarSha1Hex);
}
private inline function get_type() {
return this.attr.get("type");
}
private inline function get_show() {
if (type == "unavailable") return Offline;
return switch (this.getChildText("show")) {
case "away": Idle;
case "dnd": DoNotDisturb;
case "xa": Standby;
default: Online;
};
}
private inline function get_priority() {
return Std.parseInt(this.getChildText("priority") ?? "0") ?? 0;
}
}