diff --git a/src/actions/artworks/generateArtworkColors.ts b/src/actions/artworks/generateArtworkColors.ts index 8a4b757..eb1108b 100644 --- a/src/actions/artworks/generateArtworkColors.ts +++ b/src/actions/artworks/generateArtworkColors.ts @@ -1,36 +1,49 @@ "use server"; import { prisma } from "@/lib/prisma"; -import { VibrantSwatch } from "@/types/VibrantSwatch"; +import type { VibrantSwatch } from "@/types/VibrantSwatch"; import { getImageBufferFromS3Key } from "@/utils/getImageBufferFromS3"; import { generateColorName, rgbToHex } from "@/utils/uploadHelper"; import { converter, parse } from "culori"; import { Vibrant } from "node-vibrant/node"; const toOklab = converter("oklab"); -const A_MIN = -0.5, A_MAX = 0.5; -const B_MIN = -0.5, B_MAX = 0.5; +const A_MIN = -0.5, + A_MAX = 0.5; +const B_MIN = -0.5, + B_MAX = 0.5; -function clamp01(x: number) { return Math.max(0, Math.min(1, x)); } -function norm(x: number, lo: number, hi: number) { return clamp01((x - lo) / (hi - lo)); } +function clamp01(x: number) { + return Math.max(0, Math.min(1, x)); +} +function norm(x: number, lo: number, hi: number) { + return clamp01((x - lo) / (hi - lo)); +} function hilbertIndex15(x01: number, y01: number): number { let x = Math.floor(clamp01(x01) * 32767); let y = Math.floor(clamp01(y01) * 32767); let index = 0; for (let s = 1 << 14; s > 0; s >>= 1) { - const rx = (x & s) ? 1 : 0; - const ry = (y & s) ? 1 : 0; + const rx = x & s ? 1 : 0; + const ry = y & s ? 1 : 0; index += s * s * ((3 * rx) ^ ry); if (ry === 0) { - if (rx === 1) { x = 32767 - x; y = 32767 - y; } - const t = x; x = y; y = t; + if (rx === 1) { + x = 32767 - x; + y = 32767 - y; + } + const t = x; + x = y; + y = t; } } return index >>> 0; } -function centroidFromPaletteHexes(hexByType: Record) { +function centroidFromPaletteHexes( + hexByType: Record, +) { const weights: Record = { Vibrant: 0.7, Muted: 0.15, @@ -48,14 +61,20 @@ function centroidFromPaletteHexes(hexByType: Record) hexByType["LightVibrant"] || hexByType["LightMuted"]; - let L = 0, A = 0, B = 0, W = 0; + let L = 0, + A = 0, + B = 0, + W = 0; for (const [type, w] of Object.entries(weights)) { const hex = hexByType[type] ?? fallbackHex; if (!hex || w <= 0) continue; const c = toOklab(parse(hex)); if (!c) continue; - L += c.l * w; A += c.a * w; B += c.b * w; W += w; + L += c.l * w; + A += c.a * w; + B += c.b * w; + W += w; } if (W === 0) return { l: 0.5, a: 0, b: 0 }; @@ -78,7 +97,11 @@ export async function generateArtworkColorsForArtwork(artworkId: string) { where: { id: artworkId }, select: { file: { select: { fileKey: true } }, - variants: { where: { type: "original" }, select: { s3Key: true }, take: 1 }, + variants: { + where: { type: "original" }, + select: { s3Key: true }, + take: 1, + }, }, }); if (!artwork) throw new Error("Artwork not found"); @@ -117,11 +140,14 @@ export async function generateArtworkColorsForArtwork(artworkId: string) { } const hexByType: Record = Object.fromEntries( - vibrantHexes.map(({ type, hex }) => [type, hex]) + vibrantHexes.map(({ type, hex }) => [type, hex]), ); const { l, a, b } = centroidFromPaletteHexes(hexByType); - const sortKey = hilbertIndex15(norm(a, A_MIN, A_MAX), norm(b, B_MIN, B_MAX)); + const sortKey = hilbertIndex15( + norm(a, A_MIN, A_MAX), + norm(b, B_MIN, B_MAX), + ); await prisma.artwork.update({ where: { id: artworkId }, @@ -144,6 +170,9 @@ export async function generateArtworkColorsForArtwork(artworkId: string) { colorError: e instanceof Error ? e.message : "Color generation failed", }, }); - return { ok: false as const, error: e instanceof Error ? e.message : "Color generation failed" }; + return { + ok: false as const, + error: e instanceof Error ? e.message : "Color generation failed", + }; } } diff --git a/src/actions/colors/processPendingArtworkColors.ts b/src/actions/colors/processPendingArtworkColors.ts index c6e1e27..73db36c 100644 --- a/src/actions/colors/processPendingArtworkColors.ts +++ b/src/actions/colors/processPendingArtworkColors.ts @@ -1,6 +1,6 @@ "use server"; -import { Prisma } from "@/generated/prisma/client"; +import type { Prisma } from "@/generated/prisma/client"; import { prisma } from "@/lib/prisma"; import { generateArtworkColorsForArtwork } from "../artworks/generateArtworkColors";