feat (tracker-assist): 3.4.9: focus on remote click & remote scroll & less messages per send for some browsers
This commit is contained in:
parent
1809c2eda1
commit
f50355a67c
6 changed files with 53 additions and 14 deletions
2
tracker/tracker-assist/package-lock.json
generated
2
tracker/tracker-assist/package-lock.json
generated
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@openreplay/tracker-assist",
|
||||
"version": "3.4.7",
|
||||
"version": "3.4.8",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -5,4 +5,4 @@
|
|||
*/
|
||||
|
||||
// @ts-ignore
|
||||
window.parcelRequire = window.parcelRequire || undefined;
|
||||
typeof window !== "undefined" && (window.parcelRequire = window.parcelRequire || undefined);
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue