From 29ca70a6d534e1cd79963718c793ae740318cff1 Mon Sep 17 00:00:00 2001 From: Marvin W Date: Fri, 10 Mar 2017 19:34:56 +0100 Subject: Initial plugin system --- libdino/src/ui/conversation_selector/list.vala | 173 +++++++++++++++++++++++++ 1 file changed, 173 insertions(+) create mode 100644 libdino/src/ui/conversation_selector/list.vala (limited to 'libdino/src/ui/conversation_selector/list.vala') diff --git a/libdino/src/ui/conversation_selector/list.vala b/libdino/src/ui/conversation_selector/list.vala new file mode 100644 index 00000000..e6a5231c --- /dev/null +++ b/libdino/src/ui/conversation_selector/list.vala @@ -0,0 +1,173 @@ +using Gee; +using Gtk; + +using Xmpp; +using Dino.Entities; + +namespace Dino.Ui.ConversationSelector { +public class List : ListBox { + + public signal void conversation_selected(Conversation conversation); + + private StreamInteractor stream_interactor; + private string[]? filter_values; + private HashMap rows = new HashMap(Conversation.hash_func, Conversation.equals_func); + + public List(StreamInteractor stream_interactor) { + this.stream_interactor = stream_interactor; + + get_style_context().add_class("sidebar"); + set_filter_func(filter); + set_header_func(header); + set_sort_func(sort); + + ChatInteraction.get_instance(stream_interactor).conversation_read.connect((conversation) => { + Idle.add(() => {rows[conversation].mark_read(); return false;}); + }); + ChatInteraction.get_instance(stream_interactor).conversation_unread.connect((conversation) => { + Idle.add(() => {rows[conversation].mark_unread(); return false;}); + }); + ConversationManager.get_instance(stream_interactor).conversation_activated.connect((conversation) => { + Idle.add(() => {add_conversation(conversation); return false;}); + }); + MessageManager.get_instance(stream_interactor).message_received.connect((message, conversation) => { + Idle.add(() => {message_received(message, conversation); return false;}); + }); + MessageManager.get_instance(stream_interactor).message_sent.connect((message, conversation) => { + Idle.add(() => {message_received(message, conversation); return false;}); + }); + PresenceManager.get_instance(stream_interactor).show_received.connect((show, jid, account) => { + Idle.add(() => { + Conversation? conversation = ConversationManager.get_instance(stream_interactor).get_conversation(jid, account); + if (conversation != null && rows.has_key(conversation)) rows[conversation].on_show_received(show); + return false; + }); + }); + RosterManager.get_instance(stream_interactor).updated_roster_item.connect((account, jid, roster_item) => { + Idle.add(() => { + Conversation? conversation = ConversationManager.get_instance(stream_interactor).get_conversation(jid, account); + if (conversation != null && rows.has_key(conversation)) { + ChatRow row = rows[conversation] as ChatRow; + if (row != null) row.on_updated_roster_item(roster_item); + } + return false; + }); + }); + AvatarManager.get_instance(stream_interactor).received_avatar.connect((avatar, jid, account) => { + Idle.add(() => { + Conversation? conversation = ConversationManager.get_instance(stream_interactor).get_conversation(jid, account); + if (conversation != null && rows.has_key(conversation)) { + ChatRow row = rows[conversation] as ChatRow; + if (row != null) row.update_avatar(); + } + return false; + }); + }); + stream_interactor.connection_manager.connection_state_changed.connect((account, state) => { + Idle.add(() => { + foreach (ConversationRow row in rows.values) { + if (row.conversation.account.equals(account)) row.network_connection(state == ConnectionManager.ConnectionState.CONNECTED); + } + return false; + }); + }); + Timeout.add_seconds(60, () => { + foreach (ConversationRow row in rows.values) row.update(); + return true; + }); + } + + public override void row_activated(ListBoxRow r) { + if (r.get_type().is_a(typeof(ConversationRow))) { + ConversationRow row = r as ConversationRow; + conversation_selected(row.conversation); + } + } + + public void set_filter_values(string[]? values) { + if (filter_values == values) { + return; + } + filter_values = values; + invalidate_filter(); + } + + public void add_conversation(Conversation conversation) { + ConversationRow row; + if (!rows.has_key(conversation)) { + if (conversation.type_ == Conversation.Type.GROUPCHAT) { + row = new GroupchatRow(stream_interactor, conversation); + } else { + row = new ChatRow(stream_interactor, conversation); + } + rows[conversation] = row; + add(row); + row.main_revealer.set_reveal_child(true); + conversation.notify["active"].connect((s, p) => { + if (rows.has_key(conversation) && !conversation.active) { + remove_conversation(conversation); + } + }); + } + invalidate_sort(); + queue_draw(); + } + + public void remove_conversation(Conversation conversation) { + remove(rows[conversation]); + rows.unset(conversation); + } + + public void on_conversation_selected(Conversation conversation) { + if (!rows.has_key(conversation)) { + add_conversation(conversation); + } + this.select_row(rows[conversation]); + } + + private void message_received(Entities.Message message, Conversation conversation) { + if (rows.has_key(conversation)) { + rows[conversation].message_received(message); + invalidate_sort(); + } + } + + private void header(ListBoxRow row, ListBoxRow? before_row) { + if (row.get_header() == null && before_row != null) { + row.set_header(new Separator(Orientation.HORIZONTAL)); + } + } + + private bool filter(ListBoxRow r) { + if (r.get_type().is_a(typeof(ConversationRow))) { + ConversationRow row = r as ConversationRow; + if (filter_values != null && filter_values.length != 0) { + foreach (string filter in filter_values) { + if (!(Util.get_conversation_display_name(stream_interactor, row.conversation).down().contains(filter.down()) || + row.conversation.counterpart.to_string().down().contains(filter.down()))) { + return false; + } + } + } + } + return true; + } + + private int sort(ListBoxRow row1, ListBoxRow row2) { + ConversationRow cr1 = row1 as ConversationRow; + ConversationRow cr2 = row2 as ConversationRow; + if (cr1 != null && cr2 != null) { + Conversation c1 = cr1.conversation; + Conversation c2 = cr2.conversation; + 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; + } +} +} \ No newline at end of file -- cgit v1.2.3-54-g00ecf