fuzzyworld

dao-game / commit

Added browser check for online games, which aren't working in Edge and Safari due to a bug in PeerJs: https://github.com/peers/peerjs/issues/899

db09721d2e1def6568ecf6df56f9337e456eecf8 · Pavel Safronov · 2022-03-22 14:14:08 -0700 · parents cf42c5f80241

Added browser check for online games, which aren't working in Edge and Safari due to a bug in PeerJs: https://github.com/peers/peerjs/issues/899
 package-lock.json       | 11 ++++++++++
 package.json            |  1 +
 src/game/remote-game.ts | 58 ++++++++++++++++++++++++++++++++++++-------------
 src/utils/modal.ts      | 16 +++++---------
 4 files changed, 60 insertions(+), 26 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index 63f1378..6db6ab6 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9,6 +9,7 @@
       "version": "1.0.0",
       "license": "ISC",
       "dependencies": {
+        "detect-browser": "^5.3.0",
         "esbuild": "^0.14.25",
         "peerjs": "^1.3.2",
         "web-animations-js": "^2.3.2"
@@ -126,6 +127,11 @@
       "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
       "dev": true
     },
+    "node_modules/detect-browser": {
+      "version": "5.3.0",
+      "resolved": "https://registry.npmjs.org/detect-browser/-/detect-browser-5.3.0.tgz",
+      "integrity": "sha512-53rsFbGdwMwlF7qvCt0ypLM5V5/Mbl0szB7GPN8y9NCcbknYOeVVXdrXEq+90IwAfrrzt6Hd+u2E2ntakICU8w=="
+    },
     "node_modules/diff": {
       "version": "4.0.2",
       "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
@@ -792,6 +798,11 @@
       "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
       "dev": true
     },
+    "detect-browser": {
+      "version": "5.3.0",
+      "resolved": "https://registry.npmjs.org/detect-browser/-/detect-browser-5.3.0.tgz",
+      "integrity": "sha512-53rsFbGdwMwlF7qvCt0ypLM5V5/Mbl0szB7GPN8y9NCcbknYOeVVXdrXEq+90IwAfrrzt6Hd+u2E2ntakICU8w=="
+    },
     "diff": {
       "version": "4.0.2",
       "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
diff --git a/package.json b/package.json
index 2647ca4..69750b8 100644
--- a/package.json
+++ b/package.json
@@ -21,6 +21,7 @@
   },
   "homepage": "https://gitlab.com/fuzzy-rp/dao-game#readme",
   "dependencies": {
+    "detect-browser": "^5.3.0",
     "esbuild": "^0.14.25",
     "peerjs": "^1.3.2",
     "web-animations-js": "^2.3.2"
diff --git a/src/game/remote-game.ts b/src/game/remote-game.ts
index d6d281b..2a377e4 100644
--- a/src/game/remote-game.ts
+++ b/src/game/remote-game.ts
@@ -8,6 +8,7 @@ import { Coord } from './coord';
 import { generateHash } from '../utils/hashing';
 import { delay } from '../utils/delay';
 import { copyToClipboard } from '../utils/clipboard';
+import { detect } from 'detect-browser';
 
 interface LocalData {
     id: string;
@@ -41,6 +42,14 @@ const dropFileExtension = (path: string) => {
     const dirName = path.substring(0, lastSlashIndex);
     return dirName;
 }
+const showMessageAndLeave = async (title, text) => {
+    await showModal({ title, text, willBackgroundCancel: false });
+    sessionStorage.clear();
+    const { protocol, host, pathname } = location;
+    const dir = dropFileExtension(pathname);
+    const newUrl = `${protocol}//${host}${dir}`
+    document.location = newUrl;
+}
 
 export class PeerGame extends LocalGame {
     public conn: Peer.DataConnection;
@@ -66,13 +75,8 @@ export class PeerGame extends LocalGame {
     }
     public override async handleMoveResult(result: MoveResult): Promise<void> {
         const { isTerminal, message } = result;
-        if (result.isTerminal) {
-            await showModal({ text: message });
-            sessionStorage.clear();
-            const { protocol, host, pathname } = location;
-            const dir = dropFileExtension(pathname);
-            const newUrl = `${protocol}//${host}${dir}`
-            document.location = newUrl;
+        if (isTerminal) {
+            await showMessageAndLeave('Game Over', message);
         } else {
             this.resetUi();
             this.setActiveUi();
@@ -156,6 +160,15 @@ export class PeerGame extends LocalGame {
                     }
                 }
             });
+            conn.on('error', (err) => {
+                showMessageAndLeave(`Connection error`, err);
+            });
+            conn.on('close', () => {
+                showMessageAndLeave(`Connection closed`, 'Connection closed for some reason')
+            });
+            // conn.on('open', () => {
+            //     showModal({ title: 'conn-on-open', text: 'connected!' });
+            // });
         };
 
         const { host, protocol, pathname, search } = location;
@@ -165,12 +178,7 @@ export class PeerGame extends LocalGame {
         window.onunload = () => peer.destroy();
         peer.on('connection', (conn) => handleConn(conn));
         peer.on('error', async (err) => {
-            await showModal({
-                text: err,
-                title: 'Error encountered:',
-                willBackgroundCancel: false
-            });
-            sessionStorage.clear();
+            await showMessageAndLeave('Peer error encountered', err);
         });
         peer.on('open', (trueId) => {
             id = trueId;
@@ -192,7 +200,9 @@ export class PeerGame extends LocalGame {
                 shareContainer.classList.remove('invisible');
             }
         });
-
+        peer.on('disconnected', async () => {
+            await showMessageAndLeave('Peer disconnected', 'For some reason')
+        });
         while (game === undefined) {
             console.log('Waiting to connect to peer');
             await delay(500);
@@ -201,6 +211,24 @@ export class PeerGame extends LocalGame {
     }
 }
 
+const isBrowserSupported = () => {
+    const browser = detect();
+    switch (browser && browser.name) {
+        case 'chrome':
+        case 'firefox':
+            return true;
+        default:
+            return false;
+    }
+}
 export const playGame = async () => {
-    await PeerGame.createPeerGame();
+    if (isBrowserSupported()) {
+        await PeerGame.createPeerGame();
+    } else {
+        showMessageAndLeave(
+            'Unsupported browser',
+            '<p>Your current browser is not yet supported.</p>' +
+            '<p>This PeerJs issue is tracking support in Microsoft Edge and Safari: </p>' +
+            '<p><a href="https://github.com/peers/peerjs/issues/899" target="_blank">https://github.com/peers/peerjs/issues/899</a></p>')
+    }
 };
diff --git a/src/utils/modal.ts b/src/utils/modal.ts
index 02ff4d0..0c50198 100644
--- a/src/utils/modal.ts
+++ b/src/utils/modal.ts
@@ -1,10 +1,10 @@
 export interface Options {
     text: string;
-    willBackgroundCancel?: boolean;
     title?: string;
+    willBackgroundCancel?: boolean;
 }
 
-
+let previousPromise: Promise<void> = undefined;
 /*
     <div class="modal">
         <div class="modal-content">
@@ -25,8 +25,8 @@ export const showModal = (options: Options): Promise<void> => {
 
     if (title) {
         const modelContentTitle = document.createElement('div');
-        modelContentTitle.classList.add('title');
-        modelContentTitle.innerText = 'This is a title!';
+        modelContentTitle.classList.add('info');
+        modelContentTitle.innerText = title;
         modalContentDiv.appendChild(modelContentTitle);
     }
 
@@ -42,12 +42,6 @@ export const showModal = (options: Options): Promise<void> => {
 
     document.body.appendChild(modal);
 
-    // Get the <span> element that closes the modal
-    var span = document.getElementsByClassName("close")[0] as HTMLSpanElement;
-
-    var content = document.getElementById('modal-content') as HTMLParagraphElement;
-    content.innerText = text;
-
     const promise = new Promise<void>((resolve, reject) => {
         let isModalOpen = true;
         const closeModal = () => {
@@ -58,7 +52,7 @@ export const showModal = (options: Options): Promise<void> => {
         }
 
         // When the user clicks on <span> (x), close the modal
-        span.onclick = () => closeModal();
+        closeSpan.onclick = () => closeModal();
 
         if (willBackgroundCancel === undefined || willBackgroundCancel === true) {
             // When the user clicks anywhere outside of the modal, close it