Refactor search, favorites and calendar widget
This commit is contained in:
@@ -1,53 +0,0 @@
|
||||
package de.mm20.launcher2.search
|
||||
|
||||
import kotlinx.coroutines.*
|
||||
import org.koin.core.component.KoinComponent
|
||||
import org.koin.core.component.inject
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
import kotlin.coroutines.EmptyCoroutineContext
|
||||
|
||||
abstract class BaseSearchableRepository: KoinComponent {
|
||||
|
||||
private val scope = CoroutineScope(Job() + Dispatchers.Main)
|
||||
val searchRepository: SearchRepository by inject()
|
||||
private val searchQuery = searchRepository.currentQuery
|
||||
|
||||
init {
|
||||
searchQuery.observeForever {
|
||||
onQueryChange(it)
|
||||
}
|
||||
}
|
||||
|
||||
protected open fun onCancel() {
|
||||
|
||||
}
|
||||
|
||||
protected fun launch(
|
||||
context: CoroutineContext = EmptyCoroutineContext,
|
||||
start: CoroutineStart = CoroutineStart.DEFAULT,
|
||||
block: suspend CoroutineScope.() -> Unit
|
||||
) {
|
||||
scope.launch(context, start, block)
|
||||
}
|
||||
|
||||
private var searchJob: Job? = null
|
||||
private fun onQueryChange(query: String) {
|
||||
scope.launch {
|
||||
onCancel()
|
||||
searchJob?.takeIf { !it.isCompleted || !it.isCancelled }?.cancelAndJoin()
|
||||
searchJob = scope.launch {
|
||||
searchRepository.startSearch()
|
||||
search(query)
|
||||
}.also {
|
||||
it.invokeOnCompletion { searchRepository.endSearch() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the query string changes. This method should change the current data presented
|
||||
* by this SearchableRepository.
|
||||
*/
|
||||
protected abstract suspend fun search(query: String)
|
||||
|
||||
}
|
||||
@@ -1,12 +1,9 @@
|
||||
package de.mm20.launcher2.search
|
||||
|
||||
import org.koin.android.ext.koin.androidContext
|
||||
import org.koin.androidx.viewmodel.dsl.viewModel
|
||||
import org.koin.dsl.module
|
||||
|
||||
val searchModule = module {
|
||||
single { SearchRepository() }
|
||||
viewModel { SearchViewModel(get()) }
|
||||
single { WebsearchRepository(androidContext()) }
|
||||
single<WebsearchRepository> { WebsearchRepositoryImpl(get()) }
|
||||
viewModel { WebsearchViewModel(get()) }
|
||||
}
|
||||
@@ -22,9 +22,4 @@ class SearchRepository {
|
||||
}
|
||||
}
|
||||
|
||||
fun endSearch() {
|
||||
synchronized(runningSearches) {
|
||||
runningSearches--
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
package de.mm20.launcher2.search
|
||||
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
|
||||
class SearchViewModel(
|
||||
private val searchRepository: SearchRepository
|
||||
) : ViewModel() {
|
||||
|
||||
val isSearching: LiveData<Boolean> = searchRepository.isSearching
|
||||
|
||||
fun search(query: String) {
|
||||
searchRepository.currentQuery.value = query
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,54 +1,56 @@
|
||||
package de.mm20.launcher2.search
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.graphics.Color
|
||||
import androidx.lifecycle.MediatorLiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import de.mm20.launcher2.database.AppDatabase
|
||||
import de.mm20.launcher2.search.data.Websearch
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.withContext
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.flow.*
|
||||
|
||||
class WebsearchRepository(val context: Context) : BaseSearchableRepository() {
|
||||
interface WebsearchRepository {
|
||||
fun search(query: String): Flow<List<Websearch>>
|
||||
|
||||
val websearches = MutableLiveData<List<Websearch>>(emptyList())
|
||||
fun getWebsearches(): Flow<List<Websearch>>
|
||||
|
||||
val allWebsearches = MediatorLiveData<List<Websearch>>()
|
||||
fun insertWebsearch(websearch: Websearch)
|
||||
fun deleteWebsearch(websearch: Websearch)
|
||||
}
|
||||
|
||||
init {
|
||||
val databaseWebsearches = AppDatabase.getInstance(context).searchDao().getWebSearchesLiveData()
|
||||
allWebsearches.addSource(databaseWebsearches) {
|
||||
allWebsearches.value = it.map { Websearch(it) }
|
||||
}
|
||||
}
|
||||
class WebsearchRepositoryImpl(
|
||||
private val database: AppDatabase
|
||||
) : WebsearchRepository {
|
||||
|
||||
override suspend fun search(query: String) {
|
||||
private val scope = CoroutineScope(Job() + Dispatchers.Main)
|
||||
|
||||
override fun search(query: String): Flow<List<Websearch>> = channelFlow {
|
||||
if (query.isEmpty()) {
|
||||
websearches.value = emptyList()
|
||||
return
|
||||
send(emptyList())
|
||||
return@channelFlow
|
||||
}
|
||||
val searches = withContext(Dispatchers.IO) {
|
||||
AppDatabase.getInstance(context).searchDao().getWebSearches().map {
|
||||
Websearch(it, query)
|
||||
withContext(Dispatchers.IO) {
|
||||
database.searchDao().getWebSearches().map {
|
||||
it.map { Websearch(it, query) }
|
||||
}
|
||||
}.collectLatest {
|
||||
send(it)
|
||||
}
|
||||
websearches.value = searches
|
||||
}
|
||||
|
||||
fun insertWebsearch(websearch: Websearch) {
|
||||
launch {
|
||||
override fun getWebsearches(): Flow<List<Websearch>> =
|
||||
database.searchDao().getWebSearches().map {
|
||||
it.map { Websearch(it) }
|
||||
}
|
||||
|
||||
override fun insertWebsearch(websearch: Websearch) {
|
||||
scope.launch {
|
||||
withContext(Dispatchers.IO) {
|
||||
AppDatabase.getInstance(context).searchDao().insertWebsearch(websearch.toDatabaseEntity())
|
||||
database.searchDao().insertWebsearch(websearch.toDatabaseEntity())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun deleteWebsearch(websearch: Websearch) {
|
||||
launch {
|
||||
override fun deleteWebsearch(websearch: Websearch) {
|
||||
scope.launch {
|
||||
withContext(Dispatchers.IO) {
|
||||
AppDatabase.getInstance(context).searchDao().deleteWebsearch(websearch.toDatabaseEntity())
|
||||
database.searchDao().deleteWebsearch(websearch.toDatabaseEntity())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package de.mm20.launcher2.search
|
||||
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.asLiveData
|
||||
import de.mm20.launcher2.search.data.Websearch
|
||||
|
||||
class WebsearchViewModel(
|
||||
@@ -16,7 +17,6 @@ class WebsearchViewModel(
|
||||
websearchRepository.deleteWebsearch(websearch)
|
||||
}
|
||||
|
||||
val websearches = websearchRepository.websearches
|
||||
val allWebsearches = websearchRepository.allWebsearches
|
||||
val allWebsearches = websearchRepository.getWebsearches().asLiveData()
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user