diff --git a/main-core/src/commonMain/kotlin/ru/bartwell/kick/core/presentation/AppUiEnvironment.kt b/main-core/src/commonMain/kotlin/ru/bartwell/kick/core/presentation/AppUiEnvironment.kt index cd42c9a0..fab0733a 100644 --- a/main-core/src/commonMain/kotlin/ru/bartwell/kick/core/presentation/AppUiEnvironment.kt +++ b/main-core/src/commonMain/kotlin/ru/bartwell/kick/core/presentation/AppUiEnvironment.kt @@ -9,4 +9,5 @@ public val LocalAppUiEnvironment: ProvidableCompositionLocal = public class AppUiEnvironment( public val screenCloser: () -> Unit, + public val canNavigateBack: Boolean, ) diff --git a/main-core/src/commonMain/kotlin/ru/bartwell/kick/core/presentation/BackOrCloseButton.kt b/main-core/src/commonMain/kotlin/ru/bartwell/kick/core/presentation/BackOrCloseButton.kt new file mode 100644 index 00000000..2c9d3f6e --- /dev/null +++ b/main-core/src/commonMain/kotlin/ru/bartwell/kick/core/presentation/BackOrCloseButton.kt @@ -0,0 +1,23 @@ +package ru.bartwell.kick.core.presentation + +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.automirrored.outlined.ArrowBack +import androidx.compose.material.icons.outlined.Close +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.runtime.Composable + +@Composable +public fun BackOrCloseButton( + onBack: () -> Unit, +) { + val uiEnvironment = LocalAppUiEnvironment.current + val canGoBack = uiEnvironment.canNavigateBack + val action = if (canGoBack) onBack else uiEnvironment.screenCloser + val icon = if (canGoBack) Icons.AutoMirrored.Outlined.ArrowBack else Icons.Outlined.Close + val description = if (canGoBack) "Back" else "Close" + + IconButton(onClick = action) { + Icon(imageVector = icon, contentDescription = description) + } +} diff --git a/main-runtime/src/commonMain/kotlin/ru/bartwell/kick/runtime/core/component/RootContent.kt b/main-runtime/src/commonMain/kotlin/ru/bartwell/kick/runtime/core/component/RootContent.kt index b631461f..88da8616 100644 --- a/main-runtime/src/commonMain/kotlin/ru/bartwell/kick/runtime/core/component/RootContent.kt +++ b/main-runtime/src/commonMain/kotlin/ru/bartwell/kick/runtime/core/component/RootContent.kt @@ -3,10 +3,12 @@ package ru.bartwell.kick.runtime.core.component import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider +import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier import com.arkivanov.decompose.extensions.compose.stack.Children import com.arkivanov.decompose.extensions.compose.stack.animation.slide import com.arkivanov.decompose.extensions.compose.stack.animation.stackAnimation +import com.arkivanov.decompose.extensions.compose.subscribeAsState import ru.bartwell.kick.core.component.RootComponent import ru.bartwell.kick.core.presentation.AppUiEnvironment import ru.bartwell.kick.core.presentation.LocalAppUiEnvironment @@ -21,7 +23,11 @@ internal fun RootContent( component: RootComponent, modifier: Modifier = Modifier, ) { - val environment = AppUiEnvironment(screenCloser = screenCloser()) + val stack by component.stack.subscribeAsState() + val environment = AppUiEnvironment( + screenCloser = screenCloser(), + canNavigateBack = stack.backStack.isNotEmpty(), + ) CompositionLocalProvider(LocalAppUiEnvironment provides environment) { Children( stack = component.stack, diff --git a/module/files/file-explorer/src/commonMain/kotlin/ru/bartwell/kick/module/explorer/feature/list/presentation/FileExplorerContent.kt b/module/files/file-explorer/src/commonMain/kotlin/ru/bartwell/kick/module/explorer/feature/list/presentation/FileExplorerContent.kt index 2f4aa11c..06961a17 100644 --- a/module/files/file-explorer/src/commonMain/kotlin/ru/bartwell/kick/module/explorer/feature/list/presentation/FileExplorerContent.kt +++ b/module/files/file-explorer/src/commonMain/kotlin/ru/bartwell/kick/module/explorer/feature/list/presentation/FileExplorerContent.kt @@ -15,7 +15,6 @@ import androidx.compose.foundation.lazy.LazyRow import androidx.compose.foundation.lazy.items import androidx.compose.foundation.rememberScrollState import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.outlined.ArrowBack import androidx.compose.material.icons.filled.ArrowUpward import androidx.compose.material.icons.filled.Description import androidx.compose.material.icons.filled.Folder @@ -23,7 +22,6 @@ import androidx.compose.material3.AlertDialog import androidx.compose.material3.AssistChip import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon -import androidx.compose.material3.IconButton import androidx.compose.material3.ListItem import androidx.compose.material3.ModalBottomSheet import androidx.compose.material3.Surface @@ -43,6 +41,7 @@ import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import com.arkivanov.decompose.extensions.compose.subscribeAsState import ru.bartwell.kick.core.data.platformContext +import ru.bartwell.kick.core.presentation.BackOrCloseButton import ru.bartwell.kick.core.presentation.ErrorAlert import ru.bartwell.kick.module.explorer.feature.list.util.FileSystemUtils import ru.bartwell.kick.module.explorer.feature.list.util.KnownFolder @@ -70,9 +69,7 @@ internal fun FileExplorerContent( Text(text = state.folderName, maxLines = 1) }, navigationIcon = { - IconButton(onClick = { component.onBackClick() }) { - Icon(imageVector = Icons.AutoMirrored.Outlined.ArrowBack, contentDescription = "Back") - } + BackOrCloseButton(onBack = component::onBackClick) } ) KnownFoldersRow(component = component) diff --git a/module/firebase/firebase-cloud-messaging/src/commonMain/kotlin/ru/bartwell/kick/module/firebase/cloudmessaging/feature/main/presentation/FirebaseCloudMessagingContent.kt b/module/firebase/firebase-cloud-messaging/src/commonMain/kotlin/ru/bartwell/kick/module/firebase/cloudmessaging/feature/main/presentation/FirebaseCloudMessagingContent.kt index d79431cb..4d5fa774 100644 --- a/module/firebase/firebase-cloud-messaging/src/commonMain/kotlin/ru/bartwell/kick/module/firebase/cloudmessaging/feature/main/presentation/FirebaseCloudMessagingContent.kt +++ b/module/firebase/firebase-cloud-messaging/src/commonMain/kotlin/ru/bartwell/kick/module/firebase/cloudmessaging/feature/main/presentation/FirebaseCloudMessagingContent.kt @@ -10,7 +10,6 @@ import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.foundation.text.selection.SelectionContainer import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.outlined.ArrowBack import androidx.compose.material.icons.filled.MoreVert import androidx.compose.material.icons.outlined.ContentCopy import androidx.compose.material.icons.outlined.History @@ -38,6 +37,7 @@ import androidx.compose.ui.platform.testTag import androidx.compose.ui.unit.dp import com.arkivanov.decompose.extensions.compose.subscribeAsState import ru.bartwell.kick.core.data.platformContext +import ru.bartwell.kick.core.presentation.BackOrCloseButton @OptIn(ExperimentalMaterial3Api::class) @Composable @@ -63,9 +63,7 @@ internal fun FirebaseCloudMessagingContent( TopAppBar( title = { Text("Firebase Cloud Messaging") }, navigationIcon = { - IconButton(onClick = component::onBackPressed, modifier = Modifier.testTag("back")) { - Icon(imageVector = Icons.AutoMirrored.Outlined.ArrowBack, contentDescription = "Back") - } + BackOrCloseButton(onBack = component::onBackPressed) }, actions = { IconButton(onClick = { isMenuExpanded = true }, modifier = Modifier.testTag("menu_button")) { diff --git a/module/logging/logging/src/commonMain/kotlin/ru/bartwell/kick/module/logging/feature/table/presentation/LogViewerContent.kt b/module/logging/logging/src/commonMain/kotlin/ru/bartwell/kick/module/logging/feature/table/presentation/LogViewerContent.kt index 9460b846..bfca4756 100644 --- a/module/logging/logging/src/commonMain/kotlin/ru/bartwell/kick/module/logging/feature/table/presentation/LogViewerContent.kt +++ b/module/logging/logging/src/commonMain/kotlin/ru/bartwell/kick/module/logging/feature/table/presentation/LogViewerContent.kt @@ -8,7 +8,6 @@ import androidx.compose.foundation.lazy.LazyRow import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.outlined.ArrowBack import androidx.compose.material.icons.filled.ClearAll import androidx.compose.material.icons.filled.ContentCopy import androidx.compose.material.icons.filled.FilterList @@ -33,6 +32,7 @@ import androidx.compose.ui.unit.dp import com.arkivanov.decompose.extensions.compose.subscribeAsState import ru.bartwell.kick.core.data.Platform import ru.bartwell.kick.core.data.platformContext +import ru.bartwell.kick.core.presentation.BackOrCloseButton import ru.bartwell.kick.core.presentation.ErrorBox import ru.bartwell.kick.core.util.PlatformUtils import ru.bartwell.kick.module.logging.core.data.LogLevel @@ -52,9 +52,7 @@ internal fun LogViewerContent( TopAppBar( title = { Text("Logging") }, navigationIcon = { - IconButton(onClick = component::onBackPressed) { - Icon(imageVector = Icons.AutoMirrored.Outlined.ArrowBack, contentDescription = "Back") - } + BackOrCloseButton(onBack = component::onBackPressed) }, actions = { IconButton(onClick = component::onFilterClick, modifier = Modifier.testTag("filter_toggle")) { diff --git a/module/logging/overlay/src/commonMain/kotlin/ru/bartwell/kick/module/overlay/feature/settings/presentation/OverlayContent.kt b/module/logging/overlay/src/commonMain/kotlin/ru/bartwell/kick/module/overlay/feature/settings/presentation/OverlayContent.kt index d95c44c2..ebca7c62 100644 --- a/module/logging/overlay/src/commonMain/kotlin/ru/bartwell/kick/module/overlay/feature/settings/presentation/OverlayContent.kt +++ b/module/logging/overlay/src/commonMain/kotlin/ru/bartwell/kick/module/overlay/feature/settings/presentation/OverlayContent.kt @@ -7,14 +7,10 @@ import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.outlined.ArrowBack import androidx.compose.material3.DropdownMenu import androidx.compose.material3.DropdownMenuItem import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ExposedDropdownMenuDefaults -import androidx.compose.material3.Icon -import androidx.compose.material3.IconButton import androidx.compose.material3.ListItem import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedTextField @@ -33,6 +29,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import com.arkivanov.decompose.extensions.compose.subscribeAsState import ru.bartwell.kick.core.data.platformContext +import ru.bartwell.kick.core.presentation.BackOrCloseButton import ru.bartwell.kick.core.ui.ExposedDropdownMenuBox import ru.bartwell.kick.module.overlay.core.store.OverlayStore @@ -61,12 +58,7 @@ internal fun OverlayContent( TopAppBar( title = { Text("Overlay") }, navigationIcon = { - IconButton(onClick = { component.onBackClick() }) { - Icon( - imageVector = Icons.AutoMirrored.Outlined.ArrowBack, - contentDescription = "Back" - ) - } + BackOrCloseButton(onBack = component::onBackClick) } ) } diff --git a/module/network/ktor3/src/commonMain/kotlin/ru/bartwell/kick/module/ktor3/feature/list/presentation/RequestsListContent.kt b/module/network/ktor3/src/commonMain/kotlin/ru/bartwell/kick/module/ktor3/feature/list/presentation/RequestsListContent.kt index ec6364af..6133cfa9 100644 --- a/module/network/ktor3/src/commonMain/kotlin/ru/bartwell/kick/module/ktor3/feature/list/presentation/RequestsListContent.kt +++ b/module/network/ktor3/src/commonMain/kotlin/ru/bartwell/kick/module/ktor3/feature/list/presentation/RequestsListContent.kt @@ -15,7 +15,6 @@ import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.outlined.ArrowBack import androidx.compose.material.icons.filled.ClearAll import androidx.compose.material.icons.filled.Lock import androidx.compose.material.icons.filled.LockOpen @@ -40,6 +39,7 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.testTag import androidx.compose.ui.unit.dp import com.arkivanov.decompose.extensions.compose.subscribeAsState +import ru.bartwell.kick.core.presentation.BackOrCloseButton import ru.bartwell.kick.core.presentation.ErrorBox import ru.bartwell.kick.module.ktor3.core.persist.RequestEntity import ru.bartwell.kick.module.ktor3.feature.detail.extension.formatDuration @@ -60,9 +60,7 @@ internal fun RequestsListContent( TopAppBar( title = { Text("Network Requests") }, navigationIcon = { - IconButton(onClick = component::onBackPressed) { - Icon(imageVector = Icons.AutoMirrored.Outlined.ArrowBack, contentDescription = "Back") - } + BackOrCloseButton(onBack = component::onBackPressed) }, actions = { IconButton(onClick = component::onSearchClick, modifier = Modifier.testTag("search_toggle")) { diff --git a/module/settings/control-panel/src/commonMain/kotlin/ru/bartwell/kick/module/controlpanel/feature/main/presentation/ControlPanelContent.kt b/module/settings/control-panel/src/commonMain/kotlin/ru/bartwell/kick/module/controlpanel/feature/main/presentation/ControlPanelContent.kt index 92518e64..85c535d0 100644 --- a/module/settings/control-panel/src/commonMain/kotlin/ru/bartwell/kick/module/controlpanel/feature/main/presentation/ControlPanelContent.kt +++ b/module/settings/control-panel/src/commonMain/kotlin/ru/bartwell/kick/module/controlpanel/feature/main/presentation/ControlPanelContent.kt @@ -14,7 +14,6 @@ import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.outlined.ArrowBack import androidx.compose.material.icons.filled.ExpandLess import androidx.compose.material.icons.filled.ExpandMore import androidx.compose.material.icons.filled.Save @@ -42,6 +41,7 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import com.arkivanov.decompose.extensions.compose.subscribeAsState +import ru.bartwell.kick.core.presentation.BackOrCloseButton import ru.bartwell.kick.core.ui.ExposedDropdownMenuBox import ru.bartwell.kick.module.controlpanel.data.ActionType import ru.bartwell.kick.module.controlpanel.data.ControlPanelItem @@ -60,9 +60,7 @@ internal fun ControlPanelContent( TopAppBar( title = { Text("Control Panel") }, navigationIcon = { - IconButton(onClick = component::onBackPressed, modifier = Modifier.testTag("back")) { - Icon(imageVector = Icons.AutoMirrored.Outlined.ArrowBack, contentDescription = "Back") - } + BackOrCloseButton(onBack = component::onBackPressed) }, actions = { IconButton(onClick = component::onSavePressed, modifier = Modifier.testTag("save")) { diff --git a/module/settings/multiplatform-settings/src/commonMain/kotlin/ru/bartwell/kick/module/multiplatformsettings/feature/list/presentation/SettingsListContent.kt b/module/settings/multiplatform-settings/src/commonMain/kotlin/ru/bartwell/kick/module/multiplatformsettings/feature/list/presentation/SettingsListContent.kt index eb5c2acb..e2c2f2d9 100644 --- a/module/settings/multiplatform-settings/src/commonMain/kotlin/ru/bartwell/kick/module/multiplatformsettings/feature/list/presentation/SettingsListContent.kt +++ b/module/settings/multiplatform-settings/src/commonMain/kotlin/ru/bartwell/kick/module/multiplatformsettings/feature/list/presentation/SettingsListContent.kt @@ -8,11 +8,7 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.rememberLazyListState -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.outlined.ArrowBack import androidx.compose.material3.ExperimentalMaterial3Api -import androidx.compose.material3.Icon -import androidx.compose.material3.IconButton import androidx.compose.material3.ListItem import androidx.compose.material3.Text import androidx.compose.material3.TopAppBar @@ -23,6 +19,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.platform.testTag import androidx.compose.ui.unit.dp import com.arkivanov.decompose.extensions.compose.subscribeAsState +import ru.bartwell.kick.core.presentation.BackOrCloseButton @OptIn(ExperimentalMaterial3Api::class) @Composable @@ -36,9 +33,7 @@ public fun SettingsListContent( TopAppBar( title = { Text("Storages") }, navigationIcon = { - IconButton(onClick = component::onBackPressed, modifier = Modifier.testTag("back")) { - Icon(imageVector = Icons.AutoMirrored.Outlined.ArrowBack, contentDescription = "Back") - } + BackOrCloseButton(onBack = component::onBackPressed) }, ) diff --git a/module/sqlite/sqlite-runtime/src/commonMain/kotlin/ru/bartwell/kick/module/sqlite/runtime/feature/table/presentation/TablesListContent.kt b/module/sqlite/sqlite-runtime/src/commonMain/kotlin/ru/bartwell/kick/module/sqlite/runtime/feature/table/presentation/TablesListContent.kt index 9646b9ba..bd600aba 100644 --- a/module/sqlite/sqlite-runtime/src/commonMain/kotlin/ru/bartwell/kick/module/sqlite/runtime/feature/table/presentation/TablesListContent.kt +++ b/module/sqlite/sqlite-runtime/src/commonMain/kotlin/ru/bartwell/kick/module/sqlite/runtime/feature/table/presentation/TablesListContent.kt @@ -10,7 +10,6 @@ import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.outlined.ArrowBack import androidx.compose.material.icons.filled.EditNote import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon @@ -22,6 +21,7 @@ import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import com.arkivanov.decompose.extensions.compose.subscribeAsState +import ru.bartwell.kick.core.presentation.BackOrCloseButton import ru.bartwell.kick.core.presentation.ErrorBox @OptIn(ExperimentalMaterial3Api::class) @@ -36,9 +36,7 @@ internal fun TablesListContent( TopAppBar( title = { Text("Tables") }, navigationIcon = { - IconButton(onClick = component::onBackPressed) { - Icon(imageVector = Icons.AutoMirrored.Outlined.ArrowBack, contentDescription = "Back") - } + BackOrCloseButton(onBack = component::onBackPressed) }, actions = { IconButton(onClick = component::onQueryClick) { diff --git a/module/ui/layout/src/commonMain/kotlin/ru/bartwell/kick/module/layout/feature/settings/presentation/LayoutContent.kt b/module/ui/layout/src/commonMain/kotlin/ru/bartwell/kick/module/layout/feature/settings/presentation/LayoutContent.kt index 78562824..1575b4bd 100644 --- a/module/ui/layout/src/commonMain/kotlin/ru/bartwell/kick/module/layout/feature/settings/presentation/LayoutContent.kt +++ b/module/ui/layout/src/commonMain/kotlin/ru/bartwell/kick/module/layout/feature/settings/presentation/LayoutContent.kt @@ -2,11 +2,7 @@ package ru.bartwell.kick.module.layout.feature.settings.presentation import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.padding -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.outlined.ArrowBack import androidx.compose.material3.ExperimentalMaterial3Api -import androidx.compose.material3.Icon -import androidx.compose.material3.IconButton import androidx.compose.material3.ListItem import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Scaffold @@ -23,6 +19,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import com.arkivanov.decompose.extensions.compose.subscribeAsState import ru.bartwell.kick.core.data.platformContext +import ru.bartwell.kick.core.presentation.BackOrCloseButton @OptIn(ExperimentalMaterial3Api::class) @Composable @@ -46,12 +43,7 @@ internal fun LayoutContent( TopAppBar( title = { Text("Layout") }, navigationIcon = { - IconButton(onClick = { component.onBackClick() }) { - Icon( - imageVector = Icons.AutoMirrored.Outlined.ArrowBack, - contentDescription = "Back" - ) - } + BackOrCloseButton(onBack = component::onBackClick) } ) }