2025-04-30 15:58:47 -07:00
|
|
|
using GLib;
|
|
|
|
|
using Gee;
|
|
|
|
|
|
|
|
|
|
public class MessageListModel : Object, ListModel
|
|
|
|
|
{
|
2025-04-30 19:50:36 -07:00
|
|
|
public signal void messages_changed();
|
|
|
|
|
|
2025-05-14 17:37:23 -07:00
|
|
|
public ArrayList<Message> messages {
|
|
|
|
|
get { return _messages; }
|
2025-04-30 15:58:47 -07:00
|
|
|
}
|
|
|
|
|
|
2025-05-03 23:19:15 -07:00
|
|
|
public bool is_group_chat {
|
|
|
|
|
get {
|
|
|
|
|
return participants.size > 2;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-05-02 15:09:12 -07:00
|
|
|
public string conversation_guid { get; private set; }
|
2025-05-03 23:19:15 -07:00
|
|
|
|
2025-05-14 17:37:23 -07:00
|
|
|
private ArrayList<Message> _messages;
|
2025-05-03 23:19:15 -07:00
|
|
|
private HashSet<string> participants = new HashSet<string>();
|
2025-06-13 17:48:50 -07:00
|
|
|
private ulong update_handler_id = 0;
|
|
|
|
|
private ulong reconnected_handler_id = 0;
|
2025-04-30 15:58:47 -07:00
|
|
|
|
2025-05-14 17:37:23 -07:00
|
|
|
public MessageListModel(string conversation_guid) {
|
|
|
|
|
_messages = new ArrayList<Message>();
|
2025-05-02 15:09:12 -07:00
|
|
|
this.conversation_guid = conversation_guid;
|
2025-04-30 15:58:47 -07:00
|
|
|
}
|
2025-05-14 17:37:23 -07:00
|
|
|
|
|
|
|
|
~MessageListModel() {
|
|
|
|
|
// NOTE: this won't actually get destructed automatically because of a retain cycle with the signal handler.
|
|
|
|
|
// unwatch_updates() should be called explicitly when the model is no longer needed.
|
|
|
|
|
unwatch_updates();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void watch_updates() {
|
2025-06-13 17:48:50 -07:00
|
|
|
if (this.update_handler_id == 0) {
|
2025-06-13 17:13:04 -07:00
|
|
|
weak MessageListModel self = this;
|
2025-06-13 17:48:50 -07:00
|
|
|
this.update_handler_id = Repository.get_instance().messages_updated.connect((conversation_guid) => {
|
2025-06-13 17:13:04 -07:00
|
|
|
self.got_messages_updated(conversation_guid);
|
|
|
|
|
});
|
2025-06-13 17:48:50 -07:00
|
|
|
}
|
2025-06-13 17:13:04 -07:00
|
|
|
|
2025-06-13 17:48:50 -07:00
|
|
|
if (this.reconnected_handler_id == 0) {
|
|
|
|
|
weak MessageListModel self = this;
|
|
|
|
|
this.reconnected_handler_id = Repository.get_instance().reconnected.connect(() => {
|
2025-06-13 17:13:04 -07:00
|
|
|
// On reconnect, reload the messages that we're looking at now.
|
|
|
|
|
self.load_messages();
|
|
|
|
|
});
|
2025-05-14 17:37:23 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void unwatch_updates() {
|
2025-06-13 17:48:50 -07:00
|
|
|
if (this.update_handler_id != 0) {
|
|
|
|
|
Repository.get_instance().disconnect(this.update_handler_id);
|
|
|
|
|
this.update_handler_id = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (this.reconnected_handler_id != 0) {
|
|
|
|
|
Repository.get_instance().disconnect(this.reconnected_handler_id);
|
|
|
|
|
this.reconnected_handler_id = 0;
|
2025-05-14 17:37:23 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-04-30 15:58:47 -07:00
|
|
|
public void load_messages() {
|
|
|
|
|
try {
|
2025-05-02 15:09:12 -07:00
|
|
|
Message[] messages = Repository.get_instance().get_messages(conversation_guid);
|
2025-04-30 15:58:47 -07:00
|
|
|
|
|
|
|
|
// Clear existing set
|
|
|
|
|
uint old_count = _messages.size;
|
|
|
|
|
_messages.clear();
|
2025-05-03 23:19:15 -07:00
|
|
|
participants.clear();
|
2025-04-30 15:58:47 -07:00
|
|
|
|
|
|
|
|
// Notify of removal
|
|
|
|
|
if (old_count > 0) {
|
|
|
|
|
items_changed(0, old_count, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Process each conversation
|
|
|
|
|
uint position = 0;
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < messages.length; i++) {
|
|
|
|
|
var message = messages[i];
|
|
|
|
|
_messages.add(message);
|
2025-05-03 23:19:15 -07:00
|
|
|
participants.add(message.sender);
|
|
|
|
|
|
2025-04-30 15:58:47 -07:00
|
|
|
position++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Notify of additions
|
|
|
|
|
if (position > 0) {
|
|
|
|
|
items_changed(0, 0, position);
|
|
|
|
|
}
|
|
|
|
|
} catch (Error e) {
|
|
|
|
|
warning("Failed to load messages: %s", e.message);
|
|
|
|
|
}
|
2025-04-30 19:50:36 -07:00
|
|
|
|
|
|
|
|
messages_changed();
|
2025-04-30 15:58:47 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void got_messages_updated(string conversation_guid) {
|
2025-05-02 15:09:12 -07:00
|
|
|
if (conversation_guid == this.conversation_guid) {
|
2025-04-30 15:58:47 -07:00
|
|
|
load_messages();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ListModel implementation
|
|
|
|
|
public Type get_item_type() {
|
|
|
|
|
return typeof(Message);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public uint get_n_items() {
|
|
|
|
|
return _messages.size;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public Object? get_item(uint position) {
|
2025-05-14 17:37:23 -07:00
|
|
|
return _messages.get((int)position);
|
2025-04-30 15:58:47 -07:00
|
|
|
}
|
|
|
|
|
}
|