mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-23 15:36:33 +00:00
15aefa449e
Everything here came out of putting the first commit in front of somebody and watching them use it. **The marker card is one card now, and it carries the entry's photos.** Leaflet showed a one-line label and the GL map a two-line card, so the same marker said different things depending on a renderer setting nobody connects to journeys. Both now build from one module: a strip of up to three thumbnails bleeding to the card's edges, the name, and the place and date as chips. On the GL map the thumbnails open the entry's photos; the rest of the card still never takes the pointer, so the map drags from anywhere on it. **A pin that would not sit still.** Dragging the map left the marker trailing behind and snapping back at the end. The app's press-feedback rule puts a 180ms transition on `[role="button"]`, MapLibre and Mapbox give their marker element exactly that role, and both rewrite its `transform` on every frame of a movement. Markers are excluded now — every map in TREK, not just this one. **The phone card, after four rounds of looking at it.** The day is the card's own edge rather than a bar across its foot, and the ring is inset because the carousel clips. A card without a photo is opaque: it was a wash of the day's colour over the map. The country is a real flag rather than two letters — Windows has no flag glyphs, so the emoji drew "DE" where a flag was meant, and the image falls back to the emoji when it cannot be fetched. Mood, weather and the date share the top edge; the flag sits opposite them. **The day bar answers to a finger.** Press the date and slide sideways to run through the days. The bar is still a row of buttons underneath, because that is the only version of it a keyboard can reach, and each one is 20px tall now rather than 3. Also here: - Videos upload to an entry (issue #2341). The gallery has taken them since #823 and an entry could not: everything went through the images-only filter and came back 400, reported as "1 of 1 photos failed". Same two-part upload, same absence of transcoding, and the editor now previews a clip in a `<video>` instead of a broken-image glyph. - The search box takes the gap the toolbar already had instead of clipping its own placeholder. - Entry cards line up with the day header again: the reorder arrows moved out of a column of their own into the feed's padding and appear on hover, and the day-coloured ring on the active card is a layer over it — an outline tight enough to sit on the card's edge was painting behind it. - Map attribution is collapsed to its ⓘ. It cannot go away — the OSM licence asks for it — but it does not have to lie under the carousel. - The suggestion dismiss and the day-header plus use TREK's own tooltip rather than the browser's.
48 lines
1.8 KiB
TypeScript
48 lines
1.8 KiB
TypeScript
import { useState } from 'react'
|
|
import { countryCodeToFlag } from '../../pages/atlas/atlasModel'
|
|
|
|
/**
|
|
* A country's flag, drawn on every platform.
|
|
*
|
|
* The emoji alone is not enough. A flag is two regional-indicator code points,
|
|
* and Windows has never shipped glyphs for the pairs — Chrome and Edge there
|
|
* fall back to drawing the two letters, so `DE` appears where a flag was meant
|
|
* and reads as something broken. Atlas has always had that, and the journey
|
|
* cards inherited it.
|
|
*
|
|
* So the emoji is turned into its Twemoji image, the same way the collaboration
|
|
* chat draws emoji (`CollabChatTwemojiImg`). When that image cannot be fetched —
|
|
* offline, or an install that blocks the CDN — the emoji itself is rendered
|
|
* instead, which is the old behaviour: a flag on Apple and Android, two letters
|
|
* on Windows. Nothing is worse than it was, and on most screens it is a flag.
|
|
*/
|
|
export default function CountryFlag({ code, size = 14, title }: { code: string | null | undefined; size?: number; title?: string }) {
|
|
const [failed, setFailed] = useState(false)
|
|
if (!code || !/^[A-Za-z]{2}$/.test(code)) return null
|
|
|
|
const emoji = countryCodeToFlag(code)
|
|
if (!emoji) return null
|
|
if (failed) {
|
|
return (
|
|
<span aria-hidden style={{ fontSize: size, lineHeight: 1 }} title={title}>
|
|
{emoji}
|
|
</span>
|
|
)
|
|
}
|
|
|
|
const cp = [...code.toUpperCase()]
|
|
.map(c => (0x1f1e6 + c.charCodeAt(0) - 65).toString(16))
|
|
.join('-')
|
|
return (
|
|
<img
|
|
src={`https://cdn.jsdelivr.net/gh/twitter/twemoji@14.0.2/assets/72x72/${cp}.png`}
|
|
alt={code.toUpperCase()}
|
|
title={title}
|
|
draggable={false}
|
|
loading="lazy"
|
|
onError={() => setFailed(true)}
|
|
style={{ width: size, height: size, display: 'block', borderRadius: 2 }}
|
|
/>
|
|
)
|
|
}
|