The server nests a saved place's category, while the markers and the hover
card read the flat fields a trip place carries, so every pin on a
collection's map was the grey default. The map now hands its places on with
the category's colour, icon and name where the markers look for them.
nativeApi goes to 3 with 5.1.4, whose UI follows a widget or Live Activity
tap that starts the app. The apps refuse an older server with the hint to
update, and check a server they remember once more.
Saving the AirTrail settings with a different URL and the key field left
masked or blank kept the stored key, so the next sync sent the old
instance's key to the new host. The key now goes with the host, as it
already did for the connection test and for Dawarich: a new origin without
a new key clears it, a path edit on the same origin keeps it. The key is
cleared before the new address is written.
A tap on a widget or a Live Activity hands the app
com.liketrek.trek://navigate/<path>. A running app gets it as appUrlOpen;
an app started by the tap gets it as its launch URL, which nothing read, so
the path was lost and the app opened its start page (the packing widget
landed on the trip's plan instead of its lists). The launch link is now
followed once per launch.
A flight created with a day and times but no endpoints (over MCP) showed
them in the form, but buildTransportPayload took a flight's span only from
rows with an airport, so a save sent day, end day and both times as null.
Like a train without stations, such a flight now takes its day, times,
airline, flight number and seat from the raw rows. Endpoints and legs still
come only from rows with an airport.
Fixes#3070
The edit dialog's component crossed the complexity limit with the section's
conditions; the section and its confirm step now live in SsoUnlinkSection,
which decides itself when it shows.
A sign-in the app starts runs through the server's handoff page in the
system browser. When the SSO callback failed (an expired or overwritten
state), the login page dropped the way back to that page, so the retry from
there was a plain web login and ended in the web app inside the app's
browser sheet instead of signing in the app. The login page now keeps a way
back that points at the handoff page, and only that, and renews its
fallback copy for a slow retry. State, nonce, PKCE and the handoff verifier
are unchanged; the handoff page still asks for a tap before it passes
anything on.
- The SSO unlink answers with a response contract (adminSsoUnlinkResponseSchema).
- It reuses linkOidcIdentity with nulls instead of a new repository method,
so UsersRepository keeps its method count and size.
- The client calls the route through apiClient, so api/client.ts does not
grow, and its confirm dialog takes no async callback.
- The pager's preview step and pagesFor keep their complexity.
A sign-in with another subject of the same provider is refused, so an
account whose provider re-issued the subject (a migrated or rebuilt IdP, a
changed sub format) was locked out: editing the email, as the wiki advised,
never touched the stored link. The edit dialog now offers "Remove SSO link"
for other accounts while SSO is set up (DELETE /api/admin/users/:id/sso,
audit admin.user_sso_unlink). The next SSO sign-in links again under the
rules of a first one, so it still needs a verified, not self-set email.
The log line names the remedy, and the wiki tells the two refusals apart.
Fixes#3065
Only the selected day and two on either side were drawn, and the selection
moves only once the strip comes to rest, which iOS takes a while for. A run
of fast swipes ran past the drawn pages into blank ones until it settled.
The drawn window now also follows the day the swipe is heading for, so the
next days are there before they slide in. At most two windows of five pages
are mounted, however long the trip.
Fixes#3067
The transport form re-seeded itself whenever the trip's costs arrived as a
new array, and the booking form whenever days, places or stays did. A
socket reconnect re-reads the whole trip, so behind a proxy that drops idle
sockets every 15 to 30 seconds everything typed so far was wiped. Both forms
now re-seed only for what opens a different form; the data is read when the
form is seeded, as before.
Fixes#3069
- native-shell/amount.ts: the no-break spaces in the price pattern were
written out as characters; \s already matches them.
- widgets.ts: the Live Activity's lead time stays inside the module.
- i18n: the count strings of the new plan tiles replace the removed ones
on NOT_PLURAL, and the address placeholders of the non-Latin locales
are their own instead of English copies.
- mobile.css: the side safe-area margins of the floating bars use
margin-inline, swapped for right to left, instead of physical sides.
The Live Activity started with the first sync of a travel day and stayed on
the lock screen all day, so a day whose first stop is an evening flight held
it from the early morning on. It now appears three hours before the day's
first timed stop and stays until the day is done; liveDayDue() decides.
A load that failed sent the app to the address screen with a general message only, and a tester's screenshot told nothing. The web view's own error (net::ERR_..., an HTTP status, NSURLErrorDomain and its code, a client certificate the proxy asked for) is kept natively and shown under the message once.
The cloud screen shows real screens of the app. The plans are a choice now: one tap marks a plan, the recommended one is marked, what every plan has is said once above them, storage says how many photos it holds, and the yearly switch shows what a year saves; one button at the foot carries the chosen plan on. The claim screen names the plan with a way to change it, shows the address as it will be once it is free, ticks off the password rules while typing, says in three words where the servers are, that it can be cancelled and that there are no ads, and puts the photo behind the form away.
One subscription per Apple ID or Google account. Choosing another plan in the app changed the running subscription on the App Store, and the redeem then failed with 'We could not set up your TREK'. The app now asks the store first and shows a screen of its own: the account already has TREK Cloud, a new one can be taken out once it has ended, with Open my TREK and the store's page to manage it. The native purchase refuses as well; a paid one that was never set up is still redeemed. On the address screens the link 'What is a TREK server?' is gone, and the small print under a purchase is set in the system text face at regular weight.
The iOS app hands the page the safe area it measures, a floor under env() where WebKit reports none, and on a phone the floating bars keep clear of the side insets as well.
A Samsung phone may end the app while the sign-in runs in the browser. The browser's return then started the app anew without the call that waited for it, the first page load failed while the network was still held back, and the user came back to 'server not reachable' and then to the sign-in page, in a loop. The return is now kept natively and redeemed by the sign-in page with the verifier kept until then, and a page that failed on the network is loaded once more before the app gives up.
The import was only offered once the check saw the proxy ask for a certificate during the handshake. A proxy that refuses without asking left no way in. The wiki also points to the certificate's new place in Settings and explains why a certificate from an iOS configuration profile cannot be used by the app.
The dim faded in on the sheet's own parent, and opacity multiplies down the tree, so for its first frames even the opaque sheet let the list behind read through as ghost text (Android tester, expense editor). The dim now fades on a layer of its own beside the sheet, and the card is opaque halfway through its pop.
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.
A tester could not tell which settings follow the account to every device and which stay on the phone, and looked for offline mode for a while. The section list and dropdown now stand under two headings, "Your account" and "This device". The server the app opens, the app lock and a client certificate move out of Account into a section of their own, "App", shown only in the app, next to Offline; About stands under TREK. Labels in all locales. TestFlight feedback, 5.1.3.
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
The two new test files mocked the db module and built VacayService by hand,
which the test-mocks and new-service ratchets refuse for files without a
baseline entry. The cases move back into vacay.service.test.ts and
vacay.test.ts unchanged; VACAY-037 asks for a year no other case caches. The
unrelated admin addon test change is reverted and two comments name the new
provider.
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.
The dashboard, journeys and notifications switched the iOS bounce off entirely so it would not race the pull. The pull now holds only a clearly downward move from the very top, from its first pixel, and the page bounces everywhere else, its end included. TestFlight feedback, 5.1.3.
The page took 100vh with no top inset inside the touch shell, so the plugin's header ran under the status bar and the frame reached past the screen and under the dock. It now takes the visible height (100dvh) less the dock, after the safe area and the rail, and the plugin's own document scrolls. TestFlight feedback, 5.1.3 (Trip Importer).
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.
A field outside a form gets enterkeyhint="done", but a web view only sends Enter and nothing listened, so the key did nothing. When no handler took the Enter (same text, still focused a moment later) the field lets go of the focus; a field that acts on Enter and clears itself keeps it. TestFlight feedback, 5.1.3.
A proxy's block page or a refused client certificate (Cloudflare's "Sorry, you have been blocked") left the app on a page without TREK's UI and no way to change the server. Any 4xx main-frame page that the client-certificate path does not handle now shows the sign-in bar with its own hint and "Change server", on iOS and Android. TestFlight feedback, 5.1.2.
Both files had grown past their size limit with this round's fixes. The
two-factor step moves to pages/login/MfaCodeStep.tsx and the reservation row
types to reservation-rows.ts, re-exported from the repository, and both size
baselines come down to match.
Behind Pangolin or authentik the app shows the proxy's sign-in page itself, and
nothing on it led back to the address screen: a failed passkey left users stuck
on every launch. A bar over that page now offers to change the server and says
that passkeys and security keys do not work there, as a web view cannot use them
for a domain the app is not tied to. It steps aside while the keyboard is up.
On iOS the page also gets the room the keyboard takes, so a button under it can
be scrolled into view. The address screen hands the bar its words in the user's
language when it connects.
The pager held the selected day and two either side, and moved that window
only once the strip had come to rest. Swiping on before the snap settled ran
into the end of the strip after two days and sprang back until the animation
was over. Every day now has its page, only the selection and two either side
draw their content, so a run of swipes goes as far as the trip does.
A booking with stopovers was one stop at its first departure, and a stop
counted as done the moment it began. With a car at one and a connecting flight
at two, the Live Activity said all done for today mid-afternoon. Each leg is
now a stop of its own, as the planner shows it, and a flight or anything else
with an end time counts as under way until it lands or ends.
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.
The prompt looked at the app's features once, when the user counted as signed
in. After the sign-in the page loads with the session already there, and on
iOS the bridge had not named its features yet, so the prompt gave up for good.
It now waits for them. It also counted as asked the moment it opened, so a
sheet that went under another one never came back; it counts once answered.
The code step drops the email field, so a password manager had no login to
match a one-time code to; the step now keeps the address in a hidden username
field. The code field names itself and sets its keyboard hints directly
(characters, no autocorrect), as autoFocus gave it focus before anything could
prepare it, and its placeholder is translated.
The fixes that keep the app's sign-in in the app live in the server's UI,
so an updated app on a 5.1.2 server still ended in the browser. The server now
reports nativeApi 2 and the app refuses anything below it, naming 5.1.3.
A server the app remembers from before is not loaded unchecked: the first
launch after the update shows the address screen filled in with it, says why
and checks it right away. A server that is new enough loads again with its
session; an older one gets the update hint.
The strip re-centred only when its window of pages changed. On a trip of up
to five days a tap can keep the same pages, so the rail showed the new day
while the card below stayed on the old one.
The app's browser sign-in opens /native-handoff, which sends the user on to
the identity provider by itself. The page was not on the list of public auth
pages, so the 401 from loading the user sent the browser to /login with the
hand-off as its return path first. On a server that also offers passwords the
user then had to pick SSO a second time before getting back to the app.
A PDF, image or document opened in the app went straight to the share sheet.
It now opens in Quick Look on iOS, to page through and zoom with its own share
button, and in the app that views its type on Android. An app without the
viewer (feature filePreview), or a type nothing on the device shows, gets the
share sheet as before.