Dhurgh commited on
Commit
8c6f70f
Β·
1 Parent(s): 443832f

Fix calls fully: remove bad default TURN, conditional relay fallback, mobile control bindings (v2.8.3)

Browse files
Files changed (4) hide show
  1. client.js +57 -2
  2. index.html +6 -6
  3. package.json +1 -1
  4. server.js +1 -20
client.js CHANGED
@@ -100,6 +100,13 @@ function getDefaultIceServers() {
100
  ];
101
  }
102
 
 
 
 
 
 
 
 
103
  async function ensureRtcConfigLoaded() {
104
  if (rtcConfigLoaded) return;
105
  rtcConfigLoaded = true;
@@ -343,6 +350,50 @@ function ensureRemoteMediaPlayback(videoEl) {
343
  setTimeout(tryPlay, 900);
344
  }
345
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
346
 
347
 
348
  function toggleAuthMode() {
@@ -5718,6 +5769,7 @@ function showToastClickable(message, type = 'success', chatContext = null) {
5718
  window.addEventListener('DOMContentLoaded', () => {
5719
  loadTheme();
5720
  applySettingsToUI();
 
5721
  pinnedChats = JSON.parse(localStorage.getItem('pinnedChats') || '[]');
5722
  joinedCommunities = JSON.parse(localStorage.getItem('joinedCommunities') || '[]');
5723
  joinedGroups = JSON.parse(localStorage.getItem('joinedGroups') || '[]');
@@ -6206,6 +6258,7 @@ function createPeerConnection(peerId) {
6206
  const runtimeIceServers = Array.isArray(rtcRuntimeConfig?.iceServers) && rtcRuntimeConfig.iceServers.length
6207
  ? rtcRuntimeConfig.iceServers
6208
  : getDefaultIceServers();
 
6209
  activeIceServers = runtimeIceServers;
6210
 
6211
  peerConnection = new RTCPeerConnection({
@@ -6400,13 +6453,15 @@ function createPeerConnection(peerId) {
6400
  callIceFailureCount += 1;
6401
 
6402
  try {
6403
- if (callIceFailureCount >= 2 && !forceRelayOnly) {
6404
  forceRelayOnly = true;
6405
  peerConnection.setConfiguration({
6406
  iceServers: activeIceServers,
6407
  iceTransportPolicy: 'relay'
6408
  });
6409
  showToast('Switching call to relay mode for network compatibility...', 'warning');
 
 
6410
  }
6411
 
6412
  peerConnection.restartIce?.();
@@ -6478,7 +6533,7 @@ async function startCallSession(peerName, peerId, isCaller) {
6478
  const localVideo = document.getElementById('localCallVideo');
6479
  if (localVideo && localCallStream) {
6480
  localVideo.srcObject = localCallStream;
6481
- localVideo.play().catch(() => {});
6482
  } else if (localVideo) {
6483
  localVideo.srcObject = null;
6484
  }
 
100
  ];
101
  }
102
 
103
+ function hasTurnServerConfigured(iceServers = []) {
104
+ return iceServers.some((server) => {
105
+ const urls = Array.isArray(server?.urls) ? server.urls : [server?.urls];
106
+ return urls.some((url) => typeof url === 'string' && /^turns?:/i.test(url));
107
+ });
108
+ }
109
+
110
  async function ensureRtcConfigLoaded() {
111
  if (rtcConfigLoaded) return;
112
  rtcConfigLoaded = true;
 
350
  setTimeout(tryPlay, 900);
351
  }
352
 
353
+ function ensureLocalPreviewPlayback(videoEl) {
354
+ if (!videoEl || !videoEl.srcObject) return;
355
+
356
+ videoEl.muted = true;
357
+ videoEl.autoplay = true;
358
+ videoEl.playsInline = true;
359
+
360
+ const tryPlay = () => {
361
+ videoEl.play().catch(() => {});
362
+ };
363
+
364
+ tryPlay();
365
+ setTimeout(tryPlay, 120);
366
+ setTimeout(tryPlay, 500);
367
+ }
368
+
369
+ let callControlBindingsDone = false;
370
+ function bindCallControlButtons() {
371
+ if (callControlBindingsDone) return;
372
+
373
+ const bindings = [
374
+ ['muteBtn', toggleLocalMute],
375
+ ['cameraBtn', toggleCallCamera],
376
+ ['endCallBtn', endVideoCall],
377
+ ['callDebugBtn', toggleCallDebug]
378
+ ];
379
+
380
+ bindings.forEach(([id, action]) => {
381
+ const button = document.getElementById(id);
382
+ if (!button) return;
383
+
384
+ const handlePress = (event) => {
385
+ event.preventDefault();
386
+ action();
387
+ };
388
+
389
+ button.addEventListener('click', handlePress);
390
+ button.addEventListener('touchend', handlePress, { passive: false });
391
+ button.style.pointerEvents = 'auto';
392
+ });
393
+
394
+ callControlBindingsDone = true;
395
+ }
396
+
397
 
398
 
399
  function toggleAuthMode() {
 
5769
  window.addEventListener('DOMContentLoaded', () => {
5770
  loadTheme();
5771
  applySettingsToUI();
5772
+ bindCallControlButtons();
5773
  pinnedChats = JSON.parse(localStorage.getItem('pinnedChats') || '[]');
5774
  joinedCommunities = JSON.parse(localStorage.getItem('joinedCommunities') || '[]');
5775
  joinedGroups = JSON.parse(localStorage.getItem('joinedGroups') || '[]');
 
6258
  const runtimeIceServers = Array.isArray(rtcRuntimeConfig?.iceServers) && rtcRuntimeConfig.iceServers.length
6259
  ? rtcRuntimeConfig.iceServers
6260
  : getDefaultIceServers();
6261
+ const hasTurnServersConfigured = hasTurnServerConfigured(runtimeIceServers);
6262
  activeIceServers = runtimeIceServers;
6263
 
6264
  peerConnection = new RTCPeerConnection({
 
6453
  callIceFailureCount += 1;
6454
 
6455
  try {
6456
+ if (callIceFailureCount >= 2 && !forceRelayOnly && hasTurnServersConfigured) {
6457
  forceRelayOnly = true;
6458
  peerConnection.setConfiguration({
6459
  iceServers: activeIceServers,
6460
  iceTransportPolicy: 'relay'
6461
  });
6462
  showToast('Switching call to relay mode for network compatibility...', 'warning');
6463
+ } else if (callIceFailureCount >= 2 && !hasTurnServersConfigured) {
6464
+ showToast('Retrying call without relay fallback...', 'warning');
6465
  }
6466
 
6467
  peerConnection.restartIce?.();
 
6533
  const localVideo = document.getElementById('localCallVideo');
6534
  if (localVideo && localCallStream) {
6535
  localVideo.srcObject = localCallStream;
6536
+ ensureLocalPreviewPlayback(localVideo);
6537
  } else if (localVideo) {
6538
  localVideo.srcObject = null;
6539
  }
index.html CHANGED
@@ -3098,7 +3098,7 @@
3098
  <div class="chat-header-title" id="chatTitle">πŸ’¬ Select a friend to chat</div>
3099
  </div>
3100
  <div class="chat-header-actions">
3101
- <span class="build-badge mobile-essential" id="buildVersionBadge" title="Frontend build version">v2.8.2</span>
3102
  <button class="header-btn mobile-essential" onclick="toggleArchiveChat()" title="Archive chat">
3103
  <i class="fas fa-archive"></i>
3104
  </button>
@@ -3688,15 +3688,15 @@
3688
  <div id="callOverlayPeerName" style="color:#fff; font-size:18px; font-weight:700;"></div>
3689
  <div id="callTimerLabel" style="color:rgba(255,255,255,0.7); font-size:13px; margin-top:4px;">00:00:00</div>
3690
  </div>
3691
- <button onclick="toggleCallDebug()" style="background:rgba(255,255,255,0.18); border:none; color:white; padding:7px 13px; border-radius:8px; cursor:pointer; font-size:12px; font-weight:600;">πŸ”§ Debug</button>
3692
  </div>
3693
 
3694
  <div id="callDebugPanel"></div>
3695
 
3696
  <div class="call-overlay-controls">
3697
- <button id="muteBtn" class="call-ctrl-btn" onclick="toggleLocalMute()" title="Mute/Unmute">🎀</button>
3698
- <button id="cameraBtn" class="call-ctrl-btn" onclick="toggleCallCamera()" title="Camera on/off">πŸ“·</button>
3699
- <button class="call-end-btn" onclick="endVideoCall()" title="End Call">πŸ“΅</button>
3700
  </div>
3701
  </div>
3702
  </div>
@@ -3717,7 +3717,7 @@
3717
 
3718
  <script src="/socket.io/socket.io.js"></script>
3719
  <script src="https://cdnjs.cloudflare.com/ajax/libs/qrcodejs/1.0.0/qrcode.min.js"></script>
3720
- <script src="client.js?v=2.8.2"></script>
3721
  </body>
3722
  </html>
3723
 
 
3098
  <div class="chat-header-title" id="chatTitle">πŸ’¬ Select a friend to chat</div>
3099
  </div>
3100
  <div class="chat-header-actions">
3101
+ <span class="build-badge mobile-essential" id="buildVersionBadge" title="Frontend build version">v2.8.3</span>
3102
  <button class="header-btn mobile-essential" onclick="toggleArchiveChat()" title="Archive chat">
3103
  <i class="fas fa-archive"></i>
3104
  </button>
 
3688
  <div id="callOverlayPeerName" style="color:#fff; font-size:18px; font-weight:700;"></div>
3689
  <div id="callTimerLabel" style="color:rgba(255,255,255,0.7); font-size:13px; margin-top:4px;">00:00:00</div>
3690
  </div>
3691
+ <button id="callDebugBtn" style="background:rgba(255,255,255,0.18); border:none; color:white; padding:7px 13px; border-radius:8px; cursor:pointer; font-size:12px; font-weight:600;">πŸ”§ Debug</button>
3692
  </div>
3693
 
3694
  <div id="callDebugPanel"></div>
3695
 
3696
  <div class="call-overlay-controls">
3697
+ <button id="muteBtn" class="call-ctrl-btn" title="Mute/Unmute">🎀</button>
3698
+ <button id="cameraBtn" class="call-ctrl-btn" title="Camera on/off">πŸ“·</button>
3699
+ <button id="endCallBtn" class="call-end-btn" title="End Call">πŸ“΅</button>
3700
  </div>
3701
  </div>
3702
  </div>
 
3717
 
3718
  <script src="/socket.io/socket.io.js"></script>
3719
  <script src="https://cdnjs.cloudflare.com/ajax/libs/qrcodejs/1.0.0/qrcode.min.js"></script>
3720
+ <script src="client.js?v=2.8.3"></script>
3721
  </body>
3722
  </html>
3723
 
package.json CHANGED
@@ -1,6 +1,6 @@
1
  {
2
  "name": "discord-like-app",
3
- "version": "2.8.2",
4
  "main": "server.js",
5
  "scripts": {
6
  "dev": "nodemon server.js",
 
1
  {
2
  "name": "discord-like-app",
3
+ "version": "2.8.3",
4
  "main": "server.js",
5
  "scripts": {
6
  "dev": "nodemon server.js",
server.js CHANGED
@@ -73,26 +73,7 @@ app.get('/api/rtc-config', (req, res) => {
73
  { urls: 'stun:stun2.l.google.com:19302' },
74
  { urls: 'stun:stun3.l.google.com:19302' },
75
  { urls: 'stun:stun4.l.google.com:19302' },
76
- { urls: 'stun:stun.cloudflare.com:3478' },
77
- {
78
- urls: [
79
- 'turn:a.relay.metered.ca:80',
80
- 'turn:a.relay.metered.ca:80?transport=tcp',
81
- 'turn:a.relay.metered.ca:443',
82
- 'turns:a.relay.metered.ca:443?transport=tcp'
83
- ],
84
- username: 'openrelayproject',
85
- credential: 'openrelayproject'
86
- },
87
- {
88
- urls: [
89
- 'turn:openrelay.metered.ca:80',
90
- 'turn:openrelay.metered.ca:443',
91
- 'turn:openrelay.metered.ca:443?transport=tcp'
92
- ],
93
- username: 'openrelayproject',
94
- credential: 'openrelayproject'
95
- }
96
  ];
97
 
98
  const turnUrlsRaw = process.env.TURN_URLS || '';
 
73
  { urls: 'stun:stun2.l.google.com:19302' },
74
  { urls: 'stun:stun3.l.google.com:19302' },
75
  { urls: 'stun:stun4.l.google.com:19302' },
76
+ { urls: 'stun:stun.cloudflare.com:3478' }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77
  ];
78
 
79
  const turnUrlsRaw = process.env.TURN_URLS || '';