Files
muza/app/src/main/kotlin/it/vfsfitvnm/vimusic/utils/Preferences.kt

143 lines
5.4 KiB
Kotlin

package it.vfsfitvnm.vimusic.utils
import android.content.Context
import android.content.SharedPreferences
import androidx.compose.runtime.*
import androidx.compose.ui.platform.LocalContext
import androidx.core.content.edit
import androidx.media3.common.Player
import it.vfsfitvnm.vimusic.enums.*
import it.vfsfitvnm.youtubemusic.YouTube
@Stable
class Preferences(
private val edit: (action: SharedPreferences.Editor.() -> Unit) -> Unit,
initialSongSortBy: SongSortBy,
initialSongSortOrder: SortOrder,
initialColorPaletteMode: ColorPaletteMode,
initialSearchFilter: String,
initialRepeatMode: Int,
initialThumbnailRoundness: ThumbnailRoundness,
initialCoilDiskCacheMaxSizeBytes: Long,
initialExoPlayerDiskCacheMaxSizeBytes: Long,
initialSkipSilence: Boolean,
initialVolumeNormalization: Boolean,
initialPersistentQueue: Boolean,
) {
constructor(preferences: SharedPreferences) : this(
edit = { action: SharedPreferences.Editor.() -> Unit ->
preferences.edit(action = action)
},
initialSongSortBy = preferences.getEnum(Keys.songSortBy, SongSortBy.DateAdded),
initialSongSortOrder = preferences.getEnum(Keys.songSortOrder, SortOrder.Descending),
initialColorPaletteMode = preferences.getEnum(Keys.colorPaletteMode, ColorPaletteMode.System),
initialSearchFilter = preferences.getString(Keys.searchFilter, YouTube.Item.Song.Filter.value)!!,
initialRepeatMode = preferences.getInt(Keys.repeatMode, Player.REPEAT_MODE_OFF),
initialThumbnailRoundness = preferences.getEnum(Keys.thumbnailRoundness, ThumbnailRoundness.Light),
initialCoilDiskCacheMaxSizeBytes = preferences.getLong(Keys.coilDiskCacheMaxSizeBytes, 512L * 1024 * 1024),
initialExoPlayerDiskCacheMaxSizeBytes = preferences.getLong(Keys.exoPlayerDiskCacheMaxSizeBytes, 512L * 1024 * 1024),
initialSkipSilence = preferences.getBoolean(Keys.skipSilence, false),
initialVolumeNormalization = preferences.getBoolean(Keys.volumeNormalization, false),
initialPersistentQueue = preferences.getBoolean(Keys.persistentQueue, false)
)
var songSortBy = initialSongSortBy
set(value) = edit { putEnum(Keys.songSortBy, value) }
var songSortOrder = initialSongSortOrder
set(value) = edit { putEnum(Keys.songSortOrder, value) }
var colorPaletteMode = initialColorPaletteMode
set(value) = edit { putEnum(Keys.colorPaletteMode, value) }
var searchFilter = initialSearchFilter
set(value) = edit { putString(Keys.searchFilter, value) }
var repeatMode = initialRepeatMode
set(value) = edit { putInt(Keys.repeatMode, value) }
var thumbnailRoundness = initialThumbnailRoundness
set(value) = edit { putEnum(Keys.thumbnailRoundness, value) }
var coilDiskCacheMaxSizeBytes = initialCoilDiskCacheMaxSizeBytes
set(value) = edit { putLong(Keys.coilDiskCacheMaxSizeBytes, value) }
var exoPlayerDiskCacheMaxSizeBytes = initialExoPlayerDiskCacheMaxSizeBytes
set(value) = edit { putLong(Keys.exoPlayerDiskCacheMaxSizeBytes, value) }
var skipSilence = initialSkipSilence
set(value) = edit { putBoolean(Keys.skipSilence, value) }
var volumeNormalization = initialVolumeNormalization
set(value) = edit { putBoolean(Keys.volumeNormalization, value) }
var persistentQueue = initialPersistentQueue
set(value) = edit { putBoolean(Keys.persistentQueue, value) }
object Keys {
const val songSortOrder = "songSortOrder"
const val songSortBy = "songSortBy"
const val colorPaletteMode = "colorPaletteMode"
const val searchFilter = "searchFilter"
const val repeatMode = "repeatMode"
const val thumbnailRoundness = "thumbnailRoundness"
const val coilDiskCacheMaxSizeBytes = "coilDiskCacheMaxSizeBytes"
const val exoPlayerDiskCacheMaxSizeBytes = "exoPlayerDiskCacheMaxSizeBytes"
const val skipSilence = "skipSilence"
const val volumeNormalization = "volumeNormalization"
const val persistentQueue = "persistentQueue"
}
companion object {
const val fileName = "preferences"
context(Context)
operator fun invoke() =
Preferences(getSharedPreferences(fileName, Context.MODE_PRIVATE))
}
}
val LocalPreferences = staticCompositionLocalOf<Preferences> { TODO() }
@Composable
fun rememberPreferences(): Preferences {
val context = LocalContext.current
var preferences by remember {
mutableStateOf(context.run { Preferences() })
}
DisposableEffect(Unit) {
val holder = context.getSharedPreferences(Preferences.fileName, Context.MODE_PRIVATE)
val listener =
SharedPreferences.OnSharedPreferenceChangeListener { sharedPreferences, _ ->
preferences = Preferences(sharedPreferences)
}
holder.registerOnSharedPreferenceChangeListener(listener)
onDispose {
holder.unregisterOnSharedPreferenceChangeListener(listener)
}
}
return preferences
}
private inline fun <reified T : Enum<T>> SharedPreferences.getEnum(
key: String,
defaultValue: T
): T =
getString(key, null)?.let {
try {
enumValueOf<T>(it)
} catch (e: IllegalArgumentException) {
null
}
} ?: defaultValue
private inline fun <reified T : Enum<T>> SharedPreferences.Editor.putEnum(key: String, value: T) =
putString(key, value.name)