diff --git a/packages/ui/index.html b/packages/ui/index.html index c179981..d2d7370 100644 --- a/packages/ui/index.html +++ b/packages/ui/index.html @@ -2,10 +2,10 @@ - Busmap + Busmap - Stop and vehicle locations of popular transit agencies. + content="Maps providing real-time arrival and departure times of vehicles for bus stops along routes in San Francisco Muni CIS, Toronto Transit Commission, OmniTrans and other transit agencies across North and South America." /> diff --git a/packages/ui/src/components/busSelector.tsx b/packages/ui/src/components/busSelector.tsx index 4ee013a..b607682 100644 --- a/packages/ui/src/components/busSelector.tsx +++ b/packages/ui/src/components/busSelector.tsx @@ -13,6 +13,7 @@ import { SelectorError } from './error/selector.js' import { useGlobals } from '../globals.js' import { useMap } from '../contexts/map.js' +import { useDocMeta } from '../hooks/useDocMeta.js' import { useHomeStop } from '../hooks/useHomeStop.js' import { useVehiclesDispatch } from '../contexts/vehicles.js' import { getAll as getAllRoutes, get as getRoute } from '../api/rb/route.js' @@ -157,6 +158,11 @@ const BusSelector = memo(function BusSelector({ agencies }: BusSelectorProps) { const error = getFirstDataError([routesError, routeError]) const isLoading = isRoutesLoading || isRouteLoading + /** + * Update page title and description. + */ + useDocMeta() + useEffect(() => { if (routes) { if (bookmark.current.route) { diff --git a/packages/ui/src/components/busmap.tsx b/packages/ui/src/components/busmap.tsx index 149fd1f..8d8e8b6 100644 --- a/packages/ui/src/components/busmap.tsx +++ b/packages/ui/src/components/busmap.tsx @@ -5,6 +5,11 @@ import type { FC } from 'react' const BusmapPage: FC = () => { return ( +

+ Busmap provides real-time arrival and departure times for vehicles servicing bus + stops along routes in San Francisco Muni CIS, Toronto Transit Commission, + OmniTrans, and other transit agencies across North and South America. +

Busmap is a public, open source project{' '} @@ -21,9 +26,7 @@ const BusmapPage: FC = () => { restbus - . -

-

+ .{' '} - predictions?: Prediction[] + predictions: Prediction[] } const Predictions = createContext({ dispatch: () => {}, - predictions: undefined + predictions: [] }) -const reducer = (state: Prediction[] | undefined, action: PredictionsAction) => { +const reducer = (state: Prediction[], action: PredictionsAction) => { switch (action.type) { case 'predictions': return action.value case 'direction': case 'stop': - return undefined + return [] default: return state } diff --git a/packages/ui/src/hooks/useDocMeta.ts b/packages/ui/src/hooks/useDocMeta.ts new file mode 100644 index 0000000..ff2c80a --- /dev/null +++ b/packages/ui/src/hooks/useDocMeta.ts @@ -0,0 +1,58 @@ +import { useEffect, useRef } from 'react' + +import { useGlobals } from '../globals.js' +import { usePredictions } from '../contexts/predictions' + +const useDocMeta = () => { + const metaDesc = useRef() + const { agency, stop } = useGlobals() + const { predictions } = usePredictions() + + useEffect(() => { + const meta = document.querySelector('meta[name="description"]') + + if (meta) { + metaDesc.current = meta + } + }, []) + + useEffect(() => { + if (metaDesc.current) { + if (agency && stop) { + let event = 'arrival' + let title = `${stop.title}` + + if (predictions.length) { + const [one, two] = predictions[0].values + + if (one.isDeparture) { + event = 'departure' + } + + title += `: ${one.minutes || 'Now'}` + + if (two) { + title += ` & ${two.minutes || 'Now'}` + } + + title += ' min' + } + + document.title = title + metaDesc.current.setAttribute( + 'content', + `Maps providing real-time ${event} times of vehicles for ${agency.title} stop ${stop.title}.` + ) + } else { + document.title = + 'Busmap - Stop and vehicle locations of popular transit agencies.' + metaDesc.current.setAttribute( + 'content', + 'Maps providing real-time arrival and departure times of vehicles for bus stops along routes in San Francisco Muni CIS, Toronto Transit Commission, OmniTrans and other transit agencies across North and South America.' + ) + } + } + }, [agency, stop, predictions]) +} + +export { useDocMeta } diff --git a/packages/ui/src/hooks/useVehiclesLayer.ts b/packages/ui/src/hooks/useVehiclesLayer.ts index 27647ff..843416d 100644 --- a/packages/ui/src/hooks/useVehiclesLayer.ts +++ b/packages/ui/src/hooks/useVehiclesLayer.ts @@ -183,14 +183,14 @@ const useVehiclesLayer = ({ vehiclesLayer }: UseVehiclesLayer) => { useVehicleSettings() const iconDimensions = useRef(null) - const preds = useRef(predictions?.length ? predictions[0].values.slice(0, 3) : []) + const preds = useRef(predictions.length ? predictions[0].values.slice(0, 3) : []) useEffect(() => { iconDimensions.current = null }, [route]) useEffect(() => { - const nextPreds = predictions?.length ? predictions[0].values.slice(0, 3) : [] + const nextPreds = predictions.length ? predictions[0].values.slice(0, 3) : [] preds.current = nextPreds }, [predictions])