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.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();

@ -136,7 +136,7 @@ public final class TaskEditFragment extends InjectingFragment
FragmentManager fragmentManager = getChildFragmentManager();
List<TaskEditControlFragment> taskEditControlFragments =
taskEditControlSetFragmentManager.getOrCreateFragments(fragmentManager, model);
taskEditControlSetFragmentManager.getOrCreateFragments(this, model);
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
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 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 <tim@todoroo.com>
*/
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<String> 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<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;
}
}
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);
}
}
}

@ -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<TaskEditControlFragment> getOrCreateFragments(
FragmentManager fragmentManager, Task task) {
TaskEditFragment taskEditFragment, Task task) {
Bundle arguments = new Bundle();
arguments.putParcelable(TaskEditControlFragment.EXTRA_TASK, task);
List<TaskEditControlFragment> fragments = new ArrayList<>();
FragmentManager fragmentManager = taskEditFragment.getChildFragmentManager();
for (int i = 0; i < numRows; i++) {
String tag = displayOrder.get(i);
TaskEditControlFragment fragment =

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

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

Loading…
Cancel
Save