wip: create poll using multiple livedata fields

Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
This commit is contained in:
Marcel Hibbe 2022-06-20 21:42:49 +02:00 committed by Andy Scherzinger (Rebase PR Action)
parent b140cc8751
commit 9f90e9c4c6
5 changed files with 87 additions and 71 deletions

View File

@ -17,7 +17,7 @@ class PollCreateOptionViewHolder(
@SuppressLint("SetTextI18n") @SuppressLint("SetTextI18n")
fun bind( fun bind(
pollCreateOptionItem: PollCreateOptionItem, pollCreateOptionItem: PollCreateOptionItem,
clickListener: PollCreateOptionsItemClickListener, itemsListener: PollCreateOptionsItemListener,
position: Int position: Int
) { ) {
@ -28,7 +28,7 @@ class PollCreateOptionViewHolder(
binding.pollOptionText.setText(pollCreateOptionItem.pollOption) binding.pollOptionText.setText(pollCreateOptionItem.pollOption)
binding.pollOptionDelete.setOnClickListener { binding.pollOptionDelete.setOnClickListener {
clickListener.onRemoveOptionsItemClick(pollCreateOptionItem, position) itemsListener.onRemoveOptionsItemClick(pollCreateOptionItem, position)
} }
textListener = getTextWatcher(pollCreateOptionItem) textListener = getTextWatcher(pollCreateOptionItem)

View File

@ -6,7 +6,7 @@ import androidx.recyclerview.widget.RecyclerView
import com.nextcloud.talk.databinding.PollCreateOptionsItemBinding import com.nextcloud.talk.databinding.PollCreateOptionsItemBinding
class PollCreateOptionsAdapter( class PollCreateOptionsAdapter(
private val clickListener: PollCreateOptionsItemClickListener private val clickListener: PollCreateOptionsItemListener
) : RecyclerView.Adapter<PollCreateOptionViewHolder>() { ) : RecyclerView.Adapter<PollCreateOptionViewHolder>() {
internal var list: ArrayList<PollCreateOptionItem> = ArrayList<PollCreateOptionItem>() internal var list: ArrayList<PollCreateOptionItem> = ArrayList<PollCreateOptionItem>()

View File

@ -1,5 +1,6 @@
package com.nextcloud.talk.polls.adapters package com.nextcloud.talk.polls.adapters
interface PollCreateOptionsItemClickListener { interface PollCreateOptionsItemListener {
fun onRemoveOptionsItemClick(pollCreateOptionItem: PollCreateOptionItem, position: Int) fun onRemoveOptionsItemClick(pollCreateOptionItem: PollCreateOptionItem, position: Int)
} }

View File

@ -10,7 +10,6 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.fragment.app.DialogFragment import androidx.fragment.app.DialogFragment
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import autodagger.AutoInjector import autodagger.AutoInjector
@ -18,14 +17,14 @@ import com.nextcloud.talk.application.NextcloudTalkApplication
import com.nextcloud.talk.databinding.DialogPollCreateBinding import com.nextcloud.talk.databinding.DialogPollCreateBinding
import com.nextcloud.talk.polls.adapters.PollCreateOptionItem import com.nextcloud.talk.polls.adapters.PollCreateOptionItem
import com.nextcloud.talk.polls.adapters.PollCreateOptionsAdapter import com.nextcloud.talk.polls.adapters.PollCreateOptionsAdapter
import com.nextcloud.talk.polls.adapters.PollCreateOptionsItemClickListener import com.nextcloud.talk.polls.adapters.PollCreateOptionsItemListener
import com.nextcloud.talk.polls.viewmodels.PollCreateViewModel import com.nextcloud.talk.polls.viewmodels.PollCreateViewModel
import javax.inject.Inject import javax.inject.Inject
@AutoInjector(NextcloudTalkApplication::class) @AutoInjector(NextcloudTalkApplication::class)
class PollCreateDialogFragment( class PollCreateDialogFragment(
private val roomToken: String private val roomToken: String
) : DialogFragment(), PollCreateOptionsItemClickListener { ) : DialogFragment(), PollCreateOptionsItemListener {
@Inject @Inject
lateinit var viewModelFactory: ViewModelProvider.Factory lateinit var viewModelFactory: ViewModelProvider.Factory
@ -40,7 +39,6 @@ class PollCreateDialogFragment(
NextcloudTalkApplication.sharedApplication!!.componentApplication.inject(this) NextcloudTalkApplication.sharedApplication!!.componentApplication.inject(this)
viewModel = ViewModelProvider(this, viewModelFactory)[PollCreateViewModel::class.java] viewModel = ViewModelProvider(this, viewModelFactory)[PollCreateViewModel::class.java]
viewModel.options.observe(this, optionsObserver)
} }
@SuppressLint("InflateParams") @SuppressLint("InflateParams")
@ -61,6 +59,11 @@ class PollCreateDialogFragment(
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
viewModel.options.observe(viewLifecycleOwner) { options -> adapter?.updateOptionsList(options) }
viewModel.question.observe(viewLifecycleOwner) { binding.pollCreateQuestion.setText(it) }
viewModel.privatePoll.observe(viewLifecycleOwner) { binding.pollPrivatePollCheckbox.isChecked = it }
viewModel.multipleAnswer.observe(viewLifecycleOwner) { binding.pollMultipleAnswersCheckbox.isChecked = it }
binding.pollCreateOptionsList.layoutManager = LinearLayoutManager(context) binding.pollCreateOptionsList.layoutManager = LinearLayoutManager(context)
adapter = PollCreateOptionsAdapter(this) adapter = PollCreateOptionsAdapter(this)
@ -68,21 +71,19 @@ class PollCreateDialogFragment(
viewModel.initialize(roomToken) viewModel.initialize(roomToken)
setupListeners()
setupStateObserver()
}
private fun setupListeners() {
binding.pollAddOptionsItem.setOnClickListener { binding.pollAddOptionsItem.setOnClickListener {
viewModel.addOption() viewModel.addOption()
// viewModel.options?.value?.let { it1 -> adapter?.notifyItemInserted(it1.size) }
// viewModel.options?.value?.let { it1 -> adapter?.notifyItemChanged(it1.size) }
// viewModel.options?.value?.let { it1 -> adapter?.notifyItemRangeInserted(it1.size, 1) }
} }
binding.pollDismiss.setOnClickListener { binding.pollDismiss.setOnClickListener {
dismiss() dismiss()
} }
binding.pollCreateQuestion.addTextChangedListener(object : TextWatcher { binding.pollCreateQuestion.addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(s: Editable) { override fun afterTextChanged(s: Editable) {
// unused atm // unused atm
@ -93,53 +94,64 @@ class PollCreateDialogFragment(
} }
override fun onTextChanged(question: CharSequence, start: Int, before: Int, count: Int) { override fun onTextChanged(question: CharSequence, start: Int, before: Int, count: Int) {
// TODO make question a livedata if (question.toString() != viewModel.question.value) {
// if(question != viewmodel.question.value) viewModel.setQuestion(question) viewModel.setQuestion(question.toString())
viewModel.question = question.toString() binding.pollCreateQuestion.setSelection(binding.pollCreateQuestion.length())
}
} }
}) })
// viewModel.question.observe { it -> binding.pollCreateQuestion.text = it }
binding.pollPrivatePollCheckbox.setOnClickListener { binding.pollPrivatePollCheckbox.setOnClickListener {
// FIXME viewModel.setPrivatePoll(binding.pollPrivatePollCheckbox.isChecked)
viewModel.multipleAnswer = binding.pollMultipleAnswersCheckbox.isChecked
} }
binding.pollMultipleAnswersCheckbox.setOnClickListener { binding.pollMultipleAnswersCheckbox.setOnClickListener {
viewModel.multipleAnswer = binding.pollMultipleAnswersCheckbox.isChecked viewModel.setMultipleAnswer(binding.pollMultipleAnswersCheckbox.isChecked)
} }
binding.pollCreateButton.setOnClickListener { binding.pollCreateButton.setOnClickListener {
viewModel.createPoll() viewModel.createPoll()
} }
}
private fun setupStateObserver() {
viewModel.viewState.observe(viewLifecycleOwner) { state -> viewModel.viewState.observe(viewLifecycleOwner) { state ->
when (state) { when (state) {
PollCreateViewModel.InitialState -> {} // PollCreateViewModel.InitialState -> showInitial()
is PollCreateViewModel.PollCreatedState -> dismiss()
is PollCreateViewModel.PollCreatedState -> { is PollCreateViewModel.PollCreationFailedState -> dismiss()
dismiss() is PollCreateViewModel.PollCreatingState -> updateDialog(state)
}
} }
} }
// viewModel.state.observe(this) { state ->
// when (state) {
// MessageSearchViewModel.InitialState -> showInitial()
// MessageSearchViewModel.EmptyState -> showEmpty()
// is MessageSearchViewModel.LoadedState -> showLoaded(state)
// MessageSearchViewModel.LoadingState -> showLoading()
// MessageSearchViewModel.ErrorState -> showError()
// is MessageSearchViewModel.FinishedState -> onFinish()
// }
// }
}
private fun updateDialog(state: PollCreateViewModel.PollCreatingState) {
// binding.pollCreateQuestion.setText(state.question)
//
// adapter!!.updateOptionsList(state.options)
//
// binding.pollPrivatePollCheckbox.isChecked = state.privatePoll
// binding.pollMultipleAnswersCheckbox.isChecked = state.multipleAnswer
}
private fun showInitial() {
binding.pollCreateButton.isEnabled = false
} }
override fun onRemoveOptionsItemClick(pollCreateOptionItem: PollCreateOptionItem, position: Int) { override fun onRemoveOptionsItemClick(pollCreateOptionItem: PollCreateOptionItem, position: Int) {
viewModel.removeOption(pollCreateOptionItem) viewModel.removeOption(pollCreateOptionItem)
// adapter?.notifyItemRemoved(position)
// adapter?.notifyItemChanged(position)
// adapter?.notifyItemRangeRemoved(position, 1)
} }
var optionsObserver: Observer<ArrayList<PollCreateOptionItem>> =
object : Observer<ArrayList<PollCreateOptionItem>> {
override fun onChanged(options: ArrayList<PollCreateOptionItem>) {
adapter?.updateOptionsList(options)
}
}
/** /**
* Fragment creator * Fragment creator
*/ */

View File

@ -16,24 +16,27 @@ class PollCreateViewModel @Inject constructor(private val repository: PollReposi
private lateinit var roomToken: String private lateinit var roomToken: String
// TODO remove testing items // private var _options: MutableLiveData<ArrayList<PollCreateOptionItem>> =
var defaultOptions: MutableList<PollCreateOptionItem> = mutableListOf<PollCreateOptionItem>().apply { // MutableLiveData<ArrayList<PollCreateOptionItem>>()
for (i in 1..3) { // val options: LiveData<ArrayList<PollCreateOptionItem>>
val item = PollCreateOptionItem("item " + i) // get() = _options
this.add(item)
}
}
private var _options: MutableLiveData<ArrayList<PollCreateOptionItem>> = private var _options: MutableLiveData<ArrayList<PollCreateOptionItem>> =
MutableLiveData<ArrayList<PollCreateOptionItem>>(defaultOptions) MutableLiveData<ArrayList<PollCreateOptionItem>>()
val options: LiveData<ArrayList<PollCreateOptionItem>> val options: LiveData<ArrayList<PollCreateOptionItem>>
get() = _options get() = _options
var question: String = "" private var _question: MutableLiveData<String> = MutableLiveData<String>()
val question: LiveData<String>
get() = _question
// lateinit var options: List<String> private var _privatePoll: MutableLiveData<Boolean> = MutableLiveData<Boolean>()
var privatePoll: Boolean = false var privatePoll: LiveData<Boolean> = _privatePoll
var multipleAnswer: Boolean = false get() = _privatePoll
private var _multipleAnswer: MutableLiveData<Boolean> = MutableLiveData<Boolean>()
var multipleAnswer: LiveData<Boolean> = _multipleAnswer
get() = _multipleAnswer
sealed interface ViewState sealed interface ViewState
object InitialState : ViewState object InitialState : ViewState
@ -56,10 +59,6 @@ class PollCreateViewModel @Inject constructor(private val repository: PollReposi
disposable?.dispose() disposable?.dispose()
} }
private fun <T> MutableLiveData<T>.notifyObserver() {
this.value = this.value
}
fun addOption() { fun addOption() {
val item = PollCreateOptionItem("") val item = PollCreateOptionItem("")
val currentOptions: ArrayList<PollCreateOptionItem> = _options.value ?: ArrayList() val currentOptions: ArrayList<PollCreateOptionItem> = _options.value ?: ArrayList()
@ -75,33 +74,37 @@ class PollCreateViewModel @Inject constructor(private val repository: PollReposi
fun createPoll() { fun createPoll() {
var maxVotes = 1 var maxVotes = 1
if (multipleAnswer) { if (multipleAnswer.value == true) {
maxVotes = 0 maxVotes = 0
} }
var resultMode = 0 var resultMode = 0
if (privatePoll) { if (privatePoll.value == true) {
resultMode = 1 resultMode = 1
} }
val items = _options.value!! if (question.value?.isNotEmpty() == true && _options.value?.isNotEmpty() == true) {
repository.createPoll(roomToken, question, items.map { it.pollOption }, resultMode, maxVotes) repository.createPoll(
?.doOnSubscribe { disposable = it } roomToken, question.value!!, _options.value!!.map { it.pollOption }, resultMode,
?.subscribeOn(Schedulers.io()) maxVotes
?.observeOn(AndroidSchedulers.mainThread()) )
?.subscribe(PollObserver()) ?.doOnSubscribe { disposable = it }
?.subscribeOn(Schedulers.io())
?.observeOn(AndroidSchedulers.mainThread())
?.subscribe(PollObserver())
}
} }
private fun map( fun setQuestion(question: String) {
list: ArrayList<PollCreateOptionItem>, _question.value = question
): List<String> { }
val resultList: ArrayList<String>? = ArrayList()
list.forEach { fun setPrivatePoll(checked: Boolean) {
resultList?.add(it.pollOption) _privatePoll.value = checked
} }
return resultList?.toList()!! fun setMultipleAnswer(checked: Boolean) {
_multipleAnswer.value = checked
} }
inner class PollObserver : Observer<Poll> { inner class PollObserver : Observer<Poll> {