mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-20 22:16:26 +00:00
f4750352e61b04e64c2a5ee5d0418912779a2d3a
503 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
f4750352e6 |
fix(tours): fit the merged tracks together after integration
Types, test expectations and helpers the seven tracks each changed on their own, brought in line with the integrated code. tours.service.ts and the tours repository grew past the size limit with every track and hand their row and write helpers to modules of their own. |
||
|
|
2e1dca9fe9 |
feat(tours): let a background check hint at changes of your own wanderer trails
Settings, Integrations, wanderer gains an optional background check of the trails you imported, off until you switch it on. While on, TREK reads the short record of each such trail at most once a day (never its GPX file) and leaves a hint when the trail may have moved on: "may have changed" when only wanderer's change time moved, "changed" when its name or description proves it, and "not checkable" when the trail is gone, no longer yours or carries no change time. Nothing is ever said to be unchanged. A new hint arrives as a notification that opens the tour (a new ?place= link in the planner); the tour's provenance shows it with the source check right beside it, and the card lists all open hints in a dialog, each leading to its tour. The check reads the source in full as before and spends the hint; taking a change in stays the confirmed reimport. No tour is ever changed or deleted. The check only asks through your own connection, only about trails your account imported into trips you can still open, and stops when you switch it off, remove the connection, wanderer refuses the token (until a test passes or a new token is saved) or the admin switches wanderer off; hints and snapshots stay. A run asks at most 25 connections for at most 10 records each, one after another, and an instance that fails (an outage, a rate limit) is left alone for an hour, doubling up to two days. Server: migration 046120 adds the switch and the run bookkeeping to wanderer_connections and the tour_source_hints table (one row per snapshot, for its importer, gone with it). WandererWatchService and an hourly wanderer-watch job on the CronRegistrar live in the tours domain and read through WandererService; GET and PUT /api/integrations/wanderer/watch and GET /api/trips/:tripId/tours/wanderer/sources/:placeId/hint (place_edit, like the check) answer with @trek/shared contracts. A new user notification event, wanderer_source_hint, can be muted per channel. Saving a new token now clears what the last check said about the old one. There is no MCP tool, as for the rest of the personal wanderer connection. All 27 locales carry the strings, and the admin wiki page says what the check does. |
||
|
|
f833a05461 |
feat(tours): point a tour at its trip's packing list
A tour can now point at the packing list of its trip, as a whole or at one of its categories (say "Hiking gear" for a hike), and shows it in its detail. The new Packing list section reads the list live as the user may see it: the backpack tile with the item count on its corner and the category's own colour, how many are packed with a thin progress bar, the first items ticked off or not with their quantity, how many more there are, and a button that opens the trip's Lists tab. Who may change the tour links one, changes it or lets go through a dialog that lists the whole list and every category with its colour and item count, and writes only on its confirm. It is a reference, never a copy: the items stay in Packing, are ticked off and edited there, and each traveller sees in the tour only the items Packing shows them, so an item kept to oneself never shows through a tour. A category that is renamed, cleared or only holds items of others reads as missing, an empty one as empty, a link that could not be read says so with a retry, and while Lists are switched off the link stays, dimmed, and can still be let go. Removing the link, or the tour, leaves the list and every item as they are. Nothing suggests or changes an item by itself. On the server the link is a row of its own in the tours domain (tour_packing_links, migration 046110), one per tour and gone with it. GET, PUT and DELETE /api/trips/:tripId/tours/:placeId/packing-link read it with the trip and change it with place_edit; linking needs the Lists addon and, for a category, an item of it the user can see. The writes answer the tour with its link and tell the trip through tours:changed, so the offline client queues them as writes of the tour and replays them like one. A copied trip keeps its tours' links, a tour saved as new or taken over does not. The MCP tools get_tour_packing, link_tour_packing and unlink_tour_packing run over the same service and checks; the read also hands the tour's facts as context for suggesting what to pack, which only becomes an item through the packing tools. The empty category placeholder now lives in @trek/shared so both sides leave it out alike. All 27 locales carry the new strings, and the wiki describes the link and the tools. |
||
|
|
65fe8cd6e5 |
fix(tours): explain a kept tour without a line, and say the take-over once
Taking a tour kept in a collection into a trip left the user guessing in two places when the tour had no line. The map box stayed an empty grey square that read as a broken map; it now says that there is no line yet, only the waypoints. Why "Line only" is dimmed was only in the tooltip of a disabled button, which never shows on hover, focus or touch; the reason now stands under the two choices, and a disabled tile sits in a span so its tooltip can show as well. A successful take-over said the same sentence twice, as a toast and as the dialog's last word with "Open trip". The toast is gone. The collection strings move out of tours.ts into a tourCollection.ts per locale, keeping their keys, so no locale's tours file grows past the 1000-line limit. The tours locale spec now holds both files to their own counts. |
||
|
|
3fe34061fd |
feat(tours): keep whole tours in collections and take them into trips
A saved tour can now be kept in a collection, apart from any trip, and later made into a tour of another trip. The bookmark button in a tour's footer and in the planner's head (waiting for the save while there are unsaved changes) opens a dialog with every list of the user; a list they may only read stays in it, dimmed with a lock and a tooltip. The list keeps an independent copy: the line, the type, every measure and setting, the waypoints in order with their roles, the origin, and the trip and tour it was saved from as they were called then. Its days, its links to places of the trip and its obstacle decisions stay in the trip, and later changes to the tour do not reach the copy. A collection shows its kept tours as cards above its places: the grade tile with the source badge, measures and the waypoint count as badges, the trip it came from, and who kept it. The owner or an admin of the list can remove one after a question; tours made from it stay. "Add to a trip" shows the kept tour on a map with its facts and numbered waypoints, lists the user's trips (the ones they may not add tours to dimmed), and asks outright whether the waypoints come along. "Line only" keeps the line as saved and adds no waypoints; a tour kept without a line can only bring them. The new tour has an id of its own, no days and no new places, and names the trip and tour it was saved from; the dialog then offers to open that trip. Neither the collection nor the original tour changes. On the server the kept tours are a table of their own in the tours domain (collection_tours, migration 046100), each row written whole once. Every copy, the in-trip "save as new tour", the take-over from another trip and both directions here, now goes through one copy model (tour-copy.helpers) instead of a second one. Reading and removing follow the collection's roles, keeping one also needs access to the source trip, and taking one over needs place_edit on the target trip; the kept tour is read again inside the write, so one removed meanwhile leaves no half-made tour. The MCP tools list_collection_tours, get_collection_tour, save_tour_to_collection, take_over_collection_tour and delete_collection_tour run over the same service and checks. All 27 locales carry the new strings, and the wiki describes the flow. |
||
|
|
3659297af1 |
feat(tours): import KML and KMZ routes as tours, with a preview first
A route planned in Google My Maps or Google Earth can now become a tour without converting it to GPX first. The import button and a file dropped on the tours workspace take .kml and .kmz files beside .gpx, through the same preview, the same import routes and the same transaction as a GPX file. The preview shows every line of the file on its own, numbered, with its distance and heights; two lines of one placemark are numbered after its name and never joined. Heights count only where they are heights: kept for an absolute line, dropped for any other altitude mode and for the all-zero placeholder My Maps writes, so a missing height stays unknown. What the file holds besides its lines (pins, areas, overlays, links to other files) is counted in a dashed card, and nothing is fetched from elsewhere. The KML reading reuses the place import's codec. A KMZ only ever has its KML entry unpacked, counted byte by byte against the decompressed cap whatever its header claims. A file that cannot be read is refused with its reason (damaged, an archive without KML, too large unpacked), and the toast names the file and the reason. A KML or KMZ import keeps the gpx origin of a file import; its provenance names the real format from the stored file name. |
||
|
|
8fa75b3c4e |
feat(tours): show a multi-day tour's stages in the list and put each on a day
A multi-day tour in the planner's list of the trip's tours now unfolds into its stages (MDT-02), so the stages can be seen together and fitted into the trip without leaving the one route they are cut from. - The fold beside a multi-day tour lists its stages in route order, each from stop to stop with its distance, climb, descent and moving time, read off the saved tour the way the planner reads them, and below them what the whole tour adds up to. A value no stage tells is left out, a total some stages do not tell is marked as at least that much and says for how many, and a stage whose route is not planned yet says so. - Each stage has its own day: a pill opens the trip's days, moves the stage to another one or takes it off again. A stage without a day shows a dashed "No day" pill. A day holds a tour, or one of its stages, once, and a stage is on one day at most; the plan's own offline path writes it. - A stage opens in the planner: the tour opens as any tour does and the stage is shown once its points are in. - The day plan names the stage a day holds with its own figures, and the day's route runs to that stage's start and on from its end; the trip map draws that stretch only. The tour list still counts a tour once, however many days hold it or its stages. - A saved change that takes a stage away (its stage end gone, the tour a day tour again, back to the recorded track) takes it off its day in the same write and tells every client; the planner says so before the save. - REST and the assign_place_to_day tool take the stage by the key of the stop it starts at, with the same checks; list_tours names the stops between the stages and the stage each day holds. A day assignment remembers its stage by that key (migration 046010); every assignment made before holds the whole tour, as it did. |
||
|
|
2449616ee9 |
feat(tours): plan a multi-day tour as one route split into stages
A hut-to-hut hike or a paddle trip over several days is now planned in the Tours planner as one tour: the whole route is planned as before, and stops along it are marked as stage ends (MDT-01). The stages are read off that one route in its order, never kept as copies, so a change inside a stage changes the whole tour and every figure on it. - A Day tour / Multi-day tour switch beside the tour type; a stop's menu ends a stage there or lets it go on. Back to a day tour removes every stage end after a confirmation, as one step undo brings back. - The list of points is headed per stage with its distance and moving time; a stop that ends a stage carries a moon at its number, on the map too. - The overview lists the stages from stop to stop with distance, climb, descent and time (hiking rule per stage, paddle estimate per stage, the router's time shared by distance otherwise), marks where each ends across the elevation profile, and a stage of more than a day on the move warns. - A stage end a change cannot keep (its stop removed, moved to an end or made a shaping point) is dropped and said so, with undo, never moved to another point. - A multi-day tour may take a day a stage, so its time limit grows with its stages; the tour keeps its one type, portages included. - The list and the MCP tools show the stage count and where stages end. Stage ends are a flag on the waypoint (migration 046000); a tour without one is a day tour, as every tour saved before. |
||
|
|
acc294dd8e |
fix(atlas): count shared days for every member, keep routes and multi-day tours honest (STA-02)
A day of a tour that names nobody now counts for every member of the trip, not only for its owner. In the planner an empty participant list means everyone, and a full member list is stored back as empty, so members got nothing for most shared tours. Only a day that names participants without the user stays theirs. The tours of a shared trip on no day or only on undated days are now named as not counting for members as well. A whole route a multi-day tour's stages were planned from is no longer dropped on the server as soon as any stage has a day. Each entry carries derived_from_place_id and the shared summary leaves the route out only while one of its stages is done, counted and in the period and type. A route walked last year now still counts when a stage of it is planned for next month or was left out because it fell through, in the Atlas and over MCP alike. A tour on several days is dated on the last of them, as is a recording on no day, so it no longer counts while it is still under way. The info text, the get_tour_activity_stats description and the wiki say so. |
||
|
|
bde2ad2ca8 |
feat(atlas): sum up the tours you have done, by period and type (STA-02)
With the Tours addon on, the Atlas panel gets a third tab, Tours, beside
Stats and Bucket List: what you have done on your tours across all your
trips. A period (all time, this year, the last 12 months or an earlier year)
and a tour type narrow it; the tab shows the distance large with the number
of tours at its corner, the ascent and descent, and the types with their
distance. "Show tours" opens every tour of the period in a dialog with the
same filters, the sums, the split by type and one row per tour.
What counts is said, never guessed. A tour counts once the day it is on is
over, with the values of the planning, badged "Planned" and explained as
not measured. A linked actual track (ACT-01) replaces those values for its
execution, badged "Recorded" and named, and is never added on top nor
counted as a tour of its own. A tour on several days counts once, a whole
route does not count beside the stages planned from it, a paddle tour sums
no heights, and a value nobody knows stays out of the sum, which then reads
"at least". Only the user's own part counts: a day names them among its
participants, or names nobody on a trip of their own; being able to open
somebody else's trip makes none of its tours theirs. Tours still ahead, on
no day or only on undated days are named as not counting. A tour that fell
through can be left out of the sums ("Leave out"): it stays in the plan
and in the list, dimmed, and "Count again" brings it back. Only the user's
own numbers change.
Server: GET /api/tours/activity-stats answers the user's activity entries
across every trip they can open, and PUT /api/tours/activity-stats/exclusions
leaves a tour out or counts it again (the tour must be in such a trip, else
404). A tour_activity_exclusions table keeps the exclusions per user and
tour. The sums are added up by a shared summary in @trek/shared, so the
Atlas and the assistant say the same numbers. MCP: get_tour_activity_stats
and set_tour_activity_excluded over the same service. The tab reads live
and needs a connection, like the rest of the Atlas statistics.
|
||
|
|
6a0c54cb2f |
feat(tours): compare a tour's plan with the track it was actually done with (ACT-02)
Each actual track in a tour's detail now stands beside the plan instead of
on its own: a table names the plan and the actual track as columns, each with
the line it is drawn as on the map, and sets distance, ascent, descent and the
time with breaks side by side. The difference is shown, signed and with an
arrow, only where both values are known and mean the same thing; a planned
total that leaves a stay out reads "at least" and is not subtracted from. A
value one side does not carry is named as missing ("Not in the plan", "Not in
the track", "No time stamps"), never estimated. Below the table, how far the
track left the planned line: its farthest point and the recorded stretches
more than 50 m away, or that there is no line to compare.
On the desktop plan map, "Compare on map" draws the actual track dotted in
the colour of done next to the plan, which stays picked in its own track
colour (and is put back should it be hidden on the map). The recording leaves
the map as a tour of its own meanwhile, so it is never drawn twice or in a
plan's colour. A frosted legend over the map names both lines and ends the
comparison; so do closing the detail, comparing another track, or the track
being unlinked. Comparing only reads: neither the plan nor the track changes.
The track is laid into the day's route lines the map already draws, so both
renderers show it without a layer of their own. distancesToLine in the shared
route corridor measures many points against one line laid flat once; a long
recording is measured in at most 1500 samples.
|
||
|
|
a8be1c5b45 |
fix(tours): keep unknown actual tracks unknown and name every track a link replaces (ACT-01)
A tour detail that cannot be read (offline without a cached copy, or a server error) no longer shows "No actual track yet" while the trip list names tracks of the tour; the section says they could not be loaded and offers no link over them. The day a track was recorded on is the viewer's calendar day of its first time stamp, not the UTC one, in the tour detail, the link dialog and the GPX preview alike, through one helper. Taking a tour off a day keeps its actual track without a day, so "no day" can hold several. A change now starts on the track it was asked for, and the link dialog names every track it replaces, as the server clears all of them. The migration, repository, service and MCP texts say so. The refusal for linking a tour to itself or a track with tracks of its own now reads "This track cannot be linked to this tour", which is true of both, and the offline helper of the tour cache sits above the doc of replaceTripTours again. |
||
|
|
d0cc6fc2f4 |
feat(tours): link the track a tour was actually done with, and show its own values (ACT-01)
A planned tour can now be given the track it was actually done with. In the tour's detail, "Add actual track" opens a dialog that asks for the day the tour was done on (or none) and a recording of the trip: an import nobody planned over, or a new one through the existing GPX import, its preview preset to the tour's type. What the choice measures is shown before anything is written, and only "Link" writes. The linked track keeps its own name and source; the detail shows its distance, heights, profile and, only where the file carried time stamps, the time it took, marked as actual values next to the untouched plan. A track can be changed or unlinked again. Server: a tour_activities table points a tour's execution (a day assignment, or none) at a recording of the same trip, and the tours GPX import keeps the first and last time of a track whose every point carries one. The values are read from the recording's own line on every read, so a changed recording updates them while the plan's line, measures and revision stay as they were. Every check runs inside the write: the recording must be an import of this trip not planned over, documenting no other tour; the day must be one of this tour; a refusal names its reason and changes nothing. PUT and DELETE /api/trips/:tripId/tours/:placeId/activities answer the detail, which now carries the actual tracks; the list names them per tour and per recording. MCP: assign_tour_track and unassign_tour_track over the same service and checks, get_tour_plan reads the values without the line. A recording linked as a tour's actual track is no longer counted as a tour of its own in the trip's tour summary, and the GPX preview imports a city walk as one instead of as a hike. |
||
|
|
f016972a4e |
fix(tours): explain and offer to re-ask hike ways that could not be asked
A way OpenStreetMap could not be asked about this time now carries a tooltip saying so, and the unknown list offers to ask again whenever such a row is there, not only when nothing at all was answered. |
||
|
|
f745ca13c9 |
feat(tours): suggest round hikes of about a wished length from a stop (RTE-03)
A hike can now be planned as a round out of one of its stops without building the loop point by point. "Round hike from here" in a stop's menu, or the round button in the head of the waypoints for the start, opens a card over the planner map: the start (any stop of the tour, picked from a list), the wished length in the traveller's unit, the window of a fifth either way it allows, and the tour's hiking limit, which every question to the router keeps to together with the hike's preferences. TREK looks for up to three different rounds itself on the hiking router it already uses. It steers loops round circles in several directions from the start, asks a loop that missed the length once more at a corrected size, and learns from each answer how much longer the paths are than straight lines. A loop that walks most of its ground twice (a way there and back), a spot too far from any path, and a round that repeats one found are left out, and nothing outside the window is offered. The rounds show up in their colours on the map and in 3D as they are found, the map frames the area they can lie in, and each lists its length, how far it lies off the wish, climb, descent and walking time once the heights are in. Fewer rounds than three, none, or a router that does not answer are said so. Showing, choosing and closing change nothing. "Take this round" puts the start, the steering spots as shaping points and the way back in place of the plan as one step of the history, with a "Round taken" note and its undo; a tour that held more than its start asks first. The round is then an ordinary tour to edit and save. A start moved or a limit changed while rounds are shown lets them go and the card says why. The card shares its frame, buttons and rows with the comparison of a section's ways, and the map corner still holds one card at a time. |
||
|
|
64445a5204 |
feat(tours): compare other ways for one section of a hike (RTE-02)
A routed section of a hike between two neighbouring points can now be compared with the other ways the router knows between the same two points, under the same limit and preferences. "Compare ways for the next leg" in a waypoint's menu opens a card over the planner map: the way taken now and up to three others, each drawn on the map in its own colour, with length, climb, descent and walking time by the signposts' rule. Figures without heights stay unknown, and the differences to the current way are shown only where both are known. When the router knows no other way, or does not answer, the card says so. Showing, hovering and choosing change nothing. Only "Take this way" does: the router is first asked whether a few shaping points hold the chosen way (the check the road trip's picker already uses), and only then are they set into that one leg as a single step of the history, with a "Way taken" note and its undo at the foot of the map. Other legs, fixed lines, days and points stay as they were, the totals follow from the replanned route, and the shaping points can be dragged like any other. A section that changed while the router was asked, or a way it does not keep to, is not written, and the card says why. The ways are drawn in 3D too. |
||
|
|
3572f4b8a3 |
feat(tours): show the known surfaces and way types along a hike (MAP-04)
The hike's "SAC grades" card becomes "Trail details": one switch, then a segmented choice between SAC, Surface and Way type, three things kept apart and drawn along the route on the planner map one at a time. Every facet reads from the same answer: the ways under the line are matched on foot once, their OpenStreetMap values fetched once through the trail-grades read MAP-03 already uses, and each stretch is placed against the tour's own line once. Switching facets asks nothing new. The server now hands on a way's surface and highway tags as OpenStreetMap wrote them, only trimmed and bounded. The planner groups them (asphalt or concrete, paving stones, compacted, gravel, natural ground, grass, rock, wood or metal, unpaved without a kind, other; path, footway, steps, farm or forest track, cycle path, minor road, road, via ferrata, other), and each row's tooltip names the values recorded, such as surface=gravel, surface=pebblestone. The router's own surface reading is never used: it is normalised and a default where nothing is recorded. What is not known stays unknown and says why, in every facet: no value recorded, a value no group takes or two at once (unclear, never the nearest group), no way clearly under the tour's line, or a way that could not be asked about. Imported tracks and hand-drawn stretches keep their geometry; a matched way only counts where it keeps within 25 m of it. A summary badge gives the known share and the most common class; the SAC facet keeps its highest step and routing limit badges. Nothing about the tour, its places or its days changes, and no routing preference is set. |
||
|
|
ea9e997338 |
feat(tours): show the known SAC grades along a hike (MAP-03)
A hike in the planner, being edited or viewed as an import, now has an "SAC grades" card. Switched on, it asks the router which OpenStreetMap ways lie under the line (matched on foot, every grade of path open) and the server reads their sac_scale through the Overpass mirrors, the same trail-grades read the mountain bike grades use. The grades are drawn along the route on the planner map in one ramp of a single hue, T1 to T6, and listed by share and length; a row draws its class alone. Each row names its source in a tooltip: the SAC hiking scale and the sac_scale value OpenStreetMap wrote. What is not known stays unknown and says why, never T1: a way without a grade, a grade that names no single step (handed on as written), a stretch with no way clearly under the tour's line, or a way that could not be asked about. For imported tracks and stretches drawn by hand a matched way only counts where it keeps within 25 m of the tour's own line, so the original line is kept and nothing is guessed. The router's own reading of the scale is not asked for, since it may be normalised. The routing limit of a planned hike sits apart as a setting with its own badge, and a known step above it is marked. Nothing about the tour, its places or its days changes; switched off, the map is as it was. No regional colour categories and no grade derived from slope, height or trail markings. |
||
|
|
b177daea3c |
fix(tours): point undo_tour_change at the revision prepare_tour_undo returns
The expected_revision field told assistants to read now.revision of the preview, but prepare_tour_undo never returns that field: the revision sits at undo.expected_revision. An assistant following the description either guessed or left the value out and ran into a validation error or a revision conflict. The description now names the real field, and the schema spec pins it. |
||
|
|
63a7a4d397 |
feat(tours): undo_tour_change takes back a saved change to a tour once the traveller confirmed it
An assistant can now take back a change it saved with save_tour_change, the way the change was saved: listed, shown, then taken back only after the traveller said yes. Until now a saved step could be followed but not undone; the traveller had to rebuild the walk by hand in the planner. - list_tour_change_steps lists the steps of a tour, the latest first, with the changes as confirmed and where each stands: latest, undone, later change on top or no readable earlier state. Planner saves are no steps. - prepare_tour_undo shows what taking a step back does without writing anything: the tour now, with the stations visited or skipped, set against the tour exactly as the step kept it, the stations kept, coming back and removed, and the distance and walking time stored then. - undo_tour_change restores that tour whole or not at all, through the write the planner's save uses: line, stations with their keys and the measures stored then, in one transaction with the mark on the step, and the trip is told after the commit. It needs place editing on the trip and checks everything again inside the write. - Only the tour's latest change goes back. A step something was saved on top of since, in the planner or by another step, is a conflict on the tour's one revision (no second one), so no later edit is lost unseen; a preview read at another revision is a conflict too. Taking back a step that would remove a station visited or skipped since, or bring back a station whose place of the trip is gone, is refused with every reason, and so is a step without a readable earlier state. Every refusal and failure leaves the tour as it is. - A step is taken back once: tour_change_steps records the revision that raised the tour to, who confirmed it and when, and nothing else is kept. - None of it touches a planner draft: the planner's own undo stays in the browser, and discarding a draft never changes a saved tour. The tool descriptions and the wiki say so. The write of a tour's line and points and the tour as the answer gives it now come from one place for the save and the undo. |
||
|
|
f4533fc69b |
feat(tours): save_tour_change saves a confirmed change to a city walk whole or not at all
An assistant can now save the change prepare_tour_change prepared, once the traveller said yes to it exactly as shown. Until now a proposal could only be looked at; the traveller had to redo it by hand in the planner. - The save names the proposal: the same changes, the revision it was prepared on, the proposal_id the preparation answered and confirmed true. Anything else, a change altered on the way or no yes, is refused and nothing is saved. - Place editing on the trip and the tour are checked again before anything is written. A tour changed since the proposal was prepared is a conflict on the tour's one revision (no second one), telling the assistant to prepare the change anew instead of writing over newer edits. The changes are laid on the saved tour once more inside the write, so a station visited or skipped meanwhile, or a place of the trip gone, refuses the save with every reason. - The change goes through the write the planner's save uses, in one transaction: line, stations, keys, measures and visits together or not at all, and the trip is told only after the commit. Stations kept keep their keys and visits. Where the router gives no way on foot the walk keeps its stations only and waits for the planner, as a created one does. - Every save is kept as a step of the tour (tour_change_steps): the proposal, the revision it was prepared on and the one it raised the tour to, the changes and the tour as it was before them, so the step can be followed and taken back later. Nothing of the conversation is kept. - A new walk has no revision to name and stays with create_city_walk; both tool descriptions and the wiki say which is which. |
||
|
|
1969ca57d9 |
feat(tours): prepare_tour_change prepares a change to a saved city walk for review
An assistant can now prepare a change to a saved city walk and show the traveller what it would do before anything is saved. Preparing writes nothing: no tour, station, visit or day plan changes, and turning the proposal down keeps the plan as it was. - The changes apply in order and name the saved stations by their keys: add a station after another (a spontaneous stop is an add after the station the traveller is at), remove, replace and move. Stops put after the same station keep the order they were given in. - What the travellers did stays as it is: a station visited or skipped on any day of the walk is never removed, replaced or moved, nothing goes before the last station already done, a protected station keeps its place and a leg drawn by hand stays as drawn. A proposal breaking a rule is refused whole, naming every change and why. Other tour types, and a walk that is a recorded track, are refused too: so far only a city walk takes prepared changes, since the others plan their way with routing of their own the server cannot run. - The answer sets the walk after the change against the saved one: each station with what changed it and where it stood, what was removed, the way on foot before and after planned by the same router (the stored distance and walking time given apart, never mixed in), the stays as far as known, every leg with the new ones marked, the gaps that could not be worked out, a warning for a must station removed or replaced, and each new station as create_place takes it, to keep it for later as a place of the trip instead. - The proposal names the revision it was prepared on, so a save of it is refused once the tour has moved on, and says whether the traveller may change the trip's places at all. The way on foot of a new walk, its creation and a prepared change now come from one CityWalkFootWayService instead of a copy in the briefing service. |
||
|
|
6577595058 |
feat(tours): take a recorded ride from a GPX file as it was ridden
A ride recorded elsewhere comes in through the one Tours GPX import (HOR-02): pick the file, choose Horse ride in the preview and confirm. Once a ride is chosen, the preview says in three badges what the import will and will not do for it: the line stays as the file recorded it, no riding time is worked out, and nothing checks whether its ways may be ridden. Each badge gives its reason in a tooltip, reachable by keyboard. Nothing is stored before the confirmation. Opened again, the ride's rail carries a Recorded ride card with the same badges above its measures, and names heights the file did not carry instead of showing them as zero. Its origin and file name stay in the tour's provenance, it goes on a day like any tour, and no editable version is planned from it on foot. The import itself was already canonical and needed no change; end to end tests now pin what this card promises: the stored line equals the recorded points, the ride keeps its origin, distance and heights and has no riding time, a file without heights keeps them unknown, a failed or refused import leaves an existing ride and its place untouched, and the same file twice is skipped. |
||
|
|
78366a9024 |
fix(tours): long rides save, the horse route store stays bounded
A ride sends its full line with heights and every horse route section's own line besides, about fifty bytes a point, so a ride along a few thousand points of bridleway hit the API's 100kb body ceiling and the save failed with a 413. Creating and editing a tour are now measured against TOUR_WRITE_MAX_BYTES (2 MB), like the book and list file routes; every other route, the tour copy among them, keeps 100kb. The horse routes kept in memory are now bounded by section points as well as by count (64 answers, 500k points), so panning a dense map can no longer grow the server by hundreds of megabytes. A search that found no connection can be asked again on the view whose routes are shown, and a ride with a recorded time shows the horseshoe beside its riding time instead of footprints. |
||
|
|
0331d9950f |
feat(tours): plan rides on horseback from signposted horse routes
A tour can now be a ride (HOR-01). The planner offers "Horse ride" as a tour type with its own horseshoe, and a Horse routes card beside the waypoints looks, when asked, for the route=horse relations OpenStreetMap knows in the map view. A route opens in a dialog that shows it on a map in the sections it is made of, split at forks, gaps and crossings, so nothing is ever joined across a gap. The rider picks a section and its direction, sees what the horse=* tags along it say (open, limited, closed, or unknown where untagged) and whether it is signposted the other way, and takes it as one undoable step. A section that does not start where the ride ends is only joined by a straight manual stretch once the rider switched that on. Nothing of a ride is routed: every leg follows a section or is drawn by hand, and the waypoint list and the map say which (a section as a solid line with its route, a manual stretch dashed and marked unchecked). A point at a section stays where the route has it, a ride works out no riding time, and distance, heights, day assignment, GPX import and export, the 3D view and the reversed ride keep working with each leg's origin saved and opened again. A failed lookup leaves the ride and the routes already found as they were. The server reads the routes through the shared Overpass client (GET /api/trips/:tripId/tours/horse-routes, Tours addon, trip access), keeps an answer twelve hours per grid-aligned view, and the tour contract refuses a routed leg, a via ferrata or a riding time on a ride and a horse route section on any other type. A migration enables the horse tour type. |
||
|
|
008aaeb408 |
fix(tours): say to zoom in when the pistes are on further out than they draw
The pistes overlay has no tiles below zoom 9, so switching it on at a region or country view left the map empty while the switch looked on, which read as broken. Both maps now report their zoom with the viewport, on the 256 px tile scale raster sources count in (a GL map's own zoom is one step lower there), and the planner hands it to its overlays. While the pistes are on and the map is further out than their first tiles, the switch stays pressed in the soft accent, its tooltip and the key's first line say to zoom in, and the screen reader hears it once. An unknown zoom claims nothing. |
||
|
|
5ff7e54e09 |
feat(tours): lay pistes, cross-country trails and lifts over the planner map
SKI-01. The Tours planner's layer switch gains a winter layer: OpenSnowMap's transparent piste overlay over whichever base map is shown, so a ski area can be looked at while preparing a winter trip. It is offered with no tour open (a resort without any route), beside a hike for winter hiking and on an imported ski track; it needs neither a GPX import nor the ski type, and a bike tour, a run and a paddle tour do not offer it. It is off until switched on, and the choice belongs to the map view: switching it changes no point, no step and no route, and it stays on from no tour to a hike and into 3D, where the terrain draws it too. The switch goes by its icon alone, named by its tooltip, so a hike's row stays short. While the layer shows, a small key button rides beside it in the same pill, its badge the four grade colours. The key opens above the map as a popover: the downhill grades in OpenSnowMap's own colours (novice, easy, intermediate, advanced, expert, freeride), cross-country trails, winter and snowshoe trails, toboggan runs and lifts, a note that this is mapped data that says nothing about what is open or groomed, the snow or avalanches, and a link to the full key at OpenSnowMap. If the tiles stop coming, the switch turns to the warning tone with its badge and says that the map and the route still work, and the key stays away. Only the overlay is used, never OpenSnowMap's relief or base maps. Like every overlay it loads only the tiles in view: nothing is prefetched or cached by the Service Worker, as their terms forbid bulk downloads. The tiles go out with the page's origin as the referer, the attribution credits OpenSnowMap (CC BY-SA) and the OpenStreetMap contributors, and the layer stops at zoom 18, beyond which the server answers a picture instead of a transparent tile. The CSP admits tiles.opensnowmap.org for the GL map, which reads tiles through fetch. |
||
|
|
0169be3d79 |
feat(tours): import a ski track from GPX and keep it as recorded
SKI-02. Ski joins the types a GPX file can be imported as, offered in the import preview's type field only: TREK routes no ski track, so the planner never offers it. The preview asks for the discipline on purpose (alpine, snowboard, cross-country or ski touring, none chosen at first) and, for cross-country, the technique (classic, skating or unknown); Import waits until both are named, and the technique stays in sight but dimmed for the other disciplines. The track is stored exactly as recorded, with its file name as provenance, its distance and heights from the file and no time: no ski time is worked out and no hiking estimate stands in for one. Opened in the planner, a ski track gets a rail card with its discipline on a tinted tile, a cross-country technique as a badge beside it, the ski time said as not worked out, and an info dot on what TREK does not say (snow, avalanches, open runs, and that the 3D gradient colours are no difficulty or avalanche rating). Change opens a dialog to classify the track again; only the classification changes, through the offline core, with the revision it was made at. Planning over the import is not offered for ski. The existing 3D terrain view, the elevation profile and its focus work on the track as for any import, with the standard map, topo and satellite and no via ferratas. Lists, the day plan and the detail show the discipline as a frosted corner badge on the tile and as a pill with the technique inside; day assignment, copies and take-overs work as for any tour. The corner badge is now one component that the winter label shares. The server keeps tours.ski_discipline and tours.ski_technique (CHECK lists, NULL on every other type), switches the ski type on without a routing profile, refuses a ski import without its discipline, a technique outside cross-country and ski fields on any other type, and takes a planned save's classification off. PUT /api/trips/:tripId/tours/:placeId/ski classifies a ski track again (place_edit, 409 on a stale revision, 400 for a tour that is no ski track) and broadcasts tours:changed. GPX export names the discipline (alpine_skiing, snowboarding, cross_country_skiing, backcountry_skiing), and list_tours describes both fields with what a ski track does not say. Ski is labelled plainly as Ski in every language, so it no longer reads as ski touring. |
||
|
|
68907ec811 |
fix(tours): name the path grades on the run card without dashes
The run card's grade rows and its hardest-grade badge borrowed the hiking
limit's labels, which read 'T1 — Hiking'. The card now has its own labels in
the bike card's style ('T1, hiking') in every language, and the hiking limit
keeps its own wording.
|
||
|
|
51bfb5abd1 |
feat(tours): plan a trail run on forest tracks and natural paths
RUN-02. Trail running joins Running as a run profile, chosen on purpose in the planner and in the GPX import. It asks Valhalla's pedestrian costing for tracks wherever they serve (use_tracks 1) and admits mountain paths up to T2 (max_hiking_difficulty 2), never T3 and above, with ferries only where no way on land exists. Checked with trace_attributes against the public instance: above Freiburg Guenterstal up to the Schauinsland the route went from 82 % roads and 83 % paved (running) to 78 % forest tracks and 81 % compacted, gravel and dirt; Rathen to the Bastei took 28 % of T2 path that running leaves out; Heidelberg's old town stayed as it was. Leaning on footways (walkway_factor) was tried and left out, it moved runs onto paved footways. While a run is planned, a card says what it runs on: its surfaces, the hiking grades of its paths (sac_scale, T1 to T6, as mappers gave them) and its kinds of way, each as shares with lengths that point at their stretches on the map. A way without a grade or a surface is its own row, unknown and never easy, and an info dot says the grades say nothing about whether a way can be run. The head carries the unpaved share and the hardest graded path as badges. The line is matched on foot for this, so steps and mountain paths stay on it; a bike tour's is matched as before. Reading fails, goes offline or is retried as for a bike tour, and nothing of it changes the run. Pace and time are RUN-01's: the running time stays the distance at the runner's pace, with climbs, descents and difficulty left out, whatever the profile. A profile change plans the route again and keeps the pace; a failed trail route keeps the last route and holds Save back. The card's building blocks moved out of the bike card into RouteWaySections, so both cards share one set of rows, bars and status lines. The run_profile column already allowed trail (RUN-01), so no migration. GPX export names a trail run trail_running, list_tours describes the profile as a routing preference, never a statement that a way can be run. |
||
|
|
1d9b9bf838 |
fix(tours): read a run pace the way runners write it, and keep it
A pace typed as "5.30" or "5,45" is now read as 5:30 and 5:45, the way
it is written in much of Europe, instead of quietly becoming 5:18 and
5:27. One digit after the point stays a tenth of a minute ("5,5" is
5:30); anything else is marked as no pace.
The pace field no longer flashes the out-of-bounds error while a pace
is still being typed: the first digit of "12:30" reads as 1:00, so a
pace outside the bounds now reaches the planner only on leaving the
field or pressing Enter, like text that is no pace already did.
The pace unit is translated ("мин/км", "分/km" and so on) in the field,
the sum the running time is and the pace pills, so what is shown
matches what assistive tech reads out.
A run planned over in place again keeps the pace it holds, so the
runner need not type it again before Save.
|
||
|
|
c83eb42730 |
feat(tours): plan a run at your own pace
RUN-01. Run joins the tour types in the planner, with Running as its first profile, chosen on purpose like a bike tour's. A run is routed on foot for runnable, mostly paved ways: tracks and ferries only where there is no other way (use_tracks 0, use_ferry 0, measured against the public Valhalla), no hiking limit and no via ferrata. The runner types a pace in min/km; the running time is the distance at that pace and nothing else, shown under the field as badges (8 km x 6:00 /km = 48 min). TREK suggests no pace: without one the time stays unknown and Save waits, text that is no pace or a pace outside 2:00 to 20:00 is marked. The info dot, the overview and the head say climbs, descents and difficulty are not in the time, and the time reads as planned everywhere, so it never passes for a recorded one; the heights are shown as for any tour on land. Type, profile, pace and route come back on opening, survive a draft reload, an undo of the type, a copy and a take-over; switching to another type drops profile and pace. Day assignment, the 3D terrain view (with topo and satellite, no ferratas) and a routing failure keeping the last route work as for every tour. A GPX file can be imported as a run with its profile and no pace, and planned over as a run. Runs export to GPX as running and get their own places along the way (water, toilets, parks, viewpoints). The server keeps tours.run_profile (CHECK list, already holding trail for RUN-02, since SQLite cannot widen a CHECK in place) and tours.run_pace_seconds_per_km (120 to 1200), switches the run type on, refuses a run without a profile and run fields on any other type, and list_tours names both with what the planned time does not include. |
||
|
|
cd407cf80c |
feat(tours): a hike can be marked as a winter hike or a snowshoe hike
HIK-01. The details of the hiking planner gain an optional Winter activity switch, off by default, so the normal hiking flow asks for nothing more. Switched on, the hike is a winter hike or a snowshoe hike; the choice stays dimmed and out of reach while the switch is off. The label is saved with the tour, comes back when it is opened, survives a draft reload, a copy and a take-over, and switching it off takes only the label away: the route, its grade and the days stay as they were. The label is a label only. Routing, the walking time and the 3D terrain view work as for any hike, and the info dot and the head pill's tooltip say that nothing was checked for snow, avalanches or whether a path can be walked in winter. The saved label shows as a frosted snowflake on the corner of the tour's tile in the tour list and the day plan, and as a pill beside the type in the tour's detail. The server keeps it in tours.winter_activity (CHECK list, NULL for every tour saved before and for every other type), refuses it on a bike tour, a city walk and a paddle tour, and keeps the stored label when an older client saves a hike without the field. A snowshoe hike exports to GPX as snowshoeing. list_tours names the field, with the same words on what it does not say. |
||
|
|
71fe69c1f1 |
feat(tours): mark the best known places along a city walk
A search for sights along a tour now also asks the places index for the best known places near the line, ranked by how often their Wikipedia articles are read (QRank). A row the index already found is marked as a highlight; a famous sight no kind names, like a square, is added as a sight of its own. Stations, hotels and restaurants rank a row they match but are never added. Highlights are listed first with a star in the list and a badge in the map card. A place counts as a highlight from 40000 views a year, or the best three from 5000 where fewer reach that. An index without ranks, or one older than the endpoint, leaves the search as it was. |
||
|
|
3882feec5c |
fix(tours): the last review findings of the city walks
A place closing at midnight is no longer read as open past it: the hours run on only where the next date opens at midnight (any window of the day counts, as written order is kept), and an impossible date such as 2026-02-31 reads as unknown instead of rolling into March. The hours source names the trip's places rather than "your own" entries, in all 27 locales, as the pill beside it does. The day a walk's arrivals are checked for shows its date on the pill, not only "Day N". The 12 hour clock is tested for a window to midnight. The along-the-tour term table is built once again, now that the one test that stubbed the places client without its real exports spreads them. New test seeding goes through the ORM factories. |
||
|
|
0344db6d0c |
test(shared): count the tour keys without the four hint lines taken out
The stay-unknown pill, the along-the-tour intro, its undo hint and the own theme line left the tours domain in the previous commit. |
||
|
|
5d265c98de |
feat(tours): places along the tour picked on the map, stops that keep their kind, and calmer station rows
Along the tour (PLN-02, PLN-03): the list shows one line per place (its icon, name and distance from the route) and scrolls past ten. A place picked in the list or on the map opens its card over the map, where the other cards of the planner sit, with what the source says and the way to take it in as a stop. What taking it in did is one line in the list. The intro, the theme line and the out-of-date note are gone: the themes say what they look for on hover, and the search button says when to search again. A stop taken in from there keeps the kind of place it was found as (migration 045400, poi_category, read back only where the contract knows the kind) and its number carries that kind's icon at the corner, as a via ferrata's end does. City walks (CW-02, CW-03, CW-10): a stay nobody entered says nothing. While no stay is entered at all the walk is planned as its walking time, with no "unknown" and no "at least". A must-see rings its number, an optional stop has a dashed ring, a protected one a shield at the corner; only the stay stays under the name, below the coordinates. |
||
|
|
554d6f1b9f |
feat(tours): a city walk prepared from a briefing over MCP, and the station fields an assistant reads spelled out (CW-10, CW-11)
An assistant connected over MCP can now prepare a city walk from what the traveller tells it. propose_city_walk takes a start (and an end), a time frame on a day of the trip, the themes of CW-05, the stations the traveller wishes for, the places of the trip it may use and fixed appointments with their times, and saves nothing. Places for the themes come from the search along a tour, at most eight, each with the theme, category and source that brought it; nothing is made up. The stations are ordered on estimates over the straight distance, and a place of a theme or of the trip goes in only where it is open on arrival, keeps the frame and the appointments, and leaves every station already on the walk open when the walk gets there. The walk in that order is then planned on foot by the router the road trip uses (the traveller's own routing server where they set one), and its legs give the walking distance and time from one station to the next. Where the router cannot be reached, or a station lies more than 300 m off every way (the planner's limit, now shared with the server), the times are estimates over the straight distance with an allowance for streets at 4.5 km/h, and the answer says so and why. The answer gives the arrival and leave times, the stay where the traveller gave it and unknown otherwise, which makes every later arrival the earliest one, and the opening hours checked against the arrival on that day with the helpers the planner uses. Walking and stays are counted apart, the total is complete only when every stay is known, and the minutes the frame leaves for the unknown stays are named. Free time before an appointment or at the end, wishes and appointments that cannot be kept as asked, and places left out with their reason are listed; a tour of the trip offered as a station is named as a tour. A wish or an appointment is never dropped; an appointment is a must and protected. A place's default duration is not read as a stay: every place carries one, so it says nothing. Once the traveller confirms, create_city_walk saves the walk through the same creation the planner's save uses: one write, a key for every station, the links to the trip's places checked, the trip told, with place editing permission on the trip. Its way on foot is planned by the same router and saved with the walk, together with its distance and walking time. Where the router gives no way, the walk is saved with its stations only and the answer says why: no line, no distance and no walking time. The tours list says so (route_pending), the tour detail says in one line that the way is planned in the planner, and opening the walk in the planner plans its way at once and offers to save it, with a note once it is planned that it was just planned. Such a walk can be saved as a new tour and taken over into another trip, starting at its first stop, and is never offered as a place to stay. A tour without a line needs two points of its own. get_tour_plan now spells out every field of a city walk's stations: key, name, stay (null when not known), importance (null for normal), protection (false when not set) and opening hours (null when none are known); list_tours names the station count and whether a walk waits for its way, get_city_walk_progress gives each station's key and opening hours, and take_over_tour says a walk keeps its stations with their protection. No tool changes a walk's stations; deleting a walk's place takes its stations along, protected ones included, and both delete tools now ask the assistant to name those and ask the traveller first. REST answers the stations as before. A tour create refused for a type that is switched off, a description that is too long or planned times out of range is a domain refusal now, so an assistant gets the same text REST sends; REST still answers it as an error at 400. |
||
|
|
9f0caf8539 |
feat(tours): public transit between two city walks in the day plan, from the first walk's end at the time it ends (CW-08)
"Public transit" on the connector between two city walks in the day plan, on the desktop and on the phone, now opens the existing search from where the first walk really ends to where the next one starts, at the coordinates the day's route draws, named after the first walk's last stop and the next walk's first stop. A loop ends at its first stop again. A stop without a name takes the name of the trip place it stands for, and a walk whose stops cannot be read on this device names that end "End of" or "Start of" the walk. The search opens on the walks' day and departs when the first walk ends: its start that day, the time on the day's entry before the place's own, plus its planned total, a total entered by hand before walking and stays. The assignment's own end time is not used. Above the search a note says when the first walk ends, "at the earliest" where a stay or the walking time is not known yet, and when the next walk starts. Without a start or a total no time is made up: the time field stays empty and Search waits until one is chosen. A walk that only ends after midnight says so, and the time field stays empty as well. On any other day, or for any other leg, the search opens as before, with 09:00 as its default. A connection that arrives after the next walk starts says so in its card, before its legs are opened and before it is taken. Nothing is saved until "Add to day", which keeps the connection as its own journey in the plan as before; both walks stay two walks on foot and nothing is moved. A journey saved before a walk that now arrives after the walk starts says so on its row in the plan, on the desktop and the phone, while the plan is looked at. Nothing is rewritten. The desktop no longer draws a connector of nothing between a stop and a booking at the same spot, as the phone already did, so a journey saved at the walks' ends adds no walk on either side. A leg leaving a loop tour no longer departs at the tour's start time. The leg is told by the walk it leaves, so two walks of a day that end at one spot, such as two loops from the hotel, each search from their own end and time, and a stop between two walks keeps the leg an ordinary one. Only the leg asked for last opens the search, and none opens once the plan is left while the walks' stops are still being read. Both views run on one shared hook, the walk's stops are read through one helper the stop list uses as well, and the walk's start on a day is worked out in one place for the times shown in the detail and here. |
||
|
|
7470a2c6d4 |
fix(tours): a short link whose name does not resolve just now, or that Google does not know, is said as such in the walk import (CW-06, CW-07)
When the name of maps.app.goo.gl or goo.gl could not be looked up for a moment, the walk import said the short link leads somewhere other than Google Maps. It now says the link could not be followed just now and answers 502, as for any other failure on the way; a name that leads into this network is still refused. A short link Google answers with 404 or 410 is one it does not know, and asking again changes nothing. The dialog now says so in the reader's language and asks to share the route from Google Maps again, with a 400 and the reason short_link_unknown, instead of suggesting to try again later. A busy or blocking answer from Google stays a failure that may pass. The MCP tool preview_google_maps_walk is marked open world, since it follows a short link to Google on every call, and the English text REST and MCP send for each reason is held to the English text the planner shows. |
||
|
|
4ca5728072 |
feat(tours): a city walk from a Google Maps walking route, its short link followed only to Google Maps (CW-06, CW-07)
"Add tour" in the planner now offers "Import walk from Google Maps". The dialog takes the link of a route shared in Google Maps, either a maps.app.goo.gl short link or the long google.com/maps/dir link, or the share text of the Google Maps app with the one link in it. It shows the stops in their order with their names, marks a stop the link gives no position as such, says that the route comes from Google Maps with a link to open it there, and that TREK plans the way between the stops itself and does not take the line drawn in Google Maps over. Nothing is written until "Load as walk": that opens a new, unsaved city walk in the planner with the positioned stops and their names, routed on foot by TREK, and warns first when it replaces unsaved work. A stop without a position is left out and never looked up or guessed; with fewer than two positions nothing can be loaded. While the walk is not saved, a calm notice in the planner says where it came from, also after a reload of the draft. Cancelling or a failure leaves every tour as it was. Only a route the link marks unambiguously as on foot is read. A car, bike or transit route, a link that does not say, or one that says two things is refused with a reason the dialog gives in the reader's language. Each stop takes its position from its own block of the link's data, so a line dragged through extra points or a stop given as coordinates no longer leaves the stops without positions or shifts them. The road trip and places imports read links as before. A short link is followed by a resolver of its own: every hop is checked against the Google Maps short link shapes and the strict SSRF guard before it is looked up or asked, so ALLOW_INTERNAL_NETWORK and ALLOW_LINK_LOCAL_IPS do not open it. Each request goes to the vetted addresses only, follows nothing by itself, reads no body and carries no credentials; the chain has one deadline including name lookups, at most three hops and a cap on the Location header, and the long link it ends on must be Google Maps and is never fetched. The preview is POST /api/trips/:tripId/tours/import/google-maps/preview for members who may edit places, with a 502 when Google could not be reached, and the MCP tool preview_google_maps_walk reads the same. |
||
|
|
2203ff3a2e |
feat(tours): a city walk's arrivals and opening hours for the day it is on, at each stop in the planner and the detail (CW-02, CW-04)
A city walk now shows, at each stop, when the walk gets there, until when the stay lasts, and what the stop's opening hours say about that visit. The same lines appear under each stop row in the planner and under each stop in the walk's detail, in the user's 12 or 24 hour format. A conflict names the stop, the arrival, the end of the stay and the hours it was checked against, for instance "Lenbachhaus closes at 18:00, during the stay from 17:20 to 18:20 (open 10:00 to 18:00)", in the warning colour. Nothing is changed by these hints: no stop, order or route moves. The times belong to one day the walk is on. Opened from a day of the plan, the detail keeps that day, and checking stops off stays bound to it. Opened otherwise, and in the planner, a small pill above the stops names the day and its start, and the walk's other days can be picked from it; it starts on the first day with a start time. The pick is only what is looked at and is never saved, and another day never takes over the times quietly. Without a day, a date or a start time the line says what is missing and no arrival is shown. TREK keeps no time zone on a trip, so start, arrivals and opening hours are all read as the local time of the plan, and an arrival after midnight is said to be on the next day without being checked. Opening hours come from the trip place a stop stands for, as the travellers entered them, and otherwise from OpenStreetMap; a pill at each stop names the source, and a notice says the hours are a hint to check. A stop without hours stays unknown and is never shown as open, hours that are not in a plain form are shown as written, and an arrival that is only a lower bound, because a stay before it is not entered yet, is not judged unless no later arrival could escape the conflict. A trip place that a stop stands for also gives the stop its name before "Stop N". The arrival at a stop is found where the route passes it in the walk's order, so the end of a loop and a stop passed on the way out and back get the right time. The rules live once in the shared package, for the server to give the same answers. The walk's detail reads its stops again after a save, its own or a teammate's. |
||
|
|
93a508a0e6 |
fix(tours): count a city walk's visits event in the realtime inventory (CW-03)
The registry of realtime events gained tours:visits when a city walk's stops could be checked off for every member of the trip, but the test that pins the inventory still counted 76 trip events and 109 in all. It now counts 77 and 110 and says which event the 77th is. |
||
|
|
0b92dcc86b |
feat(tours): show a city walk's progress on the phone's day row, and check its stops off offline (CW-03)
The day row on the phone now shows how many stops of a city walk were visited on that day, "2 of 5 visited", like the desktop row does. Both rows read it from one place, and a tap on the phone names it in full without opening the row. A walk's stops can be checked off, skipped and taken back without a connection. The mark shows at once, waits in the offline queue and goes out when the connection is back, in the order the marks were made and behind any older mark of the same day that still waits. The day plan, the walk's detail and a reload read the visits kept on this device with the waiting marks on top, so a mark made offline stays on screen until the server has it. A mark the server answers with "not found", because the stop, the day or the walk was removed meanwhile, counts as done and holds back no later mark of that day. Any other refusal, the Tours addon turned off among them, keeps the mark as a failed change to try again from the offline settings. The visits are read again when the connection comes and goes, and once more after the waiting marks went out, so a mark the server dropped or refused leaves the day plan. A trip's visits that answer after another trip was opened no longer show there. The offline sync keeps each trip's walk visits and reads the stops of a walk this device has never opened, so it can be checked off offline too. A walk whose stops this device could not read lists no stand-in stops and no count, and says to open it again while online. A walk put on a day while offline says its stops can be checked off once it has synced, instead of offering buttons that cannot work yet. A mark that fails says to open the walk again and try once more, in every language. Marks carry no version, so the last one to reach the server wins, as with the other changes sent after being offline. The offline guide says so. |
||
|
|
c836ee3988 |
fix(tours): a city walk saved offline shows its stays and total at once, and the planner plans the total its overview shows (CW-02)
A city walk created or changed while offline now carries its stops, the minutes its stays are entered with and how many have none yet, worked out from its points the way the server will answer them. The day row, the tour detail and the summary show the walking time with the stays as soon as the walk is saved, with "at least" where a stay is missing, and a stay changed while the write waits shows its new total rather than the one of the last answer. The server and the client count the stops in one shared place. The planner plans a walk whose walking time is not known yet with at least the stays entered, as its overview says, so the planned field and the check against the longest plan read the same total. In the tour detail a longer time such as an "at least" total wraps on a phone instead of being cut, and the boxes of a row keep one height. A total entered by hand falls back to its short name where its column is too narrow. |
||
|
|
188953158a |
fix(tours): a city walk's walking time, stays and total read apart and alike everywhere, and a stay plans no route again (CW-02)
A stay, a name, an importance or a protection set in a stop's dialog no longer plans a city walk's route again: the walk stays ready to save, its time overview follows at once, and one undo takes the change back without routing either. A stop moved or added plans the route again as before. A walk saves no breaks, so a cafe never counts as a stay and as a break at once, and a break left from another type neither counts nor holds its save up. The planner and the tour detail show a walk's walking time, its stays and their total apart and in the same words: 45 minutes of walking, a museum of 90 minutes and a cafe of 30 minutes make 2 h 45 min. A stay not entered yet makes the stays and the total at least what is known, stays nobody entered read not known yet, and stays entered as 0 read 0 min. A total entered by hand keeps its own label, and the computed total shows beside it. The head of the tour detail, the day row on the desktop and the phone, the tour summary and the library of other trips show that same total, with a ≥ where a stay is missing. Their time on the move is called walking, and the summary says a walk is planned with its stays rather than breaks. The tour list and the library carry the minutes a walk's stops are entered with and how many have no stay yet, counted from the walk's points, so the way back of a loop is no stop and its start's stay counts once. A loop run the other way keeps its start as the stop there, with its key, name and stay. The planner's waypoint list keeps the rows of a leg in a file of their own, and the tour detail its name heading in a part of its own, so both stay within their size limits. |
||
|
|
20f8266439 |
fix(tours): keep a city walk's visits through a save from the planner, and count a loop's start once (CW-02, CW-03, CW-09)
A walk saved from the planner kept its stops without the keys the server gave them, so the next save from the same open planner handed every stop a new key and dropped the visits checked off in the day plan meanwhile. The planner now takes over the keys a save answers, point by point, without planning the route again, so a stop keeps its key and its visits from one save to the next. The edits of a stop's dialog now reach the planner: a changed name, stay, importance or protection counted as no change and was dropped. It is a step of its own that can be undone, Save stays available, and the route is not planned again for it. A save that takes stops out of a walk, or makes it another type, tells every client of the trip which visits are left on each day the walk is on, the client that saved included, so the progress in the day row no longer counts a stop the walk has lost. The way back of a loop is the start again and no stop of its own. Closing a loop gives it only the start's spot and the place it stands for, and the planner's stays, the stops of the tour detail, the stop count of the tour list, the visits and the progress an assistant reads leave it out, so a loop through three stops counts three, the start's stay counts once and the way back cannot be checked off on its own. A loop saved before keeps working. The rule lives in one helper the server and the client share, and the tour list takes its stop count from the walk's points through it. The tests that seed a walk for the assistant's progress go through the ORM factories. |
||
|
|
e5f01e570a |
fix(tours): check a city walk's stops off and save a stop from its dialog, with the walk under test (CW-01 to CW-05, CW-09)
Marking a stop of a city walk visited or skipped answered with a server error every time: the write that keeps a changed status stamped its time as a function call, which neither SQLite nor Postgres takes. It now uses the clock the database itself spells, so a stop checked off, skipped or taken back stays that way and the day plan of everyone on the trip follows. The Save button of a stop's dialog in the planner did nothing, because it sat outside the dialog's form. It saves the name, stay, importance and protection again. A walk saved with two points that carry one key, as a loop back to the start does, keeps that key on the first point and gives the other one of its own, so checking one off never marks both. A walk put on one day twice is read for an assistant from its first assignment. The server tests cover the visits from the repository to the routes: per day, through a moved and a removed assignment, a copy of the walk and a copied trip without visits, a removed stop taking its visits along, and the refusals for another trip, a stop the walk does not have, a member who may not edit days and an unknown key or body. The MCP progress of a walk, the station fields and counts of the tour list, and the contracts in shared are tested too; the existing tests expect the keys every saved point now carries, the station count of a list row and the new entity. The client tests cover the stop dialog and its pills, the walk themes and categories of the search along a tour, the stop menu of the waypoint list, the walk's timing, routing and type choice, and answer the trip planner's read of the visits in the tests instead of leaving it unanswered. |
||
|
|
3c823e07f4 |
fix(tours): search along a tour through the places index along the line, and name what could not be searched (PLN-02, CW-05)
The search along a tour found nothing. It asked the places index for all kinds of a stretch at once, above the 100 rows and 200 characters of terms the index takes, so the index refused and every stretch went to the public Overpass mirrors, which do not answer from this server. Now the index is asked in small circles strung along the line, one request per kind and circle within its limits, and an empty circle counts as an answer, so a city walk lists its sights, museums, parks, cafes, restaurants and markets in well under a second. The kinds the index does not know (viewpoints, huts, drinking water, toilets and the like) are asked of Overpass along the whole line at the same time, one query per stretch of up to 50 km, three at a time, each with a short deadline of its own; a line past 400 km is searched along its start and says so. When the index answers no circle at all, its kinds go to Overpass beside the others instead of after them. A kind no source could be searched for is named in a calm notice above the list instead of reporting nothing found, and the reason is written to the log. Unnamed taps, toilets, shelters, picnic spots, viewpoints, summits, slipways and repair stands stay in the list and on the map under the name of their kind; an unnamed garden, cafe or memorial is left out. The places nearest the line are kept when there are more than sixty, listed from the start, with the opening hours the source has. A walk's parks are parks and gardens only, and its museums are museums and galleries only, no longer the beaches, summits, theatres and cinemas of the map's explore buttons; a water park the index files under parks is not one of them. The index also answers markets and summits. The explore buttons keep their single request, and a search of several kinds that would exceed the index limits is asked one kind at a time instead of being refused. The MCP tool search_tour_pois and its wiki row describe the walk kinds and the new unavailable list, and the OVERPASS_TIMEOUT_MS row says the search along a tour keeps its own shorter deadline. |
||
|
|
9ed944c1e6 |
fix(tours): city walk gates: entity collection, formatting, a walk's name hint and the tests' visits repository
The day assignments entity carries the station visits that hang off it, as the generator writes it. A city walk gets its own placeholder for an untitled name, the tour service tests hand in the visits repository the service now takes, and the files the walk touched are formatted. The theme icons of the place search overlap by their start margin, so they stack the same way in both reading directions. |