feat: add projectType metadata field (standard | shorts)
Adds optional projectType discriminator on TProjectMetadata so downstream features (preset pickers, export defaults, UI affordances) can branch on intent without inferring from canvas dimensions. - New const PROJECT_TYPES and type TProjectType - TProjectMetadata.projectType (optional for back-compat with stored projects) - ProjectManager.createNewProject accepts optional projectType, defaults to 'standard' - Unit tests for PROJECT_TYPES invariants
This commit is contained in:
parent
6fdb1559aa
commit
7131f88bf4
|
|
@ -5,6 +5,7 @@ import type {
|
|||
TProjectSortKey,
|
||||
TProjectSortOption,
|
||||
TProjectSettings,
|
||||
TProjectType,
|
||||
TTimelineViewState,
|
||||
} from "@/project/types";
|
||||
import type { ExportOptions, ExportResult, ExportState } from "@/export";
|
||||
|
|
@ -79,7 +80,13 @@ export class ProjectManager {
|
|||
await this.storageMigrationPromise;
|
||||
}
|
||||
|
||||
async createNewProject({ name }: { name: string }): Promise<string> {
|
||||
async createNewProject({
|
||||
name,
|
||||
projectType,
|
||||
}: {
|
||||
name: string;
|
||||
projectType?: TProjectType;
|
||||
}): Promise<string> {
|
||||
const mainScene = buildDefaultScene({ name: "Main scene", isMain: true });
|
||||
const newProject: TProject = {
|
||||
metadata: {
|
||||
|
|
@ -88,6 +95,7 @@ export class ProjectManager {
|
|||
duration: getProjectDurationFromScenes({ scenes: [mainScene] }),
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
projectType: projectType ?? "standard",
|
||||
},
|
||||
scenes: [mainScene],
|
||||
currentSceneId: mainScene.id,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,22 @@
|
|||
import { describe, expect, test } from "bun:test";
|
||||
import { PROJECT_TYPES, type TProjectType } from "@/project/types";
|
||||
|
||||
describe("PROJECT_TYPES", () => {
|
||||
test("contains standard and shorts", () => {
|
||||
expect(PROJECT_TYPES).toContain("standard");
|
||||
expect(PROJECT_TYPES).toContain("shorts");
|
||||
});
|
||||
|
||||
test("project metadata uses 'standard' when projectType is undefined", () => {
|
||||
function buildMetadataProjectType(input?: TProjectType): TProjectType {
|
||||
return input ?? "standard";
|
||||
}
|
||||
expect(buildMetadataProjectType(undefined)).toBe("standard");
|
||||
expect(buildMetadataProjectType("shorts")).toBe("shorts");
|
||||
expect(buildMetadataProjectType("standard")).toBe("standard");
|
||||
});
|
||||
|
||||
test("PROJECT_TYPES is stable in declared order", () => {
|
||||
expect([...PROJECT_TYPES]).toEqual(["standard", "shorts"]);
|
||||
});
|
||||
});
|
||||
|
|
@ -2,6 +2,15 @@ import type { FrameRate } from "opencut-wasm";
|
|||
import type { TScene } from "@/timeline/types";
|
||||
import type { MediaTime } from "@/wasm";
|
||||
|
||||
export const PROJECT_TYPES = ["standard", "shorts"] as const;
|
||||
/**
|
||||
* Project intent. "shorts" indicates a vertical 9:16 short-form project
|
||||
* (e.g. YouTube Shorts) — drives preset pickers, export defaults, and
|
||||
* vertical-safe text positioning. "standard" covers landscape, square,
|
||||
* and other non-Shorts aspect ratios.
|
||||
*/
|
||||
export type TProjectType = (typeof PROJECT_TYPES)[number];
|
||||
|
||||
export type TBackground =
|
||||
| {
|
||||
type: "color";
|
||||
|
|
@ -24,6 +33,13 @@ export interface TProjectMetadata {
|
|||
duration: MediaTime;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
/**
|
||||
* Discriminator for project intent. Optional for back-compat — undefined on
|
||||
* projects created before this field existed; consumers MUST treat undefined
|
||||
* as "standard" (e.g. `projectType ?? "standard"`). New projects always set
|
||||
* this explicitly via ProjectManager.createNewProject.
|
||||
*/
|
||||
projectType?: TProjectType;
|
||||
}
|
||||
|
||||
export interface TProjectSettings {
|
||||
|
|
|
|||
Loading…
Reference in New Issue