refactor(app.tsx): use constants instead of hard coded strings for better readablility (#1391)
don't use inline function as it will create a new refrence everytime
This commit is contained in:
parent
d902bbd618
commit
e98fba38be
@ -95,6 +95,7 @@ import {
|
||||
import { normalizeScroll } from "../scene";
|
||||
import { getCenter, getDistance } from "../gesture";
|
||||
import { createUndoAction, createRedoAction } from "../actions/actionHistory";
|
||||
|
||||
import {
|
||||
CURSOR_TYPE,
|
||||
ELEMENT_SHIFT_TRANSLATE_AMOUNT,
|
||||
@ -103,7 +104,16 @@ import {
|
||||
DRAGGING_THRESHOLD,
|
||||
TEXT_TO_CENTER_SNAP_THRESHOLD,
|
||||
LINE_CONFIRM_THRESHOLD,
|
||||
SCENE,
|
||||
EVENT,
|
||||
ENV,
|
||||
} from "../constants";
|
||||
import {
|
||||
FONT_LOAD_THRESHOLD,
|
||||
INITAL_SCENE_UPDATE_TIMEOUT,
|
||||
TAP_TWICE_TIMEOUT,
|
||||
} from "../time_constants";
|
||||
|
||||
import { LayerUI } from "./LayerUI";
|
||||
import { ScrollBars, SceneState } from "../scene/types";
|
||||
import { generateCollaborationLink, getCollaborationLinkData } from "../data";
|
||||
@ -363,7 +373,7 @@ export class App extends React.Component<any, AppState> {
|
||||
});
|
||||
}),
|
||||
// if fonts don't load in 1s for whatever reason, don't block the UI
|
||||
new Promise((resolve) => setTimeout(resolve, 1000)),
|
||||
new Promise((resolve) => setTimeout(resolve, FONT_LOAD_THRESHOLD)),
|
||||
]);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
@ -411,32 +421,39 @@ export class App extends React.Component<any, AppState> {
|
||||
this.onSceneUpdated,
|
||||
);
|
||||
|
||||
document.addEventListener("copy", this.onCopy);
|
||||
document.addEventListener("paste", this.pasteFromClipboard);
|
||||
document.addEventListener("cut", this.onCut);
|
||||
document.addEventListener(EVENT.COPY, this.onCopy);
|
||||
document.addEventListener(EVENT.PASTE, this.pasteFromClipboard);
|
||||
document.addEventListener(EVENT.CUT, this.onCut);
|
||||
|
||||
document.addEventListener("keydown", this.onKeyDown, false);
|
||||
document.addEventListener("keyup", this.onKeyUp, { passive: true });
|
||||
document.addEventListener("mousemove", this.updateCurrentCursorPosition);
|
||||
window.addEventListener("resize", this.onResize, false);
|
||||
window.addEventListener("unload", this.onUnload, false);
|
||||
window.addEventListener("blur", this.onBlur, false);
|
||||
window.addEventListener("dragover", this.disableEvent, false);
|
||||
window.addEventListener("drop", this.disableEvent, false);
|
||||
document.addEventListener(EVENT.KEYDOWN, this.onKeyDown, false);
|
||||
document.addEventListener(EVENT.KEYUP, this.onKeyUp, { passive: true });
|
||||
document.addEventListener(
|
||||
EVENT.MOUSE_MOVE,
|
||||
this.updateCurrentCursorPosition,
|
||||
);
|
||||
window.addEventListener(EVENT.RESIZE, this.onResize, false);
|
||||
window.addEventListener(EVENT.UNLOAD, this.onUnload, false);
|
||||
window.addEventListener(EVENT.BLUR, this.onBlur, false);
|
||||
window.addEventListener(EVENT.DRAG_OVER, this.disableEvent, false);
|
||||
window.addEventListener(EVENT.DROP, this.disableEvent, false);
|
||||
|
||||
// Safari-only desktop pinch zoom
|
||||
document.addEventListener(
|
||||
"gesturestart",
|
||||
EVENT.GESTURE_START,
|
||||
this.onGestureStart as any,
|
||||
false,
|
||||
);
|
||||
document.addEventListener(
|
||||
"gesturechange",
|
||||
EVENT.GESTURE_CHANGE,
|
||||
this.onGestureChange as any,
|
||||
false,
|
||||
);
|
||||
document.addEventListener("gestureend", this.onGestureEnd as any, false);
|
||||
window.addEventListener("beforeunload", this.beforeUnload);
|
||||
document.addEventListener(
|
||||
EVENT.GESTURE_END,
|
||||
this.onGestureEnd as any,
|
||||
false,
|
||||
);
|
||||
window.addEventListener(EVENT.BEFORE_UNLOAD, this.beforeUnload);
|
||||
|
||||
this.initializeScene();
|
||||
}
|
||||
@ -445,35 +462,39 @@ export class App extends React.Component<any, AppState> {
|
||||
this.unmounted = true;
|
||||
this.removeSceneCallback!();
|
||||
|
||||
document.removeEventListener("copy", this.onCopy);
|
||||
document.removeEventListener("paste", this.pasteFromClipboard);
|
||||
document.removeEventListener("cut", this.onCut);
|
||||
document.removeEventListener(EVENT.COPY, this.onCopy);
|
||||
document.removeEventListener(EVENT.PASTE, this.pasteFromClipboard);
|
||||
document.removeEventListener(EVENT.CUT, this.onCut);
|
||||
|
||||
document.removeEventListener("keydown", this.onKeyDown, false);
|
||||
document.removeEventListener(EVENT.KEYDOWN, this.onKeyDown, false);
|
||||
document.removeEventListener(
|
||||
"mousemove",
|
||||
EVENT.MOUSE_MOVE,
|
||||
this.updateCurrentCursorPosition,
|
||||
false,
|
||||
);
|
||||
document.removeEventListener("keyup", this.onKeyUp);
|
||||
window.removeEventListener("resize", this.onResize, false);
|
||||
window.removeEventListener("unload", this.onUnload, false);
|
||||
window.removeEventListener("blur", this.onBlur, false);
|
||||
window.removeEventListener("dragover", this.disableEvent, false);
|
||||
window.removeEventListener("drop", this.disableEvent, false);
|
||||
document.removeEventListener(EVENT.KEYUP, this.onKeyUp);
|
||||
window.removeEventListener(EVENT.RESIZE, this.onResize, false);
|
||||
window.removeEventListener(EVENT.UNLOAD, this.onUnload, false);
|
||||
window.removeEventListener(EVENT.BLUR, this.onBlur, false);
|
||||
window.removeEventListener(EVENT.DRAG_OVER, this.disableEvent, false);
|
||||
window.removeEventListener(EVENT.DROP, this.disableEvent, false);
|
||||
|
||||
document.removeEventListener(
|
||||
"gesturestart",
|
||||
EVENT.GESTURE_START,
|
||||
this.onGestureStart as any,
|
||||
false,
|
||||
);
|
||||
document.removeEventListener(
|
||||
"gesturechange",
|
||||
EVENT.GESTURE_CHANGE,
|
||||
this.onGestureChange as any,
|
||||
false,
|
||||
);
|
||||
document.removeEventListener("gestureend", this.onGestureEnd as any, false);
|
||||
window.removeEventListener("beforeunload", this.beforeUnload);
|
||||
document.removeEventListener(
|
||||
EVENT.GESTURE_END,
|
||||
this.onGestureEnd as any,
|
||||
false,
|
||||
);
|
||||
window.removeEventListener(EVENT.BEFORE_UNLOAD, this.beforeUnload);
|
||||
}
|
||||
private onResize = withBatchedUpdates(() => {
|
||||
globalSceneState
|
||||
@ -574,7 +595,7 @@ export class App extends React.Component<any, AppState> {
|
||||
getDrawingVersion(globalSceneState.getElementsIncludingDeleted()) >
|
||||
this.lastBroadcastedOrReceivedSceneVersion
|
||||
) {
|
||||
this.broadcastScene("SCENE_UPDATE");
|
||||
this.broadcastScene(SCENE.UPDATE);
|
||||
}
|
||||
|
||||
history.record(this.state, globalSceneState.getElementsIncludingDeleted());
|
||||
@ -638,11 +659,18 @@ export class App extends React.Component<any, AppState> {
|
||||
);
|
||||
};
|
||||
|
||||
private resetTapTwice() {
|
||||
didTapTwice = false;
|
||||
}
|
||||
|
||||
private onTapStart = (event: TouchEvent) => {
|
||||
if (!didTapTwice) {
|
||||
didTapTwice = true;
|
||||
clearTimeout(tappedTwiceTimer);
|
||||
tappedTwiceTimer = window.setTimeout(() => (didTapTwice = false), 300);
|
||||
tappedTwiceTimer = window.setTimeout(
|
||||
this.resetTapTwice,
|
||||
TAP_TWICE_TIMEOUT,
|
||||
);
|
||||
return;
|
||||
}
|
||||
// insert text only if we tapped twice with a single finger
|
||||
@ -809,10 +837,13 @@ export class App extends React.Component<any, AppState> {
|
||||
};
|
||||
// fallback in case you're not alone in the room but still don't receive
|
||||
// initial SCENE_UPDATE message
|
||||
const initializationTimer = setTimeout(initialize, 5000);
|
||||
const initializationTimer = setTimeout(
|
||||
initialize,
|
||||
INITAL_SCENE_UPDATE_TIMEOUT,
|
||||
);
|
||||
|
||||
const updateScene = (
|
||||
decryptedData: SocketUpdateDataSource["SCENE_INIT" | "SCENE_UPDATE"],
|
||||
decryptedData: SocketUpdateDataSource[SCENE.INIT | SCENE.UPDATE],
|
||||
{ scrollToContent = false }: { scrollToContent?: boolean } = {},
|
||||
) => {
|
||||
const { elements: remoteElements } = decryptedData.payload;
|
||||
@ -821,7 +852,7 @@ export class App extends React.Component<any, AppState> {
|
||||
this.setState({
|
||||
...this.state,
|
||||
...calculateScrollCenter(
|
||||
remoteElements.filter((element) => {
|
||||
remoteElements.filter((element: { isDeleted: boolean }) => {
|
||||
return !element.isDeleted;
|
||||
}),
|
||||
),
|
||||
@ -946,13 +977,13 @@ export class App extends React.Component<any, AppState> {
|
||||
switch (decryptedData.type) {
|
||||
case "INVALID_RESPONSE":
|
||||
return;
|
||||
case "SCENE_INIT": {
|
||||
case SCENE.INIT: {
|
||||
if (!this.portal.socketInitialized) {
|
||||
updateScene(decryptedData, { scrollToContent: true });
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "SCENE_UPDATE":
|
||||
case SCENE.UPDATE:
|
||||
updateScene(decryptedData);
|
||||
break;
|
||||
case "MOUSE_LOCATION": {
|
||||
@ -1003,7 +1034,7 @@ export class App extends React.Component<any, AppState> {
|
||||
});
|
||||
});
|
||||
this.portal.socket!.on("new-user", async (_socketID: string) => {
|
||||
this.broadcastScene("SCENE_INIT");
|
||||
this.broadcastScene(SCENE.INIT);
|
||||
});
|
||||
|
||||
this.setState({
|
||||
@ -1035,7 +1066,7 @@ export class App extends React.Component<any, AppState> {
|
||||
}
|
||||
};
|
||||
|
||||
private broadcastScene = (sceneType: "SCENE_INIT" | "SCENE_UPDATE") => {
|
||||
private broadcastScene = (sceneType: SCENE.INIT | SCENE.UPDATE) => {
|
||||
const data: SocketUpdateDataSource[typeof sceneType] = {
|
||||
type: sceneType,
|
||||
payload: {
|
||||
@ -1651,16 +1682,16 @@ export class App extends React.Component<any, AppState> {
|
||||
cursorButton: "up",
|
||||
});
|
||||
this.savePointer(event.clientX, event.clientY, "up");
|
||||
window.removeEventListener("pointermove", onPointerMove);
|
||||
window.removeEventListener("pointerup", teardown);
|
||||
window.removeEventListener("blur", teardown);
|
||||
window.removeEventListener(EVENT.POINTER_MOVE, onPointerMove);
|
||||
window.removeEventListener(EVENT.POINTER_UP, teardown);
|
||||
window.removeEventListener(EVENT.BLUR, teardown);
|
||||
}),
|
||||
);
|
||||
window.addEventListener("blur", teardown);
|
||||
window.addEventListener("pointermove", onPointerMove, {
|
||||
window.addEventListener(EVENT.BLUR, teardown);
|
||||
window.addEventListener(EVENT.POINTER_MOVE, onPointerMove, {
|
||||
passive: true,
|
||||
});
|
||||
window.addEventListener("pointerup", teardown);
|
||||
window.addEventListener(EVENT.POINTER_UP, teardown);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1755,14 +1786,14 @@ export class App extends React.Component<any, AppState> {
|
||||
cursorButton: "up",
|
||||
});
|
||||
this.savePointer(event.clientX, event.clientY, "up");
|
||||
window.removeEventListener("pointermove", onPointerMove);
|
||||
window.removeEventListener("pointerup", onPointerUp);
|
||||
window.removeEventListener(EVENT.POINTER_MOVE, onPointerMove);
|
||||
window.removeEventListener(EVENT.POINTER_UP, onPointerUp);
|
||||
});
|
||||
|
||||
lastPointerUp = onPointerUp;
|
||||
|
||||
window.addEventListener("pointermove", onPointerMove);
|
||||
window.addEventListener("pointerup", onPointerUp);
|
||||
window.addEventListener(EVENT.POINTER_MOVE, onPointerMove);
|
||||
window.addEventListener(EVENT.POINTER_UP, onPointerUp);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2230,8 +2261,8 @@ export class App extends React.Component<any, AppState> {
|
||||
resizeArrowFn = null;
|
||||
lastPointerUp = null;
|
||||
|
||||
window.removeEventListener("pointermove", onPointerMove);
|
||||
window.removeEventListener("pointerup", onPointerUp);
|
||||
window.removeEventListener(EVENT.POINTER_MOVE, onPointerMove);
|
||||
window.removeEventListener(EVENT.POINTER_UP, onPointerUp);
|
||||
|
||||
if (isLinearElement(draggingElement)) {
|
||||
if (draggingElement!.points.length > 1) {
|
||||
@ -2367,8 +2398,8 @@ export class App extends React.Component<any, AppState> {
|
||||
|
||||
lastPointerUp = onPointerUp;
|
||||
|
||||
window.addEventListener("pointermove", onPointerMove);
|
||||
window.addEventListener("pointerup", onPointerUp);
|
||||
window.addEventListener(EVENT.POINTER_MOVE, onPointerMove);
|
||||
window.addEventListener(EVENT.POINTER_UP, onPointerUp);
|
||||
};
|
||||
|
||||
private handleCanvasRef = (canvas: HTMLCanvasElement) => {
|
||||
@ -2377,13 +2408,13 @@ export class App extends React.Component<any, AppState> {
|
||||
this.canvas = canvas;
|
||||
this.rc = rough.canvas(this.canvas);
|
||||
|
||||
this.canvas.addEventListener("wheel", this.handleWheel, {
|
||||
this.canvas.addEventListener(EVENT.WHEEL, this.handleWheel, {
|
||||
passive: false,
|
||||
});
|
||||
this.canvas.addEventListener("touchstart", this.onTapStart);
|
||||
this.canvas.addEventListener(EVENT.TOUCH_START, this.onTapStart);
|
||||
} else {
|
||||
this.canvas?.removeEventListener("wheel", this.handleWheel);
|
||||
this.canvas?.removeEventListener("touchstart", this.onTapStart);
|
||||
this.canvas?.removeEventListener(EVENT.WHEEL, this.handleWheel);
|
||||
this.canvas?.removeEventListener(EVENT.TOUCH_START, this.onTapStart);
|
||||
}
|
||||
};
|
||||
|
||||
@ -2610,7 +2641,10 @@ declare global {
|
||||
}
|
||||
}
|
||||
|
||||
if (process.env.NODE_ENV === "test" || process.env.NODE_ENV === "development") {
|
||||
if (
|
||||
process.env.NODE_ENV === ENV.TEST ||
|
||||
process.env.NODE_ENV === ENV.DEVELOPMENT
|
||||
) {
|
||||
window.h = {} as Window["h"];
|
||||
|
||||
Object.defineProperties(window.h, {
|
||||
|
@ -16,3 +16,35 @@ export const POINTER_BUTTON = {
|
||||
SECONDARY: 2,
|
||||
TOUCH: -1,
|
||||
};
|
||||
|
||||
export enum SCENE {
|
||||
INIT = "SCENE_INIT",
|
||||
UPDATE = "SCENE_UPDATE",
|
||||
}
|
||||
|
||||
export enum EVENT {
|
||||
COPY = "copy",
|
||||
PASTE = "paste",
|
||||
CUT = "cut",
|
||||
KEYDOWN = "keydown",
|
||||
KEYUP = "keyup",
|
||||
MOUSE_MOVE = "mousemove",
|
||||
RESIZE = "resize",
|
||||
UNLOAD = "unload",
|
||||
BLUR = "blur",
|
||||
DRAG_OVER = "dragover",
|
||||
DROP = "drop",
|
||||
GESTURE_END = "gestureend",
|
||||
BEFORE_UNLOAD = "beforeunload",
|
||||
GESTURE_START = "gesturestart",
|
||||
GESTURE_CHANGE = "gesturechange",
|
||||
POINTER_MOVE = "pointermove",
|
||||
POINTER_UP = "pointerup",
|
||||
WHEEL = "wheel",
|
||||
TOUCH_START = "touchstart",
|
||||
}
|
||||
|
||||
export const ENV = {
|
||||
TEST: "test",
|
||||
DEVELOPMENT: "development",
|
||||
};
|
||||
|
4
src/time_constants.ts
Normal file
4
src/time_constants.ts
Normal file
@ -0,0 +1,4 @@
|
||||
// time in milliseconds
|
||||
export const FONT_LOAD_THRESHOLD = 1000;
|
||||
export const TAP_TWICE_TIMEOUT = 300;
|
||||
export const INITAL_SCENE_UPDATE_TIMEOUT = 5000;
|
Loading…
x
Reference in New Issue
Block a user