Skip to content

Commit

Permalink
Introducing guids
Browse files Browse the repository at this point in the history
  • Loading branch information
ilyabo committed Sep 8, 2024
1 parent 799a502 commit 8e3e480
Show file tree
Hide file tree
Showing 26 changed files with 956 additions and 302 deletions.
21 changes: 21 additions & 0 deletions assets/js/app-container.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import React, {useEffect} from "react";
import {TooltipProvider} from "./components/ui/tooltip";
import {MapContainer} from "./map/map-container";
import {useAppStore} from "./store/store";
import {isValudGuid} from "./store/utils";

const AppContainer: React.FC = () => {
const init = useAppStore((state) => state.initProject);
useEffect(() => {
const guid = location.pathname.split("/").pop();
init(isValudGuid(guid) ? guid : undefined);
}, [init]);

return (
<TooltipProvider>
<MapContainer />
</TooltipProvider>
);
};

export default AppContainer;
2 changes: 1 addition & 1 deletion assets/js/app.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from "react";
import {createRoot} from "react-dom/client";
import AppContainer from "./components/app-container";
import AppContainer from "./app-container";
const reactAppContainer = document.getElementById("react-app-container");
const root = createRoot(reactAppContainer);
root.render(<AppContainer />);
Expand Down
27 changes: 0 additions & 27 deletions assets/js/components/app-container.tsx

This file was deleted.

36 changes: 0 additions & 36 deletions assets/js/components/hex-size-selector.tsx

This file was deleted.

71 changes: 0 additions & 71 deletions assets/js/components/toolbar-container.tsx

This file was deleted.

38 changes: 38 additions & 0 deletions assets/js/map/geolocation-container.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import React, {FC, useCallback} from "react";
import {LocateFixedIcon} from "lucide-react";
import {ToolbarButton} from "../components/toolbar-button";
import {INITIAL_MAP_VIEW_STATE, useAppStore} from "../store/store";

type Props = {};

const GeolocationContainer: FC<Props> = () => {
const setMapViewState = useAppStore((state) => state.setMapViewState);

const handleLocate = useCallback(() => {
navigator.geolocation.getCurrentPosition(
(position) => {
const {latitude, longitude} = position.coords;
setMapViewState({
...INITIAL_MAP_VIEW_STATE,
latitude,
longitude,
zoom: 10,
});
},
(error) => {
console.error("error", error);
}
);
}, [setMapViewState]);

return (
<ToolbarButton
isSelected={false}
tooltipText={"Locate me"}
icon={LocateFixedIcon}
onClick={handleLocate}
/>
);
};

export default GeolocationContainer;
82 changes: 47 additions & 35 deletions assets/js/map/map-view.tsx → assets/js/map/map-container.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@ import {
MapboxOverlay as DeckOverlay,
MapboxOverlayProps,
} from "@deck.gl/mapbox";
import {MapRef, Map as ReactMapGl} from "react-map-gl/maplibre";
import {
MapRef,
Map as ReactMapGl,
ViewStateChangeEvent,
} from "react-map-gl/maplibre";

import {Map} from "maplibre-gl";
import React, {
Expand All @@ -21,26 +25,19 @@ import React, {
useState,
} from "react";
import {useControl} from "react-map-gl/maplibre";
import {useDrawHandler} from "../drawing/use-draw-handlers";
import {useAppStore} from "../store/store";
import {colorToRGBA, findLastLabelLayerId} from "../store/utils";
import {useKeyStrokes} from "../drawing/use-key-strokes";
import {usePanning} from "../drawing/use-panning";
import {useDrawHandler} from "./use-draw-handlers";

import MapControlsContainer from "./map-controls-container";
import {useKeyStrokes} from "./use-key-strokes";
import {usePanning} from "./use-panning";

const defaultColor: [number, number, number, number] = [150, 150, 150, 200];

const MAP_STYLE =
"https://basemaps.cartocdn.com/gl/positron-gl-style/style.json";

const INITIAL_VIEW_STATE = {
latitude: 37.77712591285937,
longitude: -122.44379091041898,
zoom: 12,
bearing: 0,
pitch: 0,
minZoom: 1.5,
};

const EDITABLE_FEATURES_LAYER_ID = "editable-geojson-layer";
const SELECTION_LAYER_ID = "selection";
const SELECTION_LINE_WIDTH = 3;
Expand All @@ -60,12 +57,19 @@ function DeckGLOverlay(props: MapboxOverlayProps): null {
return null;
}

export const MapView: FC = () => {
export const MapContainer: FC = () => {
const features = useAppStore((state) => state.features);
const selectedIds = useAppStore((state) => state.selectedIds);
const mapRef = useRef<MapRef>(null);
const [beforeId, setBeforeId] = useState();

const mapViewState = useAppStore((state) => state.mapViewState);
const setMapViewState = useAppStore((state) => state.setMapViewState);

const handleMove = useCallback((evt: ViewStateChangeEvent) => {
setMapViewState(evt.viewState);
}, []);

useKeyStrokes();
usePanning();

Expand All @@ -92,8 +96,6 @@ export const MapView: FC = () => {
[features]
);

// console.log("features", features);

const selectedFeatureIndexes = useMemo(
() =>
selectedIds
Expand All @@ -114,14 +116,19 @@ export const MapView: FC = () => {
// @ts-ignore
beforeId, // ensure the layer is rendered before the label layers
onEdit: drawHandlers.onEdit,
modeConfig: drawHandlers.modeConfig,

getFillColor: (f) =>
f.properties.color ? colorToRGBA(f.properties.color) : defaultColor,
stroked: true,
filled: true,
lineWidthUnits: "pixels",
getLineWidth: (f) =>
selectedIds?.includes(f.id) ? SELECTION_LINE_WIDTH : 1,
selectedIds?.includes(f.id)
? SELECTION_LINE_WIDTH
: f.geometry.type === "LineString"
? 3
: 1,
getLineColor: (f) =>
selectedIds?.includes(f.id)
? SELECTION_STROKE_COLOR
Expand All @@ -146,23 +153,28 @@ export const MapView: FC = () => {
}

return (
<ReactMapGl
ref={mapRef}
initialViewState={INITIAL_VIEW_STATE}
mapStyle={MAP_STYLE}
antialias
cursor="default"
onLoad={onMapLoad}
>
<DeckGLOverlay
layers={layers}
getCursor={() => drawHandlers.cursor}
onClick={drawHandlers.onClick}
onDrag={drawHandlers.onDrag}
onDragStart={drawHandlers.onDragStart}
onDragEnd={drawHandlers.onDragEnd}
interleaved
/>
</ReactMapGl>
<div className="map-container absolute w-[100vw] h-[100vh] top-0 left-0">
<ReactMapGl
ref={mapRef}
{...mapViewState}
mapStyle={MAP_STYLE}
antialias
cursor="default"
onLoad={onMapLoad}
onMove={handleMove}
>
<DeckGLOverlay
layers={layers}
getCursor={() => drawHandlers.cursor}
onClick={drawHandlers.onClick}
onDrag={drawHandlers.onDrag}
onDragStart={drawHandlers.onDragStart}
onDragEnd={drawHandlers.onDragEnd}
interleaved
/>
</ReactMapGl>

<MapControlsContainer mapRef={mapRef} />
</div>
);
};
47 changes: 47 additions & 0 deletions assets/js/map/map-controls-container.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import {LocateFixedIcon, SquareDotIcon} from "lucide-react";
import React, {FC} from "react";
import {MapRef} from "react-map-gl/maplibre";
import {ToolbarButton} from "../components/toolbar-button";
import ShareContainer from "./share-container";
import {ToolbarContainer} from "./toolbar-container";
import {UndoContainer} from "./undo-container";
import {useFitBounds} from "./use-fit-bounds";
import {useGeolocation} from "./use-geolocation";

type Props = {
mapRef: React.RefObject<MapRef>;
};

const MapControlsContainer: FC<Props> = (props) => {
const {mapRef} = props;
const {handleLocate} = useGeolocation();
const {handleFitBounds} = useFitBounds(mapRef);

return (
<>
<div className="absolute top-2 left-2">
<ToolbarContainer />
</div>
<div className="absolute bottom-2 left-2">
<UndoContainer />
</div>
<div className="absolute flex flex-col gap-1 top-2 right-2 items-end">
<ShareContainer />
<ToolbarButton
isSelected={false}
tooltipText={"Locate me"}
icon={LocateFixedIcon}
onClick={handleLocate}
/>
<ToolbarButton
isSelected={false}
tooltipText={"Fit bounds"}
icon={SquareDotIcon}
onClick={handleFitBounds}
/>
</div>
</>
);
};

export default MapControlsContainer;
Loading

0 comments on commit 8e3e480

Please sign in to comment.