Skip to content

Commit

Permalink
Better state management for Rockd StraboSpot
Browse files Browse the repository at this point in the history
  • Loading branch information
davenquinn committed Nov 27, 2024
1 parent 065f5ba commit 4847b68
Show file tree
Hide file tree
Showing 6 changed files with 108 additions and 7 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@
"jose": "^5.1.2",
"mapbox-gl": "^2.15.0",
"new-github-issue-url": "^1.0.0",
"part-regex": "^0.1.2",
"react": "^18.3.0",
"react-cookie": "^3.0.4",
"react-dom": "^18.3.0",
Expand Down
65 changes: 59 additions & 6 deletions pages/dev/map/rockd-strabospot/+Page.client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,25 +21,66 @@ import styles from "./main.module.sass";
import { DetailsPanel } from "./details-panel";
import Legend from "./legend-text.mdx";
import { useInDarkMode } from "@macrostrat/ui-components";
import { usePageContext } from "vike-react/usePageContext";
import { navigate } from "vike/client/router";
import { formatCoordForZoomLevel } from "@macrostrat/mapbox-utils";

const h = hyper.styled(styles);

mapboxgl.accessToken = mapboxAccessToken;

const baseURL = "/dev/map/rockd-strabospot";

export function Page() {
const { routeParams } = usePageContext();
const { lng, lat } = routeParams;

let initialPosition = null;
if (lng != null && lat != null) {
try {
// Try to get the zoom level from the hash
const q = new URLSearchParams(window.location.hash.slice(1));
const zoom = q.has("z") ? parseInt(q.get("z")) : 7;

initialPosition = { lng: parseFloat(lng), lat: parseFloat(lat), zoom };
} catch {
console.error("Failed to parse initial position");
}
}

const style = useRockdStraboSpotStyle();
const inDarkMode = useInDarkMode();

const [isOpen, setOpen] = useState(true);

const [inspectPosition, setInspectPosition] =
useState<mapboxgl.LngLat | null>(null);
useState<mapboxgl.LngLat | null>(initialPosition);

const [data, setData] = useState(null);

const onSelectPosition = useCallback((position: mapboxgl.LngLat) => {
setInspectPosition(position);
}, []);
const onSelectPosition = useCallback(
(
position: mapboxgl.LngLat | null,
event: Event | undefined,
map: mapboxgl.Map | undefined
) => {
setInspectPosition(position);
let newPathname = "/dev/map/rockd-strabospot";
let currentPathname = window.location.pathname;

if (map != null && position != null) {
const z = map.getZoom() ?? 7;
const lng = formatCoordForZoomLevel(position.lng, z);
const lat = formatCoordForZoomLevel(position.lat, z);
newPathname += `/loc/${lng}/${lat}`;
}
newPathname += buildHashParams(map, position);
if (currentPathname !== newPathname) {
window.history.pushState({}, "", newPathname);
}
},
[]
);

return h(
MapAreaContainer,
Expand All @@ -61,7 +102,7 @@ export function Page() {
detailPanel: h(DetailsPanel, {
position: inspectPosition,
onClose() {
setInspectPosition(null);
onSelectPosition(null, null, null);
},
nearbyFeatures: data,
}),
Expand All @@ -73,8 +114,11 @@ export function Page() {
style,
projection: { name: "globe" },
mapboxToken: mapboxAccessToken,
mapPosition: null, // Have to set map position to null for bounds to work
mapPosition: initialPosition,
bounds: [-125, 24, -66, 49],
onMapMoved(mapPosition, map) {
window.location.hash = buildHashParams(map, inspectPosition);
},
},
[
h(FeatureSelectionHandler, {
Expand All @@ -90,3 +134,12 @@ export function Page() {
)
);
}

function buildHashParams(map, selectedPosition) {
if (selectedPosition == null) return "";
const z = map.getZoom();
// Parse hash and add zoom level
let q = new URLSearchParams(window.location.hash.slice(1));
q.set("z", z.toFixed(0));
return "#" + q.toString();
}
35 changes: 35 additions & 0 deletions pages/dev/map/rockd-strabospot/+route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { partRegex } from "part-regex";
import { redirect } from "vike/abort";

const prefix = "/dev/map/rockd-strabospot";

const lngLatRegex = /(-?\d+\.\d+)/;

const routeRegex = partRegex`/loc/${lngLatRegex}/${lngLatRegex}`;

export function route(pageContext) {
const url = pageContext.urlPathname;

if (!url.startsWith(prefix)) return false;

const suffix = url.slice(prefix.length);

if (suffix == "" || suffix == "/") {
return {
routeParams: {},
};
}

if (suffix.match(routeRegex)) {
const [_, lng, lat] = suffix.match(routeRegex);
return {
routeParams: {
lng,
lat,
},
};
}

// Redirect to the root of this route
throw redirect(prefix);
}
4 changes: 4 additions & 0 deletions pages/dev/map/rockd-strabospot/sidebar-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ async function processSpotsData(nearbyFeatures) {
.filter((d) => d.source === "notableSpots")
.slice(0, 5);

if (firstFewSpots.length == 0) {
return [];
}

const ids = firstFewSpots.map((d) => d.properties.id);
const res = await pg.from("dataset").select("data").in("id", ids);
const { data, error } = res;
Expand Down
8 changes: 8 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -6438,6 +6438,7 @@ __metadata:
jose: "npm:^5.1.2"
mapbox-gl: "npm:^2.15.0"
new-github-issue-url: "npm:^1.0.0"
part-regex: "npm:^0.1.2"
prettier: "npm:^2.7.1"
react: "npm:^18.3.0"
react-arborist: "npm:^3.4.0"
Expand Down Expand Up @@ -27994,6 +27995,13 @@ __metadata:
languageName: node
linkType: hard

"part-regex@npm:^0.1.2":
version: 0.1.2
resolution: "part-regex@npm:0.1.2"
checksum: 10/e01c9532963914b8ac234ae4362a0914b24820635d8815014f745ce30fe7f035ab6618784e9a900127f8359fea8bc2c6c7cc65ddf429baa179621e56e7dd717e
languageName: node
linkType: hard

"pascal-case@npm:^3.1.2":
version: 3.1.2
resolution: "pascal-case@npm:3.1.2"
Expand Down

0 comments on commit 4847b68

Please sign in to comment.