poll creation: add logic to enable/disable buttons

Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
This commit is contained in:
Marcel Hibbe 2022-06-21 16:52:17 +02:00 committed by Andy Scherzinger (Rebase PR Action)
parent 8148bfaa65
commit ea0b7d07cc
5 changed files with 82 additions and 45 deletions

View File

@ -31,11 +31,14 @@ class PollCreateOptionViewHolder(
itemsListener.onRemoveOptionsItemClick(pollCreateOptionItem, position)
}
textListener = getTextWatcher(pollCreateOptionItem)
textListener = getTextWatcher(pollCreateOptionItem, itemsListener)
binding.pollOptionText.addTextChangedListener(textListener)
}
private fun getTextWatcher(pollCreateOptionItem: PollCreateOptionItem) =
private fun getTextWatcher(
pollCreateOptionItem: PollCreateOptionItem,
itemsListener: PollCreateOptionsItemListener
) =
object : TextWatcher {
override fun afterTextChanged(s: Editable) {
// unused atm
@ -47,6 +50,8 @@ class PollCreateOptionViewHolder(
override fun onTextChanged(option: CharSequence, start: Int, before: Int, count: Int) {
pollCreateOptionItem.pollOption = option.toString()
itemsListener.onOptionsItemTextChanged(pollCreateOptionItem)
}
}
}

View File

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

View File

@ -5,14 +5,17 @@ import android.app.Dialog
import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.fragment.app.DialogFragment
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager
import autodagger.AutoInjector
import com.nextcloud.talk.R
import com.nextcloud.talk.application.NextcloudTalkApplication
import com.nextcloud.talk.databinding.DialogPollCreateBinding
import com.nextcloud.talk.polls.adapters.PollCreateOptionItem
@ -78,6 +81,7 @@ class PollCreateDialogFragment(
private fun setupListeners() {
binding.pollAddOptionsItem.setOnClickListener {
viewModel.addOption()
adapter?.itemCount?.minus(1)?.let { it -> binding.pollCreateOptionsList.scrollToPosition(it) }
}
binding.pollDismiss.setOnClickListener {
@ -117,41 +121,32 @@ class PollCreateDialogFragment(
private fun setupStateObserver() {
viewModel.viewState.observe(viewLifecycleOwner) { state ->
when (state) {
// PollCreateViewModel.InitialState -> showInitial()
is PollCreateViewModel.PollCreatedState -> dismiss()
is PollCreateViewModel.PollCreationFailedState -> dismiss()
is PollCreateViewModel.PollCreatingState -> updateDialog(state)
is PollCreateViewModel.PollCreationFailedState -> showError()
is PollCreateViewModel.PollCreationState -> updateButtons(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 updateButtons(state: PollCreateViewModel.PollCreationState) {
binding.pollAddOptionsItem.isEnabled = state.enableAddOptionButton
binding.pollCreateButton.isEnabled = state.enableCreatePollButton
}
private fun showInitial() {
binding.pollCreateButton.isEnabled = false
private fun showError() {
dismiss()
Toast.makeText(context, R.string.nc_common_error_sorry, Toast.LENGTH_LONG).show()
Log.e(TAG, "Failed to create poll")
}
override fun onRemoveOptionsItemClick(pollCreateOptionItem: PollCreateOptionItem, position: Int) {
viewModel.removeOption(pollCreateOptionItem)
}
override fun onOptionsItemTextChanged(pollCreateOptionItem: PollCreateOptionItem) {
viewModel.optionsItemTextChanged()
}
/**
* Fragment creator
*/

View File

@ -16,10 +16,14 @@ class PollCreateViewModel @Inject constructor(private val repository: PollReposi
private lateinit var roomToken: String
// private var _options: MutableLiveData<ArrayList<PollCreateOptionItem>> =
// MutableLiveData<ArrayList<PollCreateOptionItem>>()
// val options: LiveData<ArrayList<PollCreateOptionItem>>
// get() = _options
sealed interface ViewState
open class PollCreationState(val enableAddOptionButton: Boolean, val enableCreatePollButton: Boolean) : ViewState
object PollCreatedState : ViewState
object PollCreationFailedState : ViewState
private val _viewState: MutableLiveData<ViewState> = MutableLiveData(PollCreationState(true, false))
val viewState: LiveData<ViewState>
get() = _viewState
private var _options: MutableLiveData<ArrayList<PollCreateOptionItem>> =
MutableLiveData<ArrayList<PollCreateOptionItem>>()
@ -31,27 +35,18 @@ class PollCreateViewModel @Inject constructor(private val repository: PollReposi
get() = _question
private var _privatePoll: MutableLiveData<Boolean> = MutableLiveData<Boolean>()
var privatePoll: LiveData<Boolean> = _privatePoll
val privatePoll: LiveData<Boolean>
get() = _privatePoll
private var _multipleAnswer: MutableLiveData<Boolean> = MutableLiveData<Boolean>()
var multipleAnswer: LiveData<Boolean> = _multipleAnswer
val multipleAnswer: LiveData<Boolean>
get() = _multipleAnswer
sealed interface ViewState
object InitialState : ViewState
open class PollCreatingState() : ViewState
open class PollCreatedState() : ViewState
open class PollCreationFailedState() : ViewState
private val _viewState: MutableLiveData<ViewState> = MutableLiveData(InitialState)
val viewState: LiveData<ViewState>
get() = _viewState
private var disposable: Disposable? = null
fun initialize(roomToken: String) {
this.roomToken = roomToken
updateCreationState()
}
override fun onCleared() {
@ -64,12 +59,14 @@ class PollCreateViewModel @Inject constructor(private val repository: PollReposi
val currentOptions: ArrayList<PollCreateOptionItem> = _options.value ?: ArrayList()
currentOptions.add(item)
_options.value = currentOptions
updateCreationState()
}
fun removeOption(item: PollCreateOptionItem) {
val currentOptions: ArrayList<PollCreateOptionItem> = _options.value ?: ArrayList()
currentOptions.remove(item)
_options.value = currentOptions
updateCreationState()
}
fun createPoll() {
@ -83,9 +80,9 @@ class PollCreateViewModel @Inject constructor(private val repository: PollReposi
resultMode = 1
}
if (question.value?.isNotEmpty() == true && _options.value?.isNotEmpty() == true) {
if (_question.value?.isNotEmpty() == true && _options.value?.isNotEmpty() == true) {
repository.createPoll(
roomToken, question.value!!, _options.value!!.map { it.pollOption }, resultMode,
roomToken, _question.value!!, _options.value!!.map { it.pollOption }, resultMode,
maxVotes
)
?.doOnSubscribe { disposable = it }
@ -97,6 +94,7 @@ class PollCreateViewModel @Inject constructor(private val repository: PollReposi
fun setQuestion(question: String) {
_question.value = question
updateCreationState()
}
fun setPrivatePoll(checked: Boolean) {
@ -107,6 +105,44 @@ class PollCreateViewModel @Inject constructor(private val repository: PollReposi
_multipleAnswer.value = checked
}
fun optionsItemTextChanged() {
updateCreationState()
}
private fun updateCreationState() {
_viewState.value = PollCreationState(enableAddOptionButton(), enableCreatePollButton())
}
private fun enableCreatePollButton(): Boolean {
return _question.value?.isNotEmpty() == true && atLeastTwoOptionsAreFilled()
}
private fun atLeastTwoOptionsAreFilled(): Boolean {
if (_options.value != null) {
var filledOptions = 0
_options.value?.forEach {
if (it.pollOption.isNotEmpty()) {
filledOptions++
}
if (filledOptions >= 2) {
return true
}
}
}
return false
}
private fun enableAddOptionButton(): Boolean {
if (_options.value != null && _options.value?.size != 0) {
_options.value?.forEach {
if (it.pollOption.isBlank()) {
return false
}
}
}
return true
}
inner class PollObserver : Observer<Poll> {
lateinit var poll: Poll
@ -118,11 +154,11 @@ class PollCreateViewModel @Inject constructor(private val repository: PollReposi
}
override fun onError(e: Throwable) {
_viewState.value = PollCreationFailedState()
_viewState.value = PollCreationFailedState
}
override fun onComplete() {
_viewState.value = PollCreatedState()
_viewState.value = PollCreatedState
}
}

View File

@ -31,7 +31,6 @@
<!-- android:text="@string/nc_create_poll"-->
<!-- android:textStyle="bold"-->
<!-- android:layout_marginBottom="@dimen/standard_half_margin"/>-->
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"