4 Commits

Author SHA1 Message Date
8493d2822f MainActivity: allow amount for poo and pee events
An unspecified amount has also been added
to have the same semantics as before.

During these actions, the strings for title
and description of dialogs have been cleaned up.
2025-11-12 23:13:48 +01:00
80a70dfbf3 strings: rename scale to weight in identifiers 2025-11-12 23:13:48 +01:00
0a8ca7f9d1 LunaEvent: allow quantity of 0
This is helpful for storing an index
2025-11-12 23:13:48 +01:00
4492b36b23 events: allow editing of all used values
1. Allow to change the date/time and
other relevant values of an event
on creation and after it was created.

2. Harmonize layout file names and
variable names.
2025-11-12 15:25:11 +01:00
10 changed files with 16 additions and 215 deletions

View File

@@ -85,7 +85,7 @@ class MainActivity : AppCompatActivity() {
showAddLogbookDialog(true)
}
findViewById<View>(R.id.button_bottle).setOnClickListener {
addBabyBottleEvent(LunaEvent(LunaEvent.TYPE_BABY_BOTTLE))
addBabyBottleEvent()
}
findViewById<View>(R.id.button_food).setOnClickListener {
addNoteEvent(LunaEvent(LunaEvent.TYPE_FOOD))
@@ -195,8 +195,8 @@ class MainActivity : AppCompatActivity() {
return logbook?.logs ?: arrayListOf()
}
fun addBabyBottleEvent(event: LunaEvent) {
setToPreviousQuantity(event)
fun addBabyBottleEvent() {
val event = LunaEvent(LunaEvent.TYPE_BABY_BOTTLE)
askBabyBottleContent(event, true) {
saveEvent(event)
}
@@ -239,7 +239,6 @@ class MainActivity : AppCompatActivity() {
}
fun addWeightEvent(event: LunaEvent) {
setToPreviousQuantity(event)
askWeightValue(event, true) { saveEvent(event) }
}
@@ -283,7 +282,6 @@ class MainActivity : AppCompatActivity() {
}
fun addTemperatureEvent(event: LunaEvent) {
setToPreviousQuantity(event)
askTemperatureValue(event, true) { saveEvent(event) }
}
@@ -330,7 +328,7 @@ class MainActivity : AppCompatActivity() {
alertDialog.show()
}
fun datePickerHelper(time: Long, dateTextView: TextView, onChange: () -> Unit = {}): Calendar {
fun datePickerHelper(time: Long, dateTextView: TextView): Calendar {
dateTextView.text = DateUtils.formatDateTime(time)
val dateTime = Calendar.getInstance()
@@ -349,7 +347,6 @@ class MainActivity : AppCompatActivity() {
{ _, hour, minute ->
dateTime.set(year, month, day, hour, minute)
dateTextView.text = DateUtils.formatDateTime(dateTime.time.time / 1000)
onChange.invoke()
},
startHour,
startMinute,
@@ -372,74 +369,6 @@ class MainActivity : AppCompatActivity() {
saveLogbook()
}
fun addSleepEvent(event: LunaEvent) {
askSleepValue(event) { saveEvent(event) }
}
fun askSleepValue(event: LunaEvent, onPositive: () -> Unit) {
val d = AlertDialog.Builder(this)
val dialogView = layoutInflater.inflate(R.layout.dialog_edit_duration, null)
d.setTitle(event.getTypeDescription(this))
d.setMessage(event.getDialogMessage(this))
d.setView(dialogView)
val fromTextView = dialogView.findViewById<TextView>(R.id.dialog_date_from)
val toTextView = dialogView.findViewById<TextView>(R.id.dialog_date_to)
val durationTextView = dialogView.findViewById<TextView>(R.id.dialog_date_duration)
var pickedFromTime = Calendar.getInstance()
var pickedToTime = Calendar.getInstance()
fun isValidTime(fromSeconds: Long, toSeconds: Long): Boolean {
if (fromSeconds < toSeconds) {
val durationSeconds = toSeconds - fromSeconds
// sleep between 0 seconds and 12 hours
return durationSeconds > 0 && durationSeconds < (12 * 60 * 60)
} else {
return false
}
}
val onDateChange = {
val fromSeconds = pickedFromTime.time.time / 1000
val toSeconds = pickedToTime.time.time / 1000
durationTextView.text = DateUtils.formatTimeDuration(applicationContext, toSeconds - fromSeconds)
if (isValidTime(fromSeconds, toSeconds)) {
// valid duration: set default color
durationTextView.setTextColor(durationTextView.textColors.defaultColor)
} else {
// invalid duration: set danger color
durationTextView.setTextColor(ContextCompat.getColor(this, R.color.danger))
}
}
pickedFromTime = datePickerHelper(event.time, fromTextView, onDateChange)
pickedToTime = datePickerHelper(event.time + event.quantity, toTextView, onDateChange)
d.setPositiveButton(android.R.string.ok) { dialogInterface, i ->
val fromSeconds = pickedFromTime.time.time / 1000
val toSeconds = pickedToTime.time.time / 1000
if (isValidTime(fromSeconds, toSeconds)) {
event.time = fromSeconds
event.quantity = (toSeconds - fromSeconds).toInt()
onPositive()
} else {
Toast.makeText(applicationContext, R.string.toast_date_error, Toast.LENGTH_SHORT).show()
}
dialogInterface.dismiss()
}
d.setNegativeButton(android.R.string.cancel) { dialogInterface, i ->
dialogInterface.dismiss()
}
val alertDialog = d.create()
alertDialog.show()
}
fun addAmountEvent(event: LunaEvent) {
askAmountValue(event, true) { saveEvent(event) }
}
@@ -528,59 +457,13 @@ class MainActivity : AppCompatActivity() {
val notesET = dialogView.findViewById<EditText>(R.id.notes_edittext)
val qtyET = dialogView.findViewById<EditText>(R.id.notes_qty_edittext)
val dateTV = dialogView.findViewById<TextView>(R.id.dialog_date_picker)
val dateTV = dialogView.findViewById<TextView>(R.id.notes_date_picker)
val pickedTime = datePickerHelper(event.time, dateTV)
if (!showTime) {
dateTV.visibility = View.GONE
}
val nextTextView = dialogView.findViewById<TextView>(R.id.notes_template_next)
val prevTextView = dialogView.findViewById<TextView>(R.id.notes_template_prev)
fun updateContent(current: LunaEvent) {
val allEvents = getAllEvents()
val prevEvent = getPreviousSameEvent(current, allEvents)
var nextEvent = getNextSameEvent(current, allEvents)
notesET.setText(current.notes)
if (useQuantity) {
qtyET.setText(current.quantity.toString())
}
if (nextEvent == null && current != event) {
nextEvent = event
}
if (nextEvent != null) {
nextTextView.setOnClickListener {
notesET.setText(nextEvent.notes)
if (useQuantity) {
qtyET.setText(nextEvent.quantity.toString())
}
updateContent(nextEvent)
}
nextTextView.alpha = 1.0f
} else {
nextTextView.setOnClickListener {}
nextTextView.alpha = 0.5f
}
if (prevEvent != null) {
prevTextView.setOnClickListener {
notesET.setText(prevEvent.notes)
if (useQuantity) {
qtyET.setText(prevEvent.quantity.toString())
}
updateContent(prevEvent)
}
prevTextView.alpha = 1.0f
} else {
prevTextView.setOnClickListener {}
prevTextView.alpha = 0.5f
}
}
notesET.setText(event.notes)
if (useQuantity) {
@@ -589,8 +472,6 @@ class MainActivity : AppCompatActivity() {
qtyET.visibility = View.GONE
}
updateContent(event)
d.setPositiveButton(android.R.string.ok) { dialogInterface, i ->
val notes = notesET.text.toString()
@@ -642,13 +523,6 @@ class MainActivity : AppCompatActivity() {
alertDialog.show()
}
fun setToPreviousQuantity(event: LunaEvent) {
val prev = getPreviousSameEvent(event, getAllEvents())
if (prev != null) {
event.quantity = prev.quantity
}
}
fun getPreviousSameEvent(event: LunaEvent, items: ArrayList<LunaEvent>): LunaEvent? {
var previousEvent: LunaEvent? = null
for (item in items) {
@@ -712,7 +586,6 @@ class MainActivity : AppCompatActivity() {
LunaEvent.TYPE_PUKE -> askAmountValue(event, false, updateValues)
LunaEvent.TYPE_TEMPERATURE -> askTemperatureValue(event, false, updateValues)
LunaEvent.TYPE_NOTE -> askNotes(event, false, updateValues)
LunaEvent.TYPE_SLEEP -> askSleepValue(event, updateValues)
}
}
@@ -1170,10 +1043,6 @@ class MainActivity : AppCompatActivity() {
addAmountEvent(LunaEvent(LunaEvent.TYPE_PUKE))
dismiss()
}
contentView.findViewById<View>(R.id.button_sleep).setOnClickListener {
addSleepEvent(LunaEvent(LunaEvent.TYPE_SLEEP))
dismiss()
}
contentView.findViewById<View>(R.id.button_colic).setOnClickListener {
addPlainEvent(LunaEvent(LunaEvent.TYPE_COLIC))
dismiss()

View File

@@ -30,7 +30,6 @@ class LunaEvent: Comparable<LunaEvent> {
const val TYPE_FOOD = "FOOD"
const val TYPE_PUKE = "PUKE"
const val TYPE_BATH = "BATH"
const val TYPE_SLEEP = "SLEEP"
}
private val jo: JSONObject
@@ -46,12 +45,10 @@ class LunaEvent: Comparable<LunaEvent> {
jo.put("type", value)
}
var quantity: Int
get() = jo.optInt("quantity")
get() = jo.optInt("quantity", -1)
set(value) {
if (value > 0)
if (value >= 0)
jo.put("quantity", value)
else
jo.remove("quantity")
}
var notes: String
get(): String = jo.optString("notes")
@@ -112,7 +109,6 @@ class LunaEvent: Comparable<LunaEvent> {
TYPE_FOOD -> R.string.event_food_type
TYPE_PUKE -> R.string.event_puke_type
TYPE_BATH -> R.string.event_bath_type
TYPE_SLEEP -> R.string.event_sleep_type
else -> R.string.event_unknown_type
}
)
@@ -136,7 +132,6 @@ class LunaEvent: Comparable<LunaEvent> {
TYPE_FOOD -> R.string.event_food_desc
TYPE_PUKE -> R.string.event_puke_desc
TYPE_BATH -> R.string.event_bath_desc
TYPE_SLEEP -> R.string.event_sleep_desc
else -> R.string.event_unknown_desc
}
)
@@ -152,7 +147,6 @@ class LunaEvent: Comparable<LunaEvent> {
TYPE_DIAPERCHANGE_PEE,
TYPE_PUKE -> R.string.log_amount_dialog_description
TYPE_WEIGHT -> R.string.log_weight_dialog_description
TYPE_SLEEP -> R.string.log_sleep_dialog_description
else -> R.string.log_unknown_dialog_description
}
)

View File

@@ -7,7 +7,6 @@ import android.os.Build
import android.util.Log
import it.danieleverducci.lunatracker.R
import it.danieleverducci.lunatracker.entities.LunaEvent
import utils.DateUtils.Companion.formatTimeDuration
import java.text.NumberFormat
class NumericUtils (val context: Context) {
@@ -64,7 +63,7 @@ class NumericUtils (val context: Context) {
fun formatEventQuantity(event: LunaEvent): String {
val formatted = StringBuilder()
if (event.quantity > 0) {
if (event.quantity >= 0) {
formatted.append(when (event.type) {
LunaEvent.TYPE_TEMPERATURE ->
(event.quantity / 10.0f).toString()
@@ -77,7 +76,6 @@ class NumericUtils (val context: Context) {
return ""
}
}
LunaEvent.TYPE_SLEEP -> formatTimeDuration(context, event.quantity.toLong())
else ->
event.quantity
})

View File

@@ -1,23 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:gravity="center"
android:orientation="vertical">
<Spinner
android:id="@+id/dialog_amount_value"
android:layout_width="250dp"
android:layout_height="wrap_content"
android:paddingHorizontal="16dp"
android:paddingVertical="8dp"/>
<TextView
android:id="@+id/dialog_date_picker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"/>
</LinearLayout>

View File

@@ -7,7 +7,7 @@
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center"
android:gravity="center"
android:orientation="horizontal">
@@ -30,6 +30,6 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="20dp"/>
android:layout_marginEnd="20dp"/>
</LinearLayout>

View File

@@ -24,31 +24,8 @@
android:hint="@string/log_notes_dialog_note_hint"
android:background="@drawable/textview_background"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:gravity="end"
android:orientation="horizontal">
<TextView
android:id="@+id/notes_template_prev"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18dp"
android:text="⬅️"/>
<TextView
android:id="@+id/notes_template_next"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18dp"
android:text="➡️"/>
</LinearLayout>
<TextView
android:id="@+id/dialog_date_picker"
android:id="@+id/notes_date_picker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"

View File

@@ -3,14 +3,14 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:gravity="center"
android:orientation="vertical">
<TextView
android:id="@+id/dialog_date_picker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"/>
android:layout_gravity="center"
android:layout_marginTop="20dp"
android:layout_marginEnd="20dp"/>
</LinearLayout>

View File

@@ -28,6 +28,7 @@
android:id="@+id/dialog_date_picker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"/>
android:layout_gravity="center"
android:layout_marginEnd="20dp"/>
</LinearLayout>

View File

@@ -49,16 +49,6 @@
style="@style/OverflowMenuText"
android:text="@string/overflow_event_puke"/>
<TextView
android:id="@+id/button_sleep"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="10dp"
android:padding="10dp"
android:background="@drawable/dropdown_list_item_background"
style="@style/OverflowMenuText"
android:text="@string/overflow_event_sleep"/>
<TextView
android:id="@+id/button_colic"
android:layout_width="match_parent"

View File

@@ -18,7 +18,6 @@
<string name="event_colic_type" translatable="false">💨</string>
<string name="event_puke_type" translatable="false">🤮</string>
<string name="event_bath_type" translatable="false">🛁</string>
<string name="event_sleep_type" translatable="false">💤</string>
<string name="event_unknown_type" translatable="false">\?</string>
<string name="event_bottle_desc">Baby bottle</string>
@@ -36,7 +35,6 @@
<string name="event_colic_desc">Gaseous colic</string>
<string name="event_puke_desc">Puke</string>
<string name="event_bath_desc">Bath</string>
<string name="event_sleep_desc">Sleep</string>
<string name="event_unknown_desc"></string>
<string name="overflow_event_weight">⚖️ Weight</string>
@@ -46,14 +44,12 @@
<string name="overflow_event_temperature">🌡️ Temperature</string>
<string name="overflow_event_colic">💨 Gaseous colic</string>
<string name="overflow_event_puke">🤮 Puke</string>
<string name="overflow_event_sleep">💤 Sleep</string>
<string name="overflow_event_bath">🛁 Bath</string>
<string name="toast_event_added">Event logged</string>
<string name="toast_logbook_saved">Logbook saved</string>
<string name="toast_event_add_error">Unable to log the event</string>
<string name="toast_integer_error">Invalid value. Insert an integer.</string>
<string name="toast_date_error">Invalid date.</string>
<string name="now">now</string>
<string name="second_ago">sec</string>
@@ -116,7 +112,6 @@
<string name="log_temperature_dialog_description">Select the temperature:</string>
<string name="log_unknown_dialog_description"></string>
<string name="log_weight_dialog_description">Insert the weight:</string>
<string name="log_sleep_dialog_description">Select sleep range:</string>
<string name="measurement_unit_liquid_base_metric" translatable="false">ml</string>
<string name="measurement_unit_weight_base_metric" translatable="false">g</string>