Account activity redesign (#662)
* Refactor-all-the-things version of the fix for issue #573 * Migrate SpanUtils to kotlin because why not * Minimal fix for issue #573 * Add tests for compose spanning * Clean up code suggestions * Make FakeSpannable.getSpans implementation less awkward * Add secondary validation pass for urls * Address code review feedback * Fixup type filtering in FakeSpannable again * Make all mentions in compose activity use the default link color * new layout for AccountActivity * fix the light theme * convert AccountActivity to Kotlin * introduce AccountViewModel * Merge branch 'master' into account-activity-redesign # Conflicts: # app/src/main/java/com/keylesspalace/tusky/AccountActivity.java * add Bot badge to profile * parse custom emojis in usernames * add possibility to cancel follow request * add third tab on profiles * add account fields to profile * add support for moved accounts * set click listener on account moved view * fix tests * use 24dp as statusbar size * add ability to hide reblogs from followed accounts * add button to edit own account to AccountActivity * set toolbar top margin programmatically * fix crash * add shadow behind statusbar * introduce ViewExtensions to clean up code * move code out of offsetChangedListener for perf reasons * clean up stuff * add error handling * improve type safety * fix ConstraintLayout warning * remove unneeded ressources * fix event dispatching * fix crash in event handling * set correct emoji on title * improve some things * wrap follower/foillowing/status views
This commit is contained in:
parent
c450af7b0d
commit
63f9d99390
60 changed files with 1422 additions and 978 deletions
|
@ -0,0 +1,190 @@
|
|||
package com.keylesspalace.tusky.viewmodel
|
||||
|
||||
import android.arch.lifecycle.MutableLiveData
|
||||
import android.arch.lifecycle.ViewModel
|
||||
import com.keylesspalace.tusky.appstore.BlockEvent
|
||||
import com.keylesspalace.tusky.appstore.EventHub
|
||||
import com.keylesspalace.tusky.appstore.MuteEvent
|
||||
import com.keylesspalace.tusky.appstore.UnfollowEvent
|
||||
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 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()
|
||||
|
||||
|
||||
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) {
|
||||
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) {
|
||||
if (relationshipData.value?.data?.following == 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()
|
||||
}
|
||||
}
|
||||
|
||||
enum class RelationShipAction {
|
||||
FOLLOW, UNFOLLOW, BLOCK, UNBLOCK, MUTE, UNMUTE
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue