mirror of https://github.com/M66B/FairEmail.git
Added option for local spam filter
This commit is contained in:
parent
82a629e7d1
commit
e7cce96751
4
FAQ.md
4
FAQ.md
|
@ -3423,6 +3423,10 @@ This will enable learning mode only.
|
|||
Each folder has an option to enable automatic message classification.
|
||||
When this is turned on, new messages in other folders which the classifier thinks belong to that folder will be automatically moved.
|
||||
|
||||
The option *Use local spam filter* turns on message classification and auto classification for the spam folder.
|
||||
Please understand that this is not a replacement for the spam filter of the email server.
|
||||
See also [this FAQ](#user-content-faq92).
|
||||
|
||||
A practical example: suppose there is a folder 'marketing' and auto message classification is enabled for this folder.
|
||||
Each time you move a message into this folder you'll train FairEmail that similar messages belong in this folder.
|
||||
Each time you move a message out of this folder you'll train FairEmail that similar messages do not belong in this folder.
|
||||
|
|
|
@ -6355,7 +6355,7 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
|
|||
@NonNull
|
||||
@Override
|
||||
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
|
||||
Bundle args = getArguments();
|
||||
final Bundle args = getArguments();
|
||||
final long account = args.getLong("account");
|
||||
final int protocol = args.getInt("protocol");
|
||||
final long folder = args.getLong("folder");
|
||||
|
@ -6365,15 +6365,17 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
|
|||
|
||||
View view = LayoutInflater.from(getContext()).inflate(R.layout.dialog_junk, null);
|
||||
final TextView tvMessage = view.findViewById(R.id.tvMessage);
|
||||
final ImageButton ibInfo = view.findViewById(R.id.ibInfo);
|
||||
final ImageButton ibInfoProvider = view.findViewById(R.id.ibInfoProvider);
|
||||
final CheckBox cbBlockSender = view.findViewById(R.id.cbBlockSender);
|
||||
final CheckBox cbBlockDomain = view.findViewById(R.id.cbBlockDomain);
|
||||
final Button btnEditRules = view.findViewById(R.id.btnEditRules);
|
||||
final CheckBox cbJunkFilter = view.findViewById(R.id.cbJunkFilter);
|
||||
final ImageButton ibInfoFilter = view.findViewById(R.id.ibInfoFilter);
|
||||
final Group grpInJunk = view.findViewById(R.id.grpInJunk);
|
||||
|
||||
tvMessage.setText(getString(R.string.title_ask_spam_who, from));
|
||||
|
||||
ibInfo.setOnClickListener(new View.OnClickListener() {
|
||||
ibInfoProvider.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Helper.viewFAQ(v.getContext(), 92);
|
||||
|
@ -6424,7 +6426,7 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
|
|||
protected void onException(Bundle args, Throwable ex) {
|
||||
Log.unexpectedError(getParentFragmentManager(), ex);
|
||||
}
|
||||
}.execute(FragmentDialogJunk.this, getArguments(), "junk");
|
||||
}.execute(FragmentDialogJunk.this, args, "junk:rules");
|
||||
} else {
|
||||
LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(getContext());
|
||||
lbm.sendBroadcast(
|
||||
|
@ -6438,8 +6440,81 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
|
|||
}
|
||||
});
|
||||
|
||||
cbJunkFilter.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
||||
args.putBoolean("filter", isChecked);
|
||||
|
||||
new SimpleTask<Void>() {
|
||||
@Override
|
||||
protected Void onExecute(Context context, Bundle args) throws Throwable {
|
||||
long account = args.getLong("account");
|
||||
boolean filter = args.getBoolean("filter");
|
||||
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
|
||||
DB db = DB.getInstance(context);
|
||||
EntityFolder junk = db.folder().getFolderByType(account, EntityFolder.JUNK);
|
||||
if (junk != null) {
|
||||
db.folder().setFolderAutoClassify(junk.id, filter);
|
||||
prefs.edit().putBoolean("classification", true).apply();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onException(Bundle args, Throwable ex) {
|
||||
Log.unexpectedError(getParentFragmentManager(), ex);
|
||||
}
|
||||
}.execute(FragmentDialogJunk.this, args, "junk:filter");
|
||||
}
|
||||
});
|
||||
|
||||
ibInfoFilter.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Helper.viewFAQ(v.getContext(), 163);
|
||||
}
|
||||
});
|
||||
|
||||
grpInJunk.setVisibility(inJunk ? View.GONE : View.VISIBLE);
|
||||
|
||||
new SimpleTask<Boolean>() {
|
||||
@Override
|
||||
protected void onPreExecute(Bundle args) {
|
||||
cbJunkFilter.setEnabled(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Boolean onExecute(Context context, Bundle args) throws Throwable {
|
||||
long account = args.getLong("account");
|
||||
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
boolean classification = prefs.getBoolean("classification", false);
|
||||
|
||||
DB db = DB.getInstance(context);
|
||||
EntityFolder junk = db.folder().getFolderByType(account, EntityFolder.JUNK);
|
||||
if (junk == null)
|
||||
return false;
|
||||
|
||||
return classification && junk.auto_classify;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onExecuted(Bundle args, Boolean filter) {
|
||||
if (filter != null) {
|
||||
cbJunkFilter.setChecked(filter);
|
||||
cbJunkFilter.setEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onException(Bundle args, Throwable ex) {
|
||||
Log.unexpectedError(getParentFragmentManager(), ex);
|
||||
}
|
||||
}.execute(FragmentDialogJunk.this, args, "junk:filter");
|
||||
|
||||
return new AlertDialog.Builder(getContext())
|
||||
.setView(view)
|
||||
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
|
||||
|
|
|
@ -344,6 +344,9 @@ public interface DaoFolder {
|
|||
@Query("UPDATE folder SET poll_count = :count WHERE id = :id AND NOT (poll_count IS :count)")
|
||||
int setFolderPollCount(long id, int count);
|
||||
|
||||
@Query("UPDATE folder SET auto_classify = :auto_classify WHERE id = :id AND NOT (auto_classify IS :auto_classify)")
|
||||
int setFolderAutoClassify(long id, boolean auto_classify);
|
||||
|
||||
@Query("DELETE FROM folder WHERE id = :id")
|
||||
void deleteFolder(long id);
|
||||
|
||||
|
|
|
@ -29,12 +29,12 @@
|
|||
android:text="@string/title_junk_hint"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Small"
|
||||
android:textStyle="italic"
|
||||
app:layout_constraintEnd_toStartOf="@+id/ibInfo"
|
||||
app:layout_constraintEnd_toStartOf="@+id/ibInfoProvider"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/tvMessage" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/ibInfo"
|
||||
android:id="@+id/ibInfoProvider"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:contentDescription="@string/title_info"
|
||||
|
@ -84,10 +84,33 @@
|
|||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/tvBlockHint" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/cbJunkFilter"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="12dp"
|
||||
android:text="@string/title_junk_filter"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Small"
|
||||
app:layout_constraintEnd_toStartOf="@+id/ibInfoFilter"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/btnEditRules" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/ibInfoFilter"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:contentDescription="@string/title_info"
|
||||
android:tooltipText="@string/title_info"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@id/cbJunkFilter"
|
||||
app:srcCompat="@drawable/twotone_info_24" />
|
||||
|
||||
<androidx.constraintlayout.widget.Group
|
||||
android:id="@+id/grpInJunk"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
app:constraint_referenced_ids="tvMessage,tvJunkHint,ibInfo" />
|
||||
app:constraint_referenced_ids="
|
||||
tvMessage,tvJunkHint,ibInfoProvider,
|
||||
cbJunkFilter,ibInfoFilter" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</eu.faircode.email.ScrollViewEx>
|
|
@ -99,6 +99,8 @@
|
|||
Creating and using rules is a pro feature.
|
||||
</string>
|
||||
|
||||
<string name="title_junk_filter">Use local spam filter</string>
|
||||
|
||||
<string name="title_notification_sending">Sending messages</string>
|
||||
<string name="title_notification_waiting">Waiting for suitable connection</string>
|
||||
<string name="title_notification_idle">Idle</string>
|
||||
|
|
Loading…
Reference in New Issue