diff --git a/.gitignore b/.gitignore index f79b06d45..ac138eede 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ *~.nib *.hprof .DS_Store +._.DS_Store .externalNativeBuild .gradle .idea diff --git a/CHANGELOG.md b/CHANGELOG.md index 7d889e7fc..e976b8d35 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +### 1.8.8 (June 21, 2020) + +* Make small changes to the habit scheduling algorithm, so that "1 time every x days" habits work more predictably. +* Fix crash when saving habit + ### 1.8.0 (Jan 1, 2020) * New bar chart showing number of repetitions performed in each week, month, quarter or year. diff --git a/android/build.sh b/android/build.sh index 4a2c05d2d..bb15f5541 100755 --- a/android/build.sh +++ b/android/build.sh @@ -181,8 +181,8 @@ fetch_images() { } accept_images() { - find tmp/test-screenshots -name '*.expected*' -delete - rsync -av tmp/test-screenshots/ uhabits-android/src/androidTest/assets/ + find $OUTPUTS_DIR/test-screenshots -name '*.expected*' -delete + rsync -av $OUTPUTS_DIR/test-screenshots/ uhabits-android/src/androidTest/assets/ } run_tests() { diff --git a/android/gradle.properties b/android/gradle.properties index c88c721dc..6e98ecfec 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -1,5 +1,5 @@ -VERSION_CODE = 50 -VERSION_NAME = 1.8.7 +VERSION_CODE = 51 +VERSION_NAME = 1.8.8 MIN_SDK_VERSION = 21 TARGET_SDK_VERSION = 29 diff --git a/android/uhabits-android/src/androidTest/assets/views-v26/common/HistoryChart/render.png b/android/uhabits-android/src/androidTest/assets/views-v26/common/HistoryChart/render.png index 95c71e671..d7a66cc79 100644 Binary files a/android/uhabits-android/src/androidTest/assets/views-v26/common/HistoryChart/render.png and b/android/uhabits-android/src/androidTest/assets/views-v26/common/HistoryChart/render.png differ diff --git a/android/uhabits-android/src/androidTest/assets/views-v26/common/HistoryChart/renderDataOffset.png b/android/uhabits-android/src/androidTest/assets/views-v26/common/HistoryChart/renderDataOffset.png index 9fbec7ea3..b094d1e3d 100644 Binary files a/android/uhabits-android/src/androidTest/assets/views-v26/common/HistoryChart/renderDataOffset.png and b/android/uhabits-android/src/androidTest/assets/views-v26/common/HistoryChart/renderDataOffset.png differ diff --git a/android/uhabits-android/src/androidTest/assets/views-v26/common/HistoryChart/renderDifferentSize.png b/android/uhabits-android/src/androidTest/assets/views-v26/common/HistoryChart/renderDifferentSize.png index f2a712b89..4507f30ba 100644 Binary files a/android/uhabits-android/src/androidTest/assets/views-v26/common/HistoryChart/renderDifferentSize.png and b/android/uhabits-android/src/androidTest/assets/views-v26/common/HistoryChart/renderDifferentSize.png differ diff --git a/android/uhabits-android/src/androidTest/assets/views-v26/common/HistoryChart/renderTransparent.png b/android/uhabits-android/src/androidTest/assets/views-v26/common/HistoryChart/renderTransparent.png index 860b326d4..5d997f32c 100644 Binary files a/android/uhabits-android/src/androidTest/assets/views-v26/common/HistoryChart/renderTransparent.png and b/android/uhabits-android/src/androidTest/assets/views-v26/common/HistoryChart/renderTransparent.png differ diff --git a/android/uhabits-android/src/androidTest/assets/views-v26/common/ScoreChart/render.png b/android/uhabits-android/src/androidTest/assets/views-v26/common/ScoreChart/render.png index 4ea430a67..c80bd6b5e 100644 Binary files a/android/uhabits-android/src/androidTest/assets/views-v26/common/ScoreChart/render.png and b/android/uhabits-android/src/androidTest/assets/views-v26/common/ScoreChart/render.png differ diff --git a/android/uhabits-android/src/androidTest/assets/views-v26/common/ScoreChart/renderDataOffset.png b/android/uhabits-android/src/androidTest/assets/views-v26/common/ScoreChart/renderDataOffset.png index e0bfe6fd3..3575b52c1 100644 Binary files a/android/uhabits-android/src/androidTest/assets/views-v26/common/ScoreChart/renderDataOffset.png and b/android/uhabits-android/src/androidTest/assets/views-v26/common/ScoreChart/renderDataOffset.png differ diff --git a/android/uhabits-android/src/androidTest/assets/views-v26/common/ScoreChart/renderDifferentSize.png b/android/uhabits-android/src/androidTest/assets/views-v26/common/ScoreChart/renderDifferentSize.png index b550f9814..be33abc00 100644 Binary files a/android/uhabits-android/src/androidTest/assets/views-v26/common/ScoreChart/renderDifferentSize.png and b/android/uhabits-android/src/androidTest/assets/views-v26/common/ScoreChart/renderDifferentSize.png differ diff --git a/android/uhabits-android/src/androidTest/assets/views-v26/common/ScoreChart/renderMonthly.png b/android/uhabits-android/src/androidTest/assets/views-v26/common/ScoreChart/renderMonthly.png index 11ec0904b..85d4cc2ff 100644 Binary files a/android/uhabits-android/src/androidTest/assets/views-v26/common/ScoreChart/renderMonthly.png and b/android/uhabits-android/src/androidTest/assets/views-v26/common/ScoreChart/renderMonthly.png differ diff --git a/android/uhabits-android/src/androidTest/assets/views-v26/common/ScoreChart/renderTransparent.png b/android/uhabits-android/src/androidTest/assets/views-v26/common/ScoreChart/renderTransparent.png index e34f4d671..ffe41bb0a 100644 Binary files a/android/uhabits-android/src/androidTest/assets/views-v26/common/ScoreChart/renderTransparent.png and b/android/uhabits-android/src/androidTest/assets/views-v26/common/ScoreChart/renderTransparent.png differ diff --git a/android/uhabits-android/src/androidTest/assets/views-v26/common/ScoreChart/renderYearly.png b/android/uhabits-android/src/androidTest/assets/views-v26/common/ScoreChart/renderYearly.png index df13dae29..301d43f0a 100644 Binary files a/android/uhabits-android/src/androidTest/assets/views-v26/common/ScoreChart/renderYearly.png and b/android/uhabits-android/src/androidTest/assets/views-v26/common/ScoreChart/renderYearly.png differ diff --git a/android/uhabits-android/src/androidTest/assets/views-v26/common/StreakChart/render.png b/android/uhabits-android/src/androidTest/assets/views-v26/common/StreakChart/render.png index 9eb67f547..657d433fa 100644 Binary files a/android/uhabits-android/src/androidTest/assets/views-v26/common/StreakChart/render.png and b/android/uhabits-android/src/androidTest/assets/views-v26/common/StreakChart/render.png differ diff --git a/android/uhabits-android/src/androidTest/assets/views-v26/common/StreakChart/renderSmallSize.png b/android/uhabits-android/src/androidTest/assets/views-v26/common/StreakChart/renderSmallSize.png index 6701961bc..4014e47cf 100644 Binary files a/android/uhabits-android/src/androidTest/assets/views-v26/common/StreakChart/renderSmallSize.png and b/android/uhabits-android/src/androidTest/assets/views-v26/common/StreakChart/renderSmallSize.png differ diff --git a/android/uhabits-android/src/androidTest/assets/views-v26/common/StreakChart/renderTransparent.png b/android/uhabits-android/src/androidTest/assets/views-v26/common/StreakChart/renderTransparent.png index 9eb67f547..657d433fa 100644 Binary files a/android/uhabits-android/src/androidTest/assets/views-v26/common/StreakChart/renderTransparent.png and b/android/uhabits-android/src/androidTest/assets/views-v26/common/StreakChart/renderTransparent.png differ diff --git a/android/uhabits-android/src/androidTest/assets/views-v26/habits/show/ScoreCard/render.png b/android/uhabits-android/src/androidTest/assets/views-v26/habits/show/ScoreCard/render.png index 12aaa2785..9a7eacb9c 100644 Binary files a/android/uhabits-android/src/androidTest/assets/views-v26/habits/show/ScoreCard/render.png and b/android/uhabits-android/src/androidTest/assets/views-v26/habits/show/ScoreCard/render.png differ diff --git a/android/uhabits-android/src/main/play/release-notes/en-US/alpha.txt b/android/uhabits-android/src/main/play/release-notes/en-US/alpha.txt index 3ebc70286..6cb4c5aa1 100644 --- a/android/uhabits-android/src/main/play/release-notes/en-US/alpha.txt +++ b/android/uhabits-android/src/main/play/release-notes/en-US/alpha.txt @@ -1,11 +1,12 @@ -1.8.7 -* Fix issue causing multiple notifications to be dismissed at once +1.8.8 +* Small tweaks to the habit scheduling algorithm +* Fix some crashes 1.8: * New bar chart showing number of repetitions performed each week, month or year * Performing habits on irregular weekdays will no longer break your streak * More colors to choose from (now 20 in total) -* Ability to customize how transparent the widgets are -* Ability to customize the first day of the week -* Yes/No buttons on notifications instead of just "Check" +* Customize how transparent the widgets are +* Customize the first day of the week +* Yes/No buttons on notifications * Automatic dark theme (Android 10) * Smaller APK and backup files diff --git a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/models/CheckmarkList.java b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/models/CheckmarkList.java index 7211ec15e..497a9af16 100644 --- a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/models/CheckmarkList.java +++ b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/models/CheckmarkList.java @@ -122,22 +122,28 @@ public abstract class CheckmarkList } /** - * Starting from the oldest interval, this function tries to slide the + * Starting from the second newest interval, this function tries to slide the * intervals backwards into the past, so that gaps are eliminated and - * streaks are maximized. When it detects that sliding an interval - * would not help fixing any gap, it leaves the interval unchanged. + * streaks are maximized. */ static void snapIntervalsTogether(@NonNull ArrayList intervals) { - for (int i = 1; i < intervals.size(); i++) + int n = intervals.size(); + for (int i = n - 2; i >= 0; i--) { Interval curr = intervals.get(i); - Interval prev = intervals.get(i - 1); + Interval next = intervals.get(i + 1); - int gap = prev.end.daysUntil(curr.begin) - 1; - if (gap <= 0 || curr.end.minus(gap).isOlderThan(curr.center)) continue; - intervals.set(i, new Interval(curr.begin.minus(gap), curr.center, - curr.end.minus(gap))); + int gapNextToCurrent = next.begin.daysUntil(curr.end); + int gapCenterToEnd = curr.center.daysUntil(curr.end); + + if (gapNextToCurrent >= 0) + { + int shift = Math.min(gapCenterToEnd, gapNextToCurrent + 1); + intervals.set(i, new Interval(curr.begin.minus(shift), + curr.center, + curr.end.minus(shift))); + } } } diff --git a/android/uhabits-core/src/test/java/org/isoron/uhabits/core/models/CheckmarkListTest.java b/android/uhabits-core/src/test/java/org/isoron/uhabits/core/models/CheckmarkListTest.java index 02ad7acf7..09bbe2eaf 100644 --- a/android/uhabits-core/src/test/java/org/isoron/uhabits/core/models/CheckmarkListTest.java +++ b/android/uhabits-core/src/test/java/org/isoron/uhabits/core/models/CheckmarkListTest.java @@ -319,16 +319,31 @@ public class CheckmarkListTest extends BaseUnitTest public void test_snapIntervalsTogether_1() throws Exception { ArrayList original = new ArrayList<>(); - original.add(new CheckmarkList.Interval(day(40), day(40), day(34))); - original.add(new CheckmarkList.Interval(day(25), day(25), day(19))); - original.add(new CheckmarkList.Interval(day(16), day(16), day(10))); + original.add(new CheckmarkList.Interval(day(27), day(27), day(21))); + original.add(new CheckmarkList.Interval(day(20), day(20), day(14))); + original.add(new CheckmarkList.Interval(day(12), day(12), day(6))); original.add(new CheckmarkList.Interval(day(8), day(8), day(2))); ArrayList expected = new ArrayList<>(); - expected.add(new CheckmarkList.Interval(day(40), day(40), day(34))); - expected.add(new CheckmarkList.Interval(day(25), day(25), day(19))); - expected.add(new CheckmarkList.Interval(day(18), day(16), day(12))); - expected.add(new CheckmarkList.Interval(day(11), day(8), day(5))); + expected.add(new CheckmarkList.Interval(day(29), day(27), day(23))); + expected.add(new CheckmarkList.Interval(day(22), day(20), day(16))); + expected.add(new CheckmarkList.Interval(day(15), day(12), day(9))); + expected.add(new CheckmarkList.Interval(day(8), day(8), day(2))); + + CheckmarkList.snapIntervalsTogether(original); + assertThat(original, equalTo(expected)); + } + + @Test + public void test_snapIntervalsTogether_2() throws Exception + { + ArrayList original = new ArrayList<>(); + original.add(new CheckmarkList.Interval(day(11), day(8), day(5))); + original.add(new CheckmarkList.Interval(day(6), day(4), day(0))); + + ArrayList expected = new ArrayList<>(); + expected.add(new CheckmarkList.Interval(day(13), day(8), day(7))); + expected.add(new CheckmarkList.Interval(day(6), day(4), day(0))); CheckmarkList.snapIntervalsTogether(original); assertThat(original, equalTo(expected)); diff --git a/android/uhabits-core/src/test/java/org/isoron/uhabits/core/models/ScoreListTest.java b/android/uhabits-core/src/test/java/org/isoron/uhabits/core/models/ScoreListTest.java index 0270a7e29..e5d9db1a3 100644 --- a/android/uhabits-core/src/test/java/org/isoron/uhabits/core/models/ScoreListTest.java +++ b/android/uhabits-core/src/test/java/org/isoron/uhabits/core/models/ScoreListTest.java @@ -153,9 +153,9 @@ public class ScoreListTest extends BaseUnitTest habit.getScores().groupBy(DateUtils.TruncateField.MONTH, Calendar.SATURDAY); assertThat(list.size(), equalTo(5)); - assertThat(list.get(0).getValue(), closeTo(0.653659, E)); - assertThat(list.get(1).getValue(), closeTo(0.622715, E)); - assertThat(list.get(2).getValue(), closeTo(0.520997, E)); + assertThat(list.get(0).getValue(), closeTo(0.687724, E)); + assertThat(list.get(1).getValue(), closeTo(0.636747, E)); + assertThat(list.get(2).getValue(), closeTo(0.533860, E)); } @Test