Fix private calls

This commit is contained in:
2026-05-17 15:14:52 +02:00
parent 0f6cb3ee77
commit e769a6ee4a
71 changed files with 5821 additions and 349 deletions

View File

@@ -14,7 +14,7 @@ import { FormsModule } from '@angular/forms';
import { Store } from '@ngrx/store';
import { NavigationEnd, Router } from '@angular/router';
import { NgIcon, provideIcons } from '@ng-icons/core';
import { lucidePlus } from '@ng-icons/lucide';
import { lucidePhone, lucidePlus } from '@ng-icons/lucide';
import {
EMPTY,
Subject,
@@ -35,6 +35,7 @@ import { selectCurrentUser, selectOnlineUsers } from '../../../store/users/users
import { RoomsActions } from '../../../store/rooms/rooms.actions';
import { DatabaseService } from '../../../infrastructure/persistence';
import { NotificationsFacade } from '../../../domains/notifications';
import { DirectCallService, DirectCallSession } from '../../../domains/direct-call';
import { type ServerInfo, ServerDirectoryFacade } from '../../../domains/server-directory';
import { ThemeNodeDirective } from '../../../domains/theme';
import { hasRoomBanForUser } from '../../../domains/access-control';
@@ -57,7 +58,7 @@ import {
ThemeNodeDirective,
UserBarComponent
],
viewProviders: [provideIcons({ lucidePlus })],
viewProviders: [provideIcons({ lucidePhone, lucidePlus })],
templateUrl: './servers-rail.component.html'
})
export class ServersRailComponent {
@@ -66,6 +67,7 @@ export class ServersRailComponent {
private voiceSession = inject(VoiceSessionFacade);
private db = inject(DatabaseService);
private notifications = inject(NotificationsFacade);
readonly directCalls = inject(DirectCallService);
private serverDirectory = inject(ServerDirectoryFacade);
private destroyRef = inject(DestroyRef);
private banLookupRequestVersion = 0;
@@ -92,10 +94,44 @@ export class ServersRailComponent {
isOnDirectMessage = toSignal(
this.router.events.pipe(
filter((navigationEvent): navigationEvent is NavigationEnd => navigationEvent instanceof NavigationEnd),
map((navigationEvent) => navigationEvent.urlAfterRedirects.startsWith('/dm/'))
map((navigationEvent) => navigationEvent.urlAfterRedirects.startsWith('/dm/') || navigationEvent.urlAfterRedirects.startsWith('/pm/'))
),
{ initialValue: this.router.url.startsWith('/dm/') }
{ initialValue: this.router.url.startsWith('/dm/') || this.router.url.startsWith('/pm/') }
);
isOnCall = toSignal(
this.router.events.pipe(
filter((navigationEvent): navigationEvent is NavigationEnd => navigationEvent instanceof NavigationEnd),
map((navigationEvent) => navigationEvent.urlAfterRedirects.startsWith('/call/'))
),
{ initialValue: this.router.url.startsWith('/call/') }
);
currentCallId = toSignal(
this.router.events.pipe(
filter((navigationEvent): navigationEvent is NavigationEnd => navigationEvent instanceof NavigationEnd),
map((navigationEvent) => this.callIdFromUrl(navigationEvent.urlAfterRedirects))
),
{ initialValue: this.callIdFromUrl(this.router.url) }
);
selectedCallIndex = computed(() => {
const routeCallId = this.currentCallId();
const visibleCalls = this.directCalls.visibleActiveSessions();
if (routeCallId) {
const routeMatchIndex = visibleCalls.findIndex((call) => call.callId === routeCallId || call.conversationId === routeCallId);
if (routeMatchIndex >= 0) {
return routeMatchIndex;
}
}
const currentSession = this.directCalls.currentSession();
if (!currentSession) {
return -1;
}
return visibleCalls.findIndex((call) => call.callId === currentSession.callId);
});
bannedServerName = signal('');
showBannedDialog = signal(false);
showPasswordDialog = signal(false);
@@ -203,6 +239,26 @@ export class ServersRailComponent {
this.savedRoomJoinRequests.next({ room });
}
openCall(callId: string): void {
void this.router.navigate(['/call', callId]);
}
isSelectedCall(callIndex: number): boolean {
return this.selectedCallIndex() === callIndex;
}
callAvatarUrls(call: DirectCallSession): string[] {
if (call.participantIds.length <= 2) {
return [];
}
return Object.values(call.participants)
.filter((participant) => participant.joined)
.map((participant) => this.directCalls.userForParticipant(participant.userId)?.avatarUrl || participant.profile.avatarUrl)
.filter((avatarUrl): avatarUrl is string => !!avatarUrl)
.slice(0, 3);
}
closeBannedDialog(): void {
this.showBannedDialog.set(false);
this.bannedServerName.set('');
@@ -229,6 +285,13 @@ export class ServersRailComponent {
return !!this.bannedRoomLookup()[room.id];
}
private callIdFromUrl(url: string): string | null {
const path = url.split(/[?#]/, 1)[0];
const match = path.match(/^\/call\/([^/]+)/);
return match?.[1] ? decodeURIComponent(match[1]) : null;
}
openContextMenu(evt: MouseEvent, room: Room): void {
evt.preventDefault();
this.contextRoom.set(room);
@@ -311,7 +374,7 @@ export class ServersRailComponent {
}
isSelectedRoom(room: Room): boolean {
if (this.isOnDirectMessage()) {
if (this.isOnDirectMessage() || this.isOnCall()) {
return false;
}