mirror of
https://github.com/nextcloud/talk-android.git
synced 2024-11-28 09:38:14 +03:00
wip: vote on poll
Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
This commit is contained in:
parent
81666829b5
commit
7d8aebe234
9 changed files with 134 additions and 32 deletions
|
@ -538,7 +538,8 @@ public interface NcApi {
|
||||||
|
|
||||||
@POST
|
@POST
|
||||||
Observable<PollOverall> votePoll(@Header("Authorization") String authorization,
|
Observable<PollOverall> votePoll(@Header("Authorization") String authorization,
|
||||||
@Url String url);
|
@Url String url,
|
||||||
|
@Query("optionIds[]") List<Integer> optionIds);
|
||||||
|
|
||||||
@DELETE
|
@DELETE
|
||||||
Observable<PollOverall> closePoll(@Header("Authorization") String authorization,
|
Observable<PollOverall> closePoll(@Header("Authorization") String authorization,
|
||||||
|
|
|
@ -14,4 +14,11 @@ data class Poll(
|
||||||
val votedSelf: List<Int>?,
|
val votedSelf: List<Int>?,
|
||||||
val numVoters: Int,
|
val numVoters: Int,
|
||||||
val details: List<PollDetails>?
|
val details: List<PollDetails>?
|
||||||
)
|
) {
|
||||||
|
companion object {
|
||||||
|
const val STATUS_OPEN: Int = 0
|
||||||
|
const val STATUS_CLOSED: Int = 1
|
||||||
|
const val RESULT_MODE_PUBLIC: Int = 0
|
||||||
|
const val RESULT_MODE_HIDDEN: Int = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -6,4 +6,6 @@ import io.reactivex.Observable
|
||||||
interface PollRepository {
|
interface PollRepository {
|
||||||
|
|
||||||
fun getPoll(roomToken: String, pollId: String): Observable<Poll>?
|
fun getPoll(roomToken: String, pollId: String): Observable<Poll>?
|
||||||
|
|
||||||
|
fun vote(roomToken: String, pollId: String, option: Int): Observable<Poll>?
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,12 +33,12 @@ import io.reactivex.Observable
|
||||||
class PollRepositoryImpl(private val ncApi: NcApi, private val currentUserProvider: CurrentUserProvider) :
|
class PollRepositoryImpl(private val ncApi: NcApi, private val currentUserProvider: CurrentUserProvider) :
|
||||||
PollRepository {
|
PollRepository {
|
||||||
|
|
||||||
override fun getPoll(roomToken: String, pollId: String): Observable<Poll> {
|
val credentials = ApiUtils.getCredentials(
|
||||||
|
currentUserProvider.currentUser?.username,
|
||||||
|
currentUserProvider.currentUser?.token
|
||||||
|
)
|
||||||
|
|
||||||
val credentials = ApiUtils.getCredentials(
|
override fun getPoll(roomToken: String, pollId: String): Observable<Poll> {
|
||||||
currentUserProvider.currentUser?.username,
|
|
||||||
currentUserProvider.currentUser?.token
|
|
||||||
)
|
|
||||||
|
|
||||||
return ncApi.getPoll(
|
return ncApi.getPoll(
|
||||||
credentials,
|
credentials,
|
||||||
|
@ -69,6 +69,19 @@ class PollRepositoryImpl(private val ncApi: NcApi, private val currentUserProvid
|
||||||
// )
|
// )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun vote(roomToken: String, pollId: String, option: Int): Observable<Poll>? {
|
||||||
|
|
||||||
|
return ncApi.votePoll(
|
||||||
|
credentials,
|
||||||
|
ApiUtils.getUrlForPoll(
|
||||||
|
currentUserProvider.currentUser?.baseUrl,
|
||||||
|
roomToken,
|
||||||
|
pollId
|
||||||
|
),
|
||||||
|
arrayOf(option).asList()
|
||||||
|
).map { mapToPoll(it.ocs?.data!!) }
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
private fun mapToPoll(pollResponse: PollResponse): Poll {
|
private fun mapToPoll(pollResponse: PollResponse): Poll {
|
||||||
|
|
|
@ -60,7 +60,11 @@ class PollMainDialogFragment(
|
||||||
PollViewModel.InitialState -> {}
|
PollViewModel.InitialState -> {}
|
||||||
is PollViewModel.PollClosedState -> TODO()
|
is PollViewModel.PollClosedState -> TODO()
|
||||||
is PollViewModel.PollOpenState -> {
|
is PollViewModel.PollOpenState -> {
|
||||||
val contentFragment = PollVoteFragment(viewModel)
|
val contentFragment = PollVoteFragment(
|
||||||
|
viewModel,
|
||||||
|
roomToken,
|
||||||
|
pollId
|
||||||
|
)
|
||||||
val transaction = childFragmentManager.beginTransaction()
|
val transaction = childFragmentManager.beginTransaction()
|
||||||
transaction.replace(binding.messagePollContentFragment.id, contentFragment)
|
transaction.replace(binding.messagePollContentFragment.id, contentFragment)
|
||||||
transaction.commit()
|
transaction.commit()
|
||||||
|
|
|
@ -37,7 +37,11 @@ import com.nextcloud.talk.polls.viewmodels.PollVoteViewModel
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@AutoInjector(NextcloudTalkApplication::class)
|
@AutoInjector(NextcloudTalkApplication::class)
|
||||||
class PollVoteFragment(private val parentViewModel: PollViewModel) : Fragment() {
|
class PollVoteFragment(
|
||||||
|
private val parentViewModel: PollViewModel,
|
||||||
|
private val roomToken: String,
|
||||||
|
private val pollId: String
|
||||||
|
) : Fragment() {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var viewModelFactory: ViewModelProvider.Factory
|
lateinit var viewModelFactory: ViewModelProvider.Factory
|
||||||
|
@ -70,29 +74,43 @@ class PollVoteFragment(private val parentViewModel: PollViewModel) : Fragment()
|
||||||
val poll = state.poll
|
val poll = state.poll
|
||||||
binding.radioGroup.removeAllViews()
|
binding.radioGroup.removeAllViews()
|
||||||
poll.options?.map { option ->
|
poll.options?.map { option ->
|
||||||
RadioButton(context)
|
RadioButton(context).apply { text = option }
|
||||||
.apply { text = option }
|
}?.forEachIndexed { index, radioButton ->
|
||||||
.also {
|
radioButton.id = index
|
||||||
it.setOnClickListener {
|
binding.radioGroup.addView(radioButton)
|
||||||
// todo
|
|
||||||
Log.d("bb", "click1")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}?.forEach {
|
|
||||||
binding.radioGroup.addView(it)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
viewModel.viewState.observe(viewLifecycleOwner) { state ->
|
||||||
|
when (state) {
|
||||||
|
PollVoteViewModel.InitialState -> {}
|
||||||
|
is PollVoteViewModel.PollVoteFailedState -> {
|
||||||
|
Log.d(TAG, "fail")
|
||||||
|
}
|
||||||
|
is PollVoteViewModel.PollVoteSuccessState -> {
|
||||||
|
parentViewModel.voted()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
binding.radioGroup.setOnCheckedChangeListener { group, checkedId ->
|
binding.radioGroup.setOnCheckedChangeListener { group, checkedId ->
|
||||||
// todo set selected in viewmodel
|
// todo set selected in viewmodel.
|
||||||
Log.d("bb", "click")
|
Log.d("bb", "click")
|
||||||
}
|
}
|
||||||
// todo observe viewmodel checked, set view checked with it
|
// todo observe viewmodel checked, set view checked with it
|
||||||
// todo listen to button click, submit
|
|
||||||
|
binding.submitVote.setOnClickListener {
|
||||||
|
viewModel.vote(roomToken, pollId, binding.radioGroup.checkedRadioButtonId)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroyView() {
|
override fun onDestroyView() {
|
||||||
super.onDestroyView()
|
super.onDestroyView()
|
||||||
_binding = null
|
_binding = null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val TAG = PollVoteFragment::class.java.simpleName
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,7 @@ class PollViewModel @Inject constructor(private val repository: PollRepository)
|
||||||
sealed interface ViewState
|
sealed interface ViewState
|
||||||
object InitialState : ViewState
|
object InitialState : ViewState
|
||||||
open class PollOpenState(val poll: Poll) : ViewState
|
open class PollOpenState(val poll: Poll) : ViewState
|
||||||
|
open class PollVotedState(val poll: Poll) : ViewState
|
||||||
open class PollClosedState(val poll: Poll) : ViewState
|
open class PollClosedState(val poll: Poll) : ViewState
|
||||||
|
|
||||||
private val _viewState: MutableLiveData<ViewState> = MutableLiveData(InitialState)
|
private val _viewState: MutableLiveData<ViewState> = MutableLiveData(InitialState)
|
||||||
|
@ -46,14 +47,9 @@ class PollViewModel @Inject constructor(private val repository: PollRepository)
|
||||||
loadPoll()
|
loadPoll()
|
||||||
}
|
}
|
||||||
|
|
||||||
// private fun loadPoll() {
|
fun voted() {
|
||||||
// disposable = repository.getPoll(roomToken, pollId)
|
loadPoll() // TODO load other view
|
||||||
// ?.subscribeOn(Schedulers.io())
|
}
|
||||||
// ?.observeOn(AndroidSchedulers.mainThread())
|
|
||||||
// ?.subscribe { poll ->
|
|
||||||
// _viewState.value = PollOpenState(poll)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
private fun loadPoll() {
|
private fun loadPoll() {
|
||||||
repository.getPoll(roomToken, pollId)
|
repository.getPoll(roomToken, pollId)
|
||||||
|
@ -83,7 +79,12 @@ class PollViewModel @Inject constructor(private val repository: PollRepository)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onComplete() {
|
override fun onComplete() {
|
||||||
_viewState.value = PollOpenState(poll)
|
// TODO check attributes and decide if poll is open/closed/selfvoted...
|
||||||
|
|
||||||
|
when (poll.status) {
|
||||||
|
Poll.STATUS_OPEN -> _viewState.value = PollOpenState(poll)
|
||||||
|
Poll.STATUS_CLOSED -> _viewState.value = PollClosedState(poll)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,12 +21,31 @@
|
||||||
|
|
||||||
package com.nextcloud.talk.polls.viewmodels
|
package com.nextcloud.talk.polls.viewmodels
|
||||||
|
|
||||||
|
import android.util.Log
|
||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
|
import com.nextcloud.talk.polls.model.Poll
|
||||||
|
import com.nextcloud.talk.polls.repositories.PollRepository
|
||||||
|
import io.reactivex.Observer
|
||||||
|
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||||
|
import io.reactivex.disposables.Disposable
|
||||||
|
import io.reactivex.schedulers.Schedulers
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class PollVoteViewModel @Inject constructor() : ViewModel() {
|
class PollVoteViewModel @Inject constructor(private val repository: PollRepository) : ViewModel() {
|
||||||
|
|
||||||
|
sealed interface ViewState
|
||||||
|
object InitialState : ViewState
|
||||||
|
open class PollVoteSuccessState(val poll: Poll) : ViewState
|
||||||
|
open class PollVoteFailedState() : ViewState
|
||||||
|
|
||||||
|
private val _viewState: MutableLiveData<ViewState> = MutableLiveData(InitialState)
|
||||||
|
val viewState: LiveData<ViewState>
|
||||||
|
get() = _viewState
|
||||||
|
|
||||||
|
private var disposable: Disposable? = null
|
||||||
|
|
||||||
private val _selectedOptions: MutableLiveData<List<String>> = MutableLiveData(emptyList())
|
private val _selectedOptions: MutableLiveData<List<String>> = MutableLiveData(emptyList())
|
||||||
val selectedOptions: LiveData<List<String>>
|
val selectedOptions: LiveData<List<String>>
|
||||||
get() = _selectedOptions
|
get() = _selectedOptions
|
||||||
|
@ -34,4 +53,41 @@ class PollVoteViewModel @Inject constructor() : ViewModel() {
|
||||||
fun selectOption(option: String) {
|
fun selectOption(option: String) {
|
||||||
_selectedOptions.value = listOf(option)
|
_selectedOptions.value = listOf(option)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun vote(roomToken: String, pollId: String, option: Int) {
|
||||||
|
repository.vote(roomToken, pollId, option)
|
||||||
|
?.doOnSubscribe { disposable = it }
|
||||||
|
?.subscribeOn(Schedulers.io())
|
||||||
|
?.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
?.subscribe(PollObserver())
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCleared() {
|
||||||
|
super.onCleared()
|
||||||
|
disposable?.dispose()
|
||||||
|
}
|
||||||
|
|
||||||
|
inner class PollObserver : Observer<Poll> {
|
||||||
|
|
||||||
|
lateinit var poll: Poll
|
||||||
|
|
||||||
|
override fun onSubscribe(d: Disposable) = Unit
|
||||||
|
|
||||||
|
override fun onNext(response: Poll) {
|
||||||
|
poll = response
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onError(e: Throwable) {
|
||||||
|
Log.d(TAG, "An error occurred: $e")
|
||||||
|
_viewState.value = PollVoteFailedState()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onComplete() {
|
||||||
|
_viewState.value = PollVoteSuccessState(poll)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val TAG = PollVoteViewModel::class.java.simpleName
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
</RadioGroup>
|
</RadioGroup>
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
<com.google.android.material.button.MaterialButton
|
||||||
android:id="@+id/setStatus"
|
android:id="@+id/submitVote"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
app:cornerRadius="@dimen/button_corner_radius"
|
app:cornerRadius="@dimen/button_corner_radius"
|
||||||
|
|
Loading…
Reference in a new issue