src/bootstrap-pwa-install.ts

Description

The browser's non-standard beforeinstallprompt event. Not part of the DOM lib types, so we declare the shape we rely on ourselves.

Extends

Event

Relationships

Used by

No results matching.

Depends on

Index

Properties
Methods

Methods

prompt
prompt()
Returns : Promise<void>

Properties

userChoice
userChoice: Promise<PWAInstallChoice>
Type : Promise<PWAInstallChoice>
export interface PWAInstallChoice {
  outcome: "accepted" | "dismissed";
  platform: string;
}

/**
 * The browser's non-standard `beforeinstallprompt` event.
 * Not part of the DOM lib types, so we declare the shape we rely on ourselves.
 */
export interface BeforeInstallPromptEvent extends Event {
  readonly userChoice: Promise<PWAInstallChoice>;
  prompt(): Promise<void>;
}

/** The deferred `beforeinstallprompt` event, to be triggered on user request */
let deferredInstallPrompt: BeforeInstallPromptEvent | undefined;

/** Resolves once/if it is possible to directly install the app */
let canInstallDirectly: Promise<void> | undefined;

/** The registered listener, kept so {@link resetPWAInstallListener} can remove it again */
let installPromptListener: ((e: Event) => void) | undefined;

/**
 * Start listening for the browser's `beforeinstallprompt` event and defer it,
 * so that the app can offer an install button at any later point.
 *
 * Must be called before any async operation during bootstrap, because the
 * browser fires the event early and does not replay it for later listeners.
 */
export function registerPWAInstallListener(): void {
  canInstallDirectly = new Promise((resolve) => {
    installPromptListener = (e: Event) => {
      e.preventDefault();
      deferredInstallPrompt = e as BeforeInstallPromptEvent;
      resolve();
    };
    window.addEventListener("beforeinstallprompt", installPromptListener);
  });
}

/**
 * Resolves once/if the app can be installed directly.
 * `undefined` if {@link registerPWAInstallListener} has not run.
 */
export function whenCanInstallDirectly(): Promise<void> | undefined {
  return canInstallDirectly;
}

/**
 * The deferred install prompt, if the browser has offered one already.
 */
export function getDeferredInstallPrompt():
  BeforeInstallPromptEvent | undefined {
  return deferredInstallPrompt;
}

/**
 * Discard the deferred prompt and the listener's promise, and remove the
 * `beforeinstallprompt` listener from `window`.
 * Only needed in tests, to undo the module-level state of a previous case.
 */
export function resetPWAInstallListener(): void {
  if (installPromptListener) {
    window.removeEventListener("beforeinstallprompt", installPromptListener);
    installPromptListener = undefined;
  }
  deferredInstallPrompt = undefined;
  canInstallDirectly = undefined;
}

results matching ""

    No results matching ""