diff --git a/assist/utils/socketHandlers.js b/assist/utils/socketHandlers.js index 503969c08..7921b4f9e 100644 --- a/assist/utils/socketHandlers.js +++ b/assist/utils/socketHandlers.js @@ -118,7 +118,7 @@ async function onConnect(socket) { // Stats startAssist(socket, socket.handshake.query.agentID); } - socket.to(socket.handshake.query.roomId).emit(EVENTS_DEFINITION.emit.NEW_AGENT, socket.id, socket.handshake.query.agentInfo); + socket.to(socket.handshake.query.roomId).emit(EVENTS_DEFINITION.emit.NEW_AGENT, socket.id, { ...socket.handshake.query.agentInfo, config: socket.handshake.query.config }); } // Set disconnect handler diff --git a/frontend/app/components/Assist/ChatWindow/ChatWindow.tsx b/frontend/app/components/Assist/ChatWindow/ChatWindow.tsx index b7fe24127..4ea5723b5 100644 --- a/frontend/app/components/Assist/ChatWindow/ChatWindow.tsx +++ b/frontend/app/components/Assist/ChatWindow/ChatWindow.tsx @@ -1,7 +1,7 @@ import React, { useState, useEffect } from 'react'; import cn from 'classnames'; import Counter from 'App/components/shared/SessionItem/Counter'; -import Draggable from 'react-draggable'; +import { useDraggable } from '@neodrag/react'; import type { LocalStream } from 'Player'; import { PlayerContext } from 'App/components/Session/playerContext'; import ChatControls from '../ChatControls/ChatControls'; @@ -25,6 +25,8 @@ function ChatWindow({ isPrestart, }: Props) { const { t } = useTranslation(); + const dragRef = React.useRef(null); + useDraggable(dragRef, { bounds: 'body', defaultPosition: { x: 50, y: 200 } }) const { player } = React.useContext(PlayerContext); const { toggleVideoLocalStream } = player.assistManager; @@ -39,11 +41,7 @@ function ChatWindow({ }, [localVideoEnabled]); return ( - +
- +
); } diff --git a/frontend/app/player/web/assist/AssistManager.ts b/frontend/app/player/web/assist/AssistManager.ts index 1a204cbea..9ff091aef 100644 --- a/frontend/app/player/web/assist/AssistManager.ts +++ b/frontend/app/player/web/assist/AssistManager.ts @@ -203,6 +203,7 @@ export default class AssistManager { peerId: this.peerID, query: document.location.search, }), + config: JSON.stringify(this.getIceServers()), }, })); @@ -317,7 +318,7 @@ export default class AssistManager { this.callManager = new Call( this.store, socket, - this.config, + this.getIceServers(), this.peerID, this.getAssistVersion, { @@ -357,6 +358,23 @@ export default class AssistManager { }); } + private getIceServers = () => { + if (this.config) { + return this.config; + } + return [ + { + urls: [ + 'stun:stun.l.google.com:19302', + 'stun:stun1.l.google.com:19302', + 'stun:stun2.l.google.com:19302', + 'stun:stun3.l.google.com:19302', + 'stun:stun4.l.google.com:19302' + ], + }, + ] as RTCIceServer[]; + }; + /** * Sends event ping to stats service * */ diff --git a/frontend/app/player/web/assist/Call.ts b/frontend/app/player/web/assist/Call.ts index f5116c089..972649814 100644 --- a/frontend/app/player/web/assist/Call.ts +++ b/frontend/app/player/web/assist/Call.ts @@ -43,7 +43,7 @@ export default class Call { constructor( private store: Store }>, private socket: Socket, - private config: RTCIceServer[] | null, + private config: RTCIceServer[], private peerID: string, private getAssistVersion: () => number, private agent: Record, @@ -146,7 +146,7 @@ export default class Call { // create pc with ice config const pc = new RTCPeerConnection({ - iceServers: [{ urls: 'stun:stun.l.google.com:19302' }], + iceServers: this.config, }); // If there is a local stream, add its tracks to the connection diff --git a/frontend/package.json b/frontend/package.json index 4aa2bb5a7..e1913ca8c 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -27,6 +27,7 @@ "@codewonders/html2canvas": "^1.0.2", "@eslint/js": "^9.21.0", "@medv/finder": "^4.0.2", + "@neodrag/react": "^2.3.0", "@sentry/browser": "^5.21.1", "@svg-maps/world": "^1.0.1", "@tanstack/react-query": "^5.56.2", @@ -71,7 +72,6 @@ "react-dnd": "^16.0.1", "react-dnd-html5-backend": "^15.1.2", "react-dom": "^19.0.0", - "react-draggable": "^4.4.5", "react-google-recaptcha": "^2.1.0", "react-i18next": "^15.4.1", "react-intersection-observer": "^9.13.1", diff --git a/frontend/yarn.lock b/frontend/yarn.lock index e5f6ae357..87f42b897 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -2584,6 +2584,13 @@ __metadata: languageName: node linkType: hard +"@neodrag/react@npm:^2.3.0": + version: 2.3.0 + resolution: "@neodrag/react@npm:2.3.0" + checksum: 10c1/37f549ad0bdab8badb0799bf4e6f1714fe52a2ace6c09447a9dc97a9483a0fb40f75b35b121c78a1cba3a27ec9076a5db9672454af3a216d9efee8dcd34c6736 + languageName: node + linkType: hard + "@nicolo-ribaudo/chokidar-2@npm:2.1.8-no-fsevents.3": version: 2.1.8-no-fsevents.3 resolution: "@nicolo-ribaudo/chokidar-2@npm:2.1.8-no-fsevents.3" @@ -5541,13 +5548,6 @@ __metadata: languageName: node linkType: hard -"clsx@npm:^1.1.1": - version: 1.2.1 - resolution: "clsx@npm:1.2.1" - checksum: 10c1/45d7148b63e9ec9c32bd31f8289f1c52f1ca6c3a392a0d60978c8590faa71f4a9a3acef0a71eb3492a672a3cebc6019230799bfc59ec2e96b5f32eb58fe0976f - languageName: node - linkType: hard - "clsx@npm:^2.0.0, clsx@npm:^2.1.0": version: 2.1.1 resolution: "clsx@npm:2.1.1" @@ -11947,6 +11947,7 @@ __metadata: "@eslint/js": "npm:^9.21.0" "@jest/globals": "npm:^29.7.0" "@medv/finder": "npm:^4.0.2" + "@neodrag/react": "npm:^2.3.0" "@openreplay/sourcemap-uploader": "npm:^3.0.10" "@sentry/browser": "npm:^5.21.1" "@svg-maps/world": "npm:^1.0.1" @@ -12034,7 +12035,6 @@ __metadata: react-dnd: "npm:^16.0.1" react-dnd-html5-backend: "npm:^15.1.2" react-dom: "npm:^19.0.0" - react-draggable: "npm:^4.4.5" react-google-recaptcha: "npm:^2.1.0" react-i18next: "npm:^15.4.1" react-intersection-observer: "npm:^9.13.1" @@ -14004,19 +14004,6 @@ __metadata: languageName: node linkType: hard -"react-draggable@npm:^4.4.5": - version: 4.4.6 - resolution: "react-draggable@npm:4.4.6" - dependencies: - clsx: "npm:^1.1.1" - prop-types: "npm:^15.8.1" - peerDependencies: - react: ">= 16.3.0" - react-dom: ">= 16.3.0" - checksum: 10c1/b8ae807f4556b658ae149b6542af5222d75996da47c549db54be22276579549ca2cd2fd06ca5c0852fbd1b663853cc0568b68215bd6e62433b46a7e154ddf8e2 - languageName: node - linkType: hard - "react-fit@npm:^2.0.0": version: 2.0.1 resolution: "react-fit@npm:2.0.1" diff --git a/tracker/tracker-assist/.yarn/install-state.gz b/tracker/tracker-assist/.yarn/install-state.gz index 63810d379..e7a21cc42 100644 Binary files a/tracker/tracker-assist/.yarn/install-state.gz and b/tracker/tracker-assist/.yarn/install-state.gz differ diff --git a/tracker/tracker-assist/src/Assist.ts b/tracker/tracker-assist/src/Assist.ts index c06d7ab76..bb7ab448f 100644 --- a/tracker/tracker-assist/src/Assist.ts +++ b/tracker/tracker-assist/src/Assist.ts @@ -20,6 +20,7 @@ import { gzip } from 'fflate' type StartEndCallback = (agentInfo?: Record) => ((() => any) | void) interface AgentInfo { + config: string; email: string; id: number name: string @@ -85,6 +86,7 @@ export default class Assist { private remoteControl: RemoteControl | null = null; private peerReconnectTimeout: ReturnType | null = null private agents: Record = {} + private config: RTCIceServer[] | undefined private readonly options: Options private readonly canvasMap: Map = new Map() @@ -254,7 +256,7 @@ export default class Assist { return } if (args[0] !== 'webrtc_call_ice_candidate') { - app.debug.log('Socket:', ...args) + app.debug.log("Socket:", ...args); }; socket.on('close', (e) => { app.debug.warn('Socket closed:', e); @@ -356,6 +358,9 @@ export default class Assist { this.app.stop() this.app.clearBuffers() this.app.waitStatus(0) + .then(() => { + this.config = JSON.parse(info.config); + }) .then(() => { this.app.allowAppStart() setTimeout(() => { @@ -595,7 +600,7 @@ export default class Assist { // create a new RTCPeerConnection with ice server config const pc = new RTCPeerConnection({ - iceServers: [{ urls: "stun:stun.l.google.com:19302" }], + iceServers: this.config, }); if (!callUI) { @@ -736,7 +741,7 @@ export default class Assist { if (!this.canvasPeers[uniqueId]) { this.canvasPeers[uniqueId] = new RTCPeerConnection({ - iceServers: [{ urls: "stun:stun.l.google.com:19302" }], + iceServers: this.config, }); this.setupPeerListeners(uniqueId); @@ -750,7 +755,6 @@ export default class Assist { // Send offer via signaling server socket.emit('webrtc_canvas_offer', { offer, id: uniqueId }); - } } }