Skip to content

Commit

Permalink
feat: adds generated open graph image to stop place
Browse files Browse the repository at this point in the history
  • Loading branch information
mikaelbr committed Apr 18, 2024
1 parent 22b963e commit e198672
Show file tree
Hide file tree
Showing 13 changed files with 480 additions and 32 deletions.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
"@mapbox/polyline": "^1.2.1",
"@react-aria/focus": "^3.16.2",
"@react-hook/resize-observer": "^1.2.6",
"@resvg/resvg-js": "^2.6.2",
"@turf/centroid": "^7.0.0-alpha.113",
"bunyan": "^1.8.15",
"compare-versions": "^6.1.0",
Expand All @@ -56,6 +57,7 @@
"react": "18.2.0",
"react-dom": "18.2.0",
"react-syntax-highlighter": "^15.5.0",
"satori": "^0.10.13",
"swr": "^2.2.5",
"uuid": "^9.0.1",
"zod": "^3.22.4"
Expand Down
Binary file added public/fonts/Roboto-Bold.ttf
Binary file not shown.
Binary file added public/fonts/Roboto-Regular.ttf
Binary file not shown.
2 changes: 2 additions & 0 deletions src/components/map/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,5 @@ export const Map = dynamic(() => import('./map'), {
ssr: false,
loading: () => <MapLoading />,
});

export { getStaticMapUrl } from './static-map';
26 changes: 11 additions & 15 deletions src/components/map/map.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,13 @@ import { Button } from '@atb/components/button';
import { MonoIcon } from '@atb/components/icon';
import { ComponentText, useTranslation } from '@atb/translations';
import { FocusScope } from '@react-aria/focus';
import { ZOOM_LEVEL, defaultPosition, getMapBounds } from './utils';
import {
ZOOM_LEVEL,
defaultPosition,
getMapBounds,
hasInitialPosition,
hasMapLegs,
} from './utils';
import { useMapInteractions } from './use-map-interactions';
import { useFullscreenMap } from './use-fullscreen-map';
import { useMapPin } from './use-map-pin';
Expand All @@ -20,15 +26,15 @@ export type MapProps = {
layer?: string;
onSelectStopPlace?: (id: string) => void;
} & (
| {
| {
position: Position;
initialZoom?: number;
}
| {
| {
mapLegs: MapLegType[];
}
| {}
);
| {}
);

export default function Map({ layer, onSelectStopPlace, ...props }: MapProps) {
const mapWrapper = useRef<HTMLDivElement>(null);
Expand Down Expand Up @@ -118,13 +124,3 @@ export default function Map({ layer, onSelectStopPlace, ...props }: MapProps) {
</div>
);
}

function hasInitialPosition(
a: any,
): a is { position: Position; initialZoom?: number } {
return !!a.position;
}

function hasMapLegs(a: any): a is { mapLegs: MapLegType[] } {
return a.mapLegs;
}
30 changes: 30 additions & 0 deletions src/components/map/static-map.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { mapboxData } from '@atb/modules/org-data';
import { Position } from './types';
import {
ZOOM_LEVEL,
defaultPosition,
getMapBounds,
hasInitialPosition,
hasMapLegs,
} from './utils';

export type StaticMapProps = {
layer?: 'address' | 'venue';
position: Position;
initialZoom?: number;
size: { width: number; height: number };
};

export function getStaticMapUrl(props: StaticMapProps) {
const mapLegs = hasMapLegs(props) ? props.mapLegs : undefined;
const { position, initialZoom = ZOOM_LEVEL } = hasInitialPosition(props)
? props
: { position: defaultPosition, initialZoom: ZOOM_LEVEL };
const bounds = mapLegs ? getMapBounds(mapLegs) : undefined;

const params = bounds
? `${bounds}`
: `${position.lon},${position.lat},${initialZoom}`;

return `https://api.mapbox.com/styles/v1/${mapboxData.styleAndId}/static/${params}/${props.size.width}x${props.size.height}?access_token=${mapboxData.accessToken}`;
}
10 changes: 10 additions & 0 deletions src/components/map/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,3 +146,13 @@ export function addLayerIfNotExists(map: Map, layer: AnyLayer) {
map.addLayer(layer);
}
}

export function hasInitialPosition(
a: any,
): a is { position: Position; initialZoom?: number } {
return !!a.position;
}

export function hasMapLegs(a: any): a is { mapLegs: MapLegType[] } {
return a.mapLegs;
}
35 changes: 35 additions & 0 deletions src/components/open-graph/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { getOrgData } from '@atb/modules/org-data';
import Head from 'next/head';
import { useRouter } from 'next/router';

const {
urls: {
sitemapUrls: { prod },
},
} = getOrgData();

export type OpenGraphImageProps = {
image: string;
};
export function OpenGraphImage({ image }: OpenGraphImageProps) {
return (
<Head>
<meta property="og:image" content={`${prod}${image}`} />
</Head>
);
}

export type OpenGraphBaseProps = {
title: string;
};
export function OpenGraphBase({ title }: OpenGraphBaseProps) {
const { asPath } = useRouter();

return (
<Head>
<meta property="og:title" content={title} />
<meta property="og:type" content="website" />
<meta property="og:url" content={`${prod}${asPath.slice(1)}`} />
</Head>
);
}
13 changes: 2 additions & 11 deletions src/layouts/base/index.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { OpenGraphBase } from '@atb/components/open-graph';
import Footer from '@atb/layouts/shared/footer';
import PageHeader from '@atb/layouts/shared/page-header';
import { usePageTitle } from '@atb/layouts/shared/utils';
Expand All @@ -8,25 +9,19 @@ import {
useTranslation,
} from '@atb/translations';
import Head from 'next/head';
import { useRouter } from 'next/router';
import { PropsWithChildren } from 'react';
import style from './base.module.css';
import { getOrgData } from '@atb/modules/org-data';

export type BaseLayoutProps = PropsWithChildren<{
title?: TranslatedString | string;
}>;

const { urls: { sitemapUrls: { prod } } } = getOrgData();

export function BaseLayout({ children, title }: BaseLayoutProps) {
useHtmlDarkMode();
const theme = useTheme();
const { t } = useTranslation();

const siteTitle = usePageTitle(title);
const { asPath } = useRouter()


return (
<div className={style.wrapper}>
Expand All @@ -41,13 +36,9 @@ export function BaseLayout({ children, title }: BaseLayoutProps) {
name="theme-color"
content={theme.static.background.background_1.background}
/>

<meta property="og:title" content={siteTitle} />
<meta property="og:type" content="website" />
<meta property="og:url" content={`${prod}${asPath.slice(1)}`} />

</Head>

<OpenGraphBase title={siteTitle} />

<PageHeader />

Expand Down
15 changes: 12 additions & 3 deletions src/page-modules/departures/stop-place/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import { Button } from '@atb/components/button';
import { DepartureTime } from '@atb/components/departure-time';
import { ColorIcon, MonoIcon } from '@atb/components/icon';
import LineChip from '@atb/components/line-chip';
import { MapWithHeader } from '@atb/components/map';
import { OpenGraphImage } from '@atb/components/open-graph';
import ScreenReaderOnly from '@atb/components/screen-reader-only';
import { Typo } from '@atb/components/typography';
import {
SituationMessageBox,
Expand All @@ -20,8 +23,6 @@ import { useRouter } from 'next/router';
import { useState } from 'react';
import { nextDepartures } from '../client';
import style from './stop-place.module.css';
import { DepartureTime } from '@atb/components/departure-time';
import ScreenReaderOnly from '@atb/components/screen-reader-only';

export type StopPlaceProps = {
departures: DepartureData;
Expand All @@ -30,9 +31,17 @@ export function StopPlace({ departures }: StopPlaceProps) {
const { t } = useTranslation();
const router = useRouter();
const [isHoveringRefreshButton, setIsHoveringRefreshButton] = useState(false);

return (
<section className={style.stopPlaceContainer}>
<ScreenReaderOnly text={t(PageText.Departures.stopPlace.quaySection.resultsLoaded)} role='status' />
<OpenGraphImage
image={`api/departures/open-graph?stopPlaceId=${departures.stopPlace.id}`}
/>

<ScreenReaderOnly
text={t(PageText.Departures.stopPlace.quaySection.resultsLoaded)}
role="status"
/>

<div className={style.quaysContainer}>
<button
Expand Down
Loading

0 comments on commit e198672

Please sign in to comment.