`submit()` opened with `if (call.length < 3) return`. During a pass the operator typed
a callsign, pressed done, and nothing happened - no entry, no message, no way to tell
the app had decided against them. None of the logging software surveyed for this work
- N1MM+, DXLog, PoLo, HAMRS - discards a submission silently.
Validation is deliberately loose, because strictness costs more than it saves. Checked
against 28 real callsigns, a typical strict pattern rejects 16 of them: W1AW/4, 2E0ABC,
9A1CCY and SV2ASP/A among others. A pattern permissive enough to accept those also
accepts a Maidenhead locator as a callsign. There is no regex that catches typos without
throwing away legitimate calls, so CallsignEntry rejects only what cannot be a callsign
- empty, one character, illegal characters, all digits, all letters - and reports doubt
as a warning that still logs the contact.
Two warnings exist. A six-character grid-shaped entry says so, because grid and callsign
are exchanged together on FM satellites and the fields sit side by side. A station already
worked this pass says so too, without blocking: the same station on a later pass is a
legitimate new contact, and contest loggers default to working duplicates - DXLog
describes refusing them as an outdated habit.
That warning also replaces the duplicate suppression, which was a 300ms window comparing
the last callsign, admitted in its own comment to be a workaround. It could silently
discard a real second contact, and a set of calls worked this pass is both honest and
more useful. It survives configuration changes via rememberSaveable.
Not addressed here: the QRZ grid backfill still reads the cookie out of SharedPreferences
from inside a composable through LocalContext, and still reports nothing when a lookup
fails. IQrzGridLookup is added for that, but wiring it needs the container, the view model
and the UI to change together.