aboutsummaryrefslogtreecommitdiff
path: root/main/src/ui/launcher_badge.vala
diff options
context:
space:
mode:
Diffstat (limited to 'main/src/ui/launcher_badge.vala')
-rw-r--r--main/src/ui/launcher_badge.vala118
1 files changed, 118 insertions, 0 deletions
diff --git a/main/src/ui/launcher_badge.vala b/main/src/ui/launcher_badge.vala
new file mode 100644
index 00000000..aa07fbaa
--- /dev/null
+++ b/main/src/ui/launcher_badge.vala
@@ -0,0 +1,118 @@
+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<Conversation, ulong> read_handler_ids = new HashMap<Conversation, ulong>(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<string, Variant> 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<string, Variant> 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<string, Variant> get_properties() {
+ HashTable<string, Variant> properties = new HashTable<string, Variant>(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;
+ }
+}
+
+}