Adding vote action from details screen
This commit is contained in:
parent
922b8092ac
commit
f855a36022
@ -54,6 +54,7 @@ import im.vector.app.features.crypto.verification.SupportedVerificationMethodsPr
|
||||
import im.vector.app.features.home.room.detail.RoomDetailAction.VoiceBroadcastAction
|
||||
import im.vector.app.features.home.room.detail.error.RoomNotFound
|
||||
import im.vector.app.features.home.room.detail.location.RedactLiveLocationShareEventUseCase
|
||||
import im.vector.app.features.home.room.detail.poll.VoteToPollUseCase
|
||||
import im.vector.app.features.home.room.detail.sticker.StickerPickerActionHandler
|
||||
import im.vector.app.features.home.room.detail.timeline.factory.TimelineFactory
|
||||
import im.vector.app.features.home.room.detail.timeline.url.PreviewUrlRetriever
|
||||
@ -90,7 +91,6 @@ import org.matrix.android.sdk.api.raw.RawService
|
||||
import org.matrix.android.sdk.api.session.Session
|
||||
import org.matrix.android.sdk.api.session.crypto.MXCryptoError
|
||||
import org.matrix.android.sdk.api.session.events.model.EventType
|
||||
import org.matrix.android.sdk.api.session.events.model.LocalEcho
|
||||
import org.matrix.android.sdk.api.session.events.model.RelationType
|
||||
import org.matrix.android.sdk.api.session.events.model.content.WithHeldCode
|
||||
import org.matrix.android.sdk.api.session.events.model.isAttachmentMessage
|
||||
@ -154,6 +154,7 @@ class TimelineViewModel @AssistedInject constructor(
|
||||
timelineFactory: TimelineFactory,
|
||||
private val spaceStateHandler: SpaceStateHandler,
|
||||
private val voiceBroadcastHelper: VoiceBroadcastHelper,
|
||||
private val voteToPollUseCase: VoteToPollUseCase,
|
||||
) : VectorViewModel<RoomDetailViewState, RoomDetailAction, RoomDetailViewEvents>(initialState),
|
||||
Timeline.Listener, ChatEffectManager.Delegate, CallProtocolsChecker.Listener, LocationSharingServiceConnection.Callback {
|
||||
|
||||
@ -1235,15 +1236,11 @@ class TimelineViewModel @AssistedInject constructor(
|
||||
|
||||
private fun handleVoteToPoll(action: RoomDetailAction.VoteToPoll) {
|
||||
if (room == null) return
|
||||
// Do not allow to vote unsent local echo of the poll event
|
||||
if (LocalEcho.isLocalEchoId(action.eventId)) return
|
||||
// Do not allow to vote the same option twice
|
||||
room.getTimelineEvent(action.eventId)?.let { pollTimelineEvent ->
|
||||
val currentVote = pollTimelineEvent.annotations?.pollResponseSummary?.aggregatedContent?.myVote
|
||||
if (currentVote != action.optionKey) {
|
||||
room.sendService().voteToPoll(action.eventId, action.optionKey)
|
||||
}
|
||||
}
|
||||
voteToPollUseCase.execute(
|
||||
roomId = room.roomId,
|
||||
pollEventId = action.eventId,
|
||||
optionId = action.optionKey,
|
||||
)
|
||||
}
|
||||
|
||||
private fun handleEndPoll(eventId: String) {
|
||||
|
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (c) 2023 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package im.vector.app.features.home.room.detail.poll
|
||||
|
||||
import im.vector.app.core.di.ActiveSessionHolder
|
||||
import org.matrix.android.sdk.api.session.events.model.LocalEcho
|
||||
import org.matrix.android.sdk.api.session.room.getTimelineEvent
|
||||
import javax.inject.Inject
|
||||
|
||||
// TODO add unit tests
|
||||
class VoteToPollUseCase @Inject constructor(
|
||||
private val activeSessionHolder: ActiveSessionHolder,
|
||||
) {
|
||||
|
||||
fun execute(roomId: String, pollEventId: String, optionId: String) {
|
||||
// Do not allow to vote unsent local echo of the poll event
|
||||
if (LocalEcho.isLocalEchoId(pollEventId)) return
|
||||
|
||||
val room = activeSessionHolder.getActiveSession()
|
||||
.roomService()
|
||||
.getRoom(roomId)
|
||||
|
||||
room?.getTimelineEvent(pollEventId)?.let { pollTimelineEvent ->
|
||||
val currentVote = pollTimelineEvent
|
||||
.annotations
|
||||
?.pollResponseSummary
|
||||
?.aggregatedContent
|
||||
?.myVote
|
||||
if (currentVote != optionId) {
|
||||
room.sendService().voteToPoll(
|
||||
pollEventId = pollEventId,
|
||||
answerId = optionId
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (c) 2022 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package im.vector.app.features.roomprofile.polls.detail.ui
|
||||
|
||||
import im.vector.app.core.platform.VectorViewModelAction
|
||||
|
||||
sealed interface RoomPollDetailAction : VectorViewModelAction {
|
||||
data class Vote(val pollEventId: String, val optionId: String) : RoomPollDetailAction
|
||||
}
|
@ -22,7 +22,7 @@ import javax.inject.Inject
|
||||
class RoomPollDetailController @Inject constructor() : TypedEpoxyController<RoomPollDetailViewState>() {
|
||||
|
||||
interface Callback {
|
||||
fun vote(pollId: String, optionId: String)
|
||||
fun vote(pollEventId: String, optionId: String)
|
||||
}
|
||||
|
||||
var callback: Callback? = null
|
||||
|
@ -40,7 +40,9 @@ data class RoomPollDetailArgs(
|
||||
) : Parcelable
|
||||
|
||||
@AndroidEntryPoint
|
||||
class RoomPollDetailFragment : VectorBaseFragment<FragmentRoomPollDetailBinding>() {
|
||||
class RoomPollDetailFragment :
|
||||
VectorBaseFragment<FragmentRoomPollDetailBinding>(),
|
||||
RoomPollDetailController.Callback {
|
||||
|
||||
@Inject lateinit var roomPollDetailController: RoomPollDetailController
|
||||
|
||||
@ -54,17 +56,22 @@ class RoomPollDetailFragment : VectorBaseFragment<FragmentRoomPollDetailBinding>
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
setupToolbar()
|
||||
setupDetailView()
|
||||
// TODO add link to go to timeline message + create a ViewNavigator
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
roomPollDetailController.callback = null
|
||||
views.pollDetailRecyclerView.cleanup()
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
private fun setupDetailView() {
|
||||
roomPollDetailController.callback = this
|
||||
views.pollDetailRecyclerView.configureWith(
|
||||
roomPollDetailController,
|
||||
hasFixedSize = true,
|
||||
)
|
||||
// TODO setup callback in controller for vote action
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
views.pollDetailRecyclerView.cleanup()
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
private fun setupToolbar(isEnded: Boolean? = null) {
|
||||
@ -85,4 +92,8 @@ class RoomPollDetailFragment : VectorBaseFragment<FragmentRoomPollDetailBinding>
|
||||
setupToolbar(state.pollDetail.isEnded)
|
||||
roomPollDetailController.setData(state)
|
||||
}
|
||||
|
||||
override fun vote(pollEventId: String, optionId: String) {
|
||||
viewModel.handle(RoomPollDetailAction.Vote(pollEventId = pollEventId, optionId = optionId))
|
||||
}
|
||||
}
|
||||
|
@ -72,7 +72,7 @@ abstract class RoomPollDetailItem : VectorEpoxyModel<RoomPollDetailItem.Holder>(
|
||||
val relatedEventId = eventId
|
||||
|
||||
if (canVote && relatedEventId != null) {
|
||||
callback?.vote(pollId = relatedEventId, optionId = optionViewState.optionId)
|
||||
callback?.vote(pollEventId = relatedEventId, optionId = optionViewState.optionId)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -23,19 +23,19 @@ import dagger.assisted.AssistedInject
|
||||
import im.vector.app.core.di.MavericksAssistedViewModelFactory
|
||||
import im.vector.app.core.di.hiltMavericksViewModelFactory
|
||||
import im.vector.app.core.event.GetTimelineEventUseCase
|
||||
import im.vector.app.core.platform.EmptyAction
|
||||
import im.vector.app.core.platform.VectorViewModel
|
||||
import im.vector.app.features.auth.ReAuthState
|
||||
import im.vector.app.features.auth.ReAuthViewModel
|
||||
import im.vector.app.features.home.room.detail.poll.VoteToPollUseCase
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
|
||||
// TODO add unit tests
|
||||
class RoomPollDetailViewModel @AssistedInject constructor(
|
||||
@Assisted initialState: RoomPollDetailViewState,
|
||||
private val getTimelineEventUseCase: GetTimelineEventUseCase,
|
||||
private val roomPollDetailMapper: RoomPollDetailMapper,
|
||||
) : VectorViewModel<RoomPollDetailViewState, EmptyAction, RoomPollDetailViewEvent>(initialState) {
|
||||
private val voteToPollUseCase: VoteToPollUseCase,
|
||||
) : VectorViewModel<RoomPollDetailViewState, RoomPollDetailAction, RoomPollDetailViewEvent>(initialState) {
|
||||
|
||||
@AssistedFactory
|
||||
interface Factory : MavericksAssistedViewModelFactory<RoomPollDetailViewModel, RoomPollDetailViewState> {
|
||||
@ -58,7 +58,17 @@ class RoomPollDetailViewModel @AssistedInject constructor(
|
||||
.launchIn(viewModelScope)
|
||||
}
|
||||
|
||||
override fun handle(action: EmptyAction) {
|
||||
// do nothing for now
|
||||
override fun handle(action: RoomPollDetailAction) {
|
||||
when (action) {
|
||||
is RoomPollDetailAction.Vote -> handleVote(action)
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleVote(vote: RoomPollDetailAction.Vote) = withState { state ->
|
||||
voteToPollUseCase.execute(
|
||||
roomId = state.roomId,
|
||||
pollEventId = vote.pollEventId,
|
||||
optionId = vote.optionId,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user