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

This commit is contained in:
Daniel Gultsch 2022-10-12 18:43:05 +02:00
parent ab0ea7096e
commit 90048e92bb
3 changed files with 81 additions and 40 deletions

View file

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

View file

@ -31,9 +31,18 @@ package eu.siacs.conversations.ui.util;
import android.os.Build; import android.os.Build;
import android.text.Editable; import android.text.Editable;
import android.text.style.URLSpan;
import android.text.util.Linkify; 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.Locale;
import java.util.Objects;
import eu.siacs.conversations.ui.text.FixedURLSpan; import eu.siacs.conversations.ui.text.FixedURLSpan;
import eu.siacs.conversations.utils.GeoHelper; import eu.siacs.conversations.utils.GeoHelper;
@ -118,4 +127,33 @@ public class MyLinkify {
} }
FixedURLSpan.fix(body); 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;
}
}
} }

View file

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