Timeline : introduce timeline data class to allow listening for isLoadingForward and isLoadingBackward

This commit is contained in:
ganfra
2019-01-07 19:38:36 +01:00
parent f5d64a5707
commit 1269715b5c
16 changed files with 192 additions and 94 deletions

View File

@ -6,9 +6,9 @@ import android.support.v7.widget.LinearLayoutManager
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.airbnb.mvrx.Success
import com.airbnb.mvrx.args
import com.airbnb.mvrx.fragmentViewModel
import im.vector.matrix.android.api.session.room.model.RoomSummary
import im.vector.riotredesign.R
import im.vector.riotredesign.core.platform.RiotFragment
import im.vector.riotredesign.core.platform.ToolbarConfigurable
@ -19,7 +19,6 @@ import kotlinx.android.parcel.Parcelize
import kotlinx.android.synthetic.main.fragment_room_detail.*
import org.koin.android.ext.android.inject
import org.koin.core.parameter.parametersOf
import timber.log.Timber
@Parcelize
data class RoomDetailArgs(
@ -72,7 +71,7 @@ class RoomDetailFragment : RiotFragment(), TimelineEventController.Callback {
private fun setupRecyclerView() {
val layoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, true)
//scrollOnNewMessageCallback = ScrollOnNewMessageCallback(layoutManager)
scrollOnNewMessageCallback = ScrollOnNewMessageCallback(layoutManager)
recyclerView.layoutManager = layoutManager
//timelineEventController.addModelBuildListener { it.dispatchTo(scrollOnNewMessageCallback) }
recyclerView.setHasFixedSize(true)
@ -82,16 +81,19 @@ class RoomDetailFragment : RiotFragment(), TimelineEventController.Callback {
}
private fun renderState(state: RoomDetailViewState) {
Timber.v("Render state")
val timeline = state.asyncTimeline()
if (timeline != null) {
renderTimeline(timeline)
}
renderRoomSummary(state.asyncRoomSummary())
renderRoomSummary(state)
renderTimeline(state)
}
private fun renderRoomSummary(roomSummary: RoomSummary?) {
roomSummary?.let {
private fun renderTimeline(state: RoomDetailViewState) {
when (state.asyncTimelineData) {
is Success -> timelineEventController.update(state.asyncTimelineData())
}
}
private fun renderRoomSummary(state: RoomDetailViewState) {
state.asyncRoomSummary()?.let {
toolbarTitleView.text = it.displayName
AvatarRenderer.render(it, toolbarAvatarImageView)
if (it.topic.isNotEmpty()) {
@ -103,11 +105,6 @@ class RoomDetailFragment : RiotFragment(), TimelineEventController.Callback {
}
}
private fun renderTimeline(timeline: Timeline?) {
//scrollOnNewMessageCallback.hasBeenUpdated.set(true)
timelineEventController.timeline = timeline
}
// TimelineEventController.Callback ************************************************************
override fun onUrlClicked(url: String) {

View File

@ -53,9 +53,10 @@ class RoomDetailViewModel(initialState: RoomDetailViewState,
private fun observeTimeline() {
room.rx().timeline(eventId)
.execute { asyncTimeline ->
copy(asyncTimeline = asyncTimeline)
.execute { timelineData ->
copy(asyncTimelineData= timelineData)
}
}
}

View File

@ -1,19 +1,16 @@
package im.vector.riotredesign.features.home.room.detail
import android.arch.paging.PagedList
import com.airbnb.mvrx.Async
import com.airbnb.mvrx.MvRxState
import com.airbnb.mvrx.Uninitialized
import im.vector.matrix.android.api.session.events.model.EnrichedEvent
import im.vector.matrix.android.api.session.room.model.RoomSummary
typealias Timeline = PagedList<EnrichedEvent>
import im.vector.matrix.android.api.session.room.timeline.TimelineData
data class RoomDetailViewState(
val roomId: String,
val eventId: String?,
val asyncRoomSummary: Async<RoomSummary> = Uninitialized,
val asyncTimeline: Async<Timeline> = Uninitialized
val asyncTimelineData: Async<TimelineData> = Uninitialized
) : MvRxState {
constructor(args: RoomDetailArgs) : this(roomId = args.roomId, eventId = args.eventId)

View File

@ -5,9 +5,9 @@ import com.airbnb.epoxy.EpoxyAsyncUtil
import com.airbnb.epoxy.EpoxyController
import im.vector.matrix.android.api.session.events.model.EnrichedEvent
import im.vector.matrix.android.api.session.events.model.EventType
import im.vector.matrix.android.api.session.room.timeline.TimelineData
import im.vector.riotredesign.core.extensions.localDateTime
import im.vector.riotredesign.features.home.LoadingItemModel_
import im.vector.riotredesign.features.home.room.detail.Timeline
class TimelineEventController(private val roomId: String,
private val messageItemFactory: MessageItemFactory,
@ -36,28 +36,38 @@ class TimelineEventController(private val roomId: String,
}
}
private var snapshotList: List<EnrichedEvent>? = emptyList()
var timeline: Timeline? = null
set(value) {
field?.removeWeakCallback(pagedListCallback)
field = value
field?.addWeakCallback(null, pagedListCallback)
buildSnapshotList()
}
private var snapshotList: List<EnrichedEvent> = emptyList()
private var timelineData: TimelineData? = null
var callback: Callback? = null
override fun buildModels() {
buildModels(snapshotList)
fun update(timelineData: TimelineData?) {
timelineData?.events?.removeWeakCallback(pagedListCallback)
this.timelineData = timelineData
timelineData?.events?.addWeakCallback(null, pagedListCallback)
buildSnapshotList()
}
private fun buildModels(data: List<EnrichedEvent?>?) {
if (data.isNullOrEmpty()) {
override fun buildModels() {
buildModelsWith(
snapshotList,
timelineData?.isLoadingForward ?: false,
timelineData?.isLoadingBackward ?: false
)
}
private fun buildModelsWith(events: List<EnrichedEvent?>,
isLoadingForward: Boolean,
isLoadingBackward: Boolean) {
if (events.isEmpty()) {
return
}
for (index in 0 until data.size) {
val event = data[index] ?: continue
val nextEvent = if (index + 1 < data.size) data[index + 1] else null
LoadingItemModel_()
.id(roomId + "forward_loading_item")
.addIf(isLoadingForward, this)
for (index in 0 until events.size) {
val event = events[index] ?: continue
val nextEvent = if (index + 1 < events.size) events[index + 1] else null
val date = event.root.localDateTime()
val nextDate = nextEvent?.root?.localDateTime()
@ -65,10 +75,13 @@ class TimelineEventController(private val roomId: String,
val item = when (event.root.type) {
EventType.MESSAGE -> messageItemFactory.create(event, nextEvent, addDaySeparator, date, callback)
else -> textItemFactory.create(event)
else -> textItemFactory.create(event)
}
item
?.onBind { timeline?.loadAround(index) }
?.onBind {
timelineData?.events?.loadAround(index)
}
?.id(event.localId)
?.addTo(this)
@ -78,15 +91,14 @@ class TimelineEventController(private val roomId: String,
}
}
//It's a hack at the moment
val isLastEvent = data.last()?.root?.type == EventType.STATE_ROOM_CREATE
LoadingItemModel_()
.id(roomId + "backward_loading_item")
.addIf(!isLastEvent, this)
.addIf(isLoadingBackward, this)
}
private fun buildSnapshotList() {
snapshotList = timeline?.snapshot() ?: emptyList()
snapshotList = timelineData?.events?.snapshot() ?: emptyList()
requestModelBuild()
}