diff --git a/app/src/main/java/eu/faircode/email/EntityRule.java b/app/src/main/java/eu/faircode/email/EntityRule.java
index ded6458e7f..f252004986 100644
--- a/app/src/main/java/eu/faircode/email/EntityRule.java
+++ b/app/src/main/java/eu/faircode/email/EntityRule.java
@@ -540,6 +540,41 @@ public class EntityRule {
return cal;
}
+ static EntityRule blockSender(Context context, EntityMessage message, EntityFolder junk, boolean block_domain) throws JSONException {
+ String sender = ((InternetAddress) message.from[0]).getAddress();
+ String name = MessageHelper.formatAddresses(new Address[]{message.from[0]});
+
+ if (block_domain) {
+ int at = sender.indexOf('@');
+ if (at > 0)
+ sender = sender.substring(at);
+ }
+
+ JSONObject jsender = new JSONObject();
+ jsender.put("value", sender);
+ jsender.put("regex", false);
+
+ JSONObject jcondition = new JSONObject();
+ jcondition.put("sender", jsender);
+
+ JSONObject jaction = new JSONObject();
+ jaction.put("type", EntityRule.TYPE_MOVE);
+ jaction.put("target", junk.id);
+
+ DB db = DB.getInstance(context);
+
+ EntityRule rule = new EntityRule();
+ rule.folder = message.folder;
+ rule.name = context.getString(R.string.title_block, name);
+ rule.order = 1000;
+ rule.enabled = true;
+ rule.stop = true;
+ rule.condition = jcondition.toString();
+ rule.action = jaction.toString();
+
+ return rule;
+ }
+
@Override
public boolean equals(Object obj) {
if (obj instanceof EntityRule) {
diff --git a/app/src/main/java/eu/faircode/email/FragmentMessages.java b/app/src/main/java/eu/faircode/email/FragmentMessages.java
index e5f8c7b15a..ae699d7131 100644
--- a/app/src/main/java/eu/faircode/email/FragmentMessages.java
+++ b/app/src/main/java/eu/faircode/email/FragmentMessages.java
@@ -142,7 +142,6 @@ import org.bouncycastle.cms.jcajce.JceKeyTransEnvelopedRecipient;
import org.bouncycastle.cms.jcajce.JceKeyTransRecipient;
import org.bouncycastle.util.Store;
import org.json.JSONException;
-import org.json.JSONObject;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.openintents.openpgp.AutocryptPeerUpdate;
@@ -5997,37 +5996,11 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences.
if ((block_sender || block_domain) &&
(message.from != null && message.from.length > 0)) {
- String sender = ((InternetAddress) message.from[0]).getAddress();
- String name = MessageHelper.formatAddresses(new Address[]{message.from[0]});
-
- if (block_domain) {
- int at = sender.indexOf('@');
- if (at > 0)
- sender = sender.substring(at);
- }
-
- JSONObject jsender = new JSONObject();
- jsender.put("value", sender);
- jsender.put("regex", false);
-
- JSONObject jcondition = new JSONObject();
- jcondition.put("sender", jsender);
-
- JSONObject jaction = new JSONObject();
- jaction.put("type", EntityRule.TYPE_MOVE);
- jaction.put("target", junk.id);
-
- EntityRule rule = new EntityRule();
- rule.folder = message.folder;
- rule.name = context.getString(R.string.title_block, name);
- rule.order = 1000;
- rule.enabled = true;
- rule.stop = true;
- rule.condition = jcondition.toString();
- rule.action = jaction.toString();
+ EntityRule rule = EntityRule.blockSender(context, message, junk, block_sender);
rule.id = db.rule().insertRule(rule);
}
+
db.setTransactionSuccessful();
} finally {
db.endTransaction();
diff --git a/app/src/main/java/eu/faircode/email/FragmentOptionsNotifications.java b/app/src/main/java/eu/faircode/email/FragmentOptionsNotifications.java
index b504c6b1f8..9f0e92ad24 100644
--- a/app/src/main/java/eu/faircode/email/FragmentOptionsNotifications.java
+++ b/app/src/main/java/eu/faircode/email/FragmentOptionsNotifications.java
@@ -54,6 +54,7 @@ public class FragmentOptionsNotifications extends FragmentBase implements Shared
private Button btnManageService;
private CheckBox cbNotifyActionTrash;
private CheckBox cbNotifyActionJunk;
+ private CheckBox cbNotifyActionBlockSender;
private CheckBox cbNotifyActionArchive;
private CheckBox cbNotifyActionMove;
private CheckBox cbNotifyActionReply;
@@ -82,7 +83,7 @@ public class FragmentOptionsNotifications extends FragmentBase implements Shared
private Group grpNotification;
private final static String[] RESET_OPTIONS = new String[]{
- "notify_trash", "notify_junk", "notify_archive", "notify_move",
+ "notify_trash", "notify_junk", "notify_block_sender", "notify_archive", "notify_move",
"notify_reply", "notify_reply_direct",
"notify_flag", "notify_seen", "notify_snooze",
"light", "sound",
@@ -107,6 +108,7 @@ public class FragmentOptionsNotifications extends FragmentBase implements Shared
btnManageService = view.findViewById(R.id.btnManageService);
cbNotifyActionTrash = view.findViewById(R.id.cbNotifyActionTrash);
cbNotifyActionJunk = view.findViewById(R.id.cbNotifyActionJunk);
+ cbNotifyActionBlockSender = view.findViewById(R.id.cbNotifyActionBlockSender);
cbNotifyActionArchive = view.findViewById(R.id.cbNotifyActionArchive);
cbNotifyActionMove = view.findViewById(R.id.cbNotifyActionMove);
cbNotifyActionReply = view.findViewById(R.id.cbNotifyActionReply);
@@ -189,6 +191,14 @@ public class FragmentOptionsNotifications extends FragmentBase implements Shared
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean checked) {
prefs.edit().putBoolean("notify_junk", checked).apply();
+ cbNotifyActionBlockSender.setEnabled(checked);
+ }
+ });
+
+ cbNotifyActionBlockSender.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
+ @Override
+ public void onCheckedChanged(CompoundButton buttonView, boolean checked) {
+ prefs.edit().putBoolean("notify_block_sender", checked).apply();
}
});
@@ -398,6 +408,7 @@ public class FragmentOptionsNotifications extends FragmentBase implements Shared
cbNotifyActionTrash.setChecked(prefs.getBoolean("notify_trash", true) || !pro);
cbNotifyActionJunk.setChecked(prefs.getBoolean("notify_junk", false) && pro);
+ cbNotifyActionBlockSender.setChecked(prefs.getBoolean("notify_block_sender", false) && pro);
cbNotifyActionArchive.setChecked(prefs.getBoolean("notify_archive", true) || !pro);
cbNotifyActionMove.setChecked(prefs.getBoolean("notify_move", false) && pro);
cbNotifyActionReply.setChecked(prefs.getBoolean("notify_reply", false) && pro);
@@ -427,6 +438,7 @@ public class FragmentOptionsNotifications extends FragmentBase implements Shared
cbNotifyActionTrash.setEnabled(pro && !summary);
cbNotifyActionJunk.setEnabled(pro && !summary);
+ cbNotifyActionBlockSender.setEnabled(pro && !summary && cbNotifyActionJunk.isChecked());
cbNotifyActionArchive.setEnabled(pro && !summary);
cbNotifyActionMove.setEnabled(pro && !summary);
cbNotifyActionReply.setEnabled(pro && !summary);
diff --git a/app/src/main/java/eu/faircode/email/FragmentSetup.java b/app/src/main/java/eu/faircode/email/FragmentSetup.java
index 0fff6fd96c..c9a8e5c2bd 100644
--- a/app/src/main/java/eu/faircode/email/FragmentSetup.java
+++ b/app/src/main/java/eu/faircode/email/FragmentSetup.java
@@ -471,26 +471,30 @@ public class FragmentSetup extends FragmentBase {
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
- if (requestCode == ActivitySetup.REQUEST_STILL && resultCode != Activity.RESULT_OK)
- ((FragmentBase) getParentFragment()).finish();
- else {
- boolean hasPermissions = hasPermission(Manifest.permission.READ_CONTACTS);
- Boolean isIgnoring = Helper.isIgnoringOptimizations(getContext());
+ try {
+ if (requestCode == ActivitySetup.REQUEST_STILL && resultCode != Activity.RESULT_OK)
+ ((FragmentBase) getParentFragment()).finish();
+ else {
+ boolean hasPermissions = hasPermission(Manifest.permission.READ_CONTACTS);
+ Boolean isIgnoring = Helper.isIgnoringOptimizations(getContext());
- final int top;
- if (!hasPermissions)
- top = view.findViewById(R.id.three).getTop();
- else if (isIgnoring != null && !isIgnoring)
- top = view.findViewById(R.id.four).getTop();
- else
- top = 0;
+ final int top;
+ if (!hasPermissions)
+ top = view.findViewById(R.id.three).getTop();
+ else if (isIgnoring != null && !isIgnoring)
+ top = view.findViewById(R.id.four).getTop();
+ else
+ top = 0;
- new Handler().post(new Runnable() {
- @Override
- public void run() {
- view.scrollTo(0, top);
- }
- });
+ new Handler().post(new Runnable() {
+ @Override
+ public void run() {
+ view.scrollTo(0, top);
+ }
+ });
+ }
+ } catch (Throwable ex) {
+ Log.e(ex);
}
}
diff --git a/app/src/main/java/eu/faircode/email/ServiceUI.java b/app/src/main/java/eu/faircode/email/ServiceUI.java
index 2194e5e828..1b74831d08 100644
--- a/app/src/main/java/eu/faircode/email/ServiceUI.java
+++ b/app/src/main/java/eu/faircode/email/ServiceUI.java
@@ -34,6 +34,8 @@ import androidx.core.app.AlarmManagerCompat;
import androidx.core.app.RemoteInput;
import androidx.preference.PreferenceManager;
+import org.json.JSONException;
+
import java.io.File;
import java.io.IOException;
import java.util.Collections;
@@ -112,7 +114,7 @@ public class ServiceUI extends IntentService {
case "junk":
cancel(group, id);
- onMove(id, EntityFolder.JUNK);
+ onJunk(id);
break;
case "archive":
@@ -199,15 +201,17 @@ public class ServiceUI extends IntentService {
return;
EntityFolder folder = db.folder().getFolderByType(message.account, folderType);
- if (folder != null)
- EntityOperation.queue(this, message, EntityOperation.MOVE, folder.id);
+ if (folder == null)
+ return;
+
+ EntityOperation.queue(this, message, EntityOperation.MOVE, folder.id);
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
- ServiceSynchronize.eval(ServiceUI.this, "move");
+ ServiceSynchronize.eval(this, "ui/move:" + folderType);
}
private void onMove(long id) {
@@ -230,7 +234,38 @@ public class ServiceUI extends IntentService {
db.endTransaction();
}
- ServiceSynchronize.eval(ServiceUI.this, "move");
+ ServiceSynchronize.eval(this, "ui/move:" + id);
+ }
+
+ private void onJunk(long id) throws JSONException {
+ SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
+ boolean block_sender = prefs.getBoolean("notify_block_sender", false);
+
+ DB db = DB.getInstance(this);
+ try {
+ db.beginTransaction();
+
+ EntityMessage message = db.message().getMessage(id);
+ if (message == null)
+ return;
+
+ EntityFolder junk = db.folder().getFolderByType(message.account, EntityFolder.JUNK);
+ if (junk == null)
+ return;
+
+ EntityOperation.queue(this, message, EntityOperation.MOVE, junk.id);
+
+ if (block_sender) {
+ EntityRule rule = EntityRule.blockSender(this, message, junk, false);
+ rule.id = db.rule().insertRule(rule);
+ }
+
+ db.setTransactionSuccessful();
+ } finally {
+ db.endTransaction();
+ }
+
+ ServiceSynchronize.eval(this, "ui/junk");
}
private void onReplyDirect(long id, Intent intent) throws IOException {
@@ -297,7 +332,7 @@ public class ServiceUI extends IntentService {
db.endTransaction();
}
- ServiceSend.start(ServiceUI.this);
+ ServiceSend.start(this);
ToastEx.makeText(this, R.string.title_queued, Toast.LENGTH_LONG).show();
}
@@ -325,7 +360,7 @@ public class ServiceUI extends IntentService {
db.endTransaction();
}
- ServiceSynchronize.eval(ServiceUI.this, "flag");
+ ServiceSynchronize.eval(this, "ui/flag");
}
private void onSeen(long id) {
@@ -344,7 +379,7 @@ public class ServiceUI extends IntentService {
db.endTransaction();
}
- ServiceSynchronize.eval(ServiceUI.this, "seen");
+ ServiceSynchronize.eval(this, "ui/seen");
}
private void onSnooze(long id) {
@@ -446,9 +481,9 @@ public class ServiceUI extends IntentService {
}
if (EntityFolder.OUTBOX.equals(folder.type))
- ServiceSend.start(ServiceUI.this);
+ ServiceSend.start(this);
else
- ServiceSynchronize.eval(ServiceUI.this, "wakeup");
+ ServiceSynchronize.eval(this, "ui/wakeup");
}
private void onSync(long aid, boolean reschedule) {
@@ -470,7 +505,7 @@ public class ServiceUI extends IntentService {
db.endTransaction();
}
- ServiceSynchronize.eval(this, "poll");
+ ServiceSynchronize.eval(this, "ui/poll");
if (reschedule) {
long now = new Date().getTime();
diff --git a/app/src/main/res/layout/fragment_options_notifications.xml b/app/src/main/res/layout/fragment_options_notifications.xml
index 39226375c0..f3946caaff 100644
--- a/app/src/main/res/layout/fragment_options_notifications.xml
+++ b/app/src/main/res/layout/fragment_options_notifications.xml
@@ -125,6 +125,16 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/cbNotifyActionTrash" />
+
+
+ app:layout_constraintTop_toBottomOf="@id/cbNotifyActionBlockSender" />