Added shared grid context and moved away from calling useContext directly
This commit is contained in:
parent
8991be923e
commit
f20173de35
@ -1,50 +1,43 @@
|
||||
import React from "react";
|
||||
import { Line, Group, RegularPolygon } from "react-konva";
|
||||
|
||||
import { getStrokeWidth } from "../helpers/drawing";
|
||||
import {
|
||||
getCellSize,
|
||||
getCellLocation,
|
||||
gridClipFunction,
|
||||
shouldClipCell,
|
||||
} from "../helpers/grid";
|
||||
|
||||
function Grid({ grid, strokeWidth, width, height, stroke }) {
|
||||
import { useGrid } from "../contexts/GridContext";
|
||||
|
||||
function Grid({ strokeWidth, stroke }) {
|
||||
const {
|
||||
grid,
|
||||
gridStrokeWidth,
|
||||
gridPixelSize,
|
||||
gridOffset,
|
||||
gridCellPixelSize,
|
||||
} = useGrid();
|
||||
|
||||
if (!grid?.size.x || !grid?.size.y) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const gridSizeNormalized = {
|
||||
x: (grid.inset.bottomRight.x - grid.inset.topLeft.x) / grid.size.x,
|
||||
y: (grid.inset.bottomRight.y - grid.inset.topLeft.y) / grid.size.y,
|
||||
};
|
||||
|
||||
const insetWidth = (grid.inset.bottomRight.x - grid.inset.topLeft.x) * width;
|
||||
const insetHeight =
|
||||
(grid.inset.bottomRight.y - grid.inset.topLeft.y) * height;
|
||||
|
||||
const offsetX = grid.inset.topLeft.x * width * -1;
|
||||
const offsetY = grid.inset.topLeft.y * height * -1;
|
||||
|
||||
const cellSize = getCellSize(grid, insetWidth, insetHeight);
|
||||
|
||||
const shapes = [];
|
||||
if (grid.type === "square") {
|
||||
for (let x = 1; x < grid.size.x; x++) {
|
||||
shapes.push(
|
||||
<Line
|
||||
key={`grid_x_${x}`}
|
||||
points={[x * cellSize.width, 0, x * cellSize.width, insetHeight]}
|
||||
points={[
|
||||
x * gridCellPixelSize.width,
|
||||
0,
|
||||
x * gridCellPixelSize.width,
|
||||
gridPixelSize.height,
|
||||
]}
|
||||
stroke={stroke}
|
||||
strokeWidth={getStrokeWidth(
|
||||
strokeWidth,
|
||||
gridSizeNormalized,
|
||||
width,
|
||||
height
|
||||
)}
|
||||
strokeWidth={gridStrokeWidth * strokeWidth}
|
||||
opacity={0.5}
|
||||
offsetX={offsetX}
|
||||
offsetY={offsetY}
|
||||
offset={gridOffset}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@ -52,17 +45,16 @@ function Grid({ grid, strokeWidth, width, height, stroke }) {
|
||||
shapes.push(
|
||||
<Line
|
||||
key={`grid_y_${y}`}
|
||||
points={[0, y * cellSize.height, insetWidth, y * cellSize.height]}
|
||||
points={[
|
||||
0,
|
||||
y * gridCellPixelSize.height,
|
||||
gridPixelSize.width,
|
||||
y * gridCellPixelSize.height,
|
||||
]}
|
||||
stroke={stroke}
|
||||
strokeWidth={getStrokeWidth(
|
||||
strokeWidth,
|
||||
gridSizeNormalized,
|
||||
width,
|
||||
height
|
||||
)}
|
||||
strokeWidth={gridStrokeWidth * strokeWidth}
|
||||
opacity={0.5}
|
||||
offsetX={offsetX}
|
||||
offsetY={offsetY}
|
||||
offset={gridOffset}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@ -70,29 +62,24 @@ function Grid({ grid, strokeWidth, width, height, stroke }) {
|
||||
// Start at -1 to overshoot the bounds of the grid to ensure all lines are drawn
|
||||
for (let x = -1; x < grid.size.x; x++) {
|
||||
for (let y = -1; y < grid.size.y; y++) {
|
||||
const cellLocation = getCellLocation(grid, x, y, cellSize);
|
||||
const cellLocation = getCellLocation(grid, x, y, gridCellPixelSize);
|
||||
shapes.push(
|
||||
<Group
|
||||
key={`grid_${x}_${y}`}
|
||||
clipFunc={
|
||||
shouldClipCell(grid, x, y) &&
|
||||
((context) => gridClipFunction(context, grid, x, y, cellSize))
|
||||
((context) =>
|
||||
gridClipFunction(context, grid, x, y, gridCellPixelSize))
|
||||
}
|
||||
x={cellLocation.x}
|
||||
y={cellLocation.y}
|
||||
offsetX={offsetX}
|
||||
offsetY={offsetY}
|
||||
offset={gridOffset}
|
||||
>
|
||||
<RegularPolygon
|
||||
sides={6}
|
||||
radius={cellSize.radius}
|
||||
radius={gridCellPixelSize.radius}
|
||||
stroke={stroke}
|
||||
strokeWidth={getStrokeWidth(
|
||||
strokeWidth,
|
||||
gridSizeNormalized,
|
||||
width,
|
||||
height
|
||||
)}
|
||||
strokeWidth={gridStrokeWidth * strokeWidth}
|
||||
opacity={0.5}
|
||||
rotation={grid.type === "hexVertical" ? 0 : 90}
|
||||
/>
|
||||
|
@ -1,10 +1,4 @@
|
||||
import React, {
|
||||
useRef,
|
||||
useCallback,
|
||||
useEffect,
|
||||
useContext,
|
||||
useState,
|
||||
} from "react";
|
||||
import React, { useRef, useCallback, useEffect, useState } from "react";
|
||||
import { Vector3 } from "@babylonjs/core/Maths/math";
|
||||
import { DirectionalLight } from "@babylonjs/core/Lights/directionalLight";
|
||||
import { ShadowGenerator } from "@babylonjs/core/Lights/Shadows/shadowGenerator";
|
||||
@ -21,7 +15,7 @@ import DiceResults from "./DiceResults";
|
||||
|
||||
import DiceTray from "../../dice/diceTray/DiceTray";
|
||||
|
||||
import DiceLoadingContext from "../../contexts/DiceLoadingContext";
|
||||
import { useDiceLoading } from "../../contexts/DiceLoadingContext";
|
||||
|
||||
import { getDiceRoll } from "../../helpers/dice";
|
||||
import useSetting from "../../hooks/useSetting";
|
||||
@ -43,9 +37,7 @@ function DiceTrayOverlay({
|
||||
const diceTrayRef = useRef();
|
||||
|
||||
const [diceTraySize, setDiceTraySize] = useState("single");
|
||||
const { assetLoadStart, assetLoadFinish, isLoading } = useContext(
|
||||
DiceLoadingContext
|
||||
);
|
||||
const { assetLoadStart, assetLoadFinish, isLoading } = useDiceLoading();
|
||||
const [fullScreen] = useSetting("map.fullScreen");
|
||||
|
||||
function handleAssetLoadStart() {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useState, useContext } from "react";
|
||||
import React, { useState } from "react";
|
||||
import { Group } from "react-konva";
|
||||
|
||||
import MapControls from "./MapControls";
|
||||
@ -11,8 +11,8 @@ import MapMeasure from "./MapMeasure";
|
||||
import NetworkedMapPointer from "../../network/NetworkedMapPointer";
|
||||
import MapNotes from "./MapNotes";
|
||||
|
||||
import TokenDataContext from "../../contexts/TokenDataContext";
|
||||
import SettingsContext from "../../contexts/SettingsContext";
|
||||
import { useTokenData } from "../../contexts/TokenDataContext";
|
||||
import { useSettings } from "../../contexts/SettingsContext";
|
||||
|
||||
import TokenMenu from "../token/TokenMenu";
|
||||
import TokenDragOverlay from "../token/TokenDragOverlay";
|
||||
@ -49,19 +49,10 @@ function Map({
|
||||
disabledTokens,
|
||||
session,
|
||||
}) {
|
||||
const { tokensById } = useContext(TokenDataContext);
|
||||
|
||||
const gridX = map && map.grid.size.x;
|
||||
const gridY = map && map.grid.size.y;
|
||||
const inset = map && map.grid.inset;
|
||||
const gridSizeNormalized = {
|
||||
x: gridX ? (inset.bottomRight.x - inset.topLeft.x) / gridX : 0,
|
||||
y: gridY ? (inset.bottomRight.y - inset.topLeft.y) / gridY : 0,
|
||||
};
|
||||
const tokenSizePercent = gridSizeNormalized.x;
|
||||
const { tokensById } = useTokenData();
|
||||
|
||||
const [selectedToolId, setSelectedToolId] = useState("pan");
|
||||
const { settings, setSettings } = useContext(SettingsContext);
|
||||
const { settings, setSettings } = useSettings();
|
||||
|
||||
function handleToolSettingChange(tool, change) {
|
||||
setSettings((prevSettings) => ({
|
||||
@ -243,7 +234,6 @@ function Map({
|
||||
key={tokenState.id}
|
||||
token={tokensById[tokenState.tokenId]}
|
||||
tokenState={tokenState}
|
||||
tokenSizePercent={tokenSizePercent}
|
||||
onTokenStateChange={onMapTokenStateChange}
|
||||
onTokenMenuOpen={handleTokenMenuOpen}
|
||||
onTokenDragStart={(e) =>
|
||||
@ -306,7 +296,6 @@ function Map({
|
||||
onShapesRemove={handleMapShapesRemove}
|
||||
active={selectedToolId === "drawing"}
|
||||
toolSettings={settings.drawing}
|
||||
gridSize={gridSizeNormalized}
|
||||
/>
|
||||
);
|
||||
|
||||
@ -320,7 +309,6 @@ function Map({
|
||||
onShapesEdit={handleFogShapesEdit}
|
||||
active={selectedToolId === "fog"}
|
||||
toolSettings={settings.fog}
|
||||
gridSize={gridSizeNormalized}
|
||||
editable={allowFogDrawing && !settings.fog.preview}
|
||||
/>
|
||||
);
|
||||
@ -331,7 +319,6 @@ function Map({
|
||||
<MapMeasure
|
||||
map={map}
|
||||
active={selectedToolId === "measure"}
|
||||
gridSize={gridSizeNormalized}
|
||||
selectedToolSettings={settings[selectedToolId]}
|
||||
/>
|
||||
);
|
||||
@ -339,7 +326,6 @@ function Map({
|
||||
const mapPointer = (
|
||||
<NetworkedMapPointer
|
||||
active={selectedToolId === "pointer"}
|
||||
gridSize={gridSizeNormalized}
|
||||
session={session}
|
||||
/>
|
||||
);
|
||||
@ -377,7 +363,6 @@ function Map({
|
||||
<MapNotes
|
||||
map={map}
|
||||
active={selectedToolId === "note"}
|
||||
gridSize={gridSizeNormalized}
|
||||
selectedToolSettings={settings[selectedToolId]}
|
||||
onNoteAdd={onMapNoteChange}
|
||||
onNoteChange={onMapNoteChange}
|
||||
|
@ -1,9 +1,10 @@
|
||||
import React, { useContext, useState, useEffect } from "react";
|
||||
import React, { useState, useEffect } from "react";
|
||||
import shortid from "shortid";
|
||||
import { Group, Line, Rect, Circle } from "react-konva";
|
||||
|
||||
import MapInteractionContext from "../../contexts/MapInteractionContext";
|
||||
import MapStageContext from "../../contexts/MapStageContext";
|
||||
import { useMapInteraction } from "../../contexts/MapInteractionContext";
|
||||
import { useMapStage } from "../../contexts/MapStageContext";
|
||||
import { useGrid } from "../../contexts/GridContext";
|
||||
|
||||
import Vector2 from "../../helpers/Vector2";
|
||||
import {
|
||||
@ -11,7 +12,6 @@ import {
|
||||
getDefaultShapeData,
|
||||
getUpdatedShapeData,
|
||||
simplifyPoints,
|
||||
getStrokeWidth,
|
||||
} from "../../helpers/drawing";
|
||||
|
||||
import colors from "../../helpers/colors";
|
||||
@ -23,12 +23,15 @@ function MapDrawing({
|
||||
onShapesRemove,
|
||||
active,
|
||||
toolSettings,
|
||||
gridSize,
|
||||
}) {
|
||||
const { stageScale, mapWidth, mapHeight, interactionEmitter } = useContext(
|
||||
MapInteractionContext
|
||||
);
|
||||
const mapStageRef = useContext(MapStageContext);
|
||||
const {
|
||||
stageScale,
|
||||
mapWidth,
|
||||
mapHeight,
|
||||
interactionEmitter,
|
||||
} = useMapInteraction();
|
||||
const { gridCellNormalizedSize, gridStrokeWidth } = useGrid();
|
||||
const mapStageRef = useMapStage();
|
||||
const [drawingShape, setDrawingShape] = useState(null);
|
||||
const [isBrushDown, setIsBrushDown] = useState(false);
|
||||
const [erasingShapes, setErasingShapes] = useState([]);
|
||||
@ -53,7 +56,7 @@ function MapDrawing({
|
||||
map,
|
||||
mapStage,
|
||||
map.snapToGrid && isShape,
|
||||
gridSize
|
||||
gridCellNormalizedSize
|
||||
);
|
||||
const commonShapeData = {
|
||||
color: toolSettings.color,
|
||||
@ -85,7 +88,7 @@ function MapDrawing({
|
||||
map,
|
||||
mapStage,
|
||||
map.snapToGrid && isShape,
|
||||
gridSize
|
||||
gridCellNormalizedSize
|
||||
);
|
||||
if (isBrushDown && drawingShape) {
|
||||
if (isBrush) {
|
||||
@ -102,7 +105,7 @@ function MapDrawing({
|
||||
}
|
||||
const simplified = simplifyPoints(
|
||||
[...prevPoints, brushPosition],
|
||||
gridSize,
|
||||
gridCellNormalizedSize,
|
||||
stageScale
|
||||
);
|
||||
return {
|
||||
@ -117,7 +120,7 @@ function MapDrawing({
|
||||
prevShape.shapeType,
|
||||
prevShape.data,
|
||||
brushPosition,
|
||||
gridSize
|
||||
gridCellNormalizedSize
|
||||
),
|
||||
}));
|
||||
}
|
||||
@ -191,12 +194,7 @@ function MapDrawing({
|
||||
fillEnabled={shape.pathType === "fill"}
|
||||
lineCap="round"
|
||||
lineJoin="round"
|
||||
strokeWidth={getStrokeWidth(
|
||||
shape.strokeWidth,
|
||||
gridSize,
|
||||
mapWidth,
|
||||
mapHeight
|
||||
)}
|
||||
strokeWidth={gridStrokeWidth * shape.strokeWidth}
|
||||
{...defaultProps}
|
||||
/>
|
||||
);
|
||||
@ -239,12 +237,7 @@ function MapDrawing({
|
||||
(acc, point) => [...acc, point.x * mapWidth, point.y * mapHeight],
|
||||
[]
|
||||
)}
|
||||
strokeWidth={getStrokeWidth(
|
||||
shape.strokeWidth,
|
||||
gridSize,
|
||||
mapWidth,
|
||||
mapHeight
|
||||
)}
|
||||
strokeWidth={gridStrokeWidth * shape.strokeWidth}
|
||||
stroke={colors[shape.color] || shape.color}
|
||||
lineCap="round"
|
||||
{...defaultProps}
|
||||
|
@ -13,6 +13,7 @@ import { getGridDefaultInset, getGridMaxZoom } from "../../helpers/grid";
|
||||
|
||||
import { MapInteractionProvider } from "../../contexts/MapInteractionContext";
|
||||
import KeyboardContext from "../../contexts/KeyboardContext";
|
||||
import { GridProvider } from "../../contexts/GridContext";
|
||||
|
||||
import ResetMapIcon from "../../icons/ResetMapIcon";
|
||||
import GridOnIcon from "../../icons/GridOnIcon";
|
||||
@ -130,10 +131,14 @@ function MapEditor({ map, onSettingsChange }) {
|
||||
<KeyboardContext.Provider value={keyboardValue}>
|
||||
<MapInteractionProvider value={mapInteraction}>
|
||||
{showGridControls && canEditGrid && (
|
||||
<>
|
||||
<GridProvider
|
||||
grid={map.grid}
|
||||
width={mapWidth}
|
||||
height={mapHeight}
|
||||
>
|
||||
<MapGrid map={map} strokeWidth={0.5} />
|
||||
<MapGridEditor map={map} onGridChange={handleGridChange} />
|
||||
</>
|
||||
</GridProvider>
|
||||
)}
|
||||
</MapInteractionProvider>
|
||||
</KeyboardContext.Provider>
|
||||
|
@ -1,30 +1,24 @@
|
||||
import React, {
|
||||
useContext,
|
||||
useState,
|
||||
useEffect,
|
||||
useCallback,
|
||||
useRef,
|
||||
} from "react";
|
||||
import React, { useState, useEffect, useCallback, useRef } from "react";
|
||||
import shortid from "shortid";
|
||||
import { Group, Rect } from "react-konva";
|
||||
import useImage from "use-image";
|
||||
|
||||
import diagonalPattern from "../../images/DiagonalPattern.png";
|
||||
|
||||
import MapInteractionContext from "../../contexts/MapInteractionContext";
|
||||
import MapStageContext from "../../contexts/MapStageContext";
|
||||
import { useMapInteraction } from "../../contexts/MapInteractionContext";
|
||||
import { useMapStage } from "../../contexts/MapStageContext";
|
||||
import { useGrid } from "../../contexts/GridContext";
|
||||
import { useKeyboard } from "../../contexts/KeyboardContext";
|
||||
|
||||
import Vector2 from "../../helpers/Vector2";
|
||||
import {
|
||||
getFogBrushPosition,
|
||||
simplifyPoints,
|
||||
getStrokeWidth,
|
||||
mergeShapes,
|
||||
} from "../../helpers/drawing";
|
||||
import colors from "../../helpers/colors";
|
||||
import { HoleyLine, Tick } from "../../helpers/konva";
|
||||
|
||||
import useKeyboard from "../../hooks/useKeyboard";
|
||||
import useDebounce from "../../hooks/useDebounce";
|
||||
|
||||
function MapFog({
|
||||
@ -36,13 +30,17 @@ function MapFog({
|
||||
onShapesEdit,
|
||||
active,
|
||||
toolSettings,
|
||||
gridSize,
|
||||
editable,
|
||||
}) {
|
||||
const { stageScale, mapWidth, mapHeight, interactionEmitter } = useContext(
|
||||
MapInteractionContext
|
||||
);
|
||||
const mapStageRef = useContext(MapStageContext);
|
||||
const {
|
||||
stageScale,
|
||||
mapWidth,
|
||||
mapHeight,
|
||||
interactionEmitter,
|
||||
} = useMapInteraction();
|
||||
const { gridCellNormalizedSize, gridStrokeWidth } = useGrid();
|
||||
const mapStageRef = useMapStage();
|
||||
|
||||
const [drawingShape, setDrawingShape] = useState(null);
|
||||
const [isBrushDown, setIsBrushDown] = useState(false);
|
||||
const [editingShapes, setEditingShapes] = useState([]);
|
||||
@ -70,7 +68,7 @@ function MapFog({
|
||||
map,
|
||||
mapStage,
|
||||
useGridSnapping,
|
||||
gridSize,
|
||||
gridCellNormalizedSize,
|
||||
toolSettings.useEdgeSnapping,
|
||||
shapes
|
||||
);
|
||||
@ -114,7 +112,7 @@ function MapFog({
|
||||
map,
|
||||
mapStage,
|
||||
useGridSnapping,
|
||||
gridSize,
|
||||
gridCellNormalizedSize,
|
||||
toolSettings.useEdgeSnapping,
|
||||
shapes
|
||||
);
|
||||
@ -144,7 +142,7 @@ function MapFog({
|
||||
map,
|
||||
mapStage,
|
||||
useGridSnapping,
|
||||
gridSize,
|
||||
gridCellNormalizedSize,
|
||||
toolSettings.useEdgeSnapping,
|
||||
shapes,
|
||||
prevPoints
|
||||
@ -185,7 +183,7 @@ function MapFog({
|
||||
...drawingShape.data,
|
||||
points: simplifyPoints(
|
||||
drawingShape.data.points,
|
||||
gridSize,
|
||||
gridCellNormalizedSize,
|
||||
// Downscale fog as smoothing doesn't currently work with edge snapping
|
||||
stageScale / 2
|
||||
),
|
||||
@ -211,7 +209,7 @@ function MapFog({
|
||||
map,
|
||||
mapStage,
|
||||
useGridSnapping,
|
||||
gridSize,
|
||||
gridCellNormalizedSize,
|
||||
toolSettings.useEdgeSnapping,
|
||||
shapes
|
||||
);
|
||||
@ -247,7 +245,7 @@ function MapFog({
|
||||
map,
|
||||
mapStage,
|
||||
useGridSnapping,
|
||||
gridSize,
|
||||
gridCellNormalizedSize,
|
||||
toolSettings.useEdgeSnapping,
|
||||
shapes
|
||||
);
|
||||
@ -378,12 +376,7 @@ function MapFog({
|
||||
closed
|
||||
lineCap="round"
|
||||
lineJoin="round"
|
||||
strokeWidth={getStrokeWidth(
|
||||
shape.strokeWidth,
|
||||
gridSize,
|
||||
mapWidth,
|
||||
mapHeight
|
||||
)}
|
||||
strokeWidth={gridStrokeWidth * shape.strokeWidth}
|
||||
opacity={editable ? 0.5 : 1}
|
||||
fillPatternImage={patternImage}
|
||||
fillPriority={active && !shape.visible ? "pattern" : "color"}
|
||||
|
@ -1,8 +1,6 @@
|
||||
import React, { useContext, useEffect, useState } from "react";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import useImage from "use-image";
|
||||
|
||||
import MapInteractionContext from "../../contexts/MapInteractionContext";
|
||||
|
||||
import useDataSource from "../../hooks/useDataSource";
|
||||
import { mapSources as defaultMapSources } from "../../maps";
|
||||
|
||||
@ -11,8 +9,6 @@ import { getImageLightness } from "../../helpers/image";
|
||||
import Grid from "../Grid";
|
||||
|
||||
function MapGrid({ map, strokeWidth }) {
|
||||
const { mapWidth, mapHeight } = useContext(MapInteractionContext);
|
||||
|
||||
let mapSourceMap = map;
|
||||
// Use lowest resolution for grid lightness
|
||||
if (map && map.type === "file" && map.resolutions) {
|
||||
@ -34,13 +30,7 @@ function MapGrid({ map, strokeWidth }) {
|
||||
}, [mapImage, mapLoadingStatus]);
|
||||
|
||||
return (
|
||||
<Grid
|
||||
grid={map?.grid}
|
||||
strokeWidth={strokeWidth}
|
||||
width={mapWidth}
|
||||
height={mapHeight}
|
||||
stroke={isImageLight ? "black" : "white"}
|
||||
/>
|
||||
<Grid strokeWidth={strokeWidth} stroke={isImageLight ? "black" : "white"} />
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1,19 +1,18 @@
|
||||
import React, { useContext, useRef } from "react";
|
||||
import React, { useRef } from "react";
|
||||
import { Group, Circle, Rect } from "react-konva";
|
||||
|
||||
import MapInteractionContext from "../../contexts/MapInteractionContext";
|
||||
import { useMapInteraction } from "../../contexts/MapInteractionContext";
|
||||
import { useKeyboard } from "../../contexts/KeyboardContext";
|
||||
|
||||
import Vector2 from "../../helpers/Vector2";
|
||||
|
||||
import useKeyboard from "../../hooks/useKeyboard";
|
||||
|
||||
function MapGridEditor({ map, onGridChange }) {
|
||||
const {
|
||||
mapWidth,
|
||||
mapHeight,
|
||||
stageScale,
|
||||
setPreventMapInteraction,
|
||||
} = useContext(MapInteractionContext);
|
||||
} = useMapInteraction();
|
||||
|
||||
const mapSize = { x: mapWidth, y: mapHeight };
|
||||
|
||||
|
@ -6,19 +6,18 @@ import { EventEmitter } from "events";
|
||||
|
||||
import useMapImage from "../../hooks/useMapImage";
|
||||
import usePreventOverscroll from "../../hooks/usePreventOverscroll";
|
||||
import useKeyboard from "../../hooks/useKeyboard";
|
||||
import useStageInteraction from "../../hooks/useStageInteraction";
|
||||
import useImageCenter from "../../hooks/useImageCenter";
|
||||
|
||||
import { getGridMaxZoom } from "../../helpers/grid";
|
||||
|
||||
import { MapInteractionProvider } from "../../contexts/MapInteractionContext";
|
||||
import MapStageContext, {
|
||||
MapStageProvider,
|
||||
} from "../../contexts/MapStageContext";
|
||||
import AuthContext from "../../contexts/AuthContext";
|
||||
import SettingsContext from "../../contexts/SettingsContext";
|
||||
import { MapStageProvider, useMapStage } from "../../contexts/MapStageContext";
|
||||
import AuthContext, { useAuth } from "../../contexts/AuthContext";
|
||||
import SettingsContext, { useSettings } from "../../contexts/SettingsContext";
|
||||
import KeyboardContext from "../../contexts/KeyboardContext";
|
||||
import { GridProvider } from "../../contexts/GridContext";
|
||||
import { useKeyboard } from "../../contexts/KeyboardContext";
|
||||
|
||||
function MapInteraction({
|
||||
map,
|
||||
@ -53,7 +52,7 @@ function MapInteraction({
|
||||
|
||||
// Avoid state udpates when panning the map by using a ref and updating the konva element directly
|
||||
const stageTranslateRef = useRef({ x: 0, y: 0 });
|
||||
const mapStageRef = useContext(MapStageContext);
|
||||
const mapStageRef = useMapStage();
|
||||
const mapLayerRef = useRef();
|
||||
const mapImageRef = useRef();
|
||||
|
||||
@ -177,8 +176,8 @@ function MapInteraction({
|
||||
}
|
||||
}
|
||||
|
||||
const auth = useContext(AuthContext);
|
||||
const settings = useContext(SettingsContext);
|
||||
const auth = useAuth();
|
||||
const settings = useSettings();
|
||||
|
||||
const mapInteraction = {
|
||||
stageScale,
|
||||
@ -223,9 +222,15 @@ function MapInteraction({
|
||||
<SettingsContext.Provider value={settings}>
|
||||
<KeyboardContext.Provider value={keyboardValue}>
|
||||
<MapInteractionProvider value={mapInteraction}>
|
||||
<MapStageProvider value={mapStageRef}>
|
||||
{mapLoaded && children}
|
||||
</MapStageProvider>
|
||||
<GridProvider
|
||||
grid={map?.grid}
|
||||
width={mapWidth}
|
||||
height={mapHeight}
|
||||
>
|
||||
<MapStageProvider value={mapStageRef}>
|
||||
{mapLoaded && children}
|
||||
</MapStageProvider>
|
||||
</GridProvider>
|
||||
</MapInteractionProvider>
|
||||
</KeyboardContext.Provider>
|
||||
</SettingsContext.Provider>
|
||||
@ -234,7 +239,9 @@ function MapInteraction({
|
||||
</Stage>
|
||||
</ReactResizeDetector>
|
||||
<MapInteractionProvider value={mapInteraction}>
|
||||
{controls}
|
||||
<GridProvider grid={map?.grid} width={mapWidth} height={mapHeight}>
|
||||
{controls}
|
||||
</GridProvider>
|
||||
</MapInteractionProvider>
|
||||
</Box>
|
||||
);
|
||||
|
@ -1,12 +1,12 @@
|
||||
import React, { useContext } from "react";
|
||||
import React from "react";
|
||||
import { Box } from "theme-ui";
|
||||
|
||||
import MapLoadingContext from "../../contexts/MapLoadingContext";
|
||||
import { useMapLoading } from "../../contexts/MapLoadingContext";
|
||||
|
||||
import LoadingBar from "../LoadingBar";
|
||||
|
||||
function MapLoadingOverlay() {
|
||||
const { isLoading, loadingProgressRef } = useContext(MapLoadingContext);
|
||||
const { isLoading, loadingProgressRef } = useMapLoading();
|
||||
|
||||
return (
|
||||
isLoading && (
|
||||
|
@ -1,22 +1,26 @@
|
||||
import React, { useContext, useState, useEffect } from "react";
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { Group, Line, Text, Label, Tag } from "react-konva";
|
||||
|
||||
import MapInteractionContext from "../../contexts/MapInteractionContext";
|
||||
import MapStageContext from "../../contexts/MapStageContext";
|
||||
import { useMapInteraction } from "../../contexts/MapInteractionContext";
|
||||
import { useMapStage } from "../../contexts/MapStageContext";
|
||||
import { useGrid } from "../../contexts/GridContext";
|
||||
|
||||
import {
|
||||
getBrushPosition,
|
||||
getDefaultShapeData,
|
||||
getUpdatedShapeData,
|
||||
getStrokeWidth,
|
||||
} from "../../helpers/drawing";
|
||||
import Vector2 from "../../helpers/Vector2";
|
||||
|
||||
function MapMeasure({ map, selectedToolSettings, active, gridSize }) {
|
||||
const { stageScale, mapWidth, mapHeight, interactionEmitter } = useContext(
|
||||
MapInteractionContext
|
||||
);
|
||||
const mapStageRef = useContext(MapStageContext);
|
||||
function MapMeasure({ map, selectedToolSettings, active }) {
|
||||
const {
|
||||
stageScale,
|
||||
mapWidth,
|
||||
mapHeight,
|
||||
interactionEmitter,
|
||||
} = useMapInteraction();
|
||||
const { gridCellNormalizedSize, gridStrokeWidth } = useGrid();
|
||||
const mapStageRef = useMapStage();
|
||||
const [drawingShapeData, setDrawingShapeData] = useState(null);
|
||||
const [isBrushDown, setIsBrushDown] = useState(false);
|
||||
|
||||
@ -52,7 +56,7 @@ function MapMeasure({ map, selectedToolSettings, active, gridSize }) {
|
||||
map,
|
||||
mapStage,
|
||||
map.snapToGrid,
|
||||
gridSize
|
||||
gridCellNormalizedSize
|
||||
);
|
||||
const { points } = getDefaultShapeData("line", brushPosition);
|
||||
const length = 0;
|
||||
@ -65,20 +69,26 @@ function MapMeasure({ map, selectedToolSettings, active, gridSize }) {
|
||||
map,
|
||||
mapStage,
|
||||
map.snapToGrid,
|
||||
gridSize
|
||||
gridCellNormalizedSize
|
||||
);
|
||||
if (isBrushDown && drawingShapeData) {
|
||||
const { points } = getUpdatedShapeData(
|
||||
"line",
|
||||
drawingShapeData,
|
||||
brushPosition,
|
||||
gridSize
|
||||
gridCellNormalizedSize
|
||||
);
|
||||
// Round the grid positions to the nearest 0.1 to aviod floating point issues
|
||||
const precision = { x: 0.1, y: 0.1 };
|
||||
const length = Vector2.distance(
|
||||
Vector2.roundTo(Vector2.divide(points[0], gridSize), precision),
|
||||
Vector2.roundTo(Vector2.divide(points[1], gridSize), precision),
|
||||
Vector2.roundTo(
|
||||
Vector2.divide(points[0], gridCellNormalizedSize),
|
||||
precision
|
||||
),
|
||||
Vector2.roundTo(
|
||||
Vector2.divide(points[1], gridCellNormalizedSize),
|
||||
precision
|
||||
),
|
||||
selectedToolSettings.type
|
||||
);
|
||||
setDrawingShapeData({
|
||||
@ -119,13 +129,13 @@ function MapMeasure({ map, selectedToolSettings, active, gridSize }) {
|
||||
<Group>
|
||||
<Line
|
||||
points={linePoints}
|
||||
strokeWidth={getStrokeWidth(1.5, gridSize, mapWidth, mapHeight)}
|
||||
strokeWidth={1.5 * gridStrokeWidth}
|
||||
stroke="hsla(230, 25%, 18%, 0.8)"
|
||||
lineCap="round"
|
||||
/>
|
||||
<Line
|
||||
points={linePoints}
|
||||
strokeWidth={getStrokeWidth(0.25, gridSize, mapWidth, mapHeight)}
|
||||
strokeWidth={0.25 * gridStrokeWidth}
|
||||
stroke="white"
|
||||
lineCap="round"
|
||||
/>
|
||||
|
@ -1,10 +1,11 @@
|
||||
import React, { useContext, useState, useEffect, useRef } from "react";
|
||||
import React, { useState, useEffect, useRef } from "react";
|
||||
import shortid from "shortid";
|
||||
import { Group } from "react-konva";
|
||||
|
||||
import MapInteractionContext from "../../contexts/MapInteractionContext";
|
||||
import MapStageContext from "../../contexts/MapStageContext";
|
||||
import AuthContext from "../../contexts/AuthContext";
|
||||
import { useMapInteraction } from "../../contexts/MapInteractionContext";
|
||||
import { useMapStage } from "../../contexts/MapStageContext";
|
||||
import { useAuth } from "../../contexts/AuthContext";
|
||||
import { useGrid } from "../../contexts/GridContext";
|
||||
|
||||
import { getBrushPosition } from "../../helpers/drawing";
|
||||
|
||||
@ -15,7 +16,6 @@ const defaultNoteSize = 2;
|
||||
function MapNotes({
|
||||
map,
|
||||
active,
|
||||
gridSize,
|
||||
onNoteAdd,
|
||||
onNoteChange,
|
||||
notes,
|
||||
@ -25,9 +25,10 @@ function MapNotes({
|
||||
onNoteDragEnd,
|
||||
fadeOnHover,
|
||||
}) {
|
||||
const { interactionEmitter } = useContext(MapInteractionContext);
|
||||
const { userId } = useContext(AuthContext);
|
||||
const mapStageRef = useContext(MapStageContext);
|
||||
const { interactionEmitter } = useMapInteraction();
|
||||
const { userId } = useAuth();
|
||||
const { gridCellNormalizedSize } = useGrid();
|
||||
const mapStageRef = useMapStage();
|
||||
const [isBrushDown, setIsBrushDown] = useState(false);
|
||||
const [noteData, setNoteData] = useState(null);
|
||||
|
||||
@ -44,7 +45,7 @@ function MapNotes({
|
||||
map,
|
||||
mapStage,
|
||||
map.snapToGrid,
|
||||
gridSize
|
||||
gridCellNormalizedSize
|
||||
);
|
||||
setNoteData({
|
||||
x: brushPosition.x,
|
||||
@ -68,7 +69,7 @@ function MapNotes({
|
||||
map,
|
||||
mapStage,
|
||||
map.snapToGrid,
|
||||
gridSize
|
||||
gridCellNormalizedSize
|
||||
);
|
||||
setNoteData((prev) => ({
|
||||
...prev,
|
||||
|
@ -1,10 +1,10 @@
|
||||
import React, { useContext, useEffect } from "react";
|
||||
import React, { useEffect } from "react";
|
||||
import { Group } from "react-konva";
|
||||
|
||||
import MapInteractionContext from "../../contexts/MapInteractionContext";
|
||||
import MapStageContext from "../../contexts/MapStageContext";
|
||||
import { useMapInteraction } from "../../contexts/MapInteractionContext";
|
||||
import { useMapStage } from "../../contexts/MapStageContext";
|
||||
import { useGrid } from "../../contexts/GridContext";
|
||||
|
||||
import { getStrokeWidth } from "../../helpers/drawing";
|
||||
import {
|
||||
getRelativePointerPositionNormalized,
|
||||
Trail,
|
||||
@ -14,7 +14,6 @@ import Vector2 from "../../helpers/Vector2";
|
||||
import colors from "../../helpers/colors";
|
||||
|
||||
function MapPointer({
|
||||
gridSize,
|
||||
active,
|
||||
position,
|
||||
onPointerDown,
|
||||
@ -23,10 +22,9 @@ function MapPointer({
|
||||
visible,
|
||||
color,
|
||||
}) {
|
||||
const { mapWidth, mapHeight, interactionEmitter } = useContext(
|
||||
MapInteractionContext
|
||||
);
|
||||
const mapStageRef = useContext(MapStageContext);
|
||||
const { mapWidth, mapHeight, interactionEmitter } = useMapInteraction();
|
||||
const { gridStrokeWidth } = useGrid();
|
||||
const mapStageRef = useMapStage();
|
||||
|
||||
useEffect(() => {
|
||||
if (!active) {
|
||||
@ -63,7 +61,7 @@ function MapPointer({
|
||||
};
|
||||
});
|
||||
|
||||
const size = getStrokeWidth(2, gridSize, mapWidth, mapHeight);
|
||||
const size = 2 * gridStrokeWidth;
|
||||
|
||||
return (
|
||||
<Group>
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useContext } from "react";
|
||||
import React from "react";
|
||||
import { Flex, Box, Text, IconButton, Close, Label } from "theme-ui";
|
||||
import SimpleBar from "simplebar-react";
|
||||
import Case from "case";
|
||||
@ -11,7 +11,7 @@ import MapTile from "./MapTile";
|
||||
import Link from "../Link";
|
||||
import FilterBar from "../FilterBar";
|
||||
|
||||
import DatabaseContext from "../../contexts/DatabaseContext";
|
||||
import { useDatabase } from "../../contexts/DatabaseContext";
|
||||
|
||||
import useResponsiveLayout from "../../hooks/useResponsiveLayout";
|
||||
|
||||
@ -32,7 +32,7 @@ function MapTiles({
|
||||
onSearchChange,
|
||||
onMapsGroup,
|
||||
}) {
|
||||
const { databaseStatus } = useContext(DatabaseContext);
|
||||
const { databaseStatus } = useDatabase();
|
||||
const layout = useResponsiveLayout();
|
||||
|
||||
let hasMapState = false;
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useContext, useState, useEffect, useRef } from "react";
|
||||
import React, { useState, useEffect, useRef } from "react";
|
||||
import { Image as KonvaImage, Group } from "react-konva";
|
||||
import { useSpring, animated } from "react-spring/konva";
|
||||
import useImage from "use-image";
|
||||
@ -10,8 +10,9 @@ import usePrevious from "../../hooks/usePrevious";
|
||||
|
||||
import { snapNodeToGrid } from "../../helpers/grid";
|
||||
|
||||
import AuthContext from "../../contexts/AuthContext";
|
||||
import MapInteractionContext from "../../contexts/MapInteractionContext";
|
||||
import { useAuth } from "../../contexts/AuthContext";
|
||||
import { useMapInteraction } from "../../contexts/MapInteractionContext";
|
||||
import { useGrid } from "../../contexts/GridContext";
|
||||
|
||||
import TokenStatus from "../token/TokenStatus";
|
||||
import TokenLabel from "../token/TokenLabel";
|
||||
@ -23,7 +24,6 @@ const snappingThreshold = 1 / 7;
|
||||
function MapToken({
|
||||
token,
|
||||
tokenState,
|
||||
tokenSizePercent,
|
||||
onTokenStateChange,
|
||||
onTokenMenuOpen,
|
||||
onTokenDragStart,
|
||||
@ -33,13 +33,14 @@ function MapToken({
|
||||
fadeOnHover,
|
||||
map,
|
||||
}) {
|
||||
const { userId } = useContext(AuthContext);
|
||||
const { userId } = useAuth();
|
||||
const {
|
||||
setPreventMapInteraction,
|
||||
mapWidth,
|
||||
mapHeight,
|
||||
stageScale,
|
||||
} = useContext(MapInteractionContext);
|
||||
} = useMapInteraction();
|
||||
const { gridCellPixelSize } = useGrid();
|
||||
|
||||
const tokenSource = useDataSource(token, tokenSources, unknownSource);
|
||||
const [tokenSourceImage, tokenSourceStatus] = useImage(tokenSource);
|
||||
@ -182,9 +183,9 @@ function MapToken({
|
||||
}
|
||||
}
|
||||
|
||||
const tokenWidth = tokenSizePercent * mapWidth * tokenState.size;
|
||||
const tokenWidth = gridCellPixelSize.width * tokenState.size;
|
||||
const tokenHeight =
|
||||
tokenSizePercent * (mapWidth / tokenAspectRatio) * tokenState.size;
|
||||
(gridCellPixelSize.width / tokenAspectRatio) * tokenState.size;
|
||||
|
||||
const debouncedStageScale = useDebounce(stageScale, 50);
|
||||
const imageRef = useRef();
|
||||
|
@ -1,11 +1,11 @@
|
||||
import React, { useState, useContext } from "react";
|
||||
import React, { useState } from "react";
|
||||
import { IconButton } from "theme-ui";
|
||||
|
||||
import SelectMapModal from "../../modals/SelectMapModal";
|
||||
import SelectMapIcon from "../../icons/SelectMapIcon";
|
||||
|
||||
import MapDataContext from "../../contexts/MapDataContext";
|
||||
import AuthContext from "../../contexts/AuthContext";
|
||||
import { useMapData } from "../../contexts/MapDataContext";
|
||||
import { useAuth } from "../../contexts/AuthContext";
|
||||
|
||||
function SelectMapButton({
|
||||
onMapChange,
|
||||
@ -16,8 +16,8 @@ function SelectMapButton({
|
||||
}) {
|
||||
const [isModalOpen, setIsModalOpen] = useState(false);
|
||||
|
||||
const { updateMapState } = useContext(MapDataContext);
|
||||
const { userId } = useContext(AuthContext);
|
||||
const { updateMapState } = useMapData();
|
||||
const { userId } = useAuth();
|
||||
function openModal() {
|
||||
if (currentMapState && currentMap && currentMap.owner === userId) {
|
||||
updateMapState(currentMapState.mapId, currentMapState);
|
||||
|
@ -22,7 +22,7 @@ import RedoButton from "./RedoButton";
|
||||
|
||||
import Divider from "../../Divider";
|
||||
|
||||
import useKeyboard from "../../../hooks/useKeyboard";
|
||||
import { useKeyboard } from "../../../contexts/KeyboardContext";
|
||||
|
||||
function DrawingToolSettings({
|
||||
settings,
|
||||
|
@ -20,7 +20,7 @@ import ToolSection from "./ToolSection";
|
||||
|
||||
import Divider from "../../Divider";
|
||||
|
||||
import useKeyboard from "../../../hooks/useKeyboard";
|
||||
import { useKeyboard } from "../../../contexts/KeyboardContext";
|
||||
|
||||
function BrushToolSettings({
|
||||
settings,
|
||||
|
@ -9,7 +9,7 @@ import MeasureAlternatingIcon from "../../../icons/MeasureAlternatingIcon";
|
||||
|
||||
import Divider from "../../Divider";
|
||||
|
||||
import useKeyboard from "../../../hooks/useKeyboard";
|
||||
import { useKeyboard } from "../../../contexts/KeyboardContext";
|
||||
|
||||
function MeasureToolSettings({ settings, onSettingChange }) {
|
||||
// Keyboard shortcuts
|
||||
|
@ -1,9 +1,10 @@
|
||||
import React, { useContext, useEffect, useState, useRef } from "react";
|
||||
import React, { useEffect, useState, useRef } from "react";
|
||||
import { Rect, Text } from "react-konva";
|
||||
import { useSpring, animated } from "react-spring/konva";
|
||||
|
||||
import AuthContext from "../../contexts/AuthContext";
|
||||
import MapInteractionContext from "../../contexts/MapInteractionContext";
|
||||
import { useAuth } from "../../contexts/AuthContext";
|
||||
import { useMapInteraction } from "../../contexts/MapInteractionContext";
|
||||
import { useGrid } from "../../contexts/GridContext";
|
||||
|
||||
import { snapNodeToGrid } from "../../helpers/grid";
|
||||
import colors from "../../helpers/colors";
|
||||
@ -22,12 +23,11 @@ function Note({
|
||||
onNoteDragEnd,
|
||||
fadeOnHover,
|
||||
}) {
|
||||
const { userId } = useContext(AuthContext);
|
||||
const { mapWidth, mapHeight, setPreventMapInteraction } = useContext(
|
||||
MapInteractionContext
|
||||
);
|
||||
const { userId } = useAuth();
|
||||
const { mapWidth, mapHeight, setPreventMapInteraction } = useMapInteraction();
|
||||
const { gridCellPixelSize } = useGrid();
|
||||
|
||||
const noteWidth = map && (mapWidth / map.grid.size.x) * note.size;
|
||||
const noteWidth = gridCellPixelSize.width * note.size;
|
||||
const noteHeight = noteWidth;
|
||||
const notePadding = noteWidth / 10;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useEffect, useState, useContext } from "react";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { Box, Flex, Text, IconButton, Textarea } from "theme-ui";
|
||||
|
||||
import Slider from "../Slider";
|
||||
@ -16,7 +16,7 @@ import HideIcon from "../../icons/TokenHideIcon";
|
||||
import NoteIcon from "../../icons/NoteToolIcon";
|
||||
import TextIcon from "../../icons/NoteTextIcon";
|
||||
|
||||
import AuthContext from "../../contexts/AuthContext";
|
||||
import { useAuth } from "../../contexts/AuthContext";
|
||||
|
||||
const defaultNoteMaxSize = 6;
|
||||
|
||||
@ -28,7 +28,7 @@ function NoteMenu({
|
||||
onNoteChange,
|
||||
map,
|
||||
}) {
|
||||
const { userId } = useContext(AuthContext);
|
||||
const { userId } = useAuth();
|
||||
|
||||
const wasOpen = usePrevious(isOpen);
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useContext, useEffect } from "react";
|
||||
import React, { useEffect } from "react";
|
||||
import { Flex, Box, Text } from "theme-ui";
|
||||
import SimpleBar from "simplebar-react";
|
||||
|
||||
@ -13,16 +13,13 @@ import DiceTrayButton from "./DiceTrayButton";
|
||||
|
||||
import useSetting from "../../hooks/useSetting";
|
||||
|
||||
import PartyContext from "../../contexts/PartyContext";
|
||||
import {
|
||||
PlayerUpdaterContext,
|
||||
PlayerStateContext,
|
||||
} from "../../contexts/PlayerContext";
|
||||
import { useParty } from "../../contexts/PartyContext";
|
||||
import { usePlayerState, usePlayerUpdater } from "../../contexts/PlayerContext";
|
||||
|
||||
function Party({ gameId, stream, partyStreams, onStreamStart, onStreamEnd }) {
|
||||
const setPlayerState = useContext(PlayerUpdaterContext);
|
||||
const playerState = useContext(PlayerStateContext);
|
||||
const partyState = useContext(PartyContext);
|
||||
const setPlayerState = usePlayerUpdater();
|
||||
const playerState = usePlayerState();
|
||||
const partyState = useParty();
|
||||
|
||||
const [fullScreen] = useSetting("map.fullScreen");
|
||||
const [shareDice, setShareDice] = useSetting("dice.shareDice");
|
||||
|
@ -1,11 +1,11 @@
|
||||
import React, { useEffect, useRef, useState, useContext } from "react";
|
||||
import React, { useEffect, useRef, useState } from "react";
|
||||
import ReactDOM from "react-dom";
|
||||
import { Image, Box } from "theme-ui";
|
||||
import interact from "interactjs";
|
||||
|
||||
import usePortal from "../../hooks/usePortal";
|
||||
|
||||
import MapStageContext from "../../contexts/MapStageContext";
|
||||
import { useMapStage } from "../../contexts/MapStageContext";
|
||||
|
||||
/**
|
||||
* @callback onProxyDragEnd
|
||||
@ -34,7 +34,7 @@ function ProxyToken({ tokenClassName, onProxyDragEnd, tokens }) {
|
||||
}, [tokens]);
|
||||
|
||||
const proxyOnMap = useRef(false);
|
||||
const mapStageRef = useContext(MapStageContext);
|
||||
const mapStageRef = useMapStage();
|
||||
|
||||
useEffect(() => {
|
||||
interact(`.${tokenClassName}`).draggable({
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React, { useContext } from "react";
|
||||
import React from "react";
|
||||
|
||||
import AuthContext from "../../contexts/AuthContext";
|
||||
import MapInteractionContext from "../../contexts/MapInteractionContext";
|
||||
import { useAuth } from "../../contexts/AuthContext";
|
||||
import { useMapInteraction } from "../../contexts/MapInteractionContext";
|
||||
|
||||
import DragOverlay from "../DragOverlay";
|
||||
|
||||
@ -14,8 +14,8 @@ function TokenDragOverlay({
|
||||
dragging,
|
||||
mapState,
|
||||
}) {
|
||||
const { userId } = useContext(AuthContext);
|
||||
const { mapWidth, mapHeight } = useContext(MapInteractionContext);
|
||||
const { userId } = useAuth();
|
||||
const { mapWidth, mapHeight } = useMapInteraction();
|
||||
|
||||
function handleTokenRemove() {
|
||||
// Handle other tokens when a vehicle gets deleted
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useEffect, useState, useContext } from "react";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { Box, Input, Flex, Text, IconButton } from "theme-ui";
|
||||
|
||||
import Slider from "../Slider";
|
||||
@ -14,7 +14,7 @@ import UnlockIcon from "../../icons/TokenUnlockIcon";
|
||||
import ShowIcon from "../../icons/TokenShowIcon";
|
||||
import HideIcon from "../../icons/TokenHideIcon";
|
||||
|
||||
import AuthContext from "../../contexts/AuthContext";
|
||||
import { useAuth } from "../../contexts/AuthContext";
|
||||
|
||||
const defaultTokenMaxSize = 6;
|
||||
function TokenMenu({
|
||||
@ -25,7 +25,7 @@ function TokenMenu({
|
||||
onTokenStateChange,
|
||||
map,
|
||||
}) {
|
||||
const { userId } = useContext(AuthContext);
|
||||
const { userId } = useAuth();
|
||||
|
||||
const wasOpen = usePrevious(isOpen);
|
||||
|
||||
|
@ -10,6 +10,8 @@ import useDataSource from "../../hooks/useDataSource";
|
||||
import useImageCenter from "../../hooks/useImageCenter";
|
||||
import useResponsiveLayout from "../../hooks/useResponsiveLayout";
|
||||
|
||||
import { GridProvider } from "../../contexts/GridContext";
|
||||
|
||||
import GridOnIcon from "../../icons/GridOnIcon";
|
||||
import GridOffIcon from "../../icons/GridOffIcon";
|
||||
|
||||
@ -110,7 +112,7 @@ function TokenPreview({ token }) {
|
||||
/>
|
||||
{showGridPreview && (
|
||||
<Group offsetY={gridHeight - tokenHeight}>
|
||||
<Grid
|
||||
<GridProvider
|
||||
grid={{
|
||||
size: { x: gridX, y: gridY },
|
||||
inset: {
|
||||
@ -121,7 +123,9 @@ function TokenPreview({ token }) {
|
||||
}}
|
||||
width={gridWidth}
|
||||
height={gridHeight}
|
||||
/>
|
||||
>
|
||||
<Grid />
|
||||
</GridProvider>
|
||||
<Rect
|
||||
width={gridWidth}
|
||||
height={gridHeight}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useContext } from "react";
|
||||
import React from "react";
|
||||
import { Flex, Box, Text, IconButton, Close, Label } from "theme-ui";
|
||||
import SimpleBar from "simplebar-react";
|
||||
import Case from "case";
|
||||
@ -12,7 +12,7 @@ import TokenTile from "./TokenTile";
|
||||
import Link from "../Link";
|
||||
import FilterBar from "../FilterBar";
|
||||
|
||||
import DatabaseContext from "../../contexts/DatabaseContext";
|
||||
import { useDatabase } from "../../contexts/DatabaseContext";
|
||||
|
||||
import useResponsiveLayout from "../../hooks/useResponsiveLayout";
|
||||
|
||||
@ -31,7 +31,7 @@ function TokenTiles({
|
||||
onTokensGroup,
|
||||
onTokensHide,
|
||||
}) {
|
||||
const { databaseStatus } = useContext(DatabaseContext);
|
||||
const { databaseStatus } = useDatabase();
|
||||
const layout = useResponsiveLayout();
|
||||
|
||||
let hasSelectedDefaultToken = selectedTokens.some(
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useContext } from "react";
|
||||
import React from "react";
|
||||
import { Box, Flex } from "theme-ui";
|
||||
import shortid from "shortid";
|
||||
import SimpleBar from "simplebar-react";
|
||||
@ -12,14 +12,14 @@ import { fromEntries } from "../../helpers/shared";
|
||||
|
||||
import useSetting from "../../hooks/useSetting";
|
||||
|
||||
import AuthContext from "../../contexts/AuthContext";
|
||||
import TokenDataContext from "../../contexts/TokenDataContext";
|
||||
import { useAuth } from "../../contexts/AuthContext";
|
||||
import { useTokenData } from "../../contexts/TokenDataContext";
|
||||
|
||||
const listTokenClassName = "list-token";
|
||||
|
||||
function Tokens({ onMapTokenStateCreate }) {
|
||||
const { userId } = useContext(AuthContext);
|
||||
const { ownedTokens, tokens, updateToken } = useContext(TokenDataContext);
|
||||
const { userId } = useAuth();
|
||||
const { ownedTokens, tokens, updateToken } = useTokenData();
|
||||
const [fullScreen] = useSetting("map.fullScreen");
|
||||
|
||||
function handleProxyDragEnd(isOnMap, token) {
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React, { useState, useEffect, useContext } from "react";
|
||||
import shortid from "shortid";
|
||||
|
||||
import DatabaseContext from "./DatabaseContext";
|
||||
import { useDatabase } from "./DatabaseContext";
|
||||
|
||||
import FakeStorage from "../helpers/FakeStorage";
|
||||
|
||||
@ -18,7 +18,7 @@ try {
|
||||
}
|
||||
|
||||
export function AuthProvider({ children }) {
|
||||
const { database, databaseStatus } = useContext(DatabaseContext);
|
||||
const { database, databaseStatus } = useDatabase();
|
||||
|
||||
const [password, setPassword] = useState(storage.getItem("auth") || "");
|
||||
|
||||
@ -57,4 +57,12 @@ export function AuthProvider({ children }) {
|
||||
return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;
|
||||
}
|
||||
|
||||
export function useAuth() {
|
||||
const context = useContext(AuthContext);
|
||||
if (context === undefined) {
|
||||
throw new Error("useAuth must be used within a AuthProvider");
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
export default AuthContext;
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import React, { useState, useEffect, useContext } from "react";
|
||||
import { Box, Text } from "theme-ui";
|
||||
|
||||
import Banner from "../components/Banner";
|
||||
@ -79,4 +79,12 @@ export function DatabaseProvider({ children }) {
|
||||
);
|
||||
}
|
||||
|
||||
export function useDatabase() {
|
||||
const context = useContext(DatabaseContext);
|
||||
if (context === undefined) {
|
||||
throw new Error("useDatabase must be used within a DatabaseProvider");
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
export default DatabaseContext;
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useState } from "react";
|
||||
import React, { useState, useContext } from "react";
|
||||
|
||||
const DiceLoadingContext = React.createContext();
|
||||
|
||||
@ -28,4 +28,12 @@ export function DiceLoadingProvider({ children }) {
|
||||
);
|
||||
}
|
||||
|
||||
export function useDiceLoading() {
|
||||
const context = useContext(DiceLoadingContext);
|
||||
if (context === undefined) {
|
||||
throw new Error("useDiceLoading must be used within a DiceLoadingProvider");
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
export default DiceLoadingContext;
|
||||
|
85
src/contexts/GridContext.js
Normal file
85
src/contexts/GridContext.js
Normal file
@ -0,0 +1,85 @@
|
||||
import React, { useContext } from "react";
|
||||
|
||||
import Vector2 from "../helpers/Vector2";
|
||||
import Size from "../helpers/Size";
|
||||
import { getGridPixelSize, getCellPixelSize, Grid } from "../helpers/grid";
|
||||
|
||||
/**
|
||||
* @typedef GridContextValue
|
||||
* @property {Grid} grid Base grid value
|
||||
* @property {Size} gridPixelSize Size of the grid in pixels
|
||||
* @property {Size} gridCellPixelSize Size of each cell in pixels
|
||||
* @property {Size} gridCellNormalizedSize Size of each cell normalized to the grid
|
||||
* @property {Vector2} gridOffset Offset of the grid from the top left in pixels
|
||||
* @property {number} gridStrokeWidth Stroke width of the grid in pixels
|
||||
*/
|
||||
|
||||
/**
|
||||
* @type {GridContextValue}
|
||||
*/
|
||||
const defaultValue = {
|
||||
grid: {
|
||||
size: { x: 0, y: 0 },
|
||||
inset: { topLeft: { x: 0, y: 0 }, bottomRight: { x: 1, y: 1 } },
|
||||
type: "square",
|
||||
},
|
||||
gridPixelSize: new Size(0, 0),
|
||||
gridCellPixelSize: new Size(0, 0, 0),
|
||||
gridCellNormalizedSize: new Size(0, 0, 0),
|
||||
gridOffset: { x: 0, y: 0 },
|
||||
gridStrokeWidth: 0,
|
||||
};
|
||||
|
||||
const GridContext = React.createContext(defaultValue);
|
||||
|
||||
const defaultStrokeWidth = 1 / 10;
|
||||
|
||||
export function GridProvider({ grid, width, height, children }) {
|
||||
if (!grid?.size.x || !grid?.size.y) {
|
||||
return (
|
||||
<GridContext.Provider value={defaultValue}>
|
||||
{children}
|
||||
</GridContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
const gridPixelSize = getGridPixelSize(grid, width, height);
|
||||
const gridCellPixelSize = getCellPixelSize(
|
||||
grid,
|
||||
gridPixelSize.width,
|
||||
gridPixelSize.height
|
||||
);
|
||||
const gridCellNormalizedSize = new Size(
|
||||
gridCellPixelSize.width / gridPixelSize.width,
|
||||
gridCellPixelSize.height / gridPixelSize.height
|
||||
);
|
||||
const gridOffset = {
|
||||
x: grid.inset.topLeft.x * width * -1,
|
||||
y: grid.inset.topLeft.y * height * -1,
|
||||
};
|
||||
const gridStrokeWidth =
|
||||
(gridCellPixelSize.width < gridCellPixelSize.height
|
||||
? gridCellPixelSize.width
|
||||
: gridCellPixelSize.height) * defaultStrokeWidth;
|
||||
|
||||
const value = {
|
||||
grid,
|
||||
gridPixelSize,
|
||||
gridCellPixelSize,
|
||||
gridCellNormalizedSize,
|
||||
gridOffset,
|
||||
gridStrokeWidth,
|
||||
};
|
||||
|
||||
return <GridContext.Provider value={value}>{children}</GridContext.Provider>;
|
||||
}
|
||||
|
||||
export function useGrid() {
|
||||
const context = useContext(GridContext);
|
||||
if (context === undefined) {
|
||||
throw new Error("useGrid must be used within a GridProvider");
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
export default GridContext;
|
@ -1,4 +1,4 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import React, { useEffect, useState, useContext } from "react";
|
||||
import { EventEmitter } from "events";
|
||||
|
||||
const KeyboardContext = React.createContext({ keyEmitter: new EventEmitter() });
|
||||
@ -45,4 +45,33 @@ export function KeyboardProvider({ children }) {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {KeyboardEvent} onKeyDown
|
||||
* @param {KeyboardEvent} onKeyUp
|
||||
*/
|
||||
export function useKeyboard(onKeyDown, onKeyUp) {
|
||||
const context = useContext(KeyboardContext);
|
||||
if (context === undefined) {
|
||||
throw new Error("useKeyboard must be used within a KeyboardProvider");
|
||||
}
|
||||
const { keyEmitter } = context;
|
||||
useEffect(() => {
|
||||
if (onKeyDown) {
|
||||
keyEmitter.on("keyDown", onKeyDown);
|
||||
}
|
||||
if (onKeyUp) {
|
||||
keyEmitter.on("keyUp", onKeyUp);
|
||||
}
|
||||
|
||||
return () => {
|
||||
if (onKeyDown) {
|
||||
keyEmitter.off("keyDown", onKeyDown);
|
||||
}
|
||||
if (onKeyUp) {
|
||||
keyEmitter.off("keyUp", onKeyUp);
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
export default KeyboardContext;
|
||||
|
@ -8,8 +8,8 @@ import React, {
|
||||
import * as Comlink from "comlink";
|
||||
import { decode } from "@msgpack/msgpack";
|
||||
|
||||
import AuthContext from "./AuthContext";
|
||||
import DatabaseContext from "./DatabaseContext";
|
||||
import { useAuth } from "./AuthContext";
|
||||
import { useDatabase } from "./DatabaseContext";
|
||||
|
||||
import DatabaseWorker from "worker-loader!../workers/DatabaseWorker"; // eslint-disable-line import/no-webpack-loader-syntax
|
||||
|
||||
@ -32,8 +32,8 @@ const defaultMapState = {
|
||||
const worker = Comlink.wrap(new DatabaseWorker());
|
||||
|
||||
export function MapDataProvider({ children }) {
|
||||
const { database, databaseStatus } = useContext(DatabaseContext);
|
||||
const { userId } = useContext(AuthContext);
|
||||
const { database, databaseStatus } = useDatabase();
|
||||
const { userId } = useAuth();
|
||||
|
||||
const [maps, setMaps] = useState([]);
|
||||
const [mapStates, setMapStates] = useState([]);
|
||||
@ -303,4 +303,12 @@ export function MapDataProvider({ children }) {
|
||||
);
|
||||
}
|
||||
|
||||
export function useMapData() {
|
||||
const context = useContext(MapDataContext);
|
||||
if (context === undefined) {
|
||||
throw new Error("useMapData must be used within a MapDataProvider");
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
export default MapDataContext;
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React from "react";
|
||||
import React, { useContext } from "react";
|
||||
|
||||
const MapInteractionContext = React.createContext({
|
||||
stageScale: 1,
|
||||
@ -11,4 +11,14 @@ const MapInteractionContext = React.createContext({
|
||||
});
|
||||
export const MapInteractionProvider = MapInteractionContext.Provider;
|
||||
|
||||
export function useMapInteraction() {
|
||||
const context = useContext(MapInteractionContext);
|
||||
if (context === undefined) {
|
||||
throw new Error(
|
||||
"useMapInteraction must be used within a MapInteractionProvider"
|
||||
);
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
export default MapInteractionContext;
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useState, useRef } from "react";
|
||||
import React, { useState, useRef, useContext } from "react";
|
||||
import { omit, isEmpty } from "../helpers/shared";
|
||||
|
||||
const MapLoadingContext = React.createContext();
|
||||
@ -53,4 +53,12 @@ export function MapLoadingProvider({ children }) {
|
||||
);
|
||||
}
|
||||
|
||||
export function useMapLoading() {
|
||||
const context = useContext(MapLoadingContext);
|
||||
if (context === undefined) {
|
||||
throw new Error("useMapLoading must be used within a MapLoadingProvider");
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
export default MapLoadingContext;
|
||||
|
@ -1,8 +1,16 @@
|
||||
import React from "react";
|
||||
import React, { useContext } from "react";
|
||||
|
||||
const MapStageContext = React.createContext({
|
||||
mapStageRef: { current: null },
|
||||
});
|
||||
export const MapStageProvider = MapStageContext.Provider;
|
||||
|
||||
export function useMapStage() {
|
||||
const context = useContext(MapStageContext);
|
||||
if (context === undefined) {
|
||||
throw new Error("useMapStage must be used within a MapStageProvider");
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
export default MapStageContext;
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import React, { useState, useEffect, useContext } from "react";
|
||||
|
||||
const PartyContext = React.createContext();
|
||||
|
||||
@ -27,4 +27,12 @@ export function PartyProvider({ session, children }) {
|
||||
);
|
||||
}
|
||||
|
||||
export function useParty() {
|
||||
const context = useContext(PartyContext);
|
||||
if (context === undefined) {
|
||||
throw new Error("useParty must be used within a PartyProvider");
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
export default PartyContext;
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React, { useEffect, useContext } from "react";
|
||||
|
||||
import DatabaseContext from "./DatabaseContext";
|
||||
import AuthContext from "./AuthContext";
|
||||
import { useDatabase } from "./DatabaseContext";
|
||||
import { useAuth } from "./AuthContext";
|
||||
|
||||
import { getRandomMonster } from "../helpers/monsters";
|
||||
|
||||
@ -11,8 +11,8 @@ export const PlayerStateContext = React.createContext();
|
||||
export const PlayerUpdaterContext = React.createContext(() => {});
|
||||
|
||||
export function PlayerProvider({ session, children }) {
|
||||
const { userId } = useContext(AuthContext);
|
||||
const { database, databaseStatus } = useContext(DatabaseContext);
|
||||
const { userId } = useAuth();
|
||||
const { database, databaseStatus } = useDatabase();
|
||||
|
||||
const [playerState, setPlayerState] = useNetworkedState(
|
||||
{
|
||||
@ -93,3 +93,19 @@ export function PlayerProvider({ session, children }) {
|
||||
</PlayerStateContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
export function usePlayerState() {
|
||||
const context = useContext(PlayerStateContext);
|
||||
if (context === undefined) {
|
||||
throw new Error("usePlayerState must be used within a PlayerProvider");
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
export function usePlayerUpdater() {
|
||||
const context = useContext(PlayerUpdaterContext);
|
||||
if (context === undefined) {
|
||||
throw new Error("usePlayerUpdater must be used within a PlayerProvider");
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import React, { useState, useEffect, useContext } from "react";
|
||||
|
||||
import { getSettings } from "../settings";
|
||||
|
||||
@ -28,4 +28,12 @@ export function SettingsProvider({ children }) {
|
||||
);
|
||||
}
|
||||
|
||||
export function useSettings() {
|
||||
const context = useContext(SettingsContext);
|
||||
if (context === undefined) {
|
||||
throw new Error("useSettings must be used within a SettingsProvider");
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
export default SettingsContext;
|
||||
|
@ -8,8 +8,8 @@ import React, {
|
||||
import * as Comlink from "comlink";
|
||||
import { decode } from "@msgpack/msgpack";
|
||||
|
||||
import AuthContext from "./AuthContext";
|
||||
import DatabaseContext from "./DatabaseContext";
|
||||
import { useAuth } from "./AuthContext";
|
||||
import { useDatabase } from "./DatabaseContext";
|
||||
|
||||
import DatabaseWorker from "worker-loader!../workers/DatabaseWorker"; // eslint-disable-line import/no-webpack-loader-syntax
|
||||
|
||||
@ -22,8 +22,8 @@ const cachedTokenMax = 100;
|
||||
const worker = Comlink.wrap(new DatabaseWorker());
|
||||
|
||||
export function TokenDataProvider({ children }) {
|
||||
const { database, databaseStatus } = useContext(DatabaseContext);
|
||||
const { userId } = useContext(AuthContext);
|
||||
const { database, databaseStatus } = useDatabase();
|
||||
const { userId } = useAuth();
|
||||
|
||||
const [tokens, setTokens] = useState([]);
|
||||
const [tokensLoading, setTokensLoading] = useState(true);
|
||||
@ -224,4 +224,12 @@ export function TokenDataProvider({ children }) {
|
||||
);
|
||||
}
|
||||
|
||||
export function useTokenData() {
|
||||
const context = useContext(TokenDataContext);
|
||||
if (context === undefined) {
|
||||
throw new Error("useTokenData must be used within a TokenDataProvider");
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
export default TokenDataContext;
|
||||
|
65
src/helpers/Size.js
Normal file
65
src/helpers/Size.js
Normal file
@ -0,0 +1,65 @@
|
||||
import Vector2 from "./Vector2";
|
||||
|
||||
/**
|
||||
* Wrapper for Vector2 that provides width, height and radius properties
|
||||
*/
|
||||
class Size extends Vector2 {
|
||||
_radius;
|
||||
/**
|
||||
* @param {number} width
|
||||
* @param {number} height
|
||||
* @param {number=} radius Used to represent hexagon sizes
|
||||
*/
|
||||
constructor(width, height, radius) {
|
||||
super(width, height);
|
||||
this._radius = radius;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {number}
|
||||
*/
|
||||
get width() {
|
||||
return this.x;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} width
|
||||
*/
|
||||
set width(width) {
|
||||
this.x = width;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {number}
|
||||
*/
|
||||
get height() {
|
||||
return this.y;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} height
|
||||
*/
|
||||
set height(height) {
|
||||
this.y = height;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {number}
|
||||
*/
|
||||
get radius() {
|
||||
if (this._radius) {
|
||||
return this._radius;
|
||||
} else {
|
||||
return Math.min(this.x, this.y) / 2;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} radius
|
||||
*/
|
||||
set radius(radius) {
|
||||
this._radius = radius;
|
||||
}
|
||||
}
|
||||
|
||||
export default Size;
|
@ -17,6 +17,15 @@ class Vector2 {
|
||||
*/
|
||||
y;
|
||||
|
||||
/**
|
||||
* @param {number} x
|
||||
* @param {number} y
|
||||
*/
|
||||
constructor(x, y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Vector2} p
|
||||
* @returns {number} Length squared of `p`
|
||||
@ -385,7 +394,7 @@ class Vector2 {
|
||||
* Returns the distance between two vectors
|
||||
* @param {Vector2} a
|
||||
* @param {Vector2} b
|
||||
* @param {string?} type - `chebyshev | euclidean | manhattan | alternating`
|
||||
* @param {string=} type - `chebyshev | euclidean | manhattan | alternating`
|
||||
*/
|
||||
static distance(a, b, type = "euclidean") {
|
||||
switch (type) {
|
||||
|
@ -7,7 +7,12 @@ import { getRelativePointerPositionNormalized } from "./konva";
|
||||
import { logError } from "./logging";
|
||||
|
||||
const snappingThreshold = 1 / 5;
|
||||
export function getBrushPosition(map, mapStage, useGridSnappning, gridSize) {
|
||||
export function getBrushPosition(
|
||||
map,
|
||||
mapStage,
|
||||
useGridSnappning,
|
||||
gridCellNormalizedSize
|
||||
) {
|
||||
const mapImage = mapStage.findOne("#mapImage");
|
||||
let position = getRelativePointerPositionNormalized(mapImage);
|
||||
if (useGridSnappning) {
|
||||
@ -15,18 +20,21 @@ export function getBrushPosition(map, mapStage, useGridSnappning, gridSize) {
|
||||
// Subtract offset to transform into offset space then add it back transform back
|
||||
const offset = map.grid.inset.topLeft;
|
||||
const gridSnap = Vector2.add(
|
||||
Vector2.roundTo(Vector2.subtract(position, offset), gridSize),
|
||||
Vector2.roundTo(
|
||||
Vector2.subtract(position, offset),
|
||||
gridCellNormalizedSize
|
||||
),
|
||||
offset
|
||||
);
|
||||
const gridDistance = Vector2.length(Vector2.subtract(gridSnap, position));
|
||||
// Snap to center of grid
|
||||
// Subtract offset and half size to transform it into offset half space then transform it back
|
||||
const halfSize = Vector2.multiply(gridSize, 0.5);
|
||||
const halfSize = Vector2.multiply(gridCellNormalizedSize, 0.5);
|
||||
const centerSnap = Vector2.add(
|
||||
Vector2.add(
|
||||
Vector2.roundTo(
|
||||
Vector2.subtract(Vector2.subtract(position, offset), halfSize),
|
||||
gridSize
|
||||
gridCellNormalizedSize
|
||||
),
|
||||
halfSize
|
||||
),
|
||||
@ -35,7 +43,7 @@ export function getBrushPosition(map, mapStage, useGridSnappning, gridSize) {
|
||||
const centerDistance = Vector2.length(
|
||||
Vector2.subtract(centerSnap, position)
|
||||
);
|
||||
const minGrid = Vector2.min(gridSize);
|
||||
const minGrid = Vector2.min(gridCellNormalizedSize);
|
||||
if (gridDistance < minGrid * snappingThreshold) {
|
||||
position = gridSnap;
|
||||
} else if (centerDistance < minGrid * snappingThreshold) {
|
||||
@ -49,14 +57,19 @@ export function getFogBrushPosition(
|
||||
map,
|
||||
mapStage,
|
||||
useGridSnappning,
|
||||
gridSize,
|
||||
gridCellNormalizedSize,
|
||||
useEdgeSnapping,
|
||||
fogShapes,
|
||||
rectPoints
|
||||
) {
|
||||
let position = getBrushPosition(map, mapStage, useGridSnappning, gridSize);
|
||||
let position = getBrushPosition(
|
||||
map,
|
||||
mapStage,
|
||||
useGridSnappning,
|
||||
gridCellNormalizedSize
|
||||
);
|
||||
if (useEdgeSnapping) {
|
||||
const minGrid = Vector2.min(gridSize);
|
||||
const minGrid = Vector2.min(gridCellNormalizedSize);
|
||||
let closestDistance = Number.MAX_VALUE;
|
||||
let closestPosition = position;
|
||||
// Find the closest point on all fog shapes
|
||||
@ -139,18 +152,23 @@ export function getDefaultShapeData(type, brushPosition) {
|
||||
}
|
||||
}
|
||||
|
||||
export function getGridScale(gridSize) {
|
||||
if (gridSize.x < gridSize.y) {
|
||||
return { x: gridSize.y / gridSize.x, y: 1 };
|
||||
} else if (gridSize.y < gridSize.x) {
|
||||
return { x: 1, y: gridSize.x / gridSize.y };
|
||||
export function getGridScale(cellSize) {
|
||||
if (cellSize.x < cellSize.y) {
|
||||
return { x: cellSize.y / cellSize.x, y: 1 };
|
||||
} else if (cellSize.y < cellSize.x) {
|
||||
return { x: 1, y: cellSize.x / cellSize.y };
|
||||
} else {
|
||||
return { x: 1, y: 1 };
|
||||
}
|
||||
}
|
||||
|
||||
export function getUpdatedShapeData(type, data, brushPosition, gridSize) {
|
||||
const gridScale = getGridScale(gridSize);
|
||||
export function getUpdatedShapeData(
|
||||
type,
|
||||
data,
|
||||
brushPosition,
|
||||
gridCellNormalizedSize
|
||||
) {
|
||||
const gridScale = getGridScale(gridCellNormalizedSize);
|
||||
if (type === "line") {
|
||||
return {
|
||||
points: [data.points[0], { x: brushPosition.x, y: brushPosition.y }],
|
||||
@ -210,10 +228,10 @@ export function getStrokeWidth(multiplier, gridSize, mapWidth, mapHeight) {
|
||||
}
|
||||
|
||||
const defaultSimplifySize = 1 / 100;
|
||||
export function simplifyPoints(points, gridSize, scale) {
|
||||
export function simplifyPoints(points, gridCellNormalizedSize, scale) {
|
||||
return simplify(
|
||||
points,
|
||||
(Vector2.min(gridSize) * defaultSimplifySize) / scale
|
||||
(Vector2.min(gridCellNormalizedSize) * defaultSimplifySize) / scale
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
import GridSizeModel from "../ml/gridSize/GridSizeModel";
|
||||
import Vector2 from "./Vector2";
|
||||
import Size from "./Size";
|
||||
|
||||
import { logError } from "./logging";
|
||||
|
||||
@ -8,52 +9,47 @@ const GRID_TYPE_NOT_IMPLEMENTED = new Error("Grid type not implemented");
|
||||
|
||||
/**
|
||||
* @typedef GridInset
|
||||
* @property {Vector2} topLeft
|
||||
* @property {Vector2} bottomRight
|
||||
* @property {Vector2} topLeft Top left position of the inset
|
||||
* @property {Vector2} bottomRight Bottom right position of the inset
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef Grid
|
||||
* @property {GridInset} inset
|
||||
* @property {Vector2} size
|
||||
* @property {GridInset} inset The inset of the grid from the map
|
||||
* @property {Vector2} size The number of columns and rows of the grid as `x` and `y`
|
||||
* @property {("square"|"hexVertical"|"hexHorizontal")} type
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef CellSize
|
||||
* @property {number} width
|
||||
* @property {number} height
|
||||
* @property {number?} radius - Used for hex cell sizes
|
||||
* Gets the size of a grid in pixels taking into account the inset
|
||||
* @param {Grid} grid
|
||||
* @param {number} baseWidth Width of the grid in pixels before inset
|
||||
* @param {number} baseHeight Height of the grid in pixels before inset
|
||||
* @returns {Size}
|
||||
*/
|
||||
export function getGridPixelSize(grid, baseWidth, baseHeight) {
|
||||
const width = (grid.inset.bottomRight.x - grid.inset.topLeft.x) * baseWidth;
|
||||
const height = (grid.inset.bottomRight.y - grid.inset.topLeft.y) * baseHeight;
|
||||
return new Size(width, height);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the cell size for a grid taking into account inset and grid type
|
||||
* Gets the cell size for a grid in pixels for each grid type
|
||||
* @param {Grid} grid
|
||||
* @param {number} gridWidth
|
||||
* @param {number} gridHeight
|
||||
* @returns {CellSize}
|
||||
* @param {number} gridWidth Width of the grid in pixels after inset
|
||||
* @param {number} gridHeight Height of the grid in pixels after inset
|
||||
* @returns {Size}
|
||||
*/
|
||||
export function getCellSize(grid, gridWidth, gridHeight) {
|
||||
export function getCellPixelSize(grid, gridWidth, gridHeight) {
|
||||
switch (grid.type) {
|
||||
case "square":
|
||||
return {
|
||||
width: gridWidth / grid.size.x,
|
||||
height: gridHeight / grid.size.y,
|
||||
};
|
||||
return new Size(gridWidth / grid.size.x, gridHeight / grid.size.y);
|
||||
case "hexVertical":
|
||||
const radiusVert = gridWidth / grid.size.x / SQRT3;
|
||||
return {
|
||||
width: radiusVert * SQRT3,
|
||||
height: radiusVert * 2,
|
||||
radius: radiusVert,
|
||||
};
|
||||
return new Size(radiusVert * SQRT3, radiusVert * 2, radiusVert);
|
||||
case "hexHorizontal":
|
||||
const radiusHorz = gridHeight / grid.size.y / SQRT3;
|
||||
return {
|
||||
width: radiusHorz * 2,
|
||||
height: radiusHorz * SQRT3,
|
||||
radius: radiusHorz,
|
||||
};
|
||||
return new Size(radiusHorz * 2, radiusHorz * SQRT3, radiusHorz);
|
||||
default:
|
||||
throw GRID_TYPE_NOT_IMPLEMENTED;
|
||||
}
|
||||
@ -64,7 +60,7 @@ export function getCellSize(grid, gridWidth, gridHeight) {
|
||||
* @param {Grid} grid
|
||||
* @param {number} x X-axis location of the cell
|
||||
* @param {number} y Y-axis location of the cell
|
||||
* @param {CellSize} cellSize
|
||||
* @param {Size} cellSize Cell size in pixels
|
||||
* @returns {Vector2}
|
||||
*/
|
||||
export function getCellLocation(grid, x, y, cellSize) {
|
||||
@ -111,11 +107,11 @@ export function shouldClipCell(grid, x, y) {
|
||||
|
||||
/**
|
||||
* Canvas clip function for culling hex cells that overshoot/undershoot the grid
|
||||
* @param {CanvasRenderingContext2D} context
|
||||
* @param {CanvasRenderingContext2D} context The canvas context of the clip function
|
||||
* @param {Grid} grid
|
||||
* @param {number} x
|
||||
* @param {number} y
|
||||
* @param {CellSize} cellSize
|
||||
* @param {number} x X-axis location of the cell
|
||||
* @param {number} y Y-axis location of the cell
|
||||
* @param {Size} cellSize Cell size in pixels
|
||||
*/
|
||||
export function gridClipFunction(context, grid, x, y, cellSize) {
|
||||
// Clip the undershooting cells unless they are needed to fill out a specific grid type
|
||||
@ -138,7 +134,7 @@ export function gridClipFunction(context, grid, x, y, cellSize) {
|
||||
/**
|
||||
* Get the height of a grid based off of its width
|
||||
* @param {Grid} grid
|
||||
* @param {number} gridWidth
|
||||
* @param {number} gridWidth Width of the grid in pixels after inset
|
||||
*/
|
||||
function getGridHeightFromWidth(grid, gridWidth) {
|
||||
switch (grid.type) {
|
||||
@ -157,22 +153,22 @@ function getGridHeightFromWidth(grid, gridWidth) {
|
||||
|
||||
/**
|
||||
* Get the default inset for a grid
|
||||
* @param {Grid} grid
|
||||
* @param {number} gridWidth
|
||||
* @param {number} gridHeight
|
||||
* @param {Grid} grid Grid with no inset property set
|
||||
* @param {number} mapWidth Width of the map in pixels before inset
|
||||
* @param {number} mapHeight Height of the map in pixels before inset
|
||||
* @returns {GridInset}
|
||||
*/
|
||||
export function getGridDefaultInset(grid, gridWidth, gridHeight) {
|
||||
export function getGridDefaultInset(grid, mapWidth, mapHeight) {
|
||||
// Max the width of the inset and figure out the resulting height value
|
||||
const insetHeightNorm = getGridHeightFromWidth(grid, gridWidth) / gridHeight;
|
||||
const insetHeightNorm = getGridHeightFromWidth(grid, mapWidth) / mapHeight;
|
||||
return { topLeft: { x: 0, y: 0 }, bottomRight: { x: 1, y: insetHeightNorm } };
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an updated inset for a grid when its size changes
|
||||
* @param {Grid} grid
|
||||
* @param {number} mapWidth
|
||||
* @param {number} mapHeight
|
||||
* @param {Grid} grid Grid with an inset property set
|
||||
* @param {number} mapWidth Width of the map in pixels before inset
|
||||
* @param {number} mapHeight Height of the map in pixels before inset
|
||||
* @returns {GridInset}
|
||||
*/
|
||||
export function getGridUpdatedInset(grid, mapWidth, mapHeight) {
|
||||
@ -348,7 +344,7 @@ async function gridSizeML(image, candidates) {
|
||||
* @param {Image} image
|
||||
* @returns {Vector2}
|
||||
*/
|
||||
export async function getGridSize(image) {
|
||||
export async function getGridSizeFromImage(image) {
|
||||
const candidates = dividers(image.width, image.height);
|
||||
let prediction;
|
||||
|
||||
@ -387,7 +383,7 @@ export function getGridMaxZoom(grid) {
|
||||
* @param {Grid} grid
|
||||
* @param {number} mapWidth
|
||||
* @param {number} mapHeight
|
||||
* @param {Konva.node} node
|
||||
* @param {Konva.Node} node
|
||||
* @param {number} snappingThreshold 1 = Always snap, 0 = never snap
|
||||
*/
|
||||
export function snapNodeToGrid(
|
||||
|
@ -1,30 +0,0 @@
|
||||
import { useEffect, useContext } from "react";
|
||||
|
||||
import KeyboardContext from "../contexts/KeyboardContext";
|
||||
|
||||
/**
|
||||
* @param {KeyboardEvent} onKeyDown
|
||||
* @param {KeyboardEvent} onKeyUp
|
||||
*/
|
||||
function useKeyboard(onKeyDown, onKeyUp) {
|
||||
const { keyEmitter } = useContext(KeyboardContext);
|
||||
useEffect(() => {
|
||||
if (onKeyDown) {
|
||||
keyEmitter.on("keyDown", onKeyDown);
|
||||
}
|
||||
if (onKeyUp) {
|
||||
keyEmitter.on("keyUp", onKeyUp);
|
||||
}
|
||||
|
||||
return () => {
|
||||
if (onKeyDown) {
|
||||
keyEmitter.off("keyDown", onKeyDown);
|
||||
}
|
||||
if (onKeyUp) {
|
||||
keyEmitter.off("keyUp", onKeyUp);
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
export default useKeyboard;
|
@ -1,16 +1,14 @@
|
||||
import { useContext } from "react";
|
||||
|
||||
import get from "lodash.get";
|
||||
import set from "lodash.set";
|
||||
|
||||
import SettingsContext from "../contexts/SettingsContext";
|
||||
import { useSettings } from "../contexts/SettingsContext";
|
||||
|
||||
/**
|
||||
* Helper to get and set nested settings that are saved in local storage
|
||||
* @param {String} path The path to the setting within the Settings object provided by the SettingsContext
|
||||
*/
|
||||
function useSetting(path) {
|
||||
const { settings, setSettings } = useContext(SettingsContext);
|
||||
const { settings, setSettings } = useSettings();
|
||||
|
||||
const setting = get(settings, path);
|
||||
|
||||
|
@ -1,14 +1,12 @@
|
||||
import React, { useState, useContext, useRef } from "react";
|
||||
import React, { useState, useRef } from "react";
|
||||
import { Box, Input, Button, Label, Flex } from "theme-ui";
|
||||
|
||||
import AuthContext from "../contexts/AuthContext";
|
||||
import { useAuth } from "../contexts/AuthContext";
|
||||
|
||||
import Modal from "../components/Modal";
|
||||
|
||||
function AuthModal({ isOpen }) {
|
||||
const { password, setPassword, setAuthenticationStatus } = useContext(
|
||||
AuthContext
|
||||
);
|
||||
const { password, setPassword, setAuthenticationStatus } = useAuth();
|
||||
const [tmpPassword, setTempPassword] = useState(password);
|
||||
|
||||
function handleChange(event) {
|
||||
|
@ -1,11 +1,11 @@
|
||||
import React, { useState, useContext } from "react";
|
||||
import React, { useState } from "react";
|
||||
import { Button, Flex, Label } from "theme-ui";
|
||||
|
||||
import Modal from "../components/Modal";
|
||||
import MapSettings from "../components/map/MapSettings";
|
||||
import MapEditor from "../components/map/MapEditor";
|
||||
|
||||
import MapDataContext from "../contexts/MapDataContext";
|
||||
import { useMapData } from "../contexts/MapDataContext";
|
||||
|
||||
import { isEmpty } from "../helpers/shared";
|
||||
import { getGridDefaultInset } from "../helpers/grid";
|
||||
@ -13,7 +13,7 @@ import { getGridDefaultInset } from "../helpers/grid";
|
||||
import useResponsiveLayout from "../hooks/useResponsiveLayout";
|
||||
|
||||
function EditMapModal({ isOpen, onDone, map, mapState }) {
|
||||
const { updateMap, updateMapState } = useContext(MapDataContext);
|
||||
const { updateMap, updateMapState } = useMapData();
|
||||
|
||||
function handleClose() {
|
||||
setMapSettingChanges({});
|
||||
|
@ -1,18 +1,18 @@
|
||||
import React, { useState, useContext } from "react";
|
||||
import React, { useState } from "react";
|
||||
import { Button, Flex, Label } from "theme-ui";
|
||||
|
||||
import Modal from "../components/Modal";
|
||||
import TokenSettings from "../components/token/TokenSettings";
|
||||
import TokenPreview from "../components/token/TokenPreview";
|
||||
|
||||
import TokenDataContext from "../contexts/TokenDataContext";
|
||||
import { useTokenData } from "../contexts/TokenDataContext";
|
||||
|
||||
import { isEmpty } from "../helpers/shared";
|
||||
|
||||
import useResponsiveLayout from "../hooks/useResponsiveLayout";
|
||||
|
||||
function EditTokenModal({ isOpen, onDone, token }) {
|
||||
const { updateToken } = useContext(TokenDataContext);
|
||||
const { updateToken } = useTokenData();
|
||||
|
||||
function handleClose() {
|
||||
setTokenSettingChanges({});
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useRef, useState, useContext, useEffect } from "react";
|
||||
import React, { useRef, useState, useEffect } from "react";
|
||||
import { Box, Label, Text, Button, Flex } from "theme-ui";
|
||||
import streamSaver from "streamsaver";
|
||||
import * as Comlink from "comlink";
|
||||
@ -7,14 +7,14 @@ import Modal from "../components/Modal";
|
||||
import LoadingOverlay from "../components/LoadingOverlay";
|
||||
import LoadingBar from "../components/LoadingBar";
|
||||
|
||||
import DatabaseContext from "../contexts/DatabaseContext";
|
||||
import { useDatabase } from "../contexts/DatabaseContext";
|
||||
|
||||
import DatabaseWorker from "worker-loader!../workers/DatabaseWorker"; // eslint-disable-line import/no-webpack-loader-syntax
|
||||
|
||||
const worker = Comlink.wrap(new DatabaseWorker());
|
||||
|
||||
function ImportDatabaseModal({ isOpen, onRequestClose }) {
|
||||
const { database } = useContext(DatabaseContext);
|
||||
const { database } = useDatabase();
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
|
||||
const backgroundTaskRunningRef = useRef(false);
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useRef, useState, useContext, useEffect } from "react";
|
||||
import React, { useRef, useState, useEffect } from "react";
|
||||
import { Button, Flex, Label } from "theme-ui";
|
||||
import shortid from "shortid";
|
||||
import Case from "case";
|
||||
@ -17,16 +17,16 @@ import { resizeImage } from "../helpers/image";
|
||||
import { useSearch, useGroup, handleItemSelect } from "../helpers/select";
|
||||
import {
|
||||
getGridDefaultInset,
|
||||
getGridSize,
|
||||
getGridSizeFromImage,
|
||||
gridSizeVaild,
|
||||
} from "../helpers/grid";
|
||||
import Vector2 from "../helpers/Vector2";
|
||||
|
||||
import useKeyboard from "../hooks/useKeyboard";
|
||||
import useResponsiveLayout from "../hooks/useResponsiveLayout";
|
||||
|
||||
import MapDataContext from "../contexts/MapDataContext";
|
||||
import AuthContext from "../contexts/AuthContext";
|
||||
import { useMapData } from "../contexts/MapDataContext";
|
||||
import { useAuth } from "../contexts/AuthContext";
|
||||
import { useKeyboard } from "../contexts/KeyboardContext";
|
||||
|
||||
const defaultMapProps = {
|
||||
showGrid: false,
|
||||
@ -54,7 +54,7 @@ function SelectMapModal({
|
||||
// The map currently being view in the map screen
|
||||
currentMap,
|
||||
}) {
|
||||
const { userId } = useContext(AuthContext);
|
||||
const { userId } = useAuth();
|
||||
const {
|
||||
ownedMaps,
|
||||
mapStates,
|
||||
@ -64,7 +64,7 @@ function SelectMapModal({
|
||||
updateMap,
|
||||
updateMaps,
|
||||
mapsLoading,
|
||||
} = useContext(MapDataContext);
|
||||
} = useMapData();
|
||||
|
||||
/**
|
||||
* Search
|
||||
@ -152,7 +152,7 @@ function SelectMapModal({
|
||||
}
|
||||
|
||||
if (!gridSize) {
|
||||
gridSize = await getGridSize(image);
|
||||
gridSize = await getGridSizeFromImage(image);
|
||||
}
|
||||
|
||||
// Remove file extension
|
||||
@ -207,10 +207,9 @@ function SelectMapModal({
|
||||
grid: {
|
||||
size: gridSize,
|
||||
inset: getGridDefaultInset(
|
||||
{ size: { x: gridSize.x, y: gridSize.y }, type: "square" },
|
||||
image.width,
|
||||
image.height,
|
||||
gridSize.x,
|
||||
gridSize.y
|
||||
image.height
|
||||
),
|
||||
type: "square",
|
||||
},
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useRef, useContext, useState, useEffect } from "react";
|
||||
import React, { useRef, useState, useEffect } from "react";
|
||||
import { Flex, Label, Button } from "theme-ui";
|
||||
import shortid from "shortid";
|
||||
import Case from "case";
|
||||
@ -15,21 +15,21 @@ import LoadingOverlay from "../components/LoadingOverlay";
|
||||
import blobToBuffer from "../helpers/blobToBuffer";
|
||||
import { useSearch, useGroup, handleItemSelect } from "../helpers/select";
|
||||
|
||||
import useKeyboard from "../hooks/useKeyboard";
|
||||
import useResponsiveLayout from "../hooks/useResponsiveLayout";
|
||||
|
||||
import TokenDataContext from "../contexts/TokenDataContext";
|
||||
import AuthContext from "../contexts/AuthContext";
|
||||
import { useTokenData } from "../contexts/TokenDataContext";
|
||||
import { useAuth } from "../contexts/AuthContext";
|
||||
import { useKeyboard } from "../contexts/KeyboardContext";
|
||||
|
||||
function SelectTokensModal({ isOpen, onRequestClose }) {
|
||||
const { userId } = useContext(AuthContext);
|
||||
const { userId } = useAuth();
|
||||
const {
|
||||
ownedTokens,
|
||||
addToken,
|
||||
removeTokens,
|
||||
updateTokens,
|
||||
tokensLoading,
|
||||
} = useContext(TokenDataContext);
|
||||
} = useTokenData();
|
||||
|
||||
/**
|
||||
* Search
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useState, useContext, useEffect } from "react";
|
||||
import React, { useState, useEffect } from "react";
|
||||
import {
|
||||
Label,
|
||||
Flex,
|
||||
@ -13,8 +13,8 @@ import prettyBytes from "pretty-bytes";
|
||||
import Modal from "../components/Modal";
|
||||
import Slider from "../components/Slider";
|
||||
|
||||
import AuthContext from "../contexts/AuthContext";
|
||||
import DatabaseContext from "../contexts/DatabaseContext";
|
||||
import { useAuth } from "../contexts/AuthContext";
|
||||
import { useDatabase } from "../contexts/DatabaseContext";
|
||||
|
||||
import useSetting from "../hooks/useSetting";
|
||||
|
||||
@ -22,8 +22,8 @@ import ConfirmModal from "./ConfirmModal";
|
||||
import ImportExportModal from "./ImportExportModal";
|
||||
|
||||
function SettingsModal({ isOpen, onRequestClose }) {
|
||||
const { database, databaseStatus } = useContext(DatabaseContext);
|
||||
const { userId } = useContext(AuthContext);
|
||||
const { database, databaseStatus } = useDatabase();
|
||||
const { userId } = useAuth();
|
||||
const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false);
|
||||
const [labelSize, setLabelSize] = useSetting("map.labelSize");
|
||||
const [storageEstimate, setStorageEstimate] = useState();
|
||||
|
@ -1,9 +1,9 @@
|
||||
import React, { useContext, useRef } from "react";
|
||||
import React, { useRef } from "react";
|
||||
import { Box, Label, Input, Button, Flex, Checkbox } from "theme-ui";
|
||||
import { useHistory } from "react-router-dom";
|
||||
import shortid from "shortid";
|
||||
|
||||
import AuthContext from "../contexts/AuthContext";
|
||||
import { useAuth } from "../contexts/AuthContext";
|
||||
|
||||
import useSetting from "../hooks/useSetting";
|
||||
|
||||
@ -11,7 +11,7 @@ import Modal from "../components/Modal";
|
||||
|
||||
function StartModal({ isOpen, onRequestClose }) {
|
||||
let history = useHistory();
|
||||
const { password, setPassword } = useContext(AuthContext);
|
||||
const { password, setPassword } = useAuth();
|
||||
|
||||
function handlePasswordChange(event) {
|
||||
setPassword(event.target.value);
|
||||
|
@ -1,11 +1,11 @@
|
||||
import React, { useState, useContext, useEffect, useRef } from "react";
|
||||
import React, { useState, useEffect, useRef } from "react";
|
||||
|
||||
import TokenDataContext from "../contexts/TokenDataContext";
|
||||
import MapDataContext from "../contexts/MapDataContext";
|
||||
import MapLoadingContext from "../contexts/MapLoadingContext";
|
||||
import AuthContext from "../contexts/AuthContext";
|
||||
import DatabaseContext from "../contexts/DatabaseContext";
|
||||
import PartyContext from "../contexts/PartyContext";
|
||||
import { useTokenData } from "../contexts/TokenDataContext";
|
||||
import { useMapData } from "../contexts/MapDataContext";
|
||||
import { useMapLoading } from "../contexts/MapLoadingContext";
|
||||
import { useAuth } from "../contexts/AuthContext";
|
||||
import { useDatabase } from "../contexts/DatabaseContext";
|
||||
import { useParty } from "../contexts/PartyContext";
|
||||
|
||||
import { omit } from "../helpers/shared";
|
||||
|
||||
@ -35,21 +35,17 @@ const defaultMapActions = {
|
||||
* @param {NetworkedMapProps} props
|
||||
*/
|
||||
function NetworkedMapAndTokens({ session }) {
|
||||
const { userId } = useContext(AuthContext);
|
||||
const partyState = useContext(PartyContext);
|
||||
const { userId } = useAuth();
|
||||
const partyState = useParty();
|
||||
const {
|
||||
assetLoadStart,
|
||||
assetLoadFinish,
|
||||
assetProgressUpdate,
|
||||
isLoading,
|
||||
} = useContext(MapLoadingContext);
|
||||
} = useMapLoading();
|
||||
|
||||
const { putToken, updateToken, getTokenFromDB } = useContext(
|
||||
TokenDataContext
|
||||
);
|
||||
const { putMap, updateMap, getMapFromDB, updateMapState } = useContext(
|
||||
MapDataContext
|
||||
);
|
||||
const { putToken, updateToken, getTokenFromDB } = useTokenData();
|
||||
const { putMap, updateMap, getMapFromDB, updateMapState } = useMapData();
|
||||
|
||||
const [currentMap, setCurrentMap] = useState(null);
|
||||
const [currentMapState, setCurrentMapState] = useNetworkedState(
|
||||
@ -193,7 +189,7 @@ function NetworkedMapAndTokens({ session }) {
|
||||
* Map state
|
||||
*/
|
||||
|
||||
const { database } = useContext(DatabaseContext);
|
||||
const { database } = useDatabase();
|
||||
// Sync the map state to the database after 500ms of inactivity
|
||||
const debouncedMapState = useDebounce(currentMapState, 500);
|
||||
useEffect(() => {
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React, { useState, useContext, useEffect, useRef } from "react";
|
||||
import React, { useState, useEffect, useRef } from "react";
|
||||
import { Group } from "react-konva";
|
||||
|
||||
import AuthContext from "../contexts/AuthContext";
|
||||
import { useAuth } from "../contexts/AuthContext";
|
||||
|
||||
import MapPointer from "../components/map/MapPointer";
|
||||
import { isEmpty } from "../helpers/shared";
|
||||
@ -12,8 +12,8 @@ import useSetting from "../hooks/useSetting";
|
||||
// Send pointer updates every 50ms (20fps)
|
||||
const sendTickRate = 50;
|
||||
|
||||
function NetworkedMapPointer({ session, active, gridSize }) {
|
||||
const { userId } = useContext(AuthContext);
|
||||
function NetworkedMapPointer({ session, active }) {
|
||||
const { userId } = useAuth();
|
||||
const [localPointerState, setLocalPointerState] = useState({});
|
||||
const [pointerColor] = useSetting("pointer.color");
|
||||
|
||||
@ -194,7 +194,6 @@ function NetworkedMapPointer({ session, active, gridSize }) {
|
||||
{Object.values(localPointerState).map((pointer) => (
|
||||
<MapPointer
|
||||
key={pointer.id}
|
||||
gridSize={gridSize}
|
||||
active={pointer.id === userId ? active : false}
|
||||
position={pointer.position}
|
||||
visible={pointer.visible}
|
||||
|
@ -1,10 +1,4 @@
|
||||
import React, {
|
||||
useContext,
|
||||
useState,
|
||||
useEffect,
|
||||
useCallback,
|
||||
useRef,
|
||||
} from "react";
|
||||
import React, { useState, useEffect, useCallback, useRef } from "react";
|
||||
import { useToasts } from "react-toast-notifications";
|
||||
|
||||
// Load session for auto complete
|
||||
@ -12,7 +6,7 @@ import { useToasts } from "react-toast-notifications";
|
||||
import Session from "./Session";
|
||||
import { isStreamStopped, omit } from "../helpers/shared";
|
||||
|
||||
import PartyContext from "../contexts/PartyContext";
|
||||
import { useParty } from "../contexts/PartyContext";
|
||||
|
||||
import Party from "../components/party/Party";
|
||||
|
||||
@ -26,7 +20,7 @@ import Party from "../components/party/Party";
|
||||
* @param {NetworkedPartyProps} props
|
||||
*/
|
||||
function NetworkedParty({ gameId, session }) {
|
||||
const partyState = useContext(PartyContext);
|
||||
const partyState = useParty();
|
||||
const [stream, setStream] = useState(null);
|
||||
const [partyStreams, setPartyStreams] = useState({});
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useState, useEffect, useContext, useRef } from "react";
|
||||
import React, { useState, useEffect, useRef } from "react";
|
||||
import { Flex, Box, Text } from "theme-ui";
|
||||
import { useParams } from "react-router-dom";
|
||||
|
||||
@ -9,9 +9,9 @@ import MapLoadingOverlay from "../components/map/MapLoadingOverlay";
|
||||
|
||||
import AuthModal from "../modals/AuthModal";
|
||||
|
||||
import AuthContext from "../contexts/AuthContext";
|
||||
import { useAuth } from "../contexts/AuthContext";
|
||||
import { MapStageProvider } from "../contexts/MapStageContext";
|
||||
import DatabaseContext from "../contexts/DatabaseContext";
|
||||
import { useDatabase } from "../contexts/DatabaseContext";
|
||||
import { PlayerProvider } from "../contexts/PlayerContext";
|
||||
import { PartyProvider } from "../contexts/PartyContext";
|
||||
|
||||
@ -22,12 +22,8 @@ import Session from "../network/Session";
|
||||
|
||||
function Game() {
|
||||
const { id: gameId } = useParams();
|
||||
const {
|
||||
authenticationStatus,
|
||||
password,
|
||||
setAuthenticationStatus,
|
||||
} = useContext(AuthContext);
|
||||
const { databaseStatus } = useContext(DatabaseContext);
|
||||
const { authenticationStatus, password, setAuthenticationStatus } = useAuth();
|
||||
const { databaseStatus } = useDatabase();
|
||||
|
||||
const [session] = useState(new Session());
|
||||
const [offline, setOffline] = useState();
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useState, useEffect, useContext } from "react";
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { Flex, Button, Image, Text, IconButton, Link } from "theme-ui";
|
||||
import { useHistory } from "react-router-dom";
|
||||
|
||||
@ -10,7 +10,7 @@ import GettingStartedModal from "../modals/GettingStartedModal";
|
||||
|
||||
import HelpIcon from "../icons/HelpIcon";
|
||||
|
||||
import AuthContext from "../contexts/AuthContext";
|
||||
import { useAuth } from "../contexts/AuthContext";
|
||||
|
||||
import RedditIcon from "../icons/SocialRedditIcon";
|
||||
import TwitterIcon from "../icons/SocialTwitterIcon";
|
||||
@ -28,7 +28,7 @@ function Home() {
|
||||
);
|
||||
|
||||
// Reset password on visiting home
|
||||
const { setPassword } = useContext(AuthContext);
|
||||
const { setPassword } = useAuth();
|
||||
useEffect(() => {
|
||||
setPassword("");
|
||||
}, [setPassword]);
|
||||
|
Loading…
Reference in New Issue
Block a user