fix: restore build and stabilize E2E cross-signal behavior

Revert the automated member-ordering pass that broke Angular field init
(TS2729) and disable that rule until a safe reorder strategy exists.
Fix modal/confirm dialog i18n defaults via template fallbacks, search all
active endpoints (including offline), register foreign rooms with actor
owner IDs, sync profile display names from avatar summaries, and guard
dm-chat when a private call converts to a group conversation.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-11 12:16:40 +02:00
parent 79c6f91cd6
commit 31962aeb1a
131 changed files with 2483 additions and 3896 deletions

View File

@@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/member-ordering, @typescript-eslint/no-unused-vars */
import {
Component,
inject,
@@ -50,32 +51,51 @@ import { APP_TRANSLATE_IMPORTS, AppI18nService } from '../../../../core/i18n';
export class ScreenShareViewerComponent implements OnDestroy {
@ViewChild('screenVideo') videoRef!: ElementRef<HTMLVideoElement>;
private readonly screenShareService = inject(ScreenShareFacade);
private readonly voicePlayback = inject(VoicePlaybackService);
private readonly store = inject(Store);
private readonly appI18n = inject(AppI18nService);
private remoteStreamSub: Subscription | null = null;
onlineUsers = this.store.selectSignal(selectOnlineUsers);
activeScreenSharer = signal<User | null>(null);
isFullscreen = signal(false);
hasStream = signal(false);
isLocalShare = signal(false);
screenVolume = signal(DEFAULT_VOLUME);
private readonly screenShareService = inject(ScreenShareFacade);
private readonly voicePlayback = inject(VoicePlaybackService);
private readonly store = inject(Store);
private readonly appI18n = inject(AppI18nService);
private remoteStreamSub: Subscription | null = null;
// Track the userId we're currently watching (for detecting when they stop sharing)
private watchingUserId = signal<string | null>(null);
isFullscreen = signal(false);
hasStream = signal(false);
isLocalShare = signal(false);
screenVolume = signal(DEFAULT_VOLUME);
private streamSubscription: (() => void) | null = null;
private viewerFocusHandler = (evt: CustomEvent<{ userId: string }>) => {
try {
const userId = evt.detail?.userId;
if (!userId)
return;
const stream = this.screenShareService.getRemoteScreenShareStream(userId);
const user = this.onlineUsers().find((onlineUser) => onlineUser.id === userId || onlineUser.oderId === userId) || null;
if (stream && stream.getVideoTracks().length > 0) {
if (user) {
this.setRemoteStream(stream, user);
} else if (this.videoRef) {
this.videoRef.nativeElement.srcObject = stream;
this.videoRef.nativeElement.volume = 0;
this.videoRef.nativeElement.muted = true;
this.hasStream.set(true);
this.activeScreenSharer.set(null);
this.watchingUserId.set(userId);
this.screenVolume.set(this.voicePlayback.getUserVolume(userId));
this.isLocalShare.set(false);
}
}
} catch (_error) {
// Failed to focus viewer on user stream
}
};
constructor() {
// React to screen share stream changes
@@ -272,34 +292,4 @@ export class ScreenShareViewerComponent implements OnDestroy {
}
}
}
private viewerFocusHandler = (evt: CustomEvent<{ userId: string }>) => {
try {
const userId = evt.detail?.userId;
if (!userId)
return;
const stream = this.screenShareService.getRemoteScreenShareStream(userId);
const user = this.onlineUsers().find((onlineUser) => onlineUser.id === userId || onlineUser.oderId === userId) || null;
if (stream && stream.getVideoTracks().length > 0) {
if (user) {
this.setRemoteStream(stream, user);
} else if (this.videoRef) {
this.videoRef.nativeElement.srcObject = stream;
this.videoRef.nativeElement.volume = 0;
this.videoRef.nativeElement.muted = true;
this.hasStream.set(true);
this.activeScreenSharer.set(null);
this.watchingUserId.set(userId);
this.screenVolume.set(this.voicePlayback.getUserVolume(userId));
this.isLocalShare.set(false);
}
}
} catch {
// Failed to focus viewer on user stream
}
};
}