Skip to content

Show connection status banner when the device is offline#695

Open
gemdev111 wants to merge 18 commits into
mainfrom
feature/network-connection-status
Open

Show connection status banner when the device is offline#695
gemdev111 wants to merge 18 commits into
mainfrom
feature/network-connection-status

Conversation

@gemdev111

@gemdev111 gemdev111 commented Jul 14, 2026

Copy link
Copy Markdown
Collaborator

closes #208

Monitors internet connectivity and shows a dismissible banner when the connection is lost. The banner follows across tabs and screens, hides on recovery, and returns on the next offline event. Detection is debounced so brief drops do not flash it.

What changed

  • ConnectionStatusObserver on both apps: per-component monitors stream health and roll up to one ConnectionStatus (internet today, api/nodes/stream covered by the same rollup)
  • Offline banner with dismiss on iOS and Android, localized in all languages
  • Maestro flow maestro/android/connection_banner.yaml: offline → tabs → details → recovery → re-offline → dismiss

Verification

  • Maestro flow green on the emulator with real airplane-mode cycles
  • iOS dismiss verified with an id-driven flow on the simulator
  • Unit tests green on both platforms; both apps build

images:

iOS light
Wallet home, banner above the tab bar
iOS dark Android light
Banner above the bottom navigation
Android dark
iOS light iOS dark Android light Android dark

Shared vocabulary for the connection status ladder, generated for iOS and Android via typeshare. ConnectionStatus is the user-facing rollup (online, noInternet, noService); ConnectionComponent names the monitored components (internet, api, nodes, stream); ConnectionComponentHealth carries per-component health with typed metadata (internet network conditions, unreachable chains) so monitors report detail without new plumbing.
NWPathMonitor wrapped in a ConnectivityMonitoring stream, consumed by the ConnectivityService actor that debounces offline transitions by 500ms, commits recovery immediately, and fans state out to subscribers through observe(). Includes TestKit mocks and deterministic tests.
A single connectionStatusBanner() modifier on MainTabView renders the banner above the floating tab bar so it covers every tab and pushed screen, with measured scroll content margins so content is never hidden. ConnectionStatusObserver in FeatureServices fans in ConnectionComponentMonitoring health streams and rolls them up into ConnectionStatus by component severity, resetting service health when internet recovers. InternetConnectionMonitor wrapping ConnectivityService is the first monitor and the reference pattern for api, nodes and stream, including typed metadata reporting. The observer stops in background and restarts on foreground through AppLifecycleService, rebuilding the path monitor so a stalled NWPathMonitor cannot leave a stale banner. The banner is dismissible and reappears on the next status change.
Mirror the iOS connection status architecture with Android patterns: ConnectionComponentMonitor exposes a health Flow per component, InternetConnectionMonitor wraps ConnectivityManager with a 500ms offline debounce and network metadata, and ConnectionStatusObserver fans monitors into a ConnectionStatus StateFlow with severity rollup and internet-recovery reset. AppLifecycleCoordinator starts and stops the observer with the app lifecycle, re-reading the current network on every foreground. MainActivity provides a shared ConnectionBannerState through a composition local; the main screen bottom bar and the shared Scene scaffold render the same animated, dismissible strip above the bottom chrome, so every tab and pushed screen shows connection status with one dismissal state.
@gemdev111 gemdev111 self-assigned this Jul 14, 2026
@gemdev111 gemdev111 changed the title Feature/network connection status Show connection status banner when the device is offline Jul 14, 2026
@gemdev111
gemdev111 marked this pull request as ready for review July 14, 2026 22:10
import com.gemwallet.android.ui.theme.space10

private val statusIconSize = 18.dp
private val dismissButtonSize = 28.dp

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you remove hardcoded values, use our standard spacings

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement network connectivity status service

2 participants