Render defaultItem as other item: display user avatar

Also ensure bottom sheet always has a header, for user avatar and date
This commit is contained in:
Benoit Marty 2020-01-23 15:35:46 +01:00
parent 426e291ce9
commit d530c64a84
7 changed files with 70 additions and 36 deletions

View File

@ -46,17 +46,14 @@ class MessageActionsEpoxyController @Inject constructor(
override fun buildModels(state: MessageActionState) {
// Message preview
val body = state.messageBody
if (body != null) {
bottomSheetMessagePreviewItem {
id("preview")
avatarRenderer(avatarRenderer)
matrixItem(state.informationData.matrixItem)
movementMethod(createLinkMovementMethod(listener))
userClicked { listener?.didSelectMenuAction(EventSharedAction.OpenUserProfile(state.informationData.senderId)) }
body(body.linkify(listener))
time(state.time())
}
bottomSheetMessagePreviewItem {
id("preview")
avatarRenderer(avatarRenderer)
matrixItem(state.informationData.matrixItem)
movementMethod(createLinkMovementMethod(listener))
userClicked { listener?.didSelectMenuAction(EventSharedAction.OpenUserProfile(state.informationData.senderId)) }
body(state.messageBody.linkify(listener))
time(state.time())
}
// Send state

View File

@ -15,7 +15,12 @@
*/
package im.vector.riotx.features.home.room.detail.timeline.action
import com.airbnb.mvrx.*
import com.airbnb.mvrx.Async
import com.airbnb.mvrx.FragmentViewModelContext
import com.airbnb.mvrx.MvRxState
import com.airbnb.mvrx.MvRxViewModelFactory
import com.airbnb.mvrx.Uninitialized
import com.airbnb.mvrx.ViewModelContext
import com.squareup.inject.assisted.Assisted
import com.squareup.inject.assisted.AssistedInject
import dagger.Lazy
@ -45,7 +50,8 @@ import im.vector.riotx.features.html.VectorHtmlCompressor
import im.vector.riotx.features.reactions.data.EmojiDataSource
import im.vector.riotx.features.settings.VectorPreferences
import java.text.SimpleDateFormat
import java.util.*
import java.util.Date
import java.util.Locale
/**
* Quick reactions state
@ -60,7 +66,7 @@ data class MessageActionState(
val eventId: String,
val informationData: MessageInformationData,
val timelineEvent: Async<TimelineEvent> = Uninitialized,
val messageBody: CharSequence? = null,
val messageBody: CharSequence = "",
// For quick reactions
val quickStates: Async<List<ToggleState>> = Uninitialized,
// For actions
@ -155,13 +161,16 @@ class MessageActionsViewModel @AssistedInject constructor(@Assisted
private fun observeTimelineEventState() {
asyncSubscribe(MessageActionState::timelineEvent) { timelineEvent ->
val computedMessage = computeMessageBody(timelineEvent)
val actions = actionsForEvent(timelineEvent)
setState { copy(messageBody = computedMessage, actions = actions) }
setState {
copy(
messageBody = computeMessageBody(timelineEvent),
actions = actionsForEvent(timelineEvent)
)
}
}
}
private fun computeMessageBody(timelineEvent: TimelineEvent): CharSequence? {
private fun computeMessageBody(timelineEvent: TimelineEvent): CharSequence {
return when (timelineEvent.root.getClearType()) {
EventType.MESSAGE,
EventType.STICKER -> {
@ -189,7 +198,7 @@ class MessageActionsViewModel @AssistedInject constructor(@Assisted
noticeEventFormatter.format(timelineEvent)
}
else -> null
}
} ?: ""
}
private fun actionsForEvent(timelineEvent: TimelineEvent): List<EventSharedAction> {

View File

@ -18,6 +18,7 @@ package im.vector.riotx.features.home.room.detail.timeline.item
import android.view.View
import android.view.ViewStub
import android.widget.RelativeLayout
import androidx.annotation.CallSuper
import androidx.annotation.IdRes
import androidx.core.view.updateLayoutParams
import com.airbnb.epoxy.EpoxyAttribute
@ -42,6 +43,7 @@ abstract class BaseEventItem<H : BaseEventItem.BaseHolder> : VectorEpoxyModel<H>
@EpoxyAttribute
lateinit var dimensionConverter: DimensionConverter
@CallSuper
override fun bind(holder: H) {
super.bind(holder)
holder.leftGuideline.updateLayoutParams<RelativeLayout.LayoutParams> {

View File

@ -17,6 +17,7 @@
package im.vector.riotx.features.home.room.detail.timeline.item
import android.view.View
import android.widget.ImageView
import android.widget.TextView
import com.airbnb.epoxy.EpoxyAttribute
import com.airbnb.epoxy.EpoxyModelClass
@ -50,8 +51,10 @@ abstract class DefaultItem : BaseEventItem<DefaultItem.Holder>() {
var text: CharSequence? = null
override fun bind(holder: Holder) {
holder.messageView.text = text
super.bind(holder)
holder.view.setOnLongClickListener(longClickListener)
avatarRenderer.render(informationData.matrixItem, holder.avatarView)
holder.messageView.text = text
holder.readReceiptsView.render(informationData.readReceipts, avatarRenderer, _readReceiptsClickListener)
}
@ -62,7 +65,8 @@ abstract class DefaultItem : BaseEventItem<DefaultItem.Holder>() {
override fun getViewType() = STUB_ID
class Holder : BaseHolder(STUB_ID) {
val messageView by bind<TextView>(R.id.stateMessageView)
val avatarView by bind<ImageView>(R.id.itemDefaultAvatarView)
val messageView by bind<TextView>(R.id.itemDefaultTextView)
}
companion object {

View File

@ -36,8 +36,9 @@
<ViewStub
android:id="@+id/messageContentDefaultStub"
style="@style/TimelineContentStubBaseParams"
android:inflatedId="@+id/stateMessageView"
android:layout="@layout/item_timeline_event_default_stub" />
android:layout="@layout/item_timeline_event_default_stub"
tools:layout_marginTop="80dp"
tools:visibility="visible" />
<ViewStub
android:id="@+id/messageContentBlankStub"
@ -49,7 +50,9 @@
<ViewStub
android:id="@+id/messageContentMergedHeaderStub"
style="@style/TimelineContentStubBaseParams"
android:layout="@layout/item_timeline_event_merged_header_stub" />
android:layout="@layout/item_timeline_event_merged_header_stub"
tools:layout_marginTop="160dp"
tools:visibility="visible" />
</FrameLayout>

View File

@ -1,12 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/stateMessageView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:padding="8dp"
android:textColor="?attr/colorAccent"
android:textSize="14sp"
android:textStyle="italic"
tools:text="Mon item" />
android:orientation="horizontal">
<ImageView
android:id="@+id/itemDefaultAvatarView"
android:layout_width="24dp"
android:layout_height="24dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:srcCompat="@tools:sample/avatars" />
<TextView
android:id="@+id/itemDefaultTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
android:textColor="?attr/colorAccent"
android:textSize="14sp"
android:textStyle="italic"
tools:text="@string/rendering_event_error_type_of_event_not_handled" />
</LinearLayout>

View File

@ -3,8 +3,8 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:orientation="horizontal"
android:layout_height="wrap_content">
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:id="@+id/itemNoticeAvatarView"
@ -15,16 +15,16 @@
tools:srcCompat="@tools:sample/avatars" />
<TextView
android:layout_gravity="top"
android:id="@+id/itemNoticeTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
android:textColor="?riotx_text_secondary"
android:textSize="14sp"
android:textStyle="italic"
tools:text="John doe changed their avatar" />
tools:text="@string/notice_avatar_url_changed" />
</LinearLayout>