2025-04-28 17:29:32 -07:00
|
|
|
using Adw;
|
|
|
|
|
using Gtk;
|
|
|
|
|
|
|
|
|
|
public class ConversationListView : Adw.Bin
|
|
|
|
|
{
|
2025-04-30 19:50:36 -07:00
|
|
|
public signal void conversation_selected(string? conversation_guid);
|
|
|
|
|
|
2025-04-28 17:29:32 -07:00
|
|
|
private Adw.ToolbarView container;
|
|
|
|
|
private ListBox list_box;
|
2025-04-28 18:21:02 -07:00
|
|
|
private ScrolledWindow scrolled_window;
|
2025-04-28 17:29:32 -07:00
|
|
|
private Adw.HeaderBar header_bar;
|
2025-04-28 18:21:02 -07:00
|
|
|
private ConversationListModel conversation_model;
|
2025-04-28 17:29:32 -07:00
|
|
|
|
2025-05-02 15:51:43 -07:00
|
|
|
private string? selected_conversation_guid = null;
|
|
|
|
|
private bool selection_update_queued = false;
|
|
|
|
|
|
2025-04-28 17:29:32 -07:00
|
|
|
public ConversationListView () {
|
|
|
|
|
container = new Adw.ToolbarView ();
|
|
|
|
|
set_child (container);
|
|
|
|
|
|
2025-04-28 18:21:02 -07:00
|
|
|
scrolled_window = new ScrolledWindow ();
|
|
|
|
|
container.set_content (scrolled_window);
|
|
|
|
|
|
2025-04-28 17:29:32 -07:00
|
|
|
list_box = new ListBox ();
|
|
|
|
|
list_box.add_css_class ("boxed-list");
|
|
|
|
|
list_box.set_selection_mode (SelectionMode.SINGLE);
|
2025-04-28 18:21:02 -07:00
|
|
|
scrolled_window.set_child (list_box);
|
2025-04-28 17:29:32 -07:00
|
|
|
|
2025-04-30 19:50:36 -07:00
|
|
|
list_box.row_selected.connect ((row) => {
|
|
|
|
|
var conversation_row = (ConversationRow?) row;
|
2025-05-02 15:51:43 -07:00
|
|
|
if (conversation_row != null) {
|
|
|
|
|
selected_conversation_guid = conversation_row.conversation.guid;
|
|
|
|
|
conversation_selected(selected_conversation_guid);
|
|
|
|
|
}
|
2025-04-30 19:50:36 -07:00
|
|
|
});
|
|
|
|
|
|
2025-04-28 17:29:32 -07:00
|
|
|
header_bar = new Adw.HeaderBar ();
|
|
|
|
|
header_bar.set_title_widget (new Label ("Kordophone"));
|
|
|
|
|
container.add_top_bar (header_bar);
|
|
|
|
|
|
2025-04-28 18:21:02 -07:00
|
|
|
// Set up refresh button
|
|
|
|
|
var refresh_button = new Button.from_icon_name ("view-refresh-symbolic");
|
|
|
|
|
refresh_button.tooltip_text = "Refresh Conversations";
|
|
|
|
|
refresh_button.clicked.connect (() => {
|
|
|
|
|
if (conversation_model != null) {
|
|
|
|
|
conversation_model.load_conversations ();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
header_bar.pack_end (refresh_button);
|
|
|
|
|
|
|
|
|
|
// Set up model and bind to list
|
|
|
|
|
conversation_model = new ConversationListModel ();
|
2025-05-02 15:51:43 -07:00
|
|
|
conversation_model.items_changed.connect (on_items_changed);
|
2025-04-28 18:21:02 -07:00
|
|
|
list_box.bind_model (conversation_model, create_conversation_row);
|
2025-04-28 17:29:32 -07:00
|
|
|
}
|
|
|
|
|
|
2025-05-02 15:51:43 -07:00
|
|
|
private void on_items_changed (uint position, uint removed, uint added) {
|
|
|
|
|
enqueue_selection_update();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void enqueue_selection_update() {
|
|
|
|
|
if (selection_update_queued) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
selection_update_queued = true;
|
|
|
|
|
GLib.Idle.add(() => {
|
|
|
|
|
update_selection();
|
|
|
|
|
selection_update_queued = false;
|
|
|
|
|
return false;
|
|
|
|
|
}, GLib.Priority.HIGH);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void update_selection() {
|
|
|
|
|
// Re-select selected_conversation_guid, if it has changed.
|
|
|
|
|
if (selected_conversation_guid != null) {
|
|
|
|
|
for (uint i = 0; i < conversation_model.get_n_items(); i++) {
|
|
|
|
|
var conversation = (Conversation) conversation_model.get_item(i);
|
|
|
|
|
if (conversation.guid == selected_conversation_guid) {
|
|
|
|
|
var row = list_box.get_row_at_index((int)i);
|
|
|
|
|
if (row != null) {
|
|
|
|
|
list_box.select_row(row);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2025-04-28 18:21:02 -07:00
|
|
|
private Widget create_conversation_row (Object item) {
|
|
|
|
|
Conversation conversation = (Conversation) item;
|
|
|
|
|
return new ConversationRow (conversation);
|
|
|
|
|
}
|
2025-04-28 17:29:32 -07:00
|
|
|
}
|