Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package io.getstream.chat.android.ui.feature.messages.composer.attachment.picker.poll

import android.os.Bundle
import android.text.InputFilter
import android.view.LayoutInflater
import android.view.MenuItem
import android.view.View
Expand All @@ -39,7 +40,16 @@ import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch

/**
* Represent the bottom sheet dialog that allows users to pick attachments.
* A dialog fragment that allows users to create polls with configurable character limits.
*
* This dialog provides a UI for creating polls with customizable settings including:
* - Poll question with optional character limit
* - Multiple answer options with optional character limit
* - Multiple vote configuration
* - Anonymous poll option
* - Option suggestion capability
*
* Use [newInstance] to create an instance with optional character limits.
*/
public class CreatePollDialogFragment : AppCompatDialogFragment() {

Expand All @@ -48,7 +58,10 @@ public class CreatePollDialogFragment : AppCompatDialogFragment() {
private var createPollDialogListener: CreatePollDialogListener? = null
private val createPollViewModel: CreatePollViewModel by viewModels()
private val optionsAdapter: OptionsAdapter by lazy {
OptionsAdapter { id, text -> createPollViewModel.onOptionTextChanged(id, text) }
OptionsAdapter(
optionTextLimit = arguments?.getInt(ARG_OPTION_TEXT_LIMIT)?.takeIf { it > 0 },
onOptionChange = { id, text -> createPollViewModel.onOptionTextChanged(id, text) },
)
}
private lateinit var sendMenuItem: MenuItem

Expand Down Expand Up @@ -81,6 +94,9 @@ public class CreatePollDialogFragment : AppCompatDialogFragment() {
*/
private fun setupDialog() {
setupToolbar(binding.toolbar)
arguments?.getInt(ARG_QUESTION_TEXT_LIMIT)?.takeIf { it > 0 }?.let { limit ->
binding.question.filters = arrayOf(InputFilter.LengthFilter(limit))
}
binding.multipleAnswersSwitch.setOnCheckedChangeListener { _, isChecked ->
binding.multipleAnswersCount.isVisible = isChecked
createPollViewModel.setAllowMultipleVotes(isChecked)
Expand Down Expand Up @@ -158,15 +174,29 @@ public class CreatePollDialogFragment : AppCompatDialogFragment() {

public companion object {
public const val TAG: String = "create_poll_dialog_fragment"
private const val ARG_QUESTION_TEXT_LIMIT: String = "arg_question_text_limit"
private const val ARG_OPTION_TEXT_LIMIT: String = "arg_option_text_limit"

/**
* Creates a new instance of [CreatePollDialogFragment].
*
* @param createPollDialogListener The listener for poll creation events.
* @param questionTextLimit Optional character limit for the poll question. Null means no limit.
* @param optionTextLimit Optional character limit for poll answer options. Null means no limit.
* @return A new instance of [CreatePollDialogFragment].
*/
public fun newInstance(createPollDialogListener: CreatePollDialogListener): CreatePollDialogFragment {
return CreatePollDialogFragment()
.setCreatePollDialogListener(createPollDialogListener)
@JvmOverloads
public fun newInstance(
createPollDialogListener: CreatePollDialogListener,
questionTextLimit: Int? = null,
optionTextLimit: Int? = null,
): CreatePollDialogFragment {
return CreatePollDialogFragment().apply {
arguments = Bundle().apply {
questionTextLimit?.let { putInt(ARG_QUESTION_TEXT_LIMIT, it) }
optionTextLimit?.let { putInt(ARG_OPTION_TEXT_LIMIT, it) }
}
}.setCreatePollDialogListener(createPollDialogListener)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package io.getstream.chat.android.ui.feature.messages.composer.attachment.picker.poll

import android.text.Editable
import android.text.InputFilter
import android.text.TextWatcher
import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
Expand All @@ -27,9 +28,17 @@ import io.getstream.chat.android.ui.databinding.StreamUiPollOptionBinding
import io.getstream.chat.android.ui.utils.extensions.streamThemeInflater

public class OptionsAdapter(
private val optionTextLimit: Int?,
private val onOptionChange: (id: Int, text: String) -> Unit,
) : ListAdapter<PollAnswer, OptionsAdapter.OptionViewHolder>(OptionDiffCallback) {

/**
* Builds an [OptionsAdapter] instance without providing option text limit.
*
* @param onOptionChange Callback invoked when the option text changes.
*/
public constructor(onOptionChange: (id: Int, text: String) -> Unit) : this(null, onOptionChange)

init {
setHasStableIds(true)
}
Expand All @@ -39,6 +48,7 @@ public class OptionsAdapter(
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): OptionViewHolder =
OptionViewHolder(
parent = parent,
optionTextLimit = optionTextLimit,
onOptionChange = onOptionChange,
)

Expand All @@ -53,11 +63,18 @@ public class OptionsAdapter(
parent,
false,
),
private val optionTextLimit: Int?,
private val onOptionChange: (id: Int, text: String) -> Unit,
) : RecyclerView.ViewHolder(binding.root) {

private lateinit var pollAnswer: PollAnswer

init {
optionTextLimit?.let { limit ->
binding.option.filters = arrayOf(InputFilter.LengthFilter(limit))
}
}

private val textWatcher = object : TextWatcher {
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) { /* no-op */ }
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { /* no-op */ }
Expand Down