Skip to content
Snippets Groups Projects
Unverified Commit c769c471 authored by Mohamed's avatar Mohamed Committed by GitHub
Browse files

Generic duration picker (DEV) (#2546)


- Rename Picker to a more generic name
- Move it to a suitable package
- Avoid using Target API
- Implement Builder pattern

Co-authored-by: default avatarharambasicluka <64483219+harambasicluka@users.noreply.github.com>
Co-authored-by: default avatarMatthias Urhahn <matthias.urhahn@sap.com>
parent 2c5ea8ec
No related branches found
No related tags found
No related merge requests found
Showing
with 100 additions and 46 deletions
......@@ -5,8 +5,8 @@ import android.os.Bundle
import android.view.View
import androidx.fragment.app.Fragment
import de.rki.coronawarnapp.R
import de.rki.coronawarnapp.contactdiary.ui.durationpicker.ContactDiaryDurationPickerFragment
import de.rki.coronawarnapp.contactdiary.ui.durationpicker.toContactDiaryFormat
import de.rki.coronawarnapp.ui.durationpicker.DurationPicker
import de.rki.coronawarnapp.ui.durationpicker.toContactDiaryFormat
import de.rki.coronawarnapp.databinding.FragmentTestContactDiaryBinding
import de.rki.coronawarnapp.test.menu.ui.TestMenuItem
import de.rki.coronawarnapp.util.di.AutoInject
......@@ -21,7 +21,7 @@ import javax.inject.Inject
class ContactDiaryTestFragment :
Fragment(R.layout.fragment_test_contact_diary),
AutoInject,
ContactDiaryDurationPickerFragment.OnChangeListener {
DurationPicker.OnChangeListener {
@Inject lateinit var viewModelFactory: CWAViewModelFactoryProvider.Factory
private val vm: ContactDiaryTestFragmentViewModel by cwaViewModels { viewModelFactory }
......@@ -49,15 +49,11 @@ class ContactDiaryTestFragment :
locationVisitsCleanButton.setOnClickListener { vm.clearLocationVisits() }
personEncountersCleanButton.setOnClickListener { vm.clearPersonEncounters() }
durationValue.setOnClickListener {
val args = Bundle()
args.putString(
ContactDiaryDurationPickerFragment.DURATION_ARGUMENT_KEY,
binding.durationValue.text.toString()
)
val durationPicker = ContactDiaryDurationPickerFragment()
durationPicker.arguments = args
durationPicker.setTargetFragment(this@ContactDiaryTestFragment, 0)
val durationPicker = DurationPicker.Builder()
.duration(binding.durationValue.text.toString())
.title(getString(R.string.duration_dialog_title))
.build()
durationPicker.setDurationChangeListener(this@ContactDiaryTestFragment)
durationPicker.show(parentFragmentManager, "ContactDiaryDurationPickerFragment")
}
}
......
......@@ -8,10 +8,9 @@ import androidx.navigation.fragment.navArgs
import de.rki.coronawarnapp.R
import de.rki.coronawarnapp.contactdiary.ui.day.ContactDiaryDayFragment
import de.rki.coronawarnapp.contactdiary.ui.day.ContactDiaryDayFragmentDirections
import de.rki.coronawarnapp.contactdiary.ui.durationpicker.ContactDiaryDurationPickerFragment
import de.rki.coronawarnapp.ui.durationpicker.DurationPicker
import de.rki.coronawarnapp.contactdiary.util.MarginRecyclerViewDecoration
import de.rki.coronawarnapp.databinding.ContactDiaryLocationListFragmentBinding
import de.rki.coronawarnapp.ui.doNavigate
import de.rki.coronawarnapp.util.di.AutoInject
import de.rki.coronawarnapp.util.lists.diffutil.update
import de.rki.coronawarnapp.util.onScroll
......@@ -20,13 +19,11 @@ import de.rki.coronawarnapp.util.ui.observe2
import de.rki.coronawarnapp.util.ui.viewBindingLazy
import de.rki.coronawarnapp.util.viewmodel.CWAViewModelFactoryProvider
import de.rki.coronawarnapp.util.viewmodel.cwaViewModelsAssisted
import org.joda.time.Duration
import javax.inject.Inject
class ContactDiaryLocationListFragment :
Fragment(R.layout.contact_diary_location_list_fragment),
AutoInject,
ContactDiaryDurationPickerFragment.OnChangeListener {
AutoInject {
private val binding: ContactDiaryLocationListFragmentBinding by viewBindingLazy()
......@@ -64,13 +61,14 @@ class ContactDiaryLocationListFragment :
}
viewModel.openDialog.observe2(this) {
val args = Bundle()
args.putString(ContactDiaryDurationPickerFragment.DURATION_ARGUMENT_KEY, it)
val durationPicker = ContactDiaryDurationPickerFragment()
durationPicker.arguments = args
durationPicker.setTargetFragment(this@ContactDiaryLocationListFragment, 0)
durationPicker.show(parentFragmentManager, "ContactDiaryDurationPickerFragment")
val durationPicker = DurationPicker.Builder()
.duration(it)
.title(getString(R.string.duration_dialog_title))
.build()
durationPicker.show(parentFragmentManager, "DurationPicker")
durationPicker.setDurationChangeListener { duration ->
viewModel.onDurationSelected(duration)
}
}
viewModel.openCommentInfo.observe2(this) {
......@@ -80,8 +78,4 @@ class ContactDiaryLocationListFragment :
)
}
}
override fun onChange(duration: Duration) {
viewModel.onDurationSelected(duration)
}
}
......@@ -3,8 +3,8 @@ package de.rki.coronawarnapp.contactdiary.ui.day.tabs.location
import android.view.ViewGroup
import android.view.accessibility.AccessibilityEvent
import de.rki.coronawarnapp.R
import de.rki.coronawarnapp.contactdiary.ui.durationpicker.toContactDiaryFormat
import de.rki.coronawarnapp.contactdiary.util.setClickLabel
import de.rki.coronawarnapp.ui.durationpicker.toContactDiaryFormat
import de.rki.coronawarnapp.databinding.ContactDiaryLocationListItemBinding
import de.rki.coronawarnapp.ui.lists.BaseAdapter
import de.rki.coronawarnapp.util.lists.BindableVH
......
......@@ -5,7 +5,7 @@ import dagger.Reusable
import de.rki.coronawarnapp.R
import de.rki.coronawarnapp.contactdiary.model.ContactDiaryLocationVisit
import de.rki.coronawarnapp.contactdiary.model.ContactDiaryPersonEncounter
import de.rki.coronawarnapp.contactdiary.ui.durationpicker.toReadableDuration
import de.rki.coronawarnapp.ui.durationpicker.toReadableDuration
import de.rki.coronawarnapp.util.TimeAndDateExtensions.toLocalDate
import de.rki.coronawarnapp.util.TimeStamper
import de.rki.coronawarnapp.util.coroutine.DispatcherProvider
......
......@@ -3,7 +3,7 @@ package de.rki.coronawarnapp.contactdiary.ui.overview.adapter.day
import android.view.View
import android.view.ViewGroup
import de.rki.coronawarnapp.R
import de.rki.coronawarnapp.contactdiary.ui.durationpicker.toReadableDuration
import de.rki.coronawarnapp.ui.durationpicker.toReadableDuration
import de.rki.coronawarnapp.contactdiary.util.clearAndAddAll
import de.rki.coronawarnapp.databinding.ContactDiaryOverviewNestedListItemBinding
import de.rki.coronawarnapp.ui.lists.BaseAdapter
......
package de.rki.coronawarnapp.contactdiary.ui.durationpicker
package de.rki.coronawarnapp.ui.durationpicker
import org.joda.time.Duration
......
package de.rki.coronawarnapp.contactdiary.ui.durationpicker
package de.rki.coronawarnapp.ui.durationpicker
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.DialogFragment
import de.rki.coronawarnapp.databinding.ContactDiaryDurationPickerDialogFragmentBinding
import de.rki.coronawarnapp.databinding.DurationPickerBinding
import org.joda.time.Duration
import org.joda.time.format.PeriodFormatter
import org.joda.time.format.PeriodFormatterBuilder
class ContactDiaryDurationPickerFragment : DialogFragment() {
class DurationPicker : DialogFragment() {
interface OnChangeListener {
fun interface OnChangeListener {
fun onChange(duration: Duration)
}
val binding: Lazy<ContactDiaryDurationPickerDialogFragmentBinding> = lazy {
ContactDiaryDurationPickerDialogFragmentBinding.inflate(
layoutInflater
)
}
private var onChangeListener: OnChangeListener? = null
private val binding: Lazy<DurationPickerBinding> = lazy { DurationPickerBinding.inflate(layoutInflater) }
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
return binding.value.root
......@@ -42,7 +39,7 @@ class ContactDiaryDurationPickerFragment : DialogFragment() {
}
with(binding.value) {
var duration = requireArguments().getString(DURATION_ARGUMENT_KEY)!!.split(":").toTypedArray()
var duration = requireArguments().getString(DURATION_KEY)!!.split(":").toTypedArray()
if (duration.size < 2) duration = arrayOf("00", "00")
hours.value = hoursArray.indexOf(duration[0])
......@@ -50,15 +47,19 @@ class ContactDiaryDurationPickerFragment : DialogFragment() {
cancelButton.setOnClickListener { dismiss() }
okButton.setOnClickListener {
(targetFragment as? OnChangeListener)?.onChange(getDuration(hours.value, minutes.value))
onChangeListener?.onChange(getDuration(hours.value, minutes.value))
dismiss()
}
}
}
companion object {
const val DURATION_ARGUMENT_KEY = "duration"
fun setDurationChangeListener(onChangeListener: OnChangeListener) {
this.onChangeListener = onChangeListener
}
companion object {
private const val DURATION_KEY = "duration"
private const val TITLE_KEY = "title"
val minutesArray = arrayOf("00", "15", "30", "45")
val hoursArray = Array(24) { "%02d".format(it) }
......@@ -71,5 +72,24 @@ class ContactDiaryDurationPickerFragment : DialogFragment() {
.toFormatter()
return formatter.parsePeriod(durationString).toStandardDuration()
}
private fun newInstance(builder: Builder) = DurationPicker()
.apply {
arguments = Bundle().apply {
putString(DURATION_KEY, builder.duration)
putString(TITLE_KEY, builder.title)
}
}
}
class Builder {
var title: String = ""
private set
var duration: String = ""
private set
fun title(title: String) = apply { this.title = title }
fun duration(duration: String) = apply { this.duration = duration }
fun build() = newInstance(this)
}
}
......@@ -4,6 +4,7 @@
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/duration_container"
android:layout_width="match_parent"
tools:context="de.rki.coronawarnapp.ui.durationpicker.DurationPicker"
android:layout_height="wrap_content">
<TextView
......
package de.rki.coronawarnapp.contactdiary.ui.durationpicker
package de.rki.coronawarnapp.ui.durationpicker
import io.kotest.matchers.shouldBe
import org.joda.time.Duration
......
package de.rki.coronawarnapp.contactdiary.ui.durationpicker
package de.rki.coronawarnapp.ui.durationpicker
import io.kotest.matchers.shouldBe
import io.mockk.MockKAnnotations
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
class ContactDiaryDurationPickerFragmentTest {
class DurationPickerTest {
@BeforeEach
fun setup() {
......@@ -14,30 +14,30 @@ class ContactDiaryDurationPickerFragmentTest {
@Test
fun `check hours array`() {
ContactDiaryDurationPickerFragment.hoursArray.count() shouldBe 24
DurationPicker.hoursArray.count() shouldBe 24
for (i in 0..9) {
ContactDiaryDurationPickerFragment.hoursArray[i] shouldBe "0$i"
DurationPicker.hoursArray[i] shouldBe "0$i"
}
for (i in 10..23) {
ContactDiaryDurationPickerFragment.hoursArray[i] shouldBe "$i"
DurationPicker.hoursArray[i] shouldBe "$i"
}
}
@Test
fun `check minutes array`() {
ContactDiaryDurationPickerFragment.minutesArray.count() shouldBe 4
ContactDiaryDurationPickerFragment.minutesArray[0] shouldBe "00"
DurationPicker.minutesArray.count() shouldBe 4
DurationPicker.minutesArray[0] shouldBe "00"
for (i in 1..3) {
ContactDiaryDurationPickerFragment.minutesArray[i] shouldBe "${i * 15}"
DurationPicker.minutesArray[i] shouldBe "${i * 15}"
}
}
@Test
fun `check duration`() {
ContactDiaryDurationPickerFragment.getDuration(0, 0).toContactDiaryFormat() shouldBe "00:00"
ContactDiaryDurationPickerFragment.getDuration(1, 0).toContactDiaryFormat() shouldBe "01:00"
ContactDiaryDurationPickerFragment.getDuration(23, 3).toContactDiaryFormat() shouldBe "23:45"
ContactDiaryDurationPickerFragment.getDuration(9, 2).toContactDiaryFormat() shouldBe "09:30"
ContactDiaryDurationPickerFragment.getDuration(10, 1).toContactDiaryFormat() shouldBe "10:15"
DurationPicker.getDuration(0, 0).toContactDiaryFormat() shouldBe "00:00"
DurationPicker.getDuration(1, 0).toContactDiaryFormat() shouldBe "01:00"
DurationPicker.getDuration(23, 3).toContactDiaryFormat() shouldBe "23:45"
DurationPicker.getDuration(9, 2).toContactDiaryFormat() shouldBe "09:30"
DurationPicker.getDuration(10, 1).toContactDiaryFormat() shouldBe "10:15"
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment