mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-21 06:26:26 +00:00
8f02337d45
TREK's codes 'br' (Brazilian Portuguese) and 'gr' (Greek) went straight into <html lang> and into ten Intl calls. 'br' is Breton, so Brazilian users got Breton month names and screen readers announced the page as Breton; 'gr' is no language at all, so Greek users got the default locale. getIntlLanguage maps both, and every one of those sites goes through it.
46 lines
1.7 KiB
TypeScript
46 lines
1.7 KiB
TypeScript
import { getIntlLanguage } from '@trek/shared'
|
|
|
|
export interface PlaceLocality {
|
|
/** The country's name in the reader's language, or as the address spells it. */
|
|
country: string | null
|
|
/** State, province or prefecture, as resolved from the position. */
|
|
region: string | null
|
|
}
|
|
|
|
interface LocatedPlace {
|
|
address?: string | null
|
|
country_code?: string | null
|
|
region_name?: string | null
|
|
}
|
|
|
|
const hasDigits = (part: string) => /\d/.test(part)
|
|
const hasLetters = (part: string) => /\p{L}/u.test(part)
|
|
|
|
/** The last part of a formatted address is the country, when it reads like one. */
|
|
function countryFromAddress(address: string | null | undefined): string | null {
|
|
const parts = (address ?? '').split(',').map(p => p.trim()).filter(Boolean)
|
|
if (parts.length < 2) return null
|
|
const last = parts[parts.length - 1]
|
|
return !hasDigits(last) && hasLetters(last) ? last : null
|
|
}
|
|
|
|
/**
|
|
* Where a place lies, for filtering the trip's places (#2537).
|
|
*
|
|
* Both halves come from the position the server resolved, which is exact: the country
|
|
* code, named in the reader's language, and the region. A city is not offered, since a
|
|
* formatted address cannot tell one apart reliably (it names the borough before Berlin
|
|
* and the county before Schönefeld). A place not resolved yet falls back to the country
|
|
* its address ends on.
|
|
*/
|
|
export function placeLocality(place: LocatedPlace, language: string): PlaceLocality {
|
|
let country: string | null = null
|
|
if (place.country_code) {
|
|
try { country = new Intl.DisplayNames([getIntlLanguage(language)], { type: 'region' }).of(place.country_code.toUpperCase()) ?? null } catch { country = null }
|
|
}
|
|
return {
|
|
country: country ?? countryFromAddress(place.address),
|
|
region: place.region_name || null,
|
|
}
|
|
}
|