aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libdino/CMakeLists.txt1
-rw-r--r--libdino/meson.build1
-rw-r--r--libdino/src/util/weak_timeout.vala40
-rw-r--r--main/src/ui/conversation_content_view/call_widget.vala13
-rw-r--r--main/src/ui/conversation_content_view/conversation_item_skeleton.vala10
-rw-r--r--main/src/ui/conversation_content_view/quote_widget.vala9
-rw-r--r--main/src/ui/widgets/date_separator.vala17
7 files changed, 63 insertions, 28 deletions
diff --git a/libdino/CMakeLists.txt b/libdino/CMakeLists.txt
index d52f9184..e4d786c9 100644
--- a/libdino/CMakeLists.txt
+++ b/libdino/CMakeLists.txt
@@ -70,6 +70,7 @@ SOURCES
src/util/display_name.vala
src/util/util.vala
src/util/weak_map.vala
+ src/util/weak_timeout.vala
CUSTOM_VAPIS
"${CMAKE_BINARY_DIR}/exports/xmpp-vala.vapi"
"${CMAKE_BINARY_DIR}/exports/qlite.vapi"
diff --git a/libdino/meson.build b/libdino/meson.build
index 356c15d3..17804d23 100644
--- a/libdino/meson.build
+++ b/libdino/meson.build
@@ -76,6 +76,7 @@ sources = files(
'src/util/display_name.vala',
'src/util/util.vala',
'src/util/weak_map.vala',
+ 'src/util/weak_timeout.vala',
)
sources += [version_vala]
c_args = [
diff --git a/libdino/src/util/weak_timeout.vala b/libdino/src/util/weak_timeout.vala
new file mode 100644
index 00000000..28894ed3
--- /dev/null
+++ b/libdino/src/util/weak_timeout.vala
@@ -0,0 +1,40 @@
+public class Dino.WeakTimeout {
+ // XXX: If you get an error saying your function doesn't match the delegate, make sure it's static!
+ // These are marked as "has_target=false" so you can't close over "this" and leak it in your lambda.
+ [CCode (has_target = false, instance_pos = 0)]
+ public delegate bool SourceFunc<T> (T object);
+
+ [CCode (has_target = false, instance_pos = 0)]
+ public delegate void SourceOnceFunc<T> (T object);
+
+ public static uint add<T>(uint interval, T object, owned SourceFunc<T> function, int priority = GLib.Priority.DEFAULT) {
+ var weak = WeakRef((Object)object);
+ return GLib.Timeout.add(interval, () => {
+ var strong = weak.get();
+ if (strong == null) return false;
+
+ return function(strong);
+ }, priority);
+ }
+
+ public static uint add_once<T>(uint interval, T object, owned SourceOnceFunc<T> function, int priority = GLib.Priority.DEFAULT) {
+ var weak = WeakRef((Object)object);
+ return GLib.Timeout.add(interval, () => {
+ var strong = weak.get();
+ if (strong == null) return false;
+
+ function(strong);
+ return false;
+ }, priority);
+ }
+
+ public static uint add_seconds<T>(uint interval, T object, owned SourceFunc<T> function, int priority = GLib.Priority.DEFAULT) {
+ return add(interval * 1000, object, (owned) function, priority);
+ }
+
+ // This one doesn't have an upstream equivalent, but it seems pretty obvious to me
+ public static uint add_seconds_once<T>(uint interval, T object, owned SourceOnceFunc<T> function, int priority = GLib.Priority.DEFAULT) {
+ return add_once(interval * 1000, object, (owned) function, priority);
+ }
+
+}
diff --git a/main/src/ui/conversation_content_view/call_widget.vala b/main/src/ui/conversation_content_view/call_widget.vala
index ab047196..3d6b250b 100644
--- a/main/src/ui/conversation_content_view/call_widget.vala
+++ b/main/src/ui/conversation_content_view/call_widget.vala
@@ -111,6 +111,10 @@ namespace Dino.Ui {
incoming_call_revealer.reveal_child = true;
}
+ private void on_time_update_timeout() {
+ if (time_update_handler_id != 0) update_call_state();
+ }
+
private void update_call_state() {
incoming_call_revealer.reveal_child = false;
incoming_call_revealer.remove_css_class("incoming");
@@ -156,14 +160,7 @@ namespace Dino.Ui {
string duration = get_duration_string((new DateTime.now_utc()).difference(call.local_time));
subtitle_label.label = _("Started %s ago").printf(duration);
- time_update_handler_id = Timeout.add_seconds(get_next_time_change() + 1, () => {
- if (time_update_handler_id != 0) {
- Source.remove(time_update_handler_id);
- time_update_handler_id = 0;
- update_call_state();
- }
- return true;
- });
+ time_update_handler_id = Dino.WeakTimeout.add_seconds_once(get_next_time_change() + 1, this, on_time_update_timeout);
break;
case Call.State.OTHER_DEVICE:
diff --git a/main/src/ui/conversation_content_view/conversation_item_skeleton.vala b/main/src/ui/conversation_content_view/conversation_item_skeleton.vala
index 5d86f6c7..3b818b44 100644
--- a/main/src/ui/conversation_content_view/conversation_item_skeleton.vala
+++ b/main/src/ui/conversation_content_view/conversation_item_skeleton.vala
@@ -173,14 +173,14 @@ public class ConversationItemSkeleton : Plugins.ConversationItemWidgetInterface,
set_widget(widget, Plugins.WidgetType.GTK4, 3);
}
+ private void on_time_update_timeout() {
+ if (main_grid.parent != null) update_time();
+ }
+
private void update_time() {
time_label.label = get_relative_time(item.time.to_local()).to_string();
- time_update_timeout = Timeout.add_seconds((int) get_next_time_change(item.time), () => {
- if (this.main_grid.parent == null) return false;
- update_time();
- return false;
- });
+ time_update_timeout = Dino.WeakTimeout.add_seconds_once((int) get_next_time_change(item.time), this, on_time_update_timeout);
}
private void update_name_label() {
diff --git a/main/src/ui/conversation_content_view/quote_widget.vala b/main/src/ui/conversation_content_view/quote_widget.vala
index 23b62e6a..b267e6bc 100644
--- a/main/src/ui/conversation_content_view/quote_widget.vala
+++ b/main/src/ui/conversation_content_view/quote_widget.vala
@@ -41,12 +41,13 @@ namespace Dino.Ui.Quote {
this.author_jid = content_item.jid;
}
+ private void on_display_time_timeout() {
+ if (display_time_timeout != 0) update_display_time();
+ }
+
private void update_display_time() {
this.display_time = ConversationItemSkeleton.get_relative_time(message_time.to_local());
- display_time_timeout = Timeout.add_seconds((int) ConversationItemSkeleton.get_next_time_change(message_time), () => {
- if (display_time_timeout != 0) update_display_time();
- return false;
- });
+ display_time_timeout = Dino.WeakTimeout.add_seconds_once((int) ConversationItemSkeleton.get_next_time_change(message_time), this, on_display_time_timeout);
}
public override void dispose() {
diff --git a/main/src/ui/widgets/date_separator.vala b/main/src/ui/widgets/date_separator.vala
index b5d84a5b..fcaa61d1 100644
--- a/main/src/ui/widgets/date_separator.vala
+++ b/main/src/ui/widgets/date_separator.vala
@@ -38,18 +38,13 @@ public class Dino.Ui.ViewModel.CompatDateSeparatorModel : DateSeparatorModel {
}
}
- 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 void on_time_update_timeout(CompatDateSeparatorModel self) {
+ if (self.time_update_timeout != 0) self.update_time_label();
}
- 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 void update_time_label() {
+ date_label = get_relative_time(date);
+ time_update_timeout = Dino.WeakTimeout.add_seconds_once(get_next_time_change(), this, on_time_update_timeout);
}
private int get_next_time_change() {
@@ -113,4 +108,4 @@ public class Dino.Ui.DateSeparator : Gtk.Widget {
}
base.dispose();
}
-} \ No newline at end of file
+}