aboutsummaryrefslogtreecommitdiff
path: root/client/src/ui/conversation_summary
diff options
context:
space:
mode:
authorMarvin W <git@larma.de>2017-03-10 19:34:56 +0100
committerMarvin W <git@larma.de>2017-03-10 19:50:34 +0100
commit29ca70a6d534e1cd79963718c793ae740318cff1 (patch)
tree295bc0a88b9f31f103bc970fbdcd2d940d6c83e2 /client/src/ui/conversation_summary
parentcf51e1dee22273366700c41a185c4bea343dddfe (diff)
downloaddino-29ca70a6d534e1cd79963718c793ae740318cff1.tar.gz
dino-29ca70a6d534e1cd79963718c793ae740318cff1.zip
Initial plugin system
Diffstat (limited to 'client/src/ui/conversation_summary')
-rw-r--r--client/src/ui/conversation_summary/merged_message_item.vala170
-rw-r--r--client/src/ui/conversation_summary/merged_status_item.vala30
-rw-r--r--client/src/ui/conversation_summary/status_item.vala29
-rw-r--r--client/src/ui/conversation_summary/view.vala222
4 files changed, 0 insertions, 451 deletions
diff --git a/client/src/ui/conversation_summary/merged_message_item.vala b/client/src/ui/conversation_summary/merged_message_item.vala
deleted file mode 100644
index 3647d082..00000000
--- a/client/src/ui/conversation_summary/merged_message_item.vala
+++ /dev/null
@@ -1,170 +0,0 @@
-using Gee;
-using Gdk;
-using Gtk;
-using Markup;
-
-using Dino.Entities;
-
-namespace Dino.Ui.ConversationSummary {
-
-[GtkTemplate (ui = "/org/dino-im/conversation_summary/message_item.ui")]
-public class MergedMessageItem : Grid {
-
- public Conversation conversation { get; set; }
- public Jid from { get; private set; }
- public DateTime initial_time { get; private set; }
- public ArrayList<Message> messages = new ArrayList<Message>(Message.equals_func);
-
- [GtkChild]
- private Image image;
-
- [GtkChild]
- private Label time_label;
-
- [GtkChild]
- private Label name_label;
-
- [GtkChild]
- private Image encryption_image;
-
- [GtkChild]
- private Image received_image;
-
- [GtkChild]
- private TextView message_text_view;
-
- public MergedMessageItem(StreamInteractor stream_interactor, Conversation conversation, Message message) {
- this.conversation = conversation;
- this.from = message.from;
- this.initial_time = message.time;
- setup_tags();
- add_message(message);
-
- time_label.label = get_relative_time(initial_time.to_local());
- string display_name = Util.get_message_display_name(stream_interactor, message, conversation.account);
- name_label.set_markup(@"<span foreground=\"#$(Util.get_name_hex_color(display_name))\">$display_name</span>");
- Util.image_set_from_scaled_pixbuf(image, (new AvatarGenerator(30, 30, image.scale_factor)).draw_message(stream_interactor, message));
- if (message.encryption == Entities.Message.Encryption.PGP) {
- encryption_image.visible = true;
- encryption_image.set_from_icon_name("changes-prevent-symbolic", IconSize.SMALL_TOOLBAR);
- }
- }
-
- public void update() {
- time_label.label = get_relative_time(initial_time.to_local());
- }
-
- public void add_message(Message message) {
- TextIter end;
- message_text_view.buffer.get_end_iter(out end);
- if (messages.size > 0) {
- message_text_view.buffer.insert(ref end, "\n", -1);
- }
- message_text_view.buffer.insert(ref end, message.body, -1);
- format_suffix_urls(message.body);
- messages.add(message);
- message.notify["marked"].connect_after(update_received); // TODO other thread? not main? css error? gtk main?
- update_received();
- }
-
- private void update_received() {
- bool all_received = true;
- bool all_read = true;
- foreach (Message message in messages) {
- if (message.marked == Message.Marked.WONTSEND) {
- received_image.visible = true;
- Gtk.IconTheme icon_theme = Gtk.IconTheme.get_default();
- Gtk.IconInfo? icon_info = icon_theme.lookup_icon("dialog-warning-symbolic", IconSize.SMALL_TOOLBAR, 0);
- received_image.set_from_pixbuf(icon_info.load_symbolic({1,0,0,1}));
- return;
- } else if (message.marked != Message.Marked.READ) {
- all_read = false;
- if (message.marked != Message.Marked.RECEIVED) {
- all_received = false;
- }
- }
- }
- if (all_read) {
- received_image.visible = true;
- received_image.set_from_resource("/org/dino-im/img/double_tick.svg");
- } else if (all_received) {
- received_image.visible = true;
- received_image.set_from_resource("/org/dino-im/img/tick.svg");
- } else if (received_image.visible) {
- received_image.set_from_icon_name("image-loading-symbolic", IconSize.SMALL_TOOLBAR);
- }
- }
-
- private void format_suffix_urls(string text) {
- int absolute_start = message_text_view.buffer.text.length - text.length;
-
- Regex url_regex = new Regex("""(?i)\b((?:[a-z][\w-]+:(?:\/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'".,<>?«»“”‘’]))""");
- MatchInfo match_info;
- url_regex.match(text, 0, out match_info);
- for (; match_info.matches(); match_info.next()) {
- string? url = match_info.fetch(0);
- int start;
- int end;
- match_info.fetch_pos(0, out start, out end);
- TextIter start_iter;
- TextIter end_iter;
- message_text_view.buffer.get_iter_at_offset(out start_iter, absolute_start + start);
- message_text_view.buffer.get_iter_at_offset(out end_iter, absolute_start + end);
- message_text_view.buffer.apply_tag_by_name("url", start_iter, end_iter);
- }
- }
-
- private void setup_tags() {
- message_text_view.buffer.create_tag("url", underline: Pango.Underline.SINGLE, foreground: "blue");
- message_text_view.button_release_event.connect(open_url);
- message_text_view.motion_notify_event.connect(change_cursor_over_url);
- }
-
- private bool open_url(EventButton event_button) {
- int buffer_x, buffer_y;
- message_text_view.window_to_buffer_coords(TextWindowType.TEXT, (int) event_button.x, (int) event_button.y, out buffer_x, out buffer_y);
- TextIter iter;
- message_text_view.get_iter_at_location(out iter, buffer_x, buffer_y);
- TextIter start_iter = iter, end_iter = iter;
- if (start_iter.backward_to_tag_toggle(null) && end_iter.forward_to_tag_toggle(null)) {
- string url = start_iter.get_text(end_iter);
- try{
- AppInfo.launch_default_for_uri(url, null);
- } catch (Error err) {
- print("Tryed to open " + url);
- }
- }
- return false;
- }
-
- private bool change_cursor_over_url(EventMotion event_motion) {
- TextIter iter;
- message_text_view.get_iter_at_location(out iter, (int) event_motion.x, (int) event_motion.y);
- if (iter.has_tag(message_text_view.buffer.tag_table.lookup("url"))) {
- event_motion.window.set_cursor(new Cursor.for_display(get_display(), CursorType.HAND2));
- } else {
- event_motion.window.set_cursor(new Cursor.for_display(get_display(), CursorType.XTERM));
- }
- return false;
- }
-
- private static string get_relative_time(DateTime datetime) {
- DateTime now = new DateTime.now_local();
- TimeSpan timespan = now.difference(datetime);
- if (timespan > 365 * TimeSpan.DAY) {
- return datetime.format("%d.%m.%Y %H:%M");
- } else if (timespan > 7 * TimeSpan.DAY) {
- return datetime.format("%d.%m %H:%M");
- } else if (timespan > 1 * TimeSpan.DAY) {
- return datetime.format("%a, %H:%M");
- } else if (timespan > 9 * TimeSpan.MINUTE) {
- return datetime.format("%H:%M");
- } else if (timespan > TimeSpan.MINUTE) {
- return (timespan / TimeSpan.MINUTE).to_string() + " min ago";
- } else {
- return "Just now";
- }
- }
-}
-
-}
diff --git a/client/src/ui/conversation_summary/merged_status_item.vala b/client/src/ui/conversation_summary/merged_status_item.vala
deleted file mode 100644
index 78b156e9..00000000
--- a/client/src/ui/conversation_summary/merged_status_item.vala
+++ /dev/null
@@ -1,30 +0,0 @@
-using Gee;
-using Gtk;
-
-using Dino.Entities;
-
-namespace Dino.Ui.ConversationSummary {
-
-private class MergedStatusItem : Expander {
-
- private StreamInteractor stream_interactor;
- private Conversation conversation;
- private ArrayList<Show> statuses = new ArrayList<Show>();
-
- public MergedStatusItem(StreamInteractor stream_interactor, Conversation conversation, Show show) {
- set_hexpand(true);
- add_status(show);
- }
-
- public void add_status(Show show) {
- statuses.add(show);
- StatusItem status_item = new StatusItem(stream_interactor, conversation, @"is $(show.as)");
- if (statuses.size == 1) {
- label = show.as;
- } else {
- label = @"changed their status $(statuses.size) times";
- add(new Label(show.as));
- }
- }
-}
-} \ No newline at end of file
diff --git a/client/src/ui/conversation_summary/status_item.vala b/client/src/ui/conversation_summary/status_item.vala
deleted file mode 100644
index 5918d008..00000000
--- a/client/src/ui/conversation_summary/status_item.vala
+++ /dev/null
@@ -1,29 +0,0 @@
-using Gtk;
-using Markup;
-
-using Dino.Entities;
-
-namespace Dino.Ui.ConversationSummary {
-
-private class StatusItem : Grid {
-
- private Image image = new Image();
- private Label label = new Label("");
-
- private StreamInteractor stream_interactor;
- private Conversation conversation;
-
- public StatusItem(StreamInteractor stream_interactor, Conversation conversation, string? text) {
- Object(column_spacing : 7);
- set_hexpand(true);
- this.stream_interactor = stream_interactor;
- this.conversation = conversation;
- image.set_from_pixbuf((new AvatarGenerator(30, 30)).set_greyscale(true).draw_conversation(stream_interactor, conversation));
- attach(image, 0, 0, 1, 1);
- attach(label, 1, 0, 1, 1);
- string display_name = Util.get_display_name(stream_interactor, conversation.counterpart, conversation.account);
- label.set_markup(@"<span foreground=\"#B1B1B1\"> $(escape_text(display_name)) $text </span>");
- show_all();
- }
-}
-} \ No newline at end of file
diff --git a/client/src/ui/conversation_summary/view.vala b/client/src/ui/conversation_summary/view.vala
deleted file mode 100644
index 59cf88aa..00000000
--- a/client/src/ui/conversation_summary/view.vala
+++ /dev/null
@@ -1,222 +0,0 @@
-using Gee;
-using Gtk;
-using Pango;
-
-using Dino.Entities;
-using Xmpp;
-
-namespace Dino.Ui.ConversationSummary {
-
-[GtkTemplate (ui = "/org/dino-im/conversation_summary/view.ui")]
-public class View : Box {
-
- public Conversation? conversation { get; private set; }
- public HashMap<Entities.Message, MergedMessageItem> message_items = new HashMap<Entities.Message, MergedMessageItem>(Entities.Message.hash_func, Entities.Message.equals_func);
-
- [GtkChild]
- private ScrolledWindow scrolled;
-
- [GtkChild]
- private Box main;
-
- private StreamInteractor stream_interactor;
- private MergedMessageItem? last_message_item;
- private StatusItem typing_status;
- private Entities.Message? earliest_message;
- double? was_value;
- double? was_upper;
- double? was_page_size;
- Object reloading_lock = new Object();
- bool reloading = false;
-
- public View(StreamInteractor stream_interactor) {
- Object(homogeneous : false, spacing : 0);
- this.stream_interactor = stream_interactor;
- scrolled.vadjustment.notify["upper"].connect_after(on_upper_notify);
- scrolled.vadjustment.notify["value"].connect(on_value_notify);
-
- CounterpartInteractionManager.get_instance(stream_interactor).received_state.connect((account, jid, state) => {
- Idle.add(() => { on_received_state(account, jid, state); return false; });
- });
- MessageManager.get_instance(stream_interactor).message_received.connect((message, conversation) => {
- Idle.add(() => { show_message(message, conversation, true); return false; });
- });
- MessageManager.get_instance(stream_interactor).message_sent.connect((message, conversation) => {
- Idle.add(() => { show_message(message, conversation, true); return false; });
- });
- PresenceManager.get_instance(stream_interactor).show_received.connect((show, jid, account) => {
- Idle.add(() => { on_show_received(show, jid, account); return false; });
- });
- Timeout.add_seconds(60, () => {
- foreach (MergedMessageItem message_item in message_items.values) {
- message_item.update();
- }
- return true;
- });
- }
-
- public void initialize_for_conversation(Conversation? conversation) {
- this.conversation = conversation;
- clear();
- message_items.clear();
- was_upper = null;
- was_page_size = null;
- last_message_item = null;
-
- ArrayList<Object> objects = new ArrayList<Object>();
- Gee.List<Entities.Message>? messages = MessageManager.get_instance(stream_interactor).get_messages(conversation);
- if (messages != null && messages.size > 0) {
- earliest_message = messages[0];
- objects.add_all(messages);
- }
- HashMap<Jid, ArrayList<Show>>? shows = PresenceManager.get_instance(stream_interactor).get_shows(conversation.counterpart, conversation.account);
- if (shows != null) {
- foreach (Jid jid in shows.keys) objects.add_all(shows[jid]);
- }
- objects.sort((a, b) => {
- DateTime? dt1 = null;
- DateTime? dt2 = null;
- Entities.Message m1 = a as Entities.Message;
- if (m1 != null) dt1 = m1.time;
- Show s1 = a as Show;
- if (s1 != null) dt1 = s1.datetime;
- Entities.Message m2 = b as Entities.Message;
- if (m2 != null) dt2 = m2.time;
- Show s2 = b as Show;
- if (s2 != null) dt2 = s2.datetime;
- return dt1.compare(dt2);
- });
- foreach (Object o in objects) {
- Entities.Message message = o as Entities.Message;
- Show show = o as Show;
- if (message != null) {
- show_message(message, conversation);
- } else if (show != null) {
- on_show_received(show, conversation.counterpart, conversation.account);
- }
- }
- update_chat_state();
- }
-
- private void on_received_state(Account account, Jid jid, string state) {
- if (conversation != null && conversation.account.equals(account) && conversation.counterpart.equals_bare(jid)) {
- update_chat_state(state);
- }
- }
-
- private void update_chat_state(string? state = null) {
- string? state_ = state;
- if (state_ == null) {
- state_ = CounterpartInteractionManager.get_instance(stream_interactor).get_chat_state(conversation.account, conversation.counterpart);
- }
- if (typing_status != null) {
- main.remove(typing_status);
- }
- if (state_ != null) {
- if (state_ == Xep.ChatStateNotifications.STATE_COMPOSING || state_ == Xep.ChatStateNotifications.STATE_PAUSED) {
- if (state_ == Xep.ChatStateNotifications.STATE_COMPOSING) {
- typing_status = new StatusItem(stream_interactor, conversation, "is typing...");
- } else if (state_ == Xep.ChatStateNotifications.STATE_PAUSED) {
- typing_status = new StatusItem(stream_interactor, conversation, "has stoped typing");
- }
- main.add(typing_status);
- }
- }
- }
-
- private void on_show_received(Show show, Jid jid, Account account) {
-
- }
-
- private void on_upper_notify() {
- if (was_upper == null || scrolled.vadjustment.value > was_upper - was_page_size - 1 ||
- scrolled.vadjustment.value > was_upper - was_page_size - 1) { // scrolled down or content smaller than page size
- scrolled.vadjustment.value = scrolled.vadjustment.upper - scrolled.vadjustment.page_size; // scroll down
- } else if (scrolled.vadjustment.value < scrolled.vadjustment.upper - scrolled.vadjustment.page_size - 1){
- scrolled.vadjustment.value = scrolled.vadjustment.upper - was_upper + scrolled.vadjustment.value; // stay at same content
- }
- was_upper = scrolled.vadjustment.upper;
- was_page_size = scrolled.vadjustment.page_size;
- lock(reloading_lock) {
- reloading = false;
- }
- }
-
- private void on_value_notify() {
- if (scrolled.vadjustment.value < 200) {
- load_earlier_messages();
- }
- }
-
- private void load_earlier_messages() {
- was_value = scrolled.vadjustment.value;
- lock(reloading_lock) {
- if(reloading) return;
- reloading = true;
- }
- Gee.List<Entities.Message>? messages = MessageManager.get_instance(stream_interactor).get_messages_before(conversation, earliest_message);
- if (messages != null && messages.size > 0) {
- earliest_message = messages[0];
- MergedMessageItem? current_item = null;
- int items_added = 0;
- for (int i = 0; i < messages.size; i++) {
- if (current_item != null && should_merge_message(current_item, messages[i])) {
- current_item.add_message(messages[i]);
- } else {
- current_item = new MergedMessageItem(stream_interactor, conversation, messages[i]);
- force_alloc_width(current_item, main.get_allocated_width());
- main.add(current_item);
- message_items[messages[i]] = current_item;
- main.reorder_child(current_item, items_added);
- items_added++;
- }
- }
- return;
- }
- reloading = false;
- }
-
- private void show_message(Entities.Message message, Conversation conversation, bool animate = false) {
- if (this.conversation != null && this.conversation.equals(conversation)) {
- if (should_merge_message(last_message_item, message)) {
- last_message_item.add_message(message);
- } else {
- MergedMessageItem message_item = new MergedMessageItem(stream_interactor, conversation, message);
- if (animate) {
- Revealer revealer = new Revealer() {transition_duration = 200, transition_type = RevealerTransitionType.SLIDE_UP, visible = true};
- revealer.add(message_item);
- force_alloc_width(revealer, main.get_allocated_width());
- main.add(revealer);
- revealer.set_reveal_child(true);
- } else {
- force_alloc_width(message_item, main.get_allocated_width());
- main.add(message_item);
- }
- last_message_item = message_item;
- }
- message_items[message] = last_message_item;
- update_chat_state();
- }
- }
-
- private bool should_merge_message(MergedMessageItem? message_item, Entities.Message message) {
- return message_item != null &&
- message_item.from.equals(message.from) &&
- message_item.messages.get(0).encryption == message.encryption &&
- message.time.difference(message_item.initial_time) < TimeSpan.MINUTE &&
- (message_item.messages.get(0).marked == Entities.Message.Marked.WONTSEND) == (message.marked == Entities.Message.Marked.WONTSEND);
- }
-
- private void force_alloc_width(Widget widget, int width) {
- Allocation alloc = Allocation();
- widget.get_preferred_width(out alloc.width, null);
- widget.get_preferred_height(out alloc.height, null);
- alloc.width = width;
- widget.size_allocate(alloc);
- }
-
- private void clear() {
- main.@foreach((widget) => { main.remove(widget); });
- }
-}
-}