Skip to content

fix(web): resolve map bounds crash, canvas zoom sizing, and add auto-reconnect on refresh - #1384

Open
jkboroff wants to merge 1 commit into
meshtastic:mainfrom
jkboroff:fix/map-crash-and-auto-reconnect
Open

fix(web): resolve map bounds crash, canvas zoom sizing, and add auto-reconnect on refresh#1384
jkboroff wants to merge 1 commit into
meshtastic:mainfrom
jkboroff:fix/map-crash-and-auto-reconnect

Conversation

@jkboroff

@jkboroff jkboroff commented Aug 7, 2026

Copy link
Copy Markdown

Description

This PR resolves three runtime stability and UX issues in the web client: map bounding box calculation crashes, map canvas zoom interaction blocking, and missing auto-reconnect on browser page refreshes.

Related Issues

N/A

Changes Made

• Map Bounds Calculation & Fitting (geo.ts & useMapFitting.ts): Replaced Turf lineString calls with direct min/max bounding box calculations and added coordinate sanity checks to prevent MapLibre camera transition
crashes (can't access property "center").
• Map Canvas Sizing & Controls Overlay (Map.tsx & pages/Map/index.tsx): Explicitly set width: "100%", height: "100%" on style and adjusted floating tool overlay positioning (top-36) so overlay elements don't
block + / - navigation zoom buttons.
• Auto-Reconnect on Page Reload (App.tsx & deviceStore/index.ts): Reset stale saved connection statuses to "disconnected" on IndexedDB store rehydration and added an AutoConnect handler that waits for IndexedDB
rehydration to finish before automatically reconnecting to the default/saved HTTP connection.

Testing Done

• Verified local HTTP / HTTPS connections over custom port & Nginx proxy.
• Verified auto-reconnect transitions directly to dashboard on cold page reload (Ctrl+F5).
• Tested map pan, touch zoom, scroll zoom, and NavigationControl zoom buttons.

Screenshots (if applicable)

N/A

Checklist

[✓] Code follows project style guidelines
[✓] Documentation has been updated or added
[ ] Tests have been added or updated
[✓] All i18n translation labels have been added (read CONTRIBUTING_I18N_DEVELOPER_GUIDE.md for more details)

Summary by CodeRabbit

  • New Features
    • Automatically reconnects to the default saved HTTP connection, or the first available saved connection.
    • Added touch, scroll, and double-click map zoom controls with defined zoom limits.
  • Bug Fixes
    • Improved handling of invalid map coordinates and prevented map-fitting errors.
    • Saved connections now consistently reset to a disconnected state when the app reloads.
  • Style
    • Improved map control positioning and visibility.

@vercel

vercel Bot commented Aug 7, 2026

Copy link
Copy Markdown

Someone is attempting to deploy a commit to the Meshtastic Team on Vercel.

A member of the Team first needs to authorize it.

@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.


root seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account.
You have signed the CLA already but the status is still pending? Let us recheck it.

@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The app now auto-connects to a saved HTTP connection and resets connection state during rehydration. Map rendering supports more interactions, validates coordinates before camera changes, handles map errors, and updates control placement.

Changes

Connection startup and state

Layer / File(s) Summary
Connection state rehydration
apps/web/src/core/stores/deviceStore/index.ts
Rehydration clears the status and error for every saved connection.
Automatic saved connection
apps/web/src/App.tsx
AutoConnect selects the default or first saved HTTP connection and starts one connection attempt when no device is active. App renders the component inside the error boundary.

Map behavior

Layer / File(s) Summary
Map bounds and camera validation
apps/web/src/core/utils/geo.ts, apps/web/src/core/hooks/useMapFitting.ts
Bounds calculation ignores non-finite coordinates. Map fitting validates coordinates and suppresses camera calculation and easing errors.
Map interaction and controls
apps/web/src/components/Map.tsx, apps/web/src/pages/Map/index.tsx
The map enables touch and zoom interactions, applies zoom limits and full-container sizing, and updates control positioning and stacking.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant App
  participant AutoConnect
  participant deviceStore
  participant connect
  App->>AutoConnect: render
  AutoConnect->>deviceStore: read saved connections and selected device
  AutoConnect->>connect: start selected HTTP connection
Loading

Poem

A rabbit hops through saved links bright,
Chooses the default connection right.
Maps stretch wide and cameras stay still,
Bad points are skipped by careful will.
The burrow reconnects at dawn.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the three primary web client fixes: map bounds, canvas zoom sizing, and automatic reconnection.
Description check ✅ Passed The description covers the required sections and clearly explains the changes, testing performed, screenshots status, and checklist selections.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/web/src/core/hooks/useMapFitting.ts`:
- Around line 51-52: Filter the coordinates produced in the multi-node path of
useMapFitting before passing them to boundsFromLngLat, excluding the [0, 0]
sentinel generated by toLngLat for missing positions. Preserve valid coordinates
and keep the existing single-node rejection behavior consistent.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 35fef18b-7f7f-483e-b23e-a99c7b175d29

📥 Commits

Reviewing files that changed from the base of the PR and between 9a47442 and 086dfca.

📒 Files selected for processing (6)
  • apps/web/src/App.tsx
  • apps/web/src/components/Map.tsx
  • apps/web/src/core/hooks/useMapFitting.ts
  • apps/web/src/core/stores/deviceStore/index.ts
  • apps/web/src/core/utils/geo.ts
  • apps/web/src/pages/Map/index.tsx

Comment on lines 51 to 52
const coords = nodes.map((n) => toLngLat(n.position));
const bounds = boundsFromLngLat(coords);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Exclude the invalid [0, 0] sentinel before calculating bounds.

At Line 51, toLngLat(undefined) produces [0, 0]. boundsFromLngLat accepts this pair because both values are finite. A missing node position can then move a multi-node fit toward Null Island. This differs from the single-node path, which rejects [0, 0].

Proposed fix
-      const coords = nodes.map((n) => toLngLat(n.position));
+      const coords = nodes
+        .map((n) => toLngLat(n.position))
+        .filter(
+          ([lng, lat]) =>
+            Number.isFinite(lng) &&
+            Number.isFinite(lat) &&
+            !(lng === 0 && lat === 0),
+        );
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const coords = nodes.map((n) => toLngLat(n.position));
const bounds = boundsFromLngLat(coords);
const coords = nodes
.map((n) => toLngLat(n.position))
.filter(
([lng, lat]) =>
Number.isFinite(lng) &&
Number.isFinite(lat) &&
!(lng === 0 && lat === 0),
);
const bounds = boundsFromLngLat(coords);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/web/src/core/hooks/useMapFitting.ts` around lines 51 - 52, Filter the
coordinates produced in the multi-node path of useMapFitting before passing them
to boundsFromLngLat, excluding the [0, 0] sentinel generated by toLngLat for
missing positions. Preserve valid coordinates and keep the existing single-node
rejection behavior consistent.

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