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" />