1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
|
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 = set_update_time_label_timeout((int) get_next_time_change(), this);
}
private static uint set_update_time_label_timeout(int interval, CompatDateSeparatorModel model_) {
WeakRef model_weak = WeakRef(model_);
return Timeout.add_seconds(interval, () => {
CompatDateSeparatorModel? model = (CompatDateSeparatorModel) model_weak.get();
if (model != null && model.time_update_timeout != 0) model.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();
}
}
|