From a5531c6c5cdb10c19a941f1ded1482850fdd2a9a Mon Sep 17 00:00:00 2001 From: ShiKhu Date: Fri, 25 Mar 2022 20:30:05 +0100 Subject: [PATCH] feat(tracker-assist):3.5.7: Smooth DnD & fixes * Smooth DnD of the Call Window * Ignore call window on tracking * fix: prevent annotation stop when not drawing * fix: end the call on agent disconnect when RC is enabled --- tracker/tracker-assist/package-lock.json | 19 ++---- tracker/tracker-assist/package.json | 5 +- .../tracker-assist/src/AnnotationCanvas.ts | 1 + tracker/tracker-assist/src/Assist.ts | 9 +-- tracker/tracker-assist/src/CallWindow.ts | 34 ++++------ tracker/tracker-assist/src/dnd.ts | 66 +++++++++++++++++++ 6 files changed, 90 insertions(+), 44 deletions(-) create mode 100644 tracker/tracker-assist/src/dnd.ts diff --git a/tracker/tracker-assist/package-lock.json b/tracker/tracker-assist/package-lock.json index b0c032a8b..f0fd5eb9f 100644 --- a/tracker/tracker-assist/package-lock.json +++ b/tracker/tracker-assist/package-lock.json @@ -1,16 +1,15 @@ { "name": "@openreplay/tracker-assist", - "version": "3.5.3", + "version": "3.5.7", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@openreplay/tracker-assist", - "version": "3.5.3", + "version": "3.5.7", "license": "MIT", "dependencies": { "csstype": "^3.0.10", - "npm-dragndrop": "^1.2.0", "peerjs": "^1.3.2", "socket.io-client": "^4.4.1" }, @@ -21,12 +20,12 @@ "typescript": "^4.6.0-dev.20211126" }, "peerDependencies": { - "@openreplay/tracker": "^3.5.0" + "@openreplay/tracker": "^3.5.3" } }, "../tracker": { "name": "@openreplay/tracker", - "version": "3.5.2", + "version": "3.5.4", "dev": true, "license": "MIT", "dependencies": { @@ -3338,11 +3337,6 @@ "node": ">=0.10.0" } }, - "node_modules/npm-dragndrop": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/npm-dragndrop/-/npm-dragndrop-1.2.0.tgz", - "integrity": "sha1-bgUkAP7Yay8eP0csU4EPkjcRu7U=" - }, "node_modules/p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", @@ -6487,11 +6481,6 @@ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true }, - "npm-dragndrop": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/npm-dragndrop/-/npm-dragndrop-1.2.0.tgz", - "integrity": "sha1-bgUkAP7Yay8eP0csU4EPkjcRu7U=" - }, "p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", diff --git a/tracker/tracker-assist/package.json b/tracker/tracker-assist/package.json index 0a9fda457..b0152f0db 100644 --- a/tracker/tracker-assist/package.json +++ b/tracker/tracker-assist/package.json @@ -1,7 +1,7 @@ { "name": "@openreplay/tracker-assist", "description": "Tracker plugin for screen assistance through the WebRTC", - "version": "3.5.6", + "version": "3.5.7", "keywords": [ "WebRTC", "assistance", @@ -25,12 +25,11 @@ }, "dependencies": { "csstype": "^3.0.10", - "npm-dragndrop": "^1.2.0", "peerjs": "^1.3.2", "socket.io-client": "^4.4.1" }, "peerDependencies": { - "@openreplay/tracker": "^3.5.0" + "@openreplay/tracker": "^3.5.3" }, "devDependencies": { "@openreplay/tracker": "file:../tracker", diff --git a/tracker/tracker-assist/src/AnnotationCanvas.ts b/tracker/tracker-assist/src/AnnotationCanvas.ts index afda8e2a5..11a06a781 100644 --- a/tracker/tracker-assist/src/AnnotationCanvas.ts +++ b/tracker/tracker-assist/src/AnnotationCanvas.ts @@ -26,6 +26,7 @@ export default class AnnotationCanvas { } stop = () => { + if (!this.painting) { return } this.painting = false this.fadeOut() } diff --git a/tracker/tracker-assist/src/Assist.ts b/tracker/tracker-assist/src/Assist.ts index f7569bf26..24f04e7e0 100644 --- a/tracker/tracker-assist/src/Assist.ts +++ b/tracker/tracker-assist/src/Assist.ts @@ -196,10 +196,6 @@ export default class Assist { let confirmCall:ConfirmWindow | null = null socket.on("AGENT_DISCONNECTED", (id) => { - // @ts-ignore (wtf, typescript?!) - this.agents[id] && this.agents[id].onDisconnect != null && this.agents[id].onDisconnect() - delete this.agents[id] - remoteControl.releaseControl(id) // close the call also @@ -207,6 +203,10 @@ export default class Assist { confirmCall?.remove() this.onRemoteCallEnd() } + + // @ts-ignore (wtf, typescript?!) + this.agents[id] && this.agents[id].onDisconnect != null && this.agents[id].onDisconnect() + delete this.agents[id] }) socket.on("NO_AGENT", () => { this.agents = {} @@ -293,6 +293,7 @@ export default class Assist { const onCallEnd = this.options.onCallStart() const handleCallEnd = () => { + app.debug.log("Handle Call End") call.close() callUI.remove() annot && annot.remove() diff --git a/tracker/tracker-assist/src/CallWindow.ts b/tracker/tracker-assist/src/CallWindow.ts index 1299008a8..f8c852814 100644 --- a/tracker/tracker-assist/src/CallWindow.ts +++ b/tracker/tracker-assist/src/CallWindow.ts @@ -1,4 +1,5 @@ import type { LocalStream } from './LocalStream.js'; +import attachDND from './dnd'; const SS_START_TS_KEY = "__openreplay_assist_call_start_ts" @@ -18,20 +19,21 @@ export default class CallWindow { private load: Promise constructor() { - const iframe = this.iframe = document.createElement('iframe'); + const iframe = this.iframe = document.createElement('iframe') Object.assign(iframe.style, { position: "fixed", zIndex: 2147483647 - 1, - //borderRadius: ".25em .25em .4em .4em", - //border: "4px rgba(0, 0, 0, .7)", border: "none", bottom: "10px", right: "10px", - background: "white", height: "200px", width: "200px", - }); - document.body.appendChild(iframe); + }) + // TODO: find the best attribute name for the ignoring iframes + iframe.setAttribute("data-openreplay-obscured", "") + iframe.setAttribute("data-openreplay-hidden", "") + iframe.setAttribute("data-openreplay-ignore", "") + document.body.appendChild(iframe) const doc = iframe.contentDocument; if (!doc) { @@ -91,22 +93,10 @@ export default class CallWindow { }, 500); } - // TODO: better D'n'D - // mb set cursor:move here? - doc.body.setAttribute("draggable", "true"); - doc.body.ondragstart = (e) => { - if (!e.dataTransfer || !e.target) { return; } - //@ts-ignore - if (!e.target.classList || !e.target.classList.contains("drag-area")) { return; } - e.dataTransfer.setDragImage(doc.body, e.clientX, e.clientY); - }; - doc.body.ondragend = e => { - Object.assign(iframe.style, { - left: `${e.clientX}px`, // TODO: fix the case when ecoordinates are inside the iframe - top: `${e.clientY}px`, - bottom: 'auto', - right: 'auto', - }) + const dragArea = doc.querySelector(".drag-area") + if (dragArea) { + // TODO: save coordinates on the new page + attachDND(iframe, dragArea, doc.documentElement) } }); diff --git a/tracker/tracker-assist/src/dnd.ts b/tracker/tracker-assist/src/dnd.ts new file mode 100644 index 000000000..818bb0b89 --- /dev/null +++ b/tracker/tracker-assist/src/dnd.ts @@ -0,0 +1,66 @@ +/* + Here implemented the case when both dragArea and dropArea + are located inside the document of the dragging iframe. + Thus, all the events belong and relate to that inside document. +*/ +export default function attachDND( + movingEl: HTMLIFrameElement, + dragArea: Element, + dropArea: Element, +) { + + dragArea.addEventListener('pointerdown', userPressed, { passive: true }) + + let bbox, + startX, startY, + raf, + deltaX = 0, deltaY = 0 + + function userPressed(event) { + startX = event.clientX + startY = event.clientY + bbox = movingEl.getBoundingClientRect() + dropArea.addEventListener('pointermove', userMoved, { passive: true }) + dropArea.addEventListener('pointerup', userReleased, { passive: true }) + dropArea.addEventListener('pointercancel', userReleased, { passive: true }) + }; + + /* + In case where the dropArea moves along with the dragging object + we can only append deltas, but not to define each time it moves. + */ + function userMoved(event) { + if (!raf) { + deltaX += event.clientX - startX + deltaY += event.clientY - startY + deltaX = Math.min( + Math.max(deltaX, -bbox.left), + window.innerWidth - bbox.right, + ) + deltaY = Math.min( + Math.max(deltaY, -bbox.top), + window.innerHeight - bbox.bottom, + ) + raf = requestAnimationFrame(userMovedRaf) + } + } + + function userMovedRaf() { + movingEl.style.transform = "translate3d("+deltaX+"px,"+deltaY+"px, 0px)"; + raf = null; + } + + function userReleased() { + dropArea.removeEventListener('pointermove', userMoved) + dropArea.removeEventListener('pointerup', userReleased) + dropArea.removeEventListener('pointercancel', userReleased) + if (raf) { + cancelAnimationFrame(raf) + raf = null + } + movingEl.style.left = bbox.left + deltaX + "px" + movingEl.style.top = bbox.top + deltaY + "px" + movingEl.style.transform = "translate3d(0px,0px,0px)" + deltaX = deltaY = 0 + } +} \ No newline at end of file