Convert Linkify to Kotlin

pull/1459/head
Alex Baker 3 years ago
parent a011ec5edf
commit 9960e9a0a9

@ -38,9 +38,8 @@ class CommentsController @Inject constructor(
private val userActivityDao: UserActivityDao,
private val activity: Activity,
private val preferences: Preferences,
private val locale: Locale,
private val linkify: Linkify) {
private val locale: Locale
) {
private val items = ArrayList<UserActivity>()
private var commentItems = 10
private var task: Task? = null
@ -88,7 +87,7 @@ class CommentsController @Inject constructor(
// name
val nameView = view.findViewById<TextView>(R.id.title)
nameView.text = Html.fromHtml(item.message)
linkify.safeLinkify(nameView, android.text.util.Linkify.ALL)
Linkify.safeLinkify(nameView, android.text.util.Linkify.ALL)
// date
val date = view.findViewById<TextView>(R.id.date)

@ -48,7 +48,6 @@ abstract class BaseCaldavAccountSettingsActivity : ThemedInjectingAppCompatActiv
@Inject lateinit var taskDeleter: TaskDeleter
@Inject lateinit var inventory: Inventory
@Inject lateinit var firebase: Firebase
@Inject lateinit var linkify: Linkify
protected var caldavAccount: CaldavAccount? = null
protected lateinit var binding: ActivityCaldavAccountSettingsBinding
@ -62,7 +61,7 @@ abstract class BaseCaldavAccountSettingsActivity : ThemedInjectingAppCompatActiv
binding.nameLayout.visibility = View.GONE
binding.description.visibility = View.VISIBLE
binding.description.setText(description)
linkify.safeLinkify(binding.description, android.text.util.Linkify.WEB_URLS)
Linkify.safeLinkify(binding.description, android.text.util.Linkify.WEB_URLS)
} else {
binding.nameLayout.visibility = View.VISIBLE
binding.description.visibility = View.GONE

@ -1,136 +0,0 @@
package org.tasks.dialogs;
import static java.util.Arrays.asList;
import static org.tasks.Strings.isNullOrEmpty;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.SpannableStringBuilder;
import android.text.style.URLSpan;
import android.view.View;
import android.widget.TextView;
import androidx.core.text.util.LinkifyCompat;
import dagger.hilt.android.qualifiers.ActivityContext;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import javax.inject.Inject;
import org.tasks.R;
import timber.log.Timber;
public class Linkify {
private final Context context;
private final DialogBuilder dialogBuilder;
@Inject
public Linkify(@ActivityContext Context context, DialogBuilder dialogBuilder) {
this.context = context;
this.dialogBuilder = dialogBuilder;
}
public void safeLinkify(TextView textView, int mask) {
try {
LinkifyCompat.addLinks(textView, mask);
} catch (UnsatisfiedLinkError e) {
Timber.e(e);
}
}
public void linkify(TextView textView) {
linkify(textView, () -> {});
}
public void linkify(TextView textView, Runnable onClick) {
if (textView.length() == 0) {
return;
}
safeLinkify(textView, android.text.util.Linkify.ALL);
textView.setOnClickListener(
v -> {
if (textView.getSelectionStart() == -1 && textView.getSelectionEnd() == -1) {
onClick.run();
}
});
URLSpan[] spans;
Spannable spannable;
CharSequence text = textView.getText();
if (text instanceof SpannableStringBuilder || text instanceof SpannableString) {
spannable = (Spannable) text;
} else {
return;
}
spans = spannable.getSpans(0, text.length(), URLSpan.class);
for (URLSpan span : spans) {
int start = spannable.getSpanStart(span);
int end = spannable.getSpanEnd(span);
spannable.removeSpan(span);
spannable.setSpan(new ClickHandlingURLSpan(span.getURL(), onClick), start, end, 0);
}
}
private class ClickHandlingURLSpan extends URLSpan {
private final Runnable onEdit;
ClickHandlingURLSpan(String url, Runnable onEdit) {
super(url);
this.onEdit = onEdit;
}
@Override
public void onClick(View widget) {
String title;
String edit = context.getString(R.string.TAd_actionEditTask);
String action;
String url = getURL();
Uri uri = Uri.parse(url);
String scheme = uri.getScheme();
if (isNullOrEmpty(scheme)) {
scheme = "";
}
switch (scheme) {
case "tel":
title = uri.getEncodedSchemeSpecificPart();
action = context.getString(R.string.action_call);
break;
case "mailto":
title = uri.getEncodedSchemeSpecificPart();
action = context.getString(R.string.action_open);
break;
case "geo":
title = uri.getEncodedQuery().replaceFirst("q=", "");
try {
title = URLDecoder.decode(title, "utf-8");
} catch (UnsupportedEncodingException ignored) {
}
action = context.getString(R.string.action_open);
break;
default:
title = url;
action = context.getString(R.string.action_open);
break;
}
dialogBuilder
.newDialog(title)
.setItems(
asList(action, edit),
(dialogInterface, selected) -> {
if (selected == 0) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(uri);
context.startActivity(intent);
} else {
onEdit.run();
}
})
.show();
}
}
}

@ -0,0 +1,106 @@
package org.tasks.dialogs
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.text.Spannable
import android.text.SpannableString
import android.text.SpannableStringBuilder
import android.text.style.URLSpan
import android.text.util.Linkify
import android.view.View
import android.widget.TextView
import androidx.core.text.util.LinkifyCompat
import dagger.hilt.android.qualifiers.ActivityContext
import org.tasks.R
import org.tasks.Strings.isNullOrEmpty
import timber.log.Timber
import java.io.UnsupportedEncodingException
import java.net.URLDecoder
import javax.inject.Inject
class Linkify @Inject constructor(
@ActivityContext private val context: Context,
private val dialogBuilder: DialogBuilder
) {
fun linkify(textView: TextView, onClick: Runnable = Runnable {}) {
if (textView.length() == 0) {
return
}
safeLinkify(textView, Linkify.ALL)
textView.setOnClickListener {
if (textView.selectionStart == -1 && textView.selectionEnd == -1) {
onClick.run()
}
}
val text = textView.text
if (text is SpannableStringBuilder || text is SpannableString) {
val spannable = text as Spannable
val spans = spannable.getSpans(0, text.length, URLSpan::class.java)
for (span in spans) {
val start = spannable.getSpanStart(span)
val end = spannable.getSpanEnd(span)
spannable.removeSpan(span)
spannable.setSpan(ClickHandlingURLSpan(span.url, onClick), start, end, 0)
}
}
}
private inner class ClickHandlingURLSpan constructor(
url: String?,
private val onEdit: Runnable
) : URLSpan(url) {
override fun onClick(widget: View) {
var title: String?
val edit = context.getString(R.string.TAd_actionEditTask)
val action: String
val uri = Uri.parse(url)
var scheme = uri.scheme
if (isNullOrEmpty(scheme)) {
scheme = ""
}
when (scheme) {
"tel" -> {
title = uri.encodedSchemeSpecificPart
action = context.getString(R.string.action_call)
}
"mailto" -> {
title = uri.encodedSchemeSpecificPart
action = context.getString(R.string.action_open)
}
"geo" -> {
title = uri.encodedQuery!!.replaceFirst("q=".toRegex(), "")
try {
title = URLDecoder.decode(title, "utf-8")
} catch (ignored: UnsupportedEncodingException) {
}
action = context.getString(R.string.action_open)
}
else -> {
title = url
action = context.getString(R.string.action_open)
}
}
dialogBuilder
.newDialog(title)
.setItems(listOf(action, edit)) { _, selected ->
if (selected == 0) {
context.startActivity(Intent(Intent.ACTION_VIEW, uri))
} else {
onEdit.run()
}
}
.show()
}
}
companion object {
fun safeLinkify(textView: TextView?, mask: Int) {
try {
LinkifyCompat.addLinks(textView!!, mask)
} catch (e: UnsatisfiedLinkError) {
Timber.e(e)
}
}
}
}
Loading…
Cancel
Save