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) {
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);
}
}

View file

@ -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;
}
}
}

View file

@ -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;
}
}