mirror of
https://github.com/element-hq/element-android
synced 2024-11-27 03:48:12 +03:00
Makes the timeline a little more polished
This commit is contained in:
parent
ecf728aef8
commit
6f2beef726
13 changed files with 179 additions and 70 deletions
|
@ -0,0 +1,13 @@
|
||||||
|
package im.vector.riotredesign.core.extensions
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.graphics.drawable.Drawable
|
||||||
|
import android.support.v4.content.ContextCompat
|
||||||
|
import com.amulyakhare.textdrawable.TextDrawable
|
||||||
|
import im.vector.riotredesign.R
|
||||||
|
|
||||||
|
|
||||||
|
fun Context.avatarDrawable(name: String): Drawable {
|
||||||
|
val avatarColor = ContextCompat.getColor(this, R.color.pale_teal)
|
||||||
|
return TextDrawable.builder().buildRound(name.firstCharAsString().toUpperCase(), avatarColor)
|
||||||
|
}
|
|
@ -12,10 +12,10 @@ import im.vector.matrix.android.api.session.events.model.EnrichedEvent
|
||||||
import im.vector.matrix.android.api.session.room.Room
|
import im.vector.matrix.android.api.session.room.Room
|
||||||
import im.vector.matrix.android.api.session.room.model.RoomSummary
|
import im.vector.matrix.android.api.session.room.model.RoomSummary
|
||||||
import im.vector.riotredesign.R
|
import im.vector.riotredesign.R
|
||||||
|
import im.vector.riotredesign.core.extensions.avatarDrawable
|
||||||
import im.vector.riotredesign.core.platform.RiotFragment
|
import im.vector.riotredesign.core.platform.RiotFragment
|
||||||
import im.vector.riotredesign.core.platform.ToolbarConfigurable
|
import im.vector.riotredesign.core.platform.ToolbarConfigurable
|
||||||
import im.vector.riotredesign.core.utils.FragmentArgumentDelegate
|
import im.vector.riotredesign.core.utils.FragmentArgumentDelegate
|
||||||
import im.vector.riotredesign.features.home.RoomSummaryViewHelper
|
|
||||||
import kotlinx.android.synthetic.main.fragment_room_detail.*
|
import kotlinx.android.synthetic.main.fragment_room_detail.*
|
||||||
import org.koin.android.ext.android.inject
|
import org.koin.android.ext.android.inject
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ class RoomDetailFragment : RiotFragment() {
|
||||||
private val matrix by inject<Matrix>()
|
private val matrix by inject<Matrix>()
|
||||||
private val currentSession = matrix.currentSession!!
|
private val currentSession = matrix.currentSession!!
|
||||||
private var roomId by FragmentArgumentDelegate<String>()
|
private var roomId by FragmentArgumentDelegate<String>()
|
||||||
private val timelineEventController = TimelineEventController()
|
private lateinit var timelineEventController: TimelineEventController
|
||||||
private lateinit var room: Room
|
private lateinit var room: Room
|
||||||
|
|
||||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||||
|
@ -60,14 +60,14 @@ class RoomDetailFragment : RiotFragment() {
|
||||||
private fun setupRecyclerView() {
|
private fun setupRecyclerView() {
|
||||||
val layoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, true)
|
val layoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, true)
|
||||||
recyclerView.layoutManager = layoutManager
|
recyclerView.layoutManager = layoutManager
|
||||||
|
timelineEventController = TimelineEventController(riotActivity)
|
||||||
recyclerView.setController(timelineEventController)
|
recyclerView.setController(timelineEventController)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun renderRoomSummary(roomSummary: RoomSummary?) {
|
private fun renderRoomSummary(roomSummary: RoomSummary?) {
|
||||||
roomSummary?.let {
|
roomSummary?.let {
|
||||||
val roomSummaryViewHelper = RoomSummaryViewHelper(it)
|
|
||||||
toolbarTitleView.text = it.displayName
|
toolbarTitleView.text = it.displayName
|
||||||
toolbarAvatarImageView.setImageDrawable(roomSummaryViewHelper.avatarDrawable(riotActivity))
|
toolbarAvatarImageView.setImageDrawable(riotActivity.avatarDrawable(it.displayName))
|
||||||
if (it.topic.isNotEmpty()) {
|
if (it.topic.isNotEmpty()) {
|
||||||
toolbarSubtitleView.visibility = View.VISIBLE
|
toolbarSubtitleView.visibility = View.VISIBLE
|
||||||
toolbarSubtitleView.text = it.topic
|
toolbarSubtitleView.text = it.topic
|
||||||
|
|
|
@ -1,22 +1,23 @@
|
||||||
package im.vector.riotredesign.features.home.room.detail
|
package im.vector.riotredesign.features.home.room.detail
|
||||||
|
|
||||||
import android.arch.paging.PagedList
|
import android.arch.paging.PagedList
|
||||||
|
import android.content.Context
|
||||||
import com.airbnb.epoxy.EpoxyAsyncUtil
|
import com.airbnb.epoxy.EpoxyAsyncUtil
|
||||||
import com.airbnb.epoxy.EpoxyController
|
import com.airbnb.epoxy.EpoxyController
|
||||||
import im.vector.matrix.android.api.session.events.model.EnrichedEvent
|
import im.vector.matrix.android.api.session.events.model.EnrichedEvent
|
||||||
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.EventType
|
||||||
|
import im.vector.matrix.android.api.session.events.model.roomMember
|
||||||
import im.vector.matrix.android.api.session.room.model.MessageContent
|
import im.vector.matrix.android.api.session.room.model.MessageContent
|
||||||
import im.vector.matrix.android.api.session.room.model.RoomMember
|
import im.vector.riotredesign.core.extensions.avatarDrawable
|
||||||
import im.vector.riotredesign.features.home.LoadingItemModel_
|
import im.vector.riotredesign.features.home.LoadingItemModel_
|
||||||
|
|
||||||
private const val PREFETCH_DISTANCE = 5
|
class TimelineEventController(private val context: Context) : EpoxyController(
|
||||||
|
|
||||||
class TimelineEventController : EpoxyController(
|
|
||||||
EpoxyAsyncUtil.getAsyncBackgroundHandler(),
|
EpoxyAsyncUtil.getAsyncBackgroundHandler(),
|
||||||
EpoxyAsyncUtil.getAsyncBackgroundHandler()
|
EpoxyAsyncUtil.getAsyncBackgroundHandler()
|
||||||
) {
|
) {
|
||||||
|
|
||||||
|
private val messagesLoadedWithInformation = HashSet<String?>()
|
||||||
|
|
||||||
private val pagedListCallback = object : PagedList.Callback() {
|
private val pagedListCallback = object : PagedList.Callback() {
|
||||||
override fun onChanged(position: Int, count: Int) {
|
override fun onChanged(position: Int, count: Int) {
|
||||||
requestModelBuild()
|
requestModelBuild()
|
||||||
|
@ -38,7 +39,6 @@ class TimelineEventController : EpoxyController(
|
||||||
field?.addWeakCallback(null, pagedListCallback)
|
field?.addWeakCallback(null, pagedListCallback)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
override fun buildModels() {
|
override fun buildModels() {
|
||||||
buildModels(timeline)
|
buildModels(timeline)
|
||||||
}
|
}
|
||||||
|
@ -47,22 +47,37 @@ class TimelineEventController : EpoxyController(
|
||||||
if (data.isNullOrEmpty()) {
|
if (data.isNullOrEmpty()) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
data.forEachIndexed { index, enrichedEvent ->
|
for (index in 0 until data.size) {
|
||||||
val item = if (enrichedEvent.root.type == EventType.MESSAGE) {
|
val event = data[index]
|
||||||
val messageContent = enrichedEvent.root.content<MessageContent>()
|
val nextEvent = if (index + 1 < data.size) data[index + 1] else null
|
||||||
val roomMember = enrichedEvent.getMetadata<Event>(EventType.STATE_ROOM_MEMBER)?.content<RoomMember>()
|
|
||||||
val title = "${roomMember?.displayName} : ${messageContent?.body}"
|
if (event.root.type == EventType.MESSAGE) {
|
||||||
TimelineEventItem(title = title)
|
val messageContent = event.root.content<MessageContent>()
|
||||||
} else {
|
val roomMember = event.roomMember()
|
||||||
TimelineEventItem(title = enrichedEvent.toString())
|
if (messageContent == null || roomMember == null) {
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
item
|
val nextRoomMember = nextEvent?.roomMember()
|
||||||
|
if (nextRoomMember != roomMember) {
|
||||||
|
messagesLoadedWithInformation.add(event.root.eventId)
|
||||||
|
}
|
||||||
|
val showInformation = messagesLoadedWithInformation.contains(event.root.eventId)
|
||||||
|
|
||||||
|
val avatarDrawable = context.avatarDrawable(roomMember.displayName ?: "")
|
||||||
|
TimelineMessageItem(
|
||||||
|
message = messageContent.body,
|
||||||
|
showInformation = showInformation,
|
||||||
|
avatarDrawable = avatarDrawable,
|
||||||
|
memberName = roomMember.displayName
|
||||||
|
)
|
||||||
.onBind { timeline?.loadAround(index) }
|
.onBind { timeline?.loadAround(index) }
|
||||||
.id(enrichedEvent.root.eventId)
|
.id(event.root.eventId)
|
||||||
.addTo(this)
|
.addTo(this)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val isLastEvent = data.last().getMetadata<Boolean>(EnrichedEvent.IS_LAST_EVENT) ?: false
|
//It's a hack at the moment
|
||||||
|
val isLastEvent = data.last().root.type == EventType.STATE_ROOM_CREATE
|
||||||
LoadingItemModel_()
|
LoadingItemModel_()
|
||||||
.id("backward_loading_item")
|
.id("backward_loading_item")
|
||||||
.addIf(!isLastEvent, this)
|
.addIf(!isLastEvent, this)
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
package im.vector.riotredesign.features.home.room.detail
|
||||||
|
|
||||||
|
import android.graphics.drawable.Drawable
|
||||||
|
import android.view.View
|
||||||
|
import android.widget.ImageView
|
||||||
|
import android.widget.TextView
|
||||||
|
import im.vector.riotredesign.R
|
||||||
|
import im.vector.riotredesign.core.epoxy.KotlinModel
|
||||||
|
|
||||||
|
data class TimelineMessageItem(
|
||||||
|
val message: CharSequence? = null,
|
||||||
|
val time: CharSequence? = null,
|
||||||
|
val avatarDrawable: Drawable? = null,
|
||||||
|
val memberName: CharSequence? = null,
|
||||||
|
val showInformation: Boolean = true
|
||||||
|
) : KotlinModel(R.layout.item_event_message) {
|
||||||
|
|
||||||
|
private val avatarImageView by bind<ImageView>(R.id.messageAvatarImageView)
|
||||||
|
private val memberNameView by bind<TextView>(R.id.messageMemberNameView)
|
||||||
|
private val timeView by bind<TextView>(R.id.messageTimeView)
|
||||||
|
private val messageView by bind<TextView>(R.id.messageTextView)
|
||||||
|
|
||||||
|
override fun bind() {
|
||||||
|
messageView.text = message
|
||||||
|
if (showInformation) {
|
||||||
|
avatarImageView.visibility = View.VISIBLE
|
||||||
|
memberNameView.visibility = View.VISIBLE
|
||||||
|
timeView.visibility = View.VISIBLE
|
||||||
|
|
||||||
|
avatarImageView.setImageDrawable(avatarDrawable)
|
||||||
|
timeView.text = time
|
||||||
|
memberNameView.text = memberName
|
||||||
|
} else {
|
||||||
|
avatarImageView.visibility = View.GONE
|
||||||
|
memberNameView.visibility = View.GONE
|
||||||
|
timeView.visibility = View.GONE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,8 +3,7 @@ package im.vector.riotredesign.features.home.room.list
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import com.airbnb.epoxy.Typed2EpoxyController
|
import com.airbnb.epoxy.Typed2EpoxyController
|
||||||
import im.vector.matrix.android.api.session.room.model.RoomSummary
|
import im.vector.matrix.android.api.session.room.model.RoomSummary
|
||||||
import im.vector.riotredesign.R
|
import im.vector.riotredesign.core.extensions.avatarDrawable
|
||||||
import im.vector.riotredesign.features.home.RoomSummaryViewHelper
|
|
||||||
|
|
||||||
class RoomSummaryController(private val context: Context,
|
class RoomSummaryController(private val context: Context,
|
||||||
private val callback: Callback? = null
|
private val callback: Callback? = null
|
||||||
|
@ -53,10 +52,9 @@ class RoomSummaryController(private val context: Context,
|
||||||
|
|
||||||
private fun buildRoomModels(summaries: List<RoomSummary>, selected: RoomSummary?) {
|
private fun buildRoomModels(summaries: List<RoomSummary>, selected: RoomSummary?) {
|
||||||
summaries.forEach {
|
summaries.forEach {
|
||||||
val roomSummaryViewHelper = RoomSummaryViewHelper(it)
|
|
||||||
RoomSummaryItem(
|
RoomSummaryItem(
|
||||||
title = it.displayName,
|
title = it.displayName,
|
||||||
avatarDrawable = roomSummaryViewHelper.avatarDrawable(context),
|
avatarDrawable = context.avatarDrawable(it.displayName),
|
||||||
isSelected = it.roomId == selected?.roomId,
|
isSelected = it.roomId == selected?.roomId,
|
||||||
listener = { callback?.onRoomSelected(it) }
|
listener = { callback?.onRoomSelected(it) }
|
||||||
)
|
)
|
||||||
|
|
|
@ -16,7 +16,7 @@ data class RoomSummaryItem(
|
||||||
) : KotlinModel(R.layout.item_room) {
|
) : KotlinModel(R.layout.item_room) {
|
||||||
|
|
||||||
private val titleView by bind<TextView>(R.id.titleView)
|
private val titleView by bind<TextView>(R.id.titleView)
|
||||||
private val avatarImageView by bind<ImageView>(R.id.avatarImageView)
|
private val avatarImageView by bind<ImageView>(R.id.messageAvatarImageView)
|
||||||
private val rootView by bind<CheckableFrameLayout>(R.id.itemRoomLayout)
|
private val rootView by bind<CheckableFrameLayout>(R.id.itemRoomLayout)
|
||||||
|
|
||||||
override fun bind() {
|
override fun bind() {
|
||||||
|
|
10
app/src/main/res/layout/item_event_day_separator.xml
Normal file
10
app/src/main/res/layout/item_event_day_separator.xml
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:minHeight="80dp"
|
||||||
|
android:padding="16dp">
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</android.support.constraint.ConstraintLayout>
|
66
app/src/main/res/layout/item_event_message.xml
Normal file
66
app/src/main/res/layout/item_event_message.xml
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingLeft="16dp"
|
||||||
|
android:paddingRight="16dp">
|
||||||
|
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/messageAvatarImageView"
|
||||||
|
android:layout_width="40dp"
|
||||||
|
android:layout_height="40dp"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:layout_marginBottom="8dp"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
tools:src="@tools:sample/avatars" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/messageMemberNameView"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="64dp"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:layout_marginEnd="8dp"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:paddingBottom="8dp"
|
||||||
|
android:textSize="15sp"
|
||||||
|
app:layout_constraintBottom_toTopOf="@+id/toolbarSubtitleView"
|
||||||
|
app:layout_constraintEnd_toStartOf="@+id/messageTimeView"
|
||||||
|
app:layout_constraintHorizontal_bias="0.0"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
tools:text="@tools:sample/full_names" />
|
||||||
|
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/messageTimeView"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="8dp"
|
||||||
|
android:textColor="@color/brown_grey"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintHorizontal_bias="0.0"
|
||||||
|
app:layout_constraintTop_toTopOf="@id/messageMemberNameView"
|
||||||
|
tools:text="@tools:sample/date/hhmm" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/messageTextView"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="64dp"
|
||||||
|
android:layout_marginBottom="8dp"
|
||||||
|
android:textColor="@color/dark_grey"
|
||||||
|
android:textSize="14sp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/messageMemberNameView"
|
||||||
|
tools:text="Alright finished work, heading there in about 20 mins…
Ping me when you’re outside" />
|
||||||
|
|
||||||
|
|
||||||
|
</android.support.constraint.ConstraintLayout>
|
|
@ -21,7 +21,7 @@
|
||||||
android:minHeight="48dp">
|
android:minHeight="48dp">
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/avatarImageView"
|
android:id="@+id/messageAvatarImageView"
|
||||||
android:layout_width="32dp"
|
android:layout_width="32dp"
|
||||||
android:layout_height="32dp"
|
android:layout_height="32dp"
|
||||||
android:layout_marginStart="16dp"
|
android:layout_marginStart="16dp"
|
||||||
|
@ -40,7 +40,7 @@
|
||||||
android:textSize="14sp"
|
android:textSize="14sp"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toEndOf="@id/avatarImageView"
|
app:layout_constraintStart_toEndOf="@id/messageAvatarImageView"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
tools:text="@tools:sample/full_names" />
|
tools:text="@tools:sample/full_names" />
|
||||||
|
|
||||||
|
|
|
@ -15,4 +15,5 @@
|
||||||
<color name="light_grey_blue">#9fa9ba</color>
|
<color name="light_grey_blue">#9fa9ba</color>
|
||||||
<color name="cool_grey">#a5aab2</color>
|
<color name="cool_grey">#a5aab2</color>
|
||||||
<color name="pale_grey_two">#ebedf8</color>
|
<color name="pale_grey_two">#ebedf8</color>
|
||||||
|
<color name="brown_grey">#a5a5a5</color>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package im.vector.matrix.android.api.session.events.model
|
package im.vector.matrix.android.api.session.events.model
|
||||||
|
|
||||||
|
import im.vector.matrix.android.api.session.room.model.RoomMember
|
||||||
|
|
||||||
data class EnrichedEvent(val root: Event) {
|
data class EnrichedEvent(val root: Event) {
|
||||||
|
|
||||||
val metadata = HashMap<String, Any>()
|
val metadata = HashMap<String, Any>()
|
||||||
|
@ -31,3 +33,7 @@ data class EnrichedEvent(val root: Event) {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun EnrichedEvent.roomMember(): RoomMember? {
|
||||||
|
return getMetadata<Event>(EventType.STATE_ROOM_MEMBER)?.content<RoomMember>()
|
||||||
|
}
|
||||||
|
|
|
@ -1,37 +0,0 @@
|
||||||
package im.vector.matrix.android.internal.session.events.interceptor
|
|
||||||
|
|
||||||
import com.zhuinden.monarchy.Monarchy
|
|
||||||
import im.vector.matrix.android.api.session.events.interceptor.EnrichedEventInterceptor
|
|
||||||
import im.vector.matrix.android.api.session.events.model.EnrichedEvent
|
|
||||||
import im.vector.matrix.android.internal.database.model.ChunkEntity
|
|
||||||
import im.vector.matrix.android.internal.database.model.EventEntity
|
|
||||||
import im.vector.matrix.android.internal.database.model.EventEntityFields
|
|
||||||
import im.vector.matrix.android.internal.database.query.findAllIncludingEvents
|
|
||||||
import im.vector.matrix.android.internal.database.query.where
|
|
||||||
import io.realm.Sort
|
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
|
|
||||||
class IsLastEventInterceptor(val monarchy: Monarchy) : EnrichedEventInterceptor {
|
|
||||||
|
|
||||||
override fun canEnrich(event: EnrichedEvent): Boolean {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun enrich(roomId: String, event: EnrichedEvent) {
|
|
||||||
monarchy.doWithRealm { realm ->
|
|
||||||
if (event.root.eventId == null) {
|
|
||||||
return@doWithRealm
|
|
||||||
}
|
|
||||||
val eventEntity = EventEntity.where(realm, event.root.eventId).findFirst()
|
|
||||||
val chunkEntity = ChunkEntity.findAllIncludingEvents(realm, Collections.singletonList(event.root.eventId)).firstOrNull()
|
|
||||||
if (eventEntity == null || chunkEntity == null) {
|
|
||||||
return@doWithRealm
|
|
||||||
}
|
|
||||||
val sortedChunkEvents = chunkEntity.events.where().sort(EventEntityFields.ORIGIN_SERVER_TS, Sort.ASCENDING).findAll()
|
|
||||||
val isLastEvent = chunkEntity.prevToken == null && sortedChunkEvents?.indexOf(eventEntity) == 0
|
|
||||||
event.enrichWith(EnrichedEvent.IS_LAST_EVENT, isLastEvent)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -11,7 +11,6 @@ import im.vector.matrix.android.internal.database.mapper.asDomain
|
||||||
import im.vector.matrix.android.internal.database.model.ChunkEntity
|
import im.vector.matrix.android.internal.database.model.ChunkEntity
|
||||||
import im.vector.matrix.android.internal.database.model.EventEntityFields
|
import im.vector.matrix.android.internal.database.model.EventEntityFields
|
||||||
import im.vector.matrix.android.internal.database.query.where
|
import im.vector.matrix.android.internal.database.query.where
|
||||||
import im.vector.matrix.android.internal.session.events.interceptor.IsLastEventInterceptor
|
|
||||||
import im.vector.matrix.android.internal.session.events.interceptor.MessageEventInterceptor
|
import im.vector.matrix.android.internal.session.events.interceptor.MessageEventInterceptor
|
||||||
import io.realm.Sort
|
import io.realm.Sort
|
||||||
|
|
||||||
|
@ -24,7 +23,6 @@ class DefaultTimelineHolder(private val roomId: String,
|
||||||
|
|
||||||
init {
|
init {
|
||||||
eventInterceptors.add(MessageEventInterceptor(monarchy))
|
eventInterceptors.add(MessageEventInterceptor(monarchy))
|
||||||
eventInterceptors.add(IsLastEventInterceptor(monarchy))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun liveTimeline(): LiveData<PagedList<EnrichedEvent>> {
|
override fun liveTimeline(): LiveData<PagedList<EnrichedEvent>> {
|
||||||
|
|
Loading…
Reference in a new issue