diff --git a/tracker/tracker-assist/src/Assist.ts b/tracker/tracker-assist/src/Assist.ts index a516ee35f..a9290998d 100644 --- a/tracker/tracker-assist/src/Assist.ts +++ b/tracker/tracker-assist/src/Assist.ts @@ -210,7 +210,7 @@ export default class Assist { const onRejectRecording = () => { socket.emit('recording_rejected') } - const recordingState = new ScreenRecordingState(onAcceptRecording, onRejectRecording, this.options) + const recordingState = new ScreenRecordingState(this.options.recordingConfirm) // TODO: check incoming args socket.on('request_control', this.remoteControl.requestControl) @@ -261,17 +261,13 @@ export default class Assist { this.agents[id]?.onDisconnect?.() delete this.agents[id] - if (Object.keys(this.agents).length === 0 && recordingState.isActive) { - recordingState.rejectRecording() - } else { - recordingState.stopAgentRecording(id) - } + recordingState.stopAgentRecording(id) endAgentCall(id) }) socket.on('NO_AGENT', () => { Object.values(this.agents).forEach(a => a.onDisconnect?.()) this.agents = {} - if (recordingState.isActive) recordingState.rejectRecording() + if (recordingState.isActive) recordingState.stopRecording() }) socket.on('call_end', (id) => { if (!callingAgents.has(id)) { @@ -291,14 +287,14 @@ export default class Assist { socket.on('request_recording', (id, agentData) => { if (!recordingState.isActive) { this.options.onRecordingRequest?.(JSON.parse(agentData)) - recordingState.requestRecording(id) + recordingState.requestRecording(id, onAcceptRecording, onRejectRecording) } else { this.emit('recording_busy') } }) - socket.on('stop_recording', () => { + socket.on('stop_recording', (id) => { if (recordingState.isActive) { - recordingState.rejectRecording() + recordingState.stopAgentRecording(id) } }) diff --git a/tracker/tracker-assist/src/ScreenRecordingState.ts b/tracker/tracker-assist/src/ScreenRecordingState.ts index 238c36a99..465b21012 100644 --- a/tracker/tracker-assist/src/ScreenRecordingState.ts +++ b/tracker/tracker-assist/src/ScreenRecordingState.ts @@ -1,118 +1,125 @@ import ConfirmWindow from './ConfirmWindow/ConfirmWindow.js' import { recordRequestDefault, } from './ConfirmWindow/defaults.js' -import type { Options as AssistOptions, } from './Assist' +import type { Options as ConfirmOptions, } from './ConfirmWindow/defaults.js' export enum RecordingState { - Off, - Requested, - Recording, + Off, + Requested, + Recording, } const borderStyles = { - height: '100vh', - width: '100vw', - border: '2px dashed red', - left: 0, - top: 0, - position: 'fixed', - 'pointer-events': 'none', + height: '100vh', + width: '100vw', + border: '2px dashed red', + left: 0, + top: 0, + position: 'fixed', + 'pointer-events': 'none', } const buttonStyles = { - cursor: 'pointer', - color: 'white', - position: 'fixed', - bottom: '0', - left: 'calc(50vw - 60px)', - 'font-weight': 500, - padding: '2px 4px', - background: '#394EFF', - 'border-top-right-radius': '3px', - 'border-top-left-radius': '3px', - 'text-align': 'center', + cursor: 'pointer', + color: 'white', + position: 'fixed', + bottom: '0', + left: 'calc(50vw - 60px)', + 'font-weight': 500, + padding: '2px 4px', + background: '#394EFF', + 'border-top-right-radius': '3px', + 'border-top-left-radius': '3px', + 'text-align': 'center', } export default class ScreenRecordingState { - private status = RecordingState.Off - private recordingAgent: string - private overlayAdded = false + private status = RecordingState.Off + private recordingAgent: string + private overlayAdded = false - constructor( - private readonly onAccept: () => void, - private readonly onDeny: () => void, - private readonly options: AssistOptions - ) {} + constructor( + private readonly confirmOptions: ConfirmOptions, + ) {} - public get isActive() { - return this.status !== RecordingState.Off + public get isActive() { + return this.status !== RecordingState.Off + } + + private confirm: ConfirmWindow | null = null + + public requestRecording = (id: string, onAccept: () => void, onDeny: () => void) => { + if (this.isActive) return + this.status = RecordingState.Requested + + this.confirm = new ConfirmWindow( + recordRequestDefault(this.confirmOptions), + ) + this.confirm + .mount() + .then((allowed) => { + if (allowed) { + this.acceptRecording() + onAccept() + + this.recordingAgent = id + } else { + this.rejectRecording() + onDeny() + } + }) + .then(() => { + this.confirm?.remove() + }) + .catch((e) => { + this.confirm?.remove() + console.error(e) + }) + } + + private readonly acceptRecording = () => { + if (!this.overlayAdded) { + const stopButton = window.document.createElement('div') + stopButton.onclick = () => this.rejectRecording() + Object.assign(stopButton.style, buttonStyles) + stopButton.textContent = 'Stop Recording' + stopButton.className = 'or-recording-button' + stopButton.setAttribute('data-openreplay-obscured', '') + stopButton.setAttribute('data-openreplay-hidden', '') + stopButton.setAttribute('data-openreplay-ignore', '') + window.document.body.appendChild(stopButton) + + const borderWindow = window.document.createElement('div') + Object.assign(borderWindow.style, borderStyles) + borderWindow.className = 'or-recording-border' + borderWindow.setAttribute('data-openreplay-obscured', '') + borderWindow.setAttribute('data-openreplay-hidden', '') + borderWindow.setAttribute('data-openreplay-ignore', '') + window.document.body.appendChild(borderWindow) + + this.overlayAdded = true + } + this.status = RecordingState.Recording + } + + public readonly stopAgentRecording = (id) => { + if (id === this.recordingAgent) { + this.rejectRecording() + } + } + + public readonly stopRecording = () => { + this.rejectRecording() } - private confirm: ConfirmWindow | null = null + private readonly rejectRecording = () => { + this.confirm?.remove() + this.status = RecordingState.Off - public requestRecording = (id: string) => { - if (this.status !== RecordingState.Off) return - this.status = RecordingState.Requested - - this.confirm = new ConfirmWindow(recordRequestDefault(this.options.recordingConfirm)) - this.confirm.mount().then(allowed => { - if (allowed) { - this.acceptRecording() - this.recordingAgent = id - } else { - this.rejectRecording() - } - }) - .then(() => { - this.confirm?.remove() - }) - .catch(e => { - this.confirm?.remove() - console.error(e) - }) - } - - private readonly acceptRecording = () => { - if (!this.overlayAdded) { - const stopButton = window.document.createElement('div') - stopButton.onclick = () => this.rejectRecording() - Object.assign(stopButton.style, buttonStyles) - stopButton.textContent = 'Stop Recording' - stopButton.id = 'or-recording-button' - stopButton.setAttribute('data-openreplay-obscured', '') - stopButton.setAttribute('data-openreplay-hidden', '') - stopButton.setAttribute('data-openreplay-ignore', '') - window.document.body.appendChild(stopButton) - - const borderWindow = window.document.createElement('div') - Object.assign(borderWindow.style, borderStyles) - borderWindow.id = 'or-recording-border' - borderWindow.setAttribute('data-openreplay-obscured', '') - borderWindow.setAttribute('data-openreplay-hidden', '') - borderWindow.setAttribute('data-openreplay-ignore', '') - window.document.body.appendChild(borderWindow) - - this.overlayAdded = true - } - this.onAccept() - this.status = RecordingState.Recording - } - - public readonly stopAgentRecording = (id) => { - if (id === this.recordingAgent) { - this.rejectRecording() - } - } - - public readonly rejectRecording = () => { - this.onDeny() - this.confirm?.remove() - this.status = RecordingState.Off - - const borders = window.document.querySelector('#or-recording-border') - const button = window.document.querySelector('#or-recording-button') - if (borders && button) { - borders.parentElement?.removeChild(borders) - button.parentElement?.removeChild(button) - } - } + const borders = window.document.querySelector('.or-recording-border') + const button = window.document.querySelector('.or-recording-button') + if (borders && button) { + borders.parentElement?.removeChild(borders) + button.parentElement?.removeChild(button) + } + } }