mirror of
https://github.com/SchildiChat/SchildiChat-android.git
synced 2025-02-02 20:26:47 +01:00
[merge] Bring back old url preview code
Already added back old layout in merge, but that's not enough Change-Id: I0c262f1a33890959bde77a0d54916a88c4ff2cc9
This commit is contained in:
parent
ca8d940c0e
commit
f3874be337
@ -17,10 +17,8 @@
|
||||
package im.vector.app.features.home.room.detail.timeline.item
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Color
|
||||
import android.text.TextUtils
|
||||
import android.text.method.MovementMethod
|
||||
import android.widget.LinearLayout
|
||||
import androidx.core.text.PrecomputedTextCompat
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.core.widget.TextViewCompat
|
||||
@ -36,7 +34,7 @@ import im.vector.app.features.home.room.detail.timeline.TimelineEventController
|
||||
import im.vector.app.features.home.room.detail.timeline.tools.findPillsAndProcess
|
||||
import im.vector.app.features.home.room.detail.timeline.url.PreviewUrlRetriever
|
||||
import im.vector.app.features.home.room.detail.timeline.url.PreviewUrlUiState
|
||||
import im.vector.app.features.home.room.detail.timeline.url.PreviewUrlView
|
||||
import im.vector.app.features.home.room.detail.timeline.url.PreviewUrlViewSc
|
||||
import im.vector.app.features.media.ImageContentRenderer
|
||||
import org.matrix.android.sdk.api.extensions.orFalse
|
||||
|
||||
@ -152,11 +150,11 @@ abstract class MessageTextItem : AbsMessageItem<MessageTextItem.Holder>() {
|
||||
|
||||
class Holder : AbsMessageItem.Holder(STUB_ID) {
|
||||
val messageView by bind<FooteredTextView>(R.id.messageTextView)
|
||||
val previewUrlView by bind<PreviewUrlView>(R.id.messageUrlPreview)
|
||||
val previewUrlView by bind<PreviewUrlViewSc>(R.id.messageUrlPreview)
|
||||
}
|
||||
|
||||
inner class PreviewUrlViewUpdater : PreviewUrlRetriever.PreviewUrlRetrieverListener {
|
||||
var previewUrlView: PreviewUrlView? = null
|
||||
var previewUrlView: PreviewUrlViewSc? = null
|
||||
var holder: Holder? = null
|
||||
var imageContentRenderer: ImageContentRenderer? = null
|
||||
|
||||
|
@ -23,7 +23,7 @@ import androidx.core.view.isVisible
|
||||
import com.google.android.material.card.MaterialCardView
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.extensions.setTextOrHide
|
||||
import im.vector.app.databinding.ViewUrlPreviewScBinding
|
||||
import im.vector.app.databinding.ViewUrlPreviewBinding
|
||||
import im.vector.app.features.home.room.detail.timeline.TimelineEventController
|
||||
import im.vector.app.features.media.ImageContentRenderer
|
||||
import im.vector.app.features.themes.ThemeUtils
|
||||
@ -39,10 +39,7 @@ class PreviewUrlView @JvmOverloads constructor(
|
||||
defStyleAttr: Int = 0
|
||||
) : MaterialCardView(context, attrs, defStyleAttr), View.OnClickListener {
|
||||
|
||||
private lateinit var views: ViewUrlPreviewScBinding
|
||||
|
||||
var footerWidth: Int = 0
|
||||
var footerHeight: Int = 0
|
||||
private lateinit var views: ViewUrlPreviewBinding
|
||||
|
||||
var delegate: TimelineEventController.PreviewUrlCallback? = null
|
||||
|
||||
@ -106,33 +103,11 @@ 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() {
|
||||
inflate(context, R.layout.view_url_preview_sc, this)
|
||||
views = ViewUrlPreviewScBinding.bind(this)
|
||||
inflate(context, R.layout.view_url_preview, this)
|
||||
views = ViewUrlPreviewBinding.bind(this)
|
||||
|
||||
setOnClickListener(this)
|
||||
views.urlPreviewImage.setOnClickListener { onImageClick() }
|
||||
@ -149,21 +124,17 @@ class PreviewUrlView @JvmOverloads constructor(
|
||||
}
|
||||
|
||||
private fun renderData(previewUrlData: PreviewUrlData, imageContentRenderer: ImageContentRenderer) {
|
||||
// Set footer sizes before setText() calls so they are available onMeasure
|
||||
val siteText = previewUrlData.siteName.takeIf { it != previewUrlData.title }
|
||||
updateFooterSpaceInternal(siteText)
|
||||
|
||||
isVisible = true
|
||||
|
||||
views.urlPreviewTitle.setTextOrHide(previewUrlData.title)
|
||||
views.urlPreviewImage.isVisible = previewUrlData.mxcUrl?.let { imageContentRenderer.render(it, views.urlPreviewImage, hideOnFail = true) }.orFalse()
|
||||
views.urlPreviewImage.isVisible = previewUrlData.mxcUrl?.let { imageContentRenderer.render(it, views.urlPreviewImage) }.orFalse()
|
||||
views.urlPreviewDescription.setTextOrHide(previewUrlData.description)
|
||||
views.urlPreviewDescription.maxLines = when {
|
||||
previewUrlData.mxcUrl != null -> 2
|
||||
previewUrlData.title != null -> 3
|
||||
else -> 5
|
||||
}
|
||||
views.urlPreviewSite.setTextOrHide(siteText)
|
||||
views.urlPreviewSite.setTextOrHide(previewUrlData.siteName.takeIf { it != previewUrlData.title })
|
||||
}
|
||||
|
||||
/**
|
||||
@ -175,23 +146,4 @@ class PreviewUrlView @JvmOverloads constructor(
|
||||
views.urlPreviewDescription.isVisible = false
|
||||
views.urlPreviewSite.isVisible = false
|
||||
}
|
||||
|
||||
public fun updateFooterSpace() {
|
||||
val siteText = views.urlPreviewSite.text as String?
|
||||
updateFooterSpaceInternal(siteText)
|
||||
requestLayout()
|
||||
}
|
||||
|
||||
private fun updateFooterSpaceInternal(siteText: String?) {
|
||||
val siteViewHidden = siteText == null || siteText.isBlank() // identical to setTextOrHide
|
||||
if (siteViewHidden) {
|
||||
views.urlPreviewDescription.footerWidth = footerWidth
|
||||
views.urlPreviewDescription.footerHeight = footerHeight
|
||||
} else {
|
||||
views.urlPreviewSite.footerWidth = footerWidth
|
||||
views.urlPreviewSite.footerHeight = footerHeight
|
||||
views.urlPreviewDescription.footerWidth = 0
|
||||
views.urlPreviewDescription.footerHeight = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,187 @@
|
||||
/*
|
||||
* Copyright (c) 2020 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package im.vector.app.features.home.room.detail.timeline.url
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.view.View
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.core.view.isVisible
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.extensions.setTextOrHide
|
||||
import im.vector.app.databinding.ViewUrlPreviewScBinding
|
||||
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
|
||||
|
||||
/**
|
||||
* A View to display a PreviewUrl and some other state
|
||||
*/
|
||||
class PreviewUrlViewSc @JvmOverloads constructor(
|
||||
context: Context,
|
||||
attrs: AttributeSet? = null,
|
||||
defStyleAttr: Int = 0
|
||||
) : ConstraintLayout(context, attrs, defStyleAttr), View.OnClickListener {
|
||||
|
||||
private lateinit var views: ViewUrlPreviewScBinding
|
||||
|
||||
var footerWidth: Int = 0
|
||||
var footerHeight: Int = 0
|
||||
|
||||
var delegate: TimelineEventController.PreviewUrlCallback? = null
|
||||
|
||||
init {
|
||||
setupView()
|
||||
}
|
||||
|
||||
private var state: PreviewUrlUiState = PreviewUrlUiState.Unknown
|
||||
|
||||
/**
|
||||
* This methods is responsible for rendering the view according to the newState
|
||||
*
|
||||
* @param newState the newState representing the view
|
||||
*/
|
||||
fun render(newState: PreviewUrlUiState,
|
||||
imageContentRenderer: ImageContentRenderer,
|
||||
force: Boolean = false) {
|
||||
if (newState == state && !force) {
|
||||
return
|
||||
}
|
||||
|
||||
state = newState
|
||||
|
||||
hideAll()
|
||||
when (newState) {
|
||||
PreviewUrlUiState.Unknown,
|
||||
PreviewUrlUiState.NoUrl -> renderHidden()
|
||||
PreviewUrlUiState.Loading -> renderLoading()
|
||||
is PreviewUrlUiState.Error -> renderHidden()
|
||||
is PreviewUrlUiState.Data -> renderData(newState.previewUrlData, imageContentRenderer)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onClick(v: View?) {
|
||||
when (val finalState = state) {
|
||||
is PreviewUrlUiState.Data -> delegate?.onPreviewUrlClicked(finalState.url)
|
||||
else -> Unit
|
||||
}
|
||||
}
|
||||
|
||||
private fun onImageClick() {
|
||||
when (val finalState = state) {
|
||||
is PreviewUrlUiState.Data -> {
|
||||
delegate?.onPreviewUrlImageClicked(
|
||||
sharedView = views.urlPreviewImage,
|
||||
mxcUrl = finalState.previewUrlData.mxcUrl,
|
||||
title = finalState.previewUrlData.title
|
||||
)
|
||||
}
|
||||
else -> Unit
|
||||
}
|
||||
}
|
||||
|
||||
private fun onCloseClick() {
|
||||
when (val finalState = state) {
|
||||
is PreviewUrlUiState.Data -> delegate?.onPreviewUrlCloseClicked(finalState.eventId, finalState.url)
|
||||
else -> Unit
|
||||
}
|
||||
}
|
||||
|
||||
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() {
|
||||
inflate(context, R.layout.view_url_preview_sc, this)
|
||||
views = ViewUrlPreviewScBinding.bind(this)
|
||||
|
||||
setOnClickListener(this)
|
||||
views.urlPreviewImage.setOnClickListener { onImageClick() }
|
||||
views.urlPreviewClose.setOnClickListener { onCloseClick() }
|
||||
}
|
||||
|
||||
private fun renderHidden() {
|
||||
isVisible = false
|
||||
}
|
||||
|
||||
private fun renderLoading() {
|
||||
// Just hide for the moment
|
||||
isVisible = false
|
||||
}
|
||||
|
||||
private fun renderData(previewUrlData: PreviewUrlData, imageContentRenderer: ImageContentRenderer) {
|
||||
// Set footer sizes before setText() calls so they are available onMeasure
|
||||
val siteText = previewUrlData.siteName.takeIf { it != previewUrlData.title }
|
||||
updateFooterSpaceInternal(siteText)
|
||||
|
||||
isVisible = true
|
||||
views.urlPreviewTitle.setTextOrHide(previewUrlData.title)
|
||||
views.urlPreviewImage.isVisible = previewUrlData.mxcUrl?.let { imageContentRenderer.render(it, views.urlPreviewImage, hideOnFail = true) }.orFalse()
|
||||
views.urlPreviewDescription.setTextOrHide(previewUrlData.description)
|
||||
views.urlPreviewSite.setTextOrHide(siteText)
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide all views that are not visible in all state
|
||||
*/
|
||||
private fun hideAll() {
|
||||
views.urlPreviewTitle.isVisible = false
|
||||
views.urlPreviewImage.isVisible = false
|
||||
views.urlPreviewDescription.isVisible = false
|
||||
views.urlPreviewSite.isVisible = false
|
||||
}
|
||||
|
||||
public fun updateFooterSpace() {
|
||||
val siteText = views.urlPreviewSite.text as String?
|
||||
updateFooterSpaceInternal(siteText)
|
||||
requestLayout()
|
||||
}
|
||||
|
||||
private fun updateFooterSpaceInternal(siteText: String?) {
|
||||
val siteViewHidden = siteText == null || siteText.isBlank() // identical to setTextOrHide
|
||||
if (siteViewHidden) {
|
||||
views.urlPreviewDescription.footerWidth = footerWidth
|
||||
views.urlPreviewDescription.footerHeight = footerHeight
|
||||
} else {
|
||||
views.urlPreviewSite.footerWidth = footerWidth
|
||||
views.urlPreviewSite.footerHeight = footerHeight
|
||||
views.urlPreviewDescription.footerWidth = 0
|
||||
views.urlPreviewDescription.footerHeight = 0
|
||||
}
|
||||
}
|
||||
}
|
@ -25,9 +25,9 @@
|
||||
tools:text="@sample/messages.json/data/message"
|
||||
tools:ignore="RtlHardcoded" />
|
||||
|
||||
<im.vector.app.features.home.room.detail.timeline.url.PreviewUrlView
|
||||
<im.vector.app.features.home.room.detail.timeline.url.PreviewUrlViewSc
|
||||
android:id="@+id/messageUrlPreview"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginBottom="4dp"
|
||||
|
Loading…
x
Reference in New Issue
Block a user