summaryrefslogtreecommitdiffhomepage
path: root/android/src
diff options
context:
space:
mode:
authorJanito Vaqueiro Ferreira Filho <janito@mullvad.net>2020-10-09 13:56:07 +0000
committerJanito Vaqueiro Ferreira Filho <janito@mullvad.net>2020-10-19 11:51:48 +0000
commit6c0982ac32b1ef67aa88b9a7ecb36bb8d55af3d4 (patch)
tree41e232b8c498bbb1a747c86657b90e67a2887710 /android/src
parenta4847efb5e4b1b0056609a551e2038b5aec43f16 (diff)
downloadmullvadvpn-6c0982ac32b1ef67aa88b9a7ecb36bb8d55af3d4.tar.xz
mullvadvpn-6c0982ac32b1ef67aa88b9a7ecb36bb8d55af3d4.zip
Create `Debouncer` helper class
Diffstat (limited to 'android/src')
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/util/Debouncer.kt39
1 files changed, 39 insertions, 0 deletions
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/util/Debouncer.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/util/Debouncer.kt
new file mode 100644
index 0000000000..7afb4c508f
--- /dev/null
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/util/Debouncer.kt
@@ -0,0 +1,39 @@
+package net.mullvad.mullvadvpn.util
+
+import kotlin.properties.Delegates.observable
+import kotlinx.coroutines.delay
+
+// Helper to filter out bursts of events so that only the latest event in an interval is notified.
+//
+// An interval of zero means that it will only debounce events that are sent before the job is
+// started. If the events are coming from the UI thread, this means that this class will only send
+// the last event received before the UI thread finishes its current task.
+//
+// This can be used for example to filter out focus events coming from different views. Android will
+// first send a "focus lost" event from a view followed by a "focus gained" event from another view.
+// If the only thing the listener is interested in is if any of a set of views has focus, this class
+// can be used to debounce focus events from the set of views to obtain an event that represents a
+// change from when the set contains a focused view to when the set contains no focused views (and
+// an event for the reverse situation).
+class Debouncer<T>(initialValue: T, val intervalInMs: Long = 0) {
+ private val jobTracker = JobTracker()
+
+ var listener: ((T) -> Unit)? = null
+
+ var debouncedValue = initialValue
+ private set
+
+ var rawValue by observable(initialValue) { _, oldValue, newValue ->
+ if (newValue != oldValue) {
+ jobTracker.cancelJob("notifyNewValue")
+
+ if (newValue != debouncedValue) {
+ jobTracker.newUiJob("notifyNewValue") {
+ delay(intervalInMs)
+ listener?.invoke(newValue)
+ debouncedValue = newValue
+ }
+ }
+ }
+ }
+}