import { DeviceUtilities } from "./engine_utils.js"; /** * Arguments for the native screenshot bridge exposed by the Needle Go App Clip (injected as `window.NeedleGoNativeScreenshot`). */ declare type NeedleGoNativeScreenshotArgs = { /** Data URL (PNG) of the rendered 3D layer with a transparent background. Native code composites the live camera frame behind it. */ image: string; /** "share" presents the native share sheet, "return" sends the composited image back. @default "share" */ action?: "share" | "return"; /** Share sheet title (action "share") */ title?: string; /** Share sheet text (action "share") */ text?: string; /** Share sheet url (action "share") */ url?: string; /** Mime type for the returned image (action "return"): "image/png" or "image/jpeg" (default jpeg, the composite is opaque) */ mimeType?: string; /** JPEG quality 0..1 for action "return" (default 0.9) */ quality?: number; } declare type NeedleGoNativeScreenshotResult = { /** action "share": whether the user completed the share */ shared?: boolean; /** action "share": the activity the user chose, if any */ activity?: string; /** action "return": data URL of the composited image */ image?: string; /** action "return": mime type of the returned image */ mimeType?: string; } declare type NeedleGoNativeScreenshotFunction = (args: NeedleGoNativeScreenshotArgs) => Promise; /** * Returns the native screenshot bridge when running inside the Needle Go App Clip. * * In the App Clip the camera feed is rendered natively *behind* the transparent webview, * so the page can never capture it (there is no `camera-access` WebXR feature). The bridge * lets us send the rendered 3D layer to the native app, which composites the current camera * frame behind it and can present the native share sheet — which, unlike `navigator.share`, * does not require (transient) user activation, so a single tap is enough even though the * screenshot pipeline is asynchronous. * * Returns null when not in the App Clip or when the App Clip version doesn't support it yet. */ export function getNativeScreenshotBridge(): NeedleGoNativeScreenshotFunction | null { if (typeof window === "undefined") return null; if (!DeviceUtilities.isNeedleAppClip()) return null; const fn = (window as any).NeedleGoNativeScreenshot; return typeof fn === "function" ? fn as NeedleGoNativeScreenshotFunction : null; }