chinwag-android/app/src/main/java/com/keylesspalace/tusky/viewmodel/AccountViewModel.kt
2018-09-15 21:51:53 +02:00

196 lines
No EOL
7.3 KiB
Kotlin

package com.keylesspalace.tusky.viewmodel
import android.arch.lifecycle.MutableLiveData
import android.arch.lifecycle.ViewModel
import com.keylesspalace.tusky.appstore.*
import com.keylesspalace.tusky.entity.Account
import com.keylesspalace.tusky.entity.Relationship
import com.keylesspalace.tusky.network.MastodonApi
import com.keylesspalace.tusky.util.Error
import com.keylesspalace.tusky.util.Loading
import com.keylesspalace.tusky.util.Resource
import com.keylesspalace.tusky.util.Success
import io.reactivex.disposables.Disposable
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import javax.inject.Inject
class AccountViewModel @Inject constructor(
private val mastodonApi: MastodonApi,
private val eventHub: EventHub
): ViewModel() {
val accountData = MutableLiveData<Resource<Account>>()
val relationshipData = MutableLiveData<Resource<Relationship>>()
private val callList: MutableList<Call<*>> = mutableListOf()
private val disposable: Disposable = eventHub.events
.subscribe { event ->
if (event is ProfileEditedEvent && event.newProfileData.id == accountData.value?.data?.id) {
accountData.postValue(Success(event.newProfileData))
}
}
fun obtainAccount(accountId: String, reload: Boolean = false) {
if(accountData.value == null || reload) {
accountData.postValue(Loading())
val call = mastodonApi.account(accountId)
call.enqueue(object : Callback<Account> {
override fun onResponse(call: Call<Account>,
response: Response<Account>) {
if (response.isSuccessful) {
accountData.postValue(Success(response.body()))
} else {
accountData.postValue(Error())
}
}
override fun onFailure(call: Call<Account>, t: Throwable) {
accountData.postValue(Error())
}
})
callList.add(call)
}
}
fun obtainRelationship(accountId: String, reload: Boolean = false) {
if(relationshipData.value == null || reload) {
relationshipData.postValue(Loading())
val ids = listOf(accountId)
val call = mastodonApi.relationships(ids)
call.enqueue(object : Callback<List<Relationship>> {
override fun onResponse(call: Call<List<Relationship>>,
response: Response<List<Relationship>>) {
val relationships = response.body()
if (response.isSuccessful && relationships != null && relationships.getOrNull(0) != null) {
val relationship = relationships[0]
relationshipData.postValue(Success(relationship))
} else {
relationshipData.postValue(Error())
}
}
override fun onFailure(call: Call<List<Relationship>>, t: Throwable) {
relationshipData.postValue(Error())
}
})
callList.add(call)
}
}
fun changeFollowState(id: String) {
val relationship = relationshipData.value?.data
if (relationship?.following == true || relationship?.requested == true) {
changeRelationship(RelationShipAction.UNFOLLOW, id)
} else {
changeRelationship(RelationShipAction.FOLLOW, id)
}
}
fun changeBlockState(id: String) {
if (relationshipData.value?.data?.blocking == true) {
changeRelationship(RelationShipAction.UNBLOCK, id)
} else {
changeRelationship(RelationShipAction.BLOCK, id)
}
}
fun changeMuteState(id: String) {
if (relationshipData.value?.data?.muting == true) {
changeRelationship(RelationShipAction.UNMUTE, id)
} else {
changeRelationship(RelationShipAction.MUTE, id)
}
}
fun changeShowReblogsState(id: String) {
if (relationshipData.value?.data?.showingReblogs == true) {
changeRelationship(RelationShipAction.FOLLOW, id, false)
} else {
changeRelationship(RelationShipAction.FOLLOW, id, true)
}
}
private fun changeRelationship(relationshipAction: RelationShipAction, id: String, showReblogs: Boolean = true) {
val relation = relationshipData.value?.data
val account = accountData.value?.data
if(relation != null && account != null) {
// optimistically post new state for faster response
val newRelation = when(relationshipAction) {
RelationShipAction.FOLLOW -> {
if (account.locked) {
relation.copy(requested = true)
} else {
relation.copy(following = true)
}
}
RelationShipAction.UNFOLLOW -> relation.copy(following = false)
RelationShipAction.BLOCK -> relation.copy(blocking = true)
RelationShipAction.UNBLOCK -> relation.copy(blocking = false)
RelationShipAction.MUTE -> relation.copy(muting = true)
RelationShipAction.UNMUTE -> relation.copy(muting = false)
}
relationshipData.postValue(Loading(newRelation))
}
val callback = object : Callback<Relationship> {
override fun onResponse(call: Call<Relationship>,
response: Response<Relationship>) {
val relationship = response.body()
if (response.isSuccessful && relationship != null) {
relationshipData.postValue(Success(relationship))
when (relationshipAction) {
RelationShipAction.UNFOLLOW -> eventHub.dispatch(UnfollowEvent(id))
RelationShipAction.BLOCK -> eventHub.dispatch(BlockEvent(id))
RelationShipAction.MUTE -> eventHub.dispatch(MuteEvent(id))
else -> {}
}
} else {
relationshipData.postValue(Error(relation))
}
}
override fun onFailure(call: Call<Relationship>, t: Throwable) {
relationshipData.postValue(Error(relation))
}
}
val call = when(relationshipAction) {
RelationShipAction.FOLLOW -> mastodonApi.followAccount(id, showReblogs)
RelationShipAction.UNFOLLOW -> mastodonApi.unfollowAccount(id)
RelationShipAction.BLOCK -> mastodonApi.blockAccount(id)
RelationShipAction.UNBLOCK -> mastodonApi.unblockAccount(id)
RelationShipAction.MUTE -> mastodonApi.muteAccount(id)
RelationShipAction.UNMUTE -> mastodonApi.unmuteAccount(id)
}
call.enqueue(callback)
callList.add(call)
}
override fun onCleared() {
callList.forEach {
it.cancel()
}
disposable.dispose()
}
enum class RelationShipAction {
FOLLOW, UNFOLLOW, BLOCK, UNBLOCK, MUTE, UNMUTE
}
}