chore: enforce lint across codebase and ban "maybe" in identifiers

Remove member-ordering and complexity eslint-disable comments by reordering
class members and applying targeted fixes. Add metoyou/no-maybe-in-naming,
type-safe WebRTC e2e harness helpers, and resolve remaining lint errors so
npm run lint exits cleanly.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-11 11:08:26 +02:00
parent b630bacdc6
commit 79c6f91cd6
138 changed files with 4286 additions and 2310 deletions

View File

@@ -1,4 +1,3 @@
/* eslint-disable @typescript-eslint/member-ordering */
import {
Injectable,
computed,
@@ -37,31 +36,13 @@ import { toDirectMessageParticipant } from '../../../direct-message';
@Injectable({ providedIn: 'root' })
export class DirectCallService {
private readonly router = inject(Router);
private readonly store = inject(Store);
private readonly delivery = inject(PeerDeliveryService);
private readonly directMessages = inject(DirectMessageService);
private readonly audio = inject(NotificationAudioService);
private readonly voice = inject(VoiceConnectionFacade);
private readonly voiceSession = inject(VoiceSessionFacade);
private readonly realtime = inject(RealtimeSessionFacade);
private readonly voiceActivity = inject(VoiceActivityService);
private readonly playback = inject(VoicePlaybackService);
private readonly viewport = inject(ViewportService);
private readonly mobileNotifications = inject(MobileNotificationsService);
private readonly mobileCallSession = inject(MobileCallSessionService);
private readonly mobileMedia = inject(MobileMediaService);
private readonly i18n = inject(AppI18nService);
private readonly currentUser = this.store.selectSignal(selectCurrentUser);
private readonly users = this.store.selectSignal(selectAllUsers);
private readonly sessionsSignal = signal<DirectCallSession[]>([]);
private readonly mobileOverlayCallId = signal<string | null>(null);
private readonly pendingIncomingCallPayloads: DirectCallEventPayload[] = [];
private readonly declinedCallIds = new Set<string>();
readonly sessions = computed(() => this.sessionsSignal());
readonly activeSessions = computed(() => this.sessions().filter((session) => session.status !== 'ended'));
readonly visibleActiveSessions = computed(() => this.activeSessions().filter((session) => this.hasOngoingActivity(session)));
readonly incomingCall = computed<DirectCallSession | null>(() => {
if (this.isDoNotDisturb()) {
return null;
@@ -80,8 +61,11 @@ export class DirectCallService {
&& !session.participants[meId]?.joined
&& this.hasConnectedParticipant(session)) ?? null;
});
readonly currentSession = signal<DirectCallSession | null>(null);
readonly hasActiveCall = computed(() => this.visibleActiveSessions().length > 0);
readonly mobileOverlaySession = computed(() => {
const callId = this.mobileOverlayCallId();
@@ -92,6 +76,48 @@ export class DirectCallService {
return this.visibleActiveSessions().find((session) => session.callId === callId) ?? null;
});
private readonly router = inject(Router);
private readonly store = inject(Store);
private readonly delivery = inject(PeerDeliveryService);
private readonly directMessages = inject(DirectMessageService);
private readonly audio = inject(NotificationAudioService);
private readonly voice = inject(VoiceConnectionFacade);
private readonly voiceSession = inject(VoiceSessionFacade);
private readonly realtime = inject(RealtimeSessionFacade);
private readonly voiceActivity = inject(VoiceActivityService);
private readonly playback = inject(VoicePlaybackService);
private readonly viewport = inject(ViewportService);
private readonly mobileNotifications = inject(MobileNotificationsService);
private readonly mobileCallSession = inject(MobileCallSessionService);
private readonly mobileMedia = inject(MobileMediaService);
private readonly i18n = inject(AppI18nService);
private readonly currentUser = this.store.selectSignal(selectCurrentUser);
private readonly users = this.store.selectSignal(selectAllUsers);
private readonly sessionsSignal = signal<DirectCallSession[]>([]);
private readonly mobileOverlayCallId = signal<string | null>(null);
private readonly pendingIncomingCallPayloads: DirectCallEventPayload[] = [];
private readonly declinedCallIds = new Set<string>();
constructor() {
this.mobileCallSession.initialize();
this.mobileCallSession.onCallControlAction((intent, callId) => {
@@ -392,19 +418,6 @@ export class DirectCallService {
}
}
private leaveJoinedSession(session: DirectCallSession, endForEveryone = false): void {
const action = endForEveryone ? 'end' : 'leave';
const nextSession = this.markCurrentUserLeft(session, endForEveryone);
this.audio.stop(AppSound.Call);
this.broadcastCallEvent(action, nextSession);
this.stopLocalMedia(nextSession);
this.upsertSession(nextSession);
this.currentSession.set(null);
void this.mobileCallSession.endActiveCall(session.callId);
}
async inviteUser(callId: string, user: User): Promise<void> {
const session = this.sessionById(callId);
@@ -445,6 +458,19 @@ export class DirectCallService {
return participant ? participantToUser(participant) : null;
}
private leaveJoinedSession(session: DirectCallSession, endForEveryone = false): void {
const action = endForEveryone ? 'end' : 'leave';
const nextSession = this.markCurrentUserLeft(session, endForEveryone);
this.audio.stop(AppSound.Call);
this.broadcastCallEvent(action, nextSession);
this.stopLocalMedia(nextSession);
this.upsertSession(nextSession);
this.currentSession.set(null);
void this.mobileCallSession.endActiveCall(session.callId);
}
private async drainPendingIncomingCallPayloads(): Promise<void> {
if (this.pendingIncomingCallPayloads.length === 0) {
return;
@@ -1041,4 +1067,5 @@ export class DirectCallService {
return user;
}
}

View File

@@ -36,10 +36,13 @@ import { DirectCallSession, participantToUser } from '../../domain/models/direct
})
export class IncomingCallModalComponent {
readonly calls = inject(DirectCallService);
private readonly i18n = inject(AppI18nService);
readonly currentUser = inject(Store).selectSignal(selectCurrentUser);
readonly session = this.calls.incomingCall;
readonly answering = signal(false);
readonly caller = computed(() => {
const session = this.session();
@@ -53,10 +56,13 @@ export class IncomingCallModalComponent {
return (callerId ? this.calls.userForParticipant(callerId) : null)
?? (participant ? participantToUser(participant) : null);
});
readonly callerName = computed(() => this.caller()?.displayName || this.i18n.instant('call.incoming.someone'));
readonly callerCallingLabel = computed(() =>
this.i18n.instant('call.incoming.callerCalling', { name: this.callerName() })
);
readonly callKindLabel = computed(() => {
const participantCount = this.session()?.participantIds.length ?? 0;
@@ -65,6 +71,8 @@ export class IncomingCallModalComponent {
: this.i18n.instant('call.incoming.directCall');
});
private readonly i18n = inject(AppI18nService);
@HostListener('document:keydown.escape')
onEscape(): void {
this.decline();
@@ -115,4 +123,5 @@ export class IncomingCallModalComponent {
private userKey(user: User): string {
return user.oderId || user.id;
}
}