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

@@ -35,7 +35,7 @@
<string name="aprs_notif_connected">Terhubung ke APRS-IS</string> <string name="aprs_notif_connected">Terhubung ke APRS-IS</string>
<string name="aprs_notif_error">Kesalahan koneksi</string> <string name="aprs_notif_error">Kesalahan koneksi</string>
<string name="aprs_notif_stop">Berhenti</string> <string name="aprs_notif_stop">Berhenti</string>
<string name="prefs_aprs_calc_passcode">Hitung kode sandi</string> <string name="prefs_aprs_request_passcode">Minta kode sandi</string>
<string name="aprs_toast_ok">APRS: laporan terkirim</string> <string name="aprs_toast_ok">APRS: laporan terkirim</string>
<string name="aprs_toast_fail">APRS: laporan gagal - %1$s</string> <string name="aprs_toast_fail">APRS: laporan gagal - %1$s</string>
<string name="aprs_toast_unverified">APRS-IS tidak memverifikasi passcode Anda. Laporan Anda tidak diteruskan - periksa tanda panggil dan passcode di Pengaturan.</string> <string name="aprs_toast_unverified">APRS-IS tidak memverifikasi passcode Anda. Laporan Anda tidak diteruskan - periksa tanda panggil dan passcode di Pengaturan.</string>
@@ -35,7 +35,7 @@
<string name="aprs_notif_connected">Terhubung ke APRS-IS</string> <string name="aprs_notif_connected">Terhubung ke APRS-IS</string>
<string name="aprs_notif_error">Kesalahan koneksi</string> <string name="aprs_notif_error">Kesalahan koneksi</string>
<string name="aprs_notif_stop">Berhenti</string> <string name="aprs_notif_stop">Berhenti</string>
<string name="prefs_aprs_calc_passcode">Hitung kode sandi</string> <string name="prefs_aprs_request_passcode">Minta kode sandi</string>
<string name="aprs_toast_ok">APRS: laporan terkirim</string> <string name="aprs_toast_ok">APRS: laporan terkirim</string>
<string name="aprs_toast_fail">APRS: laporan gagal - %1$s</string> <string name="aprs_toast_fail">APRS: laporan gagal - %1$s</string>
<string name="aprs_toast_unverified">APRS-IS tidak memverifikasi passcode Anda. Laporan Anda tidak diteruskan - periksa tanda panggil dan passcode di Pengaturan.</string> <string name="aprs_toast_unverified">APRS-IS tidak memverifikasi passcode Anda. Laporan Anda tidak diteruskan - periksa tanda panggil dan passcode di Pengaturan.</string>
@@ -36,7 +36,7 @@
<string name="aprs_notif_connected">APRS-IS bağlı</string> <string name="aprs_notif_connected">APRS-IS bağlı</string>
<string name="aprs_notif_error">Bağlantı hatası</string> <string name="aprs_notif_error">Bağlantı hatası</string>
<string name="aprs_notif_stop">Durdur</string> <string name="aprs_notif_stop">Durdur</string>
<string name="prefs_aprs_calc_passcode">Parolayı hesapla</string> <string name="prefs_aprs_request_passcode">Passcode isteyin</string>
<string name="aprs_toast_ok">APRS: rapor gönderildi</string> <string name="aprs_toast_ok">APRS: rapor gönderildi</string>
<string name="aprs_toast_fail">APRS: rapor başarısız - %1$s</string> <string name="aprs_toast_fail">APRS: rapor başarısız - %1$s</string>
<string name="aprs_toast_unverified">APRS-IS passcode bilginizi doğrulamadı. Raporlarınız iletilmiyor - Ayarlar bölümünde çağrı işareti ve passcode bilgisini kontrol edin.</string> <string name="aprs_toast_unverified">APRS-IS passcode bilginizi doğrulamadı. Raporlarınız iletilmiyor - Ayarlar bölümünde çağrı işareti ve passcode bilgisini kontrol edin.</string>
@@ -37,7 +37,7 @@
<string name="aprs_notif_connected">已连接 APRS-IS</string> <string name="aprs_notif_connected">已连接 APRS-IS</string>
<string name="aprs_notif_error">连接错误</string> <string name="aprs_notif_error">连接错误</string>
<string name="aprs_notif_stop">停止</string> <string name="aprs_notif_stop">停止</string>
<string name="prefs_aprs_calc_passcode">计算验证码</string> <string name="prefs_aprs_request_passcode">申请验证码</string>
<string name="aprs_toast_ok">APRS: 上报成功</string> <string name="aprs_toast_ok">APRS: 上报成功</string>
<string name="aprs_toast_fail">APRS: 上报失败 - %1$s</string> <string name="aprs_toast_fail">APRS: 上报失败 - %1$s</string>
<string name="aprs_toast_unverified">APRS-IS 未验证你的 passcode, 上报不会被转发 - 请在设置里检查呼号与 passcode。</string> <string name="aprs_toast_unverified">APRS-IS 未验证你的 passcode, 上报不会被转发 - 请在设置里检查呼号与 passcode。</string>
@@ -38,7 +38,7 @@
<string name="aprs_notif_connected">Connected to APRS-IS</string> <string name="aprs_notif_connected">Connected to APRS-IS</string>
<string name="aprs_notif_error">Connection error</string> <string name="aprs_notif_error">Connection error</string>
<string name="aprs_notif_stop">Stop</string> <string name="aprs_notif_stop">Stop</string>
<string name="prefs_aprs_calc_passcode">Compute passcode</string> <string name="prefs_aprs_request_passcode">Request a passcode</string>
<string name="aprs_toast_ok">APRS: report sent OK</string> <string name="aprs_toast_ok">APRS: report sent OK</string>
<string name="aprs_toast_fail">APRS: report failed - %1$s</string> <string name="aprs_toast_fail">APRS: report failed - %1$s</string>
<string name="aprs_toast_unverified">APRS-IS did not verify your passcode. Your reports are not being passed on - check the callsign and passcode in Settings.</string> <string name="aprs_toast_unverified">APRS-IS did not verify your passcode. Your reports are not being passed on - check the callsign and passcode in Settings.</string>
@@ -2,6 +2,7 @@ package com.rtbishop.look4sat.feature.settings
import android.content.Intent import android.content.Intent
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.net.Uri
import android.os.Build import android.os.Build
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column 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.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import com.rtbishop.look4sat.core.data.aprs.AprsConfig 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.data.aprs.AprsStore
import com.rtbishop.look4sat.core.presentation.CardButton import com.rtbishop.look4sat.core.presentation.CardButton
import com.rtbishop.look4sat.core.presentation.R 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 */ /** 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 @Composable
fun AprsCard() { fun AprsCard() {
val context = LocalContext.current val context = LocalContext.current
@@ -187,6 +195,7 @@ private fun AprsSettingsDialog(
var symbolTable by remember { mutableStateOf(config.symbolTable) } var symbolTable by remember { mutableStateOf(config.symbolTable) }
var symbolCode by remember { mutableStateOf(config.symbolCode) } var symbolCode by remember { mutableStateOf(config.symbolCode) }
val textStyle = LocalTextStyle.current.copy(fontSize = 14.sp) val textStyle = LocalTextStyle.current.copy(fontSize = 14.sp)
val context = LocalContext.current
AlertDialog( AlertDialog(
onDismissRequest = onDismiss, onDismissRequest = onDismiss,
@@ -215,16 +224,19 @@ private fun AprsSettingsDialog(
singleLine = true, singleLine = true,
textStyle = textStyle 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( TextButton(
onClick = { onClick = {
val call = callsign.trim().uppercase() runCatching {
if (call.isNotBlank()) { context.startActivity(
passcode = AprsPacket.passcode(call).toString() Intent(Intent.ACTION_VIEW, Uri.parse(PASSCODE_REQUEST_URL))
)
} }
}, }
enabled = callsign.trim().isNotBlank() ) { Text(stringResource(id = R.string.prefs_aprs_request_passcode)) }
) { Text(stringResource(id = R.string.prefs_aprs_calc_passcode)) }
Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) { Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
OutlinedTextField( OutlinedTextField(
value = ssid, value = ssid,