Added answer rule option resend

pull/207/head
M66B 4 years ago
parent ff6b18be51
commit bfc9b0cee8

@ -168,10 +168,11 @@ public class AdapterRule extends RecyclerView.Adapter<AdapterRule.ViewHolder> {
JSONObject jaction = new JSONObject(rule.action); JSONObject jaction = new JSONObject(rule.action);
String to = null; String to = null;
boolean resend = false;
int type = jaction.getInt("type"); int type = jaction.getInt("type");
if (type == EntityRule.TYPE_SNOOZE) { if (type == EntityRule.TYPE_SNOOZE) {
int duration = jaction.optInt("duration", 0); int duration = jaction.optInt("duration", 0);
setAction(type, Integer.toString(duration)); setAction(getAction(type), Integer.toString(duration));
} else if (type == EntityRule.TYPE_IMPORTANCE) { } else if (type == EntityRule.TYPE_IMPORTANCE) {
int importance = jaction.optInt("value"); int importance = jaction.optInt("value");
@ -183,15 +184,17 @@ public class AdapterRule extends RecyclerView.Adapter<AdapterRule.ViewHolder> {
else if (importance == EntityMessage.PRIORITIY_HIGH) else if (importance == EntityMessage.PRIORITIY_HIGH)
value = context.getString(R.string.title_importance_high); value = context.getString(R.string.title_importance_high);
setAction(type, value); setAction(getAction(type), value);
} else if (type == EntityRule.TYPE_KEYWORD) { } else if (type == EntityRule.TYPE_KEYWORD) {
setAction(type, jaction.optString("keyword")); setAction(getAction(type), jaction.optString("keyword"));
} else if (type == EntityRule.TYPE_ANSWER) { } else if (type == EntityRule.TYPE_ANSWER) {
to = jaction.optString("to"); to = jaction.optString("to");
if (!TextUtils.isEmpty(to)) if (!TextUtils.isEmpty(to)) {
setAction(type, to); resend = jaction.optBoolean("resend");
setAction(resend ? R.string.title_rule_resend : getAction(type), to);
}
} else } else
setAction(type, null); setAction(getAction(type), null);
if (type == EntityRule.TYPE_MOVE || type == EntityRule.TYPE_COPY || if (type == EntityRule.TYPE_MOVE || type == EntityRule.TYPE_COPY ||
(type == EntityRule.TYPE_ANSWER && TextUtils.isEmpty(to))) { (type == EntityRule.TYPE_ANSWER && TextUtils.isEmpty(to))) {
@ -228,7 +231,7 @@ public class AdapterRule extends RecyclerView.Adapter<AdapterRule.ViewHolder> {
if (id != AdapterRule.this.getItemId(pos)) if (id != AdapterRule.this.getItemId(pos))
return; return;
setAction(args.getInt("type"), value); setAction(getAction(args.getInt("type")), value);
} }
@Override @Override
@ -453,74 +456,58 @@ public class AdapterRule extends RecyclerView.Adapter<AdapterRule.ViewHolder> {
return true; return true;
} }
private void setAction(int type, String value) { private void setAction(int resid, String value) {
int resid; if (TextUtils.isEmpty(value))
tvAction.setText(resid);
else {
SpannableStringBuilder ssb = new SpannableStringBuilderEx();
ssb.append(context.getString(resid));
ssb.append(" \"");
int start = ssb.length();
ssb.append(value);
ssb.setSpan(new StyleSpan(Typeface.ITALIC), start, ssb.length(), 0);
ssb.append("\"");
tvAction.setText(ssb);
}
}
private int getAction(int type) {
switch (type) { switch (type) {
case EntityRule.TYPE_NOOP: case EntityRule.TYPE_NOOP:
resid = R.string.title_rule_noop; return R.string.title_rule_noop;
break;
case EntityRule.TYPE_SEEN: case EntityRule.TYPE_SEEN:
resid = R.string.title_rule_seen; return R.string.title_rule_seen;
break;
case EntityRule.TYPE_UNSEEN: case EntityRule.TYPE_UNSEEN:
resid = R.string.title_rule_unseen; return R.string.title_rule_unseen;
break;
case EntityRule.TYPE_HIDE: case EntityRule.TYPE_HIDE:
resid = R.string.title_rule_hide; return R.string.title_rule_hide;
break;
case EntityRule.TYPE_IGNORE: case EntityRule.TYPE_IGNORE:
resid = R.string.title_rule_ignore; return R.string.title_rule_ignore;
break;
case EntityRule.TYPE_SNOOZE: case EntityRule.TYPE_SNOOZE:
resid = R.string.title_rule_snooze; return R.string.title_rule_snooze;
break;
case EntityRule.TYPE_FLAG: case EntityRule.TYPE_FLAG:
resid = R.string.title_rule_flag; return R.string.title_rule_flag;
break;
case EntityRule.TYPE_IMPORTANCE: case EntityRule.TYPE_IMPORTANCE:
resid = R.string.title_rule_importance; return R.string.title_rule_importance;
break;
case EntityRule.TYPE_KEYWORD: case EntityRule.TYPE_KEYWORD:
resid = R.string.title_rule_keyword; return R.string.title_rule_keyword;
break;
case EntityRule.TYPE_MOVE: case EntityRule.TYPE_MOVE:
resid = R.string.title_rule_move; return R.string.title_rule_move;
break;
case EntityRule.TYPE_COPY: case EntityRule.TYPE_COPY:
resid = R.string.title_rule_copy; return R.string.title_rule_copy;
break;
case EntityRule.TYPE_ANSWER: case EntityRule.TYPE_ANSWER:
resid = R.string.title_rule_answer; return R.string.title_rule_answer;
break;
case EntityRule.TYPE_TTS: case EntityRule.TYPE_TTS:
resid = R.string.title_rule_tts; return R.string.title_rule_tts;
break;
case EntityRule.TYPE_AUTOMATION: case EntityRule.TYPE_AUTOMATION:
resid = R.string.title_rule_automation; return R.string.title_rule_automation;
break;
case EntityRule.TYPE_DELETE: case EntityRule.TYPE_DELETE:
resid = R.string.title_rule_delete; return R.string.title_rule_delete;
break;
case EntityRule.TYPE_SOUND: case EntityRule.TYPE_SOUND:
resid = R.string.title_rule_sound; return R.string.title_rule_sound;
break;
default: default:
throw new IllegalArgumentException("Unknown action type=" + type); throw new IllegalArgumentException("Unknown action type=" + type);
} }
if (TextUtils.isEmpty(value))
tvAction.setText(resid);
else {
SpannableStringBuilder ssb = new SpannableStringBuilderEx();
ssb.append(context.getString(resid));
ssb.append(" \"");
int start = ssb.length();
ssb.append(value);
ssb.setSpan(new StyleSpan(Typeface.ITALIC), start, ssb.length(), 0);
ssb.append("\"");
tvAction.setText(ssb);
}
} }
} }

@ -638,6 +638,7 @@ public class EntityRule {
private boolean onActionAnswer(Context context, EntityMessage message, JSONObject jargs) { private boolean onActionAnswer(Context context, EntityMessage message, JSONObject jargs) {
DB db = DB.getInstance(context); DB db = DB.getInstance(context);
String to = jargs.optString("to"); String to = jargs.optString("to");
boolean resend = jargs.optBoolean("resend");
boolean attachments = jargs.optBoolean("attachments"); boolean attachments = jargs.optBoolean("attachments");
if (TextUtils.isEmpty(to) && if (TextUtils.isEmpty(to) &&
@ -661,6 +662,11 @@ public class EntityRule {
EntityOperation.queue(context, message, EntityOperation.ATTACHMENT, attachment.id); EntityOperation.queue(context, message, EntityOperation.ATTACHMENT, attachment.id);
} }
if (resend && message.headers == null) {
complete = false;
EntityOperation.queue(context, message, EntityOperation.HEADERS);
}
if (!complete) { if (!complete) {
EntityOperation.queue(context, message, EntityOperation.RULE, this.id); EntityOperation.queue(context, message, EntityOperation.RULE, this.id);
return false; return false;
@ -692,6 +698,7 @@ public class EntityRule {
boolean original_text = jargs.optBoolean("original_text", true); boolean original_text = jargs.optBoolean("original_text", true);
boolean attachments = jargs.optBoolean("attachments"); boolean attachments = jargs.optBoolean("attachments");
String to = jargs.optString("to"); String to = jargs.optString("to");
boolean resend = jargs.optBoolean("resend");
boolean cc = jargs.optBoolean("cc"); boolean cc = jargs.optBoolean("cc");
boolean isReply = TextUtils.isEmpty(to); boolean isReply = TextUtils.isEmpty(to);
@ -707,7 +714,7 @@ public class EntityRule {
throw new IllegalArgumentException("Rule identity not found name=" + rule.name); throw new IllegalArgumentException("Rule identity not found name=" + rule.name);
EntityAnswer answer; EntityAnswer answer;
if (aid < 0) { if (aid < 0 || resend) {
if (isReply) if (isReply)
throw new IllegalArgumentException("Rule template missing name=" + rule.name); throw new IllegalArgumentException("Rule template missing name=" + rule.name);
@ -753,7 +760,11 @@ public class EntityRule {
reply.thread = message.thread; reply.thread = message.thread;
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);
} else { } else {
reply.wasforwardedfrom = message.msgid; if (resend) {
reply.resend = true;
reply.headers = message.headers;
} else
reply.wasforwardedfrom = message.msgid;
reply.thread = reply.msgid; // new thread reply.thread = reply.msgid; // new thread
reply.to = MessageHelper.parseAddresses(context, to); reply.to = MessageHelper.parseAddresses(context, to);
} }
@ -761,12 +772,16 @@ public class EntityRule {
reply.from = from; reply.from = from;
if (cc) if (cc)
reply.cc = message.cc; reply.cc = message.cc;
reply.unsubscribe = "mailto:" + identity.email; if (isReply)
reply.unsubscribe = "mailto:" + identity.email;
reply.auto_submitted = true; reply.auto_submitted = true;
reply.subject = EntityMessage.getSubject(context, if (resend)
message.language, reply.subject = message.subject;
answer_subject ? answer.name : message.subject, else
!isReply); reply.subject = EntityMessage.getSubject(context,
message.language,
answer_subject ? answer.name : message.subject,
!isReply);
reply.received = new Date().getTime(); reply.received = new Date().getTime();
reply.sender = MessageHelper.getSortKey(reply.from); reply.sender = MessageHelper.getSortKey(reply.from);
@ -775,29 +790,34 @@ public class EntityRule {
reply.id = db.message().insertMessage(reply); reply.id = db.message().insertMessage(reply);
String body = answer.getHtml(message.from); String body;
if (resend)
body = Helper.readText(message.getFile(context));
else {
body = answer.getHtml(message.from);
if (original_text) { if (original_text) {
Document msg = JsoupEx.parse(body); Document msg = JsoupEx.parse(body);
Element div = msg.createElement("div"); Element div = msg.createElement("div");
Element p = message.getReplyHeader(context, msg, separate_reply, extended_reply); Element p = message.getReplyHeader(context, msg, separate_reply, extended_reply);
div.appendChild(p); div.appendChild(p);
Document answering = JsoupEx.parse(message.getFile(context)); Document answering = JsoupEx.parse(message.getFile(context));
Element e = answering.body(); Element e = answering.body();
if (quote) { if (quote) {
String style = e.attr("style"); String style = e.attr("style");
style = HtmlHelper.mergeStyles(style, HtmlHelper.getQuoteStyle(e)); style = HtmlHelper.mergeStyles(style, HtmlHelper.getQuoteStyle(e));
e.tagName("blockquote").attr("style", style); e.tagName("blockquote").attr("style", style);
} else } else
e.tagName("p"); e.tagName("p");
div.appendChild(e); div.appendChild(e);
msg.body().appendChild(div); msg.body().appendChild(div);
body = msg.outerHtml(); body = msg.outerHtml();
}
} }
File file = reply.getFile(context); File file = reply.getFile(context);
@ -812,7 +832,7 @@ public class EntityRule {
reply.preview, reply.preview,
null); null);
if (attachments) if (attachments || resend)
EntityAttachment.copy(context, message.id, reply.id); EntityAttachment.copy(context, message.id, reply.id);
EntityOperation.queue(context, reply, EntityOperation.SEND); EntityOperation.queue(context, reply, EntityOperation.SEND);

@ -32,7 +32,9 @@ import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.provider.ContactsContract; import android.provider.ContactsContract;
import android.speech.tts.TextToSpeech; import android.speech.tts.TextToSpeech;
import android.text.Editable;
import android.text.TextUtils; import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Menu; import android.view.Menu;
import android.view.MenuInflater; import android.view.MenuInflater;
@ -145,6 +147,7 @@ public class FragmentRule extends FragmentBase {
private CheckBox cbWithAttachments; private CheckBox cbWithAttachments;
private EditText etTo; private EditText etTo;
private ImageButton ibTo; private ImageButton ibTo;
private CheckBox cbResend;
private CheckBox cbCc; private CheckBox cbCc;
private Button btnTtsSetup; private Button btnTtsSetup;
@ -297,6 +300,7 @@ public class FragmentRule extends FragmentBase {
cbWithAttachments = view.findViewById(R.id.cbWithAttachments); cbWithAttachments = view.findViewById(R.id.cbWithAttachments);
etTo = view.findViewById(R.id.etTo); etTo = view.findViewById(R.id.etTo);
ibTo = view.findViewById(R.id.ibTo); ibTo = view.findViewById(R.id.ibTo);
cbResend = view.findViewById(R.id.cbResend);
cbCc = view.findViewById(R.id.cbCc); cbCc = view.findViewById(R.id.cbCc);
btnTtsSetup = view.findViewById(R.id.btnTtsSetup); btnTtsSetup = view.findViewById(R.id.btnTtsSetup);
@ -617,6 +621,21 @@ public class FragmentRule extends FragmentBase {
spIdent.setOnItemSelectedListener(onItemSelectedListener); spIdent.setOnItemSelectedListener(onItemSelectedListener);
spAnswer.setOnItemSelectedListener(onItemSelectedListener); spAnswer.setOnItemSelectedListener(onItemSelectedListener);
etTo.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
cbResend.setEnabled(!TextUtils.isEmpty(s.toString()));
}
});
ibTo.setOnClickListener(new View.OnClickListener() { ibTo.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
@ -625,6 +644,17 @@ public class FragmentRule extends FragmentBase {
} }
}); });
cbResend.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
checked = (checked && compoundButton.isEnabled());
spAnswer.setEnabled(!checked);
cbAnswerSubject.setEnabled(!checked);
cbOriginalText.setEnabled(!checked);
cbWithAttachments.setEnabled(!checked);
}
});
btnTtsSetup.setOnClickListener(new View.OnClickListener() { btnTtsSetup.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View view) { public void onClick(View view) {
@ -1146,6 +1176,7 @@ public class FragmentRule extends FragmentBase {
cbWithAttachments.setChecked(jaction.optBoolean("attachments")); cbWithAttachments.setChecked(jaction.optBoolean("attachments"));
etTo.setText(jaction.optString("to")); etTo.setText(jaction.optString("to"));
cbResend.setChecked(jaction.optBoolean("resend"));
cbCc.setChecked(jaction.optBoolean("cc")); cbCc.setChecked(jaction.optBoolean("cc"));
break; break;
@ -1488,6 +1519,7 @@ public class FragmentRule extends FragmentBase {
jaction.put("original_text", cbOriginalText.isChecked()); jaction.put("original_text", cbOriginalText.isChecked());
jaction.put("attachments", cbWithAttachments.isChecked()); jaction.put("attachments", cbWithAttachments.isChecked());
jaction.put("to", etTo.getText().toString().trim()); jaction.put("to", etTo.getText().toString().trim());
jaction.put("resend", cbResend.isChecked());
jaction.put("cc", cbCc.isChecked()); jaction.put("cc", cbCc.isChecked());
break; break;

@ -902,6 +902,15 @@
app:layout_constraintTop_toTopOf="@id/etTo" app:layout_constraintTop_toTopOf="@id/etTo"
app:srcCompat="@drawable/twotone_person_add_24" /> app:srcCompat="@drawable/twotone_person_add_24" />
<CheckBox
android:id="@+id/cbResend"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:text="@string/title_rule_resend"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/etTo" />
<CheckBox <CheckBox
android:id="@+id/cbCc" android:id="@+id/cbCc"
android:layout_width="wrap_content" android:layout_width="wrap_content"
@ -909,7 +918,7 @@
android:layout_marginTop="12dp" android:layout_marginTop="12dp"
android:text="@string/title_rule_cc" android:text="@string/title_rule_cc"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/etTo" /> app:layout_constraintTop_toBottomOf="@id/cbResend" />
<eu.faircode.email.FixedTextView <eu.faircode.email.FixedTextView
android:id="@+id/tvAnswerRemark" android:id="@+id/tvAnswerRemark"
@ -1084,7 +1093,7 @@
android:id="@+id/grpAnswer" android:id="@+id/grpAnswer"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="0dp" android:layout_height="0dp"
app:constraint_referenced_ids="tvAnswerIdentity,spIdent,tvAnswerTemplate,spAnswer,cbAnswerSubject,cbOriginalText,cbWithAttachments,tvTo,etTo,ibTo,cbCc,tvAnswerRemark" /> app:constraint_referenced_ids="tvAnswerIdentity,spIdent,tvAnswerTemplate,spAnswer,cbAnswerSubject,cbOriginalText,cbWithAttachments,tvTo,etTo,ibTo,cbResend,cbCc,tvAnswerRemark" />
<androidx.constraintlayout.widget.Group <androidx.constraintlayout.widget.Group
android:id="@+id/grpTts" android:id="@+id/grpTts"

@ -1599,6 +1599,7 @@
<string name="title_rule_answer_subject">Use template name as subject</string> <string name="title_rule_answer_subject">Use template name as subject</string>
<string name="title_rule_original_text">Include original message text</string> <string name="title_rule_original_text">Include original message text</string>
<string name="title_rule_forward_to">Forward to</string> <string name="title_rule_forward_to">Forward to</string>
<string name="title_rule_resend">Resend</string>
<string name="title_rule_cc">Reply to CC addresses</string> <string name="title_rule_cc">Reply to CC addresses</string>
<string name="title_rule_with_attachments">With attachments</string> <string name="title_rule_with_attachments">With attachments</string>
<string name="title_rule_answer_remark">Only one reply will be sent for any conversation, to avoid reply loops</string> <string name="title_rule_answer_remark">Only one reply will be sent for any conversation, to avoid reply loops</string>

Loading…
Cancel
Save