From dfae34c706a174958e00521bb922c2da9d5f60a7 Mon Sep 17 00:00:00 2001 From: marc Date: Sun, 6 Sep 2026 20:37:13 +0200 Subject: [PATCH] feat(android): Navidrome-Adresse als Vorgabe, Login vorbelegt (1.3) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ergaenzt Backend und Scrobble um die Navidrome-Adresse: alle drei kommen als buildConfigField aus dem Build und greifen, wenn im Geraetespeicher nichts steht. Der Anmeldebildschirm ist damit vorbelegt — beim ersten Start bleiben nur noch Benutzer und Passwort. Die Felder in den Einstellungen bleiben sichtbar und ueberschreibbar, ein Umzug ist also ohne neues APK zu korrigieren. Zugangsdaten bleiben aussen vor. Das Publish-Skript reicht die Werte aus scripts/.env.release durch, damit kuenftige Builds sie nicht verlieren. Am erzeugten BuildConfig geprueft, alle vier Werte stehen darin. Co-Authored-By: Claude Opus 5 --- CHANGELOG.md | 6 ++++++ android/app/build.gradle.kts | 10 ++++++---- .../main/kotlin/com/novasonic/app/data/PrefsStore.kt | 7 +++++-- .../kotlin/com/novasonic/app/ui/screen/LoginScreen.kt | 3 ++- scripts/publish-apk.mjs | 8 ++++++++ 5 files changed, 27 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9e814c7..67f96af 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -150,6 +150,12 @@ Versioning: two-part `MAJOR.MINOR` — each release bumps the minor (features an mutiert, um unter Windows das Neuaufbauen der Medienkachel zu vermeiden. Über MPRIS kam davon nichts an: Plasma-Widgets zeigten dauerhaft den zuerst gespielten Titel. Bei echtem Titelwechsel wird jetzt ein neues `MediaMetadata` zugewiesen, sonst weiter in-place (Cover-Nachladen). +- **Android 1.3 (versionCode 6): keine Adressen mehr eintippen** — Navidrome-, Backend- und + Scrobble-Adresse kommen als Vorgabe aus dem Build (`-PnovasonicNavidrome=` / `-PnovasonicBackend=` + / `-PnovasonicScrobble=`, gepflegt in `scripts/.env.release`). Sie greifen, wenn im Gerätespeicher + nichts steht; die Felder in den Einstellungen bleiben sichtbar und überschreibbar, damit ein Umzug + am Gerät korrigierbar ist statt per neuem APK. Beim ersten Start ist nur noch **Benutzer und + Passwort** einzugeben — Zugangsdaten werden bewusst *nicht* eingebacken, die gehören pro Person. - **Android 1.2 (versionCode 5)** — die Web-Adresse ist keine Einstellung mehr, sondern kommt aus `BuildConfig.SHARE_HOST`, also aus **derselben** Angabe (`-PnovasonicHost=…`), die ohnehin für die App-Links ins Manifest wandert. Damit gibt es keine vierte Adresse zu pflegen, „Teilen" ist immer diff --git a/android/app/build.gradle.kts b/android/app/build.gradle.kts index 150d765..2ad268f 100644 --- a/android/app/build.gradle.kts +++ b/android/app/build.gradle.kts @@ -14,8 +14,8 @@ android { applicationId = "com.novasonic.app" minSdk = 26 targetSdk = 35 - versionCode = 5 - versionName = "1.2" + versionCode = 6 + versionName = "1.3" // Host der eigenen NovaSonic-Web-App — Ziel der geteilten Links. Einmal in // gradle.properties setzen (novasonicHost=music.example.com); ohne Angabe bleibt der // Platzhalter stehen und der App-Link greift schlicht nicht. @@ -37,10 +37,12 @@ android { // docker-compose.yml — sie zusaetzlich auf jedem Geraet einzutippen ist Arbeit ohne Nutzen. // Leer gelassen verhaelt sich die App wie bisher (Felder sichtbar, nichts vorbelegt). // Zugangsdaten bleiben bewusst aussen vor: die gehoeren pro Person, nicht ins APK. - val backendUrl = (project.findProperty("novasonicBackend") as String?) ?: "" - val scrobbleUrl = (project.findProperty("novasonicScrobble") as String?) ?: "" + val backendUrl = (project.findProperty("novasonicBackend") as String?) ?: "" + val scrobbleUrl = (project.findProperty("novasonicScrobble") as String?) ?: "" + val navidromeUrl= (project.findProperty("novasonicNavidrome") as String?) ?: "" buildConfigField("String", "DEFAULT_BACKEND_URL", "\"$backendUrl\"") buildConfigField("String", "DEFAULT_SCROBBLE_URL", "\"$scrobbleUrl\"") + buildConfigField("String", "DEFAULT_ND_URL", "\"$navidromeUrl\"") } buildFeatures { diff --git a/android/app/src/main/kotlin/com/novasonic/app/data/PrefsStore.kt b/android/app/src/main/kotlin/com/novasonic/app/data/PrefsStore.kt index 49d94ba..4fd5d91 100644 --- a/android/app/src/main/kotlin/com/novasonic/app/data/PrefsStore.kt +++ b/android/app/src/main/kotlin/com/novasonic/app/data/PrefsStore.kt @@ -59,7 +59,9 @@ class PrefsStore(private val context: Context) { val credentials: Flow = context.dataStore.data.map { prefs -> Credentials( - serverUrl = prefs[KEY_SERVER] ?: "", + // Adresse vorbelegt, Zugangsdaten bewusst nicht — die gehoeren pro Person. + serverUrl = prefs[KEY_SERVER]?.ifBlank { null } + ?: com.novasonic.app.BuildConfig.DEFAULT_ND_URL, username = prefs[KEY_USERNAME] ?: "", password = prefs[KEY_PASSWORD] ?: "", ) @@ -67,7 +69,8 @@ class PrefsStore(private val context: Context) { val appSettings: Flow = context.dataStore.data.map { prefs -> AppSettings( - serverUrl = prefs[KEY_SERVER] ?: "", + serverUrl = prefs[KEY_SERVER]?.ifBlank { null } + ?: com.novasonic.app.BuildConfig.DEFAULT_ND_URL, username = prefs[KEY_USERNAME] ?: "", password = prefs[KEY_PASSWORD] ?: "", lastFmKey = prefs[KEY_LASTFM_KEY] ?: "", diff --git a/android/app/src/main/kotlin/com/novasonic/app/ui/screen/LoginScreen.kt b/android/app/src/main/kotlin/com/novasonic/app/ui/screen/LoginScreen.kt index f536b25..d0cb5bd 100644 --- a/android/app/src/main/kotlin/com/novasonic/app/ui/screen/LoginScreen.kt +++ b/android/app/src/main/kotlin/com/novasonic/app/ui/screen/LoginScreen.kt @@ -24,7 +24,8 @@ fun LoginScreen(onLoggedIn: () -> Unit) { val vm: LoginViewModel = viewModel() val state by vm.state.collectAsStateWithLifecycle() - var serverUrl by remember { mutableStateOf("") } + // Serveradresse vorbelegen, falls im Build hinterlegt — dann bleiben nur Benutzer und Passwort. + var serverUrl by remember { mutableStateOf(com.novasonic.app.BuildConfig.DEFAULT_ND_URL) } var username by remember { mutableStateOf("") } var password by remember { mutableStateOf("") } var showPw by remember { mutableStateOf(false) } diff --git a/scripts/publish-apk.mjs b/scripts/publish-apk.mjs index 6cc23fe..ebe5281 100644 --- a/scripts/publish-apk.mjs +++ b/scripts/publish-apk.mjs @@ -43,6 +43,11 @@ const TASK = process.env.APK_GRADLE_TASK || 'assembleDebug'; // Domainwechsel (beide Adressen oeffnen dann in der App), siehe docs/share-links.md. const HOST = process.env.NOVASONIC_HOST || ''; const HOST2 = process.env.NOVASONIC_HOST2 || ''; +// Vorgabe-Adressen, die ins APK gebacken werden, damit auf einem frischen Geraet nur noch Benutzer +// und Passwort einzutippen sind. Zugangsdaten kommen hier bewusst NICHT vor. +const ND_URL = process.env.NOVASONIC_NAVIDROME || ''; +const BACKEND_URL = process.env.NOVASONIC_BACKEND || ''; +const SCROBBLE_URL= process.env.NOVASONIC_SCROBBLE || ''; function die(msg) { console.error(`\n✖ ${msg}`); process.exit(1); } if (!GITEA_URL || !GITEA_REPO || !GITEA_TOKEN) @@ -82,6 +87,9 @@ if (!HOST) { const gradleArgs = [`:app:${TASK}`]; if (HOST) gradleArgs.push(`-PnovasonicHost=${HOST}`); if (HOST2) gradleArgs.push(`-PnovasonicHost2=${HOST2}`); +if (ND_URL) gradleArgs.push(`-PnovasonicNavidrome=${ND_URL}`); +if (BACKEND_URL) gradleArgs.push(`-PnovasonicBackend=${BACKEND_URL}`); +if (SCROBBLE_URL) gradleArgs.push(`-PnovasonicScrobble=${SCROBBLE_URL}`); const build = spawnSync(gradlew, gradleArgs, { cwd: join(root, 'android'), stdio: 'inherit', shell: isWin, });