Save signature, fixes

pull/168/head
M66B 5 years ago
parent 43f537f0cd
commit 29de070dec

@ -456,9 +456,6 @@ public interface DaoMessage {
@Query("UPDATE message SET error = :error WHERE id = :id")
int setMessageError(long id, String error);
@Query("UPDATE message SET signature = :signature WHERE id = :id")
int setMessageSignature(long id, boolean signature);
@Query("UPDATE message SET revision = :revision WHERE id = :id")
int setMessageRevision(long id, Integer revision);

@ -412,33 +412,7 @@ public class FragmentCompose extends FragmentBase {
cbSignature.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
Bundle args = new Bundle();
args.putLong("id", working);
args.putBoolean("signature", checked);
new SimpleTask<Integer>() {
@Override
protected Integer onExecute(Context context, Bundle args) {
long id = args.getLong("id");
boolean signature = args.getBoolean("signature");
DB db = DB.getInstance(context);
return db.message().setMessageSignature(id, signature);
}
@Override
protected void onExecuted(Bundle args, Integer count) {
if (count > 0) {
boolean signature = args.getBoolean("signature");
tvSignature.setAlpha(signature ? 1.0f : Helper.LOW_LIGHT);
}
}
@Override
protected void onException(Bundle args, Throwable ex) {
Helper.unexpectedError(getParentFragmentManager(), ex);
}
}.execute(FragmentCompose.this, args, "draft:signature");
onAction(R.id.action_save);
}
});
@ -723,15 +697,12 @@ public class FragmentCompose extends FragmentBase {
String text = HtmlHelper.getText(ref.outerHtml());
Element p = document.createElement("p");
p.html(text.replaceAll("\\r?\\n", "<br>"));
if (document.body() != null)
document.body().appendChild(p);
document.body().appendChild(p);
} else {
Document d = HtmlHelper.sanitize(context, ref.outerHtml(), true, false);
Element b = d.body();
if (document.body() != null && b != null) {
b.tagName("div");
document.body().appendChild(b);
}
b.tagName("div");
document.body().appendChild(b);
}
return document.html();
@ -1908,6 +1879,7 @@ public class FragmentCompose extends FragmentBase {
args.putString("bcc", etBcc.getText().toString().trim());
args.putString("subject", etSubject.getText().toString().trim());
args.putString("body", HtmlHelper.toHtml(etBody.getText()));
args.putBoolean("signature", cbSignature.isChecked());
args.putBoolean("empty", isEmpty());
args.putBundle("extras", extras);
@ -2144,8 +2116,6 @@ public class FragmentCompose extends FragmentBase {
EntityMessage ref = db.message().getMessage(reference);
Document document = JsoupEx.parse("");
data.draft = new EntityMessage();
data.draft.msgid = EntityMessage.generateMessageId();
@ -2156,6 +2126,100 @@ public class FragmentCompose extends FragmentBase {
if (receipt_default)
data.draft.receipt_request = true;
// Select identity matching from address
EntityIdentity selected = null;
long aid = args.getLong("account", -1);
long iid = args.getLong("identity", -1);
if (aid < 0 && ref != null)
aid = ref.account;
if (iid < 0 && ref != null && ref.identity != null)
iid = ref.identity;
if (iid >= 0)
for (EntityIdentity identity : data.identities)
if (identity.id.equals(iid)) {
Log.i("Selected requested identity=" + iid);
selected = identity;
break;
}
if (data.draft.from != null && data.draft.from.length > 0) {
if (selected == null)
for (Address sender : data.draft.from)
for (EntityIdentity identity : data.identities)
if (identity.account.equals(aid) &&
identity.sameAddress(sender)) {
selected = identity;
Log.i("Selected same account/identity");
break;
}
if (selected == null)
for (Address sender : data.draft.from)
for (EntityIdentity identity : data.identities)
if (identity.account.equals(aid) &&
identity.similarAddress(sender)) {
selected = identity;
Log.i("Selected similar account/identity");
break;
}
if (selected == null)
for (Address sender : data.draft.from)
for (EntityIdentity identity : data.identities)
if (identity.sameAddress(sender)) {
selected = identity;
Log.i("Selected same */identity");
break;
}
if (selected == null)
for (Address sender : data.draft.from)
for (EntityIdentity identity : data.identities)
if (identity.similarAddress(sender)) {
selected = identity;
Log.i("Selected similer */identity");
break;
}
}
if (selected == null)
for (EntityIdentity identity : data.identities)
if (identity.account.equals(aid) && identity.primary) {
selected = identity;
Log.i("Selected primary account/identity");
break;
}
if (selected == null)
for (EntityIdentity identity : data.identities)
if (identity.account.equals(aid)) {
selected = identity;
Log.i("Selected account/identity");
break;
}
if (selected == null)
for (EntityIdentity identity : data.identities)
if (identity.primary) {
Log.i("Selected primary */identity");
selected = identity;
break;
}
if (selected == null)
for (EntityIdentity identity : data.identities) {
Log.i("Selected */identity");
selected = identity;
break;
}
if (selected == null)
throw new IllegalArgumentException(context.getString(R.string.title_no_identities));
Document document = Document.createShell("");
if (ref == null) {
data.draft.thread = data.draft.msgid;
@ -2185,10 +2249,8 @@ public class FragmentCompose extends FragmentBase {
if (!TextUtils.isEmpty(b)) {
Document d = HtmlHelper.sanitize(context, b, false, false);
Element e = d.body();
if (e != null) {
e.tagName("div");
document.body().appendChild(e);
}
e.tagName("div");
document.body().appendChild(e);
}
if (answer > 0) {
@ -2197,12 +2259,12 @@ public class FragmentCompose extends FragmentBase {
data.draft.subject = a.name;
Document d = JsoupEx.parse(a.getText(null));
Element e = d.body();
if (e != null) {
e.tagName("div");
document.body().appendChild(e);
}
e.tagName("div");
document.body().appendChild(e);
}
}
addSignature(document, data.draft, selected);
} else {
// Actions:
// - reply
@ -2270,10 +2332,8 @@ public class FragmentCompose extends FragmentBase {
String html = Helper.readText(ref.getFile(context));
Document d = HtmlHelper.sanitize(context, html, true, false);
Element e = d.body();
if (e != null) {
e.tagName("div");
document.body().appendChild(e);
}
e.tagName("div");
document.body().appendChild(e);
}
} else if ("list".equals(action)) {
data.draft.subject = ref.subject;
@ -2306,10 +2366,8 @@ public class FragmentCompose extends FragmentBase {
if (a != null) {
Document d = JsoupEx.parse(a.getText(data.draft.to));
Element e = d.body();
if (e != null) {
e.tagName("div");
document.body().appendChild(e);
}
e.tagName("div");
document.body().appendChild(e);
}
}
@ -2381,109 +2439,17 @@ public class FragmentCompose extends FragmentBase {
// Quote referenced message body
Element e = d.body();
if (e != null) {
boolean quote_reply = prefs.getBoolean("quote_reply", true);
boolean quote = (quote_reply && ("reply".equals(action) || "reply_all".equals(action)));
boolean quote_reply = prefs.getBoolean("quote_reply", true);
boolean quote = (quote_reply && ("reply".equals(action) || "reply_all".equals(action)));
e.tagName(quote ? "blockquote" : "div");
div.appendChild(e);
}
e.tagName(quote ? "blockquote" : "div");
div.appendChild(e);
document.body().appendChild(div);
}
}
// Select identity matching from address
EntityIdentity selected = null;
long aid = args.getLong("account", -1);
long iid = args.getLong("identity", -1);
if (aid < 0 && ref != null)
aid = ref.account;
if (iid < 0 && ref != null && ref.identity != null)
iid = ref.identity;
if (iid >= 0)
for (EntityIdentity identity : data.identities)
if (identity.id.equals(iid)) {
Log.i("Selected requested identity=" + iid);
selected = identity;
break;
}
if (data.draft.from != null && data.draft.from.length > 0) {
if (selected == null)
for (Address sender : data.draft.from)
for (EntityIdentity identity : data.identities)
if (identity.account.equals(aid) &&
identity.sameAddress(sender)) {
selected = identity;
Log.i("Selected same account/identity");
break;
}
if (selected == null)
for (Address sender : data.draft.from)
for (EntityIdentity identity : data.identities)
if (identity.account.equals(aid) &&
identity.similarAddress(sender)) {
selected = identity;
Log.i("Selected similar account/identity");
break;
}
if (selected == null)
for (Address sender : data.draft.from)
for (EntityIdentity identity : data.identities)
if (identity.sameAddress(sender)) {
selected = identity;
Log.i("Selected same */identity");
break;
}
if (selected == null)
for (Address sender : data.draft.from)
for (EntityIdentity identity : data.identities)
if (identity.similarAddress(sender)) {
selected = identity;
Log.i("Selected similer */identity");
break;
}
}
if (selected == null)
for (EntityIdentity identity : data.identities)
if (identity.account.equals(aid) && identity.primary) {
selected = identity;
Log.i("Selected primary account/identity");
break;
}
if (selected == null)
for (EntityIdentity identity : data.identities)
if (identity.account.equals(aid)) {
selected = identity;
Log.i("Selected account/identity");
break;
}
if (selected == null)
for (EntityIdentity identity : data.identities)
if (identity.primary) {
Log.i("Selected primary */identity");
selected = identity;
break;
}
if (selected == null)
for (EntityIdentity identity : data.identities) {
Log.i("Selected */identity");
selected = identity;
break;
addSignature(document, data.draft, selected);
}
if (selected == null)
throw new IllegalArgumentException(context.getString(R.string.title_no_identities));
}
EntityFolder drafts = db.folder().getFolderByType(selected.account, EntityFolder.DRAFTS);
if (drafts == null)
@ -2594,6 +2560,7 @@ public class FragmentCompose extends FragmentBase {
File file = data.draft.getFile(context);
Document doc = JsoupEx.parse(Helper.readText(file));
doc.select("div[fairemail=signature]").remove();
Elements ref = doc.select("div[fairemail=reference]");
ref.remove();
@ -2604,8 +2571,14 @@ public class FragmentCompose extends FragmentBase {
}
Document document = HtmlHelper.sanitize(context, doc.html(), true, false);
if (data.draft.identity != null) {
EntityIdentity identity = db.identity().getIdentity(data.draft.identity);
addSignature(document, data.draft, identity);
}
for (Element e : ref)
document.appendChild(e);
document.body().appendChild(e);
String html = JsoupEx.parse(document.html()).html();
Helper.writeText(file, html);
@ -2808,6 +2781,7 @@ public class FragmentCompose extends FragmentBase {
String bcc = args.getString("bcc");
String subject = args.getString("subject");
String body = args.getString("body");
boolean signature = args.getBoolean("signature");
boolean empty = args.getBoolean("empty");
Bundle extras = args.getBundle("extras");
@ -2956,6 +2930,7 @@ public class FragmentCompose extends FragmentBase {
!MessageHelper.equal(draft.cc, acc) ||
!MessageHelper.equal(draft.bcc, abcc) ||
!Objects.equals(draft.subject, subject) ||
!draft.signature.equals(signature) ||
last_available != available);
last_available = available;
@ -2969,6 +2944,7 @@ public class FragmentCompose extends FragmentBase {
draft.cc = acc;
draft.bcc = abcc;
draft.subject = subject;
draft.signature = signature;
draft.sender = MessageHelper.getSortKey(draft.from);
Uri lookupUri = ContactInfo.getLookupUri(context, draft.from);
draft.avatar = (lookupUri == null ? null : lookupUri.toString());
@ -2981,6 +2957,7 @@ public class FragmentCompose extends FragmentBase {
(extras != null && extras.containsKey("html"))) {
dirty = true;
doc.select("div[fairemail=signature]").remove();
Elements ref = doc.select("div[fairemail=reference]");
ref.remove();
@ -2989,15 +2966,17 @@ public class FragmentCompose extends FragmentBase {
if (extras != null && extras.containsKey("html")) {
// Save current revision
Document c = JsoupEx.parse(body);
if (c.body() != null && ref.size() > 0)
c.body().appendChild(ref.first());
addSignature(c, draft, identity);
for (Element e : ref)
c.body().appendChild(e);
Helper.writeText(draft.getFile(context, draft.revision), c.html());
d = JsoupEx.parse(extras.getString("html"));
} else {
d = JsoupEx.parse(body);
if (d.body() != null && ref.size() > 0)
d.body().appendChild(ref.first());
addSignature(d, draft, identity);
for (Element e : ref)
d.body().appendChild(e);
}
body = d.html();
@ -3273,6 +3252,28 @@ public class FragmentCompose extends FragmentBase {
return subject;
}
private void addSignature(Document document, EntityMessage message, EntityIdentity identity) {
if (!message.signature ||
identity == null || TextUtils.isEmpty(identity.signature))
return;
Element div = document.createElement("div");
div.attr("fairemail", "signature");
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext());
boolean usenet = prefs.getBoolean("usenet_signature", false);
if (usenet) {
// https://www.ietf.org/rfc/rfc3676.txt
Element span = document.createElement("span");
span.text("-- ");
span.appendElement("br");
div.appendChild(span);
}
div.append(identity.signature);
document.body().appendChild(div);
}
private void showDraft(final EntityMessage draft) {
Bundle args = new Bundle();
args.putLong("id", draft.id);
@ -3314,6 +3315,7 @@ public class FragmentCompose extends FragmentBase {
throw new IllegalArgumentException(context.getString(R.string.title_no_body));
Document doc = JsoupEx.parse(Helper.readText(draft.getFile(context)));
doc.select("div[fairemail=signature]").remove();
Elements ref = doc.select("div[fairemail=reference]");
ref.remove();

@ -4637,63 +4637,60 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences.
Document document = JsoupEx.parse(html);
HtmlHelper.embedInlineImages(context, id, document);
Element body = document.body();
if (body != null) {
Element p = document.createElement("p");
if (message.from != null && message.from.length > 0) {
Element span = document.createElement("span");
Element strong = document.createElement("strong");
strong.text(getString(R.string.title_from));
span.appendChild(strong);
span.appendText(" " + MessageHelper.formatAddresses(message.from));
span.appendElement("br");
p.appendChild(span);
}
Element p = document.createElement("p");
if (message.from != null && message.from.length > 0) {
Element span = document.createElement("span");
Element strong = document.createElement("strong");
strong.text(getString(R.string.title_from));
span.appendChild(strong);
span.appendText(" " + MessageHelper.formatAddresses(message.from));
span.appendElement("br");
p.appendChild(span);
}
if (message.to != null && message.to.length > 0) {
Element span = document.createElement("span");
Element strong = document.createElement("strong");
strong.text(getString(R.string.title_to));
span.appendChild(strong);
span.appendText(" " + MessageHelper.formatAddresses(message.to));
span.appendElement("br");
p.appendChild(span);
}
if (message.to != null && message.to.length > 0) {
Element span = document.createElement("span");
Element strong = document.createElement("strong");
strong.text(getString(R.string.title_to));
span.appendChild(strong);
span.appendText(" " + MessageHelper.formatAddresses(message.to));
span.appendElement("br");
p.appendChild(span);
}
if (message.cc != null && message.cc.length > 0) {
Element span = document.createElement("span");
Element strong = document.createElement("strong");
strong.text(getString(R.string.title_cc));
span.appendChild(strong);
span.appendText(" " + MessageHelper.formatAddresses(message.cc));
span.appendElement("br");
p.appendChild(span);
}
if (message.cc != null && message.cc.length > 0) {
Element span = document.createElement("span");
Element strong = document.createElement("strong");
strong.text(getString(R.string.title_cc));
span.appendChild(strong);
span.appendText(" " + MessageHelper.formatAddresses(message.cc));
span.appendElement("br");
p.appendChild(span);
}
{
DateFormat DTF = Helper.getDateTimeInstance(context, SimpleDateFormat.LONG, SimpleDateFormat.LONG);
{
DateFormat DTF = Helper.getDateTimeInstance(context, SimpleDateFormat.LONG, SimpleDateFormat.LONG);
Element span = document.createElement("span");
Element strong = document.createElement("strong");
strong.text(getString(R.string.title_received));
span.appendChild(strong);
span.appendText(" " + DTF.format(message.received));
span.appendElement("br");
p.appendChild(span);
}
Element span = document.createElement("span");
Element strong = document.createElement("strong");
strong.text(getString(R.string.title_received));
span.appendChild(strong);
span.appendText(" " + DTF.format(message.received));
span.appendElement("br");
p.appendChild(span);
}
if (!TextUtils.isEmpty(message.subject)) {
Element span = document.createElement("span");
span.appendText(message.subject);
span.appendElement("br");
p.appendChild(span);
}
if (!TextUtils.isEmpty(message.subject)) {
Element span = document.createElement("span");
span.appendText(message.subject);
span.appendElement("br");
p.appendChild(span);
}
p.appendElement("hr").appendElement("br");
p.appendElement("hr").appendElement("br");
body.prependChild(p);
}
document.prependChild(p);
return new String[]{message.subject, document.html()};
}

@ -86,10 +86,10 @@ public class HtmlHelper {
} catch (Throwable ex) {
// OutOfMemoryError
Log.e(ex);
Document document = new Document("");
Document document = Document.createShell("");
Element strong = document.createElement("strong");
strong.text(Helper.formatThrowable(ex));
document.appendChild(strong);
document.body().appendChild(strong);
return document;
}
}
@ -476,6 +476,11 @@ public class HtmlHelper {
if (!TextUtils.isEmpty(span.attr("color")))
span.tagName("font");
if (document.body() == null) {
Log.e("Sanitize without body");
document.normalise();
}
return document;
}

@ -20,19 +20,14 @@ package eu.faircode.email;
*/
import android.content.Context;
import android.content.SharedPreferences;
import android.net.MailTo;
import android.net.Uri;
import android.text.TextUtils;
import androidx.preference.PreferenceManager;
import com.sun.mail.util.FolderClosedIOException;
import com.sun.mail.util.MessageRemovedIOException;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import java.io.BufferedReader;
import java.io.File;
@ -322,28 +317,10 @@ public class MessageHelper {
// Build html body
Document document = JsoupEx.parse(Helper.readText(message.getFile(context)));
Elements ref = document.select("div[fairemail=reference]");
ref.remove();
ref.removeAttr("fairemail");
if (document.body() != null) {
// When sending message
if (identity != null && !TextUtils.isEmpty(identity.signature) && message.signature) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
boolean usenet = prefs.getBoolean("usenet_signature", false);
if (usenet) {
// https://www.ietf.org/rfc/rfc3676.txt
Element span = document.createElement("span");
span.text("-- ");
span.appendElement("br");
document.body().appendChild(span);
}
document.body().append(identity.signature);
}
if (ref.size() > 0)
document.body().appendChild(ref.first());
}
// When sending message
if (identity != null)
document.select("div[fairemail=signature],div[fairemail=reference]").removeAttr("fairemail");
// multipart/mixed
// multipart/related

Loading…
Cancel
Save