diff --git a/android/uhabits-android/src/androidTest/assets/views/widgets/HistoryWidget/render.png b/android/uhabits-android/src/androidTest/assets/views/widgets/HistoryWidget/render.png index a6ed0060b..279f22d43 100644 Binary files a/android/uhabits-android/src/androidTest/assets/views/widgets/HistoryWidget/render.png and b/android/uhabits-android/src/androidTest/assets/views/widgets/HistoryWidget/render.png differ diff --git a/android/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/common/views/ScoreChartTest.java b/android/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/common/views/ScoreChartTest.java index 6b45576b9..71ce5262f 100644 --- a/android/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/common/views/ScoreChartTest.java +++ b/android/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/common/views/ScoreChartTest.java @@ -50,7 +50,7 @@ public class ScoreChartTest extends BaseViewTest fixtures.purgeHabits(habitList); habit = fixtures.createLongHabit(); presenter = new ScoreCardPresenter(); - ScoreCardViewModel model = presenter.present(habit, prefs.getFirstWeekday(), 0); + ScoreCardViewModel model = presenter.present(habit, prefs.getFirstWeekdayInt(), 0); view = new ScoreChart(targetContext); view.setScores(model.getScores()); @@ -84,7 +84,7 @@ public class ScoreChartTest extends BaseViewTest @Test public void testRender_withMonthlyBucket() throws Throwable { - ScoreCardViewModel model = presenter.present(habit, prefs.getFirstWeekday(), 2); + ScoreCardViewModel model = presenter.present(habit, prefs.getFirstWeekdayInt(), 2); view.setScores(model.getScores()); view.setBucketSize(model.getBucketSize()); view.invalidate(); @@ -102,7 +102,7 @@ public class ScoreChartTest extends BaseViewTest @Test public void testRender_withYearlyBucket() throws Throwable { - ScoreCardViewModel model = presenter.present(habit, prefs.getFirstWeekday(), 4); + ScoreCardViewModel model = presenter.present(habit, prefs.getFirstWeekdayInt(), 4); view.setScores(model.getScores()); view.setBucketSize(model.getBucketSize()); view.invalidate(); diff --git a/android/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/show/views/HistoryCardViewTest.kt b/android/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/show/views/HistoryCardViewTest.kt index ffd2ac4db..f4db382fb 100644 --- a/android/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/show/views/HistoryCardViewTest.kt +++ b/android/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/show/views/HistoryCardViewTest.kt @@ -22,6 +22,7 @@ import android.view.LayoutInflater import android.view.View import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.MediumTest +import org.isoron.platform.time.DayOfWeek.SUNDAY import org.isoron.uhabits.BaseViewTest import org.isoron.uhabits.R import org.isoron.uhabits.core.ui.screens.habits.show.views.HistoryCardPresenter @@ -47,7 +48,7 @@ class HistoryCardViewTest : BaseViewTest() { view.update( HistoryCardPresenter().present( habit = habit, - firstWeekday = 1, + firstWeekday = SUNDAY, isSkipEnabled = false, theme = LightTheme(), ) diff --git a/android/uhabits-android/src/androidTest/java/org/isoron/uhabits/widgets/HistoryWidgetTest.java b/android/uhabits-android/src/androidTest/java/org/isoron/uhabits/widgets/HistoryWidgetTest.java index d5c59fa6c..2d7eaa8ec 100644 --- a/android/uhabits-android/src/androidTest/java/org/isoron/uhabits/widgets/HistoryWidgetTest.java +++ b/android/uhabits-android/src/androidTest/java/org/isoron/uhabits/widgets/HistoryWidgetTest.java @@ -29,8 +29,6 @@ import org.isoron.uhabits.core.models.*; import org.junit.*; import org.junit.runner.*; -import java.util.*; - @RunWith(AndroidJUnit4.class) @MediumTest public class HistoryWidgetTest extends BaseViewTest @@ -49,7 +47,7 @@ public class HistoryWidgetTest extends BaseViewTest prefs.setWidgetOpacity(255); habit = fixtures.createVeryLongHabit(); - HistoryWidget widget = new HistoryWidget(targetContext, 0, habit, Calendar.SUNDAY); + HistoryWidget widget = new HistoryWidget(targetContext, 0, habit); view = convertToView(widget, 400, 400); } diff --git a/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/common/dialogs/HistoryEditorDialog.java b/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/common/dialogs/HistoryEditorDialog.java index a5a0f7665..96c1ecb26 100644 --- a/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/common/dialogs/HistoryEditorDialog.java +++ b/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/common/dialogs/HistoryEditorDialog.java @@ -22,12 +22,12 @@ package org.isoron.uhabits.activities.common.dialogs; import android.app.*; import android.content.*; import android.os.*; +import android.util.*; -import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.annotation.*; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.*; -import android.util.*; import org.isoron.uhabits.*; import org.isoron.uhabits.core.commands.*; diff --git a/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/views/HistoryCardView.kt b/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/views/HistoryCardView.kt index 8e2533d74..d408b0d4c 100644 --- a/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/views/HistoryCardView.kt +++ b/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/views/HistoryCardView.kt @@ -47,15 +47,12 @@ class HistoryCardView(context: Context, attrs: AttributeSet) : LinearLayout(cont today = data.today, paletteColor = data.color, theme = data.theme, - dateFormatter = JavaLocalDateFormatter(Locale.getDefault()) - ).apply { - series = data.series - } + dateFormatter = JavaLocalDateFormatter(Locale.getDefault()), + series = data.series, + firstWeekday = data.firstWeekday, + ) - // binding.historyChart.setFirstWeekday(data.firstWeekday) // binding.historyChart.setSkipEnabled(data.isSkipEnabled) - // binding.historyChart.setEntries(data.entries) - // binding.historyChart.setColor(androidColor) // if (data.isNumerical) { // binding.historyChart.setNumerical(true) // } diff --git a/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/settings/SettingsFragment.java b/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/settings/SettingsFragment.java index 2b7f00070..755b3fd51 100644 --- a/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/settings/SettingsFragment.java +++ b/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/settings/SettingsFragment.java @@ -177,7 +177,7 @@ public class SettingsFragment extends PreferenceFragmentCompat private void updateWeekdayPreference() { ListPreference weekdayPref = (ListPreference) findPreference("pref_first_weekday"); - int currentFirstWeekday = prefs.getFirstWeekday(); + int currentFirstWeekday = prefs.getFirstWeekday().getDaysSinceSunday() + 1; String[] dayNames = DateUtils.getLongWeekdayNames(Calendar.SATURDAY); String[] dayValues = {"7", "1", "2", "3", "4", "5", "6"}; weekdayPref.setEntries(dayNames); diff --git a/android/uhabits-android/src/main/java/org/isoron/uhabits/widgets/FrequencyWidgetProvider.kt b/android/uhabits-android/src/main/java/org/isoron/uhabits/widgets/FrequencyWidgetProvider.kt index 40a4ba82e..488f6ecf8 100644 --- a/android/uhabits-android/src/main/java/org/isoron/uhabits/widgets/FrequencyWidgetProvider.kt +++ b/android/uhabits-android/src/main/java/org/isoron/uhabits/widgets/FrequencyWidgetProvider.kt @@ -28,7 +28,7 @@ class FrequencyWidgetProvider : BaseWidgetProvider() { context, id, habits[0], - preferences.firstWeekday + preferences.firstWeekdayInt ) else return StackWidget(context, id, StackWidgetType.FREQUENCY, habits) } diff --git a/android/uhabits-android/src/main/java/org/isoron/uhabits/widgets/HistoryWidget.kt b/android/uhabits-android/src/main/java/org/isoron/uhabits/widgets/HistoryWidget.kt index 353f382f8..0216d7c5d 100644 --- a/android/uhabits-android/src/main/java/org/isoron/uhabits/widgets/HistoryWidget.kt +++ b/android/uhabits-android/src/main/java/org/isoron/uhabits/widgets/HistoryWidget.kt @@ -35,8 +35,7 @@ import java.util.Locale class HistoryWidget( context: Context, id: Int, - private val habit: Habit, - private val firstWeekday: Int + private val habit: Habit ) : BaseWidget(context, id) { override fun getOnClickPendingIntent(context: Context): PendingIntent { @@ -66,7 +65,9 @@ class HistoryWidget( today = DateUtils.getTodayWithOffset().toLocalDate(), paletteColor = habit.color, theme = WidgetTheme(), - dateFormatter = JavaLocalDateFormatter(Locale.getDefault()) + dateFormatter = JavaLocalDateFormatter(Locale.getDefault()), + firstWeekday = prefs.firstWeekday, + series = listOf(), ) } ).apply { diff --git a/android/uhabits-android/src/main/java/org/isoron/uhabits/widgets/HistoryWidgetProvider.kt b/android/uhabits-android/src/main/java/org/isoron/uhabits/widgets/HistoryWidgetProvider.kt index 9cba71154..014579c5f 100644 --- a/android/uhabits-android/src/main/java/org/isoron/uhabits/widgets/HistoryWidgetProvider.kt +++ b/android/uhabits-android/src/main/java/org/isoron/uhabits/widgets/HistoryWidgetProvider.kt @@ -26,8 +26,7 @@ class HistoryWidgetProvider : BaseWidgetProvider() { if (habits.size == 1) return HistoryWidget( context, id, - habits[0], - preferences.firstWeekday + habits[0] ) else return StackWidget(context, id, StackWidgetType.HISTORY, habits) } diff --git a/android/uhabits-android/src/main/java/org/isoron/uhabits/widgets/ScoreWidget.kt b/android/uhabits-android/src/main/java/org/isoron/uhabits/widgets/ScoreWidget.kt index cb5a74889..2a66ad8ad 100644 --- a/android/uhabits-android/src/main/java/org/isoron/uhabits/widgets/ScoreWidget.kt +++ b/android/uhabits-android/src/main/java/org/isoron/uhabits/widgets/ScoreWidget.kt @@ -40,7 +40,7 @@ class ScoreWidget( val presenter = ScoreCardPresenter() val viewModel = presenter.present( habit = habit, - firstWeekday = prefs.firstWeekday, + firstWeekday = prefs.firstWeekdayInt, spinnerPosition = prefs.scoreCardSpinnerPosition ) val widgetView = view as GraphWidgetView diff --git a/android/uhabits-android/src/main/java/org/isoron/uhabits/widgets/StackWidgetService.java b/android/uhabits-android/src/main/java/org/isoron/uhabits/widgets/StackWidgetService.java index b03c441d3..97179af1a 100644 --- a/android/uhabits-android/src/main/java/org/isoron/uhabits/widgets/StackWidgetService.java +++ b/android/uhabits-android/src/main/java/org/isoron/uhabits/widgets/StackWidgetService.java @@ -97,11 +97,11 @@ class StackRemoteViewsFactory implements RemoteViewsService.RemoteViewsFactory case CHECKMARK: return new CheckmarkWidget(context, widgetId, habit); case FREQUENCY: - return new FrequencyWidget(context, widgetId, habit, prefs.getFirstWeekday()); + return new FrequencyWidget(context, widgetId, habit, prefs.getFirstWeekdayInt()); case SCORE: return new ScoreWidget(context, widgetId, habit); case HISTORY: - return new HistoryWidget(context, widgetId, habit, prefs.getFirstWeekday()); + return new HistoryWidget(context, widgetId, habit); case STREAKS: return new StreakWidget(context, widgetId, habit); } diff --git a/android/uhabits-android/src/main/java/org/isoron/uhabits/widgets/TargetWidget.kt b/android/uhabits-android/src/main/java/org/isoron/uhabits/widgets/TargetWidget.kt index b097785a1..bbda50005 100644 --- a/android/uhabits-android/src/main/java/org/isoron/uhabits/widgets/TargetWidget.kt +++ b/android/uhabits-android/src/main/java/org/isoron/uhabits/widgets/TargetWidget.kt @@ -46,7 +46,7 @@ class TargetWidget( if (preferedBackgroundAlpha >= 255) widgetView.setShadowAlpha(0x4f) val chart = (widgetView.dataView as TargetChart) val presenter = TargetCardPresenter() - val data = presenter.present(habit, prefs.firstWeekday) + val data = presenter.present(habit, prefs.firstWeekdayInt) chart.setColor(data.color.toThemedAndroidColor(context)) chart.setTargets(data.targets) chart.setLabels(data.intervals.map { intervalToLabel(context.resources, it) }) diff --git a/android/uhabits-core/src/main/java/org/isoron/platform/time/Dates.kt b/android/uhabits-core/src/main/java/org/isoron/platform/time/Dates.kt index d7ac92f3b..d3ef6af33 100644 --- a/android/uhabits-core/src/main/java/org/isoron/platform/time/Dates.kt +++ b/android/uhabits-core/src/main/java/org/isoron/platform/time/Dates.kt @@ -23,7 +23,7 @@ import org.isoron.uhabits.core.models.Timestamp import kotlin.math.abs import kotlin.math.ceil -enum class DayOfWeek(val index: Int) { +enum class DayOfWeek(val daysSinceSunday: Int) { SUNDAY(0), MONDAY(1), TUESDAY(2), diff --git a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/preferences/Preferences.java b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/preferences/Preferences.java index dd1260bf3..9dafdd686 100644 --- a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/preferences/Preferences.java +++ b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/preferences/Preferences.java @@ -21,6 +21,7 @@ package org.isoron.uhabits.core.preferences; import androidx.annotation.*; +import org.isoron.platform.time.*; import org.isoron.uhabits.core.models.*; import org.isoron.uhabits.core.ui.*; import org.isoron.uhabits.core.utils.*; @@ -360,13 +361,30 @@ public class Preferences * represented by 7. By default, this is based on the current system locale, * unless the user changed this in the settings. */ - public int getFirstWeekday() + @Deprecated() + public int getFirstWeekdayInt() { String weekday = storage.getString("pref_first_weekday", ""); if (weekday.isEmpty()) return DateUtils.getFirstWeekdayNumberAccordingToLocale(); return Integer.parseInt(weekday); } + public DayOfWeek getFirstWeekday() + { + int weekday = Integer.parseInt(storage.getString("pref_first_weekday", "-1")); + if (weekday < 0) weekday = DateUtils.getFirstWeekdayNumberAccordingToLocale(); + switch (weekday) { + case 1: return DayOfWeek.SUNDAY; + case 2: return DayOfWeek.MONDAY; + case 3: return DayOfWeek.TUESDAY; + case 4: return DayOfWeek.WEDNESDAY; + case 5: return DayOfWeek.THURSDAY; + case 6: return DayOfWeek.FRIDAY; + case 7: return DayOfWeek.SATURDAY; + default: throw new IllegalArgumentException(); + } + } + public interface Listener { default void onCheckmarkSequenceChanged() diff --git a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/screens/habits/show/ShowHabit.kt b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/screens/habits/show/ShowHabit.kt index 2e18cc0d7..de0c1c37e 100644 --- a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/screens/habits/show/ShowHabit.kt +++ b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/screens/habits/show/ShowHabit.kt @@ -78,7 +78,7 @@ class ShowHabitPresenter { ), target = TargetCardPresenter().present( habit = habit, - firstWeekday = preferences.firstWeekday, + firstWeekday = preferences.firstWeekdayInt, ), streaks = StreakCartPresenter().present( habit = habit, @@ -86,11 +86,11 @@ class ShowHabitPresenter { scores = ScoreCardPresenter().present( spinnerPosition = preferences.scoreCardSpinnerPosition, habit = habit, - firstWeekday = preferences.firstWeekday, + firstWeekday = preferences.firstWeekdayInt, ), frequency = FrequencyCardPresenter().present( habit = habit, - firstWeekday = preferences.firstWeekday, + firstWeekday = preferences.firstWeekdayInt, ), history = HistoryCardPresenter().present( habit = habit, @@ -100,7 +100,7 @@ class ShowHabitPresenter { ), bar = BarCardPresenter().present( habit = habit, - firstWeekday = preferences.firstWeekday, + firstWeekday = preferences.firstWeekdayInt, boolSpinnerPosition = preferences.barCardBoolSpinnerPosition, numericalSpinnerPosition = preferences.barCardNumericalSpinnerPosition, theme = theme, diff --git a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/screens/habits/show/views/HistoryCard.kt b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/screens/habits/show/views/HistoryCard.kt index 0fbce37e1..6f7b8d6b0 100644 --- a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/screens/habits/show/views/HistoryCard.kt +++ b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/screens/habits/show/views/HistoryCard.kt @@ -19,6 +19,7 @@ package org.isoron.uhabits.core.ui.screens.habits.show.views +import org.isoron.platform.time.DayOfWeek import org.isoron.platform.time.LocalDate import org.isoron.uhabits.core.models.Entry import org.isoron.uhabits.core.models.Entry.Companion.SKIP @@ -33,7 +34,7 @@ import kotlin.math.max data class HistoryCardViewModel( val color: PaletteColor, - val firstWeekday: Int, + val firstWeekday: DayOfWeek, val series: List, val theme: Theme, val today: LocalDate, @@ -42,7 +43,7 @@ data class HistoryCardViewModel( class HistoryCardPresenter { fun present( habit: Habit, - firstWeekday: Int, + firstWeekday: DayOfWeek, isSkipEnabled: Boolean, theme: Theme, ): HistoryCardViewModel { diff --git a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/views/HistoryChart.kt b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/views/HistoryChart.kt index 4455bda28..2b9442ced 100644 --- a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/views/HistoryChart.kt +++ b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/views/HistoryChart.kt @@ -23,6 +23,7 @@ import org.isoron.platform.gui.Canvas import org.isoron.platform.gui.Color import org.isoron.platform.gui.DataView import org.isoron.platform.gui.TextAlign +import org.isoron.platform.time.DayOfWeek import org.isoron.platform.time.LocalDate import org.isoron.platform.time.LocalDateFormatter import org.isoron.uhabits.core.models.PaletteColor @@ -34,6 +35,8 @@ class HistoryChart( var paletteColor: PaletteColor, var theme: Theme, var dateFormatter: LocalDateFormatter, + var firstWeekday: DayOfWeek, + var series: List, ) : DataView { enum class Square { @@ -43,9 +46,6 @@ class HistoryChart( HATCHED, } - // Data - var series = listOf() - // Style var padding = 0.0 var squareSpacing = 1.0 @@ -69,8 +69,11 @@ class HistoryChart( canvas.setFontSize(height * 0.06) val nColumns = floor((width - 2 * padding) / squareSize).toInt() - 2 - val todayWeekday = today.dayOfWeek - val topLeftOffset = (nColumns - 1 + dataOffset) * 7 + todayWeekday.index + val firstWeekdayOffset = ( + today.dayOfWeek.daysSinceSunday - + firstWeekday.daysSinceSunday + 7 + ) % 7 + val topLeftOffset = (nColumns - 1 + dataOffset) * 7 + firstWeekdayOffset val topLeftDate = today.minus(topLeftOffset) lastPrintedYear = "" diff --git a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/views/Themes.kt b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/views/Themes.kt index 5d46b9fcd..587816da6 100644 --- a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/views/Themes.kt +++ b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/views/Themes.kt @@ -114,4 +114,4 @@ class WidgetTheme : LightTheme() { override val highContrastTextColor = Color.WHITE override val mediumContrastTextColor = Color.WHITE.withAlpha(0.50) override val lowContrastTextColor = Color.WHITE.withAlpha(0.10) -} \ No newline at end of file +} diff --git a/android/uhabits-core/src/test/java/org/isoron/uhabits/core/ui/views/HistoryChartTest.kt b/android/uhabits-core/src/test/java/org/isoron/uhabits/core/ui/views/HistoryChartTest.kt index e9d8a8e87..e97870872 100644 --- a/android/uhabits-core/src/test/java/org/isoron/uhabits/core/ui/views/HistoryChartTest.kt +++ b/android/uhabits-core/src/test/java/org/isoron/uhabits/core/ui/views/HistoryChartTest.kt @@ -21,6 +21,8 @@ package org.isoron.uhabits.components import kotlinx.coroutines.runBlocking import org.isoron.platform.gui.assertRenders +import org.isoron.platform.time.DayOfWeek +import org.isoron.platform.time.DayOfWeek.SUNDAY import org.isoron.platform.time.JavaLocalDateFormatter import org.isoron.platform.time.LocalDate import org.isoron.uhabits.core.models.PaletteColor @@ -37,14 +39,13 @@ import java.util.Locale class HistoryChartTest { val base = "views/HistoryChart" - val fmt = JavaLocalDateFormatter(Locale.US) - val theme = LightTheme() + val view = HistoryChart( - LocalDate(2015, 1, 25), - PaletteColor(7), - theme, - fmt, - ).apply { + today = LocalDate(2015, 1, 25), + paletteColor = PaletteColor(7), + theme = LightTheme(), + dateFormatter = JavaLocalDateFormatter(Locale.US), + firstWeekday = SUNDAY, series = listOf( 2, // today 2, 1, 2, 1, 2, 1, 2, @@ -68,19 +69,24 @@ class HistoryChartTest { else -> OFF } } - } + ) // TODO: Label overflow // TODO: onClick // TODO: HistoryEditorDialog // TODO: Remove excessive padding on widgets - // TODO: First day of the week @Test fun testDraw() = runBlocking { assertRenders(400, 200, "$base/base.png", view) } + @Test + fun testDrawWeekDay() = runBlocking { + view.firstWeekday = DayOfWeek.MONDAY + assertRenders(400, 200, "$base/weekday.png", view) + } + @Test fun testDrawDifferentSize() = runBlocking { assertRenders(200, 200, "$base/small.png", view)