settings: improve preference management
Rework the preference classes to reduce the horrible bloat of the recursivelyHandlePreference function. This was mostly implementing new methods into IntListPreference and adding a new preference to represent the weird, "generic" dialogs that are used at points. While some preferences still need to be tweaked in recursivelyHandlePreference, it is nowhere near as bad as it was prior.
This commit is contained in:
parent
532a30325a
commit
bd92ba2175
13 changed files with 204 additions and 133 deletions
|
@ -9,6 +9,8 @@
|
|||
- Fixed broken tablet layouts
|
||||
- Fixed seam that would appear on some album covers
|
||||
- Fixed visual issue with the queue opening animation
|
||||
- Fixed crash if settings was navigated away before playback state
|
||||
finished saving
|
||||
|
||||
#### Dev/Meta
|
||||
- Migrated preferences from shared object to utility
|
||||
|
|
|
@ -21,6 +21,7 @@ import android.app.Application
|
|||
import androidx.lifecycle.AndroidViewModel
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import org.oxycblt.auxio.R
|
||||
import org.oxycblt.auxio.home.tabs.Tab
|
||||
import org.oxycblt.auxio.music.Album
|
||||
import org.oxycblt.auxio.music.Artist
|
||||
|
@ -145,9 +146,11 @@ class HomeViewModel(application: Application) :
|
|||
}
|
||||
}
|
||||
|
||||
override fun onLibrarySettingsChanged() {
|
||||
tabs = visibleTabs
|
||||
_shouldRecreateTabs.value = true
|
||||
override fun onSettingChanged(key: String) {
|
||||
if (key == application.getString(R.string.set_lib_tabs)) {
|
||||
tabs = visibleTabs
|
||||
_shouldRecreateTabs.value = true
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCleared() {
|
||||
|
|
|
@ -26,6 +26,7 @@ import android.support.v4.media.session.MediaSessionCompat
|
|||
import android.support.v4.media.session.PlaybackStateCompat
|
||||
import androidx.media.session.MediaButtonReceiver
|
||||
import com.google.android.exoplayer2.Player
|
||||
import org.oxycblt.auxio.R
|
||||
import org.oxycblt.auxio.image.BitmapProvider
|
||||
import org.oxycblt.auxio.music.MusicParent
|
||||
import org.oxycblt.auxio.music.Song
|
||||
|
@ -163,8 +164,11 @@ class MediaSessionComponent(private val context: Context, private val player: Pl
|
|||
|
||||
// --- SETTINGSMANAGER CALLBACKS ---
|
||||
|
||||
override fun onCoverSettingsChanged() {
|
||||
updateMediaMetadata(playbackManager.song)
|
||||
override fun onSettingChanged(key: String) {
|
||||
if (key == context.getString(R.string.set_key_show_covers) ||
|
||||
key == context.getString(R.string.set_key_show_covers)) {
|
||||
updateMediaMetadata(playbackManager.song)
|
||||
}
|
||||
}
|
||||
|
||||
// --- EXOPLAYER CALLBACKS ---
|
||||
|
|
|
@ -46,6 +46,7 @@ import kotlinx.coroutines.delay
|
|||
import kotlinx.coroutines.launch
|
||||
import org.oxycblt.auxio.BuildConfig
|
||||
import org.oxycblt.auxio.IntegerTable
|
||||
import org.oxycblt.auxio.R
|
||||
import org.oxycblt.auxio.music.Song
|
||||
import org.oxycblt.auxio.playback.replaygain.ReplayGainAudioProcessor
|
||||
import org.oxycblt.auxio.playback.state.PlaybackStateDatabase
|
||||
|
@ -289,21 +290,22 @@ class PlaybackService :
|
|||
|
||||
// --- SETTINGSMANAGER OVERRIDES ---
|
||||
|
||||
override fun onReplayGainSettingsChanged() {
|
||||
onTracksInfoChanged(player.currentTracksInfo)
|
||||
}
|
||||
|
||||
override fun onCoverSettingsChanged() {
|
||||
playbackManager.song?.let { song ->
|
||||
notificationComponent.updateMetadata(song, playbackManager.parent)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onNotifSettingsChanged() {
|
||||
if (settings.useAltNotifAction) {
|
||||
onShuffledChanged(playbackManager.isShuffled)
|
||||
} else {
|
||||
onRepeatChanged(playbackManager.repeatMode)
|
||||
override fun onSettingChanged(key: String) {
|
||||
when (key) {
|
||||
getString(R.string.set_replay_gain),
|
||||
getString(R.string.set_pre_amp_with),
|
||||
getString(R.string.set_pre_amp_without) -> onTracksInfoChanged(player.currentTracksInfo)
|
||||
getString(R.string.set_show_covers),
|
||||
getString(R.string.set_quality_covers) ->
|
||||
playbackManager.song?.let { song ->
|
||||
notificationComponent.updateMetadata(song, playbackManager.parent)
|
||||
}
|
||||
getString(R.string.set_key_alt_notif_action) ->
|
||||
if (settings.useAltNotifAction) {
|
||||
onShuffledChanged(playbackManager.isShuffled)
|
||||
} else {
|
||||
onRepeatChanged(playbackManager.repeatMode)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -42,6 +42,12 @@ import org.oxycblt.auxio.util.logD
|
|||
import org.oxycblt.auxio.util.requireAttached
|
||||
import org.oxycblt.auxio.util.unlikelyToBeNull
|
||||
|
||||
/**
|
||||
* Shortcut delegate in order to receive a [Settings] that will be created/destroyed
|
||||
* in each lifecycle.
|
||||
*
|
||||
* TODO: Replace with generalized method
|
||||
*/
|
||||
fun Fragment.settings(): ReadOnlyProperty<Fragment, Settings> =
|
||||
object : ReadOnlyProperty<Fragment, Settings>, DefaultLifecycleObserver {
|
||||
private var settings: Settings? = null
|
||||
|
@ -71,10 +77,20 @@ fun Fragment.settings(): ReadOnlyProperty<Fragment, Settings> =
|
|||
}
|
||||
|
||||
override fun onDestroy(owner: LifecycleOwner) {
|
||||
settings?.release()
|
||||
settings = null
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Auxio's settings.
|
||||
*
|
||||
* This object wraps [SharedPreferences] in a type-safe manner, allowing access to all of the
|
||||
* major settings that Auxio uses. Mutability is determined by use, as some values are written
|
||||
* by PreferenceManager and others are written by Auxio's code.
|
||||
*
|
||||
* @author OxygenCobalt
|
||||
*/
|
||||
class Settings(private val context: Context, private val callback: Callback? = null) :
|
||||
SharedPreferences.OnSharedPreferenceChangeListener {
|
||||
private val inner = PreferenceManager.getDefaultSharedPreferences(context.applicationContext)
|
||||
|
@ -90,18 +106,16 @@ class Settings(private val context: Context, private val callback: Callback? = n
|
|||
}
|
||||
|
||||
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) {
|
||||
val callback = unlikelyToBeNull(callback)
|
||||
when (key) {
|
||||
context.getString(R.string.set_key_alt_notif_action) ->
|
||||
callback.onNotifSettingsChanged()
|
||||
context.getString(R.string.set_key_show_covers),
|
||||
context.getString(R.string.set_key_quality_covers) -> callback.onCoverSettingsChanged()
|
||||
context.getString(R.string.set_key_lib_tabs) -> callback.onLibrarySettingsChanged()
|
||||
context.getString(R.string.set_key_replay_gain),
|
||||
context.getString(R.string.set_key_pre_amp_with),
|
||||
context.getString(R.string.set_key_pre_amp_without) ->
|
||||
callback.onReplayGainSettingsChanged()
|
||||
}
|
||||
unlikelyToBeNull(callback).onSettingChanged(key)
|
||||
}
|
||||
|
||||
/**
|
||||
* An interface for receiving some preference updates. Use/Extend this instead of
|
||||
* [SharedPreferences.OnSharedPreferenceChangeListener] if possible, as it doesn't require a
|
||||
* context.
|
||||
*/
|
||||
interface Callback {
|
||||
fun onSettingChanged(key: String)
|
||||
}
|
||||
|
||||
// --- VALUES ---
|
||||
|
@ -354,16 +368,4 @@ class Settings(private val context: Context, private val callback: Callback? = n
|
|||
apply()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An interface for receiving some preference updates. Use/Extend this instead of
|
||||
* [SharedPreferences.OnSharedPreferenceChangeListener] if possible, as it doesn't require a
|
||||
* context.
|
||||
*/
|
||||
interface Callback {
|
||||
fun onLibrarySettingsChanged() {}
|
||||
fun onNotifSettingsChanged() {}
|
||||
fun onCoverSettingsChanged() {}
|
||||
fun onReplayGainSettingsChanged() {}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,15 +33,16 @@ import org.oxycblt.auxio.home.tabs.TabCustomizeDialog
|
|||
import org.oxycblt.auxio.music.dirs.MusicDirsDialog
|
||||
import org.oxycblt.auxio.playback.PlaybackViewModel
|
||||
import org.oxycblt.auxio.playback.replaygain.PreAmpCustomizeDialog
|
||||
import org.oxycblt.auxio.playback.replaygain.ReplayGainMode
|
||||
import org.oxycblt.auxio.settings.ui.IntListPreference
|
||||
import org.oxycblt.auxio.settings.ui.IntListPreferenceDialog
|
||||
import org.oxycblt.auxio.ui.accent.AccentDialog
|
||||
import org.oxycblt.auxio.settings.ui.WrappedDialogPreference
|
||||
import org.oxycblt.auxio.ui.accent.AccentCustomizeDialog
|
||||
import org.oxycblt.auxio.util.androidActivityViewModels
|
||||
import org.oxycblt.auxio.util.getSystemBarInsetsCompat
|
||||
import org.oxycblt.auxio.util.hardRestart
|
||||
import org.oxycblt.auxio.util.isNight
|
||||
import org.oxycblt.auxio.util.logD
|
||||
import org.oxycblt.auxio.util.logEOrThrow
|
||||
import org.oxycblt.auxio.util.showToast
|
||||
|
||||
/**
|
||||
|
@ -82,24 +83,55 @@ class SettingsListFragment : PreferenceFragmentCompat() {
|
|||
|
||||
@Suppress("Deprecation")
|
||||
override fun onDisplayPreferenceDialog(preference: Preference) {
|
||||
if (preference is IntListPreference) {
|
||||
// Creating our own preference dialog is hilariously difficult. For one, we need
|
||||
// to override this random method within the class in order to launch the dialog in
|
||||
// the first (because apparently you can't just implement some interface that
|
||||
// automatically provides this behavior), then we also need to use a deprecated method
|
||||
// to adequately supply a "target fragment" (otherwise we will crash since the dialog
|
||||
// requires one), and then we need to actually show the dialog, making sure we use
|
||||
// the parent FragmentManager as again, it will crash if we don't.
|
||||
//
|
||||
// Fragments were a mistake.
|
||||
val dialog = IntListPreferenceDialog.from(preference)
|
||||
dialog.setTargetFragment(this, 0)
|
||||
dialog.show(parentFragmentManager, IntListPreferenceDialog.TAG)
|
||||
} else {
|
||||
super.onDisplayPreferenceDialog(preference)
|
||||
when (preference) {
|
||||
is IntListPreference -> {
|
||||
// Creating our own preference dialog is hilariously difficult. For one, we need
|
||||
// to override this random method within the class in order to launch the dialog in
|
||||
// the first (because apparently you can't just implement some interface that
|
||||
// automatically provides this behavior), then we also need to use a deprecated
|
||||
// method to adequately supply a "target fragment" (otherwise we will crash since
|
||||
// the dialog requires one), and then we need to actually show the dialog, making
|
||||
// sure we use the parent FragmentManager as again, it will crash if we don't.
|
||||
//
|
||||
// Fragments were a mistake.
|
||||
val dialog = IntListPreferenceDialog.from(preference)
|
||||
dialog.setTargetFragment(this, 0)
|
||||
dialog.show(parentFragmentManager, IntListPreferenceDialog.TAG)
|
||||
}
|
||||
is WrappedDialogPreference ->
|
||||
when (preference.key) {
|
||||
getString(R.string.set_key_accent) ->
|
||||
AccentCustomizeDialog()
|
||||
.show(childFragmentManager, AccentCustomizeDialog.TAG)
|
||||
getString(R.string.set_key_lib_tabs) ->
|
||||
TabCustomizeDialog().show(childFragmentManager, TabCustomizeDialog.TAG)
|
||||
getString(R.string.set_key_pre_amp) ->
|
||||
PreAmpCustomizeDialog()
|
||||
.show(childFragmentManager, PreAmpCustomizeDialog.TAG)
|
||||
getString(R.string.set_key_music_dirs) ->
|
||||
MusicDirsDialog().show(childFragmentManager, MusicDirsDialog.TAG)
|
||||
else -> logEOrThrow("Unexpected dialog key ${preference.key}")
|
||||
}
|
||||
else -> super.onDisplayPreferenceDialog(preference)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPreferenceTreeClick(preference: Preference): Boolean {
|
||||
when (preference.key) {
|
||||
getString(R.string.set_key_save_state) -> {
|
||||
playbackModel.savePlaybackState(requireContext()) {
|
||||
context?.showToast(R.string.lbl_state_saved)
|
||||
}
|
||||
}
|
||||
getString(R.string.set_key_reindex) -> {
|
||||
playbackModel.savePlaybackState(requireContext()) { context?.hardRestart() }
|
||||
}
|
||||
else -> return super.onPreferenceTreeClick(preference)
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
/** Recursively handle a preference, doing any specific actions on it. */
|
||||
private fun recursivelyHandlePreference(preference: Preference) {
|
||||
if (!preference.isVisible) return
|
||||
|
@ -113,28 +145,18 @@ class SettingsListFragment : PreferenceFragmentCompat() {
|
|||
preference.apply {
|
||||
when (key) {
|
||||
getString(R.string.set_key_theme) -> {
|
||||
setIcon(AppCompatDelegate.getDefaultNightMode().toThemeIcon())
|
||||
|
||||
onPreferenceChangeListener =
|
||||
Preference.OnPreferenceChangeListener { _, value ->
|
||||
AppCompatDelegate.setDefaultNightMode(value as Int)
|
||||
setIcon(AppCompatDelegate.getDefaultNightMode().toThemeIcon())
|
||||
true
|
||||
}
|
||||
}
|
||||
getString(R.string.set_key_accent) -> {
|
||||
onPreferenceClickListener =
|
||||
Preference.OnPreferenceClickListener {
|
||||
AccentDialog().show(childFragmentManager, AccentDialog.TAG)
|
||||
true
|
||||
}
|
||||
|
||||
// TODO: Replace with preference impl
|
||||
summary = context.getString(settings.accent.name)
|
||||
}
|
||||
getString(R.string.set_key_black_theme) -> {
|
||||
onPreferenceClickListener =
|
||||
Preference.OnPreferenceClickListener {
|
||||
onPreferenceChangeListener =
|
||||
Preference.OnPreferenceChangeListener { _, _ ->
|
||||
if (requireContext().isNight) {
|
||||
requireActivity().recreate()
|
||||
}
|
||||
|
@ -142,13 +164,6 @@ class SettingsListFragment : PreferenceFragmentCompat() {
|
|||
true
|
||||
}
|
||||
}
|
||||
getString(R.string.set_key_lib_tabs) -> {
|
||||
onPreferenceClickListener =
|
||||
Preference.OnPreferenceClickListener {
|
||||
TabCustomizeDialog().show(childFragmentManager, TabCustomizeDialog.TAG)
|
||||
true
|
||||
}
|
||||
}
|
||||
getString(R.string.set_key_show_covers),
|
||||
getString(R.string.set_key_quality_covers) -> {
|
||||
onPreferenceChangeListener =
|
||||
|
@ -157,51 +172,6 @@ class SettingsListFragment : PreferenceFragmentCompat() {
|
|||
true
|
||||
}
|
||||
}
|
||||
getString(R.string.set_key_replay_gain) -> {
|
||||
notifyDependencyChange(settings.replayGainMode == ReplayGainMode.OFF)
|
||||
onPreferenceChangeListener =
|
||||
Preference.OnPreferenceChangeListener { _, value ->
|
||||
notifyDependencyChange(
|
||||
ReplayGainMode.fromIntCode(value as Int) == ReplayGainMode.OFF)
|
||||
true
|
||||
}
|
||||
}
|
||||
getString(R.string.set_key_pre_amp) -> {
|
||||
onPreferenceClickListener =
|
||||
Preference.OnPreferenceClickListener {
|
||||
PreAmpCustomizeDialog()
|
||||
.show(childFragmentManager, PreAmpCustomizeDialog.TAG)
|
||||
true
|
||||
}
|
||||
}
|
||||
getString(R.string.set_key_save_state) -> {
|
||||
onPreferenceClickListener =
|
||||
Preference.OnPreferenceClickListener {
|
||||
// FIXME: Callback can still occur on non-attached fragment
|
||||
playbackModel.savePlaybackState(requireContext()) {
|
||||
requireContext().showToast(R.string.lbl_state_saved)
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
}
|
||||
getString(R.string.set_key_reindex) -> {
|
||||
onPreferenceClickListener =
|
||||
Preference.OnPreferenceClickListener {
|
||||
playbackModel.savePlaybackState(requireContext()) {
|
||||
requireContext().hardRestart()
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
}
|
||||
getString(R.string.set_key_music_dirs) -> {
|
||||
onPreferenceClickListener =
|
||||
Preference.OnPreferenceClickListener {
|
||||
MusicDirsDialog().show(childFragmentManager, MusicDirsDialog.TAG)
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,11 +20,16 @@ package org.oxycblt.auxio.settings.ui
|
|||
import android.content.Context
|
||||
import android.content.res.TypedArray
|
||||
import android.util.AttributeSet
|
||||
import android.widget.ImageView
|
||||
import androidx.core.content.res.getResourceIdOrThrow
|
||||
import androidx.core.content.res.getTextArrayOrThrow
|
||||
import androidx.preference.DialogPreference
|
||||
import androidx.preference.Preference
|
||||
import androidx.preference.PreferenceViewHolder
|
||||
import java.lang.reflect.Field
|
||||
import org.oxycblt.auxio.R
|
||||
import org.oxycblt.auxio.util.lazyReflectedField
|
||||
import org.oxycblt.auxio.util.logD
|
||||
|
||||
class IntListPreference
|
||||
@JvmOverloads
|
||||
|
@ -36,22 +41,39 @@ constructor(
|
|||
) : DialogPreference(context, attrs, defStyleAttr, defStyleRes) {
|
||||
val entries: Array<CharSequence>
|
||||
val values: IntArray
|
||||
private var offValue: Int? = -1
|
||||
private var icons: TypedArray? = null
|
||||
private var currentValue: Int? = null
|
||||
|
||||
// Reflect into Preference to get the (normally inaccessible) default value.
|
||||
private val defValue: Int
|
||||
get() = PREFERENCE_DEFAULT_VALUE_FIELD.get(this) as Int
|
||||
|
||||
override fun onDependencyChanged(dependency: Preference, disableDependent: Boolean) {
|
||||
super.onDependencyChanged(dependency, disableDependent)
|
||||
logD("dependency changed: $dependency")
|
||||
}
|
||||
|
||||
init {
|
||||
val prefAttrs =
|
||||
context.obtainStyledAttributes(
|
||||
attrs, R.styleable.IntListPreference, defStyleAttr, defStyleRes)
|
||||
|
||||
entries = prefAttrs.getTextArray(R.styleable.IntListPreference_entries)
|
||||
entries = prefAttrs.getTextArrayOrThrow(R.styleable.IntListPreference_entries)
|
||||
|
||||
values =
|
||||
context.resources.getIntArray(
|
||||
prefAttrs.getResourceId(R.styleable.IntListPreference_entryValues, -1))
|
||||
prefAttrs.getResourceIdOrThrow(R.styleable.IntListPreference_entryValues))
|
||||
|
||||
val offValueId = prefAttrs.getResourceId(R.styleable.IntListPreference_offValue, -1)
|
||||
if (offValueId > -1) {
|
||||
offValue = context.resources.getInteger(offValueId)
|
||||
}
|
||||
|
||||
val iconsId = prefAttrs.getResourceId(R.styleable.IntListPreference_entryIcons, -1)
|
||||
if (iconsId > -1) {
|
||||
icons = context.resources.obtainTypedArray(iconsId)
|
||||
}
|
||||
|
||||
prefAttrs.recycle()
|
||||
|
||||
|
@ -71,6 +93,19 @@ constructor(
|
|||
}
|
||||
}
|
||||
|
||||
override fun shouldDisableDependents(): Boolean = currentValue == offValue
|
||||
|
||||
override fun onBindViewHolder(holder: PreferenceViewHolder) {
|
||||
super.onBindViewHolder(holder)
|
||||
val index = getValueIndex()
|
||||
if (index > -1) {
|
||||
val resourceId = icons?.getResourceId(index, -1) ?: -1
|
||||
if (resourceId > -1) {
|
||||
(holder.findViewById(android.R.id.icon) as ImageView).setImageResource(resourceId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getValueIndex(): Int {
|
||||
val curValue = currentValue
|
||||
|
||||
|
@ -91,6 +126,7 @@ constructor(
|
|||
currentValue = value
|
||||
|
||||
callChangeListener(value)
|
||||
notifyDependencyChange(shouldDisableDependents())
|
||||
persistInt(value)
|
||||
notifyChanged()
|
||||
}
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright (c) 2022 Auxio Project
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.oxycblt.auxio.settings.ui
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import androidx.preference.DialogPreference
|
||||
|
||||
/**
|
||||
* Wraps [DialogPreference] as to make it type-distinct from other preferences while also
|
||||
* making it possible to use in a PreferenceScreen.
|
||||
*/
|
||||
class WrappedDialogPreference
|
||||
@JvmOverloads
|
||||
constructor(
|
||||
context: Context,
|
||||
attrs: AttributeSet? = null,
|
||||
defStyleAttr: Int = androidx.preference.R.attr.dialogPreferenceStyle,
|
||||
defStyleRes: Int = 0
|
||||
) : DialogPreference(context, attrs, defStyleAttr, defStyleRes)
|
|
@ -33,7 +33,8 @@ import org.oxycblt.auxio.util.unlikelyToBeNull
|
|||
* Dialog responsible for showing the list of accents to select.
|
||||
* @author OxygenCobalt
|
||||
*/
|
||||
class AccentDialog : ViewBindingDialogFragment<DialogAccentBinding>(), AccentAdapter.Listener {
|
||||
class AccentCustomizeDialog :
|
||||
ViewBindingDialogFragment<DialogAccentBinding>(), AccentAdapter.Listener {
|
||||
private var accentAdapter = AccentAdapter(this)
|
||||
private val settings: Settings by settings()
|
||||
|
|
@ -23,6 +23,7 @@ import android.os.Build
|
|||
import coil.request.ImageRequest
|
||||
import coil.size.Size
|
||||
import coil.transform.RoundedCornersTransformation
|
||||
import org.oxycblt.auxio.R
|
||||
import org.oxycblt.auxio.image.BitmapProvider
|
||||
import org.oxycblt.auxio.image.SquareFrameTransform
|
||||
import org.oxycblt.auxio.music.MusicParent
|
||||
|
@ -140,7 +141,12 @@ class WidgetComponent(private val context: Context) :
|
|||
override fun onPlayingChanged(isPlaying: Boolean) = update()
|
||||
override fun onShuffledChanged(isShuffled: Boolean) = update()
|
||||
override fun onRepeatChanged(repeatMode: RepeatMode) = update()
|
||||
override fun onCoverSettingsChanged() = update()
|
||||
override fun onSettingChanged(key: String) {
|
||||
if (key == context.getString(R.string.set_key_show_covers) ||
|
||||
key == context.getString(R.string.set_key_quality_covers)) {
|
||||
update()
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* An immutable condensed variant of the current playback state, used so that PlaybackStateManager
|
||||
|
|
|
@ -8,5 +8,7 @@
|
|||
<declare-styleable name="IntListPreference">
|
||||
<attr name="entries" format="reference" />
|
||||
<attr name="entryValues" format="reference" />
|
||||
<attr name="entryIcons" format="reference" />
|
||||
<attr name="offValue" format="reference" />
|
||||
</declare-styleable>
|
||||
</resources>
|
|
@ -44,6 +44,12 @@
|
|||
<item>@string/set_theme_night</item>
|
||||
</string-array>
|
||||
|
||||
<array name="icons_theme">
|
||||
<item>@drawable/ic_auto</item>
|
||||
<item>@drawable/ic_light</item>
|
||||
<item>@drawable/ic_dark</item>
|
||||
</array>
|
||||
|
||||
<integer-array name="values_theme">
|
||||
<item>@integer/theme_auto</item>
|
||||
<item>@integer/theme_light</item>
|
||||
|
|
|
@ -12,9 +12,10 @@
|
|||
app:iconSpaceReserved="false"
|
||||
app:isPreferenceVisible="@bool/enable_theme_settings"
|
||||
app:key="@string/set_key_theme"
|
||||
app:entryIcons="@array/icons_theme"
|
||||
app:title="@string/set_theme" />
|
||||
|
||||
<Preference
|
||||
<org.oxycblt.auxio.settings.ui.WrappedDialogPreference
|
||||
app:icon="@drawable/ic_accent"
|
||||
app:key="@string/set_key_accent"
|
||||
app:title="@string/set_accent" />
|
||||
|
@ -33,7 +34,7 @@
|
|||
app:layout="@layout/item_header"
|
||||
app:title="@string/set_display">
|
||||
|
||||
<Preference
|
||||
<org.oxycblt.auxio.settings.ui.WrappedDialogPreference
|
||||
app:iconSpaceReserved="false"
|
||||
app:key="@string/set_key_lib_tabs"
|
||||
app:summary="@string/set_lib_tabs_desc"
|
||||
|
@ -89,10 +90,11 @@
|
|||
app:entries="@array/entries_replay_gain"
|
||||
app:entryValues="@array/values_replay_gain"
|
||||
app:iconSpaceReserved="false"
|
||||
app:offValue="@integer/replay_gain_off"
|
||||
app:key="@string/set_key_replay_gain"
|
||||
app:title="@string/set_replay_gain" />
|
||||
|
||||
<Preference
|
||||
<org.oxycblt.auxio.settings.ui.WrappedDialogPreference
|
||||
app:allowDividerBelow="false"
|
||||
app:dependency="@string/set_key_replay_gain"
|
||||
app:iconSpaceReserved="false"
|
||||
|
@ -156,7 +158,7 @@
|
|||
app:summary="@string/set_reindex_desc"
|
||||
app:title="@string/set_reindex" />
|
||||
|
||||
<Preference
|
||||
<org.oxycblt.auxio.settings.ui.WrappedDialogPreference
|
||||
app:iconSpaceReserved="false"
|
||||
app:key="@string/set_key_music_dirs"
|
||||
app:summary="@string/set_dirs_desc"
|
||||
|
|
Loading…
Reference in a new issue