Skip to content

Issue 41: fix long-runtime performance slowdown#47

Open
MrSurly wants to merge 35 commits into
tmacinc:mainfrom
MrSurly:issue-41-long-runtime-slowdown
Open

Issue 41: fix long-runtime performance slowdown#47
MrSurly wants to merge 35 commits into
tmacinc:mainfrom
MrSurly:issue-41-long-runtime-slowdown

Conversation

@MrSurly

@MrSurly MrSurly commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Summary

Addresses sources of performance degradation during extended app sessions,
and fixes a message-list flicker on send.

  • Remove two StackTrace.current calls from BLE manager hot paths (connect
    timeout, disconnect) -- these capture and serialize the full call stack on
    every invocation.

  • Replace watchAllMessages() triggers in channels and contacts DAOs with
    watchMessageCount(), a count-only query that avoids deserializing all
    message rows across the isolate boundary on every table change.

  • Replace getAllContacts() live stream subscriptions in both chat screens
    with a companion-filtered contact count watch. The list reloads only when
    a contact is added, avoiding per-telemetry-packet setState rebuilds while
    still picking up new contacts discovered mid-session.

  • Add getContactCount/getContactCountByCompanion to ContactsDao. Use them
    in message_repository where full contact rows were fetched only to compare
    .length before and after a sync.

  • Scope the contactDisplayStates watch in ForwardingPolicyService to the
    active companion device. Previously watched all companions rows and fired
    on every telemetry update for any companion contacts. Now cancelled and
    re-subscribed on companion change, matching the pattern used for the
    contacts watch.

  • Use incremental contact sync (since=lastmod) on PUSH_ADVERT and
    PUSH_NEW_ADVERT notifications instead of a full pull. Firmware returns
    only contacts modified since the stored lastmod -- typically 0-1 contacts
    instead of the full list. Stored lastmod is updated after each successful
    sync so subsequent adverts stay incremental.

  • Cache the message stream in initState on both chat screens instead of
    calling watchMessagesByChannel/watchPrivateMessages in build(). Each call
    in build() created a new stream that briefly emitted no data, causing the
    message list to flash an empty-state icon on every widget rebuild (visibly
    on send).

tmacinc and others added 30 commits April 28, 2026 08:07
…creens. Fix: offline map tiles not rendering. Fix, ios chat flickering
* Add initialsettings for linux, skip permissions screen on linux,

* several changes to support linux

* gate out non-phone code paths

* skip permissions check on linux

* gate "phone" GPS for desktop

* On Linux, attempt direct connection to the target device via BlueZ system devices before falling back to scan-based reconnection, since paired devices don't advertise.

* Desktop: skip foreground task lifecycle on Linux/desktop -- mark service running directly, and guard FlutterForegroundTask calls to iOS only. Also clear manualDisconnect on any successful connection.
* Linux; re-assert device address before connected state, disconnect stale session before reconnecting

* Turn on autoReconnectEnabled (seems to only affect Linux)

* Save last connected device immediately on connect; guard auto-reconnect to only fire after a clean disconnect, not a failed connect attempt

* autoReconnectEnabled false--> true

* Clear manualDisconnect and save lastConnectedDevice immediately on connect, before sync completes

* BLE: timestamped bleLog(), 15s connect timeout with cancellable timer, Linux stale-session clear via bluetoothctl, guard disconnect handler to only fire when connected

* Fix reconnect first-attempt backoff (was 2s delay, now immediate); use bleLog for timestamped messages; pass explicit 15s timeout to reconnect connect calls

* Remove redundant lastConnectedDevice/manualDisconnect save from ConnectionViewModel; MeshConnectionService now owns this on connect

* Skip re-triggering sync if a sync is already in progress when reconnect fires mid-sync

* Rename connectionState listener parameter to fbpState to distinguish from BleConnectionState _state

* Always delay 500ms after bluetoothctl disconnect regardless of output message; add TODO.md
* docs: add stability issues analysis with false positive noted on item 1

* docs: mark issue 2 as false positive

* perf: replace per-contact DB loop with bulk GROUP BY queries in contact watch streams

* fix: add onError handlers to unread count stream subscriptions

* fix: add error handling to unawaited contact sync blocks on advert receive

* docs: finalize stability issues doc, replace next steps with numbered TODOs

* perf: replace per-channel delete/insert loop with single transaction in channel sync

* fix: prevent duplicate sync on rapid reconnect by setting non-idle phase immediately

* removed unintentional commit of TODO.md

* remove unintentional commit
…acinc#32)

Use pushAndRemoveUntil (keeping root) instead of push so tapping
multiple notifications does not accumulate duplicate screens on the
back stack.
* Add nighttime mode

* Nighttime map tile filter and no-map mode

* Linux app icon support

Add app icon resource, CMake install rule, GTK icon loading in my_application.cc, and .desktop file for Wayland compositor icon resolution.

* Fix contact marker icon visibility in nighttime mode

* Fix disabled field colors in nighttime mode

* Add Settings tab and red light discipline improvements

- Add dedicated Settings tab to bottom nav with Theme (red light discipline) and iOS background location cards
- Move app settings out of connection screen; companion settings remain there
- Replace per-screen moon toggle with NightClock widget in each AppBar, shown only in red light discipline mode
- Go immersive (hide system UI) in red light discipline mode to prevent non-red OS chrome bleed
- Delete NightModeButton widget

* Settings overhaul: hamburger menu, Connection off bottom nav, location settings moved

- Add shared AppMenuButton hamburger menu to Contacts, Channels, Map AppBars
- Add BtStatusIcon (blue/red) to the left of the hamburger on all three screens
- Remove Settings and Connection from bottom nav; both now accessible via the menu
- Connection screen: pushed route, auto-scans on open when not connected
- Move Location Source and Location Tracking from Connection into Settings screen
- Settings screen: Location section above Appearance; channel dropdown shows note when disconnected
- Fix telemetry send timing: re-apply config on sync completion so channel lookup succeeds after first sync

* Add network status icons to all main screens and settings UX polish

- NetworkStatusIcons widget (location sharing + forwarding) added to
  Contacts, Channels, and Map AppBars; removed from Map title row
- BtStatusIcon gets tooltip and reduced opacity; same for NetworkStatusIcons
- Vertical divider separates screen-specific actions from universal status icons
  on Map (layers/settings) and Channels (add channel)
- Map GPS subtitle replaced with icon row: location pin + phone icon for
  phone GPS, location pin alone for companion GPS; location_off when no fix
- Suppress location error banner on map; errors go to debug log only
- Fix sync-complete flash on Connection screen when already synced on open
- Theme setting converted from radio tiles to dropdown

* UX polish: NightClock in title, GPS subtitle icons, settings tweaks

- NightTitle widget: shows screen name with clock on second line in
  nighttime mode; used on Contacts and Channels (not Settings/Connection)
- Map screen: clock moves into GPS subtitle row to the right of source icons
- GPS source subtitle is now icon-only: location pin + phone icon for phone
  GPS, location pin alone for companion; location_off when no fix
- Suppress map location error banner entirely; log to debug only
- sensors_off icon + grey color when location sharing is disabled;
  orange when configured but not connected
- Forwarding tooltip: 'Default routing' replaces misleading 'full mesh'
- Settings: 'Companion GPS' with 'Phone fallback' subtitle; theme dropdown
- Fix sync-complete flash when opening Connection screen while already synced
MrSurly added 5 commits June 23, 2026 19:37
- Replace getAllContacts() stream subscriptions in chat screens with a
  one-shot fetch; contact list was reloaded on every telemetry-triggered
  lastSeen update just to support @mention autocomplete
- Add getContactCount/getContactCountByCompanion to ContactsDao; use them
  in message_repository instead of fetching all rows for .length comparison
- Scope contactDisplayStates watch to active companion in
  ForwardingPolicyService; previously watched all companions' rows and
  re-subscribed on companion change like _contactsSub
…Seen update

Replace one-shot contact fetch with a companion-filtered count watch; the list
reloads only when a contact is added, avoiding the per-telemetry-packet
setState churn while still picking up new contacts synced mid-session.
…VERT

Pass stored lastmod as since= instead of doing a full contact pull on every
advert notification. Update stored lastmod after each successful sync so
subsequent adverts stay incremental. Firmware typically returns 0-1 contacts
instead of the full list on each mid-session advert.
…uild

watchMessagesByChannel/watchPrivateMessages were called in build(), creating
a new stream on every rebuild. Each new stream briefly emits no data, causing
the empty-state icon to flash. Cache the stream in initState instead.
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.

2 participants