style: cut the commentary around the back handler down to what the code cannot say

The block carried seven comment lines over four of code, against 0.17 for
the file as a whole. Most of it restated the identifiers: enabled =
canHandleBack does not need a sentence explaining that Back is intercepted
while there is state to unwind.

What is left is the part that is not derivable. That enabled is a variable
rather than true is a predictive-back decision, and finish() being reachable
at all only makes sense once you know the flag trails the state it mirrors.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MdKgoKZbL5K1wsn1WsES26
This commit is contained in:
Moe Hamade 2026-08-26 00:28:55 +03:00
parent 68361d949f
commit 11097a629a
3 changed files with 9 additions and 18 deletions

View File

@ -313,15 +313,11 @@ class MainActivity : OrientationAwareActivity() {
}
OnboardingState.CHECKING, OnboardingState.INITIALIZING, OnboardingState.COMPLETE -> {
// Intercept Back only while the chat has navigation state to
// unwind. Staying disabled otherwise lets the dispatcher fall
// through to the system, which exits the app.
val canHandleBack by chatViewModel.canHandleBack.collectAsState()
// Disabled rather than always-on so predictive back can preview
// the exit instead of the app claiming every gesture.
BackHandler(enabled = canHandleBack) {
// enabled reaches this handler a dispatch and a recomposition
// after the state changes, so a second press can arrive while
// it is still true but there is no longer anything to unwind.
// Forward that press instead of swallowing it.
// enabled trails the state by a dispatch and a recomposition.
if (!chatViewModel.handleBackPressed()) finish()
}
ChatScreen(viewModel = chatViewModel)

View File

@ -170,10 +170,8 @@ class ChatState(
initialValue = false
)
// True while some in-app navigation state is open for Back to unwind.
// Mirrors the branches of ChatViewModel.handleBackPressed: the back
// handler is enabled from this, the press is consumed by that, and the
// two drifting apart is what makes Back feel broken.
// Mirrors the branches of ChatViewModel.handleBackPressed. The back handler
// is enabled from this and the press consumed by that, so they must agree.
val canHandleBack: StateFlow<Boolean> = combine(
_showAppInfo,
_showPasswordPrompt,

View File

@ -12,10 +12,9 @@ import org.junit.Before
import org.junit.Test
/**
* `canHandleBack` tells the chat screen's back handler whether there is any
* in-app navigation state left to unwind. It has to agree with the branches of
* [ChatViewModel.handleBackPressed], because the handler is enabled from one
* and the press is consumed by the other.
* `canHandleBack` must agree with the branches of
* [ChatViewModel.handleBackPressed]: the back handler is enabled from one and
* the press consumed by the other.
*/
@OptIn(ExperimentalCoroutinesApi::class)
class ChatStateBackNavigationTest {
@ -28,9 +27,7 @@ class ChatStateBackNavigationTest {
fun setUp() {
scope = TestScope(UnconfinedTestDispatcher())
state = ChatState(scope)
// canHandleBack is shared WhileSubscribed, so it only tracks its
// sources while something collects it. The composable does that in
// production; the test has to do it explicitly.
// Shared WhileSubscribed, so it only tracks its sources while collected.
subscription = scope.launch { state.canHandleBack.collect { } }
}