From 3aa3912dc3ea740a5b93f8b694ead45e1b655238 Mon Sep 17 00:00:00 2001 From: Marvin W Date: Tue, 31 Jan 2023 14:46:02 +0100 Subject: [PATCH] New Date Separator --- main/CMakeLists.txt | 1 + .../date_separator_populator.vala | 80 +------------ main/src/ui/widgets/date_separator.vala | 110 ++++++++++++++++++ 3 files changed, 112 insertions(+), 79 deletions(-) create mode 100644 main/src/ui/widgets/date_separator.vala diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index 301e1d95..30b4a52f 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -209,6 +209,7 @@ SOURCES src/ui/util/sizing_bin.vala src/ui/util/size_request_box.vala + src/ui/widgets/date_separator.vala src/ui/widgets/fixed_ratio_picture.vala src/ui/widgets/natural_size_increase.vala CUSTOM_VAPIS diff --git a/main/src/ui/conversation_content_view/date_separator_populator.vala b/main/src/ui/conversation_content_view/date_separator_populator.vala index 25ef7a51..ef8befe5 100644 --- a/main/src/ui/conversation_content_view/date_separator_populator.vala +++ b/main/src/ui/conversation_content_view/date_separator_populator.vala @@ -15,7 +15,6 @@ class DateSeparatorPopulator : Plugins.ConversationItemPopulator, Plugins.Conver private Plugins.ConversationItemCollection? item_collection; private Gee.TreeSet insert_times; - public DateSeparatorPopulator(StreamInteractor stream_interactor) { this.stream_interactor = stream_interactor; } @@ -54,92 +53,15 @@ class DateSeparatorPopulator : Plugins.ConversationItemPopulator, Plugins.Conver public class MetaDateItem : Plugins.MetaConversationItem { public override DateTime time { get; set; } - private DateTime date; - public MetaDateItem(DateTime date) { - this.date = date; this.time = date; } public override Object? get_widget(Plugins.ConversationItemWidgetInterface outer, Plugins.WidgetType widget_type) { - return new DateSeparatorWidget(date); + return new DateSeparator() { model = new ViewModel.CompatDateSeparatorModel(time) }; } public override Gee.List? get_item_actions(Plugins.WidgetType type) { return null; } - - -} - -public class DateSeparatorWidget : Box { - - private DateTime date; - private Label label; - private uint time_update_timeout = 0; - - public DateSeparatorWidget(DateTime date) { - Object(orientation:Orientation.HORIZONTAL, spacing:10); - width_request = 300; - halign = Align.CENTER; - visible = true; - this.date = date; - - label = new Label("") { use_markup=true, halign=Align.CENTER, hexpand=false }; - label.add_css_class("dim-label"); - - this.append(new Separator(Orientation.HORIZONTAL) { valign=Align.CENTER, hexpand=true }); - this.append(label); - this.append(new Separator(Orientation.HORIZONTAL) { valign=Align.CENTER, hexpand=true }); - - update_time(); - } - - private void update_time() { - label.label = @"$(get_relative_time(date))"; - time_update_timeout = Timeout.add_seconds((int) get_next_time_change(), () => { - if (this.parent == null) return false; - update_time(); - return false; - }); - } - - 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")); - } - } - - private int get_next_time_change() { - DateTime now = new DateTime.now_local(); - return (23 - now.get_hour()) * 3600 + (59 - now.get_minute()) * 60 + (59 - now.get_second()) + 1; - } - - public override void dispose() { - base.dispose(); - - if (time_update_timeout != 0) { - Source.remove(time_update_timeout); - time_update_timeout = 0; - } - } } } diff --git a/main/src/ui/widgets/date_separator.vala b/main/src/ui/widgets/date_separator.vala new file mode 100644 index 00000000..95729bce --- /dev/null +++ b/main/src/ui/widgets/date_separator.vala @@ -0,0 +1,110 @@ +using Gtk; + +public class Dino.Ui.ViewModel.DateSeparatorModel : Object { + public string date_label { get; set; } +} + +public class Dino.Ui.ViewModel.CompatDateSeparatorModel : DateSeparatorModel { + private DateTime date; + private uint time_update_timeout = 0; + + public CompatDateSeparatorModel(DateTime date) { + this.date = date; + update_time_label(); + } + + 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")); + } + } + + private void update_time_label() { + date_label = get_relative_time(date); + time_update_timeout = Timeout.add_seconds((int) get_next_time_change(), () => { + if (time_update_timeout != 0) update_time_label(); + return false; + }); + } + + private int get_next_time_change() { + DateTime now = new DateTime.now_local(); + return (23 - now.get_hour()) * 3600 + (59 - now.get_minute()) * 60 + (59 - now.get_second()) + 1; + } + + public override void dispose() { + base.dispose(); + + if (time_update_timeout != 0) { + Source.remove(time_update_timeout); + time_update_timeout = 0; + } + } +} + +public class Dino.Ui.DateSeparator : Gtk.Widget { + public ViewModel.DateSeparatorModel? model { get; set; } + public string date_label { get { return label.get_text(); } set { label.set_text(value); } } + + private Label label = new Label("") { halign = Align.CENTER, hexpand = false }; + private Binding? label_text_binding; + + construct { + layout_manager = new BinLayout(); + halign = Align.CENTER; + hexpand = true; + + label.add_css_class("dim-label"); + label.attributes = new Pango.AttrList(); + label.attributes.insert(Pango.attr_scale_new(Pango.Scale.SMALL)); + + Box box = new Box(Orientation.HORIZONTAL, 10); + box.append(new Separator(Orientation.HORIZONTAL) { valign=Align.CENTER, hexpand=true }); + box.append(label); + box.append(new Separator(Orientation.HORIZONTAL) { valign=Align.CENTER, hexpand=true }); + + Adw.Clamp clamp = new Adw.Clamp() { maximum_size = 300, tightening_threshold = 300, child = box, halign = Align.CENTER }; + clamp.insert_after(this, null); + + notify["model"].connect(on_model_changed); + } + + private void on_model_changed() { + if (label_text_binding != null) label_text_binding.unbind(); + if (model != null) { + label_text_binding = model.bind_property("date-label", this, "date-label", BindingFlags.SYNC_CREATE); + } else { + label_text_binding = null; + } + } + + public override void dispose() { + if (label_text_binding != null) label_text_binding.unbind(); + label_text_binding = null; + var clamp = get_first_child(); + if (clamp != null) { + clamp.unparent(); + clamp.dispose(); + } + base.dispose(); + } +} \ No newline at end of file