Remove paging library

gtask_related_email
Alex Baker 5 years ago
parent a9db5a2d5a
commit 73f01fb08b

@ -141,7 +141,6 @@ dependencies {
annotationProcessor("androidx.room:room-compiler:${Versions.room}")
implementation("androidx.lifecycle:lifecycle-extensions:2.1.0")
implementation("io.reactivex.rxjava2:rxandroid:2.1.1")
implementation("androidx.paging:paging-runtime:2.1.0")
annotationProcessor("com.jakewharton:butterknife-compiler:${Versions.butterknife}")
implementation("com.jakewharton:butterknife:${Versions.butterknife}")

@ -692,18 +692,6 @@
license: The Apache Software License, Version 2.0
licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt
url: https://github.com/census-instrumentation/opencensus-java
- artifact: androidx.paging:paging-common:+
name: Android Paging-Common
copyrightHolder: Android Open Source Project
license: The Apache Software License, Version 2.0
licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt
url: https://developer.android.com/topic/libraries/architecture/index.html
- artifact: androidx.paging:paging-runtime:+
name: Android Paging-Runtime
copyrightHolder: Android Open Source Project
license: The Apache Software License, Version 2.0
licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt
url: https://developer.android.com/topic/libraries/architecture/index.html
- artifact: org.ogce:xpp3:+
skip: true
- artifact: junit:junit:+

@ -1872,38 +1872,6 @@
"version": "0.19.2"
}
},
{
"notice": null,
"copyrightHolder": "Android Open Source Project",
"copyrightStatement": "Copyright © Android Open Source Project. All rights reserved.",
"license": "The Apache Software License, Version 2.0",
"licenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt",
"normalizedLicense": "apache2",
"year": null,
"url": "https://developer.android.com/topic/libraries/architecture/index.html",
"libraryName": "Android Paging-Common",
"artifactId": {
"name": "paging-common",
"group": "androidx.paging",
"version": "2.1.0"
}
},
{
"notice": null,
"copyrightHolder": "Android Open Source Project",
"copyrightStatement": "Copyright © Android Open Source Project. All rights reserved.",
"license": "The Apache Software License, Version 2.0",
"licenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt",
"normalizedLicense": "apache2",
"year": null,
"url": "https://developer.android.com/topic/libraries/architecture/index.html",
"libraryName": "Android Paging-Runtime",
"artifactId": {
"name": "paging-runtime",
"group": "androidx.paging",
"version": "2.1.0"
}
},
{
"notice": null,
"copyrightHolder": "Android Open Source Project",

@ -87,8 +87,6 @@ import org.tasks.preferences.Device;
import org.tasks.preferences.Preferences;
import org.tasks.sync.SyncAdapters;
import org.tasks.tasklist.ActionModeProvider;
import org.tasks.tasklist.ManualSortRecyclerAdapter;
import org.tasks.tasklist.PagedListRecyclerAdapter;
import org.tasks.tasklist.TaskListRecyclerAdapter;
import org.tasks.tasklist.ViewHolderFactory;
import org.tasks.ui.MenuColorizer;
@ -259,21 +257,13 @@ public final class TaskListFragment extends InjectingFragment
taskAdapter.supportsParentingOrManualSort());
recyclerAdapter =
taskAdapter.supportsParentingOrManualSort()
? new ManualSortRecyclerAdapter(
taskAdapter,
recyclerView,
viewHolderFactory,
this,
actionModeProvider,
taskListViewModel.getValue())
: new PagedListRecyclerAdapter(
taskAdapter,
recyclerView,
viewHolderFactory,
this,
actionModeProvider,
taskListViewModel.getValue());
new TaskListRecyclerAdapter(
taskAdapter,
recyclerView,
viewHolderFactory,
this,
actionModeProvider,
taskListViewModel.getValue());
taskAdapter.setHelper(recyclerAdapter);
((DefaultItemAnimator) recyclerView.getItemAnimator()).setSupportsChangeAnimations(false);
recyclerView.setLayoutManager(new LinearLayoutManager(context));

@ -9,7 +9,6 @@ package com.todoroo.astrid.dao;
import static com.todoroo.andlib.utility.DateUtilities.now;
import android.database.Cursor;
import androidx.paging.DataSource;
import androidx.room.Dao;
import androidx.room.Insert;
import androidx.room.Query;
@ -25,9 +24,6 @@ import com.todoroo.astrid.helper.UUIDHelper;
import java.util.ArrayList;
import java.util.List;
import org.tasks.BuildConfig;
import org.tasks.data.CaldavTask;
import org.tasks.data.GoogleTask;
import org.tasks.data.Tag;
import org.tasks.data.TaskContainer;
import org.tasks.jobs.WorkManager;
import timber.log.Timber;
@ -133,9 +129,6 @@ public abstract class TaskDao {
@RawQuery
public abstract List<TaskContainer> fetchTasks(SimpleSQLiteQuery query);
@RawQuery(observedEntities = {Task.class, GoogleTask.class, CaldavTask.class, Tag.class})
public abstract DataSource.Factory<Integer, TaskContainer> getTaskFactory(SimpleSQLiteQuery query);
@Query("UPDATE tasks SET modified = datetime('now', 'localtime') WHERE _id in (:ids)")
public abstract void touch(List<Long> ids);

@ -15,14 +15,14 @@ import org.tasks.data.TaskContainer;
public class ItemTouchHelperCallback extends ItemTouchHelper.Callback {
private final TaskAdapter adapter;
private final ManualSortRecyclerAdapter recyclerAdapter;
private final TaskListRecyclerAdapter recyclerAdapter;
private final Runnable onClear;
private int from = -1;
private int to = -1;
private boolean dragging;
ItemTouchHelperCallback(
TaskAdapter adapter, ManualSortRecyclerAdapter recyclerAdapter, Runnable onClear) {
TaskAdapter adapter, TaskListRecyclerAdapter recyclerAdapter, Runnable onClear) {
this.adapter = adapter;
this.recyclerAdapter = recyclerAdapter;
this.onClear = onClear;

@ -1,110 +0,0 @@
package org.tasks.tasklist;
import static com.todoroo.andlib.utility.AndroidUtilities.assertMainThread;
import static com.todoroo.andlib.utility.AndroidUtilities.assertNotMainThread;
import androidx.annotation.NonNull;
import androidx.core.util.Pair;
import androidx.recyclerview.widget.DiffUtil;
import androidx.recyclerview.widget.DiffUtil.DiffResult;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.ListUpdateCallback;
import androidx.recyclerview.widget.RecyclerView;
import com.todoroo.astrid.activity.TaskListFragment;
import com.todoroo.astrid.adapter.TaskAdapter;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.schedulers.Schedulers;
import io.reactivex.subjects.PublishSubject;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import org.tasks.data.TaskContainer;
public class ManualSortRecyclerAdapter extends TaskListRecyclerAdapter {
private final ItemTouchHelperCallback itemTouchHelperCallback;
private List<TaskContainer> list;
private PublishSubject<List<TaskContainer>> publishSubject = PublishSubject.create();
private CompositeDisposable disposables = new CompositeDisposable();
private Queue<Pair<List<TaskContainer>, DiffResult>> updates = new LinkedList<>();
public ManualSortRecyclerAdapter(
TaskAdapter adapter,
RecyclerView recyclerView,
ViewHolderFactory viewHolderFactory,
TaskListFragment taskList,
ActionModeProvider actionModeProvider,
List<TaskContainer> list) {
super(adapter, recyclerView, viewHolderFactory, taskList, actionModeProvider);
this.list = list;
itemTouchHelperCallback = new ItemTouchHelperCallback(adapter, this, this::drainQueue);
new ItemTouchHelper(itemTouchHelperCallback).attachToRecyclerView(recyclerView);
Pair<List<TaskContainer>, DiffResult> initial = Pair.create(list, null);
disposables.add(
publishSubject
.observeOn(Schedulers.computation())
.scan(initial, this::calculateDiff)
.skip(1)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(this::applyDiff));
}
private Pair<List<TaskContainer>, DiffResult> calculateDiff(
Pair<List<TaskContainer>, DiffResult> last, List<TaskContainer> next) {
assertNotMainThread();
DiffCallback cb = new DiffCallback(last.first, next, adapter);
DiffResult result = DiffUtil.calculateDiff(cb, true);
return Pair.create(next, result);
}
private void applyDiff(Pair<List<TaskContainer>, DiffResult> update) {
assertMainThread();
updates.add(update);
if (!itemTouchHelperCallback.isDragging()) {
drainQueue();
}
}
private void drainQueue() {
assertMainThread();
Pair<List<TaskContainer>, DiffResult> update = updates.poll();
while (update != null) {
list = update.first;
update.second.dispatchUpdatesTo((ListUpdateCallback) this);
update = updates.poll();
}
}
@Override
public void onDetachedFromRecyclerView(@NonNull RecyclerView recyclerView) {
disposables.dispose();
}
@Override
public int getItemCount() {
return list.size();
}
@Override
public TaskContainer getItem(int position) {
return list.get(position);
}
@Override
public void submitList(List<TaskContainer> list) {
publishSubject.onNext(list);
}
void moved(int from, int to, int indent) {
adapter.moved(from, to, indent);
TaskContainer task = list.remove(from);
list.add(from < to ? to - 1 : to, task);
taskList.loadTaskListContent();
}
}

@ -1,47 +0,0 @@
package org.tasks.tasklist;
import androidx.paging.AsyncPagedListDiffer;
import androidx.paging.PagedList;
import androidx.recyclerview.widget.AsyncDifferConfig;
import androidx.recyclerview.widget.RecyclerView;
import com.todoroo.astrid.activity.TaskListFragment;
import com.todoroo.astrid.adapter.TaskAdapter;
import java.util.List;
import org.tasks.data.TaskContainer;
public class PagedListRecyclerAdapter extends TaskListRecyclerAdapter {
private AsyncPagedListDiffer<TaskContainer> differ;
public PagedListRecyclerAdapter(
TaskAdapter adapter,
RecyclerView recyclerView,
ViewHolderFactory viewHolderFactory,
TaskListFragment taskList,
ActionModeProvider actionModeProvider,
List<TaskContainer> list) {
super(adapter, recyclerView, viewHolderFactory, taskList, actionModeProvider);
differ =
new AsyncPagedListDiffer<>(
this, new AsyncDifferConfig.Builder<>(new ItemCallback()).build());
if (list instanceof PagedList) {
differ.submitList((PagedList<TaskContainer>) list);
}
}
@Override
public int getItemCount() {
return differ.getItemCount();
}
@Override
public TaskContainer getItem(int position) {
return differ.getItem(position);
}
@Override
public void submitList(List<TaskContainer> list) {
differ.submitList((PagedList<TaskContainer>) list);
}
}

@ -1,11 +1,18 @@
package org.tasks.tasklist;
import static com.todoroo.andlib.utility.AndroidUtilities.assertMainThread;
import static com.todoroo.andlib.utility.AndroidUtilities.assertNotMainThread;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.view.ActionMode;
import androidx.core.util.Pair;
import androidx.fragment.app.FragmentActivity;
import androidx.recyclerview.widget.DiffUtil;
import androidx.recyclerview.widget.DiffUtil.DiffResult;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.ListUpdateCallback;
import androidx.recyclerview.widget.RecyclerView;
@ -15,34 +22,59 @@ import com.todoroo.astrid.api.CaldavFilter;
import com.todoroo.astrid.api.Filter;
import com.todoroo.astrid.api.GtasksFilter;
import com.todoroo.astrid.utility.Flags;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.schedulers.Schedulers;
import io.reactivex.subjects.PublishSubject;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;
import java.util.Queue;
import org.tasks.data.TaskContainer;
import org.tasks.intents.TaskIntents;
public abstract class TaskListRecyclerAdapter extends RecyclerView.Adapter<ViewHolder>
public class TaskListRecyclerAdapter extends RecyclerView.Adapter<ViewHolder>
implements ViewHolder.ViewHolderCallbacks, ListUpdateCallback {
protected final TaskAdapter adapter;
final TaskListFragment taskList;
private final TaskAdapter adapter;
private final TaskListFragment taskList;
private final RecyclerView recyclerView;
private final ViewHolderFactory viewHolderFactory;
private final ActionModeProvider actionModeProvider;
private final boolean isRemoteList;
private final ItemTouchHelperCallback itemTouchHelperCallback;
private ActionMode mode = null;
private List<TaskContainer> list;
private PublishSubject<List<TaskContainer>> publishSubject = PublishSubject.create();
private CompositeDisposable disposables = new CompositeDisposable();
private Queue<Pair<List<TaskContainer>, DiffResult>> updates = new LinkedList<>();
TaskListRecyclerAdapter(
public TaskListRecyclerAdapter(
TaskAdapter adapter,
RecyclerView recyclerView,
ViewHolderFactory viewHolderFactory,
TaskListFragment taskList,
ActionModeProvider actionModeProvider) {
ActionModeProvider actionModeProvider,
List<TaskContainer> list) {
this.adapter = adapter;
this.recyclerView = recyclerView;
this.viewHolderFactory = viewHolderFactory;
this.taskList = taskList;
this.actionModeProvider = actionModeProvider;
isRemoteList = taskList.getFilter() instanceof GtasksFilter || taskList.getFilter() instanceof CaldavFilter;
isRemoteList =
taskList.getFilter() instanceof GtasksFilter
|| taskList.getFilter() instanceof CaldavFilter;
this.list = list;
itemTouchHelperCallback = new ItemTouchHelperCallback(adapter, this, this::drainQueue);
new ItemTouchHelper(itemTouchHelperCallback).attachToRecyclerView(recyclerView);
Pair<List<TaskContainer>, DiffResult> initial = Pair.create(list, null);
disposables.add(
publishSubject
.observeOn(Schedulers.computation())
.scan(initial, this::calculateDiff)
.skip(1)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(this::applyDiff));
}
@NonNull
@ -141,9 +173,13 @@ public abstract class TaskListRecyclerAdapter extends RecyclerView.Adapter<ViewH
mode = null;
}
public abstract TaskContainer getItem(int position);
public TaskContainer getItem(int position) {
return list.get(position);
}
public abstract void submitList(List<TaskContainer> list);
public void submitList(List<TaskContainer> list) {
publishSubject.onNext(list);
}
@Override
public void onInserted(int position, int count) {
@ -175,4 +211,52 @@ public abstract class TaskListRecyclerAdapter extends RecyclerView.Adapter<ViewH
public void onChanged(int position, int count, @Nullable Object payload) {
notifyItemRangeChanged(position, count, payload);
}
private Pair<List<TaskContainer>, DiffResult> calculateDiff(
Pair<List<TaskContainer>, DiffResult> last, List<TaskContainer> next) {
assertNotMainThread();
DiffCallback cb = new DiffCallback(last.first, next, adapter);
DiffResult result = DiffUtil.calculateDiff(cb, true);
return Pair.create(next, result);
}
private void applyDiff(Pair<List<TaskContainer>, DiffResult> update) {
assertMainThread();
updates.add(update);
if (!itemTouchHelperCallback.isDragging()) {
drainQueue();
}
}
private void drainQueue() {
assertMainThread();
Pair<List<TaskContainer>, DiffResult> update = updates.poll();
while (update != null) {
list = update.first;
update.second.dispatchUpdatesTo((ListUpdateCallback) this);
update = updates.poll();
}
}
@Override
public void onDetachedFromRecyclerView(@NonNull RecyclerView recyclerView) {
disposables.dispose();
}
@Override
public int getItemCount() {
return list.size();
}
void moved(int from, int to, int indent) {
adapter.moved(from, to, indent);
TaskContainer task = list.remove(from);
list.add(from < to ? to - 1 : to, task);
taskList.loadTaskListContent();
}
}

@ -9,13 +9,9 @@ import static com.todoroo.astrid.activity.TaskListFragment.TAGS_METADATA_JOIN;
import androidx.annotation.NonNull;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModel;
import androidx.paging.DataSource.Factory;
import androidx.paging.LivePagedListBuilder;
import androidx.paging.PagedList;
import androidx.sqlite.db.SimpleSQLiteQuery;
import com.google.common.collect.Lists;
import com.todoroo.andlib.data.Property.StringProperty;
@ -53,10 +49,7 @@ import org.tasks.data.TaskContainer;
import org.tasks.preferences.Preferences;
import timber.log.Timber;
public class TaskListViewModel extends ViewModel implements Observer<PagedList<TaskContainer>> {
private static final PagedList.Config PAGED_LIST_CONFIG =
new PagedList.Config.Builder().setPageSize(20).build();
public class TaskListViewModel extends ViewModel {
private static final Table RECURSIVE = new Table("recursive_tasks");
private static final Field RECURSIVE_TASK = field(RECURSIVE + ".task");
@ -86,7 +79,6 @@ public class TaskListViewModel extends ViewModel implements Observer<PagedList<T
private Filter filter;
private boolean manualSort;
private CompositeDisposable disposable = new CompositeDisposable();
private LiveData<PagedList<TaskContainer>> internal;
public void setFilter(@NonNull Filter filter, boolean manualSort) {
if (!filter.equals(this.filter)
@ -259,55 +251,25 @@ public class TaskListViewModel extends ViewModel implements Observer<PagedList<T
invalidate();
}
private void removeObserver() {
if (internal != null) {
internal.removeObserver(this);
}
}
public void invalidate() {
assertMainThread();
removeObserver();
SimpleSQLiteQuery query = new SimpleSQLiteQuery(getQuery(preferences, filter));
Timber.v(query.getSql());
if (manualSort) {
disposable.add(
Single.fromCallable(() -> taskDao.fetchTasks(query))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(tasks::setValue, Timber::e));
} else {
Factory<Integer, TaskContainer> factory = taskDao.getTaskFactory(query);
LivePagedListBuilder<Integer, TaskContainer> builder = new LivePagedListBuilder<>(
factory, PAGED_LIST_CONFIG);
List<TaskContainer> current = tasks.getValue();
if (current instanceof PagedList) {
Object lastKey = ((PagedList<TaskContainer>) current).getLastKey();
if (lastKey instanceof Integer) {
builder.setInitialLoadKey((Integer) lastKey);
}
}
internal = builder.build();
internal.observeForever(this);
}
disposable.add(
Single.fromCallable(() -> taskDao.fetchTasks(query))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(tasks::setValue, Timber::e));
}
@Override
protected void onCleared() {
disposable.dispose();
removeObserver();
}
public List<TaskContainer> getValue() {
List<TaskContainer> value = tasks.getValue();
return value != null ? value : Collections.emptyList();
}
@Override
public void onChanged(PagedList<TaskContainer> taskContainers) {
tasks.setValue(taskContainers);
}
}

Loading…
Cancel
Save