feat: Refactor background sync to dynamically load Capacitor core and register plugin

This commit is contained in:
2026-05-17 16:51:39 +10:00
parent 40dc552c8d
commit c2fc71ddca

View File

@@ -1,6 +1,13 @@
import { Capacitor, registerPlugin, type PluginListenerHandle } from '@capacitor/core'; import type { PluginListenerHandle } from '@capacitor/core';
import type { IPusherRequest, MatrixClient } from 'matrix-js-sdk'; import type { IPusherRequest, MatrixClient } from 'matrix-js-sdk';
const CAPACITOR_CORE_MODULE_ID = '@capacitor/core';
type CapacitorCoreModule = typeof import('@capacitor/core');
const loadCapacitorCore = async (): Promise<CapacitorCoreModule> =>
import(/* @vite-ignore */ CAPACITOR_CORE_MODULE_ID);
type UnifiedPushStatus = { type UnifiedPushStatus = {
running: boolean; running: boolean;
endpoint: string; endpoint: string;
@@ -67,14 +74,15 @@ type StoredPusherState = {
appId: string; appId: string;
}; };
const MatrixBackgroundSync = registerPlugin<MatrixBackgroundSyncPlugin>('MatrixBackgroundSync');
const DEFAULT_UNIFIED_PUSH_GATEWAY = 'https://matrix.gateway.unifiedpush.org/_matrix/push/v1/notify'; const DEFAULT_UNIFIED_PUSH_GATEWAY = 'https://matrix.gateway.unifiedpush.org/_matrix/push/v1/notify';
const PUSHER_APP_ID_BASE = 'com.paarrot.app.android'; const PUSHER_APP_ID_BASE = 'com.paarrot.app.android';
const PUSHER_STORAGE_PREFIX = 'paarrot.unifiedpush'; const PUSHER_STORAGE_PREFIX = 'paarrot.unifiedpush';
/** Returns true when the current platform is Android Capacitor. */ /** Returns true when the current platform is Android Capacitor. */
export const isBackgroundSyncSupported = (): boolean => export const isBackgroundSyncSupported = (): boolean => {
Capacitor.isNativePlatform() && Capacitor.getPlatform() === 'android'; const capacitor = (window as typeof window & { Capacitor?: CapacitorCoreModule['Capacitor'] }).Capacitor;
return Boolean(capacitor?.isNativePlatform?.() && capacitor.getPlatform() === 'android');
};
const getStoredPusherKey = (userId: string | null, deviceId: string | null): string => const getStoredPusherKey = (userId: string | null, deviceId: string | null): string =>
`${PUSHER_STORAGE_PREFIX}:${userId ?? 'unknown'}:${deviceId ?? 'unknown'}`; `${PUSHER_STORAGE_PREFIX}:${userId ?? 'unknown'}:${deviceId ?? 'unknown'}`;
@@ -169,6 +177,9 @@ class AndroidUnifiedPushManager {
/** Start native UnifiedPush registration and synchronize the Matrix pusher. */ /** Start native UnifiedPush registration and synchronize the Matrix pusher. */
async start(mx: MatrixClient): Promise<void> { async start(mx: MatrixClient): Promise<void> {
const { Capacitor, registerPlugin } = await loadCapacitorCore();
const MatrixBackgroundSync = registerPlugin<MatrixBackgroundSyncPlugin>('MatrixBackgroundSync');
console.log('[BackgroundSync] start() called, platform:', Capacitor.getPlatform(), 'isNative:', Capacitor.isNativePlatform()); console.log('[BackgroundSync] start() called, platform:', Capacitor.getPlatform(), 'isNative:', Capacitor.isNativePlatform());
if (!isBackgroundSyncSupported()) { if (!isBackgroundSyncSupported()) {
@@ -216,6 +227,9 @@ class AndroidUnifiedPushManager {
async stop(): Promise<void> { async stop(): Promise<void> {
if (!isBackgroundSyncSupported()) return; if (!isBackgroundSyncSupported()) return;
const { registerPlugin } = await loadCapacitorCore();
const MatrixBackgroundSync = registerPlugin<MatrixBackgroundSyncPlugin>('MatrixBackgroundSync');
const client = this.client; const client = this.client;
if (client) { if (client) {
const deviceId = client.getDeviceId(); const deviceId = client.getDeviceId();
@@ -280,6 +294,8 @@ class AndroidUnifiedPushManager {
/** Re-opens distributor selection once after ACTION_REQUIRED and logs actionable status. */ /** Re-opens distributor selection once after ACTION_REQUIRED and logs actionable status. */
private async tryRequestDistributorSetup(): Promise<void> { private async tryRequestDistributorSetup(): Promise<void> {
try { try {
const { registerPlugin } = await loadCapacitorCore();
const MatrixBackgroundSync = registerPlugin<MatrixBackgroundSyncPlugin>('MatrixBackgroundSync');
const setupResult = await MatrixBackgroundSync.requestDistributorSetup(); const setupResult = await MatrixBackgroundSync.requestDistributorSetup();
console.warn('[BackgroundSync] requestDistributorSetup result:', setupResult); console.warn('[BackgroundSync] requestDistributorSetup result:', setupResult);
const status = await this.safeGetStatus(); const status = await this.safeGetStatus();
@@ -335,6 +351,9 @@ class AndroidUnifiedPushManager {
private async ensureListeners(): Promise<void> { private async ensureListeners(): Promise<void> {
if (this.listenersReady) return; if (this.listenersReady) return;
const { registerPlugin } = await loadCapacitorCore();
const MatrixBackgroundSync = registerPlugin<MatrixBackgroundSyncPlugin>('MatrixBackgroundSync');
this.listenerHandles = [ this.listenerHandles = [
await MatrixBackgroundSync.addListener('unifiedPushNewEndpoint', (event) => { await MatrixBackgroundSync.addListener('unifiedPushNewEndpoint', (event) => {
void this.handleNewEndpoint(event).catch((err) => { void this.handleNewEndpoint(event).catch((err) => {
@@ -363,6 +382,9 @@ class AndroidUnifiedPushManager {
const client = this.client; const client = this.client;
if (!client) return; if (!client) return;
const { registerPlugin } = await loadCapacitorCore();
const MatrixBackgroundSync = registerPlugin<MatrixBackgroundSyncPlugin>('MatrixBackgroundSync');
const status = await this.safeGetStatus(); const status = await this.safeGetStatus();
console.log('[BackgroundSync] Native status before pusher sync:', status); console.log('[BackgroundSync] Native status before pusher sync:', status);
if (status?.registered && status.endpoint) { if (status?.registered && status.endpoint) {
@@ -435,6 +457,8 @@ class AndroidUnifiedPushManager {
/** Read native registration state without failing the caller. */ /** Read native registration state without failing the caller. */
private async safeGetStatus(): Promise<UnifiedPushStatus | undefined> { private async safeGetStatus(): Promise<UnifiedPushStatus | undefined> {
try { try {
const { registerPlugin } = await loadCapacitorCore();
const MatrixBackgroundSync = registerPlugin<MatrixBackgroundSyncPlugin>('MatrixBackgroundSync');
return await MatrixBackgroundSync.getStatus(); return await MatrixBackgroundSync.getStatus();
} catch (err) { } catch (err) {
console.warn('[BackgroundSync] Failed to read UnifiedPush status:', err); console.warn('[BackgroundSync] Failed to read UnifiedPush status:', err);
@@ -458,6 +482,8 @@ export const triggerBackgroundSyncPing = async (reason?: string): Promise<void>
if (!isBackgroundSyncSupported()) return; if (!isBackgroundSyncSupported()) return;
try { try {
const { registerPlugin } = await loadCapacitorCore();
const MatrixBackgroundSync = registerPlugin<MatrixBackgroundSyncPlugin>('MatrixBackgroundSync');
await MatrixBackgroundSync.triggerPing({ reason }); await MatrixBackgroundSync.triggerPing({ reason });
} catch (err) { } catch (err) {
console.warn('[BackgroundSync] triggerPing failed:', err); console.warn('[BackgroundSync] triggerPing failed:', err);
@@ -479,6 +505,8 @@ export const setAppForegroundState = async (foreground: boolean): Promise<void>
if (!isBackgroundSyncSupported()) return; if (!isBackgroundSyncSupported()) return;
try { try {
const { registerPlugin } = await loadCapacitorCore();
const MatrixBackgroundSync = registerPlugin<MatrixBackgroundSyncPlugin>('MatrixBackgroundSync');
await MatrixBackgroundSync.setAppForeground({ foreground }); await MatrixBackgroundSync.setAppForeground({ foreground });
} catch (err) { } catch (err) {
console.warn('[BackgroundSync] setAppForeground failed:', err); console.warn('[BackgroundSync] setAppForeground failed:', err);
@@ -497,6 +525,8 @@ export const requestResetPushRegistration = async (): Promise<{ success: boolean
} }
try { try {
const { registerPlugin } = await loadCapacitorCore();
const MatrixBackgroundSync = registerPlugin<MatrixBackgroundSyncPlugin>('MatrixBackgroundSync');
const result = await MatrixBackgroundSync.requestDistributorSetup(); const result = await MatrixBackgroundSync.requestDistributorSetup();
console.log('[BackgroundSync] requestDistributorSetup completed:', result); console.log('[BackgroundSync] requestDistributorSetup completed:', result);
return result ?? { success: false }; return result ?? { success: false };
@@ -510,6 +540,8 @@ export const requestResetPushRegistration = async (): Promise<{ success: boolean
export const getBackgroundSyncStatus = async (): Promise<UnifiedPushStatus | undefined> => { export const getBackgroundSyncStatus = async (): Promise<UnifiedPushStatus | undefined> => {
if (!isBackgroundSyncSupported()) return undefined; if (!isBackgroundSyncSupported()) return undefined;
try { try {
const { registerPlugin } = await loadCapacitorCore();
const MatrixBackgroundSync = registerPlugin<MatrixBackgroundSyncPlugin>('MatrixBackgroundSync');
return await MatrixBackgroundSync.getStatus(); return await MatrixBackgroundSync.getStatus();
} catch (err) { } catch (err) {
console.warn('[BackgroundSync] getStatus failed:', err); console.warn('[BackgroundSync] getStatus failed:', err);