mirror of
https://github.com/element-hq/element-android
synced 2024-11-25 02:45:37 +03:00
Merge pull request #1436 from vector-im/feature/Fix_1430_X_made_no_change
Hide "X made no changes" event by default in timeline (#1430)
This commit is contained in:
commit
617e945afa
9 changed files with 58 additions and 3 deletions
|
@ -6,6 +6,7 @@ Features ✨:
|
||||||
|
|
||||||
Improvements 🙌:
|
Improvements 🙌:
|
||||||
- New wording for notice when current user is the sender
|
- New wording for notice when current user is the sender
|
||||||
|
- Hide "X made no changes" event by default in timeline (#1430)
|
||||||
|
|
||||||
Bugfix 🐛:
|
Bugfix 🐛:
|
||||||
- Switch theme is not fully taken into account without restarting the app
|
- Switch theme is not fully taken into account without restarting the app
|
||||||
|
|
|
@ -162,6 +162,8 @@ data class Event(
|
||||||
*/
|
*/
|
||||||
fun isRedactedBySameUser() = senderId == unsignedData?.redactedEvent?.senderId
|
fun isRedactedBySameUser() = senderId == unsignedData?.redactedEvent?.senderId
|
||||||
|
|
||||||
|
fun resolvedPrevContent(): Content? = prevContent ?: unsignedData?.prevContent
|
||||||
|
|
||||||
override fun equals(other: Any?): Boolean {
|
override fun equals(other: Any?): Boolean {
|
||||||
if (this === other) return true
|
if (this === other) return true
|
||||||
if (javaClass != other?.javaClass) return false
|
if (javaClass != other?.javaClass) return false
|
||||||
|
|
|
@ -32,6 +32,10 @@ data class TimelineSettings(
|
||||||
* A flag to filter redacted events
|
* A flag to filter redacted events
|
||||||
*/
|
*/
|
||||||
val filterRedacted: Boolean = false,
|
val filterRedacted: Boolean = false,
|
||||||
|
/**
|
||||||
|
* A flag to filter useless events, such as membership events without any change
|
||||||
|
*/
|
||||||
|
val filterUseless: Boolean = false,
|
||||||
/**
|
/**
|
||||||
* A flag to filter by types. It should be used with [allowedTypes] field
|
* A flag to filter by types. It should be used with [allowedTypes] field
|
||||||
*/
|
*/
|
||||||
|
@ -44,5 +48,4 @@ data class TimelineSettings(
|
||||||
* If true, will build read receipts for each event.
|
* If true, will build read receipts for each event.
|
||||||
*/
|
*/
|
||||||
val buildReadReceipts: Boolean = true
|
val buildReadReceipts: Boolean = true
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
|
@ -36,8 +36,8 @@ internal object EventMapper {
|
||||||
eventEntity.eventId = event.eventId ?: "$$roomId-${System.currentTimeMillis()}-${event.hashCode()}"
|
eventEntity.eventId = event.eventId ?: "$$roomId-${System.currentTimeMillis()}-${event.hashCode()}"
|
||||||
eventEntity.roomId = event.roomId ?: roomId
|
eventEntity.roomId = event.roomId ?: roomId
|
||||||
eventEntity.content = ContentMapper.map(event.content)
|
eventEntity.content = ContentMapper.map(event.content)
|
||||||
val resolvedPrevContent = event.prevContent ?: event.unsignedData?.prevContent
|
eventEntity.prevContent = ContentMapper.map(event.resolvedPrevContent())
|
||||||
eventEntity.prevContent = ContentMapper.map(resolvedPrevContent)
|
eventEntity.isUseless = IsUselessResolver.isUseless(event)
|
||||||
eventEntity.stateKey = event.stateKey
|
eventEntity.stateKey = event.stateKey
|
||||||
eventEntity.type = event.type
|
eventEntity.type = event.type
|
||||||
eventEntity.sender = event.senderId
|
eventEntity.sender = event.senderId
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020 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.matrix.android.internal.database.mapper
|
||||||
|
|
||||||
|
import im.vector.matrix.android.api.session.events.model.Event
|
||||||
|
import im.vector.matrix.android.api.session.events.model.EventType
|
||||||
|
import im.vector.matrix.android.api.session.events.model.toContent
|
||||||
|
|
||||||
|
internal object IsUselessResolver {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if the event is useless
|
||||||
|
*/
|
||||||
|
fun isUseless(event: Event): Boolean {
|
||||||
|
return when (event.type) {
|
||||||
|
EventType.STATE_ROOM_MEMBER -> {
|
||||||
|
// Call toContent(), to filter out null value
|
||||||
|
event.content != null
|
||||||
|
&& event.content.toContent() == event.resolvedPrevContent()?.toContent()
|
||||||
|
}
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -28,6 +28,7 @@ internal open class EventEntity(@Index var eventId: String = "",
|
||||||
@Index var type: String = "",
|
@Index var type: String = "",
|
||||||
var content: String? = null,
|
var content: String? = null,
|
||||||
var prevContent: String? = null,
|
var prevContent: String? = null,
|
||||||
|
var isUseless: Boolean = false,
|
||||||
@Index var stateKey: String? = null,
|
@Index var stateKey: String? = null,
|
||||||
var originServerTs: Long? = null,
|
var originServerTs: Long? = null,
|
||||||
@Index var sender: String? = null,
|
@Index var sender: String? = null,
|
||||||
|
|
|
@ -775,6 +775,9 @@ internal class DefaultTimeline(
|
||||||
if (settings.filterTypes) {
|
if (settings.filterTypes) {
|
||||||
`in`(TimelineEventEntityFields.ROOT.TYPE, settings.allowedTypes.toTypedArray())
|
`in`(TimelineEventEntityFields.ROOT.TYPE, settings.allowedTypes.toTypedArray())
|
||||||
}
|
}
|
||||||
|
if (settings.filterUseless) {
|
||||||
|
not().equalTo(TimelineEventEntityFields.ROOT.IS_USELESS, true)
|
||||||
|
}
|
||||||
if (settings.filterEdits) {
|
if (settings.filterEdits) {
|
||||||
not().like(TimelineEventEntityFields.ROOT.CONTENT, TimelineEventFilter.Content.EDIT)
|
not().like(TimelineEventEntityFields.ROOT.CONTENT, TimelineEventFilter.Content.EDIT)
|
||||||
not().like(TimelineEventEntityFields.ROOT.CONTENT, TimelineEventFilter.Content.RESPONSE)
|
not().like(TimelineEventEntityFields.ROOT.CONTENT, TimelineEventFilter.Content.RESPONSE)
|
||||||
|
|
|
@ -154,6 +154,11 @@ internal class TimelineHiddenReadReceipts constructor(private val readReceiptsSu
|
||||||
not().`in`("${ReadReceiptsSummaryEntityFields.TIMELINE_EVENT}.${TimelineEventEntityFields.ROOT.TYPE}", settings.allowedTypes.toTypedArray())
|
not().`in`("${ReadReceiptsSummaryEntityFields.TIMELINE_EVENT}.${TimelineEventEntityFields.ROOT.TYPE}", settings.allowedTypes.toTypedArray())
|
||||||
needOr = true
|
needOr = true
|
||||||
}
|
}
|
||||||
|
if (settings.filterUseless) {
|
||||||
|
if (needOr) or()
|
||||||
|
equalTo("${ReadReceiptsSummaryEntityFields.TIMELINE_EVENT}.${TimelineEventEntityFields.ROOT.IS_USELESS}", true)
|
||||||
|
needOr = true
|
||||||
|
}
|
||||||
if (settings.filterEdits) {
|
if (settings.filterEdits) {
|
||||||
if (needOr) or()
|
if (needOr) or()
|
||||||
like("${ReadReceiptsSummaryEntityFields.TIMELINE_EVENT}.${TimelineEventEntityFields.ROOT.CONTENT}", TimelineEventFilter.Content.EDIT)
|
like("${ReadReceiptsSummaryEntityFields.TIMELINE_EVENT}.${TimelineEventEntityFields.ROOT.CONTENT}", TimelineEventFilter.Content.EDIT)
|
||||||
|
|
|
@ -100,12 +100,14 @@ class RoomDetailViewModel @AssistedInject constructor(
|
||||||
TimelineSettings(30,
|
TimelineSettings(30,
|
||||||
filterEdits = false,
|
filterEdits = false,
|
||||||
filterRedacted = userPreferencesProvider.shouldShowRedactedMessages().not(),
|
filterRedacted = userPreferencesProvider.shouldShowRedactedMessages().not(),
|
||||||
|
filterUseless = false,
|
||||||
filterTypes = false,
|
filterTypes = false,
|
||||||
buildReadReceipts = userPreferencesProvider.shouldShowReadReceipts())
|
buildReadReceipts = userPreferencesProvider.shouldShowReadReceipts())
|
||||||
} else {
|
} else {
|
||||||
TimelineSettings(30,
|
TimelineSettings(30,
|
||||||
filterEdits = true,
|
filterEdits = true,
|
||||||
filterRedacted = userPreferencesProvider.shouldShowRedactedMessages().not(),
|
filterRedacted = userPreferencesProvider.shouldShowRedactedMessages().not(),
|
||||||
|
filterUseless = true,
|
||||||
filterTypes = true,
|
filterTypes = true,
|
||||||
allowedTypes = TimelineDisplayableEvents.DISPLAYABLE_TYPES,
|
allowedTypes = TimelineDisplayableEvents.DISPLAYABLE_TYPES,
|
||||||
buildReadReceipts = userPreferencesProvider.shouldShowReadReceipts())
|
buildReadReceipts = userPreferencesProvider.shouldShowReadReceipts())
|
||||||
|
|
Loading…
Reference in a new issue