mirror of
https://github.com/SchildiChat/SchildiChat-android.git
synced 2025-02-16 20:10:04 +03:00
Rich replies also when replying via media
Change-Id: I3352fe0a6c4b0c08a7564337b02d1cc8e5e4bbc4
This commit is contained in:
parent
d8ac4f53d7
commit
15d8a916b1
14 changed files with 142 additions and 52 deletions
|
@ -65,4 +65,9 @@
|
|||
<item name="closeIconTint">?vctr_content_secondary</item>
|
||||
</style>
|
||||
|
||||
<style name="InReplyToViewParams">
|
||||
<item name="android:layout_marginTop">4dp</item>
|
||||
<item name="android:layout_marginBottom">8dp</item>
|
||||
<item name="android:visibility">gone</item>
|
||||
</style>
|
||||
</resources>
|
||||
|
|
|
@ -202,11 +202,11 @@ class MessageItemFactory @Inject constructor(
|
|||
is MessageImageInfoContent -> buildImageMessageItem(messageContent, informationData, highlight, callback, attributes)
|
||||
is MessageNoticeContent -> buildNoticeMessageItem(messageContent, informationData, highlight, callback, attributes)
|
||||
is MessageVideoContent -> buildVideoMessageItem(messageContent, informationData, highlight, callback, attributes)
|
||||
is MessageFileContent -> buildFileMessageItem(messageContent, highlight, attributes)
|
||||
is MessageAudioContent -> buildAudioContent(params, messageContent, informationData, highlight, attributes)
|
||||
is MessageFileContent -> buildFileMessageItem(messageContent, highlight, callback, attributes)
|
||||
is MessageAudioContent -> buildAudioContent(params, messageContent, informationData, highlight, callback, attributes)
|
||||
is MessageVerificationRequestContent -> buildVerificationRequestMessageItem(messageContent, informationData, highlight, callback, attributes)
|
||||
is MessagePollContent -> buildPollItem(messageContent, informationData, highlight, callback, attributes)
|
||||
is MessageLocationContent -> buildLocationItem(messageContent, informationData, highlight, attributes)
|
||||
is MessageLocationContent -> buildLocationItem(messageContent, informationData, highlight, callback, attributes)
|
||||
is MessageBeaconInfoContent -> liveLocationShareMessageItemFactory.create(params.event, highlight, attributes)
|
||||
is MessageVoiceBroadcastInfoContent -> voiceBroadcastItemFactory.create(params, messageContent, highlight, attributes)
|
||||
else -> buildNotHandledMessageItem(messageContent, informationData, highlight, callback, attributes)
|
||||
|
@ -220,6 +220,7 @@ class MessageItemFactory @Inject constructor(
|
|||
locationContent: MessageLocationContent,
|
||||
informationData: MessageInformationData,
|
||||
highlight: Boolean,
|
||||
callback: TimelineEventController.Callback?,
|
||||
attributes: AbsMessageItem.Attributes,
|
||||
): MessageLocationItem? {
|
||||
val width = timelineMediaSizeProvider.getMaxSize().first
|
||||
|
@ -240,6 +241,9 @@ class MessageItemFactory @Inject constructor(
|
|||
.locationPinProvider(locationPinProvider)
|
||||
.highlighted(highlight)
|
||||
.leftGuideline(avatarSizeProvider.leftGuideline)
|
||||
.movementMethod(createLinkMovementMethod(callback))
|
||||
.replyPreviewRetriever(callback?.getReplyPreviewRetriever())
|
||||
.inReplyToClickCallback(callback)
|
||||
}
|
||||
|
||||
private fun buildPollItem(
|
||||
|
@ -262,6 +266,9 @@ class MessageItemFactory @Inject constructor(
|
|||
.highlighted(highlight)
|
||||
.leftGuideline(avatarSizeProvider.leftGuideline)
|
||||
.callback(callback)
|
||||
.movementMethod(createLinkMovementMethod(callback))
|
||||
.replyPreviewRetriever(callback?.getReplyPreviewRetriever())
|
||||
.inReplyToClickCallback(callback)
|
||||
}
|
||||
|
||||
private fun createPollQuestion(
|
||||
|
@ -279,6 +286,7 @@ class MessageItemFactory @Inject constructor(
|
|||
messageContent: MessageAudioContent,
|
||||
informationData: MessageInformationData,
|
||||
highlight: Boolean,
|
||||
callback: TimelineEventController.Callback?,
|
||||
attributes: AbsMessageItem.Attributes
|
||||
): MessageAudioItem {
|
||||
val fileUrl = getAudioFileUrl(messageContent, informationData)
|
||||
|
@ -300,6 +308,9 @@ class MessageItemFactory @Inject constructor(
|
|||
.contentDownloadStateTrackerBinder(contentDownloadStateTrackerBinder)
|
||||
.highlighted(highlight)
|
||||
.leftGuideline(avatarSizeProvider.leftGuideline)
|
||||
.movementMethod(createLinkMovementMethod(callback))
|
||||
.replyPreviewRetriever(callback?.getReplyPreviewRetriever())
|
||||
.inReplyToClickCallback(callback)
|
||||
}
|
||||
|
||||
private fun getAudioFileUrl(
|
||||
|
@ -328,6 +339,7 @@ class MessageItemFactory @Inject constructor(
|
|||
messageContent: MessageAudioContent,
|
||||
informationData: MessageInformationData,
|
||||
highlight: Boolean,
|
||||
callback: TimelineEventController.Callback?,
|
||||
attributes: AbsMessageItem.Attributes
|
||||
): MessageVoiceItem? {
|
||||
// Do not display voice broadcast messages
|
||||
|
@ -361,6 +373,9 @@ class MessageItemFactory @Inject constructor(
|
|||
.contentDownloadStateTrackerBinder(contentDownloadStateTrackerBinder)
|
||||
.highlighted(highlight)
|
||||
.leftGuideline(avatarSizeProvider.leftGuideline)
|
||||
.movementMethod(createLinkMovementMethod(callback))
|
||||
.replyPreviewRetriever(callback?.getReplyPreviewRetriever())
|
||||
.inReplyToClickCallback(callback)
|
||||
}
|
||||
|
||||
private fun buildVerificationRequestMessageItem(
|
||||
|
@ -409,6 +424,7 @@ class MessageItemFactory @Inject constructor(
|
|||
private fun buildFileMessageItem(
|
||||
messageContent: MessageFileContent,
|
||||
highlight: Boolean,
|
||||
callback: TimelineEventController.Callback?,
|
||||
attributes: AbsMessageItem.Attributes,
|
||||
): MessageFileItem {
|
||||
val mxcUrl = messageContent.getFileUrl() ?: ""
|
||||
|
@ -424,6 +440,9 @@ class MessageItemFactory @Inject constructor(
|
|||
.filename(messageContent.getFileName())
|
||||
.caption(messageContent.getCaption())
|
||||
.iconRes(R.drawable.ic_paperclip)
|
||||
.movementMethod(createLinkMovementMethod(callback))
|
||||
.replyPreviewRetriever(callback?.getReplyPreviewRetriever())
|
||||
.inReplyToClickCallback(callback)
|
||||
}
|
||||
|
||||
private fun buildAudioContent(
|
||||
|
@ -431,11 +450,12 @@ class MessageItemFactory @Inject constructor(
|
|||
messageContent: MessageAudioContent,
|
||||
informationData: MessageInformationData,
|
||||
highlight: Boolean,
|
||||
callback: TimelineEventController.Callback?,
|
||||
attributes: AbsMessageItem.Attributes,
|
||||
) = if (messageContent.voiceMessageIndicator != null) {
|
||||
buildVoiceMessageItem(params, messageContent, informationData, highlight, attributes)
|
||||
buildVoiceMessageItem(params, messageContent, informationData, highlight, callback, attributes)
|
||||
} else {
|
||||
buildAudioMessageItem(params, messageContent, informationData, highlight, attributes)
|
||||
buildAudioMessageItem(params, messageContent, informationData, highlight, callback, attributes)
|
||||
}
|
||||
|
||||
private fun buildNotHandledMessageItem(
|
||||
|
@ -481,6 +501,9 @@ class MessageItemFactory @Inject constructor(
|
|||
.contentUploadStateTrackerBinder(contentUploadStateTrackerBinder)
|
||||
.playable(playable)
|
||||
.highlighted(highlight)
|
||||
.movementMethod(createLinkMovementMethod(callback))
|
||||
.replyPreviewRetriever(callback?.getReplyPreviewRetriever())
|
||||
.inReplyToClickCallback(callback)
|
||||
.mediaData(data)
|
||||
.apply {
|
||||
if (messageContent.msgType == MessageType.MSGTYPE_STICKER_LOCAL) {
|
||||
|
@ -543,6 +566,9 @@ class MessageItemFactory @Inject constructor(
|
|||
.contentUploadStateTrackerBinder(contentUploadStateTrackerBinder)
|
||||
.playable(true)
|
||||
.highlighted(highlight)
|
||||
.movementMethod(createLinkMovementMethod(callback))
|
||||
.replyPreviewRetriever(callback?.getReplyPreviewRetriever())
|
||||
.inReplyToClickCallback(callback)
|
||||
.mediaData(thumbnailData)
|
||||
.clickListener { view -> callback?.onVideoMessageClicked(messageContent, videoData, view.findViewById(R.id.messageThumbnailView)) }
|
||||
}
|
||||
|
@ -604,14 +630,14 @@ class MessageItemFactory @Inject constructor(
|
|||
.markwonPlugins(htmlRenderer.get().plugins)
|
||||
.searchForPills(isFormatted)
|
||||
.previewUrlRetriever(callback?.getPreviewUrlRetriever())
|
||||
.replyPreviewRetriever(callback?.getReplyPreviewRetriever())
|
||||
.inReplyToClickCallback(callback)
|
||||
.imageContentRenderer(imageContentRenderer)
|
||||
.previewUrlCallback(callback)
|
||||
.leftGuideline(avatarSizeProvider.leftGuideline)
|
||||
.attributes(attributes)
|
||||
.highlighted(highlight)
|
||||
.movementMethod(createLinkMovementMethod(callback))
|
||||
.replyPreviewRetriever(callback?.getReplyPreviewRetriever())
|
||||
.inReplyToClickCallback(callback)
|
||||
}
|
||||
|
||||
private fun annotateWithEdited(
|
||||
|
@ -705,8 +731,6 @@ class MessageItemFactory @Inject constructor(
|
|||
return MessageTextItem_()
|
||||
.leftGuideline(avatarSizeProvider.leftGuideline)
|
||||
.previewUrlRetriever(callback?.getPreviewUrlRetriever())
|
||||
.replyPreviewRetriever(callback?.getReplyPreviewRetriever())
|
||||
.inReplyToClickCallback(callback)
|
||||
.imageContentRenderer(imageContentRenderer)
|
||||
.previewUrlCallback(callback)
|
||||
.attributes(attributes)
|
||||
|
@ -714,6 +738,8 @@ class MessageItemFactory @Inject constructor(
|
|||
.bindingOptions(bindingOptions)
|
||||
.highlighted(highlight)
|
||||
.movementMethod(createLinkMovementMethod(callback))
|
||||
.replyPreviewRetriever(callback?.getReplyPreviewRetriever())
|
||||
.inReplyToClickCallback(callback)
|
||||
}
|
||||
|
||||
private fun buildEmoteMessageItem(
|
||||
|
@ -740,13 +766,13 @@ class MessageItemFactory @Inject constructor(
|
|||
.bindingOptions(bindingOptions)
|
||||
.leftGuideline(avatarSizeProvider.leftGuideline)
|
||||
.previewUrlRetriever(callback?.getPreviewUrlRetriever())
|
||||
.replyPreviewRetriever(callback?.getReplyPreviewRetriever())
|
||||
.inReplyToClickCallback(callback)
|
||||
.imageContentRenderer(imageContentRenderer)
|
||||
.previewUrlCallback(callback)
|
||||
.attributes(attributes)
|
||||
.highlighted(highlight)
|
||||
.movementMethod(createLinkMovementMethod(callback))
|
||||
.replyPreviewRetriever(callback?.getReplyPreviewRetriever())
|
||||
.inReplyToClickCallback(callback)
|
||||
}
|
||||
|
||||
private fun MessageContentWithFormattedBody.getHtmlBody(): CharSequence {
|
||||
|
|
|
@ -49,6 +49,7 @@ import org.matrix.android.sdk.api.session.room.model.message.MessageVerification
|
|||
import org.matrix.android.sdk.api.session.room.send.SendState
|
||||
import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
|
||||
import org.matrix.android.sdk.api.session.room.timeline.hasBeenEdited
|
||||
import org.matrix.android.sdk.api.session.room.timeline.isReply
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
|
@ -169,6 +170,7 @@ class MessageInformationDataFactory @Inject constructor(
|
|||
senderPowerLevel = senderPowerLevel,
|
||||
isDirect = isEffectivelyDirect,
|
||||
isPublic = roomSummary?.isPublic ?: false,
|
||||
isReply = event.isReply(),
|
||||
dmChatPartnerId = dmOtherMemberId,
|
||||
isFirstFromThisSender = isFirstFromThisSender,
|
||||
isLastFromThisSender = isLastFromThisSender,
|
||||
|
|
|
@ -18,6 +18,7 @@ package im.vector.app.features.home.room.detail.timeline.item
|
|||
|
||||
import android.content.Context
|
||||
import android.graphics.Typeface
|
||||
import android.text.method.MovementMethod
|
||||
import android.view.View
|
||||
import android.widget.ImageView
|
||||
import android.widget.ProgressBar
|
||||
|
@ -37,6 +38,9 @@ import im.vector.app.features.home.AvatarRenderer
|
|||
import im.vector.app.features.home.room.detail.timeline.MessageColorProvider
|
||||
import im.vector.app.features.home.room.detail.timeline.TimelineEventController
|
||||
import im.vector.app.features.home.room.detail.timeline.helper.MatrixItemColorProvider
|
||||
import im.vector.app.features.home.room.detail.timeline.reply.InReplyToView
|
||||
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.style.TimelineMessageLayout
|
||||
import im.vector.app.features.home.room.detail.timeline.view.ScMessageBubbleWrapView
|
||||
import im.vector.app.features.home.room.detail.timeline.view.TimelineMessageLayoutRenderer
|
||||
|
@ -55,6 +59,8 @@ abstract class AbsMessageItem<H : AbsMessageItem.Holder>(
|
|||
@LayoutRes layoutId: Int = R.layout.item_timeline_event_base
|
||||
) : AbsBaseMessageItem<H>(layoutId) {
|
||||
|
||||
private val replyViewUpdater = ReplyViewUpdater()
|
||||
|
||||
override val baseAttributes: AbsBaseMessageItem.Attributes
|
||||
get() = attributes
|
||||
|
||||
|
@ -65,6 +71,15 @@ abstract class AbsMessageItem<H : AbsMessageItem.Holder>(
|
|||
@EpoxyAttribute
|
||||
lateinit var attributes: Attributes
|
||||
|
||||
@EpoxyAttribute(EpoxyAttribute.Option.DoNotHash)
|
||||
var movementMethod: MovementMethod? = null
|
||||
|
||||
@EpoxyAttribute
|
||||
var replyPreviewRetriever: ReplyPreviewRetriever? = null
|
||||
|
||||
@EpoxyAttribute
|
||||
var inReplyToClickCallback: TimelineEventController.InReplyToClickCallback? = null
|
||||
|
||||
private val _avatarClickListener = object : ClickListener {
|
||||
override fun invoke(p1: View) {
|
||||
attributes.avatarCallback?.onAvatarClicked(attributes.informationData)
|
||||
|
@ -140,6 +155,18 @@ abstract class AbsMessageItem<H : AbsMessageItem.Holder>(
|
|||
updateHighlightedMessageHeight(holder, false)
|
||||
}
|
||||
}
|
||||
|
||||
// Replies
|
||||
if (holder.replyToView != null) {
|
||||
replyViewUpdater.replyView = holder.replyToView
|
||||
val safeReplyPreviewRetriever = replyPreviewRetriever
|
||||
if (safeReplyPreviewRetriever == null) {
|
||||
holder.replyToView?.isVisible = false
|
||||
} else {
|
||||
safeReplyPreviewRetriever.addListener(attributes.informationData.eventId, replyViewUpdater)
|
||||
}
|
||||
holder.replyToView?.delegate = inReplyToClickCallback
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateHighlightedMessageHeight(holder: Holder, isExpanded: Boolean) {
|
||||
|
@ -160,6 +187,8 @@ abstract class AbsMessageItem<H : AbsMessageItem.Holder>(
|
|||
holder.memberNameView.setOnLongClickListener(null)
|
||||
attributes.avatarRenderer.clear(holder.threadSummaryAvatarImageView)
|
||||
holder.threadSummaryConstraintLayout.setOnClickListener(null)
|
||||
replyPreviewRetriever?.removeListener(attributes.informationData.eventId, replyViewUpdater)
|
||||
replyViewUpdater.replyView = null
|
||||
super.unbind(holder)
|
||||
}
|
||||
|
||||
|
@ -172,6 +201,7 @@ abstract class AbsMessageItem<H : AbsMessageItem.Holder>(
|
|||
val timeView by bind<TextView>(R.id.messageTimeView)
|
||||
val sendStateImageView by bind<SendStateImageView>(R.id.messageSendStateImageView)
|
||||
val eventSendingIndicator by bind<ProgressBar>(R.id.eventSendingIndicator)
|
||||
val replyToView: InReplyToView? by lazy { view.findViewById(R.id.inReplyToContainer) }
|
||||
val threadSummaryConstraintLayout by bind<ConstraintLayout>(R.id.messageThreadSummaryConstraintLayout)
|
||||
val threadSummaryCounterTextView by bind<TextView>(R.id.messageThreadSummaryCounterTextView)
|
||||
val threadSummaryAvatarImageView by bind<ImageView>(R.id.messageThreadSummaryAvatarImageView)
|
||||
|
@ -237,6 +267,16 @@ abstract class AbsMessageItem<H : AbsMessageItem.Holder>(
|
|||
)
|
||||
}
|
||||
|
||||
|
||||
inner class ReplyViewUpdater : ReplyPreviewRetriever.PreviewReplyRetrieverListener {
|
||||
var replyView: InReplyToView? = null
|
||||
|
||||
override fun onStateUpdated(state: PreviewReplyUiState) {
|
||||
replyPreviewRetriever?.let {
|
||||
replyView?.render(state, it, attributes.informationData, movementMethod, coroutineScope)
|
||||
}
|
||||
}
|
||||
}
|
||||
override fun ignoreMessageGuideline(context: Context): Boolean {
|
||||
val messageLayout = attributes.informationData.messageLayout as? TimelineMessageLayout.ScBubble ?: return false
|
||||
return infoInBubbles(messageLayout) && canHideAvatars(attributes)
|
||||
|
|
|
@ -145,6 +145,8 @@ abstract class MessageImageVideoItem : AbsMessageItem<MessageImageVideoItem.Hold
|
|||
|
||||
private fun hasCaption() = !mediaData.caption.isNullOrBlank()
|
||||
|
||||
private fun needsRealBubble() = hasCaption() || attributes.informationData.isReply
|
||||
|
||||
override fun unbind(holder: Holder) {
|
||||
GlideApp.with(holder.view.context.applicationContext).clear(holder.imageView)
|
||||
imageContentRenderer.clear(holder.imageView)
|
||||
|
@ -211,7 +213,7 @@ abstract class MessageImageVideoItem : AbsMessageItem<MessageImageVideoItem.Hold
|
|||
}
|
||||
|
||||
override fun getScBubbleMargin(resources: Resources): Int {
|
||||
if (hasCaption()) {
|
||||
if (needsRealBubble()) {
|
||||
return super.getScBubbleMargin(resources)
|
||||
}
|
||||
return 0
|
||||
|
@ -238,7 +240,7 @@ abstract class MessageImageVideoItem : AbsMessageItem<MessageImageVideoItem.Hold
|
|||
when {
|
||||
// Don't show it for non-bubble layouts, don't show for Stickers, ...
|
||||
// Also only supported for default corner radius
|
||||
!(messageLayout.isRealBubble || messageLayout.isPseudoBubble) || hasCaption() || mode != ImageContentRenderer.Mode.THUMBNAIL -> {
|
||||
!(messageLayout.isRealBubble || messageLayout.isPseudoBubble) || needsRealBubble() || mode != ImageContentRenderer.Mode.THUMBNAIL -> {
|
||||
holder.mediaContentView.background = null
|
||||
}
|
||||
attributes.informationData.sentByMe -> {
|
||||
|
|
|
@ -42,6 +42,7 @@ data class MessageInformationData(
|
|||
val readReceiptAnonymous: AnonymousReadReceipt,
|
||||
val isDirect: Boolean,
|
||||
val isPublic: Boolean,
|
||||
val isReply: Boolean,
|
||||
val senderPowerLevel: Int?,
|
||||
val dmChatPartnerId: String?,
|
||||
val e2eDecoration: E2EDecoration = E2EDecoration.NONE,
|
||||
|
|
|
@ -60,12 +60,6 @@ abstract class MessageTextItem : AbsMessageItem<MessageTextItem.Holder>() {
|
|||
@EpoxyAttribute
|
||||
var useBigFont: Boolean = false
|
||||
|
||||
@EpoxyAttribute
|
||||
var replyPreviewRetriever: ReplyPreviewRetriever? = null
|
||||
|
||||
@EpoxyAttribute
|
||||
var inReplyToClickCallback: TimelineEventController.InReplyToClickCallback? = null
|
||||
|
||||
@EpoxyAttribute
|
||||
var previewUrlRetriever: PreviewUrlRetriever? = null
|
||||
|
||||
|
@ -75,14 +69,14 @@ abstract class MessageTextItem : AbsMessageItem<MessageTextItem.Holder>() {
|
|||
@EpoxyAttribute
|
||||
var imageContentRenderer: ImageContentRenderer? = null
|
||||
|
||||
@EpoxyAttribute(EpoxyAttribute.Option.DoNotHash)
|
||||
var movementMethod: MovementMethod? = null
|
||||
// SC: moved to super
|
||||
//@EpoxyAttribute(EpoxyAttribute.Option.DoNotHash)
|
||||
//var movementMethod: MovementMethod? = null
|
||||
|
||||
@EpoxyAttribute(EpoxyAttribute.Option.DoNotHash)
|
||||
var markwonPlugins: (List<MarkwonPlugin>)? = null
|
||||
|
||||
private val previewUrlViewUpdater = PreviewUrlViewUpdater()
|
||||
private val replyViewUpdater = ReplyViewUpdater()
|
||||
|
||||
// Remember footer measures for URL updates
|
||||
private var footerWidth: Int = 0
|
||||
|
@ -107,15 +101,6 @@ abstract class MessageTextItem : AbsMessageItem<MessageTextItem.Holder>() {
|
|||
holder.previewUrlView.delegate = previewUrlCallback
|
||||
holder.previewUrlView.renderMessageLayout(attributes.informationData.messageLayout)
|
||||
|
||||
replyViewUpdater.replyView = holder.replyToView
|
||||
val safeReplyPreviewRetriever = replyPreviewRetriever
|
||||
if (safeReplyPreviewRetriever == null) {
|
||||
holder.replyToView.isVisible = false
|
||||
} else {
|
||||
safeReplyPreviewRetriever.addListener(attributes.informationData.eventId, replyViewUpdater)
|
||||
}
|
||||
holder.replyToView.delegate = inReplyToClickCallback
|
||||
|
||||
if (useBigFont) {
|
||||
holder.messageView.textSize = 44F
|
||||
} else {
|
||||
|
@ -155,7 +140,6 @@ abstract class MessageTextItem : AbsMessageItem<MessageTextItem.Holder>() {
|
|||
previewUrlViewUpdater.previewUrlView = null
|
||||
previewUrlViewUpdater.imageContentRenderer = null
|
||||
previewUrlRetriever?.removeListener(attributes.informationData.eventId, previewUrlViewUpdater)
|
||||
replyPreviewRetriever?.removeListener(attributes.informationData.eventId, replyViewUpdater)
|
||||
}
|
||||
|
||||
override fun getViewStubId() = STUB_ID
|
||||
|
@ -164,7 +148,6 @@ abstract class MessageTextItem : AbsMessageItem<MessageTextItem.Holder>() {
|
|||
val messageView by bind<FooteredTextView>(R.id.messageTextView)
|
||||
val previewUrlViewElement by bind<PreviewUrlView>(R.id.messageUrlPreviewElement)
|
||||
val previewUrlViewSc by bind<PreviewUrlViewSc>(R.id.messageUrlPreviewSc)
|
||||
val replyToView by bind<InReplyToView>(R.id.inReplyToContainer)
|
||||
lateinit var previewUrlView: AbstractPreviewUrlView // set to either previewUrlViewElement or previewUrlViewSc by layout
|
||||
}
|
||||
|
||||
|
@ -197,17 +180,6 @@ abstract class MessageTextItem : AbsMessageItem<MessageTextItem.Holder>() {
|
|||
}
|
||||
}
|
||||
|
||||
inner class ReplyViewUpdater : ReplyPreviewRetriever.PreviewReplyRetrieverListener {
|
||||
var replyView: InReplyToView? = null
|
||||
|
||||
override fun onStateUpdated(state: PreviewReplyUiState) {
|
||||
timber.log.Timber.i("REPLY STATE UPDATE $replyPreviewRetriever $replyView")
|
||||
replyPreviewRetriever?.let {
|
||||
replyView?.render(state, it, attributes.informationData, movementMethod, coroutineScope)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override fun allowFooterOverlay(holder: Holder, bubbleWrapView: ScMessageBubbleWrapView): Boolean {
|
||||
return true
|
||||
|
|
|
@ -28,6 +28,7 @@ import im.vector.app.features.themes.BubbleThemeUtils
|
|||
import org.matrix.android.sdk.api.session.Session
|
||||
import org.matrix.android.sdk.api.session.events.model.EventType
|
||||
import org.matrix.android.sdk.api.session.room.model.message.MessageContent
|
||||
import org.matrix.android.sdk.api.session.room.model.message.MessageImageContent
|
||||
import org.matrix.android.sdk.api.session.room.model.message.MessageNoticeContent
|
||||
import org.matrix.android.sdk.api.session.room.model.message.MessageType
|
||||
import org.matrix.android.sdk.api.session.room.model.message.MessageVerificationRequestContent
|
||||
|
@ -36,6 +37,7 @@ import org.matrix.android.sdk.api.session.room.model.message.getCaption
|
|||
import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
|
||||
import org.matrix.android.sdk.api.session.room.timeline.getLastMessageContent
|
||||
import org.matrix.android.sdk.api.session.room.timeline.isEdition
|
||||
import org.matrix.android.sdk.api.session.room.timeline.isReply
|
||||
import org.matrix.android.sdk.api.session.room.timeline.isRootThread
|
||||
import javax.inject.Inject
|
||||
|
||||
|
@ -208,9 +210,10 @@ class TimelineMessageLayoutFactory @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private fun MessageContent?.isPseudoBubble(event: TimelineEvent): Boolean {
|
||||
private fun MessageContent?.isPseudoBubble(event: TimelineEvent, ignoreReply: Boolean = false): Boolean {
|
||||
if (this == null) return false
|
||||
if (event.root.isRedacted()) return false
|
||||
if (!ignoreReply && event.isReply()) return false
|
||||
if (this is MessageWithAttachmentContent && !getCaption().isNullOrBlank()) return false
|
||||
return this.msgType in MSG_TYPES_WITH_PSEUDO_BUBBLE_LAYOUT
|
||||
}
|
||||
|
@ -242,6 +245,7 @@ class TimelineMessageLayoutFactory @Inject constructor(
|
|||
val type = root.getClearType()
|
||||
if (type in EVENT_TYPES_WITH_BUBBLE_LAYOUT) {
|
||||
val messageContent = getVectorLastMessageContent()
|
||||
if (messageContent.isPseudoBubble(this, true)) return true
|
||||
return messageContent?.msgType !in MSG_TYPES_WITHOUT_BUBBLE_LAYOUT
|
||||
}
|
||||
return false
|
||||
|
|
|
@ -604,7 +604,7 @@ fun setFlatRtl(layout: ViewGroup, direction: Int, childDirection: Int, depth: In
|
|||
}
|
||||
|
||||
// Static to use from classes that use simplified/non-sc layouts, e.g. item_timeline_event_base_noinfo
|
||||
fun renderStubMessageLayout(messageLayout: TimelineMessageLayout, viewStubContainer: FrameLayout) {
|
||||
fun renderStubMessageLayout(messageLayout: TimelineMessageLayout, viewStubContainer: View) {
|
||||
if (messageLayout !is TimelineMessageLayout.ScBubble) {
|
||||
return
|
||||
}
|
||||
|
|
|
@ -9,6 +9,13 @@
|
|||
android:minWidth="@dimen/chat_bubble_fixed_size"
|
||||
tools:viewBindingIgnore="true">
|
||||
|
||||
<im.vector.app.features.home.room.detail.timeline.reply.InReplyToView
|
||||
android:id="@+id/inReplyToContainer"
|
||||
style="@style/InReplyToViewParams"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/messageMainInnerLayout"
|
||||
style="@style/TimelineContentMediaPillStyle"
|
||||
|
|
|
@ -9,6 +9,13 @@
|
|||
android:orientation="vertical"
|
||||
tools:viewBindingIgnore="true">
|
||||
|
||||
<im.vector.app.features.home.room.detail.timeline.reply.InReplyToView
|
||||
android:id="@+id/inReplyToContainer"
|
||||
style="@style/InReplyToViewParams"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/messageFileMainLayout"
|
||||
style="@style/TimelineContentMediaPillStyle"
|
||||
|
|
|
@ -5,15 +5,28 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<im.vector.app.features.home.room.detail.timeline.reply.InReplyToView
|
||||
android:id="@+id/inReplyToContainer"
|
||||
style="@style/InReplyToViewParams"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<!-- Size will be overrode -->
|
||||
<ImageView
|
||||
android:id="@+id/staticMapImageView"
|
||||
android:layout_width="300dp"
|
||||
android:layout_height="200dp"
|
||||
android:layout_marginTop="8dp"
|
||||
app:layout_goneMarginTop="0dp"
|
||||
android:contentDescription="@string/a11y_static_map_image"
|
||||
android:scaleType="centerCrop"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/inReplyToContainer"
|
||||
tools:src="@tools:sample/backgrounds/scenic" />
|
||||
|
||||
<ImageView
|
||||
|
|
|
@ -6,15 +6,28 @@
|
|||
android:layout_height="wrap_content"
|
||||
tools:viewBindingIgnore="true">
|
||||
|
||||
<im.vector.app.features.home.room.detail.timeline.reply.InReplyToView
|
||||
android:id="@+id/inReplyToContainer"
|
||||
style="@style/InReplyToViewParams"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/messageThumbnailView"
|
||||
android:layout_width="375dp"
|
||||
android:layout_height="0dp"
|
||||
android:contentDescription="@string/a11y_image"
|
||||
android:layout_marginTop="8dp"
|
||||
app:layout_goneMarginTop="0dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/inReplyToContainer"
|
||||
tools:layout_height="300dp"
|
||||
tools:src="@tools:sample/backgrounds/scenic" />
|
||||
|
||||
|
@ -57,6 +70,6 @@
|
|||
android:visibility="gone"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/messageTextView"
|
||||
app:layout_constraintTop_toBottomOf="@id/messageCaptionView"
|
||||
tools:visibility="visible" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
|
|
@ -10,11 +10,9 @@
|
|||
|
||||
<im.vector.app.features.home.room.detail.timeline.reply.InReplyToView
|
||||
android:id="@+id/inReplyToContainer"
|
||||
style="@style/InReplyToViewParams"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<!-- Layout gravity left: fixes long display name pills moving text out:
|
||||
|
|
Loading…
Add table
Reference in a new issue