Skip to content

Commit 8536de4

Browse files
authored
Merge pull request #39 from UW-Macrostrat/state
Explore Page Updates
2 parents 73d1c28 + 5ed894b commit 8536de4

File tree

5 files changed

+123
-234
lines changed

5 files changed

+123
-234
lines changed

pages/colors.scss

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ $colors: (
99
scrollbar-track: rgba(200, 200, 200, 0.3),
1010
scrollbar-thumb: rgba(150, 150, 150, 0.6),
1111
scrollbar-thumb-hover: rgba(100, 100, 100, 0.8),
12-
panel-background: #fff,
12+
panel-background: #CCC,
13+
panel-hover: #AAA,
1314
panel-text: #333,
1415
semi-translucent-background: rgba(255, 255, 255, 0.8),
1516
translucent-background: rgba(255, 255, 255, 0.5),
@@ -30,7 +31,8 @@ $dark-colors: (
3031
scrollbar-thumb: rgba(100, 100, 100, 0.6),
3132
scrollbar-thumb-hover: rgba(180, 180, 180, 0.8),
3233
panel-background: #333,
33-
panel-text: #fff,
34+
panel-hover: #555,
35+
panel-text: #fff,
3436
semi-translucent-background: rgba(20, 26,30, 0.8),
3537
translucent-background: rgba(20, 26,30, 0.5),
3638
interval-background: rgba(79, 174, 90, .5),

pages/explore/+Page.client.ts

Lines changed: 108 additions & 213 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@ import {
1111
} from "@macrostrat/map-interface";
1212
import { buildMacrostratStyle } from "@macrostrat/map-styles";
1313
import { mergeStyles } from "@macrostrat/mapbox-utils";
14-
import { useDarkMode, useAPIResult, DarkModeButton } from "@macrostrat/ui-components";
14+
import { useDarkMode, DarkModeButton } from "@macrostrat/ui-components";
1515
import mapboxgl from "mapbox-gl";
1616
import { useCallback, useEffect, useState, useMemo } from "react";
1717
import { tileserverDomain } from "@macrostrat-web/settings";
1818
import "../main.sass";
19-
import { BlankImage, apiURL, useRockdAPI } from "../index";
19+
import { createCheckins, useRockdAPI } from "../index";
2020
import "./main.sass";
2121
import "@macrostrat/style-system";
2222
import { LngLatCoords } from "@macrostrat/map-interface";
@@ -97,220 +97,21 @@ function WeaverMap({
9797
mapboxToken?: string;
9898
}) {
9999
const style = useMapStyle(type, mapboxToken);
100-
const [sort, setSort] = useState("likes");
101100

102101
// overlay
103-
const [isOpenSelected, setOpenSelected] = useState(true);
104-
105102
const [inspectPosition, setInspectPosition] =
106103
useState<mapboxgl.LngLat | null>(null);
107104

108105
const onSelectPosition = useCallback((position: mapboxgl.LngLat) => {
109106
setInspectPosition(position);
110-
setOpenSelected(true);
111107
}, []);
112108

113-
let selectedResult = getCheckins(inspectPosition?.lat - .05, inspectPosition?.lat + .05, inspectPosition?.lng - .05, inspectPosition?.lng + .05);
114-
115-
function FeatureDetails() {
116-
// return null;
117-
const mapRef = useMapRef();
118-
const map = mapRef.current;
119-
const [bounds, setBounds] = useState(map?.getBounds());
120-
let checkins = [];
121-
let result;
122-
123-
if(!map) {
124-
result = getCheckins(0, 0, 0, 0);
125-
} else if (bounds) {
126-
result = getCheckins(bounds.getSouth(), bounds.getNorth(), bounds.getWest(), bounds.getEast());
127-
} else {
128-
result = getCheckins(0, 0, 0, 0);
129-
}
130-
131-
if (!bounds && map) {
132-
setBounds(map.getBounds());
133-
}
134-
135-
count++;
136-
137-
// add selected checkin markers
138-
useEffect(() => {
139-
let selectedCheckins = selectedResult?.success.data;
140-
let selectedCords = [];
141-
let finalCheckins = null;
142-
143-
let previousSelected = document.querySelectorAll('.selected_pin');
144-
previousSelected.forEach((marker) => {
145-
marker.remove();
146-
});
147-
148-
if(selectedCheckins?.length > 0 && inspectPosition) {
149-
finalCheckins = createCheckins(selectedCheckins, mapRef, "explore/blue-marker.png", sort);
150-
151-
selectedCheckins.forEach((checkin) => {
152-
selectedCords.push([checkin.lng, checkin.lat]);
153-
});
154-
155-
let selectedStop = 0;
156-
selectedCords.forEach((coord) => {
157-
selectedStop++;
158-
// marker
159-
const el = document.createElement('div');
160-
el.className = 'selected_pin';
161-
162-
// Create marker
163-
new mapboxgl.Marker(el)
164-
.setLngLat(coord)
165-
.addTo(map);
166-
});
167-
}
168-
}, [selectedResult]);
169-
170-
// Update bounds on move
171-
useEffect(() => {
172-
if(map) {
173-
const listener = () => {
174-
setBounds(map.getBounds());
175-
};
176-
map.on("moveend", listener);
177-
return () => {
178-
map.off("moveend", listener);
179-
};
180-
}
181-
}, [bounds]);
182-
183-
if (result == null) return h(Spinner);
184-
result = result.success.data;
185-
186-
checkins = createCheckins(result, mapRef, "explore/red-circle.png", sort);
187-
188-
let selectedCheckins = selectedResult?.success.data;
189-
190-
if (selectedCheckins?.length > 0 && inspectPosition) {
191-
console.log("returning selected")
192-
return h("div", {className: 'checkin-container'}, createCheckins(selectedCheckins, mapRef, "explore/blue-circle.png", sort));
193-
}
194-
195-
return h("div", {className: 'checkin-container'}, [
196-
h('div', checkins)
197-
]);
198-
199-
function createCheckins(result, mapRef, marker, sort) {
200-
let checkins = [];
201-
const map = mapRef?.current;
202-
let stop = 0;
203-
204-
let pinClass = "marker-number";
205-
if (marker.includes("circle")) {
206-
pinClass = "circle-number";
207-
}
208-
209-
result.forEach((checkin) => {
210-
// format rating
211-
let ratingArr = [];
212-
for(var i = 0; i < checkin.rating; i++) {
213-
ratingArr.push(h(Icon, {className: "star", icon: "star", style: {color: 'white'}}));
214-
}
215-
216-
for(var i = 0; i < 5 - checkin.rating; i++) {
217-
ratingArr.push(h(Icon, {className: "star", icon: "star-empty", style: {color: 'white'}}));
218-
}
219-
220-
let image;
221-
const showImage = checkin.photo;
222-
223-
if (showImage) {
224-
image = h(BlankImage, {className: 'observation-img', src: "https://rockd.org/api/v1/protected/image/" + checkin.person_id + "/thumb_large/" + checkin.photo});
225-
} else {
226-
image = h("div", { className: 'no-image' }, [
227-
h('h1', "Details"),
228-
h(Icon, {className: 'details-image', icon: "arrow-right", style: {color: 'white'}})
229-
]);
230-
}
231-
232-
// for trips
233-
let stop_name = checkin?.name ?? null;
234-
let LngLatProps = {
235-
position: {
236-
lat: checkin.lat,
237-
lng: checkin.lng
238-
},
239-
precision: 3,
240-
zoom: 10
241-
};
242-
243-
let temp = h('div', {
244-
className: 'checkin',
245-
onClick: () => {
246-
map.flyTo({center: [checkin.lng, checkin.lat], zoom: 12});
247-
setInspectPosition({lat: checkin.lat, lng: checkin.lng});
248-
console.log("inspect position set")
249-
},
250-
onMouseEnter: () => {
251-
// marker
252-
const el = document.createElement('div');
253-
el.className = 'marker_pin';
254-
255-
// Create marker
256-
new mapboxgl.Marker(el)
257-
.setLngLat([checkin.lng, checkin.lat])
258-
.addTo(map);
259-
},
260-
onMouseLeave: () => {
261-
let previous = document.querySelectorAll('.marker_pin');
262-
previous.forEach((marker) => {
263-
marker.remove();
264-
});
265-
}
266-
}, [
267-
h('h1', {className: 'stop-name'}, stop_name),
268-
h('div', {className: 'checkin-header'}, [
269-
h('h3', {className: 'profile-pic'}, h(BlankImage, {src: apiURL + "protected/gravatar/" + checkin.person_id, className: "profile-pic"})),
270-
h('div', {className: 'checkin-info'}, [
271-
h('h3', {className: 'name'}, checkin.first_name + " " + checkin.last_name),
272-
h('h4', {className: 'edited'}, checkin.created),
273-
h('p', "Near " + checkin.near),
274-
LngLatCoords(LngLatProps),
275-
h('h3', {className: 'rating'}, ratingArr),
276-
]),
277-
// pin,
278-
]),
279-
h('p', {className: 'description'}, checkin.notes),
280-
h('a', {className: 'checkin-link', href: "/checkin/" + checkin.checkin_id, target: "_blank"}, [
281-
image,
282-
showImage ? h('div', {className: "image-details"}, [
283-
h('h1', "Details"),
284-
h(Icon, {className: 'details-image', icon: "arrow-right", style: {color: 'white'}})
285-
]) : null
286-
]),
287-
h('div', {className: 'checkin-footer'}, [
288-
h('div', {className: 'likes-container'}, [
289-
h(Icon, {className: 'likes-icon', icon: "thumbs-up", style: {color: 'white'}}),
290-
h('h3', {className: 'likes'}, checkin.likes),
291-
]),
292-
h('div', {className: 'observations-container'}, [
293-
h(Icon, {className: 'observations-icon', icon: "camera", style: {color: 'white'}}),
294-
h('h3', {className: 'likes'}, checkin.observations.length),
295-
]),
296-
h('div', {className: 'comments-container'}, [
297-
h(Icon, {className: 'comments-icon', icon: "comment", style: {color: 'white'}}),
298-
h('h3', {className: 'comments'}, checkin.comments),
299-
])
300-
]),
301-
]);
302-
303-
checkins.push(temp);
304-
});
305-
306-
return checkins;
307-
}
308-
}
309-
310-
let featuredCheckin = h(FeatureDetails);
109+
const selectedResult = getSelectedCheckins(inspectPosition?.lat - .05, inspectPosition?.lat + .05, inspectPosition?.lng - .05, inspectPosition?.lng + .05)?.success.data;
110+
const featuredCheckin = h(FeatureDetails, {setInspectPosition});
111+
const selectedCheckin = h(SelectedCheckins, {selectedResult, inspectPosition, setInspectPosition});
311112
let overlay;
312113

313-
let LngLatProps = {
114+
const LngLatProps = {
314115
position: {
315116
lat: inspectPosition?.lat ?? 0,
316117
lng: inspectPosition?.lng ?? 0
@@ -319,22 +120,27 @@ function WeaverMap({
319120
zoom: 10
320121
};
321122

322-
if (inspectPosition && selectedResult?.success.data.length > 0) {
123+
if (inspectPosition && selectedResult.length > 0) {
323124
overlay = h("div.sidebox", [
324125
h('div.title', [
325126
h('div', { className: "selected-center" }, [
326127
h("h1", "Selected Checkins"),
327128
h('h3', { className: "coordinates" }, LngLatCoords(LngLatProps))
328129
]),
130+
h(DarkModeButton, { className: "dark-btn", showText: true } )
329131
]),
330132
h("button", {
331133
className: "close-btn",
332134
onClick: () => {
333-
setOpenSelected(false)
334135
setInspectPosition(null);
136+
137+
let previousSelected = document.querySelectorAll('.selected_pin');
138+
previousSelected.forEach((marker) => {
139+
marker.remove();
140+
});
335141
}
336142
}, "X"),
337-
h("div.overlay-div", featuredCheckin),
143+
h("div.overlay-div", selectedCheckin),
338144
]);
339145
} else {
340146
overlay = h("div.sidebox", [
@@ -415,11 +221,100 @@ function getCheckins(lat1, lat2, lng1, lng2) {
415221
"&maxlng=" + maxLng);
416222
}
417223

418-
function getPersonCheckins(personId) {
419-
return useRockdAPI("protected/checkins?person_id=" + personId);
224+
function getSelectedCheckins(lat1, lat2, lng1, lng2) {
225+
// abitrary bounds around click point
226+
let minLat = Math.floor(lat1 * 100) / 100;
227+
let maxLat = Math.floor(lat2 * 100) / 100;
228+
let minLng = Math.floor(lng1 * 100) / 100;
229+
let maxLng = Math.floor(lng2 * 100) / 100;
230+
231+
// return 10 pages of results
232+
return useRockdAPI("protected/checkins?minlat=" + minLat +
233+
"&maxlat=" + maxLat +
234+
"&minlng=" + minLng +
235+
"&maxlng=" + maxLng + "&all=10");
420236
}
421237

422-
function getTaxonCheckins(taxonId) {
423-
// not sure how to use api yet
424-
return useAPIResult("https://rockd.org/api/v1/protected/checkins?taxon_id=" + taxonId);
238+
function SelectedCheckins({selectedResult, inspectPosition, setInspectPosition}) {
239+
const mapRef = useMapRef();
240+
const map = mapRef.current;
241+
242+
// add selected checkin markers
243+
useEffect(() => {
244+
let selectedCords = [];
245+
246+
let previousSelected = document.querySelectorAll('.selected_pin');
247+
previousSelected.forEach((marker) => {
248+
marker.remove();
249+
});
250+
251+
// if selected checkins
252+
if(selectedResult?.length > 0 && inspectPosition) {
253+
selectedResult.forEach((checkin) => {
254+
selectedCords.push([checkin.lng, checkin.lat]);
255+
});
256+
257+
let selectedStop = 0;
258+
selectedCords.forEach((coord) => {
259+
selectedStop++;
260+
// marker
261+
const el = document.createElement('div');
262+
el.className = 'selected_pin';
263+
264+
// Create marker
265+
new mapboxgl.Marker(el)
266+
.setLngLat(coord)
267+
.addTo(map);
268+
});
269+
}
270+
}, [selectedResult]);
271+
272+
return h("div", {className: 'checkin-container'}, createCheckins(selectedResult, mapRef, setInspectPosition));
273+
}
274+
275+
function FeatureDetails({setInspectPosition}) {
276+
// return null;
277+
const mapRef = useMapRef();
278+
const map = mapRef.current;
279+
const [bounds, setBounds] = useState(map?.getBounds());
280+
let checkins = [];
281+
let result;
282+
283+
if(!map) {
284+
result = getCheckins(0, 0, 0, 0);
285+
} else if (bounds) {
286+
const distance = Math.abs(bounds.getEast() - bounds.getWest());
287+
const newEast = bounds.getEast() - distance * .2;
288+
result = getCheckins(bounds.getSouth(), bounds.getNorth(), bounds.getWest(), newEast);
289+
} else {
290+
result = getCheckins(0, 0, 0, 0);
291+
}
292+
293+
if (!bounds && map) {
294+
setBounds(map.getBounds());
295+
}
296+
297+
count++;
298+
299+
// Update bounds on move
300+
useEffect(() => {
301+
if(map) {
302+
const listener = () => {
303+
setBounds(map.getBounds());
304+
};
305+
map.on("moveend", listener);
306+
return () => {
307+
map.off("moveend", listener);
308+
};
309+
}
310+
}, [bounds]);
311+
312+
if (result == null) return h(Spinner);
313+
result = result.success.data;
314+
315+
checkins = createCheckins(result, mapRef, setInspectPosition);
316+
317+
return h("div", {className: 'checkin-container'}, [
318+
h('div', checkins)
319+
]);
425320
}

0 commit comments

Comments
 (0)