From dedb8f93e92e5038e82a2eda6ada74a64a101e47 Mon Sep 17 00:00:00 2001 From: Marten Gajda Date: Wed, 9 Oct 2019 00:12:37 +0200 Subject: [PATCH] Open first instance of newly created task, fixes #862 (#866) The Task Editor used to launch the details view for newly created tasks using the task Uri. In general this works, but it fails when the details view uses the Uri with the notification service (because that currently requires an instance Uri). So to fix this we load the first instance after creating a new task and use that one to show the details view. --- dependencies.gradle | 2 +- .../org/dmfs/provider/tasks/utils/With.java | 15 +++++++-- .../java/org/dmfs/tasks/EditTaskFragment.java | 33 +++++++++++++++++-- .../tasks/StaleListBroadcastReceiver.java | 4 +-- .../tasks/notification/ActionService.java | 2 +- .../notification/TaskNotificationService.java | 6 ++-- .../opentaskspal/predicates/IsProperty.java | 4 +-- .../opentaskspal/predicates/IsRelation.java | 2 +- .../opentaskspal/predicates/TaskOnList.java | 6 ++-- .../dmfs/opentaskspal/rowsets/Subtasks.java | 6 ++-- .../opentaskspal/tables/TaskListScoped.java | 9 ++--- .../opentaskspal/views/TaskListScoped.java | 2 +- 12 files changed, 65 insertions(+), 26 deletions(-) diff --git a/dependencies.gradle b/dependencies.gradle index 819e653c1..defd06e32 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -1,5 +1,5 @@ def jems_version = '1.24' -def contentpal_version = '0.5' +def contentpal_version = '0.6' def androidx_test_runner_version = '1.1.1' ext.deps = [ diff --git a/opentasks-provider/src/main/java/org/dmfs/provider/tasks/utils/With.java b/opentasks-provider/src/main/java/org/dmfs/provider/tasks/utils/With.java index e1f854f45..7ae6b4481 100644 --- a/opentasks-provider/src/main/java/org/dmfs/provider/tasks/utils/With.java +++ b/opentasks-provider/src/main/java/org/dmfs/provider/tasks/utils/With.java @@ -16,6 +16,8 @@ package org.dmfs.provider.tasks.utils; +import org.dmfs.jems.optional.Optional; +import org.dmfs.jems.optional.adapters.SinglePresent; import org.dmfs.jems.procedure.Procedure; import org.dmfs.jems.single.Single; @@ -30,7 +32,7 @@ @Deprecated public final class With implements Procedure> { - private final Single mValue; + private final Optional mValue; public With(T value) @@ -40,6 +42,12 @@ public With(T value) public With(Single value) + { + this(new SinglePresent<>(value)); + } + + + public With(Optional value) { mValue = value; } @@ -48,6 +56,9 @@ public With(Single value) @Override public void process(Procedure delegate) { - delegate.process(mValue.value()); + if (mValue.isPresent()) + { + delegate.process(mValue.value()); + } } } diff --git a/opentasks/src/main/java/org/dmfs/tasks/EditTaskFragment.java b/opentasks/src/main/java/org/dmfs/tasks/EditTaskFragment.java index ce7b23b02..07d31711f 100644 --- a/opentasks/src/main/java/org/dmfs/tasks/EditTaskFragment.java +++ b/opentasks/src/main/java/org/dmfs/tasks/EditTaskFragment.java @@ -18,6 +18,7 @@ import android.annotation.SuppressLint; import android.annotation.TargetApi; import android.app.Activity; +import android.content.ContentUris; import android.content.Context; import android.content.Intent; import android.database.Cursor; @@ -41,10 +42,20 @@ import android.widget.Toast; import org.dmfs.android.bolts.color.elementary.ValueColor; +import org.dmfs.android.contentpal.predicates.AllOf; +import org.dmfs.android.contentpal.predicates.EqArg; +import org.dmfs.android.contentpal.predicates.ReferringTo; +import org.dmfs.android.contentpal.references.RowUriReference; +import org.dmfs.android.contentpal.rowsets.Frozen; +import org.dmfs.android.contentpal.rowsets.QueryRowSet; import org.dmfs.android.retentionmagic.SupportFragment; import org.dmfs.android.retentionmagic.annotations.Parameter; import org.dmfs.android.retentionmagic.annotations.Retain; +import org.dmfs.jems.optional.adapters.First; +import org.dmfs.opentaskspal.readdata.Id; +import org.dmfs.opentaskspal.views.InstancesView; import org.dmfs.provider.tasks.AuthorityUtil; +import org.dmfs.provider.tasks.utils.With; import org.dmfs.tasks.contract.TaskContract; import org.dmfs.tasks.contract.TaskContract.TaskLists; import org.dmfs.tasks.contract.TaskContract.Tasks; @@ -722,9 +733,25 @@ public void saveAndExit() activity.finish(); if (isNewTask) { - activity.startActivity( - new Intent(Intent.ACTION_VIEW, mTaskUri) - .putExtra(ViewTaskActivity.EXTRA_COLOR, mListColor)); + // When creating a new task we're dealing with a task URI, for now we start the details view with an instance URI though + // so get the first instance of the new task and open it + new With<>( + new First<>( + new Frozen<>( + new QueryRowSet<>( + new InstancesView<>(mAuthority, activity.getContentResolver().acquireContentProviderClient(mAuthority)), + Id.PROJECTION, + new AllOf<>( + new EqArg<>(TaskContract.Instances.DISTANCE_FROM_CURRENT, 0), + new ReferringTo<>(TaskContract.Instances.TASK_ID, new RowUriReference(mTaskUri))))))) + .process( + snapShot -> + activity.startActivity( + new Intent( + Intent.ACTION_VIEW, + ContentUris.withAppendedId(TaskContract.Instances.getContentUri(mAuthority), + new Id(snapShot.values()).value())) + .putExtra(ViewTaskActivity.EXTRA_COLOR, mListColor))); } } else diff --git a/opentasks/src/main/java/org/dmfs/tasks/StaleListBroadcastReceiver.java b/opentasks/src/main/java/org/dmfs/tasks/StaleListBroadcastReceiver.java index 137766f03..08540d593 100644 --- a/opentasks/src/main/java/org/dmfs/tasks/StaleListBroadcastReceiver.java +++ b/opentasks/src/main/java/org/dmfs/tasks/StaleListBroadcastReceiver.java @@ -71,9 +71,9 @@ public void onReceive(Context context, Intent intent) new QueryRowSet<>( new TaskListsView(authority, context.getContentResolver().acquireContentProviderClient(authority)), new MultiProjection<>(TaskContract.TaskLists.ACCOUNT_NAME, TaskContract.TaskLists.ACCOUNT_TYPE), - new Not(new AnyOf( + new Not<>(new AnyOf<>( new Joined<>(new Seq<>( - new EqArg(TaskContract.TaskLists.ACCOUNT_TYPE, TaskContract.LOCAL_ACCOUNT_TYPE)), + new EqArg<>(TaskContract.TaskLists.ACCOUNT_TYPE, TaskContract.LOCAL_ACCOUNT_TYPE)), new Mapped<>(AccountEq::new, new Seq<>(accountManager.getAccounts())))))))))) { context.startActivity(accountRequestIntent); diff --git a/opentasks/src/main/java/org/dmfs/tasks/notification/ActionService.java b/opentasks/src/main/java/org/dmfs/tasks/notification/ActionService.java index 417b378c2..8972b62a1 100644 --- a/opentasks/src/main/java/org/dmfs/tasks/notification/ActionService.java +++ b/opentasks/src/main/java/org/dmfs/tasks/notification/ActionService.java @@ -124,7 +124,7 @@ protected void onHandleWork(@NonNull Intent intent) TaskTitle.PROJECTION, TaskVersion.PROJECTION, TaskIsClosed.PROJECTION), - new EqArg(TaskContract.Instances._ID, ContentUris.parseId(instanceUri)))) + new EqArg<>(TaskContract.Instances._ID, ContentUris.parseId(instanceUri)))) { resolveAction(intent.getAction()).execute(this, contentProviderClient, snapshot.values(), instanceUri); } diff --git a/opentasks/src/main/java/org/dmfs/tasks/notification/TaskNotificationService.java b/opentasks/src/main/java/org/dmfs/tasks/notification/TaskNotificationService.java index 48600c5ef..a00316ba0 100644 --- a/opentasks/src/main/java/org/dmfs/tasks/notification/TaskNotificationService.java +++ b/opentasks/src/main/java/org/dmfs/tasks/notification/TaskNotificationService.java @@ -120,10 +120,10 @@ protected void onHandleWork(@NonNull Intent intent) new InstancesView<>(authority, getContentResolver().acquireContentProviderClient(authority))), new Composite<>(Id.PROJECTION, TaskVersion.PROJECTION, TaskPin.PROJECTION, TaskIsClosed.PROJECTION, EffectiveDueDate.PROJECTION, TaskStart.PROJECTION), - new AnyOf( + new AnyOf<>( // task is either pinned or has a notification - new EqArg(Tasks.PINNED, 1), - new In(Tasks._ID, new Mapped<>(p -> ContentUris.parseId(p.instance()), currentNotifications))))), + new EqArg<>(Tasks.PINNED, 1), + new In<>(Tasks._ID, new Mapped<>(p -> ContentUris.parseId(p.instance()), currentNotifications))))), (o, o2) -> (int) (ContentUris.parseId(o.instance()) - ContentUris.parseId(o2.instance())))) { if (!diff.left().isPresent()) diff --git a/opentaskspal/src/main/java/org/dmfs/opentaskspal/predicates/IsProperty.java b/opentaskspal/src/main/java/org/dmfs/opentaskspal/predicates/IsProperty.java index 9f93d3847..514327237 100644 --- a/opentaskspal/src/main/java/org/dmfs/opentaskspal/predicates/IsProperty.java +++ b/opentaskspal/src/main/java/org/dmfs/opentaskspal/predicates/IsProperty.java @@ -27,10 +27,10 @@ * * @author Gabor Keszthelyi */ -public final class IsProperty extends DelegatingPredicate +public final class IsProperty extends DelegatingPredicate { public IsProperty(String mimeType) { - super(new EqArg(TaskContract.PropertyColumns.MIMETYPE, mimeType)); + super(new EqArg<>(TaskContract.PropertyColumns.MIMETYPE, mimeType)); } } diff --git a/opentaskspal/src/main/java/org/dmfs/opentaskspal/predicates/IsRelation.java b/opentaskspal/src/main/java/org/dmfs/opentaskspal/predicates/IsRelation.java index d130130c0..e8bf9c967 100644 --- a/opentaskspal/src/main/java/org/dmfs/opentaskspal/predicates/IsRelation.java +++ b/opentaskspal/src/main/java/org/dmfs/opentaskspal/predicates/IsRelation.java @@ -26,7 +26,7 @@ * * @author Gabor Keszthelyi */ -public final class IsRelation extends DelegatingPredicate +public final class IsRelation extends DelegatingPredicate { public IsRelation() { diff --git a/opentaskspal/src/main/java/org/dmfs/opentaskspal/predicates/TaskOnList.java b/opentaskspal/src/main/java/org/dmfs/opentaskspal/predicates/TaskOnList.java index 580d00953..bd758ee62 100644 --- a/opentaskspal/src/main/java/org/dmfs/opentaskspal/predicates/TaskOnList.java +++ b/opentaskspal/src/main/java/org/dmfs/opentaskspal/predicates/TaskOnList.java @@ -29,11 +29,11 @@ * * @author Gabor Keszthelyi */ -public final class TaskOnList extends DelegatingPredicate +public final class TaskOnList extends DelegatingPredicate { - public TaskOnList(RowSnapshot taskListRow, Predicate predicate) + public TaskOnList(RowSnapshot taskListRow, Predicate predicate) { - super(new AllOf(predicate, new ReferringTo<>(TaskContract.Tasks.LIST_ID, taskListRow))); + super(new AllOf<>(predicate, new ReferringTo<>(TaskContract.Tasks.LIST_ID, taskListRow))); } } diff --git a/opentaskspal/src/main/java/org/dmfs/opentaskspal/rowsets/Subtasks.java b/opentaskspal/src/main/java/org/dmfs/opentaskspal/rowsets/Subtasks.java index 943b44740..530a47db6 100644 --- a/opentaskspal/src/main/java/org/dmfs/opentaskspal/rowsets/Subtasks.java +++ b/opentaskspal/src/main/java/org/dmfs/opentaskspal/rowsets/Subtasks.java @@ -16,8 +16,6 @@ package org.dmfs.opentaskspal.rowsets; -import androidx.annotation.NonNull; - import org.dmfs.android.contentpal.Projection; import org.dmfs.android.contentpal.RowReference; import org.dmfs.android.contentpal.RowSet; @@ -27,6 +25,8 @@ import org.dmfs.android.contentpal.rowsets.QueryRowSet; import org.dmfs.tasks.contract.TaskContract.Tasks; +import androidx.annotation.NonNull; + /** * {@link RowSet} for the subtasks of a given task. @@ -37,7 +37,7 @@ public final class Subtasks extends DelegatingRowSet { public Subtasks(@NonNull View view, - @NonNull Projection projection, + @NonNull Projection projection, @NonNull RowReference parentTask) { super(new QueryRowSet<>(view, projection, new ReferringTo<>(Tasks.PARENT_ID, parentTask))); diff --git a/opentaskspal/src/main/java/org/dmfs/opentaskspal/tables/TaskListScoped.java b/opentaskspal/src/main/java/org/dmfs/opentaskspal/tables/TaskListScoped.java index 16f362509..68ea0c3dd 100644 --- a/opentaskspal/src/main/java/org/dmfs/opentaskspal/tables/TaskListScoped.java +++ b/opentaskspal/src/main/java/org/dmfs/opentaskspal/tables/TaskListScoped.java @@ -17,7 +17,6 @@ package org.dmfs.opentaskspal.tables; import android.content.ContentProviderClient; -import androidx.annotation.NonNull; import org.dmfs.android.contentpal.InsertOperation; import org.dmfs.android.contentpal.Operation; @@ -30,6 +29,8 @@ import org.dmfs.opentaskspal.predicates.TaskOnList; import org.dmfs.tasks.contract.TaskContract; +import androidx.annotation.NonNull; + /** * A view onto the {@link TaskContract.Tasks} table which contains only tasks from a specific task list. @@ -61,7 +62,7 @@ public InsertOperation insertOperation(@NonNull UriParams ur @NonNull @Override - public Operation updateOperation(@NonNull UriParams uriParams, @NonNull Predicate predicate) + public Operation updateOperation(@NonNull UriParams uriParams, @NonNull Predicate predicate) { return mDelegate.updateOperation(uriParams, new TaskOnList(mTaskListRow, predicate)); } @@ -69,7 +70,7 @@ public Operation updateOperation(@NonNull UriParams uriParam @NonNull @Override - public Operation deleteOperation(@NonNull UriParams uriParams, @NonNull Predicate predicate) + public Operation deleteOperation(@NonNull UriParams uriParams, @NonNull Predicate predicate) { return mDelegate.deleteOperation(uriParams, new TaskOnList(mTaskListRow, predicate)); } @@ -77,7 +78,7 @@ public Operation deleteOperation(@NonNull UriParams uriParam @NonNull @Override - public Operation assertOperation(@NonNull UriParams uriParams, @NonNull Predicate predicate) + public Operation assertOperation(@NonNull UriParams uriParams, @NonNull Predicate predicate) { return mDelegate.assertOperation(uriParams, new TaskOnList(mTaskListRow, predicate)); } diff --git a/opentaskspal/src/main/java/org/dmfs/opentaskspal/views/TaskListScoped.java b/opentaskspal/src/main/java/org/dmfs/opentaskspal/views/TaskListScoped.java index 46797335d..db1ada10d 100644 --- a/opentaskspal/src/main/java/org/dmfs/opentaskspal/views/TaskListScoped.java +++ b/opentaskspal/src/main/java/org/dmfs/opentaskspal/views/TaskListScoped.java @@ -54,7 +54,7 @@ public TaskListScoped(@NonNull RowSnapshot taskListRow, @NonNull @Override - public Cursor rows(@NonNull UriParams uriParams, @NonNull Projection projection, @NonNull Predicate predicate, @NonNull Optional sorting) throws RemoteException + public Cursor rows(@NonNull UriParams uriParams, @NonNull Projection projection, @NonNull Predicate predicate, @NonNull Optional sorting) throws RemoteException { return mDelegate.rows(uriParams, projection, new TaskOnList(mTaskListRow, predicate), sorting); }