85 lines
2.6 KiB
TypeScript
85 lines
2.6 KiB
TypeScript
export type EnvironmentMediaKind = "image" | "video";
|
|
export type EnvironmentMediaSource = "file" | "url";
|
|
|
|
export interface EnvironmentMediaItem {
|
|
id: string;
|
|
source: EnvironmentMediaSource;
|
|
url: string | null;
|
|
mediaKind: EnvironmentMediaKind | null;
|
|
fileName: string | null;
|
|
}
|
|
|
|
export interface EnvironmentBackground {
|
|
enabled: boolean;
|
|
imageDurationSeconds: number;
|
|
items: EnvironmentMediaItem[];
|
|
}
|
|
|
|
export interface EnvironmentPage {
|
|
headerLabel: string;
|
|
eyebrow: string;
|
|
title: string;
|
|
description: string;
|
|
primaryWorkspaceId: string | null;
|
|
secondaryWorkspaceId: string | null;
|
|
background: EnvironmentBackground;
|
|
}
|
|
|
|
export interface EnvironmentSettings { revision: number; pages: Record<string, EnvironmentPage> }
|
|
export interface UploadedEnvironmentMedia { url: string; fileName: string; mediaKind: EnvironmentMediaKind }
|
|
export interface EnvironmentAction { id: string; label: string; description?: string }
|
|
export interface EnvironmentSurface { id: string; home?: boolean; description?: string; actions: readonly EnvironmentAction[] }
|
|
|
|
export const defaultEnvironmentImageDurationSeconds = 10;
|
|
export const maxEnvironmentMediaItems = 24;
|
|
|
|
export function createEnvironmentMediaItem(): EnvironmentMediaItem {
|
|
return {
|
|
id: `media-${crypto.randomUUID()}`,
|
|
source: "file",
|
|
url: null,
|
|
mediaKind: null,
|
|
fileName: null,
|
|
};
|
|
}
|
|
|
|
export function appendEnvironmentMediaItem(
|
|
background: EnvironmentBackground,
|
|
item: EnvironmentMediaItem = createEnvironmentMediaItem(),
|
|
): EnvironmentBackground {
|
|
if (
|
|
background.items.length >= maxEnvironmentMediaItems
|
|
|| background.items.some((candidate) => candidate.id === item.id)
|
|
) {
|
|
return background;
|
|
}
|
|
return {
|
|
...background,
|
|
enabled: background.items.length === 0 ? true : background.enabled,
|
|
items: [...background.items, item],
|
|
};
|
|
}
|
|
|
|
export function removeEnvironmentMediaItem(
|
|
background: EnvironmentBackground,
|
|
itemId: string,
|
|
): EnvironmentBackground {
|
|
const items = background.items.filter((item) => item.id !== itemId);
|
|
if (items.length === background.items.length) return background;
|
|
return {
|
|
...background,
|
|
enabled: items.length > 0 && background.enabled,
|
|
items,
|
|
};
|
|
}
|
|
|
|
export function inferEnvironmentMediaKind(url: string): EnvironmentMediaKind {
|
|
return /\.(mp4|webm|mov)(?:[?#].*)?$/i.test(url) ? "video" : "image";
|
|
}
|
|
|
|
export function cloneEnvironmentSettings(settings: EnvironmentSettings): EnvironmentSettings {
|
|
return { ...settings, pages: Object.fromEntries(Object.entries(settings.pages).map(([id, page]) => [id, {
|
|
...page, background: { ...page.background, items: page.background.items.map(item => ({ ...item })) },
|
|
}])) };
|
|
}
|