feat(tracker-assist): 3.4.13: scroll behaviour improvement & mouse events incapsulation

This commit is contained in:
ShiKhu 2022-01-11 09:30:59 +01:00
parent a71d3db540
commit f056f69067
5 changed files with 89 additions and 52 deletions

View file

@ -72,7 +72,7 @@ onAgentConnect: () => {
Warning: it is possible for the same agent to be connected/disconnected several times during one session due to a bad network. Several agents may connect simultaneously.
A callback `onCallStart` will be fired when the end-user accepts the call. It can return another callback that will be called on call end.
A callback `onCallStart` will be fired when the end-user accepts the call. It can return another callback that will be called on the call end.
```ts
onCallStart: () => {
console.log("Allo!")

View file

@ -1,7 +1,7 @@
{
"name": "@openreplay/tracker-assist",
"description": "Tracker plugin for screen assistance through the WebRTC",
"version": "3.4.11",
"version": "3.4.13",
"keywords": [
"WebRTC",
"assistance",

View file

@ -207,14 +207,6 @@ export default class CallWindow {
private toggleAudio() {
const enabled = this.localStream?.toggleAudio() || false
this.toggleAudioUI(enabled)
// if (!this.audioBtn) { return; }
// if (enabled) {
// this.audioBtn.classList.remove("muted");
// this.audioBtn.childNodes[1].textContent = "Mute";
// } else {
// this.audioBtn.classList.add("muted");
// this.audioBtn.childNodes[1].textContent = "Unmute";
// }
}
private toggleVideoUI(enabled: boolean) {

View file

@ -1,3 +1,5 @@
type XY = [number, number]
export default class Mouse {
private mouse: HTMLDivElement
@ -14,23 +16,90 @@ export default class Mouse {
background: "radial-gradient(red, transparent)",
});
document.body.appendChild(this.mouse);
window.addEventListener("scroll", this.handleWScroll)
window.addEventListener("resize", this.resetLastScrEl)
}
move({x, y}: {x: number, y: number}) {
this.position = [x, y];
move(pos: XY) {
if (this.position[0] !== pos[0] || this.position[1] !== pos[1]) {
this.resetLastScrEl()
}
this.position = pos;
Object.assign(this.mouse.style, {
left: `${x || 0}px`,
top: `${y || 0}px`
left: `${pos[0] || 0}px`,
top: `${pos[1] || 0}px`
})
}
getPosition(): [ number, number] {
getPosition(): XY {
return this.position;
}
click(pos: XY) {
const el = document.elementFromPoint(pos[0], pos[1])
if (el instanceof HTMLElement) {
el.click()
el.focus()
}
}
private readonly pScrEl = document.scrollingElement || document.documentElement
private lastScrEl: Element | "window" | null = null
private resetLastScrEl = () => { this.lastScrEl = null }
private handleWScroll = e => {
if (e.target !== this.lastScrEl) {
this.resetLastScrEl()
}
}
scroll(delta: XY) {
// what would be the browser-like logic?
const [mouseX, mouseY] = this.position
const [dX, dY] = delta
let el = this.lastScrEl
// Scroll the same one
if (el instanceof Element) {
el.scrollLeft += dX
el.scrollTop += dY
return // TODO: if not scrolled
}
if (el === "window") {
window.scroll(this.pScrEl.scrollLeft + dX, this.pScrEl.scrollTop + dY)
return
}
el = document.elementFromPoint(
mouseX-this.pScrEl.scrollLeft,
mouseY-this.pScrEl.scrollTop,
)
while (el) {
//if(el.scrollWidth > el.clientWidth) // - This check doesn't work in common case
const esl = el.scrollLeft
el.scrollLeft += dX
const est = el.scrollTop
el.scrollTop += dY
if (esl !== el.scrollLeft || est !== el.scrollTop) {
this.lastScrEl = el
return
} else {
el = el.parentElement
}
}
// If not scrolled
window.scroll(this.pScrEl.scrollLeft + dX, this.pScrEl.scrollTop + dY)
this.lastScrEl = "window"
}
remove() {
if (this.mouse.parentElement) {
document.body.removeChild(this.mouse);
}
window.removeEventListener("scroll", this.handleWScroll)
window.removeEventListener("resize", this.resetLastScrEl)
}
}

View file

@ -11,13 +11,13 @@ import ConfirmWindow from './ConfirmWindow.js';
import RequestLocalStream from './LocalStream.js';
export interface Options {
onAgentConnect: () => (()=>{} | void),
onCallStart: () => (()=>{} | void),
onAgentConnect: () => ((()=>{}) | void),
onCallStart: () => ((()=>{}) | void),
confirmText: string,
confirmStyle: Object, // Styles object
session_calling_peer_key: string,
config: RTCConfiguration,
__messages_per_send?: number,
// __messages_per_send?: number,
}
enum CallingState {
@ -27,7 +27,7 @@ enum CallingState {
};
//@ts-ignore peerjs hack for webpack5 (?!) TODO: ES/node modules;
Peer = Peer.default || Peer;
//Peer = Peer.default || Peer;
// type IncomeMessages =
// "call_end" |
@ -102,11 +102,11 @@ export default function(opts?: Partial<Options>) {
log('Connection opened.')
assistDemandedRestart = true;
app.stop();
openDataConnections[conn.peer] = new BufferingConnection(conn, options.__messages_per_send)
openDataConnections[conn.peer] = new BufferingConnection(conn)
const onAgentDisconnect = options.onAgentConnect();
conn.on('close', () => {
onAgentDisconnect?.();
onAgentDisconnect && onAgentDisconnect();
log("Connection close: ", conn.peer)
delete openDataConnections[conn.peer] // TODO: check if works properly
})
@ -174,7 +174,7 @@ export default function(opts?: Partial<Options>) {
let callUI = new CallWindow()
const handleCallEnd = () => {
onCallEnd?.()
onCallEnd && onCallEnd()
mouse.remove();
callUI.remove();
setCallingState(CallingState.False);
@ -212,46 +212,22 @@ export default function(opts?: Partial<Options>) {
document.addEventListener("click", onInteraction)
});
dataConn.on('data', (data: any) => {
log("Income data: ", data)
if (!data) { return }
if (data === "call_end") {
log('"call_end" received')
handleCallEnd();
return;
return handleCallEnd();
}
if (data.name === 'string') {
log("Name received: ", data)
callUI.setAssistentName(data.name);
return callUI.setAssistentName(data.name);
}
if (data.type === "scroll" && Array.isArray(data.delta)) {
const scrEl = document.scrollingElement || document.documentElement
const [mouseX, mouseY] = mouse.getPosition()
const [dX, dY] = data.delta;
const el = document.elementFromPoint(mouseX-scrEl.scrollLeft, mouseY-scrEl.scrollTop)
let scrolled = false // what would be the browser-like logic?
if (el) {
if(el.scrollWidth > el.clientWidth) {
el.scrollLeft += data.delta[0]
scrolled = true
}
if (el && el.scrollHeight > el.clientHeight) {
el.scrollTop += data.delta[1]
scrolled = true
}
}
if (!scrolled) {
window.scroll(scrEl.scrollLeft + data.delta[0], scrEl.scrollTop + data.delta[1])
}
return mouse.scroll(data.delta)
}
if (data.type === "click" && typeof data.x === 'number' && typeof data.y === 'number') {
const el = document.elementFromPoint(data.x, data.y)
if (el instanceof HTMLElement) {
el.click()
el.focus()
}
return
return mouse.click([ data.x, data.y ])
}
if (typeof data.x === 'number' && typeof data.y === 'number') {
mouse.move(data);
return mouse.move([ data.x, data.y ])
}
});