fuzzyworld

dao-game / commit

PeerJs seems to have a bug that's impacting Edge and Safari: https://github.com/peers/peerjs/issues/899

f2837cac940c85cd1200dba40bdcedd92c43f16e · Pavel Safronov · 2022-03-22 13:53:19 -0700 · parents e46456c24ebd

PeerJs seems to have a bug that's impacting Edge and Safari: https://github.com/peers/peerjs/issues/899
 package-lock.json  | 710 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
 package.json       |   1 +
 public/index.html  |  76 +++---
 src/game-board.ts  |   2 +-
 src/index.ts       |   4 +-
 src/modal.ts       |  17 +-
 src/remote-game.ts |  96 ++++++--
 7 files changed, 827 insertions(+), 79 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index 2a87567..6db6ab6 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,8 +1,711 @@
 {
   "name": "dao-game",
   "version": "1.0.0",
-  "lockfileVersion": 1,
+  "lockfileVersion": 2,
   "requires": true,
+  "packages": {
+    "": {
+      "name": "dao-game",
+      "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"
+      },
+      "devDependencies": {
+        "@types/node": "^17.0.21",
+        "rimraf": "^3.0.2",
+        "ts-node": "^10.6.0",
+        "typescript": "^4.6.2"
+      }
+    },
+    "node_modules/@cspotcode/source-map-consumer": {
+      "version": "0.8.0",
+      "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz",
+      "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==",
+      "dev": true,
+      "engines": {
+        "node": ">= 12"
+      }
+    },
+    "node_modules/@cspotcode/source-map-support": {
+      "version": "0.7.0",
+      "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz",
+      "integrity": "sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==",
+      "dev": true,
+      "dependencies": {
+        "@cspotcode/source-map-consumer": "0.8.0"
+      },
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@tsconfig/node10": {
+      "version": "1.0.8",
+      "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz",
+      "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==",
+      "dev": true
+    },
+    "node_modules/@tsconfig/node12": {
+      "version": "1.0.9",
+      "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz",
+      "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==",
+      "dev": true
+    },
+    "node_modules/@tsconfig/node14": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz",
+      "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==",
+      "dev": true
+    },
+    "node_modules/@tsconfig/node16": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz",
+      "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==",
+      "dev": true
+    },
+    "node_modules/@types/node": {
+      "version": "17.0.21",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.21.tgz",
+      "integrity": "sha512-DBZCJbhII3r90XbQxI8Y9IjjiiOGlZ0Hr32omXIZvwwZ7p4DMMXGrKXVyPfuoBOri9XNtL0UK69jYIBIsRX3QQ==",
+      "dev": true
+    },
+    "node_modules/acorn": {
+      "version": "8.7.0",
+      "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz",
+      "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==",
+      "dev": true,
+      "bin": {
+        "acorn": "bin/acorn"
+      },
+      "engines": {
+        "node": ">=0.4.0"
+      }
+    },
+    "node_modules/acorn-walk": {
+      "version": "8.2.0",
+      "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz",
+      "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.4.0"
+      }
+    },
+    "node_modules/arg": {
+      "version": "4.1.3",
+      "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
+      "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
+      "dev": true
+    },
+    "node_modules/balanced-match": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+      "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+      "dev": true
+    },
+    "node_modules/brace-expansion": {
+      "version": "1.1.11",
+      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+      "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+      "dev": true,
+      "dependencies": {
+        "balanced-match": "^1.0.0",
+        "concat-map": "0.0.1"
+      }
+    },
+    "node_modules/concat-map": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+      "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
+      "dev": true
+    },
+    "node_modules/create-require": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
+      "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",
+      "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.3.1"
+      }
+    },
+    "node_modules/esbuild": {
+      "version": "0.14.25",
+      "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.25.tgz",
+      "integrity": "sha512-4JHEIOMNFvK09ziiL+iVmldIhLbn49V4NAVo888tcGFKedEZY/Y8YapfStJ6zSE23tzYPKxqKwQBnQoIO0BI/Q==",
+      "hasInstallScript": true,
+      "bin": {
+        "esbuild": "bin/esbuild"
+      },
+      "engines": {
+        "node": ">=12"
+      },
+      "optionalDependencies": {
+        "esbuild-android-64": "0.14.25",
+        "esbuild-android-arm64": "0.14.25",
+        "esbuild-darwin-64": "0.14.25",
+        "esbuild-darwin-arm64": "0.14.25",
+        "esbuild-freebsd-64": "0.14.25",
+        "esbuild-freebsd-arm64": "0.14.25",
+        "esbuild-linux-32": "0.14.25",
+        "esbuild-linux-64": "0.14.25",
+        "esbuild-linux-arm": "0.14.25",
+        "esbuild-linux-arm64": "0.14.25",
+        "esbuild-linux-mips64le": "0.14.25",
+        "esbuild-linux-ppc64le": "0.14.25",
+        "esbuild-linux-riscv64": "0.14.25",
+        "esbuild-linux-s390x": "0.14.25",
+        "esbuild-netbsd-64": "0.14.25",
+        "esbuild-openbsd-64": "0.14.25",
+        "esbuild-sunos-64": "0.14.25",
+        "esbuild-windows-32": "0.14.25",
+        "esbuild-windows-64": "0.14.25",
+        "esbuild-windows-arm64": "0.14.25"
+      }
+    },
+    "node_modules/esbuild-android-64": {
+      "version": "0.14.25",
+      "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.25.tgz",
+      "integrity": "sha512-L5vCUk7TzFbBnoESNoXjU3x9+/+7TDIE/1mTfy/erAfvZAqC+S3sp/Qa9wkypFMcFvN9FzvESkTlpeQDolREtQ==",
+      "cpu": [
+        "x64"
+      ],
+      "optional": true,
+      "os": [
+        "android"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-android-arm64": {
+      "version": "0.14.25",
+      "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.25.tgz",
+      "integrity": "sha512-4jv5xPjM/qNm27T5j3ZEck0PvjgQtoMHnz4FzwF5zNP56PvY2CT0WStcAIl6jNlsuDdN63rk2HRBIsO6xFbcFw==",
+      "cpu": [
+        "arm64"
+      ],
+      "optional": true,
+      "os": [
+        "android"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-darwin-64": {
+      "version": "0.14.25",
+      "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.25.tgz",
+      "integrity": "sha512-TGp8tuudIxOyWd1+8aYPxQmC1ZQyvij/AfNBa35RubixD0zJ1vkKHVAzo0Zao1zcG6pNqiSyzfPto8vmg0s7oA==",
+      "cpu": [
+        "x64"
+      ],
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-darwin-arm64": {
+      "version": "0.14.25",
+      "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.25.tgz",
+      "integrity": "sha512-oTcDgdm0MDVEmw2DWu8BV68pYuImpFgvWREPErBZmNA4MYKGuBRaCiJqq6jZmBR1x+3y1DWCjez+5uLtuAm6mw==",
+      "cpu": [
+        "arm64"
+      ],
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-freebsd-64": {
+      "version": "0.14.25",
+      "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.25.tgz",
+      "integrity": "sha512-ueAqbnMZ8arnuLH8tHwTCQYeptnHOUV7vA6px6j4zjjQwDx7TdP7kACPf3TLZLdJQ3CAD1XCvQ2sPhX+8tacvQ==",
+      "cpu": [
+        "x64"
+      ],
+      "optional": true,
+      "os": [
+        "freebsd"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-freebsd-arm64": {
+      "version": "0.14.25",
+      "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.25.tgz",
+      "integrity": "sha512-+ZVWud2HKh+Ob6k/qiJWjBtUg4KmJGGmbvEXXW1SNKS7hW7HU+Zq2ZCcE1akFxOPkVB+EhOty/sSek30tkCYug==",
+      "cpu": [
+        "arm64"
+      ],
+      "optional": true,
+      "os": [
+        "freebsd"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-linux-32": {
+      "version": "0.14.25",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.25.tgz",
+      "integrity": "sha512-3OP/lwV3kCzEz45tobH9nj+uE4ubhGsfx+tn0L26WAGtUbmmcRpqy7XRG/qK7h1mClZ+eguIANcQntYMdYklfw==",
+      "cpu": [
+        "ia32"
+      ],
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-linux-64": {
+      "version": "0.14.25",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.25.tgz",
+      "integrity": "sha512-+aKHdHZmX9qwVlQmu5xYXh7GsBFf4TWrePgeJTalhXHOG7NNuUwoHmketGiZEoNsWyyqwH9rE5BC+iwcLY30Ug==",
+      "cpu": [
+        "x64"
+      ],
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-linux-arm": {
+      "version": "0.14.25",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.25.tgz",
+      "integrity": "sha512-aTLcE2VBoLydL943REcAcgnDi3bHtmULSXWLbjtBdtykRatJVSxKMjK9YlBXUZC4/YcNQfH7AxwVeQr9fNxPhw==",
+      "cpu": [
+        "arm"
+      ],
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-linux-arm64": {
+      "version": "0.14.25",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.25.tgz",
+      "integrity": "sha512-UxfenPx/wSZx55gScCImPtXekvZQLI2GW3qe5dtlmU7luiqhp5GWPzGeQEbD3yN3xg/pHc671m5bma5Ns7lBHw==",
+      "cpu": [
+        "arm64"
+      ],
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-linux-mips64le": {
+      "version": "0.14.25",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.25.tgz",
+      "integrity": "sha512-wLWYyqVfYx9Ur6eU5RT92yJVsaBGi5RdkoWqRHOqcJ38Kn60QMlcghsKeWfe9jcYut8LangYZ98xO1LxIoSXrQ==",
+      "cpu": [
+        "mips64el"
+      ],
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-linux-ppc64le": {
+      "version": "0.14.25",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.25.tgz",
+      "integrity": "sha512-0dR6Csl6Zas3g4p9ULckEl8Mo8IInJh33VCJ3eaV1hj9+MHGdmDOakYMN8MZP9/5nl+NU/0ygpd14cWgy8uqRw==",
+      "cpu": [
+        "ppc64"
+      ],
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-linux-riscv64": {
+      "version": "0.14.25",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.25.tgz",
+      "integrity": "sha512-J4d20HDmTrgvhR0bdkDhvvJGaikH3LzXQnNaseo8rcw9Yqby9A90gKUmWpfwqLVNRILvNnAmKLfBjCKU9ajg8w==",
+      "cpu": [
+        "riscv64"
+      ],
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-linux-s390x": {
+      "version": "0.14.25",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.25.tgz",
+      "integrity": "sha512-YI2d5V6nTE73ZnhEKQD7MtsPs1EtUZJ3obS21oxQxGbbRw1G+PtJKjNyur+3t6nzHP9oTg6GHQ3S3hOLLmbDIQ==",
+      "cpu": [
+        "s390x"
+      ],
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-netbsd-64": {
+      "version": "0.14.25",
+      "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.25.tgz",
+      "integrity": "sha512-TKIVgNWLUOkr+Exrye70XTEE1lJjdQXdM4tAXRzfHE9iBA7LXWcNtVIuSnphTqpanPzTDFarF0yqq4kpbC6miA==",
+      "cpu": [
+        "x64"
+      ],
+      "optional": true,
+      "os": [
+        "netbsd"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-openbsd-64": {
+      "version": "0.14.25",
+      "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.25.tgz",
+      "integrity": "sha512-QgFJ37A15D7NIXBTYEqz29+uw3nNBOIyog+3kFidANn6kjw0GHZ0lEYQn+cwjyzu94WobR+fes7cTl/ZYlHb1A==",
+      "cpu": [
+        "x64"
+      ],
+      "optional": true,
+      "os": [
+        "openbsd"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-sunos-64": {
+      "version": "0.14.25",
+      "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.25.tgz",
+      "integrity": "sha512-rmWfjUItYIVlqr5EnTH1+GCxXiBOC42WBZ3w++qh7n2cS9Xo0lO5pGSG2N+huOU2fX5L+6YUuJ78/vOYvefeFw==",
+      "cpu": [
+        "x64"
+      ],
+      "optional": true,
+      "os": [
+        "sunos"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-windows-32": {
+      "version": "0.14.25",
+      "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.25.tgz",
+      "integrity": "sha512-HGAxVUofl3iUIz9W10Y9XKtD0bNsK9fBXv1D55N/ljNvkrAYcGB8YCm0v7DjlwtyS6ws3dkdQyXadbxkbzaKOA==",
+      "cpu": [
+        "ia32"
+      ],
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-windows-64": {
+      "version": "0.14.25",
+      "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.25.tgz",
+      "integrity": "sha512-TirEohRkfWU9hXLgoDxzhMQD1g8I2mOqvdQF2RS9E/wbkORTAqJHyh7wqGRCQAwNzdNXdg3JAyhQ9/177AadWA==",
+      "cpu": [
+        "x64"
+      ],
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-windows-arm64": {
+      "version": "0.14.25",
+      "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.25.tgz",
+      "integrity": "sha512-4ype9ERiI45rSh+R8qUoBtaj6kJvUOI7oVLhKqPEpcF4Pa5PpT3hm/mXAyotJHREkHpM87PAJcA442mLnbtlNA==",
+      "cpu": [
+        "arm64"
+      ],
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/eventemitter3": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz",
+      "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q=="
+    },
+    "node_modules/fs.realpath": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+      "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
+      "dev": true
+    },
+    "node_modules/glob": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
+      "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==",
+      "dev": true,
+      "dependencies": {
+        "fs.realpath": "^1.0.0",
+        "inflight": "^1.0.4",
+        "inherits": "2",
+        "minimatch": "^3.0.4",
+        "once": "^1.3.0",
+        "path-is-absolute": "^1.0.0"
+      },
+      "engines": {
+        "node": "*"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/inflight": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+      "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+      "dev": true,
+      "dependencies": {
+        "once": "^1.3.0",
+        "wrappy": "1"
+      }
+    },
+    "node_modules/inherits": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+      "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+      "dev": true
+    },
+    "node_modules/make-error": {
+      "version": "1.3.6",
+      "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
+      "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
+      "dev": true
+    },
+    "node_modules/minimatch": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+      "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+      "dev": true,
+      "dependencies": {
+        "brace-expansion": "^1.1.7"
+      },
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/once": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+      "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+      "dev": true,
+      "dependencies": {
+        "wrappy": "1"
+      }
+    },
+    "node_modules/path-is-absolute": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+      "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/peerjs": {
+      "version": "1.3.2",
+      "resolved": "https://registry.npmjs.org/peerjs/-/peerjs-1.3.2.tgz",
+      "integrity": "sha512-+PHfmsC7QGUU8Ye3OLi6tKQZGPCNy7QatUVNw4JtE8alkguF3+DdO5W0bzepqP2OtE9FqH/ltXt37qyvHw2CqA==",
+      "dependencies": {
+        "@types/node": "^10.14.33",
+        "eventemitter3": "^3.1.2",
+        "peerjs-js-binarypack": "1.0.1",
+        "webrtc-adapter": "^7.7.1"
+      }
+    },
+    "node_modules/peerjs-js-binarypack": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/peerjs-js-binarypack/-/peerjs-js-binarypack-1.0.1.tgz",
+      "integrity": "sha512-N6aeia3NhdpV7kiGxJV5xQiZZCVEEVjRz2T2C6UZQiBkHWHzUv/oWA4myQLcwBwO8LUoR1KWW5oStvwVesmfCg=="
+    },
+    "node_modules/peerjs/node_modules/@types/node": {
+      "version": "10.17.60",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz",
+      "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw=="
+    },
+    "node_modules/rimraf": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
+      "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+      "dev": true,
+      "dependencies": {
+        "glob": "^7.1.3"
+      },
+      "bin": {
+        "rimraf": "bin.js"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/rtcpeerconnection-shim": {
+      "version": "1.2.15",
+      "resolved": "https://registry.npmjs.org/rtcpeerconnection-shim/-/rtcpeerconnection-shim-1.2.15.tgz",
+      "integrity": "sha512-C6DxhXt7bssQ1nHb154lqeL0SXz5Dx4RczXZu2Aa/L1NJFnEVDxFwCBo3fqtuljhHIGceg5JKBV4XJ0gW5JKyw==",
+      "dependencies": {
+        "sdp": "^2.6.0"
+      },
+      "engines": {
+        "node": ">=6.0.0",
+        "npm": ">=3.10.0"
+      }
+    },
+    "node_modules/sdp": {
+      "version": "2.12.0",
+      "resolved": "https://registry.npmjs.org/sdp/-/sdp-2.12.0.tgz",
+      "integrity": "sha512-jhXqQAQVM+8Xj5EjJGVweuEzgtGWb3tmEEpl3CLP3cStInSbVHSg0QWOGQzNq8pSID4JkpeV2mPqlMDLrm0/Vw=="
+    },
+    "node_modules/ts-node": {
+      "version": "10.6.0",
+      "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.6.0.tgz",
+      "integrity": "sha512-CJen6+dfOXolxudBQXnVjRVvYTmTWbyz7cn+xq2XTsvnaXbHqr4gXSCNbS2Jj8yTZMuGwUoBESLaOkLascVVvg==",
+      "dev": true,
+      "dependencies": {
+        "@cspotcode/source-map-support": "0.7.0",
+        "@tsconfig/node10": "^1.0.7",
+        "@tsconfig/node12": "^1.0.7",
+        "@tsconfig/node14": "^1.0.0",
+        "@tsconfig/node16": "^1.0.2",
+        "acorn": "^8.4.1",
+        "acorn-walk": "^8.1.1",
+        "arg": "^4.1.0",
+        "create-require": "^1.1.0",
+        "diff": "^4.0.1",
+        "make-error": "^1.1.1",
+        "v8-compile-cache-lib": "^3.0.0",
+        "yn": "3.1.1"
+      },
+      "bin": {
+        "ts-node": "dist/bin.js",
+        "ts-node-cwd": "dist/bin-cwd.js",
+        "ts-node-script": "dist/bin-script.js",
+        "ts-node-transpile-only": "dist/bin-transpile.js",
+        "ts-script": "dist/bin-script-deprecated.js"
+      },
+      "peerDependencies": {
+        "@swc/core": ">=1.2.50",
+        "@swc/wasm": ">=1.2.50",
+        "@types/node": "*",
+        "typescript": ">=2.7"
+      },
+      "peerDependenciesMeta": {
+        "@swc/core": {
+          "optional": true
+        },
+        "@swc/wasm": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/typescript": {
+      "version": "4.6.2",
+      "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.2.tgz",
+      "integrity": "sha512-HM/hFigTBHZhLXshn9sN37H085+hQGeJHJ/X7LpBWLID/fbc2acUMfU+lGD98X81sKP+pFa9f0DZmCwB9GnbAg==",
+      "dev": true,
+      "bin": {
+        "tsc": "bin/tsc",
+        "tsserver": "bin/tsserver"
+      },
+      "engines": {
+        "node": ">=4.2.0"
+      }
+    },
+    "node_modules/v8-compile-cache-lib": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.0.tgz",
+      "integrity": "sha512-mpSYqfsFvASnSn5qMiwrr4VKfumbPyONLCOPmsR3A6pTY/r0+tSaVbgPWSAIuzbk3lCTa+FForeTiO+wBQGkjA==",
+      "dev": true
+    },
+    "node_modules/web-animations-js": {
+      "version": "2.3.2",
+      "resolved": "https://registry.npmjs.org/web-animations-js/-/web-animations-js-2.3.2.tgz",
+      "integrity": "sha512-TOMFWtQdxzjWp8qx4DAraTWTsdhxVSiWa6NkPFSaPtZ1diKUxTn4yTix73A1euG1WbSOMMPcY51cnjTIHrGtDA=="
+    },
+    "node_modules/webrtc-adapter": {
+      "version": "7.7.1",
+      "resolved": "https://registry.npmjs.org/webrtc-adapter/-/webrtc-adapter-7.7.1.tgz",
+      "integrity": "sha512-TbrbBmiQBL9n0/5bvDdORc6ZfRY/Z7JnEj+EYOD1ghseZdpJ+nF2yx14k3LgQKc7JZnG7HAcL+zHnY25So9d7A==",
+      "dependencies": {
+        "rtcpeerconnection-shim": "^1.2.15",
+        "sdp": "^2.12.0"
+      },
+      "engines": {
+        "node": ">=6.0.0",
+        "npm": ">=3.10.0"
+      }
+    },
+    "node_modules/wrappy": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+      "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
+      "dev": true
+    },
+    "node_modules/yn": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
+      "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    }
+  },
   "dependencies": {
     "@cspotcode/source-map-consumer": {
       "version": "0.8.0",
@@ -95,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/public/index.html b/public/index.html
index a9fcaae..adba5c1 100644
--- a/public/index.html
+++ b/public/index.html
@@ -1,42 +1,44 @@
 <!DOCTYPE html>
 <html lang="en">
-  <head>
-    <meta charset="utf-8" />
-    <title>Dao Game</title>
-    <meta name="viewport" content="width=device-width, initial-scale=1" />
-    <link rel="icon" href="yin-yang.svg" type="image/svg+xml" />
-    <link rel="stylesheet" href="styles.css" />
-    <!-- <script defer src="js/index.js"></script> -->
-  </head>
 
-  <body>
-    <div class="title">
-      <p>Board game <a href="https://en.wikipedia.org/wiki/Dao_(game)" target="_blank" rel="noopener">Dao</a>.</p>
-    </div>
+<head>
+  <meta charset="utf-8" />
+  <title>Dao Game</title>
+  <meta name="viewport" content="width=device-width, initial-scale=1" />
+  <link rel="icon" href="yin-yang.svg" type="image/svg+xml" />
+  <link rel="stylesheet" href="styles.css" />
+  <script defer src="js/index.js"></script>
+</head>
 
-    <div class="info">
-      The game consists of only one simple rule and three ways to win. Rules:
-      <ul>
-        <li>Pieces move in a straight line, including diagonally, as far as possible with no jumps.</li>
-      </ul>
-      Ways to win:
-      <ol>
-        <li>Arrange your pieces in a straight line on the board (not diagonally)</li>
-        <li>Occupy four corners of the board</li>
-        <li>Form a 2x2 square anywhere on the board</li>
-      </ol>
-    </div>
-    <hr />
-    <div class="info">
-      <div>Play local (pass-and-play) game of Dao <a href="local.html">here</a>.</div>
-      <div>Play online game of Dao <a href="remote.html">here</a>.</div>
-    </div>
+<body>
+  <div class="title">
+    <p>Board game <a href="https://en.wikipedia.org/wiki/Dao_(game)" target="_blank" rel="noopener">Dao</a>.</p>
+  </div>
 
-    <div class="info">
-      <p>
-        Here is the
-        <a href="https://gitlab.com/fuzzy-rp/dao-game" target="_blank" rel="noopener">source code</a>
-      </p>
-    </div>
-  </body>
-</html>
+  <div class="info">
+    The game consists of only one simple rule and three ways to win. Rules:
+    <ul>
+      <li>Pieces move in a straight line, including diagonally, as far as possible with no jumps.</li>
+    </ul>
+    Ways to win:
+    <ol>
+      <li>Arrange your pieces in a straight line on the board (not diagonally)</li>
+      <li>Occupy four corners of the board</li>
+      <li>Form a 2x2 square anywhere on the board</li>
+    </ol>
+  </div>
+  <hr />
+  <div class="info">
+    <div>Play local (pass-and-play) game of Dao <a href="local.html">here</a>.</div>
+    <div>Play online game of Dao <a href="remote.html">here</a>.</div>
+  </div>
+
+  <div class="info">
+    <p>
+      Here is the
+      <a href="https://gitlab.com/fuzzy-rp/dao-game" target="_blank" rel="noopener">source code</a>
+    </p>
+  </div>
+</body>
+
+</html>
\ No newline at end of file
diff --git a/src/game-board.ts b/src/game-board.ts
index f9f54e9..71ac871 100644
--- a/src/game-board.ts
+++ b/src/game-board.ts
@@ -19,7 +19,7 @@ export class GameBoard {
       .concat([player1Id, null, player2Id, null])
       .concat([player1Id, null, null, null])
       .concat([null, player1Id, null, player2Id]);
-    this.board = defaultBoard;
+    this.board = testBoard;
     this.size = new Coord(4, 4);
     this.player1Id = player1Id;
     this.player2Id = player2Id;
diff --git a/src/index.ts b/src/index.ts
index fc5ffe4..545baf6 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -2,7 +2,9 @@ import { showModal } from "./modal";
 
 const doStuff = async () => {
   await showModal({
-    text: 'Blah blah blah blah',
+    text: "<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\">https://github.com/peers/peerjs/issues/899</a></p>",
     willBackgroundCancel: false
   });
   await showModal({
diff --git a/src/modal.ts b/src/modal.ts
index 02ff4d0..5ce1f50 100644
--- a/src/modal.ts
+++ b/src/modal.ts
@@ -1,10 +1,9 @@
 export interface Options {
     text: string;
-    willBackgroundCancel?: boolean;
     title?: string;
+    willBackgroundCancel?: boolean;
 }
 
-
 /*
     <div class="modal">
         <div class="modal-content">
@@ -25,8 +24,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.innerHTML = title;
         modalContentDiv.appendChild(modelContentTitle);
     }
 
@@ -37,17 +36,11 @@ export const showModal = (options: Options): Promise<void> => {
 
     const modalContentPara = document.createElement('p');
     modalContentPara.id = 'modal-content';
-    modalContentPara.innerText = text;
+    modalContentPara.innerHTML = text;
     modalContentDiv.appendChild(modalContentPara);
 
     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 +51,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
diff --git a/src/remote-game.ts b/src/remote-game.ts
index 808f467..f84c192 100644
--- a/src/remote-game.ts
+++ b/src/remote-game.ts
@@ -5,6 +5,7 @@ import { useSessionStorage } from './storage';
 import { Coord, Move, MoveResult } from './types';
 import { copyToClipboard, delay, generateHash } from './utils';
 import { showSnackbar } from "./snackbar";
+import { detect } from 'detect-browser';
 
 interface LocalData {
     id: string;
@@ -18,7 +19,7 @@ interface PeerData {
     mousePos?: Pos;
     move?: Move;
 }
-const peerOptions: PeerJSOption = { debug: 0 };
+const peerOptions: PeerJSOption = { debug: 3 };
 const { getter: getData, setter: setData } = useSessionStorage<LocalData>('dao-game', { id: undefined, peerId: undefined });
 const otherMouseElement = document.getElementById('other-mouse');
 const shareContainer = document.getElementById('share-container');
@@ -38,6 +39,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;
@@ -63,28 +72,23 @@ 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) {
+            showMessageAndLeave('Game Over', message)
         } else {
             this.resetUi();
             this.setActiveUi();
         }
     }
 
+
     public static async createPeerGame(): Promise<PeerGame> {
         let { id, peerId } = getData();
         const main = document.getElementsByTagName('main')[0];
         let game: PeerGame = undefined;
 
-        const handleConn = (conn: Peer.DataConnection) => {
-            if (game !== undefined) {
-                conn.close();
-                return;
+        const handleConn = (source: string, conn: Peer.DataConnection) => {
+            if (source === 'peer-on-connection') {
+                conn.open
             }
 
             shareContainer.classList.add('invisible');
@@ -102,21 +106,26 @@ export class PeerGame extends LocalGame {
             main.classList.remove('invisible');
 
             const table = document.getElementById('table');
-            table.addEventListener('mousemove', (ev: MouseEvent) => {
+            table.addEventListener('click', (ev: MouseEvent) => {
                 const xTable = ev.clientX - table.offsetLeft;
                 const yTable = ev.clientY - table.offsetTop;
                 const xRatio = xTable / table.clientWidth;
                 const yRatio = yTable / table.clientHeight;
                 const peerData: PeerData = { mousePos: { x: xRatio, y: yRatio } };
-                conn.send(JSON.stringify(peerData));
-            });
-            table.addEventListener('mouseleave', () => {
-                const peerData: PeerData = { mousePos: { x: -1, y: -1 } };
-                conn.send(JSON.stringify(peerData));
+                const data = JSON.stringify(peerData);
+                console.table({ on: 'mousemove', from: id, to: peerId, data });
+                conn.send(data);
             });
+            // table.addEventListener('mouseleave', () => {
+            //     const peerData: PeerData = { mousePos: { x: -1, y: -1 } };
+            //     const text = JSON.stringify(peerData);
+            //     console.table({ on: 'mouseleave', from: id, to: peerId, text });
+            //     conn.send(text);
+            // });
 
             let lastTimerId = undefined;
             conn.on('data', (data: string) => {
+                console.table({ on: 'data', to: id, from: peerId, data });
                 const peerData = JSON.parse(data) as PeerData;
                 const { mousePos, move } = peerData;
 
@@ -153,6 +162,15 @@ export class PeerGame extends LocalGame {
                     }
                 }
             });
+            conn.on('error', (err) => {
+                showMessageAndLeave(`Connection error: ${source}`, err);
+            });
+            conn.on('close', () => {
+                showMessageAndLeave(`Connection closed: ${source}`, 'Connection closed for some reason')
+            });
+            conn.on('open', () => {
+                showModal({ title: 'conn-on-open', text: 'connected!' });
+            });
         };
 
         const { host, protocol, pathname, search } = location;
@@ -160,14 +178,15 @@ export class PeerGame extends LocalGame {
 
         const peer = id === undefined ? new Peer(peerOptions) : new Peer(id, peerOptions);
         window.onunload = () => peer.destroy();
-        peer.on('connection', (conn) => handleConn(conn));
+        peer.on('connection', (conn) => handleConn('peer-on-connection', conn));
         peer.on('error', async (err) => {
-            await showModal({
-                text: err,
-                title: 'Error encountered:',
-                willBackgroundCancel: false
-            });
-            sessionStorage.clear();
+            // await showModal({
+            //     text: err,
+            //     title: 'Error encountered:',
+            //     willBackgroundCancel: false
+            // });
+            // sessionStorage.clear();
+            await showMessageAndLeave('Error encountered', err);
         });
         peer.on('open', (trueId) => {
             id = trueId;
@@ -177,11 +196,12 @@ export class PeerGame extends LocalGame {
             if (peerId) {
                 console.log(`${id} connecting to peer "${peerId}"`);
                 const conn = peer.connect(peerId);
-                handleConn(conn);
+                handleConn('peer-connect', conn);
             } else {
                 queryParams.set('peerId', id);
                 const newSearch = queryParams.toString();
                 const newUrl = `${protocol}//${host}${pathname}?${newSearch}`;
+                // const newUrl = `microsoft-edge:${protocol}//${host}${pathname}?${newSearch}`;
                 shareLinkButton.onclick = () => {
                     showSnackbar('Url copied to clipboard');
                     copyToClipboard(newUrl);
@@ -189,6 +209,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');
@@ -198,6 +221,25 @@ 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>')
+    }
 };