Skip to content

Implement Maplibre and patch dependency/font issues#36

Merged
Mr-Technician merged 4 commits into
mainfrom
integrate-backend
May 8, 2026
Merged

Implement Maplibre and patch dependency/font issues#36
Mr-Technician merged 4 commits into
mainfrom
integrate-backend

Conversation

@Mr-Technician
Copy link
Copy Markdown
Member

@Mr-Technician Mr-Technician commented May 8, 2026

This pull request migrates the mobile app's map implementation from react-native-maps (Google Maps) to MapLibre (@maplibre/maplibre-react-native), updating all related components, configuration, and dependencies. It also introduces MapLibre-compatible map styles, updates mocks for testing, and removes now-obsolete code and dependencies.

Migration to MapLibre:

  • Replaced all usage of react-native-maps with @maplibre/maplibre-react-native in map-related components such as AnimatedRoute, AnimatedStationMarker, LiveTrainMarker, and MapScreen. This includes switching to MapLibre's Map, Marker, GeoJSONSource, Layer, and related APIs. [1] [2] [3] [4]
  • Updated the app's configuration (app.config.ts) to add the MapLibre plugin and remove the Google Maps plugin and API keys. [1] [2]

Map Styles and Configuration:

  • Replaced the old Google Maps dark style with MapLibre vector tile style URLs in map-styles.ts, supporting standard, dark, and satellite modes.
  • Added MapLibre-specific zoom level utilities and constants to map.ts.

Dependency and Build Updates:

  • Removed react-native-maps from dependencies and added @maplibre/maplibre-react-native. [1] [2]
  • Updated the Jest setup to mock MapLibre components instead of react-native-maps.

Component and Code Cleanup:

  • Removed unused or incompatible props and state (such as tracksViewChanges and animated coordinate logic) from marker components, adapting them for MapLibre. [1] [2]
  • Removed the unused RouteOverlay dependency on react-native-maps. [1] [2]

iOS Font Configuration:

  • Added required icon fonts for iOS in the app config to ensure icons render correctly with MapLibre.

Summary by CodeRabbit

  • New Features

    • Map now uses MapLibre rendering with multiple style options (standard, dark, satellite).
    • Improved marker and route visuals with smoother camera controls and explicit zoom-level handling.
    • App fonts explicitly registered for iOS.
  • Chores

    • Replaced map library and updated test mocks.
    • Fixed widget extension compatibility for Xcode 26 and applied workspace patch.

Mr-Technician and others added 2 commits April 29, 2026 22:27
…wiftUI Previews

- Created a patch file for expo-widgets@55.0.4 to disable Xcode 26's debug-dylib and SwiftUI Previews for the widget extension target.
- Updated pnpm-lock.yaml to include the new patch and its hash.
- Modified pnpm-workspace.yaml to register the patched dependency.

Co-authored-by: Copilot <copilot@github.com>
Without these UIAppFonts entries, react-native-vector-icons fonts
were copied into the bundle by the Pod but not registered with the
system, so every icon rendered as a missing-glyph "?" box on a fresh
prebuild. Covers the four font families actually imported in the app:
Ionicons, MaterialCommunityIcons, MaterialIcons (used only by
MapSettingsPill), and FontAwesome6 (solid variant).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 8, 2026

Review Change Stack
No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: f9f08ed7-441e-48b9-a2f7-3430ecfe8bef

📥 Commits

Reviewing files that changed from the base of the PR and between 306e77f and 7833ee5.

📒 Files selected for processing (1)
  • apps/mobile/constants/map.ts

📝 Walkthrough

Walkthrough

The PR migrates the mobile app from react-native-maps to @maplibre/maplibre-react-native, updating configuration, dependencies, map constants/styles, refactoring map components and MapScreen camera/overlays, and adding test mocks.

Changes

Map Library Migration from react-native-maps to MapLibre

Layer / File(s) Summary
Configuration & Dependencies
apps/mobile/app.config.ts, apps/mobile/package.json, pnpm-workspace.yaml, patches/expo-widgets@55.0.4.patch
App config gains UIAppFonts and swaps react-native-maps plugin for @maplibre/maplibre-react-native. package.json adds MapLibre and pins expo-widgets to 55.0.4. Workspace applies patch disabling Xcode 26 debug-dylib and SwiftUI previews for widget compilation.
Map Constants & Conversion Functions
apps/mobile/constants/map.ts
Add FOCUS_ZOOM_LEVEL, INITIAL_ZOOM_LEVEL, and latDeltaToZoom() / zoomToLatDelta() conversion helpers for MapLibre zoom handling.
Map Styles
apps/mobile/constants/map-styles.ts
Replace darkMapStyle with MAP_STYLE exporting MapLibre vector tile style URLs for standard, dark, and satellite.
Map Components
apps/mobile/components/map/AnimatedRoute.tsx, AnimatedStationMarker.tsx, LiveTrainMarker.tsx, RouteOverlay.tsx
AnimatedRoute now uses GeoJSONSource + Layer. Station and train markers use MapLibre Marker with lngLat and TouchableOpacity; animated-region and tracksViewChanges logic removed. RouteOverlay removes unused react-native-maps type import.
Main Map Screen
apps/mobile/screens/MapScreen.tsx
Replace MapView with MapLibre Map + Camera; camera actions use cameraRef.easeTo()/cameraRef.fitBounds(); region handler uses onRegionDidChange and viewState.bounds; overlays use GeoJSONSource+Layer; marker props updated.
Testing
apps/mobile/jest.setup.js
Add Jest mock for @maplibre/maplibre-react-native exporting stubbed components as RN View wrappers.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant MapHandlers
  participant CameraRef
  participant MapLibre
  User->>MapHandlers: tap/select/fit request
  MapHandlers->>CameraRef: easeTo(center, zoom) / fitBounds(bounds)
  CameraRef->>MapLibre: update camera/view
  MapLibre-->>MapHandlers: onRegionDidChange(viewState)
  MapHandlers->>MapHandlers: update region state
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Poem

🐰 From polylines old to GeoJSON threads,

I hopped through maps and font-file beds.
Markers now sit with lngLat pride,
Cameras ease where regions used to glide.
A MapLibre parade — hop, skip, and stride!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the two main objectives of the PR: migrating to MapLibre and addressing dependency/font configuration issues in the Expo app.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch integrate-backend

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


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

@Mr-Technician Mr-Technician requested a review from Mootbing May 8, 2026 01:45
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (3)
apps/mobile/components/map/AnimatedRoute.tsx (2)

14-14: 💤 Low value

Unused zoomOpacity prop.

The zoomOpacity prop is declared in the interface but never used in the component. Consider removing it if it's no longer needed after the MapLibre migration, or implementing the intended opacity behavior.

🤖 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/mobile/components/map/AnimatedRoute.tsx` at line 14, The props interface
for the AnimatedRoute component declares zoomOpacity but the component does not
use it; either remove zoomOpacity from the props interface and any callers that
pass it, or implement its intended behavior inside the AnimatedRoute component
(e.g., apply zoomOpacity to the route layer or container style when rendering)
so the prop has effect; locate the zoomOpacity declaration in the AnimatedRoute
props interface and the AnimatedRoute functional component to update the
signature and callers or to read the prop and apply it to the rendered map
layer/container.

18-25: ⚡ Quick win

Memoize the GeoJSON object to avoid unnecessary layer updates.

The geoJSON object is recreated on every render. Since MapLibre may diff/update the source when the object reference changes, consider memoizing it with useMemo to only recompute when coordinates changes.

♻️ Proposed fix
+import React, { useMemo } from 'react';
-import React from 'react';
 import { GeoJSONSource, Layer } from '@maplibre/maplibre-react-native';

 // ... interface definitions ...

 export const AnimatedRoute = React.memo(function AnimatedRoute({ id, coordinates, strokeColor, strokeWidth }: AnimatedRouteProps) {
-  const geoJSON: GeoJSON.Feature<GeoJSON.LineString> = {
+  const geoJSON = useMemo<GeoJSON.Feature<GeoJSON.LineString>>(() => ({
     type: 'Feature',
     geometry: {
       type: 'LineString',
       coordinates: coordinates.map(c => [c.longitude, c.latitude]),
     },
     properties: {},
-  };
+  }), [coordinates]);
🤖 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/mobile/components/map/AnimatedRoute.tsx` around lines 18 - 25, The
geoJSON object in AnimatedRoute is being recreated every render which can
trigger unnecessary MapLibre source updates; wrap the geoJSON construction in
React.useMemo so it only recomputes when coordinates changes (e.g., const
geoJSON = useMemo(() => ({ type: 'Feature', geometry: { type: 'LineString',
coordinates: coordinates.map(c => [c.longitude, c.latitude]) }, properties: {}
}), [coordinates])); update references in the component to use this memoized
geoJSON.
apps/mobile/constants/map-styles.ts (1)

5-5: 💤 Low value

Satellite style uses the same base map as standard.

The satellite key uses voyager-gl-style, which is identical to standard. If satellite imagery isn't available from CARTO's free tier, consider adding a comment clarifying this is a fallback, or removing the satellite option from the UI to avoid user confusion.

🤖 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/mobile/constants/map-styles.ts` at line 5, The satellite entry in the
map styles object (the "satellite" key) points to the same CARTO Voyager style
as "standard", so update apps/mobile/constants/map-styles.ts to avoid confusion
by adding a clear comment above the "satellite" key stating that true satellite
imagery is not available on CARTO's free tier and that this entry is a visual
fallback (or remove the "satellite" key entirely); if you remove it, also remove
or disable the "satellite" option in the UI component (e.g., MapStylePicker) so
the option no longer appears to users.
🤖 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/mobile/constants/map.ts`:
- Around line 59-61: latDeltaToZoom should guard against zero or negative
latitudeDelta to avoid Infinity/NaN from Math.log2; update the function
(latDeltaToZoom) to validate or clamp latitudeDelta (e.g., if latitudeDelta <= 0
then set to a small positive minimum like 1e-6 or return a sensible max zoom
value) before computing Math.log2(360 / latitudeDelta), and document the chosen
minimum/clamp behavior in a short comment.

---

Nitpick comments:
In `@apps/mobile/components/map/AnimatedRoute.tsx`:
- Line 14: The props interface for the AnimatedRoute component declares
zoomOpacity but the component does not use it; either remove zoomOpacity from
the props interface and any callers that pass it, or implement its intended
behavior inside the AnimatedRoute component (e.g., apply zoomOpacity to the
route layer or container style when rendering) so the prop has effect; locate
the zoomOpacity declaration in the AnimatedRoute props interface and the
AnimatedRoute functional component to update the signature and callers or to
read the prop and apply it to the rendered map layer/container.
- Around line 18-25: The geoJSON object in AnimatedRoute is being recreated
every render which can trigger unnecessary MapLibre source updates; wrap the
geoJSON construction in React.useMemo so it only recomputes when coordinates
changes (e.g., const geoJSON = useMemo(() => ({ type: 'Feature', geometry: {
type: 'LineString', coordinates: coordinates.map(c => [c.longitude, c.latitude])
}, properties: {} }), [coordinates])); update references in the component to use
this memoized geoJSON.

In `@apps/mobile/constants/map-styles.ts`:
- Line 5: The satellite entry in the map styles object (the "satellite" key)
points to the same CARTO Voyager style as "standard", so update
apps/mobile/constants/map-styles.ts to avoid confusion by adding a clear comment
above the "satellite" key stating that true satellite imagery is not available
on CARTO's free tier and that this entry is a visual fallback (or remove the
"satellite" key entirely); if you remove it, also remove or disable the
"satellite" option in the UI component (e.g., MapStylePicker) so the option no
longer appears to users.
🪄 Autofix (Beta)

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: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 9d5b9248-5b6b-4717-be71-233281279065

📥 Commits

Reviewing files that changed from the base of the PR and between 77786cd and bdd788f.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (12)
  • apps/mobile/app.config.ts
  • apps/mobile/components/map/AnimatedRoute.tsx
  • apps/mobile/components/map/AnimatedStationMarker.tsx
  • apps/mobile/components/map/LiveTrainMarker.tsx
  • apps/mobile/components/map/RouteOverlay.tsx
  • apps/mobile/constants/map-styles.ts
  • apps/mobile/constants/map.ts
  • apps/mobile/jest.setup.js
  • apps/mobile/package.json
  • apps/mobile/screens/MapScreen.tsx
  • patches/expo-widgets@55.0.4.patch
  • pnpm-workspace.yaml
💤 Files with no reviewable changes (1)
  • apps/mobile/components/map/RouteOverlay.tsx

Comment thread apps/mobile/constants/map.ts
Mr-Technician and others added 2 commits May 7, 2026 22:03
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
@Mr-Technician Mr-Technician merged commit 51d0412 into main May 8, 2026
1 check passed
@Mr-Technician Mr-Technician deleted the integrate-backend branch May 8, 2026 03:09
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.

1 participant