2023-03-11 13:12:50 +01:00
|
|
|
package com.keylesspalace.tusky.components.filters
|
|
|
|
|
|
|
|
import android.view.View
|
|
|
|
import androidx.lifecycle.ViewModel
|
|
|
|
import androidx.lifecycle.viewModelScope
|
|
|
|
import at.connyduck.calladapter.networkresult.fold
|
|
|
|
import com.google.android.material.snackbar.Snackbar
|
|
|
|
import com.keylesspalace.tusky.appstore.EventHub
|
|
|
|
import com.keylesspalace.tusky.appstore.PreferenceChangedEvent
|
|
|
|
import com.keylesspalace.tusky.entity.Filter
|
|
|
|
import com.keylesspalace.tusky.network.MastodonApi
|
2023-10-25 12:53:10 +02:00
|
|
|
import com.keylesspalace.tusky.util.isHttpNotFound
|
2023-03-30 19:29:42 +02:00
|
|
|
import kotlinx.coroutines.flow.Flow
|
2023-03-11 13:12:50 +01:00
|
|
|
import kotlinx.coroutines.flow.MutableStateFlow
|
|
|
|
import kotlinx.coroutines.launch
|
|
|
|
import javax.inject.Inject
|
|
|
|
|
|
|
|
class FiltersViewModel @Inject constructor(
|
|
|
|
private val api: MastodonApi,
|
|
|
|
private val eventHub: EventHub
|
|
|
|
) : ViewModel() {
|
2023-03-30 19:29:42 +02:00
|
|
|
|
|
|
|
enum class LoadingState {
|
|
|
|
INITIAL, LOADING, LOADED, ERROR_NETWORK, ERROR_OTHER
|
|
|
|
}
|
|
|
|
|
|
|
|
data class State(val filters: List<Filter>, val loadingState: LoadingState)
|
|
|
|
|
|
|
|
val state: Flow<State> get() = _state
|
|
|
|
private val _state = MutableStateFlow(State(emptyList(), LoadingState.INITIAL))
|
2023-03-11 13:12:50 +01:00
|
|
|
|
|
|
|
fun load() {
|
2023-03-30 19:29:42 +02:00
|
|
|
this@FiltersViewModel._state.value = _state.value.copy(loadingState = LoadingState.LOADING)
|
|
|
|
|
2023-03-11 13:12:50 +01:00
|
|
|
viewModelScope.launch {
|
|
|
|
api.getFilters().fold(
|
|
|
|
{ filters ->
|
2023-03-30 19:29:42 +02:00
|
|
|
this@FiltersViewModel._state.value = State(filters, LoadingState.LOADED)
|
2023-03-11 13:12:50 +01:00
|
|
|
},
|
|
|
|
{ throwable ->
|
2023-10-25 12:53:10 +02:00
|
|
|
if (throwable.isHttpNotFound()) {
|
2023-03-11 13:12:50 +01:00
|
|
|
api.getFiltersV1().fold(
|
|
|
|
{ filters ->
|
2023-03-30 19:29:42 +02:00
|
|
|
this@FiltersViewModel._state.value = State(filters.map { it.toFilter() }, LoadingState.LOADED)
|
2023-03-11 13:12:50 +01:00
|
|
|
},
|
2023-10-25 12:53:10 +02:00
|
|
|
{ _ ->
|
2023-03-30 19:29:42 +02:00
|
|
|
// TODO log errors (also below)
|
|
|
|
this@FiltersViewModel._state.value = _state.value.copy(loadingState = LoadingState.ERROR_OTHER)
|
2023-03-11 13:12:50 +01:00
|
|
|
}
|
|
|
|
)
|
2023-03-30 19:29:42 +02:00
|
|
|
this@FiltersViewModel._state.value = _state.value.copy(loadingState = LoadingState.ERROR_OTHER)
|
2023-03-11 13:12:50 +01:00
|
|
|
} else {
|
2023-03-30 19:29:42 +02:00
|
|
|
this@FiltersViewModel._state.value = _state.value.copy(loadingState = LoadingState.ERROR_NETWORK)
|
2023-03-11 13:12:50 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fun deleteFilter(filter: Filter, parent: View) {
|
|
|
|
viewModelScope.launch {
|
|
|
|
api.deleteFilter(filter.id).fold(
|
|
|
|
{
|
2023-03-30 19:29:42 +02:00
|
|
|
this@FiltersViewModel._state.value = State(this@FiltersViewModel._state.value.filters.filter { it.id != filter.id }, LoadingState.LOADED)
|
2023-03-11 13:12:50 +01:00
|
|
|
for (context in filter.context) {
|
|
|
|
eventHub.dispatch(PreferenceChangedEvent(context))
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{ throwable ->
|
2023-10-25 12:53:10 +02:00
|
|
|
if (throwable.isHttpNotFound()) {
|
2023-03-11 13:12:50 +01:00
|
|
|
api.deleteFilterV1(filter.id).fold(
|
|
|
|
{
|
2023-03-30 19:29:42 +02:00
|
|
|
this@FiltersViewModel._state.value = State(this@FiltersViewModel._state.value.filters.filter { it.id != filter.id }, LoadingState.LOADED)
|
2023-03-11 13:12:50 +01:00
|
|
|
},
|
|
|
|
{
|
|
|
|
Snackbar.make(parent, "Error deleting filter '${filter.title}'", Snackbar.LENGTH_SHORT).show()
|
2023-03-13 13:16:39 +01:00
|
|
|
}
|
2023-03-11 13:12:50 +01:00
|
|
|
)
|
|
|
|
} else {
|
|
|
|
Snackbar.make(parent, "Error deleting filter '${filter.title}'", Snackbar.LENGTH_SHORT).show()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|