LunaEvent: add sleep event

This commit is contained in:
2025-11-14 21:42:35 +01:00
parent aa2347f802
commit 3ae71c36a7
6 changed files with 153 additions and 1 deletions

View File

@@ -330,7 +330,7 @@ class MainActivity : AppCompatActivity() {
alertDialog.show()
}
fun datePickerHelper(time: Long, dateTextView: TextView): Calendar {
fun datePickerHelper(time: Long, dateTextView: TextView, onChange: () -> Unit = {}): Calendar {
dateTextView.text = DateUtils.formatDateTime(time)
val dateTime = Calendar.getInstance()
@@ -349,6 +349,7 @@ class MainActivity : AppCompatActivity() {
{ _, hour, minute ->
dateTime.set(year, month, day, hour, minute)
dateTextView.text = DateUtils.formatDateTime(dateTime.time.time / 1000)
onChange.invoke()
},
startHour,
startMinute,
@@ -371,6 +372,74 @@ 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(this, 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) }
}
@@ -643,6 +712,7 @@ 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)
}
}
@@ -1100,6 +1170,10 @@ 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,6 +30,7 @@ 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
@@ -111,6 +112,7 @@ 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
}
)
@@ -134,6 +136,7 @@ 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
}
)
@@ -149,6 +152,7 @@ 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,6 +7,7 @@ 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) {
@@ -76,6 +77,7 @@ class NumericUtils (val context: Context) {
return ""
}
}
LunaEvent.TYPE_SLEEP -> formatTimeDuration(context, event.quantity.toLong())
else ->
event.quantity
})

View File

@@ -0,0 +1,57 @@
<?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">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:layout_marginTop="20dp"
android:orientation="horizontal">
<TextView
android:layout_width="40sp"
android:layout_height="wrap_content"
android:layout_marginEnd="10dp"
android:text="From"/>
<TextView
android:id="@+id/dialog_date_from"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:layout_marginTop="20dp"
android:orientation="horizontal">
<TextView
android:layout_width="40sp"
android:layout_height="wrap_content"
android:layout_marginEnd="10dp"
android:text="To"/>
<TextView
android:id="@+id/dialog_date_to"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
<TextView
android:id="@+id/dialog_date_duration"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:text="0"/>
</LinearLayout>

View File

@@ -49,6 +49,16 @@
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,6 +18,7 @@
<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>
@@ -35,6 +36,7 @@
<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>
@@ -44,12 +46,14 @@
<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>
@@ -112,6 +116,7 @@
<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>