126 lines
4.7 KiB
Vala
126 lines
4.7 KiB
Vala
using GLib;
|
|
using Gee;
|
|
|
|
public class ConversationListModel : Object, ListModel
|
|
{
|
|
public SortedSet<Conversation> conversations {
|
|
owned get { return _conversations.read_only_view; }
|
|
}
|
|
|
|
private SortedSet<Conversation> _conversations;
|
|
|
|
public ConversationListModel() {
|
|
_conversations = new TreeSet<Conversation>((a, b) => {
|
|
// Sort by date in descending order (newest first)
|
|
return (int)(b.date - a.date);
|
|
});
|
|
|
|
Repository.get_instance().conversations_updated.connect(load_conversations);
|
|
Repository.get_instance().messages_updated.connect(load_conversations);
|
|
}
|
|
|
|
public void load_conversations() {
|
|
try {
|
|
Conversation[] new_conversations = Repository.get_instance().get_conversations();
|
|
|
|
// Create a map of old conversations for quick lookup
|
|
var old_conversations_map = new HashMap<string, Conversation>();
|
|
foreach (var conv in _conversations) {
|
|
old_conversations_map[conv.guid] = conv;
|
|
}
|
|
|
|
// Create a map of new conversations for quick lookup
|
|
var new_conversations_map = new HashMap<string, Conversation>();
|
|
foreach (var conv in new_conversations) {
|
|
new_conversations_map[conv.guid] = conv;
|
|
}
|
|
|
|
// Find removed conversations
|
|
var removed_positions = new ArrayList<uint>();
|
|
var current_position = 0;
|
|
foreach (var old_conv in _conversations) {
|
|
if (!new_conversations_map.has_key(old_conv.guid)) {
|
|
removed_positions.add(current_position);
|
|
}
|
|
current_position++;
|
|
}
|
|
|
|
// Remove conversations in reverse order to maintain correct positions
|
|
for (int i = removed_positions.size - 1; i >= 0; i--) {
|
|
var pos = removed_positions[i];
|
|
_conversations.remove(_conversations.to_array()[pos]);
|
|
items_changed(pos, 1, 0);
|
|
}
|
|
|
|
// Find added conversations and changed conversations
|
|
var added_conversations = new ArrayList<Conversation>();
|
|
var changed_conversations = new ArrayList<Conversation>();
|
|
foreach (var new_conv in new_conversations) {
|
|
if (!old_conversations_map.has_key(new_conv.guid)) {
|
|
added_conversations.add(new_conv);
|
|
} else {
|
|
var old_conv = old_conversations_map[new_conv.guid];
|
|
if (!old_conv.equals(new_conv)) {
|
|
changed_conversations.add(new_conv);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Add new conversations
|
|
foreach (var conv in added_conversations) {
|
|
_conversations.add(conv);
|
|
// Find the position by counting how many items are before this one
|
|
uint pos = 0;
|
|
foreach (var existing_conv in _conversations) {
|
|
if (existing_conv.guid == conv.guid) break;
|
|
pos++;
|
|
}
|
|
items_changed(pos, 0, 1);
|
|
}
|
|
|
|
// Update changed conversations
|
|
GLib.message("Changed conversations: %d", changed_conversations.size);
|
|
foreach (var conv in changed_conversations) {
|
|
// Find position of old conversation
|
|
uint old_pos = 0;
|
|
var old_conv = old_conversations_map[conv.guid];
|
|
foreach (var existing_conv in _conversations) {
|
|
if (existing_conv.guid == old_conv.guid) break;
|
|
old_pos++;
|
|
}
|
|
|
|
// Remove the old one
|
|
_conversations.remove(old_conv);
|
|
|
|
// Add the new one
|
|
_conversations.add(conv);
|
|
|
|
// Find the new (sorted) position
|
|
uint new_pos = 0;
|
|
foreach (var existing_conv in _conversations) {
|
|
if (existing_conv.guid == conv.guid) break;
|
|
new_pos++;
|
|
}
|
|
|
|
// Notify of the change
|
|
items_changed(old_pos, 1, 0);
|
|
items_changed(new_pos, 0, 1);
|
|
}
|
|
} catch (Error e) {
|
|
warning("Failed to load conversations: %s", e.message);
|
|
}
|
|
}
|
|
|
|
// ListModel implementation
|
|
public Type get_item_type() {
|
|
return typeof(Conversation);
|
|
}
|
|
|
|
public uint get_n_items() {
|
|
return _conversations.size;
|
|
}
|
|
|
|
public Object? get_item(uint position) {
|
|
return _conversations.to_array()[position];
|
|
}
|
|
} |