diff --git a/apps/matrix/apps/web/src/lib/components/call/CallView.svelte b/apps/matrix/apps/web/src/lib/components/call/CallView.svelte
index c23e14ab9..c1247ea10 100644
--- a/apps/matrix/apps/web/src/lib/components/call/CallView.svelte
+++ b/apps/matrix/apps/web/src/lib/components/call/CallView.svelte
@@ -6,6 +6,7 @@
MicrophoneSlash,
VideoCamera,
VideoCameraSlash,
+ Screencast,
User,
} from '@manacore/shared-icons';
import { onDestroy } from 'svelte';
@@ -66,6 +67,10 @@
matrixStore.toggleCameraMute();
}
+ async function handleScreenShare() {
+ await matrixStore.toggleScreenShare();
+ }
+
function handleHangup() {
matrixStore.hangupCall();
onHangup?.();
@@ -108,8 +113,14 @@
{/if}
{call.opponentName || 'Unbekannt'}
-
- {call.type === 'video' ? 'Videoanruf' : 'Sprachanruf'} ยท {getStateText(call.state)}
+
+ {call.type === 'video' ? 'Videoanruf' : 'Sprachanruf'} ยท {getStateText(call.state)}
+ {#if call.isScreenSharing}
+
+
+ Bildschirmfreigabe
+
+ {/if}
@@ -189,6 +200,16 @@
{/if}
+
+
+
{/if}
diff --git a/apps/matrix/apps/web/src/lib/components/chat/Message.svelte b/apps/matrix/apps/web/src/lib/components/chat/Message.svelte
index 312cdc44c..e83b59b38 100644
--- a/apps/matrix/apps/web/src/lib/components/chat/Message.svelte
+++ b/apps/matrix/apps/web/src/lib/components/chat/Message.svelte
@@ -48,9 +48,22 @@
let imageLoading = $state(true);
let imageError = $state(false);
- // Quick reaction emojis
+ // Quick reaction emojis (always visible)
const quickEmojis = ['๐', 'โค๏ธ', '๐', '๐ฎ', '๐ข', '๐'];
+ // Extended emoji categories for full picker
+ const emojiCategories = [
+ { name: 'Hรคufig', emojis: ['๐', '๐', 'โค๏ธ', '๐', '๐ฎ', '๐ข', '๐', '๐ฅ', '๐ฏ', 'โจ'] },
+ { name: 'Smileys', emojis: ['๐', '๐', '๐', '๐', '๐', '๐ฅน', '๐
', '๐คฃ', '๐', '๐', '๐', '๐', '๐', '๐', '๐ฅฐ', '๐'] },
+ { name: 'Gesten', emojis: ['๐', '๐', '๐', '๐ค', '๐', 'โ๏ธ', '๐ค', '๐ค', '๐ค', '๐', '๐ค', '๐', '๐ช', '๐'] },
+ { name: 'Symbole', emojis: ['โ
', 'โ', 'โญ', '๐ซ', '๐', '๐ก', '๐ฏ', '๐', '๐', '๐', '๐', '๐', '๐', '๐ฌ'] },
+ { name: 'Tiere', emojis: ['๐ฑ', '๐ถ', '๐ป', '๐ฆ', '๐ผ', '๐จ', '๐ฆ', '๐ธ', '๐ต', '๐ฆ', '๐', '๐ฆ'] },
+ { name: 'Essen', emojis: ['๐', '๐', '๐', '๐ฎ', '๐', '๐ฃ', '๐ฆ', '๐ฉ', '๐ช', 'โ', '๐บ', '๐ท'] },
+ ];
+
+ let showFullPicker = $state(false);
+ let selectedCategory = $state(0);
+
async function handleReaction(emoji: string) {
showEmojiPicker = false;
await matrixStore.reactToMessage(message.id, emoji);
@@ -539,23 +552,67 @@
- {#each quickEmojis as emoji}
-
- {/each}
+ {#if showFullPicker}
+
+
+
+
+ {#each emojiCategories as category, i}
+
+ {/each}
+
+
+
+ {#each emojiCategories[selectedCategory].emojis as emoji}
+
+ {/each}
+
+
+ {:else}
+
+
+ {#each quickEmojis as emoji}
+
+ {/each}
+
+
+
+ {/if}
{/if}
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 d97ff5e83..f25714f9d 100644
--- a/apps/matrix/apps/web/src/lib/components/chat/RoomHeader.svelte
+++ b/apps/matrix/apps/web/src/lib/components/chat/RoomHeader.svelte
@@ -45,6 +45,23 @@
});
}
});
+
+ // Presence for DMs
+ let isOnline = $derived(room?.isDirect && room?.presence === 'online');
+
+ // Format last active time
+ let presenceText = $derived(() => {
+ if (!room?.isDirect) return '';
+ if (room.presence === 'online') return 'Online';
+ if (!room.lastActiveAgo) return 'Offline';
+ const minutes = Math.floor(room.lastActiveAgo / 60000);
+ if (minutes < 1) return 'Gerade aktiv';
+ if (minutes < 60) return `Vor ${minutes} Min. aktiv`;
+ const hours = Math.floor(minutes / 60);
+ if (hours < 24) return `Vor ${hours} Std. aktiv`;
+ const days = Math.floor(hours / 24);
+ return `Vor ${days} Tag${days > 1 ? 'en' : ''} aktiv`;
+ });
{#if room}
@@ -59,15 +76,25 @@
-
-
- {#if room.avatar}
-

- {:else}
-
{room.name.charAt(0).toUpperCase()}
+
+
+
+ {#if room.avatar}
+

+ {:else}
+
{room.name.charAt(0).toUpperCase()}
+ {/if}
+
+
+ {#if room.isDirect}
+
{/if}
@@ -94,11 +121,19 @@
{/if}
-
+
{#if room.topic}
{room.topic}
{:else if room.isDirect}
- Direktnachricht
+
+ {#if isOnline}
+
+ Online
+ {:else}
+
+ {presenceText() || 'Offline'}
+ {/if}
+
{:else}
{room.memberCount} Mitglieder
diff --git a/apps/matrix/apps/web/src/lib/matrix/store.svelte.ts b/apps/matrix/apps/web/src/lib/matrix/store.svelte.ts
index b88561639..150795d6c 100644
--- a/apps/matrix/apps/web/src/lib/matrix/store.svelte.ts
+++ b/apps/matrix/apps/web/src/lib/matrix/store.svelte.ts
@@ -1485,6 +1485,39 @@ class MatrixStore {
}
}
+ /**
+ * Toggle screen sharing
+ */
+ async toggleScreenShare(): Promise {
+ if (!this._matrixCall || !this._activeCall) return false;
+
+ try {
+ const isSharing = this._activeCall.isScreenSharing;
+
+ if (isSharing) {
+ // Stop screen sharing - switch back to camera
+ await this._matrixCall.setScreensharingEnabled(false);
+ this._activeCall = { ...this._activeCall, isScreenSharing: false };
+ } else {
+ // Start screen sharing
+ const success = await this._matrixCall.setScreensharingEnabled(true, {
+ audio: true, // Include system audio if available
+ });
+ if (success) {
+ this._activeCall = { ...this._activeCall, isScreenSharing: true };
+ } else {
+ console.warn('Screen sharing was denied or failed');
+ return false;
+ }
+ }
+ return true;
+ } catch (err) {
+ console.error('Error toggling screen share:', err);
+ this._error = 'Bildschirmfreigabe fehlgeschlagen';
+ return false;
+ }
+ }
+
/**
* Set up call event handlers
*/