fix(screenshare): enable button feedback, audio capture fallback and bump version
This commit is contained in:
1 parent
5757156843
commit
7b29cf7d10
2 files changed
+39
-8
No files matched your search
+37
-6
@@ -119,7 +119,7 @@ function leaveVoice(reason) {
|
|||||||
if (S.ws) { try { S.ws.close(); } catch {} S.ws = null; }
|
if (S.ws) { try { S.ws.close(); } catch {} S.ws = null; }
|
||||||
if (S.micStream) { S.micStream.getTracks().forEach((t) => t.stop()); S.micStream = null; }
|
if (S.micStream) { S.micStream.getTracks().forEach((t) => t.stop()); S.micStream = null; }
|
||||||
els.mic.disabled = false;
|
els.mic.disabled = false;
|
||||||
$('#btn-share').disabled = true;
|
// Keep btn-share enabled so clicking it prompts the user to join a channel
|
||||||
updateMicButton();
|
updateMicButton();
|
||||||
document.querySelectorAll('.channel.voice').forEach((c) => c.classList.remove('active'));
|
document.querySelectorAll('.channel.voice').forEach((c) => c.classList.remove('active'));
|
||||||
S.room = null;
|
S.room = null;
|
||||||
@@ -388,21 +388,52 @@ function orientListener() {
|
|||||||
// screen share (local)
|
// screen share (local)
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
async function startScreenShare() {
|
async function startScreenShare() {
|
||||||
if (S.sharing || !S.room) return;
|
if (S.sharing) {
|
||||||
|
stopScreenShare();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!S.room) {
|
||||||
|
toast('Join a voice channel first to share your screen', 'warn');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!navigator.mediaDevices || !navigator.mediaDevices.getDisplayMedia) {
|
||||||
|
toast('Screen sharing is not supported in this browser or context', 'error');
|
||||||
|
return;
|
||||||
|
}
|
||||||
let stream;
|
let stream;
|
||||||
try {
|
try {
|
||||||
|
// Try requesting display media with audio first
|
||||||
stream = await navigator.mediaDevices.getDisplayMedia({
|
stream = await navigator.mediaDevices.getDisplayMedia({
|
||||||
video: { frameRate: 30 }, audio: true,
|
video: { frameRate: 30 }, audio: true,
|
||||||
});
|
});
|
||||||
} catch {
|
} catch (err) {
|
||||||
return; // user cancelled
|
// If user cancelled / denied, don't toast as error unless it's not NotAllowedError/AbortError
|
||||||
|
if (err.name === 'NotAllowedError' || err.name === 'AbortError') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Try fallback without audio constraint if audio failed
|
||||||
|
try {
|
||||||
|
stream = await navigator.mediaDevices.getDisplayMedia({
|
||||||
|
video: { frameRate: 30 },
|
||||||
|
});
|
||||||
|
} catch (fallbackErr) {
|
||||||
|
if (fallbackErr.name === 'NotAllowedError' || fallbackErr.name === 'AbortError') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
console.error('Failed to get display media:', fallbackErr);
|
||||||
|
toast(`Could not share screen: ${fallbackErr.message || fallbackErr}`, 'error');
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
S.screenStream = stream;
|
S.screenStream = stream;
|
||||||
S.sharing = true;
|
S.sharing = true;
|
||||||
send({ type: 'state', state: { muted: S.muted, deafened: S.deafened, sharing: true } });
|
send({ type: 'state', state: { muted: S.muted, deafened: S.deafened, sharing: true } });
|
||||||
|
|
||||||
for (const peer of S.peers.values()) addScreenToPeer(peer);
|
for (const peer of S.peers.values()) addScreenToPeer(peer);
|
||||||
stream.getVideoTracks()[0].addEventListener('ended', () => stopScreenShare());
|
const videoTrack = stream.getVideoTracks()[0];
|
||||||
|
if (videoTrack) {
|
||||||
|
videoTrack.addEventListener('ended', () => stopScreenShare());
|
||||||
|
}
|
||||||
renderScreens();
|
renderScreens();
|
||||||
renderTiles();
|
renderTiles();
|
||||||
$('#btn-share').classList.add('active');
|
$('#btn-share').classList.add('active');
|
||||||
@@ -823,7 +854,7 @@ window.addEventListener('keydown', (ev) => {
|
|||||||
if (ev.target.tagName === 'INPUT' || ev.target.tagName === 'TEXTAREA') return;
|
if (ev.target.tagName === 'INPUT' || ev.target.tagName === 'TEXTAREA') return;
|
||||||
if (ev.key === 'm') toggleMic();
|
if (ev.key === 'm') toggleMic();
|
||||||
if (ev.key === 'd') toggleDeafen();
|
if (ev.key === 'd') toggleDeafen();
|
||||||
if (ev.key === 's' && S.room) $('#btn-share').click();
|
if (ev.key === 's') $('#btn-share').click();
|
||||||
});
|
});
|
||||||
window.addEventListener('beforeunload', () => { try { leaveVoice(); } catch {} });
|
window.addEventListener('beforeunload', () => { try { leaveVoice(); } catch {} });
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -46,7 +46,7 @@
|
|||||||
<div class="user-buttons">
|
<div class="user-buttons">
|
||||||
<button id="btn-mic" class="ctl" title="Toggle mic (M)">🎤</button>
|
<button id="btn-mic" class="ctl" title="Toggle mic (M)">🎤</button>
|
||||||
<button id="btn-deafen" class="ctl" title="Toggle deafen (D)">👀</button>
|
<button id="btn-deafen" class="ctl" title="Toggle deafen (D)">👀</button>
|
||||||
<button id="btn-share" class="ctl" title="Share your screen" disabled>🖥️</button>
|
<button id="btn-share" class="ctl" title="Share your screen (S)">🖥️</button>
|
||||||
<button id="btn-settings" class="ctl" title="Voice & ICE settings">⚙️</button>
|
<button id="btn-settings" class="ctl" title="Voice & ICE settings">⚙️</button>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
@@ -97,6 +97,6 @@
|
|||||||
|
|
||||||
<div id="toasts"></div>
|
<div id="toasts"></div>
|
||||||
|
|
||||||
<script src="app.js?v=6"></script>
|
<script src="app.js?v=7"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
Reference in new issue
Block a user