Files
admin.fellies.app/src/actions/images/generatePalette.ts

58 lines
2.1 KiB
TypeScript

"use server"
import prisma from "@/lib/prisma";
import { VibrantSwatch } from "@/types/VibrantSwatch";
import { getImageBufferFromS3 } from "@/utils/getImageBufferFromS3";
import { extractPaletteTones, rgbToHex, upsertPalettes } from "@/utils/uploadHelper";
import { argbFromHex, themeFromSourceColor } from "@material/material-color-utilities";
import { Vibrant } from "node-vibrant/node";
export async function generatePaletteAction(imageId: string, fileKey: string) {
const buffer = await getImageBufferFromS3(fileKey);
const palette = await Vibrant.from(buffer).getPalette();
const vibrantHexes = Object.fromEntries(
Object.entries(palette).map(([key, swatch]) => {
const castSwatch = swatch as VibrantSwatch | null;
const rgb = castSwatch?._rgb;
const hex = castSwatch?.hex || (rgb ? rgbToHex(rgb) : undefined);
return [key, hex];
})
);
const seedHex =
vibrantHexes.Vibrant ??
vibrantHexes.Muted ??
vibrantHexes.DarkVibrant ??
vibrantHexes.DarkMuted ??
vibrantHexes.LightVibrant ??
vibrantHexes.LightMuted ??
"#dfffff";
const theme = themeFromSourceColor(argbFromHex(seedHex));
const primaryTones = extractPaletteTones(theme.palettes.primary);
const secondaryTones = extractPaletteTones(theme.palettes.secondary);
const tertiaryTones = extractPaletteTones(theme.palettes.tertiary);
const neutralTones = extractPaletteTones(theme.palettes.neutral);
const neutralVariantTones = extractPaletteTones(theme.palettes.neutralVariant);
const errorTones = extractPaletteTones(theme.palettes.error);
await upsertPalettes(primaryTones, imageId, "primary");
await upsertPalettes(secondaryTones, imageId, "secondary");
await upsertPalettes(tertiaryTones, imageId, "tertiary");
await upsertPalettes(neutralTones, imageId, "neutral");
await upsertPalettes(neutralVariantTones, imageId, "neutralVariant");
await upsertPalettes(errorTones, imageId, "error");
await prisma.themeSeed.create({
data: {
seedHex,
imageId,
},
});
return await prisma.colorPalette.findMany({
where: { images: { some: { id: imageId } } },
include: { items: true },
});
}