diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java index 3b923adce..f6626c3a1 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +++ b/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); } } diff --git a/src/main/java/eu/siacs/conversations/ui/util/MyLinkify.java b/src/main/java/eu/siacs/conversations/ui/util/MyLinkify.java index b72c5aa86..d5d3a82da 100644 --- a/src/main/java/eu/siacs/conversations/ui/util/MyLinkify.java +++ b/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 extractLinks(final Editable body) { + MyLinkify.addLinks(body, false); + final Collection spans = + Arrays.asList(body.getSpans(0, body.length() - 1, URLSpan.class)); + final Collection urlWrappers = + Collections2.filter( + Collections2.transform( + spans, + s -> + s == null + ? null + : new UrlWrapper(body.getSpanStart(s), s.getURL())), + uw -> uw != null); + List 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; + } + } } diff --git a/src/main/java/eu/siacs/conversations/ui/util/ShareUtil.java b/src/main/java/eu/siacs/conversations/ui/util/ShareUtil.java index 8ff81a203..007575307 100644 --- a/src/main/java/eu/siacs/conversations/ui/util/ShareUtil.java +++ b/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; + } }