using Gee; using GLib; using Dino.Entities; namespace Dino.Ui { [DBus (name = "com.canonical.Unity.LauncherEntry")] public class LauncherBadge : Object { private const string APP_URI = "application://im.dino.Dino.desktop"; private const string BUS_NAME = "com.canonical.Unity"; private const string OBJECT_PATH = "/im/dino/Dino/LauncherEntry"; private StreamInteractor stream_interactor; private DBusConnection connection; private HashMap read_handler_ids = new HashMap(Conversation.hash_func, Conversation.equals_func); private int64 unread_count = -1; private uint object_registration_id; private uint watcher_id; private ulong conversation_activated_handler_id; private ulong conversation_deactivated_handler_id; private ulong new_item_handler_id; private ulong setting_handler_id; public signal void update(string app_uri, HashTable properties); public LauncherBadge(StreamInteractor stream_interactor) throws IOError { this.stream_interactor = stream_interactor; connection = Bus.get_sync(BusType.SESSION); object_registration_id = connection.register_object(OBJECT_PATH, this); ConversationManager conversation_manager = stream_interactor.get_module(ConversationManager.IDENTITY); conversation_activated_handler_id = conversation_manager.conversation_activated.connect(add_conversation); conversation_deactivated_handler_id = conversation_manager.conversation_deactivated.connect(remove_conversation); new_item_handler_id = stream_interactor.get_module(ContentItemStore.IDENTITY).new_item.connect(() => update_count()); setting_handler_id = Dino.Application.get_default().settings.notify["notifications-badge"].connect(() => update_count(true)); foreach (Conversation conversation in conversation_manager.get_active_conversations()) { connect_conversation(conversation); } watcher_id = Bus.watch_name_on_connection( connection, BUS_NAME, BusNameWatcherFlags.NONE, () => update_count(true)); update_count(true); } public void query(out string app_uri, out HashTable properties) throws Error { app_uri = APP_URI; properties = get_properties(); } internal void shutdown() { unread_count = 0; update(APP_URI, get_properties()); ConversationManager conversation_manager = stream_interactor.get_module(ConversationManager.IDENTITY); conversation_manager.disconnect(conversation_activated_handler_id); conversation_manager.disconnect(conversation_deactivated_handler_id); stream_interactor.get_module(ContentItemStore.IDENTITY).disconnect(new_item_handler_id); Dino.Application.get_default().settings.disconnect(setting_handler_id); foreach (Conversation conversation in read_handler_ids.keys) { conversation.disconnect(read_handler_ids[conversation]); } read_handler_ids.clear(); if (watcher_id != 0) { Bus.unwatch_name(watcher_id); watcher_id = 0; } if (object_registration_id != 0) { connection.unregister_object(object_registration_id); object_registration_id = 0; } } private void add_conversation(Conversation conversation) { connect_conversation(conversation); update_count(); } private void remove_conversation(Conversation conversation) { if (read_handler_ids.has_key(conversation)) { conversation.disconnect(read_handler_ids[conversation]); read_handler_ids.unset(conversation); } update_count(); } private void connect_conversation(Conversation conversation) { if (read_handler_ids.has_key(conversation)) return; read_handler_ids[conversation] = conversation.notify["read-up-to-item"].connect(() => update_count()); } private void update_count(bool force = false) { int64 count = 0; ChatInteraction chat_interaction = stream_interactor.get_module(ChatInteraction.IDENTITY); foreach (Conversation conversation in stream_interactor.get_module(ConversationManager.IDENTITY).get_active_conversations()) { count += chat_interaction.get_num_unread(conversation); } if (!force && count == unread_count) return; unread_count = count; update(APP_URI, get_properties()); } private HashTable get_properties() { HashTable properties = new HashTable(str_hash, str_equal); properties["count"] = new Variant.int64(unread_count); properties["count-visible"] = new Variant.boolean(Dino.Application.get_default().settings.notifications_badge && unread_count > 0); return properties; } } }