diff --git a/app/src/main/java/eu/faircode/email/EntityRule.java b/app/src/main/java/eu/faircode/email/EntityRule.java
index b36e9bc119..3e25cb4e66 100644
--- a/app/src/main/java/eu/faircode/email/EntityRule.java
+++ b/app/src/main/java/eu/faircode/email/EntityRule.java
@@ -19,11 +19,16 @@ package eu.faircode.email;
Copyright 2018-2019 by Marcel Bokhorst (M66B)
*/
+import android.Manifest;
import android.content.Context;
import android.content.Intent;
+import android.content.SharedPreferences;
+import android.database.Cursor;
import android.net.Uri;
+import android.provider.ContactsContract;
import androidx.annotation.NonNull;
+import androidx.preference.PreferenceManager;
import androidx.room.Entity;
import androidx.room.ForeignKey;
import androidx.room.Index;
@@ -102,16 +107,51 @@ public class EntityRule {
if (jsender != null) {
String value = jsender.getString("value");
boolean regex = jsender.getBoolean("regex");
+ boolean known = jsender.optBoolean("known");
boolean matches = false;
if (message.from != null) {
for (Address from : message.from) {
InternetAddress ia = (InternetAddress) from;
+ String email = ia.getAddress();
String personal = ia.getPersonal();
- String formatted = ((personal == null ? "" : personal + " ") + "<" + ia.getAddress() + ">");
- if (matches(context, value, formatted, regex)) {
- matches = true;
- break;
+
+ if (known) {
+ SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
+ boolean suggest_sent = prefs.getBoolean("suggest_sent", false);
+ if (suggest_sent) {
+ DB db = DB.getInstance(context);
+ EntityContact contact =
+ db.contact().getContact(message.account, EntityContact.TYPE_TO, email);
+ if (contact != null) {
+ Log.i(email + " is local contact");
+ matches = true;
+ break;
+ }
+ }
+
+ boolean contacts = Helper.hasPermission(context, Manifest.permission.READ_CONTACTS);
+ if (contacts) {
+ Cursor cursor = context.getContentResolver().query(
+ ContactsContract.CommonDataKinds.Email.CONTENT_URI,
+ new String[]{ContactsContract.CommonDataKinds.Email.CONTACT_ID},
+ ContactsContract.CommonDataKinds.Email.DATA + " = ? COLLATE NOCASE",
+ new String[]{email},
+ null);
+
+ while (cursor != null && cursor.moveToNext()) {
+ Log.i(email + " is Android contact");
+ matches = true;
+ break;
+ }
+ }
+
+ } else {
+ String formatted = ((personal == null ? "" : personal + " ") + "<" + email + ">");
+ if (matches(context, value, formatted, regex)) {
+ matches = true;
+ break;
+ }
}
}
}
diff --git a/app/src/main/java/eu/faircode/email/FragmentRule.java b/app/src/main/java/eu/faircode/email/FragmentRule.java
index bf318e9d64..c4c221813f 100644
--- a/app/src/main/java/eu/faircode/email/FragmentRule.java
+++ b/app/src/main/java/eu/faircode/email/FragmentRule.java
@@ -40,6 +40,7 @@ import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
+import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
@@ -89,6 +90,7 @@ public class FragmentRule extends FragmentBase {
private EditText etSender;
private CheckBox cbSender;
private ImageView ibSender;
+ private CheckBox cbKnownSender;
private EditText etRecipient;
private CheckBox cbRecipient;
@@ -192,6 +194,7 @@ public class FragmentRule extends FragmentBase {
etSender = view.findViewById(R.id.etSender);
cbSender = view.findViewById(R.id.cbSender);
ibSender = view.findViewById(R.id.ibSender);
+ cbKnownSender = view.findViewById(R.id.cbKnownSender);
etRecipient = view.findViewById(R.id.etRecipient);
cbRecipient = view.findViewById(R.id.cbRecipient);
@@ -252,6 +255,15 @@ public class FragmentRule extends FragmentBase {
}
});
+ cbKnownSender.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
+ @Override
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ etSender.setEnabled(!isChecked);
+ ibSender.setEnabled(!isChecked);
+ cbSender.setEnabled(!isChecked);
+ }
+ });
+
ibRecipient.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
@@ -628,6 +640,10 @@ public class FragmentRule extends FragmentBase {
etSender.setText(jsender == null ? args.getString("sender") : jsender.getString("value"));
cbSender.setChecked(jsender != null && jsender.getBoolean("regex"));
+ cbKnownSender.setChecked(jsender != null && jsender.optBoolean("known"));
+ etSender.setEnabled(!cbKnownSender.isChecked());
+ ibSender.setEnabled(!cbKnownSender.isChecked());
+ cbSender.setEnabled(!cbKnownSender.isChecked());
etRecipient.setText(jrecipient == null ? args.getString("recipient") : jrecipient.getString("value"));
cbRecipient.setChecked(jrecipient != null && jrecipient.getBoolean("regex"));
@@ -877,10 +893,12 @@ public class FragmentRule extends FragmentBase {
JSONObject jcondition = new JSONObject();
String sender = etSender.getText().toString();
- if (!TextUtils.isEmpty(sender)) {
+ boolean known = cbKnownSender.isChecked();
+ if (!TextUtils.isEmpty(sender) || known) {
JSONObject jsender = new JSONObject();
jsender.put("value", sender);
jsender.put("regex", cbSender.isChecked());
+ jsender.put("known", known);
jcondition.put("sender", jsender);
}
diff --git a/app/src/main/res/layout/fragment_rule.xml b/app/src/main/res/layout/fragment_rule.xml
index 8f3bd8c9d2..b7d0228725 100644
--- a/app/src/main/res/layout/fragment_rule.xml
+++ b/app/src/main/res/layout/fragment_rule.xml
@@ -160,6 +160,14 @@
app:layout_constraintTop_toTopOf="@id/etSender"
app:srcCompat="@drawable/baseline_person_add_24" />
+
+
+ app:layout_constraintTop_toBottomOf="@+id/cbKnownSender" />
Enabled
Stop processing rules after executing this rule
Sender contains
+ Sender is a contact
Recipient contains
Subject contains
Header contains