Commit graph

18 commits

Author SHA1 Message Date
Ullrich Schäfer
bdde95e69b
Use @gorhom/bottom-sheet for waypoint sheet
Replace custom View-based bottom sheet with @gorhom/bottom-sheet:
- Native gesture-driven drag, snap points, pan-down-to-close
- Proper safe area handling built in
- Wrap app with GestureHandlerRootView
- Add react-native-reanimated plugin to Expo config

Adds react-native-reanimated and react-native-gesture-handler as
native dependencies (requires new EAS build).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 01:09:13 +02:00
Ullrich Schäfer
fe07fbdf59
Fix WaypointSheet safe area: add bottom inset padding
Close button was overlapping the home indicator. Now uses
useSafeAreaInsets() for dynamic bottom padding.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 01:06:10 +02:00
Ullrich Schäfer
d45f1e14fd
Fix route display: parse track coordinates from GPX on init
The route polyline wasn't visible because segments were initialized
empty. Now extractSegmentsFromGpx() parses trkpt coordinates from
the GPX string via regex on init, so the route shows immediately
in both view and edit modes.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 01:06:10 +02:00
Ullrich Schäfer
bd311cd339
Implement mobile route editor with MapLibre and BRouter routing
Route editing (Phase 3.3):
- useRouteEditor hook: waypoint state, add/move/delete, BRouter
  routing via Journal API proxy, GPX generation, save to API
- RouteMap component: MapLibre Native with OSM raster tiles,
  route polyline (ShapeSource + LineLayer), waypoint markers
  (MarkerView), long-press to add waypoints, computing indicator
- WaypointSheet: bottom sheet for waypoint actions — delete with
  confirmation, overnight stop toggle, coordinates display
- Route detail screen: view mode (map preview + stats) and edit
  mode (full-screen map with save button)
- Unsaved changes guard on navigation (beforeRemove listener)
- Smart waypoint insertion at nearest route segment
- Waypoint extraction from GPX via regex (sync, no DOM needed)

Adds DOM.Iterable to mobile tsconfig for gpx package compat.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 01:06:10 +02:00
Ullrich Schäfer
b465081e1b
Fix CI: add react-test-renderer to match react version
The smoke test failed in CI with version mismatch between react
(19.2.5 from catalog) and react-test-renderer (19.2.0 transitive).
Adding it explicitly ensures they stay in sync.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 02:30:00 +02:00
Ullrich Schäfer
1414924746
Enable Sentry source map upload in EAS builds
- Remove SENTRY_DISABLE_AUTO_UPLOAD from all build profiles
- Add @sentry/cli as explicit dependency to fix pnpm module
  resolution in EAS cloud builds
- SENTRY_AUTH_TOKEN configured as EAS environment secret

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 02:12:36 +02:00
Ullrich Schäfer
42a9c29c84
Set up Sentry crash reporting for mobile app
- Initialize @sentry/react-native with dedicated mobile project DSN
- Wrap root layout with Sentry.wrap() for unhandled error capture
- Configure Sentry plugin with org (trails-qq) and project (mobile)
  for source map uploads during EAS builds
- Disabled in dev, full tracing in production

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 02:07:44 +02:00
Ullrich Schäfer
dd06d2f231
Add all native dependencies for remaining phases
Batch-install native modules to minimize EAS build credits:
- @maplibre/maplibre-react-native — map view for routes (Phase 3)
- @sentry/react-native — crash reporting and error tracking
- expo-sqlite — offline route storage (Phase 5)
- expo-notifications — push notifications (Phase 7)
- expo-location — GPS for activity recording (future)

All registered as Expo config plugins. Requires one new EAS build
to include the native modules.

Also:
- Use npx eas-cli in build scripts (not global eas)
- Add pnpm dev:ios / dev:android root scripts using eas build:dev
- Fix expo-doctor: add expo-constants, expo-linking, dedupe react

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 01:49:40 +02:00
Ullrich Schäfer
204fd7084b
Configure EAS Build and fix expo-doctor issues
- Add eas.json with development, preview, and production profiles
- Link project to EAS (projectId: 93c75cae-fecf-4ce5-8cd8-c823760b12e2)
- Add expo-dev-client, expo-constants, expo-linking dependencies
- Remove eas-cli from project deps (use globally)
- Add ITSAppUsesNonExemptEncryption to iOS infoPlist
- Use catalog react with expo.install.exclude to skip version check
- Fix slug to match EAS project registration
- Run pnpm dedupe to resolve duplicate react across workspaces

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 01:35:15 +02:00
Ullrich Schäfer
2f99ce926a
Add route detail screen with metadata and action buttons
Route detail at /routes/:id shows:
- Header with back navigation and route name
- Map placeholder (MapLibre requires EAS dev build)
- Stats row: distance, elevation gain/loss, day count
- Description text
- Version count
- "Edit in Planner" opens Journal web UI
- "Download Offline" button (handler pending Phase 5)

Safe area insets applied to header and scroll content.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 01:15:41 +02:00
Ullrich Schäfer
77e3c1b1ee
Build Routes tab with paginated list and Zod-validated API responses
Routes tab (Phase 3.1):
- Paginated FlatList fetching from Journal REST API
- Route cards with name, distance (km), elevation gain, day count
- Pull-to-refresh, loading spinner, error state with retry, empty state
- Safe area insets for notch and tab bar

API client:
- Import types from @trails-cool/api instead of hand-written interfaces
- Parse list/detail responses through Zod schemas at runtime
- Add zod as mobile app dependency

i18n:
- Add mobile namespace (en + de) for routes, activities, profile, login

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 01:15:40 +02:00
Ullrich Schäfer
1ae406a8aa
Implement OAuth2 PKCE auth, discovery, and mobile API client
Journal server (Phase 1.4 + 1.5):
- Add oauth_clients, oauth_codes, oauth_tokens tables to journal schema
- Implement GET /oauth/authorize with PKCE flow and login redirect
- Implement POST /oauth/token (authorization_code + refresh_token grants)
- Add validateBearerToken() + getAuthenticatedUser() middleware
- Seed trails-cool-mobile as trusted OAuth client on server startup
- Add GET /.well-known/trails-cool discovery endpoint
- Add returnTo support to login page and magic link verify
- Add @trails-cool/api workspace dependency to journal

Mobile app (Phase 1.5 + 1.6):
- Login screen with server URL input and discovery validation
- OAuth2 PKCE login via expo-web-browser with expo-crypto for Hermes
- Token storage in expo-secure-store with auto-refresh on 401
- API client with bearer token injection and typed errors
- Server URL persistence with localhost default in dev mode
- API version compatibility check on app foreground
- Log out + switch server on Profile tab
- iOS ATS exception for local networking

Tests:
- PKCE crypto verification, OAuthError, token generation
- Discovery endpoint response shape
- API version semver compatibility
- API client error types

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 00:41:40 +02:00
Ullrich Schäfer
2ac4014521
Standardize monorepo pipeline: test, lint, typecheck across all workspaces
Previously only 2-3 workspaces participated in each turbo task. This
expands test, lint, and typecheck to cover all 11 workspaces with
parallel execution and caching.

Test pipeline:
- Move from single root vitest to per-workspace test scripts via turbo
- Shared vitest config (vitest.shared.ts) with passWithNoTests
- Per-workspace configs re-export the shared base
- Mobile uses Jest (jest-expo + React Native Testing Library)
- Add node-environment GPX tests verifying linkedom fallback
- Add i18n mobile init tests
- Exclude apps/mobile from root vitest (uses Jest separately)

Lint pipeline:
- Add eslint lint script to all 9 previously unlinted workspaces
- Standardize all scripts to "eslint ." with shared root config
- Add .expo/ to global ESLint ignores
- Fix lint errors: unused imports in api/types, export parseGpx

Typecheck pipeline:
- Add "typecheck": "tsc" to all 8 packages
- Add @types/node (catalog) to gpx and db packages
- Fix mobile app.config.ts: remove deprecated experiments.monorepo
  and newArchEnabled (both default in Expo SDK 55)
- Add allowImportingTsExtensions to mobile tsconfig

Shared package compatibility (mobile-app Phase 1.3):
- Add linkedom as explicit dependency to @trails-cool/gpx
- Add initI18nMobile() export to @trails-cool/i18n
- Confirm @trails-cool/types is pure interfaces (no DOM deps)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 00:00:43 +02:00
Ullrich Schäfer
4738d77ebe
Use bicycle SF Symbol for Activities tab
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 23:30:18 +02:00
Ullrich Schäfer
70ff0652a5
Use NativeTabs for liquid glass tab bar on iOS 26
Switches from expo-router Tabs to NativeTabs (unstable API) which
renders native tab bars with liquid glass on iOS 26 and Material
bottom navigation on Android. Adds SF Symbols and Material icons.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 23:24:51 +02:00
Ullrich Schäfer
b762fc424b
Fix Expo 55 dependency compatibility
expo install --fix updated all deps to SDK 55 compatible versions:
- expo-router 5.0.7 → 55.0.12
- expo-status-bar 3.0.9 → 55.0.5
- react 19.1.0 → 19.2.0
- react-native 0.81.5 → 0.83.4
- react-native-safe-area-context 5.7.0 → 5.6.2
- react-native-screens 4.12.0 → 4.23.0
- @types/react 19.1.0 → 19.2.14

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 23:13:54 +02:00
Ullrich Schäfer
acce158b99
Upgrade mobile app to Expo SDK 55
expo 54 → 55, expo-router 4 → 5, react-native-safe-area-context 5.4 → 5.7

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 23:09:14 +02:00
Ullrich Schäfer
95fdbfee2f
Initialize Expo mobile app with tab navigation and monorepo support
- Expo managed project at apps/mobile/ with TypeScript
- Expo Router with 4 tabs: Map, Routes, Activities, Profile
- app.config.ts with monorepo experiment, bundle IDs, scheme
- Workspace packages linked: api, gpx, i18n, map-core, types
- Profile tab imports API_VERSION from @trails-cool/api to verify
  shared package resolution

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 23:05:57 +02:00