Add BasicRecurrenceDialog

pull/513/head
Alex Baker 8 years ago
parent 73af733144
commit 3f5f825c22

@ -33,7 +33,6 @@ import com.todoroo.astrid.dao.TaskDao;
import com.todoroo.astrid.data.Task; import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.gtasks.GtasksListService; import com.todoroo.astrid.gtasks.GtasksListService;
import com.todoroo.astrid.gtasks.GtasksSubtaskListFragment; import com.todoroo.astrid.gtasks.GtasksSubtaskListFragment;
import com.todoroo.astrid.repeats.RepeatControlSet;
import com.todoroo.astrid.subtasks.SubtasksHelper; import com.todoroo.astrid.subtasks.SubtasksHelper;
import com.todoroo.astrid.subtasks.SubtasksListFragment; import com.todoroo.astrid.subtasks.SubtasksListFragment;
import com.todoroo.astrid.subtasks.SubtasksTagListFragment; import com.todoroo.astrid.subtasks.SubtasksTagListFragment;
@ -76,7 +75,6 @@ public class MainActivity extends InjectingAppCompatActivity
TaskListFragment.TaskListFragmentCallbackHandler, TaskListFragment.TaskListFragmentCallbackHandler,
PriorityControlSet.OnPriorityChanged, PriorityControlSet.OnPriorityChanged,
TimerControlSet.TimerControlSetCallback, TimerControlSet.TimerControlSetCallback,
RepeatControlSet.RepeatChangedListener,
DeadlineControlSet.DueDateChangeListener, DeadlineControlSet.DueDateChangeListener,
TaskEditFragment.TaskEditFragmentCallbackHandler, TaskEditFragment.TaskEditFragmentCallbackHandler,
CommentBarFragment.CommentBarFragmentCallback, CommentBarFragment.CommentBarFragmentCallback,
@ -431,11 +429,6 @@ public class MainActivity extends InjectingAppCompatActivity
getTaskEditFragment().onPriorityChange(priority); getTaskEditFragment().onPriorityChange(priority);
} }
@Override
public void repeatChanged(boolean repeat) {
getTaskEditFragment().onRepeatChanged(repeat);
}
@Override @Override
public Task stopTimer() { public Task stopTimer() {
return getTaskEditFragment().stopTimer(); return getTaskEditFragment().stopTimer();

@ -136,7 +136,7 @@ public final class TaskEditFragment extends InjectingFragment
FragmentManager fragmentManager = getChildFragmentManager(); FragmentManager fragmentManager = getChildFragmentManager();
List<TaskEditControlFragment> taskEditControlFragments = List<TaskEditControlFragment> taskEditControlFragments =
taskEditControlSetFragmentManager.getOrCreateFragments(fragmentManager, model); taskEditControlSetFragmentManager.getOrCreateFragments(this, model);
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
for (int i = 0; i < taskEditControlFragments.size(); i++) { for (int i = 0; i < taskEditControlFragments.size(); i++) {

@ -7,16 +7,10 @@ package com.todoroo.astrid.repeats;
import static android.support.v4.content.ContextCompat.getColor; import static android.support.v4.content.ContextCompat.getColor;
import static com.google.common.collect.Lists.newArrayList; 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.MONTHLY;
import static com.google.ical.values.Frequency.WEEKLY; import static org.tasks.repeats.BasicRecurrenceDialog.newBasicRecurrenceDialog;
import static com.google.ical.values.Frequency.YEARLY;
import static org.tasks.repeats.CustomRecurrenceDialog.newCustomRecurrenceDialog;
import static org.tasks.time.DateTimeUtils.currentTimeMillis; import static org.tasks.time.DateTimeUtils.currentTimeMillis;
import android.app.Activity;
import android.content.Context; import android.content.Context;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.os.Bundle; import android.os.Bundle;
@ -36,9 +30,9 @@ import butterknife.BindView;
import butterknife.OnClick; import butterknife.OnClick;
import butterknife.OnItemSelected; import butterknife.OnItemSelected;
import com.google.common.base.Strings; import com.google.common.base.Strings;
import com.google.ical.values.Frequency;
import com.google.ical.values.RRule; import com.google.ical.values.RRule;
import com.google.ical.values.WeekdayNum; import com.google.ical.values.WeekdayNum;
import com.todoroo.astrid.activity.TaskEditFragment;
import com.todoroo.astrid.data.Task; import com.todoroo.astrid.data.Task;
import java.text.ParseException; import java.text.ParseException;
import java.util.ArrayList; import java.util.ArrayList;
@ -47,16 +41,13 @@ import java.util.List;
import javax.inject.Inject; import javax.inject.Inject;
import org.tasks.R; import org.tasks.R;
import org.tasks.analytics.Tracker; import org.tasks.analytics.Tracker;
import org.tasks.analytics.Tracking;
import org.tasks.dialogs.DialogBuilder; import org.tasks.dialogs.DialogBuilder;
import org.tasks.injection.ForActivity; import org.tasks.injection.ForActivity;
import org.tasks.injection.FragmentComponent; import org.tasks.injection.FragmentComponent;
import org.tasks.repeats.CustomRecurrenceDialog;
import org.tasks.repeats.RepeatRuleToString; import org.tasks.repeats.RepeatRuleToString;
import org.tasks.themes.Theme; import org.tasks.themes.Theme;
import org.tasks.time.DateTime; import org.tasks.time.DateTime;
import org.tasks.ui.HiddenTopArrayAdapter; import org.tasks.ui.HiddenTopArrayAdapter;
import org.tasks.ui.SingleCheckedArrayAdapter;
import org.tasks.ui.TaskEditControlFragment; import org.tasks.ui.TaskEditControlFragment;
/** /**
@ -64,13 +55,12 @@ import org.tasks.ui.TaskEditControlFragment;
* *
* @author Tim Su <tim@todoroo.com> * @author Tim Su <tim@todoroo.com>
*/ */
public class RepeatControlSet extends TaskEditControlFragment public class RepeatControlSet extends TaskEditControlFragment {
implements CustomRecurrenceDialog.CustomRecurrenceCallback {
public static final int TAG = R.string.TEA_ctrl_repeat_pref; public static final int TAG = R.string.TEA_ctrl_repeat_pref;
private static final int TYPE_DUE_DATE = 1; private static final int TYPE_DUE_DATE = 1;
private static final int TYPE_COMPLETION_DATE = 2; 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_RECURRENCE = "extra_recurrence";
private static final String EXTRA_DUE_DATE = "extra_due_date"; private static final String EXTRA_DUE_DATE = "extra_due_date";
private static final String EXTRA_REPEAT_AFTER_COMPLETION = "extra_repeat_after_completion"; 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 RRule rrule;
private HiddenTopArrayAdapter<String> typeAdapter; private HiddenTopArrayAdapter<String> typeAdapter;
private long dueDate; private long dueDate;
private RepeatChangedListener callback;
private boolean repeatAfterCompletion; private boolean repeatAfterCompletion;
@Override
public void onSelected(RRule rrule) { public void onSelected(RRule rrule) {
this.rrule = rrule; this.rrule = rrule;
tracker.reportEvent(Tracking.Events.RECURRENCE_CUSTOM, rrule.toIcal());
refreshDisplayView(); refreshDisplayView();
} }
@ -199,109 +186,15 @@ public class RepeatControlSet extends TaskEditControlFragment
outState.putLong(EXTRA_DUE_DATE, dueDate); outState.putLong(EXTRA_DUE_DATE, dueDate);
} }
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
callback = (RepeatChangedListener) activity;
}
@Override @Override
protected void inject(FragmentComponent component) { protected void inject(FragmentComponent component) {
component.inject(this); 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) @OnClick(R.id.display_row_edit)
void openPopup(View view) { void openPopup(View view) {
boolean customPicked = isCustomValue(); newBasicRecurrenceDialog(this, rrule, dueDate)
List<String> repeatOptions = .show(getFragmentManager(), FRAG_TAG_BASIC_RECURRENCE);
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();
} }
@Override @Override
@ -359,10 +252,9 @@ public class RepeatControlSet extends TaskEditControlFragment
displayView.setText(repeatRuleToString.toString(rrule)); displayView.setText(repeatRuleToString.toString(rrule));
repeatTypeContainer.setVisibility(View.VISIBLE); repeatTypeContainer.setVisibility(View.VISIBLE);
} }
TaskEditFragment targetFragment = (TaskEditFragment) getParentFragment();
if (targetFragment != null) {
targetFragment.onRepeatChanged(rrule != null);
} }
public interface RepeatChangedListener {
void repeatChanged(boolean repeat);
} }
} }

@ -4,6 +4,7 @@ import android.app.Activity;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentManager;
import com.todoroo.astrid.activity.BeastModePreferences; import com.todoroo.astrid.activity.BeastModePreferences;
import com.todoroo.astrid.activity.TaskEditFragment;
import com.todoroo.astrid.data.Task; import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.files.FilesControlSet; import com.todoroo.astrid.files.FilesControlSet;
import com.todoroo.astrid.repeats.RepeatControlSet; import com.todoroo.astrid.repeats.RepeatControlSet;
@ -64,6 +65,7 @@ public class TaskEditControlSetFragmentManager {
}; };
static { static {
//noinspection ConstantConditions
if (BuildConfig.DEBUG if (BuildConfig.DEBUG
&& TASK_EDIT_CONTROL_FRAGMENT_ROWS.length != TASK_EDIT_CONTROL_SET_FRAGMENTS.length) { && TASK_EDIT_CONTROL_FRAGMENT_ROWS.length != TASK_EDIT_CONTROL_SET_FRAGMENTS.length) {
throw new AssertionError(); throw new AssertionError();
@ -106,11 +108,12 @@ public class TaskEditControlSetFragmentManager {
} }
public List<TaskEditControlFragment> getOrCreateFragments( public List<TaskEditControlFragment> getOrCreateFragments(
FragmentManager fragmentManager, Task task) { TaskEditFragment taskEditFragment, Task task) {
Bundle arguments = new Bundle(); Bundle arguments = new Bundle();
arguments.putParcelable(TaskEditControlFragment.EXTRA_TASK, task); arguments.putParcelable(TaskEditControlFragment.EXTRA_TASK, task);
List<TaskEditControlFragment> fragments = new ArrayList<>(); List<TaskEditControlFragment> fragments = new ArrayList<>();
FragmentManager fragmentManager = taskEditFragment.getChildFragmentManager();
for (int i = 0; i < numRows; i++) { for (int i = 0; i < numRows; i++) {
String tag = displayOrder.get(i); String tag = displayOrder.get(i);
TaskEditControlFragment fragment = TaskEditControlFragment fragment =

@ -13,6 +13,7 @@ import org.tasks.gtasks.RenameListDialog;
import org.tasks.reminders.MissedCallDialog; import org.tasks.reminders.MissedCallDialog;
import org.tasks.reminders.NotificationDialog; import org.tasks.reminders.NotificationDialog;
import org.tasks.reminders.SnoozeDialog; import org.tasks.reminders.SnoozeDialog;
import org.tasks.repeats.BasicRecurrenceDialog;
import org.tasks.repeats.CustomRecurrenceDialog; import org.tasks.repeats.CustomRecurrenceDialog;
@Subcomponent(modules = DialogFragmentModule.class) @Subcomponent(modules = DialogFragmentModule.class)
@ -43,4 +44,6 @@ public interface DialogFragmentComponent {
void inject(RenameListDialog renameListDialog); void inject(RenameListDialog renameListDialog);
void inject(CustomRecurrenceDialog customRecurrenceDialog); void inject(CustomRecurrenceDialog customRecurrenceDialog);
void inject(BasicRecurrenceDialog basicRecurrenceDialog);
} }

@ -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<String> 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);
}
}

@ -27,7 +27,6 @@ import android.graphics.drawable.StateListDrawable;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.view.ViewCompat; import android.support.v4.view.ViewCompat;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
@ -52,6 +51,7 @@ import com.google.ical.values.Weekday;
import com.google.ical.values.WeekdayNum; import com.google.ical.values.WeekdayNum;
import com.todoroo.andlib.utility.DateUtilities; import com.todoroo.andlib.utility.DateUtilities;
import com.todoroo.astrid.data.Task; import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.repeats.RepeatControlSet;
import java.text.DateFormatSymbols; import java.text.DateFormatSymbols;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Calendar; import java.util.Calendar;
@ -60,6 +60,8 @@ import java.util.List;
import javax.inject.Inject; import javax.inject.Inject;
import org.tasks.R; import org.tasks.R;
import org.tasks.activities.DatePickerActivity; import org.tasks.activities.DatePickerActivity;
import org.tasks.analytics.Tracker;
import org.tasks.analytics.Tracking;
import org.tasks.dialogs.DialogBuilder; import org.tasks.dialogs.DialogBuilder;
import org.tasks.injection.DialogFragmentComponent; import org.tasks.injection.DialogFragmentComponent;
import org.tasks.injection.ForActivity; import org.tasks.injection.ForActivity;
@ -80,6 +82,7 @@ public class CustomRecurrenceDialog extends InjectingDialogFragment {
@Inject @ForActivity Context context; @Inject @ForActivity Context context;
@Inject DialogBuilder dialogBuilder; @Inject DialogBuilder dialogBuilder;
@Inject Locale locale; @Inject Locale locale;
@Inject Tracker tracker;
@BindView(R.id.weekGroup) @BindView(R.id.weekGroup)
LinearLayout weekGroup1; LinearLayout weekGroup1;
@ -144,7 +147,7 @@ public class CustomRecurrenceDialog extends InjectingDialogFragment {
private RRule rrule; private RRule rrule;
public static CustomRecurrenceDialog newCustomRecurrenceDialog( public static CustomRecurrenceDialog newCustomRecurrenceDialog(
Fragment target, RRule rrule, long dueDate) { RepeatControlSet target, RRule rrule, long dueDate) {
CustomRecurrenceDialog dialog = new CustomRecurrenceDialog(); CustomRecurrenceDialog dialog = new CustomRecurrenceDialog();
dialog.setTargetFragment(target, 0); dialog.setTargetFragment(target, 0);
Bundle arguments = new Bundle(); Bundle arguments = new Bundle();
@ -379,7 +382,11 @@ public class CustomRecurrenceDialog extends InjectingDialogFragment {
} else { } else {
rrule.setByDay(Collections.emptyList()); 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(); dismiss();
} }
@ -563,9 +570,4 @@ public class CustomRecurrenceDialog extends InjectingDialogFragment {
protected void inject(DialogFragmentComponent component) { protected void inject(DialogFragmentComponent component) {
component.inject(this); component.inject(this);
} }
public interface CustomRecurrenceCallback {
void onSelected(RRule rrule);
}
} }

Loading…
Cancel
Save