Skip to content

Commit

Permalink
Show subtasks on details view. #442
Browse files Browse the repository at this point in the history
  • Loading branch information
Gabor Keszthelyi committed Dec 20, 2017
1 parent 62e6af8 commit e9f8cc6
Show file tree
Hide file tree
Showing 33 changed files with 1,179 additions and 13 deletions.
1 change: 1 addition & 0 deletions .idea/dictionaries/dictionary.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions opentasks-provider/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ dependencies {
exclude module: 'jems'
}
androidTestImplementation 'com.android.support:support-annotations:' + SUPPORT_LIBRARY_VERSION
androidTestImplementation 'com.android.support.test:runner:0.5'
androidTestImplementation 'com.android.support.test:rules:0.5'
androidTestImplementation 'com.android.support.test:runner:' + ANDROID_TEST_RUNNER_VERSION
androidTestImplementation 'com.android.support.test:rules:' + ANDROID_TEST_RUNNER_VERSION
testImplementation 'org.robolectric:robolectric:' + ROBOLECTRIC_VERSION
testImplementation 'junit:junit:4.12'
testImplementation 'org.mockito:mockito-core:2.10.0'
Expand Down
10 changes: 10 additions & 0 deletions opentasks/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,14 @@ android {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
dataBinding {
enabled = true
}
}

dependencies {
implementation project(':opentasks-provider')
implementation project(':opentaskspal')
implementation 'com.android.support:appcompat-v7:' + SUPPORT_LIBRARY_VERSION
implementation 'com.android.support:design:' + SUPPORT_LIBRARY_VERSION
implementation('org.dmfs:android-xml-magic:0.1.1') {
Expand All @@ -66,10 +70,16 @@ dependencies {
implementation 'org.dmfs:jems:' + JEMS_VERSION
implementation 'org.dmfs:rfc5545-datetime:' + RFC5545_DATETIME_VERSION
implementation 'com.github.dmfs.bolts:color-bolts:' + BOLTS_VERSION
implementation 'io.reactivex.rxjava2:rxjava:2.1.5'
implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'

testImplementation 'junit:junit:4.12'
testImplementation 'org.robolectric:robolectric:3.5.1'

implementation('com.github.dmfs.contentpal:contentpal:' + CONTENTPAL_VERSION) {
exclude module: 'jems'
}

androidTestImplementation('com.android.support.test:runner:' + ANDROID_TEST_RUNNER_VERSION) {
exclude group: 'com.android.support', module: 'support-annotations'
}
Expand Down
5 changes: 4 additions & 1 deletion opentasks/proguard.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -77,4 +77,7 @@
java.lang.String TAG;
@org.dmfs.android.retentionmagic.annotations.* <fields>;
private long mId;
}
}

-dontwarn android.databinding.**
-keep class android.databinding.** { *; }
3 changes: 2 additions & 1 deletion opentasks/src/main/java/org/dmfs/tasks/EditTaskFragment.java
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
import org.dmfs.tasks.model.OnContentChangeListener;
import org.dmfs.tasks.model.Sources;
import org.dmfs.tasks.model.TaskFieldAdapters;
import org.dmfs.tasks.utils.BasicTaskDetailsUi;
import org.dmfs.tasks.utils.ContentValueMapper;
import org.dmfs.tasks.utils.OnModelLoadedListener;
import org.dmfs.tasks.utils.RecentlyUsedLists;
Expand Down Expand Up @@ -793,7 +794,7 @@ public void saveAndExit()
activity.finish();
if (isNewTask)
{
activity.startActivity(new Intent("android.intent.action.VIEW", mTaskUri));
new BasicTaskDetailsUi(mTaskUri).show(activity);
}
}
else
Expand Down
2 changes: 2 additions & 0 deletions opentasks/src/main/java/org/dmfs/tasks/ViewTaskActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import org.dmfs.android.bolts.color.Color;
import org.dmfs.tasks.model.ContentSet;
import org.dmfs.tasks.utils.BaseActivity;
import org.dmfs.tasks.utils.Darkened;


/**
Expand Down Expand Up @@ -152,6 +153,7 @@ public void updateColor(Color color)
{
Window window = getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);

window.setStatusBarColor(darkenColor(color.argb()));
}
}
Expand Down
41 changes: 33 additions & 8 deletions opentasks/src/main/java/org/dmfs/tasks/ViewTaskFragment.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,15 @@
import android.widget.TextView;

import org.dmfs.android.bolts.color.colors.ValueColor;

import org.dmfs.android.contentpal.RowDataSnapshot;

import org.dmfs.android.retentionmagic.SupportFragment;
import org.dmfs.android.retentionmagic.annotations.Parameter;
import org.dmfs.android.retentionmagic.annotations.Retain;
import org.dmfs.tasks.contract.TaskContract;
import org.dmfs.tasks.contract.TaskContract.Tasks;
import org.dmfs.tasks.data.SubtasksSource;
import org.dmfs.tasks.model.ContentSet;
import org.dmfs.tasks.model.Model;
import org.dmfs.tasks.model.OnContentChangeListener;
Expand All @@ -63,13 +68,18 @@
import org.dmfs.tasks.notification.TaskNotificationHandler;
import org.dmfs.tasks.share.ShareIntentFactory;
import org.dmfs.tasks.utils.ContentValueMapper;
import org.dmfs.tasks.utils.Darkened;
import org.dmfs.tasks.utils.OnModelLoadedListener;
import org.dmfs.tasks.widget.SubtasksView;
import org.dmfs.tasks.widget.TaskView;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.functions.Consumer;


/**
* A fragment representing a single Task detail screen. This fragment is either contained in a {@link TaskListActivity} in two-pane mode (on tablets) or in a
Expand Down Expand Up @@ -130,6 +140,8 @@ public class ViewTaskFragment extends SupportFragment
*/
private TaskView mDetailView;

private CompositeDisposable mDisposables;

private int mListColor;
private int mOldStatus = -1;
private boolean mPinned = false;
Expand Down Expand Up @@ -207,14 +219,6 @@ public static ViewTaskFragment newInstance(Uri uri)
}


/**
* Mandatory empty constructor for the fragment manager to instantiate the fragment (e.g. upon screen orientation changes).
*/
public ViewTaskFragment()
{
}


@Override
public void onCreate(Bundle savedInstanceState)
{
Expand Down Expand Up @@ -265,6 +269,7 @@ public void onDestroyView()
mDetailView.setValues(null);
}

mDisposables.dispose();
}


Expand Down Expand Up @@ -319,6 +324,8 @@ else if (mTaskUri != null)
loadUri(uri);
}

mDisposables = new CompositeDisposable();

return mRootView;
}

Expand Down Expand Up @@ -400,6 +407,7 @@ public void loadUri(Uri uri)
if ((oldUri == null) != (uri == null))
{
/*
* getActivity().invalidateOptionsMenu() doesn't work in Android 2.x so use the compat lib
*/
ActivityCompat.invalidateOptionsMenu(getActivity());
Expand Down Expand Up @@ -715,6 +723,23 @@ public void onContentLoaded(ContentSet contentSet)
postUpdateView();
}
}

mDisposables.add(
new SubtasksSource(mAppContext, mTaskUri)
.subscribe(new Consumer<Iterable<RowDataSnapshot<TaskContract.Tasks>>>()
{
@Override
public void accept(Iterable<RowDataSnapshot<TaskContract.Tasks>> subTasks)
{
if (subTasks.iterator().hasNext())
{
new SubtasksView(mContent).update(subTasks);
((TextView) mContent.findViewById(R.id.opentasks_view_item_task_details_subtitles_section_header))
.setTextColor(new Darkened(mListColor).argb());
mContent.requestLayout();
}
}
}));
}


Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* Copyright 2017 dmfs GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.dmfs.tasks.data;

import android.content.ContentProviderClient;
import android.os.Build;

import org.dmfs.tasks.utils.rxjava.disposable.DelegatingDisposable;

import io.reactivex.disposables.Disposable;
import io.reactivex.disposables.Disposables;


/**
* {@link Disposable} for {@link ContentProviderClient}.
*
* @author Gabor Keszthelyi
*/
public final class ContentProviderClientDisposable extends DelegatingDisposable
{
public ContentProviderClientDisposable(final ContentProviderClient client)
{
super(Disposables.fromRunnable(new Runnable()
{
@Override
public void run()
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
{
client.close();
}
else
{
client.release();
}
}
}));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
* Copyright 2017 dmfs GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.dmfs.tasks.data;

import android.content.ContentProviderClient;
import android.content.Context;
import android.net.Uri;

import org.dmfs.provider.tasks.AuthorityUtil;
import org.dmfs.tasks.contract.TaskContract;
import org.dmfs.tasks.utils.rxjava.singlesource.DelegatingSingleSource;

import io.reactivex.Single;
import io.reactivex.SingleEmitter;
import io.reactivex.SingleOnSubscribe;
import io.reactivex.SingleSource;
import io.reactivex.annotations.NonNull;


/**
* {@link SingleSource} for accessing a {@link ContentProviderClient} for the given {@link Uri}.
* Takes care of closing the client upon disposal.
*
* @author Gabor Keszthelyi
*/
public class ContentProviderClientSource extends DelegatingSingleSource<ContentProviderClient>
{

public ContentProviderClientSource(final Context context, final Uri uri)
{
super(Single.create(new SingleOnSubscribe<ContentProviderClient>()
{
@Override
public void subscribe(@NonNull SingleEmitter<ContentProviderClient> emitter) throws Exception
{
ContentProviderClient client = context.getContentResolver().acquireContentProviderClient(uri);
emitter.setDisposable(new ContentProviderClientDisposable(client));
emitter.onSuccess(client);
}
}));
}


public ContentProviderClientSource(Context context)
{
this(context, TaskContract.getContentUri(AuthorityUtil.taskAuthority(context)));
}

}
38 changes: 38 additions & 0 deletions opentasks/src/main/java/org/dmfs/tasks/data/CpQuery.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Copyright 2017 dmfs GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.dmfs.tasks.data;

import android.content.ContentProviderClient;
import android.content.Context;

import org.dmfs.android.contentpal.RowSet;


/**
* Represents a ContentProvider query resulting in ContentPal's {@link RowSet}.
*
* @author Gabor Keszthelyi
*/
public interface CpQuery<T>
{

/**
* Returns the {@link RowSet} that represent the result of this query.
*/
RowSet<T> rowSet(ContentProviderClient client, Context appContext);

}
Loading

0 comments on commit e9f8cc6

Please sign in to comment.