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 Nov 13, 2017
1 parent 1b106c6 commit fa28433
Show file tree
Hide file tree
Showing 52 changed files with 1,684 additions and 150 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.

6 changes: 6 additions & 0 deletions .idea/inspectionProfiles/Project_Default.xml

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

4 changes: 3 additions & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@ TARGET_SDK_VERSION=25
# dependency versions
SUPPORT_LIBRARY_VERSION=25.0.1
CONTENTPAL_VERSION=2d16bb5
ROBOLECTRIC_VERSION=3.1.4
ROBOLECTRIC_VERSION=3.1.4
BOLTS_VERSION=a43822b
ANDROID_TEST_RUNNER_VERSION=0.5
4 changes: 2 additions & 2 deletions opentasks-provider/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ dependencies {
androidTestCompile project(':opentaskspal')
androidTestCompile 'com.github.dmfs.contentpal:contenttestpal:' + CONTENTPAL_VERSION
androidTestCompile 'com.android.support:support-annotations:' + SUPPORT_LIBRARY_VERSION
androidTestCompile 'com.android.support.test:runner:0.5'
androidTestCompile 'com.android.support.test:rules:0.5'
androidTestCompile 'com.android.support.test:runner:' + ANDROID_TEST_RUNNER_VERSION
androidTestCompile 'com.android.support.test:rules:' + ANDROID_TEST_RUNNER_VERSION
androidTestCompile 'org.hamcrest:hamcrest-library:1.3'
}
16 changes: 15 additions & 1 deletion opentasks/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ android {
targetSdkVersion TARGET_SDK_VERSION.toInteger()
versionCode gitCommitNo() * 10 // spread version code to allow inserting versions if necessary
versionName version
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
Expand All @@ -41,6 +42,9 @@ android {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
dataBinding {
enabled = true
}
}

dependencies {
Expand All @@ -51,14 +55,24 @@ dependencies {
exclude group: 'xmlpull', module: 'xmlpull'
}
compile project(':opentasks-provider')
compile project(':opentaskspal')
compile 'com.google.android.apps.dashclock:dashclock-api:2.0.0'
compile 'com.github.dmfs:color-picker:1.0'
compile 'au.com.codeka:carrot:2.4.0'
compile('com.github.dmfs.androidcarrot:androidcarrot:5a4baa0222') {
exclude module: 'carrot'
exclude group: 'com.android.support'
}
compile 'org.dmfs:essentials:1.9'
compile 'org.dmfs:essentials:1.10'
compile 'io.reactivex.rxjava2:rxjava:2.1.5'
compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
compile 'com.github.dmfs.bolts:color-bolts:' + BOLTS_VERSION

testCompile 'junit:junit:4.12'
androidTestCompile ('com.android.support.test:runner:' + ANDROID_TEST_RUNNER_VERSION) {
exclude group: 'com.android.support', module: 'support-annotations'
}
androidTestCompile ('com.android.support.test:rules:' + ANDROID_TEST_RUNNER_VERSION) {
exclude group: 'com.android.support', module: 'support-annotations'
}
}
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.** { *; }
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
/*
* 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.utils;

import android.support.test.runner.AndroidJUnit4;
import android.text.format.Time;

import org.dmfs.rfc5545.DateTime;
import org.dmfs.rfc5545.Duration;
import org.junit.Test;
import org.junit.runner.RunWith;

import java.util.TimeZone;


/**
* Test for {@link DateFormatter#toTime(DateTime)} method.
*
* @author Gabor Keszthelyi
*/
@RunWith(AndroidJUnit4.class)
public class DateTimeToTimeConversionTest
{

@Test
public void test_toTime_withVariousDateTimes()
{
assertCorrectlyConverted(DateTime.now());

assertCorrectlyConverted(DateTime.now(TimeZone.getTimeZone("UTC+04:00")));

assertCorrectlyConverted(DateTime.nowAndHere());

assertCorrectlyConverted(new DateTime(1509473781000L));

assertCorrectlyConverted(new DateTime(1509473781000L).addDuration(new Duration(1, 1, 0)));

assertCorrectlyConverted(DateTime.now(TimeZone.getTimeZone("UTC+04:00")).shiftTimeZone(TimeZone.getTimeZone("UTC+05:00")));

// Floating, all-day
assertCorrectlyConverted(DateTime.now().toAllDay());

// Not DST (March 2017 in Hungary):
assertCorrectlyConverted(new DateTime(TimeZone.getTimeZone("Europe/Budapest"), 2017, 2 - 1, 7, 15, 0, 0));
assertCorrectlyConverted(new DateTime(2017, 2 - 1, 7, 15, 0, 0).shiftTimeZone(TimeZone.getTimeZone("Europe/Budapest")));
assertCorrectlyConverted(new DateTime(2017, 2 - 1, 7, 15, 0, 0).swapTimeZone(TimeZone.getTimeZone("Europe/Budapest")));

// DST (July 2017 in Hungary):
assertCorrectlyConverted(new DateTime(TimeZone.getTimeZone("Europe/Budapest"), 2017, 7 - 1, 7, 15, 0, 0));
assertCorrectlyConverted(new DateTime(2017, 7 - 1, 7, 15, 0, 0).shiftTimeZone(TimeZone.getTimeZone("Europe/Budapest")));
assertCorrectlyConverted(new DateTime(2017, 7 - 1, 7, 15, 0, 0).swapTimeZone(TimeZone.getTimeZone("Europe/Budapest")));
}


@Test(expected = IllegalArgumentException.class)
public void test_toTime_forFloatingButNotAllDayDateTime_throwsSinceItIsNotSupported()
{
new DateFormatter(null).toTime(new DateTime(2017, 7 - 1, 7, 15, 0, 0));
}


private void assertCorrectlyConverted(DateTime dateTime)
{
Time time = new DateFormatter(null).toTime(dateTime);
if (!isEquivalentDateTimeAndTime(dateTime, time))
{
throw new AssertionError(String.format("DateTime=%s and Time=%s are not equivalent", dateTime, time));
}
}


/**
* Contains the definition/requirement of when a {@link DateTime} and {@link Time} is considered equivalent in this project.
*/
private boolean isEquivalentDateTimeAndTime(DateTime dateTime, Time time)
{
// Time doesn't seem to store in millis precision, there is a 1000 multiplier internally when calculating millis,
// so we can only compare to this precision:
boolean millisMatch =
dateTime.getTimestamp() / 1000
==
time.toMillis(false) / 1000;

boolean allDaysMatch = time.allDay == dateTime.isAllDay();

boolean timeZoneMatch =
// If DateTime is floating, all-day then if the all-day flag is matched with Time (checked earlier)
// then we consider the Time's timezone matching, we ignore that basically,
// because Time always has a time zone, and there is no other way to represent all-day date-times with Time.
(dateTime.isFloating() && dateTime.isAllDay())
||
// This is the regular case with non-floating DateTime
(dateTime.getTimeZone() != null && time.timezone.equals(dateTime.getTimeZone().getID()));

return millisMatch && allDaysMatch && timeZoneMatch;
}

}
7 changes: 6 additions & 1 deletion opentasks/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="org.dmfs.tasks">

<uses-permission android:name="org.dmfs.permission.READ_TASKS"/>
Expand All @@ -11,12 +12,16 @@
<uses-permission android:name="com.android.alarm.permission.SET_ALARM"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>

<!--TODO Remove after https://github.com/dmfs/opentasks/issues/392-->
<uses-sdk tools:overrideLibrary="org.dmfs.android.bolts"/>

<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:name=".TasksApplication"
android:taskAffinity="org.dmfs.tasks.TaskListActivity"
android:theme="@style/OpenTasksAppTheme">
android:theme="@style/OpenTasksAppTheme"
android:supportsRtl="false">

<!-- TaskListActivity listens for MAIN intents -->
<activity
Expand Down
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 @@ -809,7 +810,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
14 changes: 2 additions & 12 deletions opentasks/src/main/java/org/dmfs/tasks/ViewTaskActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@

import android.annotation.SuppressLint;
import android.content.Intent;
import android.graphics.Color;
import android.net.Uri;
import android.os.Build.VERSION;
import android.os.Bundle;
Expand All @@ -30,6 +29,7 @@

import org.dmfs.tasks.model.ContentSet;
import org.dmfs.tasks.utils.BaseActivity;
import org.dmfs.tasks.utils.Darkened;


/**
Expand Down Expand Up @@ -132,16 +132,6 @@ public void onDelete(Uri taskUri)
}


private int darkenColor(int color)
{
float[] hsv = new float[3];
Color.colorToHSV(color, hsv);
hsv[2] = hsv[2] * 0.75f;
color = Color.HSVToColor(hsv);
return color;
}


@SuppressLint("NewApi")
@Override
public void updateColor(int color)
Expand All @@ -151,7 +141,7 @@ public void updateColor(int color)
{
Window window = getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.setStatusBarColor(darkenColor(color));
window.setStatusBarColor(new Darkened(color).argb());
}
}

Expand Down
43 changes: 31 additions & 12 deletions opentasks/src/main/java/org/dmfs/tasks/ViewTaskFragment.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,13 @@
import android.view.animation.AlphaAnimation;
import android.widget.TextView;

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 @@ -64,13 +67,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.Disposable;
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 @@ -131,6 +139,8 @@ public class ViewTaskFragment extends SupportFragment
*/
private TaskView mDetailView;

private Disposable mDisposable;

private int mListColor;
private int mOldStatus = -1;
private boolean mPinned = false;
Expand Down Expand Up @@ -208,14 +218,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 @@ -266,6 +268,7 @@ public void onDestroyView()
mDetailView.setValues(null);
}

mDisposable.dispose();
}


Expand Down Expand Up @@ -400,8 +403,8 @@ public void loadUri(Uri uri)

if ((oldUri == null) != (uri == null))
{
/*
* getActivity().invalidateOptionsMenu() doesn't work in Android 2.x so use the compat lib
/*
* getActivity().invalidateOptionsMenu() doesn't work in Android 2.x so use the compat lib
*/
ActivityCompat.invalidateOptionsMenu(getActivity());
}
Expand Down Expand Up @@ -491,8 +494,8 @@ public void onModelLoaded(Model model)
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater)
{
/*
* Don't show any options if we don't have a task to show.
/*
* Don't show any options if we don't have a task to show.
*/
if (mTaskUri != null)
{
Expand Down Expand Up @@ -717,6 +720,22 @@ public void onContentLoaded(ContentSet contentSet)
postUpdateView();
}
}

mDisposable = 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
Loading

0 comments on commit fa28433

Please sign in to comment.