Merge pull request #4610 from vector-im/feature/adm/url-preview

Updating URL preview design
This commit is contained in:
Benoit Marty 2021-12-07 17:35:50 +01:00 committed by GitHub
commit 7cf92ec17d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 105 additions and 97 deletions

1
changelog.d/4278.feature Normal file
View File

@ -0,0 +1 @@
Updates URL previews to match latest designs

View File

@ -39,4 +39,7 @@
<!-- Navigation Drawer --> <!-- Navigation Drawer -->
<dimen name="navigation_drawer_max_width">320dp</dimen> <dimen name="navigation_drawer_max_width">320dp</dimen>
<!-- Preview Url -->
<dimen name="preview_url_view_corner_radius">8dp</dimen>
</resources> </resources>

View File

@ -20,7 +20,7 @@ import android.content.Context
import android.content.res.ColorStateList import android.content.res.ColorStateList
import android.util.AttributeSet import android.util.AttributeSet
import androidx.appcompat.widget.AppCompatImageView import androidx.appcompat.widget.AppCompatImageView
import androidx.core.view.isVisible import androidx.core.view.isInvisible
import im.vector.app.R import im.vector.app.R
import im.vector.app.features.home.room.detail.timeline.item.SendStateDecoration import im.vector.app.features.home.room.detail.timeline.item.SendStateDecoration
import im.vector.app.features.themes.ThemeUtils import im.vector.app.features.themes.ThemeUtils
@ -38,28 +38,28 @@ class SendStateImageView @JvmOverloads constructor(
} }
fun render(sendState: SendStateDecoration) { fun render(sendState: SendStateDecoration) {
isVisible = when (sendState) { isInvisible = when (sendState) {
SendStateDecoration.SENDING_NON_MEDIA -> { SendStateDecoration.SENDING_NON_MEDIA -> {
setImageResource(R.drawable.ic_sending_message) setImageResource(R.drawable.ic_sending_message)
imageTintList = ColorStateList.valueOf(ThemeUtils.getColor(context, R.attr.vctr_content_tertiary)) imageTintList = ColorStateList.valueOf(ThemeUtils.getColor(context, R.attr.vctr_content_tertiary))
contentDescription = context.getString(R.string.event_status_a11y_sending) contentDescription = context.getString(R.string.event_status_a11y_sending)
true false
} }
SendStateDecoration.SENT -> { SendStateDecoration.SENT -> {
setImageResource(R.drawable.ic_message_sent) setImageResource(R.drawable.ic_message_sent)
imageTintList = ColorStateList.valueOf(ThemeUtils.getColor(context, R.attr.vctr_content_tertiary)) imageTintList = ColorStateList.valueOf(ThemeUtils.getColor(context, R.attr.vctr_content_tertiary))
contentDescription = context.getString(R.string.event_status_a11y_sent) contentDescription = context.getString(R.string.event_status_a11y_sent)
true false
} }
SendStateDecoration.FAILED -> { SendStateDecoration.FAILED -> {
setImageResource(R.drawable.ic_sending_message_failed) setImageResource(R.drawable.ic_sending_message_failed)
imageTintList = null imageTintList = null
contentDescription = context.getString(R.string.event_status_a11y_failed) contentDescription = context.getString(R.string.event_status_a11y_failed)
true false
} }
SendStateDecoration.SENDING_MEDIA, SendStateDecoration.SENDING_MEDIA,
SendStateDecoration.NONE -> { SendStateDecoration.NONE -> {
false true
} }
} }
} }

View File

@ -43,22 +43,12 @@ abstract class BaseEventItem<H : BaseEventItem.BaseHolder> : VectorEpoxyModel<H>
@EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash)
lateinit var dimensionConverter: DimensionConverter lateinit var dimensionConverter: DimensionConverter
protected var ignoreSendStatusVisibility = false
@CallSuper @CallSuper
override fun bind(holder: H) { override fun bind(holder: H) {
super.bind(holder) super.bind(holder)
holder.leftGuideline.updateLayoutParams<RelativeLayout.LayoutParams> { holder.leftGuideline.updateLayoutParams<RelativeLayout.LayoutParams> {
this.marginStart = leftGuideline this.marginStart = leftGuideline
} }
// Ignore visibility of the send status icon?
holder.contentContainer.updateLayoutParams<RelativeLayout.LayoutParams> {
if (ignoreSendStatusVisibility) {
addRule(RelativeLayout.ALIGN_PARENT_END)
} else {
removeRule(RelativeLayout.ALIGN_PARENT_END)
}
}
holder.checkableBackground.isChecked = highlighted holder.checkableBackground.isChecked = highlighted
} }

View File

@ -33,10 +33,6 @@ import im.vector.app.features.home.room.detail.timeline.helper.VoiceMessagePlayb
@EpoxyModelClass(layout = R.layout.item_timeline_event_base) @EpoxyModelClass(layout = R.layout.item_timeline_event_base)
abstract class MessageVoiceItem : AbsMessageItem<MessageVoiceItem.Holder>() { abstract class MessageVoiceItem : AbsMessageItem<MessageVoiceItem.Holder>() {
init {
ignoreSendStatusVisibility = true
}
@EpoxyAttribute @EpoxyAttribute
var mxcUrl: String = "" var mxcUrl: String = ""

View File

@ -19,13 +19,14 @@ package im.vector.app.features.home.room.detail.timeline.url
import android.content.Context import android.content.Context
import android.util.AttributeSet import android.util.AttributeSet
import android.view.View import android.view.View
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.view.isVisible import androidx.core.view.isVisible
import com.google.android.material.card.MaterialCardView
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.extensions.setTextOrHide import im.vector.app.core.extensions.setTextOrHide
import im.vector.app.databinding.ViewUrlPreviewBinding import im.vector.app.databinding.ViewUrlPreviewBinding
import im.vector.app.features.home.room.detail.timeline.TimelineEventController import im.vector.app.features.home.room.detail.timeline.TimelineEventController
import im.vector.app.features.media.ImageContentRenderer import im.vector.app.features.media.ImageContentRenderer
import im.vector.app.features.themes.ThemeUtils
import org.matrix.android.sdk.api.extensions.orFalse import org.matrix.android.sdk.api.extensions.orFalse
import org.matrix.android.sdk.api.session.media.PreviewUrlData import org.matrix.android.sdk.api.session.media.PreviewUrlData
@ -36,7 +37,7 @@ class PreviewUrlView @JvmOverloads constructor(
context: Context, context: Context,
attrs: AttributeSet? = null, attrs: AttributeSet? = null,
defStyleAttr: Int = 0 defStyleAttr: Int = 0
) : ConstraintLayout(context, attrs, defStyleAttr), View.OnClickListener { ) : MaterialCardView(context, attrs, defStyleAttr), View.OnClickListener {
private lateinit var views: ViewUrlPreviewBinding private lateinit var views: ViewUrlPreviewBinding
@ -44,6 +45,9 @@ class PreviewUrlView @JvmOverloads constructor(
init { init {
setupView() setupView()
radius = resources.getDimensionPixelSize(R.dimen.preview_url_view_corner_radius).toFloat()
cardElevation = 0f
setCardBackgroundColor(ThemeUtils.getColor(context, R.attr.vctr_system))
} }
private var state: PreviewUrlUiState = PreviewUrlUiState.Unknown private var state: PreviewUrlUiState = PreviewUrlUiState.Unknown
@ -121,9 +125,15 @@ class PreviewUrlView @JvmOverloads constructor(
private fun renderData(previewUrlData: PreviewUrlData, imageContentRenderer: ImageContentRenderer) { private fun renderData(previewUrlData: PreviewUrlData, imageContentRenderer: ImageContentRenderer) {
isVisible = true isVisible = true
views.urlPreviewTitle.setTextOrHide(previewUrlData.title) views.urlPreviewTitle.setTextOrHide(previewUrlData.title)
views.urlPreviewImage.isVisible = previewUrlData.mxcUrl?.let { imageContentRenderer.render(it, views.urlPreviewImage) }.orFalse() views.urlPreviewImage.isVisible = previewUrlData.mxcUrl?.let { imageContentRenderer.render(it, views.urlPreviewImage) }.orFalse()
views.urlPreviewDescription.setTextOrHide(previewUrlData.description) views.urlPreviewDescription.setTextOrHide(previewUrlData.description)
views.urlPreviewDescription.maxLines = when {
previewUrlData.mxcUrl != null -> 2
previewUrlData.title != null -> 3
else -> 5
}
views.urlPreviewSite.setTextOrHide(previewUrlData.siteName.takeIf { it != previewUrlData.title }) views.urlPreviewSite.setTextOrHide(previewUrlData.siteName.takeIf { it != previewUrlData.title })
} }

View File

@ -0,0 +1,23 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillAlpha="0.9"
android:fillColor="?vctr_content_quinary"
android:pathData="M24,12C24,18.6274 18.6274,24 12,24C5.3726,24 0,18.6274 0,12C0,5.3726 5.3726,0 12,0C18.6274,0 24,5.3726 24,12Z"
android:strokeAlpha="0.9" />
<path
android:fillColor="#00000000"
android:pathData="M7.9998,7.9998L15.9998,15.9998"
android:strokeWidth="1.33333"
android:strokeColor="?vctr_content_secondary"
android:strokeLineCap="round" />
<path
android:fillColor="#00000000"
android:pathData="M16.0005,7.9998L8.0006,15.9998"
android:strokeWidth="1.33333"
android:strokeColor="?vctr_content_secondary"
android:strokeLineCap="round" />
</vector>

View File

@ -80,6 +80,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@id/messageMemberNameView" android:layout_below="@id/messageMemberNameView"
android:layout_marginEnd="8dp"
android:layout_toStartOf="@id/messageSendStateImageView" android:layout_toStartOf="@id/messageSendStateImageView"
android:layout_toEndOf="@id/messageStartGuideline" android:layout_toEndOf="@id/messageStartGuideline"
android:addStatesFromChildren="true"> android:addStatesFromChildren="true">
@ -115,27 +116,23 @@
android:id="@+id/messageContentRedactedStub" android:id="@+id/messageContentRedactedStub"
style="@style/TimelineContentStubBaseParams" style="@style/TimelineContentStubBaseParams"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="56dp"
android:layout="@layout/item_timeline_event_redacted_stub" /> android:layout="@layout/item_timeline_event_redacted_stub" />
<ViewStub <ViewStub
android:id="@+id/messagePollStub" android:id="@+id/messagePollStub"
style="@style/TimelineContentStubBaseParams" style="@style/TimelineContentStubBaseParams"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="56dp"
android:layout="@layout/item_timeline_event_poll_stub" /> android:layout="@layout/item_timeline_event_poll_stub" />
<ViewStub <ViewStub
android:id="@+id/messageOptionsStub" android:id="@+id/messageOptionsStub"
style="@style/TimelineContentStubBaseParams" style="@style/TimelineContentStubBaseParams"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="56dp"
android:layout="@layout/item_timeline_event_option_buttons_stub" /> android:layout="@layout/item_timeline_event_option_buttons_stub" />
<ViewStub <ViewStub
android:id="@+id/messageContentVoiceStub" android:id="@+id/messageContentVoiceStub"
style="@style/TimelineContentStubBaseParams" style="@style/TimelineContentStubBaseParams"
android:layout_marginEnd="56dp"
android:layout="@layout/item_timeline_event_voice_stub" android:layout="@layout/item_timeline_event_voice_stub"
tools:visibility="visible" /> tools:visibility="visible" />
@ -152,7 +149,7 @@
android:layout_marginBottom="4dp" android:layout_marginBottom="4dp"
android:contentDescription="@string/event_status_a11y_sending" android:contentDescription="@string/event_status_a11y_sending"
android:src="@drawable/ic_sending_message" android:src="@drawable/ic_sending_message"
android:visibility="gone" android:visibility="invisible"
tools:tint="?vctr_content_tertiary" tools:tint="?vctr_content_tertiary"
tools:visibility="visible" /> tools:visibility="visible" />

View File

@ -16,7 +16,7 @@
<im.vector.app.features.home.room.detail.timeline.url.PreviewUrlView <im.vector.app.features.home.room.detail.timeline.url.PreviewUrlView
android:id="@+id/messageUrlPreview" android:id="@+id/messageUrlPreview"
android:layout_width="match_parent" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:layout_marginBottom="4dp" android:layout_marginBottom="4dp"

View File

@ -1,89 +1,77 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android" <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" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/informationUrlPreviewContainer" android:id="@+id/informationUrlPreviewContainer"
android:layout_width="match_parent" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
tools:parentTag="androidx.constraintlayout.widget.ConstraintLayout"> tools:parentTag="com.google.android.material.card.MaterialCardView">
<View <LinearLayout
android:id="@+id/url_preview_left_border" android:layout_width="wrap_content"
android:layout_width="2dp"
android:layout_height="0dp"
android:background="?vctr_content_tertiary"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/url_preview_title"
style="@style/Widget.Vector.TextView.Body"
android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="7dp" android:orientation="vertical">
android:ellipsize="end"
android:maxLines="2"
android:textColor="?vctr_content_primary"
android:textStyle="bold"
app:layout_constraintEnd_toStartOf="@id/url_preview_close"
app:layout_constraintStart_toStartOf="@id/url_preview_left_border"
app:layout_constraintTop_toTopOf="parent"
tools:text="Jo Malone denounces her former brand's John Boyega decision" />
<ImageView <ImageView
android:id="@+id/url_preview_image" android:id="@+id/url_preview_image"
android:layout_width="0dp" android:layout_width="wrap_content"
android:layout_height="157dp" android:layout_height="wrap_content"
android:layout_marginTop="16dp" android:adjustViewBounds="true"
android:importantForAccessibility="no" android:importantForAccessibility="no"
android:scaleType="fitStart" android:maxHeight="200dp"
app:layout_constraintEnd_toEndOf="parent" android:scaleType="fitXY"
app:layout_constraintStart_toStartOf="@id/url_preview_title" tools:src="@tools:sample/backgrounds/scenic" />
app:layout_constraintTop_toBottomOf="@id/url_preview_title"
tools:src="@tools:sample/backgrounds/scenic" />
<TextView <TextView
android:id="@+id/url_preview_description" android:id="@+id/url_preview_site"
style="@style/Widget.Vector.TextView.Body" style="@style/Widget.Vector.TextView.Caption"
android:layout_width="0dp" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="7dp" android:layout_marginStart="8dp"
android:layout_marginTop="8dp" android:layout_marginTop="6dp"
android:ellipsize="end" android:layout_marginEnd="8dp"
android:maxLines="4" android:ellipsize="end"
android:textColor="?vctr_content_secondary" android:maxLines="1"
app:layout_constraintEnd_toEndOf="parent" android:singleLine="true"
app:layout_constraintStart_toStartOf="@id/url_preview_left_border" android:textColor="?vctr_content_secondary"
app:layout_constraintTop_toBottomOf="@id/url_preview_image" tools:text="BBC News" />
tools:text="The British perfumer says removing actor John Boyega from his own advert was “utterly despicable”." />
<TextView <TextView
android:id="@+id/url_preview_site" android:id="@+id/url_preview_title"
style="@style/Widget.Vector.TextView.Body" style="@style/Widget.Vector.TextView.Body.Medium"
android:layout_width="0dp" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="7dp" android:layout_marginStart="8dp"
android:layout_marginTop="4dp" android:layout_marginTop="4dp"
android:ellipsize="end" android:layout_marginEnd="@dimen/layout_touch_size"
android:maxLines="1" android:ellipsize="end"
android:singleLine="true" android:maxLines="2"
android:textColor="?vctr_content_tertiary" android:textColor="?vctr_content_primary"
app:layout_constraintEnd_toEndOf="parent" android:textStyle="bold"
app:layout_constraintStart_toStartOf="@id/url_preview_left_border" tools:text="Jo Malone denounces her former brand's John Boyega decision" />
app:layout_constraintTop_toBottomOf="@id/url_preview_description"
tools:text="BBC News" /> <TextView
android:id="@+id/url_preview_description"
style="@style/Widget.Vector.TextView.Body"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="4dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
android:ellipsize="end"
android:textColor="?vctr_content_secondary"
tools:text="The British perfumer says removing actor John Boyega from his own advert was “utterly despicable”." />
</LinearLayout>
<ImageView <ImageView
android:id="@+id/url_preview_close" android:id="@+id/url_preview_close"
android:layout_width="@dimen/layout_touch_size" android:layout_width="@dimen/layout_touch_size"
android:layout_height="@dimen/layout_touch_size" android:layout_height="@dimen/layout_touch_size"
android:layout_gravity="top|end"
android:contentDescription="@string/action_close" android:contentDescription="@string/action_close"
android:scaleType="center" android:scaleType="center"
android:src="@drawable/ic_close_24dp" android:src="@drawable/ic_close_with_circular_bg"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:tint="?vctr_content_secondary"
tools:ignore="MissingPrefix" /> tools:ignore="MissingPrefix" />
</merge> </merge>