From 6381815fd9bc457fb1d81d609ea855f8d275d2c8 Mon Sep 17 00:00:00 2001 From: OxygenCobalt Date: Mon, 25 Jul 2022 09:53:13 -0600 Subject: [PATCH] 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. --- .../java/org/oxycblt/auxio/detail/SongDetailDialog.kt | 5 +++++ .../java/org/oxycblt/auxio/playback/PlaybackViewModel.kt | 8 ++++++++ .../oxycblt/auxio/playback/state/PlaybackStateDatabase.kt | 8 +++----- .../oxycblt/auxio/playback/state/PlaybackStateManager.kt | 7 +++++-- .../org/oxycblt/auxio/settings/SettingsListFragment.kt | 5 +++-- app/src/main/res/values/settings.xml | 1 + app/src/main/res/values/strings.xml | 4 ++++ app/src/main/res/xml/prefs_main.xml | 5 +++++ info/FAQ.md | 3 ++- 9 files changed, 36 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/org/oxycblt/auxio/detail/SongDetailDialog.kt b/app/src/main/java/org/oxycblt/auxio/detail/SongDetailDialog.kt index 1a787b85d..1e949366d 100644 --- a/app/src/main/java/org/oxycblt/auxio/detail/SongDetailDialog.kt +++ b/app/src/main/java/org/oxycblt/auxio/detail/SongDetailDialog.kt @@ -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() { private val detailModel: DetailViewModel by androidActivityViewModels() private val args: SongDetailDialogArgs by navArgs() diff --git a/app/src/main/java/org/oxycblt/auxio/playback/PlaybackViewModel.kt b/app/src/main/java/org/oxycblt/auxio/playback/PlaybackViewModel.kt index b66400016..d96e3012b 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/PlaybackViewModel.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/PlaybackViewModel.kt @@ -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 diff --git a/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackStateDatabase.kt b/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackStateDatabase.kt index 4df354b76..abd1f1504 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackStateDatabase.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackStateDatabase.kt @@ -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) { diff --git a/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackStateManager.kt b/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackStateManager.kt index 1ba47ed3a..fc4c363cc 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackStateManager.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackStateManager.kt @@ -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) { diff --git a/app/src/main/java/org/oxycblt/auxio/settings/SettingsListFragment.kt b/app/src/main/java/org/oxycblt/auxio/settings/SettingsListFragment.kt index 51e09a115..87b3a2e60 100644 --- a/app/src/main/java/org/oxycblt/auxio/settings/SettingsListFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/settings/SettingsListFragment.kt @@ -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) { diff --git a/app/src/main/res/values/settings.xml b/app/src/main/res/values/settings.xml index 398f577a3..16e55339b 100644 --- a/app/src/main/res/values/settings.xml +++ b/app/src/main/res/values/settings.xml @@ -24,6 +24,7 @@ KEY_LOOP_PAUSE auxio_save_state + auxio_wipe_state auxio_restore_state auxio_reindex auxio_music_dirs diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 793dd025a..350240898 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -102,6 +102,8 @@ State saved + State cleared + State restored @@ -181,6 +183,8 @@ Content Save playback state Save the current playback state now + Clear playback state + Wipe the previously saved playback state (if any) Restore playback state Restore the previously saved playback state (if any) Reload music diff --git a/app/src/main/res/xml/prefs_main.xml b/app/src/main/res/xml/prefs_main.xml index 418e000e7..be075ef11 100644 --- a/app/src/main/res/xml/prefs_main.xml +++ b/app/src/main/res/xml/prefs_main.xml @@ -128,6 +128,11 @@ app:summary="@string/set_save_desc" app:title="@string/set_save" /> + +