From 9c549ddcad8adb9ada2ecb030426e1f21d2c8d7a Mon Sep 17 00:00:00 2001 From: Moritz Warning Date: Tue, 16 Sep 2025 01:49:20 +0200 Subject: [PATCH] add previous/next event link to details dialog The links will point to the previous/next event of the same type --- .../lunatracker/MainActivity.kt | 64 ++++++++++++++++++- app/src/main/java/utils/DateUtils.kt | 56 ++++++++++++++++ .../main/res/layout/dialog_event_detail.xml | 29 +++++++++ app/src/main/res/values/strings.xml | 10 ++- 4 files changed, 155 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/it/danieleverducci/lunatracker/MainActivity.kt b/app/src/main/java/it/danieleverducci/lunatracker/MainActivity.kt index 9441add..0d51fd0 100644 --- a/app/src/main/java/it/danieleverducci/lunatracker/MainActivity.kt +++ b/app/src/main/java/it/danieleverducci/lunatracker/MainActivity.kt @@ -39,6 +39,7 @@ import it.danieleverducci.lunatracker.repository.WebDAVLogbookRepository import kotlinx.coroutines.Runnable import okio.IOException import org.json.JSONException +import utils.DateUtils import utils.NumericUtils import java.text.DateFormat import java.util.Calendar @@ -131,7 +132,7 @@ class MainActivity : AppCompatActivity() { val adapter = LunaEventRecyclerAdapter(this, items) adapter.onItemClickListener = object: LunaEventRecyclerAdapter.OnItemClickListener{ override fun onItemClick(event: LunaEvent) { - showEventDetailDialog(event) + showEventDetailDialog(event, items) } } recyclerView.adapter = adapter @@ -308,7 +309,35 @@ class MainActivity : AppCompatActivity() { alertDialog.show() } - fun showEventDetailDialog(event: LunaEvent) { + fun getPreviousSameEvent(event: LunaEvent, items: ArrayList): LunaEvent? { + var previousEvent: LunaEvent? = null + for (item in items) { + if (item.type == event.type && item.time < event.time) { + if (previousEvent == null) { + previousEvent = item + } else if (previousEvent.time < item.time) { + previousEvent = item + } + } + } + return previousEvent + } + + fun getNextSameEvent(event: LunaEvent, items: ArrayList): LunaEvent? { + var nextEvent: LunaEvent? = null + for (item in items) { + if (item.type == event.type && item.time > event.time) { + if (nextEvent == null) { + nextEvent = item + } else if (nextEvent.time > item.time) { + nextEvent = item + } + } + } + return nextEvent + } + + fun showEventDetailDialog(event: LunaEvent, items: ArrayList) { // 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() @@ -359,6 +388,37 @@ class MainActivity : AppCompatActivity() { // Resume logbook update pauseLogbookUpdate = false }) + + // create next/previous links to events of the same type + + val previousTextView = dialogView.findViewById(R.id.dialog_event_previous) + val nextTextView = dialogView.findViewById(R.id.dialog_event_next) + val nextEvent = getNextSameEvent(event, items) + val previousEvent = getPreviousSameEvent(event, items) + + if (previousEvent != null) { + val emoji = previousEvent.getTypeEmoji(applicationContext) + val time = DateUtils.formatTimeDuration(applicationContext, event.time - previousEvent.time) + previousTextView.text = String.format("⬅️ %s %s", emoji, time) + previousTextView.setOnClickListener { + alertDialog.cancel() + showEventDetailDialog(previousEvent, items) + } + } else { + previousTextView.visibility = View.GONE + } + + if (nextEvent != null) { + val emoji = nextEvent.getTypeEmoji(applicationContext) + val time = DateUtils.formatTimeDuration(applicationContext, nextEvent.time - event.time) + nextTextView.text = String.format("%s %s ➡️", time, emoji) + nextTextView.setOnClickListener { + alertDialog.cancel() + showEventDetailDialog(nextEvent, items) + } + } else { + nextTextView.visibility = View.GONE + } } fun showAddLogbookDialog(requestedByUser: Boolean) { diff --git a/app/src/main/java/utils/DateUtils.kt b/app/src/main/java/utils/DateUtils.kt index b192f25..207a6d4 100644 --- a/app/src/main/java/utils/DateUtils.kt +++ b/app/src/main/java/utils/DateUtils.kt @@ -7,6 +7,62 @@ import java.util.Date class DateUtils { companion object { + fun formatTimeDuration(context: Context, secondsDiff: Long): String { + var seconds = secondsDiff + + val years = (seconds / (365 * 24 * 60 * 60F)).toLong() + seconds -= years * (365 * 24 * 60 * 60) + val days = (seconds / (24 * 60 * 60F)).toLong() + seconds -= days * (24 * 60 * 60) + val hours = (seconds / (60 * 60F)).toLong() + seconds -= hours * (60 * 60) + val minutes = (seconds / 60F).toLong() + seconds -= minutes * 60 + + fun format(value1: Long, value2: Long, resIdSingular1: Int, resIdPlural1: Int, resIdSingular2: Int, resIdPlural2: Int): String { + val builder = StringBuilder() + if (value1 == 0L) { + // omit + } else if (value1 == 1L) { + builder.append(value1) + builder.append(" ") + builder.append(context.getString(resIdSingular1)) + } else { + builder.append(value1) + builder.append(" ") + builder.append(context.getString(resIdPlural1)) + } + + if (value1 > 0L && value2 > 0L) { + builder.append(", ") + } + + if (value2 == 0L) { + // omit + } else if (value2 == 1L) { + builder.append(value2) + builder.append(" ") + builder.append(context.getString(resIdSingular2)) + } else { + builder.append(value2) + builder.append(" ") + builder.append(context.getString(resIdPlural2)) + } + return builder.toString() + } + + if (years > 0) { + return format(years, days, R.string.year_ago, R.string.years_ago, R.string.day_ago, R.string.days_ago) + } else if (days > 0) { + return format(days, hours, R.string.day_ago, R.string.days_ago, R.string.hour_ago, R.string.hours_ago) + } else if (hours > 0) { + return format(hours, minutes, R.string.hour_ago, R.string.hours_ago, R.string.minute_ago, R.string.minutes_ago) + } else if (minutes > 0) { + return format(minutes, seconds, R.string.minute_ago, R.string.minute_ago, R.string.second_ago, R.string.seconds_ago) + } else { + return context.getString(R.string.now) + } + } /** * Formats the provided unix timestamp in a string like "3 hours, 26 minutes ago) diff --git a/app/src/main/res/layout/dialog_event_detail.xml b/app/src/main/res/layout/dialog_event_detail.xml index ab468cc..ead5f81 100644 --- a/app/src/main/res/layout/dialog_event_detail.xml +++ b/app/src/main/res/layout/dialog_event_detail.xml @@ -60,4 +60,33 @@ android:text="@string/dialog_event_detail_notes"/> + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index d621b49..4898314 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -55,10 +55,16 @@ Invalid value. Insert an integer. now - hour - hours + sec + secs min mins + hour + hours + year + years + year + years No connection Unable to reach WebDAV service