diff --git a/app/schemas/eu.faircode.email.DB/1.json b/app/schemas/eu.faircode.email.DB/1.json
index 57b2db60..9a486f83 100644
--- a/app/schemas/eu.faircode.email.DB/1.json
+++ b/app/schemas/eu.faircode.email.DB/1.json
@@ -2,7 +2,7 @@
"formatVersion": 1,
"database": {
"version": 1,
- "identityHash": "23016f9b3ae09175ada077c837687ab6",
+ "identityHash": "cd3cf378d6f71c13ba8beb38a8bf58cf",
"entities": [
{
"tableName": "identity",
@@ -313,7 +313,7 @@
},
{
"tableName": "message",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `account` INTEGER, `folder` INTEGER NOT NULL, `identity` INTEGER, `replying` INTEGER, `uid` INTEGER, `msgid` TEXT, `references` TEXT, `inreplyto` TEXT, `thread` TEXT, `from` TEXT, `to` TEXT, `cc` TEXT, `bcc` TEXT, `reply` TEXT, `subject` TEXT, `body` TEXT, `sent` INTEGER, `received` INTEGER NOT NULL, `stored` INTEGER NOT NULL, `seen` INTEGER NOT NULL, `ui_seen` INTEGER NOT NULL, `ui_hide` INTEGER NOT NULL, `error` TEXT, FOREIGN KEY(`account`) REFERENCES `account`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE , FOREIGN KEY(`folder`) REFERENCES `folder`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE , FOREIGN KEY(`identity`) REFERENCES `identity`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE , FOREIGN KEY(`replying`) REFERENCES `message`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `account` INTEGER, `folder` INTEGER NOT NULL, `identity` INTEGER, `replying` INTEGER, `uid` INTEGER, `msgid` TEXT, `references` TEXT, `inreplyto` TEXT, `thread` TEXT, `from` TEXT, `to` TEXT, `cc` TEXT, `bcc` TEXT, `reply` TEXT, `subject` TEXT, `sent` INTEGER, `received` INTEGER NOT NULL, `stored` INTEGER NOT NULL, `seen` INTEGER NOT NULL, `ui_seen` INTEGER NOT NULL, `ui_hide` INTEGER NOT NULL, `error` TEXT, FOREIGN KEY(`account`) REFERENCES `account`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE , FOREIGN KEY(`folder`) REFERENCES `folder`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE , FOREIGN KEY(`identity`) REFERENCES `identity`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE , FOREIGN KEY(`replying`) REFERENCES `message`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )",
"fields": [
{
"fieldPath": "id",
@@ -411,12 +411,6 @@
"affinity": "TEXT",
"notNull": false
},
- {
- "fieldPath": "body",
- "columnName": "body",
- "affinity": "TEXT",
- "notNull": false
- },
{
"fieldPath": "sent",
"columnName": "sent",
@@ -599,7 +593,7 @@
},
{
"tableName": "attachment",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `message` INTEGER NOT NULL, `sequence` INTEGER NOT NULL, `name` TEXT, `type` TEXT NOT NULL, `size` INTEGER, `progress` INTEGER, `filename` TEXT, FOREIGN KEY(`message`) REFERENCES `message`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `message` INTEGER NOT NULL, `sequence` INTEGER NOT NULL, `name` TEXT, `type` TEXT NOT NULL, `size` INTEGER, `progress` INTEGER, `available` INTEGER NOT NULL, FOREIGN KEY(`message`) REFERENCES `message`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )",
"fields": [
{
"fieldPath": "id",
@@ -644,10 +638,10 @@
"notNull": false
},
{
- "fieldPath": "filename",
- "columnName": "filename",
- "affinity": "TEXT",
- "notNull": false
+ "fieldPath": "available",
+ "columnName": "available",
+ "affinity": "INTEGER",
+ "notNull": true
}
],
"primaryKey": {
@@ -782,7 +776,7 @@
],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
- "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, \"23016f9b3ae09175ada077c837687ab6\")"
+ "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, \"cd3cf378d6f71c13ba8beb38a8bf58cf\")"
]
}
}
\ No newline at end of file
diff --git a/app/src/main/java/eu/faircode/email/ActivityView.java b/app/src/main/java/eu/faircode/email/ActivityView.java
index 542cab77..94c3f4f1 100644
--- a/app/src/main/java/eu/faircode/email/ActivityView.java
+++ b/app/src/main/java/eu/faircode/email/ActivityView.java
@@ -225,6 +225,8 @@ public class ActivityView extends ActivityBase implements FragmentManager.OnBack
file.delete();
+ String body = "
" + sb.toString().replaceAll("\\r?\\n", "
") + "
";
+
EntityMessage draft = null;
DB db = DB.getInstance(context);
@@ -239,12 +241,12 @@ public class ActivityView extends ActivityBase implements FragmentManager.OnBack
draft.msgid = EntityMessage.generateMessageId();
draft.to = new Address[]{Helper.myAddress()};
draft.subject = context.getString(R.string.app_name) + " crash log";
- draft.body = "" + sb.toString().replaceAll("\\r?\\n", "
") + "
";
draft.received = new Date().getTime();
draft.seen = false;
draft.ui_seen = false;
draft.ui_hide = false;
draft.id = db.message().insertMessage(draft);
+ draft.write(context, body);
}
EntityOperation.queue(db, draft, EntityOperation.ADD);
diff --git a/app/src/main/java/eu/faircode/email/AdapterAttachment.java b/app/src/main/java/eu/faircode/email/AdapterAttachment.java
index 394e66ec..5cdecd51 100644
--- a/app/src/main/java/eu/faircode/email/AdapterAttachment.java
+++ b/app/src/main/java/eu/faircode/email/AdapterAttachment.java
@@ -64,7 +64,6 @@ public class AdapterAttachment extends RecyclerView.Adapter") + "";
+
EntityMessage draft;
DB db = DB.getInstance(context);
@@ -96,16 +100,19 @@ public class FragmentAbout extends FragmentEx {
draft.msgid = EntityMessage.generateMessageId();
draft.to = new Address[]{Helper.myAddress()};
draft.subject = context.getString(R.string.app_name) + " debug info";
- draft.body = "" + sb.toString().replaceAll("\\r?\\n", "
") + "
";
draft.received = new Date().getTime();
draft.seen = false;
draft.ui_seen = false;
draft.ui_hide = false;
draft.id = db.message().insertMessage(draft);
+ draft.write(context, body);
EntityOperation.queue(db, draft, EntityOperation.ADD);
db.setTransactionSuccessful();
+ } catch (IOException ex) {
+ Log.e(Helper.TAG, ex + "\n" + Log.getStackTraceString(ex));
+ return null;
} finally {
db.endTransaction();
}
@@ -118,9 +125,10 @@ public class FragmentAbout extends FragmentEx {
@Override
protected void onLoaded(Bundle args, Long id) {
btnDebugInfo.setEnabled(true);
- startActivity(new Intent(getContext(), ActivityCompose.class)
- .putExtra("action", "edit")
- .putExtra("id", id));
+ if (id != null)
+ startActivity(new Intent(getContext(), ActivityCompose.class)
+ .putExtra("action", "edit")
+ .putExtra("id", id));
}
@Override
diff --git a/app/src/main/java/eu/faircode/email/FragmentCompose.java b/app/src/main/java/eu/faircode/email/FragmentCompose.java
index 80da6041..0bb8e31d 100644
--- a/app/src/main/java/eu/faircode/email/FragmentCompose.java
+++ b/app/src/main/java/eu/faircode/email/FragmentCompose.java
@@ -30,6 +30,7 @@ import android.os.Handler;
import android.provider.ContactsContract;
import android.provider.OpenableColumns;
import android.text.Html;
+import android.text.Spanned;
import android.text.TextUtils;
import android.util.Log;
import android.view.KeyEvent;
@@ -516,7 +517,7 @@ public class FragmentCompose extends FragmentEx {
attachment.size = size;
attachment.progress = null;
- attachment.filename = file.getName();
+ attachment.available = true;
db.attachment().updateAttachment(attachment);
} finally {
try {
@@ -530,7 +531,6 @@ public class FragmentCompose extends FragmentEx {
} catch (Throwable ex) {
// Reset progress on failure
attachment.progress = null;
- attachment.filename = null;
db.attachment().updateAttachment(attachment);
throw ex;
}
@@ -571,7 +571,7 @@ public class FragmentCompose extends FragmentEx {
private SimpleTask draftLoader = new SimpleTask() {
@Override
- protected EntityMessage onLoad(Context context, Bundle args) {
+ protected EntityMessage onLoad(Context context, Bundle args) throws IOException {
String action = args.getString("action");
long id = args.getLong("id", -1);
long account = args.getLong("account", -1);
@@ -618,6 +618,8 @@ public class FragmentCompose extends FragmentEx {
if (drafts == null)
throw new IllegalArgumentException("no drafts folder");
+ String body = "";
+
draft = new EntityMessage();
draft.account = account;
draft.folder = drafts.id;
@@ -640,21 +642,21 @@ public class FragmentCompose extends FragmentEx {
if ("reply".equals(action) || "reply_all".equals(action)) {
draft.subject = context.getString(R.string.title_subject_reply, ref.subject);
- draft.body = String.format("
%s %s:
%s",
+ body = String.format("
%s %s:
%s",
Html.escapeHtml(new Date().toString()),
Html.escapeHtml(TextUtils.join(", ", draft.to)),
- HtmlHelper.sanitize(context, ref.body, true));
+ HtmlHelper.sanitize(context, ref.read(context), true));
} else if ("forward".equals(action)) {
draft.subject = context.getString(R.string.title_subject_forward, ref.subject);
- draft.body = String.format("
%s %s:
%s",
+ body = String.format("
%s %s:
%s",
Html.escapeHtml(new Date().toString()),
Html.escapeHtml(TextUtils.join(", ", ref.from)),
- HtmlHelper.sanitize(context, ref.body, true));
+ HtmlHelper.sanitize(context, ref.read(context), true));
}
}
if ("new".equals(action))
- draft.body = "";
+ body = "";
draft.received = new Date().getTime();
draft.seen = false;
@@ -662,6 +664,7 @@ public class FragmentCompose extends FragmentEx {
draft.ui_hide = false;
draft.id = db.message().insertMessage(draft);
+ draft.write(context, body);
EntityOperation.queue(db, draft, EntityOperation.ADD);
@@ -687,7 +690,22 @@ public class FragmentCompose extends FragmentEx {
etBcc.setText(draft.bcc == null ? null : TextUtils.join(", ", draft.bcc));
etSubject.setText(draft.subject);
- etBody.setText(TextUtils.isEmpty(draft.body) ? null : Html.fromHtml(draft.body));
+ etBody.setText(null);
+
+ Bundle a = new Bundle();
+ a.putLong("id", draft.id);
+
+ new SimpleTask() {
+ @Override
+ protected Spanned onLoad(Context context, Bundle args) throws Throwable {
+ return Html.fromHtml(EntityMessage.read(context, args.getLong("id")));
+ }
+
+ @Override
+ protected void onLoaded(Bundle args, Spanned body) {
+ etBody.setText(body);
+ }
+ }.load(FragmentCompose.this, a);
getActivity().invalidateOptionsMenu();
Helper.setViewsEnabled(view, true);
@@ -836,14 +854,16 @@ public class FragmentCompose extends FragmentEx {
draft.cc = acc;
draft.bcc = abcc;
draft.subject = subject;
- draft.body = "" + body.replaceAll("\\r?\\n", "
") + "
";
draft.received = new Date().getTime();
+ body = "" + body.replaceAll("\\r?\\n", "
") + "
";
+
// Execute action
if (action == R.id.action_trash) {
draft.ui_seen = true;
draft.ui_hide = true;
db.message().updateMessage(draft);
+ draft.write(context, body);
EntityOperation.queue(db, draft, EntityOperation.SEEN, true);
@@ -857,11 +877,13 @@ public class FragmentCompose extends FragmentEx {
return null;
db.message().updateMessage(draft);
+ draft.write(context, body);
EntityOperation.queue(db, draft, EntityOperation.ADD);
} else if (action == R.id.action_send) {
db.message().updateMessage(draft);
+ draft.write(context, body);
// Check data
if (draft.identity == null)
@@ -876,7 +898,7 @@ public class FragmentCompose extends FragmentEx {
// Save attachments
List attachments = db.attachment().getAttachments(draft.id);
for (EntityAttachment attachment : attachments)
- if (attachment.filename == null)
+ if (!attachment.available)
throw new IllegalArgumentException(context.getString(R.string.title_attachments_missing));
// Delete draft (cannot move to outbox)
diff --git a/app/src/main/java/eu/faircode/email/FragmentMessage.java b/app/src/main/java/eu/faircode/email/FragmentMessage.java
index 5be144b7..67abcbd4 100644
--- a/app/src/main/java/eu/faircode/email/FragmentMessage.java
+++ b/app/src/main/java/eu/faircode/email/FragmentMessage.java
@@ -29,6 +29,7 @@ import android.preference.PreferenceManager;
import android.text.Html;
import android.text.Layout;
import android.text.Spannable;
+import android.text.Spanned;
import android.text.method.LinkMovementMethod;
import android.text.style.URLSpan;
import android.view.LayoutInflater;
@@ -339,9 +340,23 @@ public class FragmentMessage extends FragmentEx {
: R.drawable.baseline_visibility_24);
actionSeen.setTitle(message.ui_seen ? R.string.title_unseen : R.string.title_seen);
- tvBody.setText(message.body == null
- ? null
- : Html.fromHtml(HtmlHelper.sanitize(getContext(), message.body, false)));
+ tvBody.setText(null);
+
+ Bundle args = new Bundle();
+ args.putLong("id", message.id);
+
+ new SimpleTask() {
+ @Override
+ protected Spanned onLoad(Context context, Bundle args) throws Throwable {
+ String body = EntityMessage.read(context, args.getLong("id"));
+ return Html.fromHtml(HtmlHelper.sanitize(getContext(), body, false));
+ }
+
+ @Override
+ protected void onLoaded(Bundle args, Spanned body) {
+ tvBody.setText(body);
+ }
+ }.load(FragmentMessage.this, args);
db.folder().liveFolders(message.account).removeObservers(getViewLifecycleOwner());
db.folder().liveFolders(message.account).observe(getViewLifecycleOwner(), new Observer>() {
diff --git a/app/src/main/java/eu/faircode/email/MessageHelper.java b/app/src/main/java/eu/faircode/email/MessageHelper.java
index 1fcbddfd..10155ad7 100644
--- a/app/src/main/java/eu/faircode/email/MessageHelper.java
+++ b/app/src/main/java/eu/faircode/email/MessageHelper.java
@@ -93,7 +93,7 @@ public class MessageHelper {
return props;
}
- static MimeMessageEx from(Context context, EntityMessage message, List attachments, Session isession) throws MessagingException {
+ static MimeMessageEx from(Context context, EntityMessage message, List attachments, Session isession) throws MessagingException, IOException {
MimeMessageEx imessage = new MimeMessageEx(isession, message.msgid);
imessage.setFlag(Flags.Flag.SEEN, message.seen);
@@ -115,25 +115,22 @@ public class MessageHelper {
// TODO: plain message?
- if (message.body == null)
- throw new IllegalArgumentException("null message");
-
if (attachments.size() == 0)
- imessage.setText(message.body, Charset.defaultCharset().name(), "html");
+ imessage.setText(message.read(context), Charset.defaultCharset().name(), "html");
else {
Multipart multipart = new MimeMultipart();
BodyPart bpMessage = new MimeBodyPart();
- bpMessage.setContent(message.body, "text/html; charset=" + Charset.defaultCharset().name());
+ bpMessage.setContent(message.read(context), "text/html; charset=" + Charset.defaultCharset().name());
multipart.addBodyPart(bpMessage);
for (final EntityAttachment attachment : attachments)
- if (attachment.filename != null) {
+ if (attachment.available) {
BodyPart bpAttachment = new MimeBodyPart();
bpAttachment.setFileName(attachment.name);
File dir = new File(context.getFilesDir(), "attachments");
- File file = new File(dir, attachment.filename);
+ File file = new File(dir, attachment.id.toString());
FileDataSource dataSource = new FileDataSource(file);
dataSource.setFileTypeMap(new FileTypeMap() {
@Override
@@ -159,7 +156,7 @@ public class MessageHelper {
return imessage;
}
- static MimeMessageEx from(Context context, EntityMessage message, EntityMessage reply, List attachments, Session isession) throws MessagingException {
+ static MimeMessageEx from(Context context, EntityMessage message, EntityMessage reply, List attachments, Session isession) throws MessagingException, IOException {
MimeMessageEx imessage = from(context, message, attachments, isession);
imessage.addHeader("In-Reply-To", reply.msgid);
imessage.addHeader("References", (reply.references == null ? "" : reply.references + " ") + reply.msgid);
diff --git a/app/src/main/java/eu/faircode/email/ServiceSynchronize.java b/app/src/main/java/eu/faircode/email/ServiceSynchronize.java
index 5a038eeb..3aea8a97 100644
--- a/app/src/main/java/eu/faircode/email/ServiceSynchronize.java
+++ b/app/src/main/java/eu/faircode/email/ServiceSynchronize.java
@@ -851,7 +851,7 @@ public class ServiceSynchronize extends LifecycleService {
db.message().setMessageSeen(message.id, seen);
}
- private void doAdd(EntityFolder folder, Session isession, IMAPFolder ifolder, EntityMessage message, JSONArray jargs, DB db) throws MessagingException, JSONException {
+ private void doAdd(EntityFolder folder, Session isession, IMAPFolder ifolder, EntityMessage message, JSONArray jargs, DB db) throws MessagingException, JSONException, IOException {
// Append message
List attachments = db.attachment().getAttachments(message.id);
@@ -871,7 +871,7 @@ public class ServiceSynchronize extends LifecycleService {
Log.i(Helper.TAG, "Appended uid=" + message.uid);
}
- private void doMove(EntityFolder folder, Session isession, IMAPStore istore, IMAPFolder ifolder, EntityMessage message, JSONArray jargs, DB db) throws JSONException, MessagingException {
+ private void doMove(EntityFolder folder, Session isession, IMAPStore istore, IMAPFolder ifolder, EntityMessage message, JSONArray jargs, DB db) throws JSONException, MessagingException, IOException {
// Move message
long id = jargs.getLong(0);
EntityFolder target = db.folder().getFolder(id);
@@ -914,7 +914,7 @@ public class ServiceSynchronize extends LifecycleService {
db.message().deleteMessage(message.id);
}
- private void doSend(Session isession, EntityMessage message, DB db) throws MessagingException {
+ private void doSend(Session isession, EntityMessage message, DB db) throws MessagingException, IOException {
// Send message
EntityIdentity ident = db.identity().getIdentity(message.identity);
EntityMessage reply = (message.replying == null ? null : db.message().getMessage(message.replying));
@@ -1033,7 +1033,7 @@ public class ServiceSynchronize extends LifecycleService {
// Store attachment data
attachment.size = size;
attachment.progress = null;
- attachment.filename = file.getName();
+ attachment.available = true;
db.attachment().updateAttachment(attachment);
} finally {
try {
@@ -1048,7 +1048,6 @@ public class ServiceSynchronize extends LifecycleService {
} catch (Throwable ex) {
// Reset progress on failure
attachment.progress = null;
- attachment.filename = null;
db.attachment().updateAttachment(attachment);
throw ex;
}
@@ -1296,7 +1295,6 @@ public class ServiceSynchronize extends LifecycleService {
message.bcc = helper.getBcc();
message.reply = helper.getReply();
message.subject = imessage.getSubject();
- message.body = helper.getHtml();
message.received = imessage.getReceivedDate().getTime();
message.sent = (imessage.getSentDate() == null ? null : imessage.getSentDate().getTime());
message.seen = seen;
@@ -1304,6 +1302,7 @@ public class ServiceSynchronize extends LifecycleService {
message.ui_hide = false;
message.id = db.message().insertMessage(message);
+ message.write(this, helper.getHtml());
Log.i(Helper.TAG, folder.name + " added id=" + message.id + " uid=" + message.uid);
int sequence = 0;
diff --git a/app/src/main/res/layout/item_attachment.xml b/app/src/main/res/layout/item_attachment.xml
index d7626bd7..f008aa28 100644
--- a/app/src/main/res/layout/item_attachment.xml
+++ b/app/src/main/res/layout/item_attachment.xml
@@ -61,24 +61,15 @@
-
-