diff options
Diffstat (limited to 'src/main/java/eu/siacs/conversations/ui')
3 files changed, 74 insertions, 30 deletions
diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java index 15e75d7f5..02c09a5f2 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java @@ -53,6 +53,7 @@ import eu.siacs.conversations.entities.MucOptions; import eu.siacs.conversations.entities.Presence; import eu.siacs.conversations.entities.Transferable; import eu.siacs.conversations.entities.TransferablePlaceholder; +import eu.siacs.conversations.http.HttpDownloadConnection; import eu.siacs.conversations.services.MessageArchiveService; import eu.siacs.conversations.services.XmppConnectionService; import eu.siacs.conversations.ui.XmppActivity.OnPresenceSelected; @@ -520,6 +521,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa private void populateContextMenu(ContextMenu menu) { final Message m = this.selectedMessage; + final Transferable t = m.getTransferable(); Message relevantForCorrection = m; while(relevantForCorrection.mergeable(relevantForCorrection.next())) { relevantForCorrection = relevantForCorrection.next(); @@ -536,7 +538,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa MenuItem downloadFile = menu.findItem(R.id.download_file); MenuItem cancelTransmission = menu.findItem(R.id.cancel_transmission); if ((m.getType() == Message.TYPE_TEXT || m.getType() == Message.TYPE_PRIVATE) - && m.getTransferable() == null + && t == null && !GeoHelper.isGeoUri(m.getBody()) && m.treatAsDownloadable() != Message.Decision.MUST) { copyText.setVisible(true); @@ -550,7 +552,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa } if ((m.getType() != Message.TYPE_TEXT && m.getType() != Message.TYPE_PRIVATE - && m.getTransferable() == null) + && t == null) || (GeoHelper.isGeoUri(m.getBody()))) { shareWith.setVisible(true); } @@ -559,15 +561,16 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa } if (m.hasFileOnRemoteHost() || GeoHelper.isGeoUri(m.getBody()) - || m.treatAsDownloadable() == Message.Decision.MUST) { + || m.treatAsDownloadable() == Message.Decision.MUST + || (t != null && t instanceof HttpDownloadConnection)) { copyUrl.setVisible(true); } - if ((m.getType() == Message.TYPE_TEXT && m.getTransferable() == null && m.treatAsDownloadable() != Message.Decision.NEVER) - || (m.isFileOrImage() && m.getTransferable() instanceof TransferablePlaceholder && m.hasFileOnRemoteHost())){ + if ((m.getType() == Message.TYPE_TEXT && t == null && m.treatAsDownloadable() != Message.Decision.NEVER) + || (m.isFileOrImage() && t instanceof TransferablePlaceholder && m.hasFileOnRemoteHost())){ downloadFile.setVisible(true); downloadFile.setTitle(activity.getString(R.string.download_x_file,UIHelper.getFileDescriptionString(activity, m))); } - if ((m.getTransferable() != null && !(m.getTransferable() instanceof TransferablePlaceholder)) + if ((t != null && !(t instanceof TransferablePlaceholder)) || (m.isFileOrImage() && (m.getStatus() == Message.STATUS_WAITING || m.getStatus() == Message.STATUS_OFFERED))) { cancelTransmission.setVisible(true); diff --git a/src/main/java/eu/siacs/conversations/ui/PublishProfilePictureActivity.java b/src/main/java/eu/siacs/conversations/ui/PublishProfilePictureActivity.java index 411407a19..828f39d84 100644 --- a/src/main/java/eu/siacs/conversations/ui/PublishProfilePictureActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/PublishProfilePictureActivity.java @@ -8,6 +8,8 @@ import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.net.Uri; import android.os.Bundle; +import android.view.Menu; +import android.view.MenuItem; import android.view.View; import android.view.View.OnClickListener; import android.view.View.OnLongClickListener; @@ -28,13 +30,12 @@ import eu.siacs.conversations.persistance.FileBackend; import eu.siacs.conversations.utils.ExifHelper; import eu.siacs.conversations.utils.FileUtils; import eu.siacs.conversations.utils.PhoneHelper; -import eu.siacs.conversations.xmpp.jid.InvalidJidException; -import eu.siacs.conversations.xmpp.jid.Jid; import eu.siacs.conversations.xmpp.pep.Avatar; public class PublishProfilePictureActivity extends XmppActivity { - private static final int REQUEST_CHOOSE_FILE = 0xac23; + private static final int REQUEST_CHOOSE_FILE_AND_CROP = 0xac23; + private static final int REQUEST_CHOOSE_FILE = 0xac24; private ImageView avatar; private TextView accountTextView; private TextView hintOrWarning; @@ -139,7 +140,7 @@ public class PublishProfilePictureActivity extends XmppActivity { @Override public void onClick(View v) { if (hasStoragePermission(REQUEST_CHOOSE_FILE)) { - chooseAvatar(); + chooseAvatar(false); } } @@ -147,20 +148,22 @@ public class PublishProfilePictureActivity extends XmppActivity { this.defaultUri = PhoneHelper.getSefliUri(getApplicationContext()); } - private void chooseAvatar() { + private void chooseAvatar(boolean crop) { Intent attachFileIntent = new Intent(); attachFileIntent.setType("image/*"); attachFileIntent.setAction(Intent.ACTION_GET_CONTENT); Intent chooser = Intent.createChooser(attachFileIntent, getString(R.string.attach_file)); - startActivityForResult(chooser, REQUEST_CHOOSE_FILE); + startActivityForResult(chooser, crop ? REQUEST_CHOOSE_FILE_AND_CROP : REQUEST_CHOOSE_FILE); } @Override public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { if (grantResults.length > 0) if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { - if (requestCode == REQUEST_CHOOSE_FILE) { - chooseAvatar(); + if (requestCode == REQUEST_CHOOSE_FILE_AND_CROP) { + chooseAvatar(true); + } else if (requestCode == REQUEST_CHOOSE_FILE) { + chooseAvatar(false); } } else { Toast.makeText(this, R.string.no_storage_permission, Toast.LENGTH_SHORT).show(); @@ -168,11 +171,29 @@ public class PublishProfilePictureActivity extends XmppActivity { } @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.publish_avatar, menu); + return super.onCreateOptionsMenu(menu); + } + + @Override + public boolean onOptionsItemSelected(final MenuItem item) { + if (item.getItemId() == R.id.action_crop_image) { + if (hasStoragePermission(REQUEST_CHOOSE_FILE_AND_CROP)) { + chooseAvatar(true); + } + return true; + } else { + return onOptionsItemSelected(item); + } + } + + @Override protected void onActivityResult(int requestCode, int resultCode, final Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode == RESULT_OK) { switch (requestCode) { - case REQUEST_CHOOSE_FILE: + case REQUEST_CHOOSE_FILE_AND_CROP: Uri source = data.getData(); String original = FileUtils.getPath(this, source); if (original != null) { @@ -182,9 +203,17 @@ public class PublishProfilePictureActivity extends XmppActivity { final int size = getPixel(Config.AVATAR_SIZE); Crop.of(source, destination).asSquare().withMaxSize(size, size).start(this); break; + case REQUEST_CHOOSE_FILE: + this.avatarUri = data.getData(); + if (xmppConnectionServiceBound) { + loadImageIntoPreview(this.avatarUri); + } + break; case Crop.REQUEST_CROP: this.avatarUri = Uri.fromFile(new File(getCacheDir(), "croppedAvatar")); - loadImageIntoPreview(this.avatarUri); + if (xmppConnectionServiceBound) { + loadImageIntoPreview(this.avatarUri); + } break; } } else { @@ -249,21 +278,10 @@ public class PublishProfilePictureActivity extends XmppActivity { } } - private Bitmap loadScaledBitmap(Uri uri, int reqSize) throws FileNotFoundException { - final BitmapFactory.Options options = new BitmapFactory.Options(); - options.inJustDecodeBounds = true; - BitmapFactory.decodeStream(getContentResolver().openInputStream(uri), null, options); - int rotation = ExifHelper.getOrientation(getContentResolver().openInputStream(uri)); - options.inSampleSize = FileBackend.calcSampleSize(options, reqSize); - options.inJustDecodeBounds = false; - Bitmap bm = BitmapFactory.decodeStream(getContentResolver().openInputStream(uri), null, options); - return FileBackend.rotate(bm,rotation); - } - protected void loadImageIntoPreview(Uri uri) { Bitmap bm = null; try { - bm = loadScaledBitmap(uri, getPixel(Config.AVATAR_SIZE)); + bm = xmppConnectionService.getFileBackend().cropCenterSquare(uri, getPixel(Config.AVATAR_SIZE)); } catch (Exception e) { e.printStackTrace(); } diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java index 45e54ded5..16bde282d 100644 --- a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java +++ b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java @@ -17,6 +17,7 @@ import android.text.Spanned; import android.text.style.ForegroundColorSpan; import android.text.style.RelativeSizeSpan; import android.text.style.StyleSpan; +import android.text.util.Linkify; import android.util.DisplayMetrics; import android.util.Patterns; import android.view.View; @@ -31,9 +32,11 @@ import android.widget.TextView; import android.widget.Toast; import java.lang.ref.WeakReference; +import java.net.URL; import java.util.List; import java.util.concurrent.RejectedExecutionException; import java.util.regex.Matcher; +import java.util.regex.Pattern; import eu.siacs.conversations.R; import eu.siacs.conversations.crypto.axolotl.XmppAxolotlSession; @@ -53,6 +56,11 @@ public class MessageAdapter extends ArrayAdapter<Message> { private static final int SENT = 0; private static final int RECEIVED = 1; private static final int STATUS = 2; + private static final Pattern XMPP_PATTERN = Pattern + .compile("xmpp\\:(?:(?:[" + + Patterns.GOOD_IRI_CHAR + + "\\;\\/\\?\\@\\&\\=\\#\\~\\-\\.\\+\\!\\*\\'\\(\\)\\,\\_])" + + "|(?:\\%[a-fA-F0-9]{2}))+"); private ConversationActivity activity; @@ -351,6 +359,9 @@ public class MessageAdapter extends ArrayAdapter<Message> { urlCount++; } viewHolder.messageBody.setTextIsSelectable(urlCount <= 1); + viewHolder.messageBody.setAutoLinkMask(0); + Linkify.addLinks(viewHolder.messageBody, Linkify.WEB_URLS); + Linkify.addLinks(viewHolder.messageBody, XMPP_PATTERN, "xmpp"); } else { viewHolder.messageBody.setText(""); viewHolder.messageBody.setTextIsSelectable(false); @@ -628,8 +639,20 @@ public class MessageAdapter extends ArrayAdapter<Message> { displayLocationMessage(viewHolder,message); } else if (message.bodyIsHeart()) { displayHeartMessage(viewHolder, message.getBody().trim()); - } else if (message.treatAsDownloadable() == Message.Decision.MUST || message.treatAsDownloadable() == Message.Decision.SHOULD) { - displayDownloadableMessage(viewHolder, message, activity.getString(R.string.check_x_filesize, UIHelper.getFileDescriptionString(activity, message))); + } else if (message.treatAsDownloadable() == Message.Decision.MUST) { + try { + URL url = new URL(message.getBody()); + displayDownloadableMessage(viewHolder, + message, + activity.getString(R.string.check_x_filesize_on_host, + UIHelper.getFileDescriptionString(activity, message), + url.getHost())); + } catch (Exception e) { + displayDownloadableMessage(viewHolder, + message, + activity.getString(R.string.check_x_filesize, + UIHelper.getFileDescriptionString(activity, message))); + } } else { displayTextMessage(viewHolder, message, darkBackground); } |