From 31cdbbb8ddb8038842ebbdea7dcc8660ac7c313a Mon Sep 17 00:00:00 2001 From: Mitchell McCaffrey Date: Sun, 31 May 2020 10:23:45 +1000 Subject: [PATCH 01/13] Fix bug with deleteing tokens that have been removed --- src/components/map/MapToken.js | 4 ++-- src/components/token/TokenDragOverlay.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/map/MapToken.js b/src/components/map/MapToken.js index 9f67bba..f55dd4e 100644 --- a/src/components/map/MapToken.js +++ b/src/components/map/MapToken.js @@ -48,7 +48,7 @@ function MapToken({ const tokenImage = event.target; const tokenImageRect = tokenImage.getClientRect(); - if (token.isVehicle) { + if (token && token.isVehicle) { // Find all other tokens on the map const layer = tokenImage.getLayer(); const tokens = layer.find(".token"); @@ -83,7 +83,7 @@ function MapToken({ const tokenImage = event.target; const mountChanges = {}; - if (token.isVehicle) { + if (token && token.isVehicle) { const layer = tokenImage.getLayer(); const mountedTokens = tokenImage.find(".token"); for (let mountedToken of mountedTokens) { diff --git a/src/components/token/TokenDragOverlay.js b/src/components/token/TokenDragOverlay.js index 70097bc..cb32009 100644 --- a/src/components/token/TokenDragOverlay.js +++ b/src/components/token/TokenDragOverlay.js @@ -66,7 +66,7 @@ function TokenDragOverlay({ function handleTokenDragEnd() { if (isRemoveHovered) { // Handle other tokens when a vehicle gets deleted - if (token.isVehicle) { + if (token && token.isVehicle) { const layer = tokenImage.getLayer(); const mountedTokens = tokenImage.find(".token"); for (let mountedToken of mountedTokens) { From 55bf9e4d03f5c6be4ebf9eba9d322126d9c7fad0 Mon Sep 17 00:00:00 2001 From: Mitchell McCaffrey Date: Sun, 31 May 2020 10:53:33 +1000 Subject: [PATCH 02/13] Added multiple simultaneous map and token upload support --- src/components/ImageDrop.js | 10 +++++++--- src/modals/SelectMapModal.js | 34 +++++++++++++++++++++------------ src/modals/SelectTokensModal.js | 33 +++++++++++++++++++++----------- 3 files changed, 51 insertions(+), 26 deletions(-) diff --git a/src/components/ImageDrop.js b/src/components/ImageDrop.js index da41987..8bd71d3 100644 --- a/src/components/ImageDrop.js +++ b/src/components/ImageDrop.js @@ -18,10 +18,14 @@ function ImageDrop({ onDrop, dropText, children }) { function handleImageDrop(event) { event.preventDefault(); event.stopPropagation(); - const file = event.dataTransfer.files[0]; - if (file && file.type.startsWith("image")) { - onDrop(file); + const files = event.dataTransfer.files; + let imageFiles = []; + for (let file of files) { + if (file.type.startsWith("image")) { + imageFiles.push(file); + } } + onDrop(imageFiles); setDragging(false); } diff --git a/src/modals/SelectMapModal.js b/src/modals/SelectMapModal.js index 91de48a..d721f6e 100644 --- a/src/modals/SelectMapModal.js +++ b/src/modals/SelectMapModal.js @@ -51,9 +51,17 @@ function SelectMapModal({ const fileInputRef = useRef(); - function handleImageUpload(file) { + async function handleImagesUpload(files) { + for (let file of files) { + await handleImageUpload(file); + } + // Set file input to null to allow adding the same image 2 times in a row + fileInputRef.current.value = null; + } + + async function handleImageUpload(file) { if (!file) { - return; + return Promise.reject(); } let fileGridX = defaultMapSize; let fileGridY = defaultMapSize; @@ -86,11 +94,13 @@ function SelectMapModal({ let image = new Image(); setImageLoading(true); - blobToBuffer(file).then((buffer) => { - // Copy file to avoid permissions issues - const blob = new Blob([buffer]); - // Create and load the image temporarily to get its dimensions - const url = URL.createObjectURL(blob); + const buffer = await blobToBuffer(file); + // Copy file to avoid permissions issues + const blob = new Blob([buffer]); + // Create and load the image temporarily to get its dimensions + const url = URL.createObjectURL(blob); + + return new Promise((resolve, reject) => { image.onload = function () { handleMapAdd({ // Save as a buffer to send with msgpack @@ -109,11 +119,10 @@ function SelectMapModal({ }); setImageLoading(false); URL.revokeObjectURL(url); + resolve(); }; + image.onerror = reject; image.src = url; - - // Set file input to null to allow adding the same image 2 times in a row - fileInputRef.current.value = null; }); } @@ -172,12 +181,13 @@ function SelectMapModal({ return ( - + handleImageUpload(event.target.files[0])} + onChange={(event) => handleImagesUpload(event.target.files)} type="file" accept="image/*" style={{ display: "none" }} + multiple ref={fileInputRef} /> { - // Copy file to avoid permissions issues - const blob = new Blob([buffer]); - // Create and load the image temporarily to get its dimensions - const url = URL.createObjectURL(blob); + const buffer = await blobToBuffer(file); + + // Copy file to avoid permissions issues + const blob = new Blob([buffer]); + // Create and load the image temporarily to get its dimensions + const url = URL.createObjectURL(blob); + + return new Promise((resolve, reject) => { image.onload = function () { handleTokenAdd({ file: buffer, @@ -68,11 +79,10 @@ function SelectTokensModal({ isOpen, onRequestClose }) { hideInSidebar: false, }); setImageLoading(false); + resolve(); }; + image.onerror = reject; image.src = url; - - // Set file input to null to allow adding the same image 2 times in a row - fileInputRef.current.value = null; }); } @@ -96,13 +106,14 @@ function SelectTokensModal({ isOpen, onRequestClose }) { return ( - + handleImageUpload(event.target.files[0])} + onChange={(event) => handleImagesUpload(event.target.files)} type="file" accept="image/*" style={{ display: "none" }} ref={fileInputRef} + multiple /> Date: Sun, 31 May 2020 12:12:16 +1000 Subject: [PATCH 03/13] Changed map and fog erase to allow for multi item selection --- src/components/map/Map.js | 18 ++++---- src/components/map/MapDrawing.js | 62 ++++++++++++------------- src/components/map/MapFog.js | 78 ++++++++++++++++---------------- 3 files changed, 78 insertions(+), 80 deletions(-) diff --git a/src/components/map/Map.js b/src/components/map/Map.js index f44e5e1..71b0a1f 100644 --- a/src/components/map/Map.js +++ b/src/components/map/Map.js @@ -97,8 +97,8 @@ function Map({ onMapDraw({ type: "add", shapes: [shape] }); } - function handleMapShapeRemove(shapeId) { - onMapDraw({ type: "remove", shapeIds: [shapeId] }); + function handleMapShapesRemove(shapeIds) { + onMapDraw({ type: "remove", shapeIds }); } const [fogShapes, setFogShapes] = useState([]); @@ -107,12 +107,12 @@ function Map({ onFogDraw({ type: "add", shapes: [shape] }); } - function handleFogShapeRemove(shapeId) { - onFogDraw({ type: "remove", shapeIds: [shapeId] }); + function handleFogShapesRemove(shapeIds) { + onFogDraw({ type: "remove", shapeIds }); } - function handleFogShapeEdit(shape) { - onFogDraw({ type: "edit", shapes: [shape] }); + function handleFogShapesEdit(shapes) { + onFogDraw({ type: "edit", shapes }); } // Replay the draw actions and convert them to shapes for the map drawing @@ -275,7 +275,7 @@ function Map({ { + setIsBrushDown(false); + if (erasingShapes.length > 0) { + onShapesRemove(erasingShapes.map((shape) => shape.id)); + setErasingShapes([]); + } + }, [erasingShapes, onShapesRemove]); + const handleShapeDraw = useCallback( (brushState, mapBrushPosition) => { function startShape() { @@ -65,6 +75,7 @@ function MapDrawing({ ...commonShapeData, }); } + setIsBrushDown(true); } function continueShape() { @@ -119,6 +130,7 @@ function MapDrawing({ onShapeAdd(drawingShape); } setDrawingShape(null); + handleBrushUp(); } switch (brushState) { @@ -143,48 +155,27 @@ function MapDrawing({ onShapeAdd, shapes, drawingShape, + handleBrushUp, ] ); useMapBrush(isEditing, handleShapeDraw); - function handleShapeClick(_, shape) { - if (selectedToolId === "erase") { - onShapeRemove(shape.id); - } - } - - function handleShapeMouseOver(event, shape) { - if (shouldHover) { - const path = event.target; - const hoverColor = "#BB99FF"; - path.fill(hoverColor); - if (shape.type === "path") { - path.stroke(hoverColor); + function handleShapeOver(shape, isDown) { + if (shouldHover && isDown) { + if (erasingShapes.findIndex((s) => s.id === shape.id) === -1) { + setErasingShapes((prevShapes) => [...prevShapes, shape]); } - path.getLayer().draw(); - } - } - - function handleShapeMouseOut(event, shape) { - if (shouldHover) { - const path = event.target; - const color = colors[shape.color] || shape.color; - path.fill(color); - if (shape.type === "path") { - path.stroke(color); - } - path.getLayer().draw(); } } function renderShape(shape) { const defaultProps = { key: shape.id, - onMouseOver: (e) => handleShapeMouseOver(e, shape), - onMouseOut: (e) => handleShapeMouseOut(e, shape), - onClick: (e) => handleShapeClick(e, shape), - onTap: (e) => handleShapeClick(e, shape), + onMouseMove: () => handleShapeOver(shape, isBrushDown), + onTouchOver: () => handleShapeOver(shape, isBrushDown), + onMouseDown: () => handleShapeOver(shape, true), + onTouchStart: () => handleShapeOver(shape, true), fill: colors[shape.color] || shape.color, opacity: shape.blend ? 0.5 : 1, }; @@ -245,10 +236,19 @@ function MapDrawing({ } } + function renderErasingShape(shape) { + const eraseShape = { + ...shape, + color: "#BB99FF", + }; + return renderShape(eraseShape); + } + return ( {shapes.map(renderShape)} {drawingShape && renderShape(drawingShape)} + {erasingShapes.length > 0 && erasingShapes.map(renderErasingShape)} ); } diff --git a/src/components/map/MapFog.js b/src/components/map/MapFog.js index fbb8782..84dc929 100644 --- a/src/components/map/MapFog.js +++ b/src/components/map/MapFog.js @@ -20,14 +20,16 @@ import useMapBrush from "../../helpers/useMapBrush"; function MapFog({ shapes, onShapeAdd, - onShapeRemove, - onShapeEdit, + onShapesRemove, + onShapesEdit, selectedToolId, selectedToolSettings, gridSize, }) { const { stageScale, mapWidth, mapHeight } = useContext(MapInteractionContext); const [drawingShape, setDrawingShape] = useState(null); + const [isBrushDown, setIsBrushDown] = useState(false); + const [editingShapes, setEditingShapes] = useState([]); const isEditing = selectedToolId === "fog"; const shouldHover = @@ -37,6 +39,20 @@ function MapFog({ const [patternImage] = useImage(diagonalPattern); + const handleBrushUp = useCallback(() => { + setIsBrushDown(false); + if (editingShapes.length > 0) { + if (selectedToolSettings.type === "remove") { + onShapesRemove(editingShapes.map((shape) => shape.id)); + } else if (selectedToolSettings.type === "toggle") { + onShapesEdit( + editingShapes.map((shape) => ({ ...shape, visible: !shape.visible })) + ); + } + setEditingShapes([]); + } + }, [editingShapes, onShapesRemove, onShapesEdit, selectedToolSettings]); + const handleShapeDraw = useCallback( (brushState, mapBrushPosition) => { function startShape() { @@ -58,6 +74,7 @@ function MapFog({ visible: true, }); } + setIsBrushDown(true); } function continueShape() { @@ -106,6 +123,7 @@ function MapFog({ } } setDrawingShape(null); + handleBrushUp(); } switch (brushState) { @@ -130,46 +148,17 @@ function MapFog({ onShapeAdd, shapes, drawingShape, + handleBrushUp, ] ); useMapBrush(isEditing, handleShapeDraw); - function handleShapeClick(_, shape) { - if (!isEditing) { - return; - } - - if (selectedToolSettings.type === "remove") { - onShapeRemove(shape.id); - } else if (selectedToolSettings.type === "toggle") { - onShapeEdit({ ...shape, visible: !shape.visible }); - } - } - - function handleShapeMouseOver(event, shape) { - if (shouldHover) { - const path = event.target; - if (shape.visible) { - const hoverColor = "#BB99FF"; - path.fill(hoverColor); - } else { - path.opacity(1); + function handleShapeOver(shape, isDown) { + if (shouldHover && isDown) { + if (editingShapes.findIndex((s) => s.id === shape.id) === -1) { + setEditingShapes((prevShapes) => [...prevShapes, shape]); } - path.getLayer().draw(); - } - } - - function handleShapeMouseOut(event, shape) { - if (shouldHover) { - const path = event.target; - if (shape.visible) { - const color = colors[shape.color] || shape.color; - path.fill(color); - } else { - path.opacity(0.5); - } - path.getLayer().draw(); } } @@ -177,10 +166,10 @@ function MapFog({ return ( handleShapeMouseOver(e, shape)} - onMouseOut={(e) => handleShapeMouseOut(e, shape)} - onClick={(e) => handleShapeClick(e, shape)} - onTap={(e) => handleShapeClick(e, shape)} + onMouseMove={() => handleShapeOver(shape, isBrushDown)} + onTouchOver={() => handleShapeOver(shape, isBrushDown)} + onMouseDown={() => handleShapeOver(shape, true)} + onTouchStart={() => handleShapeOver(shape, true)} points={shape.data.points.reduce( (acc, point) => [...acc, point.x * mapWidth, point.y * mapHeight], [] @@ -203,10 +192,19 @@ function MapFog({ ); } + function renderEditingShape(shape) { + const editingShape = { + ...shape, + color: "#BB99FF", + }; + return renderShape(editingShape); + } + return ( {shapes.map(renderShape)} {drawingShape && renderShape(drawingShape)} + {editingShapes.length > 0 && editingShapes.map(renderEditingShape)} ); } From 7dac49f690202479210f2b1abc1ef365c1036715 Mon Sep 17 00:00:00 2001 From: Mitchell McCaffrey Date: Sun, 31 May 2020 13:56:33 +1000 Subject: [PATCH 04/13] Fix fog undo disabling --- src/components/map/Map.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/map/Map.js b/src/components/map/Map.js index 71b0a1f..9be30fb 100644 --- a/src/components/map/Map.js +++ b/src/components/map/Map.js @@ -174,7 +174,7 @@ function Map({ disabledSettings.shape.push("redo"); disabledSettings.erase.push("redo"); } - if (fogShapes.length === 0) { + if (!mapState || mapState.fogDrawActionIndex < 0) { disabledSettings.fog.push("undo"); } if ( From 98543f60eb9bfd519d837c6fdeb3a298a64f3004 Mon Sep 17 00:00:00 2001 From: Mitchell McCaffrey Date: Sun, 31 May 2020 15:35:03 +1000 Subject: [PATCH 05/13] Added log image helper function --- src/helpers/shared.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/helpers/shared.js b/src/helpers/shared.js index 7552d7b..8f11569 100644 --- a/src/helpers/shared.js +++ b/src/helpers/shared.js @@ -39,3 +39,14 @@ export function toDegrees(angle) { export function lerp(a, b, alpha) { return a * (1 - alpha) + b * alpha; } + +// Console log an image +export function logImage(url, width, height) { + const style = [ + "font-size: 1px;", + `padding: ${height}px ${width}px;`, + `background: url(${url}) no-repeat;`, + "background-size: contain;", + ].join(" "); + console.log("%c ", style); +} From a5a2c1ac7768a3b31ad6e4a31fbeb40e00df6810 Mon Sep 17 00:00:00 2001 From: Mitchell McCaffrey Date: Sun, 31 May 2020 16:24:17 +1000 Subject: [PATCH 06/13] Add fill option to divider --- src/components/Divider.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/components/Divider.js b/src/components/Divider.js index 853aa0c..0d51b0a 100644 --- a/src/components/Divider.js +++ b/src/components/Divider.js @@ -1,15 +1,15 @@ import React from "react"; import { Divider } from "theme-ui"; -function StyledDivider({ vertical, color }) { +function StyledDivider({ vertical, color, fill }) { return ( Date: Sun, 31 May 2020 16:24:39 +1000 Subject: [PATCH 07/13] Added more visual to checkbox disabled --- src/index.css | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/index.css b/src/index.css index e679604..fb96b26 100644 --- a/src/index.css +++ b/src/index.css @@ -9,3 +9,7 @@ html { .simplebar-scrollbar:before { background: #fff; } + +input[type="checkbox"]:disabled ~ svg { + opacity: 0.1; +} From faddf03ecf9906a1c0a6628195a0afa5015585a0 Mon Sep 17 00:00:00 2001 From: Mitchell McCaffrey Date: Sun, 31 May 2020 16:25:05 +1000 Subject: [PATCH 08/13] Added show map grid option to maps --- src/components/map/Map.js | 6 ++ src/components/map/MapGrid.js | 93 +++++++++++++++++++++++++++++++ src/components/map/MapSettings.js | 33 +++++++---- src/contexts/MapDataContext.js | 1 + src/database.js | 11 ++++ src/modals/SelectMapModal.js | 1 + 6 files changed, 135 insertions(+), 10 deletions(-) create mode 100644 src/components/map/MapGrid.js diff --git a/src/components/map/Map.js b/src/components/map/Map.js index 9be30fb..38b54dc 100644 --- a/src/components/map/Map.js +++ b/src/components/map/Map.js @@ -6,6 +6,7 @@ import MapToken from "./MapToken"; import MapDrawing from "./MapDrawing"; import MapFog from "./MapFog"; import MapDice from "./MapDice"; +import MapGrid from "./MapGrid"; import TokenDataContext from "../../contexts/TokenDataContext"; import MapLoadingContext from "../../contexts/MapLoadingContext"; @@ -294,6 +295,10 @@ function Map({ /> ); + const mapGrid = map && map.showGrid && ( + + ); + return ( + {mapGrid} {mapDrawing} {mapTokens} {mapFog} diff --git a/src/components/map/MapGrid.js b/src/components/map/MapGrid.js new file mode 100644 index 0000000..06df57a --- /dev/null +++ b/src/components/map/MapGrid.js @@ -0,0 +1,93 @@ +import React, { useContext, useEffect, useState } from "react"; +import { Line, Group } from "react-konva"; +import useImage from "use-image"; + +import MapInteractionContext from "../../contexts/MapInteractionContext"; + +import useDataSource from "../../helpers/useDataSource"; +import { mapSources as defaultMapSources } from "../../maps"; + +import { getStrokeWidth } from "../../helpers/drawing"; + +const lightnessDetectionOffset = 0.1; + +function MapGrid({ map, gridSize }) { + const mapSource = useDataSource(map, defaultMapSources); + const [mapImage, mapLoadingStatus] = useImage(mapSource); + + const gridX = map && map.gridX; + const gridY = map && map.gridY; + + const { mapWidth, mapHeight } = useContext(MapInteractionContext); + + const lineSpacingX = mapWidth / gridX; + const lineSpacingY = mapHeight / gridY; + + const [isImageLight, setIsImageLight] = useState(true); + + // When the map changes find the average lightness of its pixels + useEffect(() => { + if (mapLoadingStatus === "loaded") { + const imageWidth = mapImage.width; + const imageHeight = mapImage.height; + let canvas = document.createElement("canvas"); + canvas.width = imageWidth; + canvas.height = imageHeight; + let context = canvas.getContext("2d"); + context.drawImage(mapImage, 0, 0); + const imageData = context.getImageData(0, 0, imageWidth, imageHeight); + + const data = imageData.data; + let lightPixels = 0; + let darkPixels = 0; + // Loop over every pixels rgba values + for (let i = 0; i < data.length; i += 4) { + const r = data[i]; + const g = data[i + 1]; + const b = data[i + 2]; + + const max = Math.max(Math.max(r, g), b); + if (max < 128) { + darkPixels++; + } else { + lightPixels++; + } + } + + const norm = (lightPixels - darkPixels) / (imageWidth * imageHeight); + if (norm + lightnessDetectionOffset < 0) { + setIsImageLight(false); + } else { + setIsImageLight(true); + } + } + }, [mapImage, mapLoadingStatus]); + + const lines = []; + for (let x = 1; x < gridX; x++) { + lines.push( + + ); + } + for (let y = 1; y < gridY; y++) { + lines.push( + + ); + } + + return {lines}; +} + +export default MapGrid; diff --git a/src/components/map/MapSettings.js b/src/components/map/MapSettings.js index dcefccb..1861bd4 100644 --- a/src/components/map/MapSettings.js +++ b/src/components/map/MapSettings.js @@ -3,6 +3,8 @@ import { Flex, Box, Label, Input, Checkbox, IconButton } from "theme-ui"; import ExpandMoreIcon from "../../icons/ExpandMoreIcon"; +import Divider from "../Divider"; + function MapSettings({ map, mapState, @@ -57,6 +59,27 @@ function MapSettings({ {showMore && ( <> + + onSettingsChange("name", e.target.value)} + disabled={!map || map.type === "default"} + my={1} + /> + + + + + + - - - onSettingsChange("name", e.target.value)} - disabled={!map || map.type === "default"} - my={1} - /> - )} { + return tx + .table("maps") + .toCollection() + .modify((map) => { + map.showGrid = false; + }); + }); } // Get the dexie database used in DatabaseContext diff --git a/src/modals/SelectMapModal.js b/src/modals/SelectMapModal.js index d721f6e..bebe250 100644 --- a/src/modals/SelectMapModal.js +++ b/src/modals/SelectMapModal.js @@ -17,6 +17,7 @@ const defaultMapProps = { // Grid type // TODO: add support for hex horizontal and hex vertical gridType: "grid", + showGrid: false, }; function SelectMapModal({ From 2abbbdda79c7b2d12d831c79009ff2b0d55887c5 Mon Sep 17 00:00:00 2001 From: Mitchell McCaffrey Date: Sun, 31 May 2020 16:32:20 +1000 Subject: [PATCH 09/13] Changed back to dev severs --- .env.production | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.env.production b/.env.production index 3305ecc..fc85f2e 100644 --- a/.env.production +++ b/.env.production @@ -1,2 +1,2 @@ -REACT_APP_BROKER_URL=https://broker.owlbear.app -REACT_APP_ICE_SERVERS_URL=https://broker.owlbear.app/iceservers \ No newline at end of file +REACT_APP_BROKER_URL=https://agent.owlbear.dev +REACT_APP_ICE_SERVERS_URL=https://agent.owlbear.dev/iceservers \ No newline at end of file From 74fb6a2c3718184e7b2606d7693bd65b1c8c7a58 Mon Sep 17 00:00:00 2001 From: Mitchell McCaffrey Date: Sun, 31 May 2020 18:30:23 +1000 Subject: [PATCH 10/13] Fixed padding bottom on footer for ios --- src/components/Footer.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/Footer.js b/src/components/Footer.js index 69b3d0b..03e54d8 100644 --- a/src/components/Footer.js +++ b/src/components/Footer.js @@ -12,6 +12,7 @@ function Footer() { width: "100%", alignItems: "center", justifyContent: "center", + paddingBottom: "env(safe-area-inset-bottom)", }} > From 443aff8e4db88941d15217b2a4d4d3dd4ed92dc1 Mon Sep 17 00:00:00 2001 From: Mitchell McCaffrey Date: Sun, 31 May 2020 18:53:35 +1000 Subject: [PATCH 11/13] Added 1.3.1 release notes --- src/docs/releaseNotes/v1.3.1.md | 11 +++++++++++ src/routes/ReleaseNotes.js | 4 ++++ 2 files changed, 15 insertions(+) create mode 100644 src/docs/releaseNotes/v1.3.1.md diff --git a/src/docs/releaseNotes/v1.3.1.md b/src/docs/releaseNotes/v1.3.1.md new file mode 100644 index 0000000..e678133 --- /dev/null +++ b/src/docs/releaseNotes/v1.3.1.md @@ -0,0 +1,11 @@ +# v1.3.1 + +## Minor Changes + +- Fixed a bug where tokens that were placed on the map then removed from the token select screen could no longer be deleted from the map. +- Fixed a bug where fog drawing couldn't be undone if there the last fog shape was deleted. +- Added the ability to add multiple new maps or tokens at the same time. +- Added a Show Grid option for maps that will overlay a grid on the map. This can be useful for when you have a map with no grid or you want to verify your current grid settings. +- Added the ability to erase multiple shapes at a time by dragging over a shape with the eraser tool. This works for fog erase and toggle as well. + +[Reddit]() diff --git a/src/routes/ReleaseNotes.js b/src/routes/ReleaseNotes.js index b991e5a..2c9c74a 100644 --- a/src/routes/ReleaseNotes.js +++ b/src/routes/ReleaseNotes.js @@ -9,6 +9,7 @@ const v110 = raw("../docs/releaseNotes/v1.1.0.md"); const v120 = raw("../docs/releaseNotes/v1.2.0.md"); const v121 = raw("../docs/releaseNotes/v1.2.1.md"); const v130 = raw("../docs/releaseNotes/v1.3.0.md"); +const v131 = raw("../docs/releaseNotes/v1.3.1.md"); function ReleaseNotes() { return ( @@ -31,6 +32,9 @@ function ReleaseNotes() { Release Notes +
+ +
From 2252cceb969f0b65b7a147a515741e3ba07dc9e2 Mon Sep 17 00:00:00 2001 From: Mitchell McCaffrey Date: Sun, 31 May 2020 18:53:46 +1000 Subject: [PATCH 12/13] Bump version to 1.3.1 --- package.json | 2 +- src/routes/Home.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 247f710..58e4641 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "owlbear-rodeo", - "version": "1.3.0", + "version": "1.3.1", "private": true, "dependencies": { "@msgpack/msgpack": "^1.12.1", diff --git a/src/routes/Home.js b/src/routes/Home.js index b1265cc..0e87712 100644 --- a/src/routes/Home.js +++ b/src/routes/Home.js @@ -51,7 +51,7 @@ function Home() { Join Game - Beta v1.3.0 + Beta v1.3.1