DayPlanSidebar grew past its size baseline with the Firefox drag fix. Its drag state (what is dragged, the drop line, the day under the drag, whether a drag happened) and the effect that ends a lost drag move into useDayPlanDragState, typed, which also lowers the file's strict-mode count; size and strict baselines are lowered with it.
vacay.service.test.ts went past the 2000-line limit once the Nager v4 cases were back in it. They move into vacay.holiday-provider.test.ts, which takes VacayService from a Nest testing module over a snapshot db, so neither the db mock nor a hand-built service is needed.
- iOS: the navigation proxy reports an error page through a callback the controller sets; it called the controller's method on itself and did not build.
- keyboard: the done key reads the field's text in the capture phase, before the field's own handler, so a list that adds an item on Enter and clears itself keeps the keyboard; the tests wire it as the app does.
- Ireland migration: the queued writes use addSql instead of awaiting inside loops; only table constants and integer ids reach the SQL.
- tests: the Dawarich GL test types its two layer specs once (strict baseline lowered), the collab test reads the id off the listed message, the reasoning test runs its four servers in parallel, and a wasm copy covers the precompressed branch without a charset.
- en wording: the deviations agreement no longer calls TREK self-hosted.
Firefox fires dragstart while it handles the mouse move that starts the
drag and delivers that move to the page afterwards, button still held.
The listener that clears a drag whose dragend never arrived took that
move as the end of the drag and dropped the drag data at pick-up, so a
stop could only be reordered with its arrows. The same held-button moves
come from the touch polyfill on hybrid laptops throughout a drag. Only a
move with no button held now counts as the drag being over.
The day list also switched its stagger animation back on whenever a drag
ended, which replayed the entrance of every day card ("weird reload").
It now plays once on mount and stays off after the first drag.
Fixes#3041
A multi-day hike restocks on the way: bread in the morning, food for
lunch and supper every day or two. Neither could be searched for.
- Explore pill: new `bakery` and `supermarket` chips. `supermarket`
already existed on the server (shop=supermarket|convenience) but no
pill offered it; `bakery` is new (shop=bakery).
- Along the tour: `bakery` and `supermarket` are offered to a hike,
after its existing kinds so a new hike still starts on the same three.
- TREK places index: `bakery` maps to food_and_drink>casual_eatery>bakery;
`supermarket` is narrowed to grocery and convenience stores, since the
whole food_and_beverage_store branch also brought tobacconists and
wine shops. Both paths checked against a live answer of the index.
As the more specific term, a bakery is no longer listed as a place to
eat when only `food` is asked along a tour.
- Category guess: a bakery or grocer picked from the map was preselected
as Bar/Cafe or Shopping even where the admin had made a Bakery or
Groceries category. The guess now looks for such a category first, by
name in the usual languages or by icon, and keeps the broad one when
there is none. The category icon picker offers Croissant and
ShoppingBasket, the icons the map chips use.
- Labels in every locale; MCP tool description names the new kinds.
A thin, translucent dash over a nearly opaque white casing read as a pale trace and was barely visible on past trips. Full colour, a wider line and longer dashes, shared by the Leaflet and GL layers. TestFlight feedback, 5.1.3.
The edit form fell back to the linked stay's times, the cards read only the
booking's metadata, so a hotel showed 15:00 and 11:00 when edited and no times
in the list. The reservation list now carries the stay's check-in window and
check-out, and the desktop facts and the phone card fall back to them. On the
phone they come first, so a price or a seat cannot push them off the card.
Mapbox GL measures its container on window resizes only. In the app on a
tablet the trip's plan pane closes beside the map without one: the box grew
to the full width while the canvas kept its old size, and the rest stayed
black. Every GL map built through buildGlMap now watches its container and
resizes once per frame while it changes; the observer goes with the map.
Closes#3023
Packing items, tasks and expenses swipe sideways to their actions, as in
Mail or Reminders: done or open one way, delete and edit the other, the
first one run by a full swipe. They are second ways to what each row
already offers; an expense still asks before it goes.
A long press on a trip card lifts it and opens its menu with the card's own
actions. Plain confirmations in MConfirmSheet now also ask through the
system where the app can.
Lists, the atlas and a journey show grey placeholders in their shape while
loading instead of a spinner in an empty screen (MSkeleton); buttons keep
theirs. A picture still loading fades in once it is there; one from the
cache shows at once. In the iOS app the page bounces at its ends again,
except on screens with pull-to-refresh, whose pull it would race; Android
keeps its stretch off.
On iOS a long press on the app icon offers "New trip" and the trip coming
up by its name, set by the UI in its language (TrekShell.setQuickActions,
feature quickActions), and a tap opens it, also from a cold start.
The app's own CSS moves out of index.css into native/nativeApp.css, which
had outgrown its size budget.
After a tap, WebKit and Chrome keep :hover on what was tapped and send a
made-up mouseover, so buttons and rows stayed tinted until the next tap.
While a finger drives the app <html> carries data-touch-input: a PostCSS
step guards every :hover rule with it (no specificity change), and the
made-up mouseover and mouseout stop before any handler. A trackpad or mouse
clears the mark and gets hover back; a browser never sets it.
A control without a press of its own dims the moment a finger lands on it,
after a 60 ms wait so a scroll does not flash rows, and only the innermost
pressed control. A focus: ring no longer stays round a tapped button.
Fields get a fitting return key ("done", "go" in a form, "search" on the
search fields), and addresses, codes and numbers are no longer capitalised
or corrected. Ticking off packing items and tasks, a picker chip, a select
option, a picked date and dragging a plan row now give the haptics a native
list gives.
Confirmations ask through the system where the binary has the new
@capacitor/action-sheet and @capacitor/dialog plugins: a sheet with the
action in red when it destroys something, an alert otherwise, also for
"discard changes" in a sheet. An older app, a browser and a question with a
list under it keep the HTML dialog, as does a system that could not ask.
iOS no longer lifts a page preview on a long press on a link.
The watch's snapshot was rebuilt every fifteen minutes, so a tick in the app or one arriving over the WebSocket did not reach the watch until then. It is now rebuilt as soon as the packing lists or the to-dos change in the offline tables. A tick on the watch goes as a message while the phone is in reach, which wakes the phone app, and a phone app in the background writes it to the server itself, so the trip's other devices hear of it at once instead of when the phone app is next opened.
The desktop's import dialog keeps its markup and moves its logic into
useGoogleRouteImport, unchanged: the link previewed, its stops in order with
the unresolved ones named, and the resolved ones appended to the day picked,
at least two, under one request id per opening and day. The large screens
get the same flow as a sheet, offered on the stage card under the track
offer to a member who may add places to days. The phone has no entry to it.
The mock called the real useIsPhone only while a test left the answer open,
so a map still mounted when the answer was reset rendered with one hook more
and React threw. It now calls the real hook every time and overrides only its
answer.
- useCollabChatData: the resize observer that keeps the chat at its newest
message attaches when the list is drawn (after the messages load), not at
mount when there is no list yet. The test renders the real list after load.
- MCollabTab: the chat stays mounted, hidden, while a board fills the page on
its own, so leaving two panes with Notes picked keeps the half typed
message and the scroll position. The links card hugs its links on a wide
window instead of a page-high empty card.
- openingView: the floored opening zoom and the second fit for the map's own
size apply only beside the pane in the touch shell; the desktop planner
and the phone open at Leaflet's nearest level again.
In the touch shell the back, forward, disclosure, date-range and flow
arrows kept pointing right in Arabic, so Settle up showed the debt the
wrong way round and Vacay's year arrows pointed inward. The shell now
mirrors lucide's direction arrows in right-to-left languages; an icon
that names its own treatment keeps it, and the lightbox arrows stay on
their physical sides.
Latin user text in Arabic rows lost its beginning when cut and moved its
punctuation to the wrong end. Names, titles, addresses and file names take
their direction from their own text (dir=auto) and still line up with the
row; markdown paragraphs, chat messages, poll options and journal stories
are isolated; signed balances, amounts, sizes, rates and leg figures read
as one left-to-right run; URL fields read left to right. Name pairs joined
by an arrow isolate each name and point from the first to the second.
The hero progress and poll result bars fill from the start edge. Arabic
and Hebrew uppercase caption labels grow a step and take the muted ink,
and a todo's due date in a notification is written in the reader's
language instead of as YYYY-MM-DD.
From the large-screen review (visual findings of the shell and the top-level
screens):
- Rail: 80px wide, one caption size for every name (no shrinking per item),
balanced two-line names with every entry as tall as the tallest, short rail
names where a language's word is too long (mobileNav.rail*, all locales),
and near-opaque glass so a map's colours no longer smear through it.
- Rail head: always one 56px circle, so the entries never jump between pages:
the create action, the screen's own action (the vacation calendar's
year/editor switch moves there instead of floating over the days) or the
quiet logo on settings and administration. It stays put while a short rail
scrolls.
- Vacation calendar: weekday letters over each month on a wide window; the
editor's mode switch sits at the foot with room kept for it.
- Docks: More is marked with a ring rather than the centre button's fill, the
dock glass is denser, and lists fade out under the dock instead of showing
in the gap below it.
- Dashboard: trip names get the card's width with the dates under them, the
hero's facts wrap as whole chips, the filter chips scroll with a fade, the
hero ends above the dock on a phone on its side and its buttons sit on a
dark ground; the header bar stands in the content's column.
- Journeys: on a wide window the header is the same glass bar, in the column
of the cards, and the other journeys' label starts with them.
- Notifications: the round chevron back button, in the list's column.
- Settings and administration share one frame and width. Admin's new-user
action sits under the section list's title, the users card header wraps
inside the card, stat labels ellipsize, role badges read in dark mode.
- Collections: one card per place with the status inside it, worded in a
readable mix of its colour.
- Atlas and the journey map frame clear of the rail and the header; the
journey's day bar sits on a glass plate, and a phone on its side gets
smaller cards.
- Rail label tests rewritten for the new rule; FE-MOB-PANES-016 duplicate
renumbered to 017.
From the large-screen review (code findings H1, M1, M2, M3, M4, M7, L1, L3, L4, L6, L7):
- The size class is one value in JavaScript (hooks/sizeClass.ts) and the
stylesheet follows it: MobileShell writes it to the shell as data-size, the
wide:/split: variants and mobile.css key on that instead of media queries of
their own. A window that only grows shorter at the same width while a field
has focus is Android's soft keyboard, not a new window, so the rail, the form
sheets and the panes no longer fold away (and take the focused field with
them) while one types.
- The large-screen layout is the app's only. In a browser the touch shell is
the phone's below 768px and stays compact there, as before this branch.
- Shortcuts are the app's only, so a browser keeps Ctrl+1 and Alt+Left. The
command key is the platform's own (Cmd on Apple, Ctrl elsewhere), digits are
matched by the key's place as well (AZERTY), and nothing runs while a sheet
or another modal dialog is open: the page listens to nothing and the app is
handed no key commands, so Cmd+[ can no longer drop an unsaved form.
- Inside a trip Cmd+N belongs to the trip shell and creates what the tab on
show creates, named after it.
- Inside the touch shell the desktop navbar of the few PageShell routes is
hidden and --nav-h is 0.
- The rail comes before the page in the DOM, so a keyboard reaches it first.
- The phone's deep day colour for a journey card without a photo stays the
phone's; the desktop and shared timelines keep their faint wash. Its card is
opaque, a suggestion included, so the map's names do not read through.
- The trip widget's iPad mini layout keys on the iPad mini's width alone.
- The trip dock gets the scroll-edge strip and the denser dock glass the
global dock has.
- Duplicate test id FE-MOB-PANES-016 renumbered.
Expense, payment, booking, transport, day note, place edit, new trip,
journey entry, collab note, poll, task, packing item and packing import
use the form sheet: one header with its icon tile, a body that scrolls
with a fade, the footer, and full height with the actions beside the
title on a short window. Create New Trip loses its nested section cards.
Details:
- Add payment gets its icon tile and the currency inside the amount field.
- The expense's category field has the same fill as every other field.
- Day and date fields keep their year at phone width; From and To stack
in a narrow form.
- The place sheet's category chip sits under the name, uncut, the photo
on the cards' leading edge, labels in the sheets' small capitals.
- Stars no longer keep a hover preview after a tap.
- A hotel booking shows its stay's check-in and check-out when it has
none of its own, instead of the grey hint reading as a saved time.
- The collab note's title field is labelled Title (common.title).
- Shorter airport hint in German and Russian; long hints end in an ellipsis.
- The journey story grows with its lines (useAutoGrow).
- Member avatars show the member's initial, yours too, and turn over on
a selected chip.
- The trip's More sheet scrolls, dims a short window and is marked in
the dock while open; long titles wrap to two lines.
From a screen by screen pass over the iPad and foldable sizes:
- Card lists (transports, bookings, tasks, polls) flow down their columns
instead of filling rows, so the columns start level and a short card no
longer ends above its neighbour in a ragged row. The cards' own top
margin gives way to an even gap under each, so every column starts on
one line.
- A booking's or transport's title may take two lines in a column of a wide
window instead of being cut after a few words.
- The map beside the plan opened too close: the opening frame was worked
out for the window, not the narrower map, and Leaflet rounded its zoom up
to the next whole level, so the day ran off the top and bottom. The map
now opens at the whole level that fits and, once it knows its own size,
works the frame out again for it (OpeningFrameFit). On a wide window the
touch shell frames a day clear of its floating toolbar and corner
buttons.
- Costs and to-dos in two panes are one element tree with the stacked
arrangement, so a rotation or a fold between them keeps what is typed or
open in either pane, and the row at the top of the list stays at the top.
- The place sheet's category pill has room for its name on a wide window.
On an iPad or an unfolded foldable the list screens kept one phone-wide
column in the middle of the page. They now lay out for the room they have:
- Transports, bookings, polls and tasks put their cards in a grid of as many
phone-wide columns as the page holds (CardGrid), three on a 13" iPad on
its side, two upright, one in a narrow Split View.
- Costs: with room for two panes (split size class) the summary (total,
owe and owed, settle up, final budget, categories) stands in a pane of its
own beside the expenses, each scrolling on its own (TabPanes). The search
field sits in the expenses' column again instead of running past it.
- Files: a grid of tiles with each photo's picture; with room for two panes
the picked file is previewed beside the grid with what it belongs to and
its actions, the way Files on an iPad does. The signed preview address
comes through fileRepo.previewUrl.
- Packing: the categories stand in columns, each card whole in its column;
the action menu drops from its button at a popover's width.
- To-dos: the four smart filters as tiles and the trip's lists in a pane
beside the tasks, which take the filter's name as their head.
- Collab: the chat stays in view at the trailing edge beside the notes,
links or polls, and the header switches only the board. The chat keeps its
place in the tree, so a fold or a rotation into two panes keeps the draft;
a chat at its newest message stays there when its box changes size. Notes
stand as a board in columns.
- Administration and settings share a section list beside the page
(MSectionNav); the stats grid takes four columns.
- Collections: the lists stand in a column beside the places, which take two
columns, and the head names the list on show.
- Journal: the entries become a feed beside the map, under their days, with
photo, place and the start of the story, in step with the map like the
strip of cards it replaces; it fades out under the header.
- The assistant opens as a tall panel at the trailing edge over a dimmed
page, as Slide Over would, instead of covering the whole screen.
- The rail fits every name: a word too wide for it shrinks the label before
it is hyphenated, and the admin entry uses its short name.
- The journeys and notifications headers keep to their column.
- The address screen of the native shell sets the photo as a panel beside
the choices on a large screen on its side.
On a foldable that reports its fold, a leading pane ends at the fold and a
trailing one starts there. Phones keep their layout.
The app shows the touch shell at every size now, an iPad's and an unfolded
foldable's included, instead of switching to the desktop pages from 768px.
One route tree survives rotation, Split View, Stage Manager and folding, and
the app's own features (Wallet, sharing into a trip, the edge swipe back)
are there on the big screen too.
Two size classes drive the layout (hooks/sizeClass.ts, Tailwind variants
wide: and split:):
- wide (600pt and taller than a phone on its side): a glass navigation rail
on the leading edge replaces the dock and holds every destination with its
name; sheets become centred form sheets; the trip's More menu is a popover
beside the rail; lists keep a readable measure; dashboard, journey and
vacay get columns; full-bleed maps run under the floating rail.
- split (900pt): the trip's plan, places or road trip chain sit in a pane
beside the map, which follows the plan's day; the list/map switch hides
and shows the pane like a sidebar; on a foldable that reports its fold the
pane ends at the fold. Settings show their sections beside the page and the
dashboard keeps its widgets in a column of their own.
A hardware keyboard gets the shortcuts an iPad app has (⌘1 to ⌘9 for the
sections, ⌘N, ⌘, , ⌥←/⌥→ through the days, ⌃⌘S for the pane, ⌘[ back),
answered by the page or, with a binary that has the keyCommands feature,
handed to it as native key commands.
The day strip fades at an edge that runs on, journey cards grow on a wide
window and a card without a photo takes the day's colour, and the Leaflet
map measures itself again when its box changes size.
The hero trip goes to the watch in full: every day with its stops and
coordinates, the bookings with reference, seat, platform and both ends,
the packing list and to-dos with ids. Ticks from the watch come back
through TrekShell.takeWatchActions and are written through the trip
store's toggles, so they take the repos and the mutation queue like a tap
in the app.
The trip PDF's print view linked Poppins from fonts.googleapis.com, so printing
a trip sent the reader's IP address to Google, the case German courts treated as
a GDPR breach (LG München I, 3 O 17493/20). It now declares the Poppins files
TREK already ships under /fonts, and the content security policy no longer
allows fonts.googleapis.com or fonts.gstatic.com, so no font can be fetched
from Google again by accident.
components/ may not import from mobile/ (lint:layers). The phone dashboard
mounts the sheet itself, as it already mounted the welcome, and the desktop
dialog no longer asks which shell it is in.
On a phone the head took half the screen, the list scrolled in a small window
and the start button broke over two lines next to the links. The phone now gets
a bottom sheet of the phone shell: a small head with the countdown, the same
content as a list, a full-width start button with the two links under it. The
photo credits open in its place and back, as on the desktop.
- The carousel and timeline tests step by the new 90 ms settle
- The journey search keeps its suggestion type through the fallback
- nearestCardIndex leaves useJourneyCarouselSync, which had grown past its
line limit; WidgetBag is not exported; the test baseline drops by the
non-null assertions a test no longer needs
The journal searched the full text only, which for a hotel in Osaka listed
the Japanese names the index holds. It now asks the planner's typed-ahead
search first (usePlaceSuggestions, the user's language, one billed session
per search), shows each place with where it is, and takes its point from the
details once picked; the full search still answers when there are no
suggestions. (#3003)
Widgets followed the dashboard's trip only, which is the one under way, so a
packing list or to-dos for a trip still being planned could not sit on the
home screen. The trip, today, bookings, to-dos, packing and group widgets now
take a trip in Edit Widget (an AppIntent with the trips running or ahead,
Automatic by default, which keeps following the dashboard); the world map
needs none.
- The app writes a snapshot per trip running or ahead (at most six, the
dashboard's order) and the list to pick from, under their own keys
(feature widgetTrips, so an older binary never mistakes one for the
dashboard's); bags, chat and polls are kept ten minutes, covers per trip
- The widget extension targets iOS 17, which configurable widgets need; the
apps are not released, so no installed widget goes away
- The choices and their texts in the 28 languages of the gallery