From 3e1fa63fdff431826ffa1fa5c041f557da9e385f Mon Sep 17 00:00:00 2001 From: James Magahern Date: Wed, 30 Apr 2025 15:19:44 -0700 Subject: [PATCH] reorg: separate dbus code out of conversation list model and into repository --- .../conversation-list-model.vala | 62 +------------ src/meson.build | 4 +- src/models/conversation.vala | 46 +++------- src/service/repository.vala | 88 +++++++++++++++++++ 4 files changed, 109 insertions(+), 91 deletions(-) create mode 100644 src/service/repository.vala diff --git a/src/conversation-list/conversation-list-model.vala b/src/conversation-list/conversation-list-model.vala index b2a513d..18fc2fa 100644 --- a/src/conversation-list/conversation-list-model.vala +++ b/src/conversation-list/conversation-list-model.vala @@ -8,8 +8,6 @@ public class ConversationListModel : Object, ListModel } private SortedSet _conversations; - private DBusService.Repository repository; - private uint dbus_watch_id; public ConversationListModel() { _conversations = new TreeSet((a, b) => { @@ -17,62 +15,12 @@ public class ConversationListModel : Object, ListModel return (int)(b.date - a.date); }); - connect_to_dbus.begin(); - } - - ~ConversationListModel() { - if (dbus_watch_id > 0) { - Bus.unwatch_name(dbus_watch_id); - } - } - - private async void connect_to_dbus() { - bool connected = false; - const string path = "/net/buzzert/kordophonecd/daemon"; - - try { - debug("Trying to connect to DBus service at path: %s", path); - repository = yield Bus.get_proxy(BusType.SESSION, - "net.buzzert.kordophonecd", - path); - - // Test the connection - repository.get_version(); - - // If we get here, connection succeeded - debug("Connected to DBus service at path: %s", path); - connected = true; - - // Listen for updates - repository.conversations_updated.connect(load_conversations); - - // Initial load - load_conversations(); - } catch (Error e) { - debug("Failed to connect to kordophonecd at %s: %s", path, e.message); - } - - if (!connected) { - warning("Failed to connect to kordophonecd on any known path"); - - // Watch for the service to appear - dbus_watch_id = Bus.watch_name(BusType.SESSION, - "net.buzzert.kordophonecd", - BusNameWatcherFlags.AUTO_START, - () => { - connect_to_dbus.begin(); - }, - null); - } + Repository.get_instance().conversations_updated.connect(load_conversations); } public void load_conversations() { - if (repository == null) { - return; - } - try { - Variant conversations_variant = repository.get_conversations(); + Conversation[] conversations = Repository.get_instance().get_conversations(); // Clear existing set uint old_count = _conversations.size; @@ -84,12 +32,10 @@ public class ConversationListModel : Object, ListModel } // Process each conversation - size_t n_children = conversations_variant.n_children(); uint position = 0; - for (size_t i = 0; i < n_children; i++) { - Variant child = conversations_variant.get_child_value(i); - var conversation = new Conversation.from_variant(child); + for (int i = 0; i < conversations.length; i++) { + var conversation = conversations[i]; _conversations.add(conversation); position++; } diff --git a/src/meson.build b/src/meson.build index 70740ac..fe69dab 100644 --- a/src/meson.build +++ b/src/meson.build @@ -2,7 +2,8 @@ dependencies = [ dependency('gtk4', required : true), dependency('libadwaita-1', required : true), dependency('gio-2.0', required : true), - dependency('gee-0.8', required : true) + dependency('gee-0.8', required : true), + dependency('gio-unix-2.0', required : true) ] sources = [ @@ -10,6 +11,7 @@ sources = [ 'application/main-window.vala', 'service/interface/dbusservice.vala', + 'service/repository.vala', 'conversation-list/conversation-list-view.vala', 'conversation-list/conversation-list-model.vala', diff --git a/src/models/conversation.vala b/src/models/conversation.vala index a88ddbd..3e489ea 100644 --- a/src/models/conversation.vala +++ b/src/models/conversation.vala @@ -1,7 +1,7 @@ using GLib; public class Conversation : Object { - public string id { get; set; default = ""; } + public string guid { get; set; default = ""; } public string last_message_preview { get; set; default = ""; } public int64 date { get; set; default = 0; } public string[] participants { get; set; default = new string[0]; } @@ -29,45 +29,27 @@ public class Conversation : Object { private string? _display_name = null; - public Conversation.from_variant (Variant dict) { - id = ""; - last_message_preview = ""; - participants = new string[0]; - - if (dict.get_type_string() != "a{sv}") { - warning("Expected dictionary variant, got %s", dict.get_type_string()); - return; - } - - // Safe extraction with type checking - Variant? id_variant = dict.lookup_value("id", VariantType.STRING); - if (id_variant != null) { - id = id_variant.get_string(); + public Conversation.from_hash_table(HashTable conversation_data) { + guid = conversation_data["guid"].get_string(); + + if (conversation_data.contains("last_message_preview")) { + last_message_preview = conversation_data["last_message_preview"].get_string(); } - Variant? display_name_variant = dict.lookup_value("display_name", VariantType.STRING); - if (display_name_variant != null) { - _display_name = display_name_variant.get_string(); + if (conversation_data.contains("participants")) { + participants = conversation_data["participants"].dup_strv(); } - Variant? last_message_variant = dict.lookup_value("last_message_preview", VariantType.STRING); - if (last_message_variant != null) { - last_message_preview = last_message_variant.get_string(); + if (conversation_data.contains("unread_count")) { + unread_count = conversation_data["unread_count"].get_int32(); } - Variant? date_variant = dict.lookup_value("date", VariantType.INT64); - if (date_variant != null) { - date = date_variant.get_int64(); + if (conversation_data.contains("date")) { + date = conversation_data["date"].get_int64(); } - Variant? participants_variant = dict.lookup_value("participants", new VariantType("as")); - if (participants_variant != null) { - participants = participants_variant.dup_strv(); - } - - Variant? unread_count_variant = dict.lookup_value("unread_count", VariantType.INT32); - if (unread_count_variant != null) { - unread_count = unread_count_variant.get_int32(); + if (conversation_data.contains("display_name")) { + _display_name = conversation_data["display_name"].get_string(); } } } \ No newline at end of file diff --git a/src/service/repository.vala b/src/service/repository.vala new file mode 100644 index 0000000..82a1a7a --- /dev/null +++ b/src/service/repository.vala @@ -0,0 +1,88 @@ +using GLib; +using Gee; + +public class Repository : Object +{ + public signal void conversations_updated(); + + public static Repository get_instance() { + if (instance == null) { + instance = new Repository(); + } + + return instance; + } + + private static Repository instance = null; + private DBusService.Repository dbus_repository; + private uint dbus_watch_id; + + private Repository() { + connect_to_dbus.begin((obj, res) => { + connect_to_dbus.end(res); + }); + } + + ~Repository() { + if (dbus_watch_id > 0) { + Bus.unwatch_name(dbus_watch_id); + } + } + + public Conversation[] get_conversations() throws Error { + if (dbus_repository == null) { + throw new Error(1337, 1, "Repository not connected"); + } + + var conversations = dbus_repository.get_conversations(); + Conversation[] returned_conversations = new Conversation[conversations.length]; + + for (int i = 0; i < conversations.length; i++) { + returned_conversations[i] = new Conversation.from_hash_table(conversations[i]); + } + + return returned_conversations; + } + + private async void connect_to_dbus() { + bool connected = false; + const string path = "/net/buzzert/kordophonecd/daemon"; + + try { + debug("Trying to connect to DBus service at path: %s", path); + dbus_repository = yield Bus.get_proxy(BusType.SESSION, + "net.buzzert.kordophonecd", + path); + + // Test the connection + dbus_repository.get_version(); + + // If we get here, connection succeeded + debug("Connected to DBus service at path: %s", path); + connected = true; + + // Listen for updates + dbus_repository.conversations_updated.connect(() => { + conversations_updated(); + }); + + // Initial load + conversations_updated(); + } catch (Error e) { + debug("Failed to connect to kordophonecd at %s: %s", path, e.message); + } + + if (!connected) { + warning("Failed to connect to kordophonecd on any known path"); + + // Watch for the service to appear + dbus_watch_id = Bus.watch_name(BusType.SESSION, + "net.buzzert.kordophonecd", + BusNameWatcherFlags.AUTO_START, + () => { + connect_to_dbus.begin(); + }, + null); + } + } +}