Merge pull request #2984 from vector-im/feature/bma/fixes_release

2 fixes for release 1.1.2
This commit is contained in:
Benoit Marty 2021-03-11 22:43:39 +01:00 committed by GitHub
commit 5cb577be58
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 58 additions and 58 deletions

View File

@ -87,7 +87,7 @@ internal class DefaultTimelineService @AssistedInject constructor(@Assisted priv
}
override fun getTimeLineEventLive(eventId: String): LiveData<Optional<TimelineEvent>> {
return LiveTimelineEvent(timelineInput, monarchy, taskExecutor.executorScope, timelineEventMapper, roomId, eventId)
return LiveTimelineEvent(monarchy, taskExecutor.executorScope, timelineEventMapper, roomId, eventId)
}
override fun getAttachmentMessages(): List<TimelineEvent> {

View File

@ -18,8 +18,9 @@ package org.matrix.android.sdk.internal.session.room.timeline
import androidx.lifecycle.LiveData
import androidx.lifecycle.MediatorLiveData
import androidx.lifecycle.Transformations
import com.zhuinden.monarchy.Monarchy
import io.realm.Realm
import io.realm.RealmQuery
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
@ -29,66 +30,57 @@ import org.matrix.android.sdk.api.util.Optional
import org.matrix.android.sdk.api.util.toOptional
import org.matrix.android.sdk.internal.database.mapper.TimelineEventMapper
import org.matrix.android.sdk.internal.database.model.TimelineEventEntity
import org.matrix.android.sdk.internal.database.model.TimelineEventEntityFields
import org.matrix.android.sdk.internal.database.query.where
import java.util.concurrent.atomic.AtomicBoolean
/**
* This class takes care of handling case where local echo is replaced by the synced event in the db.
*/
internal class LiveTimelineEvent(private val timelineInput: TimelineInput,
private val monarchy: Monarchy,
internal class LiveTimelineEvent(private val monarchy: Monarchy,
private val coroutineScope: CoroutineScope,
private val timelineEventMapper: TimelineEventMapper,
private val roomId: String,
private val eventId: String)
: TimelineInput.Listener,
MediatorLiveData<Optional<TimelineEvent>>() {
private var queryLiveData: LiveData<Optional<TimelineEvent>>? = null
// If we are listening to local echo, we want to be aware when event is synced
private var shouldObserveSync = AtomicBoolean(LocalEcho.isLocalEchoId(eventId))
: MediatorLiveData<Optional<TimelineEvent>>() {
init {
buildAndObserveQuery(eventId)
buildAndObserveQuery()
}
private var initialLiveData: LiveData<List<TimelineEvent>>? = null
// Makes sure it's made on the main thread
private fun buildAndObserveQuery(eventIdToObserve: String) = coroutineScope.launch(Dispatchers.Main) {
queryLiveData?.also {
removeSource(it)
}
private fun buildAndObserveQuery() = coroutineScope.launch(Dispatchers.Main) {
val liveData = monarchy.findAllMappedWithChanges(
{ TimelineEventEntity.where(it, roomId = roomId, eventId = eventIdToObserve) },
{ TimelineEventEntity.where(it, roomId = roomId, eventId = eventId) },
{ timelineEventMapper.map(it) }
)
queryLiveData = Transformations.map(liveData) { events ->
events.firstOrNull().toOptional()
}.also {
addSource(it) { newValue -> value = newValue }
addSource(liveData) { newValue ->
value = newValue.firstOrNull().toOptional()
}
initialLiveData = liveData
if (LocalEcho.isLocalEchoId(eventId)) {
observeTimelineEventWithTxId()
}
}
override fun onLocalEchoSynced(roomId: String, localEchoEventId: String, syncedEventId: String) {
if (this.roomId == roomId && localEchoEventId == this.eventId) {
timelineInput.listeners.remove(this)
shouldObserveSync.set(false)
// rebuild the query with the new eventId
buildAndObserveQuery(syncedEventId)
private fun observeTimelineEventWithTxId() {
val liveData = monarchy.findAllMappedWithChanges(
{ it.queryTimelineEventWithTxId() },
{ timelineEventMapper.map(it) }
)
addSource(liveData) { newValue ->
val optionalValue = newValue.firstOrNull().toOptional()
if (optionalValue.hasValue()) {
initialLiveData?.also { removeSource(it) }
value = optionalValue
}
}
}
override fun onActive() {
super.onActive()
if (shouldObserveSync.get()) {
timelineInput.listeners.add(this)
}
}
override fun onInactive() {
super.onInactive()
if (shouldObserveSync.get()) {
timelineInput.listeners.remove(this)
}
private fun Realm.queryTimelineEventWithTxId(): RealmQuery<TimelineEventEntity> {
return where(TimelineEventEntity::class.java)
.equalTo(TimelineEventEntityFields.ROOM_ID, roomId)
.like(TimelineEventEntityFields.ROOT.UNSIGNED_DATA, """{*"transaction_id":*"$eventId"*}""")
}
}

View File

@ -35,16 +35,11 @@ internal class TimelineInput @Inject constructor() {
listeners.toSet().forEach { it.onNewTimelineEvents(roomId, eventIds) }
}
fun onLocalEchoSynced(roomId: String, localEchoEventId: String, syncEventId: String) {
listeners.toSet().forEach { it.onLocalEchoSynced(roomId, localEchoEventId, syncEventId) }
}
val listeners = mutableSetOf<Listener>()
internal interface Listener {
fun onLocalEchoCreated(roomId: String, timelineEvent: TimelineEvent) = Unit
fun onLocalEchoUpdated(roomId: String, eventId: String, sendState: SendState) = Unit
fun onNewTimelineEvents(roomId: String, eventIds: List<String>) = Unit
fun onLocalEchoSynced(roomId: String, localEchoEventId: String, syncedEventId: String) = Unit
}
}

View File

@ -400,7 +400,6 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle
event.mxDecryptionResult = adapter.fromJson(json)
}
}
timelineInput.onLocalEchoSynced(roomId, it, event.eventId)
// Finally delete the local echo
sendingEventEntity.deleteOnCascade(true)
} else {

View File

@ -434,7 +434,7 @@ dependencies {
implementation "androidx.emoji:emoji-appcompat:1.1.0"
implementation 'com.github.BillCarsonFr:JsonViewer:0.5'
implementation 'com.github.BillCarsonFr:JsonViewer:0.6'
// WebRTC
// org.webrtc:google-webrtc is for development purposes only

View File

@ -57,6 +57,7 @@ abstract class BottomSheetMessagePreviewItem : VectorEpoxyModel<BottomSheetMessa
super.bind(holder)
avatarRenderer.render(matrixItem, holder.avatar)
holder.avatar.setOnClickListener { userClicked?.invoke() }
holder.sender.setOnClickListener { userClicked?.invoke() }
holder.sender.setTextOrHide(matrixItem.displayName)
holder.body.movementMethod = movementMethod
holder.body.text = body

View File

@ -73,12 +73,19 @@ class MessageActionsEpoxyController @Inject constructor(
text(stringProvider.getString(R.string.unable_to_send_message))
drawableStart(R.drawable.ic_warning_badge)
}
} else if (sendState != SendState.SYNCED) {
} else if (sendState?.isSending().orFalse()) {
bottomSheetSendStateItem {
id("send_state")
showProgress(true)
text(stringProvider.getString(R.string.event_status_sending_message))
}
} else if (sendState == SendState.SENT) {
bottomSheetSendStateItem {
id("send_state")
showProgress(false)
drawableStart(R.drawable.ic_message_sent)
text(stringProvider.getString(R.string.event_status_sent_message))
}
}
when (state.informationData.e2eDecoration) {
@ -124,9 +131,11 @@ class MessageActionsEpoxyController @Inject constructor(
}
}
// Separator
dividerItem {
id("actions_separator")
if (state.actions.isNotEmpty()) {
// Separator
dividerItem {
id("actions_separator")
}
}
// Action

View File

@ -4,7 +4,8 @@
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/bottom_sheet_message_preview"
android:layout_width="match_parent"
android:layout_height="wrap_content">
android:layout_height="wrap_content"
tools:background="#1FF00FF0">
<ImageView
android:id="@+id/bottom_sheet_message_preview_avatar"
@ -13,7 +14,7 @@
android:layout_margin="@dimen/layout_horizontal_margin"
android:adjustViewBounds="true"
android:background="@drawable/circle"
android:contentDescription="@string/avatar"
android:importantForAccessibility="no"
android:scaleType="centerCrop"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
@ -23,17 +24,17 @@
<TextView
android:id="@+id/bottom_sheet_message_preview_sender"
android:layout_width="wrap_content"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:layout_marginStart="8dp"
android:layout_marginEnd="@dimen/layout_horizontal_margin"
android:ellipsize="end"
android:fontFamily="sans-serif-bold"
android:singleLine="true"
android:textColor="@color/riotx_accent"
android:textColor="?riotx_text_primary"
android:textSize="14sp"
android:textStyle="bold"
app:layout_constraintEnd_toStartOf="@+id/bottom_sheet_message_preview_timestamp"
app:layout_constraintStart_toEndOf="@id/bottom_sheet_message_preview_avatar"
app:layout_constraintTop_toTopOf="@id/bottom_sheet_message_preview_avatar"
tools:text="@tools:sample/full_names" />
@ -45,15 +46,14 @@
android:layout_marginEnd="@dimen/layout_horizontal_margin"
android:textColor="?riotx_text_secondary"
android:textSize="12sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="@id/bottom_sheet_message_preview_sender"
app:layout_constraintEnd_toEndOf="parent"
tools:text="Friday 8pm" />
<TextView
android:id="@+id/bottom_sheet_message_preview_body"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:layout_marginStart="8dp"
android:layout_marginEnd="@dimen/layout_horizontal_margin"
android:layout_marginBottom="4dp"
@ -62,8 +62,10 @@
android:textColor="?riotx_text_secondary"
android:textIsSelectable="false"
android:textSize="14sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/bottom_sheet_message_preview_avatar"
app:layout_constraintTop_toBottomOf="@id/bottom_sheet_message_preview_sender"
tools:text="Quis harum id autem cumque consequatur laboriosam aliquam sed. Sint accusamus dignissimos nobis ullam earum debitis aspernatur. Sint accusamus dignissimos nobis ullam earum debitis aspernatur. " />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -208,6 +208,8 @@
<string name="initial_sync_start_importing_account_groups">Initial Sync:\nImporting Communities</string>
<string name="initial_sync_start_importing_account_data">Initial Sync:\nImporting Account Data</string>
<string name="event_status_sent_message">Message sent</string>
<string name="event_status_sending_message">Sending message…</string>
<string name="clear_timeline_send_queue">Clear sending queue</string>