mirror of
https://github.com/nextcloud/talk-android
synced 2025-07-13 07:44:11 +01:00
wip: show user avatars for closed public polls
Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
This commit is contained in:
parent
fb54b35cf0
commit
318549a63a
@ -125,6 +125,7 @@ class IncomingPollMessageViewHolder(incomingView: View, payload: Any) : MessageH
|
|||||||
|
|
||||||
binding.bubble.setOnClickListener {
|
binding.bubble.setOnClickListener {
|
||||||
val pollVoteDialog = PollMainDialogFragment.newInstance(
|
val pollVoteDialog = PollMainDialogFragment.newInstance(
|
||||||
|
message.activeUser!!,
|
||||||
roomToken,
|
roomToken,
|
||||||
pollId,
|
pollId,
|
||||||
pollName
|
pollName
|
||||||
|
@ -141,6 +141,7 @@ class OutcomingPollMessageViewHolder(outcomingView: View, payload: Any) : Messag
|
|||||||
|
|
||||||
binding.bubble.setOnClickListener {
|
binding.bubble.setOnClickListener {
|
||||||
val pollVoteDialog = PollMainDialogFragment.newInstance(
|
val pollVoteDialog = PollMainDialogFragment.newInstance(
|
||||||
|
message.activeUser!!,
|
||||||
roomToken,
|
roomToken,
|
||||||
pollId,
|
pollId,
|
||||||
pollName
|
pollName
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
package com.nextcloud.talk.polls.adapters
|
package com.nextcloud.talk.polls.adapters
|
||||||
|
|
||||||
class PollResultItem(
|
import com.nextcloud.talk.polls.model.PollDetails
|
||||||
val pollOption: String,
|
|
||||||
val pollPercent: Int,
|
|
||||||
val selfVoted: Boolean
|
|
||||||
|
|
||||||
// val voters....
|
class PollResultItem(
|
||||||
|
val name: String,
|
||||||
|
val percent: Int,
|
||||||
|
val selfVoted: Boolean,
|
||||||
|
val voters: List<PollDetails>?
|
||||||
)
|
)
|
||||||
|
@ -2,34 +2,106 @@ package com.nextcloud.talk.polls.adapters
|
|||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.graphics.Typeface
|
import android.graphics.Typeface
|
||||||
|
import android.text.TextUtils
|
||||||
import android.view.View
|
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 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.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(
|
class PollResultViewHolder(
|
||||||
private val binding: PollResultItemBinding,
|
private val user: UserEntity,
|
||||||
private val showDetails: Boolean,
|
private val binding: PollResultItemBinding
|
||||||
|
) : RecyclerView.ViewHolder(binding.root) {
|
||||||
) : RecyclerView.ViewHolder(binding.root) {
|
|
||||||
|
|
||||||
@SuppressLint("SetTextI18n")
|
@SuppressLint("SetTextI18n")
|
||||||
fun bind(pollResultItem: PollResultItem, clickListener: PollResultItemClickListener) {
|
fun bind(pollResultItem: PollResultItem, clickListener: PollResultItemClickListener) {
|
||||||
binding.root.setOnClickListener { clickListener.onClick(pollResultItem) }
|
binding.root.setOnClickListener { clickListener.onClick(pollResultItem) }
|
||||||
|
|
||||||
binding.pollOptionText.text = pollResultItem.pollOption
|
// binding.root.setOnClickListener { clickListener.onClick(pollResultItem) }
|
||||||
binding.pollOptionPercentText.text = pollResultItem.pollPercent.toString() + "%"
|
|
||||||
|
binding.pollOptionText.text = pollResultItem.name
|
||||||
|
binding.pollOptionPercentText.text = "${pollResultItem.percent}%"
|
||||||
|
|
||||||
if (pollResultItem.selfVoted) {
|
if (pollResultItem.selfVoted) {
|
||||||
binding.pollOptionText.setTypeface(null, Typeface.BOLD)
|
binding.pollOptionText.setTypeface(null, Typeface.BOLD)
|
||||||
binding.pollOptionPercentText.setTypeface(null, Typeface.BOLD)
|
binding.pollOptionPercentText.setTypeface(null, Typeface.BOLD)
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.pollOptionBar.progress = pollResultItem.pollPercent
|
binding.pollOptionBar.progress = pollResultItem.percent
|
||||||
|
|
||||||
if (showDetails) {
|
if (!pollResultItem.voters.isNullOrEmpty()) {
|
||||||
binding.pollOptionDetail.visibility = View.VISIBLE
|
binding.pollOptionDetail.visibility = View.VISIBLE
|
||||||
|
|
||||||
|
val lp = LinearLayout.LayoutParams(
|
||||||
|
90,
|
||||||
|
70
|
||||||
|
)
|
||||||
|
|
||||||
|
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 {
|
} else {
|
||||||
binding.pollOptionDetail.visibility = View.GONE
|
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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,20 +4,22 @@ 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.PollResultItemBinding
|
||||||
|
import com.nextcloud.talk.models.database.UserEntity
|
||||||
|
|
||||||
class PollResultsAdapter(
|
class PollResultsAdapter(
|
||||||
|
private val user: UserEntity,
|
||||||
private val clickListener: PollResultItemClickListener,
|
private val clickListener: PollResultItemClickListener,
|
||||||
private val showDetails: Boolean
|
|
||||||
) : RecyclerView.Adapter<PollResultViewHolder>() {
|
) : RecyclerView.Adapter<PollResultViewHolder>() {
|
||||||
internal var list: MutableList<PollResultItem> = ArrayList<PollResultItem>()
|
internal var list: MutableList<PollResultItem> = ArrayList<PollResultItem>()
|
||||||
|
|
||||||
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)
|
val itemBinding = PollResultItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)
|
||||||
return PollResultViewHolder(itemBinding, showDetails)
|
return PollResultViewHolder(user, itemBinding)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onBindViewHolder(holder: PollResultViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: PollResultViewHolder, position: Int) {
|
||||||
holder.bind(list[position], clickListener)
|
val pollResultItem = list[position]
|
||||||
|
holder.bind(pollResultItem, clickListener)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getItemCount(): Int {
|
override fun getItemCount(): Int {
|
||||||
|
@ -13,12 +13,14 @@ import autodagger.AutoInjector
|
|||||||
import com.nextcloud.talk.R
|
import com.nextcloud.talk.R
|
||||||
import com.nextcloud.talk.application.NextcloudTalkApplication
|
import com.nextcloud.talk.application.NextcloudTalkApplication
|
||||||
import com.nextcloud.talk.databinding.DialogPollMainBinding
|
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.model.Poll
|
||||||
import com.nextcloud.talk.polls.viewmodels.PollMainViewModel
|
import com.nextcloud.talk.polls.viewmodels.PollMainViewModel
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@AutoInjector(NextcloudTalkApplication::class)
|
@AutoInjector(NextcloudTalkApplication::class)
|
||||||
class PollMainDialogFragment(
|
class PollMainDialogFragment(
|
||||||
|
private val user: UserEntity,
|
||||||
private val pollId: String,
|
private val pollId: String,
|
||||||
private val roomToken: String,
|
private val roomToken: String,
|
||||||
private val pollTitle: String
|
private val pollTitle: String
|
||||||
@ -91,6 +93,7 @@ class PollMainDialogFragment(
|
|||||||
initVotersAmount(poll.numVoters)
|
initVotersAmount(poll.numVoters)
|
||||||
|
|
||||||
val contentFragment = PollResultsFragment(
|
val contentFragment = PollResultsFragment(
|
||||||
|
user,
|
||||||
viewModel,
|
viewModel,
|
||||||
roomToken,
|
roomToken,
|
||||||
pollId
|
pollId
|
||||||
@ -114,9 +117,10 @@ class PollMainDialogFragment(
|
|||||||
companion object {
|
companion object {
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun newInstance(
|
fun newInstance(
|
||||||
|
user: UserEntity,
|
||||||
roomTokenParam: String,
|
roomTokenParam: String,
|
||||||
pollId: String,
|
pollId: String,
|
||||||
name: String
|
name: String
|
||||||
): PollMainDialogFragment = PollMainDialogFragment(pollId, roomTokenParam, name)
|
): PollMainDialogFragment = PollMainDialogFragment(user, pollId, roomTokenParam, name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,7 @@ import androidx.recyclerview.widget.LinearLayoutManager
|
|||||||
import autodagger.AutoInjector
|
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.polls.adapters.PollResultItem
|
import com.nextcloud.talk.polls.adapters.PollResultItem
|
||||||
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
|
||||||
@ -42,6 +43,7 @@ import javax.inject.Inject
|
|||||||
|
|
||||||
@AutoInjector(NextcloudTalkApplication::class)
|
@AutoInjector(NextcloudTalkApplication::class)
|
||||||
class PollResultsFragment(
|
class PollResultsFragment(
|
||||||
|
private val user: UserEntity,
|
||||||
private val parentViewModel: PollMainViewModel,
|
private val parentViewModel: PollMainViewModel,
|
||||||
private val roomToken: String,
|
private val roomToken: String,
|
||||||
private val pollId: String
|
private val pollId: String
|
||||||
@ -78,7 +80,7 @@ class PollResultsFragment(
|
|||||||
|
|
||||||
parentViewModel.viewState.observe(viewLifecycleOwner) { state ->
|
parentViewModel.viewState.observe(viewLifecycleOwner) { state ->
|
||||||
if (state is PollMainViewModel.PollResultState) {
|
if (state is PollMainViewModel.PollResultState) {
|
||||||
initAdapter(state.showParticipants)
|
initAdapter()
|
||||||
initPollResults(state.poll)
|
initPollResults(state.poll)
|
||||||
initEditButton(state.showEditButton)
|
initEditButton(state.showEditButton)
|
||||||
initCloseButton(state.showCloseButton)
|
initCloseButton(state.showCloseButton)
|
||||||
@ -86,8 +88,8 @@ class PollResultsFragment(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun initAdapter(showParticipants: Boolean) {
|
private fun initAdapter() {
|
||||||
adapter = PollResultsAdapter(this, showParticipants)
|
adapter = PollResultsAdapter(user, this)
|
||||||
_binding?.pollResultsList?.adapter = adapter
|
_binding?.pollResultsList?.adapter = adapter
|
||||||
_binding?.pollResultsList?.layoutManager = LinearLayoutManager(context)
|
_binding?.pollResultsList?.layoutManager = LinearLayoutManager(context)
|
||||||
}
|
}
|
||||||
@ -98,15 +100,15 @@ class PollResultsFragment(
|
|||||||
val oneVoteInPercent = 100 / votersAmount // TODO: poll.numVoters when fixed on api
|
val oneVoteInPercent = 100 / votersAmount // TODO: poll.numVoters when fixed on api
|
||||||
|
|
||||||
poll.options?.forEachIndexed { index, option ->
|
poll.options?.forEachIndexed { index, option ->
|
||||||
val votersForThisOption = poll.details.filter { it.optionId == index }.size
|
val votersForThisOption = poll.details.filter { it.optionId == index }
|
||||||
val optionsPercent = oneVoteInPercent * votersForThisOption
|
val optionsPercent = oneVoteInPercent * votersForThisOption.size
|
||||||
|
|
||||||
val pollResultItem = PollResultItem(
|
val pollResultItem = PollResultItem(
|
||||||
option,
|
option,
|
||||||
optionsPercent,
|
optionsPercent,
|
||||||
isOptionSelfVoted(poll, index)
|
isOptionSelfVoted(poll, index),
|
||||||
|
votersForThisOption
|
||||||
)
|
)
|
||||||
// TODO add participants to PollResultItem
|
|
||||||
adapter?.list?.add(pollResultItem)
|
adapter?.list?.add(pollResultItem)
|
||||||
}
|
}
|
||||||
} else if (poll.votes != null) {
|
} else if (poll.votes != null) {
|
||||||
@ -114,16 +116,17 @@ class PollResultsFragment(
|
|||||||
val oneVoteInPercent = 100 / votersAmount
|
val oneVoteInPercent = 100 / votersAmount
|
||||||
|
|
||||||
poll.options?.forEachIndexed { index, option ->
|
poll.options?.forEachIndexed { index, option ->
|
||||||
var votersForThisOption = poll.votes.filter { it.key.toInt() == index }[index.toString()]
|
var votersAmountForThisOption = poll.votes.filter { it.key.toInt() == index }[index.toString()]
|
||||||
if (votersForThisOption == null) {
|
if (votersAmountForThisOption == null) {
|
||||||
votersForThisOption = 0
|
votersAmountForThisOption = 0
|
||||||
}
|
}
|
||||||
val optionsPercent = oneVoteInPercent * votersForThisOption
|
val optionsPercent = oneVoteInPercent * votersAmountForThisOption
|
||||||
|
|
||||||
val pollResultItem = PollResultItem(
|
val pollResultItem = PollResultItem(
|
||||||
option,
|
option,
|
||||||
optionsPercent,
|
optionsPercent,
|
||||||
isOptionSelfVoted(poll, index)
|
isOptionSelfVoted(poll, index),
|
||||||
|
null
|
||||||
)
|
)
|
||||||
adapter?.list?.add(pollResultItem)
|
adapter?.list?.add(pollResultItem)
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,6 @@ class PollMainViewModel @Inject constructor(private val repository: PollReposito
|
|||||||
|
|
||||||
open class PollResultState(
|
open class PollResultState(
|
||||||
val poll: Poll,
|
val poll: Poll,
|
||||||
val showParticipants: Boolean,
|
|
||||||
val showEditButton: Boolean,
|
val showEditButton: Boolean,
|
||||||
val showCloseButton: Boolean
|
val showCloseButton: Boolean
|
||||||
) : ViewState
|
) : ViewState
|
||||||
@ -129,11 +128,10 @@ class PollMainViewModel @Inject constructor(private val repository: PollReposito
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun setPollResultState(poll: Poll) {
|
private fun setPollResultState(poll: Poll) {
|
||||||
val showDetails = poll.status == Poll.STATUS_CLOSED && poll.resultMode == Poll.RESULT_MODE_PUBLIC
|
|
||||||
val showEditButton = poll.status == Poll.STATUS_OPEN && poll.resultMode == Poll.RESULT_MODE_PUBLIC
|
val showEditButton = poll.status == Poll.STATUS_OPEN && poll.resultMode == Poll.RESULT_MODE_PUBLIC
|
||||||
val showCloseButton = poll.status == Poll.STATUS_OPEN && isPollCreatedByCurrentUser(poll)
|
val showCloseButton = poll.status == Poll.STATUS_OPEN && isPollCreatedByCurrentUser(poll)
|
||||||
|
|
||||||
_viewState.value = PollResultState(poll, showDetails, showEditButton, showCloseButton)
|
_viewState.value = PollResultState(poll, showEditButton, showCloseButton)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun votedForOpenHiddenPoll(poll: Poll): Boolean {
|
private fun votedForOpenHiddenPoll(poll: Poll): Boolean {
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/poll_results_list_wrapper"
|
android:id="@+id/poll_results_list_wrapper"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="288dp"
|
android:layout_height="wrap_content"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent">
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
|
@ -38,11 +38,6 @@
|
|||||||
app:layout_constraintStart_toStartOf="@+id/poll_option_text"
|
app:layout_constraintStart_toStartOf="@+id/poll_option_text"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/poll_option_bar">
|
app:layout_constraintTop_toBottomOf="@+id/poll_option_bar">
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="here the details..." />
|
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
Loading…
Reference in New Issue
Block a user