453e0df27bee27c20cfbab223b4f2d0fe801b8e0
6
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
40ecfb9fa9 |
refactor(decodes): read the list the way DXHunter's reads
Compared side by side, DXHunter's decode list is plainly easier to read, and three things account for the gap. The Call column repeated what the message already said. Every FT8 line opens with the callsigns — "CQ A93MO LL56", "PG5FRL JH3CUL PM74" — so a column in front of it printed the same token twice and pushed the line everyone actually reads to the middle of the row. It is gone; the message is the identity, and the tokens worth finding are picked out inside it: green for CQ and for our own call when someone answers, red for the station we are calling. The grid went with it, being the message's last token. Time is on every row now, compact, no separators. A decode belongs to a period and the section heading names it — but once a slot runs past a screenful the heading is somewhere above, and an instant you cannot read where the decode is is not an instant you have. Band and mode became their own columns, band as a chip, and the status flags moved into one column at the right edge with LoTW and a "worked" marker beside them. Rows are tighter: 13 px for the message and the report, 11 px for the figures, 10 px for the badges, and the column rules run through the lot. |
||
|
|
6da30f91c4 |
feat(decodes): slot clock, and the QSO in progress stands out
A countdown for the T/R slot, against the UTC clock — a bar, the seconds
left, and the mode. Slots are anchored to UTC rather than to when OpsLog
started, so it is computed from the wall clock alone and keeps running when
the band is dead and there is nothing to group. The last fifth of a slot
turns amber: that is when a decode is imminent and an operator deciding
whether to answer has run out of time to think.
Which exposed a real fault in the grouping. Status reports the T/R period
as a whole number of seconds, so FT4 arrives as 7 or 8 depending on which
way the sender rounded, and the code floored to whole seconds on top of
that — two FT4 periods landed in one heading and others were split down the
middle. The slot length now comes from the MODE, which knows the exact
figure and the whole halving family (FT8 15, FT4 7.5, FT2 3.75), with the
sender's number only as a fallback; and the arithmetic is in milliseconds.
Sub-second slots get a decimal in their heading, or two FT4 periods inside
one second would print the same time twice.
Two rows now stand out from the band behind them, because they are not
about the band at all but about the QSO in progress:
- the station being called is red, taken from the transmit state, so it
can be found in a slot holding thirty others;
- anyone ANSWERING is green and labelled, which outranks everything else
on the screen. A reply is a decoded line that opens with our own
callsign — bracketed too, since a non-standard call comes back
compressed.
|
||
|
|
fba7e79a1c |
feat(decodes): answer a station on click, DT and Freq, badge filters
Clicking a decode now ANSWERS it. It sends WSJT-X/MSHV a Reply message (type 4), which is the same thing as double-clicking the line in their own Band Activity window: the application looks the decode up, sets its transmit frequency to the caller's and starts the exchange. It deliberately does not tune the radio, which is what it did before and why nothing happened. On FT8 the whole band sits inside one passband, so moving the dial changes nothing about who gets answered - the decision belongs to the decoding application, and the Reply is the only way to hand it over. Tuning would also just fight it for the VFO. The entry is still filled so the QSO can be logged here. The reply is routed by PROGRAM ID, not by listener: two receivers can share one multicast group, and answering a station heard on the 6 m instance by talking to the 20 m one would start a call on the wrong band. It goes to the address that instance's packets actually arrive from - a multicast listener must answer the sender, never the group. WSJT-X matches the reply against its own decode list, so the payload replays the decode field for field: time, snr, delta time, audio offset, mode and message text. Two columns added, DT and Freq - the audio offset inside the passband, not the RF frequency, which is the same for every station in the list and says nothing. Past about two seconds DT takes a warning tint: that station is drifting out of the window. The transmit strip. "You cannot see what you are sending, or who you are calling" - two separate faults. The message was only ever threaded into its period, and in FT8 you transmit in the slots you are NOT receiving in, so its period had no decodes and the whole line was dropped; a transmit slot now creates its period. And the state is a strip of its own at the top, because it is the one thing on the screen that is about the operator rather than the band. It is fed by every Status rather than only by one carrying transmit text, so it can still name the station being called on MSHV and older JTDX builds, which stop before tx_message in the Status payload. "New only" became per-category badges, in the colours and the vocabulary of the Chase New panel. None lit shows the whole band - this is a decode log first, and a panel that opened by hiding most of the traffic would be lying about what is on the air. |
||
|
|
ffaf6fc869 |
refactor(decodes): column rules, left-aligned grid, no CQ stutter
Three things from reading it on a real screen. Column rules. The grid alone was not enough to follow a line across: cells now carry a right border and the row stretches, so the rules run unbroken from the header to the bottom of the list. That is what turns rows of text into a table. Left-aligned. The previous pass centred the grid inside a maximum width, which on a wide screen opened a dead margin down the left before the first callsign - trading the hole in the middle for a bigger one at the edge. Now it fills the width and the slack lands in the message column, which is the one that can use it and the one bounded by rules on both sides, so it reads as a cell rather than a gap. "CQ CQ PE1NAO JO32" - a green CQ badge in front of a message whose own first word is CQ. The badge is gone; the word already in the line is picked out instead, which scans the same and stutters not at all. |
||
|
|
4f77d51ffe |
refactor(decodes): real columns, spelled-out flags, bigger type
First pass on the panel from operating feedback. Columns are a grid template shared by the header row and every data row, so the two cannot drift and the eye has a rail to follow. It is capped at 1500 px and centred: free-flowing, a 2500 px window put the country a foot from the callsign it belonged to and left a hole in the middle of every line. "New" gets a COLUMN. It was only a coloured edge before, which says something is special without saying what — and every one of these is a reason to break off what you are doing and call. The entity verdict is a solid badge, the orthogonal ones (park, grid, prefix, county) are outlined in the colours markerColour already gives the cluster list and the band map, so a new park is the same green in all three. Applied inline because those are categorical --chart-* custom properties, which the theme does not expose as Tailwind colour utilities: written as border-chart-7 the badge would simply have had no colour. Band and mode selectors now appear only when the feed actually carries more than one of each. One MSHV is one band and one mode, so for most operators they were furniture; they show up the day a second instance puts a second band on the link, which is the only day they mean anything. Same rule for continent, and a receiver count when more than one instance is feeding. Added a LoTW-only filter, and raised the type throughout (call and message to 14 px, secondary to 12 px, badges to 11 px) with more room per row. The decode payload now carries the sending application's own id. It tells two receivers apart on one multicast group — and it is the address a WSJT-X Reply message would have to go back to, so it is carried now rather than requiring another trip through the parser later. |
||
|
|
a197d124dc |
feat(decodes): an FT decodes tab fed by the inbound UDP link
Every FTx decode WSJT-X, JTDX or MSHV puts on the wire, grouped by T/R
period. Optional and closable, from Tools -> FT decodes; its open state is
remembered, because an operator running digital modes leaves it open for
the session rather than consulting and closing it.
The period is the point, and what separates this from the cluster list.
FT8 is a sequence of fifteen-second slots and a band is read by watching
them go by: who called CQ this slot, who answered, what I was sending while
they did. A flat list sorted by time loses exactly that, so the list is
grouped one section per period, newest first, with the operator's own
transmission shown inside the slot it went out in.
Three fields had to be carried up from the wire to make it possible:
- the decode's OWN timestamp, which the parser read and threw away. It is
what assigns a slot: a period's decodes arrive in one burst a second or
two after it closes, so arrival time piles a whole period into the next
one. Rebuilt to UTC from milliseconds-since-midnight, with the
day-boundary case handled - a decode stamped 23:59:58 arriving at
00:00:01 would otherwise be dated a day ahead and sit at the top of the
list for the rest of the session.
- the decoded line itself. The exchange is what says where a station is in
a QSO, and no set of extracted fields reads like "R-09" does.
- tx_message and transmitting from Status, which nothing parsed before.
Recorded once per message rather than on every Status, which repeats it
about once a second for the whole over.
Also picked up on the way: is_new, low_confidence, off_air, the operator's
own call and grid, and the T/R period itself - better authority on slot
length than the mode name, which says nothing about a custom period. The
Status tail is read defensively: those fields were appended over successive
schema versions and JTDX and MSHV each stop at their own point, so a short
packet is normal and keeps whatever parsed.
Status flags come from ClusterSpotStatuses, the resolver the cluster list
and band map already use, filling the same cache. One verdict per call:
"new band" in this panel and plain worked in the cluster two seconds later
would be worse than no flag at all. Clicking a call goes through the same
handler as a cluster spot, so answering a station is one gesture whether it
came off telnet or off the receiver.
Filters: CQ only, new-anything only, band, mode, continent, an SNR floor
and a free search. The band, mode and continent choices are built from what
is actually on the feed - offering 160 m to a station whose receivers are
all on 6 m is noise.
Decodes are held in the frontend and pruned to a rolling half hour: they
are a live view, not data, nothing outside the panel reads them, and a
night of FT8 on 20 m would otherwise grow a list no filter can rescue.
Arrivals are staged on a 300 ms timer so a period landing as fifty packets
costs one status lookup and one render.
|