use RxAwareViewModel for more ViewModels (#1613)

* use RxAwareViewModel for more ViewModels

* fix ReportViewModel
This commit is contained in:
Konrad Pozniak 2020-01-02 18:50:58 +01:00 committed by GitHub
parent 88d59da13c
commit cdb9d87f41
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 83 additions and 115 deletions

View file

@ -4,15 +4,13 @@ import android.util.Log
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Transformations import androidx.lifecycle.Transformations
import androidx.lifecycle.ViewModel
import androidx.paging.PagedList import androidx.paging.PagedList
import com.keylesspalace.tusky.db.AccountManager import com.keylesspalace.tusky.db.AccountManager
import com.keylesspalace.tusky.db.AppDatabase import com.keylesspalace.tusky.db.AppDatabase
import com.keylesspalace.tusky.network.TimelineCases import com.keylesspalace.tusky.network.TimelineCases
import com.keylesspalace.tusky.util.Listing import com.keylesspalace.tusky.util.Listing
import com.keylesspalace.tusky.util.NetworkState import com.keylesspalace.tusky.util.NetworkState
import io.reactivex.disposables.CompositeDisposable import com.keylesspalace.tusky.util.RxAwareViewModel
import io.reactivex.rxkotlin.addTo
import io.reactivex.schedulers.Schedulers import io.reactivex.schedulers.Schedulers
import javax.inject.Inject import javax.inject.Inject
@ -21,7 +19,7 @@ class ConversationsViewModel @Inject constructor(
private val timelineCases: TimelineCases, private val timelineCases: TimelineCases,
private val database: AppDatabase, private val database: AppDatabase,
private val accountManager: AccountManager private val accountManager: AccountManager
) : ViewModel() { ) : RxAwareViewModel() {
private val repoResult = MutableLiveData<Listing<ConversationEntity>>() private val repoResult = MutableLiveData<Listing<ConversationEntity>>()
@ -29,8 +27,6 @@ class ConversationsViewModel @Inject constructor(
val networkState: LiveData<NetworkState> = Transformations.switchMap(repoResult) { it.networkState } val networkState: LiveData<NetworkState> = Transformations.switchMap(repoResult) { it.networkState }
val refreshState: LiveData<NetworkState> = Transformations.switchMap(repoResult) { it.refreshState } val refreshState: LiveData<NetworkState> = Transformations.switchMap(repoResult) { it.refreshState }
private val disposables = CompositeDisposable()
fun load() { fun load() {
val accountId = accountManager.activeAccount?.id ?: return val accountId = accountManager.activeAccount?.id ?: return
if (repoResult.value == null) { if (repoResult.value == null) {
@ -61,7 +57,7 @@ class ConversationsViewModel @Inject constructor(
.doOnError { t -> Log.w("ConversationViewModel", "Failed to favourite conversation", t) } .doOnError { t -> Log.w("ConversationViewModel", "Failed to favourite conversation", t) }
.onErrorReturnItem(0) .onErrorReturnItem(0)
.subscribe() .subscribe()
.addTo(disposables) .autoDispose()
} }
} }
@ -79,7 +75,7 @@ class ConversationsViewModel @Inject constructor(
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())
.doOnError { t -> Log.w("ConversationViewModel", "Failed to bookmark conversation", t) } .doOnError { t -> Log.w("ConversationViewModel", "Failed to bookmark conversation", t) }
.subscribe() .subscribe()
.addTo(disposables) .autoDispose()
} }
} }
@ -98,7 +94,7 @@ class ConversationsViewModel @Inject constructor(
.doOnError { t -> Log.w("ConversationViewModel", "Failed to favourite conversation", t) } .doOnError { t -> Log.w("ConversationViewModel", "Failed to favourite conversation", t) }
.onErrorReturnItem(0) .onErrorReturnItem(0)
.subscribe() .subscribe()
.addTo(disposables) .autoDispose()
} }
} }
@ -150,8 +146,4 @@ class ConversationsViewModel @Inject constructor(
.subscribe() .subscribe()
} }
override fun onCleared() {
disposables.dispose()
}
} }

View file

@ -18,7 +18,6 @@ package com.keylesspalace.tusky.components.report
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Transformations import androidx.lifecycle.Transformations
import androidx.lifecycle.ViewModel
import androidx.paging.PagedList import androidx.paging.PagedList
import com.keylesspalace.tusky.components.report.adapter.StatusesRepository import com.keylesspalace.tusky.components.report.adapter.StatusesRepository
import com.keylesspalace.tusky.components.report.model.StatusViewState import com.keylesspalace.tusky.components.report.model.StatusViewState
@ -26,16 +25,13 @@ import com.keylesspalace.tusky.entity.Relationship
import com.keylesspalace.tusky.entity.Status import com.keylesspalace.tusky.entity.Status
import com.keylesspalace.tusky.network.MastodonApi import com.keylesspalace.tusky.network.MastodonApi
import com.keylesspalace.tusky.util.* import com.keylesspalace.tusky.util.*
import io.reactivex.Single
import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.schedulers.Schedulers import io.reactivex.schedulers.Schedulers
import javax.inject.Inject import javax.inject.Inject
class ReportViewModel @Inject constructor( class ReportViewModel @Inject constructor(
private val mastodonApi: MastodonApi, private val mastodonApi: MastodonApi,
private val statusesRepository: StatusesRepository) : ViewModel() { private val statusesRepository: StatusesRepository) : RxAwareViewModel() {
private val disposables = CompositeDisposable()
private val navigationMutable = MutableLiveData<Screen>() private val navigationMutable = MutableLiveData<Screen>()
val navigation: LiveData<Screen> = navigationMutable val navigation: LiveData<Screen> = navigationMutable
@ -87,11 +83,6 @@ class ReportViewModel @Inject constructor(
repoResult.value = statusesRepository.getStatuses(accountId, statusId, disposables) repoResult.value = statusesRepository.getStatuses(accountId, statusId, disposables)
} }
override fun onCleared() {
super.onCleared()
disposables.clear()
}
fun navigateTo(screen: Screen) { fun navigateTo(screen: Screen) {
navigationMutable.value = screen navigationMutable.value = screen
} }
@ -105,19 +96,19 @@ class ReportViewModel @Inject constructor(
val ids = listOf(accountId) val ids = listOf(accountId)
muteStateMutable.value = Loading() muteStateMutable.value = Loading()
blockStateMutable.value = Loading() blockStateMutable.value = Loading()
disposables.add( mastodonApi.relationshipsObservable(ids)
mastodonApi.relationshipsObservable(ids) .subscribeOn(Schedulers.io())
.subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread())
.observeOn(AndroidSchedulers.mainThread()) .subscribe(
.subscribe( { data ->
{ data -> updateRelationship(data.getOrNull(0))
updateRelationship(data.getOrNull(0))
}, },
{ {
updateRelationship(null) updateRelationship(null)
} }
)) )
.autoDispose()
} }
@ -132,62 +123,61 @@ class ReportViewModel @Inject constructor(
} }
fun toggleMute() { fun toggleMute() {
val single: Single<Relationship> = if (muteStateMutable.value?.data == true) { if (muteStateMutable.value?.data == true) {
mastodonApi.unmuteAccountObservable(accountId) mastodonApi.unmuteAccountObservable(accountId)
} else { } else {
mastodonApi.muteAccountObservable(accountId) mastodonApi.muteAccountObservable(accountId)
} }
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
{ relationship ->
muteStateMutable.value = Success(relationship?.muting == true)
},
{ error ->
muteStateMutable.value = Error(false, error.message)
}
).autoDispose()
muteStateMutable.value = Loading() muteStateMutable.value = Loading()
disposables.add(
single
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
{ relationship ->
muteStateMutable.value = Success(relationship?.muting == true)
},
{ error ->
muteStateMutable.value = Error(false, error.message)
}
))
} }
fun toggleBlock() { fun toggleBlock() {
val single: Single<Relationship> = if (blockStateMutable.value?.data == true) { if (blockStateMutable.value?.data == true) {
mastodonApi.unblockAccountObservable(accountId) mastodonApi.unblockAccountObservable(accountId)
} else { } else {
mastodonApi.blockAccountObservable(accountId) mastodonApi.blockAccountObservable(accountId)
} }
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
{ relationship ->
blockStateMutable.value = Success(relationship?.blocking == true)
},
{ error ->
blockStateMutable.value = Error(false, error.message)
}
)
.autoDispose()
blockStateMutable.value = Loading() blockStateMutable.value = Loading()
disposables.add(
single
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
{ relationship ->
blockStateMutable.value = Success(relationship?.blocking == true)
},
{ error ->
blockStateMutable.value = Error(false, error.message)
}
))
} }
fun doReport() { fun doReport() {
reportingStateMutable.value = Loading() reportingStateMutable.value = Loading()
disposables.add( mastodonApi.reportObservable(accountId, selectedIds.toList(), reportNote, if (isRemoteAccount) isRemoteNotify else null)
mastodonApi.reportObservable(accountId, selectedIds.toList(), reportNote, if (isRemoteAccount) isRemoteNotify else null) .subscribeOn(Schedulers.io())
.subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread())
.observeOn(AndroidSchedulers.mainThread()) .subscribe(
.subscribe( {
{ reportingStateMutable.value = Success(true)
reportingStateMutable.value = Success(true) },
}, { error ->
{ error -> reportingStateMutable.value = Error(cause = error)
reportingStateMutable.value = Error(cause = error) }
} )
) .autoDispose()
)
} }
fun retryStatusLoad() { fun retryStatusLoad() {

View file

@ -16,7 +16,6 @@
package com.keylesspalace.tusky.components.scheduled package com.keylesspalace.tusky.components.scheduled
import android.util.Log import android.util.Log
import androidx.lifecycle.ViewModel
import androidx.paging.Config import androidx.paging.Config
import androidx.paging.toLiveData import androidx.paging.toLiveData
import com.keylesspalace.tusky.appstore.EventHub import com.keylesspalace.tusky.appstore.EventHub
@ -25,8 +24,6 @@ import com.keylesspalace.tusky.entity.ScheduledStatus
import com.keylesspalace.tusky.network.MastodonApi import com.keylesspalace.tusky.network.MastodonApi
import com.keylesspalace.tusky.util.RxAwareViewModel import com.keylesspalace.tusky.util.RxAwareViewModel
import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.rxkotlin.addTo
import javax.inject.Inject import javax.inject.Inject
class ScheduledTootViewModel @Inject constructor( class ScheduledTootViewModel @Inject constructor(

View file

@ -4,7 +4,6 @@ import android.util.Log
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Transformations import androidx.lifecycle.Transformations
import androidx.lifecycle.ViewModel
import androidx.paging.PagedList import androidx.paging.PagedList
import com.keylesspalace.tusky.components.search.adapter.SearchRepository import com.keylesspalace.tusky.components.search.adapter.SearchRepository
import com.keylesspalace.tusky.db.AccountEntity import com.keylesspalace.tusky.db.AccountEntity
@ -14,18 +13,17 @@ import com.keylesspalace.tusky.network.MastodonApi
import com.keylesspalace.tusky.network.TimelineCases import com.keylesspalace.tusky.network.TimelineCases
import com.keylesspalace.tusky.util.Listing import com.keylesspalace.tusky.util.Listing
import com.keylesspalace.tusky.util.NetworkState import com.keylesspalace.tusky.util.NetworkState
import com.keylesspalace.tusky.util.RxAwareViewModel
import com.keylesspalace.tusky.util.ViewDataUtils import com.keylesspalace.tusky.util.ViewDataUtils
import com.keylesspalace.tusky.viewdata.StatusViewData import com.keylesspalace.tusky.viewdata.StatusViewData
import io.reactivex.Single import io.reactivex.Single
import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.rxkotlin.addTo
import javax.inject.Inject import javax.inject.Inject
class SearchViewModel @Inject constructor( class SearchViewModel @Inject constructor(
mastodonApi: MastodonApi, mastodonApi: MastodonApi,
private val timelineCases: TimelineCases, private val timelineCases: TimelineCases,
private val accountManager: AccountManager) : ViewModel() { private val accountManager: AccountManager) : RxAwareViewModel() {
var currentQuery: String = "" var currentQuery: String = ""
@ -37,7 +35,6 @@ class SearchViewModel @Inject constructor(
val mediaPreviewEnabled: Boolean val mediaPreviewEnabled: Boolean
get() = activeAccount?.mediaPreviewEnabled ?: false get() = activeAccount?.mediaPreviewEnabled ?: false
private val disposables = CompositeDisposable()
private val statusesRepository = SearchRepository<Pair<Status, StatusViewData.Concrete>>(mastodonApi) private val statusesRepository = SearchRepository<Pair<Status, StatusViewData.Concrete>>(mastodonApi)
private val accountsRepository = SearchRepository<Account>(mastodonApi) private val accountsRepository = SearchRepository<Account>(mastodonApi)
@ -83,11 +80,6 @@ class SearchViewModel @Inject constructor(
} }
override fun onCleared() {
super.onCleared()
disposables.clear()
}
fun removeItem(status: Pair<Status, StatusViewData.Concrete>) { fun removeItem(status: Pair<Status, StatusViewData.Concrete>) {
timelineCases.delete(status.first.id) timelineCases.delete(status.first.id)
.subscribe({ .subscribe({
@ -96,7 +88,7 @@ class SearchViewModel @Inject constructor(
}, { }, {
err -> Log.d(TAG, "Failed to delete status", err) err -> Log.d(TAG, "Failed to delete status", err)
}) })
.addTo(disposables) .autoDispose()
} }
@ -110,13 +102,13 @@ class SearchViewModel @Inject constructor(
} }
fun reblog(status: Pair<Status, StatusViewData.Concrete>, reblog: Boolean) { fun reblog(status: Pair<Status, StatusViewData.Concrete>, reblog: Boolean) {
disposables.add(timelineCases.reblog(status.first, reblog) timelineCases.reblog(status.first, reblog)
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe( .subscribe(
{ setRebloggedForStatus(status, reblog) }, { setRebloggedForStatus(status, reblog) },
{ err -> Log.d(TAG, "Failed to reblog status ${status.first.id}", err) } { err -> Log.d(TAG, "Failed to reblog status ${status.first.id}", err) }
) )
) .autoDispose()
} }
private fun setRebloggedForStatus(status: Pair<Status, StatusViewData.Concrete>, reblog: Boolean) { private fun setRebloggedForStatus(status: Pair<Status, StatusViewData.Concrete>, reblog: Boolean) {
@ -152,7 +144,7 @@ class SearchViewModel @Inject constructor(
fun voteInPoll(status: Pair<Status, StatusViewData.Concrete>, choices: MutableList<Int>) { fun voteInPoll(status: Pair<Status, StatusViewData.Concrete>, choices: MutableList<Int>) {
val votedPoll = status.first.actionableStatus.poll!!.votedCopy(choices) val votedPoll = status.first.actionableStatus.poll!!.votedCopy(choices)
updateStatus(status, votedPoll) updateStatus(status, votedPoll)
disposables.add(timelineCases.voteInPoll(status.first, choices) timelineCases.voteInPoll(status.first, choices)
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe( .subscribe(
{ newPoll -> updateStatus(status, newPoll) }, { newPoll -> updateStatus(status, newPoll) },
@ -160,7 +152,8 @@ class SearchViewModel @Inject constructor(
Log.d(TAG, Log.d(TAG,
"Failed to vote in poll: ${status.first.id}", t) "Failed to vote in poll: ${status.first.id}", t)
} }
)) )
.autoDispose()
} }
private fun updateStatus(status: Pair<Status, StatusViewData.Concrete>, newPoll: Poll) { private fun updateStatus(status: Pair<Status, StatusViewData.Concrete>, newPoll: Poll) {
@ -182,9 +175,10 @@ class SearchViewModel @Inject constructor(
loadedStatuses[idx] = newPair loadedStatuses[idx] = newPair
repoResultStatus.value?.refresh?.invoke() repoResultStatus.value?.refresh?.invoke()
} }
disposables.add(timelineCases.favourite(status.first, isFavorited) timelineCases.favourite(status.first, isFavorited)
.onErrorReturnItem(status.first) .onErrorReturnItem(status.first)
.subscribe()) .subscribe()
.autoDispose()
} }
fun bookmark(status: Pair<Status, StatusViewData.Concrete>, isBookmarked: Boolean) { fun bookmark(status: Pair<Status, StatusViewData.Concrete>, isBookmarked: Boolean) {
@ -194,9 +188,10 @@ class SearchViewModel @Inject constructor(
loadedStatuses[idx] = newPair loadedStatuses[idx] = newPair
repoResultStatus.value?.refresh?.invoke() repoResultStatus.value?.refresh?.invoke()
} }
disposables.add(timelineCases.favourite(status.first, isBookmarked) timelineCases.favourite(status.first, isBookmarked)
.onErrorReturnItem(status.first) .onErrorReturnItem(status.first)
.subscribe()) .subscribe()
.autoDispose()
} }
fun getAllAccountsOrderedByActive(): List<AccountEntity> { fun getAllAccountsOrderedByActive(): List<AccountEntity> {

View file

@ -17,26 +17,23 @@
package com.keylesspalace.tusky.viewmodel package com.keylesspalace.tusky.viewmodel
import android.util.Log import android.util.Log
import androidx.lifecycle.ViewModel
import com.keylesspalace.tusky.entity.Account import com.keylesspalace.tusky.entity.Account
import com.keylesspalace.tusky.network.MastodonApi import com.keylesspalace.tusky.network.MastodonApi
import com.keylesspalace.tusky.util.Either import com.keylesspalace.tusky.util.Either
import com.keylesspalace.tusky.util.Either.Left import com.keylesspalace.tusky.util.Either.Left
import com.keylesspalace.tusky.util.Either.Right import com.keylesspalace.tusky.util.Either.Right
import com.keylesspalace.tusky.util.RxAwareViewModel
import com.keylesspalace.tusky.util.withoutFirstWhich import com.keylesspalace.tusky.util.withoutFirstWhich
import io.reactivex.Observable import io.reactivex.Observable
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.rxkotlin.addTo
import io.reactivex.subjects.BehaviorSubject import io.reactivex.subjects.BehaviorSubject
import javax.inject.Inject import javax.inject.Inject
data class State(val accounts: Either<Throwable, List<Account>>, val searchResult: List<Account>?) data class State(val accounts: Either<Throwable, List<Account>>, val searchResult: List<Account>?)
class AccountsInListViewModel @Inject constructor(private val api: MastodonApi) : ViewModel() { class AccountsInListViewModel @Inject constructor(private val api: MastodonApi) : RxAwareViewModel() {
val state: Observable<State> get() = _state val state: Observable<State> get() = _state
private val _state = BehaviorSubject.createDefault(State(Right(listOf()), null)) private val _state = BehaviorSubject.createDefault(State(Right(listOf()), null))
private val disposable = CompositeDisposable()
fun load(listId: String) { fun load(listId: String) {
val state = _state.value!! val state = _state.value!!
@ -45,7 +42,7 @@ class AccountsInListViewModel @Inject constructor(private val api: MastodonApi)
updateState { copy(accounts = Right(accounts)) } updateState { copy(accounts = Right(accounts)) }
}, { e -> }, { e ->
updateState { copy(accounts = Left(e)) } updateState { copy(accounts = Left(e)) }
}).addTo(disposable) }).autoDispose()
} }
} }
@ -59,7 +56,7 @@ class AccountsInListViewModel @Inject constructor(private val api: MastodonApi)
Log.i(javaClass.simpleName, Log.i(javaClass.simpleName,
"Failed to add account to the list: ${account.username}") "Failed to add account to the list: ${account.username}")
}) })
.addTo(disposable) .autoDispose()
} }
fun deleteAccountFromList(listId: String, accountId: String) { fun deleteAccountFromList(listId: String, accountId: String) {
@ -73,7 +70,7 @@ class AccountsInListViewModel @Inject constructor(private val api: MastodonApi)
}, { }, {
Log.i(javaClass.simpleName, "Failed to remove account from thelist: $accountId") Log.i(javaClass.simpleName, "Failed to remove account from thelist: $accountId")
}) })
.addTo(disposable) .autoDispose()
} }
fun search(query: String) { fun search(query: String) {
@ -85,7 +82,7 @@ class AccountsInListViewModel @Inject constructor(private val api: MastodonApi)
updateState { copy(searchResult = result) } updateState { copy(searchResult = result) }
}, { }, {
updateState { copy(searchResult = listOf()) } updateState { copy(searchResult = listOf()) }
}).addTo(disposable) }).autoDispose()
} }
} }

View file

@ -16,14 +16,12 @@
package com.keylesspalace.tusky.viewmodel package com.keylesspalace.tusky.viewmodel
import androidx.lifecycle.ViewModel
import com.keylesspalace.tusky.entity.MastoList import com.keylesspalace.tusky.entity.MastoList
import com.keylesspalace.tusky.network.MastodonApi import com.keylesspalace.tusky.network.MastodonApi
import com.keylesspalace.tusky.util.withoutFirstWhich import com.keylesspalace.tusky.util.RxAwareViewModel
import com.keylesspalace.tusky.util.replacedFirstWhich import com.keylesspalace.tusky.util.replacedFirstWhich
import com.keylesspalace.tusky.util.withoutFirstWhich
import io.reactivex.Observable import io.reactivex.Observable
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.rxkotlin.addTo
import io.reactivex.subjects.BehaviorSubject import io.reactivex.subjects.BehaviorSubject
import io.reactivex.subjects.PublishSubject import io.reactivex.subjects.PublishSubject
import java.io.IOException import java.io.IOException
@ -31,7 +29,7 @@ import java.net.ConnectException
import javax.inject.Inject import javax.inject.Inject
internal class ListsViewModel @Inject constructor(private val api: MastodonApi) : ViewModel() { internal class ListsViewModel @Inject constructor(private val api: MastodonApi) : RxAwareViewModel() {
enum class LoadingState { enum class LoadingState {
INITIAL, LOADING, LOADED, ERROR_NETWORK, ERROR_OTHER INITIAL, LOADING, LOADED, ERROR_NETWORK, ERROR_OTHER
} }
@ -46,7 +44,6 @@ internal class ListsViewModel @Inject constructor(private val api: MastodonApi)
val events: Observable<Event> get() = _events val events: Observable<Event> get() = _events
private val _state = BehaviorSubject.createDefault(State(listOf(), LoadingState.INITIAL)) private val _state = BehaviorSubject.createDefault(State(listOf(), LoadingState.INITIAL))
private val _events = PublishSubject.create<Event>() private val _events = PublishSubject.create<Event>()
private val disposable = CompositeDisposable()
fun retryLoading() { fun retryLoading() {
loadIfNeeded() loadIfNeeded()
@ -71,7 +68,7 @@ internal class ListsViewModel @Inject constructor(private val api: MastodonApi)
copy(loadingState = if (err is IOException || err is ConnectException) copy(loadingState = if (err is IOException || err is ConnectException)
LoadingState.ERROR_NETWORK else LoadingState.ERROR_OTHER) LoadingState.ERROR_NETWORK else LoadingState.ERROR_OTHER)
} }
}).addTo(disposable) }).autoDispose()
} }
fun createNewList(listName: String) { fun createNewList(listName: String) {
@ -81,7 +78,7 @@ internal class ListsViewModel @Inject constructor(private val api: MastodonApi)
} }
}, { }, {
sendEvent(Event.CREATE_ERROR) sendEvent(Event.CREATE_ERROR)
}).addTo(disposable) }).autoDispose()
} }
fun renameList(listId: String, listName: String) { fun renameList(listId: String, listName: String) {
@ -91,7 +88,7 @@ internal class ListsViewModel @Inject constructor(private val api: MastodonApi)
} }
}, { }, {
sendEvent(Event.RENAME_ERROR) sendEvent(Event.RENAME_ERROR)
}).addTo(disposable) }).autoDispose()
} }
fun deleteList(listId: String) { fun deleteList(listId: String) {
@ -101,7 +98,7 @@ internal class ListsViewModel @Inject constructor(private val api: MastodonApi)
} }
}, { }, {
sendEvent(Event.DELETE_ERROR) sendEvent(Event.DELETE_ERROR)
}).addTo(disposable) }).autoDispose()
} }
private inline fun updateState(crossinline fn: State.() -> State) { private inline fun updateState(crossinline fn: State.() -> State) {