dino/main/src/ui/conversation_selector/conversation_selector.vala

165 lines
5.9 KiB
Vala
Raw Normal View History

2022-05-14 12:45:59 +00:00
using Gdk;
2017-03-02 14:37:32 +00:00
using Gee;
using Gtk;
using Xmpp;
using Dino.Entities;
2019-04-12 15:43:47 +00:00
namespace Dino.Ui {
2017-03-10 17:07:28 +00:00
2022-02-14 13:55:59 +00:00
public class ConversationSelector : Widget {
2017-03-02 14:37:32 +00:00
public signal void conversation_selected(Conversation conversation);
2022-02-14 13:55:59 +00:00
ListBox list_box = new ListBox() { hexpand=true };
2017-03-02 14:37:32 +00:00
private StreamInteractor stream_interactor;
private uint? drag_timeout;
2019-04-12 15:43:47 +00:00
private HashMap<Conversation, ConversationSelectorRow> rows = new HashMap<Conversation, ConversationSelectorRow>(Conversation.hash_func, Conversation.equals_func);
2017-03-02 14:37:32 +00:00
2019-04-12 15:43:47 +00:00
public ConversationSelector init(StreamInteractor stream_interactor) {
2017-03-02 14:37:32 +00:00
this.stream_interactor = stream_interactor;
2022-05-14 12:45:59 +00:00
list_box.set_parent(this);
2022-02-14 13:55:59 +00:00
this.layout_manager = new BinLayout();
2017-03-02 14:37:32 +00:00
2017-11-11 20:29:13 +00:00
stream_interactor.get_module(ConversationManager.IDENTITY).conversation_activated.connect(add_conversation);
stream_interactor.get_module(ConversationManager.IDENTITY).conversation_deactivated.connect(remove_conversation);
stream_interactor.get_module(ContentItemStore.IDENTITY).new_item.connect(on_content_item_received);
2017-03-02 14:37:32 +00:00
Timeout.add_seconds(60, () => {
2019-04-12 15:43:47 +00:00
foreach (ConversationSelectorRow row in rows.values) row.update();
2017-03-02 14:37:32 +00:00
return true;
});
foreach (Conversation conversation in stream_interactor.get_module(ConversationManager.IDENTITY).get_active_conversations()) {
add_conversation(conversation);
}
return this;
}
construct {
2022-02-14 13:55:59 +00:00
list_box.set_sort_func(sort);
realize.connect(() => {
2022-02-14 13:55:59 +00:00
ListBoxRow? first_row = list_box.get_row_at_index(0);
if (first_row != null) {
2022-02-14 13:55:59 +00:00
list_box.select_row(first_row);
row_activated(first_row);
}
});
2022-02-14 13:55:59 +00:00
list_box.row_activated.connect(row_activated);
2017-03-02 14:37:32 +00:00
}
2022-02-14 13:55:59 +00:00
public void row_activated(ListBoxRow r) {
2019-04-12 15:43:47 +00:00
ConversationSelectorRow? row = r as ConversationSelectorRow;
if (row != null) {
2017-03-02 14:37:32 +00:00
conversation_selected(row.conversation);
}
}
public void on_conversation_selected(Conversation conversation) {
if (!rows.has_key(conversation)) {
add_conversation(conversation);
}
2022-02-14 13:55:59 +00:00
list_box.select_row(rows[conversation]);
}
private void on_content_item_received(ContentItem item, Conversation conversation) {
if (rows.has_key(conversation)) {
2022-02-14 13:55:59 +00:00
list_box.invalidate_sort();
}
}
private void add_conversation(Conversation conversation) {
2019-04-12 15:43:47 +00:00
ConversationSelectorRow row;
2017-03-02 14:37:32 +00:00
if (!rows.has_key(conversation)) {
conversation.notify["pinned"].connect(list_box.invalidate_sort);
2019-04-12 15:43:47 +00:00
row = new ConversationSelectorRow(stream_interactor, conversation);
2017-03-02 14:37:32 +00:00
rows[conversation] = row;
2022-02-14 13:55:59 +00:00
list_box.append(row);
2017-03-02 14:37:32 +00:00
row.main_revealer.set_reveal_child(true);
2022-05-14 12:45:59 +00:00
// Set up drag motion behaviour (select conversation after timeout)
DropControllerMotion drop_motion_controller = new DropControllerMotion();
uint drag_timeout = 0;
drop_motion_controller.motion.connect((x, y) => {
if (drag_timeout != 0) return;
drag_timeout = Timeout.add(200, () => {
conversation_selected(conversation);
drag_timeout = 0;
return false;
});
});
drop_motion_controller.leave.connect(() => {
if (drag_timeout != 0) {
Source.remove(drag_timeout);
drag_timeout = 0;
}
});
row.add_controller(drop_motion_controller);
2017-03-02 14:37:32 +00:00
}
2022-02-14 13:55:59 +00:00
list_box.invalidate_sort();
2017-03-02 14:37:32 +00:00
}
private void select_fallback_conversation(Conversation conversation) {
2022-02-14 13:55:59 +00:00
if (list_box.get_selected_row() == rows[conversation]) {
int index = rows[conversation].get_index();
2022-02-14 13:55:59 +00:00
ListBoxRow? next_select_row = list_box.get_row_at_index(index + 1);
if (next_select_row == null) {
2022-02-14 13:55:59 +00:00
next_select_row = list_box.get_row_at_index(index - 1);
}
if (next_select_row != null) {
2022-02-14 13:55:59 +00:00
list_box.select_row(next_select_row);
row_activated(next_select_row);
}
2017-03-02 14:37:32 +00:00
}
}
private async void remove_conversation(Conversation conversation) {
select_fallback_conversation(conversation);
if (rows.has_key(conversation)) {
conversation.notify["pinned"].disconnect(list_box.invalidate_sort);
yield rows[conversation].colapse();
2022-02-14 13:55:59 +00:00
list_box.remove(rows[conversation]);
rows.unset(conversation);
2017-03-02 14:37:32 +00:00
}
}
public void loop_conversations(bool backwards) {
2022-02-14 13:55:59 +00:00
int index = list_box.get_selected_row().get_index();
int new_index = ((index + (backwards ? -1 : 1)) + rows.size) % rows.size;
2022-02-14 13:55:59 +00:00
ListBoxRow? next_select_row = list_box.get_row_at_index(new_index);
if (next_select_row != null) {
2022-02-14 13:55:59 +00:00
list_box.select_row(next_select_row);
row_activated(next_select_row);
}
}
2017-03-02 14:37:32 +00:00
private int sort(ListBoxRow row1, ListBoxRow row2) {
2019-04-12 15:43:47 +00:00
ConversationSelectorRow cr1 = row1 as ConversationSelectorRow;
ConversationSelectorRow cr2 = row2 as ConversationSelectorRow;
2017-03-02 14:37:32 +00:00
if (cr1 != null && cr2 != null) {
Conversation c1 = cr1.conversation;
Conversation c2 = cr2.conversation;
int pin_comp = c2.pinned - c1.pinned;
if (pin_comp != 0) return pin_comp;
2017-03-30 23:17:01 +00:00
if (c1.last_active == null) return -1;
if (c2.last_active == null) return 1;
2017-03-02 14:37:32 +00:00
int comp = c2.last_active.compare(c1.last_active);
if (comp == 0) {
return Util.get_conversation_display_name(stream_interactor, c1)
.collate(Util.get_conversation_display_name(stream_interactor, c2));
} else {
return comp;
}
}
return 0;
}
}
2017-03-10 17:07:28 +00:00
2017-08-31 20:22:44 +00:00
}