mirror of
https://github.com/vector-im/element-android.git
synced 2024-11-16 02:05:06 +08:00
Invalidate previous votes for edited polls.
This commit is contained in:
parent
5d07c71dcf
commit
9dd48045f6
@ -39,6 +39,8 @@ import org.matrix.android.sdk.api.session.room.model.message.MessagePollResponse
|
||||
import org.matrix.android.sdk.api.session.room.model.message.MessageRelationContent
|
||||
import org.matrix.android.sdk.api.session.room.model.relation.ReactionContent
|
||||
import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper
|
||||
import org.matrix.android.sdk.api.session.room.timeline.getLastMessageContent
|
||||
import org.matrix.android.sdk.internal.SessionManager
|
||||
import org.matrix.android.sdk.internal.crypto.model.event.EncryptedEventContent
|
||||
import org.matrix.android.sdk.internal.crypto.verification.toState
|
||||
import org.matrix.android.sdk.internal.database.mapper.ContentMapper
|
||||
@ -56,6 +58,7 @@ import org.matrix.android.sdk.internal.database.model.TimelineEventEntity
|
||||
import org.matrix.android.sdk.internal.database.query.create
|
||||
import org.matrix.android.sdk.internal.database.query.getOrCreate
|
||||
import org.matrix.android.sdk.internal.database.query.where
|
||||
import org.matrix.android.sdk.internal.di.SessionId
|
||||
import org.matrix.android.sdk.internal.di.UserId
|
||||
import org.matrix.android.sdk.internal.session.EventInsertLiveProcessor
|
||||
import org.matrix.android.sdk.internal.session.room.state.StateEventDataSource
|
||||
@ -64,7 +67,9 @@ import javax.inject.Inject
|
||||
|
||||
internal class EventRelationsAggregationProcessor @Inject constructor(
|
||||
@UserId private val userId: String,
|
||||
private val stateEventDataSource: StateEventDataSource
|
||||
private val stateEventDataSource: StateEventDataSource,
|
||||
@SessionId private val sessionId: String,
|
||||
private val sessionManager: SessionManager
|
||||
) : EventInsertLiveProcessor {
|
||||
|
||||
private val allowedTypes = listOf(
|
||||
@ -284,6 +289,20 @@ internal class EventRelationsAggregationProcessor @Inject constructor(
|
||||
Timber.v("###REPLACE ignoring event for summary, it's known $eventId")
|
||||
return
|
||||
}
|
||||
|
||||
ContentMapper
|
||||
.map(eventAnnotationsSummaryEntity.pollResponseSummary?.aggregatedContent)
|
||||
?.toModel<PollSummaryContent>()
|
||||
?.apply {
|
||||
totalVotes = 0
|
||||
winnerVoteCount = 0
|
||||
votes = emptyList()
|
||||
votesSummary = emptyMap()
|
||||
}
|
||||
?.apply {
|
||||
eventAnnotationsSummaryEntity.pollResponseSummary?.aggregatedContent = ContentMapper.map(toContent())
|
||||
}
|
||||
|
||||
val txId = event.unsignedData?.transactionId
|
||||
// is it a remote echo?
|
||||
if (!isLocalEcho && existingSummary.editions.any { it.eventId == txId }) {
|
||||
@ -325,6 +344,16 @@ internal class EventRelationsAggregationProcessor @Inject constructor(
|
||||
val targetEventId = relatedEventId ?: content.relatesTo?.eventId ?: return
|
||||
val eventTimestamp = event.originServerTs ?: return
|
||||
|
||||
val session = sessionManager.getSessionComponent(sessionId)?.session()
|
||||
|
||||
val targetPollEvent = session?.getRoom(roomId)?.getTimeLineEvent(targetEventId) ?: return Unit.also {
|
||||
Timber.v("## POLL target poll event $targetEventId not found in room $roomId")
|
||||
}
|
||||
|
||||
val targetPollContent = targetPollEvent.getLastMessageContent() as? MessagePollContent ?: return Unit.also {
|
||||
Timber.v("## POLL target poll event $targetEventId content is malformed")
|
||||
}
|
||||
|
||||
// ok, this is a poll response
|
||||
var existing = EventAnnotationsSummaryEntity.where(realm, roomId, targetEventId).findFirst()
|
||||
if (existing == null) {
|
||||
@ -365,6 +394,12 @@ internal class EventRelationsAggregationProcessor @Inject constructor(
|
||||
Timber.d("## POLL Ignoring malformed response no option eventId:$eventId content: ${event.content}")
|
||||
}
|
||||
|
||||
// Check if this option is in available options
|
||||
if (!targetPollContent.pollCreationInfo?.answers?.map { it.id }?.contains(option).orFalse()) {
|
||||
Timber.v("## POLL $targetEventId doesn't contain option $option")
|
||||
return
|
||||
}
|
||||
|
||||
val votes = sumModel.votes?.toMutableList() ?: ArrayList()
|
||||
val existingVoteIndex = votes.indexOfFirst { it.userId == senderId }
|
||||
if (existingVoteIndex != -1) {
|
||||
|
@ -61,6 +61,7 @@ import org.matrix.android.sdk.internal.di.UserId
|
||||
import org.matrix.android.sdk.internal.session.content.ThumbnailExtractor
|
||||
import org.matrix.android.sdk.internal.session.permalinks.PermalinkFactory
|
||||
import org.matrix.android.sdk.internal.session.room.send.pills.TextPillsUtils
|
||||
import java.util.UUID
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
@ -131,9 +132,9 @@ internal class LocalEchoEventFactory @Inject constructor(
|
||||
question = PollQuestion(
|
||||
question = question
|
||||
),
|
||||
answers = options.mapIndexed { index, option ->
|
||||
answers = options.map { option ->
|
||||
PollAnswer(
|
||||
id = "$index-$option",
|
||||
id = UUID.randomUUID().toString(),
|
||||
answer = option
|
||||
)
|
||||
}
|
||||
|
@ -220,13 +220,22 @@ class MessageItemFactory @Inject constructor(
|
||||
)
|
||||
}
|
||||
|
||||
val question = pollContent.pollCreationInfo?.question?.question ?: ""
|
||||
|
||||
return PollItem_()
|
||||
.attributes(attributes)
|
||||
.eventId(informationData.eventId)
|
||||
.pollQuestion(pollContent.pollCreationInfo?.question?.question ?: "")
|
||||
.pollQuestion(
|
||||
if (informationData.hasBeenEdited) {
|
||||
annotateWithEdited(question, callback, informationData)
|
||||
} else {
|
||||
question
|
||||
}.toEpoxyCharSequence()
|
||||
)
|
||||
.pollSent(isPollSent)
|
||||
.totalVotesText(totalVotesText)
|
||||
.optionViewStates(optionViewStates)
|
||||
.edited(informationData.hasBeenEdited)
|
||||
.highlighted(highlight)
|
||||
.leftGuideline(avatarSizeProvider.leftGuideline)
|
||||
.callback(callback)
|
||||
|
@ -22,6 +22,7 @@ import androidx.core.view.children
|
||||
import com.airbnb.epoxy.EpoxyAttribute
|
||||
import com.airbnb.epoxy.EpoxyModelClass
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.epoxy.charsequence.EpoxyCharSequence
|
||||
import im.vector.app.features.home.room.detail.RoomDetailAction
|
||||
import im.vector.app.features.home.room.detail.timeline.TimelineEventController
|
||||
|
||||
@ -29,7 +30,7 @@ import im.vector.app.features.home.room.detail.timeline.TimelineEventController
|
||||
abstract class PollItem : AbsMessageItem<PollItem.Holder>() {
|
||||
|
||||
@EpoxyAttribute
|
||||
var pollQuestion: String? = null
|
||||
var pollQuestion: EpoxyCharSequence? = null
|
||||
|
||||
@EpoxyAttribute
|
||||
var callback: TimelineEventController.Callback? = null
|
||||
@ -43,6 +44,9 @@ abstract class PollItem : AbsMessageItem<PollItem.Holder>() {
|
||||
@EpoxyAttribute
|
||||
var totalVotesText: String? = null
|
||||
|
||||
@EpoxyAttribute
|
||||
var edited: Boolean = false
|
||||
|
||||
@EpoxyAttribute
|
||||
lateinit var optionViewStates: List<PollOptionViewState>
|
||||
|
||||
@ -52,7 +56,7 @@ abstract class PollItem : AbsMessageItem<PollItem.Holder>() {
|
||||
|
||||
renderSendState(holder.view, holder.questionTextView)
|
||||
|
||||
holder.questionTextView.text = pollQuestion
|
||||
holder.questionTextView.text = pollQuestion?.charSequence
|
||||
holder.totalVotesTextView.text = totalVotesText
|
||||
|
||||
while (holder.optionsContainer.childCount < optionViewStates.size) {
|
||||
|
@ -24,7 +24,6 @@ import im.vector.app.core.di.MavericksAssistedViewModelFactory
|
||||
import im.vector.app.core.di.hiltMavericksViewModelFactory
|
||||
import im.vector.app.core.platform.VectorViewModel
|
||||
import org.matrix.android.sdk.api.session.Session
|
||||
import org.matrix.android.sdk.api.session.events.model.toModel
|
||||
import org.matrix.android.sdk.api.session.room.model.message.MessagePollContent
|
||||
import org.matrix.android.sdk.api.session.room.timeline.getLastMessageContent
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user