Timeline: fix some crashes

This commit is contained in:
ganfra 2019-10-04 12:12:39 +02:00
parent 588e5d6e63
commit 0582d0f641
3 changed files with 45 additions and 38 deletions

View File

@ -176,8 +176,8 @@ internal class DefaultTimeline(
override fun start() {
if (isStarted.compareAndSet(false, true)) {
Timber.v("Start timeline for roomId: $roomId and eventId: $initialEventId")
eventDecryptor.start()
BACKGROUND_HANDLER.post {
eventDecryptor.start()
val realm = Realm.getInstance(realmConfiguration)
backgroundRealm.set(realm)
clearUnlinkedEvents(realm)
@ -212,7 +212,6 @@ internal class DefaultTimeline(
isReady.set(false)
Timber.v("Dispose timeline for roomId: $roomId and eventId: $initialEventId")
cancelableBag.cancel()
BACKGROUND_HANDLER.removeCallbacksAndMessages(null)
BACKGROUND_HANDLER.post {
roomEntity?.sendingTimelineEvents?.removeAllChangeListeners()
eventRelations.removeAllChangeListeners()
@ -225,8 +224,8 @@ internal class DefaultTimeline(
backgroundRealm.getAndSet(null).also {
it.close()
}
eventDecryptor.destroy()
}
eventDecryptor.destroy()
}
}

View File

@ -23,24 +23,17 @@ import im.vector.riotx.features.home.room.detail.timeline.TimelineEventControlle
import im.vector.riotx.features.home.room.detail.timeline.helper.MessageInformationDataFactory
import im.vector.riotx.features.home.room.detail.timeline.item.DefaultItem
import im.vector.riotx.features.home.room.detail.timeline.item.DefaultItem_
import im.vector.riotx.features.home.room.detail.timeline.item.MessageInformationData
import javax.inject.Inject
class DefaultItemFactory @Inject constructor(private val avatarSizeProvider: AvatarSizeProvider,
private val avatarRenderer: AvatarRenderer,
private val informationDataFactory: MessageInformationDataFactory) {
fun create(event: TimelineEvent,
fun create(text: String,
informationData: MessageInformationData,
highlight: Boolean,
readMarkerVisible: Boolean,
callback: TimelineEventController.Callback?,
exception: Exception? = null): DefaultItem? {
val text = if (exception == null) {
"${event.root.getClearType()} events are not yet handled"
} else {
"an exception occurred when rendering the event ${event.root.eventId}"
}
val informationData = informationDataFactory.create(event, null, readMarkerVisible)
callback: TimelineEventController.Callback?): DefaultItem? {
return DefaultItem_()
.leftGuideline(avatarSizeProvider.leftGuideline)
@ -52,4 +45,18 @@ class DefaultItemFactory @Inject constructor(private val avatarSizeProvider: Ava
.readReceiptsCallback(callback)
}
fun create(event: TimelineEvent,
highlight: Boolean,
readMarkerVisible: Boolean,
callback: TimelineEventController.Callback?,
exception: Exception? = null): DefaultItem? {
val text = if (exception == null) {
"${event.root.getClearType()} events are not yet handled"
} else {
"an exception occurred when rendering the event ${event.root.eventId}"
}
val informationData = informationDataFactory.create(event, null, readMarkerVisible)
return create(text, informationData, highlight, callback)
}
}

View File

@ -73,6 +73,7 @@ class MessageItemFactory @Inject constructor(
private val messageInformationDataFactory: MessageInformationDataFactory,
private val messageItemAttributesFactory: MessageItemAttributesFactory,
private val contentUploadStateTrackerBinder: ContentUploadStateTrackerBinder,
private val defaultItemFactory: DefaultItemFactory,
private val noticeItemFactory: NoticeItemFactory,
private val avatarSizeProvider: AvatarSizeProvider) {
@ -93,13 +94,13 @@ class MessageItemFactory @Inject constructor(
return buildRedactedItem(attributes, highlight)
}
val messageContent: MessageContent =
event.getLastMessageContent()
?: //Malformed content, we should echo something on screen
return DefaultItem_().text(stringProvider.getString(R.string.malformed_message))
val messageContent = event.getLastMessageContent()
if (messageContent == null) {
val malformedText = stringProvider.getString(R.string.malformed_message)
return defaultItemFactory.create(malformedText, informationData, highlight, callback)
}
if (messageContent.relatesTo?.type == RelationType.REPLACE
|| event.isEncrypted() && event.root.content.toModel<EncryptedEventContent>()?.relatesTo?.type == RelationType.REPLACE
|| event.isEncrypted() && event.root.content.toModel<EncryptedEventContent>()?.relatesTo?.type == RelationType.REPLACE
) {
// This is an edit event, we should it when debugging as a notice event
return noticeItemFactory.create(event, highlight, readMarkerVisible, callback)
@ -110,21 +111,21 @@ class MessageItemFactory @Inject constructor(
// val ev = all.toModel<Event>()
return when (messageContent) {
is MessageEmoteContent -> buildEmoteMessageItem(messageContent,
informationData,
highlight,
callback,
attributes)
informationData,
highlight,
callback,
attributes)
is MessageTextContent -> buildTextMessageItem(messageContent,
informationData,
highlight,
callback,
attributes)
informationData,
highlight,
callback,
attributes)
is MessageImageContent -> buildImageMessageItem(messageContent, informationData, highlight, callback, attributes)
is MessageNoticeContent -> buildNoticeMessageItem(messageContent, informationData, highlight, callback, attributes)
is MessageVideoContent -> buildVideoMessageItem(messageContent, informationData, highlight, callback, attributes)
is MessageFileContent -> buildFileMessageItem(messageContent, informationData, highlight, callback, attributes)
is MessageAudioContent -> buildAudioMessageItem(messageContent, informationData, highlight, callback, attributes)
else -> buildNotHandledMessageItem(messageContent, highlight)
else -> buildNotHandledMessageItem(messageContent, informationData, highlight, callback)
}
}
@ -166,12 +167,12 @@ class MessageItemFactory @Inject constructor(
}))
}
private fun buildNotHandledMessageItem(messageContent: MessageContent, highlight: Boolean): DefaultItem? {
private fun buildNotHandledMessageItem(messageContent: MessageContent,
informationData: MessageInformationData,
highlight: Boolean,
callback: TimelineEventController.Callback?): DefaultItem? {
val text = "${messageContent.type} message events are not yet handled"
return DefaultItem_()
.leftGuideline(avatarSizeProvider.leftGuideline)
.text(text)
.highlighted(highlight)
return defaultItemFactory.create(text, informationData, highlight, callback)
}
private fun buildImageMessageItem(messageContent: MessageImageContent,
@ -216,7 +217,7 @@ class MessageItemFactory @Inject constructor(
val thumbnailData = ImageContentRenderer.Data(
filename = messageContent.body,
url = messageContent.videoInfo?.thumbnailFile?.url
?: messageContent.videoInfo?.thumbnailUrl,
?: messageContent.videoInfo?.thumbnailUrl,
elementToDecrypt = messageContent.videoInfo?.thumbnailFile?.toElementToDecrypt(),
height = messageContent.videoInfo?.height,
maxHeight = maxHeight,
@ -297,9 +298,9 @@ class MessageItemFactory @Inject constructor(
//nop
}
},
editStart,
editEnd,
Spanned.SPAN_INCLUSIVE_EXCLUSIVE)
editStart,
editEnd,
Spanned.SPAN_INCLUSIVE_EXCLUSIVE)
return spannable
}