From b29832a0b75e91f7d53e3820b12d517e6bf3ee94 Mon Sep 17 00:00:00 2001
From: Stanley Yip <stanley_yip@brown.edu>
Date: Tue, 8 Oct 2019 18:14:09 -0400
Subject: touchable added baseline

---
 src/client/views/Touchable.tsx | 82 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 82 insertions(+)
 create mode 100644 src/client/views/Touchable.tsx

(limited to 'src/client/views/Touchable.tsx')

diff --git a/src/client/views/Touchable.tsx b/src/client/views/Touchable.tsx
new file mode 100644
index 000000000..e9671ab8b
--- /dev/null
+++ b/src/client/views/Touchable.tsx
@@ -0,0 +1,82 @@
+import * as React from 'react';
+import { action } from 'mobx';
+import { InteractionUtils } from '../util/InteractionUtils';
+
+export abstract class Touchable<T> extends React.Component<T> {
+    protected _touchDrag: boolean = false;
+    protected prevPoints: Map<number, React.Touch> = new Map<number, React.Touch>();
+
+    public FirstX: number = 0;
+    public FirstY: number = 0;
+    public SecondX: number = 0;
+    public SecondY: number = 0;
+
+    /**
+     * When a touch even starts, we keep track of each touch that is associated with that event
+     */
+    @action
+    protected onTouchStart = (e: React.TouchEvent): void => {
+        for (let i = 0; i < e.targetTouches.length; i++) {
+            let pt = e.targetTouches.item(i);
+            this.prevPoints.set(pt.identifier, pt);
+        }
+        document.removeEventListener("touchmove", this.onTouch);
+        document.addEventListener("touchmove", this.onTouch);
+        document.removeEventListener("touchend", this.onTouchEnd);
+        document.addEventListener("touchend", this.onTouchEnd);
+    }
+
+    /**
+    * Handle touch move event
+    */
+    @action
+    protected onTouch = (e: TouchEvent): void => {
+        // if we're not actually moving a lot, don't consider it as dragging yet
+        if (!InteractionUtils.IsDragging(this.prevPoints, e.targetTouches, 5) && !this._touchDrag) return;
+        this._touchDrag = true;
+        switch (e.targetTouches.length) {
+            case 1:
+                this.handle1Pointer(e)
+                break;
+            case 2:
+                this.handle2Pointers(e);
+                break;
+        }
+    }
+
+    @action
+    protected onTouchEnd = (e: TouchEvent): void => {
+        this._touchDrag = false;
+        e.stopPropagation();
+
+        // remove all the touches associated with the event
+        for (let i = 0; i < e.targetTouches.length; i++) {
+            let pt = e.targetTouches.item(i);
+            if (pt) {
+                if (this.prevPoints.has(pt.identifier)) {
+                    this.prevPoints.delete(pt.identifier);
+                }
+            }
+        }
+
+        if (e.targetTouches.length === 0) {
+            this.prevPoints.clear();
+        }
+        this.cleanUpInteractions();
+    }
+
+    cleanUpInteractions = (): void => {
+        document.removeEventListener("touchmove", this.onTouch);
+        document.removeEventListener("touchend", this.onTouchEnd);
+    }
+
+    handle1Pointer = (e: TouchEvent): any => {
+        e.stopPropagation();
+        e.preventDefault();
+    }
+
+    handle2Pointers = (e: TouchEvent): any => {
+        e.stopPropagation();
+        e.preventDefault();
+    }
+}
\ No newline at end of file
-- 
cgit v1.2.3-70-g09d2

