Files
Toju/toju-app/src/app/infrastructure/mobile/services/mobile-app-lifecycle.service.ts
Myx 6b9a39fe4a fix: Bug - Android app view is below titlebar and action bar on android
Respect Android system bar insets with safe-area shell padding, inset-aware modal and bottom-sheet layouts, transparent edge-to-edge themes, and a Capacitor SystemBars refresh on mobile startup.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-11 21:24:48 +02:00

56 lines
2.0 KiB
TypeScript

import { Injectable, inject } from '@angular/core';
import { resolveMobileAdapter } from '../logic/mobile-capacitor-adapter.rules';
import { syncMobileSafeAreaInsets } from '../logic/mobile-safe-area.rules';
import type { MobileAppLifecycleAdapter } from '../contracts/mobile.contracts';
import { WebMobileAppLifecycleAdapter } from '../adapters/web/web-mobile-app-lifecycle.adapter';
import { MobilePlatformService } from './mobile-platform.service';
import { MobileRuntimePermissionsService } from './mobile-runtime-permissions.service';
/** Facade for foreground/background lifecycle events. */
@Injectable({ providedIn: 'root' })
export class MobileAppLifecycleService {
private readonly mobilePlatform = inject(MobilePlatformService);
private readonly runtimePermissions = inject(MobileRuntimePermissionsService);
private adapter: MobileAppLifecycleAdapter = new WebMobileAppLifecycleAdapter();
private adapterReady: Promise<MobileAppLifecycleAdapter> | null = null;
private initialized = false;
async initialize(): Promise<void> {
if (this.initialized) {
return;
}
const adapter = await this.ensureAdapter();
await adapter.initialize();
this.mobilePlatform.refreshRuntimeDetection();
await syncMobileSafeAreaInsets();
await this.runtimePermissions.initialize();
this.initialized = true;
}
onAppStateChange(handler: (isActive: boolean) => void): void {
this.adapter.onAppStateChange(handler);
}
private ensureAdapter(): Promise<MobileAppLifecycleAdapter> {
if (!this.adapterReady) {
this.adapterReady = resolveMobileAdapter(
this.mobilePlatform.runtime(),
this.adapter,
async () => {
const { CapacitorMobileAppLifecycleAdapter } = await import('../adapters/capacitor/capacitor-mobile-app-lifecycle.adapter');
return new CapacitorMobileAppLifecycleAdapter();
}
).then((adapter) => {
this.adapter = adapter;
return adapter;
});
}
return this.adapterReady;
}
}