Improve path page UX: prominent GPS button, share links
- "My Location" button with text label (was just an icon) - Two share buttons after results: - "Copy Link" — fixed coordinates, exact result - "Copy Link (use viewer's GPS)" — source=gps, dynamic per viewer - CopyLink JS hook copies full URL to clipboard with "Copied!" feedback
This commit is contained in:
parent
ed6a378f3e
commit
1b0b55358b
3 changed files with 63 additions and 8 deletions
|
|
@ -35,7 +35,7 @@ import {ContactMap} from "./contact_map_hook"
|
|||
import {ContactsMap} from "./contacts_map_hook"
|
||||
import {ElevationProfile} from "./elevation_profile_hook"
|
||||
import {WeatherMap} from "./weather_map_hook"
|
||||
import {LocateMe} from "./locate_me_hook"
|
||||
import {LocateMe, CopyLink} from "./locate_me_hook"
|
||||
|
||||
const UtcClock = {
|
||||
mounted() {
|
||||
|
|
@ -57,7 +57,7 @@ const csrfToken = document.querySelector("meta[name='csrf-token']").getAttribute
|
|||
const liveSocket = new LiveSocket("/live", Socket, {
|
||||
longPollFallbackMs: 2500,
|
||||
params: initLiveStash({_csrf_token: csrfToken}),
|
||||
hooks: {...colocatedHooks, PropagationMap, UtcClock, ContactMap, ContactsMap, ElevationProfile, WeatherMap, LocateMe},
|
||||
hooks: {...colocatedHooks, PropagationMap, UtcClock, ContactMap, ContactsMap, ElevationProfile, WeatherMap, LocateMe, CopyLink},
|
||||
})
|
||||
|
||||
// Show progress bar on live navigation and form submits
|
||||
|
|
|
|||
|
|
@ -1,3 +1,16 @@
|
|||
export const CopyLink = {
|
||||
mounted() {
|
||||
this.el.addEventListener("click", () => {
|
||||
const url = window.location.origin + this.el.dataset.url
|
||||
navigator.clipboard.writeText(url).then(() => {
|
||||
const orig = this.el.innerHTML
|
||||
this.el.innerHTML = '<span class="text-success">Copied!</span>'
|
||||
setTimeout(() => { this.el.innerHTML = orig }, 1500)
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export const LocateMe = {
|
||||
mounted() {
|
||||
this.el.addEventListener("click", () => this.locate())
|
||||
|
|
|
|||
|
|
@ -470,6 +470,27 @@ defmodule MicrowavepropWeb.PathLive do
|
|||
defp format_utc_hour(%DateTime{} = dt), do: Calendar.strftime(dt, "%H:%M")
|
||||
defp format_utc_hour(_), do: "?"
|
||||
|
||||
defp share_url(result, mode) do
|
||||
source =
|
||||
case mode do
|
||||
:gps -> "gps"
|
||||
:fixed -> "#{Float.round(result.source.lat, 4)},#{Float.round(result.source.lon, 4)}"
|
||||
end
|
||||
|
||||
params = %{
|
||||
"source" => source,
|
||||
"destination" => result.destination.label,
|
||||
"band" => to_string(result.band_mhz),
|
||||
"src_height_ft" => to_string(result.station_params.src_height_ft),
|
||||
"dst_height_ft" => to_string(result.station_params.dst_height_ft),
|
||||
"tx_power_dbm" => to_string(result.station_params.tx_power_dbm),
|
||||
"src_gain_dbi" => to_string(result.station_params.src_gain_dbi),
|
||||
"dst_gain_dbi" => to_string(result.station_params.dst_gain_dbi)
|
||||
}
|
||||
|
||||
"/path?" <> URI.encode_query(params)
|
||||
end
|
||||
|
||||
defp format_mw(mw) when mw >= 1000, do: "#{format_number(mw / 1000)} W"
|
||||
defp format_mw(mw) when mw >= 1, do: "#{format_number(mw)} mW"
|
||||
defp format_mw(mw), do: "#{format_number(mw * 1000)} uW"
|
||||
|
|
@ -488,25 +509,24 @@ defmodule MicrowavepropWeb.PathLive do
|
|||
<form phx-submit="calculate" phx-change="update_form" class="bg-base-200 rounded-box p-4 mb-6">
|
||||
<div class="grid grid-cols-1 md:grid-cols-4 gap-4 items-end">
|
||||
<div class="fieldset">
|
||||
<label class="label text-sm font-medium">Source (callsign or grid)</label>
|
||||
<label class="label text-sm font-medium">Source</label>
|
||||
<div class="flex gap-1">
|
||||
<input
|
||||
type="text"
|
||||
name="source"
|
||||
id="source-input"
|
||||
value={@source}
|
||||
placeholder="W5ISP or EM13sf"
|
||||
placeholder="W5ISP, EM13sf, or lat,lon"
|
||||
class="input input-bordered flex-1"
|
||||
required
|
||||
/>
|
||||
<button
|
||||
type="button"
|
||||
id="locate-me"
|
||||
phx-hook="LocateMe"
|
||||
class="btn btn-square btn-sm btn-ghost"
|
||||
title="Use GPS location"
|
||||
class="btn btn-sm btn-outline gap-1"
|
||||
title="Use device GPS"
|
||||
>
|
||||
<.icon name="hero-map-pin" class="size-4" />
|
||||
<.icon name="hero-map-pin" class="size-3.5" /> My Location
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -896,6 +916,28 @@ defmodule MicrowavepropWeb.PathLive do
|
|||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<%!-- Share links --%>
|
||||
<div class="flex flex-wrap gap-2 mb-6">
|
||||
<button
|
||||
type="button"
|
||||
phx-hook="CopyLink"
|
||||
id="copy-link"
|
||||
data-url={share_url(@result, :fixed)}
|
||||
class="btn btn-sm btn-outline gap-1"
|
||||
>
|
||||
<.icon name="hero-link" class="size-3.5" /> Copy Link
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
phx-hook="CopyLink"
|
||||
id="copy-gps-link"
|
||||
data-url={share_url(@result, :gps)}
|
||||
class="btn btn-sm btn-outline gap-1"
|
||||
>
|
||||
<.icon name="hero-map-pin" class="size-3.5" /> Copy Link (use viewer's GPS)
|
||||
</button>
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue