Compare commits
6 Commits
multiple-c
...
9fddd37fe9
Author | SHA1 | Date | |
---|---|---|---|
9fddd37fe9 | |||
efdb8f584a | |||
1511764497 | |||
744bfef62b | |||
34ca6c1cd6 | |||
b4f47ea6bb |
@ -1,5 +1,8 @@
|
||||
package it.danieleverducci.lunatracker
|
||||
|
||||
import android.app.DatePickerDialog
|
||||
import android.app.TimePickerDialog
|
||||
import android.content.DialogInterface
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.os.Handler
|
||||
@ -39,6 +42,7 @@ import okio.IOException
|
||||
import org.json.JSONException
|
||||
import utils.NumericUtils
|
||||
import java.text.DateFormat
|
||||
import java.util.Calendar
|
||||
import java.util.Date
|
||||
|
||||
class MainActivity : AppCompatActivity() {
|
||||
@ -48,7 +52,7 @@ class MainActivity : AppCompatActivity() {
|
||||
val DEBUG_CHECK_LOGBOOK_CONSISTENCY = false
|
||||
}
|
||||
|
||||
lateinit var logbook: Logbook
|
||||
var logbook: Logbook? = null
|
||||
lateinit var adapter: LunaEventRecyclerAdapter
|
||||
lateinit var progressIndicator: LinearProgressIndicator
|
||||
lateinit var buttonsContainer: ViewGroup
|
||||
@ -56,7 +60,8 @@ class MainActivity : AppCompatActivity() {
|
||||
lateinit var handler: Handler
|
||||
var savingEvent = false
|
||||
val updateListRunnable: Runnable = Runnable {
|
||||
loadLogbook(logbook.name)
|
||||
if (logbook != null)
|
||||
loadLogbook(logbook!!.name)
|
||||
handler.postDelayed(updateListRunnable, 1000*60)
|
||||
}
|
||||
var logbookRepo: LogbookRepository? = null
|
||||
@ -122,10 +127,11 @@ class MainActivity : AppCompatActivity() {
|
||||
showSettings()
|
||||
})
|
||||
findViewById<View>(R.id.button_no_connection_retry).setOnClickListener({
|
||||
loadLogbook(logbook.name)
|
||||
// This may happen at start, when logbook is still null: better ask the logbook list
|
||||
loadLogbookList()
|
||||
})
|
||||
findViewById<View>(R.id.button_sync).setOnClickListener({
|
||||
loadLogbook(logbook.name)
|
||||
loadLogbookList()
|
||||
})
|
||||
}
|
||||
|
||||
@ -136,8 +142,11 @@ class MainActivity : AppCompatActivity() {
|
||||
|
||||
fun showLogbook() {
|
||||
// Show logbook
|
||||
if (logbook == null)
|
||||
Log.w(TAG, "showLogbook(): logbook is null!")
|
||||
|
||||
adapter.items.clear()
|
||||
adapter.items.addAll(logbook.logs)
|
||||
adapter.items.addAll(logbook?.logs ?: listOf())
|
||||
adapter.notifyDataSetChanged()
|
||||
}
|
||||
|
||||
@ -162,8 +171,13 @@ class MainActivity : AppCompatActivity() {
|
||||
// Update list dates
|
||||
adapter.notifyDataSetChanged()
|
||||
|
||||
// Reload data
|
||||
loadLogbookList()
|
||||
if (logbook != null) {
|
||||
// Already running: reload data for currently selected logbook
|
||||
loadLogbook(logbook!!.name)
|
||||
} else {
|
||||
// First start: load logbook list
|
||||
loadLogbookList()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
@ -283,7 +297,7 @@ class MainActivity : AppCompatActivity() {
|
||||
}
|
||||
)
|
||||
d.setPositiveButton(R.string.trim_logbook_dialog_button_ok) { dialogInterface, i ->
|
||||
logbook.trim()
|
||||
logbook?.trim()
|
||||
saveLogbook()
|
||||
}
|
||||
d.setNegativeButton(R.string.trim_logbook_dialog_button_cancel) { dialogInterface, i ->
|
||||
@ -300,15 +314,44 @@ class MainActivity : AppCompatActivity() {
|
||||
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_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(
|
||||
NumericUtils(this).formatEventQuantity(event)
|
||||
)
|
||||
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
|
||||
}, startHour, startMinute, false).show()
|
||||
}, startYear, startMonth, startDay).show()
|
||||
})
|
||||
|
||||
d.setView(dialogView)
|
||||
d.setPositiveButton(android.R.string.ok) { dialogInterface, i -> dialogInterface.dismiss() }
|
||||
d.setPositiveButton(R.string.dialog_event_detail_save_button) { dialogInterface, i -> {
|
||||
// Save event
|
||||
event.time = currentDateTime.time.time / 1000 // Seconds since epoch
|
||||
// TODO: move event at the correct logbook position
|
||||
saveLogbook()
|
||||
} }
|
||||
d.setNegativeButton(R.string.dialog_event_detail_cancel_button) { dialogInterface, i -> dialogInterface.dismiss() }
|
||||
d.setNeutralButton(R.string.dialog_event_detail_delete_button) { dialogInterface, i -> deleteEvent(event) }
|
||||
val alertDialog = d.create()
|
||||
alertDialog.show()
|
||||
alertDialog.getButton(DialogInterface.BUTTON_NEUTRAL).setTextColor(ContextCompat.getColor(this, R.color.danger))
|
||||
}
|
||||
|
||||
fun showAddLogbookDialog(requestedByUser: Boolean) {
|
||||
@ -372,15 +415,35 @@ class MainActivity : AppCompatActivity() {
|
||||
}
|
||||
|
||||
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) {
|
||||
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) {
|
||||
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())
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -409,6 +472,8 @@ class MainActivity : AppCompatActivity() {
|
||||
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()
|
||||
}
|
||||
@ -449,7 +514,7 @@ class MainActivity : AppCompatActivity() {
|
||||
showLogbook()
|
||||
|
||||
if (DEBUG_CHECK_LOGBOOK_CONSISTENCY) {
|
||||
for (e in logbook.logs) {
|
||||
for (e in logbook?.logs ?: listOf()) {
|
||||
val em = e.getTypeEmoji(this@MainActivity)
|
||||
if (em == getString(R.string.event_unknown_type)) {
|
||||
Log.e(TAG, "UNKNOWN: ${e.type}")
|
||||
@ -472,6 +537,8 @@ class MainActivity : AppCompatActivity() {
|
||||
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()
|
||||
}
|
||||
@ -511,21 +578,37 @@ class MainActivity : AppCompatActivity() {
|
||||
recyclerView.smoothScrollToPosition(0)
|
||||
|
||||
setLoading(true)
|
||||
logbook.logs.add(0, event)
|
||||
logbook?.logs?.add(0, event)
|
||||
saveLogbook(event)
|
||||
|
||||
// Check logbook size to avoid OOM errors
|
||||
if (logbook.isTooBig()) {
|
||||
if (logbook?.isTooBig() == true) {
|
||||
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
|
||||
* of error can be removed from the list.
|
||||
*/
|
||||
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() {
|
||||
Log.d(TAG, "Logbook saved")
|
||||
runOnUiThread({
|
||||
@ -558,6 +641,8 @@ class MainActivity : AppCompatActivity() {
|
||||
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()
|
||||
}
|
||||
|
@ -103,19 +103,32 @@ class WebDAVLogbookRepository(val webDavURL: String, val username: String, val p
|
||||
listener: LogbookListObtainedListener
|
||||
) {
|
||||
Thread(Runnable {
|
||||
val logbooksNames = arrayListOf<String>()
|
||||
for (dr: DavResource in sardine.list(webDavURL)){
|
||||
if(!dr.name.startsWith(FILE_NAME_START))
|
||||
continue
|
||||
if(!dr.name.endsWith(FILE_NAME_END))
|
||||
continue
|
||||
logbooksNames.add(
|
||||
dr.name.replace("${FILE_NAME_START}_", "")
|
||||
.replace(FILE_NAME_START, "")
|
||||
.replace(FILE_NAME_END, "")
|
||||
)
|
||||
try {
|
||||
val logbooksNames = arrayListOf<String>()
|
||||
for (dr: DavResource in sardine.list(webDavURL)){
|
||||
if(!dr.name.startsWith(FILE_NAME_START))
|
||||
continue
|
||||
if(!dr.name.endsWith(FILE_NAME_END))
|
||||
continue
|
||||
logbooksNames.add(
|
||||
dr.name.replace("${FILE_NAME_START}_", "")
|
||||
.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()
|
||||
}
|
||||
|
||||
|
5
app/src/main/res/drawable/ic_edit.xml
Normal file
5
app/src/main/res/drawable/ic_edit.xml
Normal 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>
|
@ -25,19 +25,23 @@
|
||||
|
||||
<TextView
|
||||
android:id="@+id/dialog_event_detail_type_date"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="40dp"
|
||||
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:text="2020"/>
|
||||
android:text="@string/dialog_event_detail_datetime_icon"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/dialog_event_detail_type_quantity"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_horizontal"
|
||||
android:text="2020"/>
|
||||
android:text="Quantity"/>
|
||||
|
||||
<ScrollView
|
||||
android:layout_width="match_parent"
|
||||
@ -49,7 +53,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textStyle="italic"
|
||||
android:text="Lorem ipsum"/>
|
||||
android:text="Notes"/>
|
||||
|
||||
</ScrollView>
|
||||
</LinearLayout>
|
@ -61,6 +61,7 @@
|
||||
<string name="settings_storage_dav_pass">Password</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_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_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>
|
||||
@ -80,11 +81,15 @@
|
||||
<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_save_button">Salva</string>
|
||||
<string name="dialog_event_detail_cancel_button">Annulla</string>
|
||||
<string name="dialog_event_detail_delete_button">Elimina</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_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="logbook_created">Creato nuovo diario: </string>
|
||||
|
||||
|
@ -75,6 +75,7 @@
|
||||
<string name="settings_storage_dav_pass">Password</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_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_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>
|
||||
@ -103,6 +104,10 @@
|
||||
<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_datetime_icon" translatable="false">🕒 %s1</string>
|
||||
<string name="dialog_event_detail_save_button">Save</string>
|
||||
<string name="dialog_event_detail_cancel_button">Cancel</string>
|
||||
<string name="dialog_event_detail_delete_button">Delete</string>
|
||||
|
||||
<string name="dialog_add_logbook_title">Add logbook</string>
|
||||
<string name="dialog_add_logbook_logbookname">👶 Logbook name</string>
|
||||
|
Reference in New Issue
Block a user