From 2228dbf0f4109e5146fda92b4d9bea9f043b1537 Mon Sep 17 00:00:00 2001 From: "Alinson S. Xavier" Date: Thu, 26 Nov 2020 15:08:49 -0600 Subject: [PATCH] Create new UNKNOWN checkmark state --- .../activities/common/views/HistoryChart.java | 2 +- .../habits/list/views/CheckmarkButtonView.kt | 1 + .../habits/list/views/CheckmarkPanelView.kt | 2 +- .../widgets/views/CheckmarkWidgetView.java | 4 ++- .../src/main/res/values/fontawesome.xml | 2 +- .../isoron/uhabits/core/models/Checkmark.java | 17 +++++++---- .../uhabits/core/models/CheckmarkList.java | 9 ++++-- .../org/isoron/uhabits/core/models/Habit.java | 2 +- .../uhabits/core/models/Repetition.java | 2 ++ .../uhabits/core/models/RepetitionList.java | 2 +- .../uhabits/core/models/StreakList.java | 4 +-- .../models/memory/MemoryCheckmarkList.java | 2 +- .../uhabits/core/test/HabitFixtures.java | 4 ++- .../uhabits/core/ui/NotificationTray.java | 2 +- .../core/models/CheckmarkListTest.java | 28 +++++++++---------- 15 files changed, 49 insertions(+), 34 deletions(-) diff --git a/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/common/views/HistoryChart.java b/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/common/views/HistoryChart.java index 2363554a7..c3995a892 100644 --- a/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/common/views/HistoryChart.java +++ b/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/common/views/HistoryChart.java @@ -391,7 +391,7 @@ public class HistoryChart extends ScrollableChart else { checkmark = checkmarks[checkmarkOffset]; - if(checkmark == 0) + if(checkmark <= 0) { pSquareBg.setColor(colors[0]); pSquareFg.setColor(textColors[1]); diff --git a/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/views/CheckmarkButtonView.kt b/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/views/CheckmarkButtonView.kt index 166158ea2..4b55d1b97 100644 --- a/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/views/CheckmarkButtonView.kt +++ b/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/views/CheckmarkButtonView.kt @@ -114,6 +114,7 @@ class CheckmarkButtonView( val id = when (value) { SKIP -> R.string.fa_skipped NO -> R.string.fa_times + UNKNOWN -> R.string.fa_question else -> R.string.fa_check } val label = resources.getString(id) diff --git a/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/views/CheckmarkPanelView.kt b/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/views/CheckmarkPanelView.kt index 4696f0bb5..8048ad0c1 100644 --- a/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/views/CheckmarkPanelView.kt +++ b/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/views/CheckmarkPanelView.kt @@ -62,7 +62,7 @@ class CheckmarkPanelView( val timestamp = today.minus(index + dataOffset) button.value = when { index + dataOffset < values.size -> values[index + dataOffset] - else -> NO + else -> UNKNOWN } button.color = color button.onToggle = { value -> onToggle(timestamp, value) } diff --git a/android/uhabits-android/src/main/java/org/isoron/uhabits/widgets/views/CheckmarkWidgetView.java b/android/uhabits-android/src/main/java/org/isoron/uhabits/widgets/views/CheckmarkWidgetView.java index 8b4e08bc8..fd554d2c7 100644 --- a/android/uhabits-android/src/main/java/org/isoron/uhabits/widgets/views/CheckmarkWidgetView.java +++ b/android/uhabits-android/src/main/java/org/isoron/uhabits/widgets/views/CheckmarkWidgetView.java @@ -86,8 +86,8 @@ public class CheckmarkWidgetView extends HabitWidgetView { case Checkmark.YES_AUTO: case Checkmark.NO: + case Checkmark.UNKNOWN: default: - getResources().getString(R.string.fa_times); bgColor = res.getColor(R.attr.cardBgColor); fgColor = res.getColor(R.attr.mediumContrastTextColor); setShadowAlpha(0x00); @@ -120,6 +120,8 @@ public class CheckmarkWidgetView extends HabitWidgetView { return getResources().getString(R.string.fa_check); case Checkmark.SKIP: return getResources().getString(R.string.fa_skipped); + case Checkmark.UNKNOWN: + return getResources().getString(R.string.fa_question); case Checkmark.NO: default: return getResources().getString(R.string.fa_times); diff --git a/android/uhabits-android/src/main/res/values/fontawesome.xml b/android/uhabits-android/src/main/res/values/fontawesome.xml index 7c95f1b38..f12f99732 100644 --- a/android/uhabits-android/src/main/res/values/fontawesome.xml +++ b/android/uhabits-android/src/main/res/values/fontawesome.xml @@ -26,6 +26,7 @@ + @@ -281,7 +282,6 @@ - diff --git a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/models/Checkmark.java b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/models/Checkmark.java index 88bc0ae05..acaada1ca 100644 --- a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/models/Checkmark.java +++ b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/models/Checkmark.java @@ -43,27 +43,32 @@ import static org.isoron.uhabits.core.utils.StringUtils.defaultToStringStyle; public final class Checkmark { /** - * Indicates that there was an explicit skip at the timestamp. + * Checkmark value indicating that the habit is not applicable for this timestamp. */ public static final int SKIP = 3; /** - * Indicates that there was a repetition at the timestamp. + * Checkmark value indicating that the user has performed the habit at this timestamp. */ public static final int YES_MANUAL = 2; /** - * Indicates that there was no repetition at the timestamp, but one was not - * expected in any case, due to the frequency of the habit. + * Checkmark value indicating that the user did not perform the habit, but they were not + * expected to, because of the frequency of the habit. */ public static final int YES_AUTO = 1; /** - * Indicates that there was no repetition at the timestamp, even though a - * repetition was expected. + * Checkmark value indicating that the user did not perform the habit, even though they were + * expected to perform it. */ public static final int NO = 0; + /** + * Checkmark value indicating that no data is available for the given timestamp. + */ + public static final int UNKNOWN = -1; + private final Timestamp timestamp; /** 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 9e838d6c3..f92247ab8 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 @@ -62,7 +62,7 @@ public abstract class CheckmarkList int nDays = begin.daysUntil(today) + 1; List checkmarks = new ArrayList<>(nDays); for (int i = 0; i < nDays; i++) - checkmarks.add(new Checkmark(today.minus(i), NO)); + checkmarks.add(new Checkmark(today.minus(i), UNKNOWN)); for (Interval interval : intervals) { @@ -79,7 +79,10 @@ public abstract class CheckmarkList { Timestamp date = rep.getTimestamp(); int offset = date.daysUntil(today); - checkmarks.set(offset, new Checkmark(date, rep.getValue())); + int value = rep.getValue(); + int prevValue = checkmarks.get(offset).getValue(); + if (prevValue < value) + checkmarks.set(offset, new Checkmark(date, value)); } return checkmarks; @@ -224,7 +227,7 @@ public abstract class CheckmarkList { Checkmark today = getToday(); if (today != null) return today.getValue(); - else return NO; + else return UNKNOWN; } public synchronized int getThisWeekValue(int firstWeekday) diff --git a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/models/Habit.java b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/models/Habit.java index 6d2a555cd..19a0f5119 100644 --- a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/models/Habit.java +++ b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/models/Habit.java @@ -332,7 +332,7 @@ public class Habit else return todayCheckmark / 1000.0 <= data.targetValue; } - else return (todayCheckmark != NO); + else return (todayCheckmark != NO && todayCheckmark != UNKNOWN); } public synchronized boolean isNumerical() diff --git a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/models/Repetition.java b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/models/Repetition.java index a41546cb8..9c3ec30f9 100644 --- a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/models/Repetition.java +++ b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/models/Repetition.java @@ -60,6 +60,7 @@ public final class Repetition { switch(value) { case NO: + case UNKNOWN: case YES_AUTO: return YES_MANUAL; case YES_MANUAL: @@ -74,6 +75,7 @@ public final class Repetition { switch(value) { case NO: + case UNKNOWN: case YES_AUTO: return YES_MANUAL; default: diff --git a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/models/RepetitionList.java b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/models/RepetitionList.java index bdb61658d..682c865e3 100644 --- a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/models/RepetitionList.java +++ b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/models/RepetitionList.java @@ -85,7 +85,7 @@ public abstract class RepetitionList public int getValue(Timestamp timestamp) { Repetition rep = getByTimestamp(timestamp); - if (rep == null) return Checkmark.NO; + if (rep == null) return Checkmark.UNKNOWN; return rep.getValue(); } diff --git a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/models/StreakList.java b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/models/StreakList.java index 036ca2119..054c197cc 100644 --- a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/models/StreakList.java +++ b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/models/StreakList.java @@ -138,8 +138,8 @@ public abstract class StreakList current = current.plus(1); int j = checks.length - i - 1; - if ((checks[j + 1] == 0 && checks[j] > 0)) list.add(current); - if ((checks[j + 1] > 0 && checks[j] == 0)) list.add(current.minus(1)); + if ((checks[j + 1] <= 0 && checks[j] > 0)) list.add(current); + if ((checks[j + 1] > 0 && checks[j] <= 0)) list.add(current.minus(1)); } if (list.size() % 2 == 1) list.add(current); diff --git a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/models/memory/MemoryCheckmarkList.java b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/models/memory/MemoryCheckmarkList.java index 3504c2a3d..b6f8e29b9 100644 --- a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/models/memory/MemoryCheckmarkList.java +++ b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/models/memory/MemoryCheckmarkList.java @@ -68,7 +68,7 @@ public class MemoryCheckmarkList extends CheckmarkList { Timestamp t = to.minus(i); if(t.isNewerThan(newestComputed) || t.isOlderThan(oldestComputed)) - filtered.add(new Checkmark(t, Checkmark.NO)); + filtered.add(new Checkmark(t, Checkmark.UNKNOWN)); else filtered.add(list.get(t.daysUntil(newestComputed))); } diff --git a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/test/HabitFixtures.java b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/test/HabitFixtures.java index 7ac134f07..4ab2675a8 100644 --- a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/test/HabitFixtures.java +++ b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/test/HabitFixtures.java @@ -142,7 +142,9 @@ public class HabitFixtures Timestamp timestamp = DateUtils.getToday(); for (boolean c : NON_DAILY_HABIT_CHECKS) { - if (c) habit.getRepetitions().setValue(timestamp, YES_MANUAL); + int value = NO; + if (c) value = YES_MANUAL; + habit.getRepetitions().setValue(timestamp, value); timestamp = timestamp.minus(1); } diff --git a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/NotificationTray.java b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/NotificationTray.java index 4ada13756..f41b57e43 100644 --- a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/NotificationTray.java +++ b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/NotificationTray.java @@ -186,7 +186,7 @@ public class NotificationTray { systemTray.log("Showing notification for habit=" + habit.id); - if (todayValue != Checkmark.NO) { + if (todayValue != Checkmark.UNKNOWN) { systemTray.log(String.format( Locale.US, "Habit %d already checked. Skipping.", 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 802ca9e23..54787bed1 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 @@ -80,14 +80,14 @@ public class CheckmarkListTest extends BaseUnitTest intervals.add(new CheckmarkList.Interval(day(2), day(2), day(1))); List expected = new ArrayList<>(); - expected.add(new Checkmark(day(0), NO)); + expected.add(new Checkmark(day(0), UNKNOWN)); expected.add(new Checkmark(day(1), YES_MANUAL)); expected.add(new Checkmark(day(2), YES_MANUAL)); - expected.add(new Checkmark(day(3), NO)); + expected.add(new Checkmark(day(3), UNKNOWN)); expected.add(new Checkmark(day(4), YES_AUTO)); expected.add(new Checkmark(day(5), YES_MANUAL)); expected.add(new Checkmark(day(6), YES_AUTO)); - expected.add(new Checkmark(day(7), NO)); + expected.add(new Checkmark(day(7), UNKNOWN)); expected.add(new Checkmark(day(8), YES_AUTO)); expected.add(new Checkmark(day(9), YES_AUTO)); expected.add(new Checkmark(day(10), YES_MANUAL)); @@ -220,9 +220,9 @@ public class CheckmarkListTest extends BaseUnitTest travelInTime(3); int[] expectedValues = { - NO, - NO, - NO, + UNKNOWN, + UNKNOWN, + UNKNOWN, YES_MANUAL, NO, YES_AUTO, @@ -296,7 +296,7 @@ public class CheckmarkListTest extends BaseUnitTest assertThat(checkmarks.getTodayValue(), equalTo(YES_MANUAL)); travelInTime(1); - assertThat(checkmarks.getTodayValue(), equalTo(NO)); + assertThat(checkmarks.getTodayValue(), equalTo(UNKNOWN)); } @Test @@ -320,12 +320,12 @@ public class CheckmarkListTest extends BaseUnitTest YES_AUTO, YES_MANUAL, YES_MANUAL, - NO, - NO, - NO, - NO, - NO, - NO + UNKNOWN, + UNKNOWN, + UNKNOWN, + UNKNOWN, + UNKNOWN, + UNKNOWN }; int[] actualValues = nonDailyHabit.getCheckmarks().getValues(from, to); @@ -475,7 +475,7 @@ public class CheckmarkListTest extends BaseUnitTest assertThat(checkmarks.getThisMonthValue(), equalTo(1006)); DateUtils.setFixedLocalTime(unixTime(2000, MAY, 1)); - assertThat(checkmarks.getTodayValue(), equalTo(0)); + assertThat(checkmarks.getTodayValue(), equalTo(UNKNOWN)); assertThat(checkmarks.getThisWeekValue(SATURDAY), equalTo(0)); assertThat(checkmarks.getThisMonthValue(), equalTo(0)); }