forked from penguin86/luna-tracker
add previous/next event link to details dialog
The links will point to the previous/next event of the same type
This commit is contained in:
@@ -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>): 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>): 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<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()
|
||||
@@ -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<TextView>(R.id.dialog_event_previous)
|
||||
val nextTextView = dialogView.findViewById<TextView>(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) {
|
||||
|
@@ -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)
|
||||
|
@@ -60,4 +60,33 @@
|
||||
android:text="@string/dialog_event_detail_notes"/>
|
||||
|
||||
</ScrollView>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/dialog_event_previous"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="10dp"
|
||||
android:textSize="12sp"
|
||||
android:text="" />
|
||||
|
||||
<Space
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/dialog_event_next"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="10dp"
|
||||
android:textSize="12sp"
|
||||
android:text="" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
@@ -55,10 +55,16 @@
|
||||
<string name="toast_integer_error">Invalid value. Insert an integer.</string>
|
||||
|
||||
<string name="now">now</string>
|
||||
<string name="hour_ago">hour</string>
|
||||
<string name="hours_ago">hours</string>
|
||||
<string name="second_ago">sec</string>
|
||||
<string name="seconds_ago">secs</string>
|
||||
<string name="minute_ago">min</string>
|
||||
<string name="minutes_ago">mins</string>
|
||||
<string name="hour_ago">hour</string>
|
||||
<string name="hours_ago">hours</string>
|
||||
<string name="day_ago">year</string>
|
||||
<string name="days_ago">years</string>
|
||||
<string name="year_ago">year</string>
|
||||
<string name="years_ago">years</string>
|
||||
|
||||
<string name="no_connection">No connection</string>
|
||||
<string name="no_connection_explain">Unable to reach WebDAV service</string>
|
||||
|
Reference in New Issue
Block a user