import { Modal, ModalBody, ModalContent, ModalHeader, useDisclosure, } from "@nextui-org/react"; import { CanvasLib } from "@sc07-canvas/lib/src/canvas"; import { useAppContext } from "../../contexts/AppContext"; import { Canvas } from "../../lib/canvas"; import { useEffect, useState } from "react"; import { ClientConfig } from "@sc07-canvas/lib/src/net"; import network from "../../lib/network"; const getTimeLeft = (pixels: { available: number }, config: ClientConfig) => { // this implementation matches the server's implementation const cooldown = CanvasLib.getPixelCooldown(pixels.available + 1, config); const pixelExpiresAt = Canvas.instance?.lastPlace && Canvas.instance.lastPlace + cooldown * 1000; const pixelCooldown = pixelExpiresAt && (Date.now() - pixelExpiresAt) / 1000; if (!pixelCooldown) return undefined; if (pixelCooldown > 0) return 0; return Math.abs(pixelCooldown).toFixed(1); }; const PlaceCountdown = () => { const { pixels, config } = useAppContext(); const [timeLeft, setTimeLeft] = useState(getTimeLeft(pixels, config)); useEffect(() => { const timer = setInterval(() => { setTimeLeft(getTimeLeft(pixels, config)); }, 100); return () => { clearInterval(timer); }; }, [pixels]); return ( <> {timeLeft ? pixels.available + 1 < config.canvas.pixel.maxStack && timeLeft + "s" : ""} ); }; const OnlineCount = () => { const [online, setOnline] = useState(); useEffect(() => { function handleOnline(count: number) { setOnline(count); } network.waitFor("online").then(([count]) => setOnline(count)); network.on("online", handleOnline); return () => { network.off("online", handleOnline); }; }, []); return <>{typeof online === "number" ? online : "???"}; }; export const CanvasMeta = () => { const { canvasPosition, cursorPosition, pixels, config } = useAppContext(); const { isOpen, onOpen, onOpenChange } = useDisclosure(); return ( <>
{canvasPosition && ( {cursorPosition && ( <> {" "} (Cursor: {cursorPosition.x}, {cursorPosition.y}) )} )} Pixels:{" "} {pixels.available}/{config.canvas.pixel.maxStack} {" "} Users Online:{" "}
); }; const ShareModal = ({ isOpen, onOpenChange, }: { isOpen: boolean; onOpenChange: () => void; }) => { return ( {() => ( <> share modal

share the current zoom level & position as a url

params would be not a hash so the server can generate an oembed

)}
); };