mirror of
https://github.com/M66B/FairEmail.git
synced 2025-02-24 15:11:03 +00:00
Added rule recipient condition
This commit is contained in:
parent
e52f478b22
commit
ed3dba810f
5 changed files with 162 additions and 15 deletions
|
@ -117,6 +117,7 @@ public class ActivityView extends ActivityBilling implements FragmentManager.OnB
|
|||
static final int REQUEST_ATTACHMENTS = 3;
|
||||
static final int REQUEST_DECRYPT = 4;
|
||||
static final int REQUEST_SENDER = 5;
|
||||
static final int REQUEST_RECIPIENT = 6;
|
||||
|
||||
static final String ACTION_VIEW_MESSAGES = BuildConfig.APPLICATION_ID + ".VIEW_MESSAGES";
|
||||
static final String ACTION_VIEW_THREAD = BuildConfig.APPLICATION_ID + ".VIEW_THREAD";
|
||||
|
|
|
@ -26,8 +26,11 @@ import org.json.JSONException;
|
|||
import org.json.JSONObject;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.mail.Address;
|
||||
|
@ -83,6 +86,7 @@ public class EntityRule {
|
|||
try {
|
||||
JSONObject jcondition = new JSONObject(condition);
|
||||
|
||||
// Sender
|
||||
JSONObject jsender = jcondition.optJSONObject("sender");
|
||||
if (jsender != null) {
|
||||
String value = jsender.getString("value");
|
||||
|
@ -104,6 +108,31 @@ public class EntityRule {
|
|||
return false;
|
||||
}
|
||||
|
||||
// Recipient
|
||||
JSONObject jrecipient = jcondition.optJSONObject("recipient");
|
||||
if (jrecipient != null) {
|
||||
String value = jrecipient.getString("value");
|
||||
boolean regex = jrecipient.getBoolean("regex");
|
||||
|
||||
boolean matches = false;
|
||||
List<Address> recipients = new ArrayList<>();
|
||||
if (message.to != null)
|
||||
recipients.addAll(Arrays.asList(message.to));
|
||||
if (message.cc != null)
|
||||
recipients.addAll(Arrays.asList(message.cc));
|
||||
for (Address recipient : recipients) {
|
||||
InternetAddress ia = (InternetAddress) recipient;
|
||||
String personal = ia.getPersonal();
|
||||
String formatted = ((personal == null ? "" : personal + " ") + "<" + ia.getAddress() + ">");
|
||||
if (matches(context, value, formatted, regex)) {
|
||||
matches = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!matches)
|
||||
return false;
|
||||
}
|
||||
|
||||
JSONObject jsubject = jcondition.optJSONObject("subject");
|
||||
if (jsubject != null) {
|
||||
String value = jsubject.getString("value");
|
||||
|
@ -133,7 +162,7 @@ public class EntityRule {
|
|||
}
|
||||
|
||||
// Safeguard
|
||||
if (jsender == null && jsubject == null && jheader == null)
|
||||
if (jsender == null && jrecipient == null && jsubject == null && jheader == null)
|
||||
return false;
|
||||
} catch (JSONException ex) {
|
||||
Log.e(ex);
|
||||
|
|
|
@ -62,26 +62,37 @@ public class FragmentRule extends FragmentBase {
|
|||
private ViewGroup view;
|
||||
private ScrollView scroll;
|
||||
private ConstraintLayout content;
|
||||
|
||||
private TextView tvFolder;
|
||||
private EditText etName;
|
||||
private EditText etOrder;
|
||||
private CheckBox cbEnabled;
|
||||
private CheckBox cbStop;
|
||||
|
||||
private EditText etSender;
|
||||
private CheckBox cbSender;
|
||||
private ImageView ivSender;
|
||||
|
||||
private EditText etRecipient;
|
||||
private CheckBox cbRecipient;
|
||||
private ImageView ivRecipient;
|
||||
|
||||
private EditText etSubject;
|
||||
private CheckBox cbSubject;
|
||||
|
||||
private EditText etHeader;
|
||||
private CheckBox cbHeader;
|
||||
|
||||
private Spinner spAction;
|
||||
private TextView tvActionRemark;
|
||||
private Spinner spTarget;
|
||||
private Spinner spIdent;
|
||||
private Spinner spAnswer;
|
||||
private CheckBox cbCc;
|
||||
|
||||
private BottomNavigationView bottom_navigation;
|
||||
private ContentLoadingProgressBar pbWait;
|
||||
|
||||
private Group grpReady;
|
||||
private Group grpMove;
|
||||
private Group grpAnswer;
|
||||
|
@ -116,26 +127,37 @@ public class FragmentRule extends FragmentBase {
|
|||
// Get controls
|
||||
scroll = view.findViewById(R.id.scroll);
|
||||
content = view.findViewById(R.id.content);
|
||||
|
||||
tvFolder = view.findViewById(R.id.tvFolder);
|
||||
etName = view.findViewById(R.id.etName);
|
||||
etOrder = view.findViewById(R.id.etOrder);
|
||||
cbEnabled = view.findViewById(R.id.cbEnabled);
|
||||
cbStop = view.findViewById(R.id.cbStop);
|
||||
|
||||
etSender = view.findViewById(R.id.etSender);
|
||||
cbSender = view.findViewById(R.id.cbSender);
|
||||
ivSender = view.findViewById(R.id.ivSender);
|
||||
|
||||
etRecipient = view.findViewById(R.id.etRecipient);
|
||||
cbRecipient = view.findViewById(R.id.cbRecipient);
|
||||
ivRecipient = view.findViewById(R.id.ivRecipient);
|
||||
|
||||
etSubject = view.findViewById(R.id.etSubject);
|
||||
cbSubject = view.findViewById(R.id.cbSubject);
|
||||
|
||||
etHeader = view.findViewById(R.id.etHeader);
|
||||
cbHeader = view.findViewById(R.id.cbHeader);
|
||||
|
||||
spAction = view.findViewById(R.id.spAction);
|
||||
tvActionRemark = view.findViewById(R.id.tvActionRemark);
|
||||
spTarget = view.findViewById(R.id.spTarget);
|
||||
spIdent = view.findViewById(R.id.spIdent);
|
||||
spAnswer = view.findViewById(R.id.spAnswer);
|
||||
cbCc = view.findViewById(R.id.cbCc);
|
||||
|
||||
bottom_navigation = view.findViewById(R.id.bottom_navigation);
|
||||
pbWait = view.findViewById(R.id.pbWait);
|
||||
|
||||
grpReady = view.findViewById(R.id.grpReady);
|
||||
grpMove = view.findViewById(R.id.grpMove);
|
||||
grpAnswer = view.findViewById(R.id.grpAnswer);
|
||||
|
@ -151,6 +173,17 @@ public class FragmentRule extends FragmentBase {
|
|||
}
|
||||
});
|
||||
|
||||
ivRecipient.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Intent pick = new Intent(Intent.ACTION_PICK, ContactsContract.CommonDataKinds.Email.CONTENT_URI);
|
||||
if (pick.resolveActivity(getContext().getPackageManager()) == null)
|
||||
Snackbar.make(view, R.string.title_no_contacts, Snackbar.LENGTH_LONG).show();
|
||||
else
|
||||
startActivityForResult(Helper.getChooser(getContext(), pick), ActivityView.REQUEST_RECIPIENT);
|
||||
}
|
||||
});
|
||||
|
||||
adapterAction = new ArrayAdapter<>(getContext(), R.layout.spinner_item1, android.R.id.text1, new ArrayList<Action>());
|
||||
adapterAction.setDropDownViewResource(R.layout.spinner_item1_dropdown);
|
||||
spAction.setAdapter(adapterAction);
|
||||
|
@ -295,14 +328,14 @@ public class FragmentRule extends FragmentBase {
|
|||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
Log.i("Request=" + requestCode + " result=" + resultCode + " data=" + data);
|
||||
if (resultCode == RESULT_OK) {
|
||||
if (requestCode == ActivityView.REQUEST_SENDER) {
|
||||
if (data != null)
|
||||
handlePickContact(data);
|
||||
}
|
||||
if (data != null && requestCode == ActivityView.REQUEST_SENDER)
|
||||
handlePickContact(data, true);
|
||||
if (data != null && requestCode == ActivityView.REQUEST_RECIPIENT)
|
||||
handlePickContact(data, false);
|
||||
}
|
||||
}
|
||||
|
||||
private void handlePickContact(Intent data) {
|
||||
private void handlePickContact(Intent data, boolean sender) {
|
||||
Uri uri = data.getData();
|
||||
if (uri == null) return;
|
||||
try (Cursor cursor = getContext().getContentResolver().query(uri,
|
||||
|
@ -311,7 +344,10 @@ public class FragmentRule extends FragmentBase {
|
|||
},
|
||||
null, null, null)) {
|
||||
if (cursor != null && cursor.moveToFirst())
|
||||
etSender.setText(cursor.getString(0));
|
||||
if (sender)
|
||||
etSender.setText(cursor.getString(0));
|
||||
else
|
||||
etRecipient.setText(cursor.getString(0));
|
||||
} catch (Throwable ex) {
|
||||
Log.e(ex);
|
||||
Helper.unexpectedError(getContext(), getViewLifecycleOwner(), ex);
|
||||
|
@ -338,6 +374,7 @@ public class FragmentRule extends FragmentBase {
|
|||
JSONObject jaction = (rule == null ? new JSONObject() : new JSONObject(rule.action));
|
||||
|
||||
JSONObject jsender = jcondition.optJSONObject("sender");
|
||||
JSONObject jrecipient = jcondition.optJSONObject("recipient");
|
||||
JSONObject jsubject = jcondition.optJSONObject("subject");
|
||||
JSONObject jheader = jcondition.optJSONObject("header");
|
||||
|
||||
|
@ -345,10 +382,16 @@ public class FragmentRule extends FragmentBase {
|
|||
etOrder.setText(rule == null ? null : Integer.toString(rule.order));
|
||||
cbEnabled.setChecked(rule == null || rule.enabled);
|
||||
cbStop.setChecked(rule != null && rule.stop);
|
||||
|
||||
etSender.setText(jsender == null ? args.getString("sender") : jsender.getString("value"));
|
||||
cbSender.setChecked(jsender != null && jsender.getBoolean("regex"));
|
||||
|
||||
etRecipient.setText(jrecipient == null ? null : jrecipient.getString("value"));
|
||||
cbRecipient.setChecked(jrecipient != null && jrecipient.getBoolean("regex"));
|
||||
|
||||
etSubject.setText(jsubject == null ? args.getString("subject") : jsubject.getString("value"));
|
||||
cbSubject.setChecked(jsubject != null && jsubject.getBoolean("regex"));
|
||||
|
||||
etHeader.setText(jheader == null ? null : jheader.getString("value"));
|
||||
cbHeader.setChecked(jheader != null && jheader.getBoolean("regex"));
|
||||
|
||||
|
@ -507,10 +550,11 @@ public class FragmentRule extends FragmentBase {
|
|||
|
||||
JSONObject jcondition = new JSONObject(condition);
|
||||
JSONObject jsender = jcondition.optJSONObject("sender");
|
||||
JSONObject jrecipient = jcondition.optJSONObject("recipient");
|
||||
JSONObject jsubject = jcondition.optJSONObject("subject");
|
||||
JSONObject jheader = jcondition.optJSONObject("header");
|
||||
|
||||
if (jsender == null && jsubject == null && jheader == null)
|
||||
if (jsender == null && jrecipient == null && jsubject == null && jheader == null)
|
||||
throw new IllegalArgumentException(context.getString(R.string.title_rule_condition_missing));
|
||||
|
||||
if (TextUtils.isEmpty(order))
|
||||
|
@ -576,6 +620,14 @@ public class FragmentRule extends FragmentBase {
|
|||
jcondition.put("sender", jsender);
|
||||
}
|
||||
|
||||
String recipient = etRecipient.getText().toString();
|
||||
if (!TextUtils.isEmpty(recipient)) {
|
||||
JSONObject jrecipient = new JSONObject();
|
||||
jrecipient.put("value", recipient);
|
||||
jrecipient.put("regex", cbRecipient.isChecked());
|
||||
jcondition.put("recipient", jrecipient);
|
||||
}
|
||||
|
||||
String subject = etSubject.getText().toString();
|
||||
if (!TextUtils.isEmpty(subject)) {
|
||||
JSONObject jsubject = new JSONObject();
|
||||
|
|
|
@ -143,7 +143,7 @@
|
|||
app:layout_constraintTop_toTopOf="@id/etSender" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvAndSubject"
|
||||
android:id="@+id/tvAndSender"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="12dp"
|
||||
|
@ -154,13 +154,76 @@
|
|||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/etSender" />
|
||||
|
||||
<View
|
||||
android:id="@+id/vSeparatorRecipient"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="?attr/colorSeparator"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/tvAndSender" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvRecipient"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:singleLine="true"
|
||||
android:text="@string/title_rule_recipient"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Small"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/cbRecipient"
|
||||
app:layout_constraintEnd_toStartOf="@+id/cbRecipient"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@+id/cbRecipient" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/cbRecipient"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/title_rule_regex"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/vSeparatorRecipient" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etRecipient"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/title_optional"
|
||||
android:inputType="textEmailAddress"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
|
||||
app:layout_constraintEnd_toStartOf="@+id/ivRecipient"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/cbRecipient" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/ivRecipient"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_marginStart="6dp"
|
||||
android:layout_marginEnd="6dp"
|
||||
android:src="@drawable/baseline_person_24"
|
||||
app:layout_constraintBottom_toBottomOf="@id/etRecipient"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@id/etRecipient" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvAndRecipient"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="12dp"
|
||||
android:text="@string/title_rule_and"
|
||||
android:textAppearance="@style/Base.TextAppearance.AppCompat.Medium"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/etRecipient" />
|
||||
|
||||
<View
|
||||
android:id="@+id/vSeparatorSubject"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="?attr/colorSeparator"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/tvAndSubject" />
|
||||
app:layout_constraintTop_toBottomOf="@id/tvAndRecipient" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvSubject"
|
||||
|
@ -195,7 +258,7 @@
|
|||
app:layout_constraintTop_toBottomOf="@id/cbSubject" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvAndHeader"
|
||||
android:id="@+id/tvAndSubject"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="12dp"
|
||||
|
@ -212,7 +275,7 @@
|
|||
android:layout_height="1dp"
|
||||
android:background="?attr/colorSeparator"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/tvAndHeader" />
|
||||
app:layout_constraintTop_toBottomOf="@id/tvAndSubject" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvHeader"
|
||||
|
@ -358,9 +421,10 @@
|
|||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
app:constraint_referenced_ids="
|
||||
tvName,etName,tvOrder,etOrder,cbEnabled,cbStop,
|
||||
vSeparatorSender,tvSender,cbSender,etSender,ivSender,tvAndSubject,
|
||||
vSeparatorSubject,tvSubject,cbSubject,etSubject,tvAndHeader,
|
||||
tvFolder,tvName,etName,tvOrder,etOrder,cbEnabled,cbStop,
|
||||
vSeparatorSender,tvSender,cbSender,etSender,ivSender,tvAndSender,
|
||||
vSeparatorRecipient,tvRecipient,cbRecipient,etRecipient,ivRecipient,tvAndRecipient,
|
||||
vSeparatorSubject,tvSubject,cbSubject,etSubject,tvAndSubject,
|
||||
vSeparatorHeader,tvHeader,cbHeader,etHeader,
|
||||
vSeparatorAction,tvAction,spAction,tvActionRemark,
|
||||
vSeparatorParameters" />
|
||||
|
|
|
@ -450,6 +450,7 @@
|
|||
<string name="title_rule_enabled">Enabled</string>
|
||||
<string name="title_rule_stop">Stop processing rules after executing this rule</string>
|
||||
<string name="title_rule_sender">Sender contains</string>
|
||||
<string name="title_rule_recipient">Recipient contains</string>
|
||||
<string name="title_rule_subject">Subject contains</string>
|
||||
<string name="title_rule_header">Header contains</string>
|
||||
<string name="title_rule_regex">Regex</string>
|
||||
|
|
Loading…
Reference in a new issue