diff --git a/app/build.gradle b/app/build.gradle
index 88567c148..66d5829e3 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -137,6 +137,7 @@ dependencies {
debugImplementation "com.squareup.leakcanary:leakcanary-support-fragment:${LEAKCANARY_VERSION}"
debugImplementation 'androidx.multidex:multidex:2.0.0'
+ implementation 'me.saket:better-link-movement-method:2.2.0'
implementation 'com.squareup.okhttp3:okhttp:3.11.0'
implementation 'com.google.code.gson:gson:2.8.5'
implementation 'com.github.rey5137:material:1.2.5'
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index f428a5211..0617e395a 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -5,7 +5,7 @@
package="org.tasks">
-
+
diff --git a/app/src/main/java/com/todoroo/astrid/ui/EditTitleControlSet.java b/app/src/main/java/com/todoroo/astrid/ui/EditTitleControlSet.java
index 159fa1f1e..ee2121577 100644
--- a/app/src/main/java/com/todoroo/astrid/ui/EditTitleControlSet.java
+++ b/app/src/main/java/com/todoroo/astrid/ui/EditTitleControlSet.java
@@ -8,13 +8,13 @@ package com.todoroo.astrid.ui;
import android.content.Context;
import android.graphics.Paint;
import android.os.Bundle;
-import androidx.annotation.Nullable;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
+import androidx.annotation.Nullable;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
@@ -24,6 +24,7 @@ import com.todoroo.astrid.dao.TaskDao;
import com.todoroo.astrid.data.Task;
import javax.inject.Inject;
import org.tasks.R;
+import org.tasks.dialogs.Linkify;
import org.tasks.injection.FragmentComponent;
import org.tasks.ui.CheckBoxes;
import org.tasks.ui.TaskEditControlFragment;
@@ -44,6 +45,7 @@ public class EditTitleControlSet extends TaskEditControlFragment {
@Inject TaskDao taskDao;
@Inject CheckBoxes checkBoxes;
+ @Inject Linkify linkify;
@BindView(R.id.title)
EditText editText;
@@ -85,6 +87,9 @@ public class EditTitleControlSet extends TaskEditControlFragment {
editText.setHorizontallyScrolling(false);
editText.setLines(1);
editText.setMaxLines(Integer.MAX_VALUE);
+
+ linkify.linkify(editText);
+
updateCompleteBox();
return view;
}
diff --git a/app/src/main/java/org/tasks/dialogs/Linkify.java b/app/src/main/java/org/tasks/dialogs/Linkify.java
new file mode 100644
index 000000000..d15b7c399
--- /dev/null
+++ b/app/src/main/java/org/tasks/dialogs/Linkify.java
@@ -0,0 +1,79 @@
+package org.tasks.dialogs;
+
+import static java.util.Arrays.asList;
+
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.widget.TextView;
+import com.google.common.base.Strings;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import javax.inject.Inject;
+import me.saket.bettermovementmethod.BetterLinkMovementMethod;
+import org.tasks.R;
+import org.tasks.injection.ForActivity;
+
+public class Linkify {
+
+ private final Context context;
+ private final DialogBuilder dialogBuilder;
+
+ @Inject
+ public Linkify(@ForActivity Context context, DialogBuilder dialogBuilder) {
+ this.context = context;
+ this.dialogBuilder = dialogBuilder;
+ }
+
+ public void linkify(TextView textView) {
+ BetterLinkMovementMethod.linkify(android.text.util.Linkify.ALL, textView)
+ .setOnLinkClickListener(this::handleLink);
+ }
+
+ private boolean handleLink(TextView textView, String url) {
+ String title;
+ String edit = context.getString(R.string.TAd_actionEditTask);
+ String action;
+ Uri uri = Uri.parse(url);
+ String scheme = uri.getScheme();
+ if (Strings.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()
+ .setTitle(title)
+ .setItems(
+ asList(action, edit),
+ (dialogInterface, selected) -> {
+ if (selected == 0) {
+ Intent intent = new Intent(Intent.ACTION_VIEW);
+ intent.setData(uri);
+ context.startActivity(intent);
+ }
+ })
+ .show();
+ return true;
+ }
+}
diff --git a/app/src/main/java/org/tasks/ui/DescriptionControlSet.java b/app/src/main/java/org/tasks/ui/DescriptionControlSet.java
index 00d288413..aa7a0555c 100644
--- a/app/src/main/java/org/tasks/ui/DescriptionControlSet.java
+++ b/app/src/main/java/org/tasks/ui/DescriptionControlSet.java
@@ -11,7 +11,9 @@ import android.widget.EditText;
import butterknife.BindView;
import butterknife.OnTextChanged;
import com.todoroo.astrid.data.Task;
+import javax.inject.Inject;
import org.tasks.R;
+import org.tasks.dialogs.Linkify;
import org.tasks.injection.FragmentComponent;
public class DescriptionControlSet extends TaskEditControlFragment {
@@ -19,6 +21,8 @@ public class DescriptionControlSet extends TaskEditControlFragment {
public static final int TAG = R.string.TEA_ctrl_notes_pref;
private static final String EXTRA_DESCRIPTION = "extra_description";
+ @Inject Linkify linkify;
+
@BindView(R.id.notes)
EditText editText;
@@ -37,6 +41,9 @@ public class DescriptionControlSet extends TaskEditControlFragment {
if (!isNullOrEmpty(description)) {
editText.setTextKeepState(description);
}
+
+ linkify.linkify(editText);
+
return view;
}
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index c4192bca2..8640f3b24 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -102,6 +102,8 @@ File %1$s contained %2$s.\n\n
Edit
+ Call
+ Open