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