Last event on room list

This commit is contained in:
Benoit Marty
2019-07-01 12:35:48 +02:00
committed by Benoit Marty
parent 0d433b2620
commit 4d79485fee
20 changed files with 196 additions and 106 deletions

View File

@ -504,7 +504,7 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro
private fun observeInvitationState() {
asyncSubscribe(RoomDetailViewState::asyncRoomSummary) { summary ->
if (summary.membership == Membership.INVITE) {
summary.lastMessage?.senderId?.let { senderId ->
summary.latestEvent?.root?.senderId?.let { senderId ->
session.getUser(senderId)
}?.also {
setState { copy(asyncInviter = Success(it)) }

View File

@ -25,14 +25,14 @@ class ChronologicalRoomComparator @Inject constructor() : Comparator<RoomSummary
var rightTimestamp = 0L
var leftTimestamp = 0L
if (null != leftRoomSummary) {
leftTimestamp = leftRoomSummary.lastMessage?.originServerTs ?: 0
leftTimestamp = leftRoomSummary.latestEvent?.root?.originServerTs ?: 0
}
if (null != rightRoomSummary) {
rightTimestamp = rightRoomSummary.lastMessage?.originServerTs ?: 0
rightTimestamp = rightRoomSummary.latestEvent?.root?.originServerTs ?: 0
}
return if (rightRoomSummary?.lastMessage == null) {
return if (rightRoomSummary?.latestEvent?.root == null) {
-1
} else if (leftRoomSummary?.lastMessage == null) {
} else if (leftRoomSummary?.latestEvent?.root == null) {
1
} else {
val deltaTimestamp = rightTimestamp - leftTimestamp

View File

@ -22,8 +22,6 @@ sealed class RoomListActions {
data class SelectRoom(val roomSummary: RoomSummary) : RoomListActions()
data class FilterRooms(val roomName: CharSequence? = null) : RoomListActions()
data class ToggleCategory(val category: RoomCategory) : RoomListActions()
}

View File

@ -18,14 +18,11 @@ package im.vector.riotredesign.features.home.room.list
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import arrow.core.Option
import com.airbnb.mvrx.FragmentViewModelContext
import com.airbnb.mvrx.MvRxViewModelFactory
import com.airbnb.mvrx.ViewModelContext
import com.jakewharton.rxrelay2.BehaviorRelay
import com.squareup.inject.assisted.Assisted
import com.squareup.inject.assisted.AssistedInject
import im.vector.matrix.android.api.session.Session
import im.vector.matrix.android.api.session.room.model.Membership
import im.vector.matrix.android.api.session.room.model.RoomSummary
import im.vector.matrix.android.api.session.room.model.tag.RoomTag
@ -33,10 +30,7 @@ import im.vector.riotredesign.core.platform.VectorViewModel
import im.vector.riotredesign.core.utils.LiveEvent
import im.vector.riotredesign.features.home.HomeRoomListObservableStore
typealias RoomListFilterName = CharSequence
class RoomListViewModel @AssistedInject constructor(@Assisted initialState: RoomListViewState,
private val session: Session,
private val homeRoomListObservableSource: HomeRoomListObservableStore,
private val alphabeticalRoomComparator: AlphabeticalRoomComparator,
private val chronologicalRoomComparator: ChronologicalRoomComparator)
@ -57,8 +51,6 @@ class RoomListViewModel @AssistedInject constructor(@Assisted initialState: Room
}
private val displayMode = initialState.displayMode
private val roomListDisplayModeFilter = RoomListDisplayModeFilter(displayMode)
private val roomListFilter = BehaviorRelay.createDefault<Option<RoomListFilterName>>(Option.empty())
private val _openRoomLiveData = MutableLiveData<LiveEvent<String>>()
val openRoomLiveData: LiveData<LiveEvent<String>>
@ -71,7 +63,6 @@ class RoomListViewModel @AssistedInject constructor(@Assisted initialState: Room
fun accept(action: RoomListActions) {
when (action) {
is RoomListActions.SelectRoom -> handleSelectRoom(action)
is RoomListActions.FilterRooms -> handleFilterRooms(action)
is RoomListActions.ToggleCategory -> handleToggleCategory(action)
}
}
@ -82,11 +73,6 @@ class RoomListViewModel @AssistedInject constructor(@Assisted initialState: Room
_openRoomLiveData.postValue(LiveEvent(action.roomSummary.roomId))
}
private fun handleFilterRooms(action: RoomListActions.FilterRooms) {
val optionalFilter = Option.fromNullable(action.roomName)
roomListFilter.accept(optionalFilter)
}
private fun handleToggleCategory(action: RoomListActions.ToggleCategory) = setState {
this.toggle(action.category)
}

View File

@ -18,22 +18,12 @@ package im.vector.riotredesign.features.home.room.list
import androidx.annotation.StringRes
import com.airbnb.epoxy.TypedEpoxyController
import im.vector.matrix.android.api.session.events.model.EventType
import im.vector.matrix.android.api.session.events.model.toModel
import im.vector.matrix.android.api.session.room.model.RoomSummary
import im.vector.matrix.android.api.session.room.model.message.MessageContent
import im.vector.riotredesign.core.extensions.localDateTime
import im.vector.riotredesign.core.resources.DateProvider
import im.vector.riotredesign.core.resources.StringProvider
import im.vector.riotredesign.features.home.AvatarRenderer
import im.vector.riotredesign.features.home.room.detail.timeline.format.NoticeEventFormatter
import im.vector.riotredesign.features.home.room.detail.timeline.helper.TimelineDateFormatter
import javax.inject.Inject
class RoomSummaryController @Inject constructor(private val stringProvider: StringProvider,
private val eventFormatter: NoticeEventFormatter,
private val timelineDateFormatter: TimelineDateFormatter,
private val avatarRenderer: AvatarRenderer
private val roomSummaryItemFactory: RoomSummaryItemFactory
) : TypedEpoxyController<RoomListViewState>() {
var callback: Callback? = null
@ -85,44 +75,9 @@ class RoomSummaryController @Inject constructor(private val stringProvider: Stri
private fun buildRoomModels(summaries: List<RoomSummary>) {
summaries.forEach { roomSummary ->
val unreadCount = roomSummary.notificationCount
val showHighlighted = roomSummary.highlightCount > 0
var lastMessageFormatted: CharSequence = ""
var lastMessageTime: CharSequence = ""
val lastMessage = roomSummary.lastMessage
if (lastMessage != null) {
val date = lastMessage.localDateTime()
val currentData = DateProvider.currentLocalDateTime()
val isSameDay = date.toLocalDate() == currentData.toLocalDate()
//TODO: get formatted
if (lastMessage.type == EventType.MESSAGE) {
val content = lastMessage.content?.toModel<MessageContent>()
lastMessageFormatted = content?.body ?: ""
} else {
lastMessageFormatted = lastMessage.type
}
lastMessageTime = if (isSameDay) {
timelineDateFormatter.formatMessageHour(date)
} else {
//TODO: change this
timelineDateFormatter.formatMessageDay(date)
}
}
roomSummaryItem {
avatarRenderer(avatarRenderer)
id(roomSummary.roomId)
roomId(roomSummary.roomId)
lastEventTime(lastMessageTime)
lastFormattedEvent(lastMessageFormatted)
roomName(roomSummary.displayName)
avatarUrl(roomSummary.avatarUrl)
showHighlighted(showHighlighted)
unreadCount(unreadCount)
listener { callback?.onRoomSelected(roomSummary) }
}
roomSummaryItemFactory
.create(roomSummary) { callback?.onRoomSelected(it) }
.addTo(this)
}
}

View File

@ -0,0 +1,86 @@
/*
* Copyright 2019 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package im.vector.riotredesign.features.home.room.list
import im.vector.matrix.android.api.session.events.model.EventType
import im.vector.matrix.android.api.session.events.model.toModel
import im.vector.matrix.android.api.session.room.model.RoomSummary
import im.vector.matrix.android.api.session.room.model.message.MessageContent
import im.vector.riotredesign.R
import im.vector.riotredesign.core.extensions.localDateTime
import im.vector.riotredesign.core.resources.ColorProvider
import im.vector.riotredesign.core.resources.DateProvider
import im.vector.riotredesign.features.home.room.detail.timeline.format.NoticeEventFormatter
import im.vector.riotredesign.features.home.room.detail.timeline.helper.TimelineDateFormatter
import im.vector.riotredesign.features.home.room.detail.timeline.helper.senderName
import me.gujun.android.span.span
import javax.inject.Inject
class RoomSummaryItemFactory @Inject constructor(private val noticeEventFormatter: NoticeEventFormatter,
private val timelineDateFormatter: TimelineDateFormatter,
private val colorProvider: ColorProvider) {
fun create(roomSummary: RoomSummary, onRoomSelected: (RoomSummary) -> Unit): RoomSummaryItem {
val unreadCount = roomSummary.notificationCount
val showHighlighted = roomSummary.highlightCount > 0
var latestFormattedEvent: CharSequence = ""
var latestEventTime: CharSequence = ""
val latestEvent = roomSummary.latestEvent
if (latestEvent != null) {
val date = latestEvent.root.localDateTime()
val currentData = DateProvider.currentLocalDateTime()
val isSameDay = date.toLocalDate() == currentData.toLocalDate()
latestFormattedEvent = if (latestEvent.root.type == EventType.MESSAGE) {
val senderName = latestEvent.senderName() ?: latestEvent.root.senderId
val content = latestEvent.root.content?.toModel<MessageContent>()
val message = content?.body ?: ""
if (roomSummary.isDirect.not() && senderName != null) {
span {
text = senderName
textColor = colorProvider.getColorFromAttribute(R.attr.riotx_text_primary)
}
.append(" - ")
.append(message)
} else {
message
}
} else {
span {
text = noticeEventFormatter.format(latestEvent) ?: ""
textStyle = "italic"
}
}
latestEventTime = if (isSameDay) {
timelineDateFormatter.formatMessageHour(date)
} else {
//TODO: change this
timelineDateFormatter.formatMessageDay(date)
}
}
return RoomSummaryItem_()
.id(roomSummary.roomId)
.roomId(roomSummary.roomId)
.lastEventTime(latestEventTime)
.lastFormattedEvent(latestFormattedEvent)
.roomName(roomSummary.displayName)
.avatarUrl(roomSummary.avatarUrl)
.showHighlighted(showHighlighted)
.unreadCount(unreadCount)
.listener { onRoomSelected(roomSummary) }
}
}