diff --git a/app/src/main/java/im/vector/riotredesign/features/home/HomeModule.kt b/app/src/main/java/im/vector/riotredesign/features/home/HomeModule.kt index d87f6bff8a..f8c27d1323 100644 --- a/app/src/main/java/im/vector/riotredesign/features/home/HomeModule.kt +++ b/app/src/main/java/im/vector/riotredesign/features/home/HomeModule.kt @@ -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() diff --git a/app/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/BlankItem.kt b/app/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/BlankItem.kt index 2c58e289c7..264d6da80e 100644 --- a/app/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/BlankItem.kt +++ b/app/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/BlankItem.kt @@ -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) \ No newline at end of file +class BlankItem + : KotlinModel(R.layout.item_event_blank) { + + override fun bind() { + //no-op + } + +} \ No newline at end of file diff --git a/app/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/TimelineDaySeparatorItem.kt b/app/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/DaySeparatorItem.kt similarity index 91% rename from app/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/TimelineDaySeparatorItem.kt rename to app/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/DaySeparatorItem.kt index 6a533590fc..7fbcb2ae90 100644 --- a/app/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/TimelineDaySeparatorItem.kt +++ b/app/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/DaySeparatorItem.kt @@ -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) { diff --git a/app/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/TimelineMessageItem.kt b/app/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/MessageItem.kt similarity index 97% rename from app/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/TimelineMessageItem.kt rename to app/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/MessageItem.kt index f8a8ead364..52ae2159a7 100644 --- a/app/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/TimelineMessageItem.kt +++ b/app/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/MessageItem.kt @@ -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?, diff --git a/app/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/MessageItemFactory.kt b/app/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/MessageItemFactory.kt new file mode 100644 index 0000000000..ca5f2d9e2b --- /dev/null +++ b/app/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/MessageItemFactory.kt @@ -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() + + fun create(event: EnrichedEvent, nextEvent: EnrichedEvent?, addDaySeparator: Boolean, date: LocalDateTime): MessageItem? { + val messageContent = event.root.content() + 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 + ) + } + + +} \ No newline at end of file diff --git a/app/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/TimelineEventItem.kt b/app/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/TextItem.kt similarity index 51% rename from app/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/TimelineEventItem.kt rename to app/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/TextItem.kt index 570bfcc598..8848b58bd9 100644 --- a/app/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/TimelineEventItem.kt +++ b/app/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/TextItem.kt @@ -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(R.id.titleView) + private val messageView by bind(R.id.stateMessageView) override fun bind() { - titleView.text = title + messageView.text = text } } \ No newline at end of file diff --git a/app/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/TextItemFactory.kt b/app/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/TextItemFactory.kt new file mode 100644 index 0000000000..e123d7f8bc --- /dev/null +++ b/app/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/TextItemFactory.kt @@ -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) + } + +} \ No newline at end of file diff --git a/app/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/TimelineEventController.kt b/app/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/TimelineEventController.kt index 0fef3fcb89..c8e95fa13f 100644 --- a/app/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/TimelineEventController.kt +++ b/app/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/TimelineEventController.kt @@ -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() - 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() - 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) } } diff --git a/app/src/main/java/im/vector/riotredesign/features/home/room/list/RoomSummaryItem.kt b/app/src/main/java/im/vector/riotredesign/features/home/room/list/RoomSummaryItem.kt index 8e5d837fdd..cbe4df6d72 100644 --- a/app/src/main/java/im/vector/riotredesign/features/home/room/list/RoomSummaryItem.kt +++ b/app/src/main/java/im/vector/riotredesign/features/home/room/list/RoomSummaryItem.kt @@ -15,8 +15,8 @@ data class RoomSummaryItem( val listener: (() -> Unit)? = null ) : KotlinModel(R.layout.item_room) { - private val titleView by bind(R.id.titleView) - private val avatarImageView by bind(R.id.messageAvatarImageView) + private val titleView by bind(R.id.roomNameView) + private val avatarImageView by bind(R.id.roomAvatarImageView) private val rootView by bind(R.id.itemRoomLayout) override fun bind() { diff --git a/app/src/main/res/layout/item_event.xml b/app/src/main/res/layout/item_event.xml deleted file mode 100644 index de61c99230..0000000000 --- a/app/src/main/res/layout/item_event.xml +++ /dev/null @@ -1,9 +0,0 @@ - - \ No newline at end of file diff --git a/app/src/main/res/layout/item_event_blank.xml b/app/src/main/res/layout/item_event_blank.xml new file mode 100644 index 0000000000..b94bf30dd3 --- /dev/null +++ b/app/src/main/res/layout/item_event_blank.xml @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/app/src/main/res/layout/item_event_text.xml b/app/src/main/res/layout/item_event_text.xml new file mode 100644 index 0000000000..45bb106446 --- /dev/null +++ b/app/src/main/res/layout/item_event_text.xml @@ -0,0 +1,13 @@ + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_room.xml b/app/src/main/res/layout/item_room.xml index d53c2101a4..8de9ae646d 100644 --- a/app/src/main/res/layout/item_room.xml +++ b/app/src/main/res/layout/item_room.xml @@ -21,7 +21,7 @@ android:minHeight="48dp"> diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/events/model/Event.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/events/model/Event.kt index 06cc008824..6282d9c9e4 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/events/model/Event.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/events/model/Event.kt @@ -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 - } - } \ No newline at end of file diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/events/model/EventType.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/events/model/EventType.kt index bfb0bdc89a..58db936ce3 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/events/model/EventType.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/events/model/EventType.kt @@ -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) + } + } \ No newline at end of file