From 9cccbd7aae0b43a5dad3a36203f7542d2d8e3afe Mon Sep 17 00:00:00 2001 From: jubb Date: Fri, 25 Jun 2021 16:30:23 +1000 Subject: [PATCH] refactor: use activity dispatcher --- .../conversation/v2/AlbumThumbnailView.kt | 43 +++++++++++++------ .../conversation/v2/ConversationActivityV2.kt | 28 +++++++++--- .../conversation/v2/ConversationAdapter.kt | 2 +- .../v2/messages/VisibleMessageContentView.kt | 13 +----- .../v2/messages/VisibleMessageView.kt | 8 ++-- .../loki/utilities/ActivityUtilities.kt | 13 ++++++ 6 files changed, 72 insertions(+), 35 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/AlbumThumbnailView.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/AlbumThumbnailView.kt index d8136c9f12..56da118f3b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/AlbumThumbnailView.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/AlbumThumbnailView.kt @@ -1,6 +1,7 @@ package org.thoughtcrime.securesms.conversation.v2 import android.content.Context +import android.content.Intent import android.graphics.Canvas import android.graphics.Rect import android.util.AttributeSet @@ -11,9 +12,12 @@ import androidx.core.view.children import androidx.core.view.isVisible import kotlinx.android.synthetic.main.album_thumbnail_view.view.* import network.loki.messenger.R +import org.thoughtcrime.securesms.MediaPreviewActivity import org.thoughtcrime.securesms.components.CornerMask import org.thoughtcrime.securesms.conversation.v2.utilities.KThumbnailView import org.thoughtcrime.securesms.database.model.MmsMessageRecord +import org.thoughtcrime.securesms.loki.utilities.ActivityDispatcher +import org.thoughtcrime.securesms.longmessage.LongMessageActivity import org.thoughtcrime.securesms.mms.GlideRequests import org.thoughtcrime.securesms.mms.Slide @@ -35,12 +39,6 @@ class AlbumThumbnailView : FrameLayout { private val cornerMask by lazy { CornerMask(this) } private var slides: List = listOf() - sealed class Hit { - object ReadMoreHit : Hit() - data class SlideHit(val slide: Slide) : Hit() - data class DownloadHit(val slide: Slide) : Hit() - } - private fun initialize() { LayoutInflater.from(context).inflate(R.layout.album_thumbnail_view, this) } @@ -54,25 +52,42 @@ class AlbumThumbnailView : FrameLayout { // region Interaction - fun calculateHitObject(hitRect: Rect): Hit? { + fun calculateHitObject(rawRect: Rect, mms: MmsMessageRecord) { // Z-check in specific order val testRect = Rect() // test "Read More" - albumCellBodyTextReadMore.getHitRect(testRect) - if (Rect.intersects(hitRect, testRect)) { - return Hit.ReadMoreHit + albumCellBodyTextReadMore.getGlobalVisibleRect(testRect) + if (Rect.intersects(rawRect, testRect)) { + // dispatch to activity view + ActivityDispatcher.get(context)?.dispatchIntent { context -> + LongMessageActivity.getIntent(context, mms.recipient.address, mms.getId(), true) + } + return } // test each album child albumCellContainer.findViewById(R.id.album_thumbnail_root)?.children?.forEachIndexed { index, child -> - child.getHitRect(testRect) - if (Rect.intersects(hitRect, testRect)) { + child.getGlobalVisibleRect(testRect) + if (Rect.intersects(rawRect, testRect)) { // hit intersects with this particular child slides.getOrNull(index)?.let { slide -> - return Hit.SlideHit(slide) + // dispatch to view image + if (MediaPreviewActivity.isContentTypeSupported(slide.contentType) && slide.uri != null) { + ActivityDispatcher.get(context)?.dispatchIntent { context -> + Intent(context, MediaPreviewActivity::class.java).apply { + addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) + setDataAndType(slide.uri, slide.contentType) + putExtra(MediaPreviewActivity.ADDRESS_EXTRA, mms.recipient.address) + putExtra(MediaPreviewActivity.OUTGOING_EXTRA, mms.isOutgoing) + putExtra(MediaPreviewActivity.DATE_EXTRA, mms.timestamp) + putExtra(MediaPreviewActivity.SIZE_EXTRA, slide.asAttachment().size) + putExtra(MediaPreviewActivity.CAPTION_EXTRA, slide.caption.orNull()) + putExtra(MediaPreviewActivity.LEFT_IS_RECENT_EXTRA, false) + } + } + } } } } - return null } fun bind(glideRequests: GlideRequests, message: MmsMessageRecord, diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt index a424a5d5d9..52038d7316 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt @@ -2,6 +2,9 @@ package org.thoughtcrime.securesms.conversation.v2 import android.animation.FloatEvaluator import android.animation.ValueAnimator +import android.app.Activity +import android.content.Context +import android.content.Intent import android.content.res.Resources import android.database.Cursor import android.graphics.Rect @@ -46,6 +49,9 @@ import org.thoughtcrime.securesms.database.model.MessageRecord import org.thoughtcrime.securesms.linkpreview.LinkPreviewRepository import org.thoughtcrime.securesms.linkpreview.LinkPreviewViewModel import org.thoughtcrime.securesms.linkpreview.LinkPreviewViewModel.LinkPreviewState +import org.thoughtcrime.securesms.loki.utilities.ActivityDispatcher +import org.thoughtcrime.securesms.loki.utilities.push +import org.thoughtcrime.securesms.loki.utilities.show import org.thoughtcrime.securesms.loki.utilities.toPx import org.thoughtcrime.securesms.mms.GlideApp import org.thoughtcrime.securesms.util.DateUtils @@ -57,7 +63,7 @@ import kotlin.math.* // price we pay is a bit of back and forth between the input bar and the conversation activity. class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDelegate, - InputBarRecordingViewDelegate, ConversationRecyclerViewDelegate { + InputBarRecordingViewDelegate, ConversationRecyclerViewDelegate, ActivityDispatcher { private val scrollButtonFullVisibilityThreshold by lazy { toPx(120.0f, resources) } private val scrollButtonNoVisibilityThreshold by lazy { toPx(20.0f, resources) } private val screenWidth = Resources.getSystem().displayMetrics.widthPixels @@ -76,8 +82,8 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe val adapter = ConversationAdapter( this, cursor, - onItemPress = { message, position, view, rect -> - handlePress(message, position, view, rect) + onItemPress = { message, position, view, rawRect -> + handlePress(message, position, view, rawRect) }, onItemSwipeToReply = { message, position -> handleSwipeToReply(message, position) @@ -138,6 +144,18 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe ApplicationContext.getInstance(this).messageNotifier.setVisibleThread(-1) } + override fun getSystemService(name: String): Any? { + if (name == ActivityDispatcher.SERVICE) { + return this + } + return super.getSystemService(name) + } + + override fun dispatchIntent(body: (Context) -> Intent) { + val intent = body(this) + push(intent, false) + } + private fun setUpRecyclerView() { conversationRecyclerView.adapter = adapter val layoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, true) @@ -452,7 +470,7 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe } // `position` is the adapter position; not the visual position - private fun handlePress(message: MessageRecord, position: Int, view: VisibleMessageView, hitRect: Rect) { + private fun handlePress(message: MessageRecord, position: Int, view: VisibleMessageView, rawRect: Rect) { val actionMode = this.actionMode if (actionMode != null) { adapter.toggleSelection(message, position) @@ -467,7 +485,7 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe // We have to use onContentClick (rather than a click listener directly on // the view) so as to not interfere with all the other gestures. Do not add // onClickListeners directly to message content views. - view.onContentClick(hitRect) + view.onContentClick(rawRect) } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationAdapter.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationAdapter.kt index 2a409ab0e8..c5c0d1e028 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationAdapter.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationAdapter.kt @@ -69,7 +69,7 @@ class ConversationAdapter(context: Context, cursor: Cursor, private val onItemPr view.messageTimestampTextView.isVisible = isSelected val position = viewHolder.adapterPosition view.bind(message, getMessageBefore(position, cursor), getMessageAfter(position, cursor), glide) - view.onPress = { x, y -> onItemPress(message, viewHolder.adapterPosition, view, Rect(x,y,x,y)) } + view.onPress = { rawX, rawY -> onItemPress(message, viewHolder.adapterPosition, view, Rect(rawX, rawY, rawX, rawY)) } view.onSwipeToReply = { onItemSwipeToReply(message, viewHolder.adapterPosition) } view.onLongPress = { onItemLongPress(message, viewHolder.adapterPosition) } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/VisibleMessageContentView.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/VisibleMessageContentView.kt index b32be1a2e3..0a9c2decb9 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/VisibleMessageContentView.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/VisibleMessageContentView.kt @@ -31,7 +31,7 @@ import org.thoughtcrime.securesms.mms.GlideRequests import kotlin.math.roundToInt class VisibleMessageContentView : LinearLayout { - var onContentClick: ((Rect) -> Unit)? = null + var onContentClick: ((rawRect: Rect) -> Unit)? = null // region Lifecycle constructor(context: Context) : super(context) { initialize() } @@ -96,16 +96,7 @@ class VisibleMessageContentView : LinearLayout { isStart = isStartOfMessageCluster, isEnd = isEndOfMessageCluster ) - onContentClick = { - when (val hitObject = albumThumbnailView.calculateHitObject(it)) { - is AlbumThumbnailView.Hit.SlideHit -> Log.d("Loki-UI", "clicked display slide ${hitObject.slide}")// open the slide preview - is AlbumThumbnailView.Hit.DownloadHit -> Log.d("Loki-UI", "clicked display download") - AlbumThumbnailView.Hit.ReadMoreHit -> Log.d("Loki-UI", "clicked the read more display") - else -> { - Log.d("Loki-UI", "DIDN'T click anything important") - } - } - } + onContentClick = { albumThumbnailView.calculateHitObject(it, message) } } else if (message.isOpenGroupInvitation) { val openGroupInvitationView = OpenGroupInvitationView(context) openGroupInvitationView.bind(message, VisibleMessageContentView.getTextColor(context, message)) diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/VisibleMessageView.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/VisibleMessageView.kt index 4e4add768c..e0ad3930ab 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/VisibleMessageView.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/VisibleMessageView.kt @@ -50,7 +50,7 @@ class VisibleMessageView : LinearLayout { private var onDownTimestamp = 0L var snIsSelected = false set(value) { field = value; handleIsSelectedChanged()} - var onPress: ((x: Int, y: Int) -> Unit)? = null + var onPress: ((rawX: Int, rawY: Int) -> Unit)? = null var onSwipeToReply: (() -> Unit)? = null var onLongPress: (() -> Unit)? = null @@ -272,7 +272,7 @@ class VisibleMessageView : LinearLayout { onSwipeToReply?.invoke() } else if ((Date().time - onDownTimestamp) < VisibleMessageView.longPressDurationThreshold) { longPressCallback?.let { gestureHandler.removeCallbacks(it) } - onPress?.invoke(event.x.toInt(), event.y.toInt()) + onPress?.invoke(event.rawX.toInt(), event.rawY.toInt()) } resetPosition() } @@ -297,8 +297,8 @@ class VisibleMessageView : LinearLayout { onLongPress?.invoke() } - fun onContentClick(hitRect: Rect) { - messageContentView.onContentClick?.invoke(hitRect) + fun onContentClick(rawRect: Rect) { + messageContentView.onContentClick?.invoke(rawRect) } // endregion } diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/utilities/ActivityUtilities.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/utilities/ActivityUtilities.kt index 6fd9250e0d..16bc9b1df8 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/utilities/ActivityUtilities.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/utilities/ActivityUtilities.kt @@ -1,6 +1,10 @@ package org.thoughtcrime.securesms.loki.utilities +import android.annotation.SuppressLint +import android.app.Activity +import android.content.Context import android.content.Intent +import android.os.Bundle import android.view.View import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.widget.Toolbar @@ -52,4 +56,13 @@ fun AppCompatActivity.show(intent: Intent, isForResult: Boolean = false) { startActivity(intent) } overridePendingTransition(R.anim.slide_from_bottom, R.anim.fade_scale_out) +} + +interface ActivityDispatcher { + companion object { + const val SERVICE = "ActivityDispatcher_SERVICE" + @SuppressLint("WrongConstant") + fun get(context: Context) = context.getSystemService(SERVICE) as? ActivityDispatcher + } + fun dispatchIntent(body: (Context)->Intent) } \ No newline at end of file