16 Commits

Author SHA1 Message Date
62d2f9deb4 DateUtils: simplify code 2025-09-16 09:41:13 +02:00
5d2ba2e3f5 add previous/next event link to details dialog
The links will point to the previous/next
event of the same type
2025-09-16 09:40:47 +02:00
999ab96d9d make more strings translateable 2025-09-16 09:40:47 +02:00
5797159f8f make some val constant 2025-09-16 09:40:47 +02:00
e987d9cd40 remove unused imports 2025-09-16 09:40:47 +02:00
d57cd8b166 remove stray 1 character from time 2025-09-16 09:40:47 +02:00
2580bc882a activity_main: move progress bar next to event list title
Save some vertical space and prevent vertical size change/flicker.
2025-09-16 09:40:47 +02:00
baea313cbb MainActivity: support 24h format 2025-09-16 09:40:47 +02:00
15a9fab5f5 MainActivity: small code cleanup 2025-09-16 09:40:47 +02:00
63a8dde6c5 bigger font for event detail dialog 2025-09-16 09:39:58 +02:00
e566624a29 remove log event title
Keep the main page simpler and have a bit more
space for log messages.
2025-09-16 09:39:58 +02:00
77f6a89fcc add setting to disable breastfeeding buttons
Some women do not breastfeed. Hide the buttons
in order to have more space for log messages.
2025-09-16 09:39:58 +02:00
9efe2a3574 replace dp with sp
As suggested by android-studio.
2025-09-16 09:39:58 +02:00
3a65d09e58 values: escape apostrophe characters 2025-09-16 09:39:58 +02:00
1508db2a56 add password toggle view icon 2025-09-16 09:39:58 +02:00
674d4fd744 layout_marginLeft is deprecated 2025-09-16 09:39:21 +02:00
43 changed files with 597 additions and 2646 deletions

1
.idea/.name generated
View File

@@ -1 +0,0 @@
LunaTracker

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AndroidProjectSystem">
<option name="providerId" value="com.android.tools.idea.GradleProjectSystem" />
</component>
</project>

6
.idea/compiler.xml generated
View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<bytecodeTargetLevel target="21" />
</component>
</project>

View File

@@ -1,7 +1,5 @@
# 🌜 LunaTracker 🌛
[<img src="https://fdroid.gitlab.io/artwork/badge/get-it-on.png" alt="Get it on F-Droid" height="80">](https://f-droid.org/it/packages/it.danieleverducci.lunatracker/)
LunaTracker is a newborn baby tracking app.
Parenting can be tough. You get home from the hospital, exhausted, with this little fragile unknown thingy that has no user manual and a single way to let you know something's not ok: crying.
@@ -13,8 +11,7 @@ Dedicated to my daughter Luna.
![Screenshot](fastlane/metadata/android/en-US/images/phoneScreenshots/1.png)
## Thanks for the valuable contributions to:
Thanks for the valuable contributions to:
- Chepycou (French translation)
- Daniel Neubauer (German translation)
- Moritz Warning (Various bugfixes and new features)
Chepycou (French translation)
Daniel Neubauer (German translation)

View File

@@ -6,14 +6,14 @@ plugins {
android {
namespace = "it.danieleverducci.lunatracker"
compileSdk = 36
compileSdk = 34
defaultConfig {
applicationId = "it.danieleverducci.lunatracker"
minSdk = 21
targetSdk = 36
versionCode = 7
versionName = "0.9"
targetSdk = 34
versionCode = 4
versionName = "0.6"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
@@ -31,12 +31,6 @@ android {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}
dependenciesInfo {
// Disables dependency metadata when building APKs.
includeInApk = false
// Disables dependency metadata when building Android App Bundles.
includeInBundle = false
}
kotlinOptions {
jvmTarget = "11"
}
@@ -46,6 +40,7 @@ android {
}
dependencies {
implementation(libs.androidx.core.ktx)
implementation(libs.androidx.lifecycle.runtime.ktx)
implementation(libs.androidx.activity.compose)
@@ -56,7 +51,7 @@ dependencies {
implementation(libs.androidx.material3)
implementation(libs.androidx.appcompat)
implementation(libs.androidx.recyclerview)
implementation(libs.sardine.android)
implementation("com.github.thegrizzlylabs:sardine-android:v0.9")
implementation(libs.material)
testImplementation(libs.junit)
androidTestImplementation(libs.androidx.junit)
@@ -65,5 +60,4 @@ dependencies {
androidTestImplementation(libs.androidx.ui.test.junit4)
debugImplementation(libs.androidx.ui.tooling)
debugImplementation(libs.androidx.ui.test.manifest)
implementation(libs.mpandroidchart.vv310)
}

View File

@@ -30,10 +30,6 @@
android:name=".SettingsActivity"
android:label="@string/settings_title"
android:theme="@style/Theme.LunaTracker"/>
<activity
android:name=".StatisticsActivity"
android:label="@string/statistics_title"
android:theme="@style/Theme.LunaTracker"/>
</application>
</manifest>

View File

@@ -2,9 +2,7 @@ package it.danieleverducci.lunatracker
import android.os.Bundle
import android.view.View
import android.widget.EditText
import android.widget.RadioButton
import android.widget.Spinner
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
@@ -25,8 +23,7 @@ open class SettingsActivity : AppCompatActivity() {
protected lateinit var textViewWebDAVUser: TextView
protected lateinit var textViewWebDAVPass: TextView
protected lateinit var progressIndicator: LinearProgressIndicator
protected lateinit var switchDynamicMenu: SwitchMaterial
protected lateinit var textViewSignature: EditText
protected lateinit var switchNoBreastfeeding: SwitchMaterial
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@@ -38,8 +35,7 @@ open class SettingsActivity : AppCompatActivity() {
textViewWebDAVUser = findViewById(R.id.settings_data_webdav_user)
textViewWebDAVPass = findViewById(R.id.settings_data_webdav_pass)
progressIndicator = findViewById(R.id.progress_indicator)
switchDynamicMenu = findViewById(R.id.switch_dynamic_menu)
textViewSignature = findViewById(R.id.settings_signature)
switchNoBreastfeeding = findViewById(R.id.switch_no_breastfeeding)
findViewById<View>(R.id.settings_save).setOnClickListener({
validateAndSave()
@@ -55,21 +51,19 @@ open class SettingsActivity : AppCompatActivity() {
fun loadSettings() {
val dataRepo = settingsRepository.loadDataRepository()
val webDavCredentials = settingsRepository.loadWebdavCredentials()
val dynamicMenu = settingsRepository.loadDynamicMenu()
val signature = settingsRepository.loadSignature()
val noBreastfeeding = settingsRepository.loadNoBreastfeeding()
when (dataRepo) {
LocalSettingsRepository.DATA_REPO.LOCAL_FILE -> radioDataLocal.isChecked = true
LocalSettingsRepository.DATA_REPO.WEBDAV -> radioDataWebDAV.isChecked = true
}
textViewSignature.setText(signature)
switchDynamicMenu.isChecked = dynamicMenu
switchNoBreastfeeding.isChecked = noBreastfeeding
if (webDavCredentials != null) {
textViewWebDAVUrl.text = webDavCredentials[0]
textViewWebDAVUser.text = webDavCredentials[1]
textViewWebDAVPass.text = webDavCredentials[2]
textViewWebDAVUrl.setText(webDavCredentials[0])
textViewWebDAVUser.setText(webDavCredentials[1])
textViewWebDAVPass.setText(webDavCredentials[2])
}
}
@@ -161,8 +155,7 @@ open class SettingsActivity : AppCompatActivity() {
if (radioDataWebDAV.isChecked) LocalSettingsRepository.DATA_REPO.WEBDAV
else LocalSettingsRepository.DATA_REPO.LOCAL_FILE
)
settingsRepository.saveDynamicMenu(switchDynamicMenu.isChecked)
settingsRepository.saveSignature(textViewSignature.text.toString())
settingsRepository.saveNoBreastfeeding(switchNoBreastfeeding.isChecked)
settingsRepository.saveWebdavCredentials(
textViewWebDAVUrl.text.toString(),
textViewWebDAVUser.text.toString(),
@@ -177,7 +170,7 @@ open class SettingsActivity : AppCompatActivity() {
*/
private fun copyLocalLogbooksToWebdav(webDAVLogbookRepository: WebDAVLogbookRepository, listener: OnCopyLocalLogbooksToWebdavFinishedListener) {
Thread(Runnable {
val errors = StringBuilder()
var errors = StringBuilder()
val fileLogbookRepo = FileLogbookRepository()
val logbooks = fileLogbookRepo.getAllLogbooks(this)
for (logbook in logbooks) {

View File

@@ -52,22 +52,18 @@ class LunaEventRecyclerAdapter: RecyclerView.Adapter<LunaEventRecyclerAdapter.Lu
)
holder.quantity.setTextColor(ContextCompat.getColor(context, R.color.textColor))
// Contents
holder.type.text = item.getHeaderEmoji(context)
holder.type.text = item.getTypeEmoji(context)
holder.description.text = when(item.type) {
LunaEvent.Type.MEDICINE -> item.notes
LunaEvent.Type.NOTE -> item.notes
else -> item.getRowItemTitle(context)
LunaEvent.TYPE_MEDICINE -> item.notes
LunaEvent.TYPE_NOTE -> item.notes
LunaEvent.TYPE_CUSTOM -> item.notes
else -> item.getTypeDescription(context)
}
val endTime = if (item.type == LunaEvent.Type.SLEEP) {
item.quantity + item.time
} else {
item.time
}
holder.time.text = DateUtils.formatTimeAgo(context, endTime)
holder.time.text = DateUtils.formatTimeAgo(context, item.time)
var quantityText = numericUtils.formatEventQuantity(item)
// if the event is weight, show difference with the last one
if (item.type == LunaEvent.Type.WEIGHT) {
if (item.type == LunaEvent.TYPE_WEIGHT) {
val lastWeight = getPreviousWeightEvent(position)
if (lastWeight != null) {
val differenceInWeight = item.quantity - lastWeight.quantity
@@ -98,7 +94,7 @@ class LunaEventRecyclerAdapter: RecyclerView.Adapter<LunaEventRecyclerAdapter.Lu
return null
for (pos in startFromPosition + 1 until items.size) {
val item = items.get(pos)
if (item.type != LunaEvent.Type.WEIGHT)
if (item.type != LunaEvent.TYPE_WEIGHT)
continue
return item
}

View File

@@ -12,24 +12,22 @@ import java.util.Date
* release, it is simply ignored by previous ones).
*/
class LunaEvent: Comparable<LunaEvent> {
enum class Type {
BABY_BOTTLE,
FOOD,
BREASTFEEDING_LEFT_NIPPLE,
BREASTFEEDING_BOTH_NIPPLE,
BREASTFEEDING_RIGHT_NIPPLE,
DIAPERCHANGE_POO,
DIAPERCHANGE_PEE,
SLEEP,
WEIGHT,
MEDICINE,
ENEMA,
NOTE,
COLIC,
TEMPERATURE,
PUKE,
BATH,
UNKNOWN
companion object {
const val TYPE_BABY_BOTTLE = "BABY_BOTTLE"
const val TYPE_WEIGHT = "WEIGHT"
const val TYPE_BREASTFEEDING_LEFT_NIPPLE = "BREASTFEEDING_LEFT_NIPPLE"
const val TYPE_BREASTFEEDING_BOTH_NIPPLE = "BREASTFEEDING_BOTH_NIPPLE"
const val TYPE_BREASTFEEDING_RIGHT_NIPPLE = "BREASTFEEDING_RIGHT_NIPPLE"
const val TYPE_DIAPERCHANGE_POO = "DIAPERCHANGE_POO"
const val TYPE_DIAPERCHANGE_PEE = "DIAPERCHANGE_PEE"
const val TYPE_MEDICINE = "MEDICINE"
const val TYPE_ENEMA = "ENEMA"
const val TYPE_NOTE = "NOTE"
const val TYPE_CUSTOM = "CUSTOM"
const val TYPE_COLIC = "COLIC"
const val TYPE_TEMPERATURE = "TEMPERATURE"
const val TYPE_FOOD = "FOOD"
}
private val jo: JSONObject
@@ -39,36 +37,22 @@ class LunaEvent: Comparable<LunaEvent> {
set(value) {
jo.put("time", value)
}
var type: Type
get(): Type {
return try {
Type.valueOf(jo.getString("type"))
} catch (_: Exception) {
Type.UNKNOWN
}
}
var type: String
get(): String = jo.getString("type")
set(value) {
jo.put("type", value.name)
jo.put("type", value)
}
var quantity: Int
get() = jo.optInt("quantity")
set(value) {
if (value > 0)
jo.put("quantity", value)
else
jo.remove("quantity")
}
var notes: String
get(): String = jo.optString("notes")
set(value) {
jo.put("notes", value)
}
var signature: String
get(): String = jo.optString("signature")
set(value) {
if (value.isNotEmpty())
jo.put("signature", value)
}
constructor(jo: JSONObject) {
this.jo = jo
@@ -77,42 +61,66 @@ class LunaEvent: Comparable<LunaEvent> {
throw IllegalArgumentException("JSONObject is not a LunaEvent")
}
constructor(event: LunaEvent) {
this.jo = JSONObject()
this.type = event.type
this.time = event.time
this.quantity = event.quantity
this.notes = event.notes
this.signature = event.signature
}
constructor(type: Type) {
constructor(type: String) {
this.jo = JSONObject()
this.time = System.currentTimeMillis() / 1000
this.type = type
}
constructor(type: Type, quantity: Int) {
constructor(type: String, quantity: Int) {
this.jo = JSONObject()
this.time = System.currentTimeMillis() / 1000
this.type = type
this.quantity = quantity
}
fun getHeaderEmoji(context: Context): String {
return getHeaderEmoji(context, type)
fun getTypeEmoji(context: Context): String {
return context.getString(
when (type) {
TYPE_BABY_BOTTLE -> R.string.event_bottle_type
TYPE_WEIGHT -> R.string.event_scale_type
TYPE_BREASTFEEDING_LEFT_NIPPLE -> R.string.event_breastfeeding_left_type
TYPE_BREASTFEEDING_BOTH_NIPPLE -> R.string.event_breastfeeding_both_type
TYPE_BREASTFEEDING_RIGHT_NIPPLE -> R.string.event_breastfeeding_right_type
TYPE_DIAPERCHANGE_POO -> R.string.event_diaperchange_poo_type
TYPE_DIAPERCHANGE_PEE -> R.string.event_diaperchange_pee_type
TYPE_MEDICINE -> R.string.event_medicine_type
TYPE_ENEMA -> R.string.event_enema_type
TYPE_NOTE -> R.string.event_note_type
TYPE_TEMPERATURE -> R.string.event_temperature_type
TYPE_COLIC -> R.string.event_colic_type
TYPE_FOOD -> R.string.event_food_type
else -> R.string.event_unknown_type
}
)
}
fun getDialogTitle(context: Context): String {
return getDialogTitle(context, type)
fun getTypeDescription(context: Context): String {
return context.getString(
when (type) {
TYPE_BABY_BOTTLE -> R.string.event_bottle_desc
TYPE_WEIGHT -> R.string.event_scale_desc
TYPE_BREASTFEEDING_LEFT_NIPPLE -> R.string.event_breastfeeding_left_desc
TYPE_BREASTFEEDING_BOTH_NIPPLE -> R.string.event_breastfeeding_both_desc
TYPE_BREASTFEEDING_RIGHT_NIPPLE -> R.string.event_breastfeeding_right_desc
TYPE_DIAPERCHANGE_POO -> R.string.event_diaperchange_poo_desc
TYPE_DIAPERCHANGE_PEE -> R.string.event_diaperchange_pee_desc
TYPE_MEDICINE -> R.string.event_medicine_desc
TYPE_ENEMA -> R.string.event_enema_desc
TYPE_NOTE -> R.string.event_note_desc
TYPE_TEMPERATURE -> R.string.event_temperature_desc
TYPE_COLIC -> R.string.event_colic_desc
TYPE_FOOD -> R.string.event_food_desc
else -> R.string.event_unknown_desc
}
)
}
fun getRowItemTitle(context: Context): String {
return getPopupItemTitle(context, type).split(" ", limit = 2).last() // remove emoji
fun getDialogMessage(context: Context): String? {
return when(type) {
TYPE_MEDICINE -> context.getString(R.string.log_medicine_dialog_description)
else -> null
}
fun getDialogMessage(context: Context): String {
return getDialogMessage(context, type)
}
fun toJson(): JSONObject {
@@ -120,101 +128,10 @@ class LunaEvent: Comparable<LunaEvent> {
}
override fun toString(): String {
return "$type qty: $quantity time: ${Date(time * 1000)}"
return "${type} qty: $quantity time: ${Date(time * 1000)}"
}
override fun compareTo(other: LunaEvent): Int {
return (this.time - other.time).toInt()
}
companion object {
fun getHeaderEmoji(context: Context, type: Type): String {
return context.getString(
when (type) {
Type.BABY_BOTTLE -> R.string.event_bottle_type
Type.WEIGHT -> R.string.event_weight_type
Type.BREASTFEEDING_LEFT_NIPPLE -> R.string.event_breastfeeding_left_type
Type.BREASTFEEDING_BOTH_NIPPLE -> R.string.event_breastfeeding_both_type
Type.BREASTFEEDING_RIGHT_NIPPLE -> R.string.event_breastfeeding_right_type
Type.DIAPERCHANGE_POO -> R.string.event_diaperchange_poo_type
Type.DIAPERCHANGE_PEE -> R.string.event_diaperchange_pee_type
Type.MEDICINE -> R.string.event_medicine_type
Type.ENEMA -> R.string.event_enema_type
Type.NOTE -> R.string.event_note_type
Type.TEMPERATURE -> R.string.event_temperature_type
Type.COLIC -> R.string.event_colic_type
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
Type.UNKNOWN -> R.string.event_unknown_type
}
)
}
fun getDialogMessage(context: Context, type: Type): String {
return context.getString(
when (type) {
Type.BABY_BOTTLE -> R.string.log_bottle_dialog_description
Type.MEDICINE -> R.string.log_medicine_dialog_description
Type.TEMPERATURE -> R.string.log_temperature_dialog_description
Type.DIAPERCHANGE_POO,
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
}
)
}
fun getDialogTitle(context: Context, type: Type): String {
return context.getString(
when (type) {
Type.BABY_BOTTLE -> R.string.event_bottle_desc
Type.WEIGHT -> R.string.event_weight_desc
Type.BREASTFEEDING_LEFT_NIPPLE -> R.string.event_breastfeeding_left_desc
Type.BREASTFEEDING_BOTH_NIPPLE -> R.string.event_breastfeeding_both_desc
Type.BREASTFEEDING_RIGHT_NIPPLE -> R.string.event_breastfeeding_right_desc
Type.DIAPERCHANGE_POO -> R.string.event_diaperchange_poo_desc
Type.DIAPERCHANGE_PEE -> R.string.event_diaperchange_pee_desc
Type.MEDICINE -> R.string.event_medicine_desc
Type.ENEMA -> R.string.event_enema_desc
Type.NOTE -> R.string.event_note_desc
Type.TEMPERATURE -> R.string.event_temperature_desc
Type.COLIC -> R.string.event_colic_desc
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
Type.UNKNOWN -> R.string.event_unknown_desc
}
)
}
// Entries for for popup list
fun getPopupItemTitle(context: Context, type: Type): String {
return context.getString(
when (type) {
Type.BABY_BOTTLE -> R.string.event_type_item_bottle
Type.WEIGHT -> R.string.event_type_item_weight
Type.BREASTFEEDING_LEFT_NIPPLE -> R.string.event_type_item_breastfeeding_left
Type.BREASTFEEDING_BOTH_NIPPLE -> R.string.event_type_item_breastfeeding_both
Type.BREASTFEEDING_RIGHT_NIPPLE -> R.string.event_type_item_breastfeeding_right
Type.DIAPERCHANGE_POO -> R.string.event_type_item_diaperchange_poo
Type.DIAPERCHANGE_PEE -> R.string.event_type_item_diaperchange_pee
Type.MEDICINE -> R.string.event_type_item_medicine
Type.ENEMA -> R.string.event_type_item_enema
Type.NOTE -> R.string.event_type_item_note
Type.TEMPERATURE -> R.string.event_type_item_temperature
Type.COLIC -> R.string.event_type_item_colic
Type.FOOD -> R.string.event_type_item_food
Type.PUKE -> R.string.event_type_item_puke
Type.BATH -> R.string.event_type_item_bath
Type.SLEEP -> R.string.event_type_item_sleep
Type.UNKNOWN -> R.string.event_type_item_unknown
}
)
}
}
}

View File

@@ -13,9 +13,9 @@ import java.io.FilenameFilter
class FileLogbookRepository: LogbookRepository {
companion object {
const val TAG = "FileLogbookRepository"
const val FILE_NAME_START = "data"
const val FILE_NAME_END = ".json"
val TAG = "FileLogbookRepository"
val FILE_NAME_START = "data"
val FILE_NAME_END = ".json"
}
override fun loadLogbook(context: Context, name: String, listener: LogbookLoadedListener) {
@@ -32,7 +32,7 @@ class FileLogbookRepository: LogbookRepository {
fun loadLogbook(context: Context, name: String): Logbook {
val logbook = Logbook(name)
val fileName = getFileName(name)
val file = File(context.filesDir, fileName)
val file = File(context.getFilesDir(), fileName)
val json = FileInputStream(file).bufferedReader().use { it.readText() }
val ja = JSONArray(json)
for (i in 0 until ja.length()) {
@@ -58,7 +58,7 @@ class FileLogbookRepository: LogbookRepository {
fun saveLogbook(context: Context, logbook: Logbook) {
val fileName = getFileName(logbook.name)
val file = File(context.filesDir, fileName)
val file = File(context.getFilesDir(), fileName)
val ja = JSONArray()
for (l in logbook.logs) {
ja.put(l.toJson())
@@ -82,7 +82,7 @@ class FileLogbookRepository: LogbookRepository {
}
private fun listLogbooks(context: Context): ArrayList<String> {
val logbooksFileNames = context.filesDir.list(object: FilenameFilter {
val logbooksFileNames = context.getFilesDir().list(object: FilenameFilter {
override fun accept(dir: File?, name: String?): Boolean {
if (name == null)
return false

View File

@@ -7,14 +7,13 @@ import androidx.core.content.edit
class LocalSettingsRepository(val context: Context) {
companion object {
const val SHARED_PREFS_FILE_NAME = "lunasettings"
const val SHARED_PREFS_BB_CONTENT = "bbcontent"
const val SHARED_PREFS_DATA_REPO = "data_repo"
const val SHARED_PREFS_DAV_URL = "webdav_url"
const val SHARED_PREFS_DAV_USER = "webdav_user"
const val SHARED_PREFS_DAV_PASS = "webdav_password"
const val SHARED_PREFS_DYNAMIC_MENU = "dynamic_menu"
const val SHARED_PREFS_SIGNATURE = "signature"
val SHARED_PREFS_FILE_NAME = "lunasettings"
val SHARED_PREFS_BB_CONTENT = "bbcontent"
val SHARED_PREFS_DATA_REPO = "data_repo"
val SHARED_PREFS_DAV_URL = "webdav_url"
val SHARED_PREFS_DAV_USER = "webdav_user"
val SHARED_PREFS_DAV_PASS = "webdav_password"
val SHARED_PREFS_NO_BREASTFEEDING = "no_breastfeeding"
}
enum class DATA_REPO {LOCAL_FILE, WEBDAV}
val sharedPreferences: SharedPreferences
@@ -23,32 +22,32 @@ class LocalSettingsRepository(val context: Context) {
sharedPreferences = context.getSharedPreferences(SHARED_PREFS_FILE_NAME, MODE_PRIVATE)
}
fun saveSignature(content: String) {
sharedPreferences.edit { putString(SHARED_PREFS_SIGNATURE, content) }
fun saveBabyBottleContent(content: Int) {
sharedPreferences.edit().putInt(SHARED_PREFS_BB_CONTENT, content).apply()
}
fun loadSignature(): String {
return sharedPreferences.getString(SHARED_PREFS_SIGNATURE, "") ?: ""
fun loadBabyBottleContent(): Int {
return sharedPreferences.getInt(SHARED_PREFS_BB_CONTENT, 1)
}
fun saveDynamicMenu(content: Boolean) {
sharedPreferences.edit { putBoolean(SHARED_PREFS_DYNAMIC_MENU, content) }
fun saveNoBreastfeeding(content: Boolean) {
sharedPreferences.edit().putBoolean(SHARED_PREFS_NO_BREASTFEEDING, content).apply()
}
fun loadDynamicMenu(): Boolean {
return sharedPreferences.getBoolean(SHARED_PREFS_DYNAMIC_MENU, false)
fun loadNoBreastfeeding(): Boolean {
return sharedPreferences.getBoolean(SHARED_PREFS_NO_BREASTFEEDING, false)
}
fun saveDataRepository(repo: DATA_REPO) {
sharedPreferences.edit(commit = true) {
putString(
val spe = sharedPreferences.edit()
spe.putString(
SHARED_PREFS_DATA_REPO,
when (repo) {
DATA_REPO.WEBDAV -> "webdav"
DATA_REPO.LOCAL_FILE -> "localfile"
}
)
}
spe.commit()
}
fun loadDataRepository(): DATA_REPO {
@@ -61,11 +60,11 @@ class LocalSettingsRepository(val context: Context) {
}
fun saveWebdavCredentials(url: String, username: String, password: String) {
sharedPreferences.edit(commit = true) {
putString(SHARED_PREFS_DAV_URL, url)
putString(SHARED_PREFS_DAV_USER, username)
putString(SHARED_PREFS_DAV_PASS, password)
}
val spe = sharedPreferences.edit()
spe.putString(SHARED_PREFS_DAV_URL, url)
spe.putString(SHARED_PREFS_DAV_USER, username)
spe.putString(SHARED_PREFS_DAV_PASS, password)
spe.commit()
}
fun loadWebdavCredentials(): Array<String>? {

View File

@@ -1,17 +1,12 @@
package utils
import android.content.Context
import android.os.Build
import android.text.format.DateFormat
import it.danieleverducci.lunatracker.R
import java.util.Date
class DateUtils {
companion object {
/**
* Format time duration in seconds as e.g. "2 hours, 1 min".
* Used for the duration to the next/previous event in the event details dialog.
*/
fun formatTimeDuration(context: Context, secondsDiff: Long): String {
var seconds = secondsDiff
@@ -62,14 +57,15 @@ class DateUtils {
return format(days, hours, R.string.day_ago, R.string.days_ago, R.string.hour_ago, R.string.hours_ago)
} else if (hours > 0) {
return format(hours, minutes, R.string.hour_ago, R.string.hours_ago, R.string.minute_ago, R.string.minutes_ago)
} else {
} else if (minutes > 0) {
return format(minutes, seconds, R.string.minute_ago, R.string.minute_ago, R.string.second_ago, R.string.seconds_ago)
} else {
return context.getString(R.string.now)
}
}
/**
* Formats the provided unix timestamp in a string like "3 hours, 26 minutes ago".
* Used for the event list.
* Formats the provided unix timestamp in a string like "3 hours, 26 minutes ago)
*/
fun formatTimeAgo(context: Context, unixTime: Long): String {
val secondsDiff = (System.currentTimeMillis() / 1000) - unixTime
@@ -104,21 +100,5 @@ class DateUtils {
}
return formattedTime.toString()
}
/**
* Format time as localized string without seconds. E.g. "Sept 18, 2025, 03:36 PM".
* Used in the event detail dialog.
*/
fun formatDateTime(unixTime: Long): String {
val date = Date(unixTime * 1000)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
val dateFormat = android.icu.text.DateFormat.getDateTimeInstance(android.icu.text.DateFormat.DEFAULT, android.icu.text.DateFormat.SHORT)
return dateFormat.format(date)
} else {
// fallback
val dateFormat = java.text.DateFormat.getDateTimeInstance()
return dateFormat.format(date)
}
}
}
}

View File

@@ -3,11 +3,8 @@ package utils
import android.content.Context
import android.icu.util.LocaleData
import android.icu.util.ULocale
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) {
@@ -17,101 +14,66 @@ class NumericUtils (val context: Context) {
val measurement_unit_weight_tiny: String
val measurement_unit_temperature_base: String
private fun isMetricSystem(): Boolean {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
val measurementSystem = LocaleData.getMeasurementSystem(ULocale.getDefault())
return (measurementSystem == LocaleData.MeasurementSystem.SI)
} else {
val locale = context.resources.configuration.locale
return when (locale.country) {
// https://en.wikipedia.org/wiki/United_States_customary_units
// https://en.wikipedia.org/wiki/Imperial_units
"US" -> false // US IMPERIAL
// UK, Myanmar, Liberia,
"GB", "MM", "LR" -> false // IMPERIAL
else -> true // METRIC
}
}
}
init {
this.numberFormat = NumberFormat.getInstance()
val measurementSystem = LocaleData.getMeasurementSystem(ULocale.getDefault())
this.measurement_unit_liquid_base = context.getString(
if (isMetricSystem())
if (measurementSystem == LocaleData. MeasurementSystem.SI)
R.string.measurement_unit_liquid_base_metric
else
R.string.measurement_unit_liquid_base_imperial
)
this.measurement_unit_weight_base = context.getString(
if (isMetricSystem())
if (measurementSystem == LocaleData. MeasurementSystem.SI)
R.string.measurement_unit_weight_base_metric
else
R.string.measurement_unit_weight_base_imperial
)
this.measurement_unit_weight_tiny = context.getString(
if (isMetricSystem())
if (measurementSystem == LocaleData. MeasurementSystem.SI)
R.string.measurement_unit_weight_tiny_metric
else
R.string.measurement_unit_weight_tiny_imperial
)
this.measurement_unit_temperature_base = context.getString(
if (isMetricSystem())
if (measurementSystem == LocaleData. MeasurementSystem.SI)
R.string.measurement_unit_temperature_base_metric
else
R.string.measurement_unit_temperature_base_imperial
)
}
fun formatEventQuantity(event: LunaEvent): String {
return formatEventQuantity(event.type, event.quantity)
}
fun formatEventQuantity(type: LunaEvent.Type, quantity: Int): String {
fun formatEventQuantity(item: LunaEvent): String {
val formatted = StringBuilder()
if (quantity > 0) {
formatted.append(when (type) {
LunaEvent.Type.TEMPERATURE ->
(quantity / 10.0f).toString()
LunaEvent.Type.DIAPERCHANGE_POO,
LunaEvent.Type.DIAPERCHANGE_PEE,
LunaEvent.Type.PUKE -> {
val array = context.resources.getStringArray(R.array.AmountLabels)
return array.getOrElse(quantity) {
Log.e("NumericUtils", "Invalid index $quantity")
return ""
}
}
LunaEvent.Type.SLEEP -> formatTimeDuration(context, quantity.toLong())
else -> quantity
})
if ((item.quantity ?: 0) > 0) {
if (item.type == LunaEvent.TYPE_TEMPERATURE)
formatted.append((item.quantity / 10.0f).toString())
else
formatted.append(item.quantity)
formatted.append(" ")
formatted.append(
when (type) {
LunaEvent.Type.BABY_BOTTLE -> measurement_unit_liquid_base
LunaEvent.Type.WEIGHT -> measurement_unit_weight_base
LunaEvent.Type.MEDICINE -> measurement_unit_weight_tiny
LunaEvent.Type.TEMPERATURE -> measurement_unit_temperature_base
when (item.type) {
LunaEvent.TYPE_BABY_BOTTLE -> measurement_unit_liquid_base
LunaEvent.TYPE_WEIGHT -> measurement_unit_weight_base
LunaEvent.TYPE_MEDICINE -> measurement_unit_weight_tiny
LunaEvent.TYPE_TEMPERATURE -> measurement_unit_temperature_base
else -> ""
}
)
} else {
formatted.append(when (type) {
LunaEvent.Type.SLEEP -> "💤" // baby is sleeping
else -> ""
})
}
return formatted.toString().trim()
return formatted.toString()
}
/**
* Returns a valid quantity range for the event type.
* @return min, max, normal
*/
fun getValidEventQuantityRange(lunaEventType: LunaEvent.Type): Triple<Int, Int, Int>? {
fun getValidEventQuantityRange(lunaEventType: String): Triple<Int, Int, Int>? {
val measurementSystem = LocaleData.getMeasurementSystem(ULocale.getDefault())
return when (lunaEventType) {
LunaEvent.Type.TEMPERATURE -> {
if (isMetricSystem())
LunaEvent.TYPE_TEMPERATURE -> {
if (measurementSystem == LocaleData. MeasurementSystem.SI)
Triple(
context.resources.getInteger(R.integer.human_body_temp_min_metric),
context.resources.getInteger(R.integer.human_body_temp_max_metric),

View File

@@ -0,0 +1,5 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:tint="#000000" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">
<path android:fillColor="@android:color/white" android:pathData="M12,8c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2 -2,0.9 -2,2 0.9,2 2,2zM12,10c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2zM12,16c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2z"/>
</vector>

View File

@@ -47,7 +47,7 @@
<LinearLayout
android:layout_width="match_parent"
android:layout_height="38dp"
android:layout_margin="5dp"
android:layout_margin="10dp"
android:orientation="horizontal"
android:gravity="center_vertical">
@@ -86,28 +86,27 @@
android:orientation="vertical">
<LinearLayout
android:id="@+id/linear_layout_row1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/button1_row1"
android:id="@+id/button_bottle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_margin="5dp"
android:layout_weight="2"
android:layout_margin="10dp"
android:background="@drawable/button_background"
android:gravity="center_horizontal"
android:textSize="50sp"
android:text="@string/event_bottle_type"/>
<TextView
android:id="@+id/button2_row1"
android:id="@+id/button_food"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_margin="5dp"
android:layout_margin="10dp"
android:background="@drawable/button_background"
android:gravity="center_horizontal"
android:textSize="50sp"
@@ -116,77 +115,80 @@
</LinearLayout>
<LinearLayout
android:id="@+id/linear_layout_row2"
android:layout_width="match_parent"
android:layout_height="wrap_content">
android:layout_height="wrap_content"
android:id="@+id/layout_nipples">
<TextView
android:id="@+id/button1_row2"
android:id="@+id/button_nipple_left"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:layout_weight="1"
android:background="@drawable/button_background"
android:gravity="center_horizontal"
android:textSize="30sp"/>
<TextView
android:id="@+id/button2_row2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:layout_weight="1"
android:background="@drawable/button_background"
android:gravity="center_horizontal"
android:textSize="30sp"/>
<TextView
android:id="@+id/button3_row2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:layout_weight="1"
android:background="@drawable/button_background"
android:gravity="center_horizontal"
android:textSize="30sp"/>
</LinearLayout>
<LinearLayout
android:id="@+id/linear_layout_row3"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/button1_row3"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:layout_weight="2"
android:background="@drawable/button_background"
android:gravity="center_horizontal"
android:textSize="30sp"/>
<TextView
android:id="@+id/button2_row3"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:layout_weight="2"
android:background="@drawable/button_background"
android:gravity="center_horizontal"
android:textSize="30sp"/>
<TextView
android:id="@+id/button_more"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:layout_margin="10dp"
android:layout_weight="1"
android:background="@drawable/button_background"
android:gravity="center_horizontal"
android:textSize="30sp"
android:text="☰"
android:text="🤱⬅️"/>
<TextView
android:id="@+id/button_nipple_both"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:layout_weight="1"
android:background="@drawable/button_background"
android:gravity="center_horizontal"
android:textSize="30sp"
android:text="🤱↔️"/>
<TextView
android:id="@+id/button_nipple_right"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:layout_weight="1"
android:background="@drawable/button_background"
android:gravity="center_horizontal"
android:textSize="30sp"
android:text="🤱➡️️"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/button_change_poo"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:layout_weight="2"
android:background="@drawable/button_background"
android:gravity="center_horizontal"
android:textSize="30sp"
android:text="🚼 💩"/>
<TextView
android:id="@+id/button_change_pee"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:layout_weight="2"
android:background="@drawable/button_background"
android:gravity="center_horizontal"
android:textSize="30sp"
android:text="🚼 💧"/>
<ImageView
android:id="@+id/button_more"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_margin="10dp"
android:layout_weight="1"
android:background="@drawable/button_background"
android:gravity="center_horizontal"
android:src="@drawable/ic_more"
app:tint="@android:color/darker_gray"/>
</LinearLayout>
@@ -196,7 +198,6 @@
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:orientation="horizontal">
<TextView

View File

@@ -45,7 +45,7 @@
<RadioButton android:id="@+id/settings_data_webdav"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:layout_marginTop="30dp"
android:text="@string/settings_storage_dav"/>
<TextView
@@ -119,57 +119,27 @@
android:visibility="invisible"/>
</RadioGroup>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textStyle="bold"
android:text="@string/settings_signature" />
<EditText
android:id="@+id/settings_signature"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginTop="5dp"
android:inputType="textEmailAddress"
android:background="@drawable/textview_background"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginTop="5dp"
android:text="@string/settings_signature_desc"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginTop="20dp">
android:layout_marginEnd="30dp">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_height="wrap_content"
android:textStyle="bold"
android:text="@string/settings_dynamic_menu" />
android:text="@string/no_breastfeeding" />
<com.google.android.material.switchmaterial.SwitchMaterial
android:id="@+id/switch_dynamic_menu"
android:layout_width="wrap_content"
android:id="@+id/switch_no_breastfeeding"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="20dp"
android:layout_weight="1" />
</LinearLayout>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginTop="5dp"
android:text="@string/settings_dynamic_menu_desc"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"

View File

@@ -1,50 +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:orientation="vertical"
android:padding="10dp">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1">
<com.github.mikephil.charting.charts.HorizontalBarChart
android:id="@+id/bar_chart"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<TextView
android:id="@+id/no_data"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"
android:gravity="center"
android:text="@string/statistics_no_data"/>
</FrameLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0"
android:orientation="horizontal">
<Spinner
android:id="@+id/graph_type_selection"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"/>
<Spinner
android:id="@+id/time_range_selection"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"/>
</LinearLayout>
</LinearLayout>

View File

@@ -1,35 +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:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:orientation="horizontal">
<NumberPicker
android:id="@+id/dialog_number_picker"
android:layout_width="150dp"
android:layout_height="wrap_content"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:text="ml"/>
</LinearLayout>
<TextView
android:id="@+id/dialog_date_picker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="20dp"/>
</LinearLayout>

View File

@@ -1,56 +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">
<TextView
android:id="@+id/dialog_date_duration"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp"
android:text="💤"/>
<LinearLayout
android:id="@+id/duration_buttons"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:layout_marginTop="20dp"
android:layout_marginHorizontal="10dp"
android:orientation="horizontal">
<Button
android:id="@+id/dialog_date_duration_minus5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="-5"/>
<Button
android:id="@+id/dialog_date_duration_now"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/now"/>
<Button
android:id="@+id/dialog_date_duration_plus5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="+5"/>
</LinearLayout>
<TextView
android:id="@+id/dialog_date_picker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="20dp"/>
</LinearLayout>

View File

@@ -1,38 +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:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:gravity="center"
android:orientation="horizontal">
<EditText
android:id="@+id/dialog_number_edittext"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:inputType="number"
android:hint="0"
android:background="@drawable/textview_background"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:text="g"/>
</LinearLayout>
<TextView
android:id="@+id/dialog_date_picker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="20dp"/>
</LinearLayout>

View File

@@ -1,11 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="20dp"
android:paddingBottom="10dp"
android:paddingHorizontal="20dp">
android:padding="20dp">
<TextView
android:id="@+id/dialog_event_detail_type_emoji"
@@ -35,7 +34,9 @@
android:drawablePadding="10dp"
android:drawableTint="@color/accent"
android:textSize="16sp"
android:textStyle="bold"/>
android:textStyle="bold"
android:text="@string/dialog_event_detail_datetime_icon"
app:drawableEndCompat="@drawable/ic_edit" />
<TextView
android:id="@+id/dialog_event_detail_type_quantity"
@@ -45,18 +46,6 @@
android:textSize="28sp"
android:text="@string/dialog_event_detail_quantity"/>
<TextView
android:id="@+id/dialog_event_detail_type_date_end"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:layout_gravity="center_horizontal"
android:gravity="center_vertical"
android:drawablePadding="10dp"
android:drawableTint="@color/accent"
android:visibility="gone"
android:textSize="16sp"
android:textStyle="bold"/>
<ScrollView
android:layout_width="match_parent"
android:layout_height="200dp"
@@ -72,14 +61,6 @@
</ScrollView>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:id="@+id/dialog_event_detail_type_signature"
android:layout_marginBottom="5dp"
android:visibility="gone"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"

View File

@@ -24,34 +24,4 @@
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:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="15dp"/>
</LinearLayout>

View File

@@ -2,25 +2,73 @@
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="10dp"
android:padding="20dp"
android:background="@color/transparent">
<LinearLayout
android:id="@+id/layout_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/button_statistics"
android:id="@+id/button_medicine"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="10dp"
android:padding="20dp"
android:background="@drawable/dropdown_list_item_background"
style="@style/OverflowMenuText"
android:text="📊 Statistics"/>
android:text="@string/overflow_event_medicine"/>
<TextView
android:id="@+id/button_enema"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="10dp"
android:padding="20dp"
android:background="@drawable/dropdown_list_item_background"
style="@style/OverflowMenuText"
android:text="@string/overflow_event_enema"/>
<TextView
android:id="@+id/button_note"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="10dp"
android:padding="20dp"
android:background="@drawable/dropdown_list_item_background"
style="@style/OverflowMenuText"
android:text="@string/overflow_event_note"/>
<TextView
android:id="@+id/button_temperature"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="10dp"
android:padding="20dp"
android:background="@drawable/dropdown_list_item_background"
style="@style/OverflowMenuText"
android:text="@string/overflow_event_temperature"/>
<TextView
android:id="@+id/button_colic"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="10dp"
android:padding="20dp"
android:background="@drawable/dropdown_list_item_background"
style="@style/OverflowMenuText"
android:text="@string/overflow_event_colic"/>
<TextView
android:id="@+id/button_scale"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="10dp"
android:padding="20dp"
android:background="@drawable/dropdown_list_item_background"
style="@style/OverflowMenuText"
android:text="@string/overflow_event_scale"/>
<!-- Other buttons are inserted dynamically -->
</LinearLayout>
</ScrollView>

View File

@@ -1,11 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/tv"
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="Item Template"/>

View File

@@ -4,19 +4,19 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:gravity="center"
android:orientation="vertical">
android:gravity="center">
<Spinner
android:id="@+id/dialog_amount_value"
android:layout_width="250dp"
<EditText
android:id="@+id/dialog_number_edittext"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:paddingHorizontal="16dp"/>
android:inputType="number"
android:hint="0"
android:background="@drawable/textview_background"/>
<TextView
android:id="@+id/dialog_date_picker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"/>
android:layout_marginStart="10dp"
android:text="g"/>
</LinearLayout>

View File

@@ -4,12 +4,16 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:gravity="center"
android:orientation="vertical">
android:gravity="center">
<TextView
android:id="@+id/dialog_date_picker"
android:layout_width="wrap_content"
<NumberPicker
android:id="@+id/dialog_number_picker"
android:layout_width="150dp"
android:layout_height="wrap_content"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:text="ml"/>
</LinearLayout>

View File

@@ -11,7 +11,7 @@
android:id="@+id/type"
android:layout_width="90dp"
android:layout_height="wrap_content"
android:paddingStart="10dp"
android:paddingLeft="10dp"
android:textSize="28sp"
android:lines="1"
android:maxLines="1"

View File

@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="20sp"
android:gravity="center"
android:padding="5dip" />

View File

@@ -23,11 +23,4 @@
android:layout_height="wrap_content"
android:textSize="30sp"
android:textColor="@color/accent"/>
<TextView
android:id="@+id/dialog_date_picker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"/>
</LinearLayout>

View File

@@ -3,9 +3,18 @@
<string name="title">🌜 LunaTracker 🌛</string>
<string name="logbook">Ereignisprotokoll</string>
<string name="log_bottle_dialog_title">Fläschchen</string>
<string name="log_bottle_dialog_description">Trinkmenge eingeben</string>
<string name="log_weight_dialog_title">Gewicht</string>
<string name="log_weight_dialog_description">Gewicht eingeben</string>
<string name="log_temperature_dialog_title">Temperatur</string>
<string name="log_temperature_dialog_description">Temperatur eingeben</string>
<string name="event_bottle_desc">Fläschchen</string>
<string name="event_food_desc">Essen</string>
<string name="event_weight_desc">Gewicht</string>
<string name="event_scale_desc">Gewicht</string>
<string name="event_breastfeeding_left_desc">Stillen (links)</string>
<string name="event_breastfeeding_both_desc">Stillen</string>
<string name="event_breastfeeding_right_desc">Stillen (rechts)</string>
@@ -18,6 +27,13 @@
<string name="event_colic_desc">Blähungskolik</string>
<string name="event_unknown_desc"></string>
<string name="overflow_event_scale">⚖️ Gewicht</string>
<string name="overflow_event_medicine">💊 Medikament</string>
<string name="overflow_event_enema">🪠 Einlauf</string>
<string name="overflow_event_note">📝 Notiz</string>
<string name="overflow_event_temperature">🌡️ Temperatur</string>
<string name="overflow_event_colic">💨 Blähungskolik</string>
<string name="toast_event_added">Ereignis gespeichert</string>
<string name="toast_logbook_saved">Logbuch gespeichert</string>
<string name="toast_event_add_error">Ereignis konnte nicht protokolliert werden</string>
@@ -34,6 +50,8 @@
<string name="no_connection_go_to_settings">Einstellungen</string>
<string name="no_connection_retry">Erneut versuchen</string>
<string name="no_breastfeeding">Kein Stillen</string>
<string name="settings_title">Einstellungen</string>
<string name="settings_storage">Speicherort für Daten auswählen</string>
<string name="settings_storage_local">Auf dem Gerät</string>
@@ -60,13 +78,10 @@
<string name="trim_logbook_dialog_button_ok">Jetzt bereinigen</string>
<string name="trim_logbook_dialog_button_cancel">Später erinnern</string>
<string name="log_bottle_dialog_description">Trinkmenge eingeben</string>
<string name="log_medicine_dialog_description">Medikamentenname, Menge, Art, Notizen, …:</string>
<string name="log_notes_dialog_description">Notizen:</string>
<string name="log_notes_dialog_note_hint">Notiz eingeben</string>
<string name="log_medicine_dialog_description">Medikamentenname, Menge, Art, Notizen, …:</string>
<string name="log_notes_dialog_qty_hint">Menge (optional)</string>
<string name="log_temperature_dialog_description">Temperatur eingeben</string>
<string name="log_weight_dialog_description">Gewicht eingeben</string>
<string name="log_notes_dialog_note_hint">Notiz eingeben</string>
<string name="dialog_event_detail_title">Ereignisdetails</string>
<string name="dialog_event_detail_close_button">OK</string>

View File

@@ -3,9 +3,18 @@
<string name="title">🌜 LunaTracker 🌛</string>
<string name="logbook">Entrées enregistrées</string>
<string name="log_bottle_dialog_title">Biberon</string>
<string name="log_bottle_dialog_description">Renseignez la quantité contenue dans le biberon</string>
<string name="log_weight_dialog_title">Poids</string>
<string name="log_weight_dialog_description">Renseignez le poids</string>
<string name="log_temperature_dialog_title">Température</string>
<string name="log_temperature_dialog_description">Renseignez la Température</string>
<string name="event_bottle_desc">Biberon</string>
<string name="event_food_desc">Nourriture</string>
<string name="event_weight_desc">Poids</string>
<string name="event_scale_desc">Poids</string>
<string name="event_breastfeeding_left_desc">Allaitement (sein gauche)</string>
<string name="event_breastfeeding_both_desc">Allaitement</string>
<string name="event_breastfeeding_right_desc">Allaitement (sein droit)</string>
@@ -18,6 +27,13 @@
<string name="event_colic_desc">Colique gazeuse</string>
<string name="event_unknown_desc"></string>
<string name="overflow_event_scale">⚖️ Poids</string>
<string name="overflow_event_medicine">💊 Médicament</string>
<string name="overflow_event_enema">🪠 Lavement</string>
<string name="overflow_event_note">📝 Note</string>
<string name="overflow_event_temperature">🌡️ Température</string>
<string name="overflow_event_colic">💨 Colique gazeuse</string>
<string name="toast_event_added">Entrée ajoutée</string>
<string name="toast_logbook_saved">Journal ajouté</string>
<string name="toast_event_add_error">Impossible d\'enregistrer cette entrée</string>
@@ -60,13 +76,10 @@
<string name="trim_logbook_dialog_button_ok">Supprimer les vieilles entrées maintenant</string>
<string name="trim_logbook_dialog_button_cancel">Me rappeller plus tard</string>
<string name="log_bottle_dialog_description">Renseignez la quantité contenue dans le biberon</string>
<string name="log_medicine_dialog_description">nom du médicament, quantité, type, notes …:</string>
<string name="log_notes_dialog_description">Notes:</string>
<string name="log_notes_dialog_note_hint">Notes ...</string>
<string name="log_medicine_dialog_description">nom du médicament, quantité, type, notes …:</string>
<string name="log_notes_dialog_qty_hint">Quantité (ou vide)</string>
<string name="log_temperature_dialog_description">Renseignez la Température</string>
<string name="log_weight_dialog_description">Renseignez le poids</string>
<string name="log_notes_dialog_note_hint">Notes ...</string>
<string name="dialog_event_detail_title">Détails de l\'entrée</string>
<string name="dialog_event_detail_close_button">OK</string>

View File

@@ -3,9 +3,25 @@
<string name="title">🌜 LunaTracker 🌛</string>
<string name="logbook">Diario di bordo</string>
<string name="log_bottle_dialog_title">Biberon</string>
<string name="log_bottle_dialog_description">Inserisci la quantità contenuta nel biberon</string>
<string name="log_weight_dialog_title">Pesata</string>
<string name="log_weight_dialog_description">Inserisci il peso rilevato</string>
<string name="log_temperature_dialog_title">Temperatura</string>
<string name="log_temperature_dialog_description">Inserisci la temperatura</string>
<string name="overflow_event_scale">⚖️ Peso</string>
<string name="overflow_event_medicine">💊 Medicina</string>
<string name="overflow_event_enema">🪠 Clistere</string>
<string name="overflow_event_note">📝 Nota</string>
<string name="overflow_event_temperature">🌡️ Temperatura</string>
<string name="overflow_event_colic">💨 Colichette</string>
<string name="event_bottle_desc">Biberon</string>
<string name="event_food_desc">Cibo</string>
<string name="event_weight_desc">Pesata</string>
<string name="event_scale_desc">Pesata</string>
<string name="event_breastfeeding_left_desc">Allatt. al seno (sx)</string>
<string name="event_breastfeeding_both_desc">Allatt. al seno</string>
<string name="event_breastfeeding_right_desc">Allatt. al seno (dx)</string>
@@ -60,13 +76,10 @@
<string name="trim_logbook_dialog_button_ok">Cancella i più vecchi</string>
<string name="trim_logbook_dialog_button_cancel">Ricordamelo dopo</string>
<string name="log_bottle_dialog_description">Inserisci la quantità contenuta nel biberon</string>
<string name="log_medicine_dialog_description">Nome della medicina, quantità, formato, note…:</string>
<string name="log_notes_dialog_description">Note:</string>
<string name="log_notes_dialog_note_hint">Inserisci le note</string>
<string name="log_medicine_dialog_description">Nome della medicina, quantità, formato, note…:</string>
<string name="log_notes_dialog_qty_hint">Quantità, o vuoto</string>
<string name="log_temperature_dialog_description">Inserisci la temperatura</string>
<string name="log_weight_dialog_description">Inserisci il peso rilevato</string>
<string name="log_notes_dialog_note_hint">Inserisci le note</string>
<string name="dialog_event_detail_title">Dettaglio evento</string>
<string name="dialog_event_detail_close_button">OK</string>

View File

@@ -1,39 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="AmountLabels">
<item>@string/amount_unspecified</item>
<item>@string/amount_little</item>
<item>@string/amount_normal</item>
<item>@string/amount_plenty</item>
</string-array>
<string-array name="StatisticsTypeLabels">
<item>@string/statistics_bottle_sum</item>
<item>@string/statistics_bottle_events</item>
<item>@string/statistics_sleep_sum</item>
<item>@string/statistics_sleep_events</item>
<item>@string/statistics_sleep_pattern</item>
<item>@string/statistics_medicine_events</item>
</string-array>
<string-array name="StatisticsTypeValues">
<item>BOTTLE_SUM</item>
<item>BOTTLE_EVENTS</item>
<item>SLEEP_SUM</item>
<item>SLEEP_EVENTS</item>
<item>SLEEP_PATTERN</item>
<item>MEDICINE_EVENTS</item>
</string-array>
<string-array name="StatisticsTimeLabels">
<item>Day</item>
<item>Week</item>
<item>Month</item>
</string-array>
<string-array name="StatisticsTimeValues">
<item>DAY</item>
<item>WEEK</item>
<item>MONTH</item>
</string-array>
</resources>

View File

@@ -3,13 +3,21 @@
<string name="title">🌜 LunaTracker 🌛</string>
<string name="logbook">Logged events</string>
<!-- menu header items -->
<string name="log_bottle_dialog_title">Baby bottle</string>
<string name="log_bottle_dialog_description">Insert the quantity contained in the baby bottle</string>
<string name="log_weight_dialog_title">Weight</string>
<string name="log_weight_dialog_description">Insert the weight</string>
<string name="log_temperature_dialog_title">Temperature</string>
<string name="log_temperature_dialog_description">Insert the temperature</string>
<string name="event_bottle_type" translatable="false">🍼</string>
<string name="event_food_type" translatable="false">🥣</string>
<string name="event_weight_type" translatable="false">⚖️</string>
<string name="event_breastfeeding_left_type" translatable="false">🤱⬅️</string>
<string name="event_breastfeeding_both_type" translatable="false">🤱↔</string>
<string name="event_breastfeeding_right_type" translatable="false">🤱➡️️</string>
<string name="event_scale_type" translatable="false">⚖️</string>
<string name="event_breastfeeding_left_type" translatable="false">🤱</string>
<string name="event_breastfeeding_both_type" translatable="false">🤱 </string>
<string name="event_breastfeeding_right_type" translatable="false">🤱</string>
<string name="event_diaperchange_poo_type" translatable="false">🚼 💩</string>
<string name="event_diaperchange_pee_type" translatable="false">🚼 💧</string>
<string name="event_medicine_type" translatable="false">💊</string>
@@ -17,54 +25,34 @@
<string name="event_note_type" translatable="false">📝</string>
<string name="event_temperature_type" translatable="false">🌡️</string>
<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_unknown_type" translatable="false">\?</string>
<!-- dropdown menu item -->
<string name="event_type_item_bottle">🍼 Bottle</string>
<string name="event_type_item_food">🥣 Food</string>
<string name="event_type_item_weight">⚖️ Weight</string>
<string name="event_type_item_breastfeeding_left">🤱⬅️ Nursing</string>
<string name="event_type_item_breastfeeding_both">🤱↔️ Nursing</string>
<string name="event_type_item_breastfeeding_right">🤱➡️️ Nursing</string>
<string name="event_type_item_diaperchange_poo">🚼💩 Diaper</string>
<string name="event_type_item_diaperchange_pee">🚼💧 Diaper</string>
<string name="event_type_item_medicine">💊 Medicine</string>
<string name="event_type_item_enema">🪠 Enema</string>
<string name="event_type_item_note">📝 Note</string>
<string name="event_type_item_temperature">🌡️ Temperature</string>
<string name="event_type_item_colic">💨 Colic</string>
<string name="event_type_item_puke">🤮 Puke</string>
<string name="event_type_item_sleep">💤 Sleep</string>
<string name="event_type_item_bath">🛁 Bath</string>
<string name="event_type_item_unknown">❓ Unknown</string>
<!-- dialog titles -->
<string name="event_bottle_desc">Milk Bottle</string>
<string name="event_bottle_desc">Baby bottle</string>
<string name="event_food_desc">Food</string>
<string name="event_weight_desc">Weight</string>
<string name="event_breastfeeding_left_desc">Nursing (left)</string>
<string name="event_breastfeeding_both_desc">Nursing (both)</string>
<string name="event_breastfeeding_right_desc">Nursing (right)</string>
<string name="event_diaperchange_poo_desc">Diaper Change (poo)</string>
<string name="event_diaperchange_pee_desc">Diaper Change (pee)</string>
<string name="event_scale_desc">Weight</string>
<string name="event_breastfeeding_left_desc">Breastfeeding (left)</string>
<string name="event_breastfeeding_both_desc">Breastfeeding</string>
<string name="event_breastfeeding_right_desc">Breastfeeding (right)</string>
<string name="event_diaperchange_poo_desc">Diaper chg (poo)</string>
<string name="event_diaperchange_pee_desc">Diaper chg (pee)</string>
<string name="event_medicine_desc">Medicine</string>
<string name="event_enema_desc">Enema</string>
<string name="event_note_desc">Note</string>
<string name="event_temperature_desc">Temperature</string>
<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">Unknown</string>
<string name="event_unknown_desc"></string>
<string name="overflow_event_scale">⚖️ Weight</string>
<string name="overflow_event_medicine">💊 Medicine</string>
<string name="overflow_event_enema">🪠 Enema</string>
<string name="overflow_event_note">📝 Note</string>
<string name="overflow_event_temperature">🌡️ Temperature</string>
<string name="overflow_event_colic">💨 Gaseous colic</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>
@@ -73,29 +61,19 @@
<string name="minutes_ago">mins</string>
<string name="hour_ago">hour</string>
<string name="hours_ago">hours</string>
<string name="day_ago">day</string>
<string name="days_ago">days</string>
<string name="day_ago">year</string>
<string name="days_ago">years</string>
<string name="year_ago">year</string>
<string name="years_ago">years</string>
<string name="amount_unspecified"></string>
<string name="amount_little">Little</string>
<string name="amount_normal">Normal</string>
<string name="amount_plenty">Plenty</string>
<string name="no_connection">No connection</string>
<string name="no_connection_explain">Unable to reach WebDAV service</string>
<string name="no_connection_go_to_settings">Settings</string>
<string name="no_connection_retry">Retry</string>
<string name="statistics_title">Statistics</string>
<string name="statistics_no_data">No Data</string>
<string name="no_breastfeeding">No Breastfeeding</string>
<string name="settings_dynamic_menu">Dynamic Menu</string>
<string name="settings_dynamic_menu_desc">Populate the header menu with the most used events.</string>
<string name="settings_title">Settings</string>
<string name="settings_signature">Signature</string>
<string name="settings_signature_desc">Attach a signature to each event you create and for others to see. Useful if multiple people add events.</string>
<string name="settings_storage">Choose where to save data</string>
<string name="settings_storage_local">On device</string>
<string name="settings_storage_local_desc">Most privacy-friendly solution: data doesn\'t leave your device</string>
@@ -121,17 +99,10 @@
<string name="trim_logbook_dialog_button_ok">Trim it now</string>
<string name="trim_logbook_dialog_button_cancel">Remind me later</string>
<string name="log_amount_dialog_description">Select the amount:</string>
<string name="log_bottle_dialog_description">Insert the quantity contained in the baby bottle:</string>
<string name="log_medicine_dialog_description">Medicine name, quantity, type, notes…:</string>
<string name="log_notes_dialog_description">Notes:</string>
<string name="log_notes_dialog_note_hint">Write some notes</string>
<string name="log_medicine_dialog_description">Medicine name, quantity, type, notes…:</string>
<string name="log_notes_dialog_qty_hint">Quantity (or empty)</string>
<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">Set sleep duration:</string>
<string name="log_sleep_dialog_description_start">Start sleep cycle:</string>
<string name="log_notes_dialog_note_hint">Write some notes</string>
<string name="measurement_unit_liquid_base_metric" translatable="false">ml</string>
<string name="measurement_unit_weight_base_metric" translatable="false">g</string>
@@ -142,24 +113,16 @@
<string name="measurement_unit_temperature_base_imperial" translatable="false">°F</string>
<string name="measurement_unit_temperature_base_metric" translatable="false">°C</string>
<string name="statistics_bottle_events">Bottle Events</string>
<string name="statistics_bottle_sum">Bottle Per Day</string>
<string name="statistics_medicine_events">Medicine Events</string>
<string name="statistics_sleep_sum">Sleep Per Day</string>
<string name="statistics_sleep_events">Sleep Events</string>
<string name="statistics_sleep_pattern">Sleep Pattern</string>
<string name="row_luna_event_description">Description</string>
<string name="row_luna_event_quantity">Qty</string>
<string name="row_luna_event_time">Time</string>
<string name="dialog_event_detail_title">Event detail</string>
<string name="dialog_event_detail_close_button">Close</string>
<string name="dialog_event_detail_save_button">Save</string>
<string name="dialog_event_detail_datetime_icon" translatable="false">🕒 %s</string>
<string name="dialog_event_detail_close_button">OK</string>
<string name="dialog_event_detail_delete_button">Delete</string>
<string name="dialog_event_detail_quantity">Quantity</string>
<string name="dialog_event_detail_notes">Notes</string>
<string name="dialog_event_detail_signature">by %s</string>
<string name="dialog_add_logbook_title">Add logbook</string>
<string name="dialog_add_logbook_logbookname">👶 Logbook name</string>

View File

@@ -4,11 +4,6 @@
<style name="Theme.LunaTracker" parent="Theme.AppCompat.NoActionBar">
<item name="colorAccent">@color/accent</item>
<item name="android:textColor">@color/textColor</item>
<!-- make the screen not overlap with the system bars -->
<item name="android:fitsSystemWindows">true</item>
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>
</style>
<style name="OverflowMenuText">

View File

@@ -6,7 +6,6 @@ This app is meant to log all the relevant events (diaper change, breastfeeding,
Dedicated to my daughter Luna.
A HUGE thanks to all our contributors. See https://git.ichibi.eu/penguin86/luna-tracker/src/branch/master/README.md
NOTE: The content on this app is for informational or educational purposes only and does not substitute professional medical advice or consultations with healthcare professionals.
Feature graphic ("Baby and baby milk bottle. Baby feeding."): © Vyacheslav Argenberg / http://www.vascoplanet.com/, CC BY 4.0 <https://creativecommons.org/licenses/by/4.0>, via Wikimedia Commons

View File

@@ -8,8 +8,6 @@ Elle permet de synchroniser les données entre différents appareils (en utilisa
Dédié à ma fille Luna.
Un grand merci à tous nos contributeurs. Voir https://git.ichibi.eu/penguin86/luna-tracker/src/branch/master/README.md
REMARQUE : le contenu de cette application est fourni à titre informatif ou éducatif uniquement et ne remplace pas les conseils médicaux professionnels ou les consultations avec des professionnels de la santé.
Crédit image ("Baby and baby milk bottle. Baby feeding."): © Vyacheslav Argenberg / http://www.vascoplanet.com/, CC BY 4.0 <https://creativecommons.org/licenses/by/4.0>, via Wikimedia Commons

View File

@@ -6,7 +6,6 @@ Quest'app è pensata per memorizzare tutti gli eventi del bambino (cambio di pan
Dedicato a mia figlia Luna.
Un grandissimo ringraziamento a tutti i contributors! Vedi https://git.ichibi.eu/penguin86/luna-tracker/src/branch/master/README.md
NOTA: il contenuto di quest'app ha solo scopo informativo o didattico e non sostituisce il consulto medico professionale o le consulenze con operatori sanitari.
Feature graphic ("Baby and baby milk bottle. Baby feeding."): © Vyacheslav Argenberg / http://www.vascoplanet.com/, CC BY 4.0 <https://creativecommons.org/licenses/by/4.0>, via Wikimedia Commons

View File

@@ -1,5 +1,5 @@
[versions]
agp = "8.13.0"
agp = "8.7.2"
kotlin = "2.0.0"
coreKtx = "1.10.1"
junit = "4.13.2"
@@ -9,11 +9,8 @@ lifecycleRuntimeKtx = "2.6.1"
activityCompose = "1.8.0"
composeBom = "2024.04.01"
appcompat = "1.7.0"
mpandroidchart = "v4.2.2"
mpandroidchartVersion = "v3.1.0"
recyclerview = "1.3.2"
material = "1.12.0"
sardineAndroid = "v0.9"
[libraries]
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
@@ -33,9 +30,6 @@ androidx-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit
androidx-material3 = { group = "androidx.compose.material3", name = "material3" }
androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" }
material = { group = "com.google.android.material", name = "material", version.ref = "material" }
mpandroidchart = { module = "com.github.PhilJay:MPAndroidChart", version.ref = "mpandroidchart" }
mpandroidchart-vv310 = { module = "com.github.PhilJay:MPAndroidChart", version.ref = "mpandroidchartVersion" }
sardine-android = { module = "com.github.thegrizzlylabs:sardine-android", version.ref = "sardineAndroid" }
[plugins]
android-application = { id = "com.android.application", version.ref = "agp" }

View File

@@ -1,6 +1,6 @@
#Sat Nov 02 10:58:51 CET 2024
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

View File

@@ -16,7 +16,7 @@ dependencyResolutionManagement {
repositories {
google()
mavenCentral()
maven(url = uri("https://jitpack.io"))
maven(url = "https://jitpack.io")
}
}