Private
Public Access
1
0
Files
Kordophone/src/transcript/message-list-model.vala

110 lines
3.1 KiB
Vala
Raw Normal View History

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-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-05-14 17:37:23 -07:00
private ulong handler_id = 0;
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-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() {
if (this.handler_id == 0) {
weak MessageListModel self = this;
this.handler_id = Repository.get_instance().messages_updated.connect((conversation_guid) => {
self.got_messages_updated(conversation_guid);
});
this.handler_id = Repository.get_instance().reconnected.connect(() => {
// 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() {
if (this.handler_id != 0) {
Repository.get_instance().disconnect(this.handler_id);
this.handler_id = 0;
}
}
public void load_messages() {
try {
2025-05-02 15:09:12 -07:00
Message[] messages = Repository.get_instance().get_messages(conversation_guid);
// Clear existing set
uint old_count = _messages.size;
_messages.clear();
2025-05-03 23:19:15 -07:00
participants.clear();
// 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);
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();
}
private void got_messages_updated(string conversation_guid) {
2025-05-02 15:09:12 -07:00
if (conversation_guid == this.conversation_guid) {
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);
}
}