Add Help section to Settings (about, source, guide, support) (v0.11.1)

A new Help card under Project shows the app name + live version (read from the
package, so it never drifts from the build) and links to the source repo, the
user guide, and the support page. Each link is a full-width ~64 dp row with a
large label, the destination URL beneath, and a chevron affordance — a
comfortable thumb target that opens in the system browser (missing-browser safe).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Reactorcoremeltdown
2026-07-18 23:25:37 +02:00
parent 3508777ba9
commit 40a946a894
2 changed files with 48 additions and 2 deletions

View File

@@ -22,8 +22,8 @@ android {
// (android.media.midi) and AAudio low-latency audio we rely on.
minSdk = 26
targetSdk = 34
versionCode = 27
versionName = "0.10.0"
versionCode = 29
versionName = "0.11.1"
// We provide our own instrumentation runner if/when tests are added.
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"

View File

@@ -7,6 +7,7 @@ import android.content.Context
import android.content.Intent
import android.media.AudioDeviceInfo
import android.media.AudioManager
import android.net.Uri
import android.view.KeyEvent
import androidx.activity.compose.BackHandler
import androidx.activity.compose.rememberLauncherForActivityResult
@@ -93,6 +94,7 @@ fun SettingsScreen(vm: AppViewModel) {
) {
item { PanicButton(vm) }
item { ProjectCard(vm) }
item { HelpCard() }
item { AudioDevicesCard(vm) }
item { InterfaceCard(vm) }
item { ThemeCard(vm) }
@@ -370,6 +372,50 @@ private fun AudioDevicesCard(vm: AppViewModel) {
}
}
/** About + external links: app version, source, user guide, and support. */
@Composable
private fun HelpCard() {
val context = LocalContext.current
val version = remember {
runCatching { context.packageManager.getPackageInfo(context.packageName, 0).versionName }.getOrNull()
}
val appName = remember { context.applicationInfo.loadLabel(context.packageManager).toString() }
SettingsCard("Help", subtitle = "About, source, user guide & support") {
Text(
appName + (version?.let { " v$it" } ?: ""),
style = MaterialTheme.typography.bodyMedium,
)
LinkRow("Source code", "https://git.rcmd.space/tiredsysadmin/sizzletracker-android")
LinkRow(
"User guide",
"https://git.rcmd.space/tiredsysadmin/sizzletracker-android/src/branch/main/docs/USER_GUIDE.md",
)
LinkRow("Support us", "https://rcmd.space/pages/support/")
}
}
/** A tappable label + destination URL that opens in the system browser. A tall,
* full-width row (~64 dp) so it's a comfortable thumb target on a phone. */
@Composable
private fun LinkRow(label: String, url: String) {
val context = LocalContext.current
Row(
Modifier.fillMaxWidth().clickable { openUrl(context, url) }.padding(vertical = 12.dp),
verticalAlignment = Alignment.CenterVertically,
) {
Column(Modifier.weight(1f)) {
Text(label, style = MaterialTheme.typography.titleMedium, color = MaterialTheme.colorScheme.primary)
Text(url, style = MaterialTheme.typography.bodySmall, color = MaterialTheme.colorScheme.onSurfaceVariant)
}
Icon(Icons.Filled.ChevronRight, contentDescription = null, tint = MaterialTheme.colorScheme.primary)
}
}
/** Open [url] in the user's browser; a missing browser is ignored rather than crashing. */
private fun openUrl(context: Context, url: String) {
runCatching { context.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(url))) }
}
/** Interface options: currently the mixer VU-meter toggle. */
@Composable
private fun InterfaceCard(vm: AppViewModel) {