From ebc14207f782579c80acbb24b11352877133ef51 Mon Sep 17 00:00:00 2001 From: Shekar Siri Date: Mon, 19 Jun 2023 13:11:59 +0200 Subject: [PATCH] dev - fix message type, assist etc., (#1349) * fix(ui): fix for messages type from ws * fix(ui): fixes for tab typings, use State instead of array to keep tabs * fix(assist): fixed issue with sessionUpdate event * fix(ui): fix support for old version of assist proto --------- Co-authored-by: nick-delirium Co-authored-by: Alexander Zavorotynskiy --- assist/servers/websocket.js | 5 ++-- ee/assist/servers/websocket-cluster.js | 5 ++-- ee/assist/servers/websocket.js | 5 ++-- frontend/app/player/web/MessageManager.ts | 28 ++++++++++++++----- frontend/app/player/web/TabManager.ts | 4 +++ .../app/player/web/assist/AssistManager.ts | 21 +++++++++++--- frontend/app/player/web/assist/Call.ts | 13 +++++++-- .../app/player/web/assist/RemoteControl.ts | 9 +++++- .../app/player/web/assist/ScreenRecording.ts | 12 ++++++-- 9 files changed, 76 insertions(+), 26 deletions(-) diff --git a/assist/servers/websocket.js b/assist/servers/websocket.js index 6dbb5bf21..f146057e0 100644 --- a/assist/servers/websocket.js +++ b/assist/servers/websocket.js @@ -345,11 +345,10 @@ module.exports = { } Object.assign(socket.handshake.query.sessionInfo, args[0].data, {tabId: args[0].meta.tabId}); socket.to(socket.roomId).emit(EVENTS_DEFINITION.emit.UPDATE_EVENT, args[0]); - // Update sessionInfo for all sessions (TODO: rewrite this) + // Update sessionInfo for all sessions in room const rooms = await getAvailableRooms(io); for (let roomId of rooms.keys()) { - let {projectKey} = extractPeerId(roomId); - if (projectKey === connProjectKey) { + if (roomId === socket.roomId) { const connected_sockets = await io.in(roomId).fetchSockets(); for (let item of connected_sockets) { if (item.handshake.query.identity === IDENTITIES.session && item.handshake.query.sessionInfo) { diff --git a/ee/assist/servers/websocket-cluster.js b/ee/assist/servers/websocket-cluster.js index a03d582c1..4cad9dcb1 100644 --- a/ee/assist/servers/websocket-cluster.js +++ b/ee/assist/servers/websocket-cluster.js @@ -398,11 +398,10 @@ module.exports = { } Object.assign(socket.handshake.query.sessionInfo, args[0].data, {tabId: args[0].meta.tabId}); socket.to(socket.roomId).emit(EVENTS_DEFINITION.emit.UPDATE_EVENT, args[0]); - // Update sessionInfo for all sessions (TODO: rewrite this) + // Update sessionInfo for all sessions in room const rooms = await getAvailableRooms(io); for (let roomId of rooms.keys()) { - let {projectKey} = extractPeerId(roomId); - if (projectKey === connProjectKey) { + if (roomId === socket.roomId) { const connected_sockets = await io.in(roomId).fetchSockets(); for (let item of connected_sockets) { if (item.handshake.query.identity === IDENTITIES.session && item.handshake.query.sessionInfo) { diff --git a/ee/assist/servers/websocket.js b/ee/assist/servers/websocket.js index 255d3e5be..4411593e4 100644 --- a/ee/assist/servers/websocket.js +++ b/ee/assist/servers/websocket.js @@ -366,11 +366,10 @@ module.exports = { } Object.assign(socket.handshake.query.sessionInfo, args[0].data, {tabId: args[0].meta.tabId}); socket.to(socket.roomId).emit(EVENTS_DEFINITION.emit.UPDATE_EVENT, args[0]); - // Update sessionInfo for all sessions (TODO: rewrite this) + // Update sessionInfo for all sessions in room const rooms = await getAvailableRooms(io); for (let roomId of rooms.keys()) { - let {projectKey} = extractPeerId(roomId); - if (projectKey === connProjectKey) { + if (roomId === socket.roomId) { const connected_sockets = await io.in(roomId).fetchSockets(); for (let item of connected_sockets) { if (item.handshake.query.identity === IDENTITIES.session && item.handshake.query.sessionInfo) { diff --git a/frontend/app/player/web/MessageManager.ts b/frontend/app/player/web/MessageManager.ts index 3522148c2..dc1441e69 100644 --- a/frontend/app/player/web/MessageManager.ts +++ b/frontend/app/player/web/MessageManager.ts @@ -29,6 +29,17 @@ interface RawList { exceptions: ILog[]; } +type TabChangeEvent = { + tabId: string; + timestamp: number; + tabName: string; + time: number; + toTab: string; + fromTab: string; + type: string; + activeUrl: ''; +}; + export interface State extends ScreenState { skipIntervals: SkipInterval[]; connType?: string; @@ -51,7 +62,7 @@ export interface State extends ScreenState { messagesProcessed: boolean; currentTab: string; tabs: Set; - tabChangeEvents: { tabId: string; timestamp: number; tabName: string }[]; + tabChangeEvents: TabChangeEvent[]; } export const visualChanges = [ @@ -93,7 +104,7 @@ export default class MessageManager { private lastMessageTime: number = 0; private firstVisualEventSet = false; public readonly tabs: Record = {}; - private tabChangeEvents: Record[] = []; + private tabChangeEvents: TabChangeEvent[] = []; private activeTab = ''; constructor( @@ -132,7 +143,7 @@ export default class MessageManager { // if (Object.values(list).some((l) => l.length > 0)) { // this.tabs[tab]!.updateLists(list); // } - }) + }); } public _sortMessagesHack = (msgs: Message[]) => { @@ -197,7 +208,7 @@ export default class MessageManager { this.tabs[this.activeTab].clean(); } const activeTabs = this.state.get().tabs; - if (activeTabs.length !== this.activeTabManager.tabInstances.size) { + if (activeTabs.size !== this.activeTabManager.tabInstances.size) { this.state.update({ tabs: this.activeTabManager.tabInstances }); } } @@ -262,10 +273,12 @@ export default class MessageManager { this.tabChangeEvents.push({ tabId: msg.tabId, time: msg.time, + tabName: prevChange?.tabId ? mapTabs(this.tabs)[prevChange.tabId] : '', timestamp: this.sessionStart + msg.time, toTab: mapTabs(this.tabs)[msg.tabId], fromTab: prevChange?.tabId ? mapTabs(this.tabs)[prevChange.tabId] : '', type: 'TABCHANGE', + activeUrl: '', }); this.activeTabManager.append(msg); } @@ -302,6 +315,7 @@ export default class MessageManager { this.updateChangeEvents(); } this.screen.display(!messagesLoading); + // @ts-ignore idk this.state.update({ messagesLoading, ready: !messagesLoading && !this.state.get().cssLoading }); }; @@ -320,11 +334,11 @@ export default class MessageManager { } } -function mapTabs(tabs: Record) { +function mapTabs(tabs: Record) { const tabIds = Object.keys(tabs); - const tabMap = {}; + const tabMap: Record = {}; tabIds.forEach((tabId) => { - tabMap[tabId] = `Tab ${tabIds.indexOf(tabId)+1}`; + tabMap[tabId] = `Tab ${tabIds.indexOf(tabId) + 1}`; }); return tabMap; diff --git a/frontend/app/player/web/TabManager.ts b/frontend/app/player/web/TabManager.ts index fb4f374f9..e96a87100 100644 --- a/frontend/app/player/web/TabManager.ts +++ b/frontend/app/player/web/TabManager.ts @@ -25,6 +25,7 @@ export interface TabState extends ListsState { performanceChartTime: PerformanceChartPoint[] cssLoading: boolean location: string + urlsList: SetPageLocation[] } /** @@ -39,6 +40,7 @@ export default class TabSessionManager { performanceChartTime: [], cssLoading: false, location: '', + urlsList: [], } public locationManager: ListWalker = new ListWalker(); @@ -88,6 +90,7 @@ export default class TabSessionManager { const currentState = this.state.get() this.state.update({ + // @ts-ignore comes from parent state eventCount: currentState.eventCount + eventCount, tabStates: { ...currentState.tabStates, @@ -258,6 +261,7 @@ export default class TabSessionManager { /* === */ const lastLocationMsg = this.locationManager.moveGetLast(t, index); if (!!lastLocationMsg) { + // @ts-ignore comes from parent state this.state.update({ location: lastLocationMsg.url }) } const lastConnectionInfoMsg = this.connectionInfoManger.moveGetLast(t, index); diff --git a/frontend/app/player/web/assist/AssistManager.ts b/frontend/app/player/web/assist/AssistManager.ts index 50ddc369c..2750d461f 100644 --- a/frontend/app/player/web/assist/AssistManager.ts +++ b/frontend/app/player/web/assist/AssistManager.ts @@ -53,6 +53,7 @@ export function getStatusText(status: ConnectionStatus): string { const MAX_RECONNECTION_COUNT = 4; export default class AssistManager { + assistVersion = 1 static readonly INITIAL_STATE = { peerConnectionStatus: ConnectionStatus.Connecting, assistStart: 0, @@ -71,6 +72,8 @@ export default class AssistManager { public readonly uiErrorHandler?: { error: (msg: string) => void } ) {} + public getAssistVersion = () => this.assistVersion + private get borderStyle() { const { recordingState, remoteControl } = this.store.get() @@ -168,7 +171,10 @@ export default class AssistManager { }) socket.on('messages', messages => { - jmr.append(messages.data) // as RawMessage[] + if (messages.data !== undefined) this.assistVersion = 2 + + const data = messages.data || messages + jmr.append(data) // as RawMessage[] if (waitingForMessages) { waitingForMessages = false // TODO: more explicit this.setStatus(ConnectionStatus.Connected) @@ -188,7 +194,8 @@ export default class AssistManager { socket.on('UPDATE_SESSION', (evData) => { const { meta = {}, data = {} } = evData const { tabId } = meta - const { active } = data + const usedData = this.assistVersion === 1 ? evData : data + const { active } = usedData const currentTab = this.store.get().currentTab this.clearDisconnectTimeout() !this.inactiveTimeout && this.setStatus(ConnectionStatus.Connected) @@ -197,6 +204,9 @@ export default class AssistManager { if (active) { this.setStatus(ConnectionStatus.Connected) } else { + if (tabId === undefined) { + this.inactiveTimeout = setTimeout(() => this.setStatus(ConnectionStatus.Inactive), 5000) + } if (tabId === currentTab) { this.inactiveTimeout = setTimeout(() => this.setStatus(ConnectionStatus.Inactive), 5000) } @@ -222,20 +232,23 @@ export default class AssistManager { socket, this.config, this.peerID, + this.getAssistVersion ) this.remoteControl = new RemoteControl( this.store, socket, this.screen, this.session.agentInfo, - () => this.screen.setBorderStyle(this.borderStyle) + () => this.screen.setBorderStyle(this.borderStyle), + this.getAssistVersion, ) this.screenRecording = new ScreenRecording( this.store, socket, this.session.agentInfo, () => this.screen.setBorderStyle(this.borderStyle), - this.uiErrorHandler + this.uiErrorHandler, + this.getAssistVersion, ) document.addEventListener('visibilitychange', this.onVisChange) diff --git a/frontend/app/player/web/assist/Call.ts b/frontend/app/player/web/assist/Call.ts index cf6d9afd2..5399a2b25 100644 --- a/frontend/app/player/web/assist/Call.ts +++ b/frontend/app/player/web/assist/Call.ts @@ -22,6 +22,7 @@ export interface State { } export default class Call { + private assistVersion = 1 static readonly INITIAL_STATE: Readonly = { calling: CallingState.NoCall } @@ -36,6 +37,7 @@ export default class Call { private socket: Socket, private config: RTCIceServer[] | null, private peerID: string, + private getAssistVersion: () => number ) { socket.on('call_end', this.onRemoteCallEnd) socket.on('videofeed', ({ streamId, enabled }) => { @@ -64,6 +66,7 @@ export default class Call { socket.on("disconnect", () => { this.store.update({ calling: CallingState.NoCall }) }) + this.assistVersion = this.getAssistVersion() } private getPeer(): Promise { @@ -170,7 +173,11 @@ export default class Call { } private emitData = (event: string, data?: any) => { - this.socket?.emit(event, { meta: { tabId: this.store.get().currentTab }, data }) + if (this.assistVersion === 1) { + this.socket?.emit(event, data) + } else { + this.socket?.emit(event, { meta: { tabId: this.store.get().currentTab }, data }) + } } @@ -231,8 +238,8 @@ export default class Call { if (!this.store.get().currentTab) { console.warn('No tab data to connect to peer') } - console.log(tab) - void this._peerConnection(`${this.peerID}-${tab || Object.keys(this.store.get().tabs)[0]}`); + const peerId = this.assistVersion === 1 ? this.peerID : `${this.peerID}-${tab || Object.keys(this.store.get().tabs)[0]}` + void this._peerConnection(peerId); this.emitData("_agent_name", appStore.getState().getIn([ 'user', 'account', 'name'])) } diff --git a/frontend/app/player/web/assist/RemoteControl.ts b/frontend/app/player/web/assist/RemoteControl.ts index ecde14eb6..3b7405788 100644 --- a/frontend/app/player/web/assist/RemoteControl.ts +++ b/frontend/app/player/web/assist/RemoteControl.ts @@ -16,6 +16,7 @@ export interface State { } export default class RemoteControl { + private assistVersion = 1 static readonly INITIAL_STATE: Readonly = { remoteControl: RemoteControlStatus.Disabled, annotating: false, @@ -28,6 +29,7 @@ export default class RemoteControl { private screen: Screen, private agentInfo: Object, private onToggle: (active: boolean) => void, + private getAssistVersion: () => number, ){ socket.on("control_granted", ({ meta, data }) => { this.toggleRemoteControl(data === socket.id) @@ -47,6 +49,7 @@ export default class RemoteControl { socket.on("error", () => { this.toggleRemoteControl(false) }) + this.assistVersion = getAssistVersion() } private onMouseMove = (e: MouseEvent): void => { @@ -55,7 +58,11 @@ export default class RemoteControl { } private emitData = (event: string, data?: any) => { - this.socket.emit(event, { meta: { tabId: this.store.get().currentTab }, data }) + if (this.assistVersion === 1) { + this.socket.emit(event, data) + } else { + this.socket.emit(event, { meta: { tabId: this.store.get().currentTab }, data }) + } } private onWheel = (e: WheelEvent): void => { diff --git a/frontend/app/player/web/assist/ScreenRecording.ts b/frontend/app/player/web/assist/ScreenRecording.ts index fdbd850a2..3a7c71947 100644 --- a/frontend/app/player/web/assist/ScreenRecording.ts +++ b/frontend/app/player/web/assist/ScreenRecording.ts @@ -14,6 +14,7 @@ export interface State { } export default class ScreenRecording { + private assistVersion = 1 onDeny: () => void = () => {} static readonly INITIAL_STATE: Readonly = { recordingState: SessionRecordingStatus.Off, @@ -23,7 +24,8 @@ export default class ScreenRecording { private socket: Socket, private agentInfo: Object, private onToggle: (active: boolean) => void, - public readonly uiErrorHandler: { error: (msg: string) => void } | undefined + public readonly uiErrorHandler: { error: (msg: string) => void } | undefined, + private getAssistVersion: () => number ) { socket.on('recording_accepted', () => { this.toggleRecording(true) @@ -35,6 +37,8 @@ export default class ScreenRecording { socket.on('recording_busy', () => { this.onRecordingBusy() }) + + this.assistVersion = getAssistVersion() } private onRecordingBusy = () => { @@ -55,7 +59,11 @@ export default class ScreenRecording { } private emitData = (event: string, data?: any) => { - this.socket.emit(event, { meta: { tabId: this.store.get().currentTab }, data }) + if (this.assistVersion === 1) { + this.socket.emit(event, data) + } else { + this.socket.emit(event, { meta: { tabId: this.store.get().currentTab }, data }) + } } stopRecording = () => {