Skip to content

Commit

Permalink
Feature/all poll options (#5406)
Browse files Browse the repository at this point in the history
* Create view for poll option

* Create a dialog to show all options

* Create click listener to show all options

* Add new option button to show all poll options

* Use AllPollOption dialog when click on the poll attachment

* Update CHANGELOG.md

* Simplify logic to show dialog fragment

* Move `AllPollOptionsDialogFragment` to a custom package
  • Loading branch information
JcMinarro authored Sep 18, 2024
1 parent 88d14a9 commit 99fbfde
Show file tree
Hide file tree
Showing 13 changed files with 484 additions and 13 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
### ⬆️ Improved

### ✅ Added
- Split poll options on the poll attachment to show a fit nubmer of options and a button to open new view with all options.[#5406](https://github.com/GetStream/stream-chat-android/pull/5406)

### ⚠️ Changed

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2446,6 +2446,10 @@ public abstract interface class io/getstream/chat/android/ui/feature/messages/li
public abstract fun onScrollToBottom ()V
}

public abstract interface class io/getstream/chat/android/ui/feature/messages/list/MessageListView$OnShowAllPollOptionClickListener {
public abstract fun onShowAllPollOptionClick (Lio/getstream/chat/android/models/Message;Lio/getstream/chat/android/models/Poll;)Z
}

public abstract interface class io/getstream/chat/android/ui/feature/messages/list/MessageListView$OnThreadClickListener {
public abstract fun onThreadClick (Lio/getstream/chat/android/models/Message;)Z
}
Expand Down Expand Up @@ -2966,6 +2970,7 @@ public abstract interface class io/getstream/chat/android/ui/feature/messages/li
public abstract fun getMessageRetryListener ()Lio/getstream/chat/android/ui/feature/messages/list/MessageListView$OnMessageRetryListener;
public abstract fun getOnPollCloseClickListener ()Lio/getstream/chat/android/ui/feature/messages/list/MessageListView$OnPollCloseClickListener;
public abstract fun getOnPollOptionClickListener ()Lio/getstream/chat/android/ui/feature/messages/list/MessageListView$OnPollOptionClickListener;
public abstract fun getOnShowAllPollOptionClickListener ()Lio/getstream/chat/android/ui/feature/messages/list/MessageListView$OnShowAllPollOptionClickListener;
public abstract fun getOnViewPollResultClickListener ()Lio/getstream/chat/android/ui/feature/messages/list/MessageListView$OnViewPollResultClickListener;
public abstract fun getReactionViewClickListener ()Lio/getstream/chat/android/ui/feature/messages/list/MessageListView$OnReactionViewClickListener;
public abstract fun getThreadClickListener ()Lio/getstream/chat/android/ui/feature/messages/list/MessageListView$OnThreadClickListener;
Expand Down Expand Up @@ -3292,6 +3297,20 @@ public class io/getstream/chat/android/ui/feature/messages/list/background/Messa
public final class io/getstream/chat/android/ui/feature/messages/list/background/MessageBackgroundFactoryImpl$Companion {
}

public final class io/getstream/chat/android/ui/feature/messages/list/internal/poll/AllPollOptionsDialogFragment : androidx/appcompat/app/AppCompatDialogFragment {
public static final field Companion Lio/getstream/chat/android/ui/feature/messages/list/internal/poll/AllPollOptionsDialogFragment$Companion;
public static final field TAG Ljava/lang/String;
public fun <init> ()V
public fun getTheme ()I
public fun onCreateView (Landroid/view/LayoutInflater;Landroid/view/ViewGroup;Landroid/os/Bundle;)Landroid/view/View;
public fun onDestroyView ()V
public fun onViewCreated (Landroid/view/View;Landroid/os/Bundle;)V
}

public final class io/getstream/chat/android/ui/feature/messages/list/internal/poll/AllPollOptionsDialogFragment$Companion {
public final fun newInstance (Lio/getstream/chat/android/models/Message;)Lio/getstream/chat/android/ui/feature/messages/list/internal/poll/AllPollOptionsDialogFragment;
}

public class io/getstream/chat/android/ui/feature/messages/list/options/message/DefaultMessageOptionItemsFactory : io/getstream/chat/android/ui/feature/messages/list/options/message/MessageOptionItemsFactory {
public fun <init> (Landroid/content/Context;)V
public fun createMessageOptionItems (Lio/getstream/chat/android/models/Message;Lio/getstream/chat/android/models/User;ZLjava/util/Set;Lio/getstream/chat/android/ui/feature/messages/list/MessageListViewStyle;)Ljava/util/List;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ import io.getstream.chat.android.ui.feature.messages.list.background.MessageBack
import io.getstream.chat.android.ui.feature.messages.list.background.MessageBackgroundFactoryImpl
import io.getstream.chat.android.ui.feature.messages.list.internal.HiddenMessageListItemPredicate
import io.getstream.chat.android.ui.feature.messages.list.internal.MessageListScrollHelper
import io.getstream.chat.android.ui.feature.messages.list.internal.poll.AllPollOptionsDialogFragment
import io.getstream.chat.android.ui.feature.messages.list.options.message.MessageOptionItem
import io.getstream.chat.android.ui.feature.messages.list.options.message.MessageOptionItemsFactory
import io.getstream.chat.android.ui.feature.messages.list.options.message.MessageOptionsDialogFragment
Expand Down Expand Up @@ -591,6 +592,13 @@ public class MessageListView : ConstraintLayout {
false
}
private val defaultOnPollOptionClickListener = OnPollOptionClickListener { _, _, _ -> false }
private val defaultOnShowAllPollOptionClickListener = OnShowAllPollOptionClickListener { message, _ ->
context.getFragmentManager()?.let { fragmentManager ->
AllPollOptionsDialogFragment.newInstance(message)
.show(fragmentManager, AllPollOptionsDialogFragment.TAG)
true
} ?: false
}
private val defaultOnPollCloseClickListener = OnPollCloseClickListener { false }
private val defaultOnViewPollResultClickListener = OnViewPollResultClickListener { false }

Expand All @@ -606,6 +614,7 @@ public class MessageListView : ConstraintLayout {
giphySendListener = defaultGiphySendListener,
linkClickListener = defaultLinkClickListener,
onPollOptionClickListener = defaultOnPollOptionClickListener,
onShowAllPollOptionClickListener = defaultOnShowAllPollOptionClickListener,
onPollCloseClickListener = defaultOnPollCloseClickListener,
onViewPollResultClickListener = defaultOnViewPollResultClickListener,
)
Expand Down Expand Up @@ -2190,6 +2199,10 @@ public class MessageListView : ConstraintLayout {
public fun onPollOptionClick(message: Message, poll: Poll, option: Option): Boolean
}

public fun interface OnShowAllPollOptionClickListener {
public fun onShowAllPollOptionClick(message: Message, poll: Poll): Boolean
}

public fun interface OnPollCloseClickListener {
public fun onPollCloseClick(poll: Poll): Boolean
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import io.getstream.chat.android.ui.feature.messages.list.MessageListView.OnMess
import io.getstream.chat.android.ui.feature.messages.list.MessageListView.OnPollCloseClickListener
import io.getstream.chat.android.ui.feature.messages.list.MessageListView.OnPollOptionClickListener
import io.getstream.chat.android.ui.feature.messages.list.MessageListView.OnReactionViewClickListener
import io.getstream.chat.android.ui.feature.messages.list.MessageListView.OnShowAllPollOptionClickListener
import io.getstream.chat.android.ui.feature.messages.list.MessageListView.OnThreadClickListener
import io.getstream.chat.android.ui.feature.messages.list.MessageListView.OnUnreadLabelReachedListener
import io.getstream.chat.android.ui.feature.messages.list.MessageListView.OnUserClickListener
Expand Down Expand Up @@ -72,6 +73,7 @@ public sealed interface MessageListListeners {
public val linkClickListener: OnLinkClickListener
public val unreadLabelReachedListener: OnUnreadLabelReachedListener
public val onPollOptionClickListener: OnPollOptionClickListener
public val onShowAllPollOptionClickListener: OnShowAllPollOptionClickListener
public val onPollCloseClickListener: OnPollCloseClickListener
public val onViewPollResultClickListener: OnViewPollResultClickListener
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import io.getstream.chat.android.ui.feature.messages.list.MessageListView.OnMess
import io.getstream.chat.android.ui.feature.messages.list.MessageListView.OnPollCloseClickListener
import io.getstream.chat.android.ui.feature.messages.list.MessageListView.OnPollOptionClickListener
import io.getstream.chat.android.ui.feature.messages.list.MessageListView.OnReactionViewClickListener
import io.getstream.chat.android.ui.feature.messages.list.MessageListView.OnShowAllPollOptionClickListener
import io.getstream.chat.android.ui.feature.messages.list.MessageListView.OnThreadClickListener
import io.getstream.chat.android.ui.feature.messages.list.MessageListView.OnUnreadLabelReachedListener
import io.getstream.chat.android.ui.feature.messages.list.MessageListView.OnUserClickListener
Expand All @@ -45,6 +46,7 @@ internal class MessageListListenerContainerImpl(
linkClickListener: OnLinkClickListener = OnLinkClickListener(EmptyFunctions.ONE_PARAM),
onUnreadLabelReachedListener: OnUnreadLabelReachedListener = OnUnreadLabelReachedListener { },
onPollOptionClickListener: OnPollOptionClickListener,
onShowAllPollOptionClickListener: OnShowAllPollOptionClickListener,
onPollCloseClickListener: OnPollCloseClickListener,
onViewPollResultClickListener: OnViewPollResultClickListener,
) : MessageListListeners {
Expand Down Expand Up @@ -149,6 +151,14 @@ internal class MessageListListenerContainerImpl(
}
}

override var onShowAllPollOptionClickListener: OnShowAllPollOptionClickListener by ListenerDelegate(
onShowAllPollOptionClickListener,
) { realListener ->
OnShowAllPollOptionClickListener { message, poll ->
realListener().onShowAllPollOptionClick(message, poll)
}
}

override var onPollCloseClickListener: OnPollCloseClickListener by ListenerDelegate(
onPollCloseClickListener,
) { realListener ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import io.getstream.chat.android.ui.databinding.StreamUiItemPollAnswerBinding
import io.getstream.chat.android.ui.databinding.StreamUiItemPollCloseBinding
import io.getstream.chat.android.ui.databinding.StreamUiItemPollHeaderBinding
import io.getstream.chat.android.ui.databinding.StreamUiItemPollResultsBinding
import io.getstream.chat.android.ui.databinding.StreamUiItemPollShowAllOptionsBinding
import io.getstream.chat.android.ui.utils.extensions.createStreamThemeWrapper
import io.getstream.chat.android.ui.utils.extensions.streamThemeInflater
import io.getstream.log.taggedLogger
Expand All @@ -47,6 +48,7 @@ internal class PollView : RecyclerView {
var onOptionClick: ((Option) -> Unit) = { _ -> }
var onClosePollClick: ((Poll) -> Unit) = { _ -> }
var onViewPollResultsClick: ((Poll) -> Unit) = { _ -> }
var onShowAllPollOptionClick: (() -> Unit) = { }

constructor(context: Context) : this(context, null, 0)

Expand Down Expand Up @@ -76,46 +78,59 @@ internal class PollView : RecyclerView {
onOptionClick = { option -> onOptionClick(option) },
onClosePollClick = { onClosePollClick(poll) },
onViewPollResultsClick = { onViewPollResultsClick(poll) },
onShowAllOptionsClick = { onShowAllPollOptionClick() },
)
adapter = pollAdapter
}

val pollItems = mutableListOf<PollItem>()
pollItems.add(PollItem.Header(poll.name, poll.description))
pollItems.addAll(
poll.options.map { option ->
PollItem.Answer(
option = option,
votes = poll.getVotes(option)
.takeUnless { poll.votingVisibility == VotingVisibility.ANONYMOUS }
?: emptyList(),
voteCount = poll.voteCountsByOption[option.id] ?: 0,
isVotedByUser = poll.ownVotes.any { it.optionId == option.id },
totalVotes = poll.voteCountsByOption.values.sum(),
closed = poll.closed,
isWinner = poll.voteCountsByOption[option.id] == poll.voteCountsByOption.values.maxOrNull(),
)
},
poll.options
.take(MAX_OPTIONS)
.map { option ->
PollItem.Answer(
option = option,
votes = poll.getVotes(option)
.takeUnless { poll.votingVisibility == VotingVisibility.ANONYMOUS }
?: emptyList(),
voteCount = poll.voteCountsByOption[option.id] ?: 0,
isVotedByUser = poll.ownVotes.any { it.optionId == option.id },
totalVotes = poll.voteCountsByOption.values.sum(),
closed = poll.closed,
isWinner = poll.voteCountsByOption[option.id] == poll.voteCountsByOption.values.maxOrNull(),
)
},
)
PollItem.ShowAllOptions
.takeIf { poll.options.size > MAX_OPTIONS }
?.takeUnless { poll.closed }
?.let { pollItems.add(it) }
PollItem.ViewResults.takeUnless { poll.ownVotes.isEmpty() }
PollItem.Close.takeIf { isMine && !poll.closed }
?.let { pollItems.add(it) }

pollAdapter.submitList(pollItems)
}

private companion object {
private const val MAX_OPTIONS = 10
}
}

private class PollAdapter(
private val onOptionClick: (Option) -> Unit,
private val onClosePollClick: () -> Unit,
private val onViewPollResultsClick: () -> Unit,
private val onShowAllOptionsClick: () -> Unit,
) : ListAdapter<PollItem, PollItemViewHolder<out PollItem>>(PollItemDiffCallback) {

companion object {
private const val VIEW_TYPE_HEADER = 1
private const val VIEW_TYPE_ANSWER = 2
private const val VIEW_TYPE_CLOSE = 3
private const val VIEW_TYPE_RESULTS = 4
private const val VIEW_TYPE_SHOW_ALL_OPTIONS = 5
}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PollItemViewHolder<out PollItem> {
Expand All @@ -135,6 +150,10 @@ private class PollAdapter(
StreamUiItemPollResultsBinding.inflate(parent.streamThemeInflater, parent, false),
onViewPollResultsClick,
)
VIEW_TYPE_SHOW_ALL_OPTIONS -> ShowAllOptionsViewHolder(
StreamUiItemPollShowAllOptionsBinding.inflate(parent.streamThemeInflater, parent, false),
onShowAllOptionsClick,
)
else -> throw IllegalArgumentException("Unknown view type: $viewType")
}
}
Expand All @@ -144,6 +163,7 @@ private class PollAdapter(
is PollItem.Answer -> VIEW_TYPE_ANSWER
PollItem.Close -> VIEW_TYPE_CLOSE
PollItem.ViewResults -> VIEW_TYPE_RESULTS
PollItem.ShowAllOptions -> VIEW_TYPE_SHOW_ALL_OPTIONS
}

override fun onBindViewHolder(holder: PollItemViewHolder<out PollItem>, position: Int) {
Expand Down Expand Up @@ -179,6 +199,7 @@ private sealed class PollItem {
) : PollItem()

data object Close : PollItem()
data object ShowAllOptions : PollItem()
data object ViewResults : PollItem()
}

Expand Down Expand Up @@ -261,6 +282,15 @@ private class CloseViewHolder(
}
}

private class ShowAllOptionsViewHolder(
private val binding: StreamUiItemPollShowAllOptionsBinding,
private val onShowAllOptions: () -> Unit,
) : PollItemViewHolder<PollItem.ShowAllOptions>(binding) {
override fun bind(pollItem: PollItem.ShowAllOptions) {
binding.root.setOnClickListener { onShowAllOptions() }
}
}

private class ViewResultsViewHolder(
private val binding: StreamUiItemPollResultsBinding,
private val onViewPollResultsClick: () -> Unit,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ public class PollViewHolder(
binding.pollView.onViewPollResultsClick = {
messageListListeners?.onViewPollResultClickListener?.onViewPollResultClick(poll)
}
binding.pollView.onShowAllPollOptionClick = {
messageListListeners?.onShowAllPollOptionClickListener?.onShowAllPollOptionClick(data.message, poll)
}
}
}
}
Loading

0 comments on commit 99fbfde

Please sign in to comment.