1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
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;
}
}
}
|