From 17f521a13f140f499ed784d2ed078e4b468f5b01 Mon Sep 17 00:00:00 2001 From: Flemmli97 <34157027+Flemmli97@users.noreply.github.com> Date: Fri, 25 Oct 2024 18:42:02 +0200 Subject: [PATCH 1/3] feat(calling): join/leave sound (#762) --- src/lib/media/Voice.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/lib/media/Voice.ts b/src/lib/media/Voice.ts index af3b7a3a9..404c06907 100644 --- a/src/lib/media/Voice.ts +++ b/src/lib/media/Voice.ts @@ -1,3 +1,4 @@ +import { playSound, Sounds } from "$lib/components/utils/SoundHandler" import { CallDirection } from "$lib/enums" import { Store } from "$lib/state/Store" import { create_cancellable_handler, type Cancellable } from "$lib/utils/CancellablePromise" @@ -194,6 +195,7 @@ export class CallRoom { let stream = await VoiceRTCInstance.getLocalStream() log.debug(`Sending local stream ${stream} to ${peer}`) room.addStream(stream, peer) + playSound(Sounds.Joined) if (!this.start) { this.start = new Date() } @@ -205,6 +207,7 @@ export class CallRoom { VoiceRTCInstance.remoteVideoCreator.delete(participant[0]) delete this.participants[participant[0]] } + playSound(Sounds.Disconnect) if (this.empty) { VoiceRTCInstance.leaveCall(true) } From 2a9b66238335e38b87a788df423f9e9eeee4cfcf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucas=20Gon=C3=A7alves=20Marchi?= Date: Fri, 25 Oct 2024 16:33:01 -0300 Subject: [PATCH 2/3] fix(User): Show all users even if they are not friends (#746) Co-authored-by: Sara Tavares <29093946+stavares843@users.noreply.github.com> Co-authored-by: Phill Wisniewski <93608357+phillsatellite@users.noreply.github.com> --- src/lib/components/calling/CallScreen.svelte | 64 +++++++++---------- .../components/messaging/Conversation.svelte | 4 +- src/lib/wasm/MultipassStore.ts | 27 +++++++- 3 files changed, 61 insertions(+), 34 deletions(-) diff --git a/src/lib/components/calling/CallScreen.svelte b/src/lib/components/calling/CallScreen.svelte index 068198fcd..b130eb5c4 100644 --- a/src/lib/components/calling/CallScreen.svelte +++ b/src/lib/components/calling/CallScreen.svelte @@ -16,23 +16,47 @@ import { callInProgress, callTimeout, TIME_TO_SHOW_CONNECTING, TIME_TO_SHOW_END_CALL_FEEDBACK, timeCallStarted, usersAcceptedTheCall, usersDeniedTheCall, VoiceRTCInstance } from "$lib/media/Voice" import { log } from "$lib/utils/Logger" import { playSound, SoundHandler, Sounds } from "../utils/SoundHandler" + import { MultipassStoreInstance } from "$lib/wasm/MultipassStore" export let expanded: boolean = false - function toggleExanded() { - expanded = !expanded - } + export let deafened: boolean = get(Store.state.devices.deafened) + export let chat: Chat let showVolumeMixer = false let showCallSettings = false - let muted: boolean = !VoiceRTCInstance.callOptions.audio.enabled let cameraEnabled: boolean = get(Store.state.devices.cameraEnabled) + let isFullScreen = false + let localVideoCurrentSrc: HTMLVideoElement - export let deafened: boolean = get(Store.state.devices.deafened) - export let chat: Chat + let showAnimation = true + let message = $_("settings.calling.connecting") + let timeout: NodeJS.Timeout | undefined + let callSound: SoundHandler | undefined = undefined + + $: if ($usersAcceptedTheCall.length > 0) { + callSound?.stop() + callSound = undefined + } + $: userCache = Store.getUsersLookup(chat.users) + $: userCallOptions = VoiceRTCInstance.callOptions + $: remoteStreams = Store.state.activeCallMeta + $: ownUserName = get(Store.state.user).name + + $: if ($usersDeniedTheCall.length === chat.users.length - 1) { + setTimeout(() => { + Store.endCall() + VoiceRTCInstance.leaveCall() + dispatch("endCall") + }, TIME_TO_SHOW_END_CALL_FEEDBACK) + } let dispatch = createEventDispatcher() + function toggleExanded() { + expanded = !expanded + } + function toggleFullscreen() { const elem = document.getElementById("call-screen") @@ -50,13 +74,6 @@ userCallOptions = userCallOptions } - let isFullScreen = false - - $: userCache = Store.getUsersLookup(chat.users) - $: userCallOptions = VoiceRTCInstance.callOptions - $: remoteStreams = Store.state.activeCallMeta - $: ownUserName = get(Store.state.user).name - let subscribeOne = Store.state.devices.muted.subscribe(state => { muted = state userCallOptions = VoiceRTCInstance.callOptions @@ -78,8 +95,6 @@ userCallOptions = VoiceRTCInstance.callOptions }) - let localVideoCurrentSrc: HTMLVideoElement - function handleClickOutside(event: MouseEvent) { const callSettingsElement = document.getElementById("call-settings") const showVolumeElement = document.getElementById("volume-mixer") @@ -118,20 +133,8 @@ } } - $: if ($usersDeniedTheCall.length === chat.users.length - 1) { - setTimeout(() => { - Store.endCall() - VoiceRTCInstance.leaveCall() - dispatch("endCall") - }, TIME_TO_SHOW_END_CALL_FEEDBACK) - } - - let showAnimation = true let noResponseVisible = false - let message = $_("settings.calling.connecting") - let timeout: NodeJS.Timeout | undefined let hideNoResponseUsersTimeout: NodeJS.Timeout | undefined - let callSound: SoundHandler | undefined = undefined function hideNoResponseUsersAfterAPeriodOfTime() { hideNoResponseUsersTimeout = setTimeout(() => { @@ -139,12 +142,9 @@ }, 10000) } - $: if ($usersAcceptedTheCall.length > 0) { - callSound?.stop() - callSound = undefined - } - onMount(async () => { + await MultipassStoreInstance.listUsersForACall(chat.users) + userCache = Store.getUsersLookup(chat.users) usersDeniedTheCall.set([]) callTimeout.set(false) usersAcceptedTheCall.set([]) diff --git a/src/lib/components/messaging/Conversation.svelte b/src/lib/components/messaging/Conversation.svelte index a8f7b993d..ac8b32130 100644 --- a/src/lib/components/messaging/Conversation.svelte +++ b/src/lib/components/messaging/Conversation.svelte @@ -96,7 +96,9 @@ } onDestroy(() => { - if (scrollContainer.scrollHeight <= scrollContainer.clientHeight) markAsRead($chat.id) + if (scrollContainer && scrollContainer.scrollHeight) { + if (scrollContainer?.scrollHeight <= scrollContainer?.clientHeight) markAsRead($chat.id) + } }) diff --git a/src/lib/wasm/MultipassStore.ts b/src/lib/wasm/MultipassStore.ts index f1d5ff927..2ac4d19c0 100644 --- a/src/lib/wasm/MultipassStore.ts +++ b/src/lib/wasm/MultipassStore.ts @@ -391,6 +391,31 @@ class MultipassStore { } } + /** + * Lists users for a call. + * Update users cache if they are not already in cache. + * It avoids problem if there is some user in call that is not current user's friend. + */ + async listUsersForACall(callUsers: Array) { + const multipass = get(this.multipassWritable) + + if (multipass) { + try { + let usersInCall: Array = [] + for (let i = 0; i < callUsers.length; i++) { + let userInCall = await this.identity_from_did(callUsers[i]) + if (userInCall) { + usersInCall.push(userInCall.key) + // Add users in cache + Store.updateUser(userInCall) + } + } + } catch (error) { + log.error("Error getting users in a call: " + error) + } + } + } + /** * Removes a friend. * @param did - The DID of the friend to be removed. @@ -611,7 +636,7 @@ class MultipassStore { overlay: "", }, status: status, - status_message: identity === undefined ? "" : (identity.status_message ?? ""), + status_message: identity === undefined ? "" : identity.status_message ?? "", }, integrations: identity === undefined ? new Map() : identity.metadata, media: { From 6cba6c9093fccc30141d65bcbb542e471e19463a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucas=20Gon=C3=A7alves=20Marchi?= Date: Fri, 25 Oct 2024 17:29:59 -0300 Subject: [PATCH 3/3] fix(calling): Stop outgoing call sound when all users denied the call (#767) Co-authored-by: Phill Wisniewski <93608357+phillsatellite@users.noreply.github.com> --- src/lib/components/calling/CallScreen.svelte | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/lib/components/calling/CallScreen.svelte b/src/lib/components/calling/CallScreen.svelte index b130eb5c4..30ca3a63f 100644 --- a/src/lib/components/calling/CallScreen.svelte +++ b/src/lib/components/calling/CallScreen.svelte @@ -74,6 +74,11 @@ userCallOptions = userCallOptions } + $: if ($usersDeniedTheCall.length === chat.users.length - 1 && chat.users.length > 1) { + callSound?.stop() + callSound = undefined + } + let subscribeOne = Store.state.devices.muted.subscribe(state => { muted = state userCallOptions = VoiceRTCInstance.callOptions