import useSWR from "swr"; const dimension = 512; function blobToBase64(blob: Blob): Promise { return new Promise((resolve, _) => { const reader = new FileReader(); reader.onloadend = () => resolve(reader.result as string); reader.readAsDataURL(blob); }); } function convertEmojiToDataToDataURL(emoji: string): string { const element = document.createElement("canvas"); const ctx = element.getContext("2d")!; element.height = dimension; element.width = dimension; ctx.fillStyle = "rgb(24 24 27)"; ctx.fillRect(0, 0, element.width, element.height); ctx.textAlign = `center`; ctx.font = `${dimension - 32}px serf`; const textMetrics = ctx.measureText(emoji); const textHeight = textMetrics.actualBoundingBoxAscent + textMetrics.actualBoundingBoxDescent; const y = dimension / 2 + (textMetrics.actualBoundingBoxAscent - textHeight / 2); ctx.fillText(emoji, dimension / 2, y); return element.toDataURL("image/jpeg", 0.5); } export const useResponse = ( revalidateOnMount: boolean, emoji: string, name: string, style: string, strength: number, seed: number, ) => { const { data, isLoading } = useSWR( [emoji, name, style, strength, seed], async ([base64, name, style, strength, seed]) => { const response = await fetch("/api/run", { headers: { accept: "image/jpeg", "content-type": "application/json", }, body: JSON.stringify({ input_image: convertEmojiToDataToDataURL(emoji).replace( /^data:image\/(png|jpeg);base64,/, "", ), prompt: `${name}, emoji ${emoji}, ${style}`, guidance_scale: 8, lcm_steps: 50, seed, steps: 4, strength, width: dimension, height: dimension, }), method: "POST", }); if (response.status !== 200) return ""; const blob = await response.blob(); return await blobToBase64(blob); }, { revalidateOnFocus: false, revalidateOnReconnect: false, revalidateOnMount, refreshWhenOffline: false, refreshInterval: 0, }, ); return { image: data as string, loading: isLoading }; };