mirror of
https://github.com/ArcaneChat/android.git
synced 2026-07-03 14:05:24 +02:00
Linkify commands (#1567)
This makes bot commands similar to /echo clickable. Patch from @adbenitez
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user