@@ -7,9 +7,13 @@ import android.graphics.Color;
import android.os.Build;
import android.text.Html;
import android.text.SpannableStringBuilder;
+import android.text.Spanned;
+import android.text.style.ImageSpan;
+import android.text.style.ClickableSpan;
import android.util.Base64;
import android.util.Log;
import android.util.Pair;
+import android.view.View;
import com.cheogram.android.BobTransfer;
import com.cheogram.android.GetThumbnailForCid;
@@ -854,6 +858,20 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable
(opening, tag, output, xmlReader) -> {}
));
+ // Make images clickable and long-clickable with BetterLinkMovementMethod
+ ImageSpan[] imageSpans = spannable.getSpans(0, spannable.length(), ImageSpan.class);
+ for (ImageSpan span : imageSpans) {
+ final int start = spannable.getSpanStart(span);
+ final int end = spannable.getSpanEnd(span);
+
+ ClickableSpan click_span = new ClickableSpan() {
+ @Override
+ public void onClick(View widget) { }
+ };
+
+ spannable.setSpan(click_span, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+ }
+
// https://stackoverflow.com/a/10187511/8611
int i = spannable.length();
while(--i >= 0 && Character.isWhitespace(spannable.charAt(i))) { }
@@ -75,6 +75,8 @@ import com.google.common.collect.ImmutableList;
import org.jetbrains.annotations.NotNull;
+import io.ipfs.cid.Cid;
+
import java.io.File;
import java.net.URISyntaxException;
import java.util.ArrayList;
@@ -159,7 +161,8 @@ import eu.siacs.conversations.xmpp.stanzas.IqPacket;
public class ConversationFragment extends XmppFragment
implements EditMessage.KeyboardListener,
MessageAdapter.OnContactPictureLongClicked,
- MessageAdapter.OnContactPictureClicked {
+ MessageAdapter.OnContactPictureClicked,
+ MessageAdapter.OnInlineImageLongClicked {
public static final int REQUEST_SEND_MESSAGE = 0x0201;
public static final int REQUEST_DECRYPT_PGP = 0x0202;
@@ -1282,6 +1285,7 @@ public class ConversationFragment extends XmppFragment
messageListAdapter = new MessageAdapter((XmppActivity) getActivity(), this.messageList);
messageListAdapter.setOnContactPictureClicked(this);
messageListAdapter.setOnContactPictureLongClicked(this);
+ messageListAdapter.setOnInlineImageLongClicked(this);
binding.messagesView.setAdapter(messageListAdapter);
registerForContextMenu(binding.messagesView);
@@ -1340,6 +1344,7 @@ public class ConversationFragment extends XmppFragment
Log.d(Config.LOGTAG, "ConversationFragment.onDestroyView()");
messageListAdapter.setOnContactPictureClicked(null);
messageListAdapter.setOnContactPictureLongClicked(null);
+ messageListAdapter.setOnInlineImageLongClicked(null);
if (conversation != null) conversation.setupViewPager(null, null);
}
@@ -2326,6 +2331,14 @@ public class ConversationFragment extends XmppFragment
builder.create().show();
}
+ public boolean onInlineImageLongClicked(Cid cid) {
+ DownloadableFile f = activity.xmppConnectionService.getFileForCid(cid);
+ if (f == null) return false;
+
+ saveAsSticker(f, null);
+ return true;
+ }
+
private void saveAsSticker(final Message m) {
String existingName = m.getFileParams() != null && m.getFileParams().getName() != null ? m.getFileParams().getName() : "";
existingName = existingName.lastIndexOf(".") == -1 ? existingName : existingName.substring(0, existingName.lastIndexOf("."));
@@ -14,6 +14,8 @@ import android.preference.PreferenceManager;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.SpannableStringBuilder;
+import android.text.style.ImageSpan;
+import android.text.style.ClickableSpan;
import android.text.format.DateUtils;
import android.text.style.ForegroundColorSpan;
import android.text.style.RelativeSizeSpan;
@@ -111,6 +113,7 @@ public class MessageAdapter extends ArrayAdapter<Message> {
private OnContactPictureClicked mOnContactPictureClickedListener;
private OnContactPictureClicked mOnMessageBoxClickedListener;
private OnContactPictureLongClicked mOnContactPictureLongClickedListener;
+ private OnInlineImageLongClicked mOnInlineImageLongClickedListener;
private boolean mUseGreenBackground = false;
private final boolean mForceNames;
@@ -162,6 +165,10 @@ public class MessageAdapter extends ArrayAdapter<Message> {
this.mOnContactPictureLongClickedListener = listener;
}
+ public void setOnInlineImageLongClicked(OnInlineImageLongClicked listener) {
+ this.mOnInlineImageLongClickedListener = listener;
+ }
+
@Override
public int getViewTypeCount() {
return 5;
@@ -577,7 +584,26 @@ public class MessageAdapter extends ArrayAdapter<Message> {
MyLinkify.addLinks(body, message.getConversation().getAccount());
viewHolder.messageBody.setAutoLinkMask(0);
viewHolder.messageBody.setText(body);
- BetterLinkMovementMethod method = BetterLinkMovementMethod.newInstance();
+ BetterLinkMovementMethod method = new BetterLinkMovementMethod() {
+ @Override
+ protected void dispatchUrlLongClick(TextView tv, ClickableSpan span) {
+ if (span instanceof URLSpan || mOnInlineImageLongClickedListener == null) {
+ super.dispatchUrlLongClick(tv, span);
+ return;
+ }
+
+ Spannable body = (Spannable) tv.getText();
+ ImageSpan[] imageSpans = body.getSpans(body.getSpanStart(span), body.getSpanEnd(span), ImageSpan.class);
+ if (imageSpans.length > 0) {
+ Uri uri = Uri.parse(imageSpans[0].getSource());
+ Cid cid = BobTransfer.cid(uri);
+ if (cid == null) return;
+ if (mOnInlineImageLongClickedListener.onInlineImageLongClicked(cid)) {
+ tv.dispatchTouchEvent(MotionEvent.obtain(0, 0, MotionEvent.ACTION_CANCEL, 0f, 0f, 0));
+ }
+ }
+ }
+ };
method.setOnLinkLongClickListener((tv, url) -> {
tv.dispatchTouchEvent(MotionEvent.obtain(0, 0, MotionEvent.ACTION_CANCEL, 0f, 0f, 0));
ShareUtil.copyLinkToClipboard(activity, url);
@@ -1096,6 +1122,10 @@ public class MessageAdapter extends ArrayAdapter<Message> {
void onContactPictureLongClicked(View v, Message message);
}
+ public interface OnInlineImageLongClicked {
+ boolean onInlineImageLongClicked(Cid cid);
+ }
+
private static class ViewHolder {
public Button load_more_messages;