Files
MahdiandCursor c236b0f621 Add display frames and improve create-page page management.
Store phone/tablet/photo-frame shells with catalogs, append pages from extra images or PDFs, and reorder drafts with drag-and-drop.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-20 14:20:16 +03:30

87 lines
2.3 KiB
TypeScript

import { eq } from "drizzle-orm";
import type { EffectId, FrameId } from "../shared/types";
import { DEFAULT_FLIP_MS, DEFAULT_FRAME, isFrameId } from "../shared/types";
import type { DbBundle } from "./db";
import { catalogsTable } from "./schema";
export type CatalogRow = {
id: string;
deleteToken: string;
title: string;
effect: EffectId;
frame: FrameId;
pageCount: number;
flipMs: number;
createdAt: string;
};
export type CatalogInsert = Omit<CatalogRow, "createdAt" | "flipMs" | "frame"> & {
createdAt?: string;
flipMs?: number;
frame?: FrameId;
};
function toRow(record: typeof catalogsTable.$inferSelect): CatalogRow {
const frameRaw = record.frame ?? DEFAULT_FRAME;
return {
id: record.id,
deleteToken: record.deleteToken,
title: record.title,
effect: record.effect as EffectId,
frame: isFrameId(frameRaw) ? frameRaw : DEFAULT_FRAME,
pageCount: record.pageCount,
flipMs: record.flipMs ?? DEFAULT_FLIP_MS,
createdAt: record.createdAt,
};
}
export function createCatalogRepo(db: DbBundle) {
return {
create(input: CatalogInsert): CatalogRow {
const createdAt = input.createdAt ?? new Date().toISOString();
const flipMs = input.flipMs ?? DEFAULT_FLIP_MS;
const frame = input.frame ?? DEFAULT_FRAME;
db.drizzle.insert(catalogsTable).values({
id: input.id,
deleteToken: input.deleteToken,
title: input.title,
effect: input.effect,
pageCount: input.pageCount,
flipMs,
frame,
createdAt,
}).run();
db.persist();
return {
id: input.id,
deleteToken: input.deleteToken,
title: input.title,
effect: input.effect,
frame,
pageCount: input.pageCount,
flipMs,
createdAt,
};
},
getById(id: string): CatalogRow | null {
const row = db.drizzle
.select()
.from(catalogsTable)
.where(eq(catalogsTable.id, id))
.get();
return row ? toRow(row) : null;
},
deleteById(id: string): boolean {
const existing = this.getById(id);
if (!existing) return false;
db.drizzle.delete(catalogsTable).where(eq(catalogsTable.id, id)).run();
db.persist();
return true;
},
};
}
export type CatalogRepo = ReturnType<typeof createCatalogRepo>;