Track selections by task id

synthesis
Alex Baker 6 years ago
parent 948e79c15a
commit 76c24fde67

@ -4,7 +4,7 @@ jdk: oraclejdk8
env:
global:
- TARGET_API=27
- BUILD_TOOLS=27.0.0
- BUILD_TOOLS=27.0.3
matrix:
- EMULATOR_API=21 ANDROID_ABI=armeabi-v7a
android:

@ -141,7 +141,6 @@ dependencies {
compile 'com.jakewharton:process-phoenix:2.0.0'
compile 'com.google.android.apps.dashclock:dashclock-api:2.0.0'
compile 'com.twofortyfouram:android-plugin-api-for-locale:1.0.2'
compile 'com.bignerdranch.android:recyclerview-multiselect:0.2'
compile ('com.rubiconproject.oss:jchronic:0.2.6') {
transitive = false
}

@ -16,6 +16,13 @@ import com.todoroo.astrid.data.Task;
import org.tasks.data.TaskAttachment;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import static com.google.common.collect.Lists.newArrayList;
import static com.google.common.primitives.Longs.asList;
/**
* Adapter for displaying a user's tasks as a list
*
@ -25,6 +32,7 @@ import org.tasks.data.TaskAttachment;
public class TaskAdapter {
private PagedListAdapterHelper<Task> helper;
private Set<Long> selected = new HashSet<>();
public int getCount() {
return helper.getItemCount();
@ -34,6 +42,14 @@ public class TaskAdapter {
this.helper = helper;
}
public List<Long> getSelected() {
return newArrayList(selected);
}
public void clearSelections() {
selected.clear();
}
public interface OnCompletedTaskListener {
void onCompletedTask(Task item, boolean newState);
}
@ -58,6 +74,24 @@ public class TaskAdapter {
return false;
}
public void setSelected(long... ids) {
selected.clear();
selected.addAll(asList(ids));
}
public boolean isSelected(Task task) {
return selected.contains(task.getId());
}
public void toggleSelection(Task task) {
long id = task.getId();
if (selected.contains(id)) {
selected.remove(id);
} else {
selected.add(id);
}
}
public boolean isManuallySorted() {
return false;
}

@ -64,11 +64,12 @@ public class TaskDeleter {
taskDao.save(item);
}
public int markDeleted(List<Task> tasks) {
public List<Task> markDeleted(List<Long> taskIds) {
List<Task> tasks = taskDao.fetch(taskIds);
for (Task task : tasks) {
markDeleted(task);
}
return tasks.size();
return tasks;
}
public int clearCompleted(Filter filter) {
@ -81,6 +82,9 @@ public class TaskDeleter {
completed.add(task);
}
}
return markDeleted(completed);
for (Task task : completed) {
markDeleted(task);
}
return completed.size();
}
}

@ -38,9 +38,9 @@ public class TaskDuplicator {
this.googleTaskDao = googleTaskDao;
}
public List<Task> duplicate(List<Task> tasks) {
public List<Task> duplicate(List<Long> taskIds) {
List<Task> result = new ArrayList<>();
for (Task task : tasks) {
for (Task task : taskDao.fetch(taskIds)) {
result.add(clone(task));
}
localBroadcastManager.broadcastRefresh();

@ -49,6 +49,10 @@ public class TimerPlugin {
updateTimer(task, true);
}
public void stopTimer(Long task) {
stopTimer(taskDao.fetch(task));
}
public void stopTimer(Task task) {
updateTimer(task, false);
}

@ -18,8 +18,6 @@ import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.ViewGroup;
import com.bignerdranch.android.multiselector.ModalMultiSelectorCallback;
import com.bignerdranch.android.multiselector.MultiSelector;
import com.google.common.primitives.Longs;
import com.todoroo.astrid.activity.TaskListActivity;
import com.todoroo.astrid.activity.TaskListFragment;
@ -35,12 +33,8 @@ import org.tasks.analytics.Tracking;
import org.tasks.dialogs.DialogBuilder;
import org.tasks.ui.MenuColorizer;
import java.util.ArrayList;
import java.util.List;
import static com.google.common.collect.Lists.newArrayList;
import static com.google.common.collect.Lists.transform;
public class TaskListRecyclerAdapter extends RecyclerView.Adapter<ViewHolder>
implements ViewHolder.ViewHolderCallbacks, ListUpdateCallback {
@ -58,8 +52,6 @@ public class TaskListRecyclerAdapter extends RecyclerView.Adapter<ViewHolder>
}
};
private final MultiSelector multiSelector = new MultiSelector();
private final Activity activity;
private final TaskAdapter adapter;
private final ViewHolderFactory viewHolderFactory;
@ -99,42 +91,26 @@ public class TaskListRecyclerAdapter extends RecyclerView.Adapter<ViewHolder>
public Bundle getSaveState() {
Bundle information = new Bundle();
List<Task> selectedTasks = transform(multiSelector.getSelectedPositions(), adapterHelper::getItem);
List<Long> selectedTaskIds = transform(selectedTasks, Task::getId);
List<Long> selectedTaskIds = adapter.getSelected();
information.putLongArray(EXTRA_SELECTED_TASK_IDS, Longs.toArray(selectedTaskIds));
return information;
}
public void restoreSaveState(Bundle savedState) {
long[] longArray = savedState.getLongArray(EXTRA_SELECTED_TASK_IDS);
if (longArray.length > 0) {
if (longArray != null && longArray.length > 0) {
mode = ((TaskListActivity) activity).startSupportActionMode(actionModeCallback);
multiSelector.setSelectable(true);
for (int position : getTaskPositions(Longs.asList(longArray))) {
multiSelector.setSelected(position, 0L, true);
}
adapter.setSelected(longArray);
updateModeTitle();
}
}
private List<Integer> getTaskPositions(List<Long> longs) {
List<Integer> result = new ArrayList<>();
for (int i = 0 ; i < adapterHelper.getItemCount() ; i++) {
Task item = adapterHelper.getItem(i);
if (longs.contains(item.getId())) {
result.add(i);
}
}
return result;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
ViewGroup view = (ViewGroup) LayoutInflater.from(activity)
.inflate(R.layout.task_adapter_row_simple, parent, false);
return viewHolderFactory.newViewHolder(view, this, multiSelector);
return viewHolderFactory.newViewHolder(view, this);
}
@Override
@ -144,6 +120,7 @@ public class TaskListRecyclerAdapter extends RecyclerView.Adapter<ViewHolder>
holder.bindView(task);
holder.setMoving(false);
holder.setIndent(adapter.getIndent(task));
holder.setSelected(adapter.isSelected(task));
}
}
@ -173,9 +150,9 @@ public class TaskListRecyclerAdapter extends RecyclerView.Adapter<ViewHolder>
}
private void toggle(ViewHolder viewHolder) {
multiSelector.setSelectable(true);
multiSelector.tapSelection(viewHolder);
if (multiSelector.getSelectedPositions().isEmpty()) {
adapter.toggleSelection(viewHolder.task);
notifyItemChanged(viewHolder.getAdapterPosition());
if (adapter.getSelected().isEmpty()) {
dragging = false;
if (mode != null) {
mode.finish();
@ -196,22 +173,18 @@ public class TaskListRecyclerAdapter extends RecyclerView.Adapter<ViewHolder>
}
}
private List<Task> getSelectedTasks() {
return newArrayList(transform(multiSelector.getSelectedPositions(), adapterHelper::getItem));
}
private void deleteSelectedItems() {
tracker.reportEvent(Tracking.Events.MULTISELECT_DELETE);
List<Task> tasks = getSelectedTasks();
List<Long> tasks = adapter.getSelected();
mode.finish();
int result = taskDeleter.markDeleted(tasks);
taskList.onTaskDelete(tasks);
taskList.makeSnackbar(activity.getString(R.string.delete_multiple_tasks_confirmation, Integer.toString(result))).show();
List<Task> result = taskDeleter.markDeleted(tasks);
taskList.onTaskDelete(result);
taskList.makeSnackbar(activity.getString(R.string.delete_multiple_tasks_confirmation, Integer.toString(result.size()))).show();
}
private void copySelectedItems() {
tracker.reportEvent(Tracking.Events.MULTISELECT_CLONE);
List<Task> tasks = getSelectedTasks();
List<Long> tasks = adapter.getSelected();
mode.finish();
List<Task> duplicates = taskDuplicator.duplicate(tasks);
taskList.onTaskCreated(duplicates);
@ -220,11 +193,11 @@ public class TaskListRecyclerAdapter extends RecyclerView.Adapter<ViewHolder>
private void updateModeTitle() {
if (mode != null) {
mode.setTitle(Integer.toString(multiSelector.getSelectedPositions().size()));
mode.setTitle(Integer.toString(adapter.getSelected().size()));
}
}
private ModalMultiSelectorCallback actionModeCallback = new ModalMultiSelectorCallback(multiSelector) {
private ActionMode.Callback actionModeCallback = new ActionMode.Callback() {
@Override
public boolean onCreateActionMode(ActionMode actionMode, Menu menu) {
MenuInflater inflater = actionMode.getMenuInflater();
@ -233,6 +206,11 @@ public class TaskListRecyclerAdapter extends RecyclerView.Adapter<ViewHolder>
return true;
}
@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
@ -255,9 +233,9 @@ public class TaskListRecyclerAdapter extends RecyclerView.Adapter<ViewHolder>
@Override
public void onDestroyActionMode(ActionMode actionMode) {
super.onDestroyActionMode(actionMode);
multiSelector.clearSelections();
adapter.clearSelections();
TaskListRecyclerAdapter.this.mode = null;
notifyDataSetChanged();
}
};

@ -5,6 +5,7 @@ import android.app.PendingIntent;
import android.content.Context;
import android.graphics.Paint;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.RecyclerView;
import android.text.SpannableString;
import android.text.TextUtils;
import android.text.method.LinkMovementMethod;
@ -15,8 +16,6 @@ import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.bignerdranch.android.multiselector.MultiSelector;
import com.bignerdranch.android.multiselector.MultiSelectorBindingHolder;
import com.google.common.collect.Lists;
import com.todoroo.andlib.utility.DateUtilities;
import com.todoroo.astrid.api.TaskAction;
@ -43,21 +42,9 @@ import static com.google.common.collect.Lists.newArrayList;
import static com.todoroo.andlib.utility.AndroidUtilities.atLeastKitKat;
import static com.todoroo.andlib.utility.AndroidUtilities.atLeastLollipop;
class ViewHolder extends MultiSelectorBindingHolder {
class ViewHolder extends RecyclerView.ViewHolder {
@Override
public void setSelectable(boolean selectable) {
this.selectable = selectable;
updateBackground();
}
@Override
public boolean isSelectable() {
return selectable;
}
@Override
public void setActivated(boolean selected) {
public void setSelected(boolean selected) {
this.selected = selected;
updateBackground();
}
@ -70,16 +57,13 @@ class ViewHolder extends MultiSelectorBindingHolder {
private void updateBackground() {
if (selected || moving) {
rowBody.setBackgroundColor(selectedColor);
} else if (selectable) {
rowBody.setBackgroundColor(0);
} else {
rowBody.setBackgroundResource(background);
rowBody.getBackground().jumpToCurrentState();
}
}
@Override
public boolean isActivated() {
public boolean isSelected() {
return selected;
}
@ -114,7 +98,6 @@ class ViewHolder extends MultiSelectorBindingHolder {
private final int selectedColor;
private final int textColorOverdue;
private int indent;
private boolean selectable = false;
private boolean selected;
private boolean moving;
@ -122,9 +105,8 @@ class ViewHolder extends MultiSelectorBindingHolder {
CheckBoxes checkBoxes, TagFormatter tagFormatter,
int textColorOverdue, int textColorSecondary, int textColorHint, TaskDao taskDao,
DialogBuilder dialogBuilder, ViewHolderCallbacks callback,
DisplayMetrics metrics, int background, int selectedColor, MultiSelector multiSelector,
int rowPadding) {
super(view, multiSelector);
DisplayMetrics metrics, int background, int selectedColor, int rowPadding) {
super(view);
this.context = context;
this.checkBoxes = checkBoxes;
this.tagFormatter = tagFormatter;

@ -4,7 +4,6 @@ import android.content.Context;
import android.util.DisplayMetrics;
import android.view.ViewGroup;
import com.bignerdranch.android.multiselector.MultiSelector;
import com.todoroo.astrid.dao.TaskDao;
import org.tasks.R;
@ -57,9 +56,9 @@ public class ViewHolderFactory {
rowPadding = convertDpToPixels(metrics, preferences.getInt(R.string.p_rowPadding, 16));
}
ViewHolder newViewHolder(ViewGroup viewGroup, ViewHolder.ViewHolderCallbacks callbacks, MultiSelector multiSelector) {
ViewHolder newViewHolder(ViewGroup viewGroup, ViewHolder.ViewHolderCallbacks callbacks) {
return new ViewHolder(context, viewGroup, showFullTaskTitle, fontSize, checkBoxes,
tagFormatter, textColorOverdue, textColorSecondary, textColorHint, taskDao,
dialogBuilder, callbacks, metrics, background, selectedColor, multiSelector, rowPadding);
dialogBuilder, callbacks, metrics, background, selectedColor, rowPadding);
}
}

Loading…
Cancel
Save