From 608bbdd4ee1bc8d75983c87568c76d09ff92f533 Mon Sep 17 00:00:00 2001 From: Valere Date: Fri, 10 May 2019 18:12:35 +0200 Subject: [PATCH 1/4] Refactoring / Use view ViewStub to avoid layout xml duplication --- .../features/home/AvatarRenderer.kt | 59 ++++++-- .../timeline/factory/MessageItemFactory.kt | 3 +- .../detail/timeline/item/AEventItemBase.kt | 82 +++++++++++ .../detail/timeline/item/AbsMessageItem.kt | 21 ++- .../room/detail/timeline/item/DefaultItem.kt | 19 ++- .../detail/timeline/item/MergedHeaderItem.kt | 23 +-- .../detail/timeline/item/MessageFileItem.kt | 25 ++-- .../timeline/item/MessageImageVideoItem.kt | 29 ++-- .../detail/timeline/item/MessageTextItem.kt | 11 +- .../room/detail/timeline/item/NoticeItem.kt | 29 ++-- ...ssage.xml => item_timeline_event_base.xml} | 62 ++++---- .../item_timeline_event_base_noinfo.xml | 43 ++++++ ...xml => item_timeline_event_blank_stub.xml} | 0 ...l => item_timeline_event_default_stub.xml} | 4 +- .../item_timeline_event_file_message.xml | 134 ------------------ .../layout/item_timeline_event_file_stub.xml | 67 +++++++++ ...tem_timeline_event_image_video_message.xml | 117 --------------- ...item_timeline_event_media_message_stub.xml | 47 ++++++ ...tem_timeline_event_merged_header_stub.xml} | 4 - .../res/layout/item_timeline_event_notice.xml | 38 ----- .../item_timeline_event_notice_stub.xml | 30 ++++ .../item_timeline_event_text_message_stub.xml | 9 ++ vector/src/main/res/values/styles_riot.xml | 21 +++ 23 files changed, 491 insertions(+), 386 deletions(-) create mode 100644 vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/AEventItemBase.kt rename vector/src/main/res/layout/{item_timeline_event_text_message.xml => item_timeline_event_base.xml} (55%) create mode 100644 vector/src/main/res/layout/item_timeline_event_base_noinfo.xml rename vector/src/main/res/layout/{item_timeline_event_blank.xml => item_timeline_event_blank_stub.xml} (100%) rename vector/src/main/res/layout/{item_timeline_event_default.xml => item_timeline_event_default_stub.xml} (81%) delete mode 100644 vector/src/main/res/layout/item_timeline_event_file_message.xml create mode 100644 vector/src/main/res/layout/item_timeline_event_file_stub.xml delete mode 100644 vector/src/main/res/layout/item_timeline_event_image_video_message.xml create mode 100644 vector/src/main/res/layout/item_timeline_event_media_message_stub.xml rename vector/src/main/res/layout/{item_timeline_event_merged_header.xml => item_timeline_event_merged_header_stub.xml} (94%) delete mode 100644 vector/src/main/res/layout/item_timeline_event_notice.xml create mode 100644 vector/src/main/res/layout/item_timeline_event_notice_stub.xml create mode 100644 vector/src/main/res/layout/item_timeline_event_text_message_stub.xml diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/AvatarRenderer.kt b/vector/src/main/java/im/vector/riotredesign/features/home/AvatarRenderer.kt index 70974710..012bdf83 100644 --- a/vector/src/main/java/im/vector/riotredesign/features/home/AvatarRenderer.kt +++ b/vector/src/main/java/im/vector/riotredesign/features/home/AvatarRenderer.kt @@ -20,6 +20,7 @@ import android.content.Context import android.graphics.drawable.Drawable import android.widget.ImageView import androidx.annotation.AnyThread +import androidx.annotation.ColorRes import androidx.annotation.UiThread import androidx.core.content.ContextCompat import com.amulyakhare.textdrawable.TextDrawable @@ -77,31 +78,35 @@ object AvatarRenderer { @AnyThread fun getPlaceholderDrawable(context: Context, identifier: String, text: String): Drawable { - val avatarColor = ContextCompat.getColor(context, getAvatarColor(identifier)) + val avatarColor = ContextCompat.getColor(context, getColorFromUserId(identifier)) return if (text.isEmpty()) { TextDrawable.builder().buildRound("", avatarColor) } else { val isUserId = MatrixPatterns.isUserId(text) val firstLetterIndex = if (isUserId) 1 else 0 val firstLetter = text[firstLetterIndex].toString().toUpperCase() - TextDrawable.builder().buildRound(firstLetter, avatarColor) + TextDrawable.builder() + .beginConfig() + .bold() + .endConfig() + .buildRound(firstLetter, avatarColor) } } // PRIVATE API ********************************************************************************* - private fun getAvatarColor(text: String? = null): Int { - var colorIndex: Long = 0 - if (!text.isNullOrEmpty()) { - var sum: Long = 0 - for (i in 0 until text.length) { - sum += text[i].toLong() - } - colorIndex = sum % AVATAR_COLOR_LIST.size - } - return AVATAR_COLOR_LIST[colorIndex.toInt()] - } +// private fun getAvatarColor(text: String? = null): Int { +// var colorIndex: Long = 0 +// if (!text.isNullOrEmpty()) { +// var sum: Long = 0 +// for (i in 0 until text.length) { +// sum += text[i].toLong() +// } +// colorIndex = sum % AVATAR_COLOR_LIST.size +// } +// return AVATAR_COLOR_LIST[colorIndex.toInt()] +// } private fun buildGlideRequest(glideRequest: GlideRequests, avatarUrl: String?): GlideRequest { val resolvedUrl = Matrix.getInstance().currentSession!!.contentUrlResolver() @@ -112,4 +117,32 @@ object AvatarRenderer { .apply(RequestOptions.circleCropTransform()) } + + //Based on riot-web implementation + @ColorRes + fun getColorFromUserId(sender: String): Int { + var hash = 0 + var i = 0 + var chr: Char + if (sender.isEmpty()) { + return R.color.username_1 + } + while (i < sender.length) { + chr = sender[i] + hash = (hash shl 5) - hash + chr.toInt() + hash = hash or 0 + i++ + } + val cI = Math.abs(hash) % 8 + 1 + return when (cI) { + 1 -> R.color.username_1 + 2 -> R.color.username_2 + 3 -> R.color.username_3 + 4 -> R.color.username_4 + 5 -> R.color.username_5 + 6 -> R.color.username_6 + 7 -> R.color.username_7 + else -> R.color.username_8 + } + } } \ No newline at end of file diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/factory/MessageItemFactory.kt b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/factory/MessageItemFactory.kt index f7849ff1..43ea34f3 100644 --- a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/factory/MessageItemFactory.kt +++ b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/factory/MessageItemFactory.kt @@ -32,6 +32,7 @@ import im.vector.riotredesign.core.extensions.localDateTime import im.vector.riotredesign.core.linkify.VectorLinkify import im.vector.riotredesign.core.resources.ColorProvider import im.vector.riotredesign.core.utils.DebouncedClickListener +import im.vector.riotredesign.features.home.AvatarRenderer import im.vector.riotredesign.features.home.room.detail.timeline.TimelineEventController import im.vector.riotredesign.features.home.room.detail.timeline.helper.TimelineDateFormatter import im.vector.riotredesign.features.home.room.detail.timeline.helper.TimelineMediaSizeProvider @@ -70,7 +71,7 @@ class MessageItemFactory(private val colorProvider: ColorProvider, val avatarUrl = event.senderAvatar val memberName = event.senderName ?: event.root.sender ?: "" val formattedMemberName = span(memberName) { - textColor = colorProvider.getColor(getColorFor(event.root.sender ?: "")) + textColor = colorProvider.getColor(AvatarRenderer.getColorFromUserId(event.root.sender ?: "")) } val informationData = MessageInformationData(eventId = eventId, senderId = event.root.sender ?: "", diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/AEventItemBase.kt b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/AEventItemBase.kt new file mode 100644 index 00000000..ab09d8af --- /dev/null +++ b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/AEventItemBase.kt @@ -0,0 +1,82 @@ +/* + * 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.detail.timeline.item + +import android.content.Context +import android.util.TypedValue +import android.view.View +import android.view.ViewStub +import androidx.annotation.IdRes +import androidx.constraintlayout.widget.Guideline +import im.vector.riotredesign.R +import im.vector.riotredesign.core.epoxy.VectorEpoxyHolder +import im.vector.riotredesign.core.epoxy.VectorEpoxyModel + +abstract class AEventItemBase : VectorEpoxyModel() { + + var avatarStyle: AvatarStyle = Companion.AvatarStyle.MEDIUM + + override fun bind(holder: H) { + super.bind(holder) + //optimize? + val px = dpToPx(avatarStyle.avatarSizeDP, holder.view.context) + holder.leftGuideline.setGuidelineBegin(px) + } + + + override fun getViewType(): Int { + return getStubType() + } + + abstract fun getStubType(): Int + + + abstract class BaseHolder : VectorEpoxyHolder() { + + val leftGuideline by bind(R.id.messageStartGuideline) + + @IdRes + abstract fun getStubId(): Int + + override fun bindView(itemView: View) { + super.bindView(itemView) + inflateStub() + } + + private fun inflateStub() { + view.findViewById(getStubId()).inflate() + } + + } + + companion object { + + enum class AvatarStyle(val avatarSizeDP: Int) { + BIG(50), + MEDIUM(40), + SMALL(30), + NONE(0) + } + + fun dpToPx(dp: Int, context: Context): Int { + return TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_DIP, + dp.toFloat(), + context.resources.displayMetrics + ).toInt() + } + } +} \ No newline at end of file diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/AbsMessageItem.kt b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/AbsMessageItem.kt index 4f2b02db..0bb45a64 100644 --- a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/AbsMessageItem.kt +++ b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/AbsMessageItem.kt @@ -19,13 +19,15 @@ package im.vector.riotredesign.features.home.room.detail.timeline.item import android.view.View import android.widget.ImageView import android.widget.TextView +import im.vector.riotredesign.R import com.airbnb.epoxy.EpoxyAttribute import com.jakewharton.rxbinding2.view.RxView import im.vector.riotredesign.core.epoxy.VectorEpoxyHolder import im.vector.riotredesign.core.epoxy.VectorEpoxyModel import im.vector.riotredesign.features.home.AvatarRenderer -abstract class AbsMessageItem : VectorEpoxyModel() { + +abstract class AbsMessageItem : AEventItemBase() { abstract val informationData: MessageInformationData @@ -41,6 +43,14 @@ abstract class AbsMessageItem : VectorEpoxyModel() override fun bind(holder: H) { super.bind(holder) if (informationData.showInformation) { + + val lp = holder.avatarImageView.layoutParams?.apply { + val size = dpToPx(avatarStyle.avatarSizeDP, holder.view.context) + height = size + width = size + } + holder.avatarImageView.layoutParams = lp + holder.avatarImageView.visibility = View.VISIBLE holder.avatarImageView.setOnClickListener(avatarClickListener) holder.memberNameView.visibility = View.VISIBLE @@ -63,10 +73,11 @@ abstract class AbsMessageItem : VectorEpoxyModel() alpha = if (informationData.sendState.isSent()) 1f else 0.5f } - abstract class Holder : VectorEpoxyHolder() { - abstract val avatarImageView: ImageView - abstract val memberNameView: TextView - abstract val timeView: TextView + abstract class Holder : BaseHolder() { + + val avatarImageView by bind(R.id.messageAvatarImageView) + val memberNameView by bind(R.id.messageMemberNameView) + val timeView by bind(R.id.messageTimeView) } } \ No newline at end of file diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/DefaultItem.kt b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/DefaultItem.kt index ea845fdc..5e3594c5 100644 --- a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/DefaultItem.kt +++ b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/DefaultItem.kt @@ -20,19 +20,26 @@ import android.widget.TextView import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyModelClass import im.vector.riotredesign.R -import im.vector.riotredesign.core.epoxy.VectorEpoxyHolder -import im.vector.riotredesign.core.epoxy.VectorEpoxyModel -@EpoxyModelClass(layout = R.layout.item_timeline_event_default) -abstract class DefaultItem : VectorEpoxyModel() { +@EpoxyModelClass(layout = R.layout.item_timeline_event_base_noinfo) +abstract class DefaultItem : AEventItemBase() { - @EpoxyAttribute var text: CharSequence? = null + @EpoxyAttribute + var text: CharSequence? = null override fun bind(holder: Holder) { holder.messageView.text = text } - class Holder : VectorEpoxyHolder() { + override fun getStubType(): Int = STUB_ID + + class Holder : BaseHolder() { + override fun getStubId(): Int = STUB_ID + val messageView by bind(R.id.stateMessageView) } + + companion object { + private val STUB_ID = R.id.messageContentDefaultStub + } } \ No newline at end of file diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/MergedHeaderItem.kt b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/MergedHeaderItem.kt index d5e05c11..227b0e1d 100644 --- a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/MergedHeaderItem.kt +++ b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/MergedHeaderItem.kt @@ -24,15 +24,14 @@ import android.widget.ImageView import android.widget.TextView import androidx.core.view.children import im.vector.riotredesign.R -import im.vector.riotredesign.core.epoxy.VectorEpoxyHolder -import im.vector.riotredesign.core.epoxy.VectorEpoxyModel import im.vector.riotredesign.features.home.AvatarRenderer + data class MergedHeaderItem(private val isCollapsed: Boolean, - private val mergeId: String, - private val mergeData: List, - private val onCollapsedStateChanged: (Boolean) -> Unit -) : VectorEpoxyModel() { + private val mergeId: String, + private val mergeData: List, + private val onCollapsedStateChanged: (Boolean) -> Unit +) : AEventItemBase() { private val distinctMergeData = mergeData.distinctBy { it.userId } @@ -41,13 +40,15 @@ data class MergedHeaderItem(private val isCollapsed: Boolean, } override fun getDefaultLayout(): Int { - return R.layout.item_timeline_event_merged_header + return R.layout.item_timeline_event_base_noinfo } override fun createNewHolder(): Holder { return Holder() } + override fun getStubType(): Int = STUB_ID + override fun bind(holder: Holder) { super.bind(holder) holder.expandView.setOnClickListener { @@ -84,11 +85,17 @@ data class MergedHeaderItem(private val isCollapsed: Boolean, val avatarUrl: String? ) - class Holder : VectorEpoxyHolder() { + class Holder : BaseHolder() { + override fun getStubId(): Int = STUB_ID + val expandView by bind(R.id.itemMergedExpandTextView) val summaryView by bind(R.id.itemMergedSummaryTextView) val separatorView by bind(R.id.itemMergedSeparatorView) val avatarListView by bind(R.id.itemMergedAvatarListView) } + + companion object { + private val STUB_ID = R.id.messageContentMergedheaderStub + } } \ No newline at end of file diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/MessageFileItem.kt b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/MessageFileItem.kt index edd3c779..66055984 100644 --- a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/MessageFileItem.kt +++ b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/MessageFileItem.kt @@ -26,13 +26,18 @@ import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyModelClass import im.vector.riotredesign.R -@EpoxyModelClass(layout = R.layout.item_timeline_event_file_message) +@EpoxyModelClass(layout = R.layout.item_timeline_event_base) abstract class MessageFileItem : AbsMessageItem() { - @EpoxyAttribute var filename: CharSequence = "" - @EpoxyAttribute @DrawableRes var iconRes: Int = 0 - @EpoxyAttribute override lateinit var informationData: MessageInformationData - @EpoxyAttribute var clickListener: View.OnClickListener? = null + @EpoxyAttribute + var filename: CharSequence = "" + @EpoxyAttribute + @DrawableRes + var iconRes: Int = 0 + @EpoxyAttribute + override lateinit var informationData: MessageInformationData + @EpoxyAttribute + var clickListener: View.OnClickListener? = null override fun bind(holder: Holder) { super.bind(holder) @@ -43,15 +48,19 @@ abstract class MessageFileItem : AbsMessageItem() { holder.filenameView.paintFlags = (holder.filenameView.paintFlags or Paint.UNDERLINE_TEXT_FLAG) } + override fun getStubType(): Int = STUB_ID class Holder : AbsMessageItem.Holder() { - override val avatarImageView by bind(R.id.messageAvatarImageView) - override val memberNameView by bind(R.id.messageMemberNameView) - override val timeView by bind(R.id.messageTimeView) + override fun getStubId(): Int = STUB_ID + val fileLayout by bind(R.id.messageFileLayout) val fileImageView by bind(R.id.messageFileImageView) val filenameView by bind(R.id.messageFilenameView) + } + companion object { + private val STUB_ID = R.id.messageContentFileStub + } } \ No newline at end of file diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/MessageImageVideoItem.kt b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/MessageImageVideoItem.kt index 5ddf2e97..b21be3ab 100644 --- a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/MessageImageVideoItem.kt +++ b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/MessageImageVideoItem.kt @@ -19,20 +19,23 @@ package im.vector.riotredesign.features.home.room.detail.timeline.item import android.view.View import android.view.ViewGroup import android.widget.ImageView -import android.widget.TextView import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyModelClass import im.vector.riotredesign.R import im.vector.riotredesign.features.home.room.detail.timeline.helper.ContentUploadStateTrackerBinder import im.vector.riotredesign.features.media.ImageContentRenderer -@EpoxyModelClass(layout = R.layout.item_timeline_event_image_video_message) +@EpoxyModelClass(layout = R.layout.item_timeline_event_base) abstract class MessageImageVideoItem : AbsMessageItem() { - @EpoxyAttribute lateinit var mediaData: ImageContentRenderer.Data - @EpoxyAttribute override lateinit var informationData: MessageInformationData - @EpoxyAttribute var playable: Boolean = false - @EpoxyAttribute var clickListener: View.OnClickListener? = null + @EpoxyAttribute + lateinit var mediaData: ImageContentRenderer.Data + @EpoxyAttribute + override lateinit var informationData: MessageInformationData + @EpoxyAttribute + var playable: Boolean = false + @EpoxyAttribute + var clickListener: View.OnClickListener? = null override fun bind(holder: Holder) { super.bind(holder) @@ -49,13 +52,21 @@ abstract class MessageImageVideoItem : AbsMessageItem(R.id.messageAvatarImageView) - override val memberNameView by bind(R.id.messageMemberNameView) - override val timeView by bind(R.id.messageTimeView) + + override fun getStubId(): Int = STUB_ID + val progressLayout by bind(R.id.messageMediaUploadProgressLayout) val imageView by bind(R.id.messageThumbnailView) val playContentView by bind(R.id.messageMediaPlayView) + + } + + + companion object { + private val STUB_ID = R.id.messageContentMediaStub } } \ No newline at end of file diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/MessageTextItem.kt b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/MessageTextItem.kt index 75c24225..790243c4 100644 --- a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/MessageTextItem.kt +++ b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/MessageTextItem.kt @@ -16,6 +16,7 @@ package im.vector.riotredesign.features.home.room.detail.timeline.item +import android.text.Spannable import android.view.View import android.widget.ImageView import android.widget.TextView @@ -33,7 +34,7 @@ import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch import kotlinx.coroutines.withContext -@EpoxyModelClass(layout = R.layout.item_timeline_event_text_message) +@EpoxyModelClass(layout = R.layout.item_timeline_event_base) abstract class MessageTextItem : AbsMessageItem() { @EpoxyAttribute @@ -67,12 +68,12 @@ abstract class MessageTextItem : AbsMessageItem() { } } + override fun getStubType(): Int = R.id.messageContentTextStub + class Holder : AbsMessageItem.Holder() { - override val avatarImageView by bind(R.id.messageAvatarImageView) - override val memberNameView by bind(R.id.messageMemberNameView) - override val timeView by bind(R.id.messageTimeView) val messageView by bind(R.id.messageTextView) + override fun getStubId(): Int = R.id.messageContentTextStub + } - } \ No newline at end of file diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/NoticeItem.kt b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/NoticeItem.kt index 3aa606eb..a16ac254 100644 --- a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/NoticeItem.kt +++ b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/NoticeItem.kt @@ -22,30 +22,41 @@ import android.widget.TextView import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyModelClass import im.vector.riotredesign.R -import im.vector.riotredesign.core.epoxy.VectorEpoxyHolder -import im.vector.riotredesign.core.epoxy.VectorEpoxyModel import im.vector.riotredesign.features.home.AvatarRenderer -@EpoxyModelClass(layout = R.layout.item_timeline_event_notice) -abstract class NoticeItem : VectorEpoxyModel() { +@EpoxyModelClass(layout = R.layout.item_timeline_event_base_noinfo) +abstract class NoticeItem : AEventItemBase() { - @EpoxyAttribute var noticeText: CharSequence? = null - @EpoxyAttribute var avatarUrl: String? = null - @EpoxyAttribute var userId: String = "" - @EpoxyAttribute var memberName: CharSequence? = null + @EpoxyAttribute + var noticeText: CharSequence? = null + @EpoxyAttribute + var avatarUrl: String? = null + @EpoxyAttribute + var userId: String = "" + @EpoxyAttribute + var memberName: CharSequence? = null @EpoxyAttribute var longClickListener: View.OnLongClickListener? = null override fun bind(holder: Holder) { + super.bind(holder) holder.noticeTextView.text = noticeText AvatarRenderer.render(avatarUrl, userId, memberName?.toString(), holder.avatarImageView) holder.view.setOnLongClickListener(longClickListener) } - class Holder : VectorEpoxyHolder() { + override fun getStubType(): Int = STUB_ID + + class Holder : BaseHolder() { + override fun getStubId(): Int = STUB_ID + val avatarImageView by bind(R.id.itemNoticeAvatarView) val noticeTextView by bind(R.id.itemNoticeTextView) } + + companion object { + private val STUB_ID = R.id.messageContentNoticeStub + } } \ No newline at end of file diff --git a/vector/src/main/res/layout/item_timeline_event_text_message.xml b/vector/src/main/res/layout/item_timeline_event_base.xml similarity index 55% rename from vector/src/main/res/layout/item_timeline_event_text_message.xml rename to vector/src/main/res/layout/item_timeline_event_base.xml index 774d6a11..e1f9d757 100644 --- a/vector/src/main/res/layout/item_timeline_event_text_message.xml +++ b/vector/src/main/res/layout/item_timeline_event_base.xml @@ -4,37 +4,42 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="wrap_content" - android:background="?attr/selectableItemBackground" - android:addStatesFromChildren="true" - android:paddingLeft="16dp" - android:paddingRight="16dp"> + android:paddingLeft="8dp" + android:paddingRight="8dp"> + + @@ -51,21 +56,26 @@ app:layout_constraintTop_toTopOf="@id/messageMemberNameView" tools:text="@tools:sample/date/hhmm" /> - + + + + + + \ No newline at end of file diff --git a/vector/src/main/res/layout/item_timeline_event_base_noinfo.xml b/vector/src/main/res/layout/item_timeline_event_base_noinfo.xml new file mode 100644 index 00000000..29f93bd3 --- /dev/null +++ b/vector/src/main/res/layout/item_timeline_event_base_noinfo.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/vector/src/main/res/layout/item_timeline_event_blank.xml b/vector/src/main/res/layout/item_timeline_event_blank_stub.xml similarity index 100% rename from vector/src/main/res/layout/item_timeline_event_blank.xml rename to vector/src/main/res/layout/item_timeline_event_blank_stub.xml diff --git a/vector/src/main/res/layout/item_timeline_event_default.xml b/vector/src/main/res/layout/item_timeline_event_default_stub.xml similarity index 81% rename from vector/src/main/res/layout/item_timeline_event_default.xml rename to vector/src/main/res/layout/item_timeline_event_default_stub.xml index 98fe706c..345bda0b 100644 --- a/vector/src/main/res/layout/item_timeline_event_default.xml +++ b/vector/src/main/res/layout/item_timeline_event_default_stub.xml @@ -4,10 +4,8 @@ android:id="@+id/stateMessageView" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginStart="64dp" - android:layout_marginLeft="64dp" android:gravity="center_vertical" - android:padding="16dp" + android:padding="8dp" android:textColor="?attr/colorAccent" android:textSize="14sp" android:textStyle="italic" diff --git a/vector/src/main/res/layout/item_timeline_event_file_message.xml b/vector/src/main/res/layout/item_timeline_event_file_message.xml deleted file mode 100644 index 58fa70df..00000000 --- a/vector/src/main/res/layout/item_timeline_event_file_message.xml +++ /dev/null @@ -1,134 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vector/src/main/res/layout/item_timeline_event_file_stub.xml b/vector/src/main/res/layout/item_timeline_event_file_stub.xml new file mode 100644 index 00000000..039d8092 --- /dev/null +++ b/vector/src/main/res/layout/item_timeline_event_file_stub.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + diff --git a/vector/src/main/res/layout/item_timeline_event_image_video_message.xml b/vector/src/main/res/layout/item_timeline_event_image_video_message.xml deleted file mode 100644 index 32e4ad2d..00000000 --- a/vector/src/main/res/layout/item_timeline_event_image_video_message.xml +++ /dev/null @@ -1,117 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vector/src/main/res/layout/item_timeline_event_media_message_stub.xml b/vector/src/main/res/layout/item_timeline_event_media_message_stub.xml new file mode 100644 index 00000000..5ea117e3 --- /dev/null +++ b/vector/src/main/res/layout/item_timeline_event_media_message_stub.xml @@ -0,0 +1,47 @@ + + + + + + + + + + \ No newline at end of file diff --git a/vector/src/main/res/layout/item_timeline_event_merged_header.xml b/vector/src/main/res/layout/item_timeline_event_merged_header_stub.xml similarity index 94% rename from vector/src/main/res/layout/item_timeline_event_merged_header.xml rename to vector/src/main/res/layout/item_timeline_event_merged_header_stub.xml index 862a15db..d4c78a01 100644 --- a/vector/src/main/res/layout/item_timeline_event_merged_header.xml +++ b/vector/src/main/res/layout/item_timeline_event_merged_header_stub.xml @@ -3,8 +3,6 @@ @@ -13,8 +11,6 @@ layout="@layout/vector_message_merge_avatar_list" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginStart="64dp" - android:layout_marginLeft="64dp" android:layout_marginTop="8dp" android:layout_marginEnd="16dp" android:layout_marginRight="16dp" diff --git a/vector/src/main/res/layout/item_timeline_event_notice.xml b/vector/src/main/res/layout/item_timeline_event_notice.xml deleted file mode 100644 index 318d5bbd..00000000 --- a/vector/src/main/res/layout/item_timeline_event_notice.xml +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/vector/src/main/res/layout/item_timeline_event_notice_stub.xml b/vector/src/main/res/layout/item_timeline_event_notice_stub.xml new file mode 100644 index 00000000..0e1dd00e --- /dev/null +++ b/vector/src/main/res/layout/item_timeline_event_notice_stub.xml @@ -0,0 +1,30 @@ + + + + + + + + \ No newline at end of file diff --git a/vector/src/main/res/layout/item_timeline_event_text_message_stub.xml b/vector/src/main/res/layout/item_timeline_event_text_message_stub.xml new file mode 100644 index 00000000..93c17c39 --- /dev/null +++ b/vector/src/main/res/layout/item_timeline_event_text_message_stub.xml @@ -0,0 +1,9 @@ + + diff --git a/vector/src/main/res/values/styles_riot.xml b/vector/src/main/res/values/styles_riot.xml index 374b5992..b04744d5 100644 --- a/vector/src/main/res/values/styles_riot.xml +++ b/vector/src/main/res/values/styles_riot.xml @@ -246,4 +246,25 @@ @color/riot_tertiary_text_color_status + + + + + + + \ No newline at end of file From 540989f38ac3675b80db9be77f3f8216475c992a Mon Sep 17 00:00:00 2001 From: Valere Date: Fri, 10 May 2019 18:43:06 +0200 Subject: [PATCH 2/4] Fix / ripple effect broken after merge --- .../room/detail/timeline/item/AbsMessageItem.kt | 3 +-- .../main/res/layout/item_timeline_event_base.xml | 14 ++++++++------ .../res/layout/item_timeline_event_base_noinfo.xml | 1 + 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/AbsMessageItem.kt b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/AbsMessageItem.kt index 0bb45a64..3f2cfd4b 100644 --- a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/AbsMessageItem.kt +++ b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/AbsMessageItem.kt @@ -44,12 +44,11 @@ abstract class AbsMessageItem : AEventItemBase() { super.bind(holder) if (informationData.showInformation) { - val lp = holder.avatarImageView.layoutParams?.apply { + holder.avatarImageView.layoutParams = holder.avatarImageView.layoutParams?.apply { val size = dpToPx(avatarStyle.avatarSizeDP, holder.view.context) height = size width = size } - holder.avatarImageView.layoutParams = lp holder.avatarImageView.visibility = View.VISIBLE holder.avatarImageView.setOnClickListener(avatarClickListener) diff --git a/vector/src/main/res/layout/item_timeline_event_base.xml b/vector/src/main/res/layout/item_timeline_event_base.xml index e1f9d757..80a0159e 100644 --- a/vector/src/main/res/layout/item_timeline_event_base.xml +++ b/vector/src/main/res/layout/item_timeline_event_base.xml @@ -4,6 +4,8 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="wrap_content" + android:addStatesFromChildren="true" + android:background="?attr/selectableItemBackground" android:paddingLeft="8dp" android:paddingRight="8dp"> @@ -18,11 +20,11 @@ tools:src="@tools:sample/avatars" /> + android:orientation="vertical" + tools:layout_constraintGuide_begin="44dp" /> + tools:ignore="MissingConstraints" + tools:visibility="visible" /> From 0c559976d699bbd8ef646ee4258d2758b866089c Mon Sep 17 00:00:00 2001 From: Valere Date: Mon, 13 May 2019 09:38:52 +0200 Subject: [PATCH 3/4] Default avatar style so small --- .../features/home/room/detail/timeline/item/AEventItemBase.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/AEventItemBase.kt b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/AEventItemBase.kt index ab09d8af..ad7d55d2 100644 --- a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/AEventItemBase.kt +++ b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/AEventItemBase.kt @@ -27,7 +27,7 @@ import im.vector.riotredesign.core.epoxy.VectorEpoxyModel abstract class AEventItemBase : VectorEpoxyModel() { - var avatarStyle: AvatarStyle = Companion.AvatarStyle.MEDIUM + var avatarStyle: AvatarStyle = Companion.AvatarStyle.SMALL override fun bind(holder: H) { super.bind(holder) From 73d5110d67bfd725f078348732542f39ca1e43dd Mon Sep 17 00:00:00 2001 From: Valere Date: Mon, 13 May 2019 16:29:33 +0200 Subject: [PATCH 4/4] Code review / Renamed base item class name --- .../home/room/detail/timeline/item/AbsMessageItem.kt | 5 +---- .../timeline/item/{AEventItemBase.kt => BaseEventItem.kt} | 2 +- .../features/home/room/detail/timeline/item/DefaultItem.kt | 2 +- .../home/room/detail/timeline/item/MergedHeaderItem.kt | 2 +- .../features/home/room/detail/timeline/item/NoticeItem.kt | 2 +- 5 files changed, 5 insertions(+), 8 deletions(-) rename vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/{AEventItemBase.kt => BaseEventItem.kt} (96%) diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/AbsMessageItem.kt b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/AbsMessageItem.kt index 3f2cfd4b..5ff41a01 100644 --- a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/AbsMessageItem.kt +++ b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/AbsMessageItem.kt @@ -21,13 +21,10 @@ import android.widget.ImageView import android.widget.TextView import im.vector.riotredesign.R import com.airbnb.epoxy.EpoxyAttribute -import com.jakewharton.rxbinding2.view.RxView -import im.vector.riotredesign.core.epoxy.VectorEpoxyHolder -import im.vector.riotredesign.core.epoxy.VectorEpoxyModel import im.vector.riotredesign.features.home.AvatarRenderer -abstract class AbsMessageItem : AEventItemBase() { +abstract class AbsMessageItem : BaseEventItem() { abstract val informationData: MessageInformationData diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/AEventItemBase.kt b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/BaseEventItem.kt similarity index 96% rename from vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/AEventItemBase.kt rename to vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/BaseEventItem.kt index ad7d55d2..7e6a2bc1 100644 --- a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/AEventItemBase.kt +++ b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/BaseEventItem.kt @@ -25,7 +25,7 @@ import im.vector.riotredesign.R import im.vector.riotredesign.core.epoxy.VectorEpoxyHolder import im.vector.riotredesign.core.epoxy.VectorEpoxyModel -abstract class AEventItemBase : VectorEpoxyModel() { +abstract class BaseEventItem : VectorEpoxyModel() { var avatarStyle: AvatarStyle = Companion.AvatarStyle.SMALL diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/DefaultItem.kt b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/DefaultItem.kt index 5e3594c5..3985e8c1 100644 --- a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/DefaultItem.kt +++ b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/DefaultItem.kt @@ -22,7 +22,7 @@ import com.airbnb.epoxy.EpoxyModelClass import im.vector.riotredesign.R @EpoxyModelClass(layout = R.layout.item_timeline_event_base_noinfo) -abstract class DefaultItem : AEventItemBase() { +abstract class DefaultItem : BaseEventItem() { @EpoxyAttribute var text: CharSequence? = null diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/MergedHeaderItem.kt b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/MergedHeaderItem.kt index 227b0e1d..6cdd7e15 100644 --- a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/MergedHeaderItem.kt +++ b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/MergedHeaderItem.kt @@ -31,7 +31,7 @@ data class MergedHeaderItem(private val isCollapsed: Boolean, private val mergeId: String, private val mergeData: List, private val onCollapsedStateChanged: (Boolean) -> Unit -) : AEventItemBase() { +) : BaseEventItem() { private val distinctMergeData = mergeData.distinctBy { it.userId } diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/NoticeItem.kt b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/NoticeItem.kt index a16ac254..dd06cb0c 100644 --- a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/NoticeItem.kt +++ b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/NoticeItem.kt @@ -25,7 +25,7 @@ import im.vector.riotredesign.R import im.vector.riotredesign.features.home.AvatarRenderer @EpoxyModelClass(layout = R.layout.item_timeline_event_base_noinfo) -abstract class NoticeItem : AEventItemBase() { +abstract class NoticeItem : BaseEventItem() { @EpoxyAttribute var noticeText: CharSequence? = null