Compare commits
10 Commits
e23ab77274
...
v0.5
Author | SHA1 | Date | |
---|---|---|---|
043a1c0283 | |||
efdb8f584a | |||
1511764497 | |||
744bfef62b | |||
34ca6c1cd6 | |||
b4f47ea6bb | |||
99743288c5 | |||
03ec28f8ef | |||
ac9f74dbd7 | |||
36f52234a3 |
@ -12,8 +12,8 @@ android {
|
|||||||
applicationId = "it.danieleverducci.lunatracker"
|
applicationId = "it.danieleverducci.lunatracker"
|
||||||
minSdk = 21
|
minSdk = 21
|
||||||
targetSdk = 34
|
targetSdk = 34
|
||||||
versionCode = 2
|
versionCode = 3
|
||||||
versionName = "0.3"
|
versionName = "0.5"
|
||||||
|
|
||||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package it.danieleverducci.lunatracker
|
package it.danieleverducci.lunatracker
|
||||||
|
|
||||||
|
import android.content.DialogInterface
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
@ -48,7 +49,7 @@ class MainActivity : AppCompatActivity() {
|
|||||||
val DEBUG_CHECK_LOGBOOK_CONSISTENCY = false
|
val DEBUG_CHECK_LOGBOOK_CONSISTENCY = false
|
||||||
}
|
}
|
||||||
|
|
||||||
lateinit var logbook: Logbook
|
var logbook: Logbook? = null
|
||||||
lateinit var adapter: LunaEventRecyclerAdapter
|
lateinit var adapter: LunaEventRecyclerAdapter
|
||||||
lateinit var progressIndicator: LinearProgressIndicator
|
lateinit var progressIndicator: LinearProgressIndicator
|
||||||
lateinit var buttonsContainer: ViewGroup
|
lateinit var buttonsContainer: ViewGroup
|
||||||
@ -56,7 +57,8 @@ class MainActivity : AppCompatActivity() {
|
|||||||
lateinit var handler: Handler
|
lateinit var handler: Handler
|
||||||
var savingEvent = false
|
var savingEvent = false
|
||||||
val updateListRunnable: Runnable = Runnable {
|
val updateListRunnable: Runnable = Runnable {
|
||||||
loadLogbook()
|
if (logbook != null)
|
||||||
|
loadLogbook(logbook!!.name)
|
||||||
handler.postDelayed(updateListRunnable, 1000*60)
|
handler.postDelayed(updateListRunnable, 1000*60)
|
||||||
}
|
}
|
||||||
var logbookRepo: LogbookRepository? = null
|
var logbookRepo: LogbookRepository? = null
|
||||||
@ -83,7 +85,7 @@ class MainActivity : AppCompatActivity() {
|
|||||||
recyclerView.adapter = adapter
|
recyclerView.adapter = adapter
|
||||||
|
|
||||||
// Set listeners
|
// Set listeners
|
||||||
findViewById<View>(R.id.logbooks_add_button).setOnClickListener { showAddLogbookDialog() }
|
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_scale).setOnClickListener { askWeightValue() }
|
||||||
findViewById<View>(R.id.button_nipple_left).setOnClickListener { logEvent(
|
findViewById<View>(R.id.button_nipple_left).setOnClickListener { logEvent(
|
||||||
@ -122,10 +124,11 @@ class MainActivity : AppCompatActivity() {
|
|||||||
showSettings()
|
showSettings()
|
||||||
})
|
})
|
||||||
findViewById<View>(R.id.button_no_connection_retry).setOnClickListener({
|
findViewById<View>(R.id.button_no_connection_retry).setOnClickListener({
|
||||||
loadLogbook()
|
// This may happen at start, when logbook is still null: better ask the logbook list
|
||||||
|
loadLogbookList()
|
||||||
})
|
})
|
||||||
findViewById<View>(R.id.button_sync).setOnClickListener({
|
findViewById<View>(R.id.button_sync).setOnClickListener({
|
||||||
loadLogbook()
|
loadLogbookList()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,8 +139,11 @@ class MainActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
fun showLogbook() {
|
fun showLogbook() {
|
||||||
// Show logbook
|
// Show logbook
|
||||||
|
if (logbook == null)
|
||||||
|
Log.w(TAG, "showLogbook(): logbook is null!")
|
||||||
|
|
||||||
adapter.items.clear()
|
adapter.items.clear()
|
||||||
adapter.items.addAll(logbook.logs)
|
adapter.items.addAll(logbook?.logs ?: listOf())
|
||||||
adapter.notifyDataSetChanged()
|
adapter.notifyDataSetChanged()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,8 +168,13 @@ class MainActivity : AppCompatActivity() {
|
|||||||
// Update list dates
|
// Update list dates
|
||||||
adapter.notifyDataSetChanged()
|
adapter.notifyDataSetChanged()
|
||||||
|
|
||||||
// Reload data
|
if (logbook != null) {
|
||||||
loadLogbookList()
|
// Already running: reload data for currently selected logbook
|
||||||
|
loadLogbook(logbook!!.name)
|
||||||
|
} else {
|
||||||
|
// First start: load logbook list
|
||||||
|
loadLogbookList()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onStop() {
|
override fun onStop() {
|
||||||
@ -283,7 +294,7 @@ class MainActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
d.setPositiveButton(R.string.trim_logbook_dialog_button_ok) { dialogInterface, i ->
|
d.setPositiveButton(R.string.trim_logbook_dialog_button_ok) { dialogInterface, i ->
|
||||||
logbook.trim()
|
logbook?.trim()
|
||||||
saveLogbook()
|
saveLogbook()
|
||||||
}
|
}
|
||||||
d.setNegativeButton(R.string.trim_logbook_dialog_button_cancel) { dialogInterface, i ->
|
d.setNegativeButton(R.string.trim_logbook_dialog_button_cancel) { dialogInterface, i ->
|
||||||
@ -307,18 +318,28 @@ class MainActivity : AppCompatActivity() {
|
|||||||
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)
|
||||||
d.setView(dialogView)
|
d.setView(dialogView)
|
||||||
d.setPositiveButton(android.R.string.ok) { dialogInterface, i -> dialogInterface.dismiss() }
|
d.setPositiveButton(android.R.string.ok) { dialogInterface, i -> dialogInterface.dismiss() }
|
||||||
|
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))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun showAddLogbookDialog() {
|
fun showAddLogbookDialog(requestedByUser: Boolean) {
|
||||||
val d = AlertDialog.Builder(this)
|
val d = AlertDialog.Builder(this)
|
||||||
d.setTitle(R.string.dialog_add_logbook_title)
|
d.setTitle(R.string.dialog_add_logbook_title)
|
||||||
val dialogView = layoutInflater.inflate(R.layout.dialog_add_logbook, null)
|
val dialogView = layoutInflater.inflate(R.layout.dialog_add_logbook, null)
|
||||||
|
dialogView.findViewById<TextView>(R.id.dialog_add_logbook_message).text = getString(
|
||||||
|
if (requestedByUser) R.string.dialog_add_logbook_message else R.string.dialog_add_logbook_message_intro
|
||||||
|
)
|
||||||
val logbookNameEditText = dialogView.findViewById<EditText>(R.id.dialog_add_logbook_logbookname)
|
val logbookNameEditText = dialogView.findViewById<EditText>(R.id.dialog_add_logbook_logbookname)
|
||||||
d.setView(dialogView)
|
d.setView(dialogView)
|
||||||
d.setPositiveButton(android.R.string.ok) { dialogInterface, i -> addLogbook(logbookNameEditText.text.toString()) }
|
d.setPositiveButton(android.R.string.ok) { dialogInterface, i -> addLogbook(logbookNameEditText.text.toString()) }
|
||||||
d.setNegativeButton(android.R.string.cancel) { dialogInterface, i -> dialogInterface.dismiss() }
|
if (requestedByUser) {
|
||||||
|
d.setCancelable(true)
|
||||||
|
d.setNegativeButton(android.R.string.cancel) { dialogInterface, i -> dialogInterface.dismiss() }
|
||||||
|
} else {
|
||||||
|
d.setCancelable(false)
|
||||||
|
}
|
||||||
val alertDialog = d.create()
|
val alertDialog = d.create()
|
||||||
alertDialog.show()
|
alertDialog.show()
|
||||||
}
|
}
|
||||||
@ -328,6 +349,11 @@ class MainActivity : AppCompatActivity() {
|
|||||||
logbookRepo?.listLogbooks(this, object: LogbookListObtainedListener {
|
logbookRepo?.listLogbooks(this, object: LogbookListObtainedListener {
|
||||||
override fun onLogbookListObtained(logbooksNames: ArrayList<String>) {
|
override fun onLogbookListObtained(logbooksNames: ArrayList<String>) {
|
||||||
runOnUiThread({
|
runOnUiThread({
|
||||||
|
if (logbooksNames.isEmpty()) {
|
||||||
|
// First run, no logbook: create one
|
||||||
|
showAddLogbookDialog(false)
|
||||||
|
return@runOnUiThread
|
||||||
|
}
|
||||||
// Show logbooks dropdown
|
// Show logbooks dropdown
|
||||||
val spinner = findViewById<Spinner>(R.id.logbooks_spinner)
|
val spinner = findViewById<Spinner>(R.id.logbooks_spinner)
|
||||||
val sAdapter = ArrayAdapter<String>(this@MainActivity, android.R.layout.simple_spinner_item)
|
val sAdapter = ArrayAdapter<String>(this@MainActivity, android.R.layout.simple_spinner_item)
|
||||||
@ -359,26 +385,87 @@ class MainActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onIOError(error: IOException) {
|
override fun onIOError(error: IOException) {
|
||||||
TODO("Not yet implemented")
|
Log.e(TAG, "Unable to load logbooks list (IOError): $error")
|
||||||
|
runOnUiThread({
|
||||||
|
setLoading(false)
|
||||||
|
onRepoError(getString(R.string.settings_network_error) + error.toString())
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onWebDAVError(error: SardineException) {
|
override fun onWebDAVError(error: SardineException) {
|
||||||
TODO("Not yet implemented")
|
Log.e(TAG, "Unable to load logbooks list (SardineException): $error")
|
||||||
|
runOnUiThread({
|
||||||
|
setLoading(false)
|
||||||
|
onRepoError(
|
||||||
|
if(error.toString().contains("401")) {
|
||||||
|
getString(R.string.settings_webdav_error_denied)
|
||||||
|
} else if(error.toString().contains("503")) {
|
||||||
|
getString(R.string.settings_webdav_error_server_offline)
|
||||||
|
} else {
|
||||||
|
getString(R.string.settings_webdav_error_generic) + error.toString()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onError(error: Exception) {
|
override fun onError(error: Exception) {
|
||||||
TODO("Not yet implemented")
|
Log.e(TAG, "Unable to load logbooks list: $error")
|
||||||
|
runOnUiThread({
|
||||||
|
setLoading(false)
|
||||||
|
onRepoError(getString(R.string.settings_generic_error) + error.toString())
|
||||||
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addLogbook(logbookName: String) {
|
fun addLogbook(logbookName: String) {
|
||||||
this.logbook = Logbook(logbookName)
|
val newLogbook = Logbook(logbookName)
|
||||||
saveLogbook()
|
setLoading(true)
|
||||||
loadLogbookList() // TODO: Does not reload logbooks buttons on top, why?
|
logbookRepo?.saveLogbook(this, newLogbook, object: LogbookSavedListener{
|
||||||
|
override fun onLogbookSaved() {
|
||||||
|
Log.d(TAG, "Logbook $logbookName created")
|
||||||
|
runOnUiThread({
|
||||||
|
setLoading(false)
|
||||||
|
loadLogbookList()
|
||||||
|
Toast.makeText(this@MainActivity, getString(R.string.logbook_created) + logbookName, Toast.LENGTH_SHORT).show()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onIOError(error: IOException) {
|
||||||
|
runOnUiThread({
|
||||||
|
onRepoError(getString(R.string.settings_network_error) + error.toString())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onWebDAVError(error: SardineException) {
|
||||||
|
runOnUiThread({
|
||||||
|
onRepoError(
|
||||||
|
if(error.toString().contains("401")) {
|
||||||
|
getString(R.string.settings_webdav_error_denied)
|
||||||
|
} else if(error.toString().contains("503")) {
|
||||||
|
getString(R.string.settings_webdav_error_server_offline)
|
||||||
|
} else {
|
||||||
|
getString(R.string.settings_webdav_error_generic) + error.toString()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onJSONError(error: JSONException) {
|
||||||
|
runOnUiThread({
|
||||||
|
onRepoError(getString(R.string.settings_json_error) + error.toString())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onError(error: Exception) {
|
||||||
|
runOnUiThread({
|
||||||
|
onRepoError(getString(R.string.settings_generic_error) + error.toString())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fun loadLogbook(name: String = LogbookRepository.DEFAULT_LOGBOOK_NAME) {
|
fun loadLogbook(name: String) {
|
||||||
if (savingEvent)
|
if (savingEvent)
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -397,7 +484,7 @@ class MainActivity : AppCompatActivity() {
|
|||||||
showLogbook()
|
showLogbook()
|
||||||
|
|
||||||
if (DEBUG_CHECK_LOGBOOK_CONSISTENCY) {
|
if (DEBUG_CHECK_LOGBOOK_CONSISTENCY) {
|
||||||
for (e in logbook.logs) {
|
for (e in logbook?.logs ?: listOf()) {
|
||||||
val em = e.getTypeEmoji(this@MainActivity)
|
val em = e.getTypeEmoji(this@MainActivity)
|
||||||
if (em == getString(R.string.event_unknown_type)) {
|
if (em == getString(R.string.event_unknown_type)) {
|
||||||
Log.e(TAG, "UNKNOWN: ${e.type}")
|
Log.e(TAG, "UNKNOWN: ${e.type}")
|
||||||
@ -420,6 +507,8 @@ class MainActivity : AppCompatActivity() {
|
|||||||
onRepoError(
|
onRepoError(
|
||||||
if(error.toString().contains("401")) {
|
if(error.toString().contains("401")) {
|
||||||
getString(R.string.settings_webdav_error_denied)
|
getString(R.string.settings_webdav_error_denied)
|
||||||
|
} else if(error.toString().contains("503")) {
|
||||||
|
getString(R.string.settings_webdav_error_server_offline)
|
||||||
} else {
|
} else {
|
||||||
getString(R.string.settings_webdav_error_generic) + error.toString()
|
getString(R.string.settings_webdav_error_generic) + error.toString()
|
||||||
}
|
}
|
||||||
@ -459,21 +548,37 @@ class MainActivity : AppCompatActivity() {
|
|||||||
recyclerView.smoothScrollToPosition(0)
|
recyclerView.smoothScrollToPosition(0)
|
||||||
|
|
||||||
setLoading(true)
|
setLoading(true)
|
||||||
logbook.logs.add(0, event)
|
logbook?.logs?.add(0, event)
|
||||||
saveLogbook(event)
|
saveLogbook(event)
|
||||||
|
|
||||||
// Check logbook size to avoid OOM errors
|
// Check logbook size to avoid OOM errors
|
||||||
if (logbook.isTooBig()) {
|
if (logbook?.isTooBig() == true) {
|
||||||
askToTrimLogbook()
|
askToTrimLogbook()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun deleteEvent(event: LunaEvent) {
|
||||||
|
// Update view
|
||||||
|
savingEvent(true)
|
||||||
|
adapter.items.remove(event)
|
||||||
|
adapter.notifyDataSetChanged()
|
||||||
|
|
||||||
|
// Update data
|
||||||
|
setLoading(true)
|
||||||
|
logbook?.logs?.remove(event)
|
||||||
|
saveLogbook()
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Saves the logbook. If saving while adding an event, please specify the event so in case
|
* Saves the logbook. If saving while adding an event, please specify the event so in case
|
||||||
* of error can be removed from the list.
|
* of error can be removed from the list.
|
||||||
*/
|
*/
|
||||||
fun saveLogbook(lastEventAdded: LunaEvent? = null) {
|
fun saveLogbook(lastEventAdded: LunaEvent? = null) {
|
||||||
logbookRepo?.saveLogbook(this, logbook, object: LogbookSavedListener{
|
if (logbook == null) {
|
||||||
|
Log.e(TAG, "Trying to save logbook, but logbook is null!")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
logbookRepo?.saveLogbook(this, logbook!!, object: LogbookSavedListener{
|
||||||
override fun onLogbookSaved() {
|
override fun onLogbookSaved() {
|
||||||
Log.d(TAG, "Logbook saved")
|
Log.d(TAG, "Logbook saved")
|
||||||
runOnUiThread({
|
runOnUiThread({
|
||||||
@ -506,6 +611,8 @@ class MainActivity : AppCompatActivity() {
|
|||||||
onRepoError(
|
onRepoError(
|
||||||
if(error.toString().contains("401")) {
|
if(error.toString().contains("401")) {
|
||||||
getString(R.string.settings_webdav_error_denied)
|
getString(R.string.settings_webdav_error_denied)
|
||||||
|
} else if(error.toString().contains("503")) {
|
||||||
|
getString(R.string.settings_webdav_error_server_offline)
|
||||||
} else {
|
} else {
|
||||||
getString(R.string.settings_webdav_error_generic) + error.toString()
|
getString(R.string.settings_webdav_error_generic) + error.toString()
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,9 @@ import android.widget.Toast
|
|||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import com.google.android.material.progressindicator.LinearProgressIndicator
|
import com.google.android.material.progressindicator.LinearProgressIndicator
|
||||||
import com.thegrizzlylabs.sardineandroid.impl.SardineException
|
import com.thegrizzlylabs.sardineandroid.impl.SardineException
|
||||||
|
import it.danieleverducci.lunatracker.repository.FileLogbookRepository
|
||||||
import it.danieleverducci.lunatracker.repository.LocalSettingsRepository
|
import it.danieleverducci.lunatracker.repository.LocalSettingsRepository
|
||||||
|
import it.danieleverducci.lunatracker.repository.LogbookListObtainedListener
|
||||||
import it.danieleverducci.lunatracker.repository.LogbookRepository
|
import it.danieleverducci.lunatracker.repository.LogbookRepository
|
||||||
import it.danieleverducci.lunatracker.repository.WebDAVLogbookRepository
|
import it.danieleverducci.lunatracker.repository.WebDAVLogbookRepository
|
||||||
import okio.IOException
|
import okio.IOException
|
||||||
@ -73,13 +75,34 @@ open class SettingsActivity : AppCompatActivity() {
|
|||||||
textViewWebDAVPass.text.toString()
|
textViewWebDAVPass.text.toString()
|
||||||
)
|
)
|
||||||
progressIndicator.visibility = View.VISIBLE
|
progressIndicator.visibility = View.VISIBLE
|
||||||
webDAVLogbookRepo.createLogbook(this, LogbookRepository.DEFAULT_LOGBOOK_NAME, object: WebDAVLogbookRepository.LogbookCreatedListener{
|
|
||||||
override fun onLogbookCreated() {
|
webDAVLogbookRepo.listLogbooks(this, object: LogbookListObtainedListener{
|
||||||
runOnUiThread({
|
|
||||||
progressIndicator.visibility = View.INVISIBLE
|
override fun onLogbookListObtained(logbooksNames: ArrayList<String>) {
|
||||||
saveSettings()
|
if (logbooksNames.isEmpty()) {
|
||||||
Toast.makeText(this@SettingsActivity, R.string.settings_webdav_creation_ok, Toast.LENGTH_SHORT).show()
|
// TODO: Ask the user if he wants to upload the local ones or to create a new one
|
||||||
})
|
copyLocalLogbooksToWebdav(webDAVLogbookRepo, object: OnCopyLocalLogbooksToWebdavFinishedListener {
|
||||||
|
|
||||||
|
override fun onCopyLocalLogbooksToWebdavFinished(errors: String?) {
|
||||||
|
runOnUiThread({
|
||||||
|
progressIndicator.visibility = View.INVISIBLE
|
||||||
|
if (errors == null) {
|
||||||
|
saveSettings()
|
||||||
|
Toast.makeText(this@SettingsActivity, R.string.settings_webdav_creation_ok, Toast.LENGTH_SHORT).show()
|
||||||
|
} else {
|
||||||
|
Toast.makeText(this@SettingsActivity, errors, Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
runOnUiThread({
|
||||||
|
progressIndicator.visibility = View.INVISIBLE
|
||||||
|
saveSettings()
|
||||||
|
Toast.makeText(this@SettingsActivity, R.string.settings_webdav_creation_ok, Toast.LENGTH_SHORT).show()
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onIOError(error: IOException) {
|
override fun onIOError(error: IOException) {
|
||||||
@ -100,6 +123,16 @@ open class SettingsActivity : AppCompatActivity() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onError(error: Exception) {
|
||||||
|
runOnUiThread({
|
||||||
|
progressIndicator.visibility = View.INVISIBLE
|
||||||
|
Toast.makeText(this@SettingsActivity, getString(R.string.settings_generic_error) + error.toString(), Toast.LENGTH_SHORT).show()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
/*webDAVLogbookRepo.createLogbook(this, LogbookRepository.DEFAULT_LOGBOOK_NAME, object: WebDAVLogbookRepository.LogbookCreatedListener{
|
||||||
|
|
||||||
override fun onJSONError(error: JSONException) {
|
override fun onJSONError(error: JSONException) {
|
||||||
runOnUiThread({
|
runOnUiThread({
|
||||||
progressIndicator.visibility = View.INVISIBLE
|
progressIndicator.visibility = View.INVISIBLE
|
||||||
@ -107,14 +140,8 @@ open class SettingsActivity : AppCompatActivity() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onError(error: Exception) {
|
|
||||||
runOnUiThread({
|
|
||||||
progressIndicator.visibility = View.INVISIBLE
|
|
||||||
Toast.makeText(this@SettingsActivity, getString(R.string.settings_generic_error) + error.toString(), Toast.LENGTH_SHORT).show()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
})
|
})*/
|
||||||
}
|
}
|
||||||
|
|
||||||
fun saveSettings() {
|
fun saveSettings() {
|
||||||
@ -130,4 +157,32 @@ open class SettingsActivity : AppCompatActivity() {
|
|||||||
finish()
|
finish()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copies the local logbooks to webdav.
|
||||||
|
* @return success
|
||||||
|
*/
|
||||||
|
private fun copyLocalLogbooksToWebdav(webDAVLogbookRepository: WebDAVLogbookRepository, listener: OnCopyLocalLogbooksToWebdavFinishedListener) {
|
||||||
|
Thread(Runnable {
|
||||||
|
var errors = StringBuilder()
|
||||||
|
val fileLogbookRepo = FileLogbookRepository()
|
||||||
|
val logbooks = fileLogbookRepo.getAllLogbooks(this)
|
||||||
|
for (logbook in logbooks) {
|
||||||
|
// Copy only if does not already exist
|
||||||
|
val error = webDAVLogbookRepository.uploadLogbookIfNotExists(this, logbook.name)
|
||||||
|
if (error != null) {
|
||||||
|
if (errors.isNotEmpty())
|
||||||
|
errors.append("\n")
|
||||||
|
errors.append(String.format(getString(R.string.settings_webdav_upload_error), logbook.name, error))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
listener.onCopyLocalLogbooksToWebdavFinished(
|
||||||
|
if (errors.isEmpty()) null else errors.toString()
|
||||||
|
)
|
||||||
|
}).start()
|
||||||
|
}
|
||||||
|
|
||||||
|
private interface OnCopyLocalLogbooksToWebdavFinishedListener {
|
||||||
|
fun onCopyLocalLogbooksToWebdavFinished(errors: String?)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -70,6 +70,18 @@ class FileLogbookRepository: LogbookRepository {
|
|||||||
context: Context,
|
context: Context,
|
||||||
listener: LogbookListObtainedListener
|
listener: LogbookListObtainedListener
|
||||||
) {
|
) {
|
||||||
|
listener.onLogbookListObtained(listLogbooks(context))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getAllLogbooks(context: Context): List<Logbook> {
|
||||||
|
val logbooks = arrayListOf<Logbook>()
|
||||||
|
for (logbookName in listLogbooks(context)) {
|
||||||
|
logbooks.add(loadLogbook(context, logbookName))
|
||||||
|
}
|
||||||
|
return logbooks
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun listLogbooks(context: Context): ArrayList<String> {
|
||||||
val logbooksFileNames = context.getFilesDir().list(object: FilenameFilter {
|
val logbooksFileNames = context.getFilesDir().list(object: FilenameFilter {
|
||||||
override fun accept(dir: File?, name: String?): Boolean {
|
override fun accept(dir: File?, name: String?): Boolean {
|
||||||
if (name == null)
|
if (name == null)
|
||||||
@ -80,8 +92,9 @@ class FileLogbookRepository: LogbookRepository {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
if (logbooksFileNames == null || logbooksFileNames.isEmpty())
|
if (logbooksFileNames == null || logbooksFileNames.isEmpty()) {
|
||||||
listener.onLogbookListObtained(arrayListOf())
|
return arrayListOf()
|
||||||
|
}
|
||||||
|
|
||||||
val logbooksNames = arrayListOf<String>()
|
val logbooksNames = arrayListOf<String>()
|
||||||
logbooksFileNames.forEach { it ->
|
logbooksFileNames.forEach { it ->
|
||||||
@ -89,7 +102,7 @@ class FileLogbookRepository: LogbookRepository {
|
|||||||
it.replace("${FILE_NAME_START}_", "").replace(FILE_NAME_START, "").replace(FILE_NAME_END, "")
|
it.replace("${FILE_NAME_START}_", "").replace(FILE_NAME_START, "").replace(FILE_NAME_END, "")
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
listener.onLogbookListObtained(logbooksNames)
|
return logbooksNames
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getFileName(name: String): String {
|
private fun getFileName(name: String): String {
|
||||||
|
@ -103,19 +103,32 @@ class WebDAVLogbookRepository(val webDavURL: String, val username: String, val p
|
|||||||
listener: LogbookListObtainedListener
|
listener: LogbookListObtainedListener
|
||||||
) {
|
) {
|
||||||
Thread(Runnable {
|
Thread(Runnable {
|
||||||
val logbooksNames = arrayListOf<String>()
|
try {
|
||||||
for (dr: DavResource in sardine.list(webDavURL)){
|
val logbooksNames = arrayListOf<String>()
|
||||||
if(!dr.name.startsWith(FILE_NAME_START))
|
for (dr: DavResource in sardine.list(webDavURL)){
|
||||||
continue
|
if(!dr.name.startsWith(FILE_NAME_START))
|
||||||
if(!dr.name.endsWith(FILE_NAME_END))
|
continue
|
||||||
continue
|
if(!dr.name.endsWith(FILE_NAME_END))
|
||||||
logbooksNames.add(
|
continue
|
||||||
dr.name.replace("${FILE_NAME_START}_", "")
|
logbooksNames.add(
|
||||||
.replace(FILE_NAME_START, "")
|
dr.name.replace("${FILE_NAME_START}_", "")
|
||||||
.replace(FILE_NAME_END, "")
|
.replace(FILE_NAME_START, "")
|
||||||
)
|
.replace(FILE_NAME_END, "")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
listener.onLogbookListObtained(logbooksNames)
|
||||||
|
} catch (e: SardineException) {
|
||||||
|
Log.e(TAG, e.toString())
|
||||||
|
listener.onWebDAVError(e)
|
||||||
|
} catch (e: IOException) {
|
||||||
|
Log.e(TAG, e.toString())
|
||||||
|
listener.onIOError(e)
|
||||||
|
} catch (e: SocketTimeoutException) {
|
||||||
|
Log.e(TAG, e.toString())
|
||||||
|
listener.onIOError(e)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
listener.onError(e)
|
||||||
}
|
}
|
||||||
listener.onLogbookListObtained(logbooksNames)
|
|
||||||
}).start()
|
}).start()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,47 +150,46 @@ class WebDAVLogbookRepository(val webDavURL: String, val username: String, val p
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Connect to server and check if a logbook already exists.
|
* Connect to server and check if a logbook already exists.
|
||||||
* If it does not exist, try to upload the local one (or create a new one).
|
* If it does not exist, try to upload the local one.
|
||||||
|
* @return error, or null if no error
|
||||||
*/
|
*/
|
||||||
fun createLogbook(context: Context, name: String, listener: LogbookCreatedListener) {
|
fun uploadLogbookIfNotExists(context: Context, name: String): String? {
|
||||||
Thread(Runnable {
|
val flr = FileLogbookRepository()
|
||||||
try {
|
try {
|
||||||
loadLogbook(name)
|
loadLogbook(name)
|
||||||
listener.onLogbookCreated()
|
Log.d(TAG, "Logbook file $name already exist on the webDav share: will not overwrite it")
|
||||||
} catch (e: SardineException) {
|
return null
|
||||||
if (e.toString().contains("404")) {
|
} catch (e: SardineException) {
|
||||||
// Connection successful, but no existing save. Upload the local one.
|
if (e.toString().contains("404")) {
|
||||||
try {
|
// Connection successful, but logbook does not exist. Upload the local one.
|
||||||
val flr = FileLogbookRepository()
|
try {
|
||||||
val logbook = flr.loadLogbook(context, name)
|
val logbook = flr.loadLogbook(context, name)
|
||||||
saveLogbook(context, logbook)
|
saveLogbook(context, logbook)
|
||||||
Log.d(TAG, "Local logbook file found, uploaded")
|
Log.d(TAG, "Local logbook file $name found, uploaded")
|
||||||
listener.onLogbookCreated()
|
return null
|
||||||
} catch (e: FileNotFoundException) {
|
} catch (e: FileNotFoundException) {
|
||||||
Log.d(TAG, "No local logbook file found, uploading empty file")
|
Log.e(TAG, "No local logbook file found, this should not happen!")
|
||||||
saveLogbook(context, Logbook(name))
|
return "No local logbook file found, app is in inconsistent state, please delete and reinstall it"
|
||||||
listener.onLogbookCreated()
|
} catch (e: SardineException) {
|
||||||
} catch (e: SardineException) {
|
Log.e(TAG, "Unable to upload logbook: $e")
|
||||||
Log.e(TAG, "Unable to upload logbook: $e")
|
return e.toString()
|
||||||
listener.onWebDAVError(e)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Log.e(TAG, e.toString())
|
|
||||||
listener.onWebDAVError(e)
|
|
||||||
}
|
}
|
||||||
} catch (e: IOException) {
|
} else {
|
||||||
Log.e(TAG, e.toString())
|
Log.e(TAG, e.toString())
|
||||||
listener.onIOError(e)
|
return e.toString()
|
||||||
} catch (e: SocketTimeoutException) {
|
|
||||||
Log.e(TAG, e.toString())
|
|
||||||
listener.onIOError(e)
|
|
||||||
} catch (e: JSONException) {
|
|
||||||
Log.e(TAG, e.toString())
|
|
||||||
listener.onJSONError(e)
|
|
||||||
} catch (e: Exception) {
|
|
||||||
listener.onError(e)
|
|
||||||
}
|
}
|
||||||
}).start()
|
} catch (e: IOException) {
|
||||||
|
Log.e(TAG, e.toString())
|
||||||
|
return e.toString()
|
||||||
|
} catch (e: SocketTimeoutException) {
|
||||||
|
Log.e(TAG, e.toString())
|
||||||
|
return e.toString()
|
||||||
|
} catch (e: JSONException) {
|
||||||
|
Log.e(TAG, e.toString())
|
||||||
|
return e.toString()
|
||||||
|
} catch (e: Exception) {
|
||||||
|
return e.toString()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getUrl(name: String): String {
|
private fun getUrl(name: String): String {
|
||||||
@ -185,13 +197,4 @@ class WebDAVLogbookRepository(val webDavURL: String, val username: String, val p
|
|||||||
Log.d(TAG, fileName)
|
Log.d(TAG, fileName)
|
||||||
return "$webDavURL/$fileName"
|
return "$webDavURL/$fileName"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
interface LogbookCreatedListener {
|
|
||||||
fun onLogbookCreated()
|
|
||||||
fun onIOError(error: okio.IOException)
|
|
||||||
fun onWebDAVError(error: SardineException)
|
|
||||||
fun onJSONError(error: JSONException)
|
|
||||||
fun onError(error: Exception)
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -6,6 +6,7 @@
|
|||||||
android:padding="20dp">
|
android:padding="20dp">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
android:id="@+id/dialog_add_logbook_message"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/dialog_add_logbook_message"/>
|
android:text="@string/dialog_add_logbook_message"/>
|
||||||
|
@ -61,11 +61,13 @@
|
|||||||
<string name="settings_storage_dav_pass">Password</string>
|
<string name="settings_storage_dav_pass">Password</string>
|
||||||
<string name="settings_network_error">Impossibile raggiungere il server: </string>
|
<string name="settings_network_error">Impossibile raggiungere il server: </string>
|
||||||
<string name="settings_webdav_error_denied">Nome utente o password WebDAV sbagliati</string>
|
<string name="settings_webdav_error_denied">Nome utente o password WebDAV sbagliati</string>
|
||||||
|
<string name="settings_webdav_error_server_offline">Il server WebDAV non è al momento disponibile</string>
|
||||||
<string name="settings_webdav_error_generic">Si è verificato un errore tentando di accedere al server WebDAV:</string>
|
<string name="settings_webdav_error_generic">Si è verificato un errore tentando di accedere al server WebDAV:</string>
|
||||||
<string name="settings_webdav_creation_error_generic">Impossibile creare un file di salvataggio sul server WebDAV:</string>
|
<string name="settings_webdav_creation_error_generic">Impossibile creare un file di salvataggio sul server WebDAV:</string>
|
||||||
<string name="settings_webdav_creation_ok">Connessione al server WebDAV avvenuta con successo</string>
|
<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_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="settings_generic_error">Si è verificato un errore: </string>
|
||||||
|
<string name="settings_webdav_upload_error">Errore durante l\'upload del logbook locale %1$s su webdav: %2$s</string>
|
||||||
|
|
||||||
<string name="trim_logbook_dialog_title">Il tuo diario è bello grande!</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_local">Il file del tuo diario sta crescendo molto. Ti suggeriamo di cancellare gli eventi più vecchi per evitare problemi di memoria.</string>
|
||||||
@ -79,11 +81,15 @@
|
|||||||
<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_delete_button">Elimina</string>
|
||||||
|
|
||||||
<string name="dialog_add_logbook_title">Aggiungi diario</string>
|
<string name="dialog_add_logbook_title">Aggiungi diario</string>
|
||||||
<string name="dialog_add_logbook_logbookname">Nome del diario</string>
|
<string name="dialog_add_logbook_logbookname">👶 Nome del diario</string>
|
||||||
<string name="dialog_add_logbook_message">Scrivi un nome per identificare questo diario. Comparirà in cima allo schermo, e se usi WebDAV sarà incluso anche nel nome del file di salvataggio.</string>
|
<string name="dialog_add_logbook_message">Scrivi un nome per identificare questo diario. Comparirà in cima allo schermo, e se usi WebDAV sarà incluso anche nel nome del file di salvataggio.\nSe vuoi un\'icona, inserisci una emoji!</string>
|
||||||
|
|
||||||
|
<string name="dialog_add_logbook_message_intro">Benvenuto! Per usare quest\'app devi creare almeno un diario. Probabilmente vuoi chiamarlo col nome di tuo figlio.</string>
|
||||||
<string name="default_logbook_name">👶 Il mio primo diario</string>
|
<string name="default_logbook_name">👶 Il mio primo diario</string>
|
||||||
|
<string name="logbook_created">Creato nuovo diario: </string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
@ -75,11 +75,13 @@
|
|||||||
<string name="settings_storage_dav_pass">Password</string>
|
<string name="settings_storage_dav_pass">Password</string>
|
||||||
<string name="settings_network_error">Unable to reach server: </string>
|
<string name="settings_network_error">Unable to reach server: </string>
|
||||||
<string name="settings_webdav_error_denied">Wrong WebDAV user or password</string>
|
<string name="settings_webdav_error_denied">Wrong WebDAV user or password</string>
|
||||||
|
<string name="settings_webdav_error_server_offline">WebDAV server is currently unavailable</string>
|
||||||
<string name="settings_webdav_error_generic">Error while trying to access WebDAV:</string>
|
<string name="settings_webdav_error_generic">Error while trying to access WebDAV:</string>
|
||||||
<string name="settings_webdav_creation_error_generic">Unable to save a file on the WebDAV server:</string>
|
<string name="settings_webdav_creation_error_generic">Unable to save a file on the WebDAV server:</string>
|
||||||
<string name="settings_webdav_creation_ok">Successfully connected with WebDAV server</string>
|
<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_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="settings_generic_error">Error: </string>
|
||||||
|
<string name="settings_webdav_upload_error">Error while uploading local logbook %1$s to webdav: %2$s</string>
|
||||||
|
|
||||||
<string name="trim_logbook_dialog_title">Your logbook is pretty big!</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_local">Your logbook file is growing a lot. We suggest trimming the oldest events to avoid crashes.</string>
|
||||||
@ -102,11 +104,15 @@
|
|||||||
<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_delete_button">Delete</string>
|
||||||
|
|
||||||
<string name="dialog_add_logbook_title">Add logbook</string>
|
<string name="dialog_add_logbook_title">Add logbook</string>
|
||||||
<string name="dialog_add_logbook_logbookname">Logbook name</string>
|
<string name="dialog_add_logbook_logbookname">👶 Logbook name</string>
|
||||||
<string name="dialog_add_logbook_message">Write a name to identify this logbook. This name will appear on top of the screen and, if you use WebDAV, will be in the save file name as well.</string>
|
<string name="dialog_add_logbook_message">Write a name to identify this logbook. This name will appear on top of the screen and, if you use WebDAV, will be in the save file name as well.</string>
|
||||||
|
<string name="dialog_add_logbook_message_intro">Welcome! To use this app you need to create at least one logbook. You would probably want to call it with your child\'s name.</string>
|
||||||
|
|
||||||
<string name="default_logbook_name">👶 My first logbook</string>
|
<string name="default_logbook_name">👶 My first logbook</string>
|
||||||
|
<string name="logbook_created">New logbook created: </string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
3
fastlane/metadata/android/en-US/changelogs/3.txt
Normal file
3
fastlane/metadata/android/en-US/changelogs/3.txt
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
Multiple children support
|
||||||
|
Fixed interface in devices with big font size
|
||||||
|
|
Reference in New Issue
Block a user