forked from Olympic/NTO-2025-Android-TeamTask
navigation fix + code review
This commit is contained in:
@@ -2,48 +2,58 @@ package ru.myitschool.work.ui.screen
|
||||
|
||||
import androidx.compose.animation.EnterTransition
|
||||
import androidx.compose.animation.ExitTransition
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.navigation.NavHostController
|
||||
import androidx.navigation.compose.NavHost
|
||||
import androidx.navigation.compose.composable
|
||||
import androidx.navigation.compose.rememberNavController
|
||||
import ru.myitschool.work.data.repo.AuthRepository
|
||||
import ru.myitschool.work.ui.nav.AuthScreenDestination
|
||||
import ru.myitschool.work.ui.nav.BookScreenDestination
|
||||
import ru.myitschool.work.ui.nav.MainScreenDestination
|
||||
import ru.myitschool.work.ui.screen.auth.AuthScreen
|
||||
import ru.myitschool.work.ui.screen.book.BookScreen
|
||||
import ru.myitschool.work.ui.screen.main.MainScreen
|
||||
|
||||
@Composable
|
||||
fun AppNavHost(
|
||||
modifier: Modifier = Modifier,
|
||||
navController: NavHostController = rememberNavController()
|
||||
) {
|
||||
// authorized state follow
|
||||
val isAuthorized by AuthRepository.isAuthorized.collectAsState()
|
||||
|
||||
LaunchedEffect(isAuthorized) {
|
||||
if (isAuthorized) {
|
||||
navController.navigate(MainScreenDestination) {
|
||||
popUpTo(0) { inclusive = false }
|
||||
}
|
||||
} else {
|
||||
navController.navigate(AuthScreenDestination) {
|
||||
popUpTo(0) { inclusive = false }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NavHost(
|
||||
modifier = modifier,
|
||||
enterTransition = { EnterTransition.None },
|
||||
exitTransition = { ExitTransition.None },
|
||||
navController = navController,
|
||||
startDestination = AuthScreenDestination,
|
||||
startDestination = if (isAuthorized) MainScreenDestination else AuthScreenDestination,
|
||||
) {
|
||||
composable<AuthScreenDestination> {
|
||||
AuthScreen(navController = navController)
|
||||
}
|
||||
composable<MainScreenDestination> {
|
||||
Box(
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
Text(text = "Hello")
|
||||
}
|
||||
MainScreen(navController = navController)
|
||||
}
|
||||
composable<BookScreenDestination> {
|
||||
Box(
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
Text(text = "Hello")
|
||||
}
|
||||
BookScreen(navController = navController)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,6 +20,7 @@ import ru.myitschool.work.R
|
||||
import ru.myitschool.work.core.TestIds
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
@@ -43,79 +44,121 @@ fun BookScreen(
|
||||
}
|
||||
}
|
||||
}
|
||||
Scaffold(
|
||||
topBar = {
|
||||
TopAppBar(
|
||||
title = { Text(stringResource(R.string.book_title)) },
|
||||
navigationIcon = {
|
||||
IconButton(
|
||||
onClick = { viewModel.onIntent(BookIntent.Back) },
|
||||
modifier = Modifier.testTag(TestIds.Book.BACK_BUTTON)
|
||||
) {
|
||||
Icon(
|
||||
// TODO
|
||||
painter = painterResource(id = R.drawable.back),
|
||||
contentDescription = null
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
when (val currentState = state) {
|
||||
BookState.Loading -> {
|
||||
Box(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
CircularProgressIndicator()
|
||||
}
|
||||
}
|
||||
) { paddingValues ->
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(paddingValues)
|
||||
) {
|
||||
when (val currentState = state) {
|
||||
BookState.Loading -> {
|
||||
CircularProgressIndicator(
|
||||
modifier = Modifier.align(Alignment.Center)
|
||||
|
||||
BookState.Empty -> {
|
||||
Scaffold(
|
||||
topBar = {
|
||||
TopAppBar(
|
||||
title = { Text(stringResource(R.string.book_title)) },
|
||||
navigationIcon = {
|
||||
IconButton(
|
||||
onClick = { viewModel.onIntent(BookIntent.Back) },
|
||||
modifier = Modifier.testTag(TestIds.Book.BACK_BUTTON)
|
||||
) {
|
||||
Icon(
|
||||
painter = painterResource(id = R.drawable.back),
|
||||
contentDescription = null
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
BookState.Empty -> {
|
||||
) { paddingValues ->
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(paddingValues)
|
||||
.padding(16.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.Center
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(R.string.book_empty),
|
||||
modifier = Modifier.testTag(TestIds.Book.EMPTY),
|
||||
textAlign = TextAlign.Center
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
is BookState.Data -> {
|
||||
if (currentState.error != null && currentState.dates.isEmpty()) {
|
||||
Scaffold(
|
||||
topBar = {
|
||||
TopAppBar(
|
||||
title = { Text(stringResource(R.string.book_title)) },
|
||||
navigationIcon = {
|
||||
IconButton(
|
||||
onClick = { viewModel.onIntent(BookIntent.Back) },
|
||||
modifier = Modifier.testTag(TestIds.Book.BACK_BUTTON)
|
||||
) {
|
||||
Icon(
|
||||
painter = painterResource(id = R.drawable.back),
|
||||
contentDescription = null
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
) { paddingValues ->
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(paddingValues)
|
||||
.padding(16.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.Center
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(R.string.book_empty),
|
||||
modifier = Modifier.testTag(TestIds.Book.EMPTY)
|
||||
text = currentState.error,
|
||||
modifier = Modifier.testTag(TestIds.Book.ERROR),
|
||||
color = MaterialTheme.colorScheme.error,
|
||||
textAlign = TextAlign.Center
|
||||
)
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
Button(
|
||||
onClick = { viewModel.onIntent(BookIntent.Back) },
|
||||
modifier = Modifier.testTag(TestIds.Book.BACK_BUTTON)
|
||||
onClick = { viewModel.onIntent(BookIntent.Refresh) },
|
||||
modifier = Modifier.testTag(TestIds.Book.REFRESH_BUTTON)
|
||||
) {
|
||||
Text(stringResource(R.string.book_back))
|
||||
Text(stringResource(R.string.book_refresh))
|
||||
}
|
||||
}
|
||||
}
|
||||
is BookState.Data -> {
|
||||
if (currentState.error != null) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(16.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.Center
|
||||
) {
|
||||
Text(
|
||||
text = currentState.error,
|
||||
modifier = Modifier.testTag(TestIds.Book.ERROR)
|
||||
)
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
Button(
|
||||
onClick = { viewModel.onIntent(BookIntent.Refresh) },
|
||||
modifier = Modifier.testTag(TestIds.Book.REFRESH_BUTTON)
|
||||
) {
|
||||
Text(stringResource(R.string.book_refresh))
|
||||
} else {
|
||||
Scaffold(
|
||||
topBar = {
|
||||
TopAppBar(
|
||||
title = { Text(stringResource(R.string.book_title)) },
|
||||
navigationIcon = {
|
||||
IconButton(
|
||||
onClick = { viewModel.onIntent(BookIntent.Back) },
|
||||
modifier = Modifier.testTag(TestIds.Book.BACK_BUTTON)
|
||||
) {
|
||||
Icon(
|
||||
painter = painterResource(id = R.drawable.back),
|
||||
contentDescription = null
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
)
|
||||
}
|
||||
) { paddingValues ->
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(paddingValues)
|
||||
.padding(16.dp)
|
||||
) {
|
||||
Content(
|
||||
state = currentState,
|
||||
onDateSelect = { viewModel.onIntent(BookIntent.SelectDate(it)) },
|
||||
@@ -140,24 +183,39 @@ private fun Content(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.verticalScroll(rememberScrollState())
|
||||
.padding(16.dp)
|
||||
) {
|
||||
if (state.error != null) {
|
||||
Text(
|
||||
text = state.error,
|
||||
color = MaterialTheme.colorScheme.error,
|
||||
modifier = Modifier
|
||||
.testTag(TestIds.Book.ERROR)
|
||||
.fillMaxWidth()
|
||||
.padding(bottom = 16.dp),
|
||||
textAlign = TextAlign.Center
|
||||
)
|
||||
}
|
||||
|
||||
ScrollableTabRow(
|
||||
selectedTabIndex = state.selectedDateIndex,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
edgePadding = 0.dp
|
||||
) {
|
||||
state.dates.forEachIndexed { index, dateItem ->
|
||||
Tab(
|
||||
selected = state.selectedDateIndex == index,
|
||||
onClick = { onDateSelect(index) },
|
||||
modifier = Modifier.testTag(TestIds.Book.getIdDateItemByPosition(index)),
|
||||
text = {
|
||||
modifier = Modifier.testTag(TestIds.Book.getIdDateItemByPosition(index))
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier.padding(vertical = 8.dp, horizontal = 16.dp)
|
||||
) {
|
||||
Text(
|
||||
text = dateItem.displayDate,
|
||||
modifier = Modifier.testTag(TestIds.Book.ITEM_DATE)
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -173,7 +231,7 @@ private fun Content(
|
||||
selected = state.selectedPlaceIndex == index,
|
||||
onClick = { onPlaceSelect(index) }
|
||||
)
|
||||
.padding(16.dp)
|
||||
.padding(vertical = 8.dp, horizontal = 16.dp)
|
||||
.testTag(TestIds.Book.getIdPlaceItemByPosition(index))
|
||||
) {
|
||||
RadioButton(
|
||||
@@ -184,7 +242,8 @@ private fun Content(
|
||||
Spacer(modifier = Modifier.width(16.dp))
|
||||
Text(
|
||||
text = placeItem.name,
|
||||
modifier = Modifier.testTag(TestIds.Book.ITEM_PLACE_TEXT)
|
||||
modifier = Modifier.testTag(TestIds.Book.ITEM_PLACE_TEXT),
|
||||
style = MaterialTheme.typography.bodyLarge
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user