settings: add option to clear state

Add an option to clear the currently saved playback state.

This does not clear playback entirely, but rather remove the saved
state so that it's not restored on the next startup. This is generally
the cleanest solution compared to allowing state restore to be toggled,
which opens up a bunch of race conditions.

Resolves #107.
This commit is contained in:
OxygenCobalt 2022-07-25 09:53:13 -06:00
parent 86a1815b1f
commit 6381815fd9
No known key found for this signature in database
GPG key ID: 37DBE3621FE9AD47
9 changed files with 36 additions and 10 deletions

View file

@ -31,6 +31,11 @@ import org.oxycblt.auxio.util.androidActivityViewModels
import org.oxycblt.auxio.util.collectImmediately
import org.oxycblt.auxio.util.formatDuration
/**
* A dialog displayed when "View properties" is selected on a song, showing more information about
* the properties of the audio file itself.
* @author OxygenCobalt
*/
class SongDetailDialog : ViewBindingDialogFragment<DialogSongDetailBinding>() {
private val detailModel: DetailViewModel by androidActivityViewModels()
private val args: SongDetailDialogArgs by navArgs()

View file

@ -282,6 +282,14 @@ class PlaybackViewModel(application: Application) :
}
}
/** Wipe the saved playback state (if any). */
fun wipePlaybackState(onDone: () -> Unit) {
viewModelScope.launch {
playbackManager.wipeState(PlaybackStateDatabase.getInstance(application))
onDone()
}
}
/**
* Force restore the last [PlaybackStateManager] saved state, regardless of if a library exists
* or not. [onDone] will be called with true if it was successfully done, or false if there was

View file

@ -186,19 +186,17 @@ class PlaybackStateDatabase private constructor(context: Context) :
}
/** Clear the previously written [SavedState] and write a new one. */
fun write(state: SavedState) {
fun write(state: SavedState?) {
requireBackgroundThread()
val song = state.queue.getOrNull(state.index)
if (song != null) {
if (state != null && state.index in state.queue.indices) {
val rawState =
RawState(
index = state.index,
positionMs = state.positionMs,
repeatMode = state.repeatMode,
isShuffled = state.isShuffled,
songId = song.id,
songId = state.queue[state.index].id,
parentId = state.parent?.id,
playbackMode =
when (state.parent) {

View file

@ -388,12 +388,15 @@ class PlaybackStateManager private constructor() {
/** Save the current state to the [database]. */
suspend fun saveState(database: PlaybackStateDatabase) {
logD("Saving state to DB")
val state = synchronized(this) { makeStateImpl() }
withContext(Dispatchers.IO) { database.write(state) }
}
suspend fun wipeState(database: PlaybackStateDatabase) {
logD("Wiping state")
withContext(Dispatchers.IO) { database.write(null) }
}
/** Sanitize the state with [newLibrary]. */
@Synchronized
fun sanitize(newLibrary: MusicStore.Library) {

View file

@ -49,8 +49,6 @@ import org.oxycblt.auxio.util.systemBarInsetsCompat
/**
* The actual fragment containing the settings menu. Inherits [PreferenceFragmentCompat].
* @author OxygenCobalt
*
* TODO: Add option to not restore state
*/
@Suppress("UNUSED")
class SettingsListFragment : PreferenceFragmentCompat() {
@ -120,6 +118,9 @@ class SettingsListFragment : PreferenceFragmentCompat() {
getString(R.string.set_key_save_state) -> {
playbackModel.savePlaybackState { context?.showToast(R.string.lbl_state_saved) }
}
getString(R.string.set_key_wipe_state) -> {
playbackModel.wipePlaybackState { context?.showToast(R.string.lbl_state_wiped) }
}
getString(R.string.set_key_restore_state) ->
playbackModel.tryRestorePlaybackState { restored ->
if (restored) {

View file

@ -24,6 +24,7 @@
<string name="set_key_repeat_pause" translatable="false">KEY_LOOP_PAUSE</string>
<string name="set_key_save_state" translatable="false">auxio_save_state</string>
<string name="set_key_wipe_state" translatable="false">auxio_wipe_state</string>
<string name="set_key_restore_state" translatable="false">auxio_restore_state</string>
<string name="set_key_reindex" translatable="false">auxio_reindex</string>
<string name="set_key_music_dirs" translatable="false">auxio_music_dirs</string>

View file

@ -102,6 +102,8 @@
<!-- Referring to playback state -->
<string name="lbl_state_saved">State saved</string>
<!-- Referring to playback state -->
<string name="lbl_state_wiped">State cleared</string>
<!-- Referring to playback state -->
<string name="lbl_state_restored">State restored</string>
<!-- Limit to 10 characters -->
@ -181,6 +183,8 @@
<string name="set_content">Content</string>
<string name="set_save">Save playback state</string>
<string name="set_save_desc">Save the current playback state now</string>
<string name="set_wipe">Clear playback state</string>
<string name="set_wipe_desc">Wipe the previously saved playback state (if any)</string>
<string name="set_restore">Restore playback state</string>
<string name="set_restore_desc">Restore the previously saved playback state (if any)</string>
<string name="set_reindex">Reload music</string>

View file

@ -128,6 +128,11 @@
app:summary="@string/set_save_desc"
app:title="@string/set_save" />
<Preference
app:key="@string/set_key_wipe_state"
app:title="@string/set_wipe"
app:summary="@string/set_wipe_desc" />
<Preference
app:key="@string/set_key_restore_state"
app:summary="@string/set_restore_desc"

View file

@ -51,7 +51,8 @@ a regression introduced by Google in that version. If this issue appears in anot
**There should be one artist, but instead I get a bunch of "Artist & Collaborator" artists:** This likely means your tags are wrong. By default, Auxio will use the
"album artist" tag for grouping if present, falling back to the "artist" tag otherwise. If your music does not have such a field, it will result in fragmented artists.
The reason why Auxio does not simply parse for separators and then extract artists that way is that it risks mangling artists that don't actually have collaborators,
such as "Black Country, New Road" becoming "Black Country".
such as "Black Country, New Road" becoming "Black Country". I understand that some users may leverage MusicBrainz tags that enable a song to be referenced by several
artists, but such functionality in Auxio will likely take awhile to implement to to UI and technical constraints.
**Auxio does not detect new music:** This is Auxio's default behavior due to limitations regarding android's filesystem APIs. To enable such behavior, turn on
"Automatic reloading" in settings. Note that this option does require a persistent notification and higher battery usage.