anotherim-desktop/libdino/src/service/presence_manager.vala

161 lines
6.4 KiB
Vala
Raw Normal View History

2017-03-02 14:37:32 +00:00
using Gee;
using Xmpp;
using Dino.Entities;
namespace Dino {
public class PresenceManager : StreamInteractionModule, Object {
public static ModuleIdentity<PresenceManager> IDENTITY = new ModuleIdentity<PresenceManager>("presence_manager");
public string id { get { return IDENTITY.id; } }
2017-03-02 14:37:32 +00:00
public signal void show_received(Show show, Jid jid, Account account);
public signal void received_subscription_request(Jid jid, Account account);
2018-07-29 22:00:56 +00:00
public signal void received_subscription_approval(Jid jid, Account account);
2017-03-02 14:37:32 +00:00
private StreamInteractor stream_interactor;
private HashMap<Jid, HashMap<Jid, ArrayList<Show>>> shows = new HashMap<Jid, HashMap<Jid, ArrayList<Show>>>(Jid.hash_bare_func, Jid.equals_bare_func);
private HashMap<Jid, ArrayList<Jid>> resources = new HashMap<Jid, ArrayList<Jid>>(Jid.hash_bare_func, Jid.equals_bare_func);
private Gee.List<Jid> subscription_requests = new ArrayList<Jid>(Jid.equals_func);
2017-03-02 14:37:32 +00:00
public static void start(StreamInteractor stream_interactor) {
PresenceManager m = new PresenceManager(stream_interactor);
stream_interactor.add_module(m);
}
private PresenceManager(StreamInteractor stream_interactor) {
this.stream_interactor = stream_interactor;
stream_interactor.account_added.connect(on_account_added);
}
public Show get_last_show(Jid jid, Account account) {
XmppStream? stream = stream_interactor.get_stream(account);
2017-03-02 14:37:32 +00:00
if (stream != null) {
Xmpp.Presence.Stanza? presence = stream.get_flag(Presence.Flag.IDENTITY).get_presence(jid);
2017-03-02 14:37:32 +00:00
if (presence != null) {
2017-08-31 16:40:58 +00:00
return new Show(jid, presence.show, new DateTime.now_utc());
2017-03-02 14:37:32 +00:00
}
}
2017-08-31 16:40:58 +00:00
return new Show(jid, Show.OFFLINE, new DateTime.now_utc());
2017-03-02 14:37:32 +00:00
}
public HashMap<Jid, ArrayList<Show>>? get_shows(Jid jid, Account account) {
return shows[jid];
}
public Gee.List<Jid>? get_full_jids(Jid jid, Account account) {
XmppStream? stream = stream_interactor.get_stream(account);
2017-03-02 14:37:32 +00:00
if (stream != null) {
Xmpp.Presence.Flag flag = stream.get_flag(Presence.Flag.IDENTITY);
if (flag == null) return null;
return flag.get_resources(jid.bare_jid);
2017-03-02 14:37:32 +00:00
}
return null;
}
public bool exists_subscription_request(Account account, Jid jid) {
return subscription_requests.contains(jid);
}
2017-03-02 14:37:32 +00:00
public void request_subscription(Account account, Jid jid) {
XmppStream stream = stream_interactor.get_stream(account);
if (stream != null) stream.get_module(Xmpp.Presence.Module.IDENTITY).request_subscription(stream, jid.bare_jid);
2017-03-02 14:37:32 +00:00
}
public void approve_subscription(Account account, Jid jid) {
XmppStream stream = stream_interactor.get_stream(account);
if (stream != null) {
stream.get_module(Xmpp.Presence.Module.IDENTITY).approve_subscription(stream, jid.bare_jid);
subscription_requests.remove(jid);
}
2017-03-02 14:37:32 +00:00
}
public void deny_subscription(Account account, Jid jid) {
XmppStream stream = stream_interactor.get_stream(account);
if (stream != null) {
stream.get_module(Xmpp.Presence.Module.IDENTITY).deny_subscription(stream, jid.bare_jid);
subscription_requests.remove(jid);
}
2017-03-02 14:37:32 +00:00
}
2017-03-22 22:55:19 +00:00
public void cancel_subscription(Account account, Jid jid) {
XmppStream stream = stream_interactor.get_stream(account);
if (stream != null) stream.get_module(Xmpp.Presence.Module.IDENTITY).cancel_subscription(stream, jid.bare_jid);
2017-03-22 22:55:19 +00:00
}
2017-03-02 14:37:32 +00:00
private void on_account_added(Account account) {
2017-03-10 20:45:56 +00:00
stream_interactor.module_manager.get_module(account, Presence.Module.IDENTITY).received_available_show.connect((stream, jid, show) =>
on_received_available_show(account, jid, show)
2017-03-02 14:37:32 +00:00
);
2017-04-11 16:06:01 +00:00
stream_interactor.module_manager.get_module(account, Presence.Module.IDENTITY).received_unavailable.connect((stream, presence) =>
on_received_unavailable(account, presence.from)
2017-03-02 14:37:32 +00:00
);
stream_interactor.module_manager.get_module(account, Presence.Module.IDENTITY).received_subscription_request.connect((stream, jid) => {
if (!subscription_requests.contains(jid)) {
subscription_requests.add(jid);
}
received_subscription_request(jid, account);
});
2018-07-29 22:00:56 +00:00
stream_interactor.module_manager.get_module(account, Presence.Module.IDENTITY).received_subscription_approval.connect((stream, jid) => {
received_subscription_approval(jid, account);
});
2017-03-02 14:37:32 +00:00
}
private void on_received_available_show(Account account, Jid jid, string show) {
lock (resources) {
if (!resources.has_key(jid)){
resources[jid] = new ArrayList<Jid>(Jid.equals_func);
}
if (!resources[jid].contains(jid)) {
resources[jid].add(jid);
}
}
add_show(account, jid, show);
}
private void on_received_unavailable(Account account, Jid jid) {
lock (resources) {
if (resources.has_key(jid)) {
resources[jid].remove(jid);
if (resources[jid].size == 0 || jid.is_bare()) {
resources.unset(jid);
}
}
}
add_show(account, jid, Show.OFFLINE);
}
private void add_show(Account account, Jid jid, string s) {
2017-08-31 16:40:58 +00:00
Show show = new Show(jid, s, new DateTime.now_utc());
2017-03-02 14:37:32 +00:00
lock (shows) {
if (!shows.has_key(jid)) {
shows[jid] = new HashMap<Jid, ArrayList<Show>>();
}
if (!shows[jid].has_key(jid)) {
shows[jid][jid] = new ArrayList<Show>();
}
shows[jid][jid].add(show);
}
show_received(show, jid, account);
}
}
public class Show : Object {
public const string ONLINE = Xmpp.Presence.Stanza.SHOW_ONLINE;
public const string AWAY = Xmpp.Presence.Stanza.SHOW_AWAY;
public const string CHAT = Xmpp.Presence.Stanza.SHOW_CHAT;
public const string DND = Xmpp.Presence.Stanza.SHOW_DND;
public const string XA = Xmpp.Presence.Stanza.SHOW_XA;
public const string OFFLINE = "offline";
public Jid jid;
public string as;
public DateTime datetime;
public Show(Jid jid, string show, DateTime datetime) {
this.jid = jid;
this.as = show;
this.datetime = datetime;
}
}
2017-08-31 16:40:58 +00:00
}