From d87a1e6949a1580aed8d3551eb851aa493dbb2bf Mon Sep 17 00:00:00 2001 From: M66B Date: Sat, 27 Mar 2021 11:51:57 +0100 Subject: [PATCH] Added rule date range --- .../java/eu/faircode/email/EntityRule.java | 10 ++ .../email/FragmentDialogDuration.java | 21 +++- .../java/eu/faircode/email/FragmentRule.java | 110 +++++++++++++++++- app/src/main/res/layout/fragment_rule.xml | 84 ++++++++++++- app/src/main/res/values/strings.xml | 5 +- 5 files changed, 221 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/eu/faircode/email/EntityRule.java b/app/src/main/java/eu/faircode/email/EntityRule.java index 34859f0757..c97e88c3e6 100644 --- a/app/src/main/java/eu/faircode/email/EntityRule.java +++ b/app/src/main/java/eu/faircode/email/EntityRule.java @@ -251,6 +251,15 @@ public class EntityRule { return false; } + // Date + JSONObject jdate = jcondition.optJSONObject("date"); + if (jdate != null) { + long after = jdate.optLong("after", 0); + long before = jdate.optLong("before", 0); + if ((after != 0 && message.received < after) || (before != 0 && message.received > before)) + return false; + } + // Schedule JSONObject jschedule = jcondition.optJSONObject("schedule"); if (jschedule != null) { @@ -274,6 +283,7 @@ public class EntityRule { jsubject == null && !jcondition.optBoolean("attachments") && jheader == null && + jdate == null && jschedule == null) return false; } catch (JSONException ex) { diff --git a/app/src/main/java/eu/faircode/email/FragmentDialogDuration.java b/app/src/main/java/eu/faircode/email/FragmentDialogDuration.java index 7eb22d3406..8f1e8a911e 100644 --- a/app/src/main/java/eu/faircode/email/FragmentDialogDuration.java +++ b/app/src/main/java/eu/faircode/email/FragmentDialogDuration.java @@ -44,7 +44,7 @@ import static android.app.Activity.RESULT_CANCELED; import static android.app.Activity.RESULT_OK; public class FragmentDialogDuration extends FragmentDialogBase { - private Calendar cal = Calendar.getInstance(); + private final Calendar cal = Calendar.getInstance(); @Override public void onSaveInstanceState(@NonNull Bundle outState) { @@ -55,7 +55,10 @@ public class FragmentDialogDuration extends FragmentDialogBase { @NonNull @Override public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) { - String title = getArguments().getString("title"); + Bundle args = getArguments(); + String title = args.getString("title"); + boolean day = args.getBoolean("day"); + long time = args.getLong("time", 0); final View dview = LayoutInflater.from(getContext()).inflate(R.layout.dialog_duration, null); final TextView tvDuration = dview.findViewById(R.id.tvDuration); @@ -65,9 +68,16 @@ public class FragmentDialogDuration extends FragmentDialogBase { final TimePicker timePicker = dview.findViewById(R.id.timePicker); final DatePicker datePicker = dview.findViewById(R.id.datePicker); - if (savedInstanceState == null) - cal.setTimeInMillis((new Date().getTime() / (3600 * 1000L) + 1) * (3600 * 1000L)); - else + if (savedInstanceState == null) { + if (time == 0) { + cal.setTimeInMillis(new Date().getTime()); + cal.set(Calendar.MINUTE, 0); + cal.set(Calendar.SECOND, 0); + cal.set(Calendar.MILLISECOND, 0); + cal.set(Calendar.HOUR_OF_DAY, day ? 0 : cal.get(Calendar.HOUR_OF_DAY) + 1); + } else + cal.setTimeInMillis(time); + } else cal.setTimeInMillis(savedInstanceState.getLong("fair:time")); Log.i("Set init=" + new Date(cal.getTimeInMillis())); @@ -107,6 +117,7 @@ public class FragmentDialogDuration extends FragmentDialogBase { @Override public void onClick(DialogInterface dialogInterface, int i) { Bundle args = getArguments(); + args.putBoolean("reset", true); args.putLong("duration", 0); args.putLong("time", new Date().getTime()); diff --git a/app/src/main/java/eu/faircode/email/FragmentRule.java b/app/src/main/java/eu/faircode/email/FragmentRule.java index 5383999cc3..fad17e14da 100644 --- a/app/src/main/java/eu/faircode/email/FragmentRule.java +++ b/app/src/main/java/eu/faircode/email/FragmentRule.java @@ -30,7 +30,6 @@ import android.os.Bundle; import android.provider.ContactsContract; import android.speech.tts.TextToSpeech; import android.text.TextUtils; -import android.text.format.DateFormat; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; @@ -66,6 +65,7 @@ import com.google.android.material.snackbar.Snackbar; import org.json.JSONException; import org.json.JSONObject; +import java.text.DateFormat; import java.text.DateFormatSymbols; import java.text.SimpleDateFormat; import java.util.ArrayList; @@ -104,6 +104,11 @@ public class FragmentRule extends FragmentBase { private EditText etHeader; private CheckBox cbHeader; + private TextView tvDateAfter; + private TextView tvDateBefore; + private Button btnDateAfter; + private Button btnDateBefore; + private Spinner spScheduleDayStart; private Spinner spScheduleDayEnd; private TextView tvScheduleHourStart; @@ -165,6 +170,8 @@ public class FragmentRule extends FragmentBase { private int protocol = -1; private long folder = -1; + private DateFormat DF; + private final static int MAX_CHECK = 10; private static final int REQUEST_SENDER = 1; @@ -176,6 +183,8 @@ public class FragmentRule extends FragmentBase { private static final int REQUEST_TO = 7; private final static int REQUEST_TTS_CHECK = 8; private final static int REQUEST_TTS_DATA = 9; + private final static int REQUEST_DATE_AFTER = 10; + private final static int REQUEST_DATE_BEFORE = 11; @Override public void onCreate(Bundle savedInstanceState) { @@ -190,6 +199,8 @@ public class FragmentRule extends FragmentBase { account = args.getLong("account", -1); protocol = args.getInt("protocol", EntityAccount.TYPE_IMAP); folder = args.getLong("folder", -1); + + DF = Helper.getDateTimeInstance(getContext(), DateFormat.SHORT, DateFormat.SHORT); } @Override @@ -228,6 +239,11 @@ public class FragmentRule extends FragmentBase { etHeader = view.findViewById(R.id.etHeader); cbHeader = view.findViewById(R.id.cbHeader); + tvDateAfter = view.findViewById(R.id.tvDateAfter); + tvDateBefore = view.findViewById(R.id.tvDateBefore); + btnDateAfter = view.findViewById(R.id.btnDateAfter); + btnDateBefore = view.findViewById(R.id.btnDateBefore); + spScheduleDayStart = view.findViewById(R.id.spScheduleDayStart); spScheduleDayEnd = view.findViewById(R.id.spScheduleDayEnd); tvScheduleHourStart = view.findViewById(R.id.tvScheduleHourStart); @@ -309,6 +325,45 @@ public class FragmentRule extends FragmentBase { } }); + tvDateAfter.setText("-"); + tvDateBefore.setText("-"); + + btnDateAfter.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Bundle args = new Bundle(); + args.putString("title", getString(R.string.title_rule_date_after)); + args.putBoolean("day", true); + + Object time = tvDateAfter.getTag(); + if (time != null) + args.putLong("time", (long) time); + + FragmentDialogDuration fragment = new FragmentDialogDuration(); + fragment.setArguments(args); + fragment.setTargetFragment(FragmentRule.this, REQUEST_DATE_AFTER); + fragment.show(getParentFragmentManager(), "date:after"); + } + }); + + btnDateBefore.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Bundle args = new Bundle(); + args.putString("title", getString(R.string.title_rule_date_before)); + args.putBoolean("day", true); + + Object time = tvDateBefore.getTag(); + if (time != null) + args.putLong("time", (long) time); + + FragmentDialogDuration fragment = new FragmentDialogDuration(); + fragment.setArguments(args); + fragment.setTargetFragment(FragmentRule.this, REQUEST_DATE_BEFORE); + fragment.show(getParentFragmentManager(), "date:before"); + } + }); + adapterDay = new ArrayAdapter<>(getContext(), R.layout.spinner_item1, android.R.id.text1, new ArrayList()); adapterDay.setDropDownViewResource(R.layout.spinner_item1_dropdown); spScheduleDayStart.setAdapter(adapterDay); @@ -678,6 +733,14 @@ public class FragmentRule extends FragmentBase { break; case REQUEST_TTS_DATA: break; + case REQUEST_DATE_AFTER: + if (resultCode == RESULT_OK && data != null) + onDateAfter(data.getBundleExtra("args")); + break; + case REQUEST_DATE_BEFORE: + if (resultCode == RESULT_OK && data != null) + onDateBefore(data.getBundleExtra("args")); + break; } } catch (Throwable ex) { Log.e(ex); @@ -748,6 +811,24 @@ public class FragmentRule extends FragmentBase { cbScheduleEnd.setChecked(true); } + private void onDateAfter(Bundle args) { + boolean reset = args.getBoolean("reset"); + long time = args.getLong("time"); + if (reset) + time = 0; + tvDateAfter.setTag(time); + tvDateAfter.setText(time == 0 ? "-" : DF.format(time)); + } + + private void onDateBefore(Bundle args) { + boolean reset = args.getBoolean("reset"); + long time = args.getLong("time"); + if (reset) + time = 0; + tvDateBefore.setTag(time); + tvDateBefore.setText(time == 0 ? "-" : DF.format(time)); + } + private void loadRule(final Bundle savedInstanceState) { Bundle rargs = new Bundle(); rargs.putLong("id", copy < 0 ? id : copy); @@ -788,6 +869,7 @@ public class FragmentRule extends FragmentBase { JSONObject jrecipient = jcondition.optJSONObject("recipient"); JSONObject jsubject = jcondition.optJSONObject("subject"); JSONObject jheader = jcondition.optJSONObject("header"); + JSONObject jdate = jcondition.optJSONObject("date"); JSONObject jschedule = jcondition.optJSONObject("schedule"); etName.setText(rule == null ? args.getString("subject") : rule.name); @@ -815,6 +897,15 @@ public class FragmentRule extends FragmentBase { etHeader.setText(jheader == null ? null : jheader.getString("value")); cbHeader.setChecked(jheader != null && jheader.getBoolean("regex")); + long after = (jdate != null && jdate.has("after") ? jdate.getLong("after") : 0); + long before = (jdate != null && jdate.has("before") ? jdate.getLong("before") : 0); + + tvDateAfter.setTag(after); + tvDateAfter.setText(after == 0 ? "-" : DF.format(after)); + + tvDateBefore.setTag(before); + tvDateBefore.setText(before == 0 ? "-" : DF.format(before)); + int start = (jschedule != null && jschedule.has("start") ? jschedule.getInt("start") : 0); int end = (jschedule != null && jschedule.has("end") ? jschedule.getInt("end") : 0); @@ -1126,6 +1217,21 @@ public class FragmentRule extends FragmentBase { jcondition.put("header", jheader); } + Object hafter = tvDateAfter.getTag(); + Object hbefore = tvDateBefore.getTag(); + + long after = (hafter == null ? 0 : (long) hafter); + long before = (hbefore == null ? 0 : (long) hbefore); + + if (after != before) { + JSONObject jdate = new JSONObject(); + if (after != 0) + jdate.put("after", after); + if (before != 0) + jdate.put("before", before); + jcondition.put("date", jdate); + } + int dstart = spScheduleDayStart.getSelectedItemPosition(); int dend = spScheduleDayEnd.getSelectedItemPosition(); Object hstart = tvScheduleHourStart.getTag(); @@ -1264,7 +1370,7 @@ public class FragmentRule extends FragmentBase { return new TimePickerDialog(getContext(), this, cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE), - DateFormat.is24HourFormat(getContext())); + android.text.format.DateFormat.is24HourFormat(getContext())); } public void onTimeSet(TimePicker view, int hour, int minute) { diff --git a/app/src/main/res/layout/fragment_rule.xml b/app/src/main/res/layout/fragment_rule.xml index 297310f8a8..2d91af94bb 100644 --- a/app/src/main/res/layout/fragment_rule.xml +++ b/app/src/main/res/layout/fragment_rule.xml @@ -408,13 +408,95 @@ app:layout_constraintTop_toBottomOf="@+id/etHeader" /> + + + + +