mirror of
https://github.com/nextcloud/talk-android
synced 2025-06-21 20:49:36 +01:00
show detailed list of voters
+ refactoring adapter and viewholders for result screen Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
This commit is contained in:
parent
909ee07ce6
commit
73d48a395c
@ -0,0 +1,19 @@
|
|||||||
|
package com.nextcloud.talk.polls.adapters
|
||||||
|
|
||||||
|
import com.nextcloud.talk.R
|
||||||
|
|
||||||
|
data class PollResultHeaderItem(
|
||||||
|
val name: String,
|
||||||
|
val percent: Int,
|
||||||
|
val selfVoted: Boolean
|
||||||
|
) : PollResultItem {
|
||||||
|
|
||||||
|
override fun getViewType(): Int {
|
||||||
|
return VIEW_TYPE
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
// layout is used as view type for uniqueness
|
||||||
|
public val VIEW_TYPE: Int = R.layout.poll_result_header_item
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
package com.nextcloud.talk.polls.adapters
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
|
import android.graphics.Typeface
|
||||||
|
import com.nextcloud.talk.databinding.PollResultHeaderItemBinding
|
||||||
|
import com.nextcloud.talk.models.database.UserEntity
|
||||||
|
|
||||||
|
class PollResultHeaderViewHolder(
|
||||||
|
private val user: UserEntity,
|
||||||
|
override val binding: PollResultHeaderItemBinding
|
||||||
|
) : PollResultViewHolder(binding) {
|
||||||
|
|
||||||
|
@SuppressLint("SetTextI18n")
|
||||||
|
override fun bind(pollResultItem: PollResultItem, clickListener: PollResultItemClickListener) {
|
||||||
|
val item = pollResultItem as PollResultHeaderItem
|
||||||
|
|
||||||
|
binding.root.setOnClickListener { clickListener.onClick(pollResultItem) }
|
||||||
|
|
||||||
|
binding.pollOptionText.text = item.name
|
||||||
|
binding.pollOptionPercentText.text = "${item.percent}%"
|
||||||
|
|
||||||
|
if (item.selfVoted) {
|
||||||
|
binding.pollOptionText.setTypeface(null, Typeface.BOLD)
|
||||||
|
binding.pollOptionPercentText.setTypeface(null, Typeface.BOLD)
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.pollOptionBar.progress = item.percent
|
||||||
|
}
|
||||||
|
}
|
@ -1,10 +1,7 @@
|
|||||||
package com.nextcloud.talk.polls.adapters
|
package com.nextcloud.talk.polls.adapters
|
||||||
|
|
||||||
import com.nextcloud.talk.polls.model.PollDetails
|
interface PollResultItem {
|
||||||
|
|
||||||
class PollResultItem(
|
fun getViewType(): Int
|
||||||
val name: String,
|
// fun getView(inflater: LayoutInflater?, convertView: View?): View?
|
||||||
val percent: Int,
|
}
|
||||||
val selfVoted: Boolean,
|
|
||||||
val voters: List<PollDetails>?
|
|
||||||
)
|
|
@ -1,5 +1,5 @@
|
|||||||
package com.nextcloud.talk.polls.adapters
|
package com.nextcloud.talk.polls.adapters
|
||||||
|
|
||||||
interface PollResultItemClickListener {
|
interface PollResultItemClickListener {
|
||||||
fun onClick(pollResultItem: PollResultItem)
|
fun onClick(pollResultHeaderItem: PollResultHeaderItem)
|
||||||
}
|
}
|
||||||
|
@ -1,107 +1,10 @@
|
|||||||
package com.nextcloud.talk.polls.adapters
|
package com.nextcloud.talk.polls.adapters
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
|
||||||
import android.graphics.Typeface
|
|
||||||
import android.text.TextUtils
|
|
||||||
import android.view.View
|
|
||||||
import android.widget.LinearLayout
|
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.facebook.drawee.backends.pipeline.Fresco
|
import androidx.viewbinding.ViewBinding
|
||||||
import com.facebook.drawee.generic.RoundingParams
|
|
||||||
import com.facebook.drawee.interfaces.DraweeController
|
|
||||||
import com.facebook.drawee.view.SimpleDraweeView
|
|
||||||
import com.nextcloud.talk.R
|
|
||||||
import com.nextcloud.talk.application.NextcloudTalkApplication
|
|
||||||
import com.nextcloud.talk.databinding.PollResultItemBinding
|
|
||||||
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 PollResultViewHolder(
|
abstract class PollResultViewHolder(
|
||||||
private val user: UserEntity,
|
open val binding: ViewBinding
|
||||||
private val binding: PollResultItemBinding
|
|
||||||
) : RecyclerView.ViewHolder(binding.root) {
|
) : RecyclerView.ViewHolder(binding.root) {
|
||||||
|
abstract fun bind(pollResultItem: PollResultItem, clickListener: PollResultItemClickListener)
|
||||||
@SuppressLint("SetTextI18n")
|
}
|
||||||
fun bind(pollResultItem: PollResultItem, clickListener: PollResultItemClickListener) {
|
|
||||||
binding.root.setOnClickListener { clickListener.onClick(pollResultItem) }
|
|
||||||
|
|
||||||
binding.root.setOnClickListener { clickListener.onClick(pollResultItem) }
|
|
||||||
|
|
||||||
binding.pollOptionText.text = pollResultItem.name
|
|
||||||
binding.pollOptionPercentText.text = "${pollResultItem.percent}%"
|
|
||||||
|
|
||||||
if (pollResultItem.selfVoted) {
|
|
||||||
binding.pollOptionText.setTypeface(null, Typeface.BOLD)
|
|
||||||
binding.pollOptionPercentText.setTypeface(null, Typeface.BOLD)
|
|
||||||
}
|
|
||||||
|
|
||||||
binding.pollOptionBar.progress = pollResultItem.percent
|
|
||||||
|
|
||||||
if (!pollResultItem.voters.isNullOrEmpty()) {
|
|
||||||
binding.pollOptionDetail.visibility = View.VISIBLE
|
|
||||||
|
|
||||||
val lp = LinearLayout.LayoutParams(
|
|
||||||
60,
|
|
||||||
50
|
|
||||||
)
|
|
||||||
|
|
||||||
pollResultItem.voters.forEach {
|
|
||||||
val avatar = SimpleDraweeView(binding.root.context)
|
|
||||||
avatar.layoutParams = lp
|
|
||||||
|
|
||||||
val roundingParams = RoundingParams.fromCornersRadius(5f)
|
|
||||||
roundingParams.roundAsCircle = true
|
|
||||||
|
|
||||||
avatar.hierarchy.roundingParams = roundingParams
|
|
||||||
avatar.controller = getAvatarDraweeController(it)
|
|
||||||
|
|
||||||
binding.pollOptionDetail.addView(avatar)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
binding.pollOptionDetail.visibility = View.GONE
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getAvatarDraweeController(pollDetail: PollDetails): DraweeController? {
|
|
||||||
if (pollDetail.actorType == "guests") {
|
|
||||||
var displayName = NextcloudTalkApplication.sharedApplication?.resources?.getString(R.string.nc_guest)
|
|
||||||
if (!TextUtils.isEmpty(pollDetail.actorDisplayName)) {
|
|
||||||
displayName = pollDetail.actorDisplayName!!
|
|
||||||
}
|
|
||||||
val draweeController: DraweeController = Fresco.newDraweeControllerBuilder()
|
|
||||||
// .setOldController(binding.avatar.controller)
|
|
||||||
.setAutoPlayAnimations(true)
|
|
||||||
.setImageRequest(
|
|
||||||
DisplayUtils.getImageRequestForUrl(
|
|
||||||
ApiUtils.getUrlForGuestAvatar(
|
|
||||||
user.baseUrl,
|
|
||||||
displayName,
|
|
||||||
false
|
|
||||||
),
|
|
||||||
null
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.build()
|
|
||||||
return draweeController
|
|
||||||
} else if (pollDetail.actorType == "users") {
|
|
||||||
val draweeController: DraweeController = Fresco.newDraweeControllerBuilder()
|
|
||||||
// .setOldController(binding.avatar.controller)
|
|
||||||
.setAutoPlayAnimations(true)
|
|
||||||
.setImageRequest(
|
|
||||||
DisplayUtils.getImageRequestForUrl(
|
|
||||||
ApiUtils.getUrlForAvatar(
|
|
||||||
user.baseUrl,
|
|
||||||
pollDetail.actorId,
|
|
||||||
false
|
|
||||||
),
|
|
||||||
null
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.build()
|
|
||||||
return draweeController
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,18 @@
|
|||||||
|
package com.nextcloud.talk.polls.adapters
|
||||||
|
|
||||||
|
import com.nextcloud.talk.R
|
||||||
|
import com.nextcloud.talk.polls.model.PollDetails
|
||||||
|
|
||||||
|
data class PollResultVoterItem(
|
||||||
|
val details: PollDetails
|
||||||
|
) : PollResultItem {
|
||||||
|
|
||||||
|
override fun getViewType(): Int {
|
||||||
|
return VIEW_TYPE
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
// layout is used as view type for uniqueness
|
||||||
|
public val VIEW_TYPE: Int = R.layout.poll_result_voter_item
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,84 @@
|
|||||||
|
package com.nextcloud.talk.polls.adapters
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
|
import android.text.TextUtils
|
||||||
|
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.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,
|
||||||
|
override val binding: PollResultVoterItemBinding
|
||||||
|
) : PollResultViewHolder(binding) {
|
||||||
|
|
||||||
|
@SuppressLint("SetTextI18n")
|
||||||
|
override fun bind(pollResultItem: PollResultItem, clickListener: PollResultItemClickListener) {
|
||||||
|
val item = pollResultItem as PollResultVoterItem
|
||||||
|
|
||||||
|
// binding.root.setOnClickListener { clickListener.onClick(pollResultVoterItem) }
|
||||||
|
|
||||||
|
// binding.pollVoterAvatar = pollResultHeaderItem.name
|
||||||
|
binding.pollVoterName.text = item.details.actorDisplayName
|
||||||
|
|
||||||
|
// val lp = LinearLayout.LayoutParams(
|
||||||
|
// 60,
|
||||||
|
// 50
|
||||||
|
// )
|
||||||
|
//
|
||||||
|
// val avatar = SimpleDraweeView(binding.root.context)
|
||||||
|
// avatar.layoutParams = lp
|
||||||
|
|
||||||
|
// val roundingParams = RoundingParams.fromCornersRadius(5f)
|
||||||
|
// roundingParams.roundAsCircle = true
|
||||||
|
//
|
||||||
|
// binding.pollVoterAvatar.hierarchy.roundingParams = roundingParams
|
||||||
|
binding.pollVoterAvatar.controller = getAvatarDraweeController(item.details)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getAvatarDraweeController(pollDetail: PollDetails): DraweeController? {
|
||||||
|
if (pollDetail.actorType == "guests") {
|
||||||
|
var displayName = NextcloudTalkApplication.sharedApplication?.resources?.getString(R.string.nc_guest)
|
||||||
|
if (!TextUtils.isEmpty(pollDetail.actorDisplayName)) {
|
||||||
|
displayName = pollDetail.actorDisplayName!!
|
||||||
|
}
|
||||||
|
val draweeController: DraweeController = Fresco.newDraweeControllerBuilder()
|
||||||
|
// .setOldController(binding.avatar.controller)
|
||||||
|
.setAutoPlayAnimations(true)
|
||||||
|
.setImageRequest(
|
||||||
|
DisplayUtils.getImageRequestForUrl(
|
||||||
|
ApiUtils.getUrlForGuestAvatar(
|
||||||
|
user.baseUrl,
|
||||||
|
displayName,
|
||||||
|
false
|
||||||
|
),
|
||||||
|
null
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.build()
|
||||||
|
return draweeController
|
||||||
|
} else if (pollDetail.actorType == "users") {
|
||||||
|
val draweeController: DraweeController = Fresco.newDraweeControllerBuilder()
|
||||||
|
// .setOldController(binding.avatar.controller)
|
||||||
|
.setAutoPlayAnimations(true)
|
||||||
|
.setImageRequest(
|
||||||
|
DisplayUtils.getImageRequestForUrl(
|
||||||
|
ApiUtils.getUrlForAvatar(
|
||||||
|
user.baseUrl,
|
||||||
|
pollDetail.actorId,
|
||||||
|
false
|
||||||
|
),
|
||||||
|
null
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.build()
|
||||||
|
return draweeController
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
@ -3,26 +3,56 @@ package com.nextcloud.talk.polls.adapters
|
|||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.nextcloud.talk.databinding.PollResultItemBinding
|
import com.nextcloud.talk.databinding.PollResultHeaderItemBinding
|
||||||
|
import com.nextcloud.talk.databinding.PollResultVoterItemBinding
|
||||||
import com.nextcloud.talk.models.database.UserEntity
|
import com.nextcloud.talk.models.database.UserEntity
|
||||||
|
|
||||||
class PollResultsAdapter(
|
class PollResultsAdapter(
|
||||||
private val user: UserEntity,
|
private val user: UserEntity,
|
||||||
private val clickListener: PollResultItemClickListener,
|
private val clickListener: PollResultItemClickListener,
|
||||||
) : RecyclerView.Adapter<PollResultViewHolder>() {
|
) : RecyclerView.Adapter<PollResultViewHolder>() {
|
||||||
internal var list: MutableList<PollResultItem> = ArrayList<PollResultItem>()
|
internal var list: MutableList<PollResultItem> = ArrayList()
|
||||||
|
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PollResultViewHolder {
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PollResultViewHolder {
|
||||||
val itemBinding = PollResultItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)
|
when (viewType) {
|
||||||
return PollResultViewHolder(user, itemBinding)
|
PollResultHeaderItem.VIEW_TYPE -> {
|
||||||
|
val itemBinding = PollResultHeaderItemBinding.inflate(
|
||||||
|
LayoutInflater.from(parent.context), parent,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
return PollResultHeaderViewHolder(user, itemBinding)
|
||||||
|
}
|
||||||
|
PollResultVoterItem.VIEW_TYPE -> {
|
||||||
|
val itemBinding = PollResultVoterItemBinding.inflate(
|
||||||
|
LayoutInflater.from(parent.context), parent,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
return PollResultVoterViewHolder(user, itemBinding)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val itemBinding = PollResultHeaderItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)
|
||||||
|
return PollResultHeaderViewHolder(user, itemBinding)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onBindViewHolder(holder: PollResultViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: PollResultViewHolder, position: Int) {
|
||||||
val pollResultItem = list[position]
|
when (holder.itemViewType) {
|
||||||
holder.bind(pollResultItem, clickListener)
|
PollResultHeaderItem.VIEW_TYPE -> {
|
||||||
|
val pollResultItem = list[position]
|
||||||
|
holder.bind(pollResultItem as PollResultHeaderItem, clickListener)
|
||||||
|
}
|
||||||
|
PollResultVoterItem.VIEW_TYPE -> {
|
||||||
|
val pollResultItem = list[position]
|
||||||
|
holder.bind(pollResultItem as PollResultVoterItem, clickListener)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getItemCount(): Int {
|
override fun getItemCount(): Int {
|
||||||
return list.size
|
return list.size
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun getItemViewType(position: Int): Int {
|
||||||
|
return list[position].getViewType()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,6 @@
|
|||||||
package com.nextcloud.talk.polls.ui
|
package com.nextcloud.talk.polls.ui
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.Log
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
@ -33,10 +32,9 @@ import autodagger.AutoInjector
|
|||||||
import com.nextcloud.talk.application.NextcloudTalkApplication
|
import com.nextcloud.talk.application.NextcloudTalkApplication
|
||||||
import com.nextcloud.talk.databinding.DialogPollResultsBinding
|
import com.nextcloud.talk.databinding.DialogPollResultsBinding
|
||||||
import com.nextcloud.talk.models.database.UserEntity
|
import com.nextcloud.talk.models.database.UserEntity
|
||||||
import com.nextcloud.talk.polls.adapters.PollResultItem
|
import com.nextcloud.talk.polls.adapters.PollResultHeaderItem
|
||||||
import com.nextcloud.talk.polls.adapters.PollResultItemClickListener
|
import com.nextcloud.talk.polls.adapters.PollResultItemClickListener
|
||||||
import com.nextcloud.talk.polls.adapters.PollResultsAdapter
|
import com.nextcloud.talk.polls.adapters.PollResultsAdapter
|
||||||
import com.nextcloud.talk.polls.model.Poll
|
|
||||||
import com.nextcloud.talk.polls.viewmodels.PollMainViewModel
|
import com.nextcloud.talk.polls.viewmodels.PollMainViewModel
|
||||||
import com.nextcloud.talk.polls.viewmodels.PollResultsViewModel
|
import com.nextcloud.talk.polls.viewmodels.PollResultsViewModel
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@ -81,11 +79,18 @@ class PollResultsFragment(
|
|||||||
parentViewModel.viewState.observe(viewLifecycleOwner) { state ->
|
parentViewModel.viewState.observe(viewLifecycleOwner) { state ->
|
||||||
if (state is PollMainViewModel.PollResultState) {
|
if (state is PollMainViewModel.PollResultState) {
|
||||||
initAdapter()
|
initAdapter()
|
||||||
initPollResults(state.poll)
|
viewModel.setPoll(state.poll)
|
||||||
initEditButton(state.showEditButton)
|
initEditButton(state.showEditButton)
|
||||||
initCloseButton(state.showCloseButton)
|
initCloseButton(state.showCloseButton)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
viewModel.items.observe(viewLifecycleOwner) {
|
||||||
|
val adapter = PollResultsAdapter(user, this).apply {
|
||||||
|
list = it
|
||||||
|
}
|
||||||
|
binding.pollResultsList.adapter = adapter
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun initAdapter() {
|
private fun initAdapter() {
|
||||||
@ -94,51 +99,6 @@ class PollResultsFragment(
|
|||||||
_binding?.pollResultsList?.layoutManager = LinearLayoutManager(context)
|
_binding?.pollResultsList?.layoutManager = LinearLayoutManager(context)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun initPollResults(poll: Poll) {
|
|
||||||
if (poll.details != null) {
|
|
||||||
val votersAmount = poll.details.size
|
|
||||||
val oneVoteInPercent = 100 / votersAmount // TODO: poll.numVoters when fixed on api
|
|
||||||
|
|
||||||
poll.options?.forEachIndexed { index, option ->
|
|
||||||
val votersForThisOption = poll.details.filter { it.optionId == index }
|
|
||||||
val optionsPercent = oneVoteInPercent * votersForThisOption.size
|
|
||||||
|
|
||||||
val pollResultItem = PollResultItem(
|
|
||||||
option,
|
|
||||||
optionsPercent,
|
|
||||||
isOptionSelfVoted(poll, index),
|
|
||||||
votersForThisOption
|
|
||||||
)
|
|
||||||
adapter?.list?.add(pollResultItem)
|
|
||||||
}
|
|
||||||
} else if (poll.votes != null) {
|
|
||||||
val votersAmount = poll.numVoters
|
|
||||||
val oneVoteInPercent = 100 / votersAmount
|
|
||||||
|
|
||||||
poll.options?.forEachIndexed { index, option ->
|
|
||||||
var votersAmountForThisOption = poll.votes.filter { it.key.toInt() == index }[index.toString()]
|
|
||||||
if (votersAmountForThisOption == null) {
|
|
||||||
votersAmountForThisOption = 0
|
|
||||||
}
|
|
||||||
val optionsPercent = oneVoteInPercent * votersAmountForThisOption
|
|
||||||
|
|
||||||
val pollResultItem = PollResultItem(
|
|
||||||
option,
|
|
||||||
optionsPercent,
|
|
||||||
isOptionSelfVoted(poll, index),
|
|
||||||
null
|
|
||||||
)
|
|
||||||
adapter?.list?.add(pollResultItem)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Log.e(TAG, "failed to get data to show poll results")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun isOptionSelfVoted(poll: Poll, index: Int): Boolean {
|
|
||||||
return poll.votedSelf?.contains(index) == true
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun initEditButton(showEditButton: Boolean) {
|
private fun initEditButton(showEditButton: Boolean) {
|
||||||
if (showEditButton) {
|
if (showEditButton) {
|
||||||
_binding?.editVoteButton?.visibility = View.VISIBLE
|
_binding?.editVoteButton?.visibility = View.VISIBLE
|
||||||
@ -161,8 +121,8 @@ class PollResultsFragment(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onClick(pollResultItem: PollResultItem) {
|
override fun onClick(pollResultHeaderItem: PollResultHeaderItem) {
|
||||||
Log.d(TAG, "click..")
|
viewModel.filterItems()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroyView() {
|
override fun onDestroyView() {
|
||||||
|
@ -24,6 +24,10 @@ package com.nextcloud.talk.polls.viewmodels
|
|||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
|
import com.nextcloud.talk.polls.adapters.PollResultHeaderItem
|
||||||
|
import com.nextcloud.talk.polls.adapters.PollResultItem
|
||||||
|
import com.nextcloud.talk.polls.adapters.PollResultVoterItem
|
||||||
|
import com.nextcloud.talk.polls.model.Poll
|
||||||
import com.nextcloud.talk.polls.repositories.PollRepository
|
import com.nextcloud.talk.polls.repositories.PollRepository
|
||||||
import io.reactivex.disposables.Disposable
|
import io.reactivex.disposables.Disposable
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@ -33,10 +37,20 @@ class PollResultsViewModel @Inject constructor(private val repository: PollRepos
|
|||||||
sealed interface ViewState
|
sealed interface ViewState
|
||||||
object InitialState : ViewState
|
object InitialState : ViewState
|
||||||
|
|
||||||
|
private var _poll: Poll? = null
|
||||||
|
val poll: Poll?
|
||||||
|
get() = _poll
|
||||||
|
|
||||||
private val _viewState: MutableLiveData<ViewState> = MutableLiveData(InitialState)
|
private val _viewState: MutableLiveData<ViewState> = MutableLiveData(InitialState)
|
||||||
val viewState: LiveData<ViewState>
|
val viewState: LiveData<ViewState>
|
||||||
get() = _viewState
|
get() = _viewState
|
||||||
|
|
||||||
|
private var _unfilteredItems: ArrayList<PollResultItem> = ArrayList()
|
||||||
|
|
||||||
|
private var _items: MutableLiveData<ArrayList<PollResultItem>> = MutableLiveData<ArrayList<PollResultItem>>()
|
||||||
|
val items: LiveData<ArrayList<PollResultItem>>
|
||||||
|
get() = _items
|
||||||
|
|
||||||
private var disposable: Disposable? = null
|
private var disposable: Disposable? = null
|
||||||
|
|
||||||
override fun onCleared() {
|
override fun onCleared() {
|
||||||
@ -44,6 +58,82 @@ class PollResultsViewModel @Inject constructor(private val repository: PollRepos
|
|||||||
disposable?.dispose()
|
disposable?.dispose()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun setPoll(poll: Poll) {
|
||||||
|
_poll = poll
|
||||||
|
initPollResults(_poll!!)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initPollResults(poll: Poll) {
|
||||||
|
_items.value = ArrayList()
|
||||||
|
|
||||||
|
val votersAmount = getVotersAmount(poll)
|
||||||
|
val oneVoteInPercent = 100 / votersAmount
|
||||||
|
|
||||||
|
poll.options?.forEachIndexed { index, option ->
|
||||||
|
val votersAmountForThisOption = getVotersAmountForOption(poll, index)
|
||||||
|
val optionsPercent = oneVoteInPercent * votersAmountForThisOption
|
||||||
|
|
||||||
|
val pollResultHeaderItem = PollResultHeaderItem(
|
||||||
|
option,
|
||||||
|
optionsPercent,
|
||||||
|
isOptionSelfVoted(poll, index)
|
||||||
|
)
|
||||||
|
addToItems(pollResultHeaderItem)
|
||||||
|
|
||||||
|
val voters = poll.details?.filter { it.optionId == index }
|
||||||
|
if (!voters.isNullOrEmpty()) {
|
||||||
|
voters.forEach {
|
||||||
|
addToItems(PollResultVoterItem(it))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_unfilteredItems = _items.value?.let { ArrayList(it) }!!
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun addToItems(pollResultItem: PollResultItem) {
|
||||||
|
val tempList = _items.value
|
||||||
|
tempList!!.add(pollResultItem)
|
||||||
|
_items.value = tempList
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getVotersAmount(poll: Poll): Int {
|
||||||
|
if (poll.details != null) {
|
||||||
|
return poll.details.size
|
||||||
|
} else if (poll.votes != null) {
|
||||||
|
return poll.numVoters
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getVotersAmountForOption(poll: Poll, index: Int): Int {
|
||||||
|
var votersAmountForThisOption: Int? = 0
|
||||||
|
if (poll.details != null) {
|
||||||
|
votersAmountForThisOption = poll.details.filter { it.optionId == index }.size
|
||||||
|
} else if (poll.votes != null) {
|
||||||
|
votersAmountForThisOption = poll.votes.filter { it.key.toInt() == index }[index.toString()]
|
||||||
|
if (votersAmountForThisOption == null) {
|
||||||
|
votersAmountForThisOption = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return votersAmountForThisOption!!
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun isOptionSelfVoted(poll: Poll, index: Int): Boolean {
|
||||||
|
return poll.votedSelf?.contains(index) == true
|
||||||
|
}
|
||||||
|
|
||||||
|
fun filterItems() {
|
||||||
|
if (_items.value?.containsAll(_unfilteredItems) == true) {
|
||||||
|
val filteredList = _items.value?.filter { it.getViewType() == PollResultHeaderItem.VIEW_TYPE } as
|
||||||
|
MutableList<PollResultItem>
|
||||||
|
|
||||||
|
_items.value = ArrayList(filteredList)
|
||||||
|
} else {
|
||||||
|
_items.value = _unfilteredItems
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val TAG = PollResultsViewModel::class.java.simpleName
|
private val TAG = PollResultsViewModel::class.java.simpleName
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,7 @@
|
|||||||
android:id="@+id/poll_results_list"
|
android:id="@+id/poll_results_list"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
tools:listitem="@layout/poll_result_item" />
|
tools:listitem="@layout/poll_result_header_item" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
<com.google.android.material.button.MaterialButton
|
||||||
|
@ -34,17 +34,7 @@
|
|||||||
app:trackColor="@color/dialog_background"
|
app:trackColor="@color/dialog_background"
|
||||||
app:trackCornerRadius="5dp"
|
app:trackCornerRadius="5dp"
|
||||||
app:trackThickness="5dp"
|
app:trackThickness="5dp"
|
||||||
|
android:paddingBottom="@dimen/standard_half_padding"
|
||||||
tools:progress="50" />
|
tools:progress="50" />
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/poll_option_detail"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="4dp"
|
|
||||||
android:layout_marginBottom="4dp"
|
|
||||||
android:orientation="horizontal"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="@+id/poll_option_text"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/poll_option_bar" />
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
25
app/src/main/res/layout/poll_result_voter_item.xml
Normal file
25
app/src/main/res/layout/poll_result_voter_item.xml
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingBottom="4dp"
|
||||||
|
tools:background="@color/white">
|
||||||
|
|
||||||
|
<com.facebook.drawee.view.SimpleDraweeView
|
||||||
|
android:id="@+id/poll_voter_avatar"
|
||||||
|
android:layout_width="32dp"
|
||||||
|
android:layout_height="32dp"
|
||||||
|
android:layout_marginStart="12dp"
|
||||||
|
android:layout_marginEnd="8dp"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
app:roundAsCircle="true" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/poll_voter_name"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
tools:text="Bill Murray" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
Loading…
Reference in New Issue
Block a user