Update remote list picker when batch moving

* Hide batch move when sync not enabled
* Show selection if source tasks belong to the same list
* No selection if source tasks belong to disparate lists
pull/699/head
Alex Baker 8 years ago
parent c96e518885
commit 6c5319cf9b

@ -525,9 +525,10 @@ public class TaskListFragment extends InjectingFragment
} }
} else if (requestCode == REQUEST_MOVE_TASKS) { } else if (requestCode == REQUEST_MOVE_TASKS) {
if (resultCode == RESULT_OK) { if (resultCode == RESULT_OK) {
tracker.reportEvent(Tracking.Events.MULTISELECT_MOVE);
taskMover.move( taskMover.move(
taskAdapter.getSelected(), taskAdapter.getSelected(),
data.getParcelableExtra(RemoteListSupportPicker.EXTRA_SELECTED)); data.getParcelableExtra(RemoteListSupportPicker.EXTRA_SELECTED_FILTER));
recyclerAdapter.finishActionMode(); recyclerAdapter.finishActionMode();
} }
} else { } else {

@ -183,8 +183,9 @@ public class FilterAdapter extends ArrayAdapter<FilterListItem> {
this.selected = selected; this.selected = selected;
} }
public int indexOf(FilterListItem item) { public int indexOf(FilterListItem item, int defaultValue) {
return items.indexOf(item); int index = items.indexOf(item);
return index == -1 ? defaultValue : index;
} }
@NonNull @NonNull

@ -15,6 +15,7 @@ import org.tasks.data.CaldavDao;
import org.tasks.data.CaldavTask; import org.tasks.data.CaldavTask;
import org.tasks.data.GoogleTask; import org.tasks.data.GoogleTask;
import org.tasks.data.GoogleTaskDao; import org.tasks.data.GoogleTaskDao;
import org.tasks.data.GoogleTaskListDao;
import org.tasks.sync.SyncAdapters; import org.tasks.sync.SyncAdapters;
public class TaskMover { public class TaskMover {
@ -22,13 +23,20 @@ public class TaskMover {
private final CaldavDao caldavDao; private final CaldavDao caldavDao;
private final GoogleTaskDao googleTaskDao; private final GoogleTaskDao googleTaskDao;
private final SyncAdapters syncAdapters; private final SyncAdapters syncAdapters;
private final GoogleTaskListDao googleTaskListDao;
@Inject @Inject
public TaskMover(TaskDao taskDao, CaldavDao caldavDao, GoogleTaskDao googleTaskDao, SyncAdapters syncAdapters) { public TaskMover(
TaskDao taskDao,
CaldavDao caldavDao,
GoogleTaskDao googleTaskDao,
SyncAdapters syncAdapters,
GoogleTaskListDao googleTaskListDao) {
this.taskDao = taskDao; this.taskDao = taskDao;
this.caldavDao = caldavDao; this.caldavDao = caldavDao;
this.googleTaskDao = googleTaskDao; this.googleTaskDao = googleTaskDao;
this.syncAdapters = syncAdapters; this.syncAdapters = syncAdapters;
this.googleTaskListDao = googleTaskListDao;
} }
public void move(List<Long> tasks, Filter selectedList) { public void move(List<Long> tasks, Filter selectedList) {
@ -46,6 +54,21 @@ public class TaskMover {
performMove(task, selectedList); performMove(task, selectedList);
} }
public Filter getSingleFilter(List<Long> tasks) {
List<String> caldavCalendars = caldavDao.getCalendars(tasks);
List<String> googleTaskLists = googleTaskDao.getLists(tasks);
if (caldavCalendars.isEmpty()) {
if (googleTaskLists.size() == 1) {
return new GtasksFilter(googleTaskListDao.getByRemoteId(googleTaskLists.get(0)));
}
} else if (googleTaskLists.isEmpty()) {
if (caldavCalendars.size() == 1) {
return new CaldavFilter(caldavDao.getCalendar(caldavCalendars.get(0)));
}
}
return null;
}
private void performMove(Task task, Filter selectedList) { private void performMove(Task task, Filter selectedList) {
long id = task.getId(); long id = task.getId();
GoogleTask googleTask = googleTaskDao.getByTaskId(id); GoogleTask googleTask = googleTaskDao.getByTaskId(id);

@ -35,7 +35,7 @@ public class FilterSelectionActivity extends InjectingAppCompatActivity {
.newDialog() .newDialog()
.setSingleChoiceItems( .setSingleChoiceItems(
filterAdapter, filterAdapter,
filterAdapter.indexOf(selected), filterAdapter.indexOf(selected, -1),
(dialog, which) -> { (dialog, which) -> {
final Filter selectedFilter = (Filter) filterAdapter.getItem(which); final Filter selectedFilter = (Filter) filterAdapter.getItem(which);
Intent data = new Intent(); Intent data = new Intent();

@ -32,8 +32,8 @@ public class RemoteListNativePicker extends InjectingNativeDialogFragment {
@Override @Override
public Dialog onCreateDialog(Bundle savedInstanceState) { public Dialog onCreateDialog(Bundle savedInstanceState) {
Bundle arguments = getArguments(); filterAdapter.populateRemoteListPicker();
Filter selected = arguments.getParcelable(EXTRA_SELECTED); int selected = filterAdapter.indexOf(getArguments().getParcelable(EXTRA_SELECTED), 0);
return createDialog(filterAdapter, dialogBuilder, selected, list -> handler.selectedList(list)); return createDialog(filterAdapter, dialogBuilder, selected, list -> handler.selectedList(list));
} }

@ -20,7 +20,8 @@ import org.tasks.injection.InjectingDialogFragment;
public class RemoteListSupportPicker extends InjectingDialogFragment { public class RemoteListSupportPicker extends InjectingDialogFragment {
public static final String EXTRA_SELECTED = "extra_selected"; public static final String EXTRA_SELECTED_FILTER = "extra_selected_filter";
private static final String EXTRA_NO_SELECTION = "extra_no_selection";
@Inject DialogBuilder dialogBuilder; @Inject DialogBuilder dialogBuilder;
@Inject FilterAdapter filterAdapter; @Inject FilterAdapter filterAdapter;
@ -29,9 +30,17 @@ public class RemoteListSupportPicker extends InjectingDialogFragment {
Filter selected, Fragment targetFragment, int requestCode) { Filter selected, Fragment targetFragment, int requestCode) {
RemoteListSupportPicker dialog = new RemoteListSupportPicker(); RemoteListSupportPicker dialog = new RemoteListSupportPicker();
Bundle arguments = new Bundle(); Bundle arguments = new Bundle();
if (selected != null) { arguments.putParcelable(EXTRA_SELECTED_FILTER, selected);
arguments.putParcelable(EXTRA_SELECTED, selected); dialog.setArguments(arguments);
dialog.setTargetFragment(targetFragment, requestCode);
return dialog;
} }
public static RemoteListSupportPicker newRemoteListSupportPicker(
Fragment targetFragment, int requestCode) {
RemoteListSupportPicker dialog = new RemoteListSupportPicker();
Bundle arguments = new Bundle();
arguments.putBoolean(EXTRA_NO_SELECTION, true);
dialog.setArguments(arguments); dialog.setArguments(arguments);
dialog.setTargetFragment(targetFragment, requestCode); dialog.setTargetFragment(targetFragment, requestCode);
return dialog; return dialog;
@ -40,10 +49,8 @@ public class RemoteListSupportPicker extends InjectingDialogFragment {
public static AlertDialog createDialog( public static AlertDialog createDialog(
FilterAdapter filterAdapter, FilterAdapter filterAdapter,
DialogBuilder dialogBuilder, DialogBuilder dialogBuilder,
Filter selected, int selectedIndex,
RemoteListSelectionHandler handler) { RemoteListSelectionHandler handler) {
filterAdapter.populateRemoteListPicker();
int selectedIndex = selected == null ? 0 : filterAdapter.indexOf(selected);
return dialogBuilder return dialogBuilder
.newDialog() .newDialog()
.setSingleChoiceItems( .setSingleChoiceItems(
@ -66,8 +73,11 @@ public class RemoteListSupportPicker extends InjectingDialogFragment {
@NonNull @NonNull
@Override @Override
public Dialog onCreateDialog(Bundle savedInstanceState) { public Dialog onCreateDialog(Bundle savedInstanceState) {
filterAdapter.populateRemoteListPicker();
Bundle arguments = getArguments(); Bundle arguments = getArguments();
Filter selected = arguments == null ? null : arguments.getParcelable(EXTRA_SELECTED); int selected =
arguments.getBoolean(EXTRA_NO_SELECTION, false)
? -1 : filterAdapter.indexOf(arguments.getParcelable(EXTRA_SELECTED_FILTER), 0);
return createDialog(filterAdapter, dialogBuilder, selected, this::selected); return createDialog(filterAdapter, dialogBuilder, selected, this::selected);
} }
@ -76,7 +86,7 @@ public class RemoteListSupportPicker extends InjectingDialogFragment {
.onActivityResult( .onActivityResult(
getTargetRequestCode(), getTargetRequestCode(),
Activity.RESULT_OK, Activity.RESULT_OK,
new Intent().putExtra(EXTRA_SELECTED, filter)); new Intent().putExtra(EXTRA_SELECTED_FILTER, filter));
} }
@Override @Override

@ -28,6 +28,7 @@ public class Tracking {
MULTISELECT_DELETE( MULTISELECT_DELETE(
R.string.tracking_category_event, R.string.tracking_event_multiselect_delete), R.string.tracking_category_event, R.string.tracking_event_multiselect_delete),
MULTISELECT_CLONE(R.string.tracking_category_event, R.string.tracking_event_multiselect_clone), MULTISELECT_CLONE(R.string.tracking_category_event, R.string.tracking_event_multiselect_clone),
MULTISELECT_MOVE(R.string.tracking_category_event, R.string.tracking_event_multiselect_clone),
CLEAR_COMPLETED(R.string.tracking_category_event, R.string.tracking_action_clear_completed), CLEAR_COMPLETED(R.string.tracking_category_event, R.string.tracking_action_clear_completed),
UPGRADE(R.string.tracking_category_event, R.string.tracking_event_upgrade), UPGRADE(R.string.tracking_category_event, R.string.tracking_event_upgrade),
DB_OPEN_FAILED(R.string.tracking_category_error, R.string.tracking_event_db_open), DB_OPEN_FAILED(R.string.tracking_category_error, R.string.tracking_event_db_open),

@ -100,4 +100,7 @@ public interface CaldavDao {
@Query("SELECT * FROM caldav_account WHERE name = :name COLLATE NOCASE LIMIT 1") @Query("SELECT * FROM caldav_account WHERE name = :name COLLATE NOCASE LIMIT 1")
CaldavAccount getAccountByName(String name); CaldavAccount getAccountByName(String name);
@Query("SELECT DISTINCT calendar FROM caldav_tasks WHERE deleted = 0 AND task IN (:tasks)")
List<String> getCalendars(List<Long> tasks);
} }

@ -51,4 +51,7 @@ public interface GoogleTaskDao {
@Query("DELETE FROM google_tasks") @Query("DELETE FROM google_tasks")
void deleteAll(); void deleteAll();
@Query("SELECT DISTINCT list_id FROM google_tasks WHERE deleted = 0 AND task IN (:tasks)")
List<String> getLists(List<Long> tasks);
} }

@ -1,5 +1,6 @@
package org.tasks.tasklist; package org.tasks.tasklist;
import static com.todoroo.astrid.activity.TaskListFragment.REQUEST_MOVE_TASKS;
import static org.tasks.activities.RemoteListSupportPicker.newRemoteListSupportPicker; import static org.tasks.activities.RemoteListSupportPicker.newRemoteListSupportPicker;
import android.content.Context; import android.content.Context;
@ -10,9 +11,11 @@ import android.view.MenuItem;
import com.todoroo.astrid.activity.TaskListActivity; import com.todoroo.astrid.activity.TaskListActivity;
import com.todoroo.astrid.activity.TaskListFragment; import com.todoroo.astrid.activity.TaskListFragment;
import com.todoroo.astrid.adapter.TaskAdapter; import com.todoroo.astrid.adapter.TaskAdapter;
import com.todoroo.astrid.api.Filter;
import com.todoroo.astrid.data.Task; import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.service.TaskDeleter; import com.todoroo.astrid.service.TaskDeleter;
import com.todoroo.astrid.service.TaskDuplicator; import com.todoroo.astrid.service.TaskDuplicator;
import com.todoroo.astrid.service.TaskMover;
import java.util.List; import java.util.List;
import javax.inject.Inject; import javax.inject.Inject;
import org.tasks.R; import org.tasks.R;
@ -20,6 +23,7 @@ import org.tasks.analytics.Tracker;
import org.tasks.analytics.Tracking; 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.sync.SyncAdapters;
import org.tasks.ui.MenuColorizer; import org.tasks.ui.MenuColorizer;
public class ActionModeProvider { public class ActionModeProvider {
@ -30,7 +34,9 @@ public class ActionModeProvider {
private final DialogBuilder dialogBuilder; private final DialogBuilder dialogBuilder;
private final TaskDeleter taskDeleter; private final TaskDeleter taskDeleter;
private final TaskDuplicator taskDuplicator; private final TaskDuplicator taskDuplicator;
private final TaskMover taskMover;
private final Tracker tracker; private final Tracker tracker;
private final SyncAdapters syncAdapters;
@Inject @Inject
public ActionModeProvider( public ActionModeProvider(
@ -38,12 +44,17 @@ public class ActionModeProvider {
DialogBuilder dialogBuilder, DialogBuilder dialogBuilder,
TaskDeleter taskDeleter, TaskDeleter taskDeleter,
TaskDuplicator taskDuplicator, TaskDuplicator taskDuplicator,
Tracker tracker) { TaskMover taskMover,
Tracker tracker,
SyncAdapters syncAdapters
) {
this.context = context; this.context = context;
this.dialogBuilder = dialogBuilder; this.dialogBuilder = dialogBuilder;
this.taskDeleter = taskDeleter; this.taskDeleter = taskDeleter;
this.taskDuplicator = taskDuplicator; this.taskDuplicator = taskDuplicator;
this.taskMover = taskMover;
this.tracker = tracker; this.tracker = tracker;
this.syncAdapters = syncAdapters;
} }
public ActionMode startActionMode( public ActionMode startActionMode(
@ -57,6 +68,9 @@ public class ActionModeProvider {
public boolean onCreateActionMode(ActionMode actionMode, Menu menu) { public boolean onCreateActionMode(ActionMode actionMode, Menu menu) {
MenuInflater inflater = actionMode.getMenuInflater(); MenuInflater inflater = actionMode.getMenuInflater();
inflater.inflate(R.menu.menu_multi_select, menu); inflater.inflate(R.menu.menu_multi_select, menu);
if (!syncAdapters.isSyncEnabled()) {
menu.findItem(R.id.move_tasks).setVisible(false);
}
MenuColorizer.colorMenu(context, menu); MenuColorizer.colorMenu(context, menu);
return true; return true;
} }
@ -70,7 +84,10 @@ public class ActionModeProvider {
public boolean onActionItemClicked(ActionMode mode, MenuItem item) { public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()) { switch (item.getItemId()) {
case R.id.move_tasks: case R.id.move_tasks:
newRemoteListSupportPicker(null, taskList, TaskListFragment.REQUEST_MOVE_TASKS) Filter singleFilter = taskMover.getSingleFilter(adapter.getSelected());
(singleFilter == null
? newRemoteListSupportPicker(taskList, REQUEST_MOVE_TASKS)
: newRemoteListSupportPicker(singleFilter, taskList, REQUEST_MOVE_TASKS))
.show(taskList.getFragmentManager(), FRAG_TAG_REMOTE_LIST_PICKER); .show(taskList.getFragmentManager(), FRAG_TAG_REMOTE_LIST_PICKER);
return true; return true;
case R.id.delete: case R.id.delete:

@ -141,7 +141,7 @@ public class RemoteListFragment extends TaskEditControlFragment {
public void onActivityResult(int requestCode, int resultCode, Intent data) { public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CODE_SELECT_LIST) { if (requestCode == REQUEST_CODE_SELECT_LIST) {
if (resultCode == RESULT_OK) { if (resultCode == RESULT_OK) {
setList(data.getParcelableExtra(RemoteListSupportPicker.EXTRA_SELECTED)); setList(data.getParcelableExtra(RemoteListSupportPicker.EXTRA_SELECTED_FILTER));
} }
} else { } else {
super.onActivityResult(requestCode, resultCode, data); super.onActivityResult(requestCode, resultCode, data);

@ -256,6 +256,7 @@
<string name="tracking_event_task_creation">Task creation</string> <string name="tracking_event_task_creation">Task creation</string>
<string name="tracking_event_multiselect_delete">Multiselect delete</string> <string name="tracking_event_multiselect_delete">Multiselect delete</string>
<string name="tracking_event_multiselect_clone">Multiselect clone</string> <string name="tracking_event_multiselect_clone">Multiselect clone</string>
<string name="tracking_event_multiselect_move">Multiselect move</string>
<string name="p_badges_enabled">badges_enabled</string> <string name="p_badges_enabled">badges_enabled</string>
<string name="p_badge_list">badge_list</string> <string name="p_badge_list">badge_list</string>
<string name="tasker_locale">Tasker/Locale</string> <string name="tasker_locale">Tasker/Locale</string>

Loading…
Cancel
Save