Compare commits
2 Commits
c6b5ec1a4d
...
abee1be72c
Author | SHA1 | Date | |
---|---|---|---|
abee1be72c | |||
653c57e6e0 |
@ -15,11 +15,9 @@ import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.google.android.material.progressindicator.LinearProgressIndicator
|
||||
import com.thegrizzlylabs.sardineandroid.impl.SardineException
|
||||
import it.danieleverducci.lunatracker.SettingsActivity
|
||||
import it.danieleverducci.lunatracker.adapters.LunaEventRecyclerAdapter
|
||||
import it.danieleverducci.lunatracker.entities.Logbook
|
||||
import it.danieleverducci.lunatracker.entities.LunaEvent
|
||||
import it.danieleverducci.lunatracker.entities.LunaEventType
|
||||
import it.danieleverducci.lunatracker.repository.FileLogbookRepository
|
||||
import it.danieleverducci.lunatracker.repository.LocalSettingsRepository
|
||||
import it.danieleverducci.lunatracker.repository.LogbookLoadedListener
|
||||
@ -68,27 +66,27 @@ class MainActivity : AppCompatActivity() {
|
||||
findViewById<View>(R.id.button_scale).setOnClickListener { askWeightValue() }
|
||||
findViewById<View>(R.id.button_nipple_left).setOnClickListener { logEvent(
|
||||
LunaEvent(
|
||||
LunaEventType.BREASTFEEDING_LEFT_NIPPLE
|
||||
LunaEvent.TYPE_BREASTFEEDING_LEFT_NIPPLE
|
||||
)
|
||||
) }
|
||||
findViewById<View>(R.id.button_nipple_both).setOnClickListener { logEvent(
|
||||
LunaEvent(
|
||||
LunaEventType.BREASTFEEDING_BOTH_NIPPLE
|
||||
LunaEvent.TYPE_BREASTFEEDING_BOTH_NIPPLE
|
||||
)
|
||||
) }
|
||||
findViewById<View>(R.id.button_nipple_right).setOnClickListener { logEvent(
|
||||
LunaEvent(
|
||||
LunaEventType.BREASTFEEDING_RIGHT_NIPPLE
|
||||
LunaEvent.TYPE_BREASTFEEDING_RIGHT_NIPPLE
|
||||
)
|
||||
) }
|
||||
findViewById<View>(R.id.button_change_poo).setOnClickListener { logEvent(
|
||||
LunaEvent(
|
||||
LunaEventType.DIAPERCHANGE_POO
|
||||
LunaEvent.TYPE_DIAPERCHANGE_POO
|
||||
)
|
||||
) }
|
||||
findViewById<View>(R.id.button_change_pee).setOnClickListener { logEvent(
|
||||
LunaEvent(
|
||||
LunaEventType.DIAPERCHANGE_PEE
|
||||
LunaEvent.TYPE_DIAPERCHANGE_PEE
|
||||
)
|
||||
) }
|
||||
findViewById<View>(R.id.button_no_connection_settings).setOnClickListener({
|
||||
@ -164,7 +162,7 @@ class MainActivity : AppCompatActivity() {
|
||||
numberPicker.wrapSelectorWheel = false
|
||||
numberPicker.value = localSettings.loadBabyBottleContent()
|
||||
d.setPositiveButton(android.R.string.ok) { dialogInterface, i ->
|
||||
logEvent(LunaEvent(LunaEventType.BABY_BOTTLE, numberPicker.value * 10))
|
||||
logEvent(LunaEvent(LunaEvent.TYPE_BABY_BOTTLE, numberPicker.value * 10))
|
||||
localSettings.saveBabyBottleContent(numberPicker.value)
|
||||
}
|
||||
d.setNegativeButton(android.R.string.cancel) { dialogInterface, i -> dialogInterface.dismiss() }
|
||||
@ -183,7 +181,7 @@ class MainActivity : AppCompatActivity() {
|
||||
d.setPositiveButton(android.R.string.ok) { dialogInterface, i ->
|
||||
val weight = weightET.text.toString().toIntOrNull()
|
||||
if (weight != null)
|
||||
logEvent(LunaEvent(LunaEventType.WEIGHT, weight))
|
||||
logEvent(LunaEvent(LunaEvent.TYPE_WEIGHT, weight))
|
||||
else
|
||||
Toast.makeText(this, R.string.toast_integer_error, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
@ -192,6 +190,26 @@ class MainActivity : AppCompatActivity() {
|
||||
alertDialog.show()
|
||||
}
|
||||
|
||||
fun askToTrimLogbook() {
|
||||
val d = AlertDialog.Builder(this)
|
||||
d.setTitle(R.string.trim_logbook_dialog_title)
|
||||
d.setMessage(
|
||||
when (LocalSettingsRepository(this).loadDataRepository()) {
|
||||
LocalSettingsRepository.DATA_REPO.WEBDAV -> R.string.trim_logbook_dialog_message_dav
|
||||
else -> R.string.trim_logbook_dialog_message_local
|
||||
}
|
||||
)
|
||||
d.setPositiveButton(R.string.trim_logbook_dialog_button_ok) { dialogInterface, i ->
|
||||
logbook.trim()
|
||||
saveLogbook()
|
||||
}
|
||||
d.setNegativeButton(R.string.trim_logbook_dialog_button_cancel) { dialogInterface, i ->
|
||||
dialogInterface.dismiss()
|
||||
}
|
||||
val alertDialog = d.create()
|
||||
alertDialog.show()
|
||||
}
|
||||
|
||||
fun loadLogbook() {
|
||||
if (savingEvent)
|
||||
return
|
||||
@ -261,13 +279,33 @@ class MainActivity : AppCompatActivity() {
|
||||
|
||||
setLoading(true)
|
||||
logbook.logs.add(0, event)
|
||||
saveLogbook(event)
|
||||
|
||||
// Check logbook size to avoid OOM errors
|
||||
if (logbook.isTooBig()) {
|
||||
askToTrimLogbook()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the logbook. If saving while adding an event, please specify the event so in case
|
||||
* of error can be removed from the list.
|
||||
*/
|
||||
fun saveLogbook(lastEventAdded: LunaEvent? = null) {
|
||||
logbookRepo?.saveLogbook(this, logbook, object: LogbookSavedListener{
|
||||
override fun onLogbookSaved() {
|
||||
Log.d(TAG, "Logbook saved")
|
||||
runOnUiThread({
|
||||
setLoading(false)
|
||||
|
||||
Toast.makeText(this@MainActivity, R.string.toast_event_added, Toast.LENGTH_SHORT).show()
|
||||
Toast.makeText(
|
||||
this@MainActivity,
|
||||
if (lastEventAdded != null)
|
||||
R.string.toast_event_added
|
||||
else
|
||||
R.string.toast_logbook_saved,
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
savingEvent(false)
|
||||
})
|
||||
}
|
||||
@ -276,7 +314,8 @@ class MainActivity : AppCompatActivity() {
|
||||
runOnUiThread({
|
||||
setLoading(false)
|
||||
onRepoError(getString(R.string.settings_network_error) + error.toString())
|
||||
onAddError(event, error.toString())
|
||||
if (lastEventAdded != null)
|
||||
onAddError(lastEventAdded, error.toString())
|
||||
})
|
||||
}
|
||||
|
||||
@ -290,7 +329,8 @@ class MainActivity : AppCompatActivity() {
|
||||
getString(R.string.settings_webdav_error_generic) + error.toString()
|
||||
}
|
||||
)
|
||||
onAddError(event, error.toString())
|
||||
if (lastEventAdded != null)
|
||||
onAddError(lastEventAdded, error.toString())
|
||||
})
|
||||
}
|
||||
|
||||
@ -298,7 +338,8 @@ class MainActivity : AppCompatActivity() {
|
||||
runOnUiThread({
|
||||
setLoading(false)
|
||||
onRepoError(getString(R.string.settings_json_error) + error.toString())
|
||||
onAddError(event, error.toString())
|
||||
if (lastEventAdded != null)
|
||||
onAddError(lastEventAdded, error.toString())
|
||||
})
|
||||
}
|
||||
|
||||
@ -306,7 +347,8 @@ class MainActivity : AppCompatActivity() {
|
||||
runOnUiThread({
|
||||
setLoading(false)
|
||||
onRepoError(getString(R.string.settings_generic_error) + error.toString())
|
||||
onAddError(event, error.toString())
|
||||
if (lastEventAdded != null)
|
||||
onAddError(lastEventAdded, error.toString())
|
||||
})
|
||||
}
|
||||
})
|
||||
|
@ -2,14 +2,12 @@ package it.danieleverducci.lunatracker.adapters
|
||||
|
||||
import android.content.Context
|
||||
import android.text.format.DateFormat
|
||||
import android.text.format.DateUtils
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.TextView
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import it.danieleverducci.lunatracker.entities.LunaEvent
|
||||
import it.danieleverducci.lunatracker.entities.LunaEventType
|
||||
import it.danieleverducci.lunatracker.R
|
||||
import java.util.Date
|
||||
|
||||
@ -37,25 +35,25 @@ class LunaEventRecyclerAdapter: RecyclerView.Adapter<LunaEventRecyclerAdapter.Lu
|
||||
val item = items.get(position)
|
||||
holder.type.text = context.getString(
|
||||
when (item.type) {
|
||||
LunaEventType.BABY_BOTTLE -> R.string.event_bottle_type
|
||||
LunaEventType.WEIGHT -> R.string.event_scale_type
|
||||
LunaEventType.BREASTFEEDING_LEFT_NIPPLE -> R.string.event_breastfeeding_left_type
|
||||
LunaEventType.BREASTFEEDING_BOTH_NIPPLE -> R.string.event_breastfeeding_both_type
|
||||
LunaEventType.BREASTFEEDING_RIGHT_NIPPLE -> R.string.event_breastfeeding_right_type
|
||||
LunaEventType.DIAPERCHANGE_POO -> R.string.event_diaperchange_poo_type
|
||||
LunaEventType.DIAPERCHANGE_PEE -> R.string.event_diaperchange_pee_type
|
||||
LunaEvent.TYPE_BABY_BOTTLE -> R.string.event_bottle_type
|
||||
LunaEvent.TYPE_WEIGHT -> R.string.event_scale_type
|
||||
LunaEvent.TYPE_BREASTFEEDING_LEFT_NIPPLE -> R.string.event_breastfeeding_left_type
|
||||
LunaEvent.TYPE_BREASTFEEDING_BOTH_NIPPLE -> R.string.event_breastfeeding_both_type
|
||||
LunaEvent.TYPE_BREASTFEEDING_RIGHT_NIPPLE -> R.string.event_breastfeeding_right_type
|
||||
LunaEvent.TYPE_DIAPERCHANGE_POO -> R.string.event_diaperchange_poo_type
|
||||
LunaEvent.TYPE_DIAPERCHANGE_PEE -> R.string.event_diaperchange_pee_type
|
||||
else -> R.string.event_unknown_type
|
||||
}
|
||||
)
|
||||
holder.description.text = context.getString(
|
||||
when (item.type) {
|
||||
LunaEventType.BABY_BOTTLE -> R.string.event_bottle_desc
|
||||
LunaEventType.WEIGHT -> R.string.event_scale_desc
|
||||
LunaEventType.BREASTFEEDING_LEFT_NIPPLE -> R.string.event_breastfeeding_left_desc
|
||||
LunaEventType.BREASTFEEDING_BOTH_NIPPLE -> R.string.event_breastfeeding_both_desc
|
||||
LunaEventType.BREASTFEEDING_RIGHT_NIPPLE -> R.string.event_breastfeeding_right_desc
|
||||
LunaEventType.DIAPERCHANGE_POO -> R.string.event_diaperchange_poo_desc
|
||||
LunaEventType.DIAPERCHANGE_PEE -> R.string.event_diaperchange_pee_desc
|
||||
LunaEvent.TYPE_BABY_BOTTLE -> R.string.event_bottle_desc
|
||||
LunaEvent.TYPE_WEIGHT -> R.string.event_scale_desc
|
||||
LunaEvent.TYPE_BREASTFEEDING_LEFT_NIPPLE -> R.string.event_breastfeeding_left_desc
|
||||
LunaEvent.TYPE_BREASTFEEDING_BOTH_NIPPLE -> R.string.event_breastfeeding_both_desc
|
||||
LunaEvent.TYPE_BREASTFEEDING_RIGHT_NIPPLE -> R.string.event_breastfeeding_right_desc
|
||||
LunaEvent.TYPE_DIAPERCHANGE_POO -> R.string.event_diaperchange_poo_desc
|
||||
LunaEvent.TYPE_DIAPERCHANGE_PEE -> R.string.event_diaperchange_pee_desc
|
||||
else -> R.string.event_unknown_desc
|
||||
}
|
||||
)
|
||||
|
@ -1,5 +1,19 @@
|
||||
package it.danieleverducci.lunatracker.entities
|
||||
|
||||
class Logbook {
|
||||
companion object {
|
||||
val MAX_SAFE_LOGBOOK_SIZE = 30000
|
||||
}
|
||||
val logs = ArrayList<LunaEvent>()
|
||||
|
||||
fun isTooBig(): Boolean {
|
||||
return logs.size > MAX_SAFE_LOGBOOK_SIZE
|
||||
}
|
||||
|
||||
/**
|
||||
* Halves the logbook to avoid the file being too big
|
||||
*/
|
||||
fun trim() {
|
||||
logs.subList(MAX_SAFE_LOGBOOK_SIZE/2, logs.size).clear()
|
||||
}
|
||||
}
|
@ -3,66 +3,68 @@ package it.danieleverducci.lunatracker.entities
|
||||
import org.json.JSONObject
|
||||
import java.util.Date
|
||||
|
||||
class LunaEvent(
|
||||
val type: LunaEventType,
|
||||
val quantity: Int? = null,
|
||||
){
|
||||
var time: Long // In unix time (seconds since 1970)
|
||||
/**
|
||||
* Represents a logged event.
|
||||
* It encloses, but doesn't parse entirely, a jsonObject. This was done to
|
||||
* allow expandability and backwards compatibility (if a field is added in a
|
||||
* release, it is simply ignored by previous ones).
|
||||
*/
|
||||
class LunaEvent {
|
||||
|
||||
init {
|
||||
time = System.currentTimeMillis() / 1000
|
||||
companion object {
|
||||
val TYPE_BABY_BOTTLE = "BABY_BOTTLE"
|
||||
val TYPE_WEIGHT = "WEIGHT"
|
||||
val TYPE_BREASTFEEDING_LEFT_NIPPLE = "BREASTFEEDING_LEFT_NIPPLE"
|
||||
val TYPE_BREASTFEEDING_BOTH_NIPPLE = "BREASTFEEDING_BOTH_NIPPLE"
|
||||
val TYPE_BREASTFEEDING_RIGHT_NIPPLE = "BREASTFEEDING_RIGHT_NIPPLE"
|
||||
val TYPE_DIAPERCHANGE_POO = "DIAPERCHANGE_POO"
|
||||
val TYPE_DIAPERCHANGE_PEE = "DIAPERCHANGE_PEE"
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return "${type.toString()} qty: $quantity time: ${Date(time * 1000)}"
|
||||
private val jo: JSONObject
|
||||
|
||||
var time: Long // In unix time (seconds since 1970)
|
||||
get() = jo.getLong("time")
|
||||
set(value) {
|
||||
jo.put("time", value)
|
||||
}
|
||||
var type: String
|
||||
get(): String = jo.getString("type")
|
||||
set(value) {
|
||||
jo.put("type", value)
|
||||
}
|
||||
var quantity: Int
|
||||
get() = jo.optInt("quantity")
|
||||
set(value) {
|
||||
if (value > 0)
|
||||
jo.put("quantity", value)
|
||||
}
|
||||
|
||||
constructor(jo: JSONObject) {
|
||||
this.jo = jo
|
||||
// A minimal LunaEvent should have at least time and type
|
||||
if (!jo.has("time") || !jo.has("type"))
|
||||
throw IllegalArgumentException("JSONObject is not a LunaEvent")
|
||||
}
|
||||
|
||||
constructor(type: String) {
|
||||
this.jo = JSONObject()
|
||||
this.time = System.currentTimeMillis() / 1000
|
||||
this.type = type
|
||||
}
|
||||
|
||||
constructor(type: String, quantity: Int) {
|
||||
this.jo = JSONObject()
|
||||
this.time = System.currentTimeMillis() / 1000
|
||||
this.type = type
|
||||
this.quantity = quantity
|
||||
}
|
||||
|
||||
fun toJson(): JSONObject {
|
||||
val jo = JSONObject()
|
||||
val type = when (type) {
|
||||
LunaEventType.BABY_BOTTLE -> "BABY_BOTTLE"
|
||||
LunaEventType.WEIGHT -> "SCALE"
|
||||
LunaEventType.BREASTFEEDING_LEFT_NIPPLE -> "BREASTFEEDING_LEFT_NIPPLE"
|
||||
LunaEventType.BREASTFEEDING_BOTH_NIPPLE -> "BREASTFEEDING_BOTH_NIPPLE"
|
||||
LunaEventType.BREASTFEEDING_RIGHT_NIPPLE -> "BREASTFEEDING_RIGHT_NIPPLE"
|
||||
LunaEventType.DIAPERCHANGE_POO -> "DIAPERCHANGE_POO"
|
||||
LunaEventType.DIAPERCHANGE_PEE -> "DIAPERCHANGE_PEE"
|
||||
else -> "UNKNOWN"
|
||||
}
|
||||
jo.put("type", type)
|
||||
jo.put("quantity", quantity)
|
||||
jo.put("time", time)
|
||||
return jo
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun fromJson(j: JSONObject): LunaEvent {
|
||||
val type = when (j.getString("type")) {
|
||||
"BABY_BOTTLE" -> LunaEventType.BABY_BOTTLE
|
||||
"SCALE" -> LunaEventType.WEIGHT
|
||||
"BREASTFEEDING_LEFT_NIPPLE" -> LunaEventType.BREASTFEEDING_LEFT_NIPPLE
|
||||
"BREASTFEEDING_BOTH_NIPPLE" -> LunaEventType.BREASTFEEDING_BOTH_NIPPLE
|
||||
"BREASTFEEDING_RIGHT_NIPPLE" -> LunaEventType.BREASTFEEDING_RIGHT_NIPPLE
|
||||
"DIAPERCHANGE_POO" -> LunaEventType.DIAPERCHANGE_POO
|
||||
"DIAPERCHANGE_PEE" -> LunaEventType.DIAPERCHANGE_PEE
|
||||
else -> LunaEventType.UNKNOWN
|
||||
}
|
||||
val quantity = j.optInt("quantity")
|
||||
val time = j.getLong("time")
|
||||
val evt = LunaEvent(type, quantity)
|
||||
evt.time = time
|
||||
return evt
|
||||
}
|
||||
override fun toString(): String {
|
||||
return "${type} qty: $quantity time: ${Date(time * 1000)}"
|
||||
}
|
||||
}
|
||||
|
||||
enum class LunaEventType {
|
||||
BABY_BOTTLE,
|
||||
WEIGHT,
|
||||
BREASTFEEDING_LEFT_NIPPLE,
|
||||
BREASTFEEDING_BOTH_NIPPLE,
|
||||
BREASTFEEDING_RIGHT_NIPPLE,
|
||||
DIAPERCHANGE_POO,
|
||||
DIAPERCHANGE_PEE,
|
||||
UNKNOWN
|
||||
}
|
@ -5,6 +5,7 @@ import it.danieleverducci.lunatracker.entities.Logbook
|
||||
import android.util.Log
|
||||
import it.danieleverducci.lunatracker.entities.LunaEvent
|
||||
import org.json.JSONArray
|
||||
import org.json.JSONException
|
||||
import java.io.File
|
||||
import java.io.FileInputStream
|
||||
import java.io.FileNotFoundException
|
||||
@ -31,9 +32,13 @@ class FileLogbookRepository: LogbookRepository {
|
||||
val json = FileInputStream(file).bufferedReader().use { it.readText() }
|
||||
val ja = JSONArray(json)
|
||||
for (i in 0 until ja.length()) {
|
||||
val jo = ja.getJSONObject(i)
|
||||
val evt = LunaEvent.fromJson(jo)
|
||||
logbook.logs.add(evt)
|
||||
try {
|
||||
val evt: LunaEvent = LunaEvent(ja.getJSONObject(i))
|
||||
logbook.logs.add(evt)
|
||||
} catch (e: IllegalArgumentException) {
|
||||
// Mangled JSON?
|
||||
throw JSONException(e.toString())
|
||||
}
|
||||
}
|
||||
return logbook
|
||||
}
|
||||
|
@ -59,10 +59,15 @@ class WebDAVLogbookRepository(val webDavURL: String, val username: String, val p
|
||||
val ja = JSONArray(json)
|
||||
val logbook = Logbook()
|
||||
for (i in 0 until ja.length()) {
|
||||
val jo = ja.getJSONObject(i)
|
||||
val evt = LunaEvent.fromJson(jo)
|
||||
logbook.logs.add(evt)
|
||||
try {
|
||||
val evt: LunaEvent = LunaEvent(ja.getJSONObject(i))
|
||||
logbook.logs.add(evt)
|
||||
} catch (e: IllegalArgumentException) {
|
||||
// Mangled JSON?
|
||||
throw JSONException(e.toString())
|
||||
}
|
||||
}
|
||||
Log.d(TAG, "Loaded ${logbook.logs.size} events into logbook")
|
||||
return logbook
|
||||
}
|
||||
|
||||
|
@ -29,6 +29,7 @@
|
||||
<string name="event_unknown_desc"></string>
|
||||
|
||||
<string name="toast_event_added">Evento aggiunto</string>
|
||||
<string name="toast_logbook_saved">Diario salvato</string>
|
||||
<string name="toast_event_add_error">Impossibile aggiungere l\'evento</string>
|
||||
<string name="toast_integer_error">Valore non valido. Inserire un numero intero.</string>
|
||||
|
||||
@ -60,4 +61,11 @@
|
||||
<string name="settings_webdav_creation_ok">Connessione al server WebDAV avvenuta con successo</string>
|
||||
<string name="settings_json_error">Sul server esiste un salvataggio, ma è corrotto o illeggibile. Cancellare il file </string>
|
||||
<string name="settings_generic_error">Si è verificato un errore: </string>
|
||||
|
||||
<string name="trim_logbook_dialog_title">Il tuo diario è bello grande!</string>
|
||||
<string name="trim_logbook_dialog_message_local">Il file del tuo diario sta crescendo molto. Ti suggeriamo di cancellare gli eventi più vecchi per evitare problemi di memoria.</string>
|
||||
<string name="trim_logbook_dialog_message_dav">Il file del tuo diario sta crescendo molto. Ti suggeriamo di cancellare gli eventi più vecchi per evitare problemi di memoria. Se vuoi conservare tutto lo storico, fai un backup del file "lunatracker_logbook.json" sul tuo server WebDAV o rinominalo per mantenerlo così e cominciare un nuovo diario.</string>
|
||||
<string name="trim_logbook_dialog_button_ok">Cancella i più vecchi</string>
|
||||
<string name="trim_logbook_dialog_button_cancel">Ricordamelo dopo</string>
|
||||
|
||||
</resources>
|
@ -29,6 +29,7 @@
|
||||
<string name="event_unknown_desc"></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>
|
||||
|
||||
@ -60,4 +61,11 @@
|
||||
<string name="settings_webdav_creation_ok">Successfully connected with WebDAV server</string>
|
||||
<string name="settings_json_error">There\'s a save file on the server, but is corrupted or unreadable. Please delete it </string>
|
||||
<string name="settings_generic_error">Error: </string>
|
||||
|
||||
<string name="trim_logbook_dialog_title">Your logbook is pretty big!</string>
|
||||
<string name="trim_logbook_dialog_message_local">Your logbook file is growing a lot. We suggest trimming the oldest events to avoid crashes.</string>
|
||||
<string name="trim_logbook_dialog_message_dav">Your logbook file is growing a lot. We suggest trimming the oldest events to avoid crashes. If you want to preserve all the events, please backup the "lunatracker_logbook.json" file on the WebDAV server or rename it to start a new logbook keeping the old one.</string>
|
||||
<string name="trim_logbook_dialog_button_ok">Trim it now</string>
|
||||
<string name="trim_logbook_dialog_button_cancel">Remind me later</string>
|
||||
|
||||
</resources>
|
Loading…
Reference in New Issue
Block a user