I have a Jetpack Compose project and I am making API call to send OTP and Verify the OTP on a second screen. My Problem now is when the OTP request is sent, and the request is successful I expect to navigate to the screen to verify the OTP which works but if I try to navigate back to the initial screen where my phone was verified, the back button never seem to work.
Here is my code.
@Composable
fun ContinueWithPhoneView(
navController: NavController,
authenticationDataViewModel: AuthenticationDataViewModel
) {
val viewModel = hiltViewModel<ContinueWithPhoneViewModel>()
val event by viewModel.events.observeAsState(null)
val phoneNumber = remember { mutableStateOf("") }
val errorMessage = remember { mutableStateOf("") }
val (gesturesEnabled, toggleGesturesEnabled) = remember { mutableStateOf(false) }
val scope = rememberCoroutineScope()
val isLoading = remember { mutableStateOf(false) }
val drawerState = rememberBottomDrawerState(BottomDrawerValue.Closed)
Surface(
modifier = Modifier.fillMaxSize(),
) {
BottomDrawer(
gesturesEnabled = gesturesEnabled,
drawerState = drawerState,
drawerShape = BottomSheetShape,
drawerElevation = 8.dp,
drawerContent = {
ErrorBottomView(message = errorMessage.value) {
scope.launch { drawerState.close() }
}
},
content = {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
) {
Column {
NavigationBar(topAppBarText = "Continue With Phone") {
navController.popBackStack()
}
}
Spacer(modifier = Modifier
.weight(1f))
Column(
modifier = Modifier
.fillMaxWidth()
.padding(start = 16.dp, end = 16.dp),
) {
OutlinedTextField(
keyboardOptions = KeyboardOptions(
capitalization = KeyboardCapitalization.None,
autoCorrect = false,
keyboardType = KeyboardType.Phone,
),
modifier = Modifier
.navigationBarsWithImePadding()
.fillMaxWidth(),
value = phoneNumber.value,
onValueChange = { phoneNumber.value = it },
label = {
Text(
text = "Phone Number"
)
},
colors = TextFieldDefaults.outlinedTextFieldColors(
focusedBorderColor = MaterialTheme.colors.onSecondary, // Set the focused border color here
focusedLabelColor = MaterialTheme.colors.onSecondary
)
)
Spacer(modifier = Modifier.padding(8.dp))
Text(modifier = Modifier, style = MaterialTheme.typography.caption, text = "By continuing, you agree to get SMS messages, WhatsApp, Telegram or calls, including automated means, from Dispatch and its affiliates to the number provided")
}
Spacer(modifier = Modifier
.weight(1f))
Column(
modifier = Modifier
.fillMaxWidth()
.padding(start = 16.dp, end = 16.dp),
) {
NavigationButton(buttonText = "Continue with Phone", isLoading = isLoading.value, onBackPressed = {
navController.popBackStack()
}) {
viewModel.sendOtp(phoneNumber = phoneNumber.value)
}
}
Spacer(modifier = Modifier.padding(6.dp))
}
}
)
LaunchedEffect(event) {
when (event) {
is Result.Loading -> {
isLoading.value = true
}
is Result.Error -> {
val exception = (event as Result.Error).exception
scope.launch {
errorMessage.value = exception
isLoading.value = false
drawerState.open()
}
}
is Result.Success -> {
val logInRequest = LogInRequest(phoneNumber = phoneNumber.value, password = "")
isLoading.value = false
navController.currentBackStackEntry?.arguments?.putParcelable("logInRequest", logInRequest)
navController.navigate(Screen.VerifyPhone.route)
}
else -> {}
}
}
}
}
My ViewModel
@HiltViewModel
class ContinueWithPhoneViewModel @Inject constructor(
private val repository: AccountRepositoryProviding,
@DefaultDispatcher private val defaultDispatcher: CoroutineDispatcher,
): ViewModel() {
private val _events = MutableLiveData<Result<Boolean>>()
val events: LiveData<Result<Boolean>> = _events
private var job: Job? = null
fun sendOtp(phoneNumber: String) {
job?.cancel()
// Timber.tag(javaClass.name)
// .d("inputted phone number %s", phoneNumber)
_events.value = Result.Loading
val handler = CoroutineExceptionHandler { _, throwable ->
val message = when (throwable) {
is HttpException -> throwable.toErrorMessage()
else -> "An Error Occurred."
}
Log.d("ContinueWithPhoneViewModel", "ERR :: ${throwable} \n")
// Timber.tag(javaClass.name)
// .e(throwable)
_events.value = Result.Error(message)
}
job = viewModelScope.launch(handler) {
val resp = repository.sendOtp(phoneNumber = phoneNumber)
Timber.tag(javaClass.name)
.d("Response ::: %s", resp)
_events.value = Result.Success(resp.data ?: false)
}
}
}
my app navigation
@Composable
fun AppNavigation() {
val navController = rememberNavController()
val authenticationDataViewModel: AuthenticationDataViewModel = viewModel()
NavHost(
navController = navController,
startDestination = Screen.Landing.route
) {
composable(Screen.Landing.route) {
LandingPageView(navController = navController)
}
composable(Screen.ContinueWithPhone.route) {
ContinueWithPhoneView(navController = navController, authenticationDataViewModel = authenticationDataViewModel)
}
composable(route = Screen.VerifyPhone.route) {
navController.previousBackStackEntry?.arguments?.getParcelable<LogInRequest>("logInRequest")?.let { request -> VerifyPhoneView(navController, request) }
}
composable(route = Screen.Base.route) {
TabBarView()
}
}
}
Any help is appreciated.
from stuck navigation in Jetpack Compose
No comments:
Post a Comment