Refactor preferences module

This commit is contained in:
MM20
2024-01-19 22:29:37 +01:00
parent 94aee6baba
commit 92ddc75060
171 changed files with 3202 additions and 2962 deletions
@@ -1,36 +1,26 @@
package de.mm20.launcher2.files
import android.content.Context
import de.mm20.launcher2.files.providers.FileProvider
import de.mm20.launcher2.files.providers.GDriveFileProvider
import de.mm20.launcher2.files.providers.LocalFileProvider
import de.mm20.launcher2.files.providers.NextcloudFileProvider
import de.mm20.launcher2.files.providers.OwncloudFileProvider
import de.mm20.launcher2.files.providers.PluginFileProvider
import de.mm20.launcher2.files.settings.FileSearchSettings
import de.mm20.launcher2.nextcloud.NextcloudApiHelper
import de.mm20.launcher2.owncloud.OwncloudClient
import de.mm20.launcher2.permissions.PermissionsManager
import de.mm20.launcher2.plugin.PluginRepository
import de.mm20.launcher2.plugin.PluginType
import de.mm20.launcher2.preferences.LauncherDataStore
import de.mm20.launcher2.preferences.search.FileSearchSettings
import de.mm20.launcher2.search.File
import de.mm20.launcher2.search.SearchableRepository
import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.channelFlow
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.map
internal class FileRepository(
private val context: Context,
private val permissionsManager: PermissionsManager,
private val settings: FileSearchSettings,
private val pluginRepository: PluginRepository,
) : SearchableRepository<File> {
private val nextcloudClient by lazy {
@@ -48,26 +38,15 @@ internal class FileRepository(
return@channelFlow
}
val filePlugins = pluginRepository.findMany(
type = PluginType.FileSearch,
enabled = true,
)
settings.data.collectLatest { settings ->
val providers = mutableListOf<FileProvider>()
if (settings.localFiles) providers.add(
LocalFileProvider(
context,
permissionsManager
)
)
if (settings.gdriveFiles) providers.add(GDriveFileProvider(context))
if (settings.nextcloudFiles) providers.add(NextcloudFileProvider(nextcloudClient))
if (settings.owncloudFiles) providers.add(OwncloudFileProvider(owncloudClient))
for (plugin in settings.plugins) {
providers.add(PluginFileProvider(context, plugin))
settings.enabledProviders.collectLatest { providerIds ->
val providers = providerIds.map {
when (it) {
"local" -> LocalFileProvider(context, permissionsManager)
"gdrive" -> GDriveFileProvider(context)
"nextcloud" -> NextcloudFileProvider(nextcloudClient)
"owncloud" -> OwncloudFileProvider(owncloudClient)
else -> PluginFileProvider(context, it)
}
}
if (providers.isEmpty()) {
@@ -1,13 +1,11 @@
package de.mm20.launcher2.files
import de.mm20.launcher2.backup.Backupable
import de.mm20.launcher2.files.providers.GDriveFile
import de.mm20.launcher2.files.providers.LocalFile
import de.mm20.launcher2.files.providers.NextcloudFile
import de.mm20.launcher2.files.providers.OneDriveFile
import de.mm20.launcher2.files.providers.OwncloudFile
import de.mm20.launcher2.files.providers.PluginFile
import de.mm20.launcher2.files.settings.FileSearchSettings
import de.mm20.launcher2.search.File
import de.mm20.launcher2.search.SearchableDeserializer
import de.mm20.launcher2.search.SearchableRepository
@@ -20,7 +18,6 @@ val filesModule = module {
FileRepository(
androidContext(),
get(),
get(),
get()
)
}
@@ -35,6 +32,4 @@ val filesModule = module {
get()
)
}
single<FileSearchSettings> { FileSearchSettings(androidContext(), get()) }
factory<Backupable>(named<FileSearchSettings>()) { get<FileSearchSettings>() }
}
@@ -1,100 +0,0 @@
package de.mm20.launcher2.files.settings
import android.content.Context
import androidx.datastore.dataStore
import de.mm20.launcher2.backup.Backupable
import de.mm20.launcher2.crashreporter.CrashReporter
import de.mm20.launcher2.files.settings.migrations.Migration1
import de.mm20.launcher2.preferences.LauncherDataStore
import de.mm20.launcher2.settings.BaseSettings
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch
import kotlinx.serialization.SerializationException
import kotlinx.serialization.json.Json
import java.io.File
class FileSearchSettings(
private val context: Context,
dataStore: LauncherDataStore,
) : BaseSettings<FileSearchSettingsData>(
context = context,
fileName = "file_search.json",
serializer = FileSearchSettingsDataSerializer,
migrations = listOf(
Migration1(dataStore),
)
) {
internal val data
get() = context.dataStore.data
val localFiles
get(): Flow<Boolean> {
return context.dataStore.data.map { it.localFiles }
}
fun setLocalFiles(localFiles: Boolean) {
updateData {
it.copy(localFiles = localFiles)
}
}
val gdriveFiles
get(): Flow<Boolean> {
return context.dataStore.data.map { it.gdriveFiles }
}
fun setGdriveFiles(gdriveFiles: Boolean) {
updateData {
it.copy(gdriveFiles = gdriveFiles)
}
}
val nextcloudFiles
get(): Flow<Boolean> {
return context.dataStore.data.map { it.nextcloudFiles }
}
fun setNextcloudFiles(nextcloudFiles: Boolean) {
updateData {
it.copy(nextcloudFiles = nextcloudFiles)
}
}
val owncloudFiles
get(): Flow<Boolean> {
return context.dataStore.data.map { it.owncloudFiles }
}
fun setOwncloudFiles(owncloudFiles: Boolean) {
updateData {
it.copy(owncloudFiles = owncloudFiles)
}
}
val enabledPlugins: Flow<Set<String>>
get(): Flow<Set<String>> {
return context.dataStore.data.map { it.plugins }
}
fun setEnabledPlugins(enabledPlugins: Set<String>) {
updateData {
it.copy(plugins = enabledPlugins)
}
}
fun setPluginEnabled(authority: String, enabled: Boolean) {
updateData {
if (enabled) {
it.copy(plugins = it.plugins + authority)
} else {
it.copy(plugins = it.plugins - authority)
}
}
}
}
@@ -1,49 +0,0 @@
package de.mm20.launcher2.files.settings
import androidx.datastore.core.CorruptionException
import androidx.datastore.core.Serializer
import kotlinx.serialization.Serializable
import kotlinx.serialization.SerializationException
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.decodeFromStream
import kotlinx.serialization.json.encodeToStream
import java.io.IOException
import java.io.InputStream
import java.io.OutputStream
@Serializable
data class FileSearchSettingsData(
val localFiles: Boolean = true,
val gdriveFiles: Boolean = false,
val nextcloudFiles: Boolean = false,
val owncloudFiles: Boolean = false,
val plugins: Set<String> = emptySet(),
val schemaVersion: Int = 1,
)
internal object FileSearchSettingsDataSerializer : Serializer<FileSearchSettingsData> {
internal val json = Json {
ignoreUnknownKeys = true
encodeDefaults = true
}
override val defaultValue: FileSearchSettingsData
get() = FileSearchSettingsData(schemaVersion = 0)
override suspend fun readFrom(input: InputStream): FileSearchSettingsData {
try {
return json.decodeFromStream(input)
} catch (e: IllegalArgumentException) {
throw (CorruptionException("Cannot read json.", e))
} catch (e: SerializationException) {
throw (CorruptionException("Cannot read json.", e))
} catch (e: IOException) {
throw (CorruptionException("Cannot read json.", e))
}
}
override suspend fun writeTo(t: FileSearchSettingsData, output: OutputStream) {
json.encodeToStream(t, output)
}
}
@@ -1,33 +0,0 @@
package de.mm20.launcher2.files.settings.migrations
import androidx.datastore.core.DataMigration
import de.mm20.launcher2.files.settings.FileSearchSettingsData
import de.mm20.launcher2.preferences.LauncherDataStore
import kotlinx.coroutines.flow.first
/**
* This migration is used to migrate the data from the old proto data store.
* TODO: remove after a few releases
*/
internal class Migration1(
private val dataStore: LauncherDataStore,
): DataMigration<FileSearchSettingsData> {
override suspend fun cleanUp() {
}
override suspend fun shouldMigrate(currentData: FileSearchSettingsData): Boolean {
return currentData.schemaVersion < 1
}
override suspend fun migrate(currentData: FileSearchSettingsData): FileSearchSettingsData {
val data = dataStore.data.first().fileSearch
return currentData.copy(
localFiles = data.localFiles,
gdriveFiles = data.gdrive,
nextcloudFiles = data.nextcloud,
owncloudFiles = data.owncloud,
schemaVersion = 1,
)
}
}