forked from penguin86/luna-tracker
		
	Weight button, auto list update, better time formatting
This commit is contained in:
		@@ -4,6 +4,7 @@ import android.os.Bundle
 | 
			
		||||
import android.os.Handler
 | 
			
		||||
import android.view.View
 | 
			
		||||
import android.widget.NumberPicker
 | 
			
		||||
import android.widget.TextView
 | 
			
		||||
import android.widget.Toast
 | 
			
		||||
import androidx.appcompat.app.AlertDialog
 | 
			
		||||
import androidx.appcompat.app.AppCompatActivity
 | 
			
		||||
@@ -23,9 +24,15 @@ class MainActivity : AppCompatActivity() {
 | 
			
		||||
    lateinit var logbook: Logbook
 | 
			
		||||
    lateinit var adapter: LunaEventRecyclerAdapter
 | 
			
		||||
    lateinit var recyclerView: RecyclerView
 | 
			
		||||
    lateinit var handler: Handler
 | 
			
		||||
    val updateListRunnable: Runnable = Runnable {
 | 
			
		||||
        adapter.notifyDataSetChanged()
 | 
			
		||||
        handler.postDelayed(updateListRunnable, 1000*30)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun onCreate(savedInstanceState: Bundle?) {
 | 
			
		||||
        super.onCreate(savedInstanceState)
 | 
			
		||||
        handler = Handler(mainLooper)
 | 
			
		||||
 | 
			
		||||
        // Load data
 | 
			
		||||
        logbook = Logbook.load(this)
 | 
			
		||||
@@ -42,6 +49,7 @@ class MainActivity : AppCompatActivity() {
 | 
			
		||||
 | 
			
		||||
        // Set listeners
 | 
			
		||||
        findViewById<View>(R.id.button_bottle).setOnClickListener { askBabyBottleContent() }
 | 
			
		||||
        findViewById<View>(R.id.button_scale).setOnClickListener { askWeightValue() }
 | 
			
		||||
        findViewById<View>(R.id.button_nipple_left).setOnClickListener { logEvent(
 | 
			
		||||
            LunaEvent(
 | 
			
		||||
                LunaEventType.BREASTFEEDING_LEFT_NIPPLE
 | 
			
		||||
@@ -74,6 +82,13 @@ class MainActivity : AppCompatActivity() {
 | 
			
		||||
 | 
			
		||||
        // Update list dates
 | 
			
		||||
        adapter.notifyDataSetChanged()
 | 
			
		||||
        handler.postDelayed(updateListRunnable, 1000*30)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun onStop() {
 | 
			
		||||
        handler.removeCallbacks(updateListRunnable)
 | 
			
		||||
 | 
			
		||||
        super.onStop()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun askBabyBottleContent() {
 | 
			
		||||
@@ -96,6 +111,26 @@ class MainActivity : AppCompatActivity() {
 | 
			
		||||
        alertDialog.show()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun askWeightValue() {
 | 
			
		||||
        // Show number picker dialog
 | 
			
		||||
        val d = AlertDialog.Builder(this)
 | 
			
		||||
        val dialogView = layoutInflater.inflate(R.layout.number_edit_dialog, null)
 | 
			
		||||
        d.setTitle(R.string.log_weight_dialog_title)
 | 
			
		||||
        d.setMessage(R.string.log_weight_dialog_description)
 | 
			
		||||
        d.setView(dialogView)
 | 
			
		||||
        val weightET = dialogView.findViewById<TextView>(R.id.dialog_number_edittext)
 | 
			
		||||
        d.setPositiveButton(android.R.string.ok) { dialogInterface, i ->
 | 
			
		||||
            val weight = weightET.text.toString().toIntOrNull()
 | 
			
		||||
            if (weight != null)
 | 
			
		||||
                logEvent(LunaEvent(LunaEventType.WEIGHT, weight))
 | 
			
		||||
            else
 | 
			
		||||
                Toast.makeText(this, R.string.toast_integer_error, Toast.LENGTH_SHORT).show()
 | 
			
		||||
        }
 | 
			
		||||
        d.setNegativeButton(android.R.string.cancel) { dialogInterface, i -> dialogInterface.dismiss() }
 | 
			
		||||
        val alertDialog = d.create()
 | 
			
		||||
        alertDialog.show()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun logEvent(event: LunaEvent) {
 | 
			
		||||
        adapter.items.add(0, event)
 | 
			
		||||
        adapter.notifyItemInserted(0)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,7 @@
 | 
			
		||||
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
 | 
			
		||||
@@ -10,7 +11,6 @@ import androidx.recyclerview.widget.RecyclerView
 | 
			
		||||
import it.danieleverducci.lunatracker.entities.LunaEvent
 | 
			
		||||
import it.danieleverducci.lunatracker.entities.LunaEventType
 | 
			
		||||
import it.danieleverducci.lunatracker.R
 | 
			
		||||
import java.text.DateFormat
 | 
			
		||||
import java.util.Date
 | 
			
		||||
 | 
			
		||||
class LunaEventRecyclerAdapter: RecyclerView.Adapter<LunaEventRecyclerAdapter.LunaEventVH> {
 | 
			
		||||
@@ -38,6 +38,7 @@ class LunaEventRecyclerAdapter: RecyclerView.Adapter<LunaEventRecyclerAdapter.Lu
 | 
			
		||||
        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
 | 
			
		||||
@@ -49,6 +50,7 @@ class LunaEventRecyclerAdapter: RecyclerView.Adapter<LunaEventRecyclerAdapter.Lu
 | 
			
		||||
        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
 | 
			
		||||
@@ -58,18 +60,50 @@ class LunaEventRecyclerAdapter: RecyclerView.Adapter<LunaEventRecyclerAdapter.Lu
 | 
			
		||||
            }
 | 
			
		||||
        )
 | 
			
		||||
        holder.quantity.text = if ((item.quantity ?: 0) > 0) item.quantity.toString() else ""
 | 
			
		||||
        // holder.time.text = DateUtils.getRelativeTimeSpanString(item.time * 1000)
 | 
			
		||||
        holder.time.text = DateUtils.getRelativeTimeSpanString(
 | 
			
		||||
            item.time * 1000,
 | 
			
		||||
            System.currentTimeMillis(),
 | 
			
		||||
            DateUtils.MINUTE_IN_MILLIS,
 | 
			
		||||
            DateUtils.FORMAT_SHOW_DATE or DateUtils.FORMAT_NO_YEAR or DateUtils.FORMAT_ABBREV_MONTH or DateUtils.FORMAT_SHOW_TIME)
 | 
			
		||||
        holder.time.text = formatTimeAgo(context, item.time)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun getItemCount(): Int {
 | 
			
		||||
        return items.size
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Formats the provided unix timestamp in a string like "3 hours, 26 minutes ago)
 | 
			
		||||
     */
 | 
			
		||||
    fun formatTimeAgo(context: Context, unixTime: Long): String {
 | 
			
		||||
        val secondsDiff = (System.currentTimeMillis() / 1000) - unixTime
 | 
			
		||||
        val minutesDiff = secondsDiff / 60
 | 
			
		||||
 | 
			
		||||
        if (minutesDiff < 1)
 | 
			
		||||
            return context.getString(R.string.now)
 | 
			
		||||
 | 
			
		||||
        val hoursAgo = (secondsDiff / (60 * 60)).toInt()
 | 
			
		||||
        val minutesAgo = (minutesDiff % 60).toInt()
 | 
			
		||||
 | 
			
		||||
        if (hoursAgo > 24)
 | 
			
		||||
            return DateFormat.getDateFormat(context).format(Date(unixTime*1000)) + "\n" +
 | 
			
		||||
                DateFormat.getTimeFormat(context).format(Date(unixTime*1000))
 | 
			
		||||
 | 
			
		||||
        var formattedTime = StringBuilder()
 | 
			
		||||
        if (hoursAgo > 0) {
 | 
			
		||||
            formattedTime.append(hoursAgo).append(" ")
 | 
			
		||||
            if (hoursAgo.toInt() == 1)
 | 
			
		||||
                formattedTime.append(context.getString(R.string.hour_ago))
 | 
			
		||||
            else
 | 
			
		||||
                formattedTime.append(context.getString(R.string.hours_ago))
 | 
			
		||||
        }
 | 
			
		||||
        if (formattedTime.isNotEmpty())
 | 
			
		||||
            formattedTime.append(", ")
 | 
			
		||||
        if (minutesAgo > 0) {
 | 
			
		||||
            formattedTime.append(minutesAgo).append(" ")
 | 
			
		||||
            if (minutesAgo.toInt() == 1)
 | 
			
		||||
                formattedTime.append(context.getString(R.string.minute_ago))
 | 
			
		||||
            else
 | 
			
		||||
                formattedTime.append(context.getString(R.string.minutes_ago))
 | 
			
		||||
        }
 | 
			
		||||
        return formattedTime.toString()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    class LunaEventVH: RecyclerView.ViewHolder {
 | 
			
		||||
        val type: TextView
 | 
			
		||||
        val description: TextView
 | 
			
		||||
 
 | 
			
		||||
@@ -21,6 +21,7 @@ class LunaEvent(
 | 
			
		||||
        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"
 | 
			
		||||
@@ -38,6 +39,7 @@ class LunaEvent(
 | 
			
		||||
        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
 | 
			
		||||
@@ -56,6 +58,7 @@ class LunaEvent(
 | 
			
		||||
 | 
			
		||||
enum class LunaEventType {
 | 
			
		||||
    BABY_BOTTLE,
 | 
			
		||||
    WEIGHT,
 | 
			
		||||
    BREASTFEEDING_LEFT_NIPPLE,
 | 
			
		||||
    BREASTFEEDING_BOTH_NIPPLE,
 | 
			
		||||
    BREASTFEEDING_RIGHT_NIPPLE,
 | 
			
		||||
 
 | 
			
		||||
@@ -18,15 +18,34 @@
 | 
			
		||||
        android:text="@string/log_an_event"
 | 
			
		||||
        android:gravity="center_horizontal"/>
 | 
			
		||||
 | 
			
		||||
    <TextView
 | 
			
		||||
        android:id="@+id/button_bottle"
 | 
			
		||||
    <LinearLayout
 | 
			
		||||
        android:layout_width="match_parent"
 | 
			
		||||
        android:layout_height="wrap_content"
 | 
			
		||||
        android:layout_margin="10dp"
 | 
			
		||||
        android:background="@drawable/button_background"
 | 
			
		||||
        android:gravity="center_horizontal"
 | 
			
		||||
        android:textSize="50sp"
 | 
			
		||||
        android:text="@string/event_bottle_type"/>
 | 
			
		||||
        android:orientation="horizontal">
 | 
			
		||||
 | 
			
		||||
        <TextView
 | 
			
		||||
            android:id="@+id/button_bottle"
 | 
			
		||||
            android:layout_width="0dp"
 | 
			
		||||
            android:layout_height="wrap_content"
 | 
			
		||||
            android:layout_weight="2"
 | 
			
		||||
            android:layout_margin="10dp"
 | 
			
		||||
            android:background="@drawable/button_background"
 | 
			
		||||
            android:gravity="center_horizontal"
 | 
			
		||||
            android:textSize="50sp"
 | 
			
		||||
            android:text="@string/event_bottle_type"/>
 | 
			
		||||
 | 
			
		||||
        <TextView
 | 
			
		||||
            android:id="@+id/button_scale"
 | 
			
		||||
            android:layout_width="0dp"
 | 
			
		||||
            android:layout_height="wrap_content"
 | 
			
		||||
            android:layout_weight="1"
 | 
			
		||||
            android:layout_margin="10dp"
 | 
			
		||||
            android:background="@drawable/button_background"
 | 
			
		||||
            android:gravity="center_horizontal"
 | 
			
		||||
            android:textSize="50sp"
 | 
			
		||||
            android:text="@string/event_scale_type"/>
 | 
			
		||||
 | 
			
		||||
    </LinearLayout>
 | 
			
		||||
 | 
			
		||||
    <LinearLayout
 | 
			
		||||
        android:layout_width="match_parent"
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										21
									
								
								app/src/main/res/layout/number_edit_dialog.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								app/src/main/res/layout/number_edit_dialog.xml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,21 @@
 | 
			
		||||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<LinearLayout
 | 
			
		||||
    xmlns:android="http://schemas.android.com/apk/res/android"
 | 
			
		||||
    android:layout_width="match_parent"
 | 
			
		||||
    android:layout_height="match_parent"
 | 
			
		||||
    android:layout_gravity="center"
 | 
			
		||||
    android:gravity="center">
 | 
			
		||||
 | 
			
		||||
    <EditText
 | 
			
		||||
        android:id="@+id/dialog_number_edittext"
 | 
			
		||||
        android:layout_width="150dp"
 | 
			
		||||
        android:layout_height="wrap_content"
 | 
			
		||||
        android:inputType="number"
 | 
			
		||||
        android:hint="0"/>
 | 
			
		||||
 | 
			
		||||
    <TextView
 | 
			
		||||
        android:layout_width="wrap_content"
 | 
			
		||||
        android:layout_height="wrap_content"
 | 
			
		||||
        android:layout_marginLeft="10dp"
 | 
			
		||||
        android:text="g"/>
 | 
			
		||||
</LinearLayout>
 | 
			
		||||
@@ -4,10 +4,16 @@
 | 
			
		||||
    android:layout_width="match_parent"
 | 
			
		||||
    android:layout_height="match_parent"
 | 
			
		||||
    android:layout_gravity="center"
 | 
			
		||||
    android:gravity="center_horizontal">
 | 
			
		||||
    android:gravity="center">
 | 
			
		||||
 | 
			
		||||
    <NumberPicker
 | 
			
		||||
        android:id="@+id/dialog_number_picker"
 | 
			
		||||
        android:layout_width="wrap_content"
 | 
			
		||||
        android:layout_width="150dp"
 | 
			
		||||
        android:layout_height="wrap_content"/>
 | 
			
		||||
 | 
			
		||||
    <TextView
 | 
			
		||||
        android:layout_width="wrap_content"
 | 
			
		||||
        android:layout_height="wrap_content"
 | 
			
		||||
        android:layout_marginLeft="10dp"
 | 
			
		||||
        android:text="ml"/>
 | 
			
		||||
</LinearLayout>
 | 
			
		||||
 
 | 
			
		||||
@@ -25,6 +25,7 @@
 | 
			
		||||
        android:layout_width="0dp"
 | 
			
		||||
        android:layout_height="wrap_content"
 | 
			
		||||
        android:layout_weight="1"
 | 
			
		||||
        android:gravity="center_horizontal"
 | 
			
		||||
        android:text="Qty"/>
 | 
			
		||||
 | 
			
		||||
    <TextView
 | 
			
		||||
@@ -32,6 +33,7 @@
 | 
			
		||||
        android:layout_width="0dp"
 | 
			
		||||
        android:layout_height="wrap_content"
 | 
			
		||||
        android:layout_weight="2"
 | 
			
		||||
        android:gravity="center_horizontal"
 | 
			
		||||
        android:textStyle="bold"
 | 
			
		||||
        android:text="Time"/>
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,11 @@
 | 
			
		||||
    <string name="log_bottle_dialog_title">Biberon</string>
 | 
			
		||||
    <string name="log_bottle_dialog_description">Inserisci la quantità contenuta nel biberon</string>
 | 
			
		||||
 | 
			
		||||
    <string name="log_weight_dialog_title">Pesata</string>
 | 
			
		||||
    <string name="log_weight_dialog_description">Inserisci il peso rilevato</string>
 | 
			
		||||
 | 
			
		||||
    <string name="event_bottle_type">🍼</string>
 | 
			
		||||
    <string name="event_scale_type">⚖️</string>
 | 
			
		||||
    <string name="event_breastfeeding_left_type">🤱 ←</string>
 | 
			
		||||
    <string name="event_breastfeeding_both_type">🤱 ↔</string>
 | 
			
		||||
    <string name="event_breastfeeding_right_type">🤱 →</string>
 | 
			
		||||
@@ -16,6 +20,7 @@
 | 
			
		||||
    <string name="event_unknown_type">-</string>
 | 
			
		||||
 | 
			
		||||
    <string name="event_bottle_desc">Biberon</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>
 | 
			
		||||
    <string name="event_breastfeeding_right_desc">Allatt. al seno (dx)</string>
 | 
			
		||||
@@ -24,5 +29,11 @@
 | 
			
		||||
    <string name="event_unknown_desc"></string>
 | 
			
		||||
 | 
			
		||||
    <string name="toast_event_added">Evento aggiunto!</string>
 | 
			
		||||
    <string name="toast_integer_error">Valore non valido. Inserire un numero intero.</string>
 | 
			
		||||
 | 
			
		||||
    <string name="now">adesso</string>
 | 
			
		||||
    <string name="hour_ago">ora</string>
 | 
			
		||||
    <string name="hours_ago">ore</string>
 | 
			
		||||
    <string name="minute_ago">min</string>
 | 
			
		||||
    <string name="minutes_ago">min</string>
 | 
			
		||||
</resources>
 | 
			
		||||
		Reference in New Issue
	
	Block a user