Commit c328a830 authored by Grant's avatar Grant
Browse files

add long press event, multi keybind, mobile whois (fixes #42)

parent 6f7aad5d
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -12,6 +12,7 @@ import {
  PanZoom,
} from "@sc07-canvas/lib/src/renderer/PanZoom";
import { toast } from "react-toastify";
import { KeybindManager } from "./keybinds";

interface CanvasEvents {
  /**
@@ -48,6 +49,7 @@ export class Canvas extends EventEmitter<CanvasEvents> {

    this.PanZoom.addListener("hover", this.handleMouseMove.bind(this));
    this.PanZoom.addListener("click", this.handleMouseDown.bind(this));
    this.PanZoom.addListener("longPress", this.handleLongPress);

    Network.waitFor("pixelLastPlaced").then(
      ([time]) => (this.lastPlace = time)
@@ -60,6 +62,7 @@ export class Canvas extends EventEmitter<CanvasEvents> {

    this.PanZoom.removeListener("hover", this.handleMouseMove.bind(this));
    this.PanZoom.removeListener("click", this.handleMouseDown.bind(this));
    this.PanZoom.removeListener("longPress", this.handleLongPress);

    Network.off("pixel", this.handlePixel);
  }
@@ -120,6 +123,18 @@ export class Canvas extends EventEmitter<CanvasEvents> {
    return pixels;
  }

  handleLongPress = (clientX: number, clientY: number) => {
    KeybindManager.handleInteraction(
      {
        key: "LONG_PRESS",
      },
      {
        clientX,
        clientY,
      }
    );
  };

  handleMouseDown(e: ClickEvent) {
    if (!e.alt && !e.ctrl && !e.meta && !e.shift && e.button === "LCLICK") {
      const [x, y] = this.screenToPos(e.clientX, e.clientY);
+24 −16
Original line number Diff line number Diff line
@@ -2,7 +2,7 @@ import EventEmitter from "eventemitter3";
import { EnforceObjectType } from "./utils";

interface IKeybind {
  key: KeyboardEvent["code"] | "LCLICK" | "RCLICK" | "MCLICK";
  key: KeyboardEvent["code"] | "LCLICK" | "RCLICK" | "MCLICK" | "LONG_PRESS";

  alt?: boolean;
  ctrl?: boolean;
@@ -15,13 +15,16 @@ interface EmittedKeybind {
  clientY: number;
}

export const enforceObjectType: EnforceObjectType<IKeybind> = (v) => v;
export const enforceObjectType: EnforceObjectType<IKeybind[]> = (v) => v;

const KEYBINDS = enforceObjectType({
  PIXEL_WHOIS: {
  PIXEL_WHOIS: [
    {
      key: "LCLICK",
      shift: true,
    },
    { key: "LONG_PRESS" },
  ],
});

class KeybindManager_ extends EventEmitter<{
@@ -98,18 +101,23 @@ class KeybindManager_ extends EventEmitter<{
  handleInteraction(key: IKeybind, emit: EmittedKeybind): boolean {
    let isHandled = false;

    for (const [name_, keybind] of Object.entries(KEYBINDS)) {
    for (const [name_, keybinds] of Object.entries(KEYBINDS)) {
      const name: keyof typeof KEYBINDS = name_ as any;

      if (keybind.key !== key.key) continue;
      if (typeof keybind.alt !== "undefined" && keybind.alt !== key.alt)
        continue;
      if (typeof keybind.ctrl !== "undefined" && keybind.ctrl !== key.ctrl)
        continue;
      if (typeof keybind.meta !== "undefined" && keybind.meta !== key.meta)
        continue;
      if (typeof keybind.shift !== "undefined" && keybind.shift !== key.shift)
        continue;
      const valid = keybinds.find((kb) => {
        if (kb.key !== key.key) return false;
        if (typeof kb.alt !== "undefined" && kb.alt !== key.alt) return false;
        if (typeof kb.ctrl !== "undefined" && kb.ctrl !== key.ctrl)
          return false;
        if (typeof kb.meta !== "undefined" && kb.meta !== key.meta)
          return false;
        if (typeof kb.shift !== "undefined" && kb.shift !== key.shift)
          return false;

        return true;
      });

      if (!valid) continue;

      this.emit(name, emit);
      isHandled = true;
+13 −0
Original line number Diff line number Diff line
@@ -112,6 +112,7 @@ export interface ViewportMoveEvent {
}

interface PanZoomEvents {
  longPress: (x: number, y: number) => void;
  doubleTap: (e: TouchEvent) => void;
  click: (e: ClickEvent) => void;
  hover: (e: HoverEvent) => void;
@@ -311,6 +312,8 @@ export class PanZoom extends EventEmitter<PanZoomEvents> {
   * @param e
   */
  private _touch_touchstart = (event: TouchEvent) => {
    event.preventDefault();

    const isDoubleTap =
      this.touch.lastTouch && +new Date() - this.touch.lastTouch < 200;

@@ -359,6 +362,16 @@ export class PanZoom extends EventEmitter<PanZoomEvents> {
   * @param e
   */
  private _touch_touchend = (event: TouchEvent) => {
    if (this.touch.lastTouch && this.panning.enabled) {
      const touch = event.changedTouches[0];
      const dx = Math.abs(this.panning.x - touch.clientX);
      const dy = Math.abs(this.panning.y - touch.clientY);

      if (Date.now() - this.touch.lastTouch > 500 && dx < 25 && dy < 25) {
        this.emit("longPress", this.panning.x, this.panning.y);
      }
    }

    if (this.panning.enabled) {
      this.panning.enabled = false;