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.session)
implementation(libs.media3.exoplayer) implementation(libs.media3.exoplayer)
implementation(libs.datastore)
implementation(libs.room) implementation(libs.room)
kapt(libs.room.compiler) kapt(libs.room.compiler)

View File

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

View File

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

View File

@@ -80,11 +80,7 @@ fun HomeScreen(
val preferences = LocalPreferences.current val preferences = LocalPreferences.current
val songCollection by remember(preferences.isReady, preferences.homePageSongCollection) { val songCollection by remember(preferences.homePageSongCollection) {
if (!preferences.isReady) {
return@remember flowOf(emptyList())
}
when (preferences.homePageSongCollection) { when (preferences.homePageSongCollection) {
SongCollection.MostPlayed -> Database.mostPlayed() SongCollection.MostPlayed -> Database.mostPlayed()
SongCollection.Favorites -> Database.favorites() SongCollection.Favorites -> Database.favorites()
@@ -321,11 +317,9 @@ fun HomeScreen(
modifier = Modifier modifier = Modifier
.clickable( .clickable(
indication = rememberRipple(bounded = true), indication = rememberRipple(bounded = true),
interactionSource = remember { MutableInteractionSource() } interactionSource = remember { MutableInteractionSource() },
) { onClick = {
preferences.onHomePageSongCollectionChange( preferences.homePageSongCollection = nextSongCollection
nextSongCollection
)
} }
// .alignByBaseline() // .alignByBaseline()
.padding(horizontal = 16.dp) .padding(horizontal = 16.dp)

View File

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

View File

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

View File

@@ -1,123 +1,114 @@
package it.vfsfitvnm.vimusic.utils package it.vfsfitvnm.vimusic.utils
import android.content.Context
import android.content.SharedPreferences
import androidx.compose.runtime.* import androidx.compose.runtime.*
import androidx.datastore.core.DataStore import androidx.compose.ui.platform.LocalContext
import androidx.datastore.preferences.core.edit import androidx.compose.ui.unit.Dp
import androidx.datastore.preferences.core.intPreferencesKey import androidx.compose.ui.unit.TextUnit
import androidx.datastore.preferences.core.stringPreferencesKey import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.core.content.edit
import androidx.media3.common.Player import androidx.media3.common.Player
import it.vfsfitvnm.vimusic.enums.ColorPaletteMode import it.vfsfitvnm.vimusic.enums.ColorPaletteMode
import it.vfsfitvnm.vimusic.enums.SongCollection import it.vfsfitvnm.vimusic.enums.SongCollection
import it.vfsfitvnm.vimusic.enums.ThumbnailRoundness import it.vfsfitvnm.vimusic.enums.ThumbnailRoundness
import it.vfsfitvnm.youtubemusic.YouTube 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
@Immutable class Preferences(holder: SharedPreferences) : SharedPreferences by holder {
data class Preferences( var colorPaletteMode by preference("colorPaletteMode", ColorPaletteMode.System)
val isReady: Boolean, var searchFilter by preference("searchFilter", YouTube.Item.Song.Filter.value)
val colorPaletteMode: ColorPaletteMode, var repeatMode by preference("repeatMode", Player.REPEAT_MODE_OFF)
val onColorPaletteModeChange: (ColorPaletteMode) -> Unit, var homePageSongCollection by preference("homePageSongCollection", SongCollection.MostPlayed)
val searchFilter: String, var thumbnailRoundness by preference("thumbnailRoundness", ThumbnailRoundness.Light)
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
)
companion object {
val Default = Preferences(isReady = false)
}
} }
val LocalPreferences = staticCompositionLocalOf { Preferences.Default } val Context.preferences: Preferences
get() = Preferences(getSharedPreferences("preferences", Context.MODE_PRIVATE))
private val colorPaletteModeKey = stringPreferencesKey("colorPaletteMode") val LocalPreferences = staticCompositionLocalOf<Preferences> { TODO() }
private val searchFilterKey = stringPreferencesKey("searchFilter")
private val repeatModeKey = intPreferencesKey("repeatMode")
private val homePageSongCollectionKey = stringPreferencesKey("homePageSongCollection")
private val thumbnailRoundnessKey = stringPreferencesKey("thumbnailRoundness")
@Composable @Composable
fun rememberPreferences(dataStore: DataStore<DataStorePreferences>): State<Preferences> { fun rememberPreferences(): Preferences {
val coroutineScope = rememberCoroutineScope() val context = LocalContext.current
return remember {
return remember(dataStore, coroutineScope) { context.preferences
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
}
}
},
)
}
}.collectAsState(initial = Preferences.Default, context = Dispatchers.IO)
} }
private fun SharedPreferences.preference(key: String, defaultValue: Boolean) =
mutableStateOf(value = getBoolean(key, defaultValue)) {
edit {
putBoolean(key, it)
}
}
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") version("accompanist", "0.24.10-beta")
alias("accompanist-systemuicontroller").to("com.google.accompanist", "accompanist-systemuicontroller").versionRef("accompanist") 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") version("room", "2.5.0-alpha01")
alias("room").to("androidx.room", "room-ktx").versionRef("room") alias("room").to("androidx.room", "room-ktx").versionRef("room")
alias("room-compiler").to("androidx.room", "room-compiler").versionRef("room") alias("room-compiler").to("androidx.room", "room-compiler").versionRef("room")