From 149e207e69d8f466ab3be18b62a5fbd736c667cf Mon Sep 17 00:00:00 2001 From: Jonathon Leight Date: Fri, 26 Jun 2026 17:38:59 -0400 Subject: [PATCH] Fix custom radio details --- internal/core/repeaters.go | 11 +++-- internal/core/templates/add_repeater.html | 52 +++++++++++++++------- internal/core/templates/confirm.html | 2 +- internal/core/templates/edit_repeater.html | 52 +++++++++++++++------- internal/web/env.go | 11 ++++- 5 files changed, 92 insertions(+), 36 deletions(-) diff --git a/internal/core/repeaters.go b/internal/core/repeaters.go index b2e5ee7..4dc25eb 100644 --- a/internal/core/repeaters.go +++ b/internal/core/repeaters.go @@ -6,6 +6,7 @@ import ( "fmt" "html/template" "image/color" + "math" "net/http" "net/url" "strconv" @@ -175,15 +176,17 @@ func (s *Handlers) handleAddRepeater(w http.ResponseWriter, r *http.Request) { } // parseRadioForm reads and validates the radio fields from a repeater form. +// Frequency and bandwidth are entered in MHz/kHz (matching the region presets) +// and stored as Hz. func parseRadioForm(r *http.Request) (freq, bw int64, sf, cr int16, ok bool) { - f, e1 := strconv.ParseInt(r.FormValue("radio_freq_hz"), 10, 64) - b, e2 := strconv.ParseInt(r.FormValue("radio_bw_hz"), 10, 64) + mhz, e1 := strconv.ParseFloat(r.FormValue("radio_freq_mhz"), 64) + khz, e2 := strconv.ParseFloat(r.FormValue("radio_bw_khz"), 64) s, e3 := strconv.ParseInt(r.FormValue("radio_sf"), 10, 16) c, e4 := strconv.ParseInt(r.FormValue("radio_cr"), 10, 16) - if e1 != nil || e2 != nil || e3 != nil || e4 != nil || f <= 0 || b <= 0 { + if e1 != nil || e2 != nil || e3 != nil || e4 != nil || mhz <= 0 || khz <= 0 { return 0, 0, 0, 0, false } - return f, b, int16(s), int16(c), true + return int64(math.Round(mhz * 1e6)), int64(math.Round(khz * 1e3)), int16(s), int16(c), true } // pageEditRepeater shows the edit form for an owned repeater. diff --git a/internal/core/templates/add_repeater.html b/internal/core/templates/add_repeater.html index dd09f02..7155be8 100644 --- a/internal/core/templates/add_repeater.html +++ b/internal/core/templates/add_repeater.html @@ -93,8 +93,8 @@
-
-
+
+
@@ -112,23 +112,45 @@ {{end}} diff --git a/internal/core/templates/confirm.html b/internal/core/templates/confirm.html index 94af626..4a27bc1 100644 --- a/internal/core/templates/confirm.html +++ b/internal/core/templates/confirm.html @@ -16,7 +16,7 @@ to verify it has access. This is optional — the repeater works either way.

{{.Repeater.PublicKeyHex}} -
{{.Repeater.RadioFreqHz}} Hz · BW {{.Repeater.RadioBwHz}} · SF{{.Repeater.RadioSF}} · CR{{.Repeater.RadioCR}}
+
{{mhz .Repeater.RadioFreqHz}} MHz · BW {{khz .Repeater.RadioBwHz}} · SF{{.Repeater.RadioSF}} · CR{{.Repeater.RadioCR}}
-
-
+
+
@@ -55,22 +55,44 @@ {{end}} diff --git a/internal/web/env.go b/internal/web/env.go index 3d2bbe2..bb3473d 100644 --- a/internal/web/env.go +++ b/internal/web/env.go @@ -12,6 +12,7 @@ import ( "net" "net/http" "net/url" + "strconv" "strings" "github.com/go-chi/chi/v5" @@ -117,8 +118,16 @@ func (e *Env) SetDefaultLayout(name string) { e.Renderer.defaultLayout = name } // NewRenderer parses the shared base layout (base.html + icons.html) and composes // each of the surface's own *.html pages onto it. Each page redefines the // content/title/header blocks, so every page gets its own cloned template set. +// templateFuncs are helpers available to every page template. mhz/khz present +// the Hz-canonical radio values in the human-readable units the region presets +// use (MHz for frequency, kHz for bandwidth), formatted without trailing zeros. +var templateFuncs = template.FuncMap{ + "mhz": func(hz int64) string { return strconv.FormatFloat(float64(hz)/1e6, 'f', -1, 64) }, + "khz": func(hz int64) string { return strconv.FormatFloat(float64(hz)/1e3, 'f', -1, 64) }, +} + func NewRenderer(cfg *config.Config, surfaceTemplates fs.FS) (*Renderer, error) { - base, err := template.New("").ParseFS(sharedTemplatesFS, "templates/base.html", "templates/icons.html", "templates/org_tabs.html", "templates/repeater_tabs.html") + base, err := template.New("").Funcs(templateFuncs).ParseFS(sharedTemplatesFS, "templates/base.html", "templates/icons.html", "templates/org_tabs.html", "templates/repeater_tabs.html") if err != nil { return nil, err }