import React, { useEffect, 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 LoadingOverlay from "../components/LoadingOverlay"; import { useMapData } from "../contexts/MapDataContext"; import { isEmpty } from "../helpers/shared"; import { getGridDefaultInset } from "../helpers/grid"; import useResponsiveLayout from "../hooks/useResponsiveLayout"; function EditMapModal({ isOpen, onDone, mapId }) { const { updateMap, updateMapState, getMapFromDB, mapStates } = useMapData(); const [isLoading, setIsLoading] = useState(true); const [map, setMap] = useState(); const [mapState, setMapState] = useState(); // Load full map when modal is opened useEffect(() => { async function loadMap() { setIsLoading(true); setMap(await getMapFromDB(mapId)); setMapState(mapStates.find((state) => state.mapId === mapId)); setIsLoading(false); } if (isOpen && mapId) { loadMap(); } else { setMap(); setMapState(); } }, [isOpen, mapId, getMapFromDB, mapStates]); function handleClose() { setMapSettingChanges({}); setMapStateSettingChanges({}); onDone(); } async function handleSave() { await applyMapChanges(); onDone(); } /** * Map settings */ // Local cache of map setting changes // Applied when done is clicked or map selection is changed const [mapSettingChanges, setMapSettingChanges] = useState({}); const [mapStateSettingChanges, setMapStateSettingChanges] = useState({}); function handleMapSettingsChange(key, value) { setMapSettingChanges((prevChanges) => ({ ...prevChanges, [key]: value, lastModified: Date.now(), })); } function handleMapStateSettingsChange(key, value) { setMapStateSettingChanges((prevChanges) => ({ ...prevChanges, [key]: value, })); } async function applyMapChanges() { if (!isEmpty(mapSettingChanges) || !isEmpty(mapStateSettingChanges)) { // Ensure grid values are positive let verifiedChanges = { ...mapSettingChanges }; if ("grid" in verifiedChanges && "size" in verifiedChanges.grid) { verifiedChanges.grid.size.x = verifiedChanges.grid.size.x || 1; verifiedChanges.grid.size.y = verifiedChanges.grid.size.y || 1; } // Ensure inset isn't flipped if ("grid" in verifiedChanges && "inset" in verifiedChanges.grid) { const inset = verifiedChanges.grid.inset; if ( inset.topLeft.x > inset.bottomRight.x || inset.topLeft.y > inset.bottomRight.y ) { if ("size" in verifiedChanges.grid) { verifiedChanges.grid.inset = getGridDefaultInset( { size: verifiedChanges.grid.size, type: map.grid.type }, map.width, map.height ); } else { verifiedChanges.grid.inset = getGridDefaultInset( map.grid, map.width, map.height ); } } } await updateMap(map.id, mapSettingChanges); await updateMapState(map.id, mapStateSettingChanges); setMapSettingChanges({}); setMapStateSettingChanges({}); } } const selectedMapWithChanges = map && { ...map, ...mapSettingChanges, }; const selectedMapStateWithChanges = mapState && { ...mapState, ...mapStateSettingChanges, }; const [showMoreSettings, setShowMoreSettings] = useState(true); const layout = useResponsiveLayout(); return ( {isLoading ? ( ) : ( )} ); } export default EditMapModal;