mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-21 14:36:31 +00:00
c1d55c463c
The Atlas country check timed out. It asked Dawarich for a year of visited cities in one request, and Dawarich computes that over every point in the window with nothing cached, so a dense recorder never got under the 15 s the server allows. The year is now asked for a month at a time, one request after another, and folded back together. The windows sit a second apart because Dawarich reads the bounds as inclusive. The recorded route only appeared after a reload. Every Dawarich call from the browser carried the shared 8 s timeout, so the browser gave up while the server carried on and cached the answer for the next page load. Calls that make the server talk to Dawarich now wait two minutes, the Atlas four. On the GL renderers the draw also gave up whenever isStyleLoaded() was false, which it is while any tile is still loading, and only retried on style.load. It now waits for idle. The hazard overlay had the same guard and gets the same wait. The pill shows a ring while the route loads, so a slow first fetch no longer looks like "done, nothing there". A collapsed day now takes its recorded route off the map, following the same folds the planner already applies to places, the road trip sidebar's included.
116 lines
3.9 KiB
TypeScript
116 lines
3.9 KiB
TypeScript
import { useTranslation } from '../../i18n'
|
|
import { Tooltip } from '../shared/Tooltip'
|
|
import DawarichIcon from '../shared/DawarichIcon'
|
|
import { MAP_CONTROL_SHADOW } from './mapControlShadow'
|
|
import type { DawarichTrailStatus } from './useDawarichTrail'
|
|
|
|
/**
|
|
* Toggle for the recorded-route overlay (#2279), in the same frosted shell as
|
|
* the compass, the layer switcher and the trip-route overview so the map's
|
|
* controls stay one family.
|
|
*
|
|
* The status rides on the button rather than in a banner: the states that
|
|
* matter — loading, nothing recorded for these dates, instance unreachable,
|
|
* device offline — are all answers to "why is there no line", and the place
|
|
* someone looks for that answer is the control they just pressed.
|
|
*/
|
|
export function DawarichTrailPill({
|
|
active,
|
|
status,
|
|
onToggle,
|
|
}: {
|
|
active: boolean
|
|
status: DawarichTrailStatus
|
|
onToggle: () => void
|
|
}) {
|
|
const { t } = useTranslation()
|
|
|
|
const label = !active
|
|
? t('dawarich.trail.show')
|
|
: status === 'loading'
|
|
? t('dawarich.trail.loading')
|
|
: status === 'empty'
|
|
? t('dawarich.trail.empty')
|
|
: status === 'offline'
|
|
? t('dawarich.trail.offline')
|
|
: status === 'unavailable'
|
|
? t('dawarich.trail.unavailable')
|
|
: t('dawarich.trail.hide')
|
|
|
|
// A problem worth seeing without reading the tooltip: the layer is on and
|
|
// there is nothing to show.
|
|
const muted = active && (status === 'empty' || status === 'offline' || status === 'unavailable')
|
|
// Loading has to be visible too. A first fetch from somebody's own server can
|
|
// take a while, and with nothing on the button it looked exactly like "done,
|
|
// but no line", so testers reloaded the page to find out.
|
|
const loading = active && status === 'loading'
|
|
|
|
return (
|
|
<div
|
|
style={{
|
|
position: 'relative',
|
|
display: 'inline-flex',
|
|
alignItems: 'center',
|
|
padding: 4,
|
|
borderRadius: 999,
|
|
pointerEvents: 'auto',
|
|
background: 'var(--sidebar-bg)',
|
|
backdropFilter: 'blur(20px) saturate(180%)',
|
|
WebkitBackdropFilter: 'blur(20px) saturate(180%)',
|
|
boxShadow: MAP_CONTROL_SHADOW,
|
|
}}
|
|
>
|
|
{/* TREK's own tooltip: the native one is unreadable in dark mode and never
|
|
appears on a touch device, and this control's whole job is to explain
|
|
why there is no line. */}
|
|
<Tooltip label={label} placement="left">
|
|
<button
|
|
type="button"
|
|
onClick={onToggle}
|
|
aria-label={label}
|
|
aria-pressed={active}
|
|
aria-busy={loading}
|
|
data-testid="dawarich-trail-pill"
|
|
style={{
|
|
display: 'block',
|
|
width: 34,
|
|
height: 34,
|
|
borderRadius: 999,
|
|
border: 'none',
|
|
cursor: 'pointer',
|
|
background: 'transparent',
|
|
padding: 0,
|
|
// The mark fills the circle and is clipped by it, so the control reads
|
|
// as the Dawarich button rather than as a frame with a logo in it.
|
|
overflow: 'hidden',
|
|
// Its own colours stay; on/off is carried by opacity, because a
|
|
// recoloured logo is a different logo.
|
|
opacity: muted ? 0.35 : active ? 1 : 0.6,
|
|
transition: 'opacity 0.14s, transform 0.14s',
|
|
}}
|
|
onMouseEnter={e => { e.currentTarget.style.transform = 'scale(1.06)' }}
|
|
onMouseLeave={e => { e.currentTarget.style.transform = 'none' }}
|
|
>
|
|
<DawarichIcon fill />
|
|
</button>
|
|
</Tooltip>
|
|
{loading && (
|
|
<span
|
|
aria-hidden="true"
|
|
data-testid="dawarich-trail-loading"
|
|
className="motion-safe:animate-spin"
|
|
style={{
|
|
position: 'absolute',
|
|
inset: 2,
|
|
borderRadius: 999,
|
|
border: '2px solid transparent',
|
|
borderTopColor: 'var(--accent)',
|
|
borderRightColor: 'var(--accent)',
|
|
pointerEvents: 'none',
|
|
}}
|
|
/>
|
|
)}
|
|
</div>
|
|
)
|
|
}
|