Revert DataStore migration

This commit is contained in:
vfsfitvnm 2022-06-10 21:03:21 +02:00
parent 3d91e23733
commit 4d79747a5d
8 changed files with 136 additions and 148 deletions

View file

@ -88,8 +88,6 @@ dependencies {
implementation(libs.media3.session)
implementation(libs.media3.exoplayer)
implementation(libs.datastore)
implementation(libs.room)
kapt(libs.room.compiler)

View file

@ -58,7 +58,7 @@ class MainActivity : ComponentActivity() {
mediaControllerFuture = MediaController.Builder(this, sessionToken).buildAsync()
setContent {
val preferences by rememberPreferences(dataStore)
val preferences = rememberPreferences()
val systemUiController = rememberSystemUiController()
val (isDarkTheme, colorPalette) = when (preferences.colorPaletteMode) {
@ -118,9 +118,7 @@ class MainActivity : ComponentActivity() {
LocalShimmerTheme provides shimmerTheme,
LocalTypography provides rememberTypography(colorPalette.text),
LocalYoutubePlayer provides rememberYoutubePlayer(mediaControllerFuture) {
if (preferences.isReady) {
it.repeatMode = preferences.repeatMode
}
it.repeatMode = preferences.repeatMode
},
LocalMenuState provides rememberMenuState(),
LocalHapticFeedback provides rememberHapticFeedback()

View file

@ -1,6 +1,7 @@
package it.vfsfitvnm.vimusic
import android.app.Application
import android.content.Context
import coil.ImageLoader
import coil.ImageLoaderFactory
import coil.disk.DiskCache
@ -13,14 +14,18 @@ class MainApplication : Application(), ImageLoaderFactory {
}
override fun newImageLoader(): ImageLoader {
return ImageLoader.Builder(this)
.crossfade(true)
.diskCache(
DiskCache.Builder()
.directory(filesDir.resolve("coil"))
.maxSizeBytes(1024 * 1024 * 1024)
.build()
)
.build()
return defaultCoilImageLoader(1024 * 1024 * 1024)
}
}
fun Context.defaultCoilImageLoader(diskCacheMaxSize: Long): ImageLoader {
return ImageLoader.Builder(this)
.crossfade(true)
.diskCache(
DiskCache.Builder()
.directory(filesDir.resolve("coil"))
.maxSizeBytes(diskCacheMaxSize)
.build()
)
.build()
}

View file

@ -80,11 +80,7 @@ fun HomeScreen(
val preferences = LocalPreferences.current
val songCollection by remember(preferences.isReady, preferences.homePageSongCollection) {
if (!preferences.isReady) {
return@remember flowOf(emptyList())
}
val songCollection by remember(preferences.homePageSongCollection) {
when (preferences.homePageSongCollection) {
SongCollection.MostPlayed -> Database.mostPlayed()
SongCollection.Favorites -> Database.favorites()
@ -311,21 +307,19 @@ fun HomeScreen(
val songCollections = enumValues<SongCollection>()
val nextSongCollection = songCollections[(preferences.homePageSongCollection.ordinal + 1) % songCollections.size]
BasicText(
text = when (nextSongCollection) {
SongCollection.MostPlayed -> "Most played"
SongCollection.Favorites -> "Favorites"
SongCollection.History -> "History"
},
style = typography.xxs.secondary.bold,
modifier = Modifier
.clickable(
indication = rememberRipple(bounded = true),
interactionSource = remember { MutableInteractionSource() }
) {
preferences.onHomePageSongCollectionChange(
nextSongCollection
)
BasicText(
text = when (nextSongCollection) {
SongCollection.MostPlayed -> "Most played"
SongCollection.Favorites -> "Favorites"
SongCollection.History -> "History"
},
style = typography.xxs.secondary.bold,
modifier = Modifier
.clickable(
indication = rememberRipple(bounded = true),
interactionSource = remember { MutableInteractionSource() },
onClick = {
preferences.homePageSongCollection = nextSongCollection
}
// .alignByBaseline()
.padding(horizontal = 16.dp)

View file

@ -80,13 +80,17 @@ fun AppearanceScreen() {
EnumValueSelectorEntry(
title = "Theme mode",
selectedValue = preferences.colorPaletteMode,
onValueSelected = preferences.onColorPaletteModeChange
onValueSelected = {
preferences.colorPaletteMode = it
}
)
EnumValueSelectorEntry(
title = "Thumbnail roundness",
selectedValue = preferences.thumbnailRoundness,
onValueSelected = preferences.onThumbnailRoundnessChange
onValueSelected = {
preferences.thumbnailRoundness = it
}
)
}
}

View file

@ -429,7 +429,7 @@ fun PlayerView(
player.mediaController.repeatMode =
(player.mediaController.repeatMode + 2) % 3
preferences.onRepeatModeChange(player.mediaController.repeatMode)
preferences.repeatMode = player.mediaController.repeatMode
}
.padding(horizontal = 16.dp)
.size(28.dp)

View file

@ -1,123 +1,114 @@
package it.vfsfitvnm.vimusic.utils
import android.content.Context
import android.content.SharedPreferences
import androidx.compose.runtime.*
import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.edit
import androidx.datastore.preferences.core.intPreferencesKey
import androidx.datastore.preferences.core.stringPreferencesKey
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.TextUnit
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.core.content.edit
import androidx.media3.common.Player
import it.vfsfitvnm.vimusic.enums.ColorPaletteMode
import it.vfsfitvnm.vimusic.enums.SongCollection
import it.vfsfitvnm.vimusic.enums.ThumbnailRoundness
import it.vfsfitvnm.youtubemusic.YouTube
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch
import androidx.datastore.preferences.core.Preferences as DataStorePreferences
@Stable
class Preferences(holder: SharedPreferences) : SharedPreferences by holder {
var colorPaletteMode by preference("colorPaletteMode", ColorPaletteMode.System)
var searchFilter by preference("searchFilter", YouTube.Item.Song.Filter.value)
var repeatMode by preference("repeatMode", Player.REPEAT_MODE_OFF)
var homePageSongCollection by preference("homePageSongCollection", SongCollection.MostPlayed)
var thumbnailRoundness by preference("thumbnailRoundness", ThumbnailRoundness.Light)
}
@Immutable
data class Preferences(
val isReady: Boolean,
val colorPaletteMode: ColorPaletteMode,
val onColorPaletteModeChange: (ColorPaletteMode) -> Unit,
val searchFilter: String,
val onSearchFilterChange: (String) -> Unit,
val repeatMode: Int,
val onRepeatModeChange: (Int) -> Unit,
val homePageSongCollection: SongCollection,
val onHomePageSongCollectionChange: (SongCollection) -> Unit,
val thumbnailRoundness: ThumbnailRoundness,
val onThumbnailRoundnessChange: (ThumbnailRoundness) -> Unit,
) {
constructor(
isReady: Boolean,
colorPaletteMode: ColorPaletteMode? = null,
onColorPaletteModeChange: (ColorPaletteMode) -> Unit = {},
searchFilter: String? = null,
onSearchFilterChange: (String) -> Unit = {},
repeatMode: Int? = null,
onRepeatModeChange: (Int) -> Unit = {},
homePageSongCollection: SongCollection? = null,
onHomePageSongCollectionChange: (SongCollection) -> Unit = {},
thumbnailRoundness: ThumbnailRoundness? = null,
onThumbnailRoundnessChange: (ThumbnailRoundness) -> Unit = {},
) : this(
isReady = isReady,
colorPaletteMode = colorPaletteMode ?: ColorPaletteMode.System,
onColorPaletteModeChange = onColorPaletteModeChange,
searchFilter = searchFilter ?: YouTube.Item.Song.Filter.value,
onSearchFilterChange = onSearchFilterChange,
repeatMode = repeatMode ?: Player.REPEAT_MODE_OFF,
onRepeatModeChange = onRepeatModeChange,
homePageSongCollection = homePageSongCollection ?: SongCollection.MostPlayed,
onHomePageSongCollectionChange = onHomePageSongCollectionChange,
thumbnailRoundness = thumbnailRoundness ?: ThumbnailRoundness.Light,
onThumbnailRoundnessChange = onThumbnailRoundnessChange
)
val Context.preferences: Preferences
get() = Preferences(getSharedPreferences("preferences", Context.MODE_PRIVATE))
companion object {
val Default = Preferences(isReady = false)
val LocalPreferences = staticCompositionLocalOf<Preferences> { TODO() }
@Composable
fun rememberPreferences(): Preferences {
val context = LocalContext.current
return remember {
context.preferences
}
}
val LocalPreferences = staticCompositionLocalOf { Preferences.Default }
private val colorPaletteModeKey = stringPreferencesKey("colorPaletteMode")
private val searchFilterKey = stringPreferencesKey("searchFilter")
private val repeatModeKey = intPreferencesKey("repeatMode")
private val homePageSongCollectionKey = stringPreferencesKey("homePageSongCollection")
private val thumbnailRoundnessKey = stringPreferencesKey("thumbnailRoundness")
@Composable
fun rememberPreferences(dataStore: DataStore<DataStorePreferences>): State<Preferences> {
val coroutineScope = rememberCoroutineScope()
return remember(dataStore, coroutineScope) {
dataStore.data.map { preferences ->
Preferences(
isReady = true,
colorPaletteMode = preferences[colorPaletteModeKey]?.let { enumValueOf<ColorPaletteMode>(it) },
onColorPaletteModeChange = { colorPaletteMode ->
coroutineScope.launch(Dispatchers.IO) {
dataStore.edit { mutablePreferences ->
mutablePreferences[colorPaletteModeKey] = colorPaletteMode.name
}
}
},
searchFilter = preferences[searchFilterKey],
onSearchFilterChange = { searchFilter ->
coroutineScope.launch(Dispatchers.IO) {
dataStore.edit { mutablePreferences ->
mutablePreferences[searchFilterKey] = searchFilter
}
}
},
repeatMode = preferences[repeatModeKey],
onRepeatModeChange = { repeatMode ->
coroutineScope.launch(Dispatchers.IO) {
dataStore.edit { mutablePreferences ->
mutablePreferences[repeatModeKey] = repeatMode
}
}
},
homePageSongCollection = preferences[homePageSongCollectionKey]?.let { enumValueOf<SongCollection>(it) },
onHomePageSongCollectionChange = { homePageSongCollection ->
coroutineScope.launch(Dispatchers.IO) {
dataStore.edit { mutablePreferences ->
mutablePreferences[homePageSongCollectionKey] = homePageSongCollection.name
}
}
},
thumbnailRoundness = preferences[thumbnailRoundnessKey]?.let { enumValueOf<ThumbnailRoundness>(it) },
onThumbnailRoundnessChange = { thumbnailRoundness ->
coroutineScope.launch(Dispatchers.IO) {
dataStore.edit { mutablePreferences ->
mutablePreferences[thumbnailRoundnessKey] = thumbnailRoundness.name
}
}
},
)
private fun SharedPreferences.preference(key: String, defaultValue: Boolean) =
mutableStateOf(value = getBoolean(key, defaultValue)) {
edit {
putBoolean(key, it)
}
}.collectAsState(initial = Preferences.Default, context = Dispatchers.IO)
}
}
private fun SharedPreferences.preference(key: String, defaultValue: Int) =
mutableStateOf(value = getInt(key, defaultValue)) {
edit {
putInt(key, it)
}
}
private fun SharedPreferences.preference(key: String, defaultValue: Long) =
mutableStateOf(value = getLong(key, defaultValue)) {
edit {
putLong(key, it)
}
}
private fun SharedPreferences.preference(key: String, defaultValue: Float) =
mutableStateOf(value = getFloat(key, defaultValue)) {
edit {
putFloat(key, it)
}
}
private fun SharedPreferences.preference(key: String, defaultValue: String) =
mutableStateOf(value = getString(key, defaultValue)!!) {
edit {
putString(key, it)
}
}
private fun SharedPreferences.preference(key: String, defaultValue: Set<String>) =
mutableStateOf(value = getStringSet(key, defaultValue)!!) {
edit {
putStringSet(key, it)
}
}
private fun SharedPreferences.preference(key: String, defaultValue: Dp) =
mutableStateOf(value = getFloat(key, defaultValue.value).dp) {
edit {
putFloat(key, it.value)
}
}
private fun SharedPreferences.preference(key: String, defaultValue: TextUnit) =
mutableStateOf(value = getFloat(key, defaultValue.value).sp) {
edit {
putFloat(key, it.value)
}
}
private inline fun <reified T : Enum<T>> SharedPreferences.preference(
key: String,
defaultValue: T
) = mutableStateOf(value = enumValueOf<T>(getString(key, defaultValue.name)!!)) {
edit {
putString(key, it.name)
}
}
private fun <T> mutableStateOf(value: T, onStructuralInequality: (newValue: T) -> Unit) =
mutableStateOf(
value = value,
policy = object : SnapshotMutationPolicy<T> {
override fun equivalent(a: T, b: T): Boolean {
val areEquals = a == b
if (!areEquals) onStructuralInequality(b)
return areEquals
}
})

View file

@ -31,8 +31,6 @@ dependencyResolutionManagement {
version("accompanist", "0.24.10-beta")
alias("accompanist-systemuicontroller").to("com.google.accompanist", "accompanist-systemuicontroller").versionRef("accompanist")
alias("datastore").to("androidx.datastore", "datastore-preferences").version("1.0.0")
version("room", "2.5.0-alpha01")
alias("room").to("androidx.room", "room-ktx").versionRef("room")
alias("room-compiler").to("androidx.room", "room-compiler").versionRef("room")