Added answer rule option resend

This commit is contained in:
M66B 2022-04-04 10:56:57 +02:00
parent ff6b18be51
commit bfc9b0cee8
5 changed files with 139 additions and 90 deletions

View File

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

View File

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

View File

@ -32,7 +32,9 @@ import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.speech.tts.TextToSpeech;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
@ -145,6 +147,7 @@ public class FragmentRule extends FragmentBase {
private CheckBox cbWithAttachments;
private EditText etTo;
private ImageButton ibTo;
private CheckBox cbResend;
private CheckBox cbCc;
private Button btnTtsSetup;
@ -297,6 +300,7 @@ public class FragmentRule extends FragmentBase {
cbWithAttachments = view.findViewById(R.id.cbWithAttachments);
etTo = view.findViewById(R.id.etTo);
ibTo = view.findViewById(R.id.ibTo);
cbResend = view.findViewById(R.id.cbResend);
cbCc = view.findViewById(R.id.cbCc);
btnTtsSetup = view.findViewById(R.id.btnTtsSetup);
@ -617,6 +621,21 @@ public class FragmentRule extends FragmentBase {
spIdent.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() {
@Override
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() {
@Override
public void onClick(View view) {
@ -1146,6 +1176,7 @@ public class FragmentRule extends FragmentBase {
cbWithAttachments.setChecked(jaction.optBoolean("attachments"));
etTo.setText(jaction.optString("to"));
cbResend.setChecked(jaction.optBoolean("resend"));
cbCc.setChecked(jaction.optBoolean("cc"));
break;
@ -1488,6 +1519,7 @@ public class FragmentRule extends FragmentBase {
jaction.put("original_text", cbOriginalText.isChecked());
jaction.put("attachments", cbWithAttachments.isChecked());
jaction.put("to", etTo.getText().toString().trim());
jaction.put("resend", cbResend.isChecked());
jaction.put("cc", cbCc.isChecked());
break;

View File

@ -902,6 +902,15 @@
app:layout_constraintTop_toTopOf="@id/etTo"
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
android:id="@+id/cbCc"
android:layout_width="wrap_content"
@ -909,7 +918,7 @@
android:layout_marginTop="12dp"
android:text="@string/title_rule_cc"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/etTo" />
app:layout_constraintTop_toBottomOf="@id/cbResend" />
<eu.faircode.email.FixedTextView
android:id="@+id/tvAnswerRemark"
@ -1084,7 +1093,7 @@
android:id="@+id/grpAnswer"
android:layout_width="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
android:id="@+id/grpTts"

View File

@ -1599,6 +1599,7 @@
<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_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_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>