mirror of
https://github.com/element-hq/element-android
synced 2024-11-28 05:31:21 +03:00
Add hasFailedSending in RoomSummary and a small warning icon on room list
This commit is contained in:
parent
d7558902f7
commit
aa5ae45a0c
10 changed files with 51 additions and 11 deletions
|
@ -53,7 +53,8 @@ data class RoomSummary constructor(
|
|||
val typingUsers: List<SenderInfo>,
|
||||
val inviterId: String? = null,
|
||||
val breadcrumbsIndex: Int = NOT_IN_BREADCRUMBS,
|
||||
val roomEncryptionTrustLevel: RoomEncryptionTrustLevel? = null
|
||||
val roomEncryptionTrustLevel: RoomEncryptionTrustLevel? = null,
|
||||
val hasFailedSending: Boolean = false
|
||||
) {
|
||||
|
||||
val isVersioned: Boolean
|
||||
|
|
|
@ -62,7 +62,8 @@ internal class RoomSummaryMapper @Inject constructor(private val timelineEventMa
|
|||
encryptionEventTs = roomSummaryEntity.encryptionEventTs,
|
||||
breadcrumbsIndex = roomSummaryEntity.breadcrumbsIndex,
|
||||
roomEncryptionTrustLevel = roomSummaryEntity.roomEncryptionTrustLevel,
|
||||
inviterId = roomSummaryEntity.inviterId
|
||||
inviterId = roomSummaryEntity.inviterId,
|
||||
hasFailedSending = roomSummaryEntity.hasFailedSending
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,7 +51,8 @@ internal open class RoomSummaryEntity(
|
|||
var isEncrypted: Boolean = false,
|
||||
var encryptionEventTs: Long? = 0,
|
||||
var roomEncryptionTrustLevelStr: String? = null,
|
||||
var inviterId: String? = null
|
||||
var inviterId: String? = null,
|
||||
var hasFailedSending: Boolean = false
|
||||
) : RealmObject() {
|
||||
|
||||
private var membershipStr: String = Membership.NONE.name
|
||||
|
|
|
@ -93,9 +93,12 @@ internal fun TimelineEventEntity.Companion.findAllInRoomWithSendStates(realm: Re
|
|||
roomId: String,
|
||||
sendStates: List<SendState>)
|
||||
: RealmResults<TimelineEventEntity> {
|
||||
val sendStatesStr = sendStates.map { it.name }.toTypedArray()
|
||||
return realm.where<TimelineEventEntity>()
|
||||
.equalTo(TimelineEventEntityFields.ROOM_ID, roomId)
|
||||
.`in`(TimelineEventEntityFields.ROOT.SEND_STATE_STR, sendStatesStr)
|
||||
return whereRoomId(realm, roomId)
|
||||
.filterSendStates(sendStates)
|
||||
.findAll()
|
||||
}
|
||||
|
||||
internal fun RealmQuery<TimelineEventEntity>.filterSendStates(sendStates: List<SendState>): RealmQuery<TimelineEventEntity> {
|
||||
val sendStatesStr = sendStates.map { it.name }.toTypedArray()
|
||||
return `in`(TimelineEventEntityFields.ROOT.SEND_STATE_STR, sendStatesStr)
|
||||
}
|
||||
|
|
|
@ -82,7 +82,7 @@ internal class LocalEchoRepository @Inject constructor(@SessionDatabase private
|
|||
realm.insert(eventInsertEntity)
|
||||
val roomEntity = RoomEntity.where(realm, roomId = roomId).findFirst() ?: return@writeAsync
|
||||
roomEntity.sendingTimelineEvents.add(0, timelineEventEntity)
|
||||
roomSummaryUpdater.update(realm, roomId)
|
||||
roomSummaryUpdater.updateSendingInformation(realm, roomId)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -96,6 +96,7 @@ internal class LocalEchoRepository @Inject constructor(@SessionDatabase private
|
|||
} else {
|
||||
sendingEventEntity.sendState = sendState
|
||||
}
|
||||
roomSummaryUpdater.update(realm, sendingEventEntity.roomId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -115,6 +116,7 @@ internal class LocalEchoRepository @Inject constructor(@SessionDatabase private
|
|||
monarchy.awaitTransaction { realm ->
|
||||
TimelineEventEntity.where(realm, roomId = roomId, eventId = localEcho.root.eventId ?: "").findFirst()?.deleteFromRealm()
|
||||
EventEntity.where(realm, eventId = localEcho.root.eventId ?: "").findFirst()?.deleteFromRealm()
|
||||
roomSummaryUpdater.updateSendingInformation(realm, roomId)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -125,6 +127,7 @@ internal class LocalEchoRepository @Inject constructor(@SessionDatabase private
|
|||
.forEach {
|
||||
it.root?.sendState = SendState.UNSENT
|
||||
}
|
||||
roomSummaryUpdater.updateSendingInformation(realm, roomId)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -134,6 +137,7 @@ internal class LocalEchoRepository @Inject constructor(@SessionDatabase private
|
|||
timelineEvents.forEach {
|
||||
it.root?.sendState = sendState
|
||||
}
|
||||
roomSummaryUpdater.updateSendingInformation(realm, roomId)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@ import im.vector.matrix.android.api.session.room.model.RoomAliasesContent
|
|||
import im.vector.matrix.android.api.session.room.model.RoomCanonicalAliasContent
|
||||
import im.vector.matrix.android.api.session.room.model.RoomNameContent
|
||||
import im.vector.matrix.android.api.session.room.model.RoomTopicContent
|
||||
import im.vector.matrix.android.api.session.room.send.SendState
|
||||
import im.vector.matrix.android.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM
|
||||
import im.vector.matrix.android.internal.crypto.crosssigning.SessionToCryptoRoomMembersUpdate
|
||||
import im.vector.matrix.android.internal.database.mapper.ContentMapper
|
||||
|
@ -34,6 +35,7 @@ import im.vector.matrix.android.internal.database.model.EventEntityFields
|
|||
import im.vector.matrix.android.internal.database.model.RoomMemberSummaryEntityFields
|
||||
import im.vector.matrix.android.internal.database.model.RoomSummaryEntity
|
||||
import im.vector.matrix.android.internal.database.model.TimelineEventEntity
|
||||
import im.vector.matrix.android.internal.database.query.findAllInRoomWithSendStates
|
||||
import im.vector.matrix.android.internal.database.query.getOrCreate
|
||||
import im.vector.matrix.android.internal.database.query.getOrNull
|
||||
import im.vector.matrix.android.internal.database.query.isEventRead
|
||||
|
@ -145,6 +147,7 @@ internal class RoomSummaryUpdater @Inject constructor(
|
|||
} else if (roomSummaryEntity.membership != Membership.INVITE) {
|
||||
roomSummaryEntity.inviterId = null
|
||||
}
|
||||
roomSummaryEntity.updateHasFailedSending()
|
||||
|
||||
if (latestPreviewableEvent?.root?.type == EventType.ENCRYPTED && latestPreviewableEvent.root?.decryptionResultJson == null) {
|
||||
Timber.v("Should decrypt ${latestPreviewableEvent.eventId}")
|
||||
|
@ -167,6 +170,17 @@ internal class RoomSummaryUpdater @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private fun RoomSummaryEntity.updateHasFailedSending() {
|
||||
hasFailedSending = TimelineEventEntity.findAllInRoomWithSendStates(realm, roomId, SendState.HAS_FAILED_STATES).isNotEmpty()
|
||||
}
|
||||
|
||||
fun updateSendingInformation(realm: Realm, roomId: String) {
|
||||
val roomSummaryEntity = RoomSummaryEntity.getOrCreate(realm, roomId)
|
||||
roomSummaryEntity.updateHasFailedSending()
|
||||
roomSummaryEntity.latestPreviewableEvent = TimelineEventEntity.latestEvent(realm, roomId, includesSending = true,
|
||||
filterTypes = PREVIEWABLE_TYPES, filterContentRelation = true)
|
||||
}
|
||||
|
||||
fun updateShieldTrust(realm: Realm,
|
||||
roomId: String,
|
||||
trust: RoomEncryptionTrustLevel?) {
|
||||
|
|
|
@ -30,6 +30,7 @@ import com.squareup.inject.assisted.AssistedInject
|
|||
import im.vector.matrix.android.api.MatrixCallback
|
||||
import im.vector.matrix.android.api.MatrixPatterns
|
||||
import im.vector.matrix.android.api.NoOpMatrixCallback
|
||||
import im.vector.matrix.android.api.extensions.orFalse
|
||||
import im.vector.matrix.android.api.query.QueryStringValue
|
||||
import im.vector.matrix.android.api.session.Session
|
||||
import im.vector.matrix.android.api.session.crypto.MXCryptoError
|
||||
|
@ -415,11 +416,11 @@ class RoomDetailViewModel @AssistedInject constructor(
|
|||
R.id.clear_message_queue ->
|
||||
// For now always disable when not in developer mode, worker cancellation is not working properly
|
||||
timeline.pendingEventCount() > 0 && vectorPreferences.developerMode()
|
||||
R.id.resend_all -> timeline.failedToDeliverEventCount() > 0
|
||||
R.id.clear_all -> timeline.failedToDeliverEventCount() > 0
|
||||
R.id.resend_all -> state.asyncRoomSummary()?.hasFailedSending == true
|
||||
R.id.clear_all -> state.asyncRoomSummary()?.hasFailedSending == true
|
||||
R.id.open_matrix_apps -> true
|
||||
R.id.voice_call,
|
||||
R.id.video_call -> room.canStartCall() && webRtcPeerConnectionManager.currentCall == null
|
||||
R.id.video_call -> state.asyncRoomSummary()?.canStartCall == true && webRtcPeerConnectionManager.currentCall == null
|
||||
R.id.hangup_call -> webRtcPeerConnectionManager.currentCall != null
|
||||
else -> false
|
||||
}
|
||||
|
|
|
@ -52,6 +52,7 @@ abstract class RoomSummaryItem : VectorEpoxyModel<RoomSummaryItem.Holder>() {
|
|||
@EpoxyAttribute var hasUnreadMessage: Boolean = false
|
||||
@EpoxyAttribute var hasDraft: Boolean = false
|
||||
@EpoxyAttribute var showHighlighted: Boolean = false
|
||||
@EpoxyAttribute var hasFailedSending: Boolean = false
|
||||
@EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) var itemLongClickListener: View.OnLongClickListener? = null
|
||||
@EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) var itemClickListener: View.OnClickListener? = null
|
||||
@EpoxyAttribute var showSelected: Boolean = false
|
||||
|
@ -72,6 +73,7 @@ abstract class RoomSummaryItem : VectorEpoxyModel<RoomSummaryItem.Holder>() {
|
|||
avatarRenderer.render(matrixItem, holder.avatarImageView)
|
||||
holder.roomAvatarDecorationImageView.isVisible = encryptionTrustLevel != null
|
||||
holder.roomAvatarDecorationImageView.setImageResource(encryptionTrustLevel.toImageRes())
|
||||
holder.roomAvatarFailSendingImageView.isVisible = hasFailedSending
|
||||
renderSelection(holder, showSelected)
|
||||
holder.typingView.setTextOrHide(typingMessage)
|
||||
holder.lastEventView.isInvisible = holder.typingView.isVisible
|
||||
|
@ -106,6 +108,7 @@ abstract class RoomSummaryItem : VectorEpoxyModel<RoomSummaryItem.Holder>() {
|
|||
val avatarCheckedImageView by bind<ImageView>(R.id.roomAvatarCheckedImageView)
|
||||
val avatarImageView by bind<ImageView>(R.id.roomAvatarImageView)
|
||||
val roomAvatarDecorationImageView by bind<ImageView>(R.id.roomAvatarDecorationImageView)
|
||||
val roomAvatarFailSendingImageView by bind<ImageView>(R.id.roomAvatarFailSendingImageView)
|
||||
val rootView by bind<ViewGroup>(R.id.itemRoomLayout)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -109,6 +109,7 @@ class RoomSummaryItemFactory @Inject constructor(private val displayableEventFor
|
|||
.lastFormattedEvent(latestFormattedEvent)
|
||||
.showHighlighted(showHighlighted)
|
||||
.showSelected(showSelected)
|
||||
.hasFailedSending(roomSummary.hasFailedSending)
|
||||
.unreadNotificationCount(unreadCount)
|
||||
.hasUnreadMessage(roomSummary.hasUnreadMessages)
|
||||
.hasDraft(roomSummary.userDrafts.isNotEmpty())
|
||||
|
|
|
@ -47,6 +47,17 @@
|
|||
|
||||
</FrameLayout>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/roomAvatarFailSendingImageView"
|
||||
android:layout_width="16dp"
|
||||
android:layout_height="16dp"
|
||||
app:layout_constraintCircle="@id/roomAvatarContainer"
|
||||
app:layout_constraintCircleAngle="45"
|
||||
app:layout_constraintCircleRadius="30dp"
|
||||
tools:ignore="MissingConstraints"
|
||||
android:src="@drawable/ic_warning_small"
|
||||
/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/roomAvatarDecorationImageView"
|
||||
android:layout_width="24dp"
|
||||
|
|
Loading…
Reference in a new issue