From b00951de19e7010efd39194e2c26efc00021e3ba Mon Sep 17 00:00:00 2001 From: Julian Boilen Date: Sat, 16 Sep 2023 12:49:02 -0400 Subject: [PATCH] Add map and image to story email --- .../templates/StoryUserEmailTemplateData.ts | 3 ++ .../business/stories/StoryUserEmailService.ts | 19 +++++++++ .../src/business/utils/forgeStaticMapUrl.ts | 39 +++++++++++++++++++ 3 files changed, 61 insertions(+) create mode 100644 backend/src/business/utils/forgeStaticMapUrl.ts diff --git a/backend/src/business/email/templates/StoryUserEmailTemplateData.ts b/backend/src/business/email/templates/StoryUserEmailTemplateData.ts index acee2b0a..c98dd3ea 100644 --- a/backend/src/business/email/templates/StoryUserEmailTemplateData.ts +++ b/backend/src/business/email/templates/StoryUserEmailTemplateData.ts @@ -3,6 +3,9 @@ export interface StoryEmailTemplateData { photoDescription: string; storyEditUrl: string; viewPhotoUrl: string; + photoThumbnailUrl: string; + mapImageUrl: string | null; + mapImageUrlRetina: string | null; } export interface StoryEmailMetadata { diff --git a/backend/src/business/stories/StoryUserEmailService.ts b/backend/src/business/stories/StoryUserEmailService.ts index 919c24b3..82118f3c 100644 --- a/backend/src/business/stories/StoryUserEmailService.ts +++ b/backend/src/business/stories/StoryUserEmailService.ts @@ -12,6 +12,7 @@ import { StoryEmailTemplateData, } from '../email/templates/StoryUserEmailTemplateData'; import StoryUserRemovedTemplate from '../email/templates/StoryUserRemovedTemplate'; +import forgeStaticMapUrl from '../utils/forgeStaticMapUrl'; import required from '../utils/required'; import { createStoryToken } from './StoryTokenService'; @@ -62,12 +63,30 @@ function forgePhotoUrl(photo: Story['photo'], lngLat: Story['lngLat']): string { return storyEditUrl.toString(); } +function forgeImageThumbnailUrl(photo: Story['photo']): string { + return `https://photos.1940s.nyc/420-jpg/${photo.identifier}.jpg`; +} + +function forgeMapImageUrl( + photo: Story['photo'], + lngLat: Story['lngLat'], + retina = false +): string | null { + if (!lngLat) { + return null; + } + return forgeStaticMapUrl(photo.identifier, lngLat, 315, 315, 16, retina); +} + function forgeStoryTemplateContext(story: Story): StoryEmailTemplateData { return { storytellerName: required(story.storytellerName, 'storytellerName'), photoDescription: describePhoto(story.photo), storyEditUrl: forgeStoryEditUrl(story), viewPhotoUrl: forgePhotoUrl(story.photo, story.lngLat), + photoThumbnailUrl: forgeImageThumbnailUrl(story.photo), + mapImageUrl: forgeMapImageUrl(story.photo, story.lngLat, false), + mapImageUrlRetina: forgeMapImageUrl(story.photo, story.lngLat, true), }; } diff --git a/backend/src/business/utils/forgeStaticMapUrl.ts b/backend/src/business/utils/forgeStaticMapUrl.ts new file mode 100644 index 00000000..ed27faac --- /dev/null +++ b/backend/src/business/utils/forgeStaticMapUrl.ts @@ -0,0 +1,39 @@ +import LngLat from '../../enum/LngLat'; + +const MAPBOX_USER = 'julianboilen'; +const MAPBOX_PK = + 'pk.eyJ1IjoianVsaWFuYm9pbGVuIiwiYSI6ImNqb3A0ODg1djFkNGIza214aDQ0NjA2ZHYifQ.nw1o5FE0rdcN5DQLzRFQfQ'; +const MAP_STYLE_ID = 'ck5jrzrs11r1p1imia7qzjkm1'; +const LAYER_ID = 'photos-1940s'; + +export default function forgeStaticMapUrl( + photoIdentifier: string, + lngLat: LngLat, + width: number, + height: number, + zoomLevel: number, + retina = false +): string | null { + if (!lngLat) { + return null; + } + const { lng, lat } = lngLat; + const mapImageUrl: URL = new URL( + `/styles/v1/${MAPBOX_USER}/${MAP_STYLE_ID}/static/${lng},${lat},${zoomLevel}/${width}x${height}${ + retina ? '@2x' : '' + }}`, + 'https://api.mapbox.com' + ); + + const mapImageUrlParams: URLSearchParams = new URLSearchParams(); + mapImageUrlParams.append('access_token', MAPBOX_PK); + mapImageUrlParams.append( + 'setfilter', + `["==", ["get", "photoIdentifier"], "${photoIdentifier}"]` + ); + mapImageUrlParams.append('layer_id', LAYER_ID); + + mapImageUrl.search = mapImageUrlParams.toString(); + + return mapImageUrl.toString(); +}