Newer
Older
PropsWithChildren,
createContext,
useContext,
useEffect,
useState,
} from "react";

Grant
committed
import { AuthSession, ClientConfig, IPosition } from "@sc07-canvas/lib/src/net";
import { Spinner } from "@nextui-org/react";

Grant
committed
interface IAppContext {
config?: ClientConfig;
user?: AuthSession;

Grant
committed
canvasPosition?: ICanvasPosition;
setCanvasPosition: (v: ICanvasPosition) => void;
cursorPosition?: IPosition;
setCursorPosition: (v?: IPosition) => void;
pixels: { available: number };
undo?: { available: true; expireAt: number };

Grant
committed
loadChat: boolean;
setLoadChat: (v: boolean) => void;
infoSidebar: boolean;
setInfoSidebar: (v: boolean) => void;

Grant
committed
settingsSidebar: boolean;
setSettingsSidebar: (v: boolean) => void;
pixelWhois?: { x: number; y: number; surrounding: string[][] };
setPixelWhois: (v: this["pixelWhois"]) => void;
showKeybinds: boolean;
setShowKeybinds: (v: boolean) => void;
blankOverlay: IMapOverlay;
setBlankOverlay: React.Dispatch<React.SetStateAction<IMapOverlay>>;

Grant
committed
heatmapOverlay: IMapOverlay;
setHeatmapOverlay: React.Dispatch<React.SetStateAction<IMapOverlay>>;
profile?: string; // sub
setProfile: (v?: string) => void;

Grant
committed
hasAdmin: boolean;
}
interface ICanvasPosition {
x: number;
y: number;
zoom: number;
}
interface IMapOverlay {
enabled: boolean;
/**
* opacity of the overlay
* 0.0 - 1.0
*/
opacity: number;
loading: boolean;
}
const appContext = createContext<IAppContext>({} as any);
export const useAppContext = () => useContext(appContext);
export const AppContext = ({ children }: PropsWithChildren) => {
const [config, setConfig] = useState<ClientConfig>(undefined as any);
const [auth, setAuth] = useState<AuthSession>();
const [canvasPosition, setCanvasPosition] = useState<ICanvasPosition>();
const [cursorPosition, setCursorPosition] = useState<IPosition>();
const [connected, setConnected] = useState(false);
// --- settings ---
const [loadChat, _setLoadChat] = useState(false);
const [undo, setUndo] = useState<{ available: true; expireAt: number }>();
const [infoSidebar, setInfoSidebar] = useState(false);
const [settingsSidebar, setSettingsSidebar] = useState(false);
const [pixelWhois, setPixelWhois] = useState<{
x: number;
y: number;
surrounding: string[][];
}>();
const [showKeybinds, setShowKeybinds] = useState(false);
const [blankOverlay, setBlankOverlay] = useState<IMapOverlay>({

Grant
committed
enabled: false,
opacity: 1,
loading: false,
});
const [heatmapOverlay, setHeatmapOverlay] = useState<IMapOverlay>({
enabled: false,
opacity: 1,
loading: false,
});
const [hasAdmin, setHasAdmin] = useState(false);
setLoadChat(
localStorage.getItem("matrix.enable") === null
? true
: localStorage.getItem("matrix.enable") === "true"
);
function handleConfig(config: ClientConfig) {
setConfig(config);
}
function handleUser(user: AuthSession) {
setAuth(user);
}
function handlePixels(pixels: { available: number }) {
setPixels(pixels);
}
function handleUndo(
data: { available: false } | { available: true; expireAt: number }
) {
if (data.available) {
setUndo({ available: true, expireAt: data.expireAt });
} else {
setUndo(undefined);
}
}
function handleConnect() {
setConnected(true);
}
function handleDisconnect() {
setConnected(false);
}
api<{}>("/api/admin/check").then(({ status, data }) => {
if (status === 200) {
if (data.success) {
setHasAdmin(true);
}
}
});
Network.on("user", handleUser);
Network.on("config", handleConfig);
Network.waitFor("pixels").then(([data]) => handlePixels(data));
Network.on("pixels", handlePixels);
Network.on("connected", handleConnect);
Network.on("disconnected", handleDisconnect);
return () => {
Network.off("user", handleUser);
Network.off("config", handleConfig);
Network.off("undo", handleUndo);
Network.off("connected", handleConnect);
Network.off("disconnected", handleDisconnect);
const setLoadChat = (v: boolean) => {
_setLoadChat(v);
localStorage.setItem("matrix.enable", v ? "true" : "false");
};
value={{
config,
user: auth,
canvasPosition,
setCanvasPosition,
cursorPosition,
setCursorPosition,
settingsSidebar,
setSettingsSidebar,
connected,
pixelWhois,
setPixelWhois,

Grant
committed
heatmapOverlay,
setHeatmapOverlay,
{!config && (
<div className="fixed top-0 left-0 w-full h-full z-[49] backdrop-blur-sm bg-black/30 text-white flex items-center justify-center">
<Spinner label="Loading..." />
</div>
)}
{children}