Added all files successfully converted
This commit is contained in:
@@ -1,13 +1,16 @@
|
||||
import React, { useState, useEffect, useContext } from "react";
|
||||
import React, { useState, useEffect, useContext, SetStateAction } from "react";
|
||||
import shortid from "shortid";
|
||||
|
||||
import { useDatabase } from "./DatabaseContext";
|
||||
|
||||
import FakeStorage from "../helpers/FakeStorage";
|
||||
|
||||
const AuthContext = React.createContext();
|
||||
type AuthContext = { userId: string; password: string; setPassword: React.Dispatch<any>; }
|
||||
|
||||
let storage;
|
||||
// TODO: check what default value we want here
|
||||
const AuthContext = React.createContext<AuthContext | undefined>(undefined);
|
||||
|
||||
let storage: Storage | FakeStorage;
|
||||
try {
|
||||
sessionStorage.setItem("__test", "__test");
|
||||
sessionStorage.removeItem("__test");
|
||||
@@ -17,28 +20,29 @@ try {
|
||||
storage = new FakeStorage();
|
||||
}
|
||||
|
||||
export function AuthProvider({ children }) {
|
||||
export function AuthProvider({ children }: { children: any }) {
|
||||
const { database, databaseStatus } = useDatabase();
|
||||
|
||||
const [password, setPassword] = useState(storage.getItem("auth") || "");
|
||||
const [password, setPassword] = useState<string>(storage.getItem("auth") || "");
|
||||
|
||||
useEffect(() => {
|
||||
storage.setItem("auth", password);
|
||||
}, [password]);
|
||||
|
||||
const [userId, setUserId] = useState();
|
||||
// TODO: check pattern here -> undefined or empty default values
|
||||
const [userId, setUserId]: [ userId: string, setUserId: React.Dispatch<SetStateAction<string>> ] = useState("");
|
||||
useEffect(() => {
|
||||
if (!database || databaseStatus === "loading") {
|
||||
return;
|
||||
}
|
||||
async function loadUserId() {
|
||||
const storedUserId = await database.table("user").get("userId");
|
||||
const storedUserId = await database?.table("user").get("userId");
|
||||
if (storedUserId) {
|
||||
setUserId(storedUserId.value);
|
||||
} else {
|
||||
const id = shortid.generate();
|
||||
setUserId(id);
|
||||
database.table("user").add({ key: "userId", value: id });
|
||||
database?.table("user").add({ key: "userId", value: id });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,20 +1,25 @@
|
||||
import React, { useState, useEffect, useContext } from "react";
|
||||
import * as Comlink from "comlink";
|
||||
import React, { useState, useEffect, useContext, SetStateAction } from "react";
|
||||
import Comlink, { Remote } from "comlink";
|
||||
|
||||
import ErrorBanner from "../components/banner/ErrorBanner";
|
||||
|
||||
import { getDatabase } from "../database";
|
||||
|
||||
//@ts-ignore
|
||||
import DatabaseWorker from "worker-loader!../workers/DatabaseWorker"; // eslint-disable-line import/no-webpack-loader-syntax
|
||||
import Dexie from "dexie";
|
||||
|
||||
const DatabaseContext = React.createContext();
|
||||
type DatabaseContext = { database: Dexie | undefined; databaseStatus: any; databaseError: Error | undefined; worker: Remote<any>; }
|
||||
|
||||
// TODO: check what default we want here
|
||||
const DatabaseContext = React.createContext< DatabaseContext | undefined>(undefined);
|
||||
|
||||
const worker = Comlink.wrap(new DatabaseWorker());
|
||||
|
||||
export function DatabaseProvider({ children }) {
|
||||
const [database, setDatabase] = useState();
|
||||
const [databaseStatus, setDatabaseStatus] = useState("loading");
|
||||
const [databaseError, setDatabaseError] = useState();
|
||||
export function DatabaseProvider({ children }: { children: any}) {
|
||||
const [database, setDatabase]: [ database: Dexie | undefined, setDatabase: React.Dispatch<SetStateAction<Dexie | undefined>>] = useState();
|
||||
const [databaseStatus, setDatabaseStatus]: [ datebaseStatus: any, setDatabaseStatus: React.Dispatch<SetStateAction<string>>] = useState("loading");
|
||||
const [databaseError, setDatabaseError]: [ databaseError: Error | undefined, setDatabaseError: React.Dispatch<SetStateAction<Error | undefined>>] = useState();
|
||||
|
||||
useEffect(() => {
|
||||
// Create a test database and open it to see if indexedDB is enabled
|
||||
@@ -43,7 +48,7 @@ export function DatabaseProvider({ children }) {
|
||||
window.indexedDB.deleteDatabase("__test");
|
||||
};
|
||||
|
||||
function handleDatabaseError(event) {
|
||||
function handleDatabaseError(event: any) {
|
||||
event.preventDefault();
|
||||
if (event.reason?.message.startsWith("QuotaExceededError")) {
|
||||
setDatabaseError({
|
||||
@@ -77,14 +82,14 @@ export function DatabaseProvider({ children }) {
|
||||
{children}
|
||||
<ErrorBanner
|
||||
error={databaseError}
|
||||
onRequestClose={() => setDatabaseError()}
|
||||
onRequestClose={() => setDatabaseError(undefined)}
|
||||
/>
|
||||
</>
|
||||
</DatabaseContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
export function useDatabase() {
|
||||
export function useDatabase(): DatabaseContext {
|
||||
const context = useContext(DatabaseContext);
|
||||
if (context === undefined) {
|
||||
throw new Error("useDatabase must be used within a DatabaseProvider");
|
||||
@@ -1,8 +1,14 @@
|
||||
import React, { useState, useContext } from "react";
|
||||
import React, { useState, useContext, ReactChild } from "react";
|
||||
|
||||
const DiceLoadingContext = React.createContext();
|
||||
type DiceLoadingContext = {
|
||||
assetLoadStart: any,
|
||||
assetLoadFinish: any,
|
||||
isLoading: boolean,
|
||||
}
|
||||
|
||||
export function DiceLoadingProvider({ children }) {
|
||||
const DiceLoadingContext = React.createContext<DiceLoadingContext | undefined>(undefined);
|
||||
|
||||
export function DiceLoadingProvider({ children }: { children: ReactChild }) {
|
||||
const [loadingAssetCount, setLoadingAssetCount] = useState(0);
|
||||
|
||||
function assetLoadStart() {
|
||||
@@ -28,7 +34,7 @@ export function DiceLoadingProvider({ children }) {
|
||||
);
|
||||
}
|
||||
|
||||
export function useDiceLoading() {
|
||||
export function useDiceLoading(): DiceLoadingContext {
|
||||
const context = useContext(DiceLoadingContext);
|
||||
if (context === undefined) {
|
||||
throw new Error("useDiceLoading must be used within a DiceLoadingProvider");
|
||||
@@ -15,11 +15,20 @@ import { getGridPixelSize, getCellPixelSize, Grid } from "../helpers/grid";
|
||||
* @property {number} gridStrokeWidth Stroke width of the grid in pixels
|
||||
* @property {Vector2} gridCellPixelOffset Offset of the grid cells to convert the center position of hex cells to the top left
|
||||
*/
|
||||
type GridContextValue = {
|
||||
grid: Grid,
|
||||
gridPixelSize: Size,
|
||||
gridCellPixelSize: Size,
|
||||
gridCellNormalizedSize: Size,
|
||||
gridOffset: Vector2,
|
||||
gridStrokeWidth: number,
|
||||
gridCellPixelOffset: Vector2
|
||||
}
|
||||
|
||||
/**
|
||||
* @type {GridContextValue}
|
||||
*/
|
||||
const defaultValue = {
|
||||
const defaultValue: GridContextValue = {
|
||||
grid: {
|
||||
size: new Vector2(0, 0),
|
||||
inset: { topLeft: new Vector2(0, 0), bottomRight: new Vector2(1, 1) },
|
||||
@@ -57,11 +66,11 @@ export const GridCellPixelOffsetContext = React.createContext(
|
||||
|
||||
const defaultStrokeWidth = 1 / 10;
|
||||
|
||||
export function GridProvider({ grid: inputGrid, width, height, children }) {
|
||||
export function GridProvider({ grid: inputGrid, width, height, children }: { grid: Required<Grid>, width: number, height: number, children: any }) {
|
||||
let grid = inputGrid;
|
||||
|
||||
if (!grid?.size.x || !grid?.size.y) {
|
||||
grid = defaultValue.grid;
|
||||
if (!grid.size.x || !grid.size.y) {
|
||||
grid = defaultValue.grid as Required<Grid>;
|
||||
}
|
||||
|
||||
const [gridPixelSize, setGridPixelSize] = useState(
|
||||
@@ -1,27 +1,28 @@
|
||||
import React, { useContext, useState, useEffect } from "react";
|
||||
import React, { useContext, useState, useEffect, ReactChild } from "react";
|
||||
import { ImageFile } from "../helpers/image";
|
||||
|
||||
import { omit } from "../helpers/shared";
|
||||
|
||||
export const ImageSourcesStateContext = React.createContext();
|
||||
export const ImageSourcesUpdaterContext = React.createContext(() => {});
|
||||
export const ImageSourcesStateContext = React.createContext(undefined) as any;
|
||||
export const ImageSourcesUpdaterContext = React.createContext(() => {}) as any;
|
||||
|
||||
/**
|
||||
* Helper to manage sharing of custom image sources between uses of useImageSource
|
||||
*/
|
||||
export function ImageSourcesProvider({ children }) {
|
||||
const [imageSources, setImageSources] = useState({});
|
||||
export function ImageSourcesProvider({ children }: { children: ReactChild }) {
|
||||
const [imageSources, setImageSources] = useState<any>({});
|
||||
|
||||
// Revoke url when no more references
|
||||
useEffect(() => {
|
||||
let sourcesToCleanup = [];
|
||||
for (let source of Object.values(imageSources)) {
|
||||
let sourcesToCleanup: any = [];
|
||||
for (let source of Object.values(imageSources) as any) {
|
||||
if (source.references <= 0) {
|
||||
URL.revokeObjectURL(source.url);
|
||||
sourcesToCleanup.push(source.id);
|
||||
}
|
||||
}
|
||||
if (sourcesToCleanup.length > 0) {
|
||||
setImageSources((prevSources) => omit(prevSources, sourcesToCleanup));
|
||||
setImageSources((prevSources: any) => omit(prevSources, sourcesToCleanup));
|
||||
}
|
||||
}, [imageSources]);
|
||||
|
||||
@@ -37,7 +38,7 @@ export function ImageSourcesProvider({ children }) {
|
||||
/**
|
||||
* Get id from image data
|
||||
*/
|
||||
function getImageFileId(data, thumbnail) {
|
||||
function getImageFileId(data: any, thumbnail: ImageFile) {
|
||||
if (thumbnail) {
|
||||
return `${data.id}-thumbnail`;
|
||||
}
|
||||
@@ -48,7 +49,7 @@ function getImageFileId(data, thumbnail) {
|
||||
} else if (!data.file) {
|
||||
// Fallback to the highest resolution
|
||||
const resolutionArray = Object.keys(data.resolutions);
|
||||
const resolution = resolutionArray[resolutionArray.length - 1];
|
||||
const resolution: any = resolutionArray[resolutionArray.length - 1];
|
||||
return `${data.id}-${resolution.id}`;
|
||||
}
|
||||
}
|
||||
@@ -58,14 +59,14 @@ function getImageFileId(data, thumbnail) {
|
||||
/**
|
||||
* Helper function to load either file or default image into a URL
|
||||
*/
|
||||
export function useImageSource(data, defaultSources, unknownSource, thumbnail) {
|
||||
const imageSources = useContext(ImageSourcesStateContext);
|
||||
export function useImageSource(data: any, defaultSources: string, unknownSource: string, thumbnail: ImageFile) {
|
||||
const imageSources: any = useContext(ImageSourcesStateContext);
|
||||
if (imageSources === undefined) {
|
||||
throw new Error(
|
||||
"useImageSource must be used within a ImageSourcesProvider"
|
||||
);
|
||||
}
|
||||
const setImageSources = useContext(ImageSourcesUpdaterContext);
|
||||
const setImageSources: any = useContext(ImageSourcesUpdaterContext);
|
||||
if (setImageSources === undefined) {
|
||||
throw new Error(
|
||||
"useImageSource must be used within a ImageSourcesProvider"
|
||||
@@ -78,9 +79,9 @@ export function useImageSource(data, defaultSources, unknownSource, thumbnail) {
|
||||
}
|
||||
const id = getImageFileId(data, thumbnail);
|
||||
|
||||
function updateImageSource(file) {
|
||||
function updateImageSource(file: File) {
|
||||
if (file) {
|
||||
setImageSources((prevSources) => {
|
||||
setImageSources((prevSources: any) => {
|
||||
if (id in prevSources) {
|
||||
// Check if the image source is already added
|
||||
return {
|
||||
@@ -124,7 +125,7 @@ export function useImageSource(data, defaultSources, unknownSource, thumbnail) {
|
||||
|
||||
return () => {
|
||||
// Decrease references
|
||||
setImageSources((prevSources) => {
|
||||
setImageSources((prevSources: any) => {
|
||||
if (id in prevSources) {
|
||||
return {
|
||||
...prevSources,
|
||||
@@ -4,6 +4,7 @@ import React, {
|
||||
useContext,
|
||||
useCallback,
|
||||
useRef,
|
||||
ReactChild,
|
||||
} from "react";
|
||||
import * as Comlink from "comlink";
|
||||
import { decode, encode } from "@msgpack/msgpack";
|
||||
@@ -12,42 +13,66 @@ import { useAuth } from "./AuthContext";
|
||||
import { useDatabase } from "./DatabaseContext";
|
||||
|
||||
import { maps as defaultMaps } from "../maps";
|
||||
import { Map, MapState, Note, TokenState } from "../components/map/Map";
|
||||
import { Fog } from "../helpers/drawing";
|
||||
|
||||
const MapDataContext = React.createContext();
|
||||
|
||||
// TODO: fix differences in types between default maps and imported maps
|
||||
type MapDataContext = {
|
||||
maps: Array<Map>,
|
||||
ownedMaps: Array<Map>
|
||||
mapStates: MapState[],
|
||||
addMap: (map: Map) => void,
|
||||
removeMap: (id: string) => void,
|
||||
removeMaps: (ids: string[]) => void,
|
||||
resetMap: (id: string) => void,
|
||||
updateMap: (id: string, update: Partial<Map>) => void,
|
||||
updateMaps: (ids: string[], update: Partial<Map>) => void,
|
||||
updateMapState: (id: string, update: Partial<MapState>) => void,
|
||||
putMap: (map: Map) => void,
|
||||
getMap: (id: string) => Map | undefined,
|
||||
getMapFromDB: (id: string) => Promise<Map>,
|
||||
mapsLoading: boolean,
|
||||
getMapStateFromDB: (id: string) => Promise<MapState>,
|
||||
}
|
||||
|
||||
const MapDataContext = React.createContext<MapDataContext | undefined>(undefined);
|
||||
|
||||
// Maximum number of maps to keep in the cache
|
||||
const cachedMapMax = 15;
|
||||
|
||||
const defaultMapState = {
|
||||
tokens: {},
|
||||
drawShapes: {},
|
||||
fogShapes: {},
|
||||
const defaultMapState: MapState = {
|
||||
mapId: "",
|
||||
tokens: {} as Record<string, TokenState>,
|
||||
drawShapes: {} as any,
|
||||
fogShapes: {} as Fog[],
|
||||
// Flags to determine what other people can edit
|
||||
editFlags: ["drawing", "tokens", "notes"],
|
||||
notes: {},
|
||||
editFlags: ["drawing", "tokens", "notes", "fog"],
|
||||
notes: {} as Note[],
|
||||
};
|
||||
|
||||
export function MapDataProvider({ children }) {
|
||||
export function MapDataProvider({ children }: { children: ReactChild }) {
|
||||
const { database, databaseStatus, worker } = useDatabase();
|
||||
const { userId } = useAuth();
|
||||
|
||||
const [maps, setMaps] = useState([]);
|
||||
const [mapStates, setMapStates] = useState([]);
|
||||
const [mapsLoading, setMapsLoading] = useState(true);
|
||||
const [maps, setMaps] = useState<Array<Map>>([]);
|
||||
const [mapStates, setMapStates] = useState<MapState[]>([]);
|
||||
const [mapsLoading, setMapsLoading] = useState<boolean>(true);
|
||||
|
||||
// Load maps from the database and ensure state is properly setup
|
||||
// Load maps from the database and ensure state is properly seup
|
||||
useEffect(() => {
|
||||
if (!userId || !database || databaseStatus === "loading") {
|
||||
return;
|
||||
}
|
||||
async function getDefaultMaps() {
|
||||
const defaultMapsWithIds = [];
|
||||
async function getDefaultMaps(): Promise<Map[]> {
|
||||
const defaultMapsWithIds: Array<Map> = [];
|
||||
for (let i = 0; i < defaultMaps.length; i++) {
|
||||
const defaultMap = defaultMaps[i];
|
||||
const id = `__default-${defaultMap.name}`;
|
||||
const mapId = `__default-${defaultMap.name}`;
|
||||
defaultMapsWithIds.push({
|
||||
...defaultMap,
|
||||
id,
|
||||
lastUsed: Date.now() + i,
|
||||
id: mapId,
|
||||
owner: userId,
|
||||
// Emulate the time increasing to avoid sort errors
|
||||
created: Date.now() + i,
|
||||
@@ -57,9 +82,9 @@ export function MapDataProvider({ children }) {
|
||||
group: "default",
|
||||
});
|
||||
// Add a state for the map if there isn't one already
|
||||
const state = await database.table("states").get(id);
|
||||
const state = await database?.table("states").get(mapId);
|
||||
if (!state) {
|
||||
await database.table("states").add({ ...defaultMapState, mapId: id });
|
||||
await database?.table("states").add({ ...defaultMapState, mapId: mapId });
|
||||
}
|
||||
}
|
||||
return defaultMapsWithIds;
|
||||
@@ -67,24 +92,24 @@ export function MapDataProvider({ children }) {
|
||||
|
||||
// Loads maps without the file data to save memory
|
||||
async function loadMaps() {
|
||||
let storedMaps = [];
|
||||
let storedMaps: Map[] = [];
|
||||
// Try to load maps with worker, fallback to database if failed
|
||||
const packedMaps = await worker.loadData("maps");
|
||||
// let packedMaps;
|
||||
if (packedMaps) {
|
||||
storedMaps = decode(packedMaps);
|
||||
storedMaps = decode(packedMaps) as Map[];
|
||||
} else {
|
||||
console.warn("Unable to load maps with worker, loading may be slow");
|
||||
await database.table("maps").each((map) => {
|
||||
await database?.table("maps").each((map) => {
|
||||
const { file, resolutions, ...rest } = map;
|
||||
storedMaps.push(rest);
|
||||
});
|
||||
}
|
||||
const sortedMaps = storedMaps.sort((a, b) => b.created - a.created);
|
||||
const defaultMapsWithIds = await getDefaultMaps();
|
||||
const allMaps = [...sortedMaps, ...defaultMapsWithIds];
|
||||
const allMaps: Array<Map> = [...sortedMaps, ...defaultMapsWithIds];
|
||||
setMaps(allMaps);
|
||||
const storedStates = await database.table("states").toArray();
|
||||
const storedStates = await database?.table("states").toArray() as MapState[];
|
||||
setMapStates(storedStates);
|
||||
setMapsLoading(false);
|
||||
}
|
||||
@@ -103,7 +128,7 @@ export function MapDataProvider({ children }) {
|
||||
|
||||
const getMapFromDB = useCallback(
|
||||
async (mapId) => {
|
||||
let map = await database.table("maps").get(mapId);
|
||||
let map = await database?.table("maps").get(mapId) as Map;
|
||||
return map;
|
||||
},
|
||||
[database]
|
||||
@@ -111,7 +136,7 @@ export function MapDataProvider({ children }) {
|
||||
|
||||
const getMapStateFromDB = useCallback(
|
||||
async (mapId) => {
|
||||
let mapState = await database.table("states").get(mapId);
|
||||
let mapState = await database?.table("states").get(mapId) as MapState;
|
||||
return mapState;
|
||||
},
|
||||
[database]
|
||||
@@ -122,30 +147,26 @@ export function MapDataProvider({ children }) {
|
||||
* Sorted by when they we're last used
|
||||
*/
|
||||
const updateCache = useCallback(async () => {
|
||||
const cachedMaps = await database
|
||||
.table("maps")
|
||||
.where("owner")
|
||||
.notEqual(userId)
|
||||
.sortBy("lastUsed");
|
||||
const cachedMaps = await database?.table("maps").where("owner").notEqual(userId).sortBy("lastUsed") as Map[];
|
||||
if (cachedMaps.length > cachedMapMax) {
|
||||
const cacheDeleteCount = cachedMaps.length - cachedMapMax;
|
||||
const idsToDelete = cachedMaps
|
||||
.slice(0, cacheDeleteCount)
|
||||
.map((map) => map.id);
|
||||
database.table("maps").where("id").anyOf(idsToDelete).delete();
|
||||
.map((map: Map) => map.id);
|
||||
database?.table("maps").where("id").anyOf(idsToDelete).delete();
|
||||
}
|
||||
}, [database, userId]);
|
||||
|
||||
/**
|
||||
* Adds a map to the database, also adds an assosiated state for that map
|
||||
* @param {Object} map map to add
|
||||
* @param {Map} map map to add
|
||||
*/
|
||||
const addMap = useCallback(
|
||||
async (map) => {
|
||||
// Just update map database as react state will be updated with an Observable
|
||||
const state = { ...defaultMapState, mapId: map.id };
|
||||
await database.table("maps").add(map);
|
||||
await database.table("states").add(state);
|
||||
await database?.table("maps").add(map);
|
||||
await database?.table("states").add(state);
|
||||
if (map.owner !== userId) {
|
||||
await updateCache();
|
||||
}
|
||||
@@ -155,16 +176,16 @@ export function MapDataProvider({ children }) {
|
||||
|
||||
const removeMap = useCallback(
|
||||
async (id) => {
|
||||
await database.table("maps").delete(id);
|
||||
await database.table("states").delete(id);
|
||||
await database?.table("maps").delete(id);
|
||||
await database?.table("states").delete(id);
|
||||
},
|
||||
[database]
|
||||
);
|
||||
|
||||
const removeMaps = useCallback(
|
||||
async (ids) => {
|
||||
await database.table("maps").bulkDelete(ids);
|
||||
await database.table("states").bulkDelete(ids);
|
||||
await database?.table("maps").bulkDelete(ids);
|
||||
await database?.table("states").bulkDelete(ids);
|
||||
},
|
||||
[database]
|
||||
);
|
||||
@@ -172,7 +193,7 @@ export function MapDataProvider({ children }) {
|
||||
const resetMap = useCallback(
|
||||
async (id) => {
|
||||
const state = { ...defaultMapState, mapId: id };
|
||||
await database.table("states").put(state);
|
||||
await database?.table("states").put(state);
|
||||
return state;
|
||||
},
|
||||
[database]
|
||||
@@ -183,10 +204,10 @@ export function MapDataProvider({ children }) {
|
||||
// fake-indexeddb throws an error when updating maps in production.
|
||||
// Catch that error and use put when it fails
|
||||
try {
|
||||
await database.table("maps").update(id, update);
|
||||
await database?.table("maps").update(id, update);
|
||||
} catch (error) {
|
||||
const map = (await getMapFromDB(id)) || {};
|
||||
await database.table("maps").put({ ...map, id, ...update });
|
||||
await database?.table("maps").put({ ...map, id, ...update });
|
||||
}
|
||||
},
|
||||
[database, getMapFromDB]
|
||||
@@ -195,7 +216,7 @@ export function MapDataProvider({ children }) {
|
||||
const updateMaps = useCallback(
|
||||
async (ids, update) => {
|
||||
await Promise.all(
|
||||
ids.map((id) => database.table("maps").update(id, update))
|
||||
ids.map((id: string) => database?.table("maps").update(id, update))
|
||||
);
|
||||
},
|
||||
[database]
|
||||
@@ -203,7 +224,7 @@ export function MapDataProvider({ children }) {
|
||||
|
||||
const updateMapState = useCallback(
|
||||
async (id, update) => {
|
||||
await database.table("states").update(id, update);
|
||||
await database?.table("states").update(id, update);
|
||||
},
|
||||
[database]
|
||||
);
|
||||
@@ -223,7 +244,7 @@ export function MapDataProvider({ children }) {
|
||||
false
|
||||
);
|
||||
if (!success) {
|
||||
await database.table("maps").put(map);
|
||||
await database?.table("maps").put(map);
|
||||
}
|
||||
if (map.owner !== userId) {
|
||||
await updateCache();
|
||||
@@ -238,13 +259,13 @@ export function MapDataProvider({ children }) {
|
||||
return;
|
||||
}
|
||||
|
||||
function handleMapChanges(changes) {
|
||||
function handleMapChanges(changes: any) {
|
||||
for (let change of changes) {
|
||||
if (change.table === "maps") {
|
||||
if (change.type === 1) {
|
||||
// Created
|
||||
const map = change.obj;
|
||||
const state = { ...defaultMapState, mapId: map.id };
|
||||
const map: Map = change.obj;
|
||||
const state: MapState = { ...defaultMapState, mapId: map.id };
|
||||
setMaps((prevMaps) => [map, ...prevMaps]);
|
||||
setMapStates((prevStates) => [state, ...prevStates]);
|
||||
} else if (change.type === 2) {
|
||||
@@ -1,16 +1,16 @@
|
||||
import React, { useContext } from "react";
|
||||
import React, { ReactChild, useContext } from "react";
|
||||
import useDebounce from "../hooks/useDebounce";
|
||||
|
||||
export const StageScaleContext = React.createContext();
|
||||
export const DebouncedStageScaleContext = React.createContext();
|
||||
export const StageWidthContext = React.createContext();
|
||||
export const StageHeightContext = React.createContext();
|
||||
export const SetPreventMapInteractionContext = React.createContext();
|
||||
export const MapWidthContext = React.createContext();
|
||||
export const MapHeightContext = React.createContext();
|
||||
export const InteractionEmitterContext = React.createContext();
|
||||
export const StageScaleContext = React.createContext(undefined) as any;
|
||||
export const DebouncedStageScaleContext = React.createContext(undefined) as any;
|
||||
export const StageWidthContext = React.createContext(undefined) as any;
|
||||
export const StageHeightContext = React.createContext(undefined) as any;
|
||||
export const SetPreventMapInteractionContext = React.createContext(undefined) as any;
|
||||
export const MapWidthContext = React.createContext(undefined) as any;
|
||||
export const MapHeightContext = React.createContext(undefined) as any;
|
||||
export const InteractionEmitterContext = React.createContext(undefined) as any;
|
||||
|
||||
export function MapInteractionProvider({ value, children }) {
|
||||
export function MapInteractionProvider({ value, children }: { value: any, children: ReactChild[]}) {
|
||||
const {
|
||||
stageScale,
|
||||
stageWidth,
|
||||
@@ -1,9 +1,9 @@
|
||||
import React, { useState, useRef, useContext } from "react";
|
||||
import { omit, isEmpty } from "../helpers/shared";
|
||||
|
||||
const MapLoadingContext = React.createContext();
|
||||
const MapLoadingContext = React.createContext<any | undefined>(undefined);
|
||||
|
||||
export function MapLoadingProvider({ children }) {
|
||||
export function MapLoadingProvider({ children }: { children: any}) {
|
||||
const [loadingAssetCount, setLoadingAssetCount] = useState(0);
|
||||
|
||||
function assetLoadStart() {
|
||||
@@ -14,9 +14,9 @@ export function MapLoadingProvider({ children }) {
|
||||
setLoadingAssetCount((prevLoadingAssets) => prevLoadingAssets - 1);
|
||||
}
|
||||
|
||||
const assetProgressRef = useRef({});
|
||||
const loadingProgressRef = useRef(null);
|
||||
function assetProgressUpdate({ id, count, total }) {
|
||||
const assetProgressRef = useRef<any>({});
|
||||
const loadingProgressRef = useRef<number | null>(null);
|
||||
function assetProgressUpdate({ id, count, total }: { id: string, count: number, total: number }) {
|
||||
if (count === total) {
|
||||
assetProgressRef.current = omit(assetProgressRef.current, [id]);
|
||||
} else {
|
||||
@@ -28,7 +28,7 @@ export function MapLoadingProvider({ children }) {
|
||||
if (!isEmpty(assetProgressRef.current)) {
|
||||
let total = 0;
|
||||
let count = 0;
|
||||
for (let progress of Object.values(assetProgressRef.current)) {
|
||||
for (let progress of Object.values(assetProgressRef.current) as any) {
|
||||
total += progress.total;
|
||||
count += progress.count;
|
||||
}
|
||||
@@ -3,7 +3,7 @@ import React, { useContext } from "react";
|
||||
const MapStageContext = React.createContext({
|
||||
mapStageRef: { current: null },
|
||||
});
|
||||
export const MapStageProvider = MapStageContext.Provider;
|
||||
export const MapStageProvider: any = MapStageContext.Provider;
|
||||
|
||||
export function useMapStage() {
|
||||
const context = useContext(MapStageContext);
|
||||
@@ -1,12 +1,14 @@
|
||||
import React, { useState, useEffect, useContext } from "react";
|
||||
import { PartyState } from "../components/party/PartyState";
|
||||
import Session from "../network/Session";
|
||||
|
||||
const PartyContext = React.createContext();
|
||||
const PartyContext = React.createContext<PartyState | undefined>(undefined);
|
||||
|
||||
export function PartyProvider({ session, children }) {
|
||||
export function PartyProvider({ session, children }: { session: Session, children: any}) {
|
||||
const [partyState, setPartyState] = useState({});
|
||||
|
||||
useEffect(() => {
|
||||
function handleSocketPartyState(partyState) {
|
||||
function handleSocketPartyState(partyState: PartyState) {
|
||||
if (partyState) {
|
||||
const { [session.id]: _, ...otherMembersState } = partyState;
|
||||
setPartyState(otherMembersState);
|
||||
@@ -6,11 +6,13 @@ import { useAuth } from "./AuthContext";
|
||||
import { getRandomMonster } from "../helpers/monsters";
|
||||
|
||||
import useNetworkedState from "../hooks/useNetworkedState";
|
||||
import Session from "../network/Session";
|
||||
import { PlayerInfo } from "../components/party/PartyState";
|
||||
|
||||
export const PlayerStateContext = React.createContext();
|
||||
export const PlayerUpdaterContext = React.createContext(() => {});
|
||||
export const PlayerStateContext = React.createContext<any>(undefined);
|
||||
export const PlayerUpdaterContext = React.createContext<any>(() => {});
|
||||
|
||||
export function PlayerProvider({ session, children }) {
|
||||
export function PlayerProvider({ session, children }: { session: Session, children: any}) {
|
||||
const { userId } = useAuth();
|
||||
const { database, databaseStatus } = useDatabase();
|
||||
|
||||
@@ -33,16 +35,16 @@ export function PlayerProvider({ session, children }) {
|
||||
return;
|
||||
}
|
||||
async function loadNickname() {
|
||||
const storedNickname = await database.table("user").get("nickname");
|
||||
const storedNickname = await database?.table("user").get("nickname");
|
||||
if (storedNickname !== undefined) {
|
||||
setPlayerState((prevState) => ({
|
||||
setPlayerState((prevState: PlayerInfo) => ({
|
||||
...prevState,
|
||||
nickname: storedNickname.value,
|
||||
}));
|
||||
} else {
|
||||
const name = getRandomMonster();
|
||||
setPlayerState((prevState) => ({ ...prevState, nickname: name }));
|
||||
database.table("user").add({ key: "nickname", value: name });
|
||||
setPlayerState((prevState: any) => ({ ...prevState, nickname: name }));
|
||||
database?.table("user").add({ key: "nickname", value: name });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,7 +65,7 @@ export function PlayerProvider({ session, children }) {
|
||||
|
||||
useEffect(() => {
|
||||
if (userId) {
|
||||
setPlayerState((prevState) => {
|
||||
setPlayerState((prevState: PlayerInfo) => {
|
||||
if (prevState) {
|
||||
return {
|
||||
...prevState,
|
||||
@@ -77,7 +79,8 @@ export function PlayerProvider({ session, children }) {
|
||||
|
||||
useEffect(() => {
|
||||
function updateSessionId() {
|
||||
setPlayerState((prevState) => {
|
||||
setPlayerState((prevState: PlayerInfo) => {
|
||||
// TODO: check useNetworkState requirements here
|
||||
if (prevState) {
|
||||
return {
|
||||
...prevState,
|
||||
@@ -92,7 +95,7 @@ export function PlayerProvider({ session, children }) {
|
||||
updateSessionId();
|
||||
}
|
||||
|
||||
function handleSocketStatus(status) {
|
||||
function handleSocketStatus(status: string) {
|
||||
if (status === "joined") {
|
||||
updateSessionId();
|
||||
}
|
||||
@@ -9,14 +9,14 @@ const SettingsContext = React.createContext({
|
||||
|
||||
const settingsProvider = getSettings();
|
||||
|
||||
export function SettingsProvider({ children }) {
|
||||
export function SettingsProvider({ children }: { children: any }) {
|
||||
const [settings, setSettings] = useState(settingsProvider.getAll());
|
||||
|
||||
useEffect(() => {
|
||||
settingsProvider.setAll(settings);
|
||||
}, [settings]);
|
||||
|
||||
const value = {
|
||||
const value: { settings: any, setSettings: any} = {
|
||||
settings,
|
||||
setSettings,
|
||||
};
|
||||
Reference in New Issue
Block a user