copy jabber id and web url via context menu

Daniel Gultsch created

Change summary

src/main/java/eu/siacs/conversations/ui/ConversationFragment.java   | 12 
src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java |  7 
src/main/java/eu/siacs/conversations/ui/util/ShareUtil.java         | 45 
src/main/java/eu/siacs/conversations/utils/Patterns.java            |  7 
src/main/res/menu/message_context.xml                               |  5 
src/main/res/values/strings.xml                                     |  4 
6 files changed, 74 insertions(+), 6 deletions(-)

Detailed changes

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

@@ -98,6 +98,7 @@ import eu.siacs.conversations.ui.widget.EditMessage;
 import eu.siacs.conversations.utils.GeoHelper;
 import eu.siacs.conversations.utils.MessageUtils;
 import eu.siacs.conversations.utils.NickValidityChecker;
+import eu.siacs.conversations.utils.Patterns;
 import eu.siacs.conversations.utils.QuickLoader;
 import eu.siacs.conversations.utils.StylingHelper;
 import eu.siacs.conversations.utils.TimeframeUtils;
@@ -1052,6 +1053,7 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke
 			activity.getMenuInflater().inflate(R.menu.message_context, menu);
 			menu.setHeaderTitle(R.string.message_options);
 			MenuItem copyMessage = menu.findItem(R.id.copy_message);
+			MenuItem copyLink = menu.findItem(R.id.copy_link);
 			MenuItem quoteMessage = menu.findItem(R.id.quote_message);
 			MenuItem retryDecryption = menu.findItem(R.id.retry_decryption);
 			MenuItem correctMessage = menu.findItem(R.id.correct_message);
@@ -1065,6 +1067,13 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke
 			if (!m.isFileOrImage() && !encrypted && !m.isGeoUri() && !m.treatAsDownloadable()) {
 				copyMessage.setVisible(true);
 				quoteMessage.setVisible(MessageUtils.prepareQuote(m).length() > 0);
+				String body = m.getMergedBody().toString();
+				if (ShareUtil.containsXmppUri(body)) {
+					copyLink.setTitle(R.string.copy_jabber_id);
+					copyLink.setVisible(true);
+				} else if (Patterns.AUTOLINK_WEB_URL.matcher(body).find()) {
+					copyLink.setVisible(true);
+				}
 			}
 			if (m.getEncryption() == Message.ENCRYPTION_DECRYPTION_FAILED) {
 				retryDecryption.setVisible(true);
@@ -1122,6 +1131,9 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke
 			case R.id.copy_message:
 				ShareUtil.copyToClipboard(activity, selectedMessage);
 				return true;
+			case R.id.copy_link:
+				ShareUtil.copyLinkToClipboard(activity, selectedMessage);
+				return true;
 			case R.id.quote_message:
 				quoteMessage(selectedMessage);
 				return true;

src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java 🔗

@@ -92,11 +92,6 @@ public class MessageAdapter extends ArrayAdapter<Message> implements CopyTextVie
 	private static final int RECEIVED = 1;
 	private static final int STATUS = 2;
 	private static final int DATE_SEPARATOR = 3;
-	private static final Pattern XMPP_PATTERN = Pattern
-			.compile("xmpp\\:(?:(?:["
-					+ Patterns.GOOD_IRI_CHAR
-					+ "\\;\\/\\?\\@\\&\\=\\#\\~\\-\\.\\+\\!\\*\\'\\(\\)\\,\\_])"
-					+ "|(?:\\%[a-fA-F0-9]{2}))+");
 
 	private List<String> highlightedTerm = null;
 
@@ -553,7 +548,7 @@ public class MessageAdapter extends ArrayAdapter<Message> implements CopyTextVie
 				StylingHelper.highlight(activity, body, highlightedTerm, StylingHelper.isDarkText(viewHolder.messageBody));
 			}
 
-			Linkify.addLinks(body, XMPP_PATTERN, "xmpp", XMPPURI_MATCH_FILTER, null);
+			Linkify.addLinks(body, Patterns.XMPP_PATTERN, "xmpp", XMPPURI_MATCH_FILTER, null);
 			Linkify.addLinks(body, Patterns.AUTOLINK_WEB_URL, "http", WEBURL_MATCH_FILTER, WEBURL_TRANSFORM_FILTER);
 			Linkify.addLinks(body, GeoHelper.GEO_URI, "geo");
 			FixedURLSpan.fix(body);

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

@@ -33,13 +33,22 @@ import android.content.ActivityNotFoundException;
 import android.content.Context;
 import android.content.Intent;
 import android.support.v4.content.ContextCompat;
+import android.util.Log;
 import android.widget.Toast;
 
+import java.net.URL;
+import java.util.regex.Matcher;
+
+import eu.siacs.conversations.Config;
 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 rocks.xmpp.addr.Jid;
 
 public class ShareUtil {
 
@@ -98,4 +107,40 @@ public class ShareUtil {
 			Toast.makeText(activity, R.string.url_copied_to_clipboard, Toast.LENGTH_SHORT).show();
 		}
 	}
+
+	public static void copyLinkToClipboard(XmppActivity activity, Message message) {
+		String body = message.getMergedBody().toString();
+		Matcher xmppPatternMatcher = Patterns.XMPP_PATTERN.matcher(body);
+		if (xmppPatternMatcher.find()) {
+			try {
+				Jid jid = new XmppUri(body.substring(xmppPatternMatcher.start(), xmppPatternMatcher.end())).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 (Exception e) {
+				e.printStackTrace();
+				return;
+			}
+		}
+		Matcher webUrlPatternMatcher = Patterns.AUTOLINK_WEB_URL.matcher(body);
+		if (webUrlPatternMatcher.find()) {
+			String url = body.substring(webUrlPatternMatcher.start(),webUrlPatternMatcher.end());
+			if (activity.copyTextToClipboard(url,R.string.web_address)) {
+				Toast.makeText(activity,R.string.url_copied_to_clipboard, Toast.LENGTH_SHORT).show();
+			}
+		}
+	}
+
+	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())).isJidValid();
+			} catch (Exception e) {
+				return false;
+			}
+		}
+		return false;
+	}
 }

src/main/java/eu/siacs/conversations/utils/Patterns.java 🔗

@@ -26,6 +26,13 @@ import java.util.regex.Pattern;
  * Commonly used regular expression patterns.
  */
 public class Patterns {
+
+    public static final Pattern XMPP_PATTERN = Pattern
+            .compile("xmpp\\:(?:(?:["
+                    + Patterns.GOOD_IRI_CHAR
+                    + "\\;\\/\\?\\@\\&\\=\\#\\~\\-\\.\\+\\!\\*\\'\\(\\)\\,\\_])"
+                    + "|(?:\\%[a-fA-F0-9]{2}))+");
+
     /**
      *  Regular expression to match all IANA top-level domains.
      *  List accurate as of 2011/07/18.  List taken from:

src/main/res/menu/message_context.xml 🔗

@@ -10,6 +10,11 @@
         android:id="@+id/copy_message"
         android:title="@string/copy_to_clipboard"
         android:visible="false"/>
+
+    <item
+        android:id="@+id/copy_link"
+        android:title="@string/copy_link"
+        android:visible="false"/>
     <item
         android:id="@+id/quote_message"
         android:title="@string/quote"

src/main/res/values/strings.xml 🔗

@@ -297,6 +297,8 @@
     <string name="send_again">Send again</string>
     <string name="file_url">File URL</string>
     <string name="url_copied_to_clipboard">Copied URL to clipboard</string>
+    <string name="jabber_id_copied_to_clipboard">Copied Jabberd ID to clipboard</string>
+    <string name="web_address">web address</string>
     <string name="scan_qr_code">Scan 2D Barcode</string>
     <string name="show_qr_code">Show 2D Barcode</string>
     <string name="show_block_list">Show block list</string>
@@ -708,4 +710,6 @@
     <string name="view_conversation">View conversation</string>
     <string name="pref_use_share_location_plugin">Share Location Plugin</string>
     <string name="pref_use_share_location_plugin_summary">Use the Share Location Plugin instead of the build in map</string>
+    <string name="copy_link">Copy web address</string>
+    <string name="copy_jabber_id">Copy Jabber ID</string>
 </resources>