From c64b4d6ac95d86e55ddfbfb3aabbf59d38c2bff6 Mon Sep 17 00:00:00 2001 From: Till-JS <101404291+Till-JS@users.noreply.github.com> Date: Thu, 29 Jan 2026 21:28:35 +0100 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20feat(matrix-web):=20add=20VoIP/vide?= =?UTF-8?q?o=20call=20support?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add VoIP types: CallState, CallType, CallDirection, SimpleCall, CallCallbacks - Add VoIP state management to Matrix store with place/answer/reject/hangup methods - Add mic/camera mute toggle functionality - Create CallView component for active calls with video streams - Create IncomingCallDialog component for incoming call notifications - Enable call buttons in RoomHeader (DMs only) - Integrate call components into chat page --- .../src/lib/components/call/CallView.svelte | 203 +++++++++++ .../components/call/IncomingCallDialog.svelte | 123 +++++++ .../apps/web/src/lib/components/call/index.ts | 2 + .../src/lib/components/chat/RoomHeader.svelte | 27 +- .../apps/web/src/lib/matrix/store.svelte.ts | 336 +++++++++++++++++- apps/matrix/apps/web/src/lib/matrix/types.ts | 59 +++ .../web/src/routes/(app)/chat/+page.svelte | 42 +++ 7 files changed, 782 insertions(+), 10 deletions(-) create mode 100644 apps/matrix/apps/web/src/lib/components/call/CallView.svelte create mode 100644 apps/matrix/apps/web/src/lib/components/call/IncomingCallDialog.svelte create mode 100644 apps/matrix/apps/web/src/lib/components/call/index.ts diff --git a/apps/matrix/apps/web/src/lib/components/call/CallView.svelte b/apps/matrix/apps/web/src/lib/components/call/CallView.svelte new file mode 100644 index 000000000..c23e14ab9 --- /dev/null +++ b/apps/matrix/apps/web/src/lib/components/call/CallView.svelte @@ -0,0 +1,203 @@ + + +
+ +
+
+ {#if call.opponentAvatar} + {call.opponentName} + {:else} +
+ +
+ {/if} +
+

{call.opponentName || 'Unbekannt'}

+

+ {call.type === 'video' ? 'Videoanruf' : 'Sprachanruf'} · {getStateText(call.state)} +

+
+
+
+ + +
+ {#if call.type === 'video'} + + + + + +
+ +
+ {:else} + +
+ {#if call.opponentAvatar} + {call.opponentName} + {:else} +
+ +
+ {/if} +

{call.opponentName || 'Unbekannt'}

+

{getStateText(call.state)}

+
+ {/if} +
+ + +
+ + + + + {#if call.type === 'video'} + + {/if} + + + +
+
diff --git a/apps/matrix/apps/web/src/lib/components/call/IncomingCallDialog.svelte b/apps/matrix/apps/web/src/lib/components/call/IncomingCallDialog.svelte new file mode 100644 index 000000000..ac21425c4 --- /dev/null +++ b/apps/matrix/apps/web/src/lib/components/call/IncomingCallDialog.svelte @@ -0,0 +1,123 @@ + + +
+
+ +
+ {#if call.opponentAvatar} + {call.opponentName} + {:else} +
+ +
+ {/if} +

{call.opponentName || 'Unbekannt'}

+

+ {call.type === 'video' ? 'Eingehender Videoanruf' : 'Eingehender Sprachanruf'} +

+
+ + +
+ {#if call.type === 'video'} + + Video + {:else} + + Audio + {/if} +
+ + +
+ + + + + +
+
+
+ + diff --git a/apps/matrix/apps/web/src/lib/components/call/index.ts b/apps/matrix/apps/web/src/lib/components/call/index.ts new file mode 100644 index 000000000..2245f06a3 --- /dev/null +++ b/apps/matrix/apps/web/src/lib/components/call/index.ts @@ -0,0 +1,2 @@ +export { default as CallView } from './CallView.svelte'; +export { default as IncomingCallDialog } from './IncomingCallDialog.svelte'; diff --git a/apps/matrix/apps/web/src/lib/components/chat/RoomHeader.svelte b/apps/matrix/apps/web/src/lib/components/chat/RoomHeader.svelte index 0176cb838..d97ff5e83 100644 --- a/apps/matrix/apps/web/src/lib/components/chat/RoomHeader.svelte +++ b/apps/matrix/apps/web/src/lib/components/chat/RoomHeader.svelte @@ -16,9 +16,14 @@ onMenuClick?: () => void; onInfoClick?: () => void; onSearchClick?: () => void; + onVoiceCall?: () => void; + onVideoCall?: () => void; } - let { onMenuClick, onInfoClick, onSearchClick }: Props = $props(); + let { onMenuClick, onInfoClick, onSearchClick, onVoiceCall, onVideoCall }: Props = $props(); + + // Check if calls are possible (DMs only for now) + let canCall = $derived(matrixStore.currentSimpleRoom?.isDirect ?? false); let room = $derived(matrixStore.currentSimpleRoom); let cryptoReady = $derived(matrixStore.cryptoReady); @@ -111,18 +116,22 @@