From 20dabf3a724e89116abf52387b05e989afae687b Mon Sep 17 00:00:00 2001 From: Marcel Hibbe Date: Wed, 20 Jul 2022 20:11:02 +0200 Subject: [PATCH] wip. toggle between voters overview and voters details Signed-off-by: Marcel Hibbe --- .../adapters/PollResultVotersOverviewItem.kt | 38 ++++++ .../PollResultVotersOverviewViewHolder.kt | 109 ++++++++++++++++++ .../talk/polls/adapters/PollResultsAdapter.kt | 12 ++ .../talk/polls/ui/PollResultsFragment.kt | 2 +- .../polls/viewmodels/PollResultsViewModel.kt | 33 +++--- .../poll_result_voters_overview_item.xml | 32 +++++ 6 files changed, 208 insertions(+), 18 deletions(-) create mode 100644 app/src/main/java/com/nextcloud/talk/polls/adapters/PollResultVotersOverviewItem.kt create mode 100644 app/src/main/java/com/nextcloud/talk/polls/adapters/PollResultVotersOverviewViewHolder.kt create mode 100644 app/src/main/res/layout/poll_result_voters_overview_item.xml diff --git a/app/src/main/java/com/nextcloud/talk/polls/adapters/PollResultVotersOverviewItem.kt b/app/src/main/java/com/nextcloud/talk/polls/adapters/PollResultVotersOverviewItem.kt new file mode 100644 index 000000000..ffb3065f3 --- /dev/null +++ b/app/src/main/java/com/nextcloud/talk/polls/adapters/PollResultVotersOverviewItem.kt @@ -0,0 +1,38 @@ +/* + * Nextcloud Talk application + * + * @author Marcel Hibbe + * Copyright (C) 2022 Marcel Hibbe + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.nextcloud.talk.polls.adapters + +import com.nextcloud.talk.R +import com.nextcloud.talk.polls.model.PollDetails + +data class PollResultVotersOverviewItem( + val detailsList: List +) : PollResultItem { + + override fun getViewType(): Int { + return VIEW_TYPE + } + + companion object { + // layout is used as view type for uniqueness + const val VIEW_TYPE: Int = R.layout.poll_result_voters_overview_item + } +} diff --git a/app/src/main/java/com/nextcloud/talk/polls/adapters/PollResultVotersOverviewViewHolder.kt b/app/src/main/java/com/nextcloud/talk/polls/adapters/PollResultVotersOverviewViewHolder.kt new file mode 100644 index 000000000..c421ef80b --- /dev/null +++ b/app/src/main/java/com/nextcloud/talk/polls/adapters/PollResultVotersOverviewViewHolder.kt @@ -0,0 +1,109 @@ +/* + * Nextcloud Talk application + * + * @author Marcel Hibbe + * Copyright (C) 2022 Marcel Hibbe + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.nextcloud.talk.polls.adapters + +import android.annotation.SuppressLint +import android.text.TextUtils +import android.widget.LinearLayout +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.data.user.model.User +import com.nextcloud.talk.databinding.PollResultVotersOverviewItemBinding +import com.nextcloud.talk.polls.model.PollDetails +import com.nextcloud.talk.utils.ApiUtils +import com.nextcloud.talk.utils.DisplayUtils + +class PollResultVotersOverviewViewHolder( + private val user: User, + override val binding: PollResultVotersOverviewItemBinding +) : PollResultViewHolder(binding) { + + @SuppressLint("SetTextI18n") + override fun bind(pollResultItem: PollResultItem, clickListener: PollResultItemClickListener) { + val item = pollResultItem as PollResultVotersOverviewItem + + val lp = LinearLayout.LayoutParams( + AVATAR_WIDTH, + AVATAR_HEIGHT + ) + + item.detailsList.forEach { + val avatar = SimpleDraweeView(binding.root.context) + avatar.layoutParams = lp + + val roundingParams = RoundingParams.fromCornersRadius(AVATAR_RADIUS) + roundingParams.roundAsCircle = true + + avatar.hierarchy.roundingParams = roundingParams + avatar.controller = getAvatarDraweeController(it) + + binding.votersAvatarsOverviewWrapper.addView(avatar) + } + } + + private fun getAvatarDraweeController(pollDetail: PollDetails): DraweeController? { + var draweeController: DraweeController? = null + if (pollDetail.actorType == "guests") { + var displayName = NextcloudTalkApplication.sharedApplication?.resources?.getString(R.string.nc_guest) + if (!TextUtils.isEmpty(pollDetail.actorDisplayName)) { + displayName = pollDetail.actorDisplayName!! + } + draweeController = Fresco.newDraweeControllerBuilder() + .setAutoPlayAnimations(true) + .setImageRequest( + DisplayUtils.getImageRequestForUrl( + ApiUtils.getUrlForGuestAvatar( + user.baseUrl, + displayName, + false + ), + user + ) + ) + .build() + } else if (pollDetail.actorType == "users") { + draweeController = Fresco.newDraweeControllerBuilder() + .setAutoPlayAnimations(true) + .setImageRequest( + DisplayUtils.getImageRequestForUrl( + ApiUtils.getUrlForAvatar( + user.baseUrl, + pollDetail.actorId, + false + ), + user + ) + ) + .build() + } + return draweeController + } + + companion object { + const val AVATAR_WIDTH = 90 + const val AVATAR_HEIGHT = 70 + const val AVATAR_RADIUS = 5f + } +} diff --git a/app/src/main/java/com/nextcloud/talk/polls/adapters/PollResultsAdapter.kt b/app/src/main/java/com/nextcloud/talk/polls/adapters/PollResultsAdapter.kt index 9fa3b1dc2..98a576cba 100644 --- a/app/src/main/java/com/nextcloud/talk/polls/adapters/PollResultsAdapter.kt +++ b/app/src/main/java/com/nextcloud/talk/polls/adapters/PollResultsAdapter.kt @@ -26,6 +26,7 @@ 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.databinding.PollResultVotersOverviewItemBinding class PollResultsAdapter( private val user: User, @@ -51,6 +52,13 @@ class PollResultsAdapter( ) viewHolder = PollResultVoterViewHolder(user, itemBinding) } + PollResultVotersOverviewItem.VIEW_TYPE -> { + val itemBinding = PollResultVotersOverviewItemBinding.inflate( + LayoutInflater.from(parent.context), parent, + false + ) + viewHolder = PollResultVotersOverviewViewHolder(user, itemBinding) + } } return viewHolder!! } @@ -65,6 +73,10 @@ class PollResultsAdapter( val pollResultItem = list[position] holder.bind(pollResultItem as PollResultVoterItem, clickListener) } + PollResultVotersOverviewItem.VIEW_TYPE -> { + val pollResultItem = list[position] + holder.bind(pollResultItem as PollResultVotersOverviewItem, clickListener) + } } } diff --git a/app/src/main/java/com/nextcloud/talk/polls/ui/PollResultsFragment.kt b/app/src/main/java/com/nextcloud/talk/polls/ui/PollResultsFragment.kt index 2c48644bd..578a7d648 100644 --- a/app/src/main/java/com/nextcloud/talk/polls/ui/PollResultsFragment.kt +++ b/app/src/main/java/com/nextcloud/talk/polls/ui/PollResultsFragment.kt @@ -128,7 +128,7 @@ class PollResultsFragment : Fragment(), PollResultItemClickListener { } override fun onClick(pollResultHeaderItem: PollResultHeaderItem) { - viewModel.filterItems() + viewModel.toggleDetails() } companion object { diff --git a/app/src/main/java/com/nextcloud/talk/polls/viewmodels/PollResultsViewModel.kt b/app/src/main/java/com/nextcloud/talk/polls/viewmodels/PollResultsViewModel.kt index e20b5731d..015341016 100644 --- a/app/src/main/java/com/nextcloud/talk/polls/viewmodels/PollResultsViewModel.kt +++ b/app/src/main/java/com/nextcloud/talk/polls/viewmodels/PollResultsViewModel.kt @@ -27,6 +27,7 @@ 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.adapters.PollResultVotersOverviewItem import com.nextcloud.talk.polls.model.Poll import io.reactivex.disposables.Disposable import javax.inject.Inject @@ -40,7 +41,8 @@ class PollResultsViewModel @Inject constructor() : ViewModel() { val poll: Poll? get() = _poll - private var _unfilteredItems: ArrayList = ArrayList() + private var _itemsOverviewList: ArrayList = ArrayList() + private var _itemsDetailsList: ArrayList = ArrayList() private var _items: MutableLiveData?> = MutableLiveData?>() val items: MutableLiveData?> @@ -72,23 +74,23 @@ class PollResultsViewModel @Inject constructor() : ViewModel() { optionsPercent, isOptionSelfVoted(poll, index) ) - addToItems(pollResultHeaderItem) + _itemsOverviewList.add(pollResultHeaderItem) + _itemsDetailsList.add(pollResultHeaderItem) val voters = poll.details?.filter { it.optionId == index } + + if (!voters.isNullOrEmpty()) { + _itemsOverviewList.add(PollResultVotersOverviewItem(voters)) + } + if (!voters.isNullOrEmpty()) { voters.forEach { - addToItems(PollResultVoterItem(it)) + _itemsDetailsList.add(PollResultVoterItem(it)) } } } - _unfilteredItems = _items.value?.let { ArrayList(it) }!! - } - - private fun addToItems(pollResultItem: PollResultItem) { - val tempList = _items.value - tempList!!.add(pollResultItem) - _items.value = tempList + _items.value = _itemsOverviewList } private fun getVotersAmountForOption(poll: Poll, index: Int): Int { @@ -108,14 +110,11 @@ class PollResultsViewModel @Inject constructor() : ViewModel() { 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 - - _items.value = ArrayList(filteredList) + fun toggleDetails() { + if (_items.value?.containsAll(_itemsDetailsList) == true) { + _items.value = _itemsOverviewList } else { - _items.value = _unfilteredItems + _items.value = _itemsDetailsList } } diff --git a/app/src/main/res/layout/poll_result_voters_overview_item.xml b/app/src/main/res/layout/poll_result_voters_overview_item.xml new file mode 100644 index 000000000..de5542cc2 --- /dev/null +++ b/app/src/main/res/layout/poll_result_voters_overview_item.xml @@ -0,0 +1,32 @@ + + + + +