The radar circle is a square, so it is limited by the shorter side of
the card it is drawn in: the small-window layout gave the radar card a
height of ~156dp in a 411x450 window, which shrank the circle to ~36% of
the page width while the full-screen layout shows ~84%.
- measure the real window with BoxWithConstraints instead of trusting the
window size class, which can still report the full screen while the app
runs in a split/floating window
- when the classic 1:1 split would give the radar less than 75% of the
page width, use a fill layout: the radar takes the largest square that
fits, a usable pager block is reserved under it while that keeps the
circle at its full-screen share, otherwise the pager collapses into a
48dp translucent tab strip with a tappable panel
- keep the normal two-row top area in the vertical layout: TimerRow and
NextPassRow both carry weight(1f) internally, so putting them in a
single row splits that row into two 50% blocks
- extract the geometry into pure Dp functions (useFillRadarLayout,
radarFillSizes) covered by unit tests
The previous compact-mode trigger used currentWindowAdaptiveInfo(),
which reports the full-screen size class in split-screen / multi-window,
so the radar never enlarged there. Measure the actual window bounds with
BoxWithConstraints: compact (radar weight 1f fills all space, pager fixed
132dp strip) when maxWidth < 600dp && maxHeight < 480dp.
build: release version 4.4.7-ba7opf.17.6 (529)
When the window is vertical (narrow) and too short for split-screen or a
small floating window, give the radar card 1.6/0.6 weight instead of the
usual 1:1 so the square radar plot stays large. The pager card shrinks
but all its pages are scrollable, so nothing is clipped. Full-screen
vertical layout (enough height) is unchanged.
P2 — markUploaded now only marks the records that actually made it
into the accepted TQ8 batch (preview.submittedIds), never the whole
candidate list. Previously, un-signable records skipped by prepare()
were still marked UP after any accepted upload, falsely showing them
as uploaded.
P4 — surface why records did not upload:
- When audit finds nothing pending, distinguish unavailable records
(invalid call/date — check logbook) from unknown-result records
(not retried automatically) instead of a blanket 'no pending'.
- Upload preview dialogs (Log tab + logbook) show a breakdown line:
N already uploaded/duplicate · N unknown result · N un-uploadable.
- Remove LOCATION_MISMATCH check: the recorded myGrid never enters the
TQ8 (the tSTATION grid is signed from the current certificate station),
so a portable/ADIF-imported record with a different grid must not block
upload. Logging and uploading are now fully decoupled from the
certificate location.
- Fingerprint now covers the CONTACT only (call, date, band, mode,
satellite, freq), excluding station fields: changing grid/zones/county/
IOTA no longer invalidates ledger entries, so already-uploaded contacts
are not re-queued and rejected as duplicates.
- prepare(): catch un-signable contacts per-record instead of aborting
the whole batch; count them as skipped and upload the rest.
- audit(): count lotwUploaded records as uploaded (ledger-loss fallback).
The LoTW upload card read uiState.lotwCertificate which was only
populated when the config dialog was opened (LoadLoTWUploadStatus).
On first entry to the settings screen it stayed null, showing
'certificate not imported' even though a certificate was stored.
Load certificate + station once in init so the card is correct
from the first frame.
The import previously swallowed all exceptions silently. Now the upload
config dialog shows a specific message for: wrong password, expired
certificate, invalid file, and unknown failures.
- displayMode no longer trusts a stale submode for non-MFSK modes: FM/CW/SSB
records (including ones persisted with the old default submode=FT4) now show
their real mode; only MODE=MFSK uses the FT4 submode. QsoRecord defaults
changed mode=MFSK->FM, submode=FT4->''.
- LoTW report bridge sets submode=FT4 for MODE=MFSK so confirmations still
match local FT4 records.
- Logbook and LoTW upload config dialogs now use SharedDialog (bottom-sheet),
matching the LoTW confirmed-grids dialog style.
The Choose .p12 button was gated on a non-blank password, which forced users
to type the password before selecting the file. Now the file picker is always
available; after selection the filename is shown, then the password field and
an Import button appear.
- Port TQ8 signing/upload pipeline (core/data/lotw: LoTWConfig, LoTWKeyMaterial,
LoTWSigner, LoTWStorage, LoTWUploadRepository) with bundled ARRL config.tq6
- Multi-grid station locations: primary grid in GRIDSQUARE + full set in
MY_VUCC_GRIDS (unsigned tSTATION extra, IOTA precedent); signer matches
myGrid against the whole grid set
- Satellite-name normalization: SatNOGS names ("SO-50 (SaudiOSCAR 50)") resolve
to official LoTW names by exact-then-substring match
- Logbook storage: separate QsoDatabase (version 1, no migration on existing
installs), QsoRepository with dedupe/confirmation merge; LoTW sync (manual +
auto) feeds confirmations into the logbook and marks local uploads confirmed
- Radar Log tab: single-callsign recording, per-satellite mode preset
(CW/SSB/FT4), English social post generation (copy/share), LoTW upload with
one-shot preview confirmation + receipts ledger
- Settings: 日志本 section (records + confirmation state, delete on tap) above
LoTW config; LoTW upload config (TrustedQSL .p12 import + password, station
grid list incl. IOTA/CQZ/ITUZ)
- i18n strings (en/zh)