import { Button, Spinner } from "@nextui-org/react"; import { useAppContext } from "../contexts/AppContext"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { faXmark } from "@fortawesome/free-solid-svg-icons"; import { ComponentPropsWithoutRef, useEffect, useRef, useState } from "react"; import { api } from "../lib/utils"; import { UserCard } from "./Profile/UserCard"; interface IPixel { userId: string; x: number; y: number; color: string; createdAt: Date; } interface IUser { sub: string; display_name?: string; picture_url?: string; profile_url?: string; isAdmin: boolean; isModerator: boolean; } interface IInstance { hostname: string; name?: string; logo_url?: string; banner_url?: string; } export const PixelWhoisSidebar = () => { const { pixelWhois, setPixelWhois } = useAppContext(); const [loading, setLoading] = useState(true); const [whois, setWhois] = useState<{ pixel: IPixel; otherPixels: number; user: IUser | null; instance: IInstance | null; }>(); useEffect(() => { if (!pixelWhois) return; setLoading(true); setWhois(undefined); api< { pixel: IPixel; otherPixels: number; user: IUser | null; instance: IInstance | null; }, "no_pixel" >(`/api/canvas/pixel/${pixelWhois.x}/${pixelWhois.y}`) .then(({ status, data }) => { if (status === 200) { if (data.success) { setWhois({ pixel: data.pixel, otherPixels: data.otherPixels, user: data.user, instance: data.instance, }); } else { // error wahhhhhh } } else { // error wahhhh } }) .finally(() => { setLoading(false); }); }, [pixelWhois]); return (
{loading && (
Loading
)}

Pixel Whois

{whois?.user && }
Placed At {whois?.pixel.createdAt?.toString()}
Covered Pixels {whois?.otherPixels}
); }; const SmallCanvas = ({ surrounding, ...props }: { surrounding: string[][] | undefined; } & ComponentPropsWithoutRef<"canvas">) => { const canvasRef = useRef(null); useEffect(() => { if (!canvasRef.current) { console.warn("[SmallCanvas] canvasRef unavailable"); return; } const ctx = canvasRef.current.getContext("2d"); if (!ctx) { console.warn("[SmallCanvas] canvas context unavailable"); return; } ctx.fillStyle = "#fff"; ctx.fillRect(0, 0, canvasRef.current.width, canvasRef.current.height); ctx.fillStyle = "rgba(0,0,0,0.2)"; ctx.fillRect(0, 0, canvasRef.current.width, canvasRef.current.height); if (surrounding) { const PIXEL_WIDTH = canvasRef.current.width / surrounding[0].length; const middle: [x: number, y: number] = [ Math.floor(surrounding[0].length / 2), Math.floor(surrounding.length / 2), ]; for (let y = 0; y < surrounding.length; y++) { for (let x = 0; x < surrounding[y].length; x++) { let color = surrounding[y][x]; ctx.beginPath(); ctx.rect(x * PIXEL_WIDTH, y * PIXEL_WIDTH, PIXEL_WIDTH, PIXEL_WIDTH); ctx.fillStyle = color; ctx.fill(); } } ctx.beginPath(); ctx.rect( middle[0] * PIXEL_WIDTH, middle[1] * PIXEL_WIDTH, PIXEL_WIDTH, PIXEL_WIDTH ); ctx.strokeStyle = "#f00"; ctx.lineWidth = 4; ctx.stroke(); } }, [surrounding]); return ( (canvasRef.current = r)} {...props} /> ); };