mirror of
https://github.com/element-hq/element-android
synced 2024-11-24 10:25:35 +03:00
Bubbles: continue exploration
This commit is contained in:
parent
ad63d3de1c
commit
f7c9b36cef
8 changed files with 20 additions and 19 deletions
|
@ -3,7 +3,7 @@
|
|||
|
||||
<declare-styleable name="MessageBubble">
|
||||
<attr name="incoming_style" format="boolean" />
|
||||
<attr name="show_background" format="boolean" />
|
||||
<attr name="show_time_overlay" format="boolean" />
|
||||
<attr name="is_first" format="boolean" />
|
||||
<attr name="is_last" format="boolean" />
|
||||
</declare-styleable>
|
||||
|
|
|
@ -358,6 +358,9 @@ class TimelineEventController @Inject constructor(private val dateFormatter: Vec
|
|||
// Should be build if not cached or if model should be refreshed
|
||||
if (modelCache[position] == null || modelCache[position]?.isCacheable(partialState) == false) {
|
||||
val prevEvent = currentSnapshot.prevOrNull(position)
|
||||
val prevDisplayableEvent = currentSnapshot.subList(0, position).lastOrNull {
|
||||
timelineEventVisibilityHelper.shouldShowEvent(it, partialState.highlightedEventId)
|
||||
}
|
||||
val nextDisplayableEvent = currentSnapshot.subList(position + 1, currentSnapshot.size).firstOrNull {
|
||||
timelineEventVisibilityHelper.shouldShowEvent(it, partialState.highlightedEventId)
|
||||
}
|
||||
|
@ -365,6 +368,7 @@ class TimelineEventController @Inject constructor(private val dateFormatter: Vec
|
|||
val params = TimelineItemFactoryParams(
|
||||
event = event,
|
||||
prevEvent = prevEvent,
|
||||
prevDisplayableEvent = prevDisplayableEvent,
|
||||
nextEvent = nextEvent,
|
||||
nextDisplayableEvent = nextDisplayableEvent,
|
||||
partialState = partialState,
|
||||
|
|
|
@ -23,6 +23,7 @@ import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
|
|||
data class TimelineItemFactoryParams(
|
||||
val event: TimelineEvent,
|
||||
val prevEvent: TimelineEvent? = null,
|
||||
val prevDisplayableEvent: TimelineEvent? = null,
|
||||
val nextEvent: TimelineEvent? = null,
|
||||
val nextDisplayableEvent: TimelineEvent? = null,
|
||||
val partialState: TimelineEventController.PartialState = TimelineEventController.PartialState(),
|
||||
|
|
|
@ -57,19 +57,21 @@ class MessageInformationDataFactory @Inject constructor(private val session: Ses
|
|||
fun create(params: TimelineItemFactoryParams): MessageInformationData {
|
||||
val event = params.event
|
||||
val nextDisplayableEvent = params.nextDisplayableEvent
|
||||
val prevEvent = params.prevEvent
|
||||
val prevDisplayableEvent = params.prevDisplayableEvent
|
||||
val eventId = event.eventId
|
||||
val isSentByMe = event.root.senderId == session.myUserId
|
||||
val isFirstFromThisSender = nextDisplayableEvent?.root?.senderId != event.root.senderId
|
||||
val isLastFromThisSender = prevEvent?.root?.senderId != event.root.senderId
|
||||
val roomSummary = params.partialState.roomSummary
|
||||
|
||||
val date = event.root.localDateTime()
|
||||
val nextDate = nextDisplayableEvent?.root?.localDateTime()
|
||||
val addDaySeparator = date.toLocalDate() != nextDate?.toLocalDate()
|
||||
|
||||
val isNextMessageReceivedMoreThanOneHourAgo = nextDate?.isBefore(date.minusMinutes(60))
|
||||
?: false
|
||||
|
||||
val isFirstFromThisSender = nextDisplayableEvent?.root?.senderId != event.root.senderId || addDaySeparator
|
||||
val isLastFromThisSender = prevDisplayableEvent?.root?.senderId != event.root.senderId || prevDisplayableEvent?.root?.localDateTime()?.toLocalDate() != date.toLocalDate()
|
||||
|
||||
val showInformation =
|
||||
(addDaySeparator ||
|
||||
event.senderInfo.avatarUrl != nextDisplayableEvent?.senderInfo?.avatarUrl ||
|
||||
|
@ -77,7 +79,7 @@ class MessageInformationDataFactory @Inject constructor(private val session: Ses
|
|||
nextDisplayableEvent.root.getClearType() !in listOf(EventType.MESSAGE, EventType.STICKER, EventType.ENCRYPTED) ||
|
||||
isNextMessageReceivedMoreThanOneHourAgo ||
|
||||
isTileTypeMessage(nextDisplayableEvent) ||
|
||||
nextDisplayableEvent.isEdition() ) && !isSentByMe
|
||||
nextDisplayableEvent.isEdition()) && !isSentByMe
|
||||
|
||||
val time = dateFormatter.format(event.root.originServerTs, DateFormatKind.MESSAGE_SIMPLE)
|
||||
val e2eDecoration = getE2EDecoration(roomSummary, event)
|
||||
|
|
|
@ -29,7 +29,6 @@ import im.vector.app.core.epoxy.onClick
|
|||
import im.vector.app.core.files.LocalFilesHelper
|
||||
import im.vector.app.core.glide.GlideApp
|
||||
import im.vector.app.features.home.room.detail.timeline.helper.ContentUploadStateTrackerBinder
|
||||
import im.vector.app.features.home.room.detail.timeline.view.MessageBubbleView
|
||||
import im.vector.app.features.home.room.detail.timeline.view.MessageViewConfiguration
|
||||
import im.vector.app.features.media.ImageContentRenderer
|
||||
|
||||
|
@ -72,7 +71,7 @@ abstract class MessageImageVideoItem : AbsMessageItem<MessageImageVideoItem.Hold
|
|||
holder.mediaContentView.onClick(attributes.itemClickListener)
|
||||
holder.mediaContentView.setOnLongClickListener(attributes.itemLongClickListener)
|
||||
holder.playContentView.visibility = if (playable) View.VISIBLE else View.GONE
|
||||
(holder.view as? MessageViewConfiguration)?.displayBorder = false
|
||||
(holder.view as? MessageViewConfiguration)?.showTimeAsOverlay = false
|
||||
}
|
||||
|
||||
override fun unbind(holder: Holder) {
|
||||
|
|
|
@ -54,7 +54,7 @@ class MessageBubbleView @JvmOverloads constructor(context: Context, attrs: Attri
|
|||
render()
|
||||
}
|
||||
|
||||
override var displayBorder: Boolean = true
|
||||
override var showTimeAsOverlay: Boolean = true
|
||||
set(value) {
|
||||
field = value
|
||||
render()
|
||||
|
@ -66,7 +66,7 @@ class MessageBubbleView @JvmOverloads constructor(context: Context, attrs: Attri
|
|||
inflate(context, R.layout.view_message_bubble, this)
|
||||
context.withStyledAttributes(attrs, R.styleable.MessageBubble) {
|
||||
isIncoming = getBoolean(R.styleable.MessageBubble_incoming_style, false)
|
||||
displayBorder = getBoolean(R.styleable.MessageBubble_show_background, true)
|
||||
showTimeAsOverlay = getBoolean(R.styleable.MessageBubble_show_time_overlay, true)
|
||||
isFirstFromSender = getBoolean(R.styleable.MessageBubble_is_first, false)
|
||||
isLastFromSender = getBoolean(R.styleable.MessageBubble_is_last, false)
|
||||
}
|
||||
|
@ -109,13 +109,14 @@ class MessageBubbleView @JvmOverloads constructor(context: Context, attrs: Attri
|
|||
ConstraintSet().apply {
|
||||
clone(bubbleView)
|
||||
clear(R.id.viewStubContainer, ConstraintSet.END)
|
||||
if (displayBorder) {
|
||||
if (showTimeAsOverlay) {
|
||||
connect(R.id.viewStubContainer, ConstraintSet.END, R.id.messageTimeView, ConstraintSet.START, 0)
|
||||
} else {
|
||||
connect(R.id.viewStubContainer, ConstraintSet.END, R.id.parent, ConstraintSet.END, 0)
|
||||
}
|
||||
applyTo(bubbleView)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private fun createBackgroundDrawable(): Drawable {
|
||||
|
@ -147,12 +148,8 @@ class MessageBubbleView @JvmOverloads constructor(context: Context, attrs: Attri
|
|||
.setBottomRightCorner(bottomCornerFamily, bottomRadius)
|
||||
}
|
||||
val shapeAppearanceModel = shapeAppearanceModelBuilder.build()
|
||||
val shapeDrawable = MaterialShapeDrawable(shapeAppearanceModel)
|
||||
if (displayBorder) {
|
||||
shapeDrawable.fillColor = ContextCompat.getColorStateList(context, backgroundColor)
|
||||
} else {
|
||||
shapeDrawable.fillColor = ContextCompat.getColorStateList(context, android.R.color.transparent)
|
||||
return MaterialShapeDrawable(shapeAppearanceModel).apply {
|
||||
fillColor = ContextCompat.getColorStateList(context, backgroundColor)
|
||||
}
|
||||
return shapeDrawable
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,5 +20,5 @@ interface MessageViewConfiguration {
|
|||
var isIncoming: Boolean
|
||||
var isFirstFromSender: Boolean
|
||||
var isLastFromSender: Boolean
|
||||
var displayBorder: Boolean
|
||||
var showTimeAsOverlay: Boolean
|
||||
}
|
||||
|
|
|
@ -4,14 +4,12 @@
|
|||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/palette_element_green"
|
||||
tools:viewBindingIgnore="true">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/messageThumbnailView"
|
||||
android:layout_width="375dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginEnd="32dp"
|
||||
android:contentDescription="@string/a11y_image"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0"
|
||||
|
|
Loading…
Reference in a new issue