Refactor search, favorites and calendar widget
This commit is contained in:
@@ -1,26 +1,26 @@
|
||||
package de.mm20.launcher2.files
|
||||
|
||||
import android.content.Context
|
||||
import androidx.lifecycle.MediatorLiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import de.mm20.launcher2.hiddenitems.HiddenItemsRepository
|
||||
import de.mm20.launcher2.nextcloud.NextcloudApiHelper
|
||||
import de.mm20.launcher2.owncloud.OwncloudClient
|
||||
import de.mm20.launcher2.search.BaseSearchableRepository
|
||||
import de.mm20.launcher2.search.data.*
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.channelFlow
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
|
||||
class FilesRepository(
|
||||
val context: Context,
|
||||
interface FileRepository {
|
||||
fun search(query: String): Flow<List<File>>
|
||||
suspend fun deleteFile(file: File)
|
||||
}
|
||||
|
||||
class FileRepositoryImpl(
|
||||
private val context: Context,
|
||||
hiddenItemsRepository: HiddenItemsRepository
|
||||
) : BaseSearchableRepository() {
|
||||
) : FileRepository {
|
||||
|
||||
private val scope = CoroutineScope(Job() + Dispatchers.Main)
|
||||
|
||||
val files = MediatorLiveData<List<File>?>()
|
||||
|
||||
private val allFiles = MutableLiveData<List<File>?>(emptyList())
|
||||
private val hiddenItemKeys = hiddenItemsRepository.hiddenItemsKeys
|
||||
private val hiddenItems = hiddenItemsRepository.hiddenItemsKeys
|
||||
|
||||
private val nextcloudClient by lazy {
|
||||
NextcloudApiHelper(context)
|
||||
@@ -29,44 +29,39 @@ class FilesRepository(
|
||||
OwncloudClient(context)
|
||||
}
|
||||
|
||||
init {
|
||||
files.addSource(hiddenItemKeys) { keys ->
|
||||
files.value = allFiles.value?.filter { !keys.contains(it.key) }
|
||||
}
|
||||
files.addSource(allFiles) { f ->
|
||||
files.value = f?.filter { hiddenItemKeys.value?.contains(it.key) != true }
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun search(query: String) {
|
||||
override fun search(query: String): Flow<List<File>> = channelFlow {
|
||||
if (query.isBlank()) {
|
||||
allFiles.value = null
|
||||
return
|
||||
send(emptyList())
|
||||
return@channelFlow
|
||||
}
|
||||
val localFiles = withContext(Dispatchers.IO) {
|
||||
LocalFile.search(context, query).sorted().toMutableList()
|
||||
}
|
||||
allFiles.value = localFiles
|
||||
|
||||
val cloudFiles = withContext(Dispatchers.IO) {
|
||||
delay(300)
|
||||
listOf(
|
||||
async { OneDriveFile.search(context, query) },
|
||||
async { GDriveFile.search(context, query) },
|
||||
async { NextcloudFile.search(context, query, nextcloudClient) },
|
||||
async { OwncloudFile.search(context, query, owncloudClient) }
|
||||
).awaitAll().flatten()
|
||||
hiddenItems.collectLatest { hiddenItems ->
|
||||
val files = mutableListOf<File>()
|
||||
|
||||
val localFiles = withContext(Dispatchers.IO) {
|
||||
LocalFile.search(context, query).sorted().filter { !hiddenItems.contains(it.key) }
|
||||
}
|
||||
files.addAll(localFiles)
|
||||
send(localFiles)
|
||||
|
||||
val cloudFiles = withContext(Dispatchers.IO) {
|
||||
delay(300)
|
||||
listOf(
|
||||
async { OneDriveFile.search(context, query) },
|
||||
async { GDriveFile.search(context, query) },
|
||||
async { NextcloudFile.search(context, query, nextcloudClient) },
|
||||
async { OwncloudFile.search(context, query, owncloudClient) }
|
||||
).awaitAll().flatten()
|
||||
}
|
||||
yield()
|
||||
files.addAll(cloudFiles.filter { !hiddenItems.contains(it.key) })
|
||||
send(files)
|
||||
}
|
||||
yield()
|
||||
allFiles.value = localFiles + cloudFiles
|
||||
}
|
||||
|
||||
fun deleteFile(file: File) {
|
||||
override suspend fun deleteFile(file: File) {
|
||||
if (file.isDeletable) {
|
||||
scope.launch {
|
||||
file.delete(context)
|
||||
allFiles.value = allFiles.value?.filter { it != file }
|
||||
}
|
||||
file.delete(context)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,16 +1,16 @@
|
||||
package de.mm20.launcher2.files
|
||||
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import de.mm20.launcher2.search.data.File
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class FilesViewModel(
|
||||
private val filesRepository: FilesRepository
|
||||
private val filesRepository: FileRepository
|
||||
): ViewModel() {
|
||||
|
||||
|
||||
val files = filesRepository.files
|
||||
|
||||
fun deleteFile(file: File) {
|
||||
filesRepository.deleteFile(file)
|
||||
viewModelScope.launch {
|
||||
filesRepository.deleteFile(file)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,6 @@ import org.koin.androidx.viewmodel.dsl.viewModel
|
||||
import org.koin.dsl.module
|
||||
|
||||
val filesModule = module {
|
||||
single { FilesRepository(androidContext(), get()) }
|
||||
single<FileRepository> { FileRepositoryImpl(androidContext(), get()) }
|
||||
viewModel { FilesViewModel(get()) }
|
||||
}
|
||||
Reference in New Issue
Block a user