aboutsummaryrefslogtreecommitdiffstats
path: root/src/main/java/eu/siacs/conversations/ui
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/eu/siacs/conversations/ui')
-rw-r--r--src/main/java/eu/siacs/conversations/ui/ConversationFragment.java15
-rw-r--r--src/main/java/eu/siacs/conversations/ui/PublishProfilePictureActivity.java62
-rw-r--r--src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java27
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);
}