Fix spurious bounds_changed events and event loops
Key fixes: - Combine bounds_changed and update_map_state into single event - Remove duplicate sendBoundsToServer() calls - Add programmaticMove flag to prevent event loops - Only process bounds updates when bounds actually change - Debounce events with 300ms timeout This eliminates: - Duplicate server events for same user action - Event loops when server updates URL - Unnecessary bounds processing - Excessive server load 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
c873614bf1
commit
a9414823f1
2 changed files with 50 additions and 7 deletions
|
|
@ -25,6 +25,7 @@ type LiveViewHookContext = {
|
|||
lastZoom?: number;
|
||||
currentPopupMarkerId?: string | null;
|
||||
oms?: any;
|
||||
programmaticMove?: boolean;
|
||||
[key: string]: any;
|
||||
};
|
||||
|
||||
|
|
@ -287,9 +288,14 @@ let MapAPRSMap = {
|
|||
|
||||
// Send bounds to LiveView when map moves
|
||||
self.map!.on("moveend", () => {
|
||||
// Skip if this is a programmatic move from the server
|
||||
if (self.programmaticMove) {
|
||||
self.programmaticMove = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (self.boundsTimer) clearTimeout(self.boundsTimer);
|
||||
self.boundsTimer = setTimeout(() => {
|
||||
self.sendBoundsToServer();
|
||||
// Save map state and update URL
|
||||
const center = self.map.getCenter();
|
||||
const zoom = self.map.getZoom();
|
||||
|
|
@ -298,16 +304,28 @@ let MapAPRSMap = {
|
|||
JSON.stringify({ lat: center.lat, lng: center.lng, zoom }),
|
||||
);
|
||||
|
||||
// Send map state update to server for URL updating
|
||||
// Send combined map state update to server for URL and bounds updating
|
||||
self.pushEvent("update_map_state", {
|
||||
center: { lat: center.lat, lng: center.lng },
|
||||
zoom: zoom
|
||||
zoom: zoom,
|
||||
bounds: {
|
||||
north: self.map.getBounds().getNorth(),
|
||||
south: self.map.getBounds().getSouth(),
|
||||
east: self.map.getBounds().getEast(),
|
||||
west: self.map.getBounds().getWest(),
|
||||
}
|
||||
});
|
||||
}, 300);
|
||||
});
|
||||
|
||||
// Handle zoom changes with optimization for large zoom differences
|
||||
self.map!.on("zoomend", () => {
|
||||
// Skip if this is a programmatic move from the server
|
||||
if (self.programmaticMove) {
|
||||
self.programmaticMove = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (self.boundsTimer) clearTimeout(self.boundsTimer);
|
||||
self.boundsTimer = setTimeout(() => {
|
||||
const currentZoom = self.map!.getZoom();
|
||||
|
|
@ -319,7 +337,6 @@ let MapAPRSMap = {
|
|||
self.pushEvent("refresh_markers", {});
|
||||
}
|
||||
|
||||
self.sendBoundsToServer();
|
||||
self.lastZoom = currentZoom;
|
||||
// Save map state and update URL
|
||||
const center = self.map.getCenter();
|
||||
|
|
@ -329,10 +346,16 @@ let MapAPRSMap = {
|
|||
JSON.stringify({ lat: center.lat, lng: center.lng, zoom }),
|
||||
);
|
||||
|
||||
// Send map state update to server for URL updating
|
||||
// Send combined map state update to server for URL and bounds updating
|
||||
self.pushEvent("update_map_state", {
|
||||
center: { lat: center.lat, lng: center.lng },
|
||||
zoom: zoom
|
||||
zoom: zoom,
|
||||
bounds: {
|
||||
north: self.map.getBounds().getNorth(),
|
||||
south: self.map.getBounds().getSouth(),
|
||||
east: self.map.getBounds().getEast(),
|
||||
west: self.map.getBounds().getWest(),
|
||||
}
|
||||
});
|
||||
}, 300);
|
||||
});
|
||||
|
|
@ -464,6 +487,8 @@ let MapAPRSMap = {
|
|||
// Use a slight delay to ensure map is ready
|
||||
setTimeout(() => {
|
||||
if (self.map) {
|
||||
// Set flag to prevent event loop
|
||||
self.programmaticMove = true;
|
||||
self.map.setView([lat, lng], zoom, {
|
||||
animate: true,
|
||||
duration: 1,
|
||||
|
|
|
|||
|
|
@ -317,7 +317,7 @@ defmodule AprsmeWeb.MapLive.Index do
|
|||
end
|
||||
|
||||
@impl true
|
||||
def handle_event("update_map_state", %{"center" => center, "zoom" => zoom}, socket) do
|
||||
def handle_event("update_map_state", %{"center" => center, "zoom" => zoom} = params, socket) do
|
||||
# Parse center coordinates
|
||||
lat =
|
||||
case center do
|
||||
|
|
@ -345,6 +345,24 @@ defmodule AprsmeWeb.MapLive.Index do
|
|||
new_path = "/?lat=#{lat}&lng=#{lng}&z=#{zoom}"
|
||||
socket = push_patch(socket, to: new_path, replace: true)
|
||||
|
||||
# If bounds are included, also process bounds update
|
||||
socket = case Map.get(params, "bounds") do
|
||||
%{"north" => north, "south" => south, "east" => east, "west" => west} ->
|
||||
map_bounds = %{
|
||||
north: north,
|
||||
south: south,
|
||||
east: east,
|
||||
west: west
|
||||
}
|
||||
# Only trigger bounds processing if bounds actually changed
|
||||
if socket.assigns.map_bounds != map_bounds do
|
||||
send(self(), {:process_bounds_update, map_bounds})
|
||||
end
|
||||
socket
|
||||
_ ->
|
||||
socket
|
||||
end
|
||||
|
||||
{:noreply, socket}
|
||||
end
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue