mirror of
https://github.com/iSoron/uhabits.git
synced 2025-12-06 09:08:52 -06:00
@@ -1,5 +1,10 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## [2.0.2] - Unreleased
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- Fix crash caused by numerical habits with zero target (#903)
|
||||||
|
|
||||||
## [2.0.1] - 2021-05-09
|
## [2.0.1] - 2021-05-09
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|||||||
@@ -37,8 +37,8 @@ android {
|
|||||||
compileSdkVersion(30)
|
compileSdkVersion(30)
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
versionCode(20001)
|
versionCode(20002)
|
||||||
versionName("2.0.1")
|
versionName("2.0.2")
|
||||||
minSdkVersion(23)
|
minSdkVersion(23)
|
||||||
targetSdkVersion(30)
|
targetSdkVersion(30)
|
||||||
applicationId("org.isoron.uhabits")
|
applicationId("org.isoron.uhabits")
|
||||||
|
|||||||
@@ -117,7 +117,11 @@ class TargetChart : View {
|
|||||||
barRect[rect.left + stop + padding, rect.top + baseSize * 0.05f, rect.right - padding] =
|
barRect[rect.left + stop + padding, rect.top + baseSize * 0.05f, rect.right - padding] =
|
||||||
rect.bottom - baseSize * 0.05f
|
rect.bottom - baseSize * 0.05f
|
||||||
canvas.drawRoundRect(barRect, round, round, paint!!)
|
canvas.drawRoundRect(barRect, round, round, paint!!)
|
||||||
var percentage = (values[row] / targets[row]).toFloat()
|
var percentage = if (targets[row] > 0) {
|
||||||
|
(values[row] / targets[row]).toFloat()
|
||||||
|
} else {
|
||||||
|
1.0f
|
||||||
|
}
|
||||||
percentage = min(1.0f, percentage)
|
percentage = min(1.0f, percentage)
|
||||||
|
|
||||||
// Draw completed box
|
// Draw completed box
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
2.0.2:
|
||||||
|
* Bug fixes
|
||||||
2.0:
|
2.0:
|
||||||
* Track numeric habits (e.g. how many pages did you read?)
|
* Track numeric habits (e.g. how many pages did you read?)
|
||||||
* Skip days without breaking your streak
|
* Skip days without breaking your streak
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import org.isoron.uhabits.core.models.Score.Companion.compute
|
|||||||
import java.util.ArrayList
|
import java.util.ArrayList
|
||||||
import java.util.HashMap
|
import java.util.HashMap
|
||||||
import javax.annotation.concurrent.ThreadSafe
|
import javax.annotation.concurrent.ThreadSafe
|
||||||
|
import kotlin.math.max
|
||||||
import kotlin.math.min
|
import kotlin.math.min
|
||||||
|
|
||||||
@ThreadSafe
|
@ThreadSafe
|
||||||
@@ -93,11 +94,15 @@ class ScoreList {
|
|||||||
for (i in values.indices) {
|
for (i in values.indices) {
|
||||||
val offset = values.size - i - 1
|
val offset = values.size - i - 1
|
||||||
if (isNumerical) {
|
if (isNumerical) {
|
||||||
rollingSum += values[offset]
|
rollingSum += max(0, values[offset])
|
||||||
if (offset + denominator < values.size) {
|
if (offset + denominator < values.size) {
|
||||||
rollingSum -= values[offset + denominator]
|
rollingSum -= values[offset + denominator]
|
||||||
}
|
}
|
||||||
val percentageCompleted = min(1.0, rollingSum / 1000 / targetValue)
|
val percentageCompleted = if (targetValue > 0) {
|
||||||
|
min(1.0, rollingSum / 1000 / targetValue)
|
||||||
|
} else {
|
||||||
|
1.0
|
||||||
|
}
|
||||||
previousValue = compute(freq, previousValue, percentageCompleted)
|
previousValue = compute(freq, previousValue, percentageCompleted)
|
||||||
} else {
|
} else {
|
||||||
if (values[offset] == Entry.YES_MANUAL) {
|
if (values[offset] == Entry.YES_MANUAL) {
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.isoron.uhabits.core.models
|
package org.isoron.uhabits.core.models
|
||||||
|
|
||||||
|
import junit.framework.Assert.assertTrue
|
||||||
import org.hamcrest.MatcherAssert.assertThat
|
import org.hamcrest.MatcherAssert.assertThat
|
||||||
import org.hamcrest.number.IsCloseTo
|
import org.hamcrest.number.IsCloseTo
|
||||||
import org.hamcrest.number.OrderingComparison
|
import org.hamcrest.number.OrderingComparison
|
||||||
@@ -121,6 +122,14 @@ class ScoreListTest : BaseUnitTest() {
|
|||||||
checkScoreValues(expectedValues)
|
checkScoreValues(expectedValues)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun test_withZeroTarget() {
|
||||||
|
habit = fixtures.createNumericalHabit()
|
||||||
|
habit.targetValue = 0.0
|
||||||
|
habit.recompute()
|
||||||
|
assertTrue(habit.scores[today].value.isFinite())
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun test_imperfectNonDaily() {
|
fun test_imperfectNonDaily() {
|
||||||
// If the habit should be performed 3 times per week and the user misses 1 repetition
|
// If the habit should be performed 3 times per week and the user misses 1 repetition
|
||||||
|
|||||||
Reference in New Issue
Block a user