use url span method to show context menu. fixes #4393

Daniel Gultsch created

Change summary

src/main/java/eu/siacs/conversations/ui/ConversationFragment.java |  6 
src/main/java/eu/siacs/conversations/ui/util/MyLinkify.java       | 38 
src/main/java/eu/siacs/conversations/ui/util/ShareUtil.java       | 77 
3 files changed, 81 insertions(+), 40 deletions(-)

Detailed changes

src/main/java/eu/siacs/conversations/ui/ConversationFragment.java 🔗

@@ -1332,11 +1332,11 @@ public class ConversationFragment extends XmppFragment
                     && t == null) {
                 copyMessage.setVisible(true);
                 quoteMessage.setVisible(!showError && MessageUtils.prepareQuote(m).length() > 0);
-                String body = m.getMergedBody().toString();
-                if (ShareUtil.containsXmppUri(body)) {
+                final String scheme = ShareUtil.getLinkScheme(m.getMergedBody());
+                if ("xmpp".equals(scheme)) {
                     copyLink.setTitle(R.string.copy_jabber_id);
                     copyLink.setVisible(true);
-                } else if (Patterns.AUTOLINK_WEB_URL.matcher(body).find()) {
+                } else if (scheme != null) {
                     copyLink.setVisible(true);
                 }
             }

src/main/java/eu/siacs/conversations/ui/util/MyLinkify.java 🔗

@@ -31,9 +31,18 @@ package eu.siacs.conversations.ui.util;
 
 import android.os.Build;
 import android.text.Editable;
+import android.text.style.URLSpan;
 import android.text.util.Linkify;
 
+import com.google.common.collect.Collections2;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
 import java.util.Locale;
+import java.util.Objects;
 
 import eu.siacs.conversations.ui.text.FixedURLSpan;
 import eu.siacs.conversations.utils.GeoHelper;
@@ -118,4 +127,33 @@ public class MyLinkify {
         }
         FixedURLSpan.fix(body);
     }
+
+    public static List<String> extractLinks(final Editable body) {
+        MyLinkify.addLinks(body, false);
+        final Collection<URLSpan> spans =
+                Arrays.asList(body.getSpans(0, body.length() - 1, URLSpan.class));
+        final Collection<UrlWrapper> urlWrappers =
+                Collections2.filter(
+                        Collections2.transform(
+                                spans,
+                                s ->
+                                        s == null
+                                                ? null
+                                                : new UrlWrapper(body.getSpanStart(s), s.getURL())),
+                        uw -> uw != null);
+        List<UrlWrapper> sorted = ImmutableList.sortedCopyOf(
+                (a, b) -> Integer.compare(a.position, b.position), urlWrappers);
+        return Lists.transform(sorted, uw -> uw.url);
+
+    }
+
+    private static class UrlWrapper {
+        private final int position;
+        private final String url;
+
+        private UrlWrapper(int position, String url) {
+            this.position = position;
+            this.url = url;
+        }
+    }
 }

src/main/java/eu/siacs/conversations/ui/util/ShareUtil.java 🔗

@@ -33,18 +33,14 @@ import android.content.ActivityNotFoundException;
 import android.content.Intent;
 import android.net.Uri;
 import android.text.SpannableStringBuilder;
-import android.text.style.URLSpan;
 import android.widget.Toast;
 
-import java.util.regex.Matcher;
-
 import eu.siacs.conversations.R;
 import eu.siacs.conversations.entities.DownloadableFile;
 import eu.siacs.conversations.entities.Message;
 import eu.siacs.conversations.persistance.FileBackend;
 import eu.siacs.conversations.ui.ConversationsActivity;
 import eu.siacs.conversations.ui.XmppActivity;
-import eu.siacs.conversations.utils.Patterns;
 import eu.siacs.conversations.utils.XmppUri;
 import eu.siacs.conversations.xmpp.Jid;
 
@@ -108,38 +104,45 @@ public class ShareUtil {
 		}
 	}
 
-	public static void copyLinkToClipboard(final XmppActivity activity, final Message message) {
-		final SpannableStringBuilder body = message.getMergedBody();
-		MyLinkify.addLinks(body, true);
-		for (final URLSpan urlspan : body.getSpans(0, body.length() - 1, URLSpan.class)) {
-			final Uri uri = Uri.parse(urlspan.getURL());
-			if ("xmpp".equals(uri.getScheme())) {
-				try {
-					final Jid jid = new XmppUri(uri).getJid();
-					if (activity.copyTextToClipboard(jid.asBareJid().toString(), R.string.account_settings_jabber_id)) {
-						Toast.makeText(activity,R.string.jabber_id_copied_to_clipboard, Toast.LENGTH_SHORT).show();
-					}
-					return;
-				} catch (final Exception e) {
-					return;
-				}
-			} else {
-				if (activity.copyTextToClipboard(urlspan.getURL(),R.string.web_address)) {
-					Toast.makeText(activity,R.string.url_copied_to_clipboard, Toast.LENGTH_SHORT).show();
-				}
-			}
-		}
-	}
+    public static void copyLinkToClipboard(final XmppActivity activity, final Message message) {
+        final SpannableStringBuilder body = message.getMergedBody();
+        for (final String url : MyLinkify.extractLinks(body)) {
+            final Uri uri = Uri.parse(url);
+            if ("xmpp".equals(uri.getScheme())) {
+                try {
+                    final Jid jid = new XmppUri(uri).getJid();
+                    if (activity.copyTextToClipboard(
+                            jid.asBareJid().toString(), R.string.account_settings_jabber_id)) {
+                        Toast.makeText(
+                                        activity,
+                                        R.string.jabber_id_copied_to_clipboard,
+                                        Toast.LENGTH_SHORT)
+                                .show();
+                    }
+                    return;
+                } catch (final Exception e) {
+                    return;
+                }
+            } else {
+                if (activity.copyTextToClipboard(url, R.string.web_address)) {
+                    Toast.makeText(activity, R.string.url_copied_to_clipboard, Toast.LENGTH_SHORT)
+                            .show();
+                }
+                return;
+            }
+        }
+    }
 
-	public static boolean containsXmppUri(String body) {
-		Matcher xmppPatternMatcher = Patterns.XMPP_PATTERN.matcher(body);
-		if (xmppPatternMatcher.find()) {
-			try {
-				return new XmppUri(body.substring(xmppPatternMatcher.start(), xmppPatternMatcher.end())).isValidJid();
-			} catch (Exception e) {
-				return false;
-			}
-		}
-		return false;
-	}
+    public static String getLinkScheme(final SpannableStringBuilder body) {
+        MyLinkify.addLinks(body, false);
+        for (final String url : MyLinkify.extractLinks(body)) {
+            final Uri uri = Uri.parse(url);
+            if ("xmpp".equals(uri.getScheme())) {
+                return uri.getScheme();
+            } else {
+                return "http";
+            }
+        }
+        return null;
+    }
 }