Support source=gps in URL for dynamic GPS-based bookmarks
Bookmarking /path?source=gps&destination=K5TR&band=10000 will use the viewer's device GPS to resolve the source location on load. The LocateMe hook handles both button clicks and server-pushed request_gps events. Once coords are resolved, the URL is updated with actual lat,lon and calculation runs automatically.
This commit is contained in:
parent
8242ba682c
commit
5acaaa9fa1
2 changed files with 56 additions and 25 deletions
|
|
@ -1,27 +1,32 @@
|
||||||
export const LocateMe = {
|
export const LocateMe = {
|
||||||
mounted() {
|
mounted() {
|
||||||
this.el.addEventListener("click", () => {
|
this.el.addEventListener("click", () => this.locate())
|
||||||
if (!navigator.geolocation) {
|
|
||||||
alert("Geolocation is not supported by this browser")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
this.el.classList.add("loading", "loading-spinner")
|
// Also respond to server-pushed request (for source=gps URLs)
|
||||||
|
this.handleEvent("request_gps", () => this.locate())
|
||||||
|
},
|
||||||
|
|
||||||
navigator.geolocation.getCurrentPosition(
|
locate() {
|
||||||
(pos) => {
|
if (!navigator.geolocation) {
|
||||||
this.el.classList.remove("loading", "loading-spinner")
|
alert("Geolocation is not supported by this browser")
|
||||||
this.pushEvent("gps_location", {
|
return
|
||||||
lat: pos.coords.latitude,
|
}
|
||||||
lon: pos.coords.longitude
|
|
||||||
})
|
this.el.classList.add("loading", "loading-spinner")
|
||||||
},
|
|
||||||
(err) => {
|
navigator.geolocation.getCurrentPosition(
|
||||||
this.el.classList.remove("loading", "loading-spinner")
|
(pos) => {
|
||||||
alert("Could not get location: " + err.message)
|
this.el.classList.remove("loading", "loading-spinner")
|
||||||
},
|
this.pushEvent("gps_location", {
|
||||||
{ enableHighAccuracy: true, timeout: 10000 }
|
lat: pos.coords.latitude,
|
||||||
)
|
lon: pos.coords.longitude
|
||||||
})
|
})
|
||||||
|
},
|
||||||
|
(err) => {
|
||||||
|
this.el.classList.remove("loading", "loading-spinner")
|
||||||
|
alert("Could not get location: " + err.message)
|
||||||
|
},
|
||||||
|
{ enableHighAccuracy: true, timeout: 10000 }
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -70,8 +70,17 @@ defmodule MicrowavepropWeb.PathLive do
|
||||||
dst_gain_dbi: p["dst_gain_dbi"]
|
dst_gain_dbi: p["dst_gain_dbi"]
|
||||||
)
|
)
|
||||||
|
|
||||||
# Auto-calculate if source and destination are in the URL
|
# If source=gps, request device location via JS
|
||||||
if p["source"] != "" and p["destination"] != "" and not socket.assigns.computing and is_nil(socket.assigns.result) do
|
if p["source"] == "gps" and connected?(socket) do
|
||||||
|
{:noreply, push_event(socket, "request_gps", %{})}
|
||||||
|
else
|
||||||
|
auto_calculate(socket, p)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp auto_calculate(socket, p) do
|
||||||
|
if p["source"] != "" and p["source"] != "gps" and p["destination"] != "" and
|
||||||
|
not socket.assigns.computing and is_nil(socket.assigns.result) do
|
||||||
src_ht = parse_float(p["src_height_ft"], 30.0)
|
src_ht = parse_float(p["src_height_ft"], 30.0)
|
||||||
dst_ht = parse_float(p["dst_height_ft"], 30.0)
|
dst_ht = parse_float(p["dst_height_ft"], 30.0)
|
||||||
tx_dbm = parse_float(p["tx_power_dbm"], 20.0)
|
tx_dbm = parse_float(p["tx_power_dbm"], 20.0)
|
||||||
|
|
@ -152,9 +161,26 @@ defmodule MicrowavepropWeb.PathLive do
|
||||||
end
|
end
|
||||||
|
|
||||||
def handle_event("gps_location", %{"lat" => lat, "lon" => lon}, socket) do
|
def handle_event("gps_location", %{"lat" => lat, "lon" => lon}, socket) do
|
||||||
# Use coordinate string as source — resolve_location handles lat,lon format
|
|
||||||
source = "#{Float.round(lat / 1, 6)},#{Float.round(lon / 1, 6)}"
|
source = "#{Float.round(lat / 1, 6)},#{Float.round(lon / 1, 6)}"
|
||||||
{:noreply, assign(socket, source: source)}
|
|
||||||
|
# Replace gps with actual coords in URL and trigger calculation
|
||||||
|
socket = assign(socket, source: source, result: nil)
|
||||||
|
|
||||||
|
url_params =
|
||||||
|
%{
|
||||||
|
"source" => source,
|
||||||
|
"destination" => socket.assigns.destination,
|
||||||
|
"band" => socket.assigns.band,
|
||||||
|
"src_height_ft" => socket.assigns.src_height_ft,
|
||||||
|
"dst_height_ft" => socket.assigns.dst_height_ft,
|
||||||
|
"tx_power_dbm" => socket.assigns.tx_power_dbm,
|
||||||
|
"src_gain_dbi" => socket.assigns.src_gain_dbi,
|
||||||
|
"dst_gain_dbi" => socket.assigns.dst_gain_dbi
|
||||||
|
}
|
||||||
|
|> Enum.reject(fn {_k, v} -> v == "" end)
|
||||||
|
|> Map.new()
|
||||||
|
|
||||||
|
{:noreply, push_patch(socket, to: ~p"/path?#{url_params}", replace: true)}
|
||||||
end
|
end
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue