feat(android): global quick-toggle to hide all on-video Home Assistant overlays - #488
Merged
Conversation
One tap hides every Home Assistant badge on live video, on every camera; tap again brings them back. The choice persists across app restarts. The switch is offered in two places, and they are the same switch: an eye button on the Live wall's action row (beside the grid/fullscreen icons) and a matching one in the fullscreen view's top-right controls, next to audio/PTZ. Because the Live wall stays on the nav back stack while the user is inside a camera, a per-screen `remember` seeded from the store would keep serving the pre-toggle value and the wall's icon would lie, so the state lives in a process-scoped HaOverlayVisibility holder in AppContainer, seeded from and written back to SecureStore (`show_ha_overlays`, default true = shown). Both screens observe its StateFlow, so a flip from either recomposes both immediately. Display-only by design: entity linking, badge placement, the per-camera entities sheet, and the detail/control popups reachable from it are all untouched — inspecting entities has to keep working precisely when an operator has decided the video should stay clean. The badge tap and long-press targets simply cease to exist along with the badges they sit on. While the overlays are hidden and no HA sheet or dialog is open, the `/ha/states` poll also stands down: there is nothing on screen left to keep converged. The fullscreen button appears only for cameras that actually have placed badges; the wall's button is the global one. Signed-off-by: badbread <badbread@users.noreply.github.com>
…the sole affordance Owner call during testing: Android wall tiles never render HA badges (badges are fullscreen-only until #444's mobile badge work), so an eye button on the wall action row toggled something invisible from where it sat. Remove it; the in-fullscreen toggle (next to the HA sheet button) is the single affordance, and the persisted state/store plumbing is unchanged. Signed-off-by: badbread <badbread@users.noreply.github.com>
…s runs Signed-off-by: badbread <badbread@users.noreply.github.com>
Signed-off-by: badbread <badbread@users.noreply.github.com> # Conflicts: # docs/COMPONENT-MAP.md
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.
What
One tap hides every Home Assistant badge on live video, on every camera; tap again brings them back. The choice persists across app restarts.
The toggle is offered in two places, and they are the same switch:
Both use
HintTooltiplike their neighbours: "Hide Home Assistant overlays" / "Show Home Assistant overlays", withIcons.Default.Visibility/VisibilityOff.How
State lives in a process-scoped
HaOverlayVisibilityholder inAppContainer, seeded from and written back toSecureStore.showHaOverlays(keyshow_ha_overlays, defaulttrue= overlays shown, so nothing changes for an existing install). Both screens observe itsStateFlow, so a flip from either surface recomposes both immediately — no restart, no re-entry.The holder exists rather than a per-screen
rememberbecause the Live wall stays on the nav back stack while the user is inside a camera: a local mirror seeded from the store would keep serving the pre-toggle value after the fullscreen button flipped it, and the wall's icon would lie.Scope: display only
Entity linking, badge placement, the per-camera entities sheet, and the detail/control popups reachable from it are untouched. Inspecting entities has to keep working precisely when an operator has decided the video should stay clean, so the HA sheet button is deliberately not gated on the toggle. The badge tap / long-press targets simply cease to exist along with the badges they sit on.
One perf nicety: while the overlays are hidden and no HA sheet or dialog is open, the
/ha/statespoll stands down — there is nothing on screen left to keep converged. Any open sheet/dialog still holds the poll up exactly as before.Files
apps/android/.../data/SecureStore.kt—showHaOverlays(mirrors theshowHaEntityId/showHaDeviceTypepattern; device-level, not cleared on logout)apps/android/.../feature/live/HaOverlayVisibility.kt— new; the shared holder +rememberHaOverlaysVisible()apps/android/.../di/AppContainer.kt— wires the holder to the storeapps/android/.../feature/live/LiveScreen.kt— the wall's eye buttonapps/android/.../feature/live/LiveFullscreenScreen.kt— the fullscreen eye button, the overlay-layer gate, the poll gateapps/android/.../test/.../HaOverlayVisibilityTest.kt— new; seeding does not write, toggle flips + persists, redundantsetis a no-opdocs/COMPONENT-MAP.md— HA-overlay row, Android cell (desktop/iOS equivalents marked deferred)Gate
dev2, JDK 17 +
/opt/android-sdk::app:testDebugUnitTest :app:assembleDebug— BUILD SUCCESSFUL,HaOverlayVisibilityTest3/3 passing, no new warnings.