diff --git a/app/src/main/java/de/softwareapp_hb/filemanager/ui/browser/BrowserScreen.kt b/app/src/main/java/de/softwareapp_hb/filemanager/ui/browser/BrowserScreen.kt index c169c2e..78261d7 100644 --- a/app/src/main/java/de/softwareapp_hb/filemanager/ui/browser/BrowserScreen.kt +++ b/app/src/main/java/de/softwareapp_hb/filemanager/ui/browser/BrowserScreen.kt @@ -1,6 +1,7 @@ package de.softwareapp_hb.filemanager.ui.browser import android.content.Intent +import androidx.activity.compose.BackHandler import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.result.contract.ActivityResultContracts import androidx.compose.foundation.layout.Box @@ -133,6 +134,35 @@ fun BrowserScreen( state.pendingDeleteRequest?.let { deleteLauncher.launch(it) } } + // Back, in the order a person expects it: close what is on top, then go up a folder, + // and only then leave the app. `enabled` is false on the roots screen with nothing + // open, which lets the system finish the activity as usual. + // + // This has to sit *above* the overlay branch below: that branch returns early, so + // anything after it is never composed while a viewer or the editor is open — which is + // exactly when Back most needs an answer. + val closesOverlay = state.overlay != Overlay.None + val answersIncoming = state.receiving != null || state.providing || state.pendingDeliver != null + val canGoBack = closesOverlay || answersIncoming || searchOpen || + state.query.isNotEmpty() || state.isSelecting || !state.isRootView + + BackHandler(enabled = canGoBack) { + when { + closesOverlay -> viewModel.closeOverlay() + + answersIncoming -> viewModel.cancelIncoming() + + searchOpen || state.query.isNotEmpty() -> { + searchOpen = false + viewModel.setQuery("") + } + + state.isSelecting -> viewModel.clearSelection() + + else -> viewModel.navigateUp() + } + } + // A viewer, editor or the usage view takes over the whole screen. when (val overlay = state.overlay) { is Overlay.Image -> {