diff --git a/app/src/main/java/to/bitkit/data/SettingsStore.kt b/app/src/main/java/to/bitkit/data/SettingsStore.kt index f7ccb9a0a..64c7593bd 100644 --- a/app/src/main/java/to/bitkit/data/SettingsStore.kt +++ b/app/src/main/java/to/bitkit/data/SettingsStore.kt @@ -85,7 +85,6 @@ data class SettingsData( val isPinEnabled: Boolean = false, val isPinOnLaunchEnabled: Boolean = false, val isBiometricEnabled: Boolean = false, - val isPinOnIdleEnabled: Boolean = false, val isPinForPaymentsEnabled: Boolean = false, val isDevModeEnabled: Boolean = false, val showWidgets: Boolean = true, @@ -109,7 +108,6 @@ data class SettingsData( fun SettingsData.resetPin() = this.copy( isPinEnabled = false, isPinOnLaunchEnabled = true, - isPinOnIdleEnabled = false, isPinForPaymentsEnabled = false, isBiometricEnabled = false, ) diff --git a/app/src/main/java/to/bitkit/ui/MainActivity.kt b/app/src/main/java/to/bitkit/ui/MainActivity.kt index d40f4b9b8..e30f9dc0e 100644 --- a/app/src/main/java/to/bitkit/ui/MainActivity.kt +++ b/app/src/main/java/to/bitkit/ui/MainActivity.kt @@ -29,7 +29,6 @@ import kotlinx.serialization.Serializable import to.bitkit.androidServices.LightningNodeService import to.bitkit.androidServices.LightningNodeService.Companion.CHANNEL_ID_NODE import to.bitkit.ui.components.AuthCheckView -import to.bitkit.ui.components.InactivityTracker import to.bitkit.ui.components.IsOnlineTracker import to.bitkit.ui.components.ToastOverlay import to.bitkit.ui.onboarding.CreateWalletWithPassphraseScreen @@ -96,18 +95,17 @@ class MainActivity : FragmentActivity() { val isAuthenticated by appViewModel.isAuthenticated.collectAsStateWithLifecycle() IsOnlineTracker(appViewModel) - InactivityTracker(appViewModel, settingsViewModel) { - ContentView( - appViewModel = appViewModel, - walletViewModel = walletViewModel, - blocktankViewModel = blocktankViewModel, - currencyViewModel = currencyViewModel, - activityListViewModel = activityListViewModel, - transferViewModel = transferViewModel, - settingsViewModel = settingsViewModel, - backupsViewModel = backupsViewModel, - ) - } + + ContentView( + appViewModel = appViewModel, + walletViewModel = walletViewModel, + blocktankViewModel = blocktankViewModel, + currencyViewModel = currencyViewModel, + activityListViewModel = activityListViewModel, + transferViewModel = transferViewModel, + settingsViewModel = settingsViewModel, + backupsViewModel = backupsViewModel, + ) AnimatedVisibility( visible = !isAuthenticated, diff --git a/app/src/main/java/to/bitkit/ui/components/AuthCheckScreen.kt b/app/src/main/java/to/bitkit/ui/components/AuthCheckScreen.kt index 699c15242..4853b4662 100644 --- a/app/src/main/java/to/bitkit/ui/components/AuthCheckScreen.kt +++ b/app/src/main/java/to/bitkit/ui/components/AuthCheckScreen.kt @@ -19,7 +19,6 @@ fun AuthCheckScreen( val isPinOnLaunchEnabled by settings.isPinOnLaunchEnabled.collectAsStateWithLifecycle() val isBiometricEnabled by settings.isBiometricEnabled.collectAsStateWithLifecycle() - val isPinOnIdleEnabled by settings.isPinOnIdleEnabled.collectAsStateWithLifecycle() val isPinForPaymentsEnabled by settings.isPinForPaymentsEnabled.collectAsStateWithLifecycle() AuthCheckView( @@ -40,11 +39,6 @@ fun AuthCheckScreen( navController.popBackStack() } - AuthCheckAction.TOGGLE_PIN_ON_IDLE -> { - settings.setIsPinOnIdleEnabled(!isPinOnIdleEnabled) - navController.popBackStack() - } - AuthCheckAction.TOGGLE_PIN_FOR_PAYMENTS -> { settings.setIsPinForPaymentsEnabled(!isPinForPaymentsEnabled) navController.popBackStack() @@ -70,7 +64,6 @@ fun AuthCheckScreen( object AuthCheckAction { const val TOGGLE_PIN_ON_LAUNCH = "TOGGLE_PIN_ON_LAUNCH" const val TOGGLE_BIOMETRICS = "TOGGLE_BIOMETRICS" - const val TOGGLE_PIN_ON_IDLE = "TOGGLE_PIN_ON_IDLE" const val TOGGLE_PIN_FOR_PAYMENTS = "TOGGLE_PIN_FOR_PAYMENTS" const val DISABLE_PIN = "DISABLE_PIN" const val NAV_TO_RESET = "NAV_TO_RESET" diff --git a/app/src/main/java/to/bitkit/ui/components/InactivityTracker.kt b/app/src/main/java/to/bitkit/ui/components/InactivityTracker.kt deleted file mode 100644 index e64cf9a76..000000000 --- a/app/src/main/java/to/bitkit/ui/components/InactivityTracker.kt +++ /dev/null @@ -1,102 +0,0 @@ -package to.bitkit.ui.components - -import androidx.compose.foundation.layout.Box -import androidx.compose.runtime.Composable -import androidx.compose.runtime.DisposableEffect -import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.runtime.rememberCoroutineScope -import androidx.compose.runtime.setValue -import androidx.compose.ui.Modifier -import androidx.compose.ui.input.pointer.pointerInput -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleEventObserver -import androidx.lifecycle.compose.LocalLifecycleOwner -import androidx.lifecycle.compose.collectAsStateWithLifecycle -import kotlinx.coroutines.Job -import kotlinx.coroutines.delay -import kotlinx.coroutines.launch -import to.bitkit.utils.Logger -import to.bitkit.viewmodels.AppViewModel -import to.bitkit.viewmodels.SettingsViewModel - -private const val INACTIVITY_DELAY = 90_000L // 90 seconds - -@Composable -fun InactivityTracker( - app: AppViewModel, - settings: SettingsViewModel, - modifier: Modifier = Modifier, - content: @Composable () -> Unit, -) { - val scope = rememberCoroutineScope() - val lifecycleOwner = LocalLifecycleOwner.current - - val isPinEnabled by settings.isPinEnabled.collectAsStateWithLifecycle() - val isPinOnIdleEnabled by settings.isPinOnIdleEnabled.collectAsStateWithLifecycle() - val isAuthenticated by app.isAuthenticated.collectAsStateWithLifecycle() - - var inactivityJob by remember { mutableStateOf(null) } - - fun resetInactivityTimeout() { - inactivityJob?.cancel()?.also { - inactivityJob = null - } - if (isPinEnabled && isPinOnIdleEnabled && isAuthenticated) { - inactivityJob = scope.launch { - delay(INACTIVITY_DELAY) - Logger.debug("Inactivity timeout reached after ${INACTIVITY_DELAY / 1000}s, resetting isAuthenticated.") - app.setIsAuthenticated(false) - resetInactivityTimeout() - } - } - } - - LaunchedEffect(isAuthenticated, isPinEnabled, isPinOnIdleEnabled) { - if (isAuthenticated) { - resetInactivityTimeout() - } else { - inactivityJob?.cancel()?.also { - inactivityJob = null - } - } - } - - DisposableEffect(lifecycleOwner) { - val observer = LifecycleEventObserver { _, event -> - when (event) { - Lifecycle.Event.ON_RESUME -> resetInactivityTimeout() - Lifecycle.Event.ON_PAUSE -> inactivityJob?.cancel()?.also { inactivityJob = null } - else -> Unit - } - } - lifecycleOwner.lifecycle.addObserver(observer) - onDispose { - lifecycleOwner.lifecycle.removeObserver(observer) - inactivityJob?.cancel()?.also { - inactivityJob = null - } - } - } - - Box( - modifier = modifier.let { baseModifier -> - if (isPinOnIdleEnabled) { - baseModifier.pointerInput(Unit) { - while (true) { - awaitPointerEventScope { - awaitPointerEvent() - resetInactivityTimeout() - } - } - } - } else { - baseModifier - } - } - ) { - content() - } -} diff --git a/app/src/main/java/to/bitkit/ui/settings/SecuritySettingsScreen.kt b/app/src/main/java/to/bitkit/ui/settings/SecuritySettingsScreen.kt index 51fa26597..29a9ff632 100644 --- a/app/src/main/java/to/bitkit/ui/settings/SecuritySettingsScreen.kt +++ b/app/src/main/java/to/bitkit/ui/settings/SecuritySettingsScreen.kt @@ -43,7 +43,6 @@ fun SecuritySettingsScreen( val isPinEnabled by settings.isPinEnabled.collectAsStateWithLifecycle() val isPinOnLaunchEnabled by settings.isPinOnLaunchEnabled.collectAsStateWithLifecycle() val isBiometricEnabled by settings.isBiometricEnabled.collectAsStateWithLifecycle() - val isPinOnIdleEnabled by settings.isPinOnIdleEnabled.collectAsStateWithLifecycle() val isPinForPaymentsEnabled by settings.isPinForPaymentsEnabled.collectAsStateWithLifecycle() val enableSwipeToHideBalance by settings.enableSwipeToHideBalance.collectAsStateWithLifecycle() val hideBalanceOnOpen by settings.hideBalanceOnOpen.collectAsStateWithLifecycle() @@ -54,7 +53,6 @@ fun SecuritySettingsScreen( isPinEnabled = isPinEnabled, isPinOnLaunchEnabled = isPinOnLaunchEnabled, isBiometricEnabled = isBiometricEnabled, - isPinOnIdleEnabled = isPinOnIdleEnabled, isPinForPaymentsEnabled = isPinForPaymentsEnabled, enableSwipeToHideBalance = enableSwipeToHideBalance, hideBalanceOnOpen = hideBalanceOnOpen, @@ -76,11 +74,6 @@ fun SecuritySettingsScreen( onSuccessActionId = AuthCheckAction.TOGGLE_PIN_ON_LAUNCH, ) }, - onPinOnIdleClick = { - navController.navigateToAuthCheck( - onSuccessActionId = AuthCheckAction.TOGGLE_PIN_ON_IDLE, - ) - }, onPinForPaymentsClick = { navController.navigateToAuthCheck( onSuccessActionId = AuthCheckAction.TOGGLE_PIN_FOR_PAYMENTS, @@ -114,7 +107,6 @@ private fun Content( isPinEnabled: Boolean, isPinOnLaunchEnabled: Boolean, isBiometricEnabled: Boolean, - isPinOnIdleEnabled: Boolean, isPinForPaymentsEnabled: Boolean, enableSwipeToHideBalance: Boolean, hideBalanceOnOpen: Boolean, @@ -124,7 +116,6 @@ private fun Content( onPinClick: () -> Unit = {}, onChangePinClick: () -> Unit = {}, onPinOnLaunchClick: () -> Unit = {}, - onPinOnIdleClick: () -> Unit = {}, onPinForPaymentsClick: () -> Unit = {}, onUseBiometricsClick: () -> Unit = {}, onSwipeToHideBalanceClick: () -> Unit = {}, @@ -198,12 +189,6 @@ private fun Content( onClick = onPinOnLaunchClick, modifier = Modifier.testTag("EnablePinOnLaunch"), ) - SettingsSwitchRow( - title = stringResource(R.string.settings__security__pin_idle), - isChecked = isPinOnIdleEnabled, - onClick = onPinOnIdleClick, - modifier = Modifier.testTag("EnablePinOnIdle"), - ) SettingsSwitchRow( title = stringResource(R.string.settings__security__pin_payments), isChecked = isPinForPaymentsEnabled, @@ -244,7 +229,6 @@ private fun Preview() { isPinEnabled = true, isPinOnLaunchEnabled = true, isBiometricEnabled = false, - isPinOnIdleEnabled = false, isPinForPaymentsEnabled = false, enableSwipeToHideBalance = true, hideBalanceOnOpen = false, diff --git a/app/src/main/java/to/bitkit/viewmodels/SettingsViewModel.kt b/app/src/main/java/to/bitkit/viewmodels/SettingsViewModel.kt index a21409eed..2757f4826 100644 --- a/app/src/main/java/to/bitkit/viewmodels/SettingsViewModel.kt +++ b/app/src/main/java/to/bitkit/viewmodels/SettingsViewModel.kt @@ -82,15 +82,6 @@ class SettingsViewModel @Inject constructor( } } - val isPinOnIdleEnabled = settingsStore.data.map { it.isPinOnIdleEnabled } - .asStateFlow(initialValue = false) - - fun setIsPinOnIdleEnabled(value: Boolean) { - viewModelScope.launch { - settingsStore.update { it.copy(isPinOnIdleEnabled = value) } - } - } - val isPinForPaymentsEnabled = settingsStore.data.map { it.isPinForPaymentsEnabled } .asStateFlow(initialValue = false) diff --git a/app/src/test/java/to/bitkit/repositories/ActivityRepoTest.kt b/app/src/test/java/to/bitkit/repositories/ActivityRepoTest.kt index 998c38a45..fe7d206cf 100644 --- a/app/src/test/java/to/bitkit/repositories/ActivityRepoTest.kt +++ b/app/src/test/java/to/bitkit/repositories/ActivityRepoTest.kt @@ -19,10 +19,12 @@ import org.mockito.kotlin.verify import org.mockito.kotlin.whenever import org.mockito.kotlin.wheneverBlocking import to.bitkit.data.AppCacheData +import to.bitkit.data.AppDb import to.bitkit.data.CacheStore import to.bitkit.data.dto.PendingBoostActivity import to.bitkit.services.CoreService import to.bitkit.test.BaseUnitTest +import to.bitkit.utils.AddressChecker import kotlin.test.assertEquals import kotlin.test.assertFalse import kotlin.test.assertNull @@ -33,6 +35,8 @@ class ActivityRepoTest : BaseUnitTest() { private val coreService: CoreService = mock() private val lightningRepo: LightningRepo = mock() private val cacheStore: CacheStore = mock() + private val addressChecker: AddressChecker = mock() + private val db: AppDb = mock() private lateinit var sut: ActivityRepo @@ -71,6 +75,8 @@ class ActivityRepoTest : BaseUnitTest() { coreService = coreService, lightningRepo = lightningRepo, cacheStore = cacheStore, + addressChecker = addressChecker, + db = db ) }