Clean a bit code of timeline + show not handled events message

This commit is contained in:
ganfra 2018-11-02 17:37:37 +01:00
parent 6d9ec2789b
commit 2885b510ab
15 changed files with 132 additions and 71 deletions

View file

@ -1,5 +1,7 @@
package im.vector.riotredesign.features.home
import im.vector.riotredesign.features.home.room.detail.timeline.MessageItemFactory
import im.vector.riotredesign.features.home.room.detail.timeline.TextItemFactory
import im.vector.riotredesign.features.home.room.detail.timeline.TimelineDateFormatter
import im.vector.riotredesign.features.home.room.detail.timeline.TimelineEventController
import org.koin.dsl.context.ModuleDefinition
@ -14,12 +16,20 @@ class HomeModule(private val homeActivity: HomeActivity) : Module {
homeActivity as HomeNavigator
}
factory {
single {
TimelineDateFormatter(get())
}
factory {
TimelineEventController(get())
single {
MessageItemFactory(get())
}
single {
TextItemFactory()
}
single {
TimelineEventController(get(), get(), get())
}
}.invoke()

View file

@ -1,8 +1,13 @@
package im.vector.riotredesign.features.home.room.detail.timeline
import android.content.Context
import android.widget.FrameLayout
import com.airbnb.epoxy.ModelView
import im.vector.riotredesign.R
import im.vector.riotredesign.core.epoxy.KotlinModel
@ModelView(autoLayout = ModelView.Size.MATCH_WIDTH_WRAP_HEIGHT)
class BlankItem(context: Context) : FrameLayout(context)
class BlankItem
: KotlinModel(R.layout.item_event_blank) {
override fun bind() {
//no-op
}
}

View file

@ -4,7 +4,7 @@ import android.widget.TextView
import im.vector.riotredesign.R
import im.vector.riotredesign.core.epoxy.KotlinModel
data class TimelineDaySeparatorItem(
data class DaySeparatorItem(
val formattedDay: CharSequence
) : KotlinModel(R.layout.item_event_day_separator) {

View file

@ -7,7 +7,7 @@ import im.vector.riotredesign.R
import im.vector.riotredesign.core.epoxy.KotlinModel
import im.vector.riotredesign.features.home.AvatarRenderer
data class TimelineMessageItem(
data class MessageItem(
val message: CharSequence? = null,
val time: CharSequence? = null,
val avatarUrl: String?,

View file

@ -0,0 +1,34 @@
package im.vector.riotredesign.features.home.room.detail.timeline
import im.vector.matrix.android.api.session.events.model.EnrichedEvent
import im.vector.matrix.android.api.session.events.model.roomMember
import im.vector.matrix.android.api.session.room.model.MessageContent
import org.threeten.bp.LocalDateTime
class MessageItemFactory(private val timelineDateFormatter: TimelineDateFormatter) {
private val messagesDisplayedWithInformation = HashSet<String?>()
fun create(event: EnrichedEvent, nextEvent: EnrichedEvent?, addDaySeparator: Boolean, date: LocalDateTime): MessageItem? {
val messageContent = event.root.content<MessageContent>()
val roomMember = event.roomMember()
if (messageContent == null || roomMember == null) {
return null
}
val nextRoomMember = nextEvent?.roomMember()
if (addDaySeparator || nextRoomMember != roomMember) {
messagesDisplayedWithInformation.add(event.root.eventId)
}
val showInformation = messagesDisplayedWithInformation.contains(event.root.eventId)
return MessageItem(
message = messageContent.body,
avatarUrl = roomMember.avatarUrl,
showInformation = showInformation,
time = timelineDateFormatter.formatMessageHour(date),
memberName = roomMember.displayName
)
}
}

View file

@ -4,13 +4,13 @@ import android.widget.TextView
import im.vector.riotredesign.R
import im.vector.riotredesign.core.epoxy.KotlinModel
data class TimelineEventItem(
val title: String
) : KotlinModel(R.layout.item_event) {
data class TextItem(
val text: CharSequence? = null
) : KotlinModel(R.layout.item_event_text) {
val titleView by bind<TextView>(R.id.titleView)
private val messageView by bind<TextView>(R.id.stateMessageView)
override fun bind() {
titleView.text = title
messageView.text = text
}
}

View file

@ -0,0 +1,12 @@
package im.vector.riotredesign.features.home.room.detail.timeline
import im.vector.matrix.android.api.session.events.model.EnrichedEvent
class TextItemFactory {
fun create(event: EnrichedEvent): TextItem? {
val text = "${event.root.type} events are not yet handled"
return TextItem(text = text)
}
}

View file

@ -5,18 +5,17 @@ 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.events.model.roomMember
import im.vector.matrix.android.api.session.room.model.MessageContent
import im.vector.riotredesign.core.extensions.localDateTime
import im.vector.riotredesign.features.home.LoadingItemModel_
class TimelineEventController(private val timelineDateFormatter: TimelineDateFormatter) : EpoxyController(
class TimelineEventController(private val messageItemFactory: MessageItemFactory,
private val textItemFactory: TextItemFactory,
private val dateFormatter: TimelineDateFormatter
) : EpoxyController(
EpoxyAsyncUtil.getAsyncBackgroundHandler(),
EpoxyAsyncUtil.getAsyncBackgroundHandler()
) {
private val messagesDisplayedWithInformation = HashSet<String?>()
private val pagedListCallback = object : PagedList.Callback() {
override fun onChanged(position: Int, count: Int) {
requestModelBuild()
@ -54,38 +53,18 @@ class TimelineEventController(private val timelineDateFormatter: TimelineDateFor
val nextDate = nextEvent?.root?.localDateTime()
val addDaySeparator = date.toLocalDate() != nextDate?.toLocalDate()
if (event.root.type == EventType.MESSAGE) {
val messageContent = event.root.content<MessageContent>()
val roomMember = event.roomMember()
if (messageContent == null || roomMember == null) {
continue
}
val nextRoomMember = nextEvent?.roomMember()
if (addDaySeparator || nextRoomMember != roomMember) {
messagesDisplayedWithInformation.add(event.root.eventId)
}
val showInformation = messagesDisplayedWithInformation.contains(event.root.eventId)
TimelineMessageItem(
message = messageContent.body,
avatarUrl = roomMember.avatarUrl,
showInformation = showInformation,
time = timelineDateFormatter.formatMessageHour(date),
memberName = roomMember.displayName
)
.onBind { timeline?.loadAround(index) }
.id(event.root.eventId)
.addTo(this)
} else {
BlankItemModel_()
.id(event.root.eventId)
.onBind { _, _, _ -> timeline?.loadAround(index) }
.addTo(this)
val item = when (event.root.type) {
EventType.MESSAGE -> messageItemFactory.create(event, nextEvent, addDaySeparator, date)
else -> textItemFactory.create(event)
}
item
?.onBind { timeline?.loadAround(index) }
?.id(event.root.eventId)
?.addTo(this)
if (addDaySeparator) {
val formattedDay = timelineDateFormatter.formatMessageDay(date)
TimelineDaySeparatorItem(formattedDay).id(formattedDay).addTo(this)
val formattedDay = dateFormatter.formatMessageDay(date)
DaySeparatorItem(formattedDay).id(formattedDay).addTo(this)
}
}

View file

@ -15,8 +15,8 @@ data class RoomSummaryItem(
val listener: (() -> Unit)? = null
) : KotlinModel(R.layout.item_room) {
private val titleView by bind<TextView>(R.id.titleView)
private val avatarImageView by bind<ImageView>(R.id.messageAvatarImageView)
private val titleView by bind<TextView>(R.id.roomNameView)
private val avatarImageView by bind<ImageView>(R.id.roomAvatarImageView)
private val rootView by bind<CheckableFrameLayout>(R.id.itemRoomLayout)
override fun bind() {

View file

@ -1,9 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/titleView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:minHeight="80dp"
android:padding="16dp"
android:textSize="14sp" />

View file

@ -0,0 +1,3 @@
<View xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="0dp"
android:layout_height="0dp" />

View file

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/stateMessageView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="64dp"
android:gravity="center_vertical"
android:padding="16dp"
android:textColor="?attr/colorAccent"
android:textSize="14sp"
android:textStyle="italic"
tools:text="Mon item" />

View file

@ -21,7 +21,7 @@
android:minHeight="48dp">
<ImageView
android:id="@+id/messageAvatarImageView"
android:id="@+id/roomAvatarImageView"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_marginStart="16dp"
@ -31,7 +31,7 @@
tools:src="@tools:sample/avatars" />
<TextView
android:id="@+id/titleView"
android:id="@+id/roomNameView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
@ -40,7 +40,7 @@
android:textSize="14sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/messageAvatarImageView"
app:layout_constraintStart_toEndOf="@id/roomAvatarImageView"
app:layout_constraintTop_toTopOf="parent"
tools:text="@tools:sample/full_names" />

View file

@ -43,11 +43,4 @@ data class Event(
return moshiAdapter.fromJsonValue(data)
}
val isCallEvent: Boolean by lazy {
EventType.CALL_INVITE == type
|| EventType.CALL_CANDIDATES == type
|| EventType.CALL_ANSWER == type
|| EventType.CALL_HANGUP == type
}
}

View file

@ -46,4 +46,25 @@ object EventType {
const val CALL_ANSWER = "m.call.answer"
const val CALL_HANGUP = "m.call.hangup"
private val STATE_EVENTS = listOf(
STATE_ROOM_NAME,
STATE_ROOM_TOPIC,
STATE_ROOM_AVATAR,
STATE_ROOM_MEMBER,
STATE_ROOM_THIRD_PARTY_INVITE,
STATE_ROOM_CREATE,
STATE_ROOM_JOIN_RULES,
STATE_ROOM_GUEST_ACCESS,
STATE_ROOM_POWER_LEVELS,
STATE_ROOM_TOMBSTONE,
STATE_HISTORY_VISIBILITY,
STATE_RELATED_GROUPS,
STATE_PINNED_EVENT
)
fun isStateEvent(type: String): Boolean {
return STATE_EVENTS.contains(type)
}
}