feat(aprs): link out to request a passcode instead of computing one

The settings card had a "Compute passcode" button that derived the value from the
callsign and filled the field in. It was added by request, so it stayed while the
previous commit removed the same derivation from the connection path - which left
the app contradicting itself: the background no longer invented a passcode, but the
UI still offered to.

APRS-IS treats the passcode as a licence check and states that supplying it to a
user is the software author's responsibility. APRSdroid carries the identical
algorithm in the same source file and deliberately does not use it for this, opting
to validate what the operator typed and link out to request one. Filling the field
in claims a check that nobody performed.

The button now opens the passcode request page. AprsPacket.passcode stays in
core:domain because validating an entry means recomputing the expected value, and
its import is dropped from the card, which no longer needs it.
This commit is contained in:
mckero committed 2026-08-25 13:18:51 +00:00
1 parent 262ae45432
commit b19c78441c
6 files changed
+25 -13

No files matched your search

@@ -2,6 +2,7 @@ package com.rtbishop.look4sat.feature.settings
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Build
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
@@ -33,12 +34,19 @@ import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.rtbishop.look4sat.core.data.aprs.AprsConfig
import com.rtbishop.look4sat.core.domain.aprs.AprsPacket
import com.rtbishop.look4sat.core.data.aprs.AprsStore
import com.rtbishop.look4sat.core.presentation.CardButton
import com.rtbishop.look4sat.core.presentation.R
/** APRS card: sits between the satellite-data and data-output containers; settings live in a gear dialog to save space */
/**
* Where an operator obtains an APRS-IS passcode.
*
* The app links here rather than deriving one: the passcode is a licence check, and APRS-IS
* states that supplying it is the software author's responsibility.
*/
private const val PASSCODE_REQUEST_URL = "https://apps.magicbug.co.uk/passcode/"
@Composable
fun AprsCard() {
val context = LocalContext.current
@@ -187,6 +195,7 @@ private fun AprsSettingsDialog(
var symbolTable by remember { mutableStateOf(config.symbolTable) }
var symbolCode by remember { mutableStateOf(config.symbolCode) }
val textStyle = LocalTextStyle.current.copy(fontSize = 14.sp)
val context = LocalContext.current
AlertDialog(
onDismissRequest = onDismiss,
@@ -215,16 +224,19 @@ private fun AprsSettingsDialog(
singleLine = true,
textStyle = textStyle
)
// Passcode compute button (user request: let the user see the computed result)
// Links out instead of computing it. APRS-IS treats the passcode as a licence
// check and says supplying it to a user is the software author's job; APRSdroid
// carries the same algorithm and deliberately does not use it here for that
// reason. Filling the field in claims a check that nobody performed.
TextButton(
onClick = {
val call = callsign.trim().uppercase()
if (call.isNotBlank()) {
passcode = AprsPacket.passcode(call).toString()
runCatching {
context.startActivity(
Intent(Intent.ACTION_VIEW, Uri.parse(PASSCODE_REQUEST_URL))
)
}
},
enabled = callsign.trim().isNotBlank()
) { Text(stringResource(id = R.string.prefs_aprs_calc_passcode)) }
}
) { Text(stringResource(id = R.string.prefs_aprs_request_passcode)) }
Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
OutlinedTextField(
value = ssid,