RNDAMP-8921: use new bottom bar

This commit is contained in:
2026-08-30 13:55:35 +03:00
parent ed11b3c967
commit 63116b4a08
3 changed files with 66 additions and 71 deletions
@@ -5,7 +5,6 @@ import androiddev.feature.updater.updater_client.generated.resources.updater_btn
import androiddev.feature.updater.updater_client.generated.resources.updater_btn_download
import androiddev.feature.updater.updater_client.generated.resources.updater_btn_grant
import androiddev.feature.updater.updater_client.generated.resources.updater_btn_install
import androiddev.feature.updater.updater_client.generated.resources.updater_btn_retry
import androiddev.feature.updater.updater_client.generated.resources.updater_changelog_empty
import androiddev.feature.updater.updater_client.generated.resources.updater_changelog_title
import androiddev.feature.updater.updater_client.generated.resources.updater_desc_permission
@@ -13,7 +12,6 @@ import androiddev.feature.updater.updater_client.generated.resources.updater_dow
import androiddev.feature.updater.updater_client.generated.resources.updater_title_available
import androiddev.feature.updater.updater_client.generated.resources.updater_title_completed
import androiddev.feature.updater.updater_client.generated.resources.updater_title_downloading
import androiddev.feature.updater.updater_client.generated.resources.updater_title_error
import androiddev.feature.updater.updater_client.generated.resources.updater_title_not_found
import androiddev.feature.updater.updater_client.generated.resources.updater_title_permission
import androiddev.feature.updater.updater_client.generated.resources.updater_title_ready
@@ -43,16 +41,14 @@ import com.arkivanov.decompose.extensions.compose.subscribeAsState
import org.jetbrains.compose.resources.StringResource
import org.jetbrains.compose.resources.stringResource
import ru.shadowsparky.ui.components.AlertContent
import ru.shadowsparky.ui.components.ErrorContent
import ru.shadowsparky.ui.components.LazyColumn
import ru.shadowsparky.ui.components.Loading
import ru.shadowsparky.updater.domain.UpdateState
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun UpdateDialog(
component: UpdateComponent,
modifier: Modifier = Modifier
) {
fun UpdateDialog(component: UpdateComponent, modifier: Modifier = Modifier) {
val state by component.state.subscribeAsState()
val canDismiss = remember(state) { !component.isForceUpdate }
val isVisible = remember(state) { state !is UpdateState.Idle }
@@ -90,8 +86,7 @@ fun UpdateDialog(
is UpdateState.Error -> UpdateErrorContent(
message = currentState.message,
onRetryClick = { component.checkUpdates() },
focusRequester = focusRequester
onRetryClick = { component.checkUpdates() }
)
is UpdateState.UpToDate -> {
@@ -158,6 +153,9 @@ private fun UpdateAvailableContent(
style = MaterialTheme.typography.bodyMedium
)
}
item {
Spacer(modifier = Modifier.height(8.dp))
}
item {
Button(
onClick = onDownloadClick,
@@ -290,76 +288,51 @@ private fun UpdateFinishedContent(
private fun UpdateErrorContent(
message: String,
onRetryClick: () -> Unit,
focusRequester: FocusRequester,
modifier: Modifier = Modifier
) {
Column(
modifier = modifier.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(16.dp)
) {
Text(
text = stringResource(Res.string.updater_title_error),
style = MaterialTheme.typography.titleLarge,
color = MaterialTheme.colorScheme.error
)
Text(text = message, style = MaterialTheme.typography.bodyMedium)
Button(
onClick = onRetryClick,
modifier = Modifier.focusRequester(focusRequester).fillMaxWidth()
) {
Text(
stringResource(Res.string.updater_btn_retry),
style = MaterialTheme.typography.labelLarge
)
}
}
ErrorContent(
message,
modifier,
onClick = onRetryClick,
buttonModifier = Modifier.fillMaxWidth()
)
}
@Preview
@Composable
private fun UpdateAvailablePreview() {
MaterialTheme {
UpdateAvailableContent(
versionName = "v1.4.0",
changeLog = "- Добавили темную тему\n- Исправили падение на главном экране\n- Повысили стабильность",
onDownloadClick = {},
focusRequester = FocusRequester()
)
}
UpdateAvailableContent(
versionName = "v1.4.0",
changeLog = "- Добавили темную тему\n- Исправили падение на главном экране\n- Повысили стабильность",
onDownloadClick = {},
focusRequester = FocusRequester()
)
}
@Preview
@Composable
private fun UpdateDownloadingPreview() {
MaterialTheme {
UpdateDownloadingContent(
progress = 0.45f,
downloadedBytes = 24_117_248L, // ~23 MB
totalBytes = 52_428_800L // 50 MB
)
}
UpdateDownloadingContent(
progress = 0.45f,
downloadedBytes = 24_117_248L, // ~23 MB
totalBytes = 52_428_800L // 50 MB
)
}
@Preview
@Composable
private fun UpdatePermissionPreview() {
MaterialTheme {
UpdatePermissionContent(
onGrantClick = {},
focusRequester = FocusRequester()
)
}
UpdatePermissionContent(
onGrantClick = {},
focusRequester = FocusRequester()
)
}
@Preview
@Composable
private fun UpdateErrorPreview() {
MaterialTheme {
UpdateErrorContent(
message = "Http status 503: Service Unavailable",
onRetryClick = {},
focusRequester = FocusRequester()
)
}
UpdateErrorContent(
message = "Http status 503: Service Unavailable",
onRetryClick = {}
)
}
@@ -3,23 +3,26 @@ package ru.shadowsparky.ui
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.navigationBars
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.windowInsetsPadding
import androidx.compose.foundation.layout.wrapContentWidth
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.IconButtonDefaults
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.NavigationBar
import androidx.compose.material3.NavigationBarDefaults
import androidx.compose.material3.NavigationBarItem
import androidx.compose.material3.Scaffold
import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.TopAppBarScrollBehavior
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Brush
@@ -62,26 +65,41 @@ private fun <T : Route> BottomBar(
) {
navigationEntries?.let { entries ->
Box(
modifier = Modifier
.fillMaxWidth()
modifier = Modifier.fillMaxWidth()
.background(
Brush.verticalGradient(
listOf(Color.Transparent, MaterialTheme.colorScheme.surfaceContainer)
)
)
.padding(8.dp)
.windowInsetsPadding(WindowInsets.navigationBars)
.windowInsetsPadding(WindowInsets.navigationBars),
contentAlignment = Alignment.Center
) {
NavigationBar(
containerColor = navBarContentColor(),
modifier = Modifier.clip(RoundedCornerShape(24.dp)).blurEffect()
Row(
modifier = Modifier.clip(RoundedCornerShape(24.dp))
.wrapContentWidth()
.background(navBarContentColor())
.blurEffect()
.padding(8.dp)
) {
entries.forEach { entry ->
NavigationBarItem(
selected = currentRoute == entry.route,
val containerColor = if (currentRoute == entry.route) {
MaterialTheme.colorScheme.secondaryContainer
} else {
Color.Unspecified
}
val contentColor = if (currentRoute == entry.route) {
MaterialTheme.colorScheme.onSecondaryContainer
} else {
Color.Unspecified
}
IconButton(
onClick = { onSelectNavigation?.invoke(entry.route) },
icon = { Icon(entry.painter, contentDescription = entry.title) }
)
modifier = Modifier.padding(4.dp),
colors = IconButtonDefaults.iconButtonColors(containerColor, contentColor)
) {
Icon(entry.painter, contentDescription = entry.title)
}
}
}
}
@@ -14,8 +14,11 @@ import androidx.compose.material3.Button
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
@@ -29,6 +32,7 @@ fun ErrorContent(
retry: Boolean = true,
onClick: () -> Unit
) {
val requester = remember { FocusRequester() }
val buttonTextRes = if (retry) Res.string.retry else Res.string.ok
Column(
verticalArrangement = Arrangement.Center,
@@ -47,7 +51,7 @@ fun ErrorContent(
textAlign = TextAlign.Center
)
Spacer(Modifier.height(8.dp))
Button(modifier = buttonModifier, onClick = { onClick() }) {
Button(modifier = buttonModifier.focusRequester(requester), onClick = { onClick() }) {
Text(
text = stringResource(buttonTextRes),
style = MaterialTheme.typography.bodyMedium