refactor(web+android): nur Warteschlange und Titel sichern, keine Sekunden
Das Mitschreiben der Abspielposition war zu viel des Guten: es bedeutete staendiges Schreiben waehrend der Wiedergabe fuer einen Gewinn, den man kaum bemerkt. Gesichert werden jetzt nur Warteschlange und aktueller Titel, der dann von vorn beginnt. Der eigentliche Gewinn bleibt und war der Ausloeser: unter Android war die Now-Playing-Leiste nach dem Oeffnen leer, bis man einmal auf Play drueckte — gesichert war nur der letzte Song, nicht die Warteschlange. Das Wiederherstellen fuellt den Zustand jetzt ueber syncState(), also ohne Abspielen. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
65fa950043
commit
a2211a62d2
6 files changed
+25
-67
No files matched your search
@@ -169,8 +169,7 @@ class MusicRepository(private val context: Context) {
|
||||
|
||||
suspend fun saveTheme(themeId: String) = prefs.saveTheme(themeId)
|
||||
|
||||
suspend fun saveQueueState(ids: List<String>, index: Int, positionMs: Long) =
|
||||
prefs.saveQueueState(ids, index, positionMs)
|
||||
suspend fun saveQueueState(ids: List<String>, index: Int) = prefs.saveQueueState(ids, index)
|
||||
suspend fun readQueueState() = prefs.readQueueState()
|
||||
suspend fun saveLastSong(song: com.novasonic.app.api.model.Song) =
|
||||
prefs.saveLastSong(song.id, song.title, song.artist ?: "", song.coverArt)
|
||||
|
||||
@@ -4,7 +4,6 @@ import android.content.Context
|
||||
import androidx.datastore.preferences.core.booleanPreferencesKey
|
||||
import androidx.datastore.preferences.core.edit
|
||||
import androidx.datastore.preferences.core.intPreferencesKey
|
||||
import androidx.datastore.preferences.core.longPreferencesKey
|
||||
import androidx.datastore.preferences.core.stringPreferencesKey
|
||||
import androidx.datastore.preferences.preferencesDataStore
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
@@ -32,10 +31,11 @@ class PrefsStore(private val context: Context) {
|
||||
val KEY_LAST_SONG_TITLE = stringPreferencesKey("last_song_title")
|
||||
val KEY_LAST_SONG_ARTIST = stringPreferencesKey("last_song_artist")
|
||||
val KEY_LAST_SONG_COVER = stringPreferencesKey("last_song_cover")
|
||||
// Warteschlange fortsetzen: Song-Ids, Position in der Liste und Position im Titel.
|
||||
// Warteschlange fortsetzen: Song-Ids und Position in der Liste. Bewusst OHNE Sekunde im
|
||||
// Titel — der zuletzt gehoerte Titel beginnt von vorn, das genuegt und spart staendiges
|
||||
// Schreiben waehrend der Wiedergabe.
|
||||
val KEY_QUEUE_IDS = stringPreferencesKey("queue_ids")
|
||||
val KEY_QUEUE_INDEX = intPreferencesKey("queue_index")
|
||||
val KEY_QUEUE_POSITION = longPreferencesKey("queue_position_ms")
|
||||
}
|
||||
|
||||
data class Credentials(val serverUrl: String, val username: String, val password: String) {
|
||||
@@ -148,15 +148,14 @@ class PrefsStore(private val context: Context) {
|
||||
* Sichert die Warteschlange als Id-Liste samt Position. Nur Ids, keine vollstaendigen Songs:
|
||||
* Titel und Cover koennen sich aendern (Metadaten-Bearbeitung), die Id ist der stabile Bezug.
|
||||
*/
|
||||
suspend fun saveQueueState(ids: List<String>, index: Int, positionMs: Long) {
|
||||
suspend fun saveQueueState(ids: List<String>, index: Int) {
|
||||
context.dataStore.edit { prefs ->
|
||||
prefs[KEY_QUEUE_IDS] = ids.joinToString(",")
|
||||
prefs[KEY_QUEUE_INDEX] = index.coerceAtLeast(0)
|
||||
prefs[KEY_QUEUE_POSITION] = positionMs.coerceAtLeast(0)
|
||||
prefs[KEY_QUEUE_IDS] = ids.joinToString(",")
|
||||
prefs[KEY_QUEUE_INDEX] = index.coerceAtLeast(0)
|
||||
}
|
||||
}
|
||||
|
||||
data class QueueState(val ids: List<String>, val index: Int, val positionMs: Long)
|
||||
data class QueueState(val ids: List<String>, val index: Int)
|
||||
|
||||
suspend fun readQueueState(): QueueState? {
|
||||
val prefs = context.dataStore.data.first()
|
||||
@@ -164,8 +163,7 @@ class PrefsStore(private val context: Context) {
|
||||
if (ids.isEmpty()) return null
|
||||
return QueueState(
|
||||
ids = ids,
|
||||
index = (prefs[KEY_QUEUE_INDEX] ?: 0).coerceIn(0, ids.lastIndex),
|
||||
positionMs = prefs[KEY_QUEUE_POSITION] ?: 0L,
|
||||
index = (prefs[KEY_QUEUE_INDEX] ?: 0).coerceIn(0, ids.lastIndex),
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -62,16 +62,16 @@ class PlayerController(private val context: Context, private val repo: MusicRepo
|
||||
}
|
||||
|
||||
/**
|
||||
* Haelt Warteschlange, Listenposition und Position im Titel fest. ABS-Hoerbuecher bleiben aussen
|
||||
* vor — die haben ihren eigenen Fortschritt auf dem Server.
|
||||
* Haelt Warteschlange und Listenposition fest — ohne die Sekunde im Titel: der zuletzt gehoerte
|
||||
* Titel beginnt von vorn. ABS-Hoerbuecher bleiben aussen vor, die haben ihren eigenen
|
||||
* Fortschritt auf dem Server.
|
||||
*/
|
||||
private fun persistQueueState() {
|
||||
val ctrl = controller ?: return
|
||||
val ids = queue.map { it.id }
|
||||
if (ids.isEmpty() || ids.any { it.startsWith("abs:") }) return
|
||||
val index = ctrl.currentMediaItemIndex
|
||||
val pos = ctrl.currentPosition
|
||||
scope.launch { runCatching { repo.saveQueueState(ids, index, pos) } }
|
||||
scope.launch { runCatching { repo.saveQueueState(ids, index) } }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -89,7 +89,7 @@ class PlayerController(private val context: Context, private val repo: MusicRepo
|
||||
if (songs.isEmpty()) return@launch
|
||||
val index = zustand.index.coerceIn(0, songs.lastIndex)
|
||||
queue = songs
|
||||
ctrl.setMediaItems(songs.map { it.toMediaItem(repo) }, index, zustand.positionMs)
|
||||
ctrl.setMediaItems(songs.map { it.toMediaItem(repo) }, index, 0L)
|
||||
ctrl.prepare()
|
||||
syncState()
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user