From 3f5f825c227b68fcabf8f24b75274b39b7fd3f64 Mon Sep 17 00:00:00 2001 From: Alex Baker Date: Fri, 29 Jun 2018 10:18:48 -0500 Subject: [PATCH] Add BasicRecurrenceDialog --- .../todoroo/astrid/activity/MainActivity.java | 7 - .../astrid/activity/TaskEditFragment.java | 2 +- .../astrid/repeats/RepeatControlSet.java | 128 +------------ .../TaskEditControlSetFragmentManager.java | 5 +- .../injection/DialogFragmentComponent.java | 3 + .../tasks/repeats/BasicRecurrenceDialog.java | 173 ++++++++++++++++++ .../tasks/repeats/CustomRecurrenceDialog.java | 18 +- 7 files changed, 201 insertions(+), 135 deletions(-) create mode 100644 app/src/main/java/org/tasks/repeats/BasicRecurrenceDialog.java diff --git a/app/src/main/java/com/todoroo/astrid/activity/MainActivity.java b/app/src/main/java/com/todoroo/astrid/activity/MainActivity.java index 5dfb2b163..30ce86c96 100644 --- a/app/src/main/java/com/todoroo/astrid/activity/MainActivity.java +++ b/app/src/main/java/com/todoroo/astrid/activity/MainActivity.java @@ -33,7 +33,6 @@ import com.todoroo.astrid.dao.TaskDao; import com.todoroo.astrid.data.Task; import com.todoroo.astrid.gtasks.GtasksListService; import com.todoroo.astrid.gtasks.GtasksSubtaskListFragment; -import com.todoroo.astrid.repeats.RepeatControlSet; import com.todoroo.astrid.subtasks.SubtasksHelper; import com.todoroo.astrid.subtasks.SubtasksListFragment; import com.todoroo.astrid.subtasks.SubtasksTagListFragment; @@ -76,7 +75,6 @@ public class MainActivity extends InjectingAppCompatActivity TaskListFragment.TaskListFragmentCallbackHandler, PriorityControlSet.OnPriorityChanged, TimerControlSet.TimerControlSetCallback, - RepeatControlSet.RepeatChangedListener, DeadlineControlSet.DueDateChangeListener, TaskEditFragment.TaskEditFragmentCallbackHandler, CommentBarFragment.CommentBarFragmentCallback, @@ -431,11 +429,6 @@ public class MainActivity extends InjectingAppCompatActivity getTaskEditFragment().onPriorityChange(priority); } - @Override - public void repeatChanged(boolean repeat) { - getTaskEditFragment().onRepeatChanged(repeat); - } - @Override public Task stopTimer() { return getTaskEditFragment().stopTimer(); diff --git a/app/src/main/java/com/todoroo/astrid/activity/TaskEditFragment.java b/app/src/main/java/com/todoroo/astrid/activity/TaskEditFragment.java index 436812f8e..9303258a2 100755 --- a/app/src/main/java/com/todoroo/astrid/activity/TaskEditFragment.java +++ b/app/src/main/java/com/todoroo/astrid/activity/TaskEditFragment.java @@ -136,7 +136,7 @@ public final class TaskEditFragment extends InjectingFragment FragmentManager fragmentManager = getChildFragmentManager(); List taskEditControlFragments = - taskEditControlSetFragmentManager.getOrCreateFragments(fragmentManager, model); + taskEditControlSetFragmentManager.getOrCreateFragments(this, model); FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); for (int i = 0; i < taskEditControlFragments.size(); i++) { diff --git a/app/src/main/java/com/todoroo/astrid/repeats/RepeatControlSet.java b/app/src/main/java/com/todoroo/astrid/repeats/RepeatControlSet.java index c2e1fc6a8..ced7b86e9 100644 --- a/app/src/main/java/com/todoroo/astrid/repeats/RepeatControlSet.java +++ b/app/src/main/java/com/todoroo/astrid/repeats/RepeatControlSet.java @@ -7,16 +7,10 @@ package com.todoroo.astrid.repeats; import static android.support.v4.content.ContextCompat.getColor; import static com.google.common.collect.Lists.newArrayList; -import static com.google.ical.values.Frequency.DAILY; -import static com.google.ical.values.Frequency.HOURLY; -import static com.google.ical.values.Frequency.MINUTELY; import static com.google.ical.values.Frequency.MONTHLY; -import static com.google.ical.values.Frequency.WEEKLY; -import static com.google.ical.values.Frequency.YEARLY; -import static org.tasks.repeats.CustomRecurrenceDialog.newCustomRecurrenceDialog; +import static org.tasks.repeats.BasicRecurrenceDialog.newBasicRecurrenceDialog; import static org.tasks.time.DateTimeUtils.currentTimeMillis; -import android.app.Activity; import android.content.Context; import android.graphics.drawable.Drawable; import android.os.Bundle; @@ -36,9 +30,9 @@ import butterknife.BindView; import butterknife.OnClick; import butterknife.OnItemSelected; import com.google.common.base.Strings; -import com.google.ical.values.Frequency; import com.google.ical.values.RRule; import com.google.ical.values.WeekdayNum; +import com.todoroo.astrid.activity.TaskEditFragment; import com.todoroo.astrid.data.Task; import java.text.ParseException; import java.util.ArrayList; @@ -47,16 +41,13 @@ import java.util.List; import javax.inject.Inject; import org.tasks.R; import org.tasks.analytics.Tracker; -import org.tasks.analytics.Tracking; import org.tasks.dialogs.DialogBuilder; import org.tasks.injection.ForActivity; import org.tasks.injection.FragmentComponent; -import org.tasks.repeats.CustomRecurrenceDialog; import org.tasks.repeats.RepeatRuleToString; import org.tasks.themes.Theme; import org.tasks.time.DateTime; import org.tasks.ui.HiddenTopArrayAdapter; -import org.tasks.ui.SingleCheckedArrayAdapter; import org.tasks.ui.TaskEditControlFragment; /** @@ -64,13 +55,12 @@ import org.tasks.ui.TaskEditControlFragment; * * @author Tim Su */ -public class RepeatControlSet extends TaskEditControlFragment - implements CustomRecurrenceDialog.CustomRecurrenceCallback { +public class RepeatControlSet extends TaskEditControlFragment { public static final int TAG = R.string.TEA_ctrl_repeat_pref; private static final int TYPE_DUE_DATE = 1; private static final int TYPE_COMPLETION_DATE = 2; - private static final String FRAG_TAG_CUSTOM_RECURRENCE = "frag_tag_custom_recurrence"; + private static final String FRAG_TAG_BASIC_RECURRENCE = "frag_tag_basic_recurrence"; private static final String EXTRA_RECURRENCE = "extra_recurrence"; private static final String EXTRA_DUE_DATE = "extra_due_date"; private static final String EXTRA_REPEAT_AFTER_COMPLETION = "extra_repeat_after_completion"; @@ -93,13 +83,10 @@ public class RepeatControlSet extends TaskEditControlFragment private RRule rrule; private HiddenTopArrayAdapter typeAdapter; private long dueDate; - private RepeatChangedListener callback; private boolean repeatAfterCompletion; - @Override public void onSelected(RRule rrule) { this.rrule = rrule; - tracker.reportEvent(Tracking.Events.RECURRENCE_CUSTOM, rrule.toIcal()); refreshDisplayView(); } @@ -199,109 +186,15 @@ public class RepeatControlSet extends TaskEditControlFragment outState.putLong(EXTRA_DUE_DATE, dueDate); } - @Override - public void onAttach(Activity activity) { - super.onAttach(activity); - - callback = (RepeatChangedListener) activity; - } - @Override protected void inject(FragmentComponent component) { component.inject(this); } - private boolean isCustomValue() { - if (rrule == null) { - return false; - } - Frequency frequency = rrule.getFreq(); - return (frequency == WEEKLY || frequency == MONTHLY) && !rrule.getByDay().isEmpty() - || frequency == HOURLY - || frequency == MINUTELY - || rrule.getUntil() != null - || rrule.getInterval() != 1 - || rrule.getCount() != 0; - } - @OnClick(R.id.display_row_edit) void openPopup(View view) { - boolean customPicked = isCustomValue(); - List repeatOptions = - newArrayList(context.getResources().getStringArray(R.array.repeat_options)); - SingleCheckedArrayAdapter adapter = - new SingleCheckedArrayAdapter(context, repeatOptions, theme.getThemeAccent()); - int selected = 0; - if (customPicked) { - adapter.insert(repeatRuleToString.toString(rrule), 0); - } else if (rrule != null) { - switch (rrule.getFreq()) { - case DAILY: - selected = 1; - break; - case WEEKLY: - selected = 2; - break; - case MONTHLY: - selected = 3; - break; - case YEARLY: - selected = 4; - break; - default: - selected = 0; - break; - } - } - dialogBuilder - .newDialog() - .setSingleChoiceItems( - adapter, - selected, - (dialogInterface, i) -> { - if (customPicked) { - if (i == 0) { - dialogInterface.dismiss(); - return; - } - i--; - } - if (i == 0) { - rrule = null; - } else if (i == 5) { - newCustomRecurrenceDialog(this, rrule, dueDate) - .show(getFragmentManager(), FRAG_TAG_CUSTOM_RECURRENCE); - dialogInterface.dismiss(); - return; - } else { - rrule = new RRule(); - rrule.setInterval(1); - repeatAfterCompletion = false; - - switch (i) { - case 1: - rrule.setFreq(DAILY); - break; - case 2: - rrule.setFreq(WEEKLY); - break; - case 3: - rrule.setFreq(MONTHLY); - break; - case 4: - rrule.setFreq(YEARLY); - break; - } - - tracker.reportEvent(Tracking.Events.RECURRENCE_PRESET, rrule.toIcal()); - } - - callback.repeatChanged(rrule != null); - refreshDisplayView(); - dialogInterface.dismiss(); - }) - .setOnCancelListener(d -> refreshDisplayView()) - .show(); + newBasicRecurrenceDialog(this, rrule, dueDate) + .show(getFragmentManager(), FRAG_TAG_BASIC_RECURRENCE); } @Override @@ -359,10 +252,9 @@ public class RepeatControlSet extends TaskEditControlFragment displayView.setText(repeatRuleToString.toString(rrule)); repeatTypeContainer.setVisibility(View.VISIBLE); } - } - - public interface RepeatChangedListener { - - void repeatChanged(boolean repeat); + TaskEditFragment targetFragment = (TaskEditFragment) getParentFragment(); + if (targetFragment != null) { + targetFragment.onRepeatChanged(rrule != null); + } } } diff --git a/app/src/main/java/org/tasks/fragments/TaskEditControlSetFragmentManager.java b/app/src/main/java/org/tasks/fragments/TaskEditControlSetFragmentManager.java index d4376241d..5214db97f 100644 --- a/app/src/main/java/org/tasks/fragments/TaskEditControlSetFragmentManager.java +++ b/app/src/main/java/org/tasks/fragments/TaskEditControlSetFragmentManager.java @@ -4,6 +4,7 @@ import android.app.Activity; import android.os.Bundle; import android.support.v4.app.FragmentManager; import com.todoroo.astrid.activity.BeastModePreferences; +import com.todoroo.astrid.activity.TaskEditFragment; import com.todoroo.astrid.data.Task; import com.todoroo.astrid.files.FilesControlSet; import com.todoroo.astrid.repeats.RepeatControlSet; @@ -64,6 +65,7 @@ public class TaskEditControlSetFragmentManager { }; static { + //noinspection ConstantConditions if (BuildConfig.DEBUG && TASK_EDIT_CONTROL_FRAGMENT_ROWS.length != TASK_EDIT_CONTROL_SET_FRAGMENTS.length) { throw new AssertionError(); @@ -106,11 +108,12 @@ public class TaskEditControlSetFragmentManager { } public List getOrCreateFragments( - FragmentManager fragmentManager, Task task) { + TaskEditFragment taskEditFragment, Task task) { Bundle arguments = new Bundle(); arguments.putParcelable(TaskEditControlFragment.EXTRA_TASK, task); List fragments = new ArrayList<>(); + FragmentManager fragmentManager = taskEditFragment.getChildFragmentManager(); for (int i = 0; i < numRows; i++) { String tag = displayOrder.get(i); TaskEditControlFragment fragment = diff --git a/app/src/main/java/org/tasks/injection/DialogFragmentComponent.java b/app/src/main/java/org/tasks/injection/DialogFragmentComponent.java index d54de6053..a7336715f 100644 --- a/app/src/main/java/org/tasks/injection/DialogFragmentComponent.java +++ b/app/src/main/java/org/tasks/injection/DialogFragmentComponent.java @@ -13,6 +13,7 @@ import org.tasks.gtasks.RenameListDialog; import org.tasks.reminders.MissedCallDialog; import org.tasks.reminders.NotificationDialog; import org.tasks.reminders.SnoozeDialog; +import org.tasks.repeats.BasicRecurrenceDialog; import org.tasks.repeats.CustomRecurrenceDialog; @Subcomponent(modules = DialogFragmentModule.class) @@ -43,4 +44,6 @@ public interface DialogFragmentComponent { void inject(RenameListDialog renameListDialog); void inject(CustomRecurrenceDialog customRecurrenceDialog); + + void inject(BasicRecurrenceDialog basicRecurrenceDialog); } diff --git a/app/src/main/java/org/tasks/repeats/BasicRecurrenceDialog.java b/app/src/main/java/org/tasks/repeats/BasicRecurrenceDialog.java new file mode 100644 index 000000000..63ac7112c --- /dev/null +++ b/app/src/main/java/org/tasks/repeats/BasicRecurrenceDialog.java @@ -0,0 +1,173 @@ +package org.tasks.repeats; + +import static com.google.common.collect.Lists.newArrayList; +import static com.google.ical.values.Frequency.DAILY; +import static com.google.ical.values.Frequency.HOURLY; +import static com.google.ical.values.Frequency.MINUTELY; +import static com.google.ical.values.Frequency.MONTHLY; +import static com.google.ical.values.Frequency.WEEKLY; +import static com.google.ical.values.Frequency.YEARLY; +import static org.tasks.repeats.CustomRecurrenceDialog.newCustomRecurrenceDialog; +import static org.tasks.time.DateTimeUtils.currentTimeMillis; + +import android.app.Dialog; +import android.content.Context; +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import com.google.common.base.Strings; +import com.google.ical.values.Frequency; +import com.google.ical.values.RRule; +import com.todoroo.astrid.repeats.RepeatControlSet; +import java.util.List; +import javax.inject.Inject; +import org.tasks.R; +import org.tasks.analytics.Tracker; +import org.tasks.analytics.Tracking; +import org.tasks.dialogs.DialogBuilder; +import org.tasks.injection.DialogFragmentComponent; +import org.tasks.injection.ForActivity; +import org.tasks.injection.InjectingDialogFragment; +import org.tasks.themes.Theme; +import org.tasks.ui.SingleCheckedArrayAdapter; +import timber.log.Timber; + +public class BasicRecurrenceDialog extends InjectingDialogFragment { + + private static final String EXTRA_RRULE = "extra_rrule"; + private static final String EXTRA_DATE = "extra_date"; + private static final String FRAG_TAG_CUSTOM_RECURRENCE = "frag_tag_custom_recurrence"; + + @Inject @ForActivity Context context; + @Inject DialogBuilder dialogBuilder; + @Inject RepeatRuleToString repeatRuleToString; + @Inject Theme theme; + @Inject Tracker tracker; + + public static BasicRecurrenceDialog newBasicRecurrenceDialog( + RepeatControlSet target, RRule rrule, long dueDate) { + BasicRecurrenceDialog dialog = new BasicRecurrenceDialog(); + dialog.setTargetFragment(target, 0); + Bundle arguments = new Bundle(); + if (rrule != null) { + arguments.putString(EXTRA_RRULE, rrule.toIcal()); + } + arguments.putLong(EXTRA_DATE, dueDate); + dialog.setArguments(arguments); + return dialog; + } + + @NonNull + @Override + public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) { + Bundle arguments = getArguments(); + long dueDate = arguments.getLong(EXTRA_DATE, currentTimeMillis()); + String rule = arguments.getString(EXTRA_RRULE); + RRule parsed = null; + try { + if (!Strings.isNullOrEmpty(rule)) { + parsed = new RRule(rule); + } + } catch (Exception e) { + Timber.e(e); + } + RRule rrule = parsed; + + boolean customPicked = isCustomValue(rrule); + List repeatOptions = + newArrayList(context.getResources().getStringArray(R.array.repeat_options)); + SingleCheckedArrayAdapter adapter = + new SingleCheckedArrayAdapter(context, repeatOptions, theme.getThemeAccent()); + int selected = 0; + if (customPicked) { + adapter.insert(repeatRuleToString.toString(rrule), 0); + } else if (rrule != null) { + switch (rrule.getFreq()) { + case DAILY: + selected = 1; + break; + case WEEKLY: + selected = 2; + break; + case MONTHLY: + selected = 3; + break; + case YEARLY: + selected = 4; + break; + default: + selected = 0; + break; + } + } + return dialogBuilder + .newDialog() + .setSingleChoiceItems( + adapter, + selected, + (dialogInterface, i) -> { + if (customPicked) { + if (i == 0) { + dialogInterface.dismiss(); + return; + } + i--; + } + RRule result; + if (i == 0) { + result = null; + } else if (i == 5) { + newCustomRecurrenceDialog((RepeatControlSet) getTargetFragment(), rrule, dueDate) + .show(getFragmentManager(), FRAG_TAG_CUSTOM_RECURRENCE); + dialogInterface.dismiss(); + return; + } else { + result = new RRule(); + result.setInterval(1); + + switch (i) { + case 1: + result.setFreq(DAILY); + break; + case 2: + result.setFreq(WEEKLY); + break; + case 3: + result.setFreq(MONTHLY); + break; + case 4: + result.setFreq(YEARLY); + break; + } + + tracker.reportEvent(Tracking.Events.RECURRENCE_PRESET, result.toIcal()); + } + + RepeatControlSet target = (RepeatControlSet) getTargetFragment(); + if (target != null) { + target.onSelected(result); + } + dialogInterface.dismiss(); + }) + .setOnCancelListener(null) + .show(); + } + + private boolean isCustomValue(RRule rrule) { + if (rrule == null) { + return false; + } + Frequency frequency = rrule.getFreq(); + return (frequency == WEEKLY || frequency == MONTHLY) && !rrule.getByDay().isEmpty() + || frequency == HOURLY + || frequency == MINUTELY + || rrule.getUntil() != null + || rrule.getInterval() != 1 + || rrule.getCount() != 0; + } + + @Override + protected void inject(DialogFragmentComponent component) { + component.inject(this); + } +} diff --git a/app/src/main/java/org/tasks/repeats/CustomRecurrenceDialog.java b/app/src/main/java/org/tasks/repeats/CustomRecurrenceDialog.java index 43a002129..f42328846 100644 --- a/app/src/main/java/org/tasks/repeats/CustomRecurrenceDialog.java +++ b/app/src/main/java/org/tasks/repeats/CustomRecurrenceDialog.java @@ -27,7 +27,6 @@ import android.graphics.drawable.StateListDrawable; import android.os.Bundle; import android.support.annotation.NonNull; import android.support.annotation.Nullable; -import android.support.v4.app.Fragment; import android.support.v4.view.ViewCompat; import android.view.LayoutInflater; import android.view.View; @@ -52,6 +51,7 @@ import com.google.ical.values.Weekday; import com.google.ical.values.WeekdayNum; import com.todoroo.andlib.utility.DateUtilities; import com.todoroo.astrid.data.Task; +import com.todoroo.astrid.repeats.RepeatControlSet; import java.text.DateFormatSymbols; import java.util.ArrayList; import java.util.Calendar; @@ -60,6 +60,8 @@ import java.util.List; import javax.inject.Inject; import org.tasks.R; import org.tasks.activities.DatePickerActivity; +import org.tasks.analytics.Tracker; +import org.tasks.analytics.Tracking; import org.tasks.dialogs.DialogBuilder; import org.tasks.injection.DialogFragmentComponent; import org.tasks.injection.ForActivity; @@ -80,6 +82,7 @@ public class CustomRecurrenceDialog extends InjectingDialogFragment { @Inject @ForActivity Context context; @Inject DialogBuilder dialogBuilder; @Inject Locale locale; + @Inject Tracker tracker; @BindView(R.id.weekGroup) LinearLayout weekGroup1; @@ -144,7 +147,7 @@ public class CustomRecurrenceDialog extends InjectingDialogFragment { private RRule rrule; public static CustomRecurrenceDialog newCustomRecurrenceDialog( - Fragment target, RRule rrule, long dueDate) { + RepeatControlSet target, RRule rrule, long dueDate) { CustomRecurrenceDialog dialog = new CustomRecurrenceDialog(); dialog.setTargetFragment(target, 0); Bundle arguments = new Bundle(); @@ -379,7 +382,11 @@ public class CustomRecurrenceDialog extends InjectingDialogFragment { } else { rrule.setByDay(Collections.emptyList()); } - ((CustomRecurrenceCallback) getTargetFragment()).onSelected(rrule); + tracker.reportEvent(Tracking.Events.RECURRENCE_CUSTOM, rrule.toIcal()); + RepeatControlSet target = (RepeatControlSet) getTargetFragment(); + if (target != null) { + target.onSelected(rrule); + } dismiss(); } @@ -563,9 +570,4 @@ public class CustomRecurrenceDialog extends InjectingDialogFragment { protected void inject(DialogFragmentComponent component) { component.inject(this); } - - public interface CustomRecurrenceCallback { - - void onSelected(RRule rrule); - } }