Polls part 1 - displaying in timelines and voting (#1200)
* add entity classes * change data models and add database migration * add polls to StatusViewData * show poll results * add methods for vote handling * add voting interface * enable voting in TimelineFragment * update polls immediately * enable custom emojis for poll options * enable voting from search fragment * add voting layout to detailed statuses * fix tests * enable voting in ViewThreadFragment * enable voting in ConversationsFragment * small refactor for StatusBaseViewHolder
This commit is contained in:
parent
82d547caf8
commit
fd7471f2ab
36 changed files with 1637 additions and 68 deletions
|
@ -76,7 +76,8 @@ data class ConversationStatusEntity(
|
|||
val showingHiddenContent: Boolean,
|
||||
val expanded: Boolean,
|
||||
val collapsible: Boolean,
|
||||
val collapsed: Boolean
|
||||
val collapsed: Boolean,
|
||||
val poll: Poll?
|
||||
|
||||
) {
|
||||
/** its necessary to override this because Spanned.equals does not work as expected */
|
||||
|
@ -104,6 +105,7 @@ data class ConversationStatusEntity(
|
|||
if (expanded != other.expanded) return false
|
||||
if (collapsible != other.collapsible) return false
|
||||
if (collapsed != other.collapsed) return false
|
||||
if (poll != other.poll) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
@ -127,6 +129,7 @@ data class ConversationStatusEntity(
|
|||
result = 31 * result + expanded.hashCode()
|
||||
result = 31 * result + collapsible.hashCode()
|
||||
result = 31 * result + collapsed.hashCode()
|
||||
result = 31 * result + poll.hashCode()
|
||||
return result
|
||||
}
|
||||
|
||||
|
@ -151,7 +154,8 @@ data class ConversationStatusEntity(
|
|||
attachments = attachments,
|
||||
mentions = mentions,
|
||||
application = null,
|
||||
pinned = false)
|
||||
pinned = false,
|
||||
poll = poll)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -172,7 +176,8 @@ fun Status.toEntity() =
|
|||
false,
|
||||
false,
|
||||
!SmartLengthInputFilter.hasBadRatio(content, SmartLengthInputFilter.LENGTH_DEFAULT),
|
||||
true
|
||||
true,
|
||||
poll
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -102,6 +102,8 @@ public class ConversationViewHolder extends StatusBaseViewHolder {
|
|||
|
||||
setAvatars(conversation.getAccounts());
|
||||
|
||||
setupPoll(status.getPoll(), status.getEmojis(), listener);
|
||||
|
||||
}
|
||||
|
||||
private void setConversationName(List<ConversationAccountEntity> accounts) {
|
||||
|
|
|
@ -18,9 +18,11 @@ package com.keylesspalace.tusky.components.conversation
|
|||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.preference.PreferenceManager
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.lifecycle.ViewModelProviders
|
||||
import androidx.paging.PagedList
|
||||
|
@ -34,11 +36,15 @@ import com.keylesspalace.tusky.db.AppDatabase
|
|||
import com.keylesspalace.tusky.di.Injectable
|
||||
import com.keylesspalace.tusky.di.ViewModelFactory
|
||||
import com.keylesspalace.tusky.fragment.SFragment
|
||||
import com.keylesspalace.tusky.fragment.SearchFragment
|
||||
import com.keylesspalace.tusky.interfaces.ReselectableFragment
|
||||
import com.keylesspalace.tusky.interfaces.StatusActionListener
|
||||
import com.keylesspalace.tusky.util.NetworkState
|
||||
import com.keylesspalace.tusky.util.ThemeUtils
|
||||
import com.keylesspalace.tusky.util.hide
|
||||
import com.uber.autodispose.android.lifecycle.AndroidLifecycleScopeProvider
|
||||
import com.uber.autodispose.autoDisposable
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import kotlinx.android.synthetic.main.fragment_timeline.*
|
||||
import javax.inject.Inject
|
||||
|
||||
|
@ -187,6 +193,10 @@ class ConversationsFragment : SFragment(), StatusActionListener, Injectable, Res
|
|||
jumpToTop()
|
||||
}
|
||||
|
||||
override fun onVoteInPoll(position: Int, choices: MutableList<Int>) {
|
||||
viewModel.voteInPoll(position, choices)
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun newInstance() = ConversationsFragment()
|
||||
}
|
||||
|
|
|
@ -67,6 +67,25 @@ class ConversationsViewModel @Inject constructor(
|
|||
|
||||
}
|
||||
|
||||
fun voteInPoll(position: Int, choices: MutableList<Int>) {
|
||||
conversations.value?.getOrNull(position)?.let { conversation ->
|
||||
timelineCases.voteInPoll(conversation.lastStatus.toStatus(), choices)
|
||||
.flatMap { poll ->
|
||||
val newConversation = conversation.copy(
|
||||
lastStatus = conversation.lastStatus.copy(poll = poll)
|
||||
)
|
||||
Single.fromCallable {
|
||||
database.conversationDao().insert(newConversation)
|
||||
}
|
||||
}
|
||||
.subscribeOn(Schedulers.io())
|
||||
.doOnError { t -> Log.w("ConversationViewModel", "Failed to favourite conversation", t) }
|
||||
.subscribe()
|
||||
.addTo(disposables)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun expandHiddenStatus(expanded: Boolean, position: Int) {
|
||||
conversations.value?.getOrNull(position)?.let { conversation ->
|
||||
val newConversation = conversation.copy(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue