2021-07-17 12:48:04 +10:00
|
|
|
import { useState } from "react";
|
2021-05-06 15:04:53 +10:00
|
|
|
import { Box } from "theme-ui";
|
2021-06-14 11:57:08 +10:00
|
|
|
import { useToasts } from "react-toast-notifications";
|
2020-03-19 17:33:57 +11:00
|
|
|
|
2020-04-18 23:31:40 +10:00
|
|
|
import MapControls from "./MapControls";
|
2020-04-27 17:29:46 +10:00
|
|
|
import MapInteraction from "./MapInteraction";
|
2020-05-31 16:25:05 +10:00
|
|
|
import MapGrid from "./MapGrid";
|
2021-07-19 15:28:09 +10:00
|
|
|
|
|
|
|
|
import DrawingTool from "../tools/DrawingTool";
|
|
|
|
|
import FogTool from "../tools/FogTool";
|
|
|
|
|
import MeasureTool from "../tools/MeasureTool";
|
2020-07-28 17:59:26 +10:00
|
|
|
import NetworkedMapPointer from "../../network/NetworkedMapPointer";
|
2020-03-20 13:33:12 +11:00
|
|
|
|
2021-02-06 13:32:38 +11:00
|
|
|
import { useSettings } from "../../contexts/SettingsContext";
|
2021-07-21 17:12:49 +10:00
|
|
|
import { useUserId } from "../../contexts/UserIdContext";
|
2020-04-27 17:29:46 +10:00
|
|
|
|
2021-07-19 15:28:09 +10:00
|
|
|
import Action from "../../actions/Action";
|
2021-02-04 09:11:27 +11:00
|
|
|
import {
|
2021-07-16 14:55:33 +10:00
|
|
|
AddStatesAction,
|
|
|
|
|
CutFogAction,
|
|
|
|
|
EditStatesAction,
|
|
|
|
|
RemoveStatesAction,
|
2021-02-04 09:11:27 +11:00
|
|
|
} from "../../actions";
|
2021-07-19 15:28:09 +10:00
|
|
|
|
2021-06-02 17:49:31 +10:00
|
|
|
import Session from "../../network/Session";
|
2021-07-19 15:28:09 +10:00
|
|
|
|
2021-07-17 12:48:04 +10:00
|
|
|
import { Drawing, DrawingState } from "../../types/Drawing";
|
|
|
|
|
import { Fog, FogState } from "../../types/Fog";
|
2021-07-20 21:45:18 +10:00
|
|
|
import { Map as MapType, MapToolId } from "../../types/Map";
|
2021-07-16 14:55:33 +10:00
|
|
|
import { MapState } from "../../types/MapState";
|
|
|
|
|
import { Settings } from "../../types/Settings";
|
|
|
|
|
import {
|
|
|
|
|
MapChangeEventHandler,
|
|
|
|
|
MapResetEventHandler,
|
2021-07-20 18:53:03 +10:00
|
|
|
TokenStateRemoveHandler,
|
2021-07-17 12:48:04 +10:00
|
|
|
NoteChangeEventHandler,
|
|
|
|
|
NoteRemoveEventHander,
|
|
|
|
|
TokenStateChangeEventHandler,
|
2021-07-20 20:17:41 +10:00
|
|
|
NoteCreateEventHander,
|
2021-07-21 18:56:18 +10:00
|
|
|
SelectionItemsChangeEventHandler,
|
2021-07-22 16:40:43 +10:00
|
|
|
SelectionItemsRemoveEventHandler,
|
2021-07-23 15:41:07 +10:00
|
|
|
SelectionItemsCreateEventHandler,
|
2021-08-06 12:04:22 +10:00
|
|
|
TokensStateCreateHandler,
|
2021-07-16 14:55:33 +10:00
|
|
|
} from "../../types/Events";
|
2021-07-19 15:28:09 +10:00
|
|
|
|
|
|
|
|
import useMapTokens from "../../hooks/useMapTokens";
|
|
|
|
|
import useMapNotes from "../../hooks/useMapNotes";
|
2021-07-21 17:12:49 +10:00
|
|
|
import { MapActions } from "../../hooks/useMapActions";
|
2021-07-22 13:16:44 +10:00
|
|
|
import useMapSelection from "../../hooks/useMapSelection";
|
2021-07-17 12:48:04 +10:00
|
|
|
|
|
|
|
|
type MapProps = {
|
2021-07-17 18:18:57 +10:00
|
|
|
map: MapType | null;
|
2021-07-17 17:25:41 +10:00
|
|
|
mapState: MapState | null;
|
2021-07-21 17:12:49 +10:00
|
|
|
mapActions: MapActions;
|
2021-07-17 12:48:04 +10:00
|
|
|
onMapTokenStateChange: TokenStateChangeEventHandler;
|
2021-07-20 18:53:03 +10:00
|
|
|
onMapTokenStateRemove: TokenStateRemoveHandler;
|
2021-08-06 12:04:22 +10:00
|
|
|
onMapTokensStateCreate: TokensStateCreateHandler;
|
2021-07-21 18:56:18 +10:00
|
|
|
onSelectionItemsChange: SelectionItemsChangeEventHandler;
|
2021-07-22 16:40:43 +10:00
|
|
|
onSelectionItemsRemove: SelectionItemsRemoveEventHandler;
|
2021-07-23 15:41:07 +10:00
|
|
|
onSelectionItemsCreate: SelectionItemsCreateEventHandler;
|
2021-07-17 12:48:04 +10:00
|
|
|
onMapChange: MapChangeEventHandler;
|
|
|
|
|
onMapReset: MapResetEventHandler;
|
|
|
|
|
onMapDraw: (action: Action<DrawingState>) => void;
|
|
|
|
|
onFogDraw: (action: Action<FogState>) => void;
|
2021-07-20 20:17:41 +10:00
|
|
|
onMapNoteCreate: NoteCreateEventHander;
|
2021-07-17 12:48:04 +10:00
|
|
|
onMapNoteChange: NoteChangeEventHandler;
|
|
|
|
|
onMapNoteRemove: NoteRemoveEventHander;
|
|
|
|
|
allowMapChange: boolean;
|
|
|
|
|
session: Session;
|
2021-07-20 21:45:18 +10:00
|
|
|
onUndo: () => void;
|
|
|
|
|
onRedo: () => void;
|
2021-07-17 12:48:04 +10:00
|
|
|
};
|
2020-03-20 13:33:12 +11:00
|
|
|
|
2020-03-20 18:06:24 +11:00
|
|
|
function Map({
|
2020-04-23 11:54:29 +10:00
|
|
|
map,
|
2020-04-23 17:23:34 +10:00
|
|
|
mapState,
|
2021-07-21 17:12:49 +10:00
|
|
|
mapActions,
|
2020-04-24 18:39:11 +10:00
|
|
|
onMapTokenStateChange,
|
|
|
|
|
onMapTokenStateRemove,
|
2021-08-06 12:04:22 +10:00
|
|
|
onMapTokensStateCreate,
|
2021-07-21 18:56:18 +10:00
|
|
|
onSelectionItemsChange,
|
2021-07-22 16:40:43 +10:00
|
|
|
onSelectionItemsRemove,
|
2021-07-23 15:41:07 +10:00
|
|
|
onSelectionItemsCreate,
|
2020-04-13 00:24:03 +10:00
|
|
|
onMapChange,
|
2021-02-22 17:14:12 +11:00
|
|
|
onMapReset,
|
2020-04-19 15:15:48 +10:00
|
|
|
onMapDraw,
|
2020-04-28 22:05:47 +10:00
|
|
|
onFogDraw,
|
2021-07-20 20:17:41 +10:00
|
|
|
onMapNoteCreate,
|
2020-11-04 15:03:34 +11:00
|
|
|
onMapNoteChange,
|
2020-11-05 14:41:33 +11:00
|
|
|
onMapNoteRemove,
|
2020-07-17 15:57:52 +10:00
|
|
|
allowMapChange,
|
2020-07-28 17:59:26 +10:00
|
|
|
session,
|
2021-07-20 21:45:18 +10:00
|
|
|
onUndo,
|
|
|
|
|
onRedo,
|
2021-07-17 12:48:04 +10:00
|
|
|
}: MapProps) {
|
2021-06-14 11:57:08 +10:00
|
|
|
const { addToast } = useToasts();
|
|
|
|
|
|
2021-07-21 17:12:49 +10:00
|
|
|
const userId = useUserId();
|
|
|
|
|
|
2021-07-16 14:55:33 +10:00
|
|
|
const [selectedToolId, setSelectedToolId] = useState<MapToolId>("move");
|
|
|
|
|
const { settings, setSettings } = useSettings();
|
2020-04-29 20:55:52 +10:00
|
|
|
|
2021-07-16 14:55:33 +10:00
|
|
|
function handleToolSettingChange(change: Partial<Settings>) {
|
|
|
|
|
setSettings((prevSettings) => ({
|
2020-04-27 17:29:46 +10:00
|
|
|
...prevSettings,
|
2021-07-16 14:55:33 +10:00
|
|
|
...change,
|
2020-04-27 17:29:46 +10:00
|
|
|
}));
|
|
|
|
|
}
|
2020-04-19 00:24:06 +10:00
|
|
|
|
2021-08-06 08:21:19 +10:00
|
|
|
const drawShapes = Object.values(mapState?.drawings || {});
|
|
|
|
|
const fogShapes = Object.values(mapState?.fogs || {});
|
2021-02-04 09:11:27 +11:00
|
|
|
|
2021-06-02 17:49:31 +10:00
|
|
|
function handleToolAction(action: string) {
|
2020-04-29 20:55:52 +10:00
|
|
|
if (action === "eraseAll") {
|
2021-07-16 14:55:33 +10:00
|
|
|
onMapDraw(new RemoveStatesAction(drawShapes.map((s) => s.id)));
|
2020-04-29 20:55:52 +10:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-07-16 14:55:33 +10:00
|
|
|
function handleMapShapeAdd(shape: Drawing) {
|
|
|
|
|
onMapDraw(new AddStatesAction([shape]));
|
2020-04-19 13:33:31 +10:00
|
|
|
}
|
|
|
|
|
|
2021-06-02 17:49:31 +10:00
|
|
|
function handleMapShapesRemove(shapeIds: string[]) {
|
2021-07-16 14:55:33 +10:00
|
|
|
onMapDraw(new RemoveStatesAction(shapeIds));
|
2020-04-20 11:56:56 +10:00
|
|
|
}
|
|
|
|
|
|
2021-07-16 14:55:33 +10:00
|
|
|
function handleFogShapesAdd(shapes: Fog[]) {
|
|
|
|
|
onFogDraw(new AddStatesAction(shapes));
|
2020-04-28 22:05:47 +10:00
|
|
|
}
|
|
|
|
|
|
2021-07-16 14:55:33 +10:00
|
|
|
function handleFogShapesCut(shapes: Fog[]) {
|
|
|
|
|
onFogDraw(new CutFogAction(shapes));
|
2020-06-09 12:45:52 +10:00
|
|
|
}
|
|
|
|
|
|
2021-06-02 17:49:31 +10:00
|
|
|
function handleFogShapesRemove(shapeIds: string[]) {
|
2021-07-16 14:55:33 +10:00
|
|
|
onFogDraw(new RemoveStatesAction(shapeIds));
|
2020-04-19 13:33:31 +10:00
|
|
|
}
|
|
|
|
|
|
2021-07-16 14:55:33 +10:00
|
|
|
function handleFogShapesEdit(shapes: Partial<Fog>[]) {
|
|
|
|
|
onFogDraw(new EditStatesAction(shapes));
|
2020-04-29 20:40:34 +10:00
|
|
|
}
|
|
|
|
|
|
2021-08-05 15:17:10 +10:00
|
|
|
const { tokens, propTokens, tokenMenu, tokenDragOverlay } = useMapTokens(
|
2021-07-19 15:28:09 +10:00
|
|
|
map,
|
|
|
|
|
mapState,
|
|
|
|
|
onMapTokenStateChange,
|
|
|
|
|
onMapTokenStateRemove,
|
2021-08-06 12:04:22 +10:00
|
|
|
onMapTokensStateCreate,
|
2021-07-21 17:12:49 +10:00
|
|
|
selectedToolId
|
2020-07-20 19:14:46 +10:00
|
|
|
);
|
2020-03-20 17:56:34 +11:00
|
|
|
|
2021-07-19 15:28:09 +10:00
|
|
|
const { notes, noteMenu, noteDragOverlay } = useMapNotes(
|
|
|
|
|
map,
|
|
|
|
|
mapState,
|
2021-07-20 20:17:41 +10:00
|
|
|
onMapNoteCreate,
|
2021-07-19 15:28:09 +10:00
|
|
|
onMapNoteChange,
|
|
|
|
|
onMapNoteRemove,
|
2021-08-05 14:36:57 +10:00
|
|
|
selectedToolId
|
2021-07-19 11:37:41 +10:00
|
|
|
);
|
|
|
|
|
|
2021-07-22 16:40:43 +10:00
|
|
|
const { selectionTool, selectionMenu, selectionDragOverlay } =
|
|
|
|
|
useMapSelection(
|
|
|
|
|
map,
|
|
|
|
|
mapState,
|
|
|
|
|
onSelectionItemsChange,
|
|
|
|
|
onSelectionItemsRemove,
|
2021-07-23 15:41:07 +10:00
|
|
|
onSelectionItemsCreate,
|
2021-07-22 16:40:43 +10:00
|
|
|
selectedToolId,
|
|
|
|
|
settings.select
|
|
|
|
|
);
|
2021-07-22 13:16:44 +10:00
|
|
|
|
2020-03-19 17:33:57 +11:00
|
|
|
return (
|
2021-05-06 15:04:53 +10:00
|
|
|
<Box sx={{ flexGrow: 1 }}>
|
2021-05-13 16:27:07 +10:00
|
|
|
<MapInteraction
|
|
|
|
|
map={map}
|
|
|
|
|
mapState={mapState}
|
|
|
|
|
controls={
|
|
|
|
|
<>
|
2021-07-19 15:28:09 +10:00
|
|
|
<MapControls
|
|
|
|
|
onMapChange={onMapChange}
|
|
|
|
|
onMapReset={onMapReset}
|
2021-07-21 17:12:49 +10:00
|
|
|
map={map}
|
|
|
|
|
mapState={mapState}
|
|
|
|
|
mapActions={mapActions}
|
|
|
|
|
allowMapChange={allowMapChange}
|
2021-07-19 15:28:09 +10:00
|
|
|
onSelectedToolChange={setSelectedToolId}
|
|
|
|
|
selectedToolId={selectedToolId}
|
|
|
|
|
toolSettings={settings}
|
|
|
|
|
onToolSettingChange={handleToolSettingChange}
|
|
|
|
|
onToolAction={handleToolAction}
|
2021-07-20 21:45:18 +10:00
|
|
|
onUndo={onUndo}
|
|
|
|
|
onRedo={onRedo}
|
2021-07-19 15:28:09 +10:00
|
|
|
/>
|
2021-05-13 16:27:07 +10:00
|
|
|
{tokenMenu}
|
|
|
|
|
{noteMenu}
|
2021-07-22 13:16:44 +10:00
|
|
|
{selectionMenu}
|
2021-05-13 16:27:07 +10:00
|
|
|
{tokenDragOverlay}
|
|
|
|
|
{noteDragOverlay}
|
2021-07-22 16:40:43 +10:00
|
|
|
{selectionDragOverlay}
|
2021-05-13 16:27:07 +10:00
|
|
|
</>
|
|
|
|
|
}
|
|
|
|
|
selectedToolId={selectedToolId}
|
|
|
|
|
onSelectedToolChange={setSelectedToolId}
|
|
|
|
|
>
|
2021-07-19 15:28:09 +10:00
|
|
|
{map && map.showGrid && <MapGrid map={map} />}
|
2021-08-05 15:17:10 +10:00
|
|
|
{propTokens}
|
2021-07-19 15:28:09 +10:00
|
|
|
<DrawingTool
|
|
|
|
|
map={map}
|
|
|
|
|
drawings={drawShapes}
|
|
|
|
|
onDrawingAdd={handleMapShapeAdd}
|
|
|
|
|
onDrawingsRemove={handleMapShapesRemove}
|
|
|
|
|
active={selectedToolId === "drawing"}
|
|
|
|
|
toolSettings={settings.drawing}
|
|
|
|
|
/>
|
|
|
|
|
{notes}
|
|
|
|
|
{tokens}
|
|
|
|
|
<FogTool
|
|
|
|
|
map={map}
|
|
|
|
|
shapes={fogShapes}
|
|
|
|
|
onShapesAdd={handleFogShapesAdd}
|
|
|
|
|
onShapesCut={handleFogShapesCut}
|
|
|
|
|
onShapesRemove={handleFogShapesRemove}
|
|
|
|
|
onShapesEdit={handleFogShapesEdit}
|
|
|
|
|
onShapeError={addToast}
|
|
|
|
|
active={selectedToolId === "fog"}
|
|
|
|
|
toolSettings={settings.fog}
|
2021-07-21 17:12:49 +10:00
|
|
|
editable={
|
|
|
|
|
!!(map?.owner === userId || mapState?.editFlags.includes("fog")) &&
|
|
|
|
|
!settings.fog.preview
|
|
|
|
|
}
|
2021-07-19 15:28:09 +10:00
|
|
|
/>
|
|
|
|
|
<NetworkedMapPointer
|
|
|
|
|
active={selectedToolId === "pointer"}
|
|
|
|
|
session={session}
|
|
|
|
|
/>
|
|
|
|
|
<MeasureTool map={map} active={selectedToolId === "measure"} />
|
2021-07-22 13:16:44 +10:00
|
|
|
{selectionTool}
|
2021-05-13 16:27:07 +10:00
|
|
|
</MapInteraction>
|
2021-05-06 15:04:53 +10:00
|
|
|
</Box>
|
2020-03-19 17:33:57 +11:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export default Map;
|