diff --git a/src/components/Banner.js b/src/components/banner/Banner.js
similarity index 81%
rename from src/components/Banner.js
rename to src/components/banner/Banner.js
index 3f9f961..7aed80a 100644
--- a/src/components/Banner.js
+++ b/src/components/banner/Banner.js
@@ -2,7 +2,13 @@ import React from "react";
import Modal from "react-modal";
import { useThemeUI, Close } from "theme-ui";
-function Banner({ isOpen, onRequestClose, children, allowClose }) {
+function Banner({
+ isOpen,
+ onRequestClose,
+ children,
+ allowClose,
+ backgroundColor,
+}) {
const { theme } = useThemeUI();
return (
@@ -12,7 +18,7 @@ function Banner({ isOpen, onRequestClose, children, allowClose }) {
style={{
overlay: { bottom: "0", top: "initial", zIndex: 2000 },
content: {
- backgroundColor: theme.colors.highlight,
+ backgroundColor: backgroundColor || theme.colors.highlight,
color: "hsl(210, 50%, 96%)",
top: "initial",
left: "50%",
@@ -22,7 +28,7 @@ function Banner({ isOpen, onRequestClose, children, allowClose }) {
border: "none",
padding: "8px",
margin: "8px",
- paddingRight: "24px",
+ paddingRight: allowClose ? "24px" : "8px",
maxWidth: "500px",
transform: "translateX(-50%)",
},
diff --git a/src/components/banner/ErrorBanner.js b/src/components/banner/ErrorBanner.js
new file mode 100644
index 0000000..6bb3574
--- /dev/null
+++ b/src/components/banner/ErrorBanner.js
@@ -0,0 +1,18 @@
+import React from "react";
+import { Box, Text } from "theme-ui";
+
+import Banner from "./Banner";
+
+function ErrorBanner({ error, onRequestClose }) {
+ return (
+
+
+
+ Error: {error && error.message}
+
+
+
+ );
+}
+
+export default ErrorBanner;
diff --git a/src/components/banner/OfflineBanner.js b/src/components/banner/OfflineBanner.js
new file mode 100644
index 0000000..d5d90ad
--- /dev/null
+++ b/src/components/banner/OfflineBanner.js
@@ -0,0 +1,33 @@
+import React from "react";
+import { Flex } from "theme-ui";
+
+import Banner from "./Banner";
+import OfflineIcon from "../../icons/OfflineIcon";
+
+function OfflineBanner({ isOpen }) {
+ return (
+ {}}
+ allowClose={false}
+ backgroundColor="transparent"
+ >
+
+
+
+
+ );
+}
+
+export default OfflineBanner;
diff --git a/src/components/banner/ReconnectBanner.js b/src/components/banner/ReconnectBanner.js
new file mode 100644
index 0000000..7fa917a
--- /dev/null
+++ b/src/components/banner/ReconnectBanner.js
@@ -0,0 +1,33 @@
+import React from "react";
+import { Flex } from "theme-ui";
+
+import Banner from "./Banner";
+import ReconnectingIcon from "../../icons/ReconnectingIcon";
+
+function ReconnectBanner({ isOpen }) {
+ return (
+ {}}
+ allowClose={false}
+ backgroundColor="transparent"
+ >
+
+
+
+
+ );
+}
+
+export default ReconnectBanner;
diff --git a/src/components/dice/DiceInteraction.js b/src/components/dice/DiceInteraction.js
index 19f709c..f5d225b 100644
--- a/src/components/dice/DiceInteraction.js
+++ b/src/components/dice/DiceInteraction.js
@@ -1,5 +1,4 @@
import React, { useRef, useEffect, useState } from "react";
-import { Box, Text } from "theme-ui";
import { Engine } from "@babylonjs/core/Engines/engine";
import { Scene } from "@babylonjs/core/scene";
import { Vector3, Color4, Matrix } from "@babylonjs/core/Maths/math";
@@ -19,7 +18,7 @@ import ReactResizeDetector from "react-resize-detector";
import usePreventTouch from "../../hooks/usePreventTouch";
-import Banner from "../Banner";
+import ErrorBanner from "../banner/ErrorBanner";
const diceThrowSpeed = 2;
@@ -166,13 +165,7 @@ function DiceInteraction({ onSceneMount, onPointerDown, onPointerUp }) {
style={{ outline: "none" }}
/>
- setError()}>
-
-
- Error: {error && error.message}
-
-
-
+ setError()} />
);
}
diff --git a/src/components/party/Stream.js b/src/components/party/Stream.js
index d3e7bcc..631f4e1 100644
--- a/src/components/party/Stream.js
+++ b/src/components/party/Stream.js
@@ -3,7 +3,7 @@ import { Text, IconButton, Box, Flex } from "theme-ui";
import StreamMuteIcon from "../../icons/StreamMuteIcon";
-import Banner from "../Banner";
+import Banner from "../banner/Banner";
import Slider from "../Slider";
function Stream({ stream, nickname }) {
diff --git a/src/contexts/DatabaseContext.js b/src/contexts/DatabaseContext.js
index d0bc2ea..a5b35d4 100644
--- a/src/contexts/DatabaseContext.js
+++ b/src/contexts/DatabaseContext.js
@@ -1,7 +1,6 @@
import React, { useState, useEffect, useContext } from "react";
-import { Box, Text } from "theme-ui";
-import Banner from "../components/Banner";
+import ErrorBanner from "../components/banner/ErrorBanner";
import { getDatabase } from "../database";
@@ -64,16 +63,10 @@ export function DatabaseProvider({ children }) {
<>
{children}
- setDatabaseError()}
- >
-
-
- {databaseError && databaseError.message}
-
-
-
+ />
>
);
diff --git a/src/icons/OfflineIcon.js b/src/icons/OfflineIcon.js
new file mode 100644
index 0000000..75e1c05
--- /dev/null
+++ b/src/icons/OfflineIcon.js
@@ -0,0 +1,18 @@
+import React from "react";
+
+function PointerToolIcon() {
+ return (
+
+ );
+}
+
+export default PointerToolIcon;
diff --git a/src/icons/ReconnectingIcon.js b/src/icons/ReconnectingIcon.js
new file mode 100644
index 0000000..b7ccdc9
--- /dev/null
+++ b/src/icons/ReconnectingIcon.js
@@ -0,0 +1,28 @@
+import React from "react";
+
+function ReconnectingIcon() {
+ return (
+
+ );
+}
+
+export default ReconnectingIcon;
diff --git a/src/modals/ImportExportModal.js b/src/modals/ImportExportModal.js
index 0552056..f665f58 100644
--- a/src/modals/ImportExportModal.js
+++ b/src/modals/ImportExportModal.js
@@ -8,7 +8,7 @@ import { useToasts } from "react-toast-notifications";
import Modal from "../components/Modal";
import LoadingOverlay from "../components/LoadingOverlay";
import LoadingBar from "../components/LoadingBar";
-import Banner from "../components/Banner";
+import ErrorBanner from "../components/banner/ErrorBanner";
import { useAuth } from "../contexts/AuthContext";
@@ -271,13 +271,7 @@ function ImportExportModal({ isOpen, onRequestClose }) {
/>
)}
- setError()}>
-
-
- Error: {error && error.message}
-
-
-
+ setError()} />
{loading && }
- setError(null)}>
-
-
- {error}
-
-
-
+ setError()} />
);
}
diff --git a/src/routes/Game.js b/src/routes/Game.js
index f07196e..7610850 100644
--- a/src/routes/Game.js
+++ b/src/routes/Game.js
@@ -2,7 +2,9 @@ import React, { useState, useEffect, useRef } from "react";
import { Flex, Box, Text } from "theme-ui";
import { useParams } from "react-router-dom";
-import Banner from "../components/Banner";
+import Banner from "../components/banner/Banner";
+import ReconnectBanner from "../components/banner/ReconnectBanner";
+import OfflineBanner from "../components/banner/OfflineBanner";
import LoadingOverlay from "../components/LoadingOverlay";
import Link from "../components/Link";
import MapLoadingOverlay from "../components/map/MapLoadingOverlay";
@@ -125,28 +127,8 @@ function Game() {
- {}}
- allowClose={false}
- >
-
-
- Unable to connect to game, refresh to reconnect.
-
-
-
- {}}
- allowClose={false}
- >
-
-
- Disconnected. Attempting to reconnect...
-
-
-
+
+