Phone apps (iOS, Android)¶
| iOS | Android | |
|---|---|---|
| Status | ⏳ | ⏳ |
| Code | — | — |
Source: click dummies docs/companion_app/sailever-ios.html and docs/companion_app/sailever-android.html.
Verified against code: 2026-10-11 (no code yet; checked against the click dummies)
Nothing in this folder is built. Every file describes the intended app as the click dummies show it, corrected where a dummy contradicts the server, the website or the glossary. Those corrections are listed under Known deviations in each file, so the dummies can be fixed.
Purpose¶
The phone app is the logbook in your pocket, plus a live chart of the boat while a watch records.
- It shows the same logbook, trips, tracks, boats, devices and account as the website (
/my). Edits made in the app and on the website are the same edits. - While a paired device records a track, the Map tab shows the boat, the track so far and live numbers.
- It adds two chart tools the website doesn't have: measuring a distance and bearing, and planning a route.
The phone never records a track itself. Recording stays on the watch (WatchApp spec). The phone is not needed at sea: the watch records offline and uploads by itself.
Relation to the other products¶
| Product | Relation |
|---|---|
| WatchApp (Garmin, Wear OS, Apple Watch; spec) | Records the tracks. While recording, it streams live values to the phone over Bluetooth (⏳ not built on any watch, see map.md). Uploads go from the watch to the server as today; the phone doesn't relay them. |
| Server (server spec) | Single source of all logbook data. The app reads and writes through a user API that doesn't exist yet (see Server API below). |
| DataField | No relation. The DataField never uploads to SailEver. |
Navigation map¶
Four top-level tabs. Pushed screens cover the tab content; on Android they also hide the bottom navigation.
Map (tab 1, start screen)
├─ Trip chip ─────────────► Trip detail
├─ Avatar ────────────────► Account
├─ Layers sheet
├─ Live panel ─ Open trip ► Trip detail
│ └─ Share position ► system share sheet
└─ Tools ─► Measure tool ⇄ Route tool
Logbook (tab 2)
├─ Underway cell ─────────► Map tab
├─ Public logbook ────────► Public logbook sheet ─► system share sheet
├─ Trip card ─────────────► Trip detail
└─ All trips ─────────────► Trips tab
Trips (tab 3)
├─ Filter / sort chips ───► menus or choice sheets
└─ Trip card ─────────────► Trip detail
├─ Share ──────────► Share trip sheet ─► system share sheet
├─ Edit ───────────► Edit trip ─► Boat form, Share trip sheet
├─ Days ─ night chip ► Night picker
└─ Tracks ─ row ───► Track editor
Boats & devices (tab 4)
├─ Boats ─ row / Add ─────► Boat form
└─ Devices ─ Pair ────────► Pair device ; Rename, Unpair dialogs
Account (from the avatar on every tab)
└─ Add passkey ───────────► system passkey sheet
Files¶
| File | Covers |
|---|---|
| conventions.md | Number and date formats, colours, feedback (toasts, confirmations), shared components, platform patterns |
| map.md | Map tab: chart, boat, live panel, layers |
| chart-tools.md | Measure tool and route tool |
| logbook.md | Logbook tab and the public logbook sheet |
| trips.md | Trips list, trip detail, night picker, edit trip, share trip |
| track-editor.md | Track editor: trim, names, move, delete |
| boats-devices.md | Boats, boat form, devices, pairing, rename, unpair |
| account.md | Profile, passkeys, subscription, app settings, sign out |
Shared and platform-specific design¶
Both apps have the same screens, data, copy and behaviour. They differ only in platform conventions. Brand tokens (colours, fonts) are the web redesign tokens (apps/server/app/assets/stylesheets/tokens.css) on both.
| Aspect | iOS (HIG, iOS 26) | Android (Material 3) |
|---|---|---|
| Tab bar | Floating Liquid Glass tab bar at the bottom; hides while a modal sheet is open | Bottom navigation bar with pill indicator; hidden on pushed screens |
| Titles | Large title that collapses into the navigation bar on scroll | Large title; the top app bar lifts and shows the title on scroll |
| Buttons on the map | Round glass buttons and a glass button stack on the right | Floating action buttons (FAB, small FAB) and an expanding FAB menu |
| Choices (filters, sort, night) | Pull-down menus anchored to the control, check mark on the current value | Modal bottom sheets with radio buttons |
| Edit trip | Page sheet (modal) with ✕ and ✓ | Full-screen dialog with ✕ and Save |
| Boat form | Page sheet (modal) | Modal bottom sheet |
| Pair device | Page sheet (modal) | Dialog |
| Account | Sheet opened from the avatar, closed with Done | Pushed full screen with back arrow |
| Confirmations | Centred alert with Cancel and a red action | Dialog with icon, Cancel and the action as text buttons |
| Feedback | Toast at the top, with optional action | Snackbar at the bottom, with optional action |
| Text case | Title Case for buttons and titles ("Delete Trip") | Sentence case ("Delete trip") |
| Share | UIActivityViewController |
Android sharesheet |
| Passkeys | iCloud Keychain, Face ID / Touch ID | Google Password Manager, fingerprint / face / screen lock |
| Icons | SF Symbols (the dummy uses Material Symbols as a stand-in) | Material Symbols Rounded |
Wording below is given in sentence case. iOS shows the same words in Title Case where the HIG asks for it.
Server API¶
The server has no user API today. The website uses HTML routes under /my with a browser session; the only JSON API (/api/v1) is the device API for watches. The phone app needs a user API with its own sign-in. All of these are ⏳ missing; the names are proposals.
| Need | Website route today | Proposed app endpoint | Status |
|---|---|---|---|
| Sign in (magic link, passkey) and an app token | /auth/magic_link, /auth/passkey (session cookie) |
POST /api/v1/session/magic_link, POST /api/v1/session/passkey, DELETE /api/v1/session |
⏳ missing |
| Logbook totals, year chart, latest trips | GET /my |
GET /api/v1/logbook |
⏳ missing |
| Trip list with filters and sort | GET /my/trips |
GET /api/v1/trips |
⏳ missing |
| Trip detail, days, tracks | GET /my/trips/:id |
GET /api/v1/trips/:id |
⏳ missing |
| Edit and delete a trip | PATCH/DELETE /my/trips/:id |
same, under /api/v1 |
⏳ missing |
| Set the night of a day | PATCH /my/trips/:trip_id/days/:id |
same, under /api/v1 |
⏳ missing |
| Track points, trim, names, move, delete | GET /my/tracks/:id/points.json, PATCH/DELETE /my/tracks/:id |
same, under /api/v1 |
⏳ missing |
| Boats | /my/boats |
/api/v1/boats |
⏳ missing |
| Devices: list, rename, unpair | /my/devices |
/api/v1/devices |
⏳ missing |
| Pair a device with the 6-digit code | POST /pair |
POST /api/v1/devices/pair |
⏳ missing |
| Profile, email change, subscription | /my/profile, /my/account, /my/subscription |
/api/v1/account |
⏳ missing |
| Passkeys | /my/passkeys |
/api/v1/passkeys |
⏳ missing |
Trip share link (sailever.com/t/…) |
none | public page + slug on trips |
⏳ missing on the server too |
Public logbook (sailever.com/@handle) |
none | public page + handle and public_logbook on users |
⏳ missing on the server too |
| Saved routes | none | /api/v1/routes |
⏳ missing, see chart-tools.md |
| Live boat position | none; the server has no live tracking by design (api.md § Endpoints) | none: watch → phone over Bluetooth | ⏳ missing on the watches |
Not in the click dummies¶
These parts of the app are needed but not designed yet. They are open questions, not spec:
- First start, sign-in (magic link, passkey) and sign-up.
- The Map tab when no track is recording.
- Offline behaviour and caching.
- Push notifications (the server sends one email per new trip).
- Uploading FIT files from the phone (the website has Upload tracks), GPX export.
- Buying a subscription in the app.
- Writing a sailing workout to HealthKit or Health Connect. The Wear OS port plan names the phone app as the way to get a Health Connect copy; the Apple Watch port plan says a phone app can come later.
Open questions¶
The whole phone app is ⏳, so these decide what gets built. Listed from ../open-questions.md.
| # | Question |
|---|---|
| M1 | Live link: the live map needs the watch to send values to the phone (Connect IQ phone messaging, Wear Data Layer, WatchConnectivity). That is new work in every watch app and would go into the WatchApp spec. Build it? |
| M2 | User API: add a token-based JSON API for users next to the device API, or wrap the website (Hotwire Native) instead of native screens? |
| M3 | Sign-in and onboarding: magic link as a deep link into the app, passkeys, first-start screens, pairing during onboarding. Not designed yet. |
| M4 | Sharing: share links (/t/{slug}) and a public logbook (/@{handle}) don't exist on the server. Build them for the website first? Who picks the handle? |
| M5 | Map tab without a recording: what does it show (last trip, empty chart at the user's position, or Logbook as the start tab)? |
| M6 | Saved routes: where are they listed, do they sync to the server, can they go to the watch, can they be shared? |
| M7 | Undo after delete: the dummies offer Undo, the website says "can't be undone". Soft delete everywhere, or final everywhere (current spec)? |
| M8 | Purchases: sell plans through App Store / Play billing, or only on the website? |
| M9 | Phone notifications: mirror the watch alerts while connected? Push instead of / next to the trip-created email? |
| M10 | Health: write a sailing workout to HealthKit / Health Connect? |
| M11 | Files and offline: import FIT / GPX, export GPX, cache the logbook and chart tiles for use at sea? |
| M12 | Scope: the phone never records (spec today). Crew following the boat on their own phones: yes or no? |