6 Commits

Author SHA1 Message Date
6232aedd04 German translation by Daniel Neubauer 2025-09-02 08:58:42 +02:00
05c34178a4 Bumped version 2025-04-28 08:48:23 +02:00
0d3be20e1e Logbook event date edit 2025-04-23 08:58:32 +02:00
4c5c7bcf1a Merge branch 'master' into develop 2025-04-19 08:53:43 +02:00
07393faf41 Added food event 2025-04-19 08:51:16 +02:00
9fddd37fe9 WIP editable date in event 2025-01-21 18:42:47 +01:00
13 changed files with 225 additions and 47 deletions

View File

@@ -10,3 +10,8 @@ This app is meant to log all the relevant events (diaper change, breastfeeding,
Dedicated to my daughter Luna. Dedicated to my daughter Luna.
![Screenshot](fastlane/metadata/android/en-US/images/phoneScreenshots/1.png) ![Screenshot](fastlane/metadata/android/en-US/images/phoneScreenshots/1.png)
Thanks for the valuable contributions to:
Chepycou (French translation)
Daniel Neubauer (German translation)

View File

@@ -12,8 +12,8 @@ android {
applicationId = "it.danieleverducci.lunatracker" applicationId = "it.danieleverducci.lunatracker"
minSdk = 21 minSdk = 21
targetSdk = 34 targetSdk = 34
versionCode = 3 versionCode = 4
versionName = "0.5" versionName = "0.6"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
} }

View File

@@ -1,5 +1,7 @@
package it.danieleverducci.lunatracker package it.danieleverducci.lunatracker
import android.app.DatePickerDialog
import android.app.TimePickerDialog
import android.content.DialogInterface import android.content.DialogInterface
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
@@ -19,7 +21,6 @@ import android.widget.Toast
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.view.children
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.progressindicator.LinearProgressIndicator import com.google.android.material.progressindicator.LinearProgressIndicator
@@ -40,6 +41,7 @@ import okio.IOException
import org.json.JSONException import org.json.JSONException
import utils.NumericUtils import utils.NumericUtils
import java.text.DateFormat import java.text.DateFormat
import java.util.Calendar
import java.util.Date import java.util.Date
class MainActivity : AppCompatActivity() { class MainActivity : AppCompatActivity() {
@@ -50,14 +52,14 @@ class MainActivity : AppCompatActivity() {
} }
var logbook: Logbook? = null var logbook: Logbook? = null
lateinit var adapter: LunaEventRecyclerAdapter var pauseLogbookUpdate = false
lateinit var progressIndicator: LinearProgressIndicator lateinit var progressIndicator: LinearProgressIndicator
lateinit var buttonsContainer: ViewGroup lateinit var buttonsContainer: ViewGroup
lateinit var recyclerView: RecyclerView lateinit var recyclerView: RecyclerView
lateinit var handler: Handler lateinit var handler: Handler
var savingEvent = false var savingEvent = false
val updateListRunnable: Runnable = Runnable { val updateListRunnable: Runnable = Runnable {
if (logbook != null) if (logbook != null && !pauseLogbookUpdate)
loadLogbook(logbook!!.name) loadLogbook(logbook!!.name)
handler.postDelayed(updateListRunnable, 1000*60) handler.postDelayed(updateListRunnable, 1000*60)
} }
@@ -68,12 +70,6 @@ class MainActivity : AppCompatActivity() {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
handler = Handler(mainLooper) handler = Handler(mainLooper)
adapter = LunaEventRecyclerAdapter(this)
adapter.onItemClickListener = object: LunaEventRecyclerAdapter.OnItemClickListener{
override fun onItemClick(event: LunaEvent) {
showEventDetailDialog(event)
}
}
// Show view // Show view
setContentView(R.layout.activity_main) setContentView(R.layout.activity_main)
@@ -82,12 +78,11 @@ class MainActivity : AppCompatActivity() {
buttonsContainer = findViewById<ViewGroup>(R.id.buttons_container) buttonsContainer = findViewById<ViewGroup>(R.id.buttons_container)
recyclerView = findViewById<RecyclerView>(R.id.list_events) recyclerView = findViewById<RecyclerView>(R.id.list_events)
recyclerView.setLayoutManager(LinearLayoutManager(applicationContext)) recyclerView.setLayoutManager(LinearLayoutManager(applicationContext))
recyclerView.adapter = adapter
// Set listeners // Set listeners
findViewById<View>(R.id.logbooks_add_button).setOnClickListener { showAddLogbookDialog(true) } findViewById<View>(R.id.logbooks_add_button).setOnClickListener { showAddLogbookDialog(true) }
findViewById<View>(R.id.button_bottle).setOnClickListener { askBabyBottleContent() } findViewById<View>(R.id.button_bottle).setOnClickListener { askBabyBottleContent() }
findViewById<View>(R.id.button_scale).setOnClickListener { askWeightValue() } findViewById<View>(R.id.button_food).setOnClickListener { askNotes(LunaEvent(LunaEvent.TYPE_FOOD)) }
findViewById<View>(R.id.button_nipple_left).setOnClickListener { logEvent( findViewById<View>(R.id.button_nipple_left).setOnClickListener { logEvent(
LunaEvent( LunaEvent(
LunaEvent.TYPE_BREASTFEEDING_LEFT_NIPPLE LunaEvent.TYPE_BREASTFEEDING_LEFT_NIPPLE
@@ -132,6 +127,16 @@ class MainActivity : AppCompatActivity() {
}) })
} }
private fun setListAdapter(items: ArrayList<LunaEvent>) {
val adapter = LunaEventRecyclerAdapter(this, items)
adapter.onItemClickListener = object: LunaEventRecyclerAdapter.OnItemClickListener{
override fun onItemClick(event: LunaEvent) {
showEventDetailDialog(event)
}
}
recyclerView.adapter = adapter
}
fun showSettings() { fun showSettings() {
val i = Intent(this, SettingsActivity::class.java) val i = Intent(this, SettingsActivity::class.java)
startActivity(i) startActivity(i)
@@ -142,9 +147,7 @@ class MainActivity : AppCompatActivity() {
if (logbook == null) if (logbook == null)
Log.w(TAG, "showLogbook(): logbook is null!") Log.w(TAG, "showLogbook(): logbook is null!")
adapter.items.clear() setListAdapter(logbook?.logs ?: arrayListOf())
adapter.items.addAll(logbook?.logs ?: listOf())
adapter.notifyDataSetChanged()
} }
override fun onStart() { override fun onStart() {
@@ -166,7 +169,7 @@ class MainActivity : AppCompatActivity() {
} }
// Update list dates // Update list dates
adapter.notifyDataSetChanged() recyclerView.adapter?.notifyDataSetChanged()
if (logbook != null) { if (logbook != null) {
// Already running: reload data for currently selected logbook // Already running: reload data for currently selected logbook
@@ -254,12 +257,7 @@ class MainActivity : AppCompatActivity() {
val d = AlertDialog.Builder(this) val d = AlertDialog.Builder(this)
val dialogView = layoutInflater.inflate(R.layout.dialog_notes, null) val dialogView = layoutInflater.inflate(R.layout.dialog_notes, null)
d.setTitle(lunaEvent.getTypeDescription(this)) d.setTitle(lunaEvent.getTypeDescription(this))
d.setMessage( d.setMessage(lunaEvent.getDialogMessage(this))
when (lunaEvent.type){
LunaEvent.TYPE_MEDICINE -> R.string.log_medicine_dialog_description
else -> R.string.log_notes_dialog_description
}
)
d.setView(dialogView) d.setView(dialogView)
val notesET = dialogView.findViewById<EditText>(R.id.notes_edittext) val notesET = dialogView.findViewById<EditText>(R.id.notes_edittext)
val qtyET = dialogView.findViewById<EditText>(R.id.notes_qty_edittext) val qtyET = dialogView.findViewById<EditText>(R.id.notes_qty_edittext)
@@ -305,23 +303,57 @@ class MainActivity : AppCompatActivity() {
} }
fun showEventDetailDialog(event: LunaEvent) { fun showEventDetailDialog(event: LunaEvent) {
// Do not update list while the detail is shown, to avoid changing the object below while it is changed by the user
pauseLogbookUpdate = true
val dateFormat = DateFormat.getDateTimeInstance(); val dateFormat = DateFormat.getDateTimeInstance();
val d = AlertDialog.Builder(this) val d = AlertDialog.Builder(this)
d.setTitle(R.string.dialog_event_detail_title) d.setTitle(R.string.dialog_event_detail_title)
val dialogView = layoutInflater.inflate(R.layout.dialog_event_detail, null) val dialogView = layoutInflater.inflate(R.layout.dialog_event_detail, null)
dialogView.findViewById<TextView>(R.id.dialog_event_detail_type_emoji).setText(event.getTypeEmoji(this)) dialogView.findViewById<TextView>(R.id.dialog_event_detail_type_emoji).setText(event.getTypeEmoji(this))
dialogView.findViewById<TextView>(R.id.dialog_event_detail_type_description).setText(event.getTypeDescription(this)) dialogView.findViewById<TextView>(R.id.dialog_event_detail_type_description).setText(event.getTypeDescription(this))
dialogView.findViewById<TextView>(R.id.dialog_event_detail_type_date).setText(dateFormat.format(Date(event.time * 1000)))
dialogView.findViewById<TextView>(R.id.dialog_event_detail_type_quantity).setText( dialogView.findViewById<TextView>(R.id.dialog_event_detail_type_quantity).setText(
NumericUtils(this).formatEventQuantity(event) NumericUtils(this).formatEventQuantity(event)
) )
dialogView.findViewById<TextView>(R.id.dialog_event_detail_type_notes).setText(event.notes) dialogView.findViewById<TextView>(R.id.dialog_event_detail_type_notes).setText(event.notes)
val currentDateTime = Calendar.getInstance()
currentDateTime.time = Date(event.time * 1000)
val dateTextView = dialogView.findViewById<TextView>(R.id.dialog_event_detail_type_date)
dateTextView.text = String.format(getString(R.string.dialog_event_detail_datetime_icon), dateFormat.format(currentDateTime.time))
dateTextView.setOnClickListener({
// Show datetime picker
val startYear = currentDateTime.get(Calendar.YEAR)
val startMonth = currentDateTime.get(Calendar.MONTH)
val startDay = currentDateTime.get(Calendar.DAY_OF_MONTH)
val startHour = currentDateTime.get(Calendar.HOUR_OF_DAY)
val startMinute = currentDateTime.get(Calendar.MINUTE)
DatePickerDialog(this, DatePickerDialog.OnDateSetListener { _, year, month, day ->
TimePickerDialog(this, TimePickerDialog.OnTimeSetListener { _, hour, minute ->
val pickedDateTime = Calendar.getInstance()
pickedDateTime.set(year, month, day, hour, minute)
currentDateTime.time = pickedDateTime.time
dateTextView.text = String.format(getString(R.string.dialog_event_detail_datetime_icon), dateFormat.format(currentDateTime.time))
// Save event and move it to the right position in the logbook
event.time = currentDateTime.time.time / 1000 // Seconds since epoch
logbook?.sort()
recyclerView.adapter?.notifyDataSetChanged()
saveLogbook()
}, startHour, startMinute, false).show()
}, startYear, startMonth, startDay).show()
})
d.setView(dialogView) d.setView(dialogView)
d.setPositiveButton(android.R.string.ok) { dialogInterface, i -> dialogInterface.dismiss() } d.setPositiveButton(R.string.dialog_event_detail_close_button) { dialogInterface, i -> dialogInterface.dismiss() }
d.setNeutralButton(R.string.dialog_event_detail_delete_button) { dialogInterface, i -> deleteEvent(event) } d.setNeutralButton(R.string.dialog_event_detail_delete_button) { dialogInterface, i -> deleteEvent(event) }
val alertDialog = d.create() val alertDialog = d.create()
alertDialog.show() alertDialog.show()
alertDialog.getButton(DialogInterface.BUTTON_NEUTRAL).setTextColor(ContextCompat.getColor(this, R.color.danger)) alertDialog.getButton(DialogInterface.BUTTON_NEUTRAL).setTextColor(ContextCompat.getColor(this, R.color.danger))
alertDialog.setOnDismissListener({
// Resume logbook update
pauseLogbookUpdate = false
})
} }
fun showAddLogbookDialog(requestedByUser: Boolean) { fun showAddLogbookDialog(requestedByUser: Boolean) {
@@ -372,8 +404,7 @@ class MainActivity : AppCompatActivity() {
id: Long id: Long
) { ) {
// Changed logbook: empty list // Changed logbook: empty list
adapter.items.clear() setListAdapter(arrayListOf())
adapter.notifyDataSetChanged()
// Load logbook // Load logbook
loadLogbook(logbooksNames.get(position)) loadLogbook(logbooksNames.get(position))
} }
@@ -543,12 +574,11 @@ class MainActivity : AppCompatActivity() {
fun logEvent(event: LunaEvent) { fun logEvent(event: LunaEvent) {
savingEvent(true) savingEvent(true)
adapter.items.add(0, event)
adapter.notifyItemInserted(0)
recyclerView.smoothScrollToPosition(0)
setLoading(true) setLoading(true)
logbook?.logs?.add(0, event) logbook?.logs?.add(0, event)
recyclerView.adapter?.notifyItemInserted(0)
recyclerView.smoothScrollToPosition(0)
saveLogbook(event) saveLogbook(event)
// Check logbook size to avoid OOM errors // Check logbook size to avoid OOM errors
@@ -560,12 +590,11 @@ class MainActivity : AppCompatActivity() {
fun deleteEvent(event: LunaEvent) { fun deleteEvent(event: LunaEvent) {
// Update view // Update view
savingEvent(true) savingEvent(true)
adapter.items.remove(event)
adapter.notifyDataSetChanged()
// Update data // Update data
setLoading(true) setLoading(true)
logbook?.logs?.remove(event) logbook?.logs?.remove(event)
recyclerView.adapter?.notifyDataSetChanged()
saveLogbook() saveLogbook()
} }
@@ -648,8 +677,7 @@ class MainActivity : AppCompatActivity() {
setLoading(false) setLoading(false)
Toast.makeText(this@MainActivity, R.string.toast_event_add_error, Toast.LENGTH_SHORT).show() Toast.makeText(this@MainActivity, R.string.toast_event_add_error, Toast.LENGTH_SHORT).show()
adapter.items.remove(event) recyclerView.adapter?.notifyDataSetChanged()
adapter.notifyDataSetChanged()
savingEvent(false) savingEvent(false)
}) })
} }
@@ -702,6 +730,10 @@ class MainActivity : AppCompatActivity() {
) )
dismiss() dismiss()
}) })
contentView.findViewById<View>(R.id.button_scale).setOnClickListener({
askWeightValue()
dismiss()
})
}.also { popupWindow -> }.also { popupWindow ->
popupWindow.setOnDismissListener({ popupWindow.setOnDismissListener({
Handler(mainLooper).postDelayed({ Handler(mainLooper).postDelayed({

View File

@@ -14,13 +14,14 @@ import utils.NumericUtils
class LunaEventRecyclerAdapter: RecyclerView.Adapter<LunaEventRecyclerAdapter.LunaEventVH> { class LunaEventRecyclerAdapter: RecyclerView.Adapter<LunaEventRecyclerAdapter.LunaEventVH> {
private val context: Context private val context: Context
val items = ArrayList<LunaEvent>() private val items: ArrayList<LunaEvent>
val numericUtils: NumericUtils val numericUtils: NumericUtils
var onItemClickListener: OnItemClickListener? = null var onItemClickListener: OnItemClickListener? = null
val layoutRes: Int val layoutRes: Int
constructor(context: Context) { constructor(context: Context, items: ArrayList<LunaEvent>) {
this.context = context this.context = context
this.items = items
this.numericUtils = NumericUtils(context) this.numericUtils = NumericUtils(context)
val fontScale = context.resources.configuration.fontScale val fontScale = context.resources.configuration.fontScale

View File

@@ -16,4 +16,8 @@ class Logbook(val name: String) {
fun trim() { fun trim() {
logs.subList(MAX_SAFE_LOGBOOK_SIZE/2, logs.size).clear() logs.subList(MAX_SAFE_LOGBOOK_SIZE/2, logs.size).clear()
} }
fun sort() {
logs.sortDescending()
}
} }

View File

@@ -11,7 +11,7 @@ import java.util.Date
* allow expandability and backwards compatibility (if a field is added in a * allow expandability and backwards compatibility (if a field is added in a
* release, it is simply ignored by previous ones). * release, it is simply ignored by previous ones).
*/ */
class LunaEvent { class LunaEvent: Comparable<LunaEvent> {
companion object { companion object {
val TYPE_BABY_BOTTLE = "BABY_BOTTLE" val TYPE_BABY_BOTTLE = "BABY_BOTTLE"
@@ -27,6 +27,7 @@ class LunaEvent {
val TYPE_CUSTOM = "CUSTOM" val TYPE_CUSTOM = "CUSTOM"
val TYPE_COLIC = "COLIC" val TYPE_COLIC = "COLIC"
val TYPE_TEMPERATURE = "TEMPERATURE" val TYPE_TEMPERATURE = "TEMPERATURE"
val TYPE_FOOD = "FOOD"
} }
private val jo: JSONObject private val jo: JSONObject
@@ -88,6 +89,7 @@ class LunaEvent {
TYPE_NOTE -> R.string.event_note_type TYPE_NOTE -> R.string.event_note_type
TYPE_TEMPERATURE -> R.string.event_temperature_type TYPE_TEMPERATURE -> R.string.event_temperature_type
TYPE_COLIC -> R.string.event_colic_type TYPE_COLIC -> R.string.event_colic_type
TYPE_FOOD -> R.string.event_food_type
else -> R.string.event_unknown_type else -> R.string.event_unknown_type
} }
) )
@@ -108,11 +110,19 @@ class LunaEvent {
TYPE_NOTE -> R.string.event_note_desc TYPE_NOTE -> R.string.event_note_desc
TYPE_TEMPERATURE -> R.string.event_temperature_desc TYPE_TEMPERATURE -> R.string.event_temperature_desc
TYPE_COLIC -> R.string.event_colic_desc TYPE_COLIC -> R.string.event_colic_desc
TYPE_FOOD -> R.string.event_food_desc
else -> R.string.event_unknown_desc else -> R.string.event_unknown_desc
} }
) )
} }
fun getDialogMessage(context: Context): String? {
return when(type) {
TYPE_MEDICINE -> context.getString(R.string.log_medicine_dialog_description)
else -> null
}
}
fun toJson(): JSONObject { fun toJson(): JSONObject {
return jo return jo
} }
@@ -120,4 +130,8 @@ class LunaEvent {
override fun toString(): String { 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()
}
} }

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="M3,17.25V21h3.75L17.81,9.94l-3.75,-3.75L3,17.25zM20.71,7.04c0.39,-0.39 0.39,-1.02 0,-1.41l-2.34,-2.34c-0.39,-0.39 -1.02,-0.39 -1.41,0l-1.83,1.83 3.75,3.75 1.83,-1.83z"/>
</vector>

View File

@@ -108,7 +108,7 @@
android:text="@string/event_bottle_type"/> android:text="@string/event_bottle_type"/>
<TextView <TextView
android:id="@+id/button_scale" android:id="@+id/button_food"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1" android:layout_weight="1"
@@ -116,7 +116,7 @@
android:background="@drawable/button_background" android:background="@drawable/button_background"
android:gravity="center_horizontal" android:gravity="center_horizontal"
android:textSize="50dp" android:textSize="50dp"
android:text="@string/event_scale_type"/> android:text="@string/event_food_type"/>
</LinearLayout> </LinearLayout>

View File

@@ -25,19 +25,23 @@
<TextView <TextView
android:id="@+id/dialog_event_detail_type_date" android:id="@+id/dialog_event_detail_type_date"
android:layout_width="match_parent" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="40dp"
android:layout_marginTop="20dp" android:layout_marginTop="20dp"
android:gravity="center_horizontal" android:layout_gravity="center_horizontal"
android:gravity="center_vertical"
android:drawableEnd="@drawable/ic_edit"
android:drawablePadding="10dp"
android:drawableTint="@color/accent"
android:textStyle="bold" android:textStyle="bold"
android:text="2020"/> android:text="@string/dialog_event_detail_datetime_icon"/>
<TextView <TextView
android:id="@+id/dialog_event_detail_type_quantity" android:id="@+id/dialog_event_detail_type_quantity"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="center_horizontal" android:gravity="center_horizontal"
android:text="2020"/> android:text="Quantity"/>
<ScrollView <ScrollView
android:layout_width="match_parent" android:layout_width="match_parent"
@@ -49,7 +53,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textStyle="italic" android:textStyle="italic"
android:text="Lorem ipsum"/> android:text="Notes"/>
</ScrollView> </ScrollView>
</LinearLayout> </LinearLayout>

View File

@@ -59,6 +59,16 @@
style="@style/OverflowMenuText" style="@style/OverflowMenuText"
android:text="@string/overflow_event_colic"/> 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"/>
</LinearLayout> </LinearLayout>
</ScrollView> </ScrollView>

View File

@@ -0,0 +1,97 @@
<resources>
<string name="app_name">LunaTracker</string>
<string name="title">🌜 LunaTracker 🌛</string>
<string name="log_an_event">Ereignis protokollieren:</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_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>
<string name="event_diaperchange_poo_desc">Windelwechsel (Stuhl)</string>
<string name="event_diaperchange_pee_desc">Windelwechsel (Urin)</string>
<string name="event_medicine_desc">Medikament</string>
<string name="event_enema_desc">Einlauf</string>
<string name="event_note_desc">Notiz</string>
<string name="event_temperature_desc">Temperatur</string>
<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>
<string name="toast_integer_error">Ungültiger Wert. Bitte eine Ganzzahl eingeben.</string>
<string name="now">jetzt</string>
<string name="hour_ago">Std.</string>
<string name="hours_ago">Std.</string>
<string name="minute_ago">Min.</string>
<string name="minutes_ago">Min.</string>
<string name="no_connection">Keine Verbindung</string>
<string name="no_connection_explain">WebDAV-Dienst nicht erreichbar</string>
<string name="no_connection_go_to_settings">Einstellungen</string>
<string name="no_connection_retry">Erneut versuchen</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>
<string name="settings_storage_local_desc">Datenschutzfreundlichste Lösung: Deine Daten verlassen dein Gerät nicht</string>
<string name="settings_storage_dav">Auf einem WebDAV-Server</string>
<string name="settings_storage_dav_desc">Du kannst jeden WebDAV-Dienst (z.B. Nextcloud, ownCloud, Dropbox, …) verwenden, um die Daten zu speichern. Auf diese Weise kannst du sie zwischen mehreren Geräten synchronisieren (z.B. dem vom Vater, der Mutter, der Großmutter, …). Dazu benötigst du die WebDAV-URL. Du findest diese in der Dokumentation deines Anbieters (z.B. bei Nextcloud im Bereich Einstellungen der Dateien-App).</string>
<string name="settings_storage_dav_url">WebDAV URL</string>
<string name="settings_storage_dav_url_hint">https://</string>
<string name="settings_storage_dav_user">Benutzername</string>
<string name="settings_storage_dav_pass">Passwort</string>
<string name="settings_network_error">Server nicht erreichbar: </string>
<string name="settings_webdav_error_denied">Falscher WebDAV-Benutzer oder falsches Passwort</string>
<string name="settings_webdav_error_server_offline">WebDAV-Server ist derzeit nicht verfügbar</string>
<string name="settings_webdav_error_generic">Fehler beim Zugriff auf WebDAV:</string>
<string name="settings_webdav_creation_error_generic">Eine Datei konnte auf dem WebDAV-Server nicht gespeichert werden:</string>
<string name="settings_webdav_creation_ok">Erfolgreich mit dem WebDAV-Server verbunden</string>
<string name="settings_json_error">Es befindet sich eine Speicherdatei auf dem Server, aber sie ist beschädigt oder unlesbar. Bitte lösche die Datei.</string>
<string name="settings_generic_error">Fehler: </string>
<string name="settings_webdav_upload_error">Fehler beim Hochladen des lokalen Logbuchs %1$s zu WebDAV: %2$s</string>
<string name="trim_logbook_dialog_title">Dein Logbuch ist ziemlich groß!</string>
<string name="trim_logbook_dialog_message_local">Deine Logbuchdatei wird sehr groß. Wir empfehlen, die ältesten Einträge zu entfernen, um Abstürze zu vermeiden.</string>
<string name="trim_logbook_dialog_message_dav">Deine Logbuchdatei wird sehr groß. Wir empfehlen, die ältesten Einträge (durch Entfernen) zu bereinigen, um Abstürze zu vermeiden. Wenn du alle Einträge behalten möchtest, sichere bitte die Datei "lunatracker_logbook.json" auf dem WebDAVServer oder benenne sie um, um ein neues Logbuch zu beginnen und das alte zu behalten.</string>
<string name="trim_logbook_dialog_button_ok">Jetzt bereinigen</string>
<string name="trim_logbook_dialog_button_cancel">Später erinnern</string>
<string name="log_notes_dialog_description">Notizen:</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_notes_dialog_note_hint">Notiz eingeben</string>
<string name="dialog_event_detail_title">Ereignisdetails</string>
<string name="dialog_event_detail_close_button">OK</string>
<string name="dialog_event_detail_delete_button">Löschen</string>
<string name="dialog_add_logbook_title">Logbuch hinzufügen</string>
<string name="dialog_add_logbook_logbookname">👶 Logbuchname</string>
<string name="dialog_add_logbook_message">Gib einen Namen ein, um dieses Logbuch zu bezeichnen. Dieser Name erscheint oben auf dem Bildschirm und wird, falls du WebDAV verwendest, auch im Dateinamen der gespeicherten Datei enthalten sein.</string>
<string name="dialog_add_logbook_message_intro">Willkommen! Um diese App zu benutzen, musst du mindestens ein Logbuch erstellen. Am besten benennst du es nach dem Namen deines Kindes.</string>
<string name="default_logbook_name">👶 Mein erstes Logbuch</string>
<string name="logbook_created">Neues Logbuch erstellt: </string>
</resources>

View File

@@ -13,6 +13,7 @@
<string name="log_temperature_dialog_title">Temperatura</string> <string name="log_temperature_dialog_title">Temperatura</string>
<string name="log_temperature_dialog_description">Inserisci la 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_medicine">💊 Medicina</string>
<string name="overflow_event_enema">🪠 Clistere</string> <string name="overflow_event_enema">🪠 Clistere</string>
<string name="overflow_event_note">📝 Nota</string> <string name="overflow_event_note">📝 Nota</string>
@@ -20,6 +21,7 @@
<string name="overflow_event_colic">💨 Colichette</string> <string name="overflow_event_colic">💨 Colichette</string>
<string name="event_bottle_desc">Biberon</string> <string name="event_bottle_desc">Biberon</string>
<string name="event_food_desc">Cibo</string>
<string name="event_scale_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_left_desc">Allatt. al seno (sx)</string>
<string name="event_breastfeeding_both_desc">Allatt. al seno</string> <string name="event_breastfeeding_both_desc">Allatt. al seno</string>
@@ -81,7 +83,7 @@
<string name="log_notes_dialog_note_hint">Inserisci le note</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_title">Dettaglio evento</string>
<string name="dialog_event_detail_save_button">Salva</string> <string name="dialog_event_detail_close_button">OK</string>
<string name="dialog_event_detail_delete_button">Elimina</string> <string name="dialog_event_detail_delete_button">Elimina</string>
<string name="dialog_add_logbook_title">Aggiungi diario</string> <string name="dialog_add_logbook_title">Aggiungi diario</string>

View File

@@ -14,6 +14,7 @@
<string name="log_temperature_dialog_description">Insert the temperature</string> <string name="log_temperature_dialog_description">Insert the temperature</string>
<string name="event_bottle_type" translatable="false">🍼</string> <string name="event_bottle_type" translatable="false">🍼</string>
<string name="event_food_type" translatable="false">🥣</string>
<string name="event_scale_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_left_type" translatable="false">🤱 ←</string>
<string name="event_breastfeeding_both_type" translatable="false">🤱 ↔</string> <string name="event_breastfeeding_both_type" translatable="false">🤱 ↔</string>
@@ -28,6 +29,7 @@
<string name="event_unknown_type" translatable="false">\?</string> <string name="event_unknown_type" translatable="false">\?</string>
<string name="event_bottle_desc">Baby bottle</string> <string name="event_bottle_desc">Baby bottle</string>
<string name="event_food_desc">Food</string>
<string name="event_scale_desc">Weight</string> <string name="event_scale_desc">Weight</string>
<string name="event_breastfeeding_left_desc">Breastfeeding (left)</string> <string name="event_breastfeeding_left_desc">Breastfeeding (left)</string>
<string name="event_breastfeeding_both_desc">Breastfeeding</string> <string name="event_breastfeeding_both_desc">Breastfeeding</string>
@@ -41,6 +43,7 @@
<string name="event_colic_desc">Gaseous colic</string> <string name="event_colic_desc">Gaseous colic</string>
<string name="event_unknown_desc"></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_medicine">💊 Medicine</string>
<string name="overflow_event_enema">🪠 Enema</string> <string name="overflow_event_enema">🪠 Enema</string>
<string name="overflow_event_note">📝 Note</string> <string name="overflow_event_note">📝 Note</string>
@@ -104,7 +107,8 @@
<string name="measurement_unit_temperature_base_metric" translatable="false">°C</string> <string name="measurement_unit_temperature_base_metric" translatable="false">°C</string>
<string name="dialog_event_detail_title">Event detail</string> <string name="dialog_event_detail_title">Event detail</string>
<string name="dialog_event_detail_save_button">Save</string> <string name="dialog_event_detail_datetime_icon" translatable="false">🕒 %s1</string>
<string name="dialog_event_detail_close_button">OK</string>
<string name="dialog_event_detail_delete_button">Delete</string> <string name="dialog_event_detail_delete_button">Delete</string>
<string name="dialog_add_logbook_title">Add logbook</string> <string name="dialog_add_logbook_title">Add logbook</string>