TX: free text is a one-shot, sent immediately (WSJT-X Tx5 style)#350
Merged
Conversation
Free text was queued like a CQ: setTransmitFreeText(true) left it repeating every cycle until STOP, and it only went out at the next slot boundary (up to a full cycle of dead air). A tester noted free text should behave like WSJT-X's Tx5 — an alternative to a 73, sent once — and that the wait felt too long. Add sendFreeTextOnce(): set the text, arm a freeTextOneShot flag, activate, and transmitNow() so it fires this cycle if we're within the late-start tolerance (immediate TX, same path tapping a decode uses). After the single send, afterPlayAudio() auto-stops the sequencer and reverts to standard messages. The app consumes the armed free text on send so the next CQ tap calls a normal CQ. Extract shouldStopAfterOneShot() as a pure predicate and unit-test it. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## dev #350 +/- ##
============================================
- Coverage 11.70% 11.46% -0.25%
- Complexity 113 120 +7
============================================
Files 85 89 +4
Lines 11691 12565 +874
Branches 2110 2247 +137
============================================
+ Hits 1369 1441 +72
- Misses 10191 10993 +802
Partials 131 131
🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
This PR changes the “free text” TX behavior to be a WSJT-X Tx5-style one-shot: when armed from the UI it should transmit once (optionally immediately via the existing late-start tolerance path) and then auto-stop/revert to normal CQ messaging.
Changes:
- Add
sendFreeTextOnce()and afreeTextOneShotflag to arm a single free-text transmission and auto-stop afterafterPlayAudio(). - Update the Compose UI CQ handler to consume/reset the armed free-text message after sending.
- Add a pure predicate (
shouldStopAfterOneShot) plus unit tests to validate auto-stop conditions.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| ft8af/app/src/test/java/com/k1af/ft8af/ft8transmit/FT8TransmitSignalTest.java | Adds unit tests for the one-shot stop predicate. |
| ft8af/app/src/main/kotlin/radio/ks3ckc/ft8af/FT8AFApp.kt | Switches CQ action to call sendFreeTextOnce() and clears the UI’s free-text state. |
| ft8af/app/src/main/java/com/k1af/ft8af/ft8transmit/FT8TransmitSignal.java | Implements one-shot arming + auto-stop logic and extracts a testable predicate. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
sendFreeTextOnce() called transmitNow(), which dereferences toCallsign (for its status toast). toCallsign is null until the first setTransmit/resetToCQ, so using a free-text one-shot as the very first TX action of a session (before any CQ press or decode tap) threw an NPE. Seed a CQ baseline when toCallsign is null before transmitting. The free-text message is built independently of toCallsign, so this only supplies the baseline target. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Tester feedback: "when I set the free text, it might need to send once. afaik, in wsjtx, free text is alternative option of the 73 not a CQ" and "i feel too long waiting time."
Today, sending free text calls
setTransmitFreeText(true)and then activates like a CQ, so:Change
New
sendFreeTextOnce()onFT8TransmitSignal:freeTextOneShotflag,setActivated(true)thentransmitNow()— so it transmits this cycle if we're within the late-start tolerance window (the same immediate-TX path tapping a decode already uses), otherwise at the next boundary,afterPlayAudio()auto-stops the sequencer and revertstransmitFreeTextto false so the next CQ is a normal CQ.The app (
onCallCQ) consumes the armed free text on send (isFreeTextMode = false), so the UI reverts to standard CQ after one shot.Safety: the one-shot stop runs at the end of
afterPlayAudio(), after playback has drained (isTransmittingalready false), sosetActivated(false)doesn't abort live audio. Activation blocked by SWR lockout / invalid callsign disarms the one-shot cleanly.Tests
shouldStopAfterOneShot()pure predicate + 4 unit tests (stops only for a free-text one-shot; never for a normal CQ).testDebugUnitTestgreen; built and installed on the Pixel 8, launches cleanly.Follow-up (not in this PR)
A general "transmit immediately" option for standard CQ (the tester mentioned "for free text and other cases") could reuse
transmitNow()on the CQ activate path. Scoped out here to keep the change focused on the free-text behavior.Part of a series addressing tester feedback on the Android UI (item 2 of 4).