mirror of
https://github.com/nextcloud/talk-android
synced 2025-03-06 14:27:24 +00:00
update poll UI for moderators etc
- allow to end poll for moderators - allow to see voters amount for voting screen for moderators and creators of the poll - replace UserEntity with User - show numVoters instead of votes - minor refactoring Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
This commit is contained in:
parent
c848659fda
commit
40f20c56d6
@ -121,12 +121,14 @@ class IncomingPollMessageViewHolder(incomingView: View, payload: Any) : MessageH
|
||||
if (pollId != null && pollName != null) {
|
||||
binding.messagePollTitle.text = pollName
|
||||
|
||||
val roomToken = (payload as? MessagePayload)!!.roomToken
|
||||
val roomToken = (payload as? MessagePayload)!!.currentConversation.token!!
|
||||
val isOwnerOrModerator = (payload as? MessagePayload)!!.currentConversation.isParticipantOwnerOrModerator
|
||||
|
||||
binding.bubble.setOnClickListener {
|
||||
val pollVoteDialog = PollMainDialogFragment.newInstance(
|
||||
message.activeUser!!,
|
||||
roomToken,
|
||||
isOwnerOrModerator,
|
||||
pollId,
|
||||
pollName
|
||||
)
|
||||
|
@ -1,8 +1,9 @@
|
||||
package com.nextcloud.talk.adapters.messages
|
||||
|
||||
import com.nextcloud.talk.models.json.conversations.Conversation
|
||||
import com.nextcloud.talk.ui.bottom.sheet.ProfileBottomSheet
|
||||
|
||||
data class MessagePayload(
|
||||
val roomToken: String,
|
||||
var currentConversation: Conversation,
|
||||
val profileBottomSheet: ProfileBottomSheet
|
||||
)
|
||||
|
@ -137,12 +137,14 @@ class OutcomingPollMessageViewHolder(outcomingView: View, payload: Any) : Messag
|
||||
if (pollId != null && pollName != null) {
|
||||
binding.messagePollTitle.text = pollName
|
||||
|
||||
val roomToken = (payload as? MessagePayload)!!.roomToken
|
||||
val roomToken = (payload as? MessagePayload)!!.currentConversation.token!!
|
||||
val isOwnerOrModerator = (payload as? MessagePayload)!!.currentConversation.isParticipantOwnerOrModerator
|
||||
|
||||
binding.bubble.setOnClickListener {
|
||||
val pollVoteDialog = PollMainDialogFragment.newInstance(
|
||||
message.activeUser!!,
|
||||
roomToken,
|
||||
isOwnerOrModerator,
|
||||
pollId,
|
||||
pollName
|
||||
)
|
||||
|
@ -487,7 +487,7 @@ class ChatController(args: Bundle) :
|
||||
val messageHolders = MessageHolders()
|
||||
val profileBottomSheet = ProfileBottomSheet(ncApi!!, conversationUser!!, router)
|
||||
|
||||
val payload = MessagePayload(roomToken!!, profileBottomSheet)
|
||||
val payload = MessagePayload(currentConversation!!, profileBottomSheet)
|
||||
|
||||
messageHolders.setIncomingTextConfig(
|
||||
MagicIncomingTextMessageViewHolder::class.java,
|
||||
|
@ -26,14 +26,14 @@ import com.facebook.drawee.backends.pipeline.Fresco
|
||||
import com.facebook.drawee.interfaces.DraweeController
|
||||
import com.nextcloud.talk.R
|
||||
import com.nextcloud.talk.application.NextcloudTalkApplication
|
||||
import com.nextcloud.talk.data.user.model.User
|
||||
import com.nextcloud.talk.databinding.PollResultVoterItemBinding
|
||||
import com.nextcloud.talk.models.database.UserEntity
|
||||
import com.nextcloud.talk.polls.model.PollDetails
|
||||
import com.nextcloud.talk.utils.ApiUtils
|
||||
import com.nextcloud.talk.utils.DisplayUtils
|
||||
|
||||
class PollResultVoterViewHolder(
|
||||
private val user: UserEntity,
|
||||
private val user: User,
|
||||
override val binding: PollResultVoterItemBinding
|
||||
) : PollResultViewHolder(binding) {
|
||||
|
||||
@ -60,7 +60,7 @@ class PollResultVoterViewHolder(
|
||||
displayName,
|
||||
false
|
||||
),
|
||||
null
|
||||
user
|
||||
)
|
||||
)
|
||||
.build()
|
||||
@ -74,7 +74,7 @@ class PollResultVoterViewHolder(
|
||||
pollDetail.actorId,
|
||||
false
|
||||
),
|
||||
null
|
||||
user
|
||||
)
|
||||
)
|
||||
.build()
|
||||
|
@ -23,12 +23,12 @@ package com.nextcloud.talk.polls.adapters
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.nextcloud.talk.data.user.model.User
|
||||
import com.nextcloud.talk.databinding.PollResultHeaderItemBinding
|
||||
import com.nextcloud.talk.databinding.PollResultVoterItemBinding
|
||||
import com.nextcloud.talk.models.database.UserEntity
|
||||
|
||||
class PollResultsAdapter(
|
||||
private val user: UserEntity,
|
||||
private val user: User,
|
||||
private val clickListener: PollResultItemClickListener,
|
||||
) : RecyclerView.Adapter<PollResultViewHolder>() {
|
||||
internal var list: MutableList<PollResultItem> = ArrayList()
|
||||
|
@ -32,17 +32,17 @@ import androidx.lifecycle.ViewModelProvider
|
||||
import autodagger.AutoInjector
|
||||
import com.nextcloud.talk.R
|
||||
import com.nextcloud.talk.application.NextcloudTalkApplication
|
||||
import com.nextcloud.talk.data.user.model.User
|
||||
import com.nextcloud.talk.databinding.DialogPollMainBinding
|
||||
import com.nextcloud.talk.models.database.UserEntity
|
||||
import com.nextcloud.talk.polls.model.Poll
|
||||
import com.nextcloud.talk.polls.viewmodels.PollMainViewModel
|
||||
import javax.inject.Inject
|
||||
|
||||
@AutoInjector(NextcloudTalkApplication::class)
|
||||
class PollMainDialogFragment : DialogFragment() {
|
||||
|
||||
lateinit var user: UserEntity
|
||||
lateinit var user: User
|
||||
lateinit var roomToken: String
|
||||
private var isOwnerOrModerator: Boolean = false
|
||||
lateinit var pollId: String
|
||||
lateinit var pollTitle: String
|
||||
|
||||
@ -60,6 +60,7 @@ class PollMainDialogFragment : DialogFragment() {
|
||||
|
||||
user = arguments?.getParcelable(KEY_USER_ENTITY)!!
|
||||
roomToken = arguments?.getString(KEY_ROOM_TOKEN)!!
|
||||
isOwnerOrModerator = arguments?.getBoolean(KEY_OWNER_OR_MODERATOR)!!
|
||||
pollId = arguments?.getString(KEY_POLL_ID)!!
|
||||
pollTitle = arguments?.getString(KEY_POLL_TITLE)!!
|
||||
}
|
||||
@ -83,19 +84,28 @@ class PollMainDialogFragment : DialogFragment() {
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
viewModel.setIsOwnerOrModerator(isOwnerOrModerator)
|
||||
|
||||
viewModel.viewState.observe(viewLifecycleOwner) { state ->
|
||||
when (state) {
|
||||
PollMainViewModel.InitialState -> {}
|
||||
is PollMainViewModel.PollVoteHiddenState -> {
|
||||
binding.pollDetailsText.visibility = View.VISIBLE
|
||||
binding.pollDetailsText.text = context?.resources?.getString(R.string.polls_private_voted)
|
||||
binding.pollVotedHidden.visibility = View.VISIBLE
|
||||
initVotersAmount(state.showVotersAmount, state.poll.numVoters, false)
|
||||
showVoteScreen()
|
||||
}
|
||||
is PollMainViewModel.PollVoteState -> {
|
||||
binding.pollDetailsText.visibility = View.GONE
|
||||
binding.pollVotedHidden.visibility = View.GONE
|
||||
initVotersAmount(state.showVotersAmount, state.poll.numVoters, false)
|
||||
showVoteScreen()
|
||||
}
|
||||
is PollMainViewModel.PollResultState -> showResultsScreen(state.poll)
|
||||
is PollMainViewModel.PollResultState -> {
|
||||
binding.pollVotedHidden.visibility = View.GONE
|
||||
initVotersAmount(state.showVotersAmount, state.poll.numVoters, true)
|
||||
showResultsScreen()
|
||||
}
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
|
||||
@ -103,7 +113,6 @@ class PollMainDialogFragment : DialogFragment() {
|
||||
}
|
||||
|
||||
private fun showVoteScreen() {
|
||||
|
||||
val contentFragment = PollVoteFragment.newInstance(
|
||||
roomToken,
|
||||
pollId
|
||||
@ -114,9 +123,7 @@ class PollMainDialogFragment : DialogFragment() {
|
||||
transaction.commit()
|
||||
}
|
||||
|
||||
private fun showResultsScreen(poll: Poll) {
|
||||
initVotesAmount(poll.totalVotes)
|
||||
|
||||
private fun showResultsScreen() {
|
||||
val contentFragment = PollResultsFragment.newInstance(
|
||||
user
|
||||
)
|
||||
@ -126,12 +133,24 @@ class PollMainDialogFragment : DialogFragment() {
|
||||
transaction.commit()
|
||||
}
|
||||
|
||||
private fun initVotesAmount(totalVotes: Int) {
|
||||
binding.pollDetailsText.visibility = View.VISIBLE
|
||||
binding.pollDetailsText.text = String.format(
|
||||
resources.getString(R.string.polls_amount_voters),
|
||||
totalVotes
|
||||
)
|
||||
private fun initVotersAmount(showVotersAmount: Boolean, numVoters: Int, showResultSubtitle: Boolean) {
|
||||
if (showVotersAmount) {
|
||||
binding.pollVotesAmount.visibility = View.VISIBLE
|
||||
binding.pollVotesAmount.text = String.format(
|
||||
resources.getString(R.string.polls_amount_voters),
|
||||
numVoters
|
||||
)
|
||||
} else {
|
||||
binding.pollVotesAmount.visibility = View.GONE
|
||||
}
|
||||
|
||||
if (showResultSubtitle) {
|
||||
binding.pollResultsSubtitle.visibility = View.VISIBLE
|
||||
binding.pollResultsSubtitleSeperator.visibility = View.VISIBLE
|
||||
} else {
|
||||
binding.pollResultsSubtitle.visibility = View.GONE
|
||||
binding.pollResultsSubtitleSeperator.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -140,19 +159,22 @@ class PollMainDialogFragment : DialogFragment() {
|
||||
companion object {
|
||||
private const val KEY_USER_ENTITY = "keyUserEntity"
|
||||
private const val KEY_ROOM_TOKEN = "keyRoomToken"
|
||||
private const val KEY_OWNER_OR_MODERATOR = "keyIsOwnerOrModerator"
|
||||
private const val KEY_POLL_ID = "keyPollId"
|
||||
private const val KEY_POLL_TITLE = "keyPollTitle"
|
||||
|
||||
@JvmStatic
|
||||
fun newInstance(
|
||||
user: UserEntity,
|
||||
user: User,
|
||||
roomTokenParam: String,
|
||||
isOwnerOrModerator: Boolean,
|
||||
pollId: String,
|
||||
name: String
|
||||
): PollMainDialogFragment {
|
||||
val args = Bundle()
|
||||
args.putParcelable(KEY_USER_ENTITY, user)
|
||||
args.putString(KEY_ROOM_TOKEN, roomTokenParam)
|
||||
args.putBoolean(KEY_OWNER_OR_MODERATOR, isOwnerOrModerator)
|
||||
args.putString(KEY_POLL_ID, pollId)
|
||||
args.putString(KEY_POLL_TITLE, name)
|
||||
val fragment = PollMainDialogFragment()
|
||||
|
@ -33,8 +33,8 @@ import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import autodagger.AutoInjector
|
||||
import com.nextcloud.talk.R
|
||||
import com.nextcloud.talk.application.NextcloudTalkApplication
|
||||
import com.nextcloud.talk.data.user.model.User
|
||||
import com.nextcloud.talk.databinding.DialogPollResultsBinding
|
||||
import com.nextcloud.talk.models.database.UserEntity
|
||||
import com.nextcloud.talk.polls.adapters.PollResultHeaderItem
|
||||
import com.nextcloud.talk.polls.adapters.PollResultItemClickListener
|
||||
import com.nextcloud.talk.polls.adapters.PollResultsAdapter
|
||||
@ -51,7 +51,7 @@ class PollResultsFragment : Fragment(), PollResultItemClickListener {
|
||||
private lateinit var parentViewModel: PollMainViewModel
|
||||
lateinit var viewModel: PollResultsViewModel
|
||||
|
||||
lateinit var user: UserEntity
|
||||
lateinit var user: User
|
||||
|
||||
lateinit var binding: DialogPollResultsBinding
|
||||
|
||||
@ -108,7 +108,7 @@ class PollResultsFragment : Fragment(), PollResultItemClickListener {
|
||||
if (showEditButton) {
|
||||
binding.editVoteButton.visibility = View.VISIBLE
|
||||
binding.editVoteButton.setOnClickListener {
|
||||
parentViewModel.edit()
|
||||
parentViewModel.editVotes()
|
||||
}
|
||||
} else {
|
||||
binding.editVoteButton.visibility = View.GONE
|
||||
@ -142,7 +142,7 @@ class PollResultsFragment : Fragment(), PollResultItemClickListener {
|
||||
|
||||
@JvmStatic
|
||||
fun newInstance(
|
||||
user: UserEntity
|
||||
user: User
|
||||
): PollResultsFragment {
|
||||
val args = Bundle()
|
||||
args.putParcelable(KEY_USER_ENTITY, user)
|
||||
|
@ -52,24 +52,29 @@ class PollMainViewModel @Inject constructor(private val repository: PollReposito
|
||||
private lateinit var roomToken: String
|
||||
private lateinit var pollId: String
|
||||
|
||||
private var editPoll: Boolean = false
|
||||
private var isOwnerOrModerator: Boolean = false
|
||||
|
||||
private var editVotes: Boolean = false
|
||||
|
||||
sealed interface ViewState
|
||||
object InitialState : ViewState
|
||||
open class PollVoteState(
|
||||
val poll: Poll,
|
||||
val showVotersAmount: Boolean,
|
||||
val showEndPollButton: Boolean
|
||||
) : ViewState
|
||||
|
||||
open class PollVoteHiddenState(
|
||||
val poll: Poll,
|
||||
val showVotersAmount: Boolean,
|
||||
val showEndPollButton: Boolean
|
||||
) : ViewState
|
||||
|
||||
open class PollResultState(
|
||||
val poll: Poll,
|
||||
val showEditButton: Boolean,
|
||||
val showEndPollButton: Boolean
|
||||
val showVotersAmount: Boolean,
|
||||
val showEndPollButton: Boolean,
|
||||
val showEditButton: Boolean
|
||||
) : ViewState
|
||||
|
||||
private val _viewState: MutableLiveData<ViewState> = MutableLiveData(InitialState)
|
||||
@ -89,8 +94,8 @@ class PollMainViewModel @Inject constructor(private val repository: PollReposito
|
||||
loadPoll()
|
||||
}
|
||||
|
||||
fun edit() {
|
||||
editPoll = true
|
||||
fun editVotes() {
|
||||
editVotes = true
|
||||
loadPoll()
|
||||
}
|
||||
|
||||
@ -130,28 +135,34 @@ class PollMainViewModel @Inject constructor(private val repository: PollReposito
|
||||
}
|
||||
|
||||
override fun onComplete() {
|
||||
val showEndPollButton = poll.status == Poll.STATUS_OPEN && isPollCreatedByCurrentUser(poll)
|
||||
val showEndPollButton = showEndPollButton(poll)
|
||||
val showVotersAmount = showVotersAmount(poll)
|
||||
|
||||
if (votedForOpenHiddenPoll(poll)) {
|
||||
_viewState.value = PollVoteHiddenState(poll, showEndPollButton)
|
||||
} else if (editPoll && poll.status == Poll.STATUS_OPEN) {
|
||||
_viewState.value = PollVoteState(poll, showEndPollButton)
|
||||
editPoll = false
|
||||
_viewState.value = PollVoteHiddenState(poll, showVotersAmount, showEndPollButton)
|
||||
} else if (editVotes && poll.status == Poll.STATUS_OPEN) {
|
||||
_viewState.value = PollVoteState(poll, false, showEndPollButton)
|
||||
editVotes = false
|
||||
} else if (poll.status == Poll.STATUS_CLOSED || poll.votedSelf?.isNotEmpty() == true) {
|
||||
setPollResultState(poll)
|
||||
val showEditButton = poll.status == Poll.STATUS_OPEN && poll.resultMode == Poll.RESULT_MODE_PUBLIC
|
||||
_viewState.value = PollResultState(poll, showVotersAmount, showEndPollButton, showEditButton)
|
||||
} else if (poll.votedSelf.isNullOrEmpty()) {
|
||||
_viewState.value = PollVoteState(poll, showEndPollButton)
|
||||
_viewState.value = PollVoteState(poll, showVotersAmount, showEndPollButton)
|
||||
} else {
|
||||
Log.w(TAG, "unknown poll state")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun setPollResultState(poll: Poll) {
|
||||
val showEditButton = poll.status == Poll.STATUS_OPEN && poll.resultMode == Poll.RESULT_MODE_PUBLIC
|
||||
val showEndPollButton = poll.status == Poll.STATUS_OPEN && isPollCreatedByCurrentUser(poll)
|
||||
private fun showEndPollButton(poll: Poll): Boolean {
|
||||
return poll.status == Poll.STATUS_OPEN && (isPollCreatedByCurrentUser(poll) || isOwnerOrModerator)
|
||||
}
|
||||
|
||||
_viewState.value = PollResultState(poll, showEditButton, showEndPollButton)
|
||||
private fun showVotersAmount(poll: Poll): Boolean {
|
||||
return votedForPublicPoll(poll) ||
|
||||
poll.status == Poll.STATUS_CLOSED ||
|
||||
isOwnerOrModerator ||
|
||||
isPollCreatedByCurrentUser(poll)
|
||||
}
|
||||
|
||||
private fun votedForOpenHiddenPoll(poll: Poll): Boolean {
|
||||
@ -160,10 +171,19 @@ class PollMainViewModel @Inject constructor(private val repository: PollReposito
|
||||
poll.votedSelf?.isNotEmpty() == true
|
||||
}
|
||||
|
||||
private fun votedForPublicPoll(poll: Poll): Boolean {
|
||||
return poll.resultMode == Poll.RESULT_MODE_PUBLIC &&
|
||||
poll.votedSelf?.isNotEmpty() == true
|
||||
}
|
||||
|
||||
private fun isPollCreatedByCurrentUser(poll: Poll): Boolean {
|
||||
return userUtils.currentUser?.userId == poll.actorId
|
||||
}
|
||||
|
||||
fun setIsOwnerOrModerator(ownerOrModerator: Boolean) {
|
||||
isOwnerOrModerator = ownerOrModerator
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val TAG = PollMainViewModel::class.java.simpleName
|
||||
}
|
||||
|
@ -49,13 +49,51 @@
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/poll_results_subtitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:textColor="@color/low_emphasis_text"
|
||||
android:text="@string/polls_results_subtitle"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/poll_results_subtitle_seperator"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:textColor="@color/low_emphasis_text"
|
||||
android:text=" - "
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible"
|
||||
tools:ignore="HardcodedText" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/poll_votes_amount"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:textColor="@color/low_emphasis_text"
|
||||
tools:text="93 votes" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
|
||||
<TextView
|
||||
android:id="@+id/poll_details_text"
|
||||
android:id="@+id/poll_voted_hidden"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:textColor="@color/low_emphasis_text"
|
||||
tools:text="Poll results - 93 votes" />
|
||||
android:text="@string/polls_private_voted" />
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/message_poll_content_fragment"
|
||||
|
@ -537,12 +537,13 @@
|
||||
<string name="message_search_begin_empty">No search results</string>
|
||||
|
||||
<!-- Polls -->
|
||||
<string name="polls_amount_voters">Poll results - %1$s votes</string>
|
||||
<string name="polls_amount_voters">%1$s voters</string>
|
||||
<string name="polls_add_option">Add Option</string>
|
||||
<string name="polls_private_voted">You successfully voted for this private poll.</string>
|
||||
<string name="polls_end_poll">End Poll</string>
|
||||
<string name="polls_end_poll_confirm">Do you really want to end this poll? This can\'t be undone.</string>
|
||||
<string name="polls_max_votes_reached">You can\'t vote with more options for this poll.</string>
|
||||
<string name="polls_results_subtitle">Results</string>
|
||||
|
||||
<string name="title_attachments">Attachments</string>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user