diff --git a/app/src/main/java/eu/faircode/email/DB.java b/app/src/main/java/eu/faircode/email/DB.java index f8c4aec077..dc59b9794a 100644 --- a/app/src/main/java/eu/faircode/email/DB.java +++ b/app/src/main/java/eu/faircode/email/DB.java @@ -287,10 +287,10 @@ public abstract class DB extends RoomDatabase { private static void createTriggers(@NonNull SupportSQLiteDatabase db) { List image = new ArrayList<>(); - for (String img : EntityAttachment.IMAGE_TYPES) + for (String img : Helper.IMAGE_TYPES) image.add("'" + img + "'"); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) - for (String img : EntityAttachment.IMAGE_TYPES8) + for (String img : Helper.IMAGE_TYPES8) image.add("'" + img + "'"); String images = TextUtils.join(",", image); diff --git a/app/src/main/java/eu/faircode/email/EntityAttachment.java b/app/src/main/java/eu/faircode/email/EntityAttachment.java index 3146ff2a84..066b25f18c 100644 --- a/app/src/main/java/eu/faircode/email/EntityAttachment.java +++ b/app/src/main/java/eu/faircode/email/EntityAttachment.java @@ -20,7 +20,6 @@ package eu.faircode.email; */ import android.content.Context; -import android.os.Build; import android.text.TextUtils; import androidx.annotation.NonNull; @@ -31,8 +30,6 @@ import androidx.room.PrimaryKey; import java.io.File; import java.io.IOException; -import java.util.Arrays; -import java.util.Collections; import java.util.List; import java.util.Locale; import java.util.Objects; @@ -64,21 +61,6 @@ public class EntityAttachment { static final Integer SMIME_SIGNED_DATA = 7; static final Integer SMIME_CONTENT = 8; - // https://developer.android.com/guide/topics/media/media-formats#image-formats - static final List IMAGE_TYPES = Collections.unmodifiableList(Arrays.asList( - "image/bmp", - "image/gif", - "image/jpeg", - "image/jpg", - "image/png", - "image/webp" - )); - - static final List IMAGE_TYPES8 = Collections.unmodifiableList(Arrays.asList( - "image/heic", - "image/heif" - )); - @PrimaryKey(autoGenerate = true) public Long id; @NonNull @@ -108,11 +90,7 @@ public class EntityAttachment { } boolean isImage() { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) - if (IMAGE_TYPES8.contains(getMimeType())) - return true; - - return IMAGE_TYPES.contains(getMimeType()); + return Helper.isImage(getMimeType()); } boolean isEncryption() { diff --git a/app/src/main/java/eu/faircode/email/FragmentCompose.java b/app/src/main/java/eu/faircode/email/FragmentCompose.java index 305bf1577b..53cf6bb690 100644 --- a/app/src/main/java/eu/faircode/email/FragmentCompose.java +++ b/app/src/main/java/eu/faircode/email/FragmentCompose.java @@ -1107,6 +1107,13 @@ public class FragmentCompose extends FragmentBase { args.putString("body", a.getString("body")); args.putString("text", a.getString("text")); args.putString("selected", a.getString("selected")); + + if (a.containsKey("attachments")) { + args.putParcelableArrayList("attachments", a.getParcelableArrayList("attachments")); + a.remove("attachments"); + setArguments(a); + } + draftLoader.execute(this, args, "compose:new"); } else { Bundle args = new Bundle(); @@ -1741,11 +1748,10 @@ public class FragmentCompose extends FragmentBase { onPickContact(requestCode, data); break; case REQUEST_SHARED: - Bundle args = getArguments(); - ArrayList uris = args.getParcelableArrayList("attachments"); - args.remove("attachments"); - if (resultCode == RESULT_OK) - onAddImageFile(uris); + if (resultCode == RESULT_OK && data != null) { + Bundle args = data.getBundleExtra("args"); + onAddImageFile(args.getParcelableArrayList("images")); + } break; case REQUEST_IMAGE: if (resultCode == RESULT_OK) { @@ -2878,42 +2884,7 @@ public class FragmentCompose extends FragmentBase { } EntityAttachment attachment = new EntityAttachment(); - - String fname = null; - String ftype = null; - Long fsize = null; - - try { - DocumentFile dfile = DocumentFile.fromSingleUri(context, uri); - if (dfile != null) { - fname = dfile.getName(); - ftype = dfile.getType(); - fsize = dfile.length(); - } - } catch (SecurityException ex) { - Log.e(ex); - } - - // Check name - if (TextUtils.isEmpty(fname)) - fname = uri.getLastPathSegment(); - - // Check type - if (!TextUtils.isEmpty(ftype)) - try { - new ContentType(ftype); - } catch (ParseException ex) { - Log.w(ex); - ftype = null; - } - - if (TextUtils.isEmpty(ftype) || - "*/*".equals(ftype) || - "application/octet-stream".equals(ftype)) - ftype = Helper.guessMimeType(fname); - - if (fsize != null && fsize <= 0) - fsize = null; + UriInfo info = getInfo(uri, context); DB db = DB.getInstance(context); try { @@ -2924,10 +2895,10 @@ public class FragmentCompose extends FragmentBase { attachment.message = draft.id; attachment.sequence = db.attachment().getAttachmentSequence(draft.id) + 1; - attachment.name = fname; - attachment.type = ftype; + attachment.name = info.name; + attachment.type = info.type; attachment.disposition = (image ? Part.INLINE : Part.ATTACHMENT); - attachment.size = fsize; + attachment.size = info.size; attachment.progress = 0; attachment.id = db.attachment().insertAttachment(attachment); @@ -3680,6 +3651,26 @@ public class FragmentCompose extends FragmentBase { } } + if ("new".equals(action)) { + ArrayList uris = args.getParcelableArrayList("attachments"); + if (uris != null) { + ArrayList images = new ArrayList<>(); + for (Uri uri : uris) + try { + UriInfo info = getInfo(uri, context); + if (info.isImage()) + images.add(uri); + else + addAttachment(context, data.draft.id, uri, false, 0, false); + } catch (IOException ex) { + Log.e(ex); + } + + if (images.size() > 0) + args.putParcelableArrayList("images", images); + } + } + if (ref != null && ("reply".equals(action) || "reply_all".equals(action) || "forward".equals(action) || "editasnew".equals(action))) { @@ -3941,21 +3932,20 @@ public class FragmentCompose extends FragmentBase { } }); - if (getArguments().containsKey("attachments")) { + if (args.containsKey("images")) { + ArrayList images = args.getParcelableArrayList("images"); boolean image_dialog = prefs.getBoolean("image_dialog", true); if (image_dialog) { Bundle aargs = new Bundle(); aargs.putInt("title", android.R.string.ok); + aargs.putParcelableArrayList("images", images); + FragmentDialogAddImage fragment = new FragmentDialogAddImage(); fragment.setArguments(aargs); fragment.setTargetFragment(FragmentCompose.this, REQUEST_SHARED); fragment.show(getParentFragmentManager(), "compose:shared"); - } else { - Bundle aargs = getArguments(); - ArrayList uris = aargs.getParcelableArrayList("attachments"); - aargs.remove("attachments"); - onAddImageFile(uris); - } + } else + onAddImageFile(images); } } @@ -5242,40 +5232,6 @@ public class FragmentCompose extends FragmentBase { }) .create(); } - - @Override - public void onActivityResult(int requestCode, int resultCode, @Nullable Intent intent) { - super.onActivityResult(requestCode, resultCode, intent); - - if (resultCode == RESULT_OK && intent != null) { - Bundle data = intent.getBundleExtra("args"); - long id = data.getLong("id"); - long duration = data.getLong("duration"); - long time = data.getLong("time"); - - Bundle args = new Bundle(); - args.putLong("id", id); - args.putLong("wakeup", duration == 0 ? -1 : time); - - new SimpleTask() { - @Override - protected Void onExecute(Context context, Bundle args) { - long id = args.getLong("id"); - long wakeup = args.getLong("wakeup"); - - DB db = DB.getInstance(context); - db.message().setMessageSnoozed(id, wakeup < 0 ? null : wakeup); - - return null; - } - - @Override - protected void onException(Bundle args, Throwable ex) { - Log.unexpectedError(getParentFragmentManager(), ex); - } - }.execute(this, args, "compose:snooze"); - } - } } public static class FragmentDialogSend extends FragmentDialogBase { @@ -5680,6 +5636,53 @@ public class FragmentCompose extends FragmentBase { } } + private static UriInfo getInfo(Uri uri, Context context) { + UriInfo result = new UriInfo(); + try { + DocumentFile dfile = DocumentFile.fromSingleUri(context, uri); + if (dfile != null) { + result.name = dfile.getName(); + result.type = dfile.getType(); + result.size = dfile.length(); + } + } catch (SecurityException ex) { + Log.e(ex); + } + + // Check name + if (TextUtils.isEmpty(result.name)) + result.name = uri.getLastPathSegment(); + + // Check type + if (!TextUtils.isEmpty(result.type)) + try { + new ContentType(result.type); + } catch (ParseException ex) { + Log.w(ex); + result.type = null; + } + + if (TextUtils.isEmpty(result.type) || + "*/*".equals(result.type) || + "application/octet-stream".equals(result.type)) + result.type = Helper.guessMimeType(result.name); + + if (result.size != null && result.size <= 0) + result.size = null; + + return result; + } + + private static class UriInfo { + String name; + String type; + Long size; + + boolean isImage() { + return Helper.isImage(type); + } + } + private static class DraftData { private EntityMessage draft; private List identities; diff --git a/app/src/main/java/eu/faircode/email/Helper.java b/app/src/main/java/eu/faircode/email/Helper.java index 8568b13c0c..84868a9857 100644 --- a/app/src/main/java/eu/faircode/email/Helper.java +++ b/app/src/main/java/eu/faircode/email/Helper.java @@ -112,6 +112,7 @@ import java.text.DecimalFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.Comparator; import java.util.Date; import java.util.List; @@ -166,6 +167,21 @@ public class Helper { ")+" ); + // https://developer.android.com/guide/topics/media/media-formats#image-formats + static final List IMAGE_TYPES = Collections.unmodifiableList(Arrays.asList( + "image/bmp", + "image/gif", + "image/jpeg", + "image/jpg", + "image/png", + "image/webp" + )); + + static final List IMAGE_TYPES8 = Collections.unmodifiableList(Arrays.asList( + "image/heic", + "image/heif" + )); + private static final ExecutorService executor = getBackgroundExecutor(1, "helper"); static ExecutorService getBackgroundExecutor(int threads, final String name) { @@ -1131,6 +1147,14 @@ public class Helper { //intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, Uri.fromFile(initial)); } + static boolean isImage(String mimeType) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) + if (IMAGE_TYPES8.contains(mimeType)) + return true; + + return IMAGE_TYPES.contains(mimeType); + } + // Cryptography static String sha256(String data) throws NoSuchAlgorithmException {