mirror of
https://github.com/iSoron/uhabits.git
synced 2025-12-06 01:08:50 -06:00
Merge branch 'hotfix/2.0.3' into dev
This commit is contained in:
@@ -37,8 +37,8 @@ android {
|
||||
compileSdkVersion(30)
|
||||
|
||||
defaultConfig {
|
||||
versionCode(20002)
|
||||
versionName("2.0.2")
|
||||
versionCode(20003)
|
||||
versionName("2.0.3")
|
||||
minSdkVersion(23)
|
||||
targetSdkVersion(30)
|
||||
applicationId("org.isoron.uhabits")
|
||||
|
||||
@@ -36,6 +36,7 @@ class AndroidCanvas : Canvas {
|
||||
var innerDensity = 1.0
|
||||
var innerWidth = 0
|
||||
var innerHeight = 0
|
||||
var mHeight = 15
|
||||
|
||||
var paint = Paint().apply {
|
||||
isAntiAlias = true
|
||||
@@ -64,11 +65,10 @@ class AndroidCanvas : Canvas {
|
||||
}
|
||||
|
||||
override fun drawText(text: String, x: Double, y: Double) {
|
||||
textPaint.getTextBounds(text, 0, text.length, textBounds)
|
||||
innerCanvas.drawText(
|
||||
text,
|
||||
x.toDp(),
|
||||
y.toDp() - textBounds.exactCenterY(),
|
||||
y.toDp() + 0.6f * mHeight,
|
||||
textPaint,
|
||||
)
|
||||
}
|
||||
@@ -126,10 +126,17 @@ class AndroidCanvas : Canvas {
|
||||
Font.BOLD -> Typeface.DEFAULT_BOLD
|
||||
Font.FONT_AWESOME -> getFontAwesome(context)
|
||||
}
|
||||
updateMHeight()
|
||||
}
|
||||
|
||||
override fun setFontSize(size: Double) {
|
||||
textPaint.textSize = size.toDp()
|
||||
updateMHeight()
|
||||
}
|
||||
|
||||
private fun updateMHeight() {
|
||||
textPaint.getTextBounds("m", 0, 1, textBounds)
|
||||
mHeight = textBounds.height()
|
||||
}
|
||||
|
||||
override fun setStrokeWidth(size: Double) {
|
||||
|
||||
@@ -30,6 +30,7 @@ import org.isoron.uhabits.core.preferences.Preferences
|
||||
import org.isoron.uhabits.core.ui.ThemeSwitcher
|
||||
import org.isoron.uhabits.core.ui.views.DarkTheme
|
||||
import org.isoron.uhabits.core.ui.views.LightTheme
|
||||
import org.isoron.uhabits.core.ui.views.PureBlackTheme
|
||||
import org.isoron.uhabits.core.ui.views.Theme
|
||||
import org.isoron.uhabits.inject.ActivityContext
|
||||
import org.isoron.uhabits.inject.ActivityScope
|
||||
@@ -66,7 +67,7 @@ constructor(
|
||||
}
|
||||
|
||||
override fun applyPureBlackTheme() {
|
||||
currentTheme = DarkTheme()
|
||||
currentTheme = PureBlackTheme()
|
||||
context.setTheme(R.style.AppBaseThemeDark_PureBlack)
|
||||
(context as Activity).window.navigationBarColor =
|
||||
ContextCompat.getColor(context, R.color.black)
|
||||
|
||||
@@ -160,26 +160,28 @@ class FrequencyPickerDialog(
|
||||
|
||||
private fun populateViews() {
|
||||
uncheckAll()
|
||||
if (freqNumerator == 1) {
|
||||
if (freqDenominator == 1) {
|
||||
contentView.everyDayRadioButton.isChecked = true
|
||||
} else {
|
||||
contentView.everyXDaysRadioButton.isChecked = true
|
||||
contentView.everyXDaysTextView.setText(freqDenominator.toString())
|
||||
focus(contentView.everyXDaysTextView)
|
||||
}
|
||||
if (freqDenominator == 30 || freqDenominator == 31) {
|
||||
contentView.xTimesPerMonthRadioButton.isChecked = true
|
||||
contentView.xTimesPerMonthTextView.setText(freqNumerator.toString())
|
||||
focus(contentView.xTimesPerMonthTextView)
|
||||
} else {
|
||||
if (freqDenominator == 7) {
|
||||
contentView.xTimesPerWeekRadioButton.isChecked = true
|
||||
contentView.xTimesPerWeekTextView.setText(freqNumerator.toString())
|
||||
focus(contentView.xTimesPerWeekTextView)
|
||||
} else if (freqDenominator == 30 || freqDenominator == 31) {
|
||||
contentView.xTimesPerMonthRadioButton.isChecked = true
|
||||
contentView.xTimesPerMonthTextView.setText(freqNumerator.toString())
|
||||
focus(contentView.xTimesPerMonthTextView)
|
||||
if (freqNumerator == 1) {
|
||||
if (freqDenominator == 1) {
|
||||
contentView.everyDayRadioButton.isChecked = true
|
||||
} else {
|
||||
contentView.everyXDaysRadioButton.isChecked = true
|
||||
contentView.everyXDaysTextView.setText(freqDenominator.toString())
|
||||
focus(contentView.everyXDaysTextView)
|
||||
}
|
||||
} else {
|
||||
Log.w("FrequencyPickerDialog", "Unknown frequency: $freqNumerator/$freqDenominator")
|
||||
contentView.everyDayRadioButton.isChecked = true
|
||||
if (freqDenominator == 7) {
|
||||
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.content.res.ColorStateList
|
||||
import android.content.res.Resources
|
||||
import android.graphics.Color
|
||||
import android.os.Bundle
|
||||
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.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() {
|
||||
|
||||
private lateinit var themeSwitcher: AndroidThemeSwitcher
|
||||
@@ -299,14 +310,7 @@ class EditHabitActivity : AppCompatActivity() {
|
||||
|
||||
@SuppressLint("StringFormatMatches")
|
||||
private fun populateFrequency() {
|
||||
binding.booleanFrequencyPicker.text = when {
|
||||
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.booleanFrequencyPicker.text = formatFrequency(freqNum, freqDen, resources)
|
||||
binding.numericalFrequencyPicker.text = when (freqDen) {
|
||||
1 -> getString(R.string.every_day)
|
||||
7 -> getString(R.string.every_week)
|
||||
|
||||
@@ -20,14 +20,13 @@ package org.isoron.uhabits.activities.habits.show.views
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.content.res.Resources
|
||||
import android.util.AttributeSet
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.widget.LinearLayout
|
||||
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.core.models.Frequency
|
||||
import org.isoron.uhabits.core.ui.screens.habits.show.views.SubtitleCardState
|
||||
import org.isoron.uhabits.databinding.ShowHabitSubtitleBinding
|
||||
import org.isoron.uhabits.utils.InterfaceUtils
|
||||
@@ -49,7 +48,11 @@ class SubtitleCardView(context: Context, attrs: AttributeSet) : LinearLayout(con
|
||||
fun setState(state: SubtitleCardState) {
|
||||
val color = state.color.toThemedAndroidColor(context)
|
||||
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.text = state.question
|
||||
binding.reminderLabel.text = if (reminder != null) {
|
||||
@@ -72,32 +75,4 @@ class SubtitleCardView(context: Context, attrs: AttributeSet) : LinearLayout(con
|
||||
|
||||
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"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,13 +63,14 @@ class PendingIntentFactory
|
||||
FLAG_UPDATE_CURRENT
|
||||
)
|
||||
|
||||
fun removeRepetition(habit: Habit): PendingIntent =
|
||||
fun removeRepetition(habit: Habit, timestamp: Timestamp?): PendingIntent =
|
||||
getBroadcast(
|
||||
context,
|
||||
3,
|
||||
Intent(context, WidgetReceiver::class.java).apply {
|
||||
action = WidgetReceiver.ACTION_REMOVE_REPETITION
|
||||
data = Uri.parse(habit.uriString)
|
||||
if (timestamp != null) putExtra("timestamp", timestamp.unixTime)
|
||||
},
|
||||
FLAG_UPDATE_CURRENT
|
||||
)
|
||||
|
||||
@@ -107,7 +107,7 @@ class AndroidNotificationTray
|
||||
val removeRepetitionAction = Action(
|
||||
R.drawable.ic_action_cancel,
|
||||
context.getString(R.string.no),
|
||||
pendingIntents.removeRepetition(habit)
|
||||
pendingIntents.removeRepetition(habit, timestamp)
|
||||
)
|
||||
|
||||
val enterAction = Action(
|
||||
|
||||
@@ -31,6 +31,7 @@ import android.widget.ListView
|
||||
import android.widget.TextView
|
||||
import org.isoron.uhabits.HabitsApplication
|
||||
import org.isoron.uhabits.R
|
||||
import org.isoron.uhabits.activities.AndroidThemeSwitcher
|
||||
import org.isoron.uhabits.core.preferences.WidgetPreferences
|
||||
import org.isoron.uhabits.widgets.WidgetUpdater
|
||||
import java.util.ArrayList
|
||||
@@ -58,6 +59,7 @@ open class HabitPickerDialog : Activity() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
val component = (applicationContext as HabitsApplication).component
|
||||
AndroidThemeSwitcher(this, component.preferences).apply()
|
||||
val habitList = component.habitList
|
||||
widgetPreferences = component.widgetPreferences
|
||||
widgetUpdater = component.widgetUpdater
|
||||
|
||||
@@ -129,6 +129,7 @@
|
||||
<item name="selectedBackground">@drawable/selected_box</item>
|
||||
<item name="textColorAlertDialogListItem">@color/grey_100</item>
|
||||
<item name="windowBackgroundColor">@color/black</item>
|
||||
<item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material.PureBlack</item>
|
||||
</style>
|
||||
|
||||
<style name="BaseDialog" parent="Theme.AppCompat.Light.Dialog">
|
||||
@@ -151,6 +152,11 @@
|
||||
<item name="palette">@array/darkPalette</item>
|
||||
</style>
|
||||
|
||||
<style name="PreferenceThemeOverlay.v14.Material.PureBlack">
|
||||
<item name="android:background">@color/black</item>
|
||||
</style>
|
||||
|
||||
|
||||
<style name="WidgetTheme" parent="AppBaseThemeDark">
|
||||
<item name="cardBgColor">@color/grey_850</item>
|
||||
<item name="contrast0">@color/white</item>
|
||||
|
||||
Reference in New Issue
Block a user