mirror of https://github.com/tasks/tasks
Convert Linkify to Kotlin
parent
a011ec5edf
commit
9960e9a0a9
@ -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…
Reference in New Issue