diff --git a/apps/multiplatform/common/src/commonMain/resources/assets/www/call.js b/apps/multiplatform/common/src/commonMain/resources/assets/www/call.js
index 8fe29a734e..9a2a52a657 100644
--- a/apps/multiplatform/common/src/commonMain/resources/assets/www/call.js
+++ b/apps/multiplatform/common/src/commonMain/resources/assets/www/call.js
@@ -35,6 +35,9 @@ var TransformOperation;
TransformOperation["Encrypt"] = "encrypt";
TransformOperation["Decrypt"] = "decrypt";
})(TransformOperation || (TransformOperation = {}));
+function localMedia(call) {
+ return call.localMediaSources.camera || call.localMediaSources.screen ? CallMediaType.Video : CallMediaType.Audio;
+}
let activeCall;
let answerTimeout = 30000;
var useWorker = false;
@@ -143,7 +146,11 @@ const processCommand = (function () {
const call = {
connection: pc,
iceCandidates,
- localMedia: mediaType,
+ localMediaSources: {
+ mic: true,
+ camera: mediaType == CallMediaType.Video && !isDesktop,
+ screen: false,
+ },
localCamera,
localStream,
remoteStream,
@@ -153,8 +160,6 @@ const processCommand = (function () {
screen: false,
},
aesKey,
- screenShareEnabled: false,
- cameraEnabled: !isDesktop,
};
await setupMediaStreams(call);
let connectionTimeout = setTimeout(connectionHandler, answerTimeout);
@@ -339,7 +344,7 @@ const processCommand = (function () {
if (!activeCall) {
resp = { type: "error", message: "media: call not started" };
}
- else if (activeCall.localMedia == CallMediaType.Audio && command.media == CallMediaType.Video && command.enable) {
+ else if (localMedia(activeCall) == CallMediaType.Audio && command.media == CallMediaType.Video && command.enable) {
await startSendingVideo(activeCall, activeCall.localCamera);
resp = { type: "ok" };
}
@@ -566,8 +571,7 @@ const processCommand = (function () {
//pc.addTrack(t, call.localStream)
console.log("LALAL ADDED VIDEO TRACK " + t);
}
- call.localMedia = CallMediaType.Video;
- call.cameraEnabled = true;
+ call.localMediaSources.camera = true;
}
catch (e) {
return;
@@ -590,15 +594,17 @@ const processCommand = (function () {
const audioWasEnabled = oldAudioTracks.some((elem) => elem.enabled);
let localStream;
try {
- localStream = call.screenShareEnabled ? await getLocalScreenCaptureStream() : await getLocalMediaStream(call.localMedia, camera);
+ localStream = call.localMediaSources.screen
+ ? await getLocalScreenCaptureStream()
+ : await getLocalMediaStream(localMedia(call), camera);
}
catch (e) {
- if (call.screenShareEnabled) {
- call.screenShareEnabled = false;
+ if (call.localMediaSources.screen) {
+ call.localMediaSources.screen = false;
}
return;
}
- if (!call.screenShareEnabled) {
+ if (!call.localMediaSources.screen) {
for (const t of call.localStream.getTracks())
t.stop();
}
@@ -620,7 +626,7 @@ const processCommand = (function () {
if (!audioWasEnabled && oldAudioTracks.length > 0) {
audioTracks.forEach((elem) => (elem.enabled = false));
}
- if (!call.cameraEnabled && !call.screenShareEnabled) {
+ if (!call.localMediaSources.camera && !call.localMediaSources.screen) {
videoTracks.forEach((elem) => (elem.enabled = false));
}
replaceTracks(pc, audioTracks);
@@ -793,14 +799,14 @@ const processCommand = (function () {
for (const t of tracks)
t.enabled = enable;
if (media == CallMediaType.Video && activeCall) {
- activeCall.cameraEnabled = enable;
+ activeCall.localMediaSources.camera = enable;
}
}
toggleScreenShare = async function () {
const call = activeCall;
if (!call)
return;
- call.screenShareEnabled = !call.screenShareEnabled;
+ call.localMediaSources.screen = !call.localMediaSources.screen;
await replaceMedia(call, call.localCamera);
};
return processCommand;
@@ -817,7 +823,7 @@ function toggleMedia(s, media) {
res = t.enabled;
}
if (media == CallMediaType.Video && activeCall) {
- activeCall.cameraEnabled = res;
+ activeCall.localMediaSources.camera = res;
}
return res;
}
diff --git a/apps/multiplatform/common/src/commonMain/resources/assets/www/desktop/ui.js b/apps/multiplatform/common/src/commonMain/resources/assets/www/desktop/ui.js
index f448d99373..d5b1838172 100644
--- a/apps/multiplatform/common/src/commonMain/resources/assets/www/desktop/ui.js
+++ b/apps/multiplatform/common/src/commonMain/resources/assets/www/desktop/ui.js
@@ -29,7 +29,7 @@ function endCallManually() {
sendMessageToNative({ resp: { type: "end" } });
}
function toggleAudioManually() {
- if (activeCall === null || activeCall === void 0 ? void 0 : activeCall.localMedia) {
+ if (activeCall && localMedia(activeCall)) {
document.getElementById("toggle-audio").innerHTML = toggleMedia(activeCall.localStream, CallMediaType.Audio)
? '
'
: '
';
@@ -43,27 +43,29 @@ function toggleSpeakerManually() {
}
}
function toggleVideoManually() {
- if (activeCall === null || activeCall === void 0 ? void 0 : activeCall.localMedia) {
- if (activeCall === null || activeCall === void 0 ? void 0 : activeCall.screenShareEnabled) {
- activeCall.cameraEnabled = !activeCall.cameraEnabled;
- enableVideoIcon(activeCall.cameraEnabled);
+ if (activeCall) {
+ if (activeCall.localMediaSources.screen) {
+ activeCall.localMediaSources.camera = !activeCall.localMediaSources.camera;
+ enableVideoIcon(activeCall.localMediaSources.camera);
// } else if (activeCall.localMedia == CallMediaType.Video) {
// enableVideoIcon(toggleMedia(activeCall.localStream, CallMediaType.Video))
}
else {
- const apiCall = { command: { type: "media", media: CallMediaType.Video, enable: activeCall.cameraEnabled != true } };
+ const apiCall = { command: { type: "media", media: CallMediaType.Video, enable: activeCall.localMediaSources.camera != true } };
reactOnMessageFromServer(apiCall);
processCommand(apiCall).then(() => {
- enableVideoIcon((activeCall === null || activeCall === void 0 ? void 0 : activeCall.cameraEnabled) == true);
+ var _a;
+ enableVideoIcon(((_a = activeCall === null || activeCall === void 0 ? void 0 : activeCall.localMediaSources) === null || _a === void 0 ? void 0 : _a.camera) == true);
});
}
}
}
async function toggleScreenManually() {
- const was = activeCall === null || activeCall === void 0 ? void 0 : activeCall.screenShareEnabled;
+ var _a;
+ const was = activeCall === null || activeCall === void 0 ? void 0 : activeCall.localMediaSources.screen;
await toggleScreenShare();
- if (was != (activeCall === null || activeCall === void 0 ? void 0 : activeCall.screenShareEnabled)) {
- document.getElementById("toggle-screen").innerHTML = (activeCall === null || activeCall === void 0 ? void 0 : activeCall.screenShareEnabled)
+ if (was != (activeCall === null || activeCall === void 0 ? void 0 : activeCall.localMediaSources.screen)) {
+ document.getElementById("toggle-screen").innerHTML = ((_a = activeCall === null || activeCall === void 0 ? void 0 : activeCall.localMediaSources) === null || _a === void 0 ? void 0 : _a.screen)
? '
'
: '
';
}
@@ -108,9 +110,11 @@ function reactOnMessageFromServer(msg) {
}
function reactOnMessageToServer(msg) {
var _a;
+ if (!activeCall)
+ return;
switch ((_a = msg.resp) === null || _a === void 0 ? void 0 : _a.type) {
case "peerMedia":
- const className = (activeCall === null || activeCall === void 0 ? void 0 : activeCall.localMedia) == CallMediaType.Video || (activeCall === null || activeCall === void 0 ? void 0 : activeCall.peerMediaSources.camera) || (activeCall === null || activeCall === void 0 ? void 0 : activeCall.peerMediaSources.screen)
+ const className = localMedia(activeCall) == CallMediaType.Video || activeCall.peerMediaSources.camera || activeCall.peerMediaSources.screen
? "video"
: "audio";
document.getElementById("info-block").className = className;
diff --git a/packages/simplex-chat-webrtc/src/call.ts b/packages/simplex-chat-webrtc/src/call.ts
index ad6bfbdd2e..5c899c92b0 100644
--- a/packages/simplex-chat-webrtc/src/call.ts
+++ b/packages/simplex-chat-webrtc/src/call.ts
@@ -234,18 +234,20 @@ interface WVAPICall {
interface Call {
connection: RTCPeerConnection
iceCandidates: Promise // JSON strings for RTCIceCandidate
- localMedia: CallMediaType
+ localMediaSources: CallMediaSources
localCamera: VideoCamera
localStream: MediaStream
remoteStream: MediaStream
peerMediaSources: CallMediaSources
- screenShareEnabled: boolean
- cameraEnabled: boolean
aesKey?: string
worker?: Worker
key?: CryptoKey
}
+function localMedia(call: Call): CallMediaType {
+ return call.localMediaSources.camera || call.localMediaSources.screen ? CallMediaType.Video : CallMediaType.Audio
+}
+
let activeCall: Call | undefined
let answerTimeout = 30_000
var useWorker = false
@@ -379,7 +381,11 @@ const processCommand = (function () {
const call: Call = {
connection: pc,
iceCandidates,
- localMedia: mediaType,
+ localMediaSources: {
+ mic: true,
+ camera: mediaType == CallMediaType.Video && !isDesktop,
+ screen: false,
+ },
localCamera,
localStream,
remoteStream,
@@ -389,8 +395,6 @@ const processCommand = (function () {
screen: false,
},
aesKey,
- screenShareEnabled: false,
- cameraEnabled: !isDesktop,
}
await setupMediaStreams(call)
let connectionTimeout: number | undefined = setTimeout(connectionHandler, answerTimeout)
@@ -571,7 +575,7 @@ const processCommand = (function () {
case "media":
if (!activeCall) {
resp = {type: "error", message: "media: call not started"}
- } else if (activeCall.localMedia == CallMediaType.Audio && command.media == CallMediaType.Video && command.enable) {
+ } else if (localMedia(activeCall) == CallMediaType.Audio && command.media == CallMediaType.Video && command.enable) {
await startSendingVideo(activeCall, activeCall.localCamera)
resp = {type: "ok"}
} else {
@@ -813,8 +817,7 @@ const processCommand = (function () {
//pc.addTrack(t, call.localStream)
console.log("LALAL ADDED VIDEO TRACK " + t)
}
- call.localMedia = CallMediaType.Video
- call.cameraEnabled = true
+ call.localMediaSources.camera = true
} catch (e: any) {
return
}
@@ -846,14 +849,16 @@ const processCommand = (function () {
const audioWasEnabled = oldAudioTracks.some((elem) => elem.enabled)
let localStream: MediaStream
try {
- localStream = call.screenShareEnabled ? await getLocalScreenCaptureStream() : await getLocalMediaStream(call.localMedia, camera)
+ localStream = call.localMediaSources.screen
+ ? await getLocalScreenCaptureStream()
+ : await getLocalMediaStream(localMedia(call), camera)
} catch (e: any) {
- if (call.screenShareEnabled) {
- call.screenShareEnabled = false
+ if (call.localMediaSources.screen) {
+ call.localMediaSources.screen = false
}
return
}
- if (!call.screenShareEnabled) {
+ if (!call.localMediaSources.screen) {
for (const t of call.localStream.getTracks()) t.stop()
} else {
// Don't stop audio track if switching to screenshare
@@ -872,7 +877,7 @@ const processCommand = (function () {
if (!audioWasEnabled && oldAudioTracks.length > 0) {
audioTracks.forEach((elem) => (elem.enabled = false))
}
- if (!call.cameraEnabled && !call.screenShareEnabled) {
+ if (!call.localMediaSources.camera && !call.localMediaSources.screen) {
videoTracks.forEach((elem) => (elem.enabled = false))
}
@@ -1063,14 +1068,14 @@ const processCommand = (function () {
const tracks = media == CallMediaType.Video ? s.getVideoTracks() : s.getAudioTracks()
for (const t of tracks) t.enabled = enable
if (media == CallMediaType.Video && activeCall) {
- activeCall.cameraEnabled = enable
+ activeCall.localMediaSources.camera = enable
}
}
toggleScreenShare = async function () {
const call = activeCall
if (!call) return
- call.screenShareEnabled = !call.screenShareEnabled
+ call.localMediaSources.screen = !call.localMediaSources.screen
await replaceMedia(call, call.localCamera)
}
@@ -1090,7 +1095,7 @@ function toggleMedia(s: MediaStream, media: CallMediaType): boolean {
res = t.enabled
}
if (media == CallMediaType.Video && activeCall) {
- activeCall.cameraEnabled = res
+ activeCall.localMediaSources.camera = res
}
return res
}
diff --git a/packages/simplex-chat-webrtc/src/desktop/ui.ts b/packages/simplex-chat-webrtc/src/desktop/ui.ts
index deb50ff808..9602a034c4 100644
--- a/packages/simplex-chat-webrtc/src/desktop/ui.ts
+++ b/packages/simplex-chat-webrtc/src/desktop/ui.ts
@@ -34,7 +34,7 @@ function endCallManually() {
}
function toggleAudioManually() {
- if (activeCall?.localMedia) {
+ if (activeCall && localMedia(activeCall)) {
document.getElementById("toggle-audio")!!.innerHTML = toggleMedia(activeCall.localStream, CallMediaType.Audio)
? '
'
: '
'
@@ -50,27 +50,27 @@ function toggleSpeakerManually() {
}
function toggleVideoManually() {
- if (activeCall?.localMedia) {
- if (activeCall?.screenShareEnabled) {
- activeCall.cameraEnabled = !activeCall.cameraEnabled
- enableVideoIcon(activeCall.cameraEnabled)
+ if (activeCall) {
+ if (activeCall.localMediaSources.screen) {
+ activeCall.localMediaSources.camera = !activeCall.localMediaSources.camera
+ enableVideoIcon(activeCall.localMediaSources.camera)
// } else if (activeCall.localMedia == CallMediaType.Video) {
// enableVideoIcon(toggleMedia(activeCall.localStream, CallMediaType.Video))
} else {
- const apiCall: WVAPICall = {command: {type: "media", media: CallMediaType.Video, enable: activeCall.cameraEnabled != true}}
+ const apiCall: WVAPICall = {command: {type: "media", media: CallMediaType.Video, enable: activeCall.localMediaSources.camera != true}}
reactOnMessageFromServer(apiCall as any)
processCommand(apiCall).then(() => {
- enableVideoIcon(activeCall?.cameraEnabled == true)
+ enableVideoIcon(activeCall?.localMediaSources?.camera == true)
})
}
}
}
async function toggleScreenManually() {
- const was = activeCall?.screenShareEnabled
+ const was = activeCall?.localMediaSources.screen
await toggleScreenShare()
- if (was != activeCall?.screenShareEnabled) {
- document.getElementById("toggle-screen")!!.innerHTML = activeCall?.screenShareEnabled
+ if (was != activeCall?.localMediaSources.screen) {
+ document.getElementById("toggle-screen")!!.innerHTML = activeCall?.localMediaSources?.screen
? '
'
: '
'
}
@@ -117,10 +117,12 @@ function reactOnMessageFromServer(msg: WVApiMessage) {
}
function reactOnMessageToServer(msg: WVApiMessage) {
+ if (!activeCall) return
+
switch (msg.resp?.type) {
case "peerMedia":
const className =
- activeCall?.localMedia == CallMediaType.Video || activeCall?.peerMediaSources.camera || activeCall?.peerMediaSources.screen
+ localMedia(activeCall) == CallMediaType.Video || activeCall.peerMediaSources.camera || activeCall.peerMediaSources.screen
? "video"
: "audio"
document.getElementById("info-block")!!.className = className