From 0bc2a8b6d4b65454528dd22e5048546513711cc3 Mon Sep 17 00:00:00 2001 From: Quentin Hibon Date: Sun, 1 Aug 2021 18:13:40 +0200 Subject: [PATCH 1/4] Handle target widget type in stacked widget Fixes #965. --- .../java/org/isoron/uhabits/widgets/StackWidgetService.kt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/widgets/StackWidgetService.kt b/uhabits-android/src/main/java/org/isoron/uhabits/widgets/StackWidgetService.kt index e73f20259..75018cead 100644 --- a/uhabits-android/src/main/java/org/isoron/uhabits/widgets/StackWidgetService.kt +++ b/uhabits-android/src/main/java/org/isoron/uhabits/widgets/StackWidgetService.kt @@ -53,7 +53,7 @@ internal class StackRemoteViewsFactory(private val context: Context, intent: Int AppWidgetManager.INVALID_APPWIDGET_ID ) private val habitIds: LongArray - private val widgetType: StackWidgetType? + private val widgetType: StackWidgetType private var remoteViews = ArrayList() override fun onCreate() {} override fun onDestroy() {} @@ -105,7 +105,7 @@ internal class StackRemoteViewsFactory(private val context: Context, intent: Int StackWidgetType.SCORE -> ScoreWidget(context, widgetId, habit, true) StackWidgetType.HISTORY -> HistoryWidget(context, widgetId, habit, true) StackWidgetType.STREAKS -> StreakWidget(context, widgetId, habit, true) - else -> throw IllegalStateException() + StackWidgetType.TARGET -> TargetWidget(context, widgetId, habit, true) } } @@ -157,6 +157,7 @@ internal class StackRemoteViewsFactory(private val context: Context, intent: Int if (widgetTypeValue < 0) throw RuntimeException("invalid widget type") if (habitIdsStr == null) throw RuntimeException("habitIdsStr is null") widgetType = StackWidgetType.getWidgetTypeFromValue(widgetTypeValue) + ?: throw RuntimeException("unknown widget type value: $widgetTypeValue") habitIds = splitLongs(habitIdsStr) } } From a5ae2eaa635a98a2ea064cabb6a35b27c7ba0573 Mon Sep 17 00:00:00 2001 From: Quentin Hibon Date: Sun, 1 Aug 2021 18:15:48 +0200 Subject: [PATCH 2/4] Improve one 'when' --- .../isoron/uhabits/widgets/StackWidgetType.kt | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/widgets/StackWidgetType.kt b/uhabits-android/src/main/java/org/isoron/uhabits/widgets/StackWidgetType.kt index f69ace1c6..68e8018aa 100644 --- a/uhabits-android/src/main/java/org/isoron/uhabits/widgets/StackWidgetType.kt +++ b/uhabits-android/src/main/java/org/isoron/uhabits/widgets/StackWidgetType.kt @@ -27,14 +27,14 @@ enum class StackWidgetType(val value: Int) { companion object { fun getWidgetTypeFromValue(value: Int): StackWidgetType? { - return when { - CHECKMARK.value == value -> CHECKMARK - FREQUENCY.value == value -> FREQUENCY - SCORE.value == value -> SCORE - HISTORY.value == value -> HISTORY - STREAKS.value == value -> STREAKS - TARGET.value == value -> TARGET - else -> throw IllegalStateException() + return when (value) { + CHECKMARK.value -> CHECKMARK + FREQUENCY.value -> FREQUENCY + SCORE.value -> SCORE + HISTORY.value -> HISTORY + STREAKS.value -> STREAKS + TARGET.value -> TARGET + else -> null } } From 67b55a4ecfb50a09e958e49f373792468d0a0153 Mon Sep 17 00:00:00 2001 From: Quentin Hibon Date: Sun, 1 Aug 2021 18:24:41 +0200 Subject: [PATCH 3/4] Fix off-by-one bug in StackWidgetService --- .../main/java/org/isoron/uhabits/widgets/StackWidgetService.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/widgets/StackWidgetService.kt b/uhabits-android/src/main/java/org/isoron/uhabits/widgets/StackWidgetService.kt index 75018cead..0e60914e5 100644 --- a/uhabits-android/src/main/java/org/isoron/uhabits/widgets/StackWidgetService.kt +++ b/uhabits-android/src/main/java/org/isoron/uhabits/widgets/StackWidgetService.kt @@ -86,7 +86,7 @@ internal class StackRemoteViewsFactory(private val context: Context, intent: Int override fun getViewAt(position: Int): RemoteViews? { Log.i("StackRemoteViewsFactory", "getViewAt $position") - return if (position < 0 || position > remoteViews.size) null else remoteViews[position] + return if (0 <= position && position < remoteViews.size) remoteViews[position] else null } private fun constructWidget( From 91ff5f7a0c63e04ad488ccdd0b261a5b87e29ed8 Mon Sep 17 00:00:00 2001 From: Quentin Hibon Date: Sun, 1 Aug 2021 19:32:36 +0200 Subject: [PATCH 4/4] Use empty array instead of sentinel value -1 as habitId --- .../isoron/uhabits/widgets/BaseWidgetProvider.kt | 2 +- .../org/isoron/uhabits/widgets/WidgetUpdater.kt | 2 +- .../uhabits/core/preferences/Preferences.kt | 2 +- .../uhabits/core/preferences/WidgetPreferences.kt | 15 +++++++-------- 4 files changed, 10 insertions(+), 11 deletions(-) diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/widgets/BaseWidgetProvider.kt b/uhabits-android/src/main/java/org/isoron/uhabits/widgets/BaseWidgetProvider.kt index 6fae9fc9c..1a41d0f4f 100644 --- a/uhabits-android/src/main/java/org/isoron/uhabits/widgets/BaseWidgetProvider.kt +++ b/uhabits-android/src/main/java/org/isoron/uhabits/widgets/BaseWidgetProvider.kt @@ -109,7 +109,7 @@ abstract class BaseWidgetProvider : AppWidgetProvider() { } protected fun getHabitsFromWidgetId(widgetId: Int): List { - val selectedIds = widgetPrefs.getHabitIdsFromWidgetId(widgetId)!! + val selectedIds = widgetPrefs.getHabitIdsFromWidgetId(widgetId) val selectedHabits = ArrayList(selectedIds.size) for (id in selectedIds) { val h = habits.getById(id) ?: throw HabitNotFoundException() diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/widgets/WidgetUpdater.kt b/uhabits-android/src/main/java/org/isoron/uhabits/widgets/WidgetUpdater.kt index bd6d7a50e..d577727e0 100644 --- a/uhabits-android/src/main/java/org/isoron/uhabits/widgets/WidgetUpdater.kt +++ b/uhabits-android/src/main/java/org/isoron/uhabits/widgets/WidgetUpdater.kt @@ -95,7 +95,7 @@ class WidgetUpdater val modifiedWidgetIds = when (modifiedHabitId) { null -> widgetIds.toList() else -> widgetIds.filter { w -> - widgetPrefs.getHabitIdsFromWidgetId(w)!!.contains(modifiedHabitId) + widgetPrefs.getHabitIdsFromWidgetId(w).contains(modifiedHabitId) } } diff --git a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/preferences/Preferences.kt b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/preferences/Preferences.kt index 8fdd26af9..70526d311 100644 --- a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/preferences/Preferences.kt +++ b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/preferences/Preferences.kt @@ -258,7 +258,7 @@ open class Preferences(private val storage: Storage) { putString(key, joinLongs(values)) } - fun getLongArray(key: String, defValue: LongArray): LongArray? { + fun getLongArray(key: String, defValue: LongArray): LongArray { val string = getString(key, "") return if (string.isEmpty()) defValue else splitLongs( string diff --git a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/preferences/WidgetPreferences.kt b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/preferences/WidgetPreferences.kt index 68bff6885..8cb8409d7 100644 --- a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/preferences/WidgetPreferences.kt +++ b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/preferences/WidgetPreferences.kt @@ -27,19 +27,18 @@ class WidgetPreferences @Inject constructor(private val storage: Preferences.Sto storage.putLongArray(getHabitIdKey(widgetId), habitIds) } - fun getHabitIdsFromWidgetId(widgetId: Int): LongArray? { - var habitIds: LongArray? + fun getHabitIdsFromWidgetId(widgetId: Int): LongArray { val habitIdKey = getHabitIdKey(widgetId) - try { - habitIds = storage.getLongArray(habitIdKey, longArrayOf(-1)) + return try { + storage.getLongArray(habitIdKey, longArrayOf()) } catch (e: ClassCastException) { // Up to Loop 1.7.11, this preference was not an array, but a single // long. Trying to read the old preference causes a cast exception. - habitIds = LongArray(1) - habitIds[0] = storage.getLong(habitIdKey, -1) - storage.putLongArray(habitIdKey, habitIds) + when (val habitId = storage.getLong(habitIdKey, -1)) { + -1L -> longArrayOf() + else -> longArrayOf(habitId) + } } - return habitIds } fun removeWidget(id: Int) {