mirror of
https://github.com/element-hq/element-android
synced 2024-11-28 05:31:21 +03:00
Invalidate previous votes for edited polls.
This commit is contained in:
parent
5d07c71dcf
commit
9dd48045f6
5 changed files with 55 additions and 7 deletions
|
@ -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.message.MessageRelationContent
|
||||||
import org.matrix.android.sdk.api.session.room.model.relation.ReactionContent
|
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.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.model.event.EncryptedEventContent
|
||||||
import org.matrix.android.sdk.internal.crypto.verification.toState
|
import org.matrix.android.sdk.internal.crypto.verification.toState
|
||||||
import org.matrix.android.sdk.internal.database.mapper.ContentMapper
|
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.create
|
||||||
import org.matrix.android.sdk.internal.database.query.getOrCreate
|
import org.matrix.android.sdk.internal.database.query.getOrCreate
|
||||||
import org.matrix.android.sdk.internal.database.query.where
|
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.di.UserId
|
||||||
import org.matrix.android.sdk.internal.session.EventInsertLiveProcessor
|
import org.matrix.android.sdk.internal.session.EventInsertLiveProcessor
|
||||||
import org.matrix.android.sdk.internal.session.room.state.StateEventDataSource
|
import org.matrix.android.sdk.internal.session.room.state.StateEventDataSource
|
||||||
|
@ -64,7 +67,9 @@ import javax.inject.Inject
|
||||||
|
|
||||||
internal class EventRelationsAggregationProcessor @Inject constructor(
|
internal class EventRelationsAggregationProcessor @Inject constructor(
|
||||||
@UserId private val userId: String,
|
@UserId private val userId: String,
|
||||||
private val stateEventDataSource: StateEventDataSource
|
private val stateEventDataSource: StateEventDataSource,
|
||||||
|
@SessionId private val sessionId: String,
|
||||||
|
private val sessionManager: SessionManager
|
||||||
) : EventInsertLiveProcessor {
|
) : EventInsertLiveProcessor {
|
||||||
|
|
||||||
private val allowedTypes = listOf(
|
private val allowedTypes = listOf(
|
||||||
|
@ -284,6 +289,20 @@ internal class EventRelationsAggregationProcessor @Inject constructor(
|
||||||
Timber.v("###REPLACE ignoring event for summary, it's known $eventId")
|
Timber.v("###REPLACE ignoring event for summary, it's known $eventId")
|
||||||
return
|
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
|
val txId = event.unsignedData?.transactionId
|
||||||
// is it a remote echo?
|
// is it a remote echo?
|
||||||
if (!isLocalEcho && existingSummary.editions.any { it.eventId == txId }) {
|
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 targetEventId = relatedEventId ?: content.relatesTo?.eventId ?: return
|
||||||
val eventTimestamp = event.originServerTs ?: 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
|
// ok, this is a poll response
|
||||||
var existing = EventAnnotationsSummaryEntity.where(realm, roomId, targetEventId).findFirst()
|
var existing = EventAnnotationsSummaryEntity.where(realm, roomId, targetEventId).findFirst()
|
||||||
if (existing == null) {
|
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}")
|
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 votes = sumModel.votes?.toMutableList() ?: ArrayList()
|
||||||
val existingVoteIndex = votes.indexOfFirst { it.userId == senderId }
|
val existingVoteIndex = votes.indexOfFirst { it.userId == senderId }
|
||||||
if (existingVoteIndex != -1) {
|
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.content.ThumbnailExtractor
|
||||||
import org.matrix.android.sdk.internal.session.permalinks.PermalinkFactory
|
import org.matrix.android.sdk.internal.session.permalinks.PermalinkFactory
|
||||||
import org.matrix.android.sdk.internal.session.room.send.pills.TextPillsUtils
|
import org.matrix.android.sdk.internal.session.room.send.pills.TextPillsUtils
|
||||||
|
import java.util.UUID
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -131,9 +132,9 @@ internal class LocalEchoEventFactory @Inject constructor(
|
||||||
question = PollQuestion(
|
question = PollQuestion(
|
||||||
question = question
|
question = question
|
||||||
),
|
),
|
||||||
answers = options.mapIndexed { index, option ->
|
answers = options.map { option ->
|
||||||
PollAnswer(
|
PollAnswer(
|
||||||
id = "$index-$option",
|
id = UUID.randomUUID().toString(),
|
||||||
answer = option
|
answer = option
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -220,13 +220,22 @@ class MessageItemFactory @Inject constructor(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val question = pollContent.pollCreationInfo?.question?.question ?: ""
|
||||||
|
|
||||||
return PollItem_()
|
return PollItem_()
|
||||||
.attributes(attributes)
|
.attributes(attributes)
|
||||||
.eventId(informationData.eventId)
|
.eventId(informationData.eventId)
|
||||||
.pollQuestion(pollContent.pollCreationInfo?.question?.question ?: "")
|
.pollQuestion(
|
||||||
|
if (informationData.hasBeenEdited) {
|
||||||
|
annotateWithEdited(question, callback, informationData)
|
||||||
|
} else {
|
||||||
|
question
|
||||||
|
}.toEpoxyCharSequence()
|
||||||
|
)
|
||||||
.pollSent(isPollSent)
|
.pollSent(isPollSent)
|
||||||
.totalVotesText(totalVotesText)
|
.totalVotesText(totalVotesText)
|
||||||
.optionViewStates(optionViewStates)
|
.optionViewStates(optionViewStates)
|
||||||
|
.edited(informationData.hasBeenEdited)
|
||||||
.highlighted(highlight)
|
.highlighted(highlight)
|
||||||
.leftGuideline(avatarSizeProvider.leftGuideline)
|
.leftGuideline(avatarSizeProvider.leftGuideline)
|
||||||
.callback(callback)
|
.callback(callback)
|
||||||
|
|
|
@ -22,6 +22,7 @@ import androidx.core.view.children
|
||||||
import com.airbnb.epoxy.EpoxyAttribute
|
import com.airbnb.epoxy.EpoxyAttribute
|
||||||
import com.airbnb.epoxy.EpoxyModelClass
|
import com.airbnb.epoxy.EpoxyModelClass
|
||||||
import im.vector.app.R
|
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.RoomDetailAction
|
||||||
import im.vector.app.features.home.room.detail.timeline.TimelineEventController
|
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>() {
|
abstract class PollItem : AbsMessageItem<PollItem.Holder>() {
|
||||||
|
|
||||||
@EpoxyAttribute
|
@EpoxyAttribute
|
||||||
var pollQuestion: String? = null
|
var pollQuestion: EpoxyCharSequence? = null
|
||||||
|
|
||||||
@EpoxyAttribute
|
@EpoxyAttribute
|
||||||
var callback: TimelineEventController.Callback? = null
|
var callback: TimelineEventController.Callback? = null
|
||||||
|
@ -43,6 +44,9 @@ abstract class PollItem : AbsMessageItem<PollItem.Holder>() {
|
||||||
@EpoxyAttribute
|
@EpoxyAttribute
|
||||||
var totalVotesText: String? = null
|
var totalVotesText: String? = null
|
||||||
|
|
||||||
|
@EpoxyAttribute
|
||||||
|
var edited: Boolean = false
|
||||||
|
|
||||||
@EpoxyAttribute
|
@EpoxyAttribute
|
||||||
lateinit var optionViewStates: List<PollOptionViewState>
|
lateinit var optionViewStates: List<PollOptionViewState>
|
||||||
|
|
||||||
|
@ -52,7 +56,7 @@ abstract class PollItem : AbsMessageItem<PollItem.Holder>() {
|
||||||
|
|
||||||
renderSendState(holder.view, holder.questionTextView)
|
renderSendState(holder.view, holder.questionTextView)
|
||||||
|
|
||||||
holder.questionTextView.text = pollQuestion
|
holder.questionTextView.text = pollQuestion?.charSequence
|
||||||
holder.totalVotesTextView.text = totalVotesText
|
holder.totalVotesTextView.text = totalVotesText
|
||||||
|
|
||||||
while (holder.optionsContainer.childCount < optionViewStates.size) {
|
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.di.hiltMavericksViewModelFactory
|
||||||
import im.vector.app.core.platform.VectorViewModel
|
import im.vector.app.core.platform.VectorViewModel
|
||||||
import org.matrix.android.sdk.api.session.Session
|
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.model.message.MessagePollContent
|
||||||
import org.matrix.android.sdk.api.session.room.timeline.getLastMessageContent
|
import org.matrix.android.sdk.api.session.room.timeline.getLastMessageContent
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue