Skip to content

Commit

Permalink
Merge pull request #421 from 100mslive/AN-865-can-vote-single-poll-mu…
Browse files Browse the repository at this point in the history
…ltiple-time

Poll double vote fix
  • Loading branch information
AniketSK committed Aug 8, 2023
2 parents d9c412f + b536ec6 commit c33235c
Show file tree
Hide file tree
Showing 7 changed files with 53 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import live.hms.video.polls.models.HmsPoll
import live.hms.video.polls.models.HmsPollCategory
import live.hms.video.polls.models.HmsPollState
import live.hms.video.polls.models.answer.PollAnswerResponse
import live.hms.video.polls.models.network.HMSPollQuestionResponse
import live.hms.video.polls.models.question.HMSPollQuestion
import live.hms.video.polls.models.question.HMSPollQuestionType
import live.hms.video.sdk.*
Expand Down Expand Up @@ -1690,7 +1691,7 @@ class MeetingViewModel(
QuestionUi.QuestionCreator -> { /*Nothing to do here*/}
is QuestionUi.ShortAnswer -> hmsPollBuilder.addShortAnswerQuestion(questionUi.text)
is QuestionUi.SingleChoiceQuestion -> {
val singleChoiceQuestionBuilder = HMSPollQuestionBuilder.Builder(HMSPollQuestionType.multiChoice)
val singleChoiceQuestionBuilder = HMSPollQuestionBuilder.Builder(HMSPollQuestionType.singleChoice)
.withTitle(questionUi.withTitle)
questionUi.options.forEachIndexed { index : Int, option : String ->
singleChoiceQuestionBuilder.addQuizOption(option, questionUi.correctOptionIndex == index)
Expand Down Expand Up @@ -1749,7 +1750,7 @@ class MeetingViewModel(
.addResponse(question, answer)
localHmsInteractivityCenter.add(response, object : HmsTypedActionResultListener<PollAnswerResponse>{
override fun onSuccess(result: PollAnswerResponse) {
Log.d("PollAnswer","Success $result")
Log.d("PollAnswer","Success")
}

override fun onError(error: HMSException) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,28 @@ class AnswerOptionsAdapter(private val canRoleViewVotes : Boolean) : ListAdapter

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DisplayAnswerOptionsViewHolder {
val binding = LayoutPollsDisplayOptionsItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return DisplayAnswerOptionsViewHolder(binding,canRoleViewVotes, ::getItem)
return DisplayAnswerOptionsViewHolder(binding,canRoleViewVotes, ::getItem, ::setItemSelected)
}

override fun onBindViewHolder(holder: DisplayAnswerOptionsViewHolder, position: Int) {
holder.bind(getItem(position))
}

// All items are in fact changed
@SuppressLint("NotifyDataSetChanged")
fun setItemSelected(position : Int, noOthers : Boolean) {
for (i in 0 until itemCount) {
val item = getItem(i)
if(i == position) {
item.isChecked = true
}
else if (noOthers) {
item.isChecked = false
}
}
notifyDataSetChanged()
}

fun getSelectedOptions() : List<Int>{
val selectedItems = mutableListOf<Int>()
for (i in 0 until itemCount) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,21 @@ class DisplayAnswerOptionsViewHolder(
val binding: LayoutPollsDisplayOptionsItemBinding,
private val canRoleViewVotes : Boolean,
getItem: (Int) -> Option,
setItemSelected: (selected : Int, noOthers: Boolean) -> Unit,
) : ViewHolder(binding.root){

fun q() {
binding.radioButton.isChecked = false
}

init {
if(bindingAdapterPosition != RecyclerView.NO_POSITION) {
binding.text.setText(getItem(bindingAdapterPosition).text)
}
// Both set the same property, only one will be used.
binding.radioButton.setOnCheckedChangeListener { _, isChecked ->
getItem(bindingAdapterPosition).apply {
this.isChecked = isChecked
}

if(isChecked)
setItemSelected(bindingAdapterPosition, true)
}

binding.checkbox.setOnCheckedChangeListener { _, isChecked ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs
import androidx.recyclerview.widget.LinearLayoutManager
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
Expand Down Expand Up @@ -62,14 +63,6 @@ class PollDisplayFragment : Fragment() {

poll = returnedPoll

lifecycleScope.launch {
meetingViewModel.events.onEach {
if (it is MeetingViewModel.Event.PollVotesUpdated) {
// Update the polls? How?
pollsDisplayAdaptor.updatePollVotes(it.hmsPoll)
}
}.collect()
}

with(binding) {
backButton.setOnSingleClickListener {
Expand All @@ -79,7 +72,22 @@ class PollDisplayFragment : Fragment() {
questionsRecyclerView.layoutManager = LinearLayoutManager(binding.root.context)
questionsRecyclerView.adapter = pollsDisplayAdaptor
pollsDisplayAdaptor.displayPoll(poll)

// The views have to be rendered before the update Poll Votes can be called.
// the delay allows for this.
delay(300)
pollsDisplayAdaptor.updatePollVotes(poll)
}

lifecycleScope.launch {
meetingViewModel.events.onEach {
if (it is MeetingViewModel.Event.PollVotesUpdated) {
// Update the polls? How?
pollsDisplayAdaptor.updatePollVotes(it.hmsPoll)
}
}.collect()
}

}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ class PollDisplayQuestionHolder<T : ViewBinding>(
fun bind(question : QuestionContainer) {
when(question.question.type) {
HMSPollQuestionType.singleChoice, HMSPollQuestionType.multiChoice -> {
optionsBinder(question)
votingProgressAdapter = VotingProgressAdapter(question.question.questionID)
optionsBinder(question)
}
HMSPollQuestionType.shortAnswer,
HMSPollQuestionType.longAnswer -> textBinder(question)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package live.hms.roomkit.ui.polls.display

import android.util.Log
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
Expand Down Expand Up @@ -43,8 +42,7 @@ class PollsDisplayAdaptor(
val updater : MutableList<PollDisplayQuestionHolder<ViewBinding>> = mutableListOf()

fun displayPoll(hmsPoll: HmsPoll) {
val questions = hmsPoll.questions?.map { QuestionContainer(it) }
Log.d("PollsDisplay","Que $questions")
val questions = hmsPoll.questions?.map { QuestionContainer(it, voted = it.voted) }
if(questions != null) {
submitList(questions)
}
Expand Down Expand Up @@ -102,12 +100,11 @@ class PollsDisplayAdaptor(
}

fun updatePollVotes(hmsPoll: HmsPoll) {
Log.d(TAG,"Received an update ${hmsPoll.result}" )
if(hmsPoll.pollId != pollId)
return

updater.forEach { action ->
val questions = hmsPoll.result?.questions
val questions = hmsPoll.questions
if(questions != null) {
action.votingProgressAdapter?.updateProgressBar(questions, hmsPoll)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import androidx.recyclerview.widget.ListAdapter
import live.hms.roomkit.databinding.LayoutPollsDisplayResultProgressBarsItemBinding
import live.hms.video.polls.models.HmsPoll
import live.hms.video.polls.models.PollStatsQuestions
import live.hms.video.polls.models.question.HMSPollQuestion

data class ProgressBarInfo(
val index : Int,
Expand All @@ -20,18 +21,19 @@ class VotingProgressAdapter(val questionIndex : Int) : ListAdapter<ProgressBarIn
/**
* Call this when the votes change, to change the progressbar.
*/
fun updateProgressBar(pollStatsQuestions: List<PollStatsQuestions>, hmsPoll: HmsPoll) {
val pollStatsQuestion = pollStatsQuestions.find { it.index == questionIndex }
fun updateProgressBar(pollStatsQuestions: List<HMSPollQuestion>, hmsPoll: HmsPoll) {
val pollStatsQuestion = pollStatsQuestions.find { it.questionID == questionIndex }
if(pollStatsQuestion == null)
return
// votesForThisOption*100/totalVotes
val items: List<ProgressBarInfo>? =
hmsPoll.questions?.get(pollStatsQuestion.index.toInt() - 1)?.options?.mapIndexed { index, it ->
val votesForThisOption = pollStatsQuestion.options?.get(index) ?: -1
val percentage : Int = if (pollStatsQuestion.attemptedTimes == 0L) {
hmsPoll.questions?.get(pollStatsQuestion.questionID - 1)?.options?.mapIndexed { index, it ->
val votesForThisOption = pollStatsQuestion.options?.get(index)?.voteCount ?: -1

val percentage : Int = if (pollStatsQuestion.total == 0) {
100
} else {
(votesForThisOption * 100 / pollStatsQuestion.attemptedTimes).toInt()
(votesForThisOption * 100 / pollStatsQuestion.total).toInt()
}
ProgressBarInfo(
optionText = it.text ?: "",
Expand Down

0 comments on commit c33235c

Please sign in to comment.