Android: lifecycle leaks in TabletModeWrapper and the conversation controller, split-ratio clamp, bubble guard, edge-to-edge inset for the Cupertino chat list - #272
Open
byaletheya-sudo wants to merge 1 commit into
Conversation
…d tablet mode in bubbles, clear the nav bar in the Cupertino chat list, cancel the keyboard listener - TabletModeWrapper subscribed to eventDispatcher.stream and registered a debounce Worker in initState with no dispose(), so every rebuild (skin/theme change, entering or leaving the split layout) left another live listener writing splitRatio to prefs. Added dispose() and a mounted guard. - splitRatio is one shared pref; goToSearch drives it to 0.3, below the mobile minRatio, and the debounced worker persisted it, so split-refresh reloaded an out-of-range value. Clamp on the refresh read path (override-split stays unclamped on purpose). - NavigatorService.isTabletMode lacked showAltLayout's !ls.isBubble guard, so in a chat bubble wider than 600dp it returned true while the nested navigators were not built. - With targetSdk 36 (edge-to-edge enforced) the Cupertino chat list's CustomScrollView did not consume the bottom inset, so the last conversation sat under the gesture bar. Added a trailing SliverPadding of MediaQuery padding.bottom. - ConversationViewController cancelled shareSubscription in onClose but never its KeyboardVisibilityController listener, which then touched the disposed scroll controller on every keyboard show/hide for the life of the process. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Five independent, self-contained fixes; happy to split further if preferred.
initStatesubscribes toeventDispatcher.streamand registers a debounceWorker, with nodispose(), so every rebuild (skin or theme change, entering or leaving the split layout) leaves another live listener writingsplitRatioto prefs. Addeddispose()and amountedguard. (Same fix as the wrapper hunk of Fix widget, animation, and controller lifecycle leaks #227, extracted so it can land on its own.)splitRatiois one shared pref;goToSearchdrives it to 0.3, below the mobileminRatio, and the debounced worker persists it, sosplit-refreshreloaded an out-of-range value into every wrapper. Clamp on the refresh read path only;override-splitstays unclamped because search deliberately goes below the minimum and restores afterwards.NavigatorService.isTabletModelackedshowAltLayout's!ls.isBubbleguard, so in a bubble wider than 600 dp it returned true while the nested navigators were not built, andns.push/pushLeft/backConversationViewrouted into navigators that are not in the tree.systemNavigationBarColor. The Material list consumes the bottom inset viaBoxScrollViewand the Samsung list is inside aSafeArea, but the Cupertino list's bareCustomScrollViewdoes neither, so the last conversation sat under the gesture bar. One trailingSliverPaddingofMediaQuery.padding.bottom; nothing restyled.ConversationViewController.onInitlistens toKeyboardVisibilityController().onChange;onClosecancelledshareSubscriptionbut never this one, so every opened chat left a listener that touched the disposed scroll controller on each keyboard show/hide for the life of the process. Stored and cancelled alongside the existing subscription.Verification. Built as a release APK (arm64) from this branch and installed on a Galaxy Z Fold 8; the app runs. Live-chat behavior (divider after search, keyboard responsiveness over many chats, the last row above the gesture bar) could not be exercised in a sideloaded build because registration needs the hosted service; each item is argued from the code above.
flutter analyzereports no new diagnostics againstrustpush.🤖 Generated with Claude Code