reorg: separate dbus code out of conversation list model and into repository
This commit is contained in:
@@ -8,8 +8,6 @@ public class ConversationListModel : Object, ListModel
|
|||||||
}
|
}
|
||||||
|
|
||||||
private SortedSet<Conversation> _conversations;
|
private SortedSet<Conversation> _conversations;
|
||||||
private DBusService.Repository repository;
|
|
||||||
private uint dbus_watch_id;
|
|
||||||
|
|
||||||
public ConversationListModel() {
|
public ConversationListModel() {
|
||||||
_conversations = new TreeSet<Conversation>((a, b) => {
|
_conversations = new TreeSet<Conversation>((a, b) => {
|
||||||
@@ -17,62 +15,12 @@ public class ConversationListModel : Object, ListModel
|
|||||||
return (int)(b.date - a.date);
|
return (int)(b.date - a.date);
|
||||||
});
|
});
|
||||||
|
|
||||||
connect_to_dbus.begin();
|
Repository.get_instance().conversations_updated.connect(load_conversations);
|
||||||
}
|
|
||||||
|
|
||||||
~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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void load_conversations() {
|
public void load_conversations() {
|
||||||
if (repository == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Variant conversations_variant = repository.get_conversations();
|
Conversation[] conversations = Repository.get_instance().get_conversations();
|
||||||
|
|
||||||
// Clear existing set
|
// Clear existing set
|
||||||
uint old_count = _conversations.size;
|
uint old_count = _conversations.size;
|
||||||
@@ -84,12 +32,10 @@ public class ConversationListModel : Object, ListModel
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Process each conversation
|
// Process each conversation
|
||||||
size_t n_children = conversations_variant.n_children();
|
|
||||||
uint position = 0;
|
uint position = 0;
|
||||||
|
|
||||||
for (size_t i = 0; i < n_children; i++) {
|
for (int i = 0; i < conversations.length; i++) {
|
||||||
Variant child = conversations_variant.get_child_value(i);
|
var conversation = conversations[i];
|
||||||
var conversation = new Conversation.from_variant(child);
|
|
||||||
_conversations.add(conversation);
|
_conversations.add(conversation);
|
||||||
position++;
|
position++;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,8 @@ dependencies = [
|
|||||||
dependency('gtk4', required : true),
|
dependency('gtk4', required : true),
|
||||||
dependency('libadwaita-1', required : true),
|
dependency('libadwaita-1', required : true),
|
||||||
dependency('gio-2.0', 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 = [
|
sources = [
|
||||||
@@ -10,6 +11,7 @@ sources = [
|
|||||||
'application/main-window.vala',
|
'application/main-window.vala',
|
||||||
|
|
||||||
'service/interface/dbusservice.vala',
|
'service/interface/dbusservice.vala',
|
||||||
|
'service/repository.vala',
|
||||||
|
|
||||||
'conversation-list/conversation-list-view.vala',
|
'conversation-list/conversation-list-view.vala',
|
||||||
'conversation-list/conversation-list-model.vala',
|
'conversation-list/conversation-list-model.vala',
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
using GLib;
|
using GLib;
|
||||||
|
|
||||||
public class Conversation : Object {
|
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 string last_message_preview { get; set; default = ""; }
|
||||||
public int64 date { get; set; default = 0; }
|
public int64 date { get; set; default = 0; }
|
||||||
public string[] participants { get; set; default = new string[0]; }
|
public string[] participants { get; set; default = new string[0]; }
|
||||||
@@ -29,45 +29,27 @@ public class Conversation : Object {
|
|||||||
|
|
||||||
private string? _display_name = null;
|
private string? _display_name = null;
|
||||||
|
|
||||||
public Conversation.from_variant (Variant dict) {
|
public Conversation.from_hash_table(HashTable<string, Variant> conversation_data) {
|
||||||
id = "";
|
guid = conversation_data["guid"].get_string();
|
||||||
last_message_preview = "";
|
|
||||||
participants = new string[0];
|
if (conversation_data.contains("last_message_preview")) {
|
||||||
|
last_message_preview = conversation_data["last_message_preview"].get_string();
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Variant? display_name_variant = dict.lookup_value("display_name", VariantType.STRING);
|
if (conversation_data.contains("participants")) {
|
||||||
if (display_name_variant != null) {
|
participants = conversation_data["participants"].dup_strv();
|
||||||
_display_name = display_name_variant.get_string();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Variant? last_message_variant = dict.lookup_value("last_message_preview", VariantType.STRING);
|
if (conversation_data.contains("unread_count")) {
|
||||||
if (last_message_variant != null) {
|
unread_count = conversation_data["unread_count"].get_int32();
|
||||||
last_message_preview = last_message_variant.get_string();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Variant? date_variant = dict.lookup_value("date", VariantType.INT64);
|
if (conversation_data.contains("date")) {
|
||||||
if (date_variant != null) {
|
date = conversation_data["date"].get_int64();
|
||||||
date = date_variant.get_int64();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Variant? participants_variant = dict.lookup_value("participants", new VariantType("as"));
|
if (conversation_data.contains("display_name")) {
|
||||||
if (participants_variant != null) {
|
_display_name = conversation_data["display_name"].get_string();
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
88
src/service/repository.vala
Normal file
88
src/service/repository.vala
Normal file
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user