diff --git a/android/app/src/main/kotlin/com/novasonic/app/player/PlayerController.kt b/android/app/src/main/kotlin/com/novasonic/app/player/PlayerController.kt index a333f39..6f1e5af 100644 --- a/android/app/src/main/kotlin/com/novasonic/app/player/PlayerController.kt +++ b/android/app/src/main/kotlin/com/novasonic/app/player/PlayerController.kt @@ -315,7 +315,11 @@ class PlayerController(private val context: Context, private val repo: MusicRepo val mediaId = ctrl.currentMediaItem?.mediaId ?: return if (mediaId.startsWith("abs:")) return val song = queue.getOrNull(ctrl.currentMediaItemIndex) ?: return - val dur = ctrl.duration.coerceAtLeast(0) + // Use the song's KNOWN duration — at a media transition ctrl.duration is still + // TIME_UNSET (→0), which collapsed the 1/3 / 2/3 modes to the 15s floor and scrobbled + // far too early. Fall back to the player only if the song has no duration. + val songDurMs = (song.duration?.toLong() ?: 0L) * 1000L + val dur = if (songDurMs > 0) songDurMs else ctrl.duration.coerceAtLeast(0) scheduleScrobble(song, dur) scope.launch { runCatching { repo.saveLastSong(song) } } prefetchLyrics(song) diff --git a/android/app/src/main/kotlin/com/novasonic/app/ui/screen/SettingsScreen.kt b/android/app/src/main/kotlin/com/novasonic/app/ui/screen/SettingsScreen.kt index ff1babf..ebe444d 100644 --- a/android/app/src/main/kotlin/com/novasonic/app/ui/screen/SettingsScreen.kt +++ b/android/app/src/main/kotlin/com/novasonic/app/ui/screen/SettingsScreen.kt @@ -67,6 +67,15 @@ fun SettingsScreen(onOpenStats: () -> Unit = {}) { ) } + // Wait for the persisted settings before drawing the form — otherwise the default state + // (e.g. theme = Dark Ocean) flashes for a frame and then jumps to the real values. + if (!state.loaded) { + Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) { + CircularProgressIndicator(color = NsAccent) + } + return + } + Column( verticalArrangement = Arrangement.spacedBy(12.dp), modifier = Modifier diff --git a/android/app/src/main/kotlin/com/novasonic/app/viewmodel/SettingsViewModel.kt b/android/app/src/main/kotlin/com/novasonic/app/viewmodel/SettingsViewModel.kt index 8d31278..d0df2a8 100644 --- a/android/app/src/main/kotlin/com/novasonic/app/viewmodel/SettingsViewModel.kt +++ b/android/app/src/main/kotlin/com/novasonic/app/viewmodel/SettingsViewModel.kt @@ -35,6 +35,7 @@ data class SettingsUiState( val absUrl: String = "", val absApiKey: String = "", val absChapterTrackMode: Boolean = false, + val loaded: Boolean = false, val isSaving: Boolean = false, val savedOk: Boolean = false, val error: String? = null, @@ -66,6 +67,7 @@ class SettingsViewModel(app: Application) : AndroidViewModel(app) { absUrl = s.absUrl, absApiKey = s.absApiKey, absChapterTrackMode = s.absChapterTrackMode, + loaded = true, ) } }