Added progress indicator to map data loading
This commit is contained in:
parent
a370b8e11d
commit
bf022e2686
@ -1,9 +1,9 @@
|
||||
import React from "react";
|
||||
import { Box } from "theme-ui";
|
||||
import { Box, Progress } from "theme-ui";
|
||||
|
||||
import Spinner from "./Spinner";
|
||||
|
||||
function LoadingOverlay() {
|
||||
function LoadingOverlay({ progress }) {
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
@ -15,10 +15,14 @@ function LoadingOverlay() {
|
||||
alignItems: "center",
|
||||
top: 0,
|
||||
left: 0,
|
||||
flexDirection: "column",
|
||||
}}
|
||||
bg="muted"
|
||||
>
|
||||
<Spinner />
|
||||
{progress && (
|
||||
<Progress max={1} value={progress} m={2} sx={{ width: "24px" }} />
|
||||
)}
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ function Map({
|
||||
disabledTokens,
|
||||
}) {
|
||||
const { tokensById } = useContext(TokenDataContext);
|
||||
const { isLoading } = useContext(MapLoadingContext);
|
||||
const { isLoading, loadingProgress } = useContext(MapLoadingContext);
|
||||
|
||||
const gridX = map && map.gridX;
|
||||
const gridY = map && map.gridY;
|
||||
@ -299,7 +299,7 @@ function Map({
|
||||
{tokenMenu}
|
||||
{tokenDragOverlay}
|
||||
<MapDice />
|
||||
{isLoading && <LoadingOverlay />}
|
||||
{isLoading && <LoadingOverlay progress={loadingProgress} />}
|
||||
</>
|
||||
}
|
||||
selectedToolId={selectedToolId}
|
||||
|
@ -1,4 +1,5 @@
|
||||
import React, { useState } from "react";
|
||||
import { omit, isEmpty } from "../helpers/shared";
|
||||
|
||||
const MapLoadingContext = React.createContext();
|
||||
|
||||
@ -13,12 +14,36 @@ export function MapLoadingProvider({ children }) {
|
||||
setLoadingAssetCount((prevLoadingAssets) => prevLoadingAssets - 1);
|
||||
}
|
||||
|
||||
const [assetProgress, setAssetProgress] = useState({});
|
||||
function assetProgressUpdate({ id, count, total }) {
|
||||
if (count === total) {
|
||||
setAssetProgress(omit(assetProgress, [id]));
|
||||
} else {
|
||||
setAssetProgress((prevAssetProgress) => ({
|
||||
...prevAssetProgress,
|
||||
[id]: { count, total },
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
const isLoading = loadingAssetCount > 0;
|
||||
let loadingProgress = null;
|
||||
if (!isEmpty(assetProgress)) {
|
||||
let total = 0;
|
||||
let count = 0;
|
||||
for (let progress of Object.values(assetProgress)) {
|
||||
total += progress.total;
|
||||
count += progress.count;
|
||||
}
|
||||
loadingProgress = count / total;
|
||||
}
|
||||
|
||||
const value = {
|
||||
assetLoadStart,
|
||||
assetLoadFinish,
|
||||
isLoading,
|
||||
assetProgressUpdate,
|
||||
loadingProgress,
|
||||
};
|
||||
|
||||
return (
|
||||
|
@ -29,6 +29,12 @@ class Peer extends SimplePeer {
|
||||
chunk.count++;
|
||||
this.currentChunks[unpacked.id] = chunk;
|
||||
|
||||
this.emit("dataProgress", {
|
||||
id: unpacked.id,
|
||||
count: chunk.count,
|
||||
total: chunk.total,
|
||||
});
|
||||
|
||||
// All chunks have been loaded
|
||||
if (chunk.count === chunk.total) {
|
||||
// Merge chunks with a blob
|
||||
|
@ -13,6 +13,7 @@ function useSession(
|
||||
onPeerConnected,
|
||||
onPeerDisconnected,
|
||||
onPeerData,
|
||||
onPeerDataProgress,
|
||||
onPeerTrackAdded,
|
||||
onPeerTrackRemoved,
|
||||
onPeerError
|
||||
@ -76,6 +77,10 @@ function useSession(
|
||||
onPeerData && onPeerData({ peer, data });
|
||||
}
|
||||
|
||||
function handleDataProgress({ id, count, total }) {
|
||||
onPeerDataProgress && onPeerDataProgress({ id, count, total });
|
||||
}
|
||||
|
||||
function handleTrack(track, stream) {
|
||||
onPeerTrackAdded && onPeerTrackAdded({ peer, track, stream });
|
||||
track.addEventListener("mute", () => {
|
||||
@ -96,6 +101,7 @@ function useSession(
|
||||
peer.connection.on("signal", handleSignal);
|
||||
peer.connection.on("connect", handleConnect);
|
||||
peer.connection.on("dataComplete", handleDataComplete);
|
||||
peer.connection.on("dataProgress", handleDataProgress);
|
||||
peer.connection.on("track", handleTrack);
|
||||
peer.connection.on("close", handleClose);
|
||||
peer.connection.on("error", handleError);
|
||||
@ -105,6 +111,7 @@ function useSession(
|
||||
handleSignal,
|
||||
handleConnect,
|
||||
handleDataComplete,
|
||||
handleDataProgress,
|
||||
handleTrack,
|
||||
handleClose,
|
||||
handleError,
|
||||
@ -118,6 +125,7 @@ function useSession(
|
||||
handleSignal,
|
||||
handleConnect,
|
||||
handleDataComplete,
|
||||
handleDataProgress,
|
||||
handleTrack,
|
||||
handleClose,
|
||||
handleError,
|
||||
@ -125,6 +133,7 @@ function useSession(
|
||||
peer.connection.off("signal", handleSignal);
|
||||
peer.connection.off("connect", handleConnect);
|
||||
peer.connection.off("dataComplete", handleDataComplete);
|
||||
peer.connection.off("dataProgress", handleDataProgress);
|
||||
peer.connection.off("track", handleTrack);
|
||||
peer.connection.off("close", handleClose);
|
||||
peer.connection.off("error", handleError);
|
||||
@ -135,6 +144,7 @@ function useSession(
|
||||
onPeerConnected,
|
||||
onPeerDisconnected,
|
||||
onPeerData,
|
||||
onPeerDataProgress,
|
||||
onPeerTrackAdded,
|
||||
onPeerTrackRemoved,
|
||||
onPeerError,
|
||||
|
@ -33,13 +33,16 @@ function Game() {
|
||||
const { authenticationStatus, userId, nickname, setNickname } = useContext(
|
||||
AuthContext
|
||||
);
|
||||
const { assetLoadStart, assetLoadFinish } = useContext(MapLoadingContext);
|
||||
const { assetLoadStart, assetLoadFinish, assetProgressUpdate } = useContext(
|
||||
MapLoadingContext
|
||||
);
|
||||
|
||||
const { peers, socket, connected } = useSession(
|
||||
gameId,
|
||||
handlePeerConnected,
|
||||
handlePeerDisconnected,
|
||||
handlePeerData,
|
||||
handlePeerDataProgress,
|
||||
handlePeerTrackAdded,
|
||||
handlePeerTrackRemoved,
|
||||
handlePeerError
|
||||
@ -322,7 +325,6 @@ function Game() {
|
||||
if (cachedMap && cachedMap.lastModified === newMap.lastModified) {
|
||||
setCurrentMap(cachedMap);
|
||||
} else {
|
||||
assetLoadStart();
|
||||
peer.connection.send({ id: "mapRequest", data: newMap.id });
|
||||
}
|
||||
} else {
|
||||
@ -336,7 +338,6 @@ function Game() {
|
||||
}
|
||||
// A new map response with a file attached
|
||||
if (data.id === "mapResponse") {
|
||||
assetLoadFinish();
|
||||
if (data.data && data.data.type === "file") {
|
||||
const newMap = { ...data.data, file: data.data.file };
|
||||
putMap(newMap).then(() => {
|
||||
@ -357,7 +358,6 @@ function Game() {
|
||||
!cachedToken ||
|
||||
cachedToken.lastModified !== newToken.lastModified
|
||||
) {
|
||||
assetLoadStart();
|
||||
peer.connection.send({
|
||||
id: "tokenRequest",
|
||||
data: newToken.id,
|
||||
@ -370,7 +370,6 @@ function Game() {
|
||||
peer.connection.send({ id: "tokenResponse", data: token });
|
||||
}
|
||||
if (data.id === "tokenResponse") {
|
||||
assetLoadFinish();
|
||||
const newToken = data.data;
|
||||
if (newToken && newToken.type === "file") {
|
||||
putToken(newToken);
|
||||
@ -414,6 +413,16 @@ function Game() {
|
||||
}
|
||||
}
|
||||
|
||||
function handlePeerDataProgress({ id, total, count }) {
|
||||
if (count === 1) {
|
||||
assetLoadStart();
|
||||
}
|
||||
if (total === count) {
|
||||
assetLoadFinish();
|
||||
}
|
||||
assetProgressUpdate({ id, total, count });
|
||||
}
|
||||
|
||||
function handlePeerDisconnected(peer) {
|
||||
setPartyNicknames((prevNicknames) => omit(prevNicknames, [peer.id]));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user