aboutsummaryrefslogtreecommitdiff
path: root/main/src/ui/conversation_summary
diff options
context:
space:
mode:
Diffstat (limited to 'main/src/ui/conversation_summary')
-rw-r--r--main/src/ui/conversation_summary/conversation_item_skeleton.vala4
-rw-r--r--main/src/ui/conversation_summary/conversation_view.vala15
-rw-r--r--main/src/ui/conversation_summary/date_separator_populator.vala107
3 files changed, 122 insertions, 4 deletions
diff --git a/main/src/ui/conversation_summary/conversation_item_skeleton.vala b/main/src/ui/conversation_summary/conversation_item_skeleton.vala
index 03e9facb..c31b7901 100644
--- a/main/src/ui/conversation_summary/conversation_item_skeleton.vala
+++ b/main/src/ui/conversation_summary/conversation_item_skeleton.vala
@@ -67,7 +67,9 @@ public class ConversationItemSkeleton : Grid {
private void setup(Plugins.MetaConversationItem item) {
update_time();
- Util.image_set_from_scaled_pixbuf(image, (new AvatarGenerator(30, 30, image.scale_factor)).set_greyscale(item.dim).draw_jid(stream_interactor, item.jid, conversation.account));
+ if (item.requires_avatar) {
+ Util.image_set_from_scaled_pixbuf(image, (new AvatarGenerator(30, 30, image.scale_factor)).set_greyscale(item.dim).draw_jid(stream_interactor, item.jid, conversation.account));
+ }
if (item.requires_header) {
set_default_title_widget(item.jid);
}
diff --git a/main/src/ui/conversation_summary/conversation_view.vala b/main/src/ui/conversation_summary/conversation_view.vala
index 15a86ca7..c50a5e3c 100644
--- a/main/src/ui/conversation_summary/conversation_view.vala
+++ b/main/src/ui/conversation_summary/conversation_view.vala
@@ -37,9 +37,13 @@ public class ConversationView : Box, Plugins.ConversationItemCollection {
message_item_populator = new MessagePopulator(stream_interactor);
+ insert_item.connect(on_insert_item);
+ remove_item.connect(on_remove_item);
+
Application app = GLib.Application.get_default() as Application;
app.plugin_registry.register_conversation_item_populator(new ChatStatePopulator(stream_interactor));
app.plugin_registry.register_conversation_item_populator(new FilePopulator(stream_interactor));
+ app.plugin_registry.register_conversation_item_populator(new DateSeparatorPopulator(stream_interactor));
Timeout.add_seconds(60, () => {
foreach (ConversationItemSkeleton item_skeleton in item_skeletons) {
@@ -52,6 +56,12 @@ public class ConversationView : Box, Plugins.ConversationItemCollection {
}
public void initialize_for_conversation(Conversation? conversation) {
+ Dino.Application app = Dino.Application.get_default();
+ if (this.conversation != null) {
+ foreach (Plugins.ConversationItemPopulator populator in app.plugin_registry.conversation_item_populators) {
+ populator.close(conversation);
+ }
+ }
this.conversation = conversation;
stack.set_visible_child_name("void");
clear();
@@ -60,7 +70,6 @@ public class ConversationView : Box, Plugins.ConversationItemCollection {
animate = false;
Timeout.add(20, () => { animate = true; return false; });
- Dino.Application app = Dino.Application.get_default();
foreach (Plugins.ConversationItemPopulator populator in app.plugin_registry.conversation_item_populators) {
populator.init(conversation, this, Plugins.WidgetType.GTK);
}
@@ -70,7 +79,7 @@ public class ConversationView : Box, Plugins.ConversationItemCollection {
stack.set_visible_child_name("main");
}
- public void insert_item(Plugins.MetaConversationItem item) {
+ public void on_insert_item(Plugins.MetaConversationItem item) {
lock (meta_items) {
if (!item.can_merge || !merge_back(item)) {
insert_new(item);
@@ -78,7 +87,7 @@ public class ConversationView : Box, Plugins.ConversationItemCollection {
}
}
- public void remove_item(Plugins.MetaConversationItem item) {
+ public void on_remove_item(Plugins.MetaConversationItem item) {
lock (meta_items) {
ConversationItemSkeleton? skeleton = item_item_skeletons[item];
if (skeleton.items.size > 1) {
diff --git a/main/src/ui/conversation_summary/date_separator_populator.vala b/main/src/ui/conversation_summary/date_separator_populator.vala
new file mode 100644
index 00000000..34005ab6
--- /dev/null
+++ b/main/src/ui/conversation_summary/date_separator_populator.vala
@@ -0,0 +1,107 @@
+using Gee;
+using Gtk;
+
+using Dino.Entities;
+using Xmpp;
+
+namespace Dino.Ui.ConversationSummary {
+
+class DateSeparatorPopulator : Plugins.ConversationItemPopulator, Object {
+
+ public string id { get { return "date_separator"; } }
+
+ private StreamInteractor stream_interactor;
+ private Conversation? current_conversation;
+ private Plugins.ConversationItemCollection? item_collection;
+ private Gee.TreeSet<DateTime> insert_times;
+
+
+ public DateSeparatorPopulator(StreamInteractor stream_interactor) {
+ this.stream_interactor = stream_interactor;
+ }
+
+ public void init(Conversation conversation, Plugins.ConversationItemCollection item_collection, Plugins.WidgetType type) {
+ current_conversation = conversation;
+ this.item_collection = item_collection;
+ item_collection.insert_item.connect(on_insert_item);
+ this.insert_times = new TreeSet<DateTime>((a, b) => {
+ return a.compare(b);
+ });
+ }
+
+ public void close(Conversation conversation) {
+ item_collection.insert_item.disconnect(on_insert_item);
+ }
+
+ public void populate_timespan(Conversation conversation, DateTime after, DateTime before) { }
+
+ public void populate_between_widgets(Conversation conversation, DateTime from, DateTime to) { }
+
+ private void on_insert_item(Plugins.MetaConversationItem item) {
+ if (item.display_time == null) return;
+
+ DateTime time = item.sort_time.to_local();
+ DateTime msg_date = new DateTime.local(time.get_year(), time.get_month(), time.get_day_of_month(), 0, 0, 0);
+ if (!insert_times.contains(msg_date)) {
+ if (insert_times.lower(msg_date) != null) {
+ item_collection.insert_item(new MetaDateItem(msg_date.to_utc()));
+ } else if (insert_times.size > 0) {
+ item_collection.insert_item(new MetaDateItem(insert_times.first().to_utc()));
+ }
+ insert_times.add(msg_date);
+ }
+ }
+}
+
+public class MetaDateItem : Plugins.MetaConversationItem {
+ public override DateTime? sort_time { get; set; }
+
+ public override bool can_merge { get; set; default=false; }
+ public override bool requires_avatar { get; set; default=false; }
+ public override bool requires_header { get; set; default=false; }
+
+ private DateTime date;
+
+ public MetaDateItem(DateTime date) {
+ this.date = date;
+ this.sort_time = date;
+ }
+
+ public override Object? get_widget(Plugins.WidgetType widget_type) {
+ Box box = new Box(Orientation.HORIZONTAL, 10) { width_request=300, halign=Align.CENTER, visible=true };
+ box.add(new Separator(Orientation.HORIZONTAL) { valign=Align.CENTER, hexpand=true, visible=true });
+ string date_str = get_relative_time(date);
+ Label label = new Label(@"<span size='small'>$date_str</span>") { use_markup=true, halign=Align.CENTER, hexpand=false, visible=true };
+ label.get_style_context().add_class("dim-label");
+ box.add(label);
+ box.add(new Separator(Orientation.HORIZONTAL) { valign=Align.CENTER, hexpand=true, visible=true });
+ return box;
+ }
+
+ private static string get_relative_time(DateTime time) {
+ DateTime time_local = time.to_local();
+ DateTime now_local = new DateTime.now_local();
+ if (time_local.get_year() == now_local.get_year() &&
+ time_local.get_month() == now_local.get_month() &&
+ time_local.get_day_of_month() == now_local.get_day_of_month()) {
+ return _("Today");
+ }
+ DateTime now_local_minus = now_local.add_days(-1);
+ if (time_local.get_year() == now_local_minus.get_year() &&
+ time_local.get_month() == now_local_minus.get_month() &&
+ time_local.get_day_of_month() == now_local_minus.get_day_of_month()) {
+ return _("Yesterday");
+ }
+ if (time_local.get_year() != now_local.get_year()) {
+ return time_local.format("%x");
+ }
+ TimeSpan timespan = now_local.difference(time_local);
+ if (timespan < 7 * TimeSpan.DAY) {
+ return time_local.format(_("%a, %b %d"));
+ } else {
+ return time_local.format(_("%b %d"));
+ }
+ }
+}
+
+}