package borogove;
import thenshim.Promise;
import haxe.ds.ReadOnlyArray;
import borogove.Chat;
import borogove.Presence;
import borogove.queries.PubsubGet;
#if cpp
import HaxeCBridge;
#end
@:expose
@:nullSafety(Strict)
#if cpp
@:build(HaxeCBridge.expose())
@:build(HaxeSwiftBridge.expose())
#end
class Member {
/**
A unique id for this member
**/
public final id: String;
/**
Display name to show for this member
**/
public final displayName: String;
/**
Avatar URI for this member, or null when none is known
**/
public final photoUri: Null<String>;
/**
Fallback avatar URI to use when no photo is available
**/
public final placeholderUri: String;
/**
True when this member is the connected account
**/
public final isSelf: Bool;
/**
Chat metadata for this member when it is available as a direct Chat
**/
public final chat: Null<AvailableChat>;
/**
Roles this member has in the Chat
**/
public final roles: ReadOnlyArray<Role>;
public final showPresence: ShowPresence;
@:allow(borogove)
private var presence: Map<String, Presence>;
@:allow(borogove)
private final jid: JID;
@:allow(borogove)
private function new(id: String, displayName: String, photoUri: Null<String>, isSelf: Bool, roles: Array<Role>, jid: JID, presence: Map<String, Presence>, chat: Null<AvailableChat>) {
this.id = id;
this.displayName = displayName;
this.photoUri = photoUri;
this.placeholderUri = Color.defaultPhoto(id, displayName.charAt(0).toUpperCase());
this.isSelf = isSelf;
this.roles = roles;
this.jid = jid;
this.presence = presence;
this.chat = chat;
var lowestShow = Offline;
var highestPrio = -100000;
for (_ => p in presence) {
if (p.priority >= highestPrio) {
highestPrio = p.priority;
if ((lowestShow : Int) > (p.show : Int)) lowestShow = p.show;
}
}
showPresence = lowestShow;
}
/**
Load the member's profile
@param client connected client used to send the profile query
@returns Promise resolving to the member Profile
**/
public function profile(client: Client): Promise<Profile> {
return new Promise((resolve, reject) -> {
final get = new PubsubGet(jid.asString(), "urn:xmpp:vcard4");
get.onFinished(() -> {
final item = get.getResult()[0];
final fromItem = item?.getChild("vcard", "urn:ietf:params:xml:ns:vcard-4.0");
final vcard = fromItem == null ? new Stanza("vcard", { xmlns: "urn:ietf:params:xml:ns:vcard-4.0" }) : fromItem;
if (!vcard.hasChild("fn")) {
vcard.insertChild(0, new Stanza("fn").textTag("text", displayName));
}
resolve(new Profile(vcard));
});
client.sendQuery(get);
});
}
/**
Load the member's status
@param client connected client used to send the profile query
@returns Promise resolving to the member Status
**/
public function status(client: Client): Promise<Status> {
return new Promise((resolve, reject) -> {
final get = new PubsubGet(jid.asString(), "http://jabber.org/protocol/activity");
get.onFinished(() -> {
final item = get.getResult()[0];
final activity = item?.getChild("activity", "http://jabber.org/protocol/activity");
resolve(new Status(activity?.getChild("undefined")?.getChildText("emoji", "https://ns.borogove.dev/") ?? "", activity?.getChildText("text") ?? ""));
});
client.sendQuery(get);
});
}
}