Dev discovery#291
Conversation
…ate related methods and settings
…ied timestamp in contact updates; refactor path handling to accommodate discovered contacts across multiple screens
…ve path construction logic and handle target contact types
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…and refactor location plausibility check in map screen
… and improve contact handling with flags and raw packet data
…tent and ensure messages are cleared after channel creation
…rker building to include labels
…er and update its usage in buildExpandedContent calls
…s to ensure valid coordinates
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…acts handling, migrate legacy keys, and set public key in community store
There was a problem hiding this comment.
Pull request overview
This PR consolidates “discovered contacts” into the main Contact model (via a new isActive flag and optional rawPacket) and then wires discovered contacts into various UI features (map, path tracing, SNR, etc.), while also fixing several per-node storage scoping issues.
Changes:
- Replace
DiscoveryContactwithContactfor discovery flows and persist additional contact fields (isActive,rawPacket) where needed. - Include discovered contacts in map/path/SNR/neighbor/path-hop resolution, plus add a settings toggle to show/hide discovery contacts on the map.
- Fix multiple SharedPreferences stores to use per-node scoped keys (
keyFor) and add some migration logic.
Reviewed changes
Copilot reviewed 56 out of 56 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| lib/widgets/snr_indicator.dart | Resolve repeater names from both saved + discovered contacts |
| lib/utils/contact_search.dart | Discovery query matcher now accepts Contact |
| lib/storage/unread_store.dart | Fix load to use scoped keyFor |
| lib/storage/contact_store.dart | Persist isActive + rawPacket for contacts |
| lib/storage/contact_group_store.dart | Fix load to use scoped keyFor |
| lib/storage/contact_discovery_store.dart | Store discovered contacts as Contact (no DiscoveryContact) |
| lib/storage/community_store.dart | Fix load to use scoped keyFor |
| lib/storage/channel_store.dart | Fix load to use scoped keyFor |
| lib/storage/channel_settings_store.dart | Adjust SMaz enabled load logic (currently broken; see comments) |
| lib/storage/channel_order_store.dart | Fix load to use scoped keyFor |
| lib/storage/channel_message_store.dart | Fix load/migration to prefer scoped key first |
| lib/services/app_settings_service.dart | Add setter for map “show discovery contacts” toggle |
| lib/screens/path_trace_map.dart | Build/trace paths with better handling + include discovered contacts |
| lib/screens/neighbors_screen.dart | Include discovered repeaters when correlating neighbors |
| lib/screens/map_screen.dart | Add discovery-contacts toggle + location plausibility filtering + label tweaks |
| lib/screens/discovery_screen.dart | Discovery screen now uses Contact + guards null rawPacket |
| lib/screens/community_qr_scanner_screen.dart | Ensure CommunityStore is scoped before saving |
| lib/screens/channels_screen.dart | Clear channel message cache on channel create/delete (store scoping issue; see comments) |
| lib/screens/channel_message_path_screen.dart | Include discovered contacts when building hop labels |
| lib/screens/ble_debug_log_screen.dart | Long-press copies payload hex to clipboard |
| lib/models/discovery_contact.dart | Removed legacy model |
| lib/models/contact.dart | Add isActive + rawPacket to unify discovery + normal contacts |
| lib/models/app_settings.dart | Add mapShowDiscoveryContacts persisted setting |
| lib/l10n/app_en.arb | Add map_showDiscoveryContacts string |
| lib/l10n/app_de.arb | Add map_showDiscoveryContacts string |
| lib/l10n/app_bg.arb | Add map_showDiscoveryContacts string |
| lib/l10n/app_es.arb | Add map_showDiscoveryContacts string |
| lib/l10n/app_fr.arb | Add map_showDiscoveryContacts string |
| lib/l10n/app_it.arb | Add map_showDiscoveryContacts string |
| lib/l10n/app_nl.arb | Add map_showDiscoveryContacts string |
| lib/l10n/app_pl.arb | Add map_showDiscoveryContacts string |
| lib/l10n/app_pt.arb | Add map_showDiscoveryContacts string |
| lib/l10n/app_ru.arb | Add map_showDiscoveryContacts string |
| lib/l10n/app_sk.arb | Add map_showDiscoveryContacts string |
| lib/l10n/app_sl.arb | Add map_showDiscoveryContacts string |
| lib/l10n/app_sv.arb | Add map_showDiscoveryContacts string |
| lib/l10n/app_uk.arb | Add map_showDiscoveryContacts string |
| lib/l10n/app_zh.arb | Add map_showDiscoveryContacts string |
| lib/l10n/app_localizations.dart | Add localization getter for map_showDiscoveryContacts |
| lib/l10n/app_localizations_en.dart | Generated localization update |
| lib/l10n/app_localizations_de.dart | Generated localization update |
| lib/l10n/app_localizations_bg.dart | Generated localization update |
| lib/l10n/app_localizations_es.dart | Generated localization update |
| lib/l10n/app_localizations_fr.dart | Generated localization update |
| lib/l10n/app_localizations_it.dart | Generated localization update |
| lib/l10n/app_localizations_nl.dart | Generated localization update |
| lib/l10n/app_localizations_pl.dart | Generated localization update |
| lib/l10n/app_localizations_pt.dart | Generated localization update |
| lib/l10n/app_localizations_ru.dart | Generated localization update |
| lib/l10n/app_localizations_sk.dart | Generated localization update |
| lib/l10n/app_localizations_sl.dart | Generated localization update |
| lib/l10n/app_localizations_sv.dart | Generated localization update |
| lib/l10n/app_localizations_uk.dart | Generated localization update |
| lib/l10n/app_localizations_zh.dart | Generated localization update |
| lib/connector/meshcore_protocol.dart | Add writeBytesPadded + extend update-contact frame writer |
| lib/connector/meshcore_connector.dart | Switch discovery list to Contact + import/update discovery logic |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| List<Marker> _buildGuessedMarker( | ||
| List<_GuessedLocation> guessed, { | ||
| required bool showLabels, | ||
| }) { | ||
| final markers = <Marker>[]; | ||
|
|
| for (final contact in _discoveredContacts) { | ||
| contact.copyWith( | ||
| isActive: !_knownContactKeys.contains(contact.publicKeyHex), |
| final key = '$keyFor$channelIndex'; | ||
| final oldKey = '$_keyPrefix$channelIndex'; | ||
| bool? enabled = prefs.getBool(oldKey); | ||
| if (enabled == null) { | ||
| // Attempt migration from legacy unscoped key on first load | ||
| enabled = prefs.getBool(oldKey); | ||
| prefs.remove(oldKey); | ||
| if (enabled != null) { | ||
| appLogger.info( | ||
| 'Migrating channel settings from legacy key $oldKey to scoped key $key', | ||
| ); | ||
| await prefs.setBool(key, enabled); | ||
| } | ||
| } | ||
| return prefs.getBool(key) ?? false; | ||
| return enabled ?? false; |
| ChannelMessageStore get _channelMessageStore => ChannelMessageStore(); | ||
|
|
| // All contacts with a known location — used as anchors regardless of | ||
| // time/key-prefix filters so that repeaters are always available. | ||
| final allContactsWithLocation = contacts | ||
| final allContactsWithLocation = allContacts | ||
| .where((c) => c.hasLocation) | ||
| .toList(); |
| if (!_checkLocationPlausibility( | ||
| position.latitude, | ||
| position.longitude, | ||
| )) { | ||
| continue; // discard implausible guesses near (0, 0 | ||
| } |
| if (!_checkLocationPlausibility( | ||
| position.latitude, | ||
| position.longitude, | ||
| )) { | ||
| continue; // discard implausible guesses near (0, 0 | ||
| } |
…acts handling and set public key in community store; enhance location plausibility check in MapScreen
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 125621cbcf
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…de and longitude fields
There was a problem hiding this comment.
Pull request overview
This PR consolidates “discovered contacts” into the main Contact model (via new isActive and optional rawPacket fields), then updates multiple UI surfaces (map, SNR, path tracing, neighbors, discovery) to treat discovered + saved contacts consistently. It also fixes several SharedPreferences store scoping issues by reading from keyFor (scoped) and migrating from legacy unscoped keys, and adds a map setting to toggle displaying discovered contacts.
Changes:
- Replace
DiscoveryContactwithContactfor discovery flows; addisActive+rawPacketpersistence support. - Combine discovered + saved contacts in map/path/SNR/neighbors UI and add a “Show Discovery Contacts” map toggle.
- Fix storage key usage (prefer scoped
keyForwith migration) and update contact update-frame construction.
Reviewed changes
Copilot reviewed 56 out of 56 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| lib/widgets/snr_indicator.dart | Look up repeater names across saved + discovered contacts. |
| lib/utils/contact_search.dart | Switch discovery query matching to Contact. |
| lib/storage/unread_store.dart | Fix unread store to load from scoped keyFor and migrate legacy key. |
| lib/storage/contact_store.dart | Persist/load new Contact.isActive and Contact.rawPacket. |
| lib/storage/contact_group_store.dart | Fix group store to load from scoped keyFor and migrate legacy key. |
| lib/storage/contact_discovery_store.dart | Store discovered contacts as Contact and persist additional fields. |
| lib/storage/community_store.dart | Fix community store to load from scoped keyFor and migrate legacy key. |
| lib/storage/channel_store.dart | Fix channel store to load from scoped keyFor and migrate legacy key. |
| lib/storage/channel_settings_store.dart | Correctly return migrated/loaded SMaz enabled value. |
| lib/storage/channel_order_store.dart | Fix order store to load from scoped keyFor and migrate legacy key. |
| lib/storage/channel_message_store.dart | Fix message store to load from scoped keyFor and migrate legacy key. |
| lib/services/app_settings_service.dart | Add setter for map discovery-contacts visibility setting. |
| lib/screens/path_trace_map.dart | Update path trace building + include discovered contacts in hop mapping; add logging. |
| lib/screens/neighbors_screen.dart | Include discovered contacts when mapping neighbors to known repeaters. |
| lib/screens/map_screen.dart | Add discovery contacts toggle, location plausibility checks, guessed marker labeling changes. |
| lib/screens/discovery_screen.dart | Switch discovery UI to Contact and guard rawPacket-dependent copy action. |
| lib/screens/community_qr_scanner_screen.dart | Ensure community store is scoped via setPublicKeyHex before saving. |
| lib/screens/channels_screen.dart | Clear channel messages after channel creation/deletion; scope community store before use. |
| lib/screens/channel_message_path_screen.dart | Include discovered contacts when labeling hops. |
| lib/screens/ble_debug_log_screen.dart | Add long-press copy of payload as hex. |
| lib/models/contact.dart | Add isActive and optional rawPacket; extend copyWith and parsing defaults. |
| lib/models/app_settings.dart | Add mapShowDiscoveryContacts setting with JSON serialization. |
| lib/l10n/app_en.arb | Add map_showDiscoveryContacts string. |
| lib/l10n/app_bg.arb | Add map_showDiscoveryContacts string. |
| lib/l10n/app_de.arb | Add map_showDiscoveryContacts string. |
| lib/l10n/app_es.arb | Add map_showDiscoveryContacts string. |
| lib/l10n/app_fr.arb | Add map_showDiscoveryContacts string. |
| lib/l10n/app_it.arb | Add map_showDiscoveryContacts string. |
| lib/l10n/app_nl.arb | Add map_showDiscoveryContacts string. |
| lib/l10n/app_pl.arb | Add map_showDiscoveryContacts string. |
| lib/l10n/app_pt.arb | Add map_showDiscoveryContacts string. |
| lib/l10n/app_ru.arb | Add map_showDiscoveryContacts string. |
| lib/l10n/app_sk.arb | Add map_showDiscoveryContacts string. |
| lib/l10n/app_sl.arb | Add map_showDiscoveryContacts string. |
| lib/l10n/app_sv.arb | Add map_showDiscoveryContacts string. |
| lib/l10n/app_uk.arb | Add map_showDiscoveryContacts string. |
| lib/l10n/app_zh.arb | Add map_showDiscoveryContacts string. |
| lib/l10n/app_localizations.dart | Add localization getter for map_showDiscoveryContacts. |
| lib/l10n/app_localizations_en.dart | Add English localization getter implementation. |
| lib/l10n/app_localizations_bg.dart | Add Bulgarian localization getter implementation. |
| lib/l10n/app_localizations_de.dart | Add German localization getter implementation. |
| lib/l10n/app_localizations_es.dart | Add Spanish localization getter implementation. |
| lib/l10n/app_localizations_fr.dart | Add French localization getter implementation. |
| lib/l10n/app_localizations_it.dart | Add Italian localization getter implementation. |
| lib/l10n/app_localizations_nl.dart | Add Dutch localization getter implementation. |
| lib/l10n/app_localizations_pl.dart | Add Polish localization getter implementation. |
| lib/l10n/app_localizations_pt.dart | Add Portuguese localization getter implementation. |
| lib/l10n/app_localizations_ru.dart | Add Russian localization getter implementation. |
| lib/l10n/app_localizations_sk.dart | Add Slovak localization getter implementation. |
| lib/l10n/app_localizations_sl.dart | Add Slovenian localization getter implementation. |
| lib/l10n/app_localizations_sv.dart | Add Swedish localization getter implementation. |
| lib/l10n/app_localizations_uk.dart | Add Ukrainian localization getter implementation. |
| lib/l10n/app_localizations_zh.dart | Add Chinese localization getter implementation. |
| lib/connector/meshcore_protocol.dart | Add padded-write helper and extend contact update frame building. |
| lib/connector/meshcore_connector.dart | Convert discovered contacts to Contact; add updateKnownDiscovered; import/update logic changes. |
| lib/models/discovery_contact.dart | Removed legacy discovery-only model. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| lastSeen: contact.lastSeen, | ||
| flags: 0, | ||
| isActive: false, | ||
| ); |
| if (selectedOption == 0) | ||
| buildExpandedContent(_channelMessageStore)!, | ||
| const Divider(height: 1), |
| import 'dart:math'; | ||
| import 'dart:typed_data'; | ||
|
|
||
| import 'package:flutter/foundation.dart'; |
| position.latitude, | ||
| position.longitude, | ||
| )) { | ||
| continue; // discard implausible guesses near (0, 0 |
| if (lastModified != null) { | ||
| // Last modified | ||
| final lastModifiedTimestamp = lastModified.millisecondsSinceEpoch ~/ 1000; | ||
| writer.writeUInt32LE(lastModifiedTimestamp); | ||
| } |
|
|
||
| // Build CMD_ADD_UPDATE_CONTACT frame to set custom path | ||
| // Format: [cmd][pub_key x32][type][flags][path_len][path x64][name x32][timestamp x4] | ||
| // Format: [cmd][pub_key x32][type][flags][path_len][path x64][name x32][Lat? x4, Lon? x4][timestamp? x4] |
Discovered contacts use the normal contacts class.
The Contacts class has a new bool, isActive, that indicates whether the contact is in the contacts list.
Discovered contacts are combined in the map view, path tracing, and SNR indicator.
Discovered contacts are accessible between companions to make it easy to add contacts to other companions.
Also fixes my mistake in the data stores.