From cfe926a99961c1653d03857837589a7799a5f1c1 Mon Sep 17 00:00:00 2001 From: Niko Diamadis Date: Mon, 17 Oct 2022 07:34:43 +0200 Subject: [PATCH] Extrahiere TimePicker-Logik in eigene Klassen (Fix #5) --- .../cyb3rko/techniklogger/data/HourMinute.kt | 40 ++++++++++ .../fragments/MissionFragment.kt | 76 ++++-------------- .../fragments/MissionPusherFragment.kt | 5 +- .../techniklogger/modals/TimePickerBuilder.kt | 78 +++++++++++++++++++ 4 files changed, 133 insertions(+), 66 deletions(-) create mode 100644 app/src/main/java/com/cyb3rko/techniklogger/data/HourMinute.kt create mode 100644 app/src/main/java/com/cyb3rko/techniklogger/modals/TimePickerBuilder.kt diff --git a/app/src/main/java/com/cyb3rko/techniklogger/data/HourMinute.kt b/app/src/main/java/com/cyb3rko/techniklogger/data/HourMinute.kt new file mode 100644 index 0000000..bc5087f --- /dev/null +++ b/app/src/main/java/com/cyb3rko/techniklogger/data/HourMinute.kt @@ -0,0 +1,40 @@ +package com.cyb3rko.techniklogger.data + +data class HourMinute( + internal val hours: Int, + internal val minutes: Int +) { + internal val millis = hours.toLong() * 3600000 + minutes.toLong() * 60000 + + override fun toString(): String { + return "${hours.toPrettyString()}:${minutes.toPrettyString()}" + } + + private fun Int.toPrettyString(): String { + val intString = this.toString() + return if (intString.length != 1) { + intString + } else { + "0$intString" + } + } + + companion object { + internal fun fromString(hourMinute: String): HourMinute { + val parts = hourMinute.split(":") + val hours = parts[0].toInt() + val minutes = parts[1].toInt() + return HourMinute(hours, minutes) + } + } +} + +internal operator fun HourMinute.compareTo(b: HourMinute): Int { + return if (this.hours == b.hours && this.minutes == b.minutes) { + 0 + } else if (this.hours == b.hours && this.minutes < b.minutes) { + -1 + } else if (this.hours < b.hours) { + -1 + } else 1 +} diff --git a/app/src/main/java/com/cyb3rko/techniklogger/fragments/MissionFragment.kt b/app/src/main/java/com/cyb3rko/techniklogger/fragments/MissionFragment.kt index 670a9e4..a21df7c 100644 --- a/app/src/main/java/com/cyb3rko/techniklogger/fragments/MissionFragment.kt +++ b/app/src/main/java/com/cyb3rko/techniklogger/fragments/MissionFragment.kt @@ -15,17 +15,16 @@ import androidx.fragment.app.Fragment import androidx.navigation.fragment.navArgs import androidx.recyclerview.widget.LinearLayoutManager import com.cyb3rko.techniklogger.* +import com.cyb3rko.techniklogger.data.HourMinute import com.cyb3rko.techniklogger.data.objects.Member import com.cyb3rko.techniklogger.data.objects.Mission import com.cyb3rko.techniklogger.data.ParseController import com.cyb3rko.techniklogger.databinding.FragmentMissionBinding import com.cyb3rko.techniklogger.data.objects.Participation +import com.cyb3rko.techniklogger.modals.TimePickerBuilder import com.cyb3rko.techniklogger.recycler.ParticipationAdapter import com.google.android.material.dialog.MaterialAlertDialogBuilder -import com.google.android.material.timepicker.MaterialTimePicker -import com.google.android.material.timepicker.TimeFormat import com.parse.ParseObject -import java.sql.Time import java.text.SimpleDateFormat import java.util.* @@ -189,71 +188,25 @@ class MissionFragment : Fragment() { .setTitle(it.name) .setMessage(Html.fromHtml(message)) .setPositiveButton("Arbeitszeit ändern") { _, _ -> - var tempTime = "" - var time1 = Time(0) - var time2 = Time(0) - val builder = MaterialTimePicker.Builder().setTimeFormat( - TimeFormat.CLOCK_24H).setTitleText("Von") - val builder2 = MaterialTimePicker.Builder().setTimeFormat(TimeFormat.CLOCK_24H).setTitleText("Bis") - val picker = builder.build() - val picker2 = builder2.build() - var hour: String - var minute: String - var hoursInMillis: Long - var minutesInMillis: Long + val builder = TimePickerBuilder() if (it.time != "0") { val times = it.time.split(" - ") - builder.setHour(times[0].split(":")[0].toInt()) - .setMinute(times[0].split(":")[1].toInt()) - builder2.setHour(times[1].split(":")[0].toInt()) - .setMinute(times[1].split(":")[1].toInt()) - } - picker.addOnPositiveButtonClickListener { - hour = picker.hour.toString() - hour = if (hour.length != 1) hour else "0$hour" - minute = picker.minute.toString() - minute = if (minute.length != 1) minute else "0$minute" - hoursInMillis = picker.hour.toLong() * 3600000 - minutesInMillis = picker.minute.toLong() * 60000 - time1 = Time(hoursInMillis + minutesInMillis) - val testTime = time.split(" ")[0] - val testHour = testTime.split(":")[0] - val testMinutes = testTime.split(":")[1] - if (testHour > hour) { - showWarningToast("Zeitpunkt nicht im Zeitraum des Einsatzes") - } else if (testHour == hour && testMinutes > minute) { - showWarningToast("Zeitpunkt nicht im Zeitraum des Einsatzes") - } else { - tempTime += "${hour}:${minute} - " - activity?.let { it1 -> picker2.show(it1.supportFragmentManager, picker2.tag) } + builder.apply { + initialStart = HourMinute.fromString(times[0]) + initialEnd = HourMinute.fromString(times[1]) + } + } else { + val times = time.split(" Uhr")[0].split(" - ") + builder.apply { + initialStart = HourMinute.fromString(times[0]) + initialEnd = HourMinute.fromString(times[1]) } } - picker2.addOnPositiveButtonClickListener { _ -> - hour = picker2.hour.toString() - hour = if (hour.length != 1) hour else "0$hour" - minute = picker2.minute.toString() - minute = if (minute.length != 1) minute else "0$minute" - hoursInMillis = hour.toLong() * 3600000 - minutesInMillis = minute.toLong() * 60000 - time2 = Time(hoursInMillis + minutesInMillis) - val testTime = time.split(" ")[2] - val testHour = testTime.split(":")[0] - val testMinutes = testTime.split(":")[1] - if (testHour < hour) { - showWarningToast("Zeitpunkt nicht im Zeitraum des Einsatzes") - return@addOnPositiveButtonClickListener - } else if (testHour == hour && testMinutes < minute) { - showWarningToast("Zeitpunkt nicht im Zeitraum des Einsatzes") - return@addOnPositiveButtonClickListener - } - tempTime += "${hour}:${minute}" - it.setTime(tempTime) - val tempDauer = (time2.time - time1.time) / 3600 / 1000.toFloat() - it.setDuration(tempDauer) + builder.show(requireActivity(), time) { time, duration -> it.apply { setDuration(duration) - setTime(it.time) + setTime(time) saveInBackground { if (it == null) { showSuccessToast("Arbeitszeit geändert") @@ -266,7 +219,6 @@ class MissionFragment : Fragment() { } } } - activity?.let { it1 -> picker.show(it1.supportFragmentManager, picker.tag) } } .setNegativeButton("Entfernen") { _, _ -> val list = participationAdapter.currentList.toMutableList() diff --git a/app/src/main/java/com/cyb3rko/techniklogger/fragments/MissionPusherFragment.kt b/app/src/main/java/com/cyb3rko/techniklogger/fragments/MissionPusherFragment.kt index 4322a9b..32f2fe5 100644 --- a/app/src/main/java/com/cyb3rko/techniklogger/fragments/MissionPusherFragment.kt +++ b/app/src/main/java/com/cyb3rko/techniklogger/fragments/MissionPusherFragment.kt @@ -59,10 +59,7 @@ class MissionPusherFragment : Fragment() { val builder = MaterialDatePicker.Builder.datePicker() .setTitleText("Datum") - val builder2 = MaterialTimePicker.Builder() - .setTimeFormat(TimeFormat.CLOCK_24H).setTitleText("Von") - val builder3 = MaterialTimePicker.Builder() - .setTimeFormat(TimeFormat.CLOCK_24H).setTitleText("Bis") + val timePickerBuilder = TimePickerBuilder() binding.dateButton.setOnClickListener { if (date != "") { diff --git a/app/src/main/java/com/cyb3rko/techniklogger/modals/TimePickerBuilder.kt b/app/src/main/java/com/cyb3rko/techniklogger/modals/TimePickerBuilder.kt new file mode 100644 index 0000000..8996e0e --- /dev/null +++ b/app/src/main/java/com/cyb3rko/techniklogger/modals/TimePickerBuilder.kt @@ -0,0 +1,78 @@ +package com.cyb3rko.techniklogger.modals + +import androidx.fragment.app.FragmentActivity +import com.cyb3rko.techniklogger.data.HourMinute +import com.cyb3rko.techniklogger.data.compareTo +import com.cyb3rko.techniklogger.showWarningToast +import com.google.android.material.timepicker.MaterialTimePicker +import com.google.android.material.timepicker.TimeFormat +import java.text.DecimalFormat +import java.text.DecimalFormatSymbols +import java.util.* + +internal class TimePickerBuilder { + companion object { + private const val TAG = "TimePickerDialog" + } + + internal var initialStart = HourMinute(0, 0) + internal var initialEnd = HourMinute(0, 0) + + internal fun show( + activity: FragmentActivity, + missionTime: String, + action: (time: String, duration: Float) -> Unit + ) { + if (!missionTime.contains("Uhr")) { + activity.showWarningToast("Ändern der Arbeitszeit bei fehlendem Einsatz-Zeitraum nicht möglich") + return + } + + val builder1 = MaterialTimePicker.Builder() + .setTimeFormat(TimeFormat.CLOCK_24H) + .setTitleText("Von") + + val builder2 = MaterialTimePicker.Builder() + .setTimeFormat(TimeFormat.CLOCK_24H) + .setTitleText("Bis") + + builder1.setHour(initialStart.hours) + builder1.setMinute(initialStart.minutes) + builder2.setHour(initialEnd.hours) + builder2.setMinute(initialEnd.minutes) + + val picker1 = builder1.build() + val picker2 = builder2.build() + + val missionTimes = missionTime.split(" Uhr")[0].split(" - ") + val missionStart = HourMinute.fromString(missionTimes[0]) + val missionEnd = HourMinute.fromString(missionTimes[1]) + var start = HourMinute(0, 0) + picker1.addOnPositiveButtonClickListener { + start = HourMinute(picker1.hour, picker1.minute) + if (start < missionStart) { + activity.showWarningToast("Start muss im Einsatz-Zeitraum liegen") + } else { + picker2.show(activity.supportFragmentManager, "$TAG von") + } + } + + var end: HourMinute + picker2.addOnPositiveButtonClickListener { + end = HourMinute(picker2.hour, picker2.minute) + if (end > missionEnd) { + activity.showWarningToast("Ende muss im Einsatz-Zeitraum liegen") + } else if (start >= end) { + activity.showWarningToast("Ungültige Arbeitszeit erkannt") + } else { + val time = "$start - $end" + val duration = ((end.millis - start.millis).toFloat() / 3600000f) + val floatFormat = DecimalFormat("#.#", DecimalFormatSymbols(Locale.ENGLISH)) + val roundedDuration = floatFormat.format(duration) + action(time, roundedDuration.toFloat()) + } + } + + picker1.show(activity.supportFragmentManager, "$TAG bis") + } +}