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 ImageLoader.Builder(this) return defaultCoilImageLoader(1024 * 1024 * 1024)
.crossfade(true)
.diskCache(
DiskCache.Builder()
.directory(filesDir.resolve("coil"))
.maxSizeBytes(1024 * 1024 * 1024)
.build()
)
.build()
} }
} }
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 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()
@@ -311,21 +307,19 @@ fun HomeScreen(
val songCollections = enumValues<SongCollection>() val songCollections = enumValues<SongCollection>()
val nextSongCollection = songCollections[(preferences.homePageSongCollection.ordinal + 1) % songCollections.size] val nextSongCollection = songCollections[(preferences.homePageSongCollection.ordinal + 1) % songCollections.size]
BasicText( BasicText(
text = when (nextSongCollection) { text = when (nextSongCollection) {
SongCollection.MostPlayed -> "Most played" SongCollection.MostPlayed -> "Most played"
SongCollection.Favorites -> "Favorites" SongCollection.Favorites -> "Favorites"
SongCollection.History -> "History" SongCollection.History -> "History"
}, },
style = typography.xxs.secondary.bold, style = typography.xxs.secondary.bold,
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
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 val Context.preferences: Preferences
data class Preferences( get() = Preferences(getSharedPreferences("preferences", Context.MODE_PRIVATE))
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
)
companion object { val LocalPreferences = staticCompositionLocalOf<Preferences> { TODO() }
val Default = Preferences(isReady = false)
@Composable
fun rememberPreferences(): Preferences {
val context = LocalContext.current
return remember {
context.preferences
} }
} }
val LocalPreferences = staticCompositionLocalOf { Preferences.Default } private fun SharedPreferences.preference(key: String, defaultValue: Boolean) =
mutableStateOf(value = getBoolean(key, defaultValue)) {
private val colorPaletteModeKey = stringPreferencesKey("colorPaletteMode") edit {
private val searchFilterKey = stringPreferencesKey("searchFilter") putBoolean(key, it)
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
}
}
},
)
} }
}.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") 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")