Loading packages/client/src/components/App.tsx +2 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ import { KeybindModal } from "./KeybindModal"; import { ProfileModal } from "./Profile/ProfileModal"; import { WelcomeModal } from "./Welcome/WelcomeModal"; import { InfoSidebar } from "./Info/InfoSidebar"; import { ModModal } from "./Moderation/ModModal"; const Chat = lazy(() => import("./Chat/Chat")); Loading Loading @@ -148,6 +149,7 @@ const AppInner = () => { <ProfileModal /> <WelcomeModal /> <ModModal /> <ToastContainer position="top-left" /> </> Loading packages/client/src/components/Moderation/ModModal.tsx 0 → 100644 +64 −0 Original line number Diff line number Diff line import { Modal, ModalBody, ModalContent, ModalFooter, ModalHeader, Switch, } from "@nextui-org/react"; import { useAppContext } from "../../contexts/AppContext"; import { useCallback, useEffect, useState } from "react"; import { KeybindManager } from "../../lib/keybinds"; import { Canvas } from "../../lib/canvas"; export const ModModal = () => { const { showModModal, setShowModModal, hasAdmin } = useAppContext(); const [bypassCooldown, setBypassCooldown_] = useState(false); useEffect(() => { setBypassCooldown_(Canvas.instance?.getCooldownBypass() || false); const handleKeybind = () => { if (!hasAdmin) { console.warn("Unable to open mod menu; hasAdmin is not set"); return; } setShowModModal((m) => !m); }; KeybindManager.on("TOGGLE_MOD_MENU", handleKeybind); return () => { KeybindManager.off("TOGGLE_MOD_MENU", handleKeybind); }; }, []); const setBypassCooldown = useCallback( (value: boolean) => { setBypassCooldown_(value); Canvas.instance?.setCooldownBypass(value); }, [setBypassCooldown_] ); return ( <Modal isOpen={showModModal} onOpenChange={setShowModModal}> <ModalContent> {(onClose) => ( <> <ModalHeader>Mod Menu</ModalHeader> <ModalBody> <Switch isSelected={bypassCooldown} onValueChange={setBypassCooldown} > Bypass placement cooldown </Switch> </ModalBody> </> )} </ModalContent> </Modal> ); }; packages/client/src/contexts/AppContext.tsx +6 −1 Original line number Diff line number Diff line import { import React, { PropsWithChildren, createContext, useContext, Loading Loading @@ -43,6 +43,8 @@ interface IAppContext { setProfile: (v?: string) => void; hasAdmin: boolean; showModModal: boolean; setShowModModal: React.Dispatch<React.SetStateAction<boolean>>; } interface ICanvasPosition { Loading Loading @@ -119,6 +121,7 @@ export const AppContext = ({ children }: PropsWithChildren) => { const [profile, setProfile] = useState<string>(); const [hasAdmin, setHasAdmin] = useState(false); const [showModModal, setShowModModal] = useState(false); useEffect(() => { function loadSettings() { Loading Loading @@ -224,6 +227,8 @@ export const AppContext = ({ children }: PropsWithChildren) => { setProfile, infoSidebar, setInfoSidebar, showModModal, setShowModModal, }} > {!config && ( Loading packages/client/src/lib/canvas.ts +19 −5 Original line number Diff line number Diff line Loading @@ -39,6 +39,8 @@ export class Canvas extends EventEmitter<CanvasEvents> { } = {}; lastPlace: number | undefined; private bypassCooldown = false; constructor(canvas: HTMLCanvasElement, PanZoom: PanZoom) { super(); Canvas.instance = this; Loading Loading @@ -99,6 +101,14 @@ export class Canvas extends EventEmitter<CanvasEvents> { return this.PanZoom; } setCooldownBypass(value: boolean) { this.bypassCooldown = value; } getCooldownBypass() { return this.bypassCooldown; } getAllPixels() { let pixels: { x: number; Loading Loading @@ -252,11 +262,15 @@ export class Canvas extends EventEmitter<CanvasEvents> { // } Network.socket .emitWithAck("place", { .emitWithAck( "place", { x, y, color: this.Pallete.getSelectedColor()!.id, }) }, this.bypassCooldown ) .then((ack) => { if (ack.success) { this.lastPlace = Date.now(); Loading packages/client/src/lib/keybinds.ts +5 −0 Original line number Diff line number Diff line Loading @@ -49,6 +49,11 @@ const KEYBINDS = enforceObjectType({ key: "KeyH", }, ], TOGGLE_MOD_MENU: [ { key: "KeyM", }, ], }); class KeybindManager_ extends EventEmitter<{ Loading Loading
packages/client/src/components/App.tsx +2 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ import { KeybindModal } from "./KeybindModal"; import { ProfileModal } from "./Profile/ProfileModal"; import { WelcomeModal } from "./Welcome/WelcomeModal"; import { InfoSidebar } from "./Info/InfoSidebar"; import { ModModal } from "./Moderation/ModModal"; const Chat = lazy(() => import("./Chat/Chat")); Loading Loading @@ -148,6 +149,7 @@ const AppInner = () => { <ProfileModal /> <WelcomeModal /> <ModModal /> <ToastContainer position="top-left" /> </> Loading
packages/client/src/components/Moderation/ModModal.tsx 0 → 100644 +64 −0 Original line number Diff line number Diff line import { Modal, ModalBody, ModalContent, ModalFooter, ModalHeader, Switch, } from "@nextui-org/react"; import { useAppContext } from "../../contexts/AppContext"; import { useCallback, useEffect, useState } from "react"; import { KeybindManager } from "../../lib/keybinds"; import { Canvas } from "../../lib/canvas"; export const ModModal = () => { const { showModModal, setShowModModal, hasAdmin } = useAppContext(); const [bypassCooldown, setBypassCooldown_] = useState(false); useEffect(() => { setBypassCooldown_(Canvas.instance?.getCooldownBypass() || false); const handleKeybind = () => { if (!hasAdmin) { console.warn("Unable to open mod menu; hasAdmin is not set"); return; } setShowModModal((m) => !m); }; KeybindManager.on("TOGGLE_MOD_MENU", handleKeybind); return () => { KeybindManager.off("TOGGLE_MOD_MENU", handleKeybind); }; }, []); const setBypassCooldown = useCallback( (value: boolean) => { setBypassCooldown_(value); Canvas.instance?.setCooldownBypass(value); }, [setBypassCooldown_] ); return ( <Modal isOpen={showModModal} onOpenChange={setShowModModal}> <ModalContent> {(onClose) => ( <> <ModalHeader>Mod Menu</ModalHeader> <ModalBody> <Switch isSelected={bypassCooldown} onValueChange={setBypassCooldown} > Bypass placement cooldown </Switch> </ModalBody> </> )} </ModalContent> </Modal> ); };
packages/client/src/contexts/AppContext.tsx +6 −1 Original line number Diff line number Diff line import { import React, { PropsWithChildren, createContext, useContext, Loading Loading @@ -43,6 +43,8 @@ interface IAppContext { setProfile: (v?: string) => void; hasAdmin: boolean; showModModal: boolean; setShowModModal: React.Dispatch<React.SetStateAction<boolean>>; } interface ICanvasPosition { Loading Loading @@ -119,6 +121,7 @@ export const AppContext = ({ children }: PropsWithChildren) => { const [profile, setProfile] = useState<string>(); const [hasAdmin, setHasAdmin] = useState(false); const [showModModal, setShowModModal] = useState(false); useEffect(() => { function loadSettings() { Loading Loading @@ -224,6 +227,8 @@ export const AppContext = ({ children }: PropsWithChildren) => { setProfile, infoSidebar, setInfoSidebar, showModModal, setShowModModal, }} > {!config && ( Loading
packages/client/src/lib/canvas.ts +19 −5 Original line number Diff line number Diff line Loading @@ -39,6 +39,8 @@ export class Canvas extends EventEmitter<CanvasEvents> { } = {}; lastPlace: number | undefined; private bypassCooldown = false; constructor(canvas: HTMLCanvasElement, PanZoom: PanZoom) { super(); Canvas.instance = this; Loading Loading @@ -99,6 +101,14 @@ export class Canvas extends EventEmitter<CanvasEvents> { return this.PanZoom; } setCooldownBypass(value: boolean) { this.bypassCooldown = value; } getCooldownBypass() { return this.bypassCooldown; } getAllPixels() { let pixels: { x: number; Loading Loading @@ -252,11 +262,15 @@ export class Canvas extends EventEmitter<CanvasEvents> { // } Network.socket .emitWithAck("place", { .emitWithAck( "place", { x, y, color: this.Pallete.getSelectedColor()!.id, }) }, this.bypassCooldown ) .then((ack) => { if (ack.success) { this.lastPlace = Date.now(); Loading
packages/client/src/lib/keybinds.ts +5 −0 Original line number Diff line number Diff line Loading @@ -49,6 +49,11 @@ const KEYBINDS = enforceObjectType({ key: "KeyH", }, ], TOGGLE_MOD_MENU: [ { key: "KeyM", }, ], }); class KeybindManager_ extends EventEmitter<{ Loading