Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Long press a link to copy it #320

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 61 additions & 4 deletions app/src/main/kotlin/org/fossify/messages/adapters/ThreadAdapter.kt
Original file line number Diff line number Diff line change
@@ -1,19 +1,25 @@
package org.fossify.messages.adapters

import android.annotation.SuppressLint
import android.app.Activity
import android.content.Intent
import android.graphics.Color
import android.graphics.Typeface
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.ColorDrawable
import android.graphics.drawable.Drawable
import android.text.Spannable
import android.text.method.LinkMovementMethod
import android.text.style.URLSpan
import android.util.Size
import android.util.TypedValue
import android.view.Menu
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import android.widget.LinearLayout
import android.widget.RelativeLayout
import android.widget.TextView
import androidx.appcompat.content.res.AppCompatResources
import androidx.constraintlayout.widget.ConstraintSet
import androidx.core.view.updateLayoutParams
Expand Down Expand Up @@ -50,6 +56,60 @@ import org.fossify.messages.models.Message
import org.fossify.messages.models.ThreadItem
import org.fossify.messages.models.ThreadItem.*

class CustomLinkMovementMethod(private val activity: Activity, private val holder: MyRecyclerViewListAdapter<ThreadItem>.ViewHolder) : LinkMovementMethod() {

private var isLongPressDetected = false
private var startClickTime: Long = 0
private val longPressTime = 180L
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should rely on ViewConfiguration.getLongPressTimeout()


override fun onTouchEvent(widget: TextView, buffer: Spannable, event: MotionEvent): Boolean {
when (event.action) {
MotionEvent.ACTION_DOWN -> {
startClickTime = System.currentTimeMillis()
isLongPressDetected = false
}

MotionEvent.ACTION_MOVE -> {
if (!isLongPressDetected) {
val elapsedTime = System.currentTimeMillis() - startClickTime
if (elapsedTime >= longPressTime) {
isLongPressDetected = true
holder.viewLongClicked()
val x = event.x.toInt()
val y = event.y.toInt()
val link = getLinkAt(widget, buffer, x, y)

link?.let {
activity.copyToClipboard(it)
return true
}
}
}
}

MotionEvent.ACTION_UP -> {
if (isLongPressDetected) {
return true
}
}

MotionEvent.ACTION_CANCEL -> {
isLongPressDetected = false
}
}

return super.onTouchEvent(widget, buffer, event)
}

private fun getLinkAt(widget: TextView, buffer: Spannable, x: Int, y: Int): String? {
val layout = widget.layout
val line = layout.getLineForVertical(y)
val offset = layout.getOffsetForHorizontal(line, x.toFloat())
val urlSpan = buffer.getSpans(offset, offset, URLSpan::class.java).firstOrNull()
return urlSpan?.url
}
}

class ThreadAdapter(
activity: SimpleActivity,
recyclerView: MyRecyclerView,
Expand Down Expand Up @@ -279,10 +339,7 @@ class ThreadAdapter(
text = message.body
setTextSize(TypedValue.COMPLEX_UNIT_PX, fontSize)
beVisibleIf(message.body.isNotEmpty())
setOnLongClickListener {
holder.viewLongClicked()
true
}
threadMessageBody.movementMethod = CustomLinkMovementMethod(activity, holder)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You shouldn't pass the holder object here. Just use a kotlin lambda e.g. onLinkLongClicked

Copy link
Author

@pufferss pufferss Feb 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah i passed it here because i thought i had to activate message selection mode when a link is long pressed

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes but even then, callbacks are the proper way to do it.


setOnClickListener {
holder.viewClicked(message)
Expand Down
Loading