mirror of
https://github.com/iSoron/uhabits.git
synced 2025-12-06 09:08:52 -06:00
@@ -1,5 +1,9 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## [2.0.3] - [Unreleased]
|
||||||
|
### Fixed
|
||||||
|
- Improve automatic checkmarks for monthly habits (@iSoron, 947)
|
||||||
|
|
||||||
## [2.0.2] - 2021-05-23
|
## [2.0.2] - 2021-05-23
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|||||||
@@ -37,8 +37,8 @@ android {
|
|||||||
compileSdkVersion(30)
|
compileSdkVersion(30)
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
versionCode(20002)
|
versionCode(20003)
|
||||||
versionName("2.0.2")
|
versionName("2.0.3")
|
||||||
minSdkVersion(23)
|
minSdkVersion(23)
|
||||||
targetSdkVersion(30)
|
targetSdkVersion(30)
|
||||||
applicationId("org.isoron.uhabits")
|
applicationId("org.isoron.uhabits")
|
||||||
|
|||||||
@@ -160,26 +160,28 @@ class FrequencyPickerDialog(
|
|||||||
|
|
||||||
private fun populateViews() {
|
private fun populateViews() {
|
||||||
uncheckAll()
|
uncheckAll()
|
||||||
if (freqNumerator == 1) {
|
if (freqDenominator == 30 || freqDenominator == 31) {
|
||||||
if (freqDenominator == 1) {
|
contentView.xTimesPerMonthRadioButton.isChecked = true
|
||||||
contentView.everyDayRadioButton.isChecked = true
|
contentView.xTimesPerMonthTextView.setText(freqNumerator.toString())
|
||||||
} else {
|
focus(contentView.xTimesPerMonthTextView)
|
||||||
contentView.everyXDaysRadioButton.isChecked = true
|
|
||||||
contentView.everyXDaysTextView.setText(freqDenominator.toString())
|
|
||||||
focus(contentView.everyXDaysTextView)
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (freqDenominator == 7) {
|
if (freqNumerator == 1) {
|
||||||
contentView.xTimesPerWeekRadioButton.isChecked = true
|
if (freqDenominator == 1) {
|
||||||
contentView.xTimesPerWeekTextView.setText(freqNumerator.toString())
|
contentView.everyDayRadioButton.isChecked = true
|
||||||
focus(contentView.xTimesPerWeekTextView)
|
} else {
|
||||||
} else if (freqDenominator == 30 || freqDenominator == 31) {
|
contentView.everyXDaysRadioButton.isChecked = true
|
||||||
contentView.xTimesPerMonthRadioButton.isChecked = true
|
contentView.everyXDaysTextView.setText(freqDenominator.toString())
|
||||||
contentView.xTimesPerMonthTextView.setText(freqNumerator.toString())
|
focus(contentView.everyXDaysTextView)
|
||||||
focus(contentView.xTimesPerMonthTextView)
|
}
|
||||||
} else {
|
} else {
|
||||||
Log.w("FrequencyPickerDialog", "Unknown frequency: $freqNumerator/$freqDenominator")
|
if (freqDenominator == 7) {
|
||||||
contentView.everyDayRadioButton.isChecked = true
|
contentView.xTimesPerWeekRadioButton.isChecked = true
|
||||||
|
contentView.xTimesPerWeekTextView.setText(freqNumerator.toString())
|
||||||
|
focus(contentView.xTimesPerWeekTextView)
|
||||||
|
} else {
|
||||||
|
Log.w("FrequencyPickerDialog", "Unknown frequency: $freqNumerator/$freqDenominator")
|
||||||
|
contentView.everyDayRadioButton.isChecked = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ package org.isoron.uhabits.activities.habits.edit
|
|||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.content.res.ColorStateList
|
import android.content.res.ColorStateList
|
||||||
|
import android.content.res.Resources
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.text.Html
|
import android.text.Html
|
||||||
@@ -59,6 +60,16 @@ import org.isoron.uhabits.utils.formatTime
|
|||||||
import org.isoron.uhabits.utils.toFormattedString
|
import org.isoron.uhabits.utils.toFormattedString
|
||||||
import org.isoron.uhabits.utils.toThemedAndroidColor
|
import org.isoron.uhabits.utils.toThemedAndroidColor
|
||||||
|
|
||||||
|
fun formatFrequency(freqNum: Int, freqDen: Int, resources: Resources) = when {
|
||||||
|
freqNum == 1 && (freqDen == 30 || freqDen == 31) -> resources.getString(R.string.every_month)
|
||||||
|
freqDen == 30 || freqDen == 31 -> resources.getString(R.string.x_times_per_month, freqNum)
|
||||||
|
freqNum == 1 && freqDen == 1 -> resources.getString(R.string.every_day)
|
||||||
|
freqNum == 1 && freqDen == 7 -> resources.getString(R.string.every_week)
|
||||||
|
freqNum == 1 && freqDen > 1 -> resources.getString(R.string.every_x_days, freqDen)
|
||||||
|
freqDen == 7 -> resources.getString(R.string.x_times_per_week, freqNum)
|
||||||
|
else -> "$freqNum/$freqDen"
|
||||||
|
}
|
||||||
|
|
||||||
class EditHabitActivity : AppCompatActivity() {
|
class EditHabitActivity : AppCompatActivity() {
|
||||||
|
|
||||||
private lateinit var themeSwitcher: AndroidThemeSwitcher
|
private lateinit var themeSwitcher: AndroidThemeSwitcher
|
||||||
@@ -299,14 +310,7 @@ class EditHabitActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
@SuppressLint("StringFormatMatches")
|
@SuppressLint("StringFormatMatches")
|
||||||
private fun populateFrequency() {
|
private fun populateFrequency() {
|
||||||
binding.booleanFrequencyPicker.text = when {
|
binding.booleanFrequencyPicker.text = formatFrequency(freqNum, freqDen, resources)
|
||||||
freqNum == 1 && freqDen == 1 -> getString(R.string.every_day)
|
|
||||||
freqNum == 1 && freqDen == 7 -> getString(R.string.every_week)
|
|
||||||
freqNum == 1 && freqDen > 1 -> getString(R.string.every_x_days, freqDen)
|
|
||||||
freqDen == 7 -> getString(R.string.x_times_per_week, freqNum)
|
|
||||||
freqDen == 30 || freqDen == 31 -> getString(R.string.x_times_per_month, freqNum)
|
|
||||||
else -> "$freqNum/$freqDen"
|
|
||||||
}
|
|
||||||
binding.numericalFrequencyPicker.text = when (freqDen) {
|
binding.numericalFrequencyPicker.text = when (freqDen) {
|
||||||
1 -> getString(R.string.every_day)
|
1 -> getString(R.string.every_day)
|
||||||
7 -> getString(R.string.every_week)
|
7 -> getString(R.string.every_week)
|
||||||
|
|||||||
@@ -20,14 +20,13 @@ package org.isoron.uhabits.activities.habits.show.views
|
|||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.res.Resources
|
|
||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.LinearLayout
|
import android.widget.LinearLayout
|
||||||
import org.isoron.uhabits.R
|
import org.isoron.uhabits.R
|
||||||
|
import org.isoron.uhabits.activities.habits.edit.formatFrequency
|
||||||
import org.isoron.uhabits.activities.habits.list.views.toShortString
|
import org.isoron.uhabits.activities.habits.list.views.toShortString
|
||||||
import org.isoron.uhabits.core.models.Frequency
|
|
||||||
import org.isoron.uhabits.core.ui.screens.habits.show.views.SubtitleCardState
|
import org.isoron.uhabits.core.ui.screens.habits.show.views.SubtitleCardState
|
||||||
import org.isoron.uhabits.databinding.ShowHabitSubtitleBinding
|
import org.isoron.uhabits.databinding.ShowHabitSubtitleBinding
|
||||||
import org.isoron.uhabits.utils.InterfaceUtils
|
import org.isoron.uhabits.utils.InterfaceUtils
|
||||||
@@ -49,7 +48,11 @@ class SubtitleCardView(context: Context, attrs: AttributeSet) : LinearLayout(con
|
|||||||
fun setState(state: SubtitleCardState) {
|
fun setState(state: SubtitleCardState) {
|
||||||
val color = state.color.toThemedAndroidColor(context)
|
val color = state.color.toThemedAndroidColor(context)
|
||||||
val reminder = state.reminder
|
val reminder = state.reminder
|
||||||
binding.frequencyLabel.text = state.frequency.format(resources)
|
binding.frequencyLabel.text = formatFrequency(
|
||||||
|
state.frequency.numerator,
|
||||||
|
state.frequency.denominator,
|
||||||
|
resources,
|
||||||
|
)
|
||||||
binding.questionLabel.setTextColor(color)
|
binding.questionLabel.setTextColor(color)
|
||||||
binding.questionLabel.text = state.question
|
binding.questionLabel.text = state.question
|
||||||
binding.reminderLabel.text = if (reminder != null) {
|
binding.reminderLabel.text = if (reminder != null) {
|
||||||
@@ -72,32 +75,4 @@ class SubtitleCardView(context: Context, attrs: AttributeSet) : LinearLayout(con
|
|||||||
|
|
||||||
postInvalidate()
|
postInvalidate()
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("StringFormatMatches")
|
|
||||||
private fun Frequency.format(resources: Resources): String {
|
|
||||||
val num = this.numerator
|
|
||||||
val den = this.denominator
|
|
||||||
if (num == den) {
|
|
||||||
return resources.getString(R.string.every_day)
|
|
||||||
}
|
|
||||||
if (den == 7) {
|
|
||||||
return resources.getString(R.string.x_times_per_week, num)
|
|
||||||
}
|
|
||||||
if (den == 30 || den == 31) {
|
|
||||||
return resources.getString(R.string.x_times_per_month, num)
|
|
||||||
}
|
|
||||||
if (num == 1) {
|
|
||||||
if (den == 7) {
|
|
||||||
return resources.getString(R.string.every_week)
|
|
||||||
}
|
|
||||||
if (den % 7 == 0) {
|
|
||||||
return resources.getString(R.string.every_x_weeks, den / 7)
|
|
||||||
}
|
|
||||||
if (den == 30 || den == 31) {
|
|
||||||
return resources.getString(R.string.every_month)
|
|
||||||
}
|
|
||||||
return resources.getString(R.string.every_x_days, den)
|
|
||||||
}
|
|
||||||
return "$num/$den"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -72,6 +72,13 @@ data class LocalDate(val daysSince2000: Int) {
|
|||||||
return dayCache
|
return dayCache
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val monthLength: Int
|
||||||
|
get() = when (month) {
|
||||||
|
4, 6, 9, 11 -> 30
|
||||||
|
2 -> if (isLeapYear(year)) 29 else 28
|
||||||
|
else -> 31
|
||||||
|
}
|
||||||
|
|
||||||
private fun updateYearMonthDayCache() {
|
private fun updateYearMonthDayCache() {
|
||||||
var currYear = 2000
|
var currYear = 2000
|
||||||
var currDay = 0
|
var currDay = 0
|
||||||
|
|||||||
@@ -248,8 +248,17 @@ open class EntryList {
|
|||||||
for (i in num - 1 until filtered.size) {
|
for (i in num - 1 until filtered.size) {
|
||||||
val (begin, _) = filtered[i]
|
val (begin, _) = filtered[i]
|
||||||
val (center, _) = filtered[i - num + 1]
|
val (center, _) = filtered[i - num + 1]
|
||||||
if (begin.daysUntil(center) < den) {
|
var size = den
|
||||||
val end = begin.plus(den - 1)
|
if (den == 30 || den == 31) {
|
||||||
|
val beginDate = begin.toLocalDate()
|
||||||
|
size = if (beginDate.day == beginDate.monthLength) {
|
||||||
|
beginDate.plus(1).monthLength
|
||||||
|
} else {
|
||||||
|
beginDate.monthLength
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (begin.daysUntil(center) < size) {
|
||||||
|
val end = begin.plus(size - 1)
|
||||||
intervals.add(Interval(begin, center, end))
|
intervals.add(Interval(begin, center, end))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user