mirror of
https://github.com/oxen-io/session-android.git
synced 2024-11-24 02:25:19 +00:00
refactor: use activity dispatcher
This commit is contained in:
parent
bb00754237
commit
9cccbd7aae
@ -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<Slide> = 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<ViewGroup>(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,
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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) }
|
||||
}
|
||||
|
@ -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))
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
Loading…
Reference in New Issue
Block a user