From 4fa0c7484fa7fd70c74123f3ac2e552baac053f8 Mon Sep 17 00:00:00 2001 From: "Kalle (Sendou)" <38327916+Sendouc@users.noreply.github.com> Date: Thu, 4 Feb 2021 09:53:51 +0200 Subject: [PATCH] migrate plans and sort stage selector --- components/plans/DraggableToolsSelector.tsx | 2 +- components/plans/MapSketch.tsx | 2 +- components/plans/StageSelector.tsx | 15 +- components/plans/index.tsx | 377 -------------------- pages/plans.tsx | 376 ++++++++++++++++++- 5 files changed, 385 insertions(+), 387 deletions(-) delete mode 100644 components/plans/index.tsx diff --git a/components/plans/DraggableToolsSelector.tsx b/components/plans/DraggableToolsSelector.tsx index 13db8d376..cc5889019 100644 --- a/components/plans/DraggableToolsSelector.tsx +++ b/components/plans/DraggableToolsSelector.tsx @@ -2,6 +2,7 @@ import { Box, Flex, IconButton } from "@chakra-ui/react"; import { Trans } from "@lingui/macro"; import ColorPicker from "components/common/ColorPicker"; import { useMyTheme } from "hooks/common"; +import { Tool } from "pages/plans"; import { useState } from "react"; import Draggable from "react-draggable"; import { useHotkeys } from "react-hotkeys-hook"; @@ -16,7 +17,6 @@ import { FaTrashAlt, FaUndo, } from "react-icons/fa"; -import { Tool } from "."; interface DraggableToolsSelectorProps { tool: Tool; diff --git a/components/plans/MapSketch.tsx b/components/plans/MapSketch.tsx index 2baa2d32a..6e7075f00 100644 --- a/components/plans/MapSketch.tsx +++ b/components/plans/MapSketch.tsx @@ -1,6 +1,6 @@ import { Box } from "@chakra-ui/react"; import { SketchField } from "@sendou/react-sketch"; -import { Tool } from "."; +import { Tool } from "pages/plans"; interface MapSketchProps { sketch: any; diff --git a/components/plans/StageSelector.tsx b/components/plans/StageSelector.tsx index 6cc2ad961..1792bb603 100644 --- a/components/plans/StageSelector.tsx +++ b/components/plans/StageSelector.tsx @@ -19,7 +19,7 @@ import salmonRunLowTide from "lib/assets/SalmonRunLowTide.svg"; // @ts-ignore import salmonRunMidTide from "lib/assets/SalmonRunMidTide.svg"; import { salmonRunStages, stages } from "lib/lists/stages"; -import { PlannerMapBg } from "."; +import { PlannerMapBg } from "pages/plans"; interface StageSelectorProps { handleChange: (event: React.ChangeEvent) => void; @@ -40,11 +40,14 @@ const StageSelector: React.FC = ({ return ( {currentBackground.tide ? ( <> diff --git a/components/plans/index.tsx b/components/plans/index.tsx deleted file mode 100644 index fc78d955d..000000000 --- a/components/plans/index.tsx +++ /dev/null @@ -1,377 +0,0 @@ -import { Button, ButtonGroup, Flex } from "@chakra-ui/react"; -import { t, Trans } from "@lingui/macro"; -import Breadcrumbs from "components/common/Breadcrumbs"; -import { stages } from "lib/lists/stages"; -import { NextPage } from "next"; -import dynamic from "next/dynamic"; -import { useEffect, useRef, useState } from "react"; -import { - FaBomb, - FaFileDownload, - FaFileImage, - FaFileUpload, -} from "react-icons/fa"; -import DraggableImageAdder from "./DraggableImageAdder"; -import DraggableToolsSelector from "./DraggableToolsSelector"; -import StageSelector from "./StageSelector"; - -const MapSketch = dynamic(() => import("./MapSketch"), { - ssr: false, -}); - -export type Tool = "pencil" | "line" | "rectangle" | "circle" | "select"; - -export interface PlannerMapBg { - view?: "M" | "R"; - stage: string; - mode?: "SZ" | "TC" | "RM" | "CB"; - tide?: "low" | "mid" | "high"; -} - -const stageToCode = new Map([ - ["Ancho-V Games", "AG"], - ["Arowana Mall", "AM"], - ["Blackbelly Skatepark", "BS"], - ["Camp Triggerfish", "CT"], - ["Goby Arena", "GA"], - ["Humpback Pump Track", "HP"], - ["Inkblot Art Academy", "IA"], - ["Kelp Dome", "KD"], - ["Musselforge Fitness", "MF"], - ["MakoMart", "MK"], - ["Manta Maria", "MM"], - ["Moray Towers", "MT"], - ["New Albacore Hotel", "NA"], - ["Port Mackerel", "PM"], - ["Piranha Pit", "PP"], - ["Snapper Canal", "SC"], - ["Shellendorf Institute", "SI"], - ["Starfish Mainstage", "SM"], - ["Skipper Pavilion", "SP"], - ["Sturgeon Shipyard", "SS"], - ["The Reef", "TR"], - ["Wahoo World", "WH"], - ["Walleye Warehouse", "WW"], -]); - -const plannerMapBgToImage = (bg: PlannerMapBg) => { - if (!bg.tide) - return `images/plannerMaps/${bg.view} ${stageToCode.get(bg.stage)} ${ - bg.mode - }.png`; - - return `images/plannerMaps/${bg.stage}-${bg.tide}.png`; -}; - -const defaultValue = { - shadowWidth: 0, - shadowOffset: 0, - enableRemoveSelected: false, - fillWithColor: false, - fillWithBackgroundColor: false, - drawings: [], - canUndo: false, - canRedo: false, - controlledSize: false, - sketchWidth: 600, - sketchHeight: 600, - stretched: true, - stretchedX: false, - stretchedY: false, - originX: "left", - originY: "top", - expandTools: false, - expandControls: false, - expandColors: false, - expandBack: false, - expandImages: false, - expandControlled: false, - enableCopyPaste: false, - backgroundImage: { - type: "image", - version: "2.4.3", - originX: "left", - originY: "top", - left: 0, - top: 0, - width: 1127, - height: 634, - fill: "rgb(0,0,0)", - stroke: null, - strokeWidth: 0, - strokeDashArray: null, - strokeLineCap: "butt", - strokeLineJoin: "miter", - strokeMiterLimit: 4, - scaleX: 1, - scaleY: 1, - angle: 0, - flipX: false, - flipY: false, - opacity: 1, - shadow: null, - visible: true, - clipTo: null, - backgroundColor: "", - fillRule: "nonzero", - paintFirst: "fill", - globalCompositeOperation: "source-over", - transformMatrix: null, - skewX: 0, - skewY: 0, - crossOrigin: "", - cropX: 0, - cropY: 0, - src: "/images/plannerMaps/M%20TR%20SZ.png", - filters: [], - }, -}; - -const MapPlannerPage: NextPage = () => { - const fileInput = useRef(null); - const sketch = useRef(null); - const [tool, setTool] = useState("pencil"); - const [color, setColor] = useState("#f44336"); - const [canUndo, setCanUndo] = useState(false); - const [canRedo, setCanRedo] = useState(false); - const [bg, setBg] = useState({ - view: "M", - stage: "The Reef", - mode: "SZ", - }); - const [controlledValue, setControlledValue] = useState(defaultValue); - - const addImageToSketch = (imgSrc: string) => { - sketch.current.addImg(imgSrc); - setTool("select"); - }; - - const addTextToSketch = () => { - sketch.current.addText("Double-click to edit", { - fill: color, - fontFamily: "lato", - stroke: "#000000", - strokeWidth: 3, - paintFirst: "stroke", - }); - setTool("select"); - }; - - const undo = () => { - sketch.current.undo(); - setCanUndo(sketch.current.canUndo()); - setCanRedo(sketch.current.canRedo()); - }; - - const redo = () => { - sketch.current.redo(); - setCanUndo(sketch.current.canUndo()); - setCanRedo(sketch.current.canRedo()); - }; - - const removeSelected = () => { - sketch.current.removeSelected(); - }; - - const onSketchChange = () => { - if (!sketch.current) return; - let prev = canUndo; - let now = sketch.current.canUndo(); - if (prev !== now) { - setCanUndo(now); - } - }; - - const getDateFormatted = () => { - const today = new Date(); - const date = - today.getFullYear() + - "-" + - (today.getMonth() + 1) + - "-" + - today.getDate(); - const time = - today.getHours() + ":" + today.getMinutes() + ":" + today.getSeconds(); - return date + " " + time; - }; - - const download = (dataUrl: string, extension: string) => { - if (!bg) return; - let a = document.createElement("a"); - document.body.appendChild(a); - a.style.display = "none"; - a.href = dataUrl; - a.download = `${bg.stage} plans ${getDateFormatted()}.${extension}`; - a.click(); - window.URL.revokeObjectURL(dataUrl); - }; - - const handleUpload = () => { - if (!fileInput.current) { - return; - } - fileInput.current.click(); - }; - - const files = fileInput.current?.files; - - useEffect(() => { - if (!fileInput.current?.files?.length) return; - - const fileObj = fileInput.current.files[0]; - const reader = new FileReader(); - reader.onload = function (event) { - const jsonObj = JSON.parse(event.target!.result as any); - setControlledValue(jsonObj); - - const imgSrc = jsonObj.backgroundImage.src; - const searchFolder = "plannerMaps"; - const imgName = imgSrc - .slice(imgSrc.lastIndexOf(searchFolder) + searchFolder.length + 1, -4) - .replace(/%20/g, " "); - - const salmonRunMaps = [ - "Spawning Grounds", - "Marooner's Bay", - "Lost Outpost", - "Salmonid Smokeyard", - "Ruins of Ark Polaris‎‎", - ]; - let isSalmonRunMap = false; - for (const map of salmonRunMaps) { - if (imgName.startsWith(map)) { - isSalmonRunMap = true; - const imageNameParts = imgName.split("-"); - if (imageNameParts.length > 1) { - const tide = imageNameParts[1]; - setBg({ tide: tide, stage: map }); - } - } - } - - if (!isSalmonRunMap) { - const imageNameParts = imgName.split(" "); - if (imageNameParts.length > 2) { - const view = imageNameParts[0]; - const mapCode = imageNameParts[1]; - const mode = imageNameParts[2]; - let mapName = ""; - stageToCode.forEach((value, key) => { - if (value === mapCode) { - mapName = key; - } - }); - setBg({ view, stage: mapName, mode }); - } - } - }; - reader.readAsText(fileObj); - }, [files]); - - useEffect(() => { - if (!sketch.current) return; - setCanUndo(false); - sketch.current.setBackgroundFromDataUrl(plannerMapBgToImage(bg)); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [bg]); - - return ( - <> - - setColor(newColor)} - /> - addImageToSketch(imgSrc)} - /> - - - - - - - - - - { - const newStage = e.target.value; - if (newStage === "") { - return; - } - const newIsSalmonRunStage = !stages.includes(newStage as any); - const oldIsSalmonRunStage = !stages.includes(bg.stage as any); - - if (newIsSalmonRunStage === oldIsSalmonRunStage) { - setBg({ ...bg, stage: e.target.value }); - return; - } - - if (newIsSalmonRunStage) { - setBg({ stage: e.target.value, tide: "mid" }); - return; - } - - setBg({ stage: e.target.value, mode: "SZ", view: "M" }); - }} - currentBackground={bg} - changeMode={(mode) => setBg({ ...bg, mode })} - changeTide={(tide: "low" | "mid" | "high") => setBg({ ...bg, tide })} - changeView={(view: "M" | "R") => setBg({ ...bg, view })} - /> - setBg({ ...bg })} - /> - - ); -}; - -export default MapPlannerPage; diff --git a/pages/plans.tsx b/pages/plans.tsx index aae48bd39..ebb03e379 100644 --- a/pages/plans.tsx +++ b/pages/plans.tsx @@ -1,5 +1,377 @@ -import MapPlanner from "components/plans"; +import { Button, ButtonGroup, Flex } from "@chakra-ui/react"; +import { t, Trans } from "@lingui/macro"; +import Breadcrumbs from "components/common/Breadcrumbs"; +import DraggableImageAdder from "components/plans/DraggableImageAdder"; +import DraggableToolsSelector from "components/plans/DraggableToolsSelector"; +import StageSelector from "components/plans/StageSelector"; +import { stages } from "lib/lists/stages"; +import { NextPage } from "next"; +import dynamic from "next/dynamic"; +import { useEffect, useRef, useState } from "react"; +import { + FaBomb, + FaFileDownload, + FaFileImage, + FaFileUpload, +} from "react-icons/fa"; -const MapPlannerPage = () => ; +const MapSketch = dynamic(() => import("components/plans/MapSketch"), { + ssr: false, +}); + +export type Tool = "pencil" | "line" | "rectangle" | "circle" | "select"; + +export interface PlannerMapBg { + view?: "M" | "R"; + stage: string; + mode?: "SZ" | "TC" | "RM" | "CB"; + tide?: "low" | "mid" | "high"; +} + +const stageToCode = new Map([ + ["Ancho-V Games", "AG"], + ["Arowana Mall", "AM"], + ["Blackbelly Skatepark", "BS"], + ["Camp Triggerfish", "CT"], + ["Goby Arena", "GA"], + ["Humpback Pump Track", "HP"], + ["Inkblot Art Academy", "IA"], + ["Kelp Dome", "KD"], + ["Musselforge Fitness", "MF"], + ["MakoMart", "MK"], + ["Manta Maria", "MM"], + ["Moray Towers", "MT"], + ["New Albacore Hotel", "NA"], + ["Port Mackerel", "PM"], + ["Piranha Pit", "PP"], + ["Snapper Canal", "SC"], + ["Shellendorf Institute", "SI"], + ["Starfish Mainstage", "SM"], + ["Skipper Pavilion", "SP"], + ["Sturgeon Shipyard", "SS"], + ["The Reef", "TR"], + ["Wahoo World", "WH"], + ["Walleye Warehouse", "WW"], +]); + +const plannerMapBgToImage = (bg: PlannerMapBg) => { + if (!bg.tide) + return `images/plannerMaps/${bg.view} ${stageToCode.get(bg.stage)} ${ + bg.mode + }.png`; + + return `images/plannerMaps/${bg.stage}-${bg.tide}.png`; +}; + +const defaultValue = { + shadowWidth: 0, + shadowOffset: 0, + enableRemoveSelected: false, + fillWithColor: false, + fillWithBackgroundColor: false, + drawings: [], + canUndo: false, + canRedo: false, + controlledSize: false, + sketchWidth: 600, + sketchHeight: 600, + stretched: true, + stretchedX: false, + stretchedY: false, + originX: "left", + originY: "top", + expandTools: false, + expandControls: false, + expandColors: false, + expandBack: false, + expandImages: false, + expandControlled: false, + enableCopyPaste: false, + backgroundImage: { + type: "image", + version: "2.4.3", + originX: "left", + originY: "top", + left: 0, + top: 0, + width: 1127, + height: 634, + fill: "rgb(0,0,0)", + stroke: null, + strokeWidth: 0, + strokeDashArray: null, + strokeLineCap: "butt", + strokeLineJoin: "miter", + strokeMiterLimit: 4, + scaleX: 1, + scaleY: 1, + angle: 0, + flipX: false, + flipY: false, + opacity: 1, + shadow: null, + visible: true, + clipTo: null, + backgroundColor: "", + fillRule: "nonzero", + paintFirst: "fill", + globalCompositeOperation: "source-over", + transformMatrix: null, + skewX: 0, + skewY: 0, + crossOrigin: "", + cropX: 0, + cropY: 0, + src: "/images/plannerMaps/M%20TR%20SZ.png", + filters: [], + }, +}; + +const MapPlannerPage: NextPage = () => { + const fileInput = useRef(null); + const sketch = useRef(null); + const [tool, setTool] = useState("pencil"); + const [color, setColor] = useState("#f44336"); + const [canUndo, setCanUndo] = useState(false); + const [canRedo, setCanRedo] = useState(false); + const [bg, setBg] = useState({ + view: "M", + stage: "The Reef", + mode: "SZ", + }); + const [controlledValue, setControlledValue] = useState(defaultValue); + + const addImageToSketch = (imgSrc: string) => { + sketch.current.addImg(imgSrc); + setTool("select"); + }; + + const addTextToSketch = () => { + sketch.current.addText("Double-click to edit", { + fill: color, + fontFamily: "lato", + stroke: "#000000", + strokeWidth: 3, + paintFirst: "stroke", + }); + setTool("select"); + }; + + const undo = () => { + sketch.current.undo(); + setCanUndo(sketch.current.canUndo()); + setCanRedo(sketch.current.canRedo()); + }; + + const redo = () => { + sketch.current.redo(); + setCanUndo(sketch.current.canUndo()); + setCanRedo(sketch.current.canRedo()); + }; + + const removeSelected = () => { + sketch.current.removeSelected(); + }; + + const onSketchChange = () => { + if (!sketch.current) return; + let prev = canUndo; + let now = sketch.current.canUndo(); + if (prev !== now) { + setCanUndo(now); + } + }; + + const getDateFormatted = () => { + const today = new Date(); + const date = + today.getFullYear() + + "-" + + (today.getMonth() + 1) + + "-" + + today.getDate(); + const time = + today.getHours() + ":" + today.getMinutes() + ":" + today.getSeconds(); + return date + " " + time; + }; + + const download = (dataUrl: string, extension: string) => { + if (!bg) return; + let a = document.createElement("a"); + document.body.appendChild(a); + a.style.display = "none"; + a.href = dataUrl; + a.download = `${bg.stage} plans ${getDateFormatted()}.${extension}`; + a.click(); + window.URL.revokeObjectURL(dataUrl); + }; + + const handleUpload = () => { + if (!fileInput.current) { + return; + } + fileInput.current.click(); + }; + + const files = fileInput.current?.files; + + useEffect(() => { + if (!fileInput.current?.files?.length) return; + + const fileObj = fileInput.current.files[0]; + const reader = new FileReader(); + reader.onload = function (event) { + const jsonObj = JSON.parse(event.target!.result as any); + setControlledValue(jsonObj); + + const imgSrc = jsonObj.backgroundImage.src; + const searchFolder = "plannerMaps"; + const imgName = imgSrc + .slice(imgSrc.lastIndexOf(searchFolder) + searchFolder.length + 1, -4) + .replace(/%20/g, " "); + + const salmonRunMaps = [ + "Spawning Grounds", + "Marooner's Bay", + "Lost Outpost", + "Salmonid Smokeyard", + "Ruins of Ark Polaris‎‎", + ]; + let isSalmonRunMap = false; + for (const map of salmonRunMaps) { + if (imgName.startsWith(map)) { + isSalmonRunMap = true; + const imageNameParts = imgName.split("-"); + if (imageNameParts.length > 1) { + const tide = imageNameParts[1]; + setBg({ tide: tide, stage: map }); + } + } + } + + if (!isSalmonRunMap) { + const imageNameParts = imgName.split(" "); + if (imageNameParts.length > 2) { + const view = imageNameParts[0]; + const mapCode = imageNameParts[1]; + const mode = imageNameParts[2]; + let mapName = ""; + stageToCode.forEach((value, key) => { + if (value === mapCode) { + mapName = key; + } + }); + setBg({ view, stage: mapName, mode }); + } + } + }; + reader.readAsText(fileObj); + }, [files]); + + useEffect(() => { + if (!sketch.current) return; + setCanUndo(false); + sketch.current.setBackgroundFromDataUrl(plannerMapBgToImage(bg)); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [bg]); + + return ( + <> + + setColor(newColor)} + /> + addImageToSketch(imgSrc)} + /> + + + + + + + + + + { + const newStage = e.target.value; + if (newStage === "") { + return; + } + const newIsSalmonRunStage = !stages.includes(newStage as any); + const oldIsSalmonRunStage = !stages.includes(bg.stage as any); + + if (newIsSalmonRunStage === oldIsSalmonRunStage) { + setBg({ ...bg, stage: e.target.value }); + return; + } + + if (newIsSalmonRunStage) { + setBg({ stage: e.target.value, tide: "mid" }); + return; + } + + setBg({ stage: e.target.value, mode: "SZ", view: "M" }); + }} + currentBackground={bg} + changeMode={(mode) => setBg({ ...bg, mode })} + changeTide={(tide: "low" | "mid" | "high") => setBg({ ...bg, tide })} + changeView={(view: "M" | "R") => setBg({ ...bg, view })} + /> + setBg({ ...bg })} + /> + + ); +}; export default MapPlannerPage;