mirror of
https://github.com/permissionlesstech/bitchat-android.git
synced 2026-11-01 07:51:15 +00:00
Refactored MainActivity by extracting the Compose application root and onboarding flow into a new BitchatApp composable. This reduces the activity's responsibilities to primarily handling Android lifecycle, permissions, and service coordination, while delegating the UI tree to a dedicated top-level composable.
This commit is contained in:
parent
e0059b5980
commit
27a13094de
@ -4,17 +4,9 @@ import android.content.Intent
|
|||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import androidx.activity.OnBackPressedCallback
|
|
||||||
import androidx.activity.compose.setContent
|
import androidx.activity.compose.setContent
|
||||||
import androidx.activity.enableEdgeToEdge
|
import androidx.activity.enableEdgeToEdge
|
||||||
import androidx.activity.viewModels
|
import androidx.activity.viewModels
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
|
||||||
import androidx.compose.foundation.layout.padding
|
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.material3.Scaffold
|
|
||||||
import androidx.compose.runtime.*
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.platform.LocalContext
|
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
import androidx.lifecycle.repeatOnLifecycle
|
import androidx.lifecycle.repeatOnLifecycle
|
||||||
@ -22,27 +14,19 @@ import androidx.lifecycle.Lifecycle
|
|||||||
import com.bitchat.android.mesh.BluetoothMeshService
|
import com.bitchat.android.mesh.BluetoothMeshService
|
||||||
import com.bitchat.android.mesh.MeshService
|
import com.bitchat.android.mesh.MeshService
|
||||||
import com.bitchat.android.geohash.LocationChannelManager
|
import com.bitchat.android.geohash.LocationChannelManager
|
||||||
import com.bitchat.android.onboarding.BluetoothCheckScreen
|
|
||||||
import com.bitchat.android.onboarding.BluetoothStatus
|
import com.bitchat.android.onboarding.BluetoothStatus
|
||||||
import com.bitchat.android.onboarding.BluetoothStatusManager
|
import com.bitchat.android.onboarding.BluetoothStatusManager
|
||||||
import com.bitchat.android.onboarding.BatteryOptimizationManager
|
import com.bitchat.android.onboarding.BatteryOptimizationManager
|
||||||
import com.bitchat.android.onboarding.BatteryOptimizationPreferenceManager
|
import com.bitchat.android.onboarding.BatteryOptimizationPreferenceManager
|
||||||
import com.bitchat.android.onboarding.BatteryOptimizationScreen
|
|
||||||
import com.bitchat.android.onboarding.BatteryOptimizationStatus
|
import com.bitchat.android.onboarding.BatteryOptimizationStatus
|
||||||
import com.bitchat.android.onboarding.BackgroundLocationPermissionScreen
|
|
||||||
import com.bitchat.android.onboarding.InitializationErrorScreen
|
|
||||||
import com.bitchat.android.onboarding.InitializingScreen
|
|
||||||
import com.bitchat.android.onboarding.LocationCheckScreen
|
|
||||||
import com.bitchat.android.onboarding.LocationStatus
|
import com.bitchat.android.onboarding.LocationStatus
|
||||||
import com.bitchat.android.onboarding.LocationStatusManager
|
import com.bitchat.android.onboarding.LocationStatusManager
|
||||||
import com.bitchat.android.onboarding.OnboardingCoordinator
|
import com.bitchat.android.onboarding.OnboardingCoordinator
|
||||||
import com.bitchat.android.onboarding.OnboardingState
|
import com.bitchat.android.onboarding.OnboardingState
|
||||||
import com.bitchat.android.onboarding.PermissionExplanationScreen
|
|
||||||
import com.bitchat.android.onboarding.PermissionManager
|
import com.bitchat.android.onboarding.PermissionManager
|
||||||
import com.bitchat.android.ui.ChatScreen
|
import com.bitchat.android.ui.BitchatApp
|
||||||
import com.bitchat.android.ui.ChatViewModel
|
import com.bitchat.android.ui.ChatViewModel
|
||||||
import com.bitchat.android.ui.OrientationAwareActivity
|
import com.bitchat.android.ui.OrientationAwareActivity
|
||||||
import com.bitchat.android.ui.theme.BitchatTheme
|
|
||||||
import com.bitchat.android.wifiaware.WifiAwareController
|
import com.bitchat.android.wifiaware.WifiAwareController
|
||||||
import com.bitchat.android.nostr.PoWPreferenceManager
|
import com.bitchat.android.nostr.PoWPreferenceManager
|
||||||
import com.bitchat.android.services.VerificationService
|
import com.bitchat.android.services.VerificationService
|
||||||
@ -155,17 +139,20 @@ class MainActivity : OrientationAwareActivity() {
|
|||||||
)
|
)
|
||||||
|
|
||||||
setContent {
|
setContent {
|
||||||
BitchatTheme {
|
BitchatApp(
|
||||||
Scaffold(
|
mainViewModel = mainViewModel,
|
||||||
modifier = Modifier.fillMaxSize(),
|
chatViewModel = chatViewModel,
|
||||||
containerColor = MaterialTheme.colorScheme.background
|
permissionManager = permissionManager,
|
||||||
) { innerPadding ->
|
onboardingCoordinator = onboardingCoordinator,
|
||||||
OnboardingFlowScreen(modifier = Modifier
|
bluetoothStatusManager = bluetoothStatusManager,
|
||||||
.fillMaxSize()
|
locationStatusManager = locationStatusManager,
|
||||||
.padding(innerPadding)
|
batteryOptimizationManager = batteryOptimizationManager,
|
||||||
)
|
onCheckBluetoothAndProceed = ::checkBluetoothAndProceed,
|
||||||
}
|
onCheckLocationAndProceed = ::checkLocationAndProceed,
|
||||||
}
|
onCheckBatteryOptimizationAndProceed = ::checkBatteryOptimizationAndProceed,
|
||||||
|
onProceedWithPermissionCheck = ::proceedWithPermissionCheck,
|
||||||
|
onCheckOnboardingStatus = ::checkOnboardingStatus
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Collect state changes in a lifecycle-aware manner
|
// Collect state changes in a lifecycle-aware manner
|
||||||
@ -195,159 +182,7 @@ class MainActivity : OrientationAwareActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
|
||||||
private fun OnboardingFlowScreen(modifier: Modifier = Modifier) {
|
|
||||||
val context = LocalContext.current
|
|
||||||
val onboardingState by mainViewModel.onboardingState.collectAsState()
|
|
||||||
val bluetoothStatus by mainViewModel.bluetoothStatus.collectAsState()
|
|
||||||
val locationStatus by mainViewModel.locationStatus.collectAsState()
|
|
||||||
val batteryOptimizationStatus by mainViewModel.batteryOptimizationStatus.collectAsState()
|
|
||||||
val errorMessage by mainViewModel.errorMessage.collectAsState()
|
|
||||||
val isBluetoothLoading by mainViewModel.isBluetoothLoading.collectAsState()
|
|
||||||
val isLocationLoading by mainViewModel.isLocationLoading.collectAsState()
|
|
||||||
val isBatteryOptimizationLoading by mainViewModel.isBatteryOptimizationLoading.collectAsState()
|
|
||||||
|
|
||||||
DisposableEffect(context, bluetoothStatusManager) {
|
|
||||||
|
|
||||||
val receiver = bluetoothStatusManager.monitorBluetoothState(
|
|
||||||
context = context,
|
|
||||||
bluetoothStatusManager = bluetoothStatusManager,
|
|
||||||
onBluetoothStateChanged = { status ->
|
|
||||||
if (status == BluetoothStatus.ENABLED && onboardingState == OnboardingState.BLUETOOTH_CHECK) {
|
|
||||||
checkBluetoothAndProceed()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
onDispose {
|
|
||||||
try {
|
|
||||||
context.unregisterReceiver(receiver)
|
|
||||||
} catch (e: IllegalStateException) {
|
|
||||||
Log.w("BluetoothStatusUI", "Receiver was not registered")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
when (onboardingState) {
|
|
||||||
OnboardingState.PERMISSION_REQUESTING -> {
|
|
||||||
InitializingScreen(modifier)
|
|
||||||
}
|
|
||||||
|
|
||||||
OnboardingState.BLUETOOTH_CHECK -> {
|
|
||||||
BluetoothCheckScreen(
|
|
||||||
modifier = modifier,
|
|
||||||
status = bluetoothStatus,
|
|
||||||
onEnableBluetooth = {
|
|
||||||
mainViewModel.updateBluetoothLoading(true)
|
|
||||||
bluetoothStatusManager.requestEnableBluetooth()
|
|
||||||
},
|
|
||||||
onRetry = {
|
|
||||||
checkBluetoothAndProceed()
|
|
||||||
},
|
|
||||||
onSkip = {
|
|
||||||
mainViewModel.skipBluetoothCheck()
|
|
||||||
checkLocationAndProceed()
|
|
||||||
},
|
|
||||||
isLoading = isBluetoothLoading
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
OnboardingState.LOCATION_CHECK -> {
|
|
||||||
LocationCheckScreen(
|
|
||||||
modifier = modifier,
|
|
||||||
status = locationStatus,
|
|
||||||
onEnableLocation = {
|
|
||||||
mainViewModel.updateLocationLoading(true)
|
|
||||||
locationStatusManager.requestEnableLocation()
|
|
||||||
},
|
|
||||||
onRetry = {
|
|
||||||
checkLocationAndProceed()
|
|
||||||
},
|
|
||||||
isLoading = isLocationLoading
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
OnboardingState.BATTERY_OPTIMIZATION_CHECK -> {
|
|
||||||
BatteryOptimizationScreen(
|
|
||||||
modifier = modifier,
|
|
||||||
status = batteryOptimizationStatus,
|
|
||||||
onDisableBatteryOptimization = {
|
|
||||||
mainViewModel.updateBatteryOptimizationLoading(true)
|
|
||||||
batteryOptimizationManager.requestDisableBatteryOptimization()
|
|
||||||
},
|
|
||||||
onRetry = {
|
|
||||||
checkBatteryOptimizationAndProceed()
|
|
||||||
},
|
|
||||||
onSkip = {
|
|
||||||
// Skip battery optimization and proceed
|
|
||||||
proceedWithPermissionCheck()
|
|
||||||
},
|
|
||||||
isLoading = isBatteryOptimizationLoading
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
OnboardingState.PERMISSION_EXPLANATION -> {
|
|
||||||
PermissionExplanationScreen(
|
|
||||||
modifier = modifier,
|
|
||||||
permissionCategories = permissionManager.getCategorizedPermissions(),
|
|
||||||
onContinue = {
|
|
||||||
mainViewModel.updateOnboardingState(OnboardingState.PERMISSION_REQUESTING)
|
|
||||||
onboardingCoordinator.requestPermissions()
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
OnboardingState.BACKGROUND_LOCATION_EXPLANATION -> {
|
|
||||||
BackgroundLocationPermissionScreen(
|
|
||||||
modifier = modifier,
|
|
||||||
onContinue = {
|
|
||||||
onboardingCoordinator.requestBackgroundLocation()
|
|
||||||
},
|
|
||||||
onRetry = {
|
|
||||||
onboardingCoordinator.checkBackgroundLocationAndProceed()
|
|
||||||
},
|
|
||||||
onSkip = {
|
|
||||||
onboardingCoordinator.skipBackgroundLocation()
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
OnboardingState.CHECKING, OnboardingState.INITIALIZING, OnboardingState.COMPLETE -> {
|
|
||||||
// Set up back navigation handling for the chat screen
|
|
||||||
val backCallback = object : OnBackPressedCallback(true) {
|
|
||||||
override fun handleOnBackPressed() {
|
|
||||||
// Let ChatViewModel handle navigation state
|
|
||||||
val handled = chatViewModel.handleBackPressed()
|
|
||||||
if (!handled) {
|
|
||||||
// If ChatViewModel doesn't handle it, disable this callback
|
|
||||||
// and let the system handle it (which will exit the app)
|
|
||||||
this.isEnabled = false
|
|
||||||
onBackPressedDispatcher.onBackPressed()
|
|
||||||
this.isEnabled = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add the callback - this will be automatically removed when the activity is destroyed
|
|
||||||
onBackPressedDispatcher.addCallback(this, backCallback)
|
|
||||||
ChatScreen(viewModel = chatViewModel)
|
|
||||||
}
|
|
||||||
|
|
||||||
OnboardingState.ERROR -> {
|
|
||||||
InitializationErrorScreen(
|
|
||||||
modifier = modifier,
|
|
||||||
errorMessage = errorMessage,
|
|
||||||
onRetry = {
|
|
||||||
mainViewModel.updateOnboardingState(OnboardingState.CHECKING)
|
|
||||||
checkOnboardingStatus()
|
|
||||||
},
|
|
||||||
onOpenSettings = {
|
|
||||||
onboardingCoordinator.openAppSettings()
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun handleOnboardingStateChange(state: OnboardingState) {
|
private fun handleOnboardingStateChange(state: OnboardingState) {
|
||||||
|
|
||||||
|
|||||||
234
app/src/main/java/com/bitchat/android/ui/BitchatApp.kt
Normal file
234
app/src/main/java/com/bitchat/android/ui/BitchatApp.kt
Normal file
@ -0,0 +1,234 @@
|
|||||||
|
package com.bitchat.android.ui
|
||||||
|
|
||||||
|
import android.util.Log
|
||||||
|
import androidx.activity.OnBackPressedCallback
|
||||||
|
import androidx.activity.compose.LocalOnBackPressedDispatcherOwner
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.Scaffold
|
||||||
|
import androidx.compose.runtime.*
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.lifecycle.compose.LocalLifecycleOwner
|
||||||
|
import com.bitchat.android.MainViewModel
|
||||||
|
import com.bitchat.android.onboarding.*
|
||||||
|
import com.bitchat.android.ui.theme.BitchatTheme
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
internal fun BitchatApp(
|
||||||
|
mainViewModel: MainViewModel,
|
||||||
|
chatViewModel: ChatViewModel,
|
||||||
|
permissionManager: PermissionManager,
|
||||||
|
onboardingCoordinator: OnboardingCoordinator,
|
||||||
|
bluetoothStatusManager: BluetoothStatusManager,
|
||||||
|
locationStatusManager: LocationStatusManager,
|
||||||
|
batteryOptimizationManager: BatteryOptimizationManager,
|
||||||
|
onCheckBluetoothAndProceed: () -> Unit,
|
||||||
|
onCheckLocationAndProceed: () -> Unit,
|
||||||
|
onCheckBatteryOptimizationAndProceed: () -> Unit,
|
||||||
|
onProceedWithPermissionCheck: () -> Unit,
|
||||||
|
onCheckOnboardingStatus: () -> Unit
|
||||||
|
) {
|
||||||
|
BitchatTheme {
|
||||||
|
Scaffold(
|
||||||
|
modifier = Modifier.fillMaxSize(),
|
||||||
|
containerColor = MaterialTheme.colorScheme.background
|
||||||
|
) { innerPadding ->
|
||||||
|
OnboardingFlowScreen(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.padding(innerPadding),
|
||||||
|
mainViewModel = mainViewModel,
|
||||||
|
chatViewModel = chatViewModel,
|
||||||
|
permissionManager = permissionManager,
|
||||||
|
onboardingCoordinator = onboardingCoordinator,
|
||||||
|
bluetoothStatusManager = bluetoothStatusManager,
|
||||||
|
locationStatusManager = locationStatusManager,
|
||||||
|
batteryOptimizationManager = batteryOptimizationManager,
|
||||||
|
onCheckBluetoothAndProceed = onCheckBluetoothAndProceed,
|
||||||
|
onCheckLocationAndProceed = onCheckLocationAndProceed,
|
||||||
|
onCheckBatteryOptimizationAndProceed = onCheckBatteryOptimizationAndProceed,
|
||||||
|
onProceedWithPermissionCheck = onProceedWithPermissionCheck,
|
||||||
|
onCheckOnboardingStatus = onCheckOnboardingStatus
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun OnboardingFlowScreen(
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
mainViewModel: MainViewModel,
|
||||||
|
chatViewModel: ChatViewModel,
|
||||||
|
permissionManager: PermissionManager,
|
||||||
|
onboardingCoordinator: OnboardingCoordinator,
|
||||||
|
bluetoothStatusManager: BluetoothStatusManager,
|
||||||
|
locationStatusManager: LocationStatusManager,
|
||||||
|
batteryOptimizationManager: BatteryOptimizationManager,
|
||||||
|
onCheckBluetoothAndProceed: () -> Unit,
|
||||||
|
onCheckLocationAndProceed: () -> Unit,
|
||||||
|
onCheckBatteryOptimizationAndProceed: () -> Unit,
|
||||||
|
onProceedWithPermissionCheck: () -> Unit,
|
||||||
|
onCheckOnboardingStatus: () -> Unit
|
||||||
|
) {
|
||||||
|
val context = LocalContext.current
|
||||||
|
val onboardingState by mainViewModel.onboardingState.collectAsState()
|
||||||
|
val bluetoothStatus by mainViewModel.bluetoothStatus.collectAsState()
|
||||||
|
val locationStatus by mainViewModel.locationStatus.collectAsState()
|
||||||
|
val batteryOptimizationStatus by mainViewModel.batteryOptimizationStatus.collectAsState()
|
||||||
|
val errorMessage by mainViewModel.errorMessage.collectAsState()
|
||||||
|
val isBluetoothLoading by mainViewModel.isBluetoothLoading.collectAsState()
|
||||||
|
val isLocationLoading by mainViewModel.isLocationLoading.collectAsState()
|
||||||
|
val isBatteryOptimizationLoading by mainViewModel.isBatteryOptimizationLoading.collectAsState()
|
||||||
|
|
||||||
|
DisposableEffect(context, bluetoothStatusManager) {
|
||||||
|
val receiver = bluetoothStatusManager.monitorBluetoothState(
|
||||||
|
context = context,
|
||||||
|
bluetoothStatusManager = bluetoothStatusManager,
|
||||||
|
onBluetoothStateChanged = { status ->
|
||||||
|
if (status == BluetoothStatus.ENABLED && onboardingState == OnboardingState.BLUETOOTH_CHECK) {
|
||||||
|
onCheckBluetoothAndProceed()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
onDispose {
|
||||||
|
try {
|
||||||
|
context.unregisterReceiver(receiver)
|
||||||
|
} catch (e: IllegalStateException) {
|
||||||
|
Log.w("BluetoothStatusUI", "Receiver was not registered")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val onBackPressedDispatcherOwner = LocalOnBackPressedDispatcherOwner.current
|
||||||
|
val lifecycleOwner = LocalLifecycleOwner.current
|
||||||
|
|
||||||
|
when (onboardingState) {
|
||||||
|
OnboardingState.PERMISSION_REQUESTING -> {
|
||||||
|
InitializingScreen(modifier)
|
||||||
|
}
|
||||||
|
|
||||||
|
OnboardingState.BLUETOOTH_CHECK -> {
|
||||||
|
BluetoothCheckScreen(
|
||||||
|
modifier = modifier,
|
||||||
|
status = bluetoothStatus,
|
||||||
|
onEnableBluetooth = {
|
||||||
|
mainViewModel.updateBluetoothLoading(true)
|
||||||
|
bluetoothStatusManager.requestEnableBluetooth()
|
||||||
|
},
|
||||||
|
onRetry = {
|
||||||
|
onCheckBluetoothAndProceed()
|
||||||
|
},
|
||||||
|
onSkip = {
|
||||||
|
mainViewModel.skipBluetoothCheck()
|
||||||
|
onCheckLocationAndProceed()
|
||||||
|
},
|
||||||
|
isLoading = isBluetoothLoading
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
OnboardingState.LOCATION_CHECK -> {
|
||||||
|
LocationCheckScreen(
|
||||||
|
modifier = modifier,
|
||||||
|
status = locationStatus,
|
||||||
|
onEnableLocation = {
|
||||||
|
mainViewModel.updateLocationLoading(true)
|
||||||
|
locationStatusManager.requestEnableLocation()
|
||||||
|
},
|
||||||
|
onRetry = {
|
||||||
|
onCheckLocationAndProceed()
|
||||||
|
},
|
||||||
|
isLoading = isLocationLoading
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
OnboardingState.BATTERY_OPTIMIZATION_CHECK -> {
|
||||||
|
BatteryOptimizationScreen(
|
||||||
|
modifier = modifier,
|
||||||
|
status = batteryOptimizationStatus,
|
||||||
|
onDisableBatteryOptimization = {
|
||||||
|
mainViewModel.updateBatteryOptimizationLoading(true)
|
||||||
|
batteryOptimizationManager.requestDisableBatteryOptimization()
|
||||||
|
},
|
||||||
|
onRetry = {
|
||||||
|
onCheckBatteryOptimizationAndProceed()
|
||||||
|
},
|
||||||
|
onSkip = {
|
||||||
|
// Skip battery optimization and proceed
|
||||||
|
onProceedWithPermissionCheck()
|
||||||
|
},
|
||||||
|
isLoading = isBatteryOptimizationLoading
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
OnboardingState.PERMISSION_EXPLANATION -> {
|
||||||
|
PermissionExplanationScreen(
|
||||||
|
modifier = modifier,
|
||||||
|
permissionCategories = permissionManager.getCategorizedPermissions(),
|
||||||
|
onContinue = {
|
||||||
|
mainViewModel.updateOnboardingState(OnboardingState.PERMISSION_REQUESTING)
|
||||||
|
onboardingCoordinator.requestPermissions()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
OnboardingState.BACKGROUND_LOCATION_EXPLANATION -> {
|
||||||
|
BackgroundLocationPermissionScreen(
|
||||||
|
modifier = modifier,
|
||||||
|
onContinue = {
|
||||||
|
onboardingCoordinator.requestBackgroundLocation()
|
||||||
|
},
|
||||||
|
onRetry = {
|
||||||
|
onboardingCoordinator.checkBackgroundLocationAndProceed()
|
||||||
|
},
|
||||||
|
onSkip = {
|
||||||
|
onboardingCoordinator.skipBackgroundLocation()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
OnboardingState.CHECKING, OnboardingState.INITIALIZING, OnboardingState.COMPLETE -> {
|
||||||
|
// Set up back navigation handling for the chat screen
|
||||||
|
if (onBackPressedDispatcherOwner != null) {
|
||||||
|
DisposableEffect(onBackPressedDispatcherOwner, lifecycleOwner) {
|
||||||
|
val backCallback = object : OnBackPressedCallback(true) {
|
||||||
|
override fun handleOnBackPressed() {
|
||||||
|
// Let ChatViewModel handle navigation state
|
||||||
|
val handled = chatViewModel.handleBackPressed()
|
||||||
|
if (!handled) {
|
||||||
|
// If ChatViewModel doesn't handle it, disable this callback
|
||||||
|
// and let the system handle it (which will exit the app)
|
||||||
|
this.isEnabled = false
|
||||||
|
onBackPressedDispatcherOwner.onBackPressedDispatcher.onBackPressed()
|
||||||
|
this.isEnabled = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onBackPressedDispatcherOwner.onBackPressedDispatcher.addCallback(lifecycleOwner, backCallback)
|
||||||
|
|
||||||
|
onDispose {
|
||||||
|
backCallback.remove()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ChatScreen(viewModel = chatViewModel)
|
||||||
|
}
|
||||||
|
|
||||||
|
OnboardingState.ERROR -> {
|
||||||
|
InitializationErrorScreen(
|
||||||
|
modifier = modifier,
|
||||||
|
errorMessage = errorMessage,
|
||||||
|
onRetry = {
|
||||||
|
mainViewModel.updateOnboardingState(OnboardingState.CHECKING)
|
||||||
|
onCheckOnboardingStatus()
|
||||||
|
},
|
||||||
|
onOpenSettings = {
|
||||||
|
onboardingCoordinator.openAppSettings()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user