mirror of
https://github.com/element-hq/element-android
synced 2024-11-26 19:35:42 +03:00
Code review fixes.
This commit is contained in:
parent
2b26f2b221
commit
a8b111dc8c
8 changed files with 100 additions and 30 deletions
|
@ -3509,6 +3509,7 @@
|
|||
<string name="message_reply_to_sender_sent_sticker">sent a sticker.</string>
|
||||
<string name="message_reply_to_sender_created_poll">created a poll.</string>
|
||||
<string name="message_reply_to_sender_ended_poll">ended a poll.</string>
|
||||
<string name="message_reply_to_poll_preview">Poll</string>
|
||||
<string name="message_reply_to_ended_poll_preview">Ended poll</string>
|
||||
|
||||
<string name="settings_access_token">Access Token</string>
|
||||
|
|
|
@ -248,7 +248,7 @@ data class Event(
|
|||
if (isRedacted()) return "Message removed"
|
||||
val text = getDecryptedValue() ?: run {
|
||||
if (isPoll()) {
|
||||
return getPollQuestion() ?: if (isPollStart()) "created a poll." else if (isPollEnd()) "ended a poll." else null
|
||||
return getTextSummaryForPoll()
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
@ -261,13 +261,23 @@ data class Event(
|
|||
isImageMessage() -> "sent an image."
|
||||
isVideoMessage() -> "sent a video."
|
||||
isSticker() -> "sent a sticker."
|
||||
isPoll() -> getPollQuestion() ?: if (isPollStart()) "created a poll." else if (isPollEnd()) "ended a poll." else null
|
||||
isPoll() -> getTextSummaryForPoll()
|
||||
isLiveLocation() -> "Live location."
|
||||
isLocationMessage() -> "has shared their location."
|
||||
else -> text
|
||||
}
|
||||
}
|
||||
|
||||
private fun getTextSummaryForPoll(): String? {
|
||||
val pollQuestion = getPollQuestion()
|
||||
return when {
|
||||
pollQuestion != null -> pollQuestion
|
||||
isPollStart() -> "created a poll."
|
||||
isPollEnd() -> "ended a poll."
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
private fun Event.isQuote(): Boolean {
|
||||
if (isReplyRenderedInThread()) return false
|
||||
return getDecryptedValue("formatted_body")?.contains("<blockquote>") ?: false
|
||||
|
|
|
@ -281,13 +281,9 @@ class MessageItemFactory @Inject constructor(
|
|||
val pollStartEvent = session.roomService().getRoom(roomId)?.getTimelineEvent(pollStartEventId)
|
||||
val pollContent = pollStartEvent?.root?.getClearContent()?.toModel<MessagePollContent>() ?: return null
|
||||
|
||||
val aggregatedInformationData = informationData.copy(
|
||||
pollResponseAggregatedSummary = messageInformationDataFactory.mapPollResponseSummary(pollStartEvent.annotations?.pollResponseSummary)
|
||||
)
|
||||
|
||||
return buildPollItem(
|
||||
pollContent,
|
||||
aggregatedInformationData,
|
||||
informationData,
|
||||
highlight,
|
||||
callback,
|
||||
attributes,
|
||||
|
|
|
@ -24,6 +24,7 @@ import org.matrix.android.sdk.api.session.events.model.isAudioMessage
|
|||
import org.matrix.android.sdk.api.session.events.model.isFileMessage
|
||||
import org.matrix.android.sdk.api.session.events.model.isImageMessage
|
||||
import org.matrix.android.sdk.api.session.events.model.isPollEnd
|
||||
import org.matrix.android.sdk.api.session.events.model.isPollStart
|
||||
import org.matrix.android.sdk.api.session.events.model.isVideoMessage
|
||||
import org.matrix.android.sdk.api.session.events.model.toModel
|
||||
import org.matrix.android.sdk.api.session.room.model.message.MessageAudioContent
|
||||
|
@ -53,11 +54,14 @@ class EventDetailsFormatter @Inject constructor(
|
|||
event.isVideoMessage() -> formatForVideoMessage(event)
|
||||
event.isAudioMessage() -> formatForAudioMessage(event)
|
||||
event.isFileMessage() -> formatForFileMessage(event)
|
||||
event.isPollStart() -> formatPollMessage()
|
||||
event.isPollEnd() -> formatPollEndMessage()
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
private fun formatPollMessage() = context.getString(R.string.message_reply_to_poll_preview)
|
||||
|
||||
private fun formatPollEndMessage() = context.getString(R.string.message_reply_to_ended_poll_preview)
|
||||
|
||||
/**
|
||||
|
|
|
@ -23,8 +23,6 @@ import im.vector.app.core.extensions.localDateTime
|
|||
import im.vector.app.features.home.room.detail.timeline.factory.TimelineItemFactoryParams
|
||||
import im.vector.app.features.home.room.detail.timeline.item.E2EDecoration
|
||||
import im.vector.app.features.home.room.detail.timeline.item.MessageInformationData
|
||||
import im.vector.app.features.home.room.detail.timeline.item.PollResponseData
|
||||
import im.vector.app.features.home.room.detail.timeline.item.PollVoteSummaryData
|
||||
import im.vector.app.features.home.room.detail.timeline.item.ReferencesInfoData
|
||||
import im.vector.app.features.home.room.detail.timeline.item.SendStateDecoration
|
||||
import im.vector.app.features.home.room.detail.timeline.style.TimelineMessageLayoutFactory
|
||||
|
@ -38,7 +36,6 @@ import org.matrix.android.sdk.api.session.events.model.isAttachmentMessage
|
|||
import org.matrix.android.sdk.api.session.events.model.isSticker
|
||||
import org.matrix.android.sdk.api.session.events.model.toModel
|
||||
import org.matrix.android.sdk.api.session.events.model.toValidDecryptedEvent
|
||||
import org.matrix.android.sdk.api.session.room.model.PollResponseAggregatedSummary
|
||||
import org.matrix.android.sdk.api.session.room.model.ReferencesAggregatedContent
|
||||
import org.matrix.android.sdk.api.session.room.model.RoomSummary
|
||||
import org.matrix.android.sdk.api.session.room.model.message.MessageType
|
||||
|
@ -55,7 +52,8 @@ class MessageInformationDataFactory @Inject constructor(
|
|||
private val session: Session,
|
||||
private val dateFormatter: VectorDateFormatter,
|
||||
private val messageLayoutFactory: TimelineMessageLayoutFactory,
|
||||
private val reactionsSummaryFactory: ReactionsSummaryFactory
|
||||
private val reactionsSummaryFactory: ReactionsSummaryFactory,
|
||||
private val pollResponseDataFactory: PollResponseDataFactory,
|
||||
) {
|
||||
|
||||
fun create(params: TimelineItemFactoryParams): MessageInformationData {
|
||||
|
@ -100,7 +98,7 @@ class MessageInformationDataFactory @Inject constructor(
|
|||
memberName = event.senderInfo.disambiguatedDisplayName,
|
||||
messageLayout = messageLayout,
|
||||
reactionsSummary = reactionsSummaryFactory.create(event),
|
||||
pollResponseAggregatedSummary = mapPollResponseSummary(event.annotations?.pollResponseSummary),
|
||||
pollResponseAggregatedSummary = pollResponseDataFactory.create(event),
|
||||
hasBeenEdited = event.hasBeenEdited(),
|
||||
hasPendingEdits = event.annotations?.editSummary?.localEchos?.any() ?: false,
|
||||
referencesInfoData = event.annotations?.referencesAggregatedSummary?.let { referencesAggregatedSummary ->
|
||||
|
@ -121,23 +119,6 @@ class MessageInformationDataFactory @Inject constructor(
|
|||
)
|
||||
}
|
||||
|
||||
fun mapPollResponseSummary(pollResponseSummary: PollResponseAggregatedSummary?): PollResponseData? {
|
||||
return pollResponseSummary?.let {
|
||||
PollResponseData(
|
||||
myVote = it.aggregatedContent?.myVote,
|
||||
isClosed = it.closedTime != null,
|
||||
votes = it.aggregatedContent?.votesSummary?.mapValues { votesSummary ->
|
||||
PollVoteSummaryData(
|
||||
total = votesSummary.value.total,
|
||||
percentage = votesSummary.value.percentage
|
||||
)
|
||||
},
|
||||
winnerVoteCount = it.aggregatedContent?.winnerVoteCount ?: 0,
|
||||
totalVotes = it.aggregatedContent?.totalVotes ?: 0
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getSenderId(event: TimelineEvent) = if (event.isEncrypted()) {
|
||||
event.root.toValidDecryptedEvent()?.let {
|
||||
session.cryptoService().deviceWithIdentityKey(it.cryptoSenderKey, it.algorithm)?.userId
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* 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.timeline.helper
|
||||
|
||||
import im.vector.app.core.di.ActiveSessionHolder
|
||||
import im.vector.app.features.home.room.detail.timeline.item.PollResponseData
|
||||
import im.vector.app.features.home.room.detail.timeline.item.PollVoteSummaryData
|
||||
import org.matrix.android.sdk.api.session.events.model.getRelationContent
|
||||
import org.matrix.android.sdk.api.session.events.model.isPollEnd
|
||||
import org.matrix.android.sdk.api.session.room.getTimelineEvent
|
||||
import org.matrix.android.sdk.api.session.room.model.PollResponseAggregatedSummary
|
||||
import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
class PollResponseDataFactory @Inject constructor(
|
||||
private val activeSessionHolder: ActiveSessionHolder,
|
||||
) {
|
||||
|
||||
fun create(event: TimelineEvent): PollResponseData? {
|
||||
val pollResponseSummary = getPollResponseSummary(event)
|
||||
return pollResponseSummary?.let {
|
||||
PollResponseData(
|
||||
myVote = it.aggregatedContent?.myVote,
|
||||
isClosed = it.closedTime != null,
|
||||
votes = it.aggregatedContent?.votesSummary?.mapValues { votesSummary ->
|
||||
PollVoteSummaryData(
|
||||
total = votesSummary.value.total,
|
||||
percentage = votesSummary.value.percentage
|
||||
)
|
||||
},
|
||||
winnerVoteCount = it.aggregatedContent?.winnerVoteCount ?: 0,
|
||||
totalVotes = it.aggregatedContent?.totalVotes ?: 0
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getPollResponseSummary(event: TimelineEvent): PollResponseAggregatedSummary? {
|
||||
if (event.root.isPollEnd()) {
|
||||
val pollStartEventId = event.root.getRelationContent()?.eventId ?: return null.also {
|
||||
Timber.e("### Cannot render poll end event because poll start event id is null")
|
||||
}
|
||||
return activeSessionHolder
|
||||
.getSafeActiveSession()
|
||||
?.roomService()
|
||||
?.getRoom(event.roomId)
|
||||
?.getTimelineEvent(pollStartEventId)
|
||||
?.annotations
|
||||
?.pollResponseSummary
|
||||
}
|
||||
return event.annotations?.pollResponseSummary
|
||||
}
|
||||
}
|
|
@ -43,7 +43,7 @@ class CheckIfCanReplyEventUseCaseTest {
|
|||
|
||||
@Test
|
||||
fun `given reply is allowed for the event type when use case is executed then result is true`() {
|
||||
val eventTypes = EventType.STATE_ROOM_BEACON_INFO.values + EventType.POLL_START.values + EventType.MESSAGE
|
||||
val eventTypes = EventType.STATE_ROOM_BEACON_INFO.values + EventType.POLL_START.values + EventType.POLL_END.values + EventType.MESSAGE
|
||||
|
||||
eventTypes.forEach { eventType ->
|
||||
val event = givenAnEvent(eventType)
|
||||
|
|
|
@ -176,6 +176,17 @@ class ProcessBodyOfReplyToEventUseCaseTest {
|
|||
executeAndAssertResult()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given a replied event of type poll end message when process the formatted body then content is replaced by correct string`() {
|
||||
// Given
|
||||
givenTypeOfRepliedEvent(isPollMessage = true)
|
||||
givenNewContentForId(R.string.message_reply_to_sender_ended_poll)
|
||||
every { fakeRepliedEvent.getClearType() } returns EventType.POLL_END.unstable
|
||||
every { fakeRepliedEvent.getPollQuestion() } returns null
|
||||
|
||||
executeAndAssertResult()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given a replied event of type live location message when process the formatted body then content is replaced by correct string`() {
|
||||
// Given
|
||||
|
|
Loading…
Reference in a new issue