mirror of
https://github.com/SchildiChat/SchildiChat-android.git
synced 2025-02-02 05:01:07 +03:00
[merge,WIP] interface'd FooteredTextView
Change-Id: I62f09fff7d094ebb3bf6690b17c951e4e48e80c7
This commit is contained in:
parent
51274af2fe
commit
8c2b9ec6f4
9 changed files with 202 additions and 145 deletions
|
@ -0,0 +1,149 @@
|
|||
package im.vector.app.core.ui.views
|
||||
|
||||
import android.graphics.Canvas
|
||||
import android.graphics.Rect
|
||||
import android.text.Layout
|
||||
import android.text.Spannable
|
||||
import android.text.Spanned
|
||||
import android.view.View
|
||||
import androidx.appcompat.widget.AppCompatTextView
|
||||
import androidx.core.text.getSpans
|
||||
import androidx.core.text.toSpanned
|
||||
import androidx.core.view.ViewCompat.LAYOUT_DIRECTION_RTL
|
||||
import im.vector.app.R
|
||||
import im.vector.app.features.html.HtmlCodeSpan
|
||||
import io.noties.markwon.core.spans.EmphasisSpan
|
||||
import kotlin.math.ceil
|
||||
import kotlin.math.max
|
||||
|
||||
/**
|
||||
* TextView that reserves space at the bottom for overlaying it with a footer, e.g. in a FrameLayout or RelativeLayout
|
||||
*/
|
||||
interface AbstractFooteredTextView {
|
||||
|
||||
fun getAppCompatTextView(): AppCompatTextView
|
||||
fun setMeasuredDimensionExposed(measuredWidth: Int, measuredHeight: Int)
|
||||
|
||||
val footerState: FooterState
|
||||
|
||||
class FooterState {
|
||||
var footerHeight: Int = 0
|
||||
var footerWidth: Int = 0
|
||||
//var widthLimit: Float = 0f
|
||||
|
||||
// Some Rect to use during draw, since we should not alloc it during draw
|
||||
val testBounds = Rect()
|
||||
|
||||
// Workaround to RTL languages with non-RTL content messages aligning left instead of start
|
||||
var requiredHorizontalCanvasMove = 0f
|
||||
}
|
||||
|
||||
fun updateDimensionsWithFooter(widthMeasureSpec: Int, heightMeasureSpec: Int) = with(getAppCompatTextView()) {
|
||||
// Default case
|
||||
footerState.requiredHorizontalCanvasMove = 0f
|
||||
|
||||
// Get max available width
|
||||
//val widthMode = MeasureSpec.getMode(widthMeasureSpec)
|
||||
val widthSize = View.MeasureSpec.getSize(widthMeasureSpec)
|
||||
//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) {
|
||||
widthLimit = this.widthLimit
|
||||
} else {
|
||||
this.widthLimit = widthLimit
|
||||
}
|
||||
*/
|
||||
|
||||
val lastLine = layout.lineCount - 1
|
||||
|
||||
// Let's check if the last line's text has the same RTL behaviour as the layout direction.
|
||||
val viewIsRtl = layoutDirection == LAYOUT_DIRECTION_RTL
|
||||
val looksLikeRtl = layout.getParagraphDirection(lastLine) == Layout.DIR_RIGHT_TO_LEFT
|
||||
/*
|
||||
val lastVisibleCharacter = layout.getLineVisibleEnd(lastLine) - 1
|
||||
val looksLikeRtl = layout.isRtlCharAt(lastVisibleCharacter)
|
||||
*/
|
||||
|
||||
// Get required width for all lines
|
||||
var maxLineWidth = 0f
|
||||
for (i in 0 until layout.lineCount) {
|
||||
// For some reasons, the getLineWidth is not working too well with RTL lines when rendering replies.
|
||||
// -> https://github.com/SchildiChat/SchildiChat-android/issues/74
|
||||
// However, the bounds method is a little generous sometimes (reserving too much space),
|
||||
// so we don't want to use it over getLineWidth() unless required.
|
||||
maxLineWidth = if (layout.getParagraphDirection(i) == Layout.DIR_RIGHT_TO_LEFT) {
|
||||
layout.getLineBounds(i, footerState.testBounds)
|
||||
max((footerState.testBounds.right - footerState.testBounds.left).toFloat(), maxLineWidth)
|
||||
} else {
|
||||
max(layout.getLineWidth(i), maxLineWidth)
|
||||
}
|
||||
}
|
||||
|
||||
// Fix wrap_content in multi-line texts by using maxLineWidth instead of measuredWidth here
|
||||
// (compare WrapWidthTextView.kt)
|
||||
var newWidth = ceil(maxLineWidth).toInt()
|
||||
var newHeight = measuredHeight
|
||||
|
||||
val widthLastLine = layout.getLineWidth(lastLine)
|
||||
|
||||
// Required width if putting footer in the same line as the last line
|
||||
val widthWithHorizontalFooter = (
|
||||
if (looksLikeRtl == viewIsRtl)
|
||||
widthLastLine
|
||||
else
|
||||
(maxLineWidth + resources.getDimensionPixelSize(R.dimen.sc_footer_rtl_mismatch_extra_padding))
|
||||
) + footerState.footerWidth
|
||||
|
||||
// If the last line is a multi-line code block, we have never space in the last line (as the black background always uses full width)
|
||||
val forceNewlineFooter: Boolean
|
||||
// For italic text, we need some extra space due to a wrap_content bug: https://stackoverflow.com/q/4353836
|
||||
val addItalicPadding: Boolean
|
||||
|
||||
if (text is Spannable || text is Spanned) {
|
||||
val span = text.toSpanned()
|
||||
// If not found, -1+1 = 0
|
||||
val lastLineStart = span.lastIndexOf("\n") + 1
|
||||
val lastLineCodeSpans = span.getSpans<HtmlCodeSpan>(lastLineStart)
|
||||
forceNewlineFooter = lastLineCodeSpans.any { it.isBlock }
|
||||
addItalicPadding = span.getSpans<EmphasisSpan>().isNotEmpty()
|
||||
} else {
|
||||
forceNewlineFooter = false
|
||||
addItalicPadding = false
|
||||
}
|
||||
|
||||
// Is there space for a horizontal footer?
|
||||
if (widthWithHorizontalFooter <= widthLimit && !forceNewlineFooter) {
|
||||
// Reserve extra horizontal footer space if necessary
|
||||
if (widthWithHorizontalFooter > newWidth) {
|
||||
newWidth = ceil(widthWithHorizontalFooter).toInt()
|
||||
|
||||
if (viewIsRtl) {
|
||||
footerState.requiredHorizontalCanvasMove = widthWithHorizontalFooter - measuredWidth
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Reserve vertical footer space
|
||||
newHeight += footerState.footerHeight
|
||||
// Ensure enough width for footer bellow
|
||||
newWidth = max(newWidth, footerState.footerWidth +
|
||||
resources.getDimensionPixelSize(R.dimen.sc_footer_padding_compensation) +
|
||||
2 * resources.getDimensionPixelSize(R.dimen.sc_footer_overlay_padding))
|
||||
}
|
||||
|
||||
if (addItalicPadding) {
|
||||
newWidth += resources.getDimensionPixelSize(R.dimen.italic_text_view_extra_padding)
|
||||
}
|
||||
|
||||
//setMeasuredDimension(newWidth, newHeight)
|
||||
Pair(newWidth, newHeight)
|
||||
}
|
||||
|
||||
fun updateFooterOnPreDraw(canvas: Canvas?) {
|
||||
// Workaround to RTL languages with non-RTL content messages aligning left instead of start
|
||||
if (footerState.requiredHorizontalCanvasMove > 0f) {
|
||||
canvas?.translate(footerState.requiredHorizontalCanvasMove, 0f)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package im.vector.app.core.ui.views
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Canvas
|
||||
import android.util.AttributeSet
|
||||
import androidx.appcompat.widget.AppCompatTextView
|
||||
import io.element.android.wysiwyg.EditorStyledTextView
|
||||
|
||||
class FooteredEditorStyledTextView @JvmOverloads constructor(
|
||||
context: Context,
|
||||
attrs: AttributeSet? = null,
|
||||
defStyleAttr: Int = 0
|
||||
): EditorStyledTextView(context, attrs, defStyleAttr), AbstractFooteredTextView {
|
||||
|
||||
override val footerState: AbstractFooteredTextView.FooterState = AbstractFooteredTextView.FooterState()
|
||||
override fun getAppCompatTextView(): AppCompatTextView = this
|
||||
override fun setMeasuredDimensionExposed(measuredWidth: Int, measuredHeight: Int) = setMeasuredDimension(measuredWidth, measuredHeight)
|
||||
|
||||
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
|
||||
// First, let super measure the content for our normal TextView use
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
|
||||
|
||||
val updatedMeasures = updateDimensionsWithFooter(widthMeasureSpec, heightMeasureSpec)
|
||||
setMeasuredDimension(updatedMeasures.first, updatedMeasures.second)
|
||||
}
|
||||
|
||||
override fun onDraw(canvas: Canvas?) {
|
||||
updateFooterOnPreDraw(canvas)
|
||||
|
||||
super.onDraw(canvas)
|
||||
}
|
||||
}
|
|
@ -2,148 +2,29 @@ package im.vector.app.core.ui.views
|
|||
|
||||
import android.content.Context
|
||||
import android.graphics.Canvas
|
||||
import android.graphics.Rect
|
||||
import android.text.Layout
|
||||
import android.text.Spannable
|
||||
import android.text.Spanned
|
||||
import android.util.AttributeSet
|
||||
import androidx.appcompat.widget.AppCompatTextView
|
||||
import androidx.core.text.getSpans
|
||||
import androidx.core.text.toSpanned
|
||||
import im.vector.app.R
|
||||
import im.vector.app.features.html.HtmlCodeSpan
|
||||
import io.noties.markwon.core.spans.EmphasisSpan
|
||||
import kotlin.math.ceil
|
||||
import kotlin.math.max
|
||||
|
||||
/**
|
||||
* TextView that reserves space at the bottom for overlaying it with a footer, e.g. in a FrameLayout or RelativeLayout
|
||||
*/
|
||||
class FooteredTextView @JvmOverloads constructor(
|
||||
context: Context,
|
||||
attrs: AttributeSet? = null,
|
||||
defStyleAttr: Int = 0
|
||||
): AppCompatTextView(context, attrs, defStyleAttr) {
|
||||
): AppCompatTextView(context, attrs, defStyleAttr), AbstractFooteredTextView {
|
||||
|
||||
var footerHeight: Int = 0
|
||||
var footerWidth: Int = 0
|
||||
//var widthLimit: Float = 0f
|
||||
|
||||
// Some Rect to use during draw, since we should not alloc it during draw
|
||||
private val testBounds = Rect()
|
||||
|
||||
// Workaround to RTL languages with non-RTL content messages aligning left instead of start
|
||||
private var requiredHorizontalCanvasMove = 0f
|
||||
override val footerState: AbstractFooteredTextView.FooterState = AbstractFooteredTextView.FooterState()
|
||||
override fun getAppCompatTextView(): AppCompatTextView = this
|
||||
override fun setMeasuredDimensionExposed(measuredWidth: Int, measuredHeight: Int) = setMeasuredDimension(measuredWidth, measuredHeight)
|
||||
|
||||
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
|
||||
// First, let super measure the content for our normal TextView use
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
|
||||
|
||||
// Default case
|
||||
requiredHorizontalCanvasMove = 0f
|
||||
|
||||
// Get max available width
|
||||
//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 = widthSize.toFloat()
|
||||
/*
|
||||
// Sometimes, widthLimit is not the actual limit, so remember it... ?
|
||||
if (this.widthLimit > widthLimit) {
|
||||
widthLimit = this.widthLimit
|
||||
} else {
|
||||
this.widthLimit = widthLimit
|
||||
}
|
||||
*/
|
||||
|
||||
val lastLine = layout.lineCount - 1
|
||||
|
||||
// Let's check if the last line's text has the same RTL behaviour as the layout direction.
|
||||
val viewIsRtl = layoutDirection == LAYOUT_DIRECTION_RTL
|
||||
val looksLikeRtl = layout.getParagraphDirection(lastLine) == Layout.DIR_RIGHT_TO_LEFT
|
||||
/*
|
||||
val lastVisibleCharacter = layout.getLineVisibleEnd(lastLine) - 1
|
||||
val looksLikeRtl = layout.isRtlCharAt(lastVisibleCharacter)
|
||||
*/
|
||||
|
||||
// Get required width for all lines
|
||||
var maxLineWidth = 0f
|
||||
for (i in 0 until layout.lineCount) {
|
||||
// For some reasons, the getLineWidth is not working too well with RTL lines when rendering replies.
|
||||
// -> https://github.com/SchildiChat/SchildiChat-android/issues/74
|
||||
// However, the bounds method is a little generous sometimes (reserving too much space),
|
||||
// so we don't want to use it over getLineWidth() unless required.
|
||||
maxLineWidth = if (layout.getParagraphDirection(i) == Layout.DIR_RIGHT_TO_LEFT) {
|
||||
layout.getLineBounds(i, testBounds)
|
||||
max((testBounds.right - testBounds.left).toFloat(), maxLineWidth)
|
||||
} else {
|
||||
max(layout.getLineWidth(i), maxLineWidth)
|
||||
}
|
||||
}
|
||||
|
||||
// Fix wrap_content in multi-line texts by using maxLineWidth instead of measuredWidth here
|
||||
// (compare WrapWidthTextView.kt)
|
||||
var newWidth = ceil(maxLineWidth).toInt()
|
||||
var newHeight = measuredHeight
|
||||
|
||||
val widthLastLine = layout.getLineWidth(lastLine)
|
||||
|
||||
// Required width if putting footer in the same line as the last line
|
||||
val widthWithHorizontalFooter = (
|
||||
if (looksLikeRtl == viewIsRtl)
|
||||
widthLastLine
|
||||
else
|
||||
(maxLineWidth + resources.getDimensionPixelSize(R.dimen.sc_footer_rtl_mismatch_extra_padding))
|
||||
) + footerWidth
|
||||
|
||||
// If the last line is a multi-line code block, we have never space in the last line (as the black background always uses full width)
|
||||
val forceNewlineFooter: Boolean
|
||||
// For italic text, we need some extra space due to a wrap_content bug: https://stackoverflow.com/q/4353836
|
||||
val addItalicPadding: Boolean
|
||||
|
||||
if (text is Spannable || text is Spanned) {
|
||||
val span = text.toSpanned()
|
||||
// If not found, -1+1 = 0
|
||||
val lastLineStart = span.lastIndexOf("\n") + 1
|
||||
val lastLineCodeSpans = span.getSpans<HtmlCodeSpan>(lastLineStart)
|
||||
forceNewlineFooter = lastLineCodeSpans.any { it.isBlock }
|
||||
addItalicPadding = span.getSpans<EmphasisSpan>().isNotEmpty()
|
||||
} else {
|
||||
forceNewlineFooter = false
|
||||
addItalicPadding = false
|
||||
}
|
||||
|
||||
// Is there space for a horizontal footer?
|
||||
if (widthWithHorizontalFooter <= widthLimit && !forceNewlineFooter) {
|
||||
// Reserve extra horizontal footer space if necessary
|
||||
if (widthWithHorizontalFooter > newWidth) {
|
||||
newWidth = ceil(widthWithHorizontalFooter).toInt()
|
||||
|
||||
if (viewIsRtl) {
|
||||
requiredHorizontalCanvasMove = widthWithHorizontalFooter - measuredWidth
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Reserve vertical footer space
|
||||
newHeight += footerHeight
|
||||
// Ensure enough width for footer bellow
|
||||
newWidth = max(newWidth, footerWidth +
|
||||
resources.getDimensionPixelSize(R.dimen.sc_footer_padding_compensation) +
|
||||
2 * resources.getDimensionPixelSize(R.dimen.sc_footer_overlay_padding))
|
||||
}
|
||||
|
||||
if (addItalicPadding) {
|
||||
newWidth += resources.getDimensionPixelSize(R.dimen.italic_text_view_extra_padding)
|
||||
}
|
||||
|
||||
setMeasuredDimension(newWidth, newHeight)
|
||||
val updatedMeasures = updateDimensionsWithFooter(widthMeasureSpec, heightMeasureSpec)
|
||||
setMeasuredDimension(updatedMeasures.first, updatedMeasures.second)
|
||||
}
|
||||
|
||||
override fun onDraw(canvas: Canvas?) {
|
||||
// Workaround to RTL languages with non-RTL content messages aligning left instead of start
|
||||
if (requiredHorizontalCanvasMove > 0f) {
|
||||
canvas?.translate(requiredHorizontalCanvasMove, 0f)
|
||||
}
|
||||
updateFooterOnPreDraw(canvas)
|
||||
|
||||
super.onDraw(canvas)
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ import im.vector.app.R
|
|||
import im.vector.app.core.epoxy.ClickListener
|
||||
import im.vector.app.core.epoxy.onClick
|
||||
import im.vector.app.core.extensions.setTextOrHide
|
||||
import im.vector.app.core.ui.views.FooteredTextView
|
||||
import im.vector.app.core.ui.views.AbstractFooteredTextView
|
||||
import im.vector.app.core.utils.TextUtils
|
||||
import im.vector.app.features.home.room.detail.timeline.helper.AudioMessagePlaybackTracker
|
||||
import im.vector.app.features.home.room.detail.timeline.helper.ContentDownloadStateTrackerBinder
|
||||
|
@ -224,7 +224,7 @@ abstract class MessageAudioItem : AbsMessageItem<MessageAudioItem.Holder>() {
|
|||
val audioPlaybackTime by bind<TextView>(R.id.audioPlaybackTime)
|
||||
val progressLayout by bind<ViewGroup>(R.id.messageFileUploadProgressLayout)
|
||||
val fileSize by bind<TextView>(R.id.fileSize)
|
||||
val captionView by bind<FooteredTextView>(R.id.messageCaptionView)
|
||||
val captionView by bind<AbstractFooteredTextView>(R.id.messageCaptionView)
|
||||
val audioPlaybackDuration by bind<TextView>(R.id.audioPlaybackDuration)
|
||||
val audioSeekBar by bind<SeekBar>(R.id.audioSeekBar)
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ import com.airbnb.epoxy.EpoxyModelClass
|
|||
import im.vector.app.R
|
||||
import im.vector.app.core.epoxy.onClick
|
||||
import im.vector.app.core.extensions.setTextOrHide
|
||||
import im.vector.app.core.ui.views.FooteredTextView
|
||||
import im.vector.app.core.ui.views.AbstractFooteredTextView
|
||||
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
|
||||
|
@ -154,7 +154,7 @@ abstract class MessageFileItem : AbsMessageItem<MessageFileItem.Holder>() {
|
|||
val fileImageWrapper by bind<ViewGroup>(R.id.messageFileImageView)
|
||||
val fileDownloadProgress by bind<ProgressBar>(R.id.messageFileProgressbar)
|
||||
val filenameView by bind<TextView>(R.id.messageFilenameView)
|
||||
val captionView by bind<FooteredTextView>(R.id.messageCaptionView)
|
||||
val captionView by bind<AbstractFooteredTextView>(R.id.messageCaptionView)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
|
|
@ -34,17 +34,15 @@ import im.vector.app.core.epoxy.onClick
|
|||
import im.vector.app.core.extensions.setTextOrHide
|
||||
import im.vector.app.core.files.LocalFilesHelper
|
||||
import im.vector.app.core.glide.GlideApp
|
||||
import im.vector.app.core.ui.views.FooteredTextView
|
||||
import im.vector.app.core.ui.views.AbstractFooteredTextView
|
||||
import im.vector.app.core.utils.DimensionConverter
|
||||
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.style.granularRoundedCorners
|
||||
import im.vector.app.features.home.room.detail.timeline.view.ScMessageBubbleWrapView
|
||||
import im.vector.app.features.media.ImageContentRenderer
|
||||
import im.vector.app.features.themes.defaultScBubbleAppearance
|
||||
import kotlin.math.round
|
||||
import org.matrix.android.sdk.api.session.room.model.message.MessageType
|
||||
import org.matrix.android.sdk.api.util.MimeTypes
|
||||
|
||||
@EpoxyModelClass
|
||||
abstract class MessageImageVideoItem : AbsMessageItem<MessageImageVideoItem.Holder>() {
|
||||
|
@ -255,7 +253,7 @@ abstract class MessageImageVideoItem : AbsMessageItem<MessageImageVideoItem.Hold
|
|||
class Holder : AbsMessageItem.Holder(STUB_ID) {
|
||||
val progressLayout by bind<ViewGroup>(R.id.messageMediaUploadProgressLayout)
|
||||
val imageView by bind<ImageView>(R.id.messageThumbnailView)
|
||||
val captionView by bind<FooteredTextView>(R.id.messageCaptionView)
|
||||
val captionView by bind<AbstractFooteredTextView>(R.id.messageCaptionView)
|
||||
val playContentView by bind<ImageView>(R.id.messageMediaPlayView)
|
||||
val mediaContentView by bind<ViewGroup>(R.id.messageContentMedia)
|
||||
}
|
||||
|
|
|
@ -17,23 +17,18 @@
|
|||
package im.vector.app.features.home.room.detail.timeline.item
|
||||
|
||||
import android.text.Spanned
|
||||
import android.text.method.MovementMethod
|
||||
import android.view.ViewStub
|
||||
import androidx.appcompat.widget.AppCompatTextView
|
||||
import androidx.core.text.PrecomputedTextCompat
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.core.widget.TextViewCompat
|
||||
import com.airbnb.epoxy.EpoxyAttribute
|
||||
import com.airbnb.epoxy.EpoxyModelClass
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.epoxy.onClick
|
||||
import im.vector.app.core.epoxy.onLongClickIgnoringLinks
|
||||
import im.vector.app.core.ui.views.FooteredTextView
|
||||
import im.vector.app.core.ui.views.AbstractFooteredTextView
|
||||
import im.vector.app.features.home.room.detail.timeline.TimelineEventController
|
||||
import im.vector.app.features.home.room.detail.timeline.reply.InReplyToView
|
||||
import im.vector.app.features.home.room.detail.timeline.style.TimelineMessageLayout
|
||||
import im.vector.app.features.home.room.detail.timeline.reply.PreviewReplyUiState
|
||||
import im.vector.app.features.home.room.detail.timeline.reply.ReplyPreviewRetriever
|
||||
import im.vector.app.features.home.room.detail.timeline.tools.findPillsAndProcess
|
||||
import im.vector.app.features.home.room.detail.timeline.url.AbstractPreviewUrlView
|
||||
import im.vector.app.features.home.room.detail.timeline.url.PreviewUrlRetriever
|
||||
|
@ -105,7 +100,7 @@ abstract class MessageTextItem : AbsMessageItem<MessageTextItem.Holder>() {
|
|||
holder.previewUrlView.delegate = previewUrlCallback
|
||||
holder.previewUrlView.renderMessageLayout(attributes.informationData.messageLayout)
|
||||
|
||||
val messageView: FooteredTextView = holder.messageView(useRichTextEditorStyle) //if (useRichTextEditorStyle) holder.richMessageView else holder.plainMessageView
|
||||
val messageView: AbstractFooteredTextView = holder.messageView(useRichTextEditorStyle) //if (useRichTextEditorStyle) holder.richMessageView else holder.plainMessageView
|
||||
if (useBigFont) {
|
||||
messageView.textSize = 44F
|
||||
} else {
|
||||
|
@ -155,10 +150,10 @@ abstract class MessageTextItem : AbsMessageItem<MessageTextItem.Holder>() {
|
|||
lateinit var previewUrlView: AbstractPreviewUrlView // set to either previewUrlViewElement or previewUrlViewSc by layout
|
||||
private val richMessageStub by bind<ViewStub>(R.id.richMessageTextViewStub)
|
||||
private val plainMessageStub by bind<ViewStub>(R.id.plainMessageTextViewStub)
|
||||
val richMessageView: FooteredTextView by lazy {
|
||||
val richMessageView: AbstractFooteredTextView by lazy {
|
||||
richMessageStub.inflate().findViewById(R.id.messageTextView)
|
||||
}
|
||||
val plainMessageView: FooteredTextView by lazy {
|
||||
val plainMessageView: AbstractFooteredTextView by lazy {
|
||||
plainMessageStub.inflate().findViewById(R.id.messageTextView)
|
||||
}
|
||||
fun messageView(useRichTextEditorStyle: Boolean) = if (useRichTextEditorStyle) richMessageView else plainMessageView
|
||||
|
|
|
@ -6,7 +6,8 @@
|
|||
but it also makes it align better for RTL texts in RTL locales - at least
|
||||
until the user pill is touched...
|
||||
-->
|
||||
<im.vector.app.core.ui.views.FooteredTextView android:id="@+id/messageTextView"
|
||||
<im.vector.app.core.ui.views.FooteredTextView
|
||||
android:id="@+id/messageTextView"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
style="@style/Widget.Vector.TextView.Body"
|
||||
|
|
|
@ -6,7 +6,8 @@
|
|||
but it also makes it align better for RTL texts in RTL locales - at least
|
||||
until the user pill is touched...
|
||||
-->
|
||||
<io.element.android.wysiwyg.EditorStyledTextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<io.element.android.wysiwyg.EditorStyledTextView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/messageTextView"
|
||||
style="@style/Widget.Vector.TextView.Body"
|
||||
|
|
Loading…
Add table
Reference in a new issue