import { Injectable, inject } from '@angular/core'; import type { CallNotificationActionIntent } from '../logic/call-notification.rules'; import { buildIncomingCallNotification, buildInCallNotification } from '../logic/call-notification.rules'; import { resolveMobileAdapter } from '../logic/mobile-capacitor-adapter.rules'; import type { MobileNotificationAdapter } from '../contracts/mobile.contracts'; import { WebMobileNotificationsAdapter } from '../adapters/web/web-mobile-notifications.adapter'; import { MobilePlatformService } from './mobile-platform.service'; import { MobilePushRegistrationService } from './mobile-push-registration.service'; /** Facade for push/local notifications with platform-specific adapters. */ @Injectable({ providedIn: 'root' }) export class MobileNotificationsService { private readonly mobilePlatform = inject(MobilePlatformService); private readonly pushRegistration = inject(MobilePushRegistrationService); private adapter: MobileNotificationAdapter = new WebMobileNotificationsAdapter(); private adapterReady: Promise | null = null; private callActionHandler: ((input: { callId: string; intent: CallNotificationActionIntent }) => void) | null = null; private initialized = false; async initialize(): Promise { if (this.initialized) { return; } const adapter = await this.ensureAdapter(); await adapter.initialize(); this.pushRegistration.initialize(); this.initialized = true; } async showIncomingCall(displayName: string, callId: string): Promise { await this.initialize(); const adapter = await this.ensureAdapter(); await adapter.showCallNotification(buildIncomingCallNotification(displayName, callId)); } async showActiveCall(input: { callId: string; displayName: string; isMuted: boolean }): Promise { await this.initialize(); const adapter = await this.ensureAdapter(); await adapter.showCallNotification(buildInCallNotification(input)); } async dismissIncomingCall(callId: string): Promise { const adapter = await this.ensureAdapter(); await adapter.dismissCallNotification(callId, 'incoming'); } async dismissActiveCall(callId: string): Promise { const adapter = await this.ensureAdapter(); await adapter.dismissCallNotification(callId, 'active'); } onCallAction(handler: (input: { callId: string; intent: CallNotificationActionIntent }) => void): void { this.callActionHandler = handler; this.adapter.onActionSelected(handler); } private ensureAdapter(): Promise { if (!this.adapterReady) { this.adapterReady = resolveMobileAdapter( this.mobilePlatform.runtime(), this.adapter, async () => { const { CapacitorMobileNotificationsAdapter } = await import('../adapters/capacitor/capacitor-mobile-notifications.adapter'); return new CapacitorMobileNotificationsAdapter(); } ).then((adapter) => { this.adapter = adapter; if (this.callActionHandler) { this.adapter.onActionSelected(this.callActionHandler); } return adapter; }); } return this.adapterReady; } }