From 39cec6f11da4585d99daa75e975c884730ba98d0 Mon Sep 17 00:00:00 2001 From: Quentin Hibon Date: Mon, 25 Jan 2021 10:56:37 +0100 Subject: [PATCH] Convert Preferences --- .../uhabits/widgets/BaseWidgetProvider.kt | 2 +- .../isoron/uhabits/widgets/WidgetUpdater.kt | 2 +- .../uhabits/core/preferences/Preferences.java | 439 ------------------ .../uhabits/core/preferences/Preferences.kt | 294 ++++++++++++ .../core/preferences/PropertiesStorage.java | 134 ------ .../core/preferences/PropertiesStorage.kt | 99 ++++ .../core/preferences/WidgetPreferences.java | 82 ---- .../core/preferences/WidgetPreferences.kt | 69 +++ .../core/reminders/ReminderScheduler.kt | 2 +- .../core/ui/screens/habits/list/HintList.kt | 2 +- 10 files changed, 466 insertions(+), 659 deletions(-) delete mode 100644 uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/preferences/Preferences.java create mode 100644 uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/preferences/Preferences.kt delete mode 100644 uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/preferences/PropertiesStorage.java create mode 100644 uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/preferences/PropertiesStorage.kt delete mode 100644 uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/preferences/WidgetPreferences.java create mode 100644 uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/preferences/WidgetPreferences.kt 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 1a41d0f4f..6fae9fc9c 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 d577727e0..bd6d7a50e 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.java b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/preferences/Preferences.java deleted file mode 100644 index 262235526..000000000 --- a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/preferences/Preferences.java +++ /dev/null @@ -1,439 +0,0 @@ -/* - * Copyright (C) 2016-2021 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -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.*; - -import java.util.*; - -public class Preferences -{ - @NonNull - private final Storage storage; - - @NonNull - private List listeners; - - @Nullable - private Boolean shouldReverseCheckmarks = null; - public Preferences(@NonNull Storage storage) - { - this.storage = storage; - listeners = new LinkedList<>(); - storage.onAttached(this); - } - - public void addListener(Listener listener) - { - listeners.add(listener); - } - - public Integer getDefaultHabitColor(int fallbackColor) - { - return storage.getInt("pref_default_habit_palette_color", - fallbackColor); - } - - public HabitList.Order getDefaultPrimaryOrder() - { - String name = storage.getString("pref_default_order", "BY_POSITION"); - - try - { - return HabitList.Order.valueOf(name); - } - catch (IllegalArgumentException e) - { - setDefaultPrimaryOrder(HabitList.Order.BY_POSITION); - return HabitList.Order.BY_POSITION; - } - } - - public HabitList.Order getDefaultSecondaryOrder() { - String name = storage.getString("pref_default_secondary_order", "BY_NAME_ASC"); - - try - { - return HabitList.Order.valueOf(name); - } - catch (IllegalArgumentException e) - { - setDefaultSecondaryOrder(HabitList.Order.BY_NAME_ASC); - return HabitList.Order.BY_POSITION; - } - } - - public void setDefaultPrimaryOrder(HabitList.Order order) - { - storage.putString("pref_default_order", order.name()); - } - - public void setDefaultSecondaryOrder(HabitList.Order order) - { - storage.putString("pref_default_secondary_order", order.name()); - } - - public int getScoreCardSpinnerPosition() - { - return Math.min(4, Math.max(0, storage.getInt("pref_score_view_interval", 1))); - } - - public void setScoreCardSpinnerPosition(int position) - { - storage.putInt("pref_score_view_interval", position); - } - - public int getBarCardBoolSpinnerPosition() - { - return Math.min(3, Math.max(0, storage.getInt("pref_bar_card_bool_spinner", 0))); - } - - public void setBarCardBoolSpinnerPosition(int position) - { - storage.putInt("pref_bar_card_bool_spinner", position); - } - - public int getBarCardNumericalSpinnerPosition() - { - return Math.min(4, Math.max(0, storage.getInt("pref_bar_card_numerical_spinner", 0))); - } - - public void setBarCardNumericalSpinnerPosition(int position) - { - storage.putInt("pref_bar_card_numerical_spinner", position); - } - - public int getLastHintNumber() - { - return storage.getInt("last_hint_number", -1); - } - - public Timestamp getLastHintTimestamp() - { - long unixTime = storage.getLong("last_hint_timestamp", -1); - if (unixTime < 0) return null; - else return new Timestamp(unixTime); - } - - public boolean getShowArchived() - { - return storage.getBoolean("pref_show_archived", false); - } - - public void setShowArchived(boolean showArchived) - { - storage.putBoolean("pref_show_archived", showArchived); - } - - public boolean getShowCompleted() - { - return storage.getBoolean("pref_show_completed", true); - } - - public void setShowCompleted(boolean showCompleted) - { - storage.putBoolean("pref_show_completed", showCompleted); - } - - public long getSnoozeInterval() - { - return Long.parseLong(storage.getString("pref_snooze_interval", "15")); - } - - public void setSnoozeInterval(int interval) - { - storage.putString("pref_snooze_interval", String.valueOf(interval)); - } - - public int getTheme() - { - return storage.getInt("pref_theme", ThemeSwitcher.THEME_AUTOMATIC); - } - - public void setTheme(int theme) - { - storage.putInt("pref_theme", theme); - } - - public void incrementLaunchCount() - { - storage.putInt("launch_count", getLaunchCount() + 1); - } - - public int getLaunchCount() - { - return storage.getInt("launch_count", 0); - } - - public boolean isDeveloper() - { - return storage.getBoolean("pref_developer", false); - } - - public void setDeveloper(boolean isDeveloper) - { - storage.putBoolean("pref_developer", isDeveloper); - } - - public boolean isFirstRun() - { - return storage.getBoolean("pref_first_run", true); - } - - public void setFirstRun(boolean isFirstRun) - { - storage.putBoolean("pref_first_run", isFirstRun); - } - - public boolean isPureBlackEnabled() - { - return storage.getBoolean("pref_pure_black", false); - } - - public void setPureBlackEnabled(boolean enabled) - { - storage.putBoolean("pref_pure_black", enabled); - } - - public boolean isShortToggleEnabled() - { - return storage.getBoolean("pref_short_toggle", false); - } - - public void setShortToggleEnabled(boolean enabled) - { - storage.putBoolean("pref_short_toggle", enabled); - } - - public void removeListener(Listener listener) - { - listeners.remove(listener); - } - - public void clear() - { - storage.clear(); - } - - public void setDefaultHabitColor(int color) - { - storage.putInt("pref_default_habit_palette_color", color); - } - - public void setNotificationsSticky(boolean sticky) - { - storage.putBoolean("pref_sticky_notifications", sticky); - for (Listener l : listeners) l.onNotificationsChanged(); - } - - public void setNotificationsLed(boolean enabled) - { - storage.putBoolean("pref_led_notifications", enabled); - for (Listener l : listeners) l.onNotificationsChanged(); - } - - public boolean shouldMakeNotificationsSticky() - { - return storage.getBoolean("pref_sticky_notifications", false); - } - - public boolean shouldMakeNotificationsLed() - { - return storage.getBoolean("pref_led_notifications", false); - } - - public boolean isCheckmarkSequenceReversed() - { - if (shouldReverseCheckmarks == null) shouldReverseCheckmarks = - storage.getBoolean("pref_checkmark_reverse_order", false); - - return shouldReverseCheckmarks; - } - - public void setCheckmarkSequenceReversed(boolean reverse) - { - shouldReverseCheckmarks = reverse; - storage.putBoolean("pref_checkmark_reverse_order", reverse); - for (Listener l : listeners) l.onCheckmarkSequenceChanged(); - } - - public void updateLastHint(int number, Timestamp timestamp) - { - storage.putInt("last_hint_number", number); - storage.putLong("last_hint_timestamp", timestamp.getUnixTime()); - } - - public int getLastAppVersion() - { - return storage.getInt("last_version", 0); - } - - public void setLastAppVersion(int version) - { - storage.putInt("last_version", version); - } - - public int getWidgetOpacity() - { - return Integer.parseInt(storage.getString("pref_widget_opacity", "255")); - } - - public void setWidgetOpacity(int value) - { - storage.putString("pref_widget_opacity", Integer.toString(value)); - } - - public boolean isSkipEnabled() - { - return storage.getBoolean("pref_skip_enabled", false); - } - - public void setSkipEnabled(boolean value) - { - storage.putBoolean("pref_skip_enabled", value); - } - - public String getSyncBaseURL() - { - return storage.getString("pref_sync_base_url", ""); - } - - public String getSyncKey() - { - return storage.getString("pref_sync_key", ""); - } - - public String getEncryptionKey() - { - return storage.getString("pref_encryption_key", ""); - } - - public boolean isSyncEnabled() - { - return storage.getBoolean("pref_sync_enabled", false); - } - - public void enableSync(String syncKey, String encKey) - { - storage.putBoolean("pref_sync_enabled", true); - storage.putString("pref_sync_key", syncKey); - storage.putString("pref_encryption_key", encKey); - for (Listener l : listeners) l.onSyncEnabled(); - } - - public void disableSync() - { - storage.putBoolean("pref_sync_enabled", false); - storage.putString("pref_sync_key", ""); - storage.putString("pref_encryption_key", ""); - } - - public boolean areQuestionMarksEnabled() - { - return storage.getBoolean("pref_unknown_enabled", false); - } - - /** - * @return An integer representing the first day of the week. Sunday - * corresponds to 1, Monday to 2, and so on, until Saturday, which is - * represented by 7. By default, this is based on the current system locale, - * unless the user changed this in the settings. - */ - @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() - { - } - - default void onNotificationsChanged() - { - } - - default void onSyncEnabled() - { - } - } - - public interface Storage - { - void clear(); - - boolean getBoolean(String key, boolean defValue); - - int getInt(String key, int defValue); - - long getLong(String key, long defValue); - - String getString(String key, String defValue); - - void onAttached(Preferences preferences); - - void putBoolean(String key, boolean value); - - void putInt(String key, int value); - - void putLong(String key, long value); - - void putString(String key, String value); - - void remove(String key); - - default void putLongArray(String key, long[] values) - { - putString(key, StringUtils.joinLongs(values)); - } - - default long[] getLongArray(String key, long[] defValue) - { - String string = getString(key, ""); - if (string.isEmpty()) return defValue; - else return StringUtils.splitLongs(string); - } - } -} 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 new file mode 100644 index 000000000..43fd47a24 --- /dev/null +++ b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/preferences/Preferences.kt @@ -0,0 +1,294 @@ +/* + * Copyright (C) 2016-2021 Álinson Santos Xavier + * + * This file is part of Loop Habit Tracker. + * + * Loop Habit Tracker is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * Loop Habit Tracker is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ +package org.isoron.uhabits.core.preferences + +import org.isoron.platform.time.DayOfWeek +import org.isoron.uhabits.core.models.HabitList +import org.isoron.uhabits.core.models.Timestamp +import org.isoron.uhabits.core.ui.ThemeSwitcher +import org.isoron.uhabits.core.utils.DateUtils.Companion.getFirstWeekdayNumberAccordingToLocale +import org.isoron.uhabits.core.utils.StringUtils.Companion.joinLongs +import org.isoron.uhabits.core.utils.StringUtils.Companion.splitLongs +import java.util.LinkedList +import kotlin.math.max +import kotlin.math.min + +class Preferences(private val storage: Storage) { + private val listeners: MutableList + private var shouldReverseCheckmarks: Boolean? = null + fun addListener(listener: Listener) { + listeners.add(listener) + } + + fun getDefaultHabitColor(fallbackColor: Int): Int { + return storage.getInt( + "pref_default_habit_palette_color", + fallbackColor + ) + } + + var defaultPrimaryOrder: HabitList.Order + get() { + val name = storage.getString("pref_default_order", "BY_POSITION") + return try { + HabitList.Order.valueOf(name) + } catch (e: IllegalArgumentException) { + defaultPrimaryOrder = HabitList.Order.BY_POSITION + HabitList.Order.BY_POSITION + } + } + set(order) { + storage.putString("pref_default_order", order.name) + } + var defaultSecondaryOrder: HabitList.Order + get() { + val name = storage.getString("pref_default_secondary_order", "BY_NAME_ASC") + return try { + HabitList.Order.valueOf(name) + } catch (e: IllegalArgumentException) { + defaultSecondaryOrder = HabitList.Order.BY_NAME_ASC + HabitList.Order.BY_POSITION + } + } + set(order) { + storage.putString("pref_default_secondary_order", order.name) + } + var scoreCardSpinnerPosition: Int + get() = min(4, max(0, storage.getInt("pref_score_view_interval", 1))) + set(position) { + storage.putInt("pref_score_view_interval", position) + } + var barCardBoolSpinnerPosition: Int + get() = min(3, max(0, storage.getInt("pref_bar_card_bool_spinner", 0))) + set(position) { + storage.putInt("pref_bar_card_bool_spinner", position) + } + var barCardNumericalSpinnerPosition: Int + get() = min(4, max(0, storage.getInt("pref_bar_card_numerical_spinner", 0))) + set(position) { + storage.putInt("pref_bar_card_numerical_spinner", position) + } + val lastHintNumber: Int + get() = storage.getInt("last_hint_number", -1) + val lastHintTimestamp: Timestamp? + get() { + val unixTime = storage.getLong("last_hint_timestamp", -1) + return if (unixTime < 0) null else Timestamp(unixTime) + } + var showArchived: Boolean + get() = storage.getBoolean("pref_show_archived", false) + set(showArchived) { + storage.putBoolean("pref_show_archived", showArchived) + } + var showCompleted: Boolean + get() = storage.getBoolean("pref_show_completed", true) + set(showCompleted) { + storage.putBoolean("pref_show_completed", showCompleted) + } + val snoozeInterval: Long + get() = storage.getString("pref_snooze_interval", "15").toLong() + + fun setSnoozeInterval(interval: Int) { + storage.putString("pref_snooze_interval", interval.toString()) + } + + var theme: Int + get() = storage.getInt("pref_theme", ThemeSwitcher.THEME_AUTOMATIC) + set(theme) { + storage.putInt("pref_theme", theme) + } + + fun incrementLaunchCount() { + storage.putInt("launch_count", launchCount + 1) + } + + val launchCount: Int + get() = storage.getInt("launch_count", 0) + var isDeveloper: Boolean + get() = storage.getBoolean("pref_developer", false) + set(isDeveloper) { + storage.putBoolean("pref_developer", isDeveloper) + } + var isFirstRun: Boolean + get() = storage.getBoolean("pref_first_run", true) + set(isFirstRun) { + storage.putBoolean("pref_first_run", isFirstRun) + } + var isPureBlackEnabled: Boolean + get() = storage.getBoolean("pref_pure_black", false) + set(enabled) { + storage.putBoolean("pref_pure_black", enabled) + } + var isShortToggleEnabled: Boolean + get() = storage.getBoolean("pref_short_toggle", false) + set(enabled) { + storage.putBoolean("pref_short_toggle", enabled) + } + + fun removeListener(listener: Listener) { + listeners.remove(listener) + } + + fun clear() { + storage.clear() + } + + fun setDefaultHabitColor(color: Int) { + storage.putInt("pref_default_habit_palette_color", color) + } + + fun setNotificationsSticky(sticky: Boolean) { + storage.putBoolean("pref_sticky_notifications", sticky) + for (l in listeners) l.onNotificationsChanged() + } + + fun setNotificationsLed(enabled: Boolean) { + storage.putBoolean("pref_led_notifications", enabled) + for (l in listeners) l.onNotificationsChanged() + } + + fun shouldMakeNotificationsSticky(): Boolean { + return storage.getBoolean("pref_sticky_notifications", false) + } + + fun shouldMakeNotificationsLed(): Boolean { + return storage.getBoolean("pref_led_notifications", false) + } + + var isCheckmarkSequenceReversed: Boolean + get() { + if (shouldReverseCheckmarks == null) shouldReverseCheckmarks = + storage.getBoolean("pref_checkmark_reverse_order", false) + return shouldReverseCheckmarks!! + } + set(reverse) { + shouldReverseCheckmarks = reverse + storage.putBoolean("pref_checkmark_reverse_order", reverse) + for (l in listeners) l.onCheckmarkSequenceChanged() + } + + fun updateLastHint(number: Int, timestamp: Timestamp) { + storage.putInt("last_hint_number", number) + storage.putLong("last_hint_timestamp", timestamp.unixTime) + } + + var lastAppVersion: Int + get() = storage.getInt("last_version", 0) + set(version) { + storage.putInt("last_version", version) + } + var widgetOpacity: Int + get() = storage.getString("pref_widget_opacity", "255").toInt() + set(value) { + storage.putString("pref_widget_opacity", value.toString()) + } + var isSkipEnabled: Boolean + get() = storage.getBoolean("pref_skip_enabled", false) + set(value) { + storage.putBoolean("pref_skip_enabled", value) + } + val syncBaseURL: String + get() = storage.getString("pref_sync_base_url", "") + val syncKey: String + get() = storage.getString("pref_sync_key", "") + val encryptionKey: String + get() = storage.getString("pref_encryption_key", "") + val isSyncEnabled: Boolean + get() = storage.getBoolean("pref_sync_enabled", false) + + fun enableSync(syncKey: String, encKey: String) { + storage.putBoolean("pref_sync_enabled", true) + storage.putString("pref_sync_key", syncKey) + storage.putString("pref_encryption_key", encKey) + for (l in listeners) l.onSyncEnabled() + } + + fun disableSync() { + storage.putBoolean("pref_sync_enabled", false) + storage.putString("pref_sync_key", "") + storage.putString("pref_encryption_key", "") + } + + fun areQuestionMarksEnabled(): Boolean { + return storage.getBoolean("pref_unknown_enabled", false) + } + + /** + * @return An integer representing the first day of the week. Sunday + * corresponds to 1, Monday to 2, and so on, until Saturday, which is + * represented by 7. By default, this is based on the current system locale, + * unless the user changed this in the settings. + */ + @get:Deprecated("") + val firstWeekdayInt: Int + get() { + val weekday = storage.getString("pref_first_weekday", "") + return if (weekday.isEmpty()) getFirstWeekdayNumberAccordingToLocale() else weekday.toInt() + } + val firstWeekday: DayOfWeek + get() { + var weekday = storage.getString("pref_first_weekday", "-1").toInt() + if (weekday < 0) weekday = getFirstWeekdayNumberAccordingToLocale() + return when (weekday) { + 1 -> DayOfWeek.SUNDAY + 2 -> DayOfWeek.MONDAY + 3 -> DayOfWeek.TUESDAY + 4 -> DayOfWeek.WEDNESDAY + 5 -> DayOfWeek.THURSDAY + 6 -> DayOfWeek.FRIDAY + 7 -> DayOfWeek.SATURDAY + else -> throw IllegalArgumentException() + } + } + + interface Listener { + fun onCheckmarkSequenceChanged() {} + fun onNotificationsChanged() {} + fun onSyncEnabled() {} + } + + interface Storage { + fun clear() + fun getBoolean(key: String, defValue: Boolean): Boolean + fun getInt(key: String, defValue: Int): Int + fun getLong(key: String, defValue: Long): Long + fun getString(key: String, defValue: String): String + fun onAttached(preferences: Preferences) + fun putBoolean(key: String, value: Boolean) + fun putInt(key: String, value: Int) + fun putLong(key: String, value: Long) + fun putString(key: String, value: String) + fun remove(key: String) + fun putLongArray(key: String, values: LongArray) { + putString(key, joinLongs(values)) + } + + fun getLongArray(key: String, defValue: LongArray): LongArray? { + val string = getString(key, "") + return if (string.isEmpty()) defValue else splitLongs( + string + ) + } + } + + init { + listeners = LinkedList() + storage.onAttached(this) + } +} diff --git a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/preferences/PropertiesStorage.java b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/preferences/PropertiesStorage.java deleted file mode 100644 index a1e231b4c..000000000 --- a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/preferences/PropertiesStorage.java +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright (C) 2016-2021 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.uhabits.core.preferences; - -import androidx.annotation.*; - -import java.io.*; -import java.util.*; - -public class PropertiesStorage implements Preferences.Storage -{ - @NonNull - private final Properties props; - - @NonNull - private File file; - - public PropertiesStorage(@NonNull File file) - { - try - { - this.file = file; - props = new Properties(); - props.load(new FileInputStream(file)); - } - catch (IOException e) - { - throw new RuntimeException(e); - } - } - - @Override - public void clear() - { - for(String key : props.stringPropertyNames()) props.remove(key); - flush(); - } - - @Override - public boolean getBoolean(String key, boolean defValue) - { - String value = props.getProperty(key, Boolean.toString(defValue)); - return Boolean.parseBoolean(value); - } - - @Override - public int getInt(String key, int defValue) - { - String value = props.getProperty(key, Integer.toString(defValue)); - return Integer.parseInt(value); - } - - @Override - public long getLong(String key, long defValue) - { - String value = props.getProperty(key, Long.toString(defValue)); - return Long.parseLong(value); - } - - @Override - public String getString(String key, String defValue) - { - return props.getProperty(key, defValue); - } - - @Override - public void onAttached(Preferences preferences) - { - // nop - } - - @Override - public void putBoolean(String key, boolean value) - { - props.setProperty(key, Boolean.toString(value)); - } - - @Override - public void putInt(String key, int value) - { - props.setProperty(key, Integer.toString(value)); - flush(); - } - - private void flush() - { - try - { - props.store(new FileOutputStream(file), ""); - } - catch (IOException e) - { - throw new RuntimeException(e); - } - } - - @Override - public void putLong(String key, long value) - { - props.setProperty(key, Long.toString(value)); - flush(); - } - - @Override - public void putString(String key, String value) - { - props.setProperty(key, value); - flush(); - } - - @Override - public void remove(String key) - { - props.remove(key); - flush(); - } -} diff --git a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/preferences/PropertiesStorage.kt b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/preferences/PropertiesStorage.kt new file mode 100644 index 000000000..8987730e6 --- /dev/null +++ b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/preferences/PropertiesStorage.kt @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2016-2021 Álinson Santos Xavier + * + * This file is part of Loop Habit Tracker. + * + * Loop Habit Tracker is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * Loop Habit Tracker is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ +package org.isoron.uhabits.core.preferences + +import java.io.File +import java.io.FileInputStream +import java.io.FileOutputStream +import java.io.IOException +import java.util.Properties + +class PropertiesStorage(file: File) : Preferences.Storage { + private var props: Properties + private val file: File + override fun clear() { + for (key in props.stringPropertyNames()) props.remove(key) + flush() + } + + override fun getBoolean(key: String, defValue: Boolean): Boolean { + val value = props.getProperty(key, java.lang.Boolean.toString(defValue)) + return java.lang.Boolean.parseBoolean(value) + } + + override fun getInt(key: String, defValue: Int): Int { + val value = props.getProperty(key, defValue.toString()) + return value.toInt() + } + + override fun getLong(key: String, defValue: Long): Long { + val value = props.getProperty(key, defValue.toString()) + return value.toLong() + } + + override fun getString(key: String, defValue: String): String { + return props.getProperty(key, defValue) + } + + override fun onAttached(preferences: Preferences) { + // nop + } + + override fun putBoolean(key: String, value: Boolean) { + props.setProperty(key, java.lang.Boolean.toString(value)) + } + + override fun putInt(key: String, value: Int) { + props.setProperty(key, value.toString()) + flush() + } + + private fun flush() { + try { + props.store(FileOutputStream(file), "") + } catch (e: IOException) { + throw RuntimeException(e) + } + } + + override fun putLong(key: String, value: Long) { + props.setProperty(key, value.toString()) + flush() + } + + override fun putString(key: String, value: String) { + props.setProperty(key, value) + flush() + } + + override fun remove(key: String) { + props.remove(key) + flush() + } + + init { + try { + this.file = file + props = Properties() + props.load(FileInputStream(file)) + } catch (e: IOException) { + throw RuntimeException(e) + } + } +} diff --git a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/preferences/WidgetPreferences.java b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/preferences/WidgetPreferences.java deleted file mode 100644 index b75316abe..000000000 --- a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/preferences/WidgetPreferences.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (C) 2016-2021 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.uhabits.core.preferences; - -import org.isoron.uhabits.core.AppScope; - -import javax.inject.Inject; - -@AppScope -public class WidgetPreferences { - private Preferences.Storage storage; - - @Inject - public WidgetPreferences(Preferences.Storage storage) { - this.storage = storage; - } - - public void addWidget(int widgetId, long[] habitIds) { - storage.putLongArray(getHabitIdKey(widgetId), habitIds); - } - - public long[] getHabitIdsFromWidgetId(int widgetId) { - long[] habitIds; - String habitIdKey = getHabitIdKey(widgetId); - try { - habitIds = storage.getLongArray(habitIdKey, new long[]{-1}); - } catch (ClassCastException e) { - // 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 = new long[1]; - habitIds[0] = storage.getLong(habitIdKey, -1); - storage.putLongArray(habitIdKey, habitIds); - } - return habitIds; - } - - public void removeWidget(int id) { - String habitIdKey = getHabitIdKey(id); - storage.remove(habitIdKey); - } - - public long getSnoozeTime(long id) - { - return storage.getLong(getSnoozeKey(id), 0); - } - - private String getHabitIdKey(int id) { - return String.format("widget-%06d-habit", id); - } - - private String getSnoozeKey(long id) - { - return String.format("snooze-%06d", id); - } - - public void removeSnoozeTime(long id) - { - storage.putLong(getSnoozeKey(id), 0); - } - - public void setSnoozeTime(Long id, long time) - { - storage.putLong(getSnoozeKey(id), time); - } -} 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 new file mode 100644 index 000000000..68bff6885 --- /dev/null +++ b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/preferences/WidgetPreferences.kt @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2016-2021 Álinson Santos Xavier + * + * This file is part of Loop Habit Tracker. + * + * Loop Habit Tracker is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * Loop Habit Tracker is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ +package org.isoron.uhabits.core.preferences + +import org.isoron.uhabits.core.AppScope +import javax.inject.Inject + +@AppScope +class WidgetPreferences @Inject constructor(private val storage: Preferences.Storage) { + fun addWidget(widgetId: Int, habitIds: LongArray) { + storage.putLongArray(getHabitIdKey(widgetId), habitIds) + } + + fun getHabitIdsFromWidgetId(widgetId: Int): LongArray? { + var habitIds: LongArray? + val habitIdKey = getHabitIdKey(widgetId) + try { + habitIds = storage.getLongArray(habitIdKey, longArrayOf(-1)) + } 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) + } + return habitIds + } + + fun removeWidget(id: Int) { + val habitIdKey = getHabitIdKey(id) + storage.remove(habitIdKey) + } + + fun getSnoozeTime(id: Long): Long { + return storage.getLong(getSnoozeKey(id), 0) + } + + private fun getHabitIdKey(id: Int): String { + return String.format("widget-%06d-habit", id) + } + + private fun getSnoozeKey(id: Long): String { + return String.format("snooze-%06d", id) + } + + fun removeSnoozeTime(id: Long) { + storage.putLong(getSnoozeKey(id), 0) + } + + fun setSnoozeTime(id: Long, time: Long) { + storage.putLong(getSnoozeKey(id), time) + } +} diff --git a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/reminders/ReminderScheduler.kt b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/reminders/ReminderScheduler.kt index 7f602e11a..1b40d30da 100644 --- a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/reminders/ReminderScheduler.kt +++ b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/reminders/ReminderScheduler.kt @@ -129,7 +129,7 @@ class ReminderScheduler @Inject constructor( fun snoozeReminder(habit: Habit, minutes: Long) { val now = applyTimezone(getLocalTime()) val snoozedUntil = now + minutes * 60 * 1000 - widgetPreferences.setSnoozeTime(habit.id, snoozedUntil) + widgetPreferences.setSnoozeTime(habit.id!!, snoozedUntil) schedule(habit) } diff --git a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/ui/screens/habits/list/HintList.kt b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/ui/screens/habits/list/HintList.kt index 8ef33a051..fec0d4099 100644 --- a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/ui/screens/habits/list/HintList.kt +++ b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/ui/screens/habits/list/HintList.kt @@ -51,6 +51,6 @@ class HintList(private val prefs: Preferences, private val hints: Array) fun shouldShow(): Boolean { val today = getToday() val lastHintTimestamp = prefs.lastHintTimestamp - return lastHintTimestamp.isOlderThan(today) + return lastHintTimestamp?.isOlderThan(today) == true } }