alright
This commit is contained in:
parent
c645b0f1d4
commit
39ef5c6646
79 changed files with 5660 additions and 2199 deletions
|
|
@ -40,7 +40,7 @@ type FormFactor = 'desktop' | 'mobile';
|
|||
// most prominent thing on screen (it sits at the top of the bottom
|
||||
// sheet which covers ~44% of the viewport), so we skip the wrapper zoom
|
||||
// entirely — see buildPre().
|
||||
const AI_ZOOM_SCALE_DESKTOP = 2.4;
|
||||
const AI_ZOOM_SCALE_DESKTOP = 2.05;
|
||||
|
||||
const TT_CARD_SELECTOR = '[data-filter-name="tt_0"]';
|
||||
const TT_SLIDER_MAX = 120;
|
||||
|
|
@ -54,14 +54,16 @@ const TT_DRAG_TO_MIN = 20;
|
|||
// sheet, not the map).
|
||||
const MAP_FOCUS_DESKTOP = vfrac(1140 / 1920, 605 / 1080);
|
||||
const MAP_FOCUS_MOBILE = vfrac(0.5, 0.3);
|
||||
const HOMEPAGE_RIGHT_PANE_SELECTOR =
|
||||
'[data-tutorial="right-pane"], .fixed.inset-0.z-50:has(button[aria-label="Close drawer"])';
|
||||
|
||||
// Mobile mapZoom intensity. 6 wheel-steps from the initial zoom (12)
|
||||
// lands around zoom 14.5 — postcode polygons clearly visible, individual
|
||||
// streets named, hex aggregation broken open. The previous 18-step
|
||||
// drill ended past zoom 20 (street-level vector tiles only), so the
|
||||
// click landed on featureless terrain.
|
||||
const MOBILE_MAP_ZOOM_STEPS = 6;
|
||||
const MOBILE_MAP_ZOOM_MS = 1400;
|
||||
// Mobile mapZoom intensity. Keep mobile below the old 18-step drill that
|
||||
// overshot into featureless street-level tiles, but make the homepage pass
|
||||
// visibly break from city blobs into postcode/street scale.
|
||||
const MOBILE_MAP_ZOOM_STEPS = 9;
|
||||
const MOBILE_MAP_ZOOM_MS = 2200;
|
||||
const DESKTOP_MAP_ZOOM_STEPS = 18;
|
||||
const DESKTOP_MAP_ZOOM_MS = 4300;
|
||||
|
||||
type RecordingLocale = 'en' | 'de' | 'zh' | 'hi';
|
||||
|
||||
|
|
@ -74,6 +76,7 @@ interface RecordingLocalization {
|
|||
promptText: string;
|
||||
travelTimeLabel: string;
|
||||
exportButtonTitle: string;
|
||||
colourMapTitle: string;
|
||||
brand: {
|
||||
name: string;
|
||||
tagline: string;
|
||||
|
|
@ -84,6 +87,8 @@ interface RecordingLocalization {
|
|||
prompt: string;
|
||||
dashboard: string;
|
||||
filters: string;
|
||||
zoom: string;
|
||||
open: string;
|
||||
details: string;
|
||||
shortlist: string;
|
||||
};
|
||||
|
|
@ -105,22 +110,29 @@ const RECORDING_LOCALIZATIONS: Record<RecordingLocale, RecordingLocalization> =
|
|||
'strong Manchester accent.',
|
||||
voiceReferenceText:
|
||||
"Welcome to the demonstration. This is the narrator voice you'll hear throughout the video.",
|
||||
promptText: 'Flat under £300k, 35 min to Manchester, good schools, low crime, quiet streets',
|
||||
promptText:
|
||||
'First home under £315k, 35 min to Manchester, good schools, check crime, road noise, tree cover, fast broadband',
|
||||
travelTimeLabel: 'Manchester city centre',
|
||||
exportButtonTitle: 'Export to Excel',
|
||||
colourMapTitle: 'Colour map',
|
||||
brand: {
|
||||
name: 'Perfect Postcode',
|
||||
tagline: 'Know where to look before listings take over.',
|
||||
tagline: 'Find the area before the house.',
|
||||
url: BRAND_URL,
|
||||
},
|
||||
cues: {
|
||||
describe: "Don't pick a home by scrolling listings.",
|
||||
describe: 'A Manchester first-time buyer wants to stop wasting Saturdays on the wrong streets.',
|
||||
prompt:
|
||||
'Describe what you want. Budget, commute, schools, whatever matters.',
|
||||
dashboard: 'The map lights up with every postcode in England that fits.',
|
||||
filters: 'Move one slider. The map answers instantly.',
|
||||
details: 'Open any postcode. Sold prices. Schools. Crime. Noise. All on one screen.',
|
||||
shortlist: 'Take your shortlist to the listings. Now you know where to search.',
|
||||
'They type the whole brief: under £315k, thirty-five minutes to town, good schools, low crime, quieter roads, trees, and fast broadband.',
|
||||
dashboard:
|
||||
'The map keeps only the postcodes that match. The rest of the country drops away.',
|
||||
filters:
|
||||
'Now tweak it: cut the commute to twenty minutes and colour the map by travel time.',
|
||||
zoom: 'Zoom in until the blobs become streets, parks, and postcode blocks.',
|
||||
open: 'Open one block that still passes the filters.',
|
||||
details:
|
||||
'On the right, you can see why it passed: journey time, listing links, Street View, sold prices, schools, crime, the noise number, and the tree score.',
|
||||
shortlist: 'Export those postcodes and only search there.',
|
||||
},
|
||||
},
|
||||
de: {
|
||||
|
|
@ -131,26 +143,29 @@ const RECORDING_LOCALIZATIONS: Record<RecordingLocale, RecordingLocalization> =
|
|||
'Calm and cheerful German male narrator with clear standard German pronunciation ' +
|
||||
'and a friendly, practical delivery.',
|
||||
voiceReferenceText:
|
||||
'Willkommen zur Demonstration. Diese Sprecherstimme hören Sie im gesamten Video.',
|
||||
'Willkommen zur Demonstration. Diese Sprecherstimme hörst du im gesamten Video.',
|
||||
promptText:
|
||||
'Wohnung unter £300k, 35 Min. nach Manchester, gute Schulen, niedrige Kriminalität, ruhige Straßen',
|
||||
travelTimeLabel: 'Stadtzentrum Manchester',
|
||||
exportButtonTitle: 'Als Excel exportieren',
|
||||
colourMapTitle: 'Karte einfärben',
|
||||
brand: {
|
||||
name: 'Perfect Postcode',
|
||||
tagline: 'Wissen, wo Sie suchen sollten, bevor Inserate Ihre Suche bestimmen.',
|
||||
tagline: 'Wissen, wo du suchen solltest, bevor Inserate deine Suche bestimmen.',
|
||||
url: BRAND_URL,
|
||||
},
|
||||
cues: {
|
||||
describe: 'Wählen Sie kein Zuhause durch endloses Scrollen.',
|
||||
describe: 'Wähle kein Zuhause durch endloses Scrollen.',
|
||||
prompt:
|
||||
'Beschreiben Sie, was Ihnen wichtig ist. Budget, Pendelzeit, Schulen, alles.',
|
||||
'Beschreibe, was dir wichtig ist. Budget, Pendelzeit, Schulen, alles.',
|
||||
dashboard: 'Die Karte zeigt jede passende Postleitzahl in ganz England.',
|
||||
filters: 'Ein Regler bewegt sich. Die Karte antwortet sofort.',
|
||||
zoom: 'Jetzt von der Stadtansicht bis zu echten Straßen zoomen.',
|
||||
open: 'Öffne einen Treffer und sieh, warum er übrig bleibt.',
|
||||
details:
|
||||
'Öffnen Sie eine Postleitzahl. Preise. Schulen. Kriminalität. Lärm. Alles auf einer Karte.',
|
||||
'Öffne eine Postleitzahl. Preise. Schulen. Kriminalität. Lärm. Alles auf einer Karte.',
|
||||
shortlist:
|
||||
'Mit dieser Auswahl zu den Inseraten. Sie wissen jetzt, wo Sie suchen sollen.',
|
||||
'Mit dieser Auswahl zu den Inseraten. Du weißt jetzt, wo du suchen sollst.',
|
||||
},
|
||||
},
|
||||
zh: {
|
||||
|
|
@ -164,6 +179,7 @@ const RECORDING_LOCALIZATIONS: Record<RecordingLocale, RecordingLocalization> =
|
|||
promptText: '30万英镑以内的公寓,35分钟到曼彻斯特,学校好,犯罪率低,街道安静',
|
||||
travelTimeLabel: '曼彻斯特市中心',
|
||||
exportButtonTitle: '导出为 Excel',
|
||||
colourMapTitle: '为地图着色',
|
||||
brand: {
|
||||
name: 'Perfect Postcode',
|
||||
tagline: '先知道该看哪里,再让房源牵着你走。',
|
||||
|
|
@ -174,6 +190,8 @@ const RECORDING_LOCALIZATIONS: Record<RecordingLocale, RecordingLocalization> =
|
|||
prompt: '用日常话告诉地图你想要的家。预算、通勤、学校,什么都行。',
|
||||
dashboard: '地图点亮每一个符合条件的英格兰邮编。',
|
||||
filters: '动一个滑块,地图立刻给答案。',
|
||||
zoom: '现在从城市范围放大到真实街道。',
|
||||
open: '打开一个匹配项,看看它为什么留下来。',
|
||||
details: '打开任意邮编。成交价、学校、犯罪率、噪音,一目了然。',
|
||||
shortlist: '带着这份清单去房源网站。现在你知道该在哪儿找了。',
|
||||
},
|
||||
|
|
@ -190,6 +208,7 @@ const RECORDING_LOCALIZATIONS: Record<RecordingLocale, RecordingLocalization> =
|
|||
promptText: 'Flat under £300k, 35 min to Manchester, good schools, low crime, quiet streets',
|
||||
travelTimeLabel: 'Manchester city centre',
|
||||
exportButtonTitle: 'Excel में निर्यात करें',
|
||||
colourMapTitle: 'नक्शे को रंगें',
|
||||
brand: {
|
||||
name: 'Perfect Postcode',
|
||||
tagline: 'Know where to look before listings take over.',
|
||||
|
|
@ -201,6 +220,8 @@ const RECORDING_LOCALIZATIONS: Record<RecordingLocale, RecordingLocalization> =
|
|||
'Describe what you want. Budget, commute, schools, whatever matters.',
|
||||
dashboard: 'The map lights up with every postcode in England that fits.',
|
||||
filters: 'Move one slider. The map answers instantly.',
|
||||
zoom: 'Now zoom in from the city pattern to actual streets.',
|
||||
open: 'Open one match and see why it made the cut.',
|
||||
details: 'Open any postcode. Sold prices. Schools. Crime. Noise. All on one screen.',
|
||||
shortlist: 'Take your shortlist to the listings. Now you know where to search.',
|
||||
},
|
||||
|
|
@ -211,25 +232,23 @@ function createCues(locale: RecordingLocale, formFactor: FormFactor): Storyboard
|
|||
const copy = RECORDING_LOCALIZATIONS[locale];
|
||||
const isMobile = formFactor === 'mobile';
|
||||
const mapFocus = isMobile ? MAP_FOCUS_MOBILE : MAP_FOCUS_DESKTOP;
|
||||
const mapZoomSteps = isMobile ? MOBILE_MAP_ZOOM_STEPS : 18;
|
||||
const mapZoomMs = isMobile ? MOBILE_MAP_ZOOM_MS : 1500;
|
||||
// Click target stays at the mapZoom focus point. On mobile we kept the
|
||||
// zoom shallow (6 wheel-steps → ~zoom 14.5) specifically so the centre
|
||||
// of the visible map area lands on a real postcode polygon at that
|
||||
// depth; using a vfrac target is deterministic and avoids needing a
|
||||
// `[data-tutorial="map"]` anchor in the MobileMapPage DOM (it has
|
||||
// none — that attribute lives only on DesktopMapPage).
|
||||
const clickTarget = mapFocus;
|
||||
const mapZoomSteps = isMobile ? MOBILE_MAP_ZOOM_STEPS : DESKTOP_MAP_ZOOM_STEPS;
|
||||
const mapZoomMs = isMobile ? MOBILE_MAP_ZOOM_MS : DESKTOP_MAP_ZOOM_MS;
|
||||
const colourTravelTime = el(`${TT_CARD_SELECTOR} button[title="${copy.colourMapTitle}"]`);
|
||||
const postcodeDemoTarget = isMobile
|
||||
? vfrac(320 / 540, 255 / 960)
|
||||
: vfrac(1087 / 1920, 520 / 1080);
|
||||
const openPostcodeTarget = postcodeDemoTarget;
|
||||
const zoomPostcodeTarget = postcodeDemoTarget;
|
||||
const cursorParkTarget = isMobile ? vfrac(0.12, 0.61) : vfrac(0.12, 0.18);
|
||||
const definingCharacteristicsSelector =
|
||||
'[data-tutorial="right-pane"] button:has-text("Defining characteristics"), ' +
|
||||
'.fixed.inset-0.z-50:has(button[aria-label="Close drawer"]) button:has-text("Defining characteristics")';
|
||||
|
||||
// Cue 5 (shortlist) on mobile: the Export button lives inside the
|
||||
// hidden hamburger menu, not in the header — opening it cleanly would
|
||||
// need a localised aria-label lookup. Instead we pull the map back
|
||||
// out to the filtered overview so the cut ends on a satisfying wide
|
||||
// shot of the matching postcodes rather than the post-click zoom.
|
||||
const shortlistActivities: Storyboard['cues'][number]['during'] =
|
||||
formFactor === 'desktop'
|
||||
? [
|
||||
{ kind: 'zoomReset', durationMs: 900 },
|
||||
{ kind: 'zoomReset', durationMs: 800 },
|
||||
{
|
||||
kind: 'click',
|
||||
target: el(`button[title="${copy.exportButtonTitle}"]`),
|
||||
|
|
@ -237,14 +256,19 @@ function createCues(locale: RecordingLocale, formFactor: FormFactor): Storyboard
|
|||
},
|
||||
]
|
||||
: [
|
||||
// Reverse the cue-4 zoom-in exactly so we land back on the
|
||||
// initial filtered dashboard view (hexagons visible).
|
||||
{
|
||||
kind: 'click',
|
||||
target: el('button[aria-label="Close drawer"]'),
|
||||
durationMs: 650,
|
||||
},
|
||||
{
|
||||
kind: 'mapZoom',
|
||||
target: mapFocus,
|
||||
steps: MOBILE_MAP_ZOOM_STEPS,
|
||||
durationMs: MOBILE_MAP_ZOOM_MS,
|
||||
direction: 'out',
|
||||
waitForMapSettled: true,
|
||||
timeoutMs: 12000,
|
||||
},
|
||||
];
|
||||
|
||||
|
|
@ -252,7 +276,17 @@ function createCues(locale: RecordingLocale, formFactor: FormFactor): Storyboard
|
|||
{
|
||||
text: copy.cues.describe,
|
||||
gapBeforeMs: 0,
|
||||
tail: [{ kind: 'wait', durationMs: 250 }],
|
||||
during: isMobile
|
||||
? [{ kind: 'wait', durationMs: 700 }]
|
||||
: [
|
||||
{
|
||||
kind: 'zoomTo',
|
||||
target: el('[data-tutorial="ai-filters"]'),
|
||||
scale: AI_ZOOM_SCALE_DESKTOP,
|
||||
durationMs: 900,
|
||||
},
|
||||
],
|
||||
tail: [{ kind: 'wait', durationMs: 150 }],
|
||||
},
|
||||
{
|
||||
text: copy.cues.prompt,
|
||||
|
|
@ -262,17 +296,25 @@ function createCues(locale: RecordingLocale, formFactor: FormFactor): Storyboard
|
|||
kind: 'type',
|
||||
selector: '[data-tutorial="ai-filters"] textarea',
|
||||
text: copy.promptText,
|
||||
durationMs: 3000,
|
||||
durationMs: 4300,
|
||||
},
|
||||
{ kind: 'submitForm', formSelector: '[data-tutorial="ai-filters"] form', durationMs: 1200 },
|
||||
],
|
||||
tail: [{ kind: 'wait', durationMs: 500 }],
|
||||
tail: [{ kind: 'wait', durationMs: 120 }],
|
||||
},
|
||||
{
|
||||
text: copy.cues.dashboard,
|
||||
gapBeforeMs: 300,
|
||||
during: [{ kind: 'zoomReset', durationMs: 1400 }],
|
||||
tail: [{ kind: 'wait', durationMs: 500 }],
|
||||
during: [
|
||||
{
|
||||
kind: 'submitForm',
|
||||
formSelector: '[data-tutorial="ai-filters"] form',
|
||||
durationMs: 2200,
|
||||
waitForMapSettled: true,
|
||||
timeoutMs: 15000,
|
||||
},
|
||||
{ kind: 'zoomReset', durationMs: 900 },
|
||||
],
|
||||
tail: [{ kind: 'wait', durationMs: 300 }],
|
||||
},
|
||||
|
||||
{
|
||||
|
|
@ -284,45 +326,106 @@ function createCues(locale: RecordingLocale, formFactor: FormFactor): Storyboard
|
|||
thumbSelector: `${TT_CARD_SELECTOR} [role="slider"] >> nth=1`,
|
||||
trackSelector: `${TT_CARD_SELECTOR} [data-orientation="horizontal"] >> nth=0`,
|
||||
toFraction: TT_DRAG_TO_MIN / TT_SLIDER_MAX,
|
||||
durationMs: 1000,
|
||||
durationMs: 1800,
|
||||
},
|
||||
{ kind: 'click', target: colourTravelTime, durationMs: 750 },
|
||||
],
|
||||
tail: [{ kind: 'wait', durationMs: 400 }],
|
||||
tail: [{ kind: 'wait', durationMs: 350 }],
|
||||
},
|
||||
|
||||
{
|
||||
text: copy.cues.details,
|
||||
text: copy.cues.zoom,
|
||||
gapBeforeMs: 500,
|
||||
during: [
|
||||
{ kind: 'cursorScale', scale: 1.4, durationMs: 200 },
|
||||
{
|
||||
kind: 'mapZoom',
|
||||
target: mapFocus,
|
||||
target: zoomPostcodeTarget,
|
||||
steps: mapZoomSteps,
|
||||
durationMs: mapZoomMs,
|
||||
},
|
||||
],
|
||||
tail: [
|
||||
// Wait for the post-zoom /api/postcodes response and a redraw
|
||||
// before the click — otherwise the click can fire on a stale
|
||||
// frame and miss the polygon.
|
||||
{ kind: 'wait', durationMs: 500 },
|
||||
{ kind: 'moveCursor', target: cursorParkTarget, durationMs: 250 },
|
||||
{ kind: 'wait', durationMs: 120 },
|
||||
],
|
||||
},
|
||||
|
||||
{
|
||||
text: copy.cues.open,
|
||||
gapBeforeMs: 200,
|
||||
during: [
|
||||
{
|
||||
kind: 'click',
|
||||
target: clickTarget,
|
||||
durationMs: 700,
|
||||
target: openPostcodeTarget,
|
||||
durationMs: 1200,
|
||||
waitForSelectionReady: true,
|
||||
timeoutMs: 6000,
|
||||
},
|
||||
{ kind: 'cursorScale', scale: 1, durationMs: 280 },
|
||||
// Linger so the climax cue lands on the right-pane reveal.
|
||||
{ kind: 'wait', durationMs: 1500 },
|
||||
{ kind: 'cursorScale', scale: 1, durationMs: 250 },
|
||||
],
|
||||
tail: [{ kind: 'wait', durationMs: 300 }],
|
||||
},
|
||||
|
||||
{
|
||||
text: copy.cues.details,
|
||||
captionPlacement: isMobile ? undefined : 'side',
|
||||
gapBeforeMs: 250,
|
||||
during: isMobile
|
||||
? [
|
||||
{
|
||||
kind: 'scrollPane',
|
||||
selector: HOMEPAGE_RIGHT_PANE_SELECTOR,
|
||||
top: 430,
|
||||
durationMs: 900,
|
||||
},
|
||||
{
|
||||
kind: 'clickIfVisible',
|
||||
target: el(definingCharacteristicsSelector),
|
||||
durationMs: 650,
|
||||
timeoutMs: 700,
|
||||
},
|
||||
{
|
||||
kind: 'scrollPane',
|
||||
selector: HOMEPAGE_RIGHT_PANE_SELECTOR,
|
||||
top: 700,
|
||||
durationMs: 850,
|
||||
},
|
||||
]
|
||||
: [
|
||||
{
|
||||
kind: 'zoomTo',
|
||||
target: el(HOMEPAGE_RIGHT_PANE_SELECTOR),
|
||||
scale: 1.35,
|
||||
durationMs: 950,
|
||||
},
|
||||
{
|
||||
kind: 'scrollPane',
|
||||
selector: HOMEPAGE_RIGHT_PANE_SELECTOR,
|
||||
top: 360,
|
||||
durationMs: 850,
|
||||
},
|
||||
{
|
||||
kind: 'clickIfVisible',
|
||||
target: el(definingCharacteristicsSelector),
|
||||
durationMs: 650,
|
||||
timeoutMs: 700,
|
||||
},
|
||||
{
|
||||
kind: 'scrollPane',
|
||||
selector: HOMEPAGE_RIGHT_PANE_SELECTOR,
|
||||
top: 920,
|
||||
durationMs: 850,
|
||||
},
|
||||
],
|
||||
tail: [{ kind: 'wait', durationMs: 700 }],
|
||||
},
|
||||
|
||||
{
|
||||
text: copy.cues.shortlist,
|
||||
gapBeforeMs: 500,
|
||||
during: shortlistActivities,
|
||||
tail: [{ kind: 'wait', durationMs: 800 }],
|
||||
tail: [{ kind: 'wait', durationMs: 650 }],
|
||||
},
|
||||
|
||||
{
|
||||
|
|
@ -344,26 +447,14 @@ function createCues(locale: RecordingLocale, formFactor: FormFactor): Storyboard
|
|||
|
||||
function buildPre(formFactor: FormFactor): Storyboard['pre'] {
|
||||
if (formFactor === 'mobile') {
|
||||
// Mobile skips the wrapper-zoom into the AI card. On a 540-wide
|
||||
// viewport the bottom sheet already occupies ~44% of the screen
|
||||
// and the AI card sits at the top of it — leaning further in would
|
||||
// overflow the card width and crop the placeholder. We just clear
|
||||
// the vignette and let the typing draw the eye.
|
||||
return [
|
||||
{ kind: 'clearVignette', durationMs: 0 },
|
||||
{ kind: 'wait', durationMs: 400 },
|
||||
{ kind: 'wait', durationMs: 120 },
|
||||
];
|
||||
}
|
||||
return [
|
||||
{ kind: 'clearVignette', durationMs: 0 },
|
||||
{ kind: 'wait', durationMs: 200 },
|
||||
{
|
||||
kind: 'zoomTo',
|
||||
target: el('[data-tutorial="ai-filters"]'),
|
||||
scale: AI_ZOOM_SCALE_DESKTOP,
|
||||
durationMs: 1300,
|
||||
},
|
||||
{ kind: 'wait', durationMs: 140 },
|
||||
{ kind: 'wait', durationMs: 120 },
|
||||
];
|
||||
}
|
||||
|
||||
|
|
@ -452,10 +543,13 @@ function createRecordingStoryboard(
|
|||
// Filters returned by the AI stub. Keys MUST match real feature names
|
||||
// from /api/features (verified against the running server's schema).
|
||||
stubbedFilters: {
|
||||
'Property type': ['Flats/Maisonettes'],
|
||||
'Estimated current price': [0, 300000],
|
||||
'Serious crime per 1k residents (avg/yr)': [0, 55],
|
||||
'Outstanding primary schools within 2km': [1, 10],
|
||||
'Property type': ['Flats/Maisonettes', 'Semi-Detached'],
|
||||
'Estimated current price': [0, 315000],
|
||||
'Serious crime per 1k residents (avg/yr)': [0, 70],
|
||||
'Good+ primary schools within 2km': [1, 10],
|
||||
'Noise (dB)': [50, 70],
|
||||
'Street tree density percentile': [25, 100],
|
||||
'Max available download speed (Mbps)': ['100', '300', '1000'],
|
||||
},
|
||||
// Travel-time filters returned by the AI stub. Slug matches the real
|
||||
// /api/travel-destinations?mode=transit response.
|
||||
|
|
@ -481,6 +575,10 @@ function createRecordingStoryboard(
|
|||
const RECORDING_LOCALES: readonly RecordingLocale[] = ['en', 'de', 'zh', 'hi'];
|
||||
const RECORDING_FORM_FACTORS: readonly FormFactor[] = ['desktop', 'mobile'];
|
||||
|
||||
const ENGLISH_HOMEPAGE_STORYBOARDS: Storyboard[] = RECORDING_FORM_FACTORS.map((formFactor) =>
|
||||
createRecordingStoryboard('en', formFactor)
|
||||
);
|
||||
|
||||
const DEMO_STORYBOARDS: Storyboard[] = RECORDING_LOCALES.flatMap((locale) =>
|
||||
RECORDING_FORM_FACTORS.map((formFactor) => createRecordingStoryboard(locale, formFactor))
|
||||
);
|
||||
|
|
@ -1271,14 +1369,21 @@ const AD_CONFIGS: DemoAdStoryboardConfig[] = [
|
|||
|
||||
const AD_STORYBOARDS = AD_CONFIGS.map(createDemoAdStoryboard);
|
||||
|
||||
const STORYBOARD_SET = process.env.VIDEO_STORYBOARD_SET ?? 'ads';
|
||||
const STORYBOARD_SET = process.env.VIDEO_STORYBOARD_SET ?? 'homepage-en';
|
||||
|
||||
export const storyboards: Storyboard[] =
|
||||
STORYBOARD_SET === 'demo'
|
||||
? DEMO_STORYBOARDS
|
||||
: STORYBOARD_SET === 'all'
|
||||
? [...AD_STORYBOARDS, ...DEMO_STORYBOARDS]
|
||||
: AD_STORYBOARDS;
|
||||
export const storyboards: Storyboard[] = (() => {
|
||||
switch (STORYBOARD_SET) {
|
||||
case 'homepage-en':
|
||||
return ENGLISH_HOMEPAGE_STORYBOARDS;
|
||||
case 'demo':
|
||||
return DEMO_STORYBOARDS;
|
||||
case 'all':
|
||||
return [...AD_STORYBOARDS, ...DEMO_STORYBOARDS];
|
||||
case 'ads':
|
||||
default:
|
||||
return AD_STORYBOARDS;
|
||||
}
|
||||
})();
|
||||
|
||||
export function getStoryboard(name: string): Storyboard {
|
||||
const sb = storyboards.find((s) => s.name === name);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue