diff --git a/frontend/app/player/web/Screen/Screen.ts b/frontend/app/player/web/Screen/Screen.ts index 4f5dad93a..9715cf011 100644 --- a/frontend/app/player/web/Screen/Screen.ts +++ b/frontend/app/player/web/Screen/Screen.ts @@ -54,9 +54,11 @@ export default class Screen { readonly cursor: Cursor private readonly iframe: HTMLIFrameElement; - private readonly screen: HTMLDivElement; - private readonly controlButton: HTMLDivElement; - private parentElement: HTMLElement | null = null; + protected readonly screen: HTMLDivElement; + protected readonly controlButton: HTMLDivElement; + protected parentElement: HTMLElement | null = null; + private remoteControlEnabled = false; + private recordingEnabled = false; constructor() { const iframe = document.createElement('iframe'); @@ -102,17 +104,23 @@ export default class Screen { }) } - getParentElement(): HTMLElement | null { - return this.parentElement - } - - toggleBorder(isEnabled: boolean ) { - const styles = isEnabled ? { border: '2px dashed blue' } : { border: 'unset'} + toggleRemoteControlStatus(isEnabled: boolean ) { + this.remoteControlEnabled = isEnabled; + if (!isEnabled) { + const styles = this.recordingEnabled ? { border: '2px dashed red' } : { border: 'unset'} + return Object.assign(this.screen.style, styles) + } + const styles = { border: '2px dashed blue' } return Object.assign(this.screen.style, styles) } toggleRecordingStatus(isEnabled: boolean) { - const styles = isEnabled ? { border: '2px dashed red' } : { border: 'unset'} + this.recordingEnabled = isEnabled; + if (!isEnabled) { + const styles = this.remoteControlEnabled ? { border: '2px dashed blue' } : { border: 'unset'} + return Object.assign(this.screen.style, styles) + } + const styles = { border: '2px dashed red' } return Object.assign(this.screen.style, styles) } diff --git a/frontend/app/player/web/assist/AssistManager.ts b/frontend/app/player/web/assist/AssistManager.ts index 45b3078d7..7d65a988d 100644 --- a/frontend/app/player/web/assist/AssistManager.ts +++ b/frontend/app/player/web/assist/AssistManager.ts @@ -283,6 +283,7 @@ export default class AssistManager { const recordingState = getState().recordingState if (!this.socket || recordingState === SessionRecordingStatus.Off) return; + console.log('stop rec') this.socket.emit("stop_recording") this.toggleRecording(false) } @@ -290,7 +291,8 @@ export default class AssistManager { private toggleRecording = (isAccepted: boolean) => { this.md.toggleRecordingStatus(isAccepted) - update({ recordingStatus: isAccepted ? SessionRecordingStatus.Recording : SessionRecordingStatus.Off }) + update({ recordingState: isAccepted ? SessionRecordingStatus.Recording : SessionRecordingStatus.Off }) + console.log('Im here', isAccepted, getState().recordingState) } /* ==== Remote Control ==== */ diff --git a/tracker/tracker-assist/src/Assist.ts b/tracker/tracker-assist/src/Assist.ts index 492dfce66..c620a3af9 100644 --- a/tracker/tracker-assist/src/Assist.ts +++ b/tracker/tracker-assist/src/Assist.ts @@ -177,7 +177,7 @@ export default class Assist { if (this.remoteControl){ callUI?.showRemoteControl(this.remoteControl.releaseControl) } - this.agents[id].onControlReleased = this.options.onRemoteControlStart(this.agents[id].agentInfo) + this.agents[id].onControlReleased = this.options.onRemoteControlStart(this.agents[id]?.agentInfo) this.emit('control_granted', id) annot = new AnnotationCanvas() annot.mount() @@ -209,7 +209,7 @@ export default class Assist { socket.emit('recording_denied') } const recordingState = new ScreenRecordingState(onAcceptRecording, onDenyRecording, this.options) - setTimeout(() => recordingState.requestRecording(), 5000) + // TODO: check incoming args socket.on('request_control', this.remoteControl.requestControl) socket.on('release_control', this.remoteControl.releaseControl) @@ -282,8 +282,13 @@ export default class Assist { }) socket.on('request_recording', (id, agentData) => { if (recordingState.status === RecordingState.Off) { - console.log('requested screen recording', this.agents[id].agentInfo, agentData) - this.options.onRecordingRequest?.(agentData) + this.options.onRecordingRequest?.(JSON.parse(agentData)) + recordingState.requestRecording(id) + } + }) + socket.on('stop_recording', (id) => { + if (recordingState.status !== RecordingState.Off) { + recordingState.denyRecording(id) } }) diff --git a/tracker/tracker-assist/src/ScreenRecordingState.ts b/tracker/tracker-assist/src/ScreenRecordingState.ts index c0833642f..0ab99cc7a 100644 --- a/tracker/tracker-assist/src/ScreenRecordingState.ts +++ b/tracker/tracker-assist/src/ScreenRecordingState.ts @@ -41,6 +41,8 @@ const borderEmulationStyles = { export default class ScreenRecordingState { public status = RecordingState.Off + private agentsRecordingSession: string[] = [] + private overlayAdded = false constructor( private readonly onAccept: () => void, @@ -50,20 +52,15 @@ export default class ScreenRecordingState { private confirm: ConfirmWindow | null = null - public requestRecording = () => { + public requestRecording = (id: string) => { if (this.status !== RecordingState.Off) return this.status = RecordingState.Requested - // todo: change timeout to deny after testing - setTimeout(() => { - console.log('starting recording') - this.acceptRecording() - }, 5000) - this.confirm = new ConfirmWindow(recordRequestDefault(this.options.controlConfirm)) this.confirm.mount().then(allowed => { if (allowed) { this.acceptRecording() + this.agentsRecordingSession.push(id) } else { this.confirm?.remove() this.denyRecording() @@ -79,43 +76,57 @@ export default class ScreenRecordingState { } private readonly acceptRecording = () => { - const borders = { - left: window.document.createElement('div'), - top: window.document.createElement('div'), - right: window.document.createElement('div'), - bottom: window.document.createElement('div'), - } + if (!this.overlayAdded) { + const borders = { + left: window.document.createElement('div'), + top: window.document.createElement('div'), + right: window.document.createElement('div'), + bottom: window.document.createElement('div'), + } - const stopButton = window.document.createElement('div') - stopButton.onclick = this.denyRecording - const styles = { - cursor: 'pointer', - color: 'white', - position: 'fixed', - bottom: 0, - left: 'calc(50vw - 10px)', - padding: 4, - background: 'blue', - borderRadius: 6, - textAlign: 'center', - } - Object.assign(stopButton.style, styles) - stopButton.textContent = 'Stop Recording' - stopButton.id = 'or-recording-border' - window.document.body.appendChild(stopButton) + const stopButton = window.document.createElement('div') + stopButton.onclick = () => this.denyRecording() + const styles = { + cursor: 'pointer', + color: 'white', + position: 'fixed', + bottom: '0', + left: 'calc(50vw - 60px)', + padding: '1px 3px', + background: 'blue', + 'border-top-right-radius': '3px', + 'border-top-left-radius': '3px', + 'text-align': 'center', + } + Object.assign(stopButton.style, styles) + stopButton.textContent = 'Stop Recording' + stopButton.id = 'or-recording-border' + window.document.body.appendChild(stopButton) - Object.entries(borderEmulationStyles).forEach(([key, style,]) => { - Object.assign(borders[key].style, style) - borders[key].id = 'or-recording-border' - window.document.body.appendChild(borders[key]) - }) + Object.entries(borderEmulationStyles).forEach(([key, style,]) => { + Object.assign(borders[key].style, style) + borders[key].id = 'or-recording-border' + window.document.body.appendChild(borders[key]) + }) + + this.overlayAdded = true + } this.onAccept() this.status = RecordingState.Recording } - private readonly denyRecording = () => { + public readonly denyRecording = (id?: string) => { + if (id) { + const agentIndex = this.agentsRecordingSession.findIndex(agentId => agentId === id) + if (agentIndex === -1) return + else this.agentsRecordingSession = this.agentsRecordingSession.filter(agentId => agentId !== id) + + if (this.agentsRecordingSession.length > 0) return + } + this.onDeny() + this.confirm?.remove() this.status = RecordingState.Off const borders = window.document.querySelectorAll('#or-recording-border')