feat (tracker-assist): 3.4.9: focus on remote click & remote scroll & less messages per send for some browsers

This commit is contained in:
ShiKhu 2021-12-01 21:14:11 +01:00
parent 1809c2eda1
commit f50355a67c
6 changed files with 53 additions and 14 deletions

View file

@ -1,6 +1,6 @@
{
"name": "@openreplay/tracker-assist",
"version": "3.4.7",
"version": "3.4.8",
"lockfileVersion": 1,
"requires": true,
"dependencies": {

View file

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

View file

@ -5,18 +5,27 @@ interface Message {
encode(w: any): boolean;
}
// 16kb should be max according to specification
const crOrFf: boolean =
typeof navigator !== "undefined" &&
(navigator.userAgent.indexOf("Chrom") !== -1 || // Chrome && Chromium
navigator.userAgent.indexOf("Firefox") !== -1);
const MESSAGES_PER_SEND = crOrFf ? 500 : 100
// Bffering required in case of webRTC
export default class BufferingConnection {
private readonly buffer: Message[][] = []
private buffering: boolean = false
constructor(readonly conn: DataConnection){}
constructor(readonly conn: DataConnection,
private readonly msgsPerSend: number = MESSAGES_PER_SEND){}
private sendNext() {
if (this.buffer.length) {
setTimeout(() => {
this.conn.send(this.buffer.shift())
this.sendNext()
}, 50)
}, 15)
} else {
this.buffering = false
}
@ -26,7 +35,7 @@ export default class BufferingConnection {
if (!this.conn.open) { return; }
let i = 0;
while (i < messages.length) {
this.buffer.push(messages.slice(i, i+=1000))
this.buffer.push(messages.slice(i, i+=this.msgsPerSend))
}
if (!this.buffering) {
this.buffering = true

View file

@ -1,8 +1,7 @@
export default class Mouse {
private mouse: HTMLDivElement
private position: [number,number] = [0,0]
constructor() {
this.mouse = document.createElement('div');
Object.assign(this.mouse.style, {
@ -17,13 +16,18 @@ export default class Mouse {
document.body.appendChild(this.mouse);
}
move({x, y}: {x?: number, y?: number}) {
move({x, y}: {x: number, y: number}) {
this.position = [x, y];
Object.assign(this.mouse.style, {
left: `${x || 0}px`,
top: `${y || 0}px`
})
}
getPosition(): [ number, number] {
return this.position;
}
remove() {
if (this.mouse.parentElement) {
document.body.removeChild(this.mouse);

View file

@ -5,4 +5,4 @@
*/
// @ts-ignore
window.parcelRequire = window.parcelRequire || undefined;
typeof window !== "undefined" && (window.parcelRequire = window.parcelRequire || undefined);

View file

@ -15,6 +15,7 @@ export interface Options {
confirmStyle: Object, // Styles object
session_calling_peer_key: string,
config: RTCConfiguration,
__messages_per_send?: number,
}
enum CallingState {
@ -23,7 +24,7 @@ enum CallingState {
False,
};
//@ts-ignore peerjs hack for webpack5 (?!)
//@ts-ignore peerjs hack for webpack5 (?!) TODO: ES/node modules;
Peer = Peer.default || Peer;
// type IncomeMessages =
@ -32,13 +33,13 @@ Peer = Peer.default || Peer;
// { type: "click", x: number, y: number } |
// { x: number, y: number }
export default function(opts: Partial<Options> = {}) {
export default function(opts?: Partial<Options>) {
const options: Options = Object.assign(
{
confirmText: "You have an incoming call. Do you want to answer?",
confirmStyle: {},
session_calling_peer_key: "__openreplay_calling_peer",
config: null
config: null,
},
opts,
);
@ -58,6 +59,7 @@ export default function(opts: Partial<Options> = {}) {
let assistDemandedRestart = false
let peer : Peer | null = null
// This is required because internal peerjs connection list is not stable. https://peerjs.com/docs.html#peerconnections
const openDataConnections: Record<string, BufferingConnection> = {}
app.addCommitCallback(function(messages) {
@ -66,7 +68,10 @@ export default function(opts: Partial<Options> = {}) {
app.attachStopCallback(function() {
if (assistDemandedRestart) { return; }
peer && peer.destroy();
if (peer) {
peer.destroy();
log('Peer destroyed!')
}
});
app.attachStartCallback(function() {
@ -77,6 +82,7 @@ export default function(opts: Partial<Options> = {}) {
host: app.getHost(),
path: '/assist',
port: location.protocol === 'http:' && appOptions.__DISABLE_SECURE_MODE ? 80 : 443,
//debug: // 0 Print nothing //1 Prints only errors. / 2 Prints errors and warnings. / 3 Prints all logs.
}
if (options.config) {
_opt['config'] = options.config
@ -92,7 +98,7 @@ export default function(opts: Partial<Options> = {}) {
log('Connection opened.')
assistDemandedRestart = true;
app.stop();
openDataConnections[conn.peer] = new BufferingConnection(conn)
openDataConnections[conn.peer] = new BufferingConnection(conn, options.__messages_per_send)
conn.on('close', () => {
log("Connection close: ", conn.peer)
delete openDataConnections[conn.peer] // TODO: check if works properly
@ -206,6 +212,26 @@ export default function(opts: Partial<Options> = {}) {
log("name recieved: ", data)
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])
}
}
if (data.type === "click" && typeof data.x === 'number' && typeof data.y === 'number') {
const el = document.elementFromPoint(data.x, data.y)
if (el instanceof HTMLElement) {