@@ -3,99 +3,50 @@ package to.bitkit.ui.components
33import androidx.compose.foundation.layout.Box
44import androidx.compose.runtime.Composable
55import androidx.compose.runtime.DisposableEffect
6- import androidx.compose.runtime.LaunchedEffect
76import androidx.compose.runtime.getValue
8- import androidx.compose.runtime.mutableStateOf
9- import androidx.compose.runtime.remember
10- import androidx.compose.runtime.rememberCoroutineScope
11- import androidx.compose.runtime.setValue
127import androidx.compose.ui.Modifier
13- import androidx.compose.ui.input.pointer.pointerInput
148import androidx.lifecycle.Lifecycle
159import androidx.lifecycle.LifecycleEventObserver
1610import androidx.lifecycle.compose.LocalLifecycleOwner
1711import androidx.lifecycle.compose.collectAsStateWithLifecycle
18- import kotlinx.coroutines.Job
19- import kotlinx.coroutines.delay
20- import kotlinx.coroutines.launch
2112import to.bitkit.utils.Logger
2213import to.bitkit.viewmodels.AppViewModel
2314import to.bitkit.viewmodels.SettingsViewModel
2415
25- private const val INACTIVITY_DELAY = 90_000L // 90 seconds
26-
2716@Composable
2817fun InactivityTracker (
2918 app : AppViewModel ,
3019 settings : SettingsViewModel ,
3120 modifier : Modifier = Modifier ,
3221 content : @Composable () -> Unit ,
3322) {
34- val scope = rememberCoroutineScope()
3523 val lifecycleOwner = LocalLifecycleOwner .current
3624
3725 val isPinEnabled by settings.isPinEnabled.collectAsStateWithLifecycle()
3826 val isPinOnIdleEnabled by settings.isPinOnIdleEnabled.collectAsStateWithLifecycle()
3927 val isAuthenticated by app.isAuthenticated.collectAsStateWithLifecycle()
4028
41- var inactivityJob by remember { mutableStateOf<Job ?>(null ) }
42-
43- fun resetInactivityTimeout () {
44- inactivityJob?.cancel()?.also {
45- inactivityJob = null
46- }
47- if (isPinEnabled && isPinOnIdleEnabled && isAuthenticated) {
48- inactivityJob = scope.launch {
49- delay(INACTIVITY_DELAY )
50- Logger .debug(" Inactivity timeout reached after ${INACTIVITY_DELAY / 1000 } s, resetting isAuthenticated." )
51- app.setIsAuthenticated(false )
52- resetInactivityTimeout()
53- }
54- }
55- }
56-
57- LaunchedEffect (isAuthenticated, isPinEnabled, isPinOnIdleEnabled) {
58- if (isAuthenticated) {
59- resetInactivityTimeout()
60- } else {
61- inactivityJob?.cancel()?.also {
62- inactivityJob = null
63- }
64- }
65- }
66-
6729 DisposableEffect (lifecycleOwner) {
6830 val observer = LifecycleEventObserver { _, event ->
6931 when (event) {
70- Lifecycle .Event .ON_RESUME -> resetInactivityTimeout()
71- Lifecycle .Event .ON_PAUSE -> inactivityJob?.cancel()?.also { inactivityJob = null }
32+ Lifecycle .Event .ON_RESUME -> {
33+ if (isPinEnabled && isPinOnIdleEnabled && isAuthenticated) {
34+ Logger .debug(" App resumed, resetting isAuthenticated." )
35+ app.setIsAuthenticated(false )
36+ }
37+ }
38+
7239 else -> Unit
7340 }
7441 }
7542 lifecycleOwner.lifecycle.addObserver(observer)
7643 onDispose {
7744 lifecycleOwner.lifecycle.removeObserver(observer)
78- inactivityJob?.cancel()?.also {
79- inactivityJob = null
80- }
8145 }
8246 }
8347
8448 Box (
85- modifier = modifier.let { baseModifier ->
86- if (isPinOnIdleEnabled) {
87- baseModifier.pointerInput(Unit ) {
88- while (true ) {
89- awaitPointerEventScope {
90- awaitPointerEvent()
91- resetInactivityTimeout()
92- }
93- }
94- }
95- } else {
96- baseModifier
97- }
98- }
49+ modifier = modifier
9950 ) {
10051 content()
10152 }
0 commit comments