add debug menu & flags
This commit is contained in:
parent
d262be82dd
commit
0ed579c0d7
|
@ -4,6 +4,7 @@ import { CanvasWrapper } from "./CanvasWrapper";
|
|||
import { Pallete } from "./Pallete";
|
||||
import { TemplateContext } from "../contexts/TemplateContext";
|
||||
import { SettingsSidebar } from "./Settings/SettingsSidebar";
|
||||
import { DebugModal } from "./Debug/DebugModal";
|
||||
|
||||
const App = () => {
|
||||
return (
|
||||
|
@ -13,6 +14,7 @@ const App = () => {
|
|||
<CanvasWrapper />
|
||||
<Pallete />
|
||||
|
||||
<DebugModal />
|
||||
<SettingsSidebar />
|
||||
</TemplateContext>
|
||||
</AppContext>
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
import { useEffect, useState } from "react";
|
||||
import { Debug, FlagCategory } from "@sc07-canvas/lib/src/debug";
|
||||
import {
|
||||
Button,
|
||||
Modal,
|
||||
ModalBody,
|
||||
ModalContent,
|
||||
ModalFooter,
|
||||
ModalHeader,
|
||||
Switch,
|
||||
useDisclosure,
|
||||
} from "@nextui-org/react";
|
||||
|
||||
export const DebugModal = () => {
|
||||
const { isOpen, onOpen, onOpenChange } = useDisclosure();
|
||||
|
||||
useEffect(() => {
|
||||
const handleOpen = () => {
|
||||
onOpen();
|
||||
};
|
||||
|
||||
Debug.on("openTools", handleOpen);
|
||||
|
||||
return () => {
|
||||
Debug.off("openTools", handleOpen);
|
||||
};
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Modal isOpen={isOpen} onOpenChange={onOpenChange} placement="center">
|
||||
<ModalContent>
|
||||
{(onClose) => (
|
||||
<>
|
||||
<ModalHeader className="flex flex-col gap-1">
|
||||
Debug Tools
|
||||
</ModalHeader>
|
||||
<ModalBody>
|
||||
<Button onPress={() => Debug.openDebug()}>
|
||||
Open Debug Information
|
||||
</Button>
|
||||
{Debug.flags.getAll().map((flag, i, arr) => (
|
||||
<>
|
||||
{arr[i - 1]?.category !== flag.category && (
|
||||
<p>{FlagCategory[flag.category]}</p>
|
||||
)}
|
||||
<div key={flag.id}>
|
||||
<Switch
|
||||
size="sm"
|
||||
defaultSelected={flag.enabled}
|
||||
onValueChange={(v) => Debug.flags.setEnabled(flag.id, v)}
|
||||
>
|
||||
{flag.id}
|
||||
</Switch>
|
||||
</div>
|
||||
</>
|
||||
))}
|
||||
</ModalBody>
|
||||
<ModalFooter>
|
||||
<Button onPress={onClose}>Close</Button>
|
||||
</ModalFooter>
|
||||
</>
|
||||
)}
|
||||
</ModalContent>
|
||||
</Modal>
|
||||
);
|
||||
};
|
|
@ -1,6 +1,7 @@
|
|||
import { Button } from "@nextui-org/react";
|
||||
import { useAppContext } from "../contexts/AppContext";
|
||||
import { User } from "./Header/User";
|
||||
import { Debug } from "@sc07-canvas/lib/src/debug";
|
||||
|
||||
export const Header = () => {
|
||||
const { setSettingsSidebar } = useAppContext();
|
||||
|
@ -12,6 +13,7 @@ export const Header = () => {
|
|||
<div className="box">
|
||||
<User />
|
||||
<Button onClick={() => setSettingsSidebar(true)}>Settings</Button>
|
||||
<Button onClick={() => Debug.openDebugTools()}>debug</Button>
|
||||
</div>
|
||||
</header>
|
||||
);
|
||||
|
|
|
@ -0,0 +1,185 @@
|
|||
import EventEmitter from "eventemitter3";
|
||||
|
||||
interface DebugEvents {
|
||||
openTools(): void;
|
||||
}
|
||||
|
||||
interface DebugArgs {
|
||||
point: [x: number, y: number, id?: string];
|
||||
text: [str: any];
|
||||
}
|
||||
|
||||
export enum FlagCategory {
|
||||
"Renderer",
|
||||
"DebugMessages",
|
||||
"Uncategorized",
|
||||
}
|
||||
|
||||
class ExperimentFlag {
|
||||
id: string;
|
||||
enabled: boolean;
|
||||
category: FlagCategory = FlagCategory.Uncategorized;
|
||||
|
||||
constructor(id: string, defaultEnabled = false, category?: FlagCategory) {
|
||||
this.id = id;
|
||||
this.enabled = defaultEnabled;
|
||||
if (category) this.category = category;
|
||||
}
|
||||
}
|
||||
|
||||
interface FlagEvents {
|
||||
enable(flag_id: string): void;
|
||||
disable(flag_id: string): void;
|
||||
}
|
||||
|
||||
class FlagManager extends EventEmitter<FlagEvents> {
|
||||
flags: ExperimentFlag[];
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.flags = [];
|
||||
|
||||
this.register(
|
||||
// RENDERER
|
||||
new ExperimentFlag(
|
||||
"PANZOOM_PINCH_TRANSFORM_1",
|
||||
false,
|
||||
FlagCategory.Renderer
|
||||
),
|
||||
new ExperimentFlag(
|
||||
"PANZOOM_PINCH_TRANSFORM_2",
|
||||
false,
|
||||
FlagCategory.Renderer
|
||||
),
|
||||
|
||||
// DEBUG MESSAGES
|
||||
new ExperimentFlag(
|
||||
"PANZOOM_PINCH_DEBUG_MESSAGES",
|
||||
false,
|
||||
FlagCategory.DebugMessages
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
register(...flags: ExperimentFlag[]) {
|
||||
this.flags.push(...flags);
|
||||
}
|
||||
|
||||
getFlag(flag: string) {
|
||||
return this.flags.find((f) => f.id === flag);
|
||||
}
|
||||
|
||||
enabled(flag: string) {
|
||||
return this.getFlag(flag)?.enabled;
|
||||
}
|
||||
|
||||
setEnabled(flagID: string, enabled: boolean) {
|
||||
const flag = this.flags.find((f) => f.id === flagID);
|
||||
if (!flag) throw new Error("Unknown flag " + flagID);
|
||||
|
||||
flag.enabled = enabled;
|
||||
|
||||
if (enabled) {
|
||||
this.emit("enable", flagID);
|
||||
} else {
|
||||
this.emit("disable", flagID);
|
||||
}
|
||||
}
|
||||
|
||||
getAll() {
|
||||
return [...this.flags].sort((a, b) => a.category - b.category);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Debug wrapper
|
||||
*
|
||||
* Goals:
|
||||
* - toggle debug flags (similar to Discord experiments)
|
||||
* - open blank debug tab with useragent and any flags
|
||||
*/
|
||||
class Debugcl extends EventEmitter<DebugEvents> {
|
||||
readonly flags = new FlagManager();
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
openDebug() {
|
||||
const wind = window.open("about:blank", "_blank");
|
||||
if (!wind) {
|
||||
alert(
|
||||
"Failed to open debug tab. Is your anti-popup too powerful? Or did this get triggered from not a trusted event"
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
wind.document.write(`
|
||||
<h1>debug menu</h1>
|
||||
<pre>${JSON.stringify(
|
||||
{
|
||||
userAgent: navigator.userAgent,
|
||||
flags: this.flags
|
||||
.getAll()
|
||||
.filter((f) => f.enabled)
|
||||
.map((f) => f.id),
|
||||
},
|
||||
null,
|
||||
2
|
||||
)}</pre>
|
||||
`);
|
||||
wind.document.close();
|
||||
}
|
||||
|
||||
openDebugTools() {
|
||||
this.emit("openTools");
|
||||
}
|
||||
|
||||
/**
|
||||
* Create debug marker
|
||||
*
|
||||
* Useful on touchscreen devices
|
||||
*
|
||||
* @param type
|
||||
* @param args
|
||||
* @returns
|
||||
*/
|
||||
debug<T extends keyof DebugArgs>(type: T, ...args: DebugArgs[T]) {
|
||||
switch (type) {
|
||||
case "point": {
|
||||
const [x, y, id] = args;
|
||||
|
||||
if (document.getElementById("debug-" + id)) {
|
||||
document.getElementById("debug-" + id)!.style.top = y + "px";
|
||||
document.getElementById("debug-" + id)!.style.left = x + "px";
|
||||
return;
|
||||
}
|
||||
let el = document.createElement("div");
|
||||
if (id) el.id = "debug-" + id;
|
||||
el.classList.add("debug-point");
|
||||
el.style.setProperty("top", y + "px");
|
||||
el.style.setProperty("left", x + "px");
|
||||
document.body.appendChild(el);
|
||||
break;
|
||||
}
|
||||
case "text": {
|
||||
const [str] = args;
|
||||
|
||||
// create debug box in canvas-meta if it doesn't exist
|
||||
if (!document.getElementById("canvas-meta-debug")) {
|
||||
let debugBox = document.createElement("div");
|
||||
debugBox.id = "canvas-meta-debug";
|
||||
debugBox.style.whiteSpace = "pre";
|
||||
debugBox.style.unicodeBidi = "embed";
|
||||
document.getElementById("canvas-meta")!.prepend(debugBox);
|
||||
}
|
||||
|
||||
document.getElementById("canvas-meta-debug")!.innerText =
|
||||
typeof str === "string" ? str : JSON.stringify(str, null, 2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const Debug = new Debugcl();
|
|
@ -1,3 +1,4 @@
|
|||
import { Debug } from "../../debug";
|
||||
import { PanZoom } from "../PanZoom";
|
||||
|
||||
export function handleCalculateZoomPositions(
|
||||
|
@ -17,7 +18,7 @@ export function handleCalculateZoomPositions(
|
|||
|
||||
const calculatedPositionX = x - mouseX * scaleDifference;
|
||||
const calculatedPositionY = y - mouseY * scaleDifference;
|
||||
contextInstance.debug(calculatedPositionX, calculatedPositionY, "zoom");
|
||||
// Debug.debug("point", calculatedPositionX, calculatedPositionY, "zoom");
|
||||
|
||||
// do not limit to bounds when there is padding animation,
|
||||
// it causes animation strange behaviour
|
||||
|
|
Loading…
Reference in New Issue