Show beacon submitter callsign, add donate link, prefer 8-char grids
- Add belongs_to :user on Beacon schema, preload in get_beacon!/1
- Show "Submitted by {callsign}" on beacon detail page
- Add NTMS donation link on the about page
- Change grid preference text to 8 characters (e.g. EM12kp37)
This commit is contained in:
parent
1174ecd9e5
commit
c3becdac9f
8 changed files with 53 additions and 17 deletions
|
|
@ -47,7 +47,7 @@ defmodule Microwaveprop.Beacons do
|
||||||
end
|
end
|
||||||
|
|
||||||
@doc "Gets a single beacon. Raises if not found."
|
@doc "Gets a single beacon. Raises if not found."
|
||||||
def get_beacon!(id), do: Repo.get!(Beacon, id)
|
def get_beacon!(id), do: Beacon |> Repo.get!(id) |> Repo.preload(:user)
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Creates a beacon. When a user is provided they are recorded as the
|
Creates a beacon. When a user is provided they are recorded as the
|
||||||
|
|
|
||||||
|
|
@ -152,7 +152,8 @@ defmodule Microwaveprop.Beacons.Beacon do
|
||||||
field :bearing, :string, default: "omni"
|
field :bearing, :string, default: "omni"
|
||||||
field :beamwidth_deg, :float
|
field :beamwidth_deg, :float
|
||||||
field :notes, :string
|
field :notes, :string
|
||||||
field :user_id, :binary_id
|
|
||||||
|
belongs_to :user, Microwaveprop.Accounts.User
|
||||||
|
|
||||||
timestamps(type: :utc_datetime)
|
timestamps(type: :utc_datetime)
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -363,10 +363,10 @@ defmodule Microwaveprop.Radio do
|
||||||
end
|
end
|
||||||
|
|
||||||
defp find_duplicate_contact(changeset) do
|
defp find_duplicate_contact(changeset) do
|
||||||
s1 = Ecto.Changeset.get_field(changeset, :station1) |> to_string() |> String.upcase()
|
s1 = changeset |> Ecto.Changeset.get_field(:station1) |> to_string() |> String.upcase()
|
||||||
s2 = Ecto.Changeset.get_field(changeset, :station2) |> to_string() |> String.upcase()
|
s2 = changeset |> Ecto.Changeset.get_field(:station2) |> to_string() |> String.upcase()
|
||||||
g1 = Ecto.Changeset.get_field(changeset, :grid1) |> to_string() |> String.upcase()
|
g1 = changeset |> Ecto.Changeset.get_field(:grid1) |> to_string() |> String.upcase()
|
||||||
g2 = Ecto.Changeset.get_field(changeset, :grid2) |> to_string() |> String.upcase()
|
g2 = changeset |> Ecto.Changeset.get_field(:grid2) |> to_string() |> String.upcase()
|
||||||
band = Ecto.Changeset.get_field(changeset, :band)
|
band = Ecto.Changeset.get_field(changeset, :band)
|
||||||
ts = Ecto.Changeset.get_field(changeset, :qso_timestamp)
|
ts = Ecto.Changeset.get_field(changeset, :qso_timestamp)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -86,7 +86,7 @@ defmodule Microwaveprop.Radio.AdifImport do
|
||||||
# Value starts right after the closing >
|
# Value starts right after the closing >
|
||||||
# Find the > after the tag
|
# Find the > after the tag
|
||||||
tag_text = String.slice(record_string, tag_start, 999)
|
tag_text = String.slice(record_string, tag_start, 999)
|
||||||
value_offset = tag_start + byte_size(String.split(tag_text, ">", parts: 2) |> List.first()) + 1
|
value_offset = tag_start + (tag_text |> String.split(">", parts: 2) |> List.first() |> byte_size()) + 1
|
||||||
value = String.slice(record_string, value_offset, size)
|
value = String.slice(record_string, value_offset, size)
|
||||||
|
|
||||||
Map.put(acc, name, value)
|
Map.put(acc, name, value)
|
||||||
|
|
@ -229,7 +229,14 @@ defmodule Microwaveprop.Radio.AdifImport do
|
||||||
defp dedupe(rows, db_map) do
|
defp dedupe(rows, db_map) do
|
||||||
{accepted, _in_batch, duplicates} =
|
{accepted, _in_batch, duplicates} =
|
||||||
Enum.reduce(rows, {[], %{}, []}, fn row, {accepted, in_batch, dups} ->
|
Enum.reduce(rows, {[], %{}, []}, fn row, {accepted, in_batch, dups} ->
|
||||||
key = dedup_key(row.attrs["station1"], row.attrs["grid1"], row.attrs["station2"], row.attrs["grid2"], row.attrs["band"])
|
key =
|
||||||
|
dedup_key(
|
||||||
|
row.attrs["station1"],
|
||||||
|
row.attrs["grid1"],
|
||||||
|
row.attrs["station2"],
|
||||||
|
row.attrs["grid2"],
|
||||||
|
row.attrs["band"]
|
||||||
|
)
|
||||||
|
|
||||||
cond do
|
cond do
|
||||||
conflict_in_map?(db_map, key, row.timestamp) ->
|
conflict_in_map?(db_map, key, row.timestamp) ->
|
||||||
|
|
|
||||||
|
|
@ -170,6 +170,15 @@ defmodule MicrowavepropWeb.AboutLive do
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="rounded-box border border-primary/30 bg-primary/10 p-3 text-center">
|
||||||
|
<p>
|
||||||
|
If this tool is useful to you, consider
|
||||||
|
<a href="https://ntms.org" target="_blank" class="link link-primary font-semibold">
|
||||||
|
donating to NTMS
|
||||||
|
</a>
|
||||||
|
to help keep the project running.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</Layouts.app>
|
</Layouts.app>
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -131,6 +131,11 @@ defmodule MicrowavepropWeb.BeaconLive.Show do
|
||||||
</div>
|
</div>
|
||||||
<div class="whitespace-pre-wrap text-sm">{@beacon.notes}</div>
|
<div class="whitespace-pre-wrap text-sm">{@beacon.notes}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div :if={@beacon.user && @beacon.user.callsign} class="mt-3 pt-3 border-t border-base-300">
|
||||||
|
<span class="text-xs opacity-60">Submitted by</span>
|
||||||
|
<span class="text-sm font-semibold">{@beacon.user.callsign}</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Layouts.app>
|
</Layouts.app>
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,8 @@ defmodule MicrowavepropWeb.SubmitLive do
|
||||||
|
|
||||||
alias Microwaveprop.Propagation.BandConfig
|
alias Microwaveprop.Propagation.BandConfig
|
||||||
alias Microwaveprop.Radio
|
alias Microwaveprop.Radio
|
||||||
alias Microwaveprop.Radio.Contact
|
|
||||||
alias Microwaveprop.Radio.AdifImport
|
alias Microwaveprop.Radio.AdifImport
|
||||||
|
alias Microwaveprop.Radio.Contact
|
||||||
alias Microwaveprop.Radio.CsvImport
|
alias Microwaveprop.Radio.CsvImport
|
||||||
alias Microwaveprop.Workers.ContactWeatherEnqueueWorker
|
alias Microwaveprop.Workers.ContactWeatherEnqueueWorker
|
||||||
|
|
||||||
|
|
@ -355,7 +355,7 @@ defmodule MicrowavepropWeb.SubmitLive do
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p class="text-sm text-base-content/60 -mt-2">
|
<p class="text-sm text-base-content/60 -mt-2">
|
||||||
Be as specific as possible with grid squares (6 characters preferred, e.g. EM12kp).
|
Be as specific as possible with grid squares (8 characters preferred, e.g. EM12kp37).
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-4">
|
<div class="grid grid-cols-1 md:grid-cols-3 gap-4">
|
||||||
|
|
@ -375,7 +375,13 @@ defmodule MicrowavepropWeb.SubmitLive do
|
||||||
options={@mode_options}
|
options={@mode_options}
|
||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
<.input field={@form[:qso_timestamp]} type="datetime-local" label="Timestamp (UTC)" lang="en-GB" required />
|
<.input
|
||||||
|
field={@form[:qso_timestamp]}
|
||||||
|
type="datetime-local"
|
||||||
|
label="Timestamp (UTC)"
|
||||||
|
lang="en-GB"
|
||||||
|
required
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<%= if @current_user do %>
|
<%= if @current_user do %>
|
||||||
|
|
@ -416,7 +422,7 @@ defmodule MicrowavepropWeb.SubmitLive do
|
||||||
Timestamps in most formats accepted (e.g. <code>2024-06-15T14:30:00Z</code>, <code>6/15/2024 2:30 PM</code>, <code>2024-06-15 14:30</code>). All times assumed UTC.
|
Timestamps in most formats accepted (e.g. <code>2024-06-15T14:30:00Z</code>, <code>6/15/2024 2:30 PM</code>, <code>2024-06-15 14:30</code>). All times assumed UTC.
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
Grid squares should be as detailed as possible (6 characters preferred, e.g. EM12kp)
|
Grid squares should be as detailed as possible (8 characters preferred, e.g. EM12kp37)
|
||||||
</li>
|
</li>
|
||||||
<li>Band in MHz (e.g. 10000, 24000)</li>
|
<li>Band in MHz (e.g. 10000, 24000)</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
@ -502,9 +508,10 @@ defmodule MicrowavepropWeb.SubmitLive do
|
||||||
</p>
|
</p>
|
||||||
<ul class="list-disc list-inside mt-2 space-y-1 text-base-content/60">
|
<ul class="list-disc list-inside mt-2 space-y-1 text-base-content/60">
|
||||||
<li>
|
<li>
|
||||||
Required fields: <code>CALL</code>, <code>STATION_CALLSIGN</code> (or <code>OPERATOR</code>),
|
Required fields: <code>CALL</code>, <code>STATION_CALLSIGN</code>
|
||||||
<code>GRIDSQUARE</code>, <code>MY_GRIDSQUARE</code>, <code>QSO_DATE</code>, <code>TIME_ON</code>,
|
(or <code>OPERATOR</code>), <code>GRIDSQUARE</code>, <code>MY_GRIDSQUARE</code>, <code>QSO_DATE</code>, <code>TIME_ON</code>,
|
||||||
and <code>FREQ</code> or <code>BAND</code>
|
and <code>FREQ</code>
|
||||||
|
or <code>BAND</code>
|
||||||
</li>
|
</li>
|
||||||
<li>Only microwave contacts (902 MHz and up) will be imported</li>
|
<li>Only microwave contacts (902 MHz and up) will be imported</li>
|
||||||
<li>Sub-microwave contacts are silently skipped</li>
|
<li>Sub-microwave contacts are silently skipped</li>
|
||||||
|
|
@ -512,7 +519,12 @@ defmodule MicrowavepropWeb.SubmitLive do
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<form id="adif-upload-form" phx-submit="upload_adif" phx-change="validate_adif" class="space-y-4">
|
<form
|
||||||
|
id="adif-upload-form"
|
||||||
|
phx-submit="upload_adif"
|
||||||
|
phx-change="validate_adif"
|
||||||
|
class="space-y-4"
|
||||||
|
>
|
||||||
<div class="fieldset mb-2">
|
<div class="fieldset mb-2">
|
||||||
<label>
|
<label>
|
||||||
<span class="label mb-1">ADIF File</span>
|
<span class="label mb-1">ADIF File</span>
|
||||||
|
|
|
||||||
|
|
@ -75,7 +75,9 @@ defmodule Microwaveprop.Radio.AdifImportTest do
|
||||||
|
|
||||||
assert {:ok, preview} = AdifImport.preview(adif, @submitter)
|
assert {:ok, preview} = AdifImport.preview(adif, @submitter)
|
||||||
assert [row] = preview.valid
|
assert [row] = preview.valid
|
||||||
assert row.attrs["band"] == expected_band, "FREQ #{freq} should map to band #{expected_band}, got #{row.attrs["band"]}"
|
|
||||||
|
assert row.attrs["band"] == expected_band,
|
||||||
|
"FREQ #{freq} should map to band #{expected_band}, got #{row.attrs["band"]}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue