[WIP] PreviewUrl-fixes for bubble layout

- Always use maximum available width for the preview
- TODO reserve footer for time
- TODO fix upstream bug which comes more apparent on Schildi:
    fast scrolling leads to previews attached to wrong messages

Change-Id: Ie8447b7a9dbace54e38c14fc7d281b7f3887736c
This commit is contained in:
SpiritCroc 2020-12-19 11:37:15 +01:00
parent 77bfa1a687
commit 002edb5e36
8 changed files with 81 additions and 11 deletions

View file

@ -36,7 +36,7 @@ internal object RoomSummaryEventsHelper {
// SC addition
private val previewFiltersScAll = TimelineEventFilters(
filterTypes = true,
allowedTypes = RoomSummaryConstants.PREVIEWABLE_TYPES_ALL,
allowedTypes = RoomSummaryConstants.PREVIEWABLE_TYPES_ALL.map { EventTypeFilter(eventType = it, stateKey = null) },
filterUseless = true,
filterRedacted = false,
filterEdits = true
@ -45,7 +45,7 @@ internal object RoomSummaryEventsHelper {
// SC addition
private val previewFiltersScOriginalContent = TimelineEventFilters(
filterTypes = true,
allowedTypes = RoomSummaryConstants.PREVIEWABLE_ORIGINAL_CONTENT_TYPES,
allowedTypes = RoomSummaryConstants.PREVIEWABLE_ORIGINAL_CONTENT_TYPES.map { EventTypeFilter(eventType = it, stateKey = null) },
filterUseless = true,
filterRedacted = true,
filterEdits = true

View file

@ -19,6 +19,7 @@ package im.vector.app.features.home.room.detail.timeline.item
import android.content.Context
import android.text.TextUtils
import android.text.method.MovementMethod
import android.widget.LinearLayout
import androidx.core.text.PrecomputedTextCompat
import androidx.core.widget.TextViewCompat
import com.airbnb.epoxy.EpoxyAttribute
@ -59,7 +60,11 @@ abstract class MessageTextItem : AbsMessageItem<MessageTextItem.Holder>() {
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
// Preview URL
previewUrlViewUpdater.holder = holder
previewUrlViewUpdater.previewUrlView = holder.previewUrlView
previewUrlViewUpdater.imageContentRenderer = imageContentRenderer
previewUrlRetriever?.addListener(attributes.informationData.eventId, previewUrlViewUpdater)
@ -109,17 +114,43 @@ abstract class MessageTextItem : AbsMessageItem<MessageTextItem.Holder>() {
override fun getViewType() = STUB_ID
class Holder : AbsMessageItem.Holder(STUB_ID) {
val messageLayout by bind<LinearLayout>(R.id.messageTextLayout) // TODO match_parent if url preview, else wrap_content
val messageView by bind<FooteredTextView>(R.id.messageTextView)
val previewUrlView by bind<PreviewUrlView>(R.id.messageUrlPreview)
}
inner class PreviewUrlViewUpdater : PreviewUrlRetriever.PreviewUrlRetrieverListener {
var previewUrlView: PreviewUrlView? = null
var holder: Holder? = null
var imageContentRenderer: ImageContentRenderer? = null
override fun onStateUpdated(state: PreviewUrlUiState) {
val safeImageContentRenderer = imageContentRenderer ?: return
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
}
}
companion object {

View file

@ -27,10 +27,12 @@ import butterknife.BindView
import butterknife.ButterKnife
import im.vector.app.R
import im.vector.app.core.extensions.setTextOrHide
import im.vector.app.core.ui.views.FooteredTextView
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
@ -48,14 +50,17 @@ class PreviewUrlView @JvmOverloads constructor(
lateinit var imageView: ImageView
@BindView(R.id.url_preview_description)
lateinit var descriptionView: TextView
lateinit var descriptionView: FooteredTextView
@BindView(R.id.url_preview_site)
lateinit var siteView: TextView
lateinit var siteView: FooteredTextView
@BindView(R.id.url_preview_close)
lateinit var closeView: View
var footerHeight: Int = 0
var footerWidth: Int = 0
var delegate: TimelineEventController.PreviewUrlCallback? = null
init {
@ -102,6 +107,28 @@ class PreviewUrlView @JvmOverloads constructor(
}
}
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
// Get max available width - we're faking "wrap_content" here to use all available space,
// since match_parent doesn't work here as our parent does wrap_content as well
/*
val widthMode = MeasureSpec.getMode(widthMeasureSpec)
val widthSize = MeasureSpec.getSize(widthMeasureSpec)
val widthLimit = if (widthMode == MeasureSpec.AT_MOST) {
widthSize.toFloat()
} else {
Float.MAX_VALUE
}
*/
//setMeasuredDimension(round(widthLimit).toInt(), measuredHeight)
// We extract the size from an AT_MOST spec, which is the width limit, but change the mode to EXACTLY
val newWidthSpec = MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.EXACTLY)
// We measure our children based on the now fixed width
super.onMeasure(newWidthSpec, heightMeasureSpec)
}
// PRIVATE METHODS ****************************************************************************************************************************************
private fun setupView() {
@ -127,6 +154,18 @@ class PreviewUrlView @JvmOverloads constructor(
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
siteView.footerWidth = footerWidth
siteView.footerHeight = footerHeight
descriptionView.footerWidth = 0
descriptionView.footerHeight = 0
} else {
descriptionView.footerWidth = footerWidth
descriptionView.footerHeight = footerHeight
}
*/
}
/**

View file

@ -33,7 +33,7 @@ import javax.inject.Inject
class CreateRoomController @Inject constructor(
private val stringProvider: StringProvider,
private val roomAliasErrorFormatter: RoomAliasErrorFormatter
private val roomAliasErrorFormatter: RoomAliasErrorFormatter,
private val vectorPreferences: VectorPreferences
) : TypedEpoxyController<CreateRoomViewState>() {

View file

@ -112,7 +112,7 @@ object ThemeUtils {
fun isLightTheme(context: Context): Boolean {
return when (getApplicationTheme(context)) {
THEME_LIGHT_VALUE,
THEME_SC_LIGHT_VALUE,
THEME_SC_LIGHT_VALUE -> true
else -> false
}
}
@ -138,7 +138,7 @@ object ThemeUtils {
val currentTheme = this.currentLightTheme.get()
return if (currentTheme == null) {
val prefs = DefaultSharedPreferences.getInstance(context)
val themeFromPref = prefs.getString(APPLICATION_THEME_KEY, THEME_SC_LIGHT_VALUE) ?: THEME_SC_LIGHT_VALUE
var themeFromPref = prefs.getString(APPLICATION_THEME_KEY, THEME_SC_LIGHT_VALUE) ?: THEME_SC_LIGHT_VALUE
if (themeFromPref == "status") {
// Migrate to light theme, which is the closest theme
themeFromPref = THEME_LIGHT_VALUE
@ -162,7 +162,7 @@ object ThemeUtils {
val currentTheme = this.currentDarkTheme.get()
return if (currentTheme == null) {
val prefs = DefaultSharedPreferences.getInstance(context)
val themeFromPref = prefs.getString(APPLICATION_DARK_THEME_KEY, THEME_SC_DARK_VALUE) ?: THEME_SC_DARK_VALUE
var themeFromPref = prefs.getString(APPLICATION_DARK_THEME_KEY, THEME_SC_DARK_VALUE) ?: THEME_SC_DARK_VALUE
if (themeFromPref == "status") {
// Migrate to light theme, which is the closest theme
themeFromPref = THEME_LIGHT_VALUE

View file

@ -138,7 +138,6 @@
style="@style/TimelineContentStubBaseParams"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:inflatedId="@id/messageTextView"
android:layout="@layout/item_timeline_event_text_message_stub"
tools:visibility="visible" />

View file

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/messageTextLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">

View file

@ -43,7 +43,7 @@
app:layout_constraintTop_toBottomOf="@+id/url_preview_title"
tools:src="@tools:sample/backgrounds/scenic" />
<TextView
<im.vector.app.core.ui.views.FooteredTextView
android:id="@+id/url_preview_description"
android:layout_width="0dp"
android:layout_height="wrap_content"
@ -58,7 +58,7 @@
app:layout_constraintTop_toBottomOf="@+id/url_preview_image"
tools:text="The British perfumer says removing actor John Boyega from his own advert was “utterly despicable”." />
<TextView
<im.vector.app.core.ui.views.FooteredTextView
android:id="@+id/url_preview_site"
android:layout_width="0dp"
android:layout_height="wrap_content"