mirror of
https://github.com/SchildiChat/SchildiChat-android.git
synced 2025-01-27 09:31:20 +01:00
Bubbles: make it works for file, voice and polls. Also add parity for "modern" layout.
This commit is contained in:
parent
d06df45e85
commit
1108ef9fbe
@ -2,9 +2,6 @@
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<!-- Tint color is provided by the theme -->
|
||||
<solid android:color="@android:color/black" />
|
||||
<size
|
||||
android:width="240dp"
|
||||
android:height="44dp" />
|
||||
<corners
|
||||
android:bottomLeftRadius="12dp"
|
||||
android:bottomRightRadius="12dp"
|
@ -2,16 +2,14 @@
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item android:id="@android:id/background">
|
||||
<shape>
|
||||
<corners android:radius="8dp" />
|
||||
<solid android:color="?vctr_room_active_widgets_banner_bg" />
|
||||
<shape android:shape="oval">
|
||||
<solid android:color="?vctr_system" />
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
<item android:id="@android:id/progress">
|
||||
<clip>
|
||||
<shape>
|
||||
<corners android:radius="8dp" />
|
||||
<shape android:shape="oval">
|
||||
<solid android:color="@color/vctr_notice_secondary_alpha12" />
|
||||
</shape>
|
||||
</clip>
|
||||
|
@ -15,6 +15,8 @@
|
||||
<dimen name="item_decoration_left_margin">72dp</dimen>
|
||||
<dimen name="item_event_message_state_size">16dp</dimen>
|
||||
|
||||
<dimen name="item_event_message_media_button_size">32dp</dimen>
|
||||
|
||||
<dimen name="chat_avatar_size">40dp</dimen>
|
||||
<dimen name="member_list_avatar_size">60dp</dimen>
|
||||
|
||||
@ -51,6 +53,7 @@
|
||||
|
||||
<dimen name="chat_bubble_margin_start">28dp</dimen>
|
||||
<dimen name="chat_bubble_margin_end">62dp</dimen>
|
||||
<dimen name="chat_bubble_fixed_size">300dp</dimen>
|
||||
|
||||
<!-- Onboarding -->
|
||||
<item name="ftue_auth_gutter_start_percent" format="float" type="dimen">0.05</item>
|
||||
|
@ -6,6 +6,7 @@
|
||||
<style name="Widget.Vector.ProgressBar.Horizontal.File">
|
||||
<item name="android:indeterminateOnly">false</item>
|
||||
<item name="android:progressDrawable">@drawable/file_progress_bar</item>
|
||||
<item name="android:progressBackgroundTint">?android:colorBackground</item>
|
||||
<item name="android:minHeight">10dp</item>
|
||||
<item name="android:maxHeight">40dp</item>
|
||||
</style>
|
||||
|
@ -12,4 +12,14 @@
|
||||
<item name="android:layout_marginTop">4dp</item>
|
||||
</style>
|
||||
|
||||
<style name="TimelineContentMediaPillStyle">
|
||||
<item name="android:paddingStart">8dp</item>
|
||||
<item name="android:paddingEnd">8dp</item>
|
||||
<item name="android:paddingTop">6dp</item>
|
||||
<item name="android:paddingBottom">6dp</item>
|
||||
<item name="minHeight">48dp</item>
|
||||
<item name="android:background">@drawable/bg_media_pill</item>
|
||||
<item name="android:backgroundTint">?vctr_content_quinary</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
@ -29,9 +29,7 @@ import org.matrix.android.sdk.api.session.file.ContentDownloadStateTracker
|
||||
import javax.inject.Inject
|
||||
|
||||
@ActivityScoped
|
||||
class ContentDownloadStateTrackerBinder @Inject constructor(private val activeSessionHolder: ActiveSessionHolder,
|
||||
private val messageColorProvider: MessageColorProvider,
|
||||
private val errorFormatter: ErrorFormatter) {
|
||||
class ContentDownloadStateTrackerBinder @Inject constructor(private val activeSessionHolder: ActiveSessionHolder){
|
||||
|
||||
private val updateListeners = mutableMapOf<String, ContentDownloadUpdater>()
|
||||
|
||||
@ -39,7 +37,7 @@ class ContentDownloadStateTrackerBinder @Inject constructor(private val activeSe
|
||||
holder: MessageFileItem.Holder) {
|
||||
activeSessionHolder.getSafeActiveSession()?.also { session ->
|
||||
val downloadStateTracker = session.contentDownloadProgressTracker()
|
||||
val updateListener = ContentDownloadUpdater(holder, messageColorProvider, errorFormatter)
|
||||
val updateListener = ContentDownloadUpdater(holder)
|
||||
updateListeners[mxcUrl] = updateListener
|
||||
downloadStateTracker.track(mxcUrl, updateListener)
|
||||
}
|
||||
@ -62,9 +60,7 @@ class ContentDownloadStateTrackerBinder @Inject constructor(private val activeSe
|
||||
}
|
||||
}
|
||||
|
||||
private class ContentDownloadUpdater(private val holder: MessageFileItem.Holder,
|
||||
private val messageColorProvider: MessageColorProvider,
|
||||
private val errorFormatter: ErrorFormatter) : ContentDownloadStateTracker.UpdateListener {
|
||||
private class ContentDownloadUpdater(private val holder: MessageFileItem.Holder) : ContentDownloadStateTracker.UpdateListener {
|
||||
|
||||
override fun onDownloadStateUpdate(state: ContentDownloadStateTracker.State) {
|
||||
when (state) {
|
||||
@ -124,7 +120,7 @@ private class ContentDownloadUpdater(private val holder: MessageFileItem.Holder,
|
||||
private fun handleSuccess() {
|
||||
stop()
|
||||
holder.fileDownloadProgress.isIndeterminate = false
|
||||
holder.fileDownloadProgress.progress = 100
|
||||
holder.fileDownloadProgress.progress = 0
|
||||
holder.fileImageView.setImageResource(R.drawable.ic_paperclip)
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,8 @@
|
||||
|
||||
package im.vector.app.features.home.room.detail.timeline.item
|
||||
|
||||
import android.content.res.ColorStateList
|
||||
import android.graphics.Color
|
||||
import android.graphics.Paint
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ImageView
|
||||
@ -29,6 +31,8 @@ import im.vector.app.R
|
||||
import im.vector.app.core.epoxy.onClick
|
||||
import im.vector.app.features.home.room.detail.timeline.helper.ContentDownloadStateTrackerBinder
|
||||
import im.vector.app.features.home.room.detail.timeline.helper.ContentUploadStateTrackerBinder
|
||||
import im.vector.app.features.home.room.detail.timeline.style.TimelineMessageLayout
|
||||
import im.vector.app.features.themes.ThemeUtils
|
||||
|
||||
@EpoxyModelClass(layout = R.layout.item_timeline_event_base)
|
||||
abstract class MessageFileItem : AbsMessageItem<MessageFileItem.Holder>() {
|
||||
@ -73,15 +77,19 @@ abstract class MessageFileItem : AbsMessageItem<MessageFileItem.Holder>() {
|
||||
} else {
|
||||
if (izDownloaded) {
|
||||
holder.fileImageView.setImageResource(iconRes)
|
||||
holder.fileDownloadProgress.progress = 100
|
||||
holder.fileDownloadProgress.progress = 0
|
||||
} else {
|
||||
contentDownloadStateTrackerBinder.bind(mxcUrl, holder)
|
||||
holder.fileImageView.setImageResource(R.drawable.ic_download)
|
||||
holder.fileDownloadProgress.progress = 0
|
||||
}
|
||||
}
|
||||
// holder.view.setOnClickListener(clickListener)
|
||||
|
||||
val backgroundTint = if(attributes.informationData.messageLayout is TimelineMessageLayout.Bubble){
|
||||
Color.TRANSPARENT
|
||||
}else {
|
||||
ThemeUtils.getColor(holder.view.context, R.attr.vctr_content_quinary)
|
||||
}
|
||||
holder.mainLayout.backgroundTintList = ColorStateList.valueOf(backgroundTint)
|
||||
holder.filenameView.onClick(attributes.itemClickListener)
|
||||
holder.filenameView.setOnLongClickListener(attributes.itemLongClickListener)
|
||||
holder.fileImageWrapper.onClick(attributes.itemClickListener)
|
||||
@ -98,6 +106,7 @@ abstract class MessageFileItem : AbsMessageItem<MessageFileItem.Holder>() {
|
||||
override fun getViewStubId() = STUB_ID
|
||||
|
||||
class Holder : AbsMessageItem.Holder(STUB_ID) {
|
||||
val mainLayout by bind<ViewGroup>(R.id.messageFileMainLayout)
|
||||
val progressLayout by bind<ViewGroup>(R.id.messageFileUploadProgressLayout)
|
||||
val fileLayout by bind<ViewGroup>(R.id.messageFileLayout)
|
||||
val fileImageView by bind<ImageView>(R.id.messageFileIconView)
|
||||
|
@ -29,6 +29,7 @@ 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.style.TimelineMessageLayout
|
||||
import im.vector.app.features.home.room.detail.timeline.view.MessageViewConfiguration
|
||||
import im.vector.app.features.media.ImageContentRenderer
|
||||
|
||||
@ -71,7 +72,8 @@ 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)?.showTimeAsOverlay = false
|
||||
(holder.view as? MessageViewConfiguration)?.showTimeAsOverlay = true
|
||||
holder.overlayView.isVisible = baseAttributes.informationData.messageLayout is TimelineMessageLayout.Bubble
|
||||
}
|
||||
|
||||
override fun unbind(holder: Holder) {
|
||||
@ -90,6 +92,7 @@ abstract class MessageImageVideoItem : AbsMessageItem<MessageImageVideoItem.Hold
|
||||
val imageView by bind<ImageView>(R.id.messageThumbnailView)
|
||||
val playContentView by bind<ImageView>(R.id.messageMediaPlayView)
|
||||
val mediaContentView by bind<ViewGroup>(R.id.messageContentMedia)
|
||||
val overlayView by bind<View>(R.id.messageMediaOverlayView)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
@ -16,10 +16,14 @@
|
||||
|
||||
package im.vector.app.features.home.room.detail.timeline.item
|
||||
|
||||
import android.content.res.ColorStateList
|
||||
import android.graphics.Color
|
||||
import android.text.format.DateUtils
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ImageButton
|
||||
import android.widget.TextView
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.view.isVisible
|
||||
import com.airbnb.epoxy.EpoxyAttribute
|
||||
import com.airbnb.epoxy.EpoxyModelClass
|
||||
@ -29,6 +33,8 @@ import im.vector.app.core.epoxy.ClickListener
|
||||
import im.vector.app.features.home.room.detail.timeline.helper.ContentDownloadStateTrackerBinder
|
||||
import im.vector.app.features.home.room.detail.timeline.helper.ContentUploadStateTrackerBinder
|
||||
import im.vector.app.features.home.room.detail.timeline.helper.VoiceMessagePlaybackTracker
|
||||
import im.vector.app.features.home.room.detail.timeline.style.TimelineMessageLayout
|
||||
import im.vector.app.features.themes.ThemeUtils
|
||||
|
||||
@EpoxyModelClass(layout = R.layout.item_timeline_event_base)
|
||||
abstract class MessageVoiceItem : AbsMessageItem<MessageVoiceItem.Holder>() {
|
||||
@ -80,6 +86,12 @@ abstract class MessageVoiceItem : AbsMessageItem<MessageVoiceItem.Holder>() {
|
||||
}
|
||||
}
|
||||
|
||||
val backgroundTint = if(attributes.informationData.messageLayout is TimelineMessageLayout.Bubble){
|
||||
Color.TRANSPARENT
|
||||
}else {
|
||||
ThemeUtils.getColor(holder.view.context, R.attr.vctr_content_quinary)
|
||||
}
|
||||
holder.voicePlaybackLayout.backgroundTintList = ColorStateList.valueOf(backgroundTint)
|
||||
holder.voicePlaybackControlButton.setOnClickListener { playbackControlButtonClickListener?.invoke(it) }
|
||||
|
||||
voiceMessagePlaybackTracker.track(attributes.informationData.eventId, object : VoiceMessagePlaybackTracker.Listener {
|
||||
@ -123,6 +135,7 @@ abstract class MessageVoiceItem : AbsMessageItem<MessageVoiceItem.Holder>() {
|
||||
override fun getViewStubId() = STUB_ID
|
||||
|
||||
class Holder : AbsMessageItem.Holder(STUB_ID) {
|
||||
val voicePlaybackLayout by bind<View>(R.id.voicePlaybackLayout)
|
||||
val voiceLayout by bind<ViewGroup>(R.id.voiceLayout)
|
||||
val voicePlaybackControlButton by bind<ImageButton>(R.id.voicePlaybackControlButton)
|
||||
val voicePlaybackTime by bind<TextView>(R.id.voicePlaybackTime)
|
||||
|
@ -35,11 +35,11 @@ class TimelineMessageLayoutFactory @Inject constructor(private val session: Sess
|
||||
companion object {
|
||||
private val EVENT_TYPES_WITH_BUBBLE_LAYOUT = setOf(
|
||||
EventType.MESSAGE,
|
||||
EventType.POLL_START,
|
||||
EventType.ENCRYPTED,
|
||||
EventType.STICKER
|
||||
)
|
||||
private val MSG_TYPES_WITHOUT_BUBBLE_LAYOUT = setOf(
|
||||
MessageType.MSGTYPE_POLL_START,
|
||||
MessageType.MSGTYPE_VERIFICATION_REQUEST
|
||||
)
|
||||
}
|
||||
@ -72,21 +72,22 @@ class TimelineMessageLayoutFactory @Inject constructor(private val session: Sess
|
||||
TimelineLayoutSettings.BUBBLE -> {
|
||||
val type = event.root.getClearType()
|
||||
if (type in EVENT_TYPES_WITH_BUBBLE_LAYOUT) {
|
||||
val messageContent = if (type == EventType.MESSAGE) params.event.getLastMessageContent() else null
|
||||
val messageContent = event.getLastMessageContent()
|
||||
if (messageContent?.msgType in MSG_TYPES_WITHOUT_BUBBLE_LAYOUT) {
|
||||
buildModernLayout(showInformation)
|
||||
}
|
||||
val isFirstFromThisSender = nextDisplayableEvent?.root?.senderId != event.root.senderId || addDaySeparator
|
||||
val isLastFromThisSender = prevDisplayableEvent?.root?.senderId != event.root.senderId ||
|
||||
prevDisplayableEvent?.root?.localDateTime()?.toLocalDate() != date.toLocalDate()
|
||||
} else {
|
||||
val isFirstFromThisSender = nextDisplayableEvent?.root?.senderId != event.root.senderId || addDaySeparator
|
||||
val isLastFromThisSender = prevDisplayableEvent?.root?.senderId != event.root.senderId ||
|
||||
prevDisplayableEvent?.root?.localDateTime()?.toLocalDate() != date.toLocalDate()
|
||||
|
||||
TimelineMessageLayout.Bubble(
|
||||
showAvatar = showInformation && !isSentByMe,
|
||||
showDisplayName = showInformation && !isSentByMe,
|
||||
isIncoming = !isSentByMe,
|
||||
isFirstFromThisSender = isFirstFromThisSender,
|
||||
isLastFromThisSender = isLastFromThisSender
|
||||
)
|
||||
TimelineMessageLayout.Bubble(
|
||||
showAvatar = showInformation && !isSentByMe,
|
||||
showDisplayName = showInformation && !isSentByMe,
|
||||
isIncoming = !isSentByMe,
|
||||
isFirstFromThisSender = isFirstFromThisSender,
|
||||
isLastFromThisSender = isLastFromThisSender,
|
||||
)
|
||||
}
|
||||
} else {
|
||||
buildModernLayout(showInformation)
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ import android.util.AttributeSet
|
||||
import android.view.View
|
||||
import android.view.ViewOutlineProvider
|
||||
import android.widget.RelativeLayout
|
||||
import android.widget.TextView
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.constraintlayout.widget.ConstraintSet
|
||||
import androidx.core.content.ContextCompat
|
||||
@ -38,7 +39,7 @@ import im.vector.app.features.themes.ThemeUtils
|
||||
|
||||
class MessageBubbleView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null,
|
||||
defStyleAttr: Int = 0) :
|
||||
RelativeLayout(context, attrs, defStyleAttr), MessageViewConfiguration {
|
||||
RelativeLayout(context, attrs, defStyleAttr), MessageViewConfiguration {
|
||||
|
||||
override var isIncoming: Boolean = false
|
||||
set(value) {
|
||||
@ -57,7 +58,7 @@ class MessageBubbleView @JvmOverloads constructor(context: Context, attrs: Attri
|
||||
render()
|
||||
}
|
||||
|
||||
override var showTimeAsOverlay: Boolean = true
|
||||
override var showTimeAsOverlay: Boolean = false
|
||||
set(value) {
|
||||
field = value
|
||||
render()
|
||||
@ -69,7 +70,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)
|
||||
showTimeAsOverlay = getBoolean(R.styleable.MessageBubble_show_time_overlay, true)
|
||||
showTimeAsOverlay = getBoolean(R.styleable.MessageBubble_show_time_overlay, false)
|
||||
isFirstFromSender = getBoolean(R.styleable.MessageBubble_is_first, false)
|
||||
isLastFromSender = getBoolean(R.styleable.MessageBubble_is_last, false)
|
||||
}
|
||||
@ -95,6 +96,9 @@ class MessageBubbleView @JvmOverloads constructor(context: Context, attrs: Attri
|
||||
findViewById<View>(R.id.messageEndGuideline).updateLayoutParams<LayoutParams> {
|
||||
marginEnd = resources.getDimensionPixelSize(R.dimen.chat_bubble_margin_end)
|
||||
}
|
||||
findViewById<View>(R.id.messageStartGuideline).updateLayoutParams<LayoutParams> {
|
||||
marginStart = resources.getDimensionPixelSize(R.dimen.chat_bubble_margin_start)
|
||||
}
|
||||
} else {
|
||||
val oppositeLayoutDirection = if (currentLayoutDirection == View.LAYOUT_DIRECTION_LTR) {
|
||||
View.LAYOUT_DIRECTION_RTL
|
||||
@ -108,14 +112,23 @@ class MessageBubbleView @JvmOverloads constructor(context: Context, attrs: Attri
|
||||
findViewById<View>(R.id.messageEndGuideline).updateLayoutParams<LayoutParams> {
|
||||
marginEnd = resources.getDimensionPixelSize(R.dimen.chat_bubble_margin_start)
|
||||
}
|
||||
findViewById<View>(R.id.messageStartGuideline).updateLayoutParams<LayoutParams> {
|
||||
marginStart = resources.getDimensionPixelSize(R.dimen.chat_bubble_margin_end)
|
||||
}
|
||||
}
|
||||
ConstraintSet().apply {
|
||||
clone(bubbleView)
|
||||
clear(R.id.viewStubContainer, ConstraintSet.END)
|
||||
if (showTimeAsOverlay) {
|
||||
connect(R.id.viewStubContainer, ConstraintSet.END, R.id.messageTimeView, ConstraintSet.START, 0)
|
||||
} else {
|
||||
val timeColor = ContextCompat.getColor(context, R.color.palette_white)
|
||||
findViewById<TextView>(R.id.messageTimeView).setTextColor(timeColor)
|
||||
connect(R.id.viewStubContainer, ConstraintSet.END, R.id.parent, ConstraintSet.END, 0)
|
||||
val margin = resources.getDimensionPixelSize(R.dimen.layout_horizontal_margin)
|
||||
setMargin(R.id.messageTimeView, ConstraintSet.END, margin)
|
||||
} else {
|
||||
val timeColor = ThemeUtils.getColor(context, R.attr.vctr_content_tertiary)
|
||||
findViewById<TextView>(R.id.messageTimeView).setTextColor(timeColor)
|
||||
connect(R.id.viewStubContainer, ConstraintSet.END, R.id.messageTimeView, ConstraintSet.START, 0)
|
||||
}
|
||||
applyTo(bubbleView)
|
||||
}
|
||||
|
8
vector/src/main/res/drawable/overlay_bubble_media.xml
Normal file
8
vector/src/main/res/drawable/overlay_bubble_media.xml
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<gradient
|
||||
android:type="linear"
|
||||
android:angle="270"
|
||||
android:startColor="#00000000"
|
||||
android:endColor="#33000000"/>
|
||||
</shape>
|
@ -78,14 +78,14 @@
|
||||
|
||||
<include
|
||||
android:id="@+id/viewStubContainer"
|
||||
layout="@layout/item_timeline_event_view_stubs_container"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
layout="@layout/item_timeline_event_view_stubs_container"
|
||||
android:layout_below="@id/messageMemberNameView"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_toStartOf="@id/messageSendStateImageView"
|
||||
android:layout_toEndOf="@id/messageStartGuideline"
|
||||
android:addStatesFromChildren="true"/>
|
||||
android:addStatesFromChildren="true" />
|
||||
|
||||
<im.vector.app.core.ui.views.SendStateImageView
|
||||
android:id="@+id/messageSendStateImageView"
|
||||
|
@ -1,80 +1,62 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout 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/messageFileLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="8dp"
|
||||
android:paddingBottom="8dp"
|
||||
android:orientation="vertical"
|
||||
tools:viewBindingIgnore="true">
|
||||
|
||||
<im.vector.app.core.ui.views.ShieldImageView
|
||||
android:id="@+id/messageFilee2eIcon"
|
||||
android:layout_width="14dp"
|
||||
android:layout_height="14dp"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<!-- the media type -->
|
||||
<RelativeLayout
|
||||
android:id="@+id/messageFileImageView"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_marginStart="4dp"
|
||||
app:layout_constraintStart_toEndOf="@id/messageFilee2eIcon"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<include layout="@layout/view_file_icon" />
|
||||
</RelativeLayout>
|
||||
|
||||
<!-- <ImageView-->
|
||||
<!-- android:id="@+id/messageFileImageView"-->
|
||||
<!-- android:layout_width="@dimen/chat_avatar_size"-->
|
||||
<!-- android:layout_height="@dimen/chat_avatar_size"-->
|
||||
<!-- android:layout_marginStart="4dp"-->
|
||||
<!-- app:layout_constraintStart_toEndOf="@id/messageFilee2eIcon"-->
|
||||
<!-- app:layout_constraintTop_toTopOf="parent"-->
|
||||
<!-- tools:src="@drawable/filetype_attachment" />-->
|
||||
|
||||
<!-- the media -->
|
||||
<TextView
|
||||
android:id="@+id/messageFilenameView"
|
||||
style="@style/Widget.Vector.TextView.Body"
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/messageFileMainLayout"
|
||||
style="@style/TimelineContentMediaPillStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="4dp"
|
||||
android:layout_marginEnd="32dp"
|
||||
android:autoLink="none"
|
||||
android:gravity="center_vertical"
|
||||
android:minHeight="@dimen/chat_avatar_size"
|
||||
app:layout_constrainedWidth="true"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0"
|
||||
app:layout_constraintStart_toEndOf="@id/messageFileImageView"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:text="A filename here" />
|
||||
tools:viewBindingIgnore="true">
|
||||
|
||||
<androidx.constraintlayout.widget.Barrier
|
||||
android:id="@+id/horizontalBarrier"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:barrierDirection="bottom"
|
||||
app:constraint_referenced_ids="messageFileImageView,messageFilenameView" />
|
||||
<FrameLayout
|
||||
android:id="@+id/messageFileImageView"
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="32dp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
<include layout="@layout/view_file_icon" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<!-- the file name-->
|
||||
<TextView
|
||||
android:id="@+id/messageFilenameView"
|
||||
style="@style/Widget.Vector.TextView.Body"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:autoLink="none"
|
||||
android:maxLines="1"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center_vertical"
|
||||
app:layout_constrainedWidth="true"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/messageFileImageView"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
tools:text="A filename here" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<include
|
||||
android:id="@+id/messageFileUploadProgressLayout"
|
||||
layout="@layout/media_upload_download_progress_layout"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="46dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginEnd="32dp"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/horizontalBarrier"
|
||||
tools:visibility="visible" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</LinearLayout>
|
@ -18,12 +18,24 @@
|
||||
tools:layout_height="300dp"
|
||||
tools:src="@tools:sample/backgrounds/scenic" />
|
||||
|
||||
<View
|
||||
android:id="@+id/messageMediaOverlayView"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:background="@drawable/overlay_bubble_media"
|
||||
android:elevation="2dp"
|
||||
app:layout_constraintStart_toStartOf="@id/messageThumbnailView"
|
||||
app:layout_constraintEnd_toEndOf="@id/messageThumbnailView"
|
||||
app:layout_constraintTop_toTopOf="@id/messageThumbnailView"
|
||||
app:layout_constraintBottom_toBottomOf="@id/messageThumbnailView"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/messageMediaPlayView"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:contentDescription="@string/action_play"
|
||||
android:src="@drawable/ic_material_play_circle"
|
||||
app:tint="?vctr_system"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="@id/messageThumbnailView"
|
||||
app:layout_constraintEnd_toEndOf="@id/messageThumbnailView"
|
||||
|
@ -2,17 +2,19 @@
|
||||
<androidx.constraintlayout.widget.ConstraintLayout 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:minWidth="@dimen/chat_bubble_fixed_size"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/questionTextView"
|
||||
style="@style/Widget.Vector.TextView.Subtitle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:textColor="?vctr_content_primary"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintHorizontal_bias="0"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
|
@ -30,6 +30,7 @@
|
||||
android:id="@+id/messageContentFileStub"
|
||||
style="@style/TimelineContentStubBaseParams"
|
||||
android:layout_height="wrap_content"
|
||||
tools:visibility="gone"
|
||||
android:layout="@layout/item_timeline_event_file_stub" />
|
||||
|
||||
<ViewStub
|
||||
@ -41,12 +42,14 @@
|
||||
<ViewStub
|
||||
android:id="@+id/messageContentVoiceStub"
|
||||
style="@style/TimelineContentStubBaseParams"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout="@layout/item_timeline_event_voice_stub"
|
||||
tools:visibility="visible" />
|
||||
tools:visibility="gone" />
|
||||
|
||||
<ViewStub
|
||||
android:id="@+id/messageContentPollStub"
|
||||
style="@style/TimelineContentStubBaseParams"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout="@layout/item_timeline_event_poll" />
|
||||
|
||||
|
||||
|
@ -1,31 +1,24 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout 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/voiceLayout"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minWidth="@dimen/chat_bubble_fixed_size"
|
||||
tools:viewBindingIgnore="true">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/voicePlaybackLayout"
|
||||
android:layout_width="0dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/bg_voice_playback"
|
||||
android:backgroundTint="?vctr_content_quinary"
|
||||
android:minHeight="48dp"
|
||||
android:paddingStart="8dp"
|
||||
android:paddingTop="6dp"
|
||||
android:paddingEnd="8dp"
|
||||
android:paddingBottom="6dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
style="@style/TimelineContentMediaPillStyle">
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/voicePlaybackControlButton"
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="32dp"
|
||||
android:layout_width="@dimen/item_event_message_media_button_size"
|
||||
android:layout_height="@dimen/item_event_message_media_button_size"
|
||||
android:background="@drawable/bg_voice_play_pause_button"
|
||||
android:backgroundTint="?android:colorBackground"
|
||||
android:contentDescription="@string/a11y_play_voice_message"
|
||||
@ -65,16 +58,12 @@
|
||||
<include
|
||||
android:id="@+id/messageFileUploadProgressLayout"
|
||||
layout="@layout/media_upload_download_progress_layout"
|
||||
android:layout_width="0dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="46dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginEnd="32dp"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/voicePlaybackLayout"
|
||||
tools:visibility="visible" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</LinearLayout>
|
||||
|
@ -2,22 +2,22 @@
|
||||
<merge 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:layout_width="50dp"
|
||||
android:layout_height="50dp"
|
||||
tools:parentTag="android.widget.RelativeLayout">
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="32dp"
|
||||
tools:parentTag="android.widget.FrameLayout">
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/messageFileProgressbar"
|
||||
style="@style/Widget.Vector.ProgressBar.Horizontal.File"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:progress="40" />
|
||||
tools:progress="40" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/messageFileIconView"
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
android:layout_centerInParent="true"
|
||||
android:layout_width="16dp"
|
||||
android:layout_height="16dp"
|
||||
android:layout_gravity="center"
|
||||
android:contentDescription="@string/attachment_type_file"
|
||||
android:src="@drawable/ic_download"
|
||||
app:tint="?vctr_notice_secondary"
|
||||
|
@ -105,7 +105,7 @@
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintWidth_max="300dp" />
|
||||
app:layout_constraintWidth_max="@dimen/chat_bubble_fixed_size" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/messageTimeView"
|
||||
|
@ -160,7 +160,7 @@
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:background="@drawable/bg_voice_playback"
|
||||
android:background="@drawable/bg_media_pill"
|
||||
android:backgroundTint="?vctr_content_quinary"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
|
Loading…
x
Reference in New Issue
Block a user