mirror of
https://github.com/iSoron/uhabits.git
synced 2025-12-06 01:08:50 -06:00
Merge branch 'master' into dev
This commit is contained in:
@@ -262,7 +262,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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -23,6 +23,7 @@ import org.isoron.uhabits.core.AppScope
|
||||
import org.isoron.uhabits.core.commands.Command
|
||||
import org.isoron.uhabits.core.commands.CommandRunner
|
||||
import org.isoron.uhabits.core.commands.CreateRepetitionCommand
|
||||
import org.isoron.uhabits.core.io.Logging
|
||||
import org.isoron.uhabits.core.models.Habit
|
||||
import org.isoron.uhabits.core.models.HabitList
|
||||
import org.isoron.uhabits.core.models.HabitList.Order
|
||||
@@ -54,8 +55,12 @@ import javax.inject.Inject
|
||||
class HabitCardListCache @Inject constructor(
|
||||
private val allHabits: HabitList,
|
||||
private val commandRunner: CommandRunner,
|
||||
taskRunner: TaskRunner
|
||||
taskRunner: TaskRunner,
|
||||
logging: Logging,
|
||||
) : CommandRunner.Listener {
|
||||
|
||||
private val logger = logging.getLogger("HabitCardListCache")
|
||||
|
||||
private var checkmarkCount = 0
|
||||
private var currentFetchTask: Task? = null
|
||||
private var listener: Listener
|
||||
@@ -316,8 +321,17 @@ class HabitCardListCache @Inject constructor(
|
||||
toPosition: Int
|
||||
) {
|
||||
data.habits.removeAt(fromPosition)
|
||||
data.habits.add(toPosition, habit)
|
||||
listener.onItemMoved(fromPosition, toPosition)
|
||||
|
||||
// Workaround for https://github.com/iSoron/uhabits/issues/968
|
||||
val checkedToPosition = if (toPosition > data.habits.size) {
|
||||
logger.error("performMove: $toPosition is strictly higher than ${data.habits.size}")
|
||||
data.habits.size
|
||||
} else {
|
||||
toPosition
|
||||
}
|
||||
|
||||
data.habits.add(checkedToPosition, habit)
|
||||
listener.onItemMoved(fromPosition, checkedToPosition)
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
|
||||
@@ -57,6 +57,7 @@ data class ShowHabitState(
|
||||
val frequency: FrequencyCardState,
|
||||
val history: HistoryCardState,
|
||||
val bar: BarCardState,
|
||||
val theme: Theme,
|
||||
)
|
||||
|
||||
class ShowHabitPresenter(
|
||||
@@ -94,11 +95,14 @@ class ShowHabitPresenter(
|
||||
title = habit.name,
|
||||
color = habit.color,
|
||||
isNumerical = habit.isNumerical,
|
||||
theme = theme,
|
||||
subtitle = SubtitleCardPresenter.buildState(
|
||||
habit = habit,
|
||||
theme = theme,
|
||||
),
|
||||
overview = OverviewCardPresenter.buildState(
|
||||
habit = habit,
|
||||
theme = theme,
|
||||
),
|
||||
notes = NotesCardPresenter.buildState(
|
||||
habit = habit,
|
||||
@@ -106,18 +110,22 @@ class ShowHabitPresenter(
|
||||
target = TargetCardPresenter.buildState(
|
||||
habit = habit,
|
||||
firstWeekday = preferences.firstWeekdayInt,
|
||||
theme = theme,
|
||||
),
|
||||
streaks = StreakCartPresenter.buildState(
|
||||
habit = habit,
|
||||
theme = theme,
|
||||
),
|
||||
scores = ScoreCardPresenter.buildState(
|
||||
spinnerPosition = preferences.scoreCardSpinnerPosition,
|
||||
habit = habit,
|
||||
firstWeekday = preferences.firstWeekdayInt,
|
||||
theme = theme,
|
||||
),
|
||||
frequency = FrequencyCardPresenter.buildState(
|
||||
habit = habit,
|
||||
firstWeekday = preferences.firstWeekdayInt,
|
||||
theme = theme,
|
||||
),
|
||||
history = HistoryCardPresenter.buildState(
|
||||
habit = habit,
|
||||
|
||||
@@ -22,12 +22,14 @@ package org.isoron.uhabits.core.ui.screens.habits.show.views
|
||||
import org.isoron.uhabits.core.models.Habit
|
||||
import org.isoron.uhabits.core.models.PaletteColor
|
||||
import org.isoron.uhabits.core.models.Timestamp
|
||||
import org.isoron.uhabits.core.ui.views.Theme
|
||||
import java.util.HashMap
|
||||
|
||||
data class FrequencyCardState(
|
||||
val color: PaletteColor,
|
||||
val firstWeekday: Int,
|
||||
val frequency: HashMap<Timestamp, Array<Int>>,
|
||||
val theme: Theme,
|
||||
)
|
||||
|
||||
class FrequencyCardPresenter {
|
||||
@@ -35,12 +37,14 @@ class FrequencyCardPresenter {
|
||||
fun buildState(
|
||||
habit: Habit,
|
||||
firstWeekday: Int,
|
||||
theme: Theme
|
||||
) = FrequencyCardState(
|
||||
color = habit.color,
|
||||
frequency = habit.originalEntries.computeWeekdayFrequency(
|
||||
isNumerical = habit.isNumerical
|
||||
),
|
||||
firstWeekday = firstWeekday,
|
||||
theme = theme,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ package org.isoron.uhabits.core.ui.screens.habits.show.views
|
||||
import org.isoron.uhabits.core.models.Entry
|
||||
import org.isoron.uhabits.core.models.Habit
|
||||
import org.isoron.uhabits.core.models.PaletteColor
|
||||
import org.isoron.uhabits.core.ui.views.Theme
|
||||
import org.isoron.uhabits.core.utils.DateUtils
|
||||
|
||||
data class OverviewCardState(
|
||||
@@ -30,11 +31,12 @@ data class OverviewCardState(
|
||||
val scoreYearDiff: Float,
|
||||
val scoreToday: Float,
|
||||
val totalCount: Long,
|
||||
val theme: Theme,
|
||||
)
|
||||
|
||||
class OverviewCardPresenter {
|
||||
companion object {
|
||||
fun buildState(habit: Habit): OverviewCardState {
|
||||
fun buildState(habit: Habit, theme: Theme): OverviewCardState {
|
||||
val today = DateUtils.getTodayWithOffset()
|
||||
val lastMonth = today.minus(30)
|
||||
val lastYear = today.minus(365)
|
||||
@@ -52,6 +54,7 @@ class OverviewCardPresenter {
|
||||
scoreMonthDiff = scoreToday - scoreLastMonth,
|
||||
scoreYearDiff = scoreToday - scoreLastYear,
|
||||
totalCount = totalCount,
|
||||
theme = theme,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import org.isoron.uhabits.core.models.Habit
|
||||
import org.isoron.uhabits.core.models.PaletteColor
|
||||
import org.isoron.uhabits.core.models.Score
|
||||
import org.isoron.uhabits.core.preferences.Preferences
|
||||
import org.isoron.uhabits.core.ui.views.Theme
|
||||
import org.isoron.uhabits.core.utils.DateUtils
|
||||
|
||||
data class ScoreCardState(
|
||||
@@ -30,6 +31,7 @@ data class ScoreCardState(
|
||||
val bucketSize: Int,
|
||||
val spinnerPosition: Int,
|
||||
val color: PaletteColor,
|
||||
val theme: Theme,
|
||||
)
|
||||
|
||||
class ScoreCardPresenter(
|
||||
@@ -53,6 +55,7 @@ class ScoreCardPresenter(
|
||||
habit: Habit,
|
||||
firstWeekday: Int,
|
||||
spinnerPosition: Int,
|
||||
theme: Theme,
|
||||
): ScoreCardState {
|
||||
val bucketSize = BUCKET_SIZES[spinnerPosition]
|
||||
val today = DateUtils.getTodayWithOffset()
|
||||
@@ -77,6 +80,7 @@ class ScoreCardPresenter(
|
||||
scores = scores,
|
||||
bucketSize = bucketSize,
|
||||
spinnerPosition = spinnerPosition,
|
||||
theme = theme,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,18 +22,21 @@ package org.isoron.uhabits.core.ui.screens.habits.show.views
|
||||
import org.isoron.uhabits.core.models.Habit
|
||||
import org.isoron.uhabits.core.models.PaletteColor
|
||||
import org.isoron.uhabits.core.models.Streak
|
||||
import org.isoron.uhabits.core.ui.views.Theme
|
||||
|
||||
data class StreakCardState(
|
||||
val color: PaletteColor,
|
||||
val bestStreaks: List<Streak>
|
||||
val bestStreaks: List<Streak>,
|
||||
val theme: Theme,
|
||||
)
|
||||
|
||||
class StreakCartPresenter {
|
||||
companion object {
|
||||
fun buildState(habit: Habit): StreakCardState {
|
||||
fun buildState(habit: Habit, theme: Theme): StreakCardState {
|
||||
return StreakCardState(
|
||||
color = habit.color,
|
||||
bestStreaks = habit.streaks.getBest(10),
|
||||
theme = theme,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import org.isoron.uhabits.core.models.Frequency
|
||||
import org.isoron.uhabits.core.models.Habit
|
||||
import org.isoron.uhabits.core.models.PaletteColor
|
||||
import org.isoron.uhabits.core.models.Reminder
|
||||
import org.isoron.uhabits.core.ui.views.Theme
|
||||
|
||||
data class SubtitleCardState(
|
||||
val color: PaletteColor,
|
||||
@@ -32,12 +33,14 @@ data class SubtitleCardState(
|
||||
val reminder: Reminder?,
|
||||
val targetValue: Double,
|
||||
val unit: String,
|
||||
val theme: Theme,
|
||||
)
|
||||
|
||||
class SubtitleCardPresenter {
|
||||
companion object {
|
||||
fun buildState(
|
||||
habit: Habit,
|
||||
theme: Theme,
|
||||
): SubtitleCardState = SubtitleCardState(
|
||||
color = habit.color,
|
||||
frequency = habit.frequency,
|
||||
@@ -46,6 +49,7 @@ class SubtitleCardPresenter {
|
||||
reminder = habit.reminder,
|
||||
targetValue = habit.targetValue,
|
||||
unit = habit.unit,
|
||||
theme = theme,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ package org.isoron.uhabits.core.ui.screens.habits.show.views
|
||||
import org.isoron.uhabits.core.models.Habit
|
||||
import org.isoron.uhabits.core.models.PaletteColor
|
||||
import org.isoron.uhabits.core.models.groupedSum
|
||||
import org.isoron.uhabits.core.ui.views.Theme
|
||||
import org.isoron.uhabits.core.utils.DateUtils
|
||||
import java.util.ArrayList
|
||||
import java.util.Calendar
|
||||
@@ -31,6 +32,7 @@ data class TargetCardState(
|
||||
val values: List<Double> = listOf(),
|
||||
val targets: List<Double> = listOf(),
|
||||
val intervals: List<Int> = listOf(),
|
||||
val theme: Theme,
|
||||
)
|
||||
|
||||
class TargetCardPresenter {
|
||||
@@ -38,6 +40,7 @@ class TargetCardPresenter {
|
||||
fun buildState(
|
||||
habit: Habit,
|
||||
firstWeekday: Int,
|
||||
theme: Theme,
|
||||
): TargetCardState {
|
||||
val today = DateUtils.getTodayWithOffset()
|
||||
val oldest = habit.computedEntries.getKnown().lastOrNull()?.timestamp ?: today
|
||||
@@ -106,6 +109,7 @@ class TargetCardPresenter {
|
||||
values = values,
|
||||
targets = targets,
|
||||
intervals = intervals,
|
||||
theme = theme,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
package org.isoron.uhabits.core.ui.views
|
||||
|
||||
import org.isoron.platform.gui.Color
|
||||
import org.isoron.uhabits.core.models.PaletteColor
|
||||
|
||||
abstract class Theme {
|
||||
open val appBackgroundColor = Color(0xf4f4f4)
|
||||
@@ -35,6 +36,10 @@ abstract class Theme {
|
||||
open val toolbarBackgroundColor = Color(0xf4f4f4)
|
||||
open val toolbarColor = Color(0xffffff)
|
||||
|
||||
fun color(paletteColor: PaletteColor): Color {
|
||||
return color(paletteColor.paletteIndex)
|
||||
}
|
||||
|
||||
open fun color(paletteIndex: Int): Color {
|
||||
return when (paletteIndex) {
|
||||
0 -> Color(0xD32F2F)
|
||||
|
||||
@@ -43,7 +43,7 @@ class HabitCardListCacheTest : BaseUnitTest() {
|
||||
for (i in 0..9) {
|
||||
if (i == 3) habitList.add(fixtures.createLongHabit()) else habitList.add(fixtures.createShortHabit())
|
||||
}
|
||||
cache = HabitCardListCache(habitList, commandRunner, taskRunner)
|
||||
cache = HabitCardListCache(habitList, commandRunner, taskRunner, mock())
|
||||
cache.setCheckmarkCount(10)
|
||||
cache.refreshAllHabits()
|
||||
cache.onAttached()
|
||||
|
||||
Reference in New Issue
Block a user