Linkify commands (#1567)

This makes bot commands similar to /echo clickable.

Patch from @adbenitez
This commit is contained in:
link2xt
2020-08-20 10:04:19 +03:00
committed by GitHub
parent 03e6dc449a
commit 37e99b659f
3 changed files with 75 additions and 22 deletions
@@ -550,6 +550,11 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
Permissions.onRequestPermissionsResult(this, requestCode, permissions, grantResults);
}
public void setDraftText(String txt) {
composeText.setText(txt);
composeText.setSelection(composeText.getText().length());
}
//////// Event Handlers
private void handleEphemeralMessages() {
@@ -32,6 +32,7 @@ import android.text.style.URLSpan;
import android.text.util.Linkify;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.util.Patterns;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
@@ -66,6 +67,8 @@ import org.thoughtcrime.securesms.util.views.Stub;
import java.util.HashSet;
import java.util.Locale;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* A view that displays an individual conversation item within a conversation
@@ -500,15 +503,44 @@ public class ConversationItem extends LinearLayout
}
private SpannableString linkifyMessageBody(SpannableString messageBody, boolean shouldLinkifyAllLinks) {
boolean hasLinks = Linkify.addLinks(messageBody,
shouldLinkifyAllLinks ? Linkify.EMAIL_ADDRESSES|Linkify.WEB_URLS|Linkify.PHONE_NUMBERS : 0);
if (!shouldLinkifyAllLinks) {
return messageBody;
}
boolean hasLinks = false;
Pattern cmdPattern = Pattern.compile("(?<=^|\\s)/[a-zA-Z][a-zA-Z@\\d_/.-]{0,254}");
hasLinks = Linkify.addLinks(messageBody, cmdPattern, "cmd:", null, null) || hasLinks;
Linkify.TransformFilter urlFilter = (match, url) -> {
if (url.startsWith("http://") || url.startsWith("https://")) {
return url;
} else {
return "https://" + url;
}
};
Linkify.MatchFilter matcher = (s, start, end) -> {
URLSpan[] urlSpans = messageBody.getSpans(start, end, URLSpan.class);
for (URLSpan urlSpan : urlSpans) {
int start2 = messageBody.getSpanStart(urlSpan);
int end2 = messageBody.getSpanEnd(urlSpan);
if ((start >= start2 && start < end2) || (end >= start2 && end < end2)) {
return false;
}
}
return true;
};
hasLinks = Linkify.addLinks(messageBody, Patterns.EMAIL_ADDRESS, "mailto:", matcher, null) || hasLinks;
hasLinks = Linkify.addLinks(messageBody, Patterns.WEB_URL, "", matcher, urlFilter) || hasLinks;
hasLinks = Linkify.addLinks(messageBody, Patterns.PHONE, "tel:", matcher, null) || hasLinks;
if (hasLinks) {
URLSpan[] urlSpans = messageBody.getSpans(0, messageBody.length(), URLSpan.class);
for (URLSpan urlSpan : urlSpans) {
int start = messageBody.getSpanStart(urlSpan);
int end = messageBody.getSpanEnd(urlSpan);
messageBody.setSpan(new LongClickCopySpan(urlSpan.getURL()), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
messageBody.setSpan(new LongClickCopySpan(urlSpan.getURL(), this.dcChat.getId()), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
return messageBody;
@@ -14,6 +14,7 @@ import android.widget.Toast;
import com.b44t.messenger.DcContact;
import com.b44t.messenger.DcContext;
import com.b44t.messenger.DcMsg;
import org.thoughtcrime.securesms.ConversationActivity;
import org.thoughtcrime.securesms.R;
@@ -22,13 +23,16 @@ import org.thoughtcrime.securesms.connect.DcHelper;
public class LongClickCopySpan extends URLSpan {
private static final String PREFIX_MAILTO = "mailto:";
private static final String PREFIX_TEL = "tel:";
private static final String PREFIX_CMD = "cmd:";
private boolean isHighlighted;
@ColorInt
private int highlightColor;
private int chatId;
public LongClickCopySpan(String url) {
public LongClickCopySpan(String url, int chatId) {
super(url);
this.chatId = chatId;
}
private void openChat(Activity activity, DcContact contact) {
@@ -44,13 +48,21 @@ public class LongClickCopySpan extends URLSpan {
@Override
public void onClick(View widget) {
String url = getURL();
if (url.startsWith(PREFIX_MAILTO)) {
if (url.startsWith(PREFIX_CMD)) {
try {
String cmd = url.substring(PREFIX_CMD.length());
ConversationActivity activity = (ConversationActivity) widget.getContext();
activity.setDraftText(cmd + " ");
} catch (Exception e) {
e.printStackTrace();
}
} else if (url.startsWith(PREFIX_MAILTO)) {
try {
String addr = prepareUrl(url);
Activity activity = (Activity) widget.getContext();
DcContext dcContext = DcHelper.getContext(activity);
DcContact contact = dcContext.getContact(dcContext.createContact(null, addr));
if (contact.getId()!=0 && dcContext.getChatIdByContactId(contact.getId())!=0) {
if (contact.getId() != 0 && dcContext.getChatIdByContactId(contact.getId()) != 0) {
openChat(activity, contact);
} else {
new AlertDialog.Builder(activity)
@@ -61,31 +73,35 @@ public class LongClickCopySpan extends URLSpan {
.setNegativeButton(R.string.cancel, null)
.show();
}
}
catch(Exception e) {
} catch (Exception e) {
e.printStackTrace();
}
}
else {
} else {
super.onClick(widget);
}
}
void onLongClick(View widget) {
Context context = widget.getContext();
String preparedUrl = prepareUrl(getURL());
String url = getURL();
new AlertDialog.Builder(context)
.setTitle(preparedUrl)
.setItems(new CharSequence[]{
context.getString(R.string.menu_copy_to_clipboard)
},
(dialogInterface, i) -> {
copyUrl(context, preparedUrl);
Toast.makeText(context, context.getString(R.string.copied_to_clipboard), Toast.LENGTH_SHORT).show();
})
.setNegativeButton(R.string.cancel, null)
.show();
if (url.startsWith(PREFIX_CMD)) {
copyUrl(context, url.substring(PREFIX_CMD.length()));
Toast.makeText(context, context.getString(R.string.copied_to_clipboard), Toast.LENGTH_SHORT).show();
} else {
String preparedUrl = prepareUrl(url);
new AlertDialog.Builder(context)
.setTitle(preparedUrl)
.setItems(new CharSequence[]{
context.getString(R.string.menu_copy_to_clipboard)
},
(dialogInterface, i) -> {
copyUrl(context, preparedUrl);
Toast.makeText(context, context.getString(R.string.copied_to_clipboard), Toast.LENGTH_SHORT).show();
})
.setNegativeButton(R.string.cancel, null)
.show();
}
}
@Override