Fix time desync if animation scale is not 1
This commit is contained in:
parent
7d945019b5
commit
cdf161f377
@ -1,13 +1,9 @@
|
||||
package de.mm20.launcher2.ui.base
|
||||
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import androidx.compose.animation.core.Animatable
|
||||
import androidx.compose.animation.core.LinearEasing
|
||||
import androidx.compose.animation.core.snap
|
||||
import androidx.compose.animation.core.tween
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.os.SystemClock
|
||||
import android.util.Log
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
@ -16,13 +12,15 @@ import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableLongStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.LocalLifecycleOwner
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.repeatOnLifecycle
|
||||
import kotlinx.coroutines.CancellationException
|
||||
import kotlinx.coroutines.awaitCancellation
|
||||
import java.time.Instant
|
||||
import java.time.ZoneId
|
||||
import kotlin.math.max
|
||||
|
||||
|
||||
/**
|
||||
* Provide the current time (in millis) to the LocalTime composition local.
|
||||
@ -31,64 +29,38 @@ import java.time.ZoneId
|
||||
@Composable
|
||||
fun ProvideCurrentTime(content: @Composable () -> Unit) {
|
||||
|
||||
val context = LocalContext.current
|
||||
val lifecycleOwner = LocalLifecycleOwner.current
|
||||
|
||||
var time by remember { mutableLongStateOf(System.currentTimeMillis()) }
|
||||
|
||||
val secondsAnimation = remember { Animatable(0f) }
|
||||
|
||||
LaunchedEffect(time) {
|
||||
val currentTime = System.currentTimeMillis()
|
||||
val seconds = Instant
|
||||
.ofEpochMilli(currentTime)
|
||||
.atZone(ZoneId.systemDefault()).second
|
||||
val millis = (currentTime % 1000).toInt()
|
||||
secondsAnimation.animateTo(seconds.toFloat() + millis / 1000f, snap())
|
||||
secondsAnimation.animateTo(
|
||||
60f,
|
||||
tween(
|
||||
(60 - seconds) * 1000 - millis,
|
||||
delayMillis = millis,
|
||||
easing = LinearEasing
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
val lifecycleOwner = LocalLifecycleOwner.current
|
||||
LaunchedEffect(null) {
|
||||
lifecycleOwner.lifecycle.repeatOnLifecycle(Lifecycle.State.RESUMED) {
|
||||
val dateTime = Instant.ofEpochMilli(System.currentTimeMillis())
|
||||
.atZone(ZoneId.systemDefault())
|
||||
.withSecond(0)
|
||||
.withNano(0)
|
||||
val handler = Handler(Looper.getMainLooper())
|
||||
val runnable = object : Runnable {
|
||||
override fun run() {
|
||||
val dateTime = Instant.now().atZone(ZoneId.systemDefault())
|
||||
|
||||
time = dateTime.toEpochSecond() * 1000
|
||||
time = dateTime.toEpochSecond() * 1000
|
||||
|
||||
val receiver = object : BroadcastReceiver() {
|
||||
override fun onReceive(context: Context?, intent: Intent?) {
|
||||
val dt = Instant.ofEpochMilli(System.currentTimeMillis())
|
||||
.atZone(ZoneId.systemDefault())
|
||||
.withSecond(0)
|
||||
.withNano(0)
|
||||
time = dt.toEpochSecond() * 1000
|
||||
}
|
||||
val millis = dateTime.nano / 1000000L
|
||||
var next = 1000L - millis
|
||||
if (next <= 200L) next += 1000L
|
||||
|
||||
handler.postDelayed(this, 1000 - millis)
|
||||
}
|
||||
|
||||
context.registerReceiver(receiver, IntentFilter().apply {
|
||||
addAction(Intent.ACTION_TIME_CHANGED)
|
||||
addAction(Intent.ACTION_TIME_TICK)
|
||||
})
|
||||
|
||||
}
|
||||
lifecycleOwner.repeatOnLifecycle(Lifecycle.State.RESUMED) {
|
||||
handler.post(runnable)
|
||||
try {
|
||||
awaitCancellation()
|
||||
} finally {
|
||||
context.unregisterReceiver(receiver)
|
||||
} catch (e: CancellationException) {
|
||||
handler.removeCallbacks(runnable)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CompositionLocalProvider(
|
||||
LocalTime provides time + secondsAnimation.value.toInt() * 1000,
|
||||
LocalTime provides time,
|
||||
content = content
|
||||
)
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user