From 76c1fe1d753a282de5770406cacb3013b7ff880f Mon Sep 17 00:00:00 2001 From: OxygenCobalt Date: Fri, 27 Nov 2020 20:11:24 -0700 Subject: [PATCH] Add library sort mode preference Save the library sort mode to a SharedPreferences object, soon to be extended with other prefs. --- .../java/org/oxycblt/auxio/MainActivity.kt | 5 +- .../oxycblt/auxio/library/LibraryViewModel.kt | 21 ++++++ .../playback/state/PlaybackStateManager.kt | 1 + .../org/oxycblt/auxio/prefs/PrefsManager.kt | 71 +++++++++++++++++++ .../oxycblt/auxio/recycler/NoLeakThumbView.kt | 8 +-- .../org/oxycblt/auxio/recycler/SortMode.kt | 30 ++++++++ 6 files changed, 128 insertions(+), 8 deletions(-) create mode 100644 app/src/main/java/org/oxycblt/auxio/prefs/PrefsManager.kt diff --git a/app/src/main/java/org/oxycblt/auxio/MainActivity.kt b/app/src/main/java/org/oxycblt/auxio/MainActivity.kt index 7d56901bb..a64680cdb 100644 --- a/app/src/main/java/org/oxycblt/auxio/MainActivity.kt +++ b/app/src/main/java/org/oxycblt/auxio/MainActivity.kt @@ -5,8 +5,8 @@ import android.content.Intent import android.util.AttributeSet import android.view.View import androidx.appcompat.app.AppCompatActivity -import androidx.appcompat.app.AppCompatDelegate import org.oxycblt.auxio.playback.PlaybackService +import org.oxycblt.auxio.prefs.PrefsManager import org.oxycblt.auxio.ui.accent // FIXME: Fix bug where fast navigation will break the animations and @@ -16,7 +16,8 @@ import org.oxycblt.auxio.ui.accent class MainActivity : AppCompatActivity(R.layout.activity_main) { override fun onCreateView(name: String, context: Context, attrs: AttributeSet): View? { - AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES) + val prefsManager = PrefsManager.init(this) + // Apply the theme setTheme(accent.second) diff --git a/app/src/main/java/org/oxycblt/auxio/library/LibraryViewModel.kt b/app/src/main/java/org/oxycblt/auxio/library/LibraryViewModel.kt index 040053928..4ad22735f 100644 --- a/app/src/main/java/org/oxycblt/auxio/library/LibraryViewModel.kt +++ b/app/src/main/java/org/oxycblt/auxio/library/LibraryViewModel.kt @@ -6,11 +6,14 @@ import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope +import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext import org.oxycblt.auxio.R import org.oxycblt.auxio.music.BaseModel import org.oxycblt.auxio.music.Header import org.oxycblt.auxio.music.MusicStore +import org.oxycblt.auxio.prefs.PrefsManager import org.oxycblt.auxio.recycler.ShowMode import org.oxycblt.auxio.recycler.SortMode @@ -36,6 +39,16 @@ class LibraryViewModel : ViewModel() { private var mSearchHasFocus = false val searchHasFocus: Boolean get() = mSearchHasFocus + init { + val prefsManager = PrefsManager.getInstance() + + viewModelScope.launch { + mSortMode.value = withContext(Dispatchers.IO) { + prefsManager.getLibrarySortMode() + } + } + } + /** * Perform a search of the music library, given a query. * Results are pushed to [searchResults]. @@ -119,6 +132,14 @@ class LibraryViewModel : ViewModel() { if (mode != mSortMode.value) { mSortMode.value = mode + + viewModelScope.launch { + withContext(Dispatchers.IO) { + val prefsManager = PrefsManager.getInstance() + + prefsManager.setLibrarySortMode(mSortMode.value!!) + } + } } } } 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 f26be2b8a..6137de9d9 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 @@ -271,6 +271,7 @@ class PlaybackStateManager private constructor() { /** * Go to the previous song, doing any checks that are needed. + * TODO: Implement option to rewind before skipping back */ fun prev() { if (mIndex > 0 && !mIsInUserQueue) { diff --git a/app/src/main/java/org/oxycblt/auxio/prefs/PrefsManager.kt b/app/src/main/java/org/oxycblt/auxio/prefs/PrefsManager.kt new file mode 100644 index 000000000..dd169cc5c --- /dev/null +++ b/app/src/main/java/org/oxycblt/auxio/prefs/PrefsManager.kt @@ -0,0 +1,71 @@ +package org.oxycblt.auxio.prefs + +import android.content.Context +import android.content.SharedPreferences +import org.oxycblt.auxio.recycler.SortMode + +/** + * Wrapper around the [SharedPreferences] class that writes & reads values. + * Please run any getter/setter in a coroutine. Its not required, but it prevents slowdowns + * on older devices. + * @author OxygenCobalt + */ +class PrefsManager private constructor(context: Context) { + private val sharedPrefs = context.getSharedPreferences( + "auxio_prefs", Context.MODE_PRIVATE + ) + + private lateinit var mLibrarySortMode: SortMode + + fun setLibrarySortMode(sortMode: SortMode) { + mLibrarySortMode = sortMode + + sharedPrefs.edit() + .putInt(Keys.KEY_LIBRARY_SORT_MODE, sortMode.toConstant()) + .apply() + } + + fun getLibrarySortMode(): SortMode { + if (!::mLibrarySortMode.isInitialized) { + mLibrarySortMode = SortMode.fromConstant( + sharedPrefs.getInt( + Keys.KEY_LIBRARY_SORT_MODE, + SortMode.CONSTANT_ALPHA_DOWN + ) + ) ?: SortMode.ALPHA_DOWN + } + + return mLibrarySortMode + } + + companion object { + @Volatile + private lateinit var INSTANCE: PrefsManager + + /** + * Init the single instance of [PrefsManager]. Done so that every object + * can have access to it regardless of if it has a context. + */ + fun init(context: Context): PrefsManager { + synchronized(this) { + INSTANCE = PrefsManager(context) + + return getInstance() + } + } + + /** + * Get the single instance of [PrefsManager]. + */ + fun getInstance(): PrefsManager { + check(::INSTANCE.isInitialized) { + "PrefsManager must be initialized with init() before getting its instance." + } + return INSTANCE + } + } + + object Keys { + const val KEY_LIBRARY_SORT_MODE = "KEY_LIBRARY_SORT_MODE" + } +} diff --git a/app/src/main/java/org/oxycblt/auxio/recycler/NoLeakThumbView.kt b/app/src/main/java/org/oxycblt/auxio/recycler/NoLeakThumbView.kt index d14e7fdff..7922a49af 100644 --- a/app/src/main/java/org/oxycblt/auxio/recycler/NoLeakThumbView.kt +++ b/app/src/main/java/org/oxycblt/auxio/recycler/NoLeakThumbView.kt @@ -36,11 +36,7 @@ class NoLeakThumbView @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = R.attr.indicatorFastScrollerThumbStyle -) : ConstraintLayout( - context, - attrs, - defStyleAttr -), +) : ConstraintLayout(context, attrs, defStyleAttr), FastScrollerView.ItemIndicatorSelectedCallback { private var thumbColor = ColorStateList.valueOf(accent.first.toColor(context)) @@ -98,7 +94,7 @@ class NoLeakThumbView @JvmOverloads constructor( /** * Hack so that I can detect when the pointer is off the FastScrollerView's items - * without using onItemIndicatorTouched [Which is internal] + * without using onItemIndicatorTouched (Which is internal) * @author OxygenCobalt */ private fun isPointerOnItem(fastScrollerView: FastScrollerView, touchY: Int): Boolean { diff --git a/app/src/main/java/org/oxycblt/auxio/recycler/SortMode.kt b/app/src/main/java/org/oxycblt/auxio/recycler/SortMode.kt index cb2ee298b..3a0cf92d9 100644 --- a/app/src/main/java/org/oxycblt/auxio/recycler/SortMode.kt +++ b/app/src/main/java/org/oxycblt/auxio/recycler/SortMode.kt @@ -94,4 +94,34 @@ enum class SortMode(val iconRes: Int) { else -> R.id.option_sort_none } } + + fun toConstant(): Int { + return when (this) { + NONE -> CONSTANT_NONE + ALPHA_UP -> CONSTANT_ALPHA_UP + ALPHA_DOWN -> CONSTANT_ALPHA_DOWN + NUMERIC_UP -> CONSTANT_NUMERIC_UP + NUMERIC_DOWN -> CONSTANT_NUMERIC_DOWN + } + } + + companion object { + const val CONSTANT_NONE = 0xA060 + const val CONSTANT_ALPHA_UP = 0xA061 + const val CONSTANT_ALPHA_DOWN = 0xA062 + const val CONSTANT_NUMERIC_UP = 0xA063 + const val CONSTANT_NUMERIC_DOWN = 0xA065 + + fun fromConstant(constant: Int): SortMode? { + return when (constant) { + CONSTANT_NONE -> NONE + CONSTANT_ALPHA_UP -> ALPHA_UP + CONSTANT_ALPHA_DOWN -> ALPHA_DOWN + CONSTANT_NUMERIC_UP -> NUMERIC_UP + CONSTANT_NUMERIC_DOWN -> NUMERIC_DOWN + + else -> null + } + } + } }