package com.keylesspalace.tusky.components.conversation
import android.util.Log
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Transformations
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 com.keylesspalace.tusky.util.RxAwareViewModel
import io.reactivex.schedulers.Schedulers
import javax.inject.Inject
class ConversationsViewModel @Inject constructor(
private val repository: ConversationsRepository,
private val timelineCases: TimelineCases,
private val database: AppDatabase,
private val accountManager: AccountManager
) : RxAwareViewModel() {
private val repoResult = MutableLiveData
>()
val conversations: LiveData> = Transformations.switchMap(repoResult) { it.pagedList }
val networkState: LiveData = Transformations.switchMap(repoResult) { it.networkState }
val refreshState: LiveData = Transformations.switchMap(repoResult) { it.refreshState }
fun load() {
val accountId = accountManager.activeAccount?.id ?: return
if (repoResult.value == null) {
repository.refresh(accountId, false)
}
repoResult.value = repository.conversations(accountId)
}
fun refresh() {
repoResult.value?.refresh?.invoke()
}
fun retry() {
repoResult.value?.retry?.invoke()
}
fun favourite(favourite: Boolean, position: Int) {
conversations.value?.getOrNull(position)?.let { conversation ->
timelineCases.favourite(conversation.lastStatus.toStatus(), favourite)
.flatMap {
val newConversation = conversation.copy(
lastStatus = conversation.lastStatus.copy(favourited = favourite)
)
database.conversationDao().insert(newConversation)
}
.subscribeOn(Schedulers.io())
.doOnError { t -> Log.w("ConversationViewModel", "Failed to favourite conversation", t) }
.onErrorReturnItem(0)
.subscribe()
.autoDispose()
}
}
fun bookmark(bookmark: Boolean, position: Int) {
conversations.value?.getOrNull(position)?.let { conversation ->
timelineCases.bookmark(conversation.lastStatus.toStatus(), bookmark)
.flatMap {
val newConversation = conversation.copy(
lastStatus = conversation.lastStatus.copy(bookmarked = bookmark)
)
database.conversationDao().insert(newConversation)
}
.subscribeOn(Schedulers.io())
.doOnError { t -> Log.w("ConversationViewModel", "Failed to bookmark conversation", t) }
.onErrorReturnItem(0)
.subscribe()
.autoDispose()
}
}
fun voteInPoll(position: Int, choices: MutableList) {
conversations.value?.getOrNull(position)?.let { conversation ->
timelineCases.voteInPoll(conversation.lastStatus.toStatus(), choices)
.flatMap { poll ->
val newConversation = conversation.copy(
lastStatus = conversation.lastStatus.copy(poll = poll)
)
database.conversationDao().insert(newConversation)
}
.subscribeOn(Schedulers.io())
.doOnError { t -> Log.w("ConversationViewModel", "Failed to favourite conversation", t) }
.onErrorReturnItem(0)
.subscribe()
.autoDispose()
}
}
fun expandHiddenStatus(expanded: Boolean, position: Int) {
conversations.value?.getOrNull(position)?.let { conversation ->
val newConversation = conversation.copy(
lastStatus = conversation.lastStatus.copy(expanded = expanded)
)
saveConversationToDb(newConversation)
}
}
fun collapseLongStatus(collapsed: Boolean, position: Int) {
conversations.value?.getOrNull(position)?.let { conversation ->
val newConversation = conversation.copy(
lastStatus = conversation.lastStatus.copy(collapsed = collapsed)
)
saveConversationToDb(newConversation)
}
}
fun showContent(showing: Boolean, position: Int) {
conversations.value?.getOrNull(position)?.let { conversation ->
val newConversation = conversation.copy(
lastStatus = conversation.lastStatus.copy(showingHiddenContent = showing)
)
saveConversationToDb(newConversation)
}
}
fun remove(position: Int) {
conversations.value?.getOrNull(position)?.let {
refresh()
}
}
private fun saveConversationToDb(conversation: ConversationEntity) {
database.conversationDao().insert(conversation)
.subscribeOn(Schedulers.io())
.subscribe()
}
}