Improved reply/forward handling

pull/147/head
M66B 7 years ago
parent 2b3d6b94da
commit 332fcb5557

@ -1215,7 +1215,7 @@ public class ActivityView extends ActivityBilling implements FragmentManager.OnB
if (encrypted == null) { if (encrypted == null) {
EntityMessage message = db.message().getMessage(id); EntityMessage message = db.message().getMessage(id);
String body = message.read(context); String body = Helper.readText(EntityMessage.getFile(context, message.id));
// https://tools.ietf.org/html/rfc4880#section-6.2 // https://tools.ietf.org/html/rfc4880#section-6.2
int begin = body.indexOf(PGP_BEGIN_MESSAGE); int begin = body.indexOf(PGP_BEGIN_MESSAGE);
@ -1252,7 +1252,7 @@ public class ActivityView extends ActivityBilling implements FragmentManager.OnB
// Write decrypted body // Write decrypted body
EntityMessage m = db.message().getMessage(id); EntityMessage m = db.message().getMessage(id);
m.write(context, decrypted.toString()); Helper.writeText(EntityMessage.getFile(context, m.id), decrypted.toString());
db.message().setMessageStored(id, new Date().getTime()); db.message().setMessageStored(id, new Date().getTime());
@ -1275,7 +1275,7 @@ public class ActivityView extends ActivityBilling implements FragmentManager.OnB
// Write decrypted body // Write decrypted body
EntityMessage m = db.message().getMessage(id); EntityMessage m = db.message().getMessage(id);
m.write(context, parts.getHtml(context)); Helper.writeText(EntityMessage.getFile(context, m.id), parts.getHtml(context));
// Remove previously decrypted attachments // Remove previously decrypted attachments
for (EntityAttachment a : attachments) for (EntityAttachment a : attachments)

@ -1115,7 +1115,7 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
TupleMessageEx message = (TupleMessageEx) args.getSerializable("message"); TupleMessageEx message = (TupleMessageEx) args.getSerializable("message");
if (body == null) if (body == null)
try { try {
body = message.read(context); body = Helper.readText(EntityMessage.getFile(context, message.id));
} catch (IOException ex) { } catch (IOException ex) {
Log.e(ex); Log.e(ex);
body = ""; body = "";
@ -1496,7 +1496,7 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
return new String[]{ return new String[]{
from, from,
message.subject, message.subject,
HtmlHelper.getText(message.read(context)) HtmlHelper.getText(Helper.readText(EntityMessage.getFile(context, message.id)))
}; };
} }

@ -347,12 +347,6 @@ public interface DaoMessage {
" WHERE id = :id") " WHERE id = :id")
int setMessageSnoozed(long id, Long wakeup); int setMessageSnoozed(long id, Long wakeup);
@Query("UPDATE message SET replying = :newid WHERE replying = :oldid")
int updateMessageReplying(long oldid, long newid);
@Query("UPDATE message SET forwarding = :newid WHERE forwarding = :oldid")
int updateMessageForwarding(long oldid, long newid);
@Query("DELETE FROM message WHERE id = :id") @Query("DELETE FROM message WHERE id = :id")
int deleteMessage(long id); int deleteMessage(long id);

@ -24,12 +24,7 @@ import android.app.PendingIntent;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File; import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Serializable; import java.io.Serializable;
import java.util.Date; import java.util.Date;
import java.util.Random; import java.util.Random;
@ -88,8 +83,8 @@ public class EntityMessage implements Serializable {
public Long folder; public Long folder;
public Long identity; public Long identity;
public String extra; // plus public String extra; // plus
public Long replying; public Long replying; // obsolete
public Long forwarding; public Long forwarding; // obsolete
public Long uid; // compose/moved = null public Long uid; // compose/moved = null
public String msgid; public String msgid;
public String references; public String references;
@ -161,38 +156,11 @@ public class EntityMessage implements Serializable {
return new File(dir, id.toString()); return new File(dir, id.toString());
} }
void write(Context context, String body) throws IOException { static File getRefFile(Context context, Long id) {
File file = getFile(context, id); File dir = new File(context.getFilesDir(), "references");
BufferedWriter out = null; if (!dir.exists())
try { dir.mkdir();
out = new BufferedWriter(new FileWriter(file)); return new File(dir, id.toString());
out.write(body == null ? "" : body);
} finally {
if (out != null)
out.close();
}
}
String read(Context context) throws IOException {
return read(context, this.id);
}
static String read(Context context, Long id) throws IOException {
File file = getFile(context, id);
BufferedReader in = null;
try {
in = new BufferedReader(new FileReader(file));
StringBuilder body = new StringBuilder();
String line;
while ((line = in.readLine()) != null) {
body.append(line);
body.append('\n');
}
return body.toString();
} finally {
if (in != null)
in.close();
}
} }
static File getRawFile(Context context, Long id) { static File getRawFile(Context context, Long id) {
@ -272,8 +240,6 @@ public class EntityMessage implements Serializable {
return ((this.account == null ? other.account == null : this.account.equals(other.account)) && return ((this.account == null ? other.account == null : this.account.equals(other.account)) &&
this.folder.equals(other.folder) && this.folder.equals(other.folder) &&
(this.identity == null ? other.identity == null : this.identity.equals(other.identity)) && (this.identity == null ? other.identity == null : this.identity.equals(other.identity)) &&
(this.replying == null ? other.replying == null : this.replying.equals(other.replying)) &&
(this.forwarding == null ? other.forwarding == null : this.forwarding.equals(other.forwarding)) &&
(this.uid == null ? other.uid == null : this.uid.equals(other.uid)) && (this.uid == null ? other.uid == null : this.uid.equals(other.uid)) &&
(this.msgid == null ? other.msgid == null : this.msgid.equals(other.msgid)) && (this.msgid == null ? other.msgid == null : this.msgid.equals(other.msgid)) &&
(this.references == null ? other.references == null : this.references.equals(other.references)) && (this.references == null ? other.references == null : this.references.equals(other.references)) &&

@ -174,10 +174,6 @@ public class EntityOperation {
message.uid = uid; message.uid = uid;
message.folder = source.id; message.folder = source.id;
// Track reference
db.message().updateMessageReplying(id, newid);
db.message().updateMessageForwarding(id, newid);
if (message.content) if (message.content)
try { try {
Helper.copy( Helper.copy(

@ -207,15 +207,16 @@ public class EntityRule {
reply.folder = db.folder().getOutbox().id; reply.folder = db.folder().getOutbox().id;
reply.identity = identity.id; reply.identity = identity.id;
reply.msgid = EntityMessage.generateMessageId(); reply.msgid = EntityMessage.generateMessageId();
reply.references = (message.references == null ? "" : message.references + " ") + message.msgid;
reply.inreplyto = message.msgid;
reply.thread = message.thread; reply.thread = message.thread;
reply.replying = message.id;
reply.to = (message.reply == null || message.reply.length == 0 ? message.from : message.reply); reply.to = (message.reply == null || message.reply.length == 0 ? message.from : message.reply);
reply.from = new InternetAddress[]{new InternetAddress(identity.email, identity.name)}; reply.from = new InternetAddress[]{new InternetAddress(identity.email, identity.name)};
reply.subject = context.getString(R.string.title_subject_reply, message.subject == null ? "" : message.subject); reply.subject = context.getString(R.string.title_subject_reply, message.subject == null ? "" : message.subject);
reply.sender = MessageHelper.getSortKey(reply.from); reply.sender = MessageHelper.getSortKey(reply.from);
reply.received = new Date().getTime(); reply.received = new Date().getTime();
reply.id = db.message().insertMessage(reply); reply.id = db.message().insertMessage(reply);
reply.write(context, body); Helper.writeText(EntityMessage.getFile(context, reply.id), body);
db.message().setMessageContent(reply.id, true, HtmlHelper.getPreview(body)); db.message().setMessageContent(reply.id, true, HtmlHelper.getPreview(body));
EntityOperation.queue(context, db, reply, EntityOperation.SEND); EntityOperation.queue(context, db, reply, EntityOperation.SEND);

@ -1474,10 +1474,10 @@ public class FragmentCompose extends FragmentBase {
if (answer > 0) if (answer > 0)
body = EntityAnswer.getAnswerText(db, answer, null) + body; body = EntityAnswer.getAnswerText(db, answer, null) + body;
} else { } else {
result.draft.thread = ref.thread;
if ("reply".equals(action) || "reply_all".equals(action)) { if ("reply".equals(action) || "reply_all".equals(action)) {
result.draft.replying = ref.id; result.draft.references = (ref.references == null ? "" : ref.references + " ") + ref.msgid;
result.draft.inreplyto = ref.msgid;
result.draft.thread = ref.thread;
result.draft.to = (ref.reply == null || ref.reply.length == 0 ? ref.from : ref.reply); result.draft.to = (ref.reply == null || ref.reply.length == 0 ? ref.from : ref.reply);
result.draft.from = ref.to; result.draft.from = ref.to;
@ -1499,7 +1499,7 @@ public class FragmentCompose extends FragmentBase {
} }
} else if ("forward".equals(action)) { } else if ("forward".equals(action)) {
result.draft.forwarding = ref.id; result.draft.thread = result.draft.msgid; // new thread
result.draft.from = ref.to; result.draft.from = ref.to;
} }
@ -1553,10 +1553,19 @@ public class FragmentCompose extends FragmentBase {
result.draft.received = new Date().getTime(); result.draft.received = new Date().getTime();
result.draft.id = db.message().insertMessage(result.draft); result.draft.id = db.message().insertMessage(result.draft);
result.draft.write(context, body == null ? "" : body); Helper.writeText(EntityMessage.getFile(context, result.draft.id), body);
db.message().setMessageContent(result.draft.id, true, HtmlHelper.getPreview(body)); db.message().setMessageContent(result.draft.id, true, HtmlHelper.getPreview(body));
// Write reference text
if (ref != null && ref.content) {
String refBody = String.format("<p>%s %s:</p>\n<blockquote>%s</blockquote>",
Html.escapeHtml(new Date(ref.received).toString()),
Html.escapeHtml(MessageHelper.formatAddresses(ref.from)),
Helper.readText(EntityMessage.getFile(context, ref.id)));
Helper.writeText(EntityMessage.getRefFile(context, result.draft.id), refBody);
}
if ("new".equals(action)) { if ("new".equals(action)) {
ArrayList<Uri> uris = args.getParcelableArrayList("attachments"); ArrayList<Uri> uris = args.getParcelableArrayList("attachments");
if (uris != null) if (uris != null)
@ -1841,7 +1850,7 @@ public class FragmentCompose extends FragmentBase {
!MessageHelper.equal(draft.bcc, abcc) || !MessageHelper.equal(draft.bcc, abcc) ||
(draft.subject == null ? subject != null : !draft.subject.equals(subject)) || (draft.subject == null ? subject != null : !draft.subject.equals(subject)) ||
last_available != available || last_available != available ||
!body.equals(draft.read(context))); !body.equals(Helper.readText(EntityMessage.getFile(context, draft.id))));
last_available = available; last_available = available;
@ -1857,7 +1866,7 @@ public class FragmentCompose extends FragmentBase {
draft.subject = subject; draft.subject = subject;
draft.received = new Date().getTime(); draft.received = new Date().getTime();
db.message().updateMessage(draft); db.message().updateMessage(draft);
draft.write(context, body); Helper.writeText(EntityMessage.getFile(context, draft.id), body);
db.message().setMessageContent(draft.id, true, HtmlHelper.getPreview(body)); db.message().setMessageContent(draft.id, true, HtmlHelper.getPreview(body));
} }
@ -1908,13 +1917,19 @@ public class FragmentCompose extends FragmentBase {
// Delete draft (cannot move to outbox) // Delete draft (cannot move to outbox)
EntityOperation.queue(context, db, draft, EntityOperation.DELETE); EntityOperation.queue(context, db, draft, EntityOperation.DELETE);
File refDraftFile = EntityMessage.getRefFile(context, draft.id);
// Copy message to outbox // Copy message to outbox
draft.id = null; draft.id = null;
draft.folder = db.folder().getOutbox().id; draft.folder = db.folder().getOutbox().id;
draft.uid = null; draft.uid = null;
draft.ui_hide = false; draft.ui_hide = false;
draft.id = db.message().insertMessage(draft); draft.id = db.message().insertMessage(draft);
draft.write(getContext(), body); Helper.writeText(EntityMessage.getFile(context, draft.id), body);
if (refDraftFile.exists()) {
File refFile = EntityMessage.getRefFile(context, draft.id);
refDraftFile.renameTo(refFile);
}
// Move attachments // Move attachments
for (EntityAttachment attachment : attachments) for (EntityAttachment attachment : attachments)
@ -2044,10 +2059,6 @@ public class FragmentCompose extends FragmentBase {
private void showDraft(EntityMessage draft) { private void showDraft(EntityMessage draft) {
Bundle args = new Bundle(); Bundle args = new Bundle();
args.putLong("id", draft.id); args.putLong("id", draft.id);
if (draft.replying != null)
args.putLong("reference", draft.replying);
else if (draft.forwarding != null)
args.putLong("reference", draft.forwarding);
args.putBoolean("show_images", show_images); args.putBoolean("show_images", show_images);
new SimpleTask<Spanned[]>() { new SimpleTask<Spanned[]>() {
@ -2066,21 +2077,21 @@ public class FragmentCompose extends FragmentBase {
@Override @Override
protected Spanned[] onExecute(final Context context, Bundle args) throws Throwable { protected Spanned[] onExecute(final Context context, Bundle args) throws Throwable {
long id = args.getLong("id"); final long id = args.getLong("id");
final long reference = args.getLong("reference", -1);
final boolean show_images = args.getBoolean("show_images", false); final boolean show_images = args.getBoolean("show_images", false);
String body = EntityMessage.read(context, id); String body = Helper.readText(EntityMessage.getFile(context, id));
Spanned spannedBody = Html.fromHtml(body, cidGetter, null); Spanned spannedBody = Html.fromHtml(body, cidGetter, null);
String quote = (reference < 0 ? null : HtmlHelper.getQuote(context, reference, true));
Spanned spannedReference = null; Spanned spannedReference = null;
if (quote != null) { File refFile = EntityMessage.getRefFile(context, id);
if (refFile.exists()) {
String quote = Helper.readText(refFile);
Spanned spannedQuote = Html.fromHtml(quote, Spanned spannedQuote = Html.fromHtml(quote,
new Html.ImageGetter() { new Html.ImageGetter() {
@Override @Override
public Drawable getDrawable(String source) { public Drawable getDrawable(String source) {
Drawable image = HtmlHelper.decodeImage(source, context, reference, show_images); Drawable image = HtmlHelper.decodeImage(source, context, id, show_images);
float width = context.getResources().getDisplayMetrics().widthPixels - float width = context.getResources().getDisplayMetrics().widthPixels -
Helper.dp2pixels(context, 12); // margins; Helper.dp2pixels(context, 12); // margins;

@ -141,7 +141,7 @@ public class FragmentWebView extends FragmentBase {
protected String onExecute(Context context, Bundle args) throws Throwable { protected String onExecute(Context context, Bundle args) throws Throwable {
long id = args.getLong("id"); long id = args.getLong("id");
String html = EntityMessage.read(context, id); String html = Helper.readText(EntityMessage.getFile(context, id));
Document doc = Jsoup.parse(html); Document doc = Jsoup.parse(html);
for (Element img : doc.select("img")) for (Element img : doc.select("img"))

@ -57,9 +57,12 @@ import com.sun.mail.imap.IMAPStore;
import java.io.BufferedInputStream; import java.io.BufferedInputStream;
import java.io.BufferedOutputStream; import java.io.BufferedOutputStream;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
@ -328,7 +331,7 @@ public class Helper {
draft.subject = context.getString(R.string.app_name) + " " + BuildConfig.VERSION_NAME + " debug info"; draft.subject = context.getString(R.string.app_name) + " " + BuildConfig.VERSION_NAME + " debug info";
draft.received = new Date().getTime(); draft.received = new Date().getTime();
draft.id = db.message().insertMessage(draft); draft.id = db.message().insertMessage(draft);
draft.write(context, body); writeText(EntityMessage.getFile(context, draft.id), body);
db.message().setMessageContent(draft.id, true, HtmlHelper.getPreview(body)); db.message().setMessageContent(draft.id, true, HtmlHelper.getPreview(body));
attachSettings(context, draft.id, 1); attachSettings(context, draft.id, 1);
@ -600,6 +603,34 @@ public class Helper {
return TextUtils.join("@", a); return TextUtils.join("@", a);
} }
static void writeText(File file, String content) throws IOException {
BufferedWriter out = null;
try {
out = new BufferedWriter(new FileWriter(file));
out.write(content == null ? "" : content);
} finally {
if (out != null)
out.close();
}
}
static String readText(File file) throws IOException {
BufferedReader in = null;
try {
in = new BufferedReader(new FileReader(file));
StringBuilder body = new StringBuilder();
String line;
while ((line = in.readLine()) != null) {
body.append(line);
body.append('\n');
}
return body.toString();
} finally {
if (in != null)
in.close();
}
}
static void copy(File src, File dst) throws IOException { static void copy(File src, File dst) throws IOException {
InputStream in = new BufferedInputStream(new FileInputStream(src)); InputStream in = new BufferedInputStream(new FileInputStream(src));
try { try {

@ -24,7 +24,6 @@ import android.graphics.Bitmap;
import android.graphics.BitmapFactory; import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.text.Html;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Base64; import android.util.Base64;
@ -47,7 +46,6 @@ import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.net.URL; import java.net.URL;
import java.util.Arrays; import java.util.Arrays;
import java.util.Date;
import java.util.List; import java.util.List;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@ -246,17 +244,6 @@ public class HtmlHelper {
} }
} }
static String getQuote(Context context, long id, boolean sanitize) throws IOException {
EntityMessage message = DB.getInstance(context).message().getMessage(id);
if (message == null)
return null;
String html = EntityMessage.read(context, id);
return String.format("<p>%s %s:</p>\n<blockquote>%s</blockquote>",
Html.escapeHtml(new Date(message.received).toString()),
Html.escapeHtml(MessageHelper.formatAddresses(message.from)),
sanitize ? sanitize(html, true) : getBody(html));
}
static String getPreview(String body) { static String getPreview(String body) {
String text = (body == null ? null : Jsoup.parse(body).text()); String text = (body == null ? null : Jsoup.parse(body).text());
return (text == null ? null : text.substring(0, Math.min(text.length(), PREVIEW_SIZE))); return (text == null ? null : text.substring(0, Math.min(text.length(), PREVIEW_SIZE)));

@ -36,7 +36,6 @@ public class JobDaily extends JobService {
private ExecutorService executor = Executors.newSingleThreadExecutor(Helper.backgroundThreadFactory); private ExecutorService executor = Executors.newSingleThreadExecutor(Helper.backgroundThreadFactory);
private static final long CLEANUP_INTERVAL = 4 * 3600 * 1000L; // milliseconds private static final long CLEANUP_INTERVAL = 4 * 3600 * 1000L; // milliseconds
private static final long FILE_DELETE_THRESHOLD = 30 * 60 * 1000L; // milliseconds
private static final long CACHE_IMAGE_DURATION = 3 * 24 * 3600 * 1000L; // milliseconds private static final long CACHE_IMAGE_DURATION = 3 * 24 * 3600 * 1000L; // milliseconds
private static final long KEEP_LOG_DURATION = 24 * 3600 * 1000L; // milliseconds private static final long KEEP_LOG_DURATION = 24 * 3600 * 1000L; // milliseconds
@ -102,8 +101,20 @@ public class JobDaily extends JobService {
Log.i("Cleanup message files"); Log.i("Cleanup message files");
File[] messages = new File(context.getFilesDir(), "messages").listFiles(); File[] messages = new File(context.getFilesDir(), "messages").listFiles();
if (messages != null) if (messages != null)
for (File file : messages) for (File file : messages) {
if (file.isFile() && (now - file.lastModified()) > FILE_DELETE_THRESHOLD) { long id = Long.parseLong(file.getName());
if (db.message().countMessage(id) == 0) {
Log.i("Cleanup message id=" + id);
if (!file.delete())
Log.w("Error deleting " + file);
}
}
// Cleanup message files
Log.i("Cleanup reference files");
File[] references = new File(context.getFilesDir(), "references").listFiles();
if (references != null)
for (File file : references) {
long id = Long.parseLong(file.getName()); long id = Long.parseLong(file.getName());
if (db.message().countMessage(id) == 0) { if (db.message().countMessage(id) == 0) {
Log.i("Cleanup message id=" + id); Log.i("Cleanup message id=" + id);
@ -116,8 +127,7 @@ public class JobDaily extends JobService {
Log.i("Cleanup attachment files"); Log.i("Cleanup attachment files");
File[] attachments = new File(context.getFilesDir(), "attachments").listFiles(); File[] attachments = new File(context.getFilesDir(), "attachments").listFiles();
if (attachments != null) if (attachments != null)
for (File file : attachments) for (File file : attachments) {
if (file.isFile() && (now - file.lastModified()) > FILE_DELETE_THRESHOLD) {
long id = Long.parseLong(file.getName()); long id = Long.parseLong(file.getName());
if (db.attachment().countAttachment(id) == 0) { if (db.attachment().countAttachment(id) == 0) {
Log.i("Cleanup attachment id=" + id); Log.i("Cleanup attachment id=" + id);

@ -196,14 +196,10 @@ public class MessageHelper {
DB db = DB.getInstance(context); DB db = DB.getInstance(context);
MimeMessageEx imessage = new MimeMessageEx(isession, message.msgid); MimeMessageEx imessage = new MimeMessageEx(isession, message.msgid);
EntityMessage replying = null; if (message.references != null)
if (message.replying != null) imessage.addHeader("References", message.references);
replying = db.message().getMessage(message.replying); if (message.inreplyto != null)
imessage.addHeader("In-Reply-To", message.inreplyto);
if (replying != null) {
imessage.addHeader("In-Reply-To", replying.msgid);
imessage.addHeader("References", (replying.references == null ? "" : replying.references + " ") + replying.msgid);
}
imessage.addHeader("X-FairEmail-ID", message.msgid); imessage.addHeader("X-FairEmail-ID", message.msgid);
imessage.addHeader("X-FairEmail-Thread", message.thread); imessage.addHeader("X-FairEmail-Thread", message.thread);
@ -300,13 +296,8 @@ public class MessageHelper {
static void build(Context context, EntityMessage message, MimeMessage imessage) throws IOException, MessagingException { static void build(Context context, EntityMessage message, MimeMessage imessage) throws IOException, MessagingException {
DB db = DB.getInstance(context); DB db = DB.getInstance(context);
String html = message.read(context);
if (message.replying != null || message.forwarding != null)
html += HtmlHelper.getQuote(context,
message.replying == null ? message.forwarding : message.replying, false);
StringBuilder body = new StringBuilder(); StringBuilder body = new StringBuilder();
body.append(html); body.append(Helper.readText(EntityMessage.getFile(context, message.id)));
if (Helper.isPro(context) && message.identity != null) { if (Helper.isPro(context) && message.identity != null) {
EntityIdentity identity = db.identity().getIdentity(message.identity); EntityIdentity identity = db.identity().getIdentity(message.identity);
@ -314,6 +305,10 @@ public class MessageHelper {
body.append(identity.signature); body.append(identity.signature);
} }
File refFile = EntityMessage.getRefFile(context, message.id);
if (refFile.exists())
body.append(Helper.readText(refFile));
String plainContent = HtmlHelper.getText(body.toString()); String plainContent = HtmlHelper.getText(body.toString());
StringBuilder htmlContent = new StringBuilder(); StringBuilder htmlContent = new StringBuilder();
@ -338,7 +333,7 @@ public class MessageHelper {
alternativePart.addBodyPart(htmlPart); alternativePart.addBodyPart(htmlPart);
List<String> cids = new ArrayList<>(); List<String> cids = new ArrayList<>();
for (Element element : Jsoup.parse(html).select("img")) { for (Element element : Jsoup.parse(body.toString()).select("img")) {
String src = element.attr("src"); String src = element.attr("src");
if (src.startsWith("cid:")) if (src.startsWith("cid:"))
cids.add("<" + src.substring(4) + ">"); cids.add("<" + src.substring(4) + ">");

@ -668,7 +668,7 @@ public class ServiceSynchronize extends LifecycleService {
if (message.content) if (message.content)
try { try {
String body = message.read(this); String body = Helper.readText(EntityMessage.getFile(this, message.id));
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
if (!TextUtils.isEmpty(message.subject)) if (!TextUtils.isEmpty(message.subject))
sb.append(message.subject).append("<br>"); sb.append(message.subject).append("<br>");
@ -1793,10 +1793,10 @@ public class ServiceSynchronize extends LifecycleService {
Long sid = null; Long sid = null;
try { try {
// Append replied/forwarded text // Append replied/forwarded text
String body = message.read(this); String body = Helper.readText(EntityMessage.getFile(this, message.id));
if (message.replying != null || message.forwarding != null) File refFile = EntityMessage.getRefFile(this, message.id);
body += HtmlHelper.getQuote(this, if (refFile.exists())
message.replying == null ? message.forwarding : message.replying, false); body += Helper.readText(refFile);
EntityFolder sent = db.folder().getFolderByType(ident.account, EntityFolder.SENT); EntityFolder sent = db.folder().getFolderByType(ident.account, EntityFolder.SENT);
if (sent != null) { if (sent != null) {
@ -1811,7 +1811,7 @@ public class ServiceSynchronize extends LifecycleService {
message.ui_browsed = true; // prevent deleting on sync message.ui_browsed = true; // prevent deleting on sync
message.error = null; message.error = null;
message.id = db.message().insertMessage(message); message.id = db.message().insertMessage(message);
message.write(this, body); Helper.writeText(EntityMessage.getFile(this, message.id), body);
sid = message.id; sid = message.id;
message.id = id; message.id = id;
@ -1835,7 +1835,7 @@ public class ServiceSynchronize extends LifecycleService {
db.message().setMessageSeen(message.id, true); db.message().setMessageSeen(message.id, true);
db.message().setMessageUiSeen(message.id, true); db.message().setMessageUiSeen(message.id, true);
db.message().setMessageError(message.id, null); db.message().setMessageError(message.id, null);
message.write(this, body); Helper.writeText(EntityMessage.getFile(this, message.id), body);
} else { } else {
db.message().setMessageSent(sid, imessage.getSentDate().getTime()); db.message().setMessageSent(sid, imessage.getSentDate().getTime());
db.message().setMessageUiHide(sid, false); db.message().setMessageUiHide(sid, false);
@ -1853,9 +1853,14 @@ public class ServiceSynchronize extends LifecycleService {
db.endTransaction(); db.endTransaction();
} }
if (message.replying != null) { if (refFile.exists())
EntityMessage replying = db.message().getMessage(message.replying); refFile.delete();
EntityOperation.queue(this, db, replying, EntityOperation.ANSWERED, true);
if (message.inreplyto != null) {
List<EntityMessage> replieds = db.message().getMessageByMsgId(message.account, message.inreplyto);
for (EntityMessage replied : replieds)
if (replied.uid != null)
EntityOperation.queue(this, db, replied, EntityOperation.ANSWERED, true);
} }
db.identity().setIdentityError(ident.id, null); db.identity().setIdentityError(ident.id, null);
@ -1967,7 +1972,7 @@ public class ServiceSynchronize extends LifecycleService {
MessageHelper.MessageParts parts = helper.getMessageParts(); MessageHelper.MessageParts parts = helper.getMessageParts();
String body = parts.getHtml(this); String body = parts.getHtml(this);
String preview = HtmlHelper.getPreview(body); String preview = HtmlHelper.getPreview(body);
message.write(this, body); Helper.writeText(EntityMessage.getFile(this, message.id), body);
db.message().setMessageContent(message.id, true, preview); db.message().setMessageContent(message.id, true, preview);
db.message().setMessageWarning(message.id, parts.getWarnings(message.warning)); db.message().setMessageWarning(message.id, parts.getWarnings(message.warning));
} }
@ -2677,7 +2682,7 @@ public class ServiceSynchronize extends LifecycleService {
if (!message.content) { if (!message.content) {
if (!metered || (message.size != null && message.size < maxSize)) { if (!metered || (message.size != null && message.size < maxSize)) {
String body = parts.getHtml(context); String body = parts.getHtml(context);
message.write(context, body); Helper.writeText(EntityMessage.getFile(context, message.id), body);
db.message().setMessageContent(message.id, true, HtmlHelper.getPreview(body)); db.message().setMessageContent(message.id, true, HtmlHelper.getPreview(body));
db.message().setMessageWarning(message.id, parts.getWarnings(message.warning)); db.message().setMessageWarning(message.id, parts.getWarnings(message.warning));
Log.i(folder.name + " downloaded message id=" + message.id + " size=" + message.size); Log.i(folder.name + " downloaded message id=" + message.id + " size=" + message.size);

@ -117,7 +117,7 @@ public class ViewModelBrowse extends ViewModel {
String body = null; String body = null;
if (message.content) if (message.content)
try { try {
body = message.read(state.context); body = Helper.readText(EntityMessage.getFile(state.context, message.id));
} catch (IOException ex) { } catch (IOException ex) {
Log.e(ex); Log.e(ex);
} }

Loading…
Cancel
Save