forked from GitHub-Mirror/riotX-android
Clean a bit code of timeline + show not handled events message
This commit is contained in:
parent
6d9ec2789b
commit
2885b510ab
@ -1,5 +1,7 @@
|
|||||||
package im.vector.riotredesign.features.home
|
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.TimelineDateFormatter
|
||||||
import im.vector.riotredesign.features.home.room.detail.timeline.TimelineEventController
|
import im.vector.riotredesign.features.home.room.detail.timeline.TimelineEventController
|
||||||
import org.koin.dsl.context.ModuleDefinition
|
import org.koin.dsl.context.ModuleDefinition
|
||||||
@ -14,12 +16,20 @@ class HomeModule(private val homeActivity: HomeActivity) : Module {
|
|||||||
homeActivity as HomeNavigator
|
homeActivity as HomeNavigator
|
||||||
}
|
}
|
||||||
|
|
||||||
factory {
|
single {
|
||||||
TimelineDateFormatter(get())
|
TimelineDateFormatter(get())
|
||||||
}
|
}
|
||||||
|
|
||||||
factory {
|
single {
|
||||||
TimelineEventController(get())
|
MessageItemFactory(get())
|
||||||
|
}
|
||||||
|
|
||||||
|
single {
|
||||||
|
TextItemFactory()
|
||||||
|
}
|
||||||
|
|
||||||
|
single {
|
||||||
|
TimelineEventController(get(), get(), get())
|
||||||
}
|
}
|
||||||
|
|
||||||
}.invoke()
|
}.invoke()
|
||||||
|
@ -1,8 +1,13 @@
|
|||||||
package im.vector.riotredesign.features.home.room.detail.timeline
|
package im.vector.riotredesign.features.home.room.detail.timeline
|
||||||
|
|
||||||
import android.content.Context
|
import im.vector.riotredesign.R
|
||||||
import android.widget.FrameLayout
|
import im.vector.riotredesign.core.epoxy.KotlinModel
|
||||||
import com.airbnb.epoxy.ModelView
|
|
||||||
|
|
||||||
@ModelView(autoLayout = ModelView.Size.MATCH_WIDTH_WRAP_HEIGHT)
|
class BlankItem
|
||||||
class BlankItem(context: Context) : FrameLayout(context)
|
: KotlinModel(R.layout.item_event_blank) {
|
||||||
|
|
||||||
|
override fun bind() {
|
||||||
|
//no-op
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -4,7 +4,7 @@ import android.widget.TextView
|
|||||||
import im.vector.riotredesign.R
|
import im.vector.riotredesign.R
|
||||||
import im.vector.riotredesign.core.epoxy.KotlinModel
|
import im.vector.riotredesign.core.epoxy.KotlinModel
|
||||||
|
|
||||||
data class TimelineDaySeparatorItem(
|
data class DaySeparatorItem(
|
||||||
val formattedDay: CharSequence
|
val formattedDay: CharSequence
|
||||||
) : KotlinModel(R.layout.item_event_day_separator) {
|
) : KotlinModel(R.layout.item_event_day_separator) {
|
||||||
|
|
@ -7,7 +7,7 @@ import im.vector.riotredesign.R
|
|||||||
import im.vector.riotredesign.core.epoxy.KotlinModel
|
import im.vector.riotredesign.core.epoxy.KotlinModel
|
||||||
import im.vector.riotredesign.features.home.AvatarRenderer
|
import im.vector.riotredesign.features.home.AvatarRenderer
|
||||||
|
|
||||||
data class TimelineMessageItem(
|
data class MessageItem(
|
||||||
val message: CharSequence? = null,
|
val message: CharSequence? = null,
|
||||||
val time: CharSequence? = null,
|
val time: CharSequence? = null,
|
||||||
val avatarUrl: String?,
|
val avatarUrl: String?,
|
@ -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
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -4,13 +4,13 @@ import android.widget.TextView
|
|||||||
import im.vector.riotredesign.R
|
import im.vector.riotredesign.R
|
||||||
import im.vector.riotredesign.core.epoxy.KotlinModel
|
import im.vector.riotredesign.core.epoxy.KotlinModel
|
||||||
|
|
||||||
data class TimelineEventItem(
|
data class TextItem(
|
||||||
val title: String
|
val text: CharSequence? = null
|
||||||
) : KotlinModel(R.layout.item_event) {
|
) : 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() {
|
override fun bind() {
|
||||||
titleView.text = title
|
messageView.text = text
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -5,18 +5,17 @@ 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.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.riotredesign.core.extensions.localDateTime
|
import im.vector.riotredesign.core.extensions.localDateTime
|
||||||
import im.vector.riotredesign.features.home.LoadingItemModel_
|
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(),
|
||||||
EpoxyAsyncUtil.getAsyncBackgroundHandler()
|
EpoxyAsyncUtil.getAsyncBackgroundHandler()
|
||||||
) {
|
) {
|
||||||
|
|
||||||
private val messagesDisplayedWithInformation = 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()
|
||||||
@ -54,38 +53,18 @@ class TimelineEventController(private val timelineDateFormatter: TimelineDateFor
|
|||||||
val nextDate = nextEvent?.root?.localDateTime()
|
val nextDate = nextEvent?.root?.localDateTime()
|
||||||
val addDaySeparator = date.toLocalDate() != nextDate?.toLocalDate()
|
val addDaySeparator = date.toLocalDate() != nextDate?.toLocalDate()
|
||||||
|
|
||||||
if (event.root.type == EventType.MESSAGE) {
|
val item = when (event.root.type) {
|
||||||
val messageContent = event.root.content<MessageContent>()
|
EventType.MESSAGE -> messageItemFactory.create(event, nextEvent, addDaySeparator, date)
|
||||||
val roomMember = event.roomMember()
|
else -> textItemFactory.create(event)
|
||||||
if (messageContent == null || roomMember == null) {
|
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
|
item
|
||||||
|
?.onBind { timeline?.loadAround(index) }
|
||||||
|
?.id(event.root.eventId)
|
||||||
|
?.addTo(this)
|
||||||
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
if (addDaySeparator) {
|
if (addDaySeparator) {
|
||||||
val formattedDay = timelineDateFormatter.formatMessageDay(date)
|
val formattedDay = dateFormatter.formatMessageDay(date)
|
||||||
TimelineDaySeparatorItem(formattedDay).id(formattedDay).addTo(this)
|
DaySeparatorItem(formattedDay).id(formattedDay).addTo(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,8 +15,8 @@ data class RoomSummaryItem(
|
|||||||
val listener: (() -> Unit)? = null
|
val listener: (() -> Unit)? = null
|
||||||
) : 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.roomNameView)
|
||||||
private val avatarImageView by bind<ImageView>(R.id.messageAvatarImageView)
|
private val avatarImageView by bind<ImageView>(R.id.roomAvatarImageView)
|
||||||
private val rootView by bind<CheckableFrameLayout>(R.id.itemRoomLayout)
|
private val rootView by bind<CheckableFrameLayout>(R.id.itemRoomLayout)
|
||||||
|
|
||||||
override fun bind() {
|
override fun bind() {
|
||||||
|
@ -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" />
|
|
3
app/src/main/res/layout/item_event_blank.xml
Normal file
3
app/src/main/res/layout/item_event_blank.xml
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<View xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="0dp" />
|
13
app/src/main/res/layout/item_event_text.xml
Normal file
13
app/src/main/res/layout/item_event_text.xml
Normal 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" />
|
@ -21,7 +21,7 @@
|
|||||||
android:minHeight="48dp">
|
android:minHeight="48dp">
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/messageAvatarImageView"
|
android:id="@+id/roomAvatarImageView"
|
||||||
android:layout_width="32dp"
|
android:layout_width="32dp"
|
||||||
android:layout_height="32dp"
|
android:layout_height="32dp"
|
||||||
android:layout_marginStart="16dp"
|
android:layout_marginStart="16dp"
|
||||||
@ -31,7 +31,7 @@
|
|||||||
tools:src="@tools:sample/avatars" />
|
tools:src="@tools:sample/avatars" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/titleView"
|
android:id="@+id/roomNameView"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
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/messageAvatarImageView"
|
app:layout_constraintStart_toEndOf="@id/roomAvatarImageView"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
tools:text="@tools:sample/full_names" />
|
tools:text="@tools:sample/full_names" />
|
||||||
|
|
||||||
|
@ -43,11 +43,4 @@ data class Event(
|
|||||||
return moshiAdapter.fromJsonValue(data)
|
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
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
@ -46,4 +46,25 @@ object EventType {
|
|||||||
const val CALL_ANSWER = "m.call.answer"
|
const val CALL_ANSWER = "m.call.answer"
|
||||||
const val CALL_HANGUP = "m.call.hangup"
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user