mirror of
https://github.com/SchildiChat/SchildiChat-android.git
synced 2024-11-22 09:25:49 +03:00
Merge pull request #7611 from vector-im/feature/fre/voice_broadcast_deletion
Be less restritive when pruning redacted events
This commit is contained in:
commit
49199bd5e2
39 changed files with 175 additions and 138 deletions
|
@ -66,7 +66,7 @@ class PollAggregationTest : InstrumentedTest {
|
||||||
|
|
||||||
val aliceEventsListener = object : Timeline.Listener {
|
val aliceEventsListener = object : Timeline.Listener {
|
||||||
override fun onTimelineUpdated(snapshot: List<TimelineEvent>) {
|
override fun onTimelineUpdated(snapshot: List<TimelineEvent>) {
|
||||||
snapshot.firstOrNull { it.root.getClearType() in EventType.POLL_START }?.let { pollEvent ->
|
snapshot.firstOrNull { it.root.getClearType() in EventType.POLL_START.values }?.let { pollEvent ->
|
||||||
val pollEventId = pollEvent.eventId
|
val pollEventId = pollEvent.eventId
|
||||||
val pollContent = pollEvent.root.content?.toModel<MessagePollContent>()
|
val pollContent = pollEvent.root.content?.toModel<MessagePollContent>()
|
||||||
val pollSummary = pollEvent.annotations?.pollResponseSummary
|
val pollSummary = pollEvent.annotations?.pollResponseSummary
|
||||||
|
|
|
@ -26,10 +26,8 @@ import org.matrix.android.sdk.api.session.crypto.model.OlmDecryptionResult
|
||||||
import org.matrix.android.sdk.api.session.events.model.content.EncryptedEventContent
|
import org.matrix.android.sdk.api.session.events.model.content.EncryptedEventContent
|
||||||
import org.matrix.android.sdk.api.session.room.model.Membership
|
import org.matrix.android.sdk.api.session.room.model.Membership
|
||||||
import org.matrix.android.sdk.api.session.room.model.RoomMemberContent
|
import org.matrix.android.sdk.api.session.room.model.RoomMemberContent
|
||||||
import org.matrix.android.sdk.api.session.room.model.message.MessageBeaconLocationDataContent
|
|
||||||
import org.matrix.android.sdk.api.session.room.model.message.MessageContent
|
import org.matrix.android.sdk.api.session.room.model.message.MessageContent
|
||||||
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.model.message.MessageStickerContent
|
|
||||||
import org.matrix.android.sdk.api.session.room.model.message.MessageType
|
import org.matrix.android.sdk.api.session.room.model.message.MessageType
|
||||||
import org.matrix.android.sdk.api.session.room.model.message.asMessageAudioEvent
|
import org.matrix.android.sdk.api.session.room.model.message.asMessageAudioEvent
|
||||||
import org.matrix.android.sdk.api.session.room.model.relation.RelationDefaultContent
|
import org.matrix.android.sdk.api.session.room.model.relation.RelationDefaultContent
|
||||||
|
@ -390,24 +388,18 @@ fun Event.isLocationMessage(): Boolean {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Event.isPoll(): Boolean = getClearType() in EventType.POLL_START || getClearType() in EventType.POLL_END
|
fun Event.isPoll(): Boolean = getClearType() in EventType.POLL_START.values || getClearType() in EventType.POLL_END.values
|
||||||
|
|
||||||
fun Event.isSticker(): Boolean = getClearType() == EventType.STICKER
|
fun Event.isSticker(): Boolean = getClearType() == EventType.STICKER
|
||||||
|
|
||||||
fun Event.isLiveLocation(): Boolean = getClearType() in EventType.STATE_ROOM_BEACON_INFO
|
fun Event.isLiveLocation(): Boolean = getClearType() in EventType.STATE_ROOM_BEACON_INFO.values
|
||||||
|
|
||||||
fun Event.getRelationContent(): RelationDefaultContent? {
|
fun Event.getRelationContent(): RelationDefaultContent? {
|
||||||
return if (isEncrypted()) {
|
return if (isEncrypted()) {
|
||||||
content.toModel<EncryptedEventContent>()?.relatesTo
|
content.toModel<EncryptedEventContent>()?.relatesTo
|
||||||
} else {
|
} else {
|
||||||
content.toModel<MessageContent>()?.relatesTo ?: run {
|
content.toModel<MessageContent>()?.relatesTo
|
||||||
// Special cases when there is only a local msgtype for some event types
|
?: getClearContent()?.get("m.relates_to")?.toContent().toModel() // Special cases when there is only a local msgtype for some event types
|
||||||
when (getClearType()) {
|
|
||||||
EventType.STICKER -> getClearContent().toModel<MessageStickerContent>()?.relatesTo
|
|
||||||
in EventType.BEACON_LOCATION_DATA -> getClearContent().toModel<MessageBeaconLocationDataContent>()?.relatesTo
|
|
||||||
else -> getClearContent()?.get("m.relates_to")?.toContent().toModel()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -451,7 +443,7 @@ fun Event.getPollContent(): MessagePollContent? {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Event.supportsNotification() =
|
fun Event.supportsNotification() =
|
||||||
this.getClearType() in EventType.MESSAGE + EventType.POLL_START + EventType.STATE_ROOM_BEACON_INFO
|
this.getClearType() in EventType.MESSAGE + EventType.POLL_START.values + EventType.STATE_ROOM_BEACON_INFO.values
|
||||||
|
|
||||||
fun Event.isContentReportable() =
|
fun Event.isContentReportable() =
|
||||||
this.getClearType() in EventType.MESSAGE + EventType.STATE_ROOM_BEACON_INFO
|
this.getClearType() in EventType.MESSAGE + EventType.STATE_ROOM_BEACON_INFO.values
|
||||||
|
|
|
@ -49,11 +49,10 @@ object EventType {
|
||||||
const val STATE_ROOM_JOIN_RULES = "m.room.join_rules"
|
const val STATE_ROOM_JOIN_RULES = "m.room.join_rules"
|
||||||
const val STATE_ROOM_GUEST_ACCESS = "m.room.guest_access"
|
const val STATE_ROOM_GUEST_ACCESS = "m.room.guest_access"
|
||||||
const val STATE_ROOM_POWER_LEVELS = "m.room.power_levels"
|
const val STATE_ROOM_POWER_LEVELS = "m.room.power_levels"
|
||||||
val STATE_ROOM_BEACON_INFO = listOf("org.matrix.msc3672.beacon_info", "m.beacon_info")
|
val STATE_ROOM_BEACON_INFO = StableUnstableId(stable = "m.beacon_info", unstable = "org.matrix.msc3672.beacon_info")
|
||||||
val BEACON_LOCATION_DATA = listOf("org.matrix.msc3672.beacon", "m.beacon")
|
val BEACON_LOCATION_DATA = StableUnstableId(stable = "m.beacon", unstable = "org.matrix.msc3672.beacon")
|
||||||
|
|
||||||
const val STATE_SPACE_CHILD = "m.space.child"
|
const val STATE_SPACE_CHILD = "m.space.child"
|
||||||
|
|
||||||
const val STATE_SPACE_PARENT = "m.space.parent"
|
const val STATE_SPACE_PARENT = "m.space.parent"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -81,8 +80,7 @@ object EventType {
|
||||||
const val CALL_NEGOTIATE = "m.call.negotiate"
|
const val CALL_NEGOTIATE = "m.call.negotiate"
|
||||||
const val CALL_REJECT = "m.call.reject"
|
const val CALL_REJECT = "m.call.reject"
|
||||||
const val CALL_HANGUP = "m.call.hangup"
|
const val CALL_HANGUP = "m.call.hangup"
|
||||||
const val CALL_ASSERTED_IDENTITY = "m.call.asserted_identity"
|
val CALL_ASSERTED_IDENTITY = StableUnstableId(stable = "m.call.asserted_identity", unstable = "org.matrix.call.asserted_identity")
|
||||||
const val CALL_ASSERTED_IDENTITY_PREFIX = "org.matrix.call.asserted_identity"
|
|
||||||
|
|
||||||
// This type is not processed by the client, just sent to the server
|
// This type is not processed by the client, just sent to the server
|
||||||
const val CALL_REPLACES = "m.call.replaces"
|
const val CALL_REPLACES = "m.call.replaces"
|
||||||
|
@ -90,10 +88,7 @@ object EventType {
|
||||||
// Key share events
|
// Key share events
|
||||||
const val ROOM_KEY_REQUEST = "m.room_key_request"
|
const val ROOM_KEY_REQUEST = "m.room_key_request"
|
||||||
const val FORWARDED_ROOM_KEY = "m.forwarded_room_key"
|
const val FORWARDED_ROOM_KEY = "m.forwarded_room_key"
|
||||||
val ROOM_KEY_WITHHELD = StableUnstableId(
|
val ROOM_KEY_WITHHELD = StableUnstableId(stable = "m.room_key.withheld", unstable = "org.matrix.room_key.withheld")
|
||||||
stable = "m.room_key.withheld",
|
|
||||||
unstable = "org.matrix.room_key.withheld"
|
|
||||||
)
|
|
||||||
|
|
||||||
const val REQUEST_SECRET = "m.secret.request"
|
const val REQUEST_SECRET = "m.secret.request"
|
||||||
const val SEND_SECRET = "m.secret.send"
|
const val SEND_SECRET = "m.secret.send"
|
||||||
|
@ -111,9 +106,9 @@ object EventType {
|
||||||
const val REACTION = "m.reaction"
|
const val REACTION = "m.reaction"
|
||||||
|
|
||||||
// Poll
|
// Poll
|
||||||
val POLL_START = listOf("org.matrix.msc3381.poll.start", "m.poll.start")
|
val POLL_START = StableUnstableId(stable = "m.poll.start", unstable = "org.matrix.msc3381.poll.start")
|
||||||
val POLL_RESPONSE = listOf("org.matrix.msc3381.poll.response", "m.poll.response")
|
val POLL_RESPONSE = StableUnstableId(stable = "m.poll.response", unstable = "org.matrix.msc3381.poll.response")
|
||||||
val POLL_END = listOf("org.matrix.msc3381.poll.end", "m.poll.end")
|
val POLL_END = StableUnstableId(stable = "m.poll.end", unstable = "org.matrix.msc3381.poll.end")
|
||||||
|
|
||||||
// Unwedging
|
// Unwedging
|
||||||
internal const val DUMMY = "m.dummy"
|
internal const val DUMMY = "m.dummy"
|
||||||
|
|
|
@ -34,7 +34,7 @@ data class MessageStickerContent(
|
||||||
* Required. A textual representation of the image. This could be the alt text of the image, the filename of the image,
|
* Required. A textual representation of the image. This could be the alt text of the image, the filename of the image,
|
||||||
* or some kind of content description for accessibility e.g. 'image attachment'.
|
* or some kind of content description for accessibility e.g. 'image attachment'.
|
||||||
*/
|
*/
|
||||||
@Json(name = "body") override val body: String,
|
@Json(name = "body") override val body: String = "",
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Metadata about the image referred to in url.
|
* Metadata about the image referred to in url.
|
||||||
|
|
|
@ -33,5 +33,7 @@ object RoomSummaryConstants {
|
||||||
EventType.ENCRYPTED,
|
EventType.ENCRYPTED,
|
||||||
EventType.STICKER,
|
EventType.STICKER,
|
||||||
EventType.REACTION
|
EventType.REACTION
|
||||||
) + EventType.POLL_START + EventType.STATE_ROOM_BEACON_INFO
|
) +
|
||||||
|
EventType.POLL_START.values +
|
||||||
|
EventType.STATE_ROOM_BEACON_INFO.values
|
||||||
}
|
}
|
||||||
|
|
|
@ -147,9 +147,9 @@ fun TimelineEvent.getLastMessageContent(): MessageContent? {
|
||||||
// Polls/Beacon are not message contents like others as there is no msgtype subtype to discriminate moshi parsing
|
// Polls/Beacon are not message contents like others as there is no msgtype subtype to discriminate moshi parsing
|
||||||
// so toModel<MessageContent> won't parse them correctly
|
// so toModel<MessageContent> won't parse them correctly
|
||||||
// It's discriminated on event type instead. Maybe it shouldn't be MessageContent at all to avoid confusion?
|
// It's discriminated on event type instead. Maybe it shouldn't be MessageContent at all to avoid confusion?
|
||||||
in EventType.POLL_START -> (getLastEditNewContent() ?: root.getClearContent()).toModel<MessagePollContent>()
|
in EventType.POLL_START.values -> (getLastEditNewContent() ?: root.getClearContent()).toModel<MessagePollContent>()
|
||||||
in EventType.STATE_ROOM_BEACON_INFO -> (getLastEditNewContent() ?: root.getClearContent()).toModel<MessageBeaconInfoContent>()
|
in EventType.STATE_ROOM_BEACON_INFO.values -> (getLastEditNewContent() ?: root.getClearContent()).toModel<MessageBeaconInfoContent>()
|
||||||
in EventType.BEACON_LOCATION_DATA -> (getLastEditNewContent() ?: root.getClearContent()).toModel<MessageBeaconLocationDataContent>()
|
in EventType.BEACON_LOCATION_DATA.values -> (getLastEditNewContent() ?: root.getClearContent()).toModel<MessageBeaconLocationDataContent>()
|
||||||
else -> (getLastEditNewContent() ?: root.getClearContent()).toModel()
|
else -> (getLastEditNewContent() ?: root.getClearContent()).toModel()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,9 +41,8 @@ internal class CallEventProcessor @Inject constructor(private val callSignalingH
|
||||||
EventType.CALL_INVITE,
|
EventType.CALL_INVITE,
|
||||||
EventType.CALL_HANGUP,
|
EventType.CALL_HANGUP,
|
||||||
EventType.ENCRYPTED,
|
EventType.ENCRYPTED,
|
||||||
EventType.CALL_ASSERTED_IDENTITY,
|
) +
|
||||||
EventType.CALL_ASSERTED_IDENTITY_PREFIX
|
EventType.CALL_ASSERTED_IDENTITY.values
|
||||||
)
|
|
||||||
|
|
||||||
private val eventsToPostProcess = mutableListOf<Event>()
|
private val eventsToPostProcess = mutableListOf<Event>()
|
||||||
|
|
||||||
|
|
|
@ -84,8 +84,7 @@ internal class CallSignalingHandler @Inject constructor(
|
||||||
EventType.CALL_NEGOTIATE -> {
|
EventType.CALL_NEGOTIATE -> {
|
||||||
handleCallNegotiateEvent(event)
|
handleCallNegotiateEvent(event)
|
||||||
}
|
}
|
||||||
EventType.CALL_ASSERTED_IDENTITY,
|
in EventType.CALL_ASSERTED_IDENTITY.values -> {
|
||||||
EventType.CALL_ASSERTED_IDENTITY_PREFIX -> {
|
|
||||||
handleCallAssertedIdentityEvent(event)
|
handleCallAssertedIdentityEvent(event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,8 +56,8 @@ internal class DefaultProcessEventForPushTask @Inject constructor(
|
||||||
|
|
||||||
val allEvents = (newJoinEvents + inviteEvents).filter { event ->
|
val allEvents = (newJoinEvents + inviteEvents).filter { event ->
|
||||||
when (event.type) {
|
when (event.type) {
|
||||||
in EventType.POLL_START,
|
in EventType.POLL_START.values,
|
||||||
in EventType.STATE_ROOM_BEACON_INFO,
|
in EventType.STATE_ROOM_BEACON_INFO.values,
|
||||||
EventType.MESSAGE,
|
EventType.MESSAGE,
|
||||||
EventType.REDACTION,
|
EventType.REDACTION,
|
||||||
EventType.ENCRYPTED,
|
EventType.ENCRYPTED,
|
||||||
|
|
|
@ -91,7 +91,12 @@ internal class EventRelationsAggregationProcessor @Inject constructor(
|
||||||
EventType.KEY_VERIFICATION_READY,
|
EventType.KEY_VERIFICATION_READY,
|
||||||
EventType.KEY_VERIFICATION_KEY,
|
EventType.KEY_VERIFICATION_KEY,
|
||||||
EventType.ENCRYPTED
|
EventType.ENCRYPTED
|
||||||
) + EventType.POLL_START + EventType.POLL_RESPONSE + EventType.POLL_END + EventType.STATE_ROOM_BEACON_INFO + EventType.BEACON_LOCATION_DATA
|
) +
|
||||||
|
EventType.POLL_START.values +
|
||||||
|
EventType.POLL_RESPONSE.values +
|
||||||
|
EventType.POLL_END.values +
|
||||||
|
EventType.STATE_ROOM_BEACON_INFO.values +
|
||||||
|
EventType.BEACON_LOCATION_DATA.values
|
||||||
|
|
||||||
override fun shouldProcess(eventId: String, eventType: String, insertType: EventInsertType): Boolean {
|
override fun shouldProcess(eventId: String, eventType: String, insertType: EventInsertType): Boolean {
|
||||||
return allowedTypes.contains(eventType)
|
return allowedTypes.contains(eventType)
|
||||||
|
@ -208,7 +213,7 @@ internal class EventRelationsAggregationProcessor @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
in EventType.POLL_START -> {
|
in EventType.POLL_START.values -> {
|
||||||
val content: MessagePollContent? = event.content.toModel()
|
val content: MessagePollContent? = event.content.toModel()
|
||||||
if (content?.relatesTo?.type == RelationType.REPLACE) {
|
if (content?.relatesTo?.type == RelationType.REPLACE) {
|
||||||
Timber.v("###REPLACE in room $roomId for event ${event.eventId}")
|
Timber.v("###REPLACE in room $roomId for event ${event.eventId}")
|
||||||
|
@ -216,26 +221,26 @@ internal class EventRelationsAggregationProcessor @Inject constructor(
|
||||||
handleReplace(realm, event, roomId, isLocalEcho, content.relatesTo.eventId)
|
handleReplace(realm, event, roomId, isLocalEcho, content.relatesTo.eventId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
in EventType.POLL_RESPONSE -> {
|
in EventType.POLL_RESPONSE.values -> {
|
||||||
event.content.toModel<MessagePollResponseContent>(catchError = true)?.let {
|
event.content.toModel<MessagePollResponseContent>(catchError = true)?.let {
|
||||||
sessionManager.getSessionComponent(sessionId)?.session()?.let { session ->
|
sessionManager.getSessionComponent(sessionId)?.session()?.let { session ->
|
||||||
pollAggregationProcessor.handlePollResponseEvent(session, realm, event)
|
pollAggregationProcessor.handlePollResponseEvent(session, realm, event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
in EventType.POLL_END -> {
|
in EventType.POLL_END.values -> {
|
||||||
sessionManager.getSessionComponent(sessionId)?.session()?.let { session ->
|
sessionManager.getSessionComponent(sessionId)?.session()?.let { session ->
|
||||||
getPowerLevelsHelper(event.roomId)?.let {
|
getPowerLevelsHelper(event.roomId)?.let {
|
||||||
pollAggregationProcessor.handlePollEndEvent(session, it, realm, event)
|
pollAggregationProcessor.handlePollEndEvent(session, it, realm, event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
in EventType.STATE_ROOM_BEACON_INFO -> {
|
in EventType.STATE_ROOM_BEACON_INFO.values -> {
|
||||||
event.content.toModel<MessageBeaconInfoContent>(catchError = true)?.let {
|
event.content.toModel<MessageBeaconInfoContent>(catchError = true)?.let {
|
||||||
liveLocationAggregationProcessor.handleBeaconInfo(realm, event, it, roomId, isLocalEcho)
|
liveLocationAggregationProcessor.handleBeaconInfo(realm, event, it, roomId, isLocalEcho)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
in EventType.BEACON_LOCATION_DATA -> {
|
in EventType.BEACON_LOCATION_DATA.values -> {
|
||||||
handleBeaconLocationData(event, realm, roomId, isLocalEcho)
|
handleBeaconLocationData(event, realm, roomId, isLocalEcho)
|
||||||
}
|
}
|
||||||
else -> Timber.v("UnHandled event ${event.eventId}")
|
else -> Timber.v("UnHandled event ${event.eventId}")
|
||||||
|
@ -324,7 +329,7 @@ internal class EventRelationsAggregationProcessor @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event.getClearType() in EventType.POLL_START) {
|
if (event.getClearType() in EventType.POLL_START.values) {
|
||||||
pollAggregationProcessor.handlePollStartEvent(realm, event)
|
pollAggregationProcessor.handlePollStartEvent(realm, event)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,7 @@ internal class DefaultGetActiveBeaconInfoForUserTask @Inject constructor(
|
||||||
) : GetActiveBeaconInfoForUserTask {
|
) : GetActiveBeaconInfoForUserTask {
|
||||||
|
|
||||||
override suspend fun execute(params: GetActiveBeaconInfoForUserTask.Params): Event? {
|
override suspend fun execute(params: GetActiveBeaconInfoForUserTask.Params): Event? {
|
||||||
return EventType.STATE_ROOM_BEACON_INFO
|
return EventType.STATE_ROOM_BEACON_INFO.values
|
||||||
.mapNotNull {
|
.mapNotNull {
|
||||||
stateEventDataSource.getStateEvent(
|
stateEventDataSource.getStateEvent(
|
||||||
roomId = params.roomId,
|
roomId = params.roomId,
|
||||||
|
|
|
@ -48,7 +48,7 @@ internal class LiveLocationShareRedactionEventProcessor @Inject constructor() :
|
||||||
val redactedEvent = EventEntity.where(realm, eventId = event.redacts).findFirst()
|
val redactedEvent = EventEntity.where(realm, eventId = event.redacts).findFirst()
|
||||||
?: return
|
?: return
|
||||||
|
|
||||||
if (redactedEvent.type in EventType.STATE_ROOM_BEACON_INFO) {
|
if (redactedEvent.type in EventType.STATE_ROOM_BEACON_INFO.values) {
|
||||||
val liveSummary = LiveLocationShareAggregatedSummaryEntity.get(realm, eventId = redactedEvent.eventId)
|
val liveSummary = LiveLocationShareAggregatedSummaryEntity.get(realm, eventId = redactedEvent.eventId)
|
||||||
|
|
||||||
if (liveSummary != null) {
|
if (liveSummary != null) {
|
||||||
|
|
|
@ -46,7 +46,7 @@ internal class DefaultStartLiveLocationShareTask @Inject constructor(
|
||||||
isLive = true,
|
isLive = true,
|
||||||
unstableTimestampMillis = clock.epochMillis()
|
unstableTimestampMillis = clock.epochMillis()
|
||||||
).toContent()
|
).toContent()
|
||||||
val eventType = EventType.STATE_ROOM_BEACON_INFO.first()
|
val eventType = EventType.STATE_ROOM_BEACON_INFO.stable
|
||||||
val sendStateTaskParams = SendStateTask.Params(
|
val sendStateTaskParams = SendStateTask.Params(
|
||||||
roomId = params.roomId,
|
roomId = params.roomId,
|
||||||
stateKey = userId,
|
stateKey = userId,
|
||||||
|
|
|
@ -45,7 +45,7 @@ internal class DefaultStopLiveLocationShareTask @Inject constructor(
|
||||||
val sendStateTaskParams = SendStateTask.Params(
|
val sendStateTaskParams = SendStateTask.Params(
|
||||||
roomId = params.roomId,
|
roomId = params.roomId,
|
||||||
stateKey = stateKey,
|
stateKey = stateKey,
|
||||||
eventType = EventType.STATE_ROOM_BEACON_INFO.first(),
|
eventType = EventType.STATE_ROOM_BEACON_INFO.stable,
|
||||||
body = updatedContent
|
body = updatedContent
|
||||||
)
|
)
|
||||||
return try {
|
return try {
|
||||||
|
|
|
@ -61,45 +61,36 @@ internal class RedactionEventProcessor @Inject constructor() : EventInsertLivePr
|
||||||
val isLocalEcho = LocalEcho.isLocalEchoId(redactionEvent.eventId ?: "")
|
val isLocalEcho = LocalEcho.isLocalEchoId(redactionEvent.eventId ?: "")
|
||||||
Timber.v("Redact event for ${redactionEvent.redacts} localEcho=$isLocalEcho")
|
Timber.v("Redact event for ${redactionEvent.redacts} localEcho=$isLocalEcho")
|
||||||
|
|
||||||
val eventToPrune = EventEntity.where(realm, eventId = redactionEvent.redacts).findFirst()
|
val eventToPrune = EventEntity.where(realm, eventId = redactionEvent.redacts).findFirst() ?: return
|
||||||
?: return
|
|
||||||
|
|
||||||
val typeToPrune = eventToPrune.type
|
val typeToPrune = eventToPrune.type
|
||||||
val stateKey = eventToPrune.stateKey
|
val stateKey = eventToPrune.stateKey
|
||||||
val allowedKeys = computeAllowedKeys(typeToPrune)
|
val allowedKeys = computeAllowedKeys(typeToPrune)
|
||||||
if (allowedKeys.isNotEmpty()) {
|
when {
|
||||||
val prunedContent = ContentMapper.map(eventToPrune.content)?.filterKeys { key -> allowedKeys.contains(key) }
|
allowedKeys.isNotEmpty() -> {
|
||||||
eventToPrune.content = ContentMapper.map(prunedContent)
|
val prunedContent = ContentMapper.map(eventToPrune.content)?.filterKeys { key -> allowedKeys.contains(key) }
|
||||||
} else {
|
eventToPrune.content = ContentMapper.map(prunedContent)
|
||||||
when (typeToPrune) {
|
}
|
||||||
EventType.ENCRYPTED,
|
canPruneEventType(typeToPrune) -> {
|
||||||
EventType.MESSAGE,
|
Timber.d("REDACTION for message ${eventToPrune.eventId}")
|
||||||
in EventType.STATE_ROOM_BEACON_INFO,
|
val unsignedData = EventMapper.map(eventToPrune).unsignedData ?: UnsignedData(null, null)
|
||||||
in EventType.BEACON_LOCATION_DATA,
|
|
||||||
in EventType.POLL_START -> {
|
|
||||||
Timber.d("REDACTION for message ${eventToPrune.eventId}")
|
|
||||||
val unsignedData = EventMapper.map(eventToPrune).unsignedData
|
|
||||||
?: UnsignedData(null, null)
|
|
||||||
|
|
||||||
// was this event a m.replace
|
// was this event a m.replace
|
||||||
// val contentModel = ContentMapper.map(eventToPrune.content)?.toModel<MessageContent>()
|
// val contentModel = ContentMapper.map(eventToPrune.content)?.toModel<MessageContent>()
|
||||||
// if (RelationType.REPLACE == contentModel?.relatesTo?.type && contentModel.relatesTo?.eventId != null) {
|
// if (RelationType.REPLACE == contentModel?.relatesTo?.type && contentModel.relatesTo?.eventId != null) {
|
||||||
// eventRelationsAggregationUpdater.handleRedactionOfReplace(eventToPrune, contentModel.relatesTo!!.eventId!!, realm)
|
// eventRelationsAggregationUpdater.handleRedactionOfReplace(eventToPrune, contentModel.relatesTo!!.eventId!!, realm)
|
||||||
// }
|
// }
|
||||||
|
|
||||||
val modified = unsignedData.copy(redactedEvent = redactionEvent)
|
val modified = unsignedData.copy(redactedEvent = redactionEvent)
|
||||||
// Deleting the content of a thread message will result to delete the thread relation, however threads are now dynamic
|
eventToPrune.content = ContentMapper.map(emptyMap())
|
||||||
// so there is not much of a problem
|
eventToPrune.unsignedData = MoshiProvider.providesMoshi().adapter(UnsignedData::class.java).toJson(modified)
|
||||||
eventToPrune.content = ContentMapper.map(emptyMap())
|
eventToPrune.decryptionResultJson = null
|
||||||
eventToPrune.unsignedData = MoshiProvider.providesMoshi().adapter(UnsignedData::class.java).toJson(modified)
|
eventToPrune.decryptionErrorCode = null
|
||||||
eventToPrune.decryptionResultJson = null
|
|
||||||
eventToPrune.decryptionErrorCode = null
|
|
||||||
|
|
||||||
handleTimelineThreadSummaryIfNeeded(realm, eventToPrune, isLocalEcho)
|
handleTimelineThreadSummaryIfNeeded(realm, eventToPrune, isLocalEcho)
|
||||||
}
|
}
|
||||||
// EventType.REACTION -> {
|
else -> {
|
||||||
// eventRelationsAggregationUpdater.handleReactionRedact(eventToPrune, realm, userId)
|
Timber.w("Not pruning event (type $typeToPrune)")
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (typeToPrune == EventType.STATE_ROOM_MEMBER && stateKey != null) {
|
if (typeToPrune == EventType.STATE_ROOM_MEMBER && stateKey != null) {
|
||||||
|
@ -167,4 +158,28 @@ internal class RedactionEventProcessor @Inject constructor() : EventInsertLivePr
|
||||||
else -> emptyList()
|
else -> emptyList()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun canPruneEventType(eventType: String): Boolean {
|
||||||
|
return when {
|
||||||
|
EventType.isCallEvent(eventType) -> false
|
||||||
|
EventType.isVerificationEvent(eventType) -> false
|
||||||
|
eventType == EventType.STATE_ROOM_WIDGET_LEGACY ||
|
||||||
|
eventType == EventType.STATE_ROOM_WIDGET ||
|
||||||
|
eventType == EventType.STATE_ROOM_NAME ||
|
||||||
|
eventType == EventType.STATE_ROOM_TOPIC ||
|
||||||
|
eventType == EventType.STATE_ROOM_AVATAR ||
|
||||||
|
eventType == EventType.STATE_ROOM_THIRD_PARTY_INVITE ||
|
||||||
|
eventType == EventType.STATE_ROOM_GUEST_ACCESS ||
|
||||||
|
eventType == EventType.STATE_SPACE_CHILD ||
|
||||||
|
eventType == EventType.STATE_SPACE_PARENT ||
|
||||||
|
eventType == EventType.STATE_ROOM_TOMBSTONE ||
|
||||||
|
eventType == EventType.STATE_ROOM_HISTORY_VISIBILITY ||
|
||||||
|
eventType == EventType.STATE_ROOM_RELATED_GROUPS ||
|
||||||
|
eventType == EventType.STATE_ROOM_PINNED_EVENT ||
|
||||||
|
eventType == EventType.STATE_ROOM_ENCRYPTION ||
|
||||||
|
eventType == EventType.STATE_ROOM_SERVER_ACL ||
|
||||||
|
eventType == EventType.REACTION -> false
|
||||||
|
else -> true
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -181,7 +181,7 @@ internal class LocalEchoEventFactory @Inject constructor(
|
||||||
originServerTs = dummyOriginServerTs(),
|
originServerTs = dummyOriginServerTs(),
|
||||||
senderId = userId,
|
senderId = userId,
|
||||||
eventId = localId,
|
eventId = localId,
|
||||||
type = EventType.POLL_START.first(),
|
type = EventType.POLL_START.stable,
|
||||||
content = newContent.toContent().plus(additionalContent.orEmpty())
|
content = newContent.toContent().plus(additionalContent.orEmpty())
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -206,7 +206,7 @@ internal class LocalEchoEventFactory @Inject constructor(
|
||||||
originServerTs = dummyOriginServerTs(),
|
originServerTs = dummyOriginServerTs(),
|
||||||
senderId = userId,
|
senderId = userId,
|
||||||
eventId = localId,
|
eventId = localId,
|
||||||
type = EventType.POLL_RESPONSE.first(),
|
type = EventType.POLL_RESPONSE.stable,
|
||||||
content = content.toContent().plus(additionalContent.orEmpty()),
|
content = content.toContent().plus(additionalContent.orEmpty()),
|
||||||
unsignedData = UnsignedData(age = null, transactionId = localId)
|
unsignedData = UnsignedData(age = null, transactionId = localId)
|
||||||
)
|
)
|
||||||
|
@ -226,7 +226,7 @@ internal class LocalEchoEventFactory @Inject constructor(
|
||||||
originServerTs = dummyOriginServerTs(),
|
originServerTs = dummyOriginServerTs(),
|
||||||
senderId = userId,
|
senderId = userId,
|
||||||
eventId = localId,
|
eventId = localId,
|
||||||
type = EventType.POLL_START.first(),
|
type = EventType.POLL_START.stable,
|
||||||
content = content.toContent().plus(additionalContent.orEmpty()),
|
content = content.toContent().plus(additionalContent.orEmpty()),
|
||||||
unsignedData = UnsignedData(age = null, transactionId = localId)
|
unsignedData = UnsignedData(age = null, transactionId = localId)
|
||||||
)
|
)
|
||||||
|
@ -249,7 +249,7 @@ internal class LocalEchoEventFactory @Inject constructor(
|
||||||
originServerTs = dummyOriginServerTs(),
|
originServerTs = dummyOriginServerTs(),
|
||||||
senderId = userId,
|
senderId = userId,
|
||||||
eventId = localId,
|
eventId = localId,
|
||||||
type = EventType.POLL_END.first(),
|
type = EventType.POLL_END.stable,
|
||||||
content = content.toContent().plus(additionalContent.orEmpty()),
|
content = content.toContent().plus(additionalContent.orEmpty()),
|
||||||
unsignedData = UnsignedData(age = null, transactionId = localId)
|
unsignedData = UnsignedData(age = null, transactionId = localId)
|
||||||
)
|
)
|
||||||
|
@ -300,7 +300,7 @@ internal class LocalEchoEventFactory @Inject constructor(
|
||||||
originServerTs = dummyOriginServerTs(),
|
originServerTs = dummyOriginServerTs(),
|
||||||
senderId = userId,
|
senderId = userId,
|
||||||
eventId = localId,
|
eventId = localId,
|
||||||
type = EventType.BEACON_LOCATION_DATA.first(),
|
type = EventType.BEACON_LOCATION_DATA.stable,
|
||||||
content = content.toContent().plus(additionalContent.orEmpty()),
|
content = content.toContent().plus(additionalContent.orEmpty()),
|
||||||
unsignedData = UnsignedData(age = null, transactionId = localId)
|
unsignedData = UnsignedData(age = null, transactionId = localId)
|
||||||
)
|
)
|
||||||
|
|
|
@ -87,7 +87,7 @@ object PollEventsTestData {
|
||||||
)
|
)
|
||||||
|
|
||||||
internal val A_POLL_START_EVENT = Event(
|
internal val A_POLL_START_EVENT = Event(
|
||||||
type = EventType.POLL_START.first(),
|
type = EventType.POLL_START.stable,
|
||||||
eventId = AN_EVENT_ID,
|
eventId = AN_EVENT_ID,
|
||||||
originServerTs = 1652435922563,
|
originServerTs = 1652435922563,
|
||||||
senderId = A_USER_ID_1,
|
senderId = A_USER_ID_1,
|
||||||
|
@ -96,7 +96,7 @@ object PollEventsTestData {
|
||||||
)
|
)
|
||||||
|
|
||||||
internal val A_POLL_RESPONSE_EVENT = Event(
|
internal val A_POLL_RESPONSE_EVENT = Event(
|
||||||
type = EventType.POLL_RESPONSE.first(),
|
type = EventType.POLL_RESPONSE.stable,
|
||||||
eventId = AN_EVENT_ID,
|
eventId = AN_EVENT_ID,
|
||||||
originServerTs = 1652435922563,
|
originServerTs = 1652435922563,
|
||||||
senderId = A_USER_ID_1,
|
senderId = A_USER_ID_1,
|
||||||
|
@ -105,7 +105,7 @@ object PollEventsTestData {
|
||||||
)
|
)
|
||||||
|
|
||||||
internal val A_POLL_END_EVENT = Event(
|
internal val A_POLL_END_EVENT = Event(
|
||||||
type = EventType.POLL_END.first(),
|
type = EventType.POLL_END.stable,
|
||||||
eventId = AN_EVENT_ID,
|
eventId = AN_EVENT_ID,
|
||||||
originServerTs = 1652435922563,
|
originServerTs = 1652435922563,
|
||||||
senderId = A_USER_ID_1,
|
senderId = A_USER_ID_1,
|
||||||
|
|
|
@ -69,7 +69,7 @@ class DefaultGetActiveBeaconInfoForUserTaskTest {
|
||||||
result shouldBeEqualTo currentStateEvent
|
result shouldBeEqualTo currentStateEvent
|
||||||
fakeStateEventDataSource.verifyGetStateEvent(
|
fakeStateEventDataSource.verifyGetStateEvent(
|
||||||
roomId = params.roomId,
|
roomId = params.roomId,
|
||||||
eventType = EventType.STATE_ROOM_BEACON_INFO.first(),
|
eventType = EventType.STATE_ROOM_BEACON_INFO.stable,
|
||||||
stateKey = QueryStringValue.Equals(A_USER_ID)
|
stateKey = QueryStringValue.Equals(A_USER_ID)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,7 +75,7 @@ internal class DefaultStartLiveLocationShareTaskTest {
|
||||||
val expectedParams = SendStateTask.Params(
|
val expectedParams = SendStateTask.Params(
|
||||||
roomId = params.roomId,
|
roomId = params.roomId,
|
||||||
stateKey = A_USER_ID,
|
stateKey = A_USER_ID,
|
||||||
eventType = EventType.STATE_ROOM_BEACON_INFO.first(),
|
eventType = EventType.STATE_ROOM_BEACON_INFO.stable,
|
||||||
body = expectedBeaconContent
|
body = expectedBeaconContent
|
||||||
)
|
)
|
||||||
fakeSendStateTask.verifyExecuteRetry(
|
fakeSendStateTask.verifyExecuteRetry(
|
||||||
|
|
|
@ -79,7 +79,7 @@ class DefaultStopLiveLocationShareTaskTest {
|
||||||
val expectedSendParams = SendStateTask.Params(
|
val expectedSendParams = SendStateTask.Params(
|
||||||
roomId = params.roomId,
|
roomId = params.roomId,
|
||||||
stateKey = A_USER_ID,
|
stateKey = A_USER_ID,
|
||||||
eventType = EventType.STATE_ROOM_BEACON_INFO.first(),
|
eventType = EventType.STATE_ROOM_BEACON_INFO.stable,
|
||||||
body = expectedBeaconContent
|
body = expectedBeaconContent
|
||||||
)
|
)
|
||||||
fakeSendStateTask.verifyExecuteRetry(
|
fakeSendStateTask.verifyExecuteRetry(
|
||||||
|
|
|
@ -79,7 +79,7 @@ class LiveLocationShareRedactionEventProcessorTest {
|
||||||
@Test
|
@Test
|
||||||
fun `given a redacted live location share event when processing it then related summaries are deleted from database`() = runTest {
|
fun `given a redacted live location share event when processing it then related summaries are deleted from database`() = runTest {
|
||||||
val event = Event(eventId = AN_EVENT_ID, redacts = A_REDACTED_EVENT_ID)
|
val event = Event(eventId = AN_EVENT_ID, redacts = A_REDACTED_EVENT_ID)
|
||||||
val redactedEventEntity = EventEntity(eventId = A_REDACTED_EVENT_ID, type = EventType.STATE_ROOM_BEACON_INFO.first())
|
val redactedEventEntity = EventEntity(eventId = A_REDACTED_EVENT_ID, type = EventType.STATE_ROOM_BEACON_INFO.stable)
|
||||||
fakeRealm.givenWhere<EventEntity>()
|
fakeRealm.givenWhere<EventEntity>()
|
||||||
.givenEqualTo(EventEntityFields.EVENT_ID, A_REDACTED_EVENT_ID)
|
.givenEqualTo(EventEntityFields.EVENT_ID, A_REDACTED_EVENT_ID)
|
||||||
.givenFindFirst(redactedEventEntity)
|
.givenFindFirst(redactedEventEntity)
|
||||||
|
|
|
@ -19,7 +19,6 @@ package im.vector.app.core.extensions
|
||||||
import im.vector.app.features.voicebroadcast.VoiceBroadcastConstants
|
import im.vector.app.features.voicebroadcast.VoiceBroadcastConstants
|
||||||
import im.vector.app.features.voicebroadcast.model.MessageVoiceBroadcastInfoContent
|
import im.vector.app.features.voicebroadcast.model.MessageVoiceBroadcastInfoContent
|
||||||
import org.matrix.android.sdk.api.session.events.model.EventType
|
import org.matrix.android.sdk.api.session.events.model.EventType
|
||||||
import org.matrix.android.sdk.api.session.events.model.toContent
|
|
||||||
import org.matrix.android.sdk.api.session.events.model.toModel
|
import org.matrix.android.sdk.api.session.events.model.toModel
|
||||||
import org.matrix.android.sdk.api.session.room.model.message.MessageContent
|
import org.matrix.android.sdk.api.session.room.model.message.MessageContent
|
||||||
import org.matrix.android.sdk.api.session.room.send.SendState
|
import org.matrix.android.sdk.api.session.room.send.SendState
|
||||||
|
@ -28,7 +27,7 @@ import org.matrix.android.sdk.api.session.room.timeline.getLastMessageContent
|
||||||
|
|
||||||
fun TimelineEvent.canReact(): Boolean {
|
fun TimelineEvent.canReact(): Boolean {
|
||||||
// Only event of type EventType.MESSAGE, EventType.STICKER and EventType.POLL_START are supported for the moment
|
// Only event of type EventType.MESSAGE, EventType.STICKER and EventType.POLL_START are supported for the moment
|
||||||
return root.getClearType() in listOf(EventType.MESSAGE, EventType.STICKER) + EventType.POLL_START &&
|
return root.getClearType() in listOf(EventType.MESSAGE, EventType.STICKER) + EventType.POLL_START.values &&
|
||||||
root.sendState == SendState.SYNCED &&
|
root.sendState == SendState.SYNCED &&
|
||||||
!root.isRedacted()
|
!root.isRedacted()
|
||||||
}
|
}
|
||||||
|
@ -41,7 +40,7 @@ fun TimelineEvent.getVectorLastMessageContent(): MessageContent? {
|
||||||
// Iterate on event types which are not part of the matrix sdk, otherwise fallback to the sdk method
|
// Iterate on event types which are not part of the matrix sdk, otherwise fallback to the sdk method
|
||||||
return when (root.getClearType()) {
|
return when (root.getClearType()) {
|
||||||
VoiceBroadcastConstants.STATE_ROOM_VOICE_BROADCAST_INFO -> {
|
VoiceBroadcastConstants.STATE_ROOM_VOICE_BROADCAST_INFO -> {
|
||||||
(annotations?.editSummary?.latestEdit?.getClearContent()?.toModel<MessageContent>().toContent().toModel<MessageVoiceBroadcastInfoContent>()
|
(annotations?.editSummary?.latestEdit?.getClearContent()?.toModel<MessageVoiceBroadcastInfoContent>()
|
||||||
?: root.getClearContent().toModel<MessageVoiceBroadcastInfoContent>())
|
?: root.getClearContent().toModel<MessageVoiceBroadcastInfoContent>())
|
||||||
}
|
}
|
||||||
else -> getLastMessageContent()
|
else -> getLastMessageContent()
|
||||||
|
|
|
@ -1774,7 +1774,7 @@ class TimelineFragment :
|
||||||
timelineViewModel.handle(RoomDetailAction.UpdateQuickReactAction(action.eventId, action.clickedOn, action.add))
|
timelineViewModel.handle(RoomDetailAction.UpdateQuickReactAction(action.eventId, action.clickedOn, action.add))
|
||||||
}
|
}
|
||||||
is EventSharedAction.Edit -> {
|
is EventSharedAction.Edit -> {
|
||||||
if (action.eventType in EventType.POLL_START) {
|
if (action.eventType in EventType.POLL_START.values) {
|
||||||
navigator.openCreatePoll(requireContext(), timelineArgs.roomId, action.eventId, PollMode.EDIT)
|
navigator.openCreatePoll(requireContext(), timelineArgs.roomId, action.eventId, PollMode.EDIT)
|
||||||
} else if (withState(messageComposerViewModel) { it.isVoiceMessageIdle }) {
|
} else if (withState(messageComposerViewModel) { it.isVoiceMessageIdle }) {
|
||||||
messageComposerViewModel.handle(MessageComposerAction.EnterEditMode(action.eventId))
|
messageComposerViewModel.handle(MessageComposerAction.EnterEditMode(action.eventId))
|
||||||
|
|
|
@ -33,8 +33,8 @@ class CheckIfCanRedactEventUseCase @Inject constructor(
|
||||||
EventType.STICKER,
|
EventType.STICKER,
|
||||||
VoiceBroadcastConstants.STATE_ROOM_VOICE_BROADCAST_INFO,
|
VoiceBroadcastConstants.STATE_ROOM_VOICE_BROADCAST_INFO,
|
||||||
) +
|
) +
|
||||||
EventType.POLL_START +
|
EventType.POLL_START.values +
|
||||||
EventType.STATE_ROOM_BEACON_INFO
|
EventType.STATE_ROOM_BEACON_INFO.values
|
||||||
|
|
||||||
return event.root.getClearType() in canRedactEventTypes &&
|
return event.root.getClearType() in canRedactEventTypes &&
|
||||||
// Message sent by the current user can always be redacted, else check permission for messages sent by other users
|
// Message sent by the current user can always be redacted, else check permission for messages sent by other users
|
||||||
|
|
|
@ -26,7 +26,7 @@ class CheckIfCanReplyEventUseCase @Inject constructor() {
|
||||||
|
|
||||||
fun execute(event: TimelineEvent, messageContent: MessageContent?, actionPermissions: ActionPermissions): Boolean {
|
fun execute(event: TimelineEvent, messageContent: MessageContent?, actionPermissions: ActionPermissions): Boolean {
|
||||||
// Only EventType.MESSAGE, EventType.POLL_START and EventType.STATE_ROOM_BEACON_INFO event types are supported for the moment
|
// Only EventType.MESSAGE, EventType.POLL_START and EventType.STATE_ROOM_BEACON_INFO event types are supported for the moment
|
||||||
if (event.root.getClearType() !in EventType.STATE_ROOM_BEACON_INFO + EventType.POLL_START + EventType.MESSAGE) return false
|
if (event.root.getClearType() !in EventType.STATE_ROOM_BEACON_INFO.values + EventType.POLL_START.values + EventType.MESSAGE) return false
|
||||||
if (!actionPermissions.canSendMessage) return false
|
if (!actionPermissions.canSendMessage) return false
|
||||||
return when (messageContent?.msgType) {
|
return when (messageContent?.msgType) {
|
||||||
MessageType.MSGTYPE_TEXT,
|
MessageType.MSGTYPE_TEXT,
|
||||||
|
|
|
@ -215,7 +215,7 @@ class MessageActionsViewModel @AssistedInject constructor(
|
||||||
EventType.CALL_ANSWER -> {
|
EventType.CALL_ANSWER -> {
|
||||||
noticeEventFormatter.format(timelineEvent, room?.roomSummary()?.isDirect.orFalse())
|
noticeEventFormatter.format(timelineEvent, room?.roomSummary()?.isDirect.orFalse())
|
||||||
}
|
}
|
||||||
in EventType.POLL_START -> {
|
in EventType.POLL_START.values -> {
|
||||||
timelineEvent.root.getClearContent().toModel<MessagePollContent>(catchError = true)
|
timelineEvent.root.getClearContent().toModel<MessagePollContent>(catchError = true)
|
||||||
?.getBestPollCreationInfo()?.question?.getBestQuestion() ?: ""
|
?.getBestPollCreationInfo()?.question?.getBestQuestion() ?: ""
|
||||||
}
|
}
|
||||||
|
@ -383,7 +383,7 @@ class MessageActionsViewModel @AssistedInject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (canRedact(timelineEvent, actionPermissions)) {
|
if (canRedact(timelineEvent, actionPermissions)) {
|
||||||
if (timelineEvent.root.getClearType() in EventType.POLL_START) {
|
if (timelineEvent.root.getClearType() in EventType.POLL_START.values) {
|
||||||
add(
|
add(
|
||||||
EventSharedAction.Redact(
|
EventSharedAction.Redact(
|
||||||
eventId,
|
eventId,
|
||||||
|
@ -530,13 +530,13 @@ class MessageActionsViewModel @AssistedInject constructor(
|
||||||
|
|
||||||
private fun canViewReactions(event: TimelineEvent): Boolean {
|
private fun canViewReactions(event: TimelineEvent): Boolean {
|
||||||
// Only event of type EventType.MESSAGE, EventType.STICKER and EventType.POLL_START are supported for the moment
|
// Only event of type EventType.MESSAGE, EventType.STICKER and EventType.POLL_START are supported for the moment
|
||||||
if (event.root.getClearType() !in listOf(EventType.MESSAGE, EventType.STICKER) + EventType.POLL_START) return false
|
if (event.root.getClearType() !in listOf(EventType.MESSAGE, EventType.STICKER) + EventType.POLL_START.values) return false
|
||||||
return event.annotations?.reactionsSummary?.isNotEmpty() ?: false
|
return event.annotations?.reactionsSummary?.isNotEmpty() ?: false
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun canEdit(event: TimelineEvent, myUserId: String, actionPermissions: ActionPermissions): Boolean {
|
private fun canEdit(event: TimelineEvent, myUserId: String, actionPermissions: ActionPermissions): Boolean {
|
||||||
// Only event of type EventType.MESSAGE and EventType.POLL_START are supported for the moment
|
// Only event of type EventType.MESSAGE and EventType.POLL_START are supported for the moment
|
||||||
if (event.root.getClearType() !in listOf(EventType.MESSAGE) + EventType.POLL_START) return false
|
if (event.root.getClearType() !in listOf(EventType.MESSAGE) + EventType.POLL_START.values) return false
|
||||||
if (!actionPermissions.canSendMessage) return false
|
if (!actionPermissions.canSendMessage) return false
|
||||||
// TODO if user is admin or moderator
|
// TODO if user is admin or moderator
|
||||||
val messageContent = event.root.getClearContent().toModel<MessageContent>()
|
val messageContent = event.root.getClearContent().toModel<MessageContent>()
|
||||||
|
@ -582,14 +582,14 @@ class MessageActionsViewModel @AssistedInject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun canEndPoll(event: TimelineEvent, actionPermissions: ActionPermissions): Boolean {
|
private fun canEndPoll(event: TimelineEvent, actionPermissions: ActionPermissions): Boolean {
|
||||||
return event.root.getClearType() in EventType.POLL_START &&
|
return event.root.getClearType() in EventType.POLL_START.values &&
|
||||||
canRedact(event, actionPermissions) &&
|
canRedact(event, actionPermissions) &&
|
||||||
event.annotations?.pollResponseSummary?.closedTime == null
|
event.annotations?.pollResponseSummary?.closedTime == null
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun canEditPoll(event: TimelineEvent): Boolean {
|
private fun canEditPoll(event: TimelineEvent): Boolean {
|
||||||
return event.root.getClearType() in EventType.POLL_START &&
|
return event.root.getClearType() in EventType.POLL_START.values &&
|
||||||
event.annotations?.pollResponseSummary?.closedTime == null &&
|
event.annotations?.pollResponseSummary?.closedTime == null &&
|
||||||
event.annotations?.pollResponseSummary?.aggregatedContent?.totalVotes ?: 0 == 0
|
(event.annotations?.pollResponseSummary?.aggregatedContent?.totalVotes ?: 0) == 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,7 @@ import im.vector.app.features.home.room.detail.timeline.helper.MessageInformatio
|
||||||
import im.vector.app.features.home.room.detail.timeline.helper.MessageItemAttributesFactory
|
import im.vector.app.features.home.room.detail.timeline.helper.MessageItemAttributesFactory
|
||||||
import im.vector.app.features.home.room.detail.timeline.helper.TimelineMediaSizeProvider
|
import im.vector.app.features.home.room.detail.timeline.helper.TimelineMediaSizeProvider
|
||||||
import im.vector.app.features.home.room.detail.timeline.item.AbsMessageItem
|
import im.vector.app.features.home.room.detail.timeline.item.AbsMessageItem
|
||||||
|
import im.vector.app.features.home.room.detail.timeline.item.BaseEventItem
|
||||||
import im.vector.app.features.home.room.detail.timeline.item.MessageAudioItem
|
import im.vector.app.features.home.room.detail.timeline.item.MessageAudioItem
|
||||||
import im.vector.app.features.home.room.detail.timeline.item.MessageAudioItem_
|
import im.vector.app.features.home.room.detail.timeline.item.MessageAudioItem_
|
||||||
import im.vector.app.features.home.room.detail.timeline.item.MessageFileItem
|
import im.vector.app.features.home.room.detail.timeline.item.MessageFileItem
|
||||||
|
@ -324,9 +325,11 @@ class MessageItemFactory @Inject constructor(
|
||||||
informationData: MessageInformationData,
|
informationData: MessageInformationData,
|
||||||
highlight: Boolean,
|
highlight: Boolean,
|
||||||
attributes: AbsMessageItem.Attributes
|
attributes: AbsMessageItem.Attributes
|
||||||
): MessageVoiceItem? {
|
): BaseEventItem<*>? {
|
||||||
// Do not display voice broadcast messages
|
// Do not display voice broadcast messages
|
||||||
if (params.event.root.asMessageAudioEvent().isVoiceBroadcast()) return null
|
if (params.event.root.asMessageAudioEvent().isVoiceBroadcast()) {
|
||||||
|
return noticeItemFactory.create(params)
|
||||||
|
}
|
||||||
|
|
||||||
val fileUrl = getAudioFileUrl(messageContent, informationData)
|
val fileUrl = getAudioFileUrl(messageContent, informationData)
|
||||||
val playbackControlButtonClickListener = createOnPlaybackButtonClickListener(messageContent, informationData, params)
|
val playbackControlButtonClickListener = createOnPlaybackButtonClickListener(messageContent, informationData, params)
|
||||||
|
|
|
@ -88,7 +88,7 @@ class TimelineItemFactory @Inject constructor(
|
||||||
EventType.STATE_ROOM_ENCRYPTION -> encryptionItemFactory.create(params)
|
EventType.STATE_ROOM_ENCRYPTION -> encryptionItemFactory.create(params)
|
||||||
// State room create
|
// State room create
|
||||||
EventType.STATE_ROOM_CREATE -> roomCreateItemFactory.create(params)
|
EventType.STATE_ROOM_CREATE -> roomCreateItemFactory.create(params)
|
||||||
in EventType.STATE_ROOM_BEACON_INFO -> messageItemFactory.create(params)
|
in EventType.STATE_ROOM_BEACON_INFO.values -> messageItemFactory.create(params)
|
||||||
VoiceBroadcastConstants.STATE_ROOM_VOICE_BROADCAST_INFO -> messageItemFactory.create(params)
|
VoiceBroadcastConstants.STATE_ROOM_VOICE_BROADCAST_INFO -> messageItemFactory.create(params)
|
||||||
// Unhandled state event types
|
// Unhandled state event types
|
||||||
else -> {
|
else -> {
|
||||||
|
@ -101,7 +101,7 @@ class TimelineItemFactory @Inject constructor(
|
||||||
when (event.root.getClearType()) {
|
when (event.root.getClearType()) {
|
||||||
// Message itemsX
|
// Message itemsX
|
||||||
EventType.STICKER,
|
EventType.STICKER,
|
||||||
in EventType.POLL_START,
|
in EventType.POLL_START.values,
|
||||||
EventType.MESSAGE -> messageItemFactory.create(params)
|
EventType.MESSAGE -> messageItemFactory.create(params)
|
||||||
EventType.REDACTION,
|
EventType.REDACTION,
|
||||||
EventType.KEY_VERIFICATION_ACCEPT,
|
EventType.KEY_VERIFICATION_ACCEPT,
|
||||||
|
@ -114,9 +114,9 @@ class TimelineItemFactory @Inject constructor(
|
||||||
EventType.CALL_SELECT_ANSWER,
|
EventType.CALL_SELECT_ANSWER,
|
||||||
EventType.CALL_NEGOTIATE,
|
EventType.CALL_NEGOTIATE,
|
||||||
EventType.REACTION,
|
EventType.REACTION,
|
||||||
in EventType.POLL_RESPONSE,
|
in EventType.POLL_RESPONSE.values,
|
||||||
in EventType.POLL_END -> noticeItemFactory.create(params)
|
in EventType.POLL_END.values -> noticeItemFactory.create(params)
|
||||||
in EventType.BEACON_LOCATION_DATA -> {
|
in EventType.BEACON_LOCATION_DATA.values -> {
|
||||||
if (event.root.isRedacted()) {
|
if (event.root.isRedacted()) {
|
||||||
messageItemFactory.create(params)
|
messageItemFactory.create(params)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -23,6 +23,7 @@ import im.vector.app.features.home.room.detail.timeline.helper.AvatarSizeProvide
|
||||||
import im.vector.app.features.home.room.detail.timeline.helper.VoiceBroadcastEventsGroup
|
import im.vector.app.features.home.room.detail.timeline.helper.VoiceBroadcastEventsGroup
|
||||||
import im.vector.app.features.home.room.detail.timeline.item.AbsMessageItem
|
import im.vector.app.features.home.room.detail.timeline.item.AbsMessageItem
|
||||||
import im.vector.app.features.home.room.detail.timeline.item.AbsMessageVoiceBroadcastItem
|
import im.vector.app.features.home.room.detail.timeline.item.AbsMessageVoiceBroadcastItem
|
||||||
|
import im.vector.app.features.home.room.detail.timeline.item.BaseEventItem
|
||||||
import im.vector.app.features.home.room.detail.timeline.item.MessageVoiceBroadcastListeningItem
|
import im.vector.app.features.home.room.detail.timeline.item.MessageVoiceBroadcastListeningItem
|
||||||
import im.vector.app.features.home.room.detail.timeline.item.MessageVoiceBroadcastListeningItem_
|
import im.vector.app.features.home.room.detail.timeline.item.MessageVoiceBroadcastListeningItem_
|
||||||
import im.vector.app.features.home.room.detail.timeline.item.MessageVoiceBroadcastRecordingItem
|
import im.vector.app.features.home.room.detail.timeline.item.MessageVoiceBroadcastRecordingItem
|
||||||
|
@ -47,6 +48,7 @@ class VoiceBroadcastItemFactory @Inject constructor(
|
||||||
private val voiceBroadcastRecorder: VoiceBroadcastRecorder?,
|
private val voiceBroadcastRecorder: VoiceBroadcastRecorder?,
|
||||||
private val voiceBroadcastPlayer: VoiceBroadcastPlayer,
|
private val voiceBroadcastPlayer: VoiceBroadcastPlayer,
|
||||||
private val playbackTracker: AudioMessagePlaybackTracker,
|
private val playbackTracker: AudioMessagePlaybackTracker,
|
||||||
|
private val noticeItemFactory: NoticeItemFactory,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
fun create(
|
fun create(
|
||||||
|
@ -54,9 +56,11 @@ class VoiceBroadcastItemFactory @Inject constructor(
|
||||||
messageContent: MessageVoiceBroadcastInfoContent,
|
messageContent: MessageVoiceBroadcastInfoContent,
|
||||||
highlight: Boolean,
|
highlight: Boolean,
|
||||||
attributes: AbsMessageItem.Attributes,
|
attributes: AbsMessageItem.Attributes,
|
||||||
): AbsMessageVoiceBroadcastItem<*>? {
|
): BaseEventItem<*>? {
|
||||||
// Only display item of the initial event with updated data
|
// Only display item of the initial event with updated data
|
||||||
if (messageContent.voiceBroadcastState != VoiceBroadcastState.STARTED) return null
|
if (messageContent.voiceBroadcastState != VoiceBroadcastState.STARTED) {
|
||||||
|
return noticeItemFactory.create(params)
|
||||||
|
}
|
||||||
|
|
||||||
val voiceBroadcastEventsGroup = params.eventsGroup?.let { VoiceBroadcastEventsGroup(it) } ?: return null
|
val voiceBroadcastEventsGroup = params.eventsGroup?.let { VoiceBroadcastEventsGroup(it) } ?: return null
|
||||||
val voiceBroadcastEvent = voiceBroadcastEventsGroup.getLastDisplayableEvent().root.asVoiceBroadcastEvent() ?: return null
|
val voiceBroadcastEvent = voiceBroadcastEventsGroup.getLastDisplayableEvent().root.asVoiceBroadcastEvent() ?: return null
|
||||||
|
|
|
@ -122,17 +122,17 @@ class DisplayableEventFormatter @Inject constructor(
|
||||||
EventType.CALL_CANDIDATES -> {
|
EventType.CALL_CANDIDATES -> {
|
||||||
span { }
|
span { }
|
||||||
}
|
}
|
||||||
in EventType.POLL_START -> {
|
in EventType.POLL_START.values -> {
|
||||||
timelineEvent.root.getClearContent().toModel<MessagePollContent>(catchError = true)?.getBestPollCreationInfo()?.question?.getBestQuestion()
|
timelineEvent.root.getClearContent().toModel<MessagePollContent>(catchError = true)?.getBestPollCreationInfo()?.question?.getBestQuestion()
|
||||||
?: stringProvider.getString(R.string.sent_a_poll)
|
?: stringProvider.getString(R.string.sent_a_poll)
|
||||||
}
|
}
|
||||||
in EventType.POLL_RESPONSE -> {
|
in EventType.POLL_RESPONSE.values -> {
|
||||||
stringProvider.getString(R.string.poll_response_room_list_preview)
|
stringProvider.getString(R.string.poll_response_room_list_preview)
|
||||||
}
|
}
|
||||||
in EventType.POLL_END -> {
|
in EventType.POLL_END.values -> {
|
||||||
stringProvider.getString(R.string.poll_end_room_list_preview)
|
stringProvider.getString(R.string.poll_end_room_list_preview)
|
||||||
}
|
}
|
||||||
in EventType.STATE_ROOM_BEACON_INFO -> {
|
in EventType.STATE_ROOM_BEACON_INFO.values -> {
|
||||||
simpleFormat(senderName, stringProvider.getString(R.string.sent_live_location), appendAuthor)
|
simpleFormat(senderName, stringProvider.getString(R.string.sent_live_location), appendAuthor)
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
|
@ -220,17 +220,17 @@ class DisplayableEventFormatter @Inject constructor(
|
||||||
emojiSpanify.spanify(stringProvider.getString(R.string.sent_a_reaction, it.key))
|
emojiSpanify.spanify(stringProvider.getString(R.string.sent_a_reaction, it.key))
|
||||||
} ?: span { }
|
} ?: span { }
|
||||||
}
|
}
|
||||||
in EventType.POLL_START -> {
|
in EventType.POLL_START.values -> {
|
||||||
event.getClearContent().toModel<MessagePollContent>(catchError = true)?.pollCreationInfo?.question?.question
|
event.getClearContent().toModel<MessagePollContent>(catchError = true)?.pollCreationInfo?.question?.question
|
||||||
?: stringProvider.getString(R.string.sent_a_poll)
|
?: stringProvider.getString(R.string.sent_a_poll)
|
||||||
}
|
}
|
||||||
in EventType.POLL_RESPONSE -> {
|
in EventType.POLL_RESPONSE.values -> {
|
||||||
stringProvider.getString(R.string.poll_response_room_list_preview)
|
stringProvider.getString(R.string.poll_response_room_list_preview)
|
||||||
}
|
}
|
||||||
in EventType.POLL_END -> {
|
in EventType.POLL_END.values -> {
|
||||||
stringProvider.getString(R.string.poll_end_room_list_preview)
|
stringProvider.getString(R.string.poll_end_room_list_preview)
|
||||||
}
|
}
|
||||||
in EventType.STATE_ROOM_BEACON_INFO -> {
|
in EventType.STATE_ROOM_BEACON_INFO.values -> {
|
||||||
stringProvider.getString(R.string.sent_live_location)
|
stringProvider.getString(R.string.sent_live_location)
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
|
|
|
@ -21,6 +21,7 @@ import im.vector.app.R
|
||||||
import im.vector.app.core.resources.StringProvider
|
import im.vector.app.core.resources.StringProvider
|
||||||
import im.vector.app.features.roomprofile.permissions.RoleFormatter
|
import im.vector.app.features.roomprofile.permissions.RoleFormatter
|
||||||
import im.vector.app.features.settings.VectorPreferences
|
import im.vector.app.features.settings.VectorPreferences
|
||||||
|
import im.vector.app.features.voicebroadcast.VoiceBroadcastConstants
|
||||||
import org.matrix.android.sdk.api.crypto.MXCRYPTO_ALGORITHM_MEGOLM
|
import org.matrix.android.sdk.api.crypto.MXCRYPTO_ALGORITHM_MEGOLM
|
||||||
import org.matrix.android.sdk.api.extensions.appendNl
|
import org.matrix.android.sdk.api.extensions.appendNl
|
||||||
import org.matrix.android.sdk.api.extensions.orFalse
|
import org.matrix.android.sdk.api.extensions.orFalse
|
||||||
|
@ -106,9 +107,10 @@ class NoticeEventFormatter @Inject constructor(
|
||||||
EventType.STATE_SPACE_PARENT,
|
EventType.STATE_SPACE_PARENT,
|
||||||
EventType.REDACTION,
|
EventType.REDACTION,
|
||||||
EventType.STICKER,
|
EventType.STICKER,
|
||||||
in EventType.POLL_RESPONSE,
|
in EventType.POLL_RESPONSE.values,
|
||||||
in EventType.POLL_END,
|
in EventType.POLL_END.values,
|
||||||
in EventType.BEACON_LOCATION_DATA -> formatDebug(timelineEvent.root)
|
in EventType.BEACON_LOCATION_DATA.values,
|
||||||
|
VoiceBroadcastConstants.STATE_ROOM_VOICE_BROADCAST_INFO -> formatDebug(timelineEvent.root)
|
||||||
else -> {
|
else -> {
|
||||||
Timber.v("Type $type not handled by this formatter")
|
Timber.v("Type $type not handled by this formatter")
|
||||||
null
|
null
|
||||||
|
|
|
@ -54,9 +54,9 @@ object TimelineDisplayableEvents {
|
||||||
EventType.KEY_VERIFICATION_CANCEL,
|
EventType.KEY_VERIFICATION_CANCEL,
|
||||||
VoiceBroadcastConstants.STATE_ROOM_VOICE_BROADCAST_INFO,
|
VoiceBroadcastConstants.STATE_ROOM_VOICE_BROADCAST_INFO,
|
||||||
) +
|
) +
|
||||||
EventType.POLL_START +
|
EventType.POLL_START.values +
|
||||||
EventType.STATE_ROOM_BEACON_INFO +
|
EventType.STATE_ROOM_BEACON_INFO.values +
|
||||||
EventType.BEACON_LOCATION_DATA
|
EventType.BEACON_LOCATION_DATA.values
|
||||||
}
|
}
|
||||||
|
|
||||||
fun TimelineEvent.isRoomConfiguration(roomCreatorUserId: String?): Boolean {
|
fun TimelineEvent.isRoomConfiguration(roomCreatorUserId: String?): Boolean {
|
||||||
|
|
|
@ -18,6 +18,11 @@ package im.vector.app.features.home.room.detail.timeline.helper
|
||||||
|
|
||||||
import im.vector.app.core.extensions.localDateTime
|
import im.vector.app.core.extensions.localDateTime
|
||||||
import im.vector.app.core.resources.UserPreferencesProvider
|
import im.vector.app.core.resources.UserPreferencesProvider
|
||||||
|
import im.vector.app.features.voicebroadcast.VoiceBroadcastConstants
|
||||||
|
import im.vector.app.features.voicebroadcast.isVoiceBroadcast
|
||||||
|
import im.vector.app.features.voicebroadcast.model.VoiceBroadcastState
|
||||||
|
import im.vector.app.features.voicebroadcast.model.asVoiceBroadcastEvent
|
||||||
|
import org.matrix.android.sdk.api.extensions.orFalse
|
||||||
import org.matrix.android.sdk.api.session.events.model.Event
|
import org.matrix.android.sdk.api.session.events.model.Event
|
||||||
import org.matrix.android.sdk.api.session.events.model.EventType
|
import org.matrix.android.sdk.api.session.events.model.EventType
|
||||||
import org.matrix.android.sdk.api.session.events.model.RelationType
|
import org.matrix.android.sdk.api.session.events.model.RelationType
|
||||||
|
@ -28,6 +33,7 @@ import org.matrix.android.sdk.api.session.events.model.toModel
|
||||||
import org.matrix.android.sdk.api.session.room.model.Membership
|
import org.matrix.android.sdk.api.session.room.model.Membership
|
||||||
import org.matrix.android.sdk.api.session.room.model.RoomMemberContent
|
import org.matrix.android.sdk.api.session.room.model.RoomMemberContent
|
||||||
import org.matrix.android.sdk.api.session.room.model.localecho.RoomLocalEcho
|
import org.matrix.android.sdk.api.session.room.model.localecho.RoomLocalEcho
|
||||||
|
import org.matrix.android.sdk.api.session.room.model.message.asMessageAudioEvent
|
||||||
import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
|
import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
@ -242,10 +248,19 @@ class TimelineEventVisibilityHelper @Inject constructor(
|
||||||
} else root.eventId != rootThreadEventId
|
} else root.eventId != rootThreadEventId
|
||||||
}
|
}
|
||||||
|
|
||||||
if (root.getClearType() in EventType.BEACON_LOCATION_DATA) {
|
if (root.getClearType() in EventType.BEACON_LOCATION_DATA.values) {
|
||||||
return !root.isRedacted()
|
return !root.isRedacted()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (root.getClearType() == VoiceBroadcastConstants.STATE_ROOM_VOICE_BROADCAST_INFO &&
|
||||||
|
root.asVoiceBroadcastEvent()?.content?.voiceBroadcastState != VoiceBroadcastState.STARTED) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
if (root.asMessageAudioEvent()?.isVoiceBroadcast().orFalse()) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,8 +47,10 @@ class TimelineMessageLayoutFactory @Inject constructor(
|
||||||
private val EVENT_TYPES_WITH_BUBBLE_LAYOUT = setOf(
|
private val EVENT_TYPES_WITH_BUBBLE_LAYOUT = setOf(
|
||||||
EventType.MESSAGE,
|
EventType.MESSAGE,
|
||||||
EventType.ENCRYPTED,
|
EventType.ENCRYPTED,
|
||||||
EventType.STICKER
|
EventType.STICKER,
|
||||||
) + EventType.POLL_START + EventType.STATE_ROOM_BEACON_INFO
|
) +
|
||||||
|
EventType.POLL_START.values +
|
||||||
|
EventType.STATE_ROOM_BEACON_INFO.values
|
||||||
|
|
||||||
// Can't be rendered in bubbles, so get back to default layout
|
// Can't be rendered in bubbles, so get back to default layout
|
||||||
private val MSG_TYPES_WITHOUT_BUBBLE_LAYOUT = setOf(
|
private val MSG_TYPES_WITHOUT_BUBBLE_LAYOUT = setOf(
|
||||||
|
|
|
@ -83,7 +83,7 @@ class LocationSharingViewModel @AssistedInject constructor(
|
||||||
.distinctUntilChanged()
|
.distinctUntilChanged()
|
||||||
.setOnEach {
|
.setOnEach {
|
||||||
val powerLevelsHelper = PowerLevelsHelper(it)
|
val powerLevelsHelper = PowerLevelsHelper(it)
|
||||||
val canShareLiveLocation = EventType.STATE_ROOM_BEACON_INFO
|
val canShareLiveLocation = EventType.STATE_ROOM_BEACON_INFO.values
|
||||||
.all { beaconInfoType ->
|
.all { beaconInfoType ->
|
||||||
powerLevelsHelper.isUserAllowedToSend(session.myUserId, true, beaconInfoType)
|
powerLevelsHelper.isUserAllowedToSend(session.myUserId, true, beaconInfoType)
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,7 +66,7 @@ class NotifiableEventResolver @Inject constructor(
|
||||||
) {
|
) {
|
||||||
|
|
||||||
private val nonEncryptedNotifiableEventTypes: List<String> =
|
private val nonEncryptedNotifiableEventTypes: List<String> =
|
||||||
listOf(EventType.MESSAGE) + EventType.POLL_START + EventType.STATE_ROOM_BEACON_INFO
|
listOf(EventType.MESSAGE) + EventType.POLL_START.values + EventType.STATE_ROOM_BEACON_INFO.values
|
||||||
|
|
||||||
suspend fun resolveEvent(event: Event, session: Session, isNoisy: Boolean): NotifiableEvent? {
|
suspend fun resolveEvent(event: Event, session: Session, isNoisy: Boolean): NotifiableEvent? {
|
||||||
val roomID = event.roomId ?: return null
|
val roomID = event.roomId ?: return null
|
||||||
|
|
|
@ -35,8 +35,13 @@ class CheckIfCanRedactEventUseCaseTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `given an event which can be redacted and owned by user when use case executes then the result is true`() {
|
fun `given an event which can be redacted and owned by user when use case executes then the result is true`() {
|
||||||
val canRedactEventTypes = listOf(EventType.MESSAGE, EventType.STICKER, VoiceBroadcastConstants.STATE_ROOM_VOICE_BROADCAST_INFO) +
|
val canRedactEventTypes = listOf(
|
||||||
EventType.POLL_START + EventType.STATE_ROOM_BEACON_INFO
|
EventType.MESSAGE,
|
||||||
|
EventType.STICKER,
|
||||||
|
VoiceBroadcastConstants.STATE_ROOM_VOICE_BROADCAST_INFO
|
||||||
|
) +
|
||||||
|
EventType.POLL_START.values +
|
||||||
|
EventType.STATE_ROOM_BEACON_INFO.values
|
||||||
|
|
||||||
canRedactEventTypes.forEach { eventType ->
|
canRedactEventTypes.forEach { eventType ->
|
||||||
val event = givenAnEvent(
|
val event = givenAnEvent(
|
||||||
|
|
|
@ -43,7 +43,7 @@ class CheckIfCanReplyEventUseCaseTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `given reply is allowed for the event type when use case is executed then result is true`() {
|
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 + EventType.POLL_START + EventType.MESSAGE
|
val eventTypes = EventType.STATE_ROOM_BEACON_INFO.values + EventType.POLL_START.values + EventType.MESSAGE
|
||||||
|
|
||||||
eventTypes.forEach { eventType ->
|
eventTypes.forEach { eventType ->
|
||||||
val event = givenAnEvent(eventType)
|
val event = givenAnEvent(eventType)
|
||||||
|
|
|
@ -63,7 +63,7 @@ object FakeCreatePollViewStates {
|
||||||
)
|
)
|
||||||
|
|
||||||
private val A_POLL_START_EVENT = Event(
|
private val A_POLL_START_EVENT = Event(
|
||||||
type = EventType.POLL_START.first(),
|
type = EventType.POLL_START.stable,
|
||||||
eventId = A_FAKE_EVENT_ID,
|
eventId = A_FAKE_EVENT_ID,
|
||||||
originServerTs = 1652435922563,
|
originServerTs = 1652435922563,
|
||||||
senderId = A_FAKE_USER_ID,
|
senderId = A_FAKE_USER_ID,
|
||||||
|
@ -80,8 +80,8 @@ object FakeCreatePollViewStates {
|
||||||
)
|
)
|
||||||
|
|
||||||
val initialCreatePollViewState = CreatePollViewState(createPollArgs).copy(
|
val initialCreatePollViewState = CreatePollViewState(createPollArgs).copy(
|
||||||
canCreatePoll = false,
|
canCreatePoll = false,
|
||||||
canAddMoreOptions = true
|
canAddMoreOptions = true
|
||||||
)
|
)
|
||||||
|
|
||||||
val pollViewStateWithOnlyQuestion = initialCreatePollViewState.copy(
|
val pollViewStateWithOnlyQuestion = initialCreatePollViewState.copy(
|
||||||
|
|
Loading…
Reference in a new issue