diff --git a/src/main.capacitor.ts b/src/main.capacitor.ts index fa1c6b44..16be9559 100644 --- a/src/main.capacitor.ts +++ b/src/main.capacitor.ts @@ -471,71 +471,6 @@ logger.log("[Capacitor] 🚀 Mounting app"); app.mount("#app"); logger.info(`[Main] ✅ App mounted successfully`); -/** - * Phase 2A: deterministic startup readiness for the SharedImage plugin (iOS). - * - * The native SharedImage plugin is registered asynchronously by AppDelegate - * (with its own retry budget), so a fixed startup delay cannot guarantee the - * plugin is reachable from JS before the first shared-image check. Instead of - * assuming readiness after an arbitrary sleep, we probe the plugin with a - * lightweight, read-only hasSharedImage() call and retry for a short bounded - * period until it responds or the budget is exhausted. - * - * This applies ONLY to the very first startup shared-image check. The - * appStateChange and appUrlOpen paths are intentionally left unchanged. - */ -const STARTUP_PLUGIN_MAX_ATTEMPTS = 10; -const STARTUP_PLUGIN_RETRY_DELAY_MS = 300; - -function sleep(ms: number): Promise { - return new Promise((resolve) => setTimeout(resolve, ms)); -} - -/** - * Wait until the iOS SharedImage native plugin is available. - * - * Probes the plugin with a read-only hasSharedImage() call; a successful - * resolution means the native plugin instance is registered and reachable. - * Retries up to STARTUP_PLUGIN_MAX_ATTEMPTS with STARTUP_PLUGIN_RETRY_DELAY_MS - * between attempts. - * - * @returns true once the plugin responds, false if the retry budget is exhausted - */ -async function waitForSharedImagePluginReady(): Promise { - // TEMPORARY SHARE TARGET DIAGNOSTICS - console.info( - "[ShareTarget] Startup shared-image check waiting for SharedImage plugin", - ); - - for (let attempt = 1; attempt <= STARTUP_PLUGIN_MAX_ATTEMPTS; attempt++) { - try { - // Lightweight, read-only probe. hasSharedImage() does not consume or - // mutate the pending share, so probing is side-effect free. - await SharedImage.hasSharedImage(); - // TEMPORARY SHARE TARGET DIAGNOSTICS - console.info( - `[ShareTarget] SharedImage plugin ready after ${attempt} attempt(s)`, - ); - return true; - } catch (error) { - // Plugin not registered yet; wait and retry within the bounded budget. - logger.debug( - `[Main] SharedImage plugin not ready (attempt ${attempt}/${STARTUP_PLUGIN_MAX_ATTEMPTS}):`, - error instanceof Error ? error.message : String(error), - ); - if (attempt < STARTUP_PLUGIN_MAX_ATTEMPTS) { - await sleep(STARTUP_PLUGIN_RETRY_DELAY_MS); - } - } - } - - // TEMPORARY SHARE TARGET DIAGNOSTICS - console.info( - `[ShareTarget] Startup shared-image check giving up after ${STARTUP_PLUGIN_MAX_ATTEMPTS} attempt(s)`, - ); - return false; -} - // Check for shared image on initial load (in case app was launched from share sheet) // On Android, share intents are processed in MainActivity.onCreate, so we need to check // after a delay to ensure the native code has finished processing @@ -550,15 +485,11 @@ if (Capacitor.isNativePlatform() && Capacitor.getPlatform() === "android") { }, delay); }); } else if (Capacitor.isNativePlatform() && Capacitor.getPlatform() === "ios") { - // Phase 2A: replace the fixed 1000ms delay with a deterministic wait for the - // SharedImage plugin. The very first startup check runs only after the plugin - // is confirmed available; if the bounded retry budget is exhausted we still - // attempt once as a best-effort fallback (appStateChange retries on the next - // activation), so startup is never worse than the previous fixed-delay path. - void (async () => { - await waitForSharedImagePluginReady(); - await checkForSharedImageAndNavigate(); - })(); + // Phase 2B-3: the SharedImage plugin is now registered deterministically from + // AppBridgeViewController.capacitorDidLoad() before the web layer loads, so it + // is guaranteed to exist here. Perform the initial shared-image check + // immediately without waiting/polling for plugin readiness. + void checkForSharedImageAndNavigate(); } // Listen for app state changes to detect when app becomes active