Reuse stops when zooming within loaded map bounds
This commit is contained in:
parent
e8d0ff5c2c
commit
8ed7b8d112
2 changed files with 17 additions and 23 deletions
|
|
@ -17,6 +17,7 @@ let hoveredMarkerHalo = null;
|
|||
let userMapInteractionPending = false;
|
||||
let mapMoveTimer = null;
|
||||
let mapRequestController = null;
|
||||
let loadedMapBounds = null;
|
||||
let returnToResults = false;
|
||||
let returnViaHistory = false;
|
||||
const MIN_MAP_STOP_ZOOM = 15;
|
||||
|
|
@ -167,25 +168,6 @@ async function loadSharedStop(type, id) {
|
|||
const response = await fetch(stopApiUrl(API_URLS.stopTemplate, type, id));
|
||||
const data = await response.json();
|
||||
if (!response.ok) throw new Error(data.message || 'Could not load that stop.');
|
||||
let nearbyData = {
|
||||
kind: 'location',
|
||||
location: {lat: data.stop.lat, lon: data.stop.lon, label: data.stop.name},
|
||||
stops: [data.stop],
|
||||
};
|
||||
try {
|
||||
const nearbyParams = new URLSearchParams({lat: data.stop.lat, lon: data.stop.lon});
|
||||
const nearbyResponse = await fetch(`${API_URLS.stops}?${nearbyParams}`);
|
||||
const nearbyResult = await nearbyResponse.json();
|
||||
if (nearbyResponse.ok) nearbyData = nearbyResult;
|
||||
} catch (_) {
|
||||
// The selected stop is still useful if the optional nearby lookup fails.
|
||||
}
|
||||
const selectedIndex = nearbyData.stops.findIndex(
|
||||
stop => stop.type === data.stop.type && stop.id === data.stop.id
|
||||
);
|
||||
if (selectedIndex === -1) nearbyData.stops.unshift(data.stop);
|
||||
else nearbyData.stops[selectedIndex] = data.stop;
|
||||
renderStops(nearbyData, true);
|
||||
returnToResults = true;
|
||||
returnViaHistory = false;
|
||||
await selectStop(data.stop, false);
|
||||
|
|
@ -245,6 +227,7 @@ function setSearchMarker(locationResult, label) {
|
|||
}
|
||||
|
||||
function renderStops(data, fitMap = true, sortOrigin = null, preserveSelection = false) {
|
||||
if (data.kind !== 'map') loadedMapBounds = null;
|
||||
const origin = data.location || sortOrigin;
|
||||
stops = [...data.stops]
|
||||
.map(stop => ({...stop, distance_metres: distanceMetres(stop, origin)}))
|
||||
|
|
@ -592,6 +575,7 @@ async function loadVisibleMapStops() {
|
|||
if (map.getZoom() < MIN_MAP_STOP_ZOOM) {
|
||||
markers.clearLayers();
|
||||
clearHoveredStop();
|
||||
loadedMapBounds = null;
|
||||
byId('map-status').textContent = 'Zoom in to load transport stops';
|
||||
show('map-status');
|
||||
return;
|
||||
|
|
@ -609,6 +593,14 @@ async function loadVisibleMapStops() {
|
|||
lat: center.lat.toFixed(6), lon: center.lng.toFixed(6),
|
||||
}), true);
|
||||
}
|
||||
if (loadedMapBounds && loadedMapBounds.contains(bounds)) {
|
||||
if (mapRequestController) {
|
||||
mapRequestController.abort();
|
||||
mapRequestController = null;
|
||||
}
|
||||
show('map-status', false);
|
||||
return;
|
||||
}
|
||||
byId('map-status').textContent = 'Loading stops in this area…';
|
||||
show('map-status');
|
||||
if (mapRequestController) mapRequestController.abort();
|
||||
|
|
@ -619,6 +611,8 @@ async function loadVisibleMapStops() {
|
|||
});
|
||||
const data = await response.json();
|
||||
if (!response.ok) throw new Error(data.message || 'Could not load this map area.');
|
||||
// A capped result may be incomplete, so do not reuse its coverage when zooming in.
|
||||
loadedMapBounds = data.stops.length < 1000 ? bounds : null;
|
||||
renderStops(data, false, map.getCenter(), Boolean(selectedStop));
|
||||
show('map-status', false);
|
||||
} catch (error) {
|
||||
|
|
|
|||
|
|
@ -122,7 +122,7 @@ def test_search_and_stop_details_in_browser(chromium_browser: Any, flask_url: st
|
|||
|
||||
|
||||
def test_moving_map_loads_only_when_zoomed_in(chromium_browser: Any, flask_url: str) -> None:
|
||||
"""Panning a close map loads visible stops while a wide map makes no query."""
|
||||
"""Map loads skip wide views and zoom-ins already covered by fetched bounds."""
|
||||
page = chromium_browser.new_page(viewport={"width": 1280, "height": 800})
|
||||
requests: list[str] = []
|
||||
|
||||
|
|
@ -154,13 +154,13 @@ def test_moving_map_loads_only_when_zoomed_in(chromium_browser: Any, flask_url:
|
|||
playwright_api.expect(page.locator("#stop-name")).to_have_text("Temple Meads")
|
||||
page.wait_for_timeout(700)
|
||||
playwright_api.expect(page.locator("#stop-detail")).to_be_visible()
|
||||
assert len(requests) == 3
|
||||
page.evaluate("userMapInteractionPending = true; map.panBy([80, 0])")
|
||||
assert len(requests) == 2
|
||||
page.evaluate("userMapInteractionPending = true; map.panBy([2500, 0])")
|
||||
page.wait_for_timeout(700)
|
||||
playwright_api.expect(page.locator("#stop-name")).to_have_text("Temple Meads")
|
||||
playwright_api.expect(page.locator("#stop-detail")).to_be_visible()
|
||||
playwright_api.expect(page).to_have_url(re.compile(r"\?node=456$"))
|
||||
assert len(requests) == 4
|
||||
assert len(requests) == 3
|
||||
page.close()
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue