Commit Graph

12 Commits

Author SHA1 Message Date
Maurice ba0cc331c1 feat(mobile): today marked on the day rail, and a button back to it
While a trip is running, today's chip on the phone carries a ring and a dot, and a button beside the rail jumps back to today from wherever it was scrolled, in the plan and on the map. It stays in place, dimmed, while today is open, so the rail never shifts under the thumb. (#2392)
2026-10-01 10:17:29 +02:00
Luffy 7d22857de8 fix(mobile): restore day selection when reopening a trip 2026-09-29 21:48:26 +02:00
Maurice 843582863c fix(docsync): offer the sync button only where something is behind it
The Documents addon put a "Document sync" button on every trip's Files
tab, and the seed ships every provider switched off, so after the
upgrade each of those buttons led into "No document providers are
available". The button now shows on a trip that is already bound, to
every member, and otherwise only to somebody who may bind the trip on
an instance that offers a provider. Without it the Files toolbar is
the one from before the feature, trash flush right, on both shells.

/api/addons carries no document providers for a normal user, so the
answer comes from the docsync routes through a new online-only
docSyncRepo and is kept per session in docSyncOfferStore. A revisit
renders the last answer at once and checks it again; offline nothing
is asked and the last answer stands. Creating a binding, removing one
and removing a connection now ping the trip with docsync:changed and
zero counts, so a member already on the Files tab sees the button come
and go without leaving it.

Both shells keep listing a binding whose provider the admin has since
switched off instead of claiming there are no providers, and name its
store through one storeName() helper. A load that answers 403 or 404
clears the bindings as well, so they do not linger once the Documents
addon is gone.

The phone admin screen gets the Documents shelf the desktop one has:
the document providers as sub rows under the addon, toggled through the
same admin route and re-read after Documents itself is toggled, because
the server switches the providers off with it.

isTripOwner and the isOwner prop become canManageSync and canManage,
which is what canManageDocSync answers. Both folder pickers take
loadScopes out of the sync object before their effect, so
exhaustive-deps is satisfied without the effect running on every
render.
2026-09-19 13:36:33 +02:00
Maurice bf0ec85372 feat(roadtrip): badges and a place picture on the phone stage bars, a compact head card
The stage bar over the road trip map joined its figures with middle dots
and led with a bare day colour dot. It now leads with a picture of the
place it names (PlaceAvatar, falling back to the category icon), ringed in
the day colour while day colours are on, and shows the stop count, the
arrival and the distance as badges. The header pill over the tab does the
same with the day and the distance, and leaves out a distance nothing has
measured yet instead of printing 0 m. Both bars carry an accessible name
built from their parts, because pills side by side lose the spaces between
them when a screen reader reads them out.

The badges are a new non interactive MBadge, a span, since every place it
sits in is itself a button. The value rules shared by both bars live in
stageBadges.ts.

The head card at the top of the chain is more compact: the drive and the
stop count ride on the date line as badges, the two clocks are a size
smaller and the separate stats band is gone. The day colour dot is gone
from it: on the list half the line it keys lies hidden under the chain, so
it read as an unexplained status light.
2026-09-16 23:21:40 +00:00
Maurice aaff8f9db4 feat(roadtrip): bring the road trip addon to the phone
A road trip tab on the mobile trip screen: the stage as a chain, the same
map underneath it, the sheets a passenger needs, and a search along the
route.

The addon was desktop only because road trip MODE is a data switch rather
than a view switch. It rewrites `assignments` and `places` for the whole
planner hook, and every mobile sheet is permanently mounted and reads those
same two lists, so turning it on there brought back documented regressions.
The mode flag is therefore untouched. A second flag, `roadtripFeedActive`,
feeds only the routing round and does it off the STORED assignments, so the
phone gets the drive without what the mode drags along with it.

The map is one instance shared by the plan tab and the road trip tab,
hoisted into a single JSX expression so React keeps it in the same position
and the WebGL context is never torn down on a tab switch.

The corridor search is scoped to what a phone can afford: a window of the
day rather than all of it, a smaller tile ceiling, a capped retry pass and a
deadline. The standard search is three requests where the desk makes
fifteen. The categories are deliberately not narrowed, because they all ride
one query per box, so a second one costs nothing.

Two gaps found while wiring it up are closed here as well. The fuel search
drew its offers nowhere on the phone, so the button did nothing visible;
they are in the dry band now, with the detour, the spare range and an accept
button. And the map credit opened as a two line ribbon across a screen the
map fills: both GL engines now start it collapsed, and Leaflet, which has no
collapsed mode of its own, is given one.
2026-09-16 21:55:18 +02:00
Maurice 04b31ec2e5 fix(mobile): give the trip map a way back to every day
The phone map filters down to one day and had no way back out. The chip
rail can only swap one day for another, the second tap on the active chip
is the day sheet, and the seed guard deliberately does not re-seed — so a
day picked on the map stayed picked until you left the trip and came back
(#2257). Desktop has had the deselect since the day header got it.

Its own round control beside the rail, map view only: the plan timeline is
single-day, so there is nothing to widen there, and the day sheet keeps the
one route into it that also exists on the map. It toggles — the first press
parks the day it came from and frames the whole trip, the second puts that
day back with its route, or falls back to the focus day if a remote delete
retired it in between. Leaving the map restores it too, since an empty
timeline would be the worse answer.
2026-09-06 13:35:30 +02:00
Maurice 800f97b8ce feat(mobile): swipe the day details to step through days (#2059)
* @
feat(mobile): swipe the day details to step through days

The phone shell hangs the days off a chip rail pinned to the top of the
screen, which on a large phone is a thin target a thumb cannot reach one
handed. The day details fill the rest of the screen and did nothing.

They now take a horizontal swipe: left for the next day, right for the
previous one, with the panel following the finger, rubber banding at the
first and last day and springing back when the swipe falls short. The
chip rail is untouched and still the accessible path; a committed swipe
announces the day it reached through a live region, and the active chip
scrolls itself back into view once the rail overflows.

The gesture never calls preventDefault or stops propagation on a touch
event and sets no touch-action, so the browser keeps sole ownership of
the card scroll and of the header chip strip, and the long press reorder
bridge keeps its own 10px self cancel. In edit mode the swipe also
refuses to claim a press held past the bridge window.
@

* @
fix(mobile): line the map controls up and widen the POI bar

The compass sat on its own under the POI bar, centre top, while the
locate button floated 42px above the dock on the other end of the
screen. Both are one handed controls, so they now share the band just
above the dock: compass bottom left, locate bottom right, off the same
--bottom-nav-h the map already reads, a dock gap lower than before.

That frees the row under the chip rail, so the nearby places bar takes
the full width between the screen margins and its segments end up the
size of everything else the thumb aims at there. Desktop keeps the
floating, content width bar.
@
2026-08-27 12:01:11 +02:00
Maurice 495c5e95ec fix(mobile): drop stale up-next cards and open the plan on the next day (#2057)
The UP NEXT card kept pointing at this morning's first stop hours after it had
started, and at day one of a trip that ended last month. A header promising what
comes next, sitting above something that is over. It now stays away on a day that
has passed and once today's timed plan has run out — a day whose stops carry no
times at all still shows its first stop, there is nothing stale about that. The
timeline card already collapses the reserved space when there is no up-next, so
the layout closes cleanly.

Seeding the plan day also lands on the next day still ahead when today falls into
a gap in the dates, instead of dropping back to day one. A trip that is already
over keeps opening on its first day.

And a day that was selected before the shell mounted now counts as seeded, so
clearing the selection is left alone instead of being re-seeded on the next
render — which is what the guard was there for in the first place.

Based on #2055.
2026-08-27 11:02:09 +02:00
Maurice da92581a16 fix(planner): let a route choice survive the map, and keep new items on their day
Two things the mobile planner forgot.

The day sheet's route toggle only ever lived in component state, and entering
the map — or tapping a day while in it — forced it back on. Turning the route
off therefore did nothing you could see and had reset itself by the time you
looked again. The choice is now remembered per trip; the map still switches it
on by default, but only while the user has never said otherwise.

Adding a place or a booking from inside a day did not connect it to that day.
The place dropped into the unplanned pool, which on mobile is a different screen
— it looks like the save was lost — and the booking opened with no date at all.
Both entry points now carry the day they were opened from, including a
long-press on the mobile map, where the chip rail names a day at all times. The
desktop map has no such context and passes nothing, so its pool behaviour stands.

While here: the import button on the bookings and transports headers only
appeared when kitinerary was installed, though the server also accepts an import
when the LLM parser is configured (#2007).

Closes #2003
Closes #1998
2026-08-21 13:27:27 +02:00
Maurice b267771772 fix(mobile): let the map show one day again
Collapsing a day card has hidden that day's places from the map since #216, and
it was the only way to reduce a busy map to one day. The phone shell does not
render DayPlanSidebar, so when it replaced the desktop page on phones that
control disappeared with it: expandedDayIds stayed null and every day's pins sat
on top of each other with nothing to do about it (#1962).

A day chip in map view now drives the same declutter the desktop chevron drives,
rather than introducing a second filter. Entering the map focuses the selected
day, tapping another chip moves the focus with it, and leaving the map clears it
so the timeline is never looking at a filtered state. Unplanned places stay
visible, exactly as the collapse path has always left them.
2026-08-18 17:40:56 +02:00
Maurice 72a82b3c44 fix(client): work through the findings from the coverage pass
214 items came out of writing the tests. Real defects are corrected, dead code
is removed rather than covered, and the tests that pinned the old behaviour
move with them.

Also drops two agent coverage scratch files that slipped into the coverage PR
and adds the ignore rule that keeps them out.
2026-07-29 12:35:00 +02:00
Maurice c884ddf527 test(mobile): cover the trip screens 2026-07-29 11:55:31 +02:00