Compare commits
5 Commits
9fddd37fe9
...
v0.6
Author | SHA1 | Date | |
---|---|---|---|
05c34178a4 | |||
0d3be20e1e | |||
4c5c7bcf1a | |||
07393faf41 | |||
043a1c0283 |
@ -12,8 +12,8 @@ android {
|
||||
applicationId = "it.danieleverducci.lunatracker"
|
||||
minSdk = 21
|
||||
targetSdk = 34
|
||||
versionCode = 2
|
||||
versionName = "0.3"
|
||||
versionCode = 4
|
||||
versionName = "0.6"
|
||||
|
||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
|
@ -21,7 +21,6 @@ import android.widget.Toast
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.view.children
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.google.android.material.progressindicator.LinearProgressIndicator
|
||||
@ -53,14 +52,14 @@ class MainActivity : AppCompatActivity() {
|
||||
}
|
||||
|
||||
var logbook: Logbook? = null
|
||||
lateinit var adapter: LunaEventRecyclerAdapter
|
||||
var pauseLogbookUpdate = false
|
||||
lateinit var progressIndicator: LinearProgressIndicator
|
||||
lateinit var buttonsContainer: ViewGroup
|
||||
lateinit var recyclerView: RecyclerView
|
||||
lateinit var handler: Handler
|
||||
var savingEvent = false
|
||||
val updateListRunnable: Runnable = Runnable {
|
||||
if (logbook != null)
|
||||
if (logbook != null && !pauseLogbookUpdate)
|
||||
loadLogbook(logbook!!.name)
|
||||
handler.postDelayed(updateListRunnable, 1000*60)
|
||||
}
|
||||
@ -71,12 +70,6 @@ class MainActivity : AppCompatActivity() {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
handler = Handler(mainLooper)
|
||||
adapter = LunaEventRecyclerAdapter(this)
|
||||
adapter.onItemClickListener = object: LunaEventRecyclerAdapter.OnItemClickListener{
|
||||
override fun onItemClick(event: LunaEvent) {
|
||||
showEventDetailDialog(event)
|
||||
}
|
||||
}
|
||||
|
||||
// Show view
|
||||
setContentView(R.layout.activity_main)
|
||||
@ -85,12 +78,11 @@ class MainActivity : AppCompatActivity() {
|
||||
buttonsContainer = findViewById<ViewGroup>(R.id.buttons_container)
|
||||
recyclerView = findViewById<RecyclerView>(R.id.list_events)
|
||||
recyclerView.setLayoutManager(LinearLayoutManager(applicationContext))
|
||||
recyclerView.adapter = adapter
|
||||
|
||||
// Set listeners
|
||||
findViewById<View>(R.id.logbooks_add_button).setOnClickListener { showAddLogbookDialog(true) }
|
||||
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(
|
||||
LunaEvent(
|
||||
LunaEvent.TYPE_BREASTFEEDING_LEFT_NIPPLE
|
||||
@ -135,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() {
|
||||
val i = Intent(this, SettingsActivity::class.java)
|
||||
startActivity(i)
|
||||
@ -145,9 +147,7 @@ class MainActivity : AppCompatActivity() {
|
||||
if (logbook == null)
|
||||
Log.w(TAG, "showLogbook(): logbook is null!")
|
||||
|
||||
adapter.items.clear()
|
||||
adapter.items.addAll(logbook?.logs ?: listOf())
|
||||
adapter.notifyDataSetChanged()
|
||||
setListAdapter(logbook?.logs ?: arrayListOf())
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
@ -169,7 +169,7 @@ class MainActivity : AppCompatActivity() {
|
||||
}
|
||||
|
||||
// Update list dates
|
||||
adapter.notifyDataSetChanged()
|
||||
recyclerView.adapter?.notifyDataSetChanged()
|
||||
|
||||
if (logbook != null) {
|
||||
// Already running: reload data for currently selected logbook
|
||||
@ -257,12 +257,7 @@ class MainActivity : AppCompatActivity() {
|
||||
val d = AlertDialog.Builder(this)
|
||||
val dialogView = layoutInflater.inflate(R.layout.dialog_notes, null)
|
||||
d.setTitle(lunaEvent.getTypeDescription(this))
|
||||
d.setMessage(
|
||||
when (lunaEvent.type){
|
||||
LunaEvent.TYPE_MEDICINE -> R.string.log_medicine_dialog_description
|
||||
else -> R.string.log_notes_dialog_description
|
||||
}
|
||||
)
|
||||
d.setMessage(lunaEvent.getDialogMessage(this))
|
||||
d.setView(dialogView)
|
||||
val notesET = dialogView.findViewById<EditText>(R.id.notes_edittext)
|
||||
val qtyET = dialogView.findViewById<EditText>(R.id.notes_qty_edittext)
|
||||
@ -308,6 +303,8 @@ class MainActivity : AppCompatActivity() {
|
||||
}
|
||||
|
||||
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 d = AlertDialog.Builder(this)
|
||||
d.setTitle(R.string.dialog_event_detail_title)
|
||||
@ -336,22 +333,27 @@ class MainActivity : AppCompatActivity() {
|
||||
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.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.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) }
|
||||
val alertDialog = d.create()
|
||||
alertDialog.show()
|
||||
alertDialog.getButton(DialogInterface.BUTTON_NEUTRAL).setTextColor(ContextCompat.getColor(this, R.color.danger))
|
||||
alertDialog.setOnDismissListener({
|
||||
// Resume logbook update
|
||||
pauseLogbookUpdate = false
|
||||
})
|
||||
}
|
||||
|
||||
fun showAddLogbookDialog(requestedByUser: Boolean) {
|
||||
@ -402,8 +404,7 @@ class MainActivity : AppCompatActivity() {
|
||||
id: Long
|
||||
) {
|
||||
// Changed logbook: empty list
|
||||
adapter.items.clear()
|
||||
adapter.notifyDataSetChanged()
|
||||
setListAdapter(arrayListOf())
|
||||
// Load logbook
|
||||
loadLogbook(logbooksNames.get(position))
|
||||
}
|
||||
@ -573,12 +574,11 @@ class MainActivity : AppCompatActivity() {
|
||||
|
||||
fun logEvent(event: LunaEvent) {
|
||||
savingEvent(true)
|
||||
adapter.items.add(0, event)
|
||||
adapter.notifyItemInserted(0)
|
||||
recyclerView.smoothScrollToPosition(0)
|
||||
|
||||
setLoading(true)
|
||||
logbook?.logs?.add(0, event)
|
||||
recyclerView.adapter?.notifyItemInserted(0)
|
||||
recyclerView.smoothScrollToPosition(0)
|
||||
saveLogbook(event)
|
||||
|
||||
// Check logbook size to avoid OOM errors
|
||||
@ -590,12 +590,11 @@ class MainActivity : AppCompatActivity() {
|
||||
fun deleteEvent(event: LunaEvent) {
|
||||
// Update view
|
||||
savingEvent(true)
|
||||
adapter.items.remove(event)
|
||||
adapter.notifyDataSetChanged()
|
||||
|
||||
// Update data
|
||||
setLoading(true)
|
||||
logbook?.logs?.remove(event)
|
||||
recyclerView.adapter?.notifyDataSetChanged()
|
||||
saveLogbook()
|
||||
}
|
||||
|
||||
@ -678,8 +677,7 @@ class MainActivity : AppCompatActivity() {
|
||||
setLoading(false)
|
||||
|
||||
Toast.makeText(this@MainActivity, R.string.toast_event_add_error, Toast.LENGTH_SHORT).show()
|
||||
adapter.items.remove(event)
|
||||
adapter.notifyDataSetChanged()
|
||||
recyclerView.adapter?.notifyDataSetChanged()
|
||||
savingEvent(false)
|
||||
})
|
||||
}
|
||||
@ -732,6 +730,10 @@ class MainActivity : AppCompatActivity() {
|
||||
)
|
||||
dismiss()
|
||||
})
|
||||
contentView.findViewById<View>(R.id.button_scale).setOnClickListener({
|
||||
askWeightValue()
|
||||
dismiss()
|
||||
})
|
||||
}.also { popupWindow ->
|
||||
popupWindow.setOnDismissListener({
|
||||
Handler(mainLooper).postDelayed({
|
||||
|
@ -14,13 +14,14 @@ import utils.NumericUtils
|
||||
|
||||
class LunaEventRecyclerAdapter: RecyclerView.Adapter<LunaEventRecyclerAdapter.LunaEventVH> {
|
||||
private val context: Context
|
||||
val items = ArrayList<LunaEvent>()
|
||||
private val items: ArrayList<LunaEvent>
|
||||
val numericUtils: NumericUtils
|
||||
var onItemClickListener: OnItemClickListener? = null
|
||||
val layoutRes: Int
|
||||
|
||||
constructor(context: Context) {
|
||||
constructor(context: Context, items: ArrayList<LunaEvent>) {
|
||||
this.context = context
|
||||
this.items = items
|
||||
this.numericUtils = NumericUtils(context)
|
||||
|
||||
val fontScale = context.resources.configuration.fontScale
|
||||
|
@ -16,4 +16,8 @@ class Logbook(val name: String) {
|
||||
fun trim() {
|
||||
logs.subList(MAX_SAFE_LOGBOOK_SIZE/2, logs.size).clear()
|
||||
}
|
||||
|
||||
fun sort() {
|
||||
logs.sortDescending()
|
||||
}
|
||||
}
|
@ -11,7 +11,7 @@ import java.util.Date
|
||||
* allow expandability and backwards compatibility (if a field is added in a
|
||||
* release, it is simply ignored by previous ones).
|
||||
*/
|
||||
class LunaEvent {
|
||||
class LunaEvent: Comparable<LunaEvent> {
|
||||
|
||||
companion object {
|
||||
val TYPE_BABY_BOTTLE = "BABY_BOTTLE"
|
||||
@ -27,6 +27,7 @@ class LunaEvent {
|
||||
val TYPE_CUSTOM = "CUSTOM"
|
||||
val TYPE_COLIC = "COLIC"
|
||||
val TYPE_TEMPERATURE = "TEMPERATURE"
|
||||
val TYPE_FOOD = "FOOD"
|
||||
}
|
||||
|
||||
private val jo: JSONObject
|
||||
@ -88,6 +89,7 @@ class LunaEvent {
|
||||
TYPE_NOTE -> R.string.event_note_type
|
||||
TYPE_TEMPERATURE -> R.string.event_temperature_type
|
||||
TYPE_COLIC -> R.string.event_colic_type
|
||||
TYPE_FOOD -> R.string.event_food_type
|
||||
else -> R.string.event_unknown_type
|
||||
}
|
||||
)
|
||||
@ -108,11 +110,19 @@ class LunaEvent {
|
||||
TYPE_NOTE -> R.string.event_note_desc
|
||||
TYPE_TEMPERATURE -> R.string.event_temperature_desc
|
||||
TYPE_COLIC -> R.string.event_colic_desc
|
||||
TYPE_FOOD -> R.string.event_food_desc
|
||||
else -> R.string.event_unknown_desc
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
fun getDialogMessage(context: Context): String? {
|
||||
return when(type) {
|
||||
TYPE_MEDICINE -> context.getString(R.string.log_medicine_dialog_description)
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
fun toJson(): JSONObject {
|
||||
return jo
|
||||
}
|
||||
@ -120,4 +130,8 @@ class LunaEvent {
|
||||
override fun toString(): String {
|
||||
return "${type} qty: $quantity time: ${Date(time * 1000)}"
|
||||
}
|
||||
|
||||
override fun compareTo(other: LunaEvent): Int {
|
||||
return (this.time - other.time).toInt()
|
||||
}
|
||||
}
|
@ -108,7 +108,7 @@
|
||||
android:text="@string/event_bottle_type"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/button_scale"
|
||||
android:id="@+id/button_food"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
@ -116,7 +116,7 @@
|
||||
android:background="@drawable/button_background"
|
||||
android:gravity="center_horizontal"
|
||||
android:textSize="50dp"
|
||||
android:text="@string/event_scale_type"/>
|
||||
android:text="@string/event_food_type"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
@ -59,6 +59,16 @@
|
||||
style="@style/OverflowMenuText"
|
||||
android:text="@string/overflow_event_colic"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/button_scale"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="10dp"
|
||||
android:padding="20dp"
|
||||
android:background="@drawable/dropdown_list_item_background"
|
||||
style="@style/OverflowMenuText"
|
||||
android:text="@string/overflow_event_scale"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</ScrollView>
|
@ -13,6 +13,7 @@
|
||||
<string name="log_temperature_dialog_title">Temperatura</string>
|
||||
<string name="log_temperature_dialog_description">Inserisci la temperatura</string>
|
||||
|
||||
<string name="overflow_event_scale">⚖️ Peso</string>
|
||||
<string name="overflow_event_medicine">💊 Medicina</string>
|
||||
<string name="overflow_event_enema">🪠 Clistere</string>
|
||||
<string name="overflow_event_note">📝 Nota</string>
|
||||
@ -20,6 +21,7 @@
|
||||
<string name="overflow_event_colic">💨 Colichette</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_breastfeeding_left_desc">Allatt. al seno (sx)</string>
|
||||
<string name="event_breastfeeding_both_desc">Allatt. al seno</string>
|
||||
@ -81,8 +83,7 @@
|
||||
<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_close_button">OK</string>
|
||||
<string name="dialog_event_detail_delete_button">Elimina</string>
|
||||
|
||||
<string name="dialog_add_logbook_title">Aggiungi diario</string>
|
||||
|
@ -14,6 +14,7 @@
|
||||
<string name="log_temperature_dialog_description">Insert the temperature</string>
|
||||
|
||||
<string name="event_bottle_type" translatable="false">🍼</string>
|
||||
<string name="event_food_type" translatable="false">🥣</string>
|
||||
<string name="event_scale_type" translatable="false">⚖️</string>
|
||||
<string name="event_breastfeeding_left_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_bottle_desc">Baby bottle</string>
|
||||
<string name="event_food_desc">Food</string>
|
||||
<string name="event_scale_desc">Weight</string>
|
||||
<string name="event_breastfeeding_left_desc">Breastfeeding (left)</string>
|
||||
<string name="event_breastfeeding_both_desc">Breastfeeding</string>
|
||||
@ -41,6 +43,7 @@
|
||||
<string name="event_colic_desc">Gaseous colic</string>
|
||||
<string name="event_unknown_desc"></string>
|
||||
|
||||
<string name="overflow_event_scale">⚖️ Weight</string>
|
||||
<string name="overflow_event_medicine">💊 Medicine</string>
|
||||
<string name="overflow_event_enema">🪠 Enema</string>
|
||||
<string name="overflow_event_note">📝 Note</string>
|
||||
@ -105,8 +108,7 @@
|
||||
|
||||
<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_close_button">OK</string>
|
||||
<string name="dialog_event_detail_delete_button">Delete</string>
|
||||
|
||||
<string name="dialog_add_logbook_title">Add logbook</string>
|
||||
|
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