use RxAwareViewModel for more ViewModels (#1613)
* use RxAwareViewModel for more ViewModels * fix ReportViewModel
This commit is contained in:
parent
88d59da13c
commit
cdb9d87f41
|
@ -4,15 +4,13 @@ import android.util.Log
|
|||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.Transformations
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.paging.PagedList
|
||||
import com.keylesspalace.tusky.db.AccountManager
|
||||
import com.keylesspalace.tusky.db.AppDatabase
|
||||
import com.keylesspalace.tusky.network.TimelineCases
|
||||
import com.keylesspalace.tusky.util.Listing
|
||||
import com.keylesspalace.tusky.util.NetworkState
|
||||
import io.reactivex.disposables.CompositeDisposable
|
||||
import io.reactivex.rxkotlin.addTo
|
||||
import com.keylesspalace.tusky.util.RxAwareViewModel
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import javax.inject.Inject
|
||||
|
||||
|
@ -21,7 +19,7 @@ class ConversationsViewModel @Inject constructor(
|
|||
private val timelineCases: TimelineCases,
|
||||
private val database: AppDatabase,
|
||||
private val accountManager: AccountManager
|
||||
) : ViewModel() {
|
||||
) : RxAwareViewModel() {
|
||||
|
||||
private val repoResult = MutableLiveData<Listing<ConversationEntity>>()
|
||||
|
||||
|
@ -29,8 +27,6 @@ class ConversationsViewModel @Inject constructor(
|
|||
val networkState: LiveData<NetworkState> = Transformations.switchMap(repoResult) { it.networkState }
|
||||
val refreshState: LiveData<NetworkState> = Transformations.switchMap(repoResult) { it.refreshState }
|
||||
|
||||
private val disposables = CompositeDisposable()
|
||||
|
||||
fun load() {
|
||||
val accountId = accountManager.activeAccount?.id ?: return
|
||||
if (repoResult.value == null) {
|
||||
|
@ -61,7 +57,7 @@ class ConversationsViewModel @Inject constructor(
|
|||
.doOnError { t -> Log.w("ConversationViewModel", "Failed to favourite conversation", t) }
|
||||
.onErrorReturnItem(0)
|
||||
.subscribe()
|
||||
.addTo(disposables)
|
||||
.autoDispose()
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -79,7 +75,7 @@ class ConversationsViewModel @Inject constructor(
|
|||
.subscribeOn(Schedulers.io())
|
||||
.doOnError { t -> Log.w("ConversationViewModel", "Failed to bookmark conversation", t) }
|
||||
.subscribe()
|
||||
.addTo(disposables)
|
||||
.autoDispose()
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -98,7 +94,7 @@ class ConversationsViewModel @Inject constructor(
|
|||
.doOnError { t -> Log.w("ConversationViewModel", "Failed to favourite conversation", t) }
|
||||
.onErrorReturnItem(0)
|
||||
.subscribe()
|
||||
.addTo(disposables)
|
||||
.autoDispose()
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -150,8 +146,4 @@ class ConversationsViewModel @Inject constructor(
|
|||
.subscribe()
|
||||
}
|
||||
|
||||
override fun onCleared() {
|
||||
disposables.dispose()
|
||||
}
|
||||
|
||||
}
|
|
@ -18,7 +18,6 @@ package com.keylesspalace.tusky.components.report
|
|||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.Transformations
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.paging.PagedList
|
||||
import com.keylesspalace.tusky.components.report.adapter.StatusesRepository
|
||||
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.network.MastodonApi
|
||||
import com.keylesspalace.tusky.util.*
|
||||
import io.reactivex.Single
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.disposables.CompositeDisposable
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import javax.inject.Inject
|
||||
|
||||
class ReportViewModel @Inject constructor(
|
||||
private val mastodonApi: MastodonApi,
|
||||
private val statusesRepository: StatusesRepository) : ViewModel() {
|
||||
private val disposables = CompositeDisposable()
|
||||
private val statusesRepository: StatusesRepository) : RxAwareViewModel() {
|
||||
|
||||
private val navigationMutable = MutableLiveData<Screen>()
|
||||
val navigation: LiveData<Screen> = navigationMutable
|
||||
|
@ -87,11 +83,6 @@ class ReportViewModel @Inject constructor(
|
|||
repoResult.value = statusesRepository.getStatuses(accountId, statusId, disposables)
|
||||
}
|
||||
|
||||
override fun onCleared() {
|
||||
super.onCleared()
|
||||
disposables.clear()
|
||||
}
|
||||
|
||||
fun navigateTo(screen: Screen) {
|
||||
navigationMutable.value = screen
|
||||
}
|
||||
|
@ -105,7 +96,6 @@ class ReportViewModel @Inject constructor(
|
|||
val ids = listOf(accountId)
|
||||
muteStateMutable.value = Loading()
|
||||
blockStateMutable.value = Loading()
|
||||
disposables.add(
|
||||
mastodonApi.relationshipsObservable(ids)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
|
@ -117,7 +107,8 @@ class ReportViewModel @Inject constructor(
|
|||
{
|
||||
updateRelationship(null)
|
||||
}
|
||||
))
|
||||
)
|
||||
.autoDispose()
|
||||
}
|
||||
|
||||
|
||||
|
@ -132,14 +123,11 @@ class ReportViewModel @Inject constructor(
|
|||
}
|
||||
|
||||
fun toggleMute() {
|
||||
val single: Single<Relationship> = if (muteStateMutable.value?.data == true) {
|
||||
if (muteStateMutable.value?.data == true) {
|
||||
mastodonApi.unmuteAccountObservable(accountId)
|
||||
} else {
|
||||
mastodonApi.muteAccountObservable(accountId)
|
||||
}
|
||||
muteStateMutable.value = Loading()
|
||||
disposables.add(
|
||||
single
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(
|
||||
|
@ -149,18 +137,17 @@ class ReportViewModel @Inject constructor(
|
|||
{ error ->
|
||||
muteStateMutable.value = Error(false, error.message)
|
||||
}
|
||||
))
|
||||
).autoDispose()
|
||||
|
||||
muteStateMutable.value = Loading()
|
||||
}
|
||||
|
||||
fun toggleBlock() {
|
||||
val single: Single<Relationship> = if (blockStateMutable.value?.data == true) {
|
||||
if (blockStateMutable.value?.data == true) {
|
||||
mastodonApi.unblockAccountObservable(accountId)
|
||||
} else {
|
||||
mastodonApi.blockAccountObservable(accountId)
|
||||
}
|
||||
blockStateMutable.value = Loading()
|
||||
disposables.add(
|
||||
single
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(
|
||||
|
@ -170,12 +157,14 @@ class ReportViewModel @Inject constructor(
|
|||
{ error ->
|
||||
blockStateMutable.value = Error(false, error.message)
|
||||
}
|
||||
))
|
||||
)
|
||||
.autoDispose()
|
||||
|
||||
blockStateMutable.value = Loading()
|
||||
}
|
||||
|
||||
fun doReport() {
|
||||
reportingStateMutable.value = Loading()
|
||||
disposables.add(
|
||||
mastodonApi.reportObservable(accountId, selectedIds.toList(), reportNote, if (isRemoteAccount) isRemoteNotify else null)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
|
@ -187,7 +176,8 @@ class ReportViewModel @Inject constructor(
|
|||
reportingStateMutable.value = Error(cause = error)
|
||||
}
|
||||
)
|
||||
)
|
||||
.autoDispose()
|
||||
|
||||
}
|
||||
|
||||
fun retryStatusLoad() {
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
package com.keylesspalace.tusky.components.scheduled
|
||||
|
||||
import android.util.Log
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.paging.Config
|
||||
import androidx.paging.toLiveData
|
||||
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.util.RxAwareViewModel
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.disposables.CompositeDisposable
|
||||
import io.reactivex.rxkotlin.addTo
|
||||
import javax.inject.Inject
|
||||
|
||||
class ScheduledTootViewModel @Inject constructor(
|
||||
|
|
|
@ -4,7 +4,6 @@ import android.util.Log
|
|||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.Transformations
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.paging.PagedList
|
||||
import com.keylesspalace.tusky.components.search.adapter.SearchRepository
|
||||
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.util.Listing
|
||||
import com.keylesspalace.tusky.util.NetworkState
|
||||
import com.keylesspalace.tusky.util.RxAwareViewModel
|
||||
import com.keylesspalace.tusky.util.ViewDataUtils
|
||||
import com.keylesspalace.tusky.viewdata.StatusViewData
|
||||
import io.reactivex.Single
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.disposables.CompositeDisposable
|
||||
import io.reactivex.rxkotlin.addTo
|
||||
import javax.inject.Inject
|
||||
|
||||
class SearchViewModel @Inject constructor(
|
||||
mastodonApi: MastodonApi,
|
||||
private val timelineCases: TimelineCases,
|
||||
private val accountManager: AccountManager) : ViewModel() {
|
||||
private val accountManager: AccountManager) : RxAwareViewModel() {
|
||||
|
||||
var currentQuery: String = ""
|
||||
|
||||
|
@ -37,7 +35,6 @@ class SearchViewModel @Inject constructor(
|
|||
|
||||
val mediaPreviewEnabled: Boolean
|
||||
get() = activeAccount?.mediaPreviewEnabled ?: false
|
||||
private val disposables = CompositeDisposable()
|
||||
|
||||
private val statusesRepository = SearchRepository<Pair<Status, StatusViewData.Concrete>>(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>) {
|
||||
timelineCases.delete(status.first.id)
|
||||
.subscribe({
|
||||
|
@ -96,7 +88,7 @@ class SearchViewModel @Inject constructor(
|
|||
}, {
|
||||
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) {
|
||||
disposables.add(timelineCases.reblog(status.first, reblog)
|
||||
timelineCases.reblog(status.first, reblog)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(
|
||||
{ setRebloggedForStatus(status, reblog) },
|
||||
{ err -> Log.d(TAG, "Failed to reblog status ${status.first.id}", err) }
|
||||
)
|
||||
)
|
||||
.autoDispose()
|
||||
}
|
||||
|
||||
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>) {
|
||||
val votedPoll = status.first.actionableStatus.poll!!.votedCopy(choices)
|
||||
updateStatus(status, votedPoll)
|
||||
disposables.add(timelineCases.voteInPoll(status.first, choices)
|
||||
timelineCases.voteInPoll(status.first, choices)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(
|
||||
{ newPoll -> updateStatus(status, newPoll) },
|
||||
|
@ -160,7 +152,8 @@ class SearchViewModel @Inject constructor(
|
|||
Log.d(TAG,
|
||||
"Failed to vote in poll: ${status.first.id}", t)
|
||||
}
|
||||
))
|
||||
)
|
||||
.autoDispose()
|
||||
}
|
||||
|
||||
private fun updateStatus(status: Pair<Status, StatusViewData.Concrete>, newPoll: Poll) {
|
||||
|
@ -182,9 +175,10 @@ class SearchViewModel @Inject constructor(
|
|||
loadedStatuses[idx] = newPair
|
||||
repoResultStatus.value?.refresh?.invoke()
|
||||
}
|
||||
disposables.add(timelineCases.favourite(status.first, isFavorited)
|
||||
timelineCases.favourite(status.first, isFavorited)
|
||||
.onErrorReturnItem(status.first)
|
||||
.subscribe())
|
||||
.subscribe()
|
||||
.autoDispose()
|
||||
}
|
||||
|
||||
fun bookmark(status: Pair<Status, StatusViewData.Concrete>, isBookmarked: Boolean) {
|
||||
|
@ -194,9 +188,10 @@ class SearchViewModel @Inject constructor(
|
|||
loadedStatuses[idx] = newPair
|
||||
repoResultStatus.value?.refresh?.invoke()
|
||||
}
|
||||
disposables.add(timelineCases.favourite(status.first, isBookmarked)
|
||||
timelineCases.favourite(status.first, isBookmarked)
|
||||
.onErrorReturnItem(status.first)
|
||||
.subscribe())
|
||||
.subscribe()
|
||||
.autoDispose()
|
||||
}
|
||||
|
||||
fun getAllAccountsOrderedByActive(): List<AccountEntity> {
|
||||
|
|
|
@ -17,26 +17,23 @@
|
|||
package com.keylesspalace.tusky.viewmodel
|
||||
|
||||
import android.util.Log
|
||||
import androidx.lifecycle.ViewModel
|
||||
import com.keylesspalace.tusky.entity.Account
|
||||
import com.keylesspalace.tusky.network.MastodonApi
|
||||
import com.keylesspalace.tusky.util.Either
|
||||
import com.keylesspalace.tusky.util.Either.Left
|
||||
import com.keylesspalace.tusky.util.Either.Right
|
||||
import com.keylesspalace.tusky.util.RxAwareViewModel
|
||||
import com.keylesspalace.tusky.util.withoutFirstWhich
|
||||
import io.reactivex.Observable
|
||||
import io.reactivex.disposables.CompositeDisposable
|
||||
import io.reactivex.rxkotlin.addTo
|
||||
import io.reactivex.subjects.BehaviorSubject
|
||||
import javax.inject.Inject
|
||||
|
||||
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
|
||||
private val _state = BehaviorSubject.createDefault(State(Right(listOf()), null))
|
||||
private val disposable = CompositeDisposable()
|
||||
|
||||
fun load(listId: String) {
|
||||
val state = _state.value!!
|
||||
|
@ -45,7 +42,7 @@ class AccountsInListViewModel @Inject constructor(private val api: MastodonApi)
|
|||
updateState { copy(accounts = Right(accounts)) }
|
||||
}, { 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,
|
||||
"Failed to add account to the list: ${account.username}")
|
||||
})
|
||||
.addTo(disposable)
|
||||
.autoDispose()
|
||||
}
|
||||
|
||||
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")
|
||||
})
|
||||
.addTo(disposable)
|
||||
.autoDispose()
|
||||
}
|
||||
|
||||
fun search(query: String) {
|
||||
|
@ -85,7 +82,7 @@ class AccountsInListViewModel @Inject constructor(private val api: MastodonApi)
|
|||
updateState { copy(searchResult = result) }
|
||||
}, {
|
||||
updateState { copy(searchResult = listOf()) }
|
||||
}).addTo(disposable)
|
||||
}).autoDispose()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,14 +16,12 @@
|
|||
|
||||
package com.keylesspalace.tusky.viewmodel
|
||||
|
||||
import androidx.lifecycle.ViewModel
|
||||
import com.keylesspalace.tusky.entity.MastoList
|
||||
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.withoutFirstWhich
|
||||
import io.reactivex.Observable
|
||||
import io.reactivex.disposables.CompositeDisposable
|
||||
import io.reactivex.rxkotlin.addTo
|
||||
import io.reactivex.subjects.BehaviorSubject
|
||||
import io.reactivex.subjects.PublishSubject
|
||||
import java.io.IOException
|
||||
|
@ -31,7 +29,7 @@ import java.net.ConnectException
|
|||
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 {
|
||||
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
|
||||
private val _state = BehaviorSubject.createDefault(State(listOf(), LoadingState.INITIAL))
|
||||
private val _events = PublishSubject.create<Event>()
|
||||
private val disposable = CompositeDisposable()
|
||||
|
||||
fun retryLoading() {
|
||||
loadIfNeeded()
|
||||
|
@ -71,7 +68,7 @@ internal class ListsViewModel @Inject constructor(private val api: MastodonApi)
|
|||
copy(loadingState = if (err is IOException || err is ConnectException)
|
||||
LoadingState.ERROR_NETWORK else LoadingState.ERROR_OTHER)
|
||||
}
|
||||
}).addTo(disposable)
|
||||
}).autoDispose()
|
||||
}
|
||||
|
||||
fun createNewList(listName: String) {
|
||||
|
@ -81,7 +78,7 @@ internal class ListsViewModel @Inject constructor(private val api: MastodonApi)
|
|||
}
|
||||
}, {
|
||||
sendEvent(Event.CREATE_ERROR)
|
||||
}).addTo(disposable)
|
||||
}).autoDispose()
|
||||
}
|
||||
|
||||
fun renameList(listId: String, listName: String) {
|
||||
|
@ -91,7 +88,7 @@ internal class ListsViewModel @Inject constructor(private val api: MastodonApi)
|
|||
}
|
||||
}, {
|
||||
sendEvent(Event.RENAME_ERROR)
|
||||
}).addTo(disposable)
|
||||
}).autoDispose()
|
||||
}
|
||||
|
||||
fun deleteList(listId: String) {
|
||||
|
@ -101,7 +98,7 @@ internal class ListsViewModel @Inject constructor(private val api: MastodonApi)
|
|||
}
|
||||
}, {
|
||||
sendEvent(Event.DELETE_ERROR)
|
||||
}).addTo(disposable)
|
||||
}).autoDispose()
|
||||
}
|
||||
|
||||
private inline fun updateState(crossinline fn: State.() -> State) {
|
||||
|
|
Loading…
Reference in New Issue