From 11097a629a19637e8df3aa5aec40e7e1ad6777f4 Mon Sep 17 00:00:00 2001 From: Moe Hamade <69801237+moehamade@users.noreply.github.com> Date: Wed, 26 Aug 2026 00:28:55 +0300 Subject: [PATCH] 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) Claude-Session: https://claude.ai/code/session_01MdKgoKZbL5K1wsn1WsES26 --- app/src/main/java/com/bitchat/android/MainActivity.kt | 10 +++------- app/src/main/java/com/bitchat/android/ui/ChatState.kt | 6 ++---- .../bitchat/android/ui/ChatStateBackNavigationTest.kt | 11 ++++------- 3 files changed, 9 insertions(+), 18 deletions(-) diff --git a/app/src/main/java/com/bitchat/android/MainActivity.kt b/app/src/main/java/com/bitchat/android/MainActivity.kt index aa336810..3d752291 100644 --- a/app/src/main/java/com/bitchat/android/MainActivity.kt +++ b/app/src/main/java/com/bitchat/android/MainActivity.kt @@ -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) diff --git a/app/src/main/java/com/bitchat/android/ui/ChatState.kt b/app/src/main/java/com/bitchat/android/ui/ChatState.kt index e0790894..16210894 100644 --- a/app/src/main/java/com/bitchat/android/ui/ChatState.kt +++ b/app/src/main/java/com/bitchat/android/ui/ChatState.kt @@ -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 = combine( _showAppInfo, _showPasswordPrompt, diff --git a/app/src/test/kotlin/com/bitchat/android/ui/ChatStateBackNavigationTest.kt b/app/src/test/kotlin/com/bitchat/android/ui/ChatStateBackNavigationTest.kt index b0bacbd8..5c5c41de 100644 --- a/app/src/test/kotlin/com/bitchat/android/ui/ChatStateBackNavigationTest.kt +++ b/app/src/test/kotlin/com/bitchat/android/ui/ChatStateBackNavigationTest.kt @@ -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 { } } }