mirror of
https://github.com/vector-im/element-android.git
synced 2024-11-15 01:35:07 +08:00
Merge pull request #524 from vector-im/feature/indicate_unread_rooms
Add unread indent on room list
This commit is contained in:
commit
d60d766354
@ -5,7 +5,7 @@ Features:
|
||||
-
|
||||
|
||||
Improvements:
|
||||
-
|
||||
- Add unread indent on room list (#485)
|
||||
|
||||
Other changes:
|
||||
-
|
||||
|
@ -29,10 +29,11 @@ data class RoomSummary(
|
||||
val topic: String = "",
|
||||
val avatarUrl: String = "",
|
||||
val isDirect: Boolean = false,
|
||||
val latestEvent: TimelineEvent? = null,
|
||||
val latestPreviewableEvent: TimelineEvent? = null,
|
||||
val otherMemberIds: List<String> = emptyList(),
|
||||
val notificationCount: Int = 0,
|
||||
val highlightCount: Int = 0,
|
||||
val hasUnreadMessages: Boolean = false,
|
||||
val tags: List<RoomTag> = emptyList(),
|
||||
val membership: Membership = Membership.NONE,
|
||||
val versioningState: VersioningState = VersioningState.NONE
|
||||
|
@ -26,8 +26,8 @@ import java.util.UUID
|
||||
import javax.inject.Inject
|
||||
|
||||
internal class RoomSummaryMapper @Inject constructor(
|
||||
val cryptoService: CryptoService,
|
||||
val timelineEventMapper: TimelineEventMapper
|
||||
private val cryptoService: CryptoService,
|
||||
private val timelineEventMapper: TimelineEventMapper
|
||||
) {
|
||||
|
||||
fun map(roomSummaryEntity: RoomSummaryEntity): RoomSummary {
|
||||
@ -35,7 +35,7 @@ internal class RoomSummaryMapper @Inject constructor(
|
||||
RoomTag(it.tagName, it.tagOrder)
|
||||
}
|
||||
|
||||
val latestEvent = roomSummaryEntity.latestEvent?.let {
|
||||
val latestEvent = roomSummaryEntity.latestPreviewableEvent?.let {
|
||||
timelineEventMapper.map(it)
|
||||
}
|
||||
if (latestEvent?.root?.isEncrypted() == true && latestEvent.root.mxDecryptionResult == null) {
|
||||
@ -53,16 +53,18 @@ internal class RoomSummaryMapper @Inject constructor(
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return RoomSummary(
|
||||
roomId = roomSummaryEntity.roomId,
|
||||
displayName = roomSummaryEntity.displayName ?: "",
|
||||
topic = roomSummaryEntity.topic ?: "",
|
||||
avatarUrl = roomSummaryEntity.avatarUrl ?: "",
|
||||
isDirect = roomSummaryEntity.isDirect,
|
||||
latestEvent = latestEvent,
|
||||
latestPreviewableEvent = latestEvent,
|
||||
otherMemberIds = roomSummaryEntity.otherMemberIds.toList(),
|
||||
highlightCount = roomSummaryEntity.highlightCount,
|
||||
notificationCount = roomSummaryEntity.notificationCount,
|
||||
hasUnreadMessages = roomSummaryEntity.hasUnreadMessages,
|
||||
tags = tags,
|
||||
membership = roomSummaryEntity.membership,
|
||||
versioningState = roomSummaryEntity.versioningState
|
||||
|
@ -26,7 +26,7 @@ internal open class RoomSummaryEntity(@PrimaryKey var roomId: String = "",
|
||||
var displayName: String? = "",
|
||||
var avatarUrl: String? = "",
|
||||
var topic: String? = "",
|
||||
var latestEvent: TimelineEventEntity? = null,
|
||||
var latestPreviewableEvent: TimelineEventEntity? = null,
|
||||
var heroes: RealmList<String> = RealmList(),
|
||||
var joinedMembersCount: Int? = 0,
|
||||
var invitedMembersCount: Int? = 0,
|
||||
@ -35,6 +35,7 @@ internal open class RoomSummaryEntity(@PrimaryKey var roomId: String = "",
|
||||
var otherMemberIds: RealmList<String> = RealmList(),
|
||||
var notificationCount: Int = 0,
|
||||
var highlightCount: Int = 0,
|
||||
var hasUnreadMessages: Boolean = false,
|
||||
var tags: RealmList<RoomTagEntity> = RealmList()
|
||||
) : RealmObject() {
|
||||
|
||||
|
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* 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.matrix.android.internal.database.query
|
||||
|
||||
import com.zhuinden.monarchy.Monarchy
|
||||
import im.vector.matrix.android.internal.database.model.ChunkEntity
|
||||
import im.vector.matrix.android.internal.database.model.ReadReceiptEntity
|
||||
|
||||
internal fun isEventRead(monarchy: Monarchy,
|
||||
userId: String?,
|
||||
roomId: String?,
|
||||
eventId: String?): Boolean {
|
||||
if (userId.isNullOrBlank() || roomId.isNullOrBlank() || eventId.isNullOrBlank()) {
|
||||
return false
|
||||
}
|
||||
|
||||
var isEventRead = false
|
||||
|
||||
monarchy.doWithRealm { realm ->
|
||||
val readReceipt = ReadReceiptEntity.where(realm, roomId, userId).findFirst() ?: return@doWithRealm
|
||||
val liveChunk = ChunkEntity.findLastLiveChunkFromRoom(realm, roomId) ?: return@doWithRealm
|
||||
val readReceiptIndex = liveChunk.timelineEvents.find(readReceipt.eventId)?.root?.displayIndex ?: Int.MIN_VALUE
|
||||
val eventToCheckIndex = liveChunk.timelineEvents.find(eventId)?.root?.displayIndex ?: Int.MAX_VALUE
|
||||
|
||||
isEventRead = eventToCheckIndex <= readReceiptIndex
|
||||
}
|
||||
|
||||
return isEventRead
|
||||
}
|
@ -24,7 +24,7 @@ import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
@MatrixScope
|
||||
internal class UserAgentHolder @Inject constructor(val context: Context) {
|
||||
internal class UserAgentHolder @Inject constructor(private val context: Context) {
|
||||
|
||||
var userAgent: String = ""
|
||||
private set
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
package im.vector.matrix.android.internal.session.room
|
||||
|
||||
import com.zhuinden.monarchy.Monarchy
|
||||
import im.vector.matrix.android.api.auth.data.Credentials
|
||||
import im.vector.matrix.android.api.session.events.model.EventType
|
||||
import im.vector.matrix.android.api.session.events.model.toModel
|
||||
@ -26,6 +27,7 @@ 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.model.RoomSummaryEntity
|
||||
import im.vector.matrix.android.internal.database.model.TimelineEventEntity
|
||||
import im.vector.matrix.android.internal.database.query.isEventRead
|
||||
import im.vector.matrix.android.internal.database.query.latestEvent
|
||||
import im.vector.matrix.android.internal.database.query.prev
|
||||
import im.vector.matrix.android.internal.database.query.where
|
||||
@ -39,7 +41,8 @@ import javax.inject.Inject
|
||||
|
||||
internal class RoomSummaryUpdater @Inject constructor(private val credentials: Credentials,
|
||||
private val roomDisplayNameResolver: RoomDisplayNameResolver,
|
||||
private val roomAvatarResolver: RoomAvatarResolver) {
|
||||
private val roomAvatarResolver: RoomAvatarResolver,
|
||||
private val monarchy: Monarchy) {
|
||||
|
||||
// TODO: maybe allow user of SDK to give that list
|
||||
private val PREVIEWABLE_TYPES = listOf(
|
||||
@ -63,8 +66,7 @@ internal class RoomSummaryUpdater @Inject constructor(private val credentials: C
|
||||
membership: Membership? = null,
|
||||
roomSummary: RoomSyncSummary? = null,
|
||||
unreadNotifications: RoomSyncUnreadNotifications? = null) {
|
||||
val roomSummaryEntity = RoomSummaryEntity.where(realm, roomId).findFirst()
|
||||
?: realm.createObject(roomId)
|
||||
val roomSummaryEntity = RoomSummaryEntity.where(realm, roomId).findFirst() ?: realm.createObject(roomId)
|
||||
|
||||
if (roomSummary != null) {
|
||||
if (roomSummary.heroes.isNotEmpty()) {
|
||||
@ -85,9 +87,13 @@ internal class RoomSummaryUpdater @Inject constructor(private val credentials: C
|
||||
roomSummaryEntity.membership = membership
|
||||
}
|
||||
|
||||
val latestEvent = TimelineEventEntity.latestEvent(realm, roomId, includesSending = true, includedTypes = PREVIEWABLE_TYPES)
|
||||
val latestPreviewableEvent = TimelineEventEntity.latestEvent(realm, roomId, includesSending = true, includedTypes = PREVIEWABLE_TYPES)
|
||||
val lastTopicEvent = EventEntity.where(realm, roomId, EventType.STATE_ROOM_TOPIC).prev()?.asDomain()
|
||||
|
||||
roomSummaryEntity.hasUnreadMessages = roomSummaryEntity.notificationCount > 0
|
||||
//avoid this call if we are sure there are unread events
|
||||
|| !isEventRead(monarchy, credentials.userId, roomId, latestPreviewableEvent?.eventId)
|
||||
|
||||
val otherRoomMembers = RoomMembers(realm, roomId)
|
||||
.queryRoomMembersEvent()
|
||||
.notEqualTo(EventEntityFields.STATE_KEY, credentials.userId)
|
||||
@ -98,9 +104,8 @@ internal class RoomSummaryUpdater @Inject constructor(private val credentials: C
|
||||
roomSummaryEntity.displayName = roomDisplayNameResolver.resolve(roomId).toString()
|
||||
roomSummaryEntity.avatarUrl = roomAvatarResolver.resolve(roomId)
|
||||
roomSummaryEntity.topic = lastTopicEvent?.content.toModel<RoomTopicContent>()?.topic
|
||||
roomSummaryEntity.latestEvent = latestEvent
|
||||
roomSummaryEntity.latestPreviewableEvent = latestPreviewableEvent
|
||||
roomSummaryEntity.otherMemberIds.clear()
|
||||
roomSummaryEntity.otherMemberIds.addAll(otherRoomMembers)
|
||||
|
||||
}
|
||||
}
|
@ -27,11 +27,8 @@ import im.vector.matrix.android.api.session.room.model.ReadReceipt
|
||||
import im.vector.matrix.android.api.session.room.read.ReadService
|
||||
import im.vector.matrix.android.internal.database.RealmLiveData
|
||||
import im.vector.matrix.android.internal.database.mapper.ReadReceiptsSummaryMapper
|
||||
import im.vector.matrix.android.internal.database.model.ChunkEntity
|
||||
import im.vector.matrix.android.internal.database.model.ReadReceiptEntity
|
||||
import im.vector.matrix.android.internal.database.model.ReadReceiptsSummaryEntity
|
||||
import im.vector.matrix.android.internal.database.query.find
|
||||
import im.vector.matrix.android.internal.database.query.findLastLiveChunkFromRoom
|
||||
import im.vector.matrix.android.internal.database.query.isEventRead
|
||||
import im.vector.matrix.android.internal.database.query.where
|
||||
import im.vector.matrix.android.internal.task.TaskExecutor
|
||||
import im.vector.matrix.android.internal.task.configureWith
|
||||
@ -78,19 +75,7 @@ internal class DefaultReadService @AssistedInject constructor(@Assisted private
|
||||
|
||||
|
||||
override fun isEventRead(eventId: String): Boolean {
|
||||
var isEventRead = false
|
||||
monarchy.doWithRealm {
|
||||
val readReceipt = ReadReceiptEntity.where(it, roomId, credentials.userId).findFirst()
|
||||
?: return@doWithRealm
|
||||
val liveChunk = ChunkEntity.findLastLiveChunkFromRoom(it, roomId)
|
||||
?: return@doWithRealm
|
||||
val readReceiptIndex = liveChunk.timelineEvents.find(readReceipt.eventId)?.root?.displayIndex
|
||||
?: Int.MIN_VALUE
|
||||
val eventToCheckIndex = liveChunk.timelineEvents.find(eventId)?.root?.displayIndex
|
||||
?: Int.MAX_VALUE
|
||||
isEventRead = eventToCheckIndex <= readReceiptIndex
|
||||
}
|
||||
return isEventRead
|
||||
return isEventRead(monarchy, credentials.userId, roomId, eventId)
|
||||
}
|
||||
|
||||
override fun getEventReadReceiptsLive(eventId: String): LiveData<List<ReadReceipt>> {
|
||||
|
@ -101,6 +101,7 @@ internal class DefaultSetReadMarkersTask @Inject constructor(private val roomAPI
|
||||
?: return@writeAsync
|
||||
roomSummary.notificationCount = 0
|
||||
roomSummary.highlightCount = 0
|
||||
roomSummary.hasUnreadMessages = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -113,12 +113,12 @@ internal class RoomSyncHandler @Inject constructor(private val monarchy: Monarch
|
||||
private fun handleJoinedRoom(realm: Realm,
|
||||
roomId: String,
|
||||
roomSync: RoomSync,
|
||||
isInitalSync: Boolean): RoomEntity {
|
||||
isInitialSync: Boolean): RoomEntity {
|
||||
|
||||
Timber.v("Handle join sync for room $roomId")
|
||||
|
||||
if (roomSync.ephemeral != null && roomSync.ephemeral.events.isNotEmpty()) {
|
||||
handleEphemeral(realm, roomId, roomSync.ephemeral, isInitalSync)
|
||||
handleEphemeral(realm, roomId, roomSync.ephemeral, isInitialSync)
|
||||
}
|
||||
|
||||
if (roomSync.accountData != null && roomSync.accountData.events.isNullOrEmpty().not()) {
|
||||
|
@ -23,7 +23,7 @@ import im.vector.riotx.core.resources.StringProvider
|
||||
import java.net.SocketTimeoutException
|
||||
import javax.inject.Inject
|
||||
|
||||
class ErrorFormatter @Inject constructor(val stringProvider: StringProvider) {
|
||||
class ErrorFormatter @Inject constructor(private val stringProvider: StringProvider) {
|
||||
|
||||
|
||||
fun toHumanReadable(failure: Failure): String {
|
||||
|
@ -34,8 +34,8 @@ import im.vector.riotx.core.ui.list.genericItem
|
||||
import java.util.*
|
||||
import javax.inject.Inject
|
||||
|
||||
class KeysBackupSettingsRecyclerViewController @Inject constructor(val stringProvider: StringProvider,
|
||||
val session: Session) : TypedEpoxyController<KeysBackupSettingViewState>() {
|
||||
class KeysBackupSettingsRecyclerViewController @Inject constructor(private val stringProvider: StringProvider,
|
||||
private val session: Session) : TypedEpoxyController<KeysBackupSettingViewState>() {
|
||||
|
||||
var listener: Listener? = null
|
||||
|
||||
|
@ -54,7 +54,7 @@ import kotlin.collections.HashMap
|
||||
*/
|
||||
|
||||
@Singleton
|
||||
class KeyRequestHandler @Inject constructor(val context: Context)
|
||||
class KeyRequestHandler @Inject constructor(private val context: Context)
|
||||
: RoomKeysRequestListener,
|
||||
SasVerificationService.SasVerificationListener {
|
||||
|
||||
|
@ -29,7 +29,7 @@ import javax.inject.Singleton
|
||||
* Listens to the VerificationManager and add a new notification when an incoming request is detected.
|
||||
*/
|
||||
@Singleton
|
||||
class IncomingVerificationRequestHandler @Inject constructor(val context: Context) : SasVerificationService.SasVerificationListener {
|
||||
class IncomingVerificationRequestHandler @Inject constructor(private val context: Context) : SasVerificationService.SasVerificationListener {
|
||||
|
||||
private var session: Session? = null
|
||||
|
||||
|
@ -658,7 +658,7 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro
|
||||
private fun observeSummaryState() {
|
||||
asyncSubscribe(RoomDetailViewState::asyncRoomSummary) { summary ->
|
||||
if (summary.membership == Membership.INVITE) {
|
||||
summary.latestEvent?.root?.senderId?.let { senderId ->
|
||||
summary.latestPreviewableEvent?.root?.senderId?.let { senderId ->
|
||||
session.getUser(senderId)
|
||||
}?.also {
|
||||
setState { copy(asyncInviter = Success(it)) }
|
||||
|
@ -25,14 +25,14 @@ class ChronologicalRoomComparator @Inject constructor() : Comparator<RoomSummary
|
||||
var rightTimestamp = 0L
|
||||
var leftTimestamp = 0L
|
||||
if (null != leftRoomSummary) {
|
||||
leftTimestamp = leftRoomSummary.latestEvent?.root?.originServerTs ?: 0
|
||||
leftTimestamp = leftRoomSummary.latestPreviewableEvent?.root?.originServerTs ?: 0
|
||||
}
|
||||
if (null != rightRoomSummary) {
|
||||
rightTimestamp = rightRoomSummary.latestEvent?.root?.originServerTs ?: 0
|
||||
rightTimestamp = rightRoomSummary.latestPreviewableEvent?.root?.originServerTs ?: 0
|
||||
}
|
||||
return if (rightRoomSummary?.latestEvent?.root == null) {
|
||||
return if (rightRoomSummary?.latestPreviewableEvent?.root == null) {
|
||||
-1
|
||||
} else if (leftRoomSummary?.latestEvent?.root == null) {
|
||||
} else if (leftRoomSummary?.latestPreviewableEvent?.root == null) {
|
||||
1
|
||||
} else {
|
||||
val deltaTimestamp = rightTimestamp - leftTimestamp
|
||||
|
@ -32,7 +32,7 @@ abstract class RoomCategoryItem : VectorEpoxyModel<RoomCategoryItem.Holder>() {
|
||||
|
||||
@EpoxyAttribute lateinit var title: CharSequence
|
||||
@EpoxyAttribute var expanded: Boolean = false
|
||||
@EpoxyAttribute var unreadCount: Int = 0
|
||||
@EpoxyAttribute var unreadNotificationCount: Int = 0
|
||||
@EpoxyAttribute var showHighlighted: Boolean = false
|
||||
@EpoxyAttribute var listener: (() -> Unit)? = null
|
||||
|
||||
@ -42,7 +42,7 @@ abstract class RoomCategoryItem : VectorEpoxyModel<RoomCategoryItem.Holder>() {
|
||||
val expandedArrowDrawable = ContextCompat.getDrawable(holder.rootView.context, expandedArrowDrawableRes)?.also {
|
||||
DrawableCompat.setTint(it, tintColor)
|
||||
}
|
||||
holder.unreadCounterBadgeView.render(UnreadCounterBadgeView.State(unreadCount, showHighlighted))
|
||||
holder.unreadCounterBadgeView.render(UnreadCounterBadgeView.State(unreadNotificationCount, showHighlighted))
|
||||
holder.titleView.setCompoundDrawablesWithIntrinsicBounds(expandedArrowDrawable, null, null, null)
|
||||
holder.titleView.text = title
|
||||
holder.rootView.setOnClickListener { listener?.invoke() }
|
||||
|
@ -101,7 +101,7 @@ class RoomSummaryController @Inject constructor(private val stringProvider: Stri
|
||||
id(titleRes)
|
||||
title(stringProvider.getString(titleRes).toUpperCase())
|
||||
expanded(isExpanded)
|
||||
unreadCount(unreadCount)
|
||||
unreadNotificationCount(unreadCount)
|
||||
showHighlighted(showHighlighted)
|
||||
listener {
|
||||
mutateExpandedState()
|
||||
|
@ -16,9 +16,11 @@
|
||||
|
||||
package im.vector.riotx.features.home.room.list
|
||||
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import androidx.core.view.isVisible
|
||||
import com.airbnb.epoxy.EpoxyAttribute
|
||||
import com.airbnb.epoxy.EpoxyModelClass
|
||||
import im.vector.riotx.R
|
||||
@ -36,7 +38,8 @@ abstract class RoomSummaryItem : VectorEpoxyModel<RoomSummaryItem.Holder>() {
|
||||
@EpoxyAttribute lateinit var lastFormattedEvent: CharSequence
|
||||
@EpoxyAttribute lateinit var lastEventTime: CharSequence
|
||||
@EpoxyAttribute var avatarUrl: String? = null
|
||||
@EpoxyAttribute var unreadCount: Int = 0
|
||||
@EpoxyAttribute var unreadNotificationCount: Int = 0
|
||||
@EpoxyAttribute var hasUnreadMessage: Boolean = false
|
||||
@EpoxyAttribute var showHighlighted: Boolean = false
|
||||
@EpoxyAttribute var listener: (() -> Unit)? = null
|
||||
|
||||
@ -47,13 +50,15 @@ abstract class RoomSummaryItem : VectorEpoxyModel<RoomSummaryItem.Holder>() {
|
||||
holder.titleView.text = roomName
|
||||
holder.lastEventTimeView.text = lastEventTime
|
||||
holder.lastEventView.text = lastFormattedEvent
|
||||
holder.unreadCounterBadgeView.render(UnreadCounterBadgeView.State(unreadCount, showHighlighted))
|
||||
holder.unreadCounterBadgeView.render(UnreadCounterBadgeView.State(unreadNotificationCount, showHighlighted))
|
||||
holder.unreadIndentIndicator.isVisible = hasUnreadMessage
|
||||
avatarRenderer.render(avatarUrl, roomId, roomName.toString(), holder.avatarImageView)
|
||||
}
|
||||
|
||||
class Holder : VectorEpoxyHolder() {
|
||||
val titleView by bind<TextView>(R.id.roomNameView)
|
||||
val unreadCounterBadgeView by bind<UnreadCounterBadgeView>(R.id.roomUnreadCounterBadgeView)
|
||||
val unreadIndentIndicator by bind<View>(R.id.roomUnreadIndicator)
|
||||
val lastEventView by bind<TextView>(R.id.roomLastEventView)
|
||||
val lastEventTimeView by bind<TextView>(R.id.roomLastEventTimeView)
|
||||
val avatarImageView by bind<ImageView>(R.id.roomAvatarImageView)
|
||||
|
@ -22,6 +22,7 @@ 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.message.MessageContent
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.date.VectorDateFormatter
|
||||
import im.vector.riotx.core.epoxy.VectorEpoxyModel
|
||||
import im.vector.riotx.core.extensions.localDateTime
|
||||
import im.vector.riotx.core.resources.ColorProvider
|
||||
@ -29,7 +30,6 @@ import im.vector.riotx.core.resources.DateProvider
|
||||
import im.vector.riotx.core.resources.StringProvider
|
||||
import im.vector.riotx.features.home.AvatarRenderer
|
||||
import im.vector.riotx.features.home.room.detail.timeline.format.NoticeEventFormatter
|
||||
import im.vector.riotx.core.date.VectorDateFormatter
|
||||
import im.vector.riotx.features.home.room.detail.timeline.helper.senderName
|
||||
import me.gujun.android.span.span
|
||||
import javax.inject.Inject
|
||||
@ -59,9 +59,9 @@ class RoomSummaryItemFactory @Inject constructor(private val noticeEventFormatte
|
||||
rejectingErrorRoomsIds: Set<String>,
|
||||
listener: RoomSummaryController.Listener?): VectorEpoxyModel<*> {
|
||||
val secondLine = if (roomSummary.isDirect) {
|
||||
roomSummary.latestEvent?.root?.senderId
|
||||
roomSummary.latestPreviewableEvent?.root?.senderId
|
||||
} else {
|
||||
roomSummary.latestEvent?.root?.senderId?.let {
|
||||
roomSummary.latestPreviewableEvent?.root?.senderId?.let {
|
||||
stringProvider.getString(R.string.invited_by, it)
|
||||
}
|
||||
}
|
||||
@ -88,7 +88,7 @@ class RoomSummaryItemFactory @Inject constructor(private val noticeEventFormatte
|
||||
|
||||
var latestFormattedEvent: CharSequence = ""
|
||||
var latestEventTime: CharSequence = ""
|
||||
val latestEvent = roomSummary.latestEvent
|
||||
val latestEvent = roomSummary.latestPreviewableEvent
|
||||
if (latestEvent != null) {
|
||||
val date = latestEvent.root.localDateTime()
|
||||
val currentDate = DateProvider.currentLocalDateTime()
|
||||
@ -131,7 +131,8 @@ class RoomSummaryItemFactory @Inject constructor(private val noticeEventFormatte
|
||||
.roomName(roomSummary.displayName)
|
||||
.avatarUrl(roomSummary.avatarUrl)
|
||||
.showHighlighted(showHighlighted)
|
||||
.unreadCount(unreadCount)
|
||||
.unreadNotificationCount(unreadCount)
|
||||
.hasUnreadMessage(roomSummary.hasUnreadMessages)
|
||||
.listener { listener?.onRoomSelected(roomSummary) }
|
||||
}
|
||||
|
||||
|
@ -40,7 +40,7 @@ import javax.inject.Singleton
|
||||
|
||||
@Singleton
|
||||
class EventHtmlRenderer @Inject constructor(context: Context,
|
||||
val avatarRenderer: AvatarRenderer,
|
||||
avatarRenderer: AvatarRenderer,
|
||||
sessionHolder: ActiveSessionHolder) {
|
||||
private val markwon = Markwon.builder(context)
|
||||
.usePlugin(MatrixPlugin.create(GlideApp.with(context), context, avatarRenderer, sessionHolder))
|
||||
|
@ -26,7 +26,7 @@ import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Singleton
|
||||
class BitmapLoader @Inject constructor(val context: Context) {
|
||||
class BitmapLoader @Inject constructor(private val context: Context) {
|
||||
|
||||
/**
|
||||
* Avatar Url -> Bitmap
|
||||
|
@ -28,7 +28,7 @@ import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Singleton
|
||||
class IconLoader @Inject constructor(val context: Context) {
|
||||
class IconLoader @Inject constructor(private val context: Context) {
|
||||
|
||||
/**
|
||||
* Avatar Url -> IconCompat
|
||||
|
@ -10,12 +10,22 @@
|
||||
android:focusable="true"
|
||||
android:foreground="?attr/selectableItemBackground">
|
||||
|
||||
<View
|
||||
android:id="@+id/roomUnreadIndicator"
|
||||
android:layout_width="4dp"
|
||||
android:layout_height="0dp"
|
||||
android:background="?attr/colorAccent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/roomAvatarImageView"
|
||||
android:layout_width="56dp"
|
||||
android:layout_height="56dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:layout_marginTop="12dp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
|
Loading…
Reference in New Issue
Block a user