Skip to content

Commit 2411aa1

Browse files
authored
drop duplicate listing coordinates (#45)
1 parent 31898f1 commit 2411aa1

6 files changed

Lines changed: 256 additions & 67 deletions

File tree

src/app/(forms)/profile/listings/[slug]/page.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ export default async function EditListingPage({ params }) {
4343
.single();
4444

4545
const { data: listing } = await supabase
46-
.from("listings")
46+
.from("listings_private_data")
4747
.select()
4848
.eq("owner_id", user.id)
4949
.match({ slug })

src/components/ListingRead/ListingRead.jsx

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ const ListingRead = memo(function Listing({
7777
? listing.name
7878
: listing.owner_first_name
7979
: getListingDisplayName(listing, user);
80+
const coordinates = listing?.coordinates;
8081

8182
if (!listing && presentation !== "demo") {
8283
console.log("Listing not found");
@@ -158,15 +159,15 @@ const ListingRead = memo(function Listing({
158159
<MapThumbnail
159160
height="320px"
160161
initialViewState={{
161-
longitude: listing.longitude,
162-
latitude: listing.latitude,
162+
longitude: coordinates.longitude,
163+
latitude: coordinates.latitude,
163164
zoom: initialZoomLevel,
164165
}}
165166
interactive={false}
166167
>
167168
<Marker
168-
longitude={listing.longitude}
169-
latitude={listing.latitude}
169+
longitude={coordinates.longitude}
170+
latitude={coordinates.latitude}
170171
anchor="center"
171172
onClick={(event) => {
172173
event.originalEvent.stopPropagation();
@@ -216,7 +217,7 @@ const ListingRead = memo(function Listing({
216217
<Button
217218
variant="secondary"
218219
size="small"
219-
href={`https://maps.apple.com/?ll=${listing.latitude},${listing.longitude}&q=${encodeURIComponent(
220+
href={`https://maps.apple.com/?ll=${coordinates.latitude},${coordinates.longitude}&q=${encodeURIComponent(
220221
listing.name
221222
)}`}
222223
target="_blank"
@@ -226,7 +227,7 @@ const ListingRead = memo(function Listing({
226227
<Button
227228
variant="secondary"
228229
size="small"
229-
href={`https://maps.google.com/?q=${listing.latitude},${listing.longitude}`}
230+
href={`https://maps.google.com/?q=${coordinates.latitude},${coordinates.longitude}`}
230231
target="_blank"
231232
>
232233
{t("Actions.openInGoogleMaps")}

src/components/ListingWrite/ListingWrite.tsx

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -114,12 +114,7 @@ export default function ListingWrite({
114114
);
115115

116116
const [coordinates, setCoordinates] = useState<Coordinates | null>(
117-
initialListing
118-
? {
119-
latitude: initialListing.latitude,
120-
longitude: initialListing.longitude,
121-
}
122-
: null
117+
initialListing?.coordinates ?? null
123118
);
124119

125120
const [areaName, setAreaName] = useState<string>(
@@ -264,10 +259,6 @@ export default function ListingWrite({
264259
...(listingType !== "residential" && { name: validatedName }),
265260
description,
266261
location: `POINT(${selectedCoordinates.longitude} ${selectedCoordinates.latitude})`,
267-
// Temporarily store the coordinates as longitude and latitude floats in the database as well
268-
// ...because I can't get the geometry type to convert to to long and lat dynamically if a user goes direct to a listing, e.g. http://localhost:3000/map?listing=9xvN9zxH0rzZ
269-
longitude: selectedCoordinates.longitude,
270-
latitude: selectedCoordinates.latitude,
271262
area_name: areaName,
272263
country_code: countryCode,
273264
accepted_items: acceptedItems.filter((item) => item.trim() !== ""),

src/components/MapImmersive/MapImmersive.jsx

Lines changed: 92 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -53,14 +53,20 @@ const DEFAULT_COORDINATES = {
5353
zoom: 9,
5454
};
5555

56+
function getListingCoordinates(listing) {
57+
return listing?.coordinates ?? null;
58+
}
59+
5660
function hasValidCoordinates(listing) {
61+
const coordinates = getListingCoordinates(listing);
62+
5763
return (
5864
listing &&
5965
!listing.error &&
60-
typeof listing.latitude === "number" &&
61-
typeof listing.longitude === "number" &&
62-
Number.isFinite(listing.latitude) &&
63-
Number.isFinite(listing.longitude)
66+
typeof coordinates?.latitude === "number" &&
67+
typeof coordinates?.longitude === "number" &&
68+
Number.isFinite(coordinates.latitude) &&
69+
Number.isFinite(coordinates.longitude)
6470
);
6571
}
6672

@@ -86,7 +92,9 @@ export default function MapImmersive({
8692
isDesktop,
8793
countryCode,
8894
}) {
89-
const isFirstLoad = useRef(true);
95+
const selectedListingCoordinates = getListingCoordinates(selectedListing);
96+
const hasAppliedInitialPositionRef = useRef(false);
97+
const centeredListingIdRef = useRef(null);
9098
const [lastKnownPosition, setLastKnownPosition] = useState(null);
9199
const [isListingInView, setIsListingInView] = useState(true);
92100
const hasInitialPosition =
@@ -111,11 +119,15 @@ export default function MapImmersive({
111119

112120
// If there's a selected listing with valid coords, center on it instead of using IP location
113121
if (hasValidCoordinates(selectedListing)) {
122+
const coordinates = getListingCoordinates(selectedListing);
123+
114124
mapRef.current?.flyTo({
115-
center: [selectedListing.longitude, selectedListing.latitude],
125+
center: [coordinates.longitude, coordinates.latitude],
116126
zoom: 12,
117127
duration: 0,
118128
});
129+
hasAppliedInitialPositionRef.current = true;
130+
centeredListingIdRef.current = selectedListing.id;
119131
}
120132

121133
const bounds = mapRef.current.getMap().getBounds();
@@ -133,9 +145,10 @@ export default function MapImmersive({
133145

134146
// Check if selected listing is in view (only when it has valid coords)
135147
if (hasValidCoordinates(selectedListing)) {
148+
const coordinates = getListingCoordinates(selectedListing);
136149
const isInView = bounds.contains([
137-
selectedListing.longitude,
138-
selectedListing.latitude,
150+
coordinates.longitude,
151+
coordinates.latitude,
139152
]);
140153
setIsListingInView(isInView);
141154
}
@@ -144,8 +157,10 @@ export default function MapImmersive({
144157
const handleFlyToListing = useCallback(() => {
145158
if (!hasValidCoordinates(selectedListing) || !mapRef.current) return;
146159

160+
const coordinates = getListingCoordinates(selectedListing);
161+
147162
mapRef.current.flyTo({
148-
center: [selectedListing.longitude, selectedListing.latitude],
163+
center: [coordinates.longitude, coordinates.latitude],
149164
duration: 1500,
150165
});
151166
}, [selectedListing]);
@@ -154,32 +169,66 @@ export default function MapImmersive({
154169
let protocol = new Protocol();
155170
maplibregl.addProtocol("pmtiles", protocol.tile);
156171

157-
// Only handle initial positioning on first load
158-
if (isFirstLoad.current) {
159-
isFirstLoad.current = false;
160-
161-
// If there's a selected listing in URL with valid coords, center on it
162-
if (hasValidCoordinates(selectedListing)) {
163-
mapRef.current?.flyTo({
164-
center: [selectedListing.longitude, selectedListing.latitude],
165-
zoom: 12,
166-
duration: 0,
167-
});
168-
}
169-
// If no listing but we have IP coordinates, use those
170-
else if (initialCoordinates) {
171-
mapRef.current?.flyTo({
172-
center: [initialCoordinates.longitude, initialCoordinates.latitude],
173-
zoom: initialCoordinates.zoom,
174-
duration: 0,
175-
});
176-
}
177-
}
178-
179172
return () => {
180173
maplibregl.removeProtocol("pmtiles");
181174
};
182-
}, []); // Empty dependency array as before
175+
}, []);
176+
177+
useEffect(() => {
178+
if (
179+
hasAppliedInitialPositionRef.current ||
180+
hasValidCoordinates(selectedListing) ||
181+
!initialCoordinates ||
182+
!mapRef.current
183+
) {
184+
return;
185+
}
186+
187+
hasAppliedInitialPositionRef.current = true;
188+
mapRef.current.flyTo({
189+
center: [initialCoordinates.longitude, initialCoordinates.latitude],
190+
zoom: initialCoordinates.zoom,
191+
duration: 0,
192+
});
193+
}, [initialCoordinates, mapRef, selectedListing]);
194+
195+
useEffect(() => {
196+
if (
197+
!mapRef.current ||
198+
!hasValidCoordinates(selectedListing) ||
199+
centeredListingIdRef.current === selectedListing.id
200+
) {
201+
return;
202+
}
203+
204+
const coordinates = getListingCoordinates(selectedListing);
205+
const map = mapRef.current.getMap();
206+
const bounds = map.getBounds();
207+
const isInView = bounds.contains([
208+
coordinates.longitude,
209+
coordinates.latitude,
210+
]);
211+
212+
if (isInView) {
213+
hasAppliedInitialPositionRef.current = true;
214+
centeredListingIdRef.current = selectedListing.id;
215+
setIsListingInView(true);
216+
return;
217+
}
218+
219+
mapRef.current.flyTo({
220+
center: [coordinates.longitude, coordinates.latitude],
221+
zoom: 12,
222+
duration: 900,
223+
});
224+
hasAppliedInitialPositionRef.current = true;
225+
centeredListingIdRef.current = selectedListing.id;
226+
}, [
227+
mapRef,
228+
selectedListing,
229+
selectedListingCoordinates?.latitude,
230+
selectedListingCoordinates?.longitude,
231+
]);
183232

184233
// Set mapController to set relationship between MapSearch and MapImmersive
185234
// Can't get this to work, perhaps delete all mapController and createMapLibreGlMapController code if I can't get it working
@@ -193,9 +242,11 @@ export default function MapImmersive({
193242
// Update lastKnownPosition when we have a valid position
194243
useEffect(() => {
195244
if (hasValidCoordinates(selectedListing)) {
245+
const coordinates = getListingCoordinates(selectedListing);
246+
196247
setLastKnownPosition({
197-
latitude: selectedListing.latitude,
198-
longitude: selectedListing.longitude,
248+
latitude: coordinates.latitude,
249+
longitude: coordinates.longitude,
199250
});
200251
} else if (initialCoordinates && !lastKnownPosition) {
201252
setLastKnownPosition(initialCoordinates);
@@ -210,9 +261,10 @@ export default function MapImmersive({
210261
}
211262

212263
const bounds = mapRef.current.getMap().getBounds();
264+
const coordinates = getListingCoordinates(selectedListing);
213265
const isInView = bounds.contains([
214-
selectedListing.longitude,
215-
selectedListing.latitude,
266+
coordinates.longitude,
267+
coordinates.latitude,
216268
]);
217269
console.log("isInView", isInView);
218270
setIsListingInView(isInView);
@@ -269,13 +321,13 @@ export default function MapImmersive({
269321
initialViewState={{
270322
longitude:
271323
(hasValidCoordinates(selectedListing)
272-
? selectedListing.longitude
324+
? selectedListingCoordinates.longitude
273325
: null) ??
274326
initialCoordinates?.longitude ??
275327
DEFAULT_COORDINATES.longitude,
276328
latitude:
277329
(hasValidCoordinates(selectedListing)
278-
? selectedListing.latitude
330+
? selectedListingCoordinates.latitude
279331
: null) ??
280332
initialCoordinates?.latitude ??
281333
DEFAULT_COORDINATES.latitude,
@@ -308,8 +360,8 @@ export default function MapImmersive({
308360
.map((listing) => (
309361
<DrawerTrigger key={listing.id}>
310362
<Marker
311-
longitude={listing.longitude}
312-
latitude={listing.latitude}
363+
longitude={listing.coordinates.longitude}
364+
latitude={listing.coordinates.latitude}
313365
anchor="center"
314366
onClick={(event) => {
315367
event.originalEvent.stopPropagation();

0 commit comments

Comments
 (0)