aboutsummaryrefslogtreecommitdiff
path: root/main/src
diff options
context:
space:
mode:
authorfiaxh <git@mx.ax.lt>2017-11-21 22:17:04 +0100
committerfiaxh <git@mx.ax.lt>2017-11-22 00:32:11 +0100
commitf3063f56b7e2ccfef255256d5bf527988fcf2957 (patch)
tree6d7ddb4fd5a8ae65ca431f575fe1b1157559f45e /main/src
parentebf8d7ab01bd9df03c3a9fda0f0e2c5da228c8ce (diff)
downloaddino-f3063f56b7e2ccfef255256d5bf527988fcf2957.tar.gz
dino-f3063f56b7e2ccfef255256d5bf527988fcf2957.zip
ConversationView: Split merged messages when an in-between one is added
Diffstat (limited to 'main/src')
-rw-r--r--main/src/ui/conversation_summary/conversation_item_skeleton.vala15
-rw-r--r--main/src/ui/conversation_summary/conversation_view.vala53
2 files changed, 58 insertions, 10 deletions
diff --git a/main/src/ui/conversation_summary/conversation_item_skeleton.vala b/main/src/ui/conversation_summary/conversation_item_skeleton.vala
index 1eb76840..ed540e5d 100644
--- a/main/src/ui/conversation_summary/conversation_item_skeleton.vala
+++ b/main/src/ui/conversation_summary/conversation_item_skeleton.vala
@@ -17,9 +17,10 @@ public class ConversationItemSkeleton : Grid {
public StreamInteractor stream_interactor;
public Conversation conversation { get; set; }
- public Gee.List<Plugins.MetaConversationItem> items = new ArrayList<Plugins.MetaConversationItem>();
+ public ArrayList<Plugins.MetaConversationItem> items = new ArrayList<Plugins.MetaConversationItem>();
private Box box = new Box(Orientation.VERTICAL, 2) { visible=true };
+ private HashMap<Plugins.MetaConversationItem, Widget> item_widgets = new HashMap<Plugins.MetaConversationItem, Widget>();
public ConversationItemSkeleton(StreamInteractor stream_interactor, Conversation conversation) {
this.conversation = conversation;
@@ -36,11 +37,17 @@ public class ConversationItemSkeleton : Grid {
Widget widget = (Widget) item.get_widget(Plugins.WidgetType.GTK);
if (item.requires_header) {
box.add(widget);
+ item_widgets[item] = widget;
} else {
set_title_widget(widget);
}
- item.notify["mark"].connect_after(update_received);
- update_received();
+ item.notify["mark"].connect_after(update_received_mark);
+ update_received_mark();
+ }
+
+ public void remove_meta_item(Plugins.MetaConversationItem item) {
+ box.remove(item_widgets[item]);
+ items.remove(item);
}
public void set_title_widget(Widget w) {
@@ -81,7 +88,7 @@ public class ConversationItemSkeleton : Grid {
set_title_widget(name_label);
}
- private void update_received() {
+ private void update_received_mark() {
bool all_received = true;
bool all_read = true;
bool all_sent = true;
diff --git a/main/src/ui/conversation_summary/conversation_view.vala b/main/src/ui/conversation_summary/conversation_view.vala
index 93464a95..5aeb27fc 100644
--- a/main/src/ui/conversation_summary/conversation_view.vala
+++ b/main/src/ui/conversation_summary/conversation_view.vala
@@ -72,7 +72,6 @@ public class ConversationView : Box, Plugins.ConversationItemCollection {
public void insert_item(Plugins.MetaConversationItem item) {
lock (meta_items) {
- meta_items.add(item);
if (!item.can_merge || !merge_back(item)) {
insert_new(item);
}
@@ -81,11 +80,16 @@ public class ConversationView : Box, Plugins.ConversationItemCollection {
public void remove_item(Plugins.MetaConversationItem item) {
lock (meta_items) {
- main.remove(widgets[item]);
- widgets.unset(item);
+ ConversationItemSkeleton? skeleton = item_item_skeletons[item];
+ if (skeleton.items.size > 1) {
+ skeleton.remove_meta_item(item);
+ } else {
+ main.remove(widgets[item]);
+ widgets.unset(item);
+ item_skeletons.remove(item_item_skeletons[item]);
+ item_item_skeletons.unset(item);
+ }
meta_items.remove(item);
- item_skeletons.remove(item_item_skeletons[item]);
- item_item_skeletons.unset(item);
}
}
@@ -101,7 +105,10 @@ public class ConversationView : Box, Plugins.ConversationItemCollection {
(item.mark == Message.Marked.WONTSEND) == (lower_start_item.mark == Message.Marked.WONTSEND)) {
lower_skeleton.add_meta_item(item);
force_alloc_width(lower_skeleton, main.get_allocated_width());
+
item_item_skeletons[item] = lower_skeleton;
+ meta_items.add(item);
+
return true;
}
}
@@ -109,13 +116,28 @@ public class ConversationView : Box, Plugins.ConversationItemCollection {
}
private void insert_new(Plugins.MetaConversationItem item) {
+ Plugins.MetaConversationItem? lower_item = meta_items.lower(item);
+
+ // Does another skeleton need to be split?
+ if (lower_item != null) {
+ ConversationItemSkeleton lower_skeleton = item_item_skeletons[lower_item];
+ if (lower_skeleton.items.size > 1) {
+ Plugins.MetaConversationItem lower_end_item = lower_skeleton.items[lower_skeleton.items.size - 1];
+ if (item.sort_time.compare(lower_end_item.sort_time) < 0) {
+ split_at_time(lower_skeleton, item.sort_time);
+ }
+ }
+ }
+
+ // Fill datastructure
ConversationItemSkeleton item_skeleton = new ConversationItemSkeleton(stream_interactor, conversation);
item_skeleton.add_meta_item(item);
item_item_skeletons[item] = item_skeleton;
- Plugins.MetaConversationItem? lower_item = meta_items.lower(item);
int index = lower_item != null ? item_skeletons.index_of(item_item_skeletons[lower_item]) + 1 : 0;
item_skeletons.insert(index, item_skeleton);
+ meta_items.add(item);
+ // Insert widget
Widget insert = item_skeleton;
if (animate) {
Revealer revealer = new Revealer() {transition_duration = 200, transition_type = RevealerTransitionType.SLIDE_UP, visible = true};
@@ -130,6 +152,7 @@ public class ConversationView : Box, Plugins.ConversationItemCollection {
force_alloc_width(insert, main.get_allocated_width());
main.reorder_child(insert, index);
+ // If an item from the past was added, add everything between that item and the (post-)first present item
if (index == 0) {
Dino.Application app = Dino.Application.get_default();
if (item_skeletons.size == 1) {
@@ -144,6 +167,24 @@ public class ConversationView : Box, Plugins.ConversationItemCollection {
}
}
+ private void split_at_time(ConversationItemSkeleton split_skeleton, DateTime time) {
+ bool already_divided = false;
+ int i = 0;
+ while(i < split_skeleton.items.size) {
+ Plugins.MetaConversationItem meta_item = split_skeleton.items[i];
+ if (time.compare(meta_item.display_time) < 0) {
+ remove_item(meta_item);
+ if (!already_divided) {
+ insert_new(meta_item);
+ already_divided = true;
+ } else {
+ insert_item(meta_item);
+ }
+ }
+ i++;
+ }
+ }
+
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