From d3700cecc3ec93f186dec58ca082231c432d9e40 Mon Sep 17 00:00:00 2001 From: SpiritCroc Date: Tue, 22 Dec 2020 10:49:11 +0100 Subject: [PATCH] Properly reserve space in URL-previews for time footer Change-Id: Iee60d34086a8b1e2b9b70674eb77df2220dff1e5 --- .../app/core/ui/views/FooteredTextView.kt | 5 +- .../detail/timeline/item/MessageTextItem.kt | 59 ++++++++++--------- .../detail/timeline/url/PreviewUrlView.kt | 28 ++++----- 3 files changed, 47 insertions(+), 45 deletions(-) diff --git a/vector/src/main/java/im/vector/app/core/ui/views/FooteredTextView.kt b/vector/src/main/java/im/vector/app/core/ui/views/FooteredTextView.kt index beb385e89d..e54d4163db 100644 --- a/vector/src/main/java/im/vector/app/core/ui/views/FooteredTextView.kt +++ b/vector/src/main/java/im/vector/app/core/ui/views/FooteredTextView.kt @@ -24,9 +24,10 @@ class FooteredTextView @JvmOverloads constructor( super.onMeasure(widthMeasureSpec, heightMeasureSpec) // Get max available width - val widthMode = MeasureSpec.getMode(widthMeasureSpec) + //val widthMode = MeasureSpec.getMode(widthMeasureSpec) val widthSize = MeasureSpec.getSize(widthMeasureSpec) - val widthLimit = if (widthMode == MeasureSpec.AT_MOST) { widthSize.toFloat() } else { Float.MAX_VALUE } + //val widthLimit = if (widthMode == MeasureSpec.AT_MOST) { widthSize.toFloat() } else { Float.MAX_VALUE } + val widthLimit = widthSize.toFloat() /* // Sometimes, widthLimit is not the actual limit, so remember it... ? if (this.widthLimit > widthLimit) { diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageTextItem.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageTextItem.kt index fec498a961..8f9c3f5040 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageTextItem.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageTextItem.kt @@ -60,10 +60,11 @@ abstract class MessageTextItem : AbsMessageItem() { private val previewUrlViewUpdater = PreviewUrlViewUpdater() - override fun bind(holder: Holder) { - // Revert potential MATCH_PARENT setting for url preview, before binding previewUrlRetriever - //holder.messageLayout.layoutParams.width = LinearLayout.LayoutParams.WRAP_CONTENT + // Remember footer measures for URL updates + private var footerWidth: Int = 0 + private var footerHeight: Int = 0 + override fun bind(holder: Holder) { // Preview URL previewUrlViewUpdater.holder = holder previewUrlViewUpdater.previewUrlView = holder.previewUrlView @@ -120,7 +121,6 @@ abstract class MessageTextItem : AbsMessageItem() { override fun getViewType() = STUB_ID class Holder : AbsMessageItem.Holder(STUB_ID) { - val messageLayout by bind(R.id.messageTextLayout) // TODO match_parent if url preview, else wrap_content val messageView by bind(R.id.messageTextView) val previewUrlView by bind(R.id.messageUrlPreview) } @@ -138,29 +138,19 @@ abstract class MessageTextItem : AbsMessageItem() { } previewUrlView?.render(state, safeImageContentRenderer) - // Don't reserve footer space in message view, but preview view | TODO - /* - previewUrlView?.footerWidth = holder?.messageView?.footerWidth ?: 0 - previewUrlView?.footerHeight = holder?.messageView?.footerHeight ?: 0 - holder?.messageView?.footerWidth = 0 - holder?.messageView?.footerHeight = 0 - */ - // Reserve more space for URL previews - //holder?.messageLayout?.layoutParams?.width = LinearLayout.LayoutParams.MATCH_PARENT - // Also increase width for the viewStubContainer, as set in AbsMessageItem (using getViewStubMinimumWidth) - // We can use an unrealistic high number here, because we reduce bubble width by margins - // TODO dis not working reliably... - /* - holder?.viewStubContainer?.minimumWidth = 1000000 - holder?.viewStubContainer?.parent?.requestLayout() - holder?.viewStubContainer?.forceLayout() - holder?.viewStubContainer?.requestLayout() - holder?.messageLayout?.forceLayout() - holder?.messageLayout?.requestLayout() - holder?.messageView?.forceLayout() - holder?.previewUrlView?.forceLayout() - */ - //holder?.viewStubContainer?.layoutParams = holder?.viewStubContainer?.layoutParams + ///* // disabled for now: just set all in reserveFooterSpace to ensure space in all scenarios + // Currently, all states except data imply hidden preview + if (state is PreviewUrlUiState.Data) { + // Don't reserve footer space in message view, but preview view + holder?.messageView?.footerWidth = 0 + holder?.messageView?.footerHeight = 0 + } else { + holder?.messageView?.footerWidth = footerWidth + holder?.messageView?.footerHeight = footerHeight + } + //holder?.messageView?.invalidate() + holder?.messageView?.requestLayout() + //*/ } } companion object { @@ -180,7 +170,18 @@ abstract class MessageTextItem : AbsMessageItem() { } override fun reserveFooterSpace(holder: Holder, width: Int, height: Int) { - holder.messageView.footerWidth = width - holder.messageView.footerHeight = height + // Remember for PreviewUrlViewUpdater.onStateUpdated + footerWidth = width + footerHeight = height + // Reserve both in preview and in message + // User might close preview, so we still need place in the message + // if we don't want to change this afterwards + // This might be a race condition, but the UI-isssue if evaluated wrongly is negligible + if (!holder.previewUrlView.isVisible) { + holder.messageView.footerWidth = width + holder.messageView.footerHeight = height + } // else: will be handled in onStateUpdated + holder.previewUrlView.footerWidth = height + holder.previewUrlView.footerHeight = height } } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/url/PreviewUrlView.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/url/PreviewUrlView.kt index e29ed41ddf..faacb7459e 100755 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/url/PreviewUrlView.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/url/PreviewUrlView.kt @@ -32,7 +32,6 @@ import im.vector.app.features.home.room.detail.timeline.TimelineEventController import im.vector.app.features.media.ImageContentRenderer import org.matrix.android.sdk.api.extensions.orFalse import org.matrix.android.sdk.api.session.media.PreviewUrlData -import kotlin.math.round /** * A View to display a PreviewUrl and some other state @@ -58,8 +57,8 @@ class PreviewUrlView @JvmOverloads constructor( @BindView(R.id.url_preview_close) lateinit var closeView: View - var footerHeight: Int = 0 var footerWidth: Int = 0 + var footerHeight: Int = 0 var delegate: TimelineEventController.PreviewUrlCallback? = null @@ -149,23 +148,24 @@ class PreviewUrlView @JvmOverloads constructor( } private fun renderData(previewUrlData: PreviewUrlData, imageContentRenderer: ImageContentRenderer) { - isVisible = true - titleView.setTextOrHide(previewUrlData.title) - imageView.isVisible = previewUrlData.mxcUrl?.let { imageContentRenderer.render(it, imageView) }.orFalse() - descriptionView.setTextOrHide(previewUrlData.description) - siteView.setTextOrHide(previewUrlData.siteName.takeIf { it != previewUrlData.title }) - /* - if (siteView.isVisible) { - // TODO does this work + // Set footer sizes before setText() calls so they are available onMeasure + val siteText = previewUrlData.siteName.takeIf { it != previewUrlData.title } + val siteViewHidden = siteText == null || siteText.isBlank() // identical to setTextOrHide + if (siteViewHidden) { + descriptionView.footerWidth = footerWidth + descriptionView.footerHeight = footerHeight + } else { siteView.footerWidth = footerWidth siteView.footerHeight = footerHeight descriptionView.footerWidth = 0 descriptionView.footerHeight = 0 - } else { - descriptionView.footerWidth = footerWidth - descriptionView.footerHeight = footerHeight } - */ + + isVisible = true + titleView.setTextOrHide(previewUrlData.title) + imageView.isVisible = previewUrlData.mxcUrl?.let { imageContentRenderer.render(it, imageView) }.orFalse() + descriptionView.setTextOrHide(previewUrlData.description) + siteView.setTextOrHide(siteText) } /**