From 301e83805dc6a14ff622624ef9a68a560dde7230 Mon Sep 17 00:00:00 2001 From: David Luzar <5153846+dwelle@users.noreply.github.com> Date: Wed, 8 May 2024 22:02:28 +0200 Subject: [PATCH] feat: add install-PWA to command palette (#7935) --- excalidraw-app/App.tsx | 47 +++++++++++++++++++++++++++++ packages/excalidraw/locales/en.json | 3 +- 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/excalidraw-app/App.tsx b/excalidraw-app/App.tsx index 25fcbd69d..ec091d95b 100644 --- a/excalidraw-app/App.tsx +++ b/excalidraw-app/App.tsx @@ -126,6 +126,38 @@ polyfill(); window.EXCALIDRAW_THROTTLE_RENDER = true; +declare global { + interface BeforeInstallPromptEventChoiceResult { + outcome: "accepted" | "dismissed"; + } + + interface BeforeInstallPromptEvent extends Event { + prompt(): Promise; + userChoice: Promise; + } + + interface WindowEventMap { + beforeinstallprompt: BeforeInstallPromptEvent; + } +} + +let pwaEvent: BeforeInstallPromptEvent | null = null; + +// Adding a listener outside of the component as it may (?) need to be +// subscribed early to catch the event. +// +// Also note that it will fire only if certain heuristics are met (user has +// used the app for some time, etc.) +window.addEventListener( + "beforeinstallprompt", + (event: BeforeInstallPromptEvent) => { + // prevent Chrome <= 67 from automatically showing the prompt + event.preventDefault(); + // cache for later use + pwaEvent = event; + }, +); + let isSelfEmbedding = false; if (window.self !== window.top) { @@ -1100,6 +1132,21 @@ const ExcalidrawWrapper = () => { ); }, }, + { + label: t("labels.installPWA"), + category: DEFAULT_CATEGORIES.app, + predicate: () => !!pwaEvent, + perform: () => { + if (pwaEvent) { + pwaEvent.prompt(); + pwaEvent.userChoice.then(() => { + // event cannot be reused, but we'll hopefully + // grab new one as the event should be fired again + pwaEvent = null; + }); + } + }, + }, ]} /> diff --git a/packages/excalidraw/locales/en.json b/packages/excalidraw/locales/en.json index 512ec4ea0..eac6a3f66 100644 --- a/packages/excalidraw/locales/en.json +++ b/packages/excalidraw/locales/en.json @@ -148,7 +148,8 @@ "discordChat": "Discord chat", "zoomToFitViewport": "Zoom to fit in viewport", "zoomToFitSelection": "Zoom to fit selection", - "zoomToFit": "Zoom to fit all elements" + "zoomToFit": "Zoom to fit all elements", + "installPWA": "Install Excalidraw locally (PWA)" }, "library": { "noItems": "No items added yet...",