Skip to content

Merge dev into main#271

Merged
Avi0n merged 53 commits into
mainfrom
dev
Mar 30, 2026
Merged

Merge dev into main#271
Avi0n merged 53 commits into
mainfrom
dev

Conversation

@Avi0n
Copy link
Copy Markdown
Owner

@Avi0n Avi0n commented Mar 30, 2026

No description provided.

robekl and others added 30 commits March 21, 2026 12:13
Extract ChannelGroup and TelemetryChartGroup from TelemetryHistoryView
into shared types so both the existing view and the new overview
ViewModel can use them.
- Add FloodScope.region case deriving scope key as SHA256("#"+name).prefix(16)
- Add CommandCode.sendAnonReq (0x39) and AnonRequestType enum (regions/owner/basic)
- Add PacketBuilder.sendAnonReq with reversed out-path wire format
- Add RegionsParser to decode comma-separated UTF-8 region names from binary response
- Add MeshCoreSession.requestRegions(from:) with flood-route workaround
- Add regionScope and knownRegions fields to Channel/Device data models
- Add localization strings for region filtering across all languages
- Add region picker section to ChannelInfoSheet with scope selection
- Add RegionManagementView with inline alert for manual region entry
- Wire setFloodScope to channel open and region change
- Show active region in channel title bar subtitle
- Implement broadcast-first region discovery via DISCOVER_REQ
- Filter wildcard '*' and whitespace from region parser responses
- Add region filtering unit tests
- Move subscribe() and send() inside do/catch that calls resetPath
- Prevents firmware contact being left in zero-hop state on transport failure
Validate packet inputs and fail closed on malformed responses
- Track textFieldID state and apply .id() to ChatInputTextField
- Rotate textFieldID on send to destroy and recreate the UIKit-backed
  text field, flushing any pending autocorrect, inline prediction, or
  IME composition state that could race against text = ""
- Assert isFocused = true in the same synchronous block so the keyboard
  stays visible after re-creation
…Response.parse

- Contact info and repeater names containing ":" and "/" were misclassified as deviceTime, silently discarding the GET response
- Move freeform text query-hint checks before the broad deviceTime heuristic
- Add regression tests for the collision case
- Persist receiveErrors in NodeStatusSnapshot and display as chart in
  both logged-in and offline history views
- Resolve neighbor names from contacts and discovered nodes in both
  live and offline history views (previously only hex prefixes offline)
- Rename "Saved History" to "Telemetry History" across all locales
- Style Telemetry History button with .tint to match adjacent buttons
fix(meshcore): decode room server status layout
- Add layout param to Parsers.StatusResponse.parse() with switch
  matching the repeater/roomServer pattern from parseFromBinaryResponse
- Re-parse push status responses in handleReceivedData() when contact
  cache identifies the sender as a room server
- Fix routeGenericBinaryResponse to resolve layout from contact cache
  before calling parseFromBinaryResponse
- Add push-path parse tests for room server and default repeater layouts
- Add BinaryRequestType.ownerInfo = 0x07 to PacketCodes
- Add OwnerInfoResponse struct (firmwareVersion, nodeName, ownerInfo) to MeshEvent
- Implement requestOwnerInfo / performOwnerInfoRequest in MeshCoreSession following the established binary request pattern
- Expose requestOwnerInfo through RemoteNodeService and RepeaterAdminService
- Route non-admin logins from the admin button to RepeaterStatusView instead of RepeaterSettingsView, in both ContactDetailView and MapView
- Show "Guest Mode" badge in RepeaterStatusView header when session permission is guest
- Add read-only owner info section to RepeaterStatusView using the new binary request path
- Add guestMode, ownerInfo, and noOwnerInfo localized strings across all 9 locales
- Call requestOwnerInfo on configure to pre-populate firmware version, node name, and owner info before any section is expanded, replacing three separate CLI round-trips
- Remove ver and get name CLI calls from fetchDeviceInfo/fetchIdentity; retry via binary on section expand if data is missing
- Add isLoadingNodeInfo flag to deduplicate concurrent binary fetches
- Fix ExpandableSettingsSection reload button to only appear when section is expanded
- Change deviceInfoLoaded and identityLoaded to check only CLI-fetched data so onLoad still fires for device time and coordinates
The button supports both admin and guest login, so "adminAccess" no
longer reflects its purpose. Renamed key and updated comments across
all 9 locales and 3 string tables; updated 3 Swift call sites.
- Add `isBatteryPresent` to BatteryInfo (false when level == 0mV)
- Guard all three BatteryMonitor threshold methods on isBatteryPresent
- Mains-powered devices that report 0mV no longer trigger spurious
  low battery notifications
…iably

- Remove the .id(textFieldID) TextField re-creation trick introduced in
  b4ee628, which was destroying the focused view on every send and
  dismissing the keyboard as a side effect
- Add InlinePredictionFix (UIViewRepresentable) that locates the backing
  UITextView via view hierarchy introspection and sets inlinePredictionType
  to .no — preventing the ghost-text race (Apple FB13727682) without
  destroying view identity or dismissing the keyboard
- Replace three-way Group { if/else } branch with messagesTable always
  rendered and empty state overlaid on top
- The previous branch swap tore down and recreated ChatTableView on first
  message, disrupting SwiftUI focus tracking and dismissing the keyboard
- Add Regions section to repeater settings with ExpandableSettingsSection
- Fetch region list via bare `region` CLI command (tree output parser)
- Support flood allow/deny toggles, home region picker, add/remove regions
- Explicit Save to Repeater step with unsaved-changes tracking
- Uses FIFO matching for region/home commands whose responses don't fit CLIResponse patterns
- Add 19 L10n keys across all 9 languages
Avi0n and others added 23 commits March 26, 2026 15:41
- Add MeshCoreURLParser utility for parsing meshcore:// URLs
- Add paste button to AddContactSheet that reads clipboard and auto-fills name, key, and type fields
- Add localized strings for paste URL button, footer, and error across all 9 locales
…state

- Add hopCount and isDirect computed properties to MessageDTO
- 0-hop messages with 2-byte hashes (pathLength 0x40) were shown as
  "64 hops" because the encoded byte was displayed raw instead of decoded
- Update isDirect checks, hop count display, path formatter, and action
  availability to use the decoded values
…navailable

- Add DeviceDTO.hasLocation (with CLLocationCoordinate2DIsValid, matching ContactDTO)
- Add AppState.bestAvailableLocation: phone GPS first, device location if set
- Fix TracePathMapView onChange guard to skip rebuildOverlays when coordinates unchanged
- Update all proximity/sorting call sites to use bestAvailableLocation
- Replace 3 divergent SNR classification systems with a single
  SNRQuality enum
- Remove veryPoor tier, update colors (green/yellow/red)
- Add SNRQuality.localizedLabel to eliminate 3 duplicate L10n switches
- Add SNRQuality.uiColor for MapKit renderers
- Remove PathLineOverlay.SignalQuality in favor of SNRQuality?
Signed-off-by: Neil Alexander <neilalexander@users.noreply.github.com>
- Specify explicit month/day format on chart x-axis labels to prevent Swift Charts from auto-appending truncated time components
fix(meshcore): handle disabled export private key
- Extract shared node management logic from Repeater-specific views into reusable helpers (NodeSettingsHelper, NodeStatusHelper, SharedNodeViews), reducing duplication across Room and Repeater management
- Add full Room management UI (RoomSettingsView, RoomStatusView) with RoomAdminService, following existing Repeater patterns
- Fix two pre-existing MeshCore spec alignment bugs validated against firmware source (CommonCLI.cpp)
Replaces MapKit with MapLibre Native across all map views (main map, Line of Sight, Trace Path, LocationPicker).

- New `MC1MapView` (UIViewRepresentable) using data-driven GeoJSON layers, sprite-based pins, and raster tile overlays for satellite/topo styles
- New `OfflineMapService` with settings UI for downloading and managing offline map packs
- New `PinSpriteRenderer` for rendering map pin sprites without a network connection
- Removed all MapKit representables and annotation views
- Added MapLibre Native SPM dependency (maplibre-gl-native-distribution 6.23+)
- Add GAT562 as nRF52 to fix incorrect 60ms pacing (should be 25ms)
- Add M5Stack Unit C6L as ESP32
- Add ThinkNode M5 as ESP32
- R1 Neo: replace synthetic linear placeholder with discharge curve
  from Meshtastic firmware PR #8716
- LTO: replace inaccurate flat curve with smoother discharge slope
- Replace chevron.forward.2 with arrowshape.bounce.right to match
  the icon used in message bubble hop count footers
- Added path decoding properties to DiscoveredNodeDTO (isFloodRouted,
  pathHopCount, pathHashSize, pathByteLength, pathNodesHex)
- Each row in the Discover view now shows the incoming hop count and
  hex path, using the same icons and truncation as message bubbles
- Adds a "Discover Neighbours" button in the Neighbours section (admin only) that sends the discover.neighbors CLI command to the repeater
- Polls the binary neighbours endpoint every 3 seconds for 60 seconds, updating the list in real time as nodes respond
- Button toggles to show a live countdown and stops discovery on tap
- Pull-to-refresh and toolbar refresh skip the neighbour fetch during active discovery to avoid conflicts
- Cleans up the polling task on view dismiss
- Localised in all 9 supported languages
- Render red X markers on map at peak of each obstruction region
- White-cased stroke style to match the LOS path lines
- Build map lines from elevation profile coords for accurate marker alignment
- Data-driven icon anchor so X centers on coordinate
- Group obstruction points into contiguous regions, one marker per region
- Align terrain profile red bars with 60% Fresnel threshold to match markers
- Fix invisible red bars for single-sample obstructions (zero-width rect)
- Replace isCrosshair/isObstruction bools with RenderStyle enum
- Extract worstObstructionPoint on PathAnalysisResult
- uiColor still had the old 4-color mapping after 007c4d2 changed color
- Map layers now use SNRQuality.uiColor instead of hardcoded UIColors
- Map was hidden behind a ContentUnavailableView when no repeaters had
  location data, now it's always visible
- Remove orphaned localization keys across all 9 languages
Instead of storing blocked sender messages and filtering at display time,
drop them before saving to the database. Update block confirmation alert
text across all 9 locales to reflect that channel messages are now
discarded rather than hidden, and cannot be recovered on unblock.
- Updated contacts.detail.ping across all 9 locales
- Matches Zero-Hop terminology used in the radio menu
- zh-Hans uses 零跳, consistent with sendZeroHopAdvert translation
- Use in-memory container when the on-disk store is inaccessible (device
  rebooted, not yet unlocked), then swap to the real store once data
  protection kicks in
- Race the protectedDataDidBecomeAvailable notification against a 1s poll
  so a missed notification while suspended doesn't hang forever
- Keep the existing retry + fatalError for real container failures when
  the disk is actually reachable
- Switch to @State + onChange so backspace works on loaded text
- Center the apply button checkmark to match other save buttons
@Avi0n Avi0n merged commit 3fa1601 into main Mar 30, 2026
3 checks passed
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.

3 participants