Quellcode durchsuchen

feat: add install-PWA to command palette (#7935)

David Luzar vor 1 Jahr
Ursprung
Commit
301e83805d
2 geänderte Dateien mit 49 neuen und 1 gelöschten Zeilen
  1. 47 0
      excalidraw-app/App.tsx
  2. 2 1
      packages/excalidraw/locales/en.json

+ 47 - 0
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<void>;
+    userChoice: Promise<BeforeInstallPromptEventChoiceResult>;
+  }
+
+  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;
+                  });
+                }
+              },
+            },
           ]}
         />
       </Excalidraw>

+ 2 - 1
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...",