Skip to content
This repository has been archived by the owner on Jun 20, 2023. It is now read-only.

Request covid certificate screen (EXPOSUREAPP-7426) #3314

Merged
merged 20 commits into from
May 28, 2021
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@ import android.annotation.SuppressLint
import android.os.Bundle
import android.view.View
import androidx.fragment.app.Fragment
import de.rki.coronawarnapp.NavGraphDirections
import de.rki.coronawarnapp.R
import de.rki.coronawarnapp.coronatest.type.CoronaTest
import de.rki.coronawarnapp.databinding.FragmentTestGreenCertificateBinding
import de.rki.coronawarnapp.test.menu.ui.TestMenuItem
import de.rki.coronawarnapp.util.di.AutoInject
import de.rki.coronawarnapp.util.ui.doNavigate
import de.rki.coronawarnapp.util.ui.viewBinding
import de.rki.coronawarnapp.util.viewmodel.CWAViewModelFactoryProvider
import de.rki.coronawarnapp.util.viewmodel.cwaViewModels
Expand All @@ -22,13 +25,28 @@ class GreenCertificateTestFragment : Fragment(R.layout.fragment_test_green_certi

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

binding.pcrScreen.setOnClickListener {
mtwalli marked this conversation as resolved.
Show resolved Hide resolved
doNavigate(
NavGraphDirections.actionSubmissionTestResultGreenCertificateFragment(
CoronaTest.Type.PCR
)
)
}
binding.ratScreen.setOnClickListener {
doNavigate(
NavGraphDirections.actionSubmissionTestResultGreenCertificateFragment(
CoronaTest.Type.RAPID_ANTIGEN
)
)
}
}

companion object {
val MENU_ITEM = TestMenuItem(
title = "Green Certificate",
description = "View & Control green certificate related features.",
targetId = R.id.vaccinationTestFragment
targetId = R.id.greenCertificateTestFragment
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,22 @@
android:orientation="vertical"
android:paddingBottom="32dp">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Request DCC screen" />

<com.google.android.material.button.MaterialButton
android:id="@+id/pcr_screen"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="CPR screen" />

<com.google.android.material.button.MaterialButton
android:id="@+id/rat_screen"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="RAT screen" />

</LinearLayout>
</androidx.core.widget.NestedScrollView>
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@
<action
android:id="@+id/action_test_menu_fragment_to_vaccinationTestFragment"
app:destination="@id/vaccinationTestFragment" />
<action
android:id="@+id/action_test_menu_fragment_to_greenCertificateTestFragment"
app:destination="@id/greenCertificateTestFragment" />
</fragment>

<fragment
Expand Down Expand Up @@ -169,7 +172,7 @@
android:id="@+id/vaccinationTestFragment"
android:name="de.rki.coronawarnapp.vaccination.ui.VaccinationTestFragment"
android:label="VaccinationTestFragment"
tools:layout="@layout/fragment_test_vaccination" >
tools:layout="@layout/fragment_test_vaccination">

<action
android:id="@+id/action_vaccinationTestFragment_to_vaccinationDetailsFragment"
Expand All @@ -185,4 +188,9 @@
android:name="vaccinationCertificateId"
app:argType="string" />
</fragment>
<fragment
android:id="@+id/greenCertificateTestFragment"
android:name="de.rki.coronawarnapp.test.greencertificate.GreenCertificateTestFragment"
android:label="GreenCertificateTestFragment"
tools:layout="@layout/fragment_test_green_certificate" />
</navigation>
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import com.google.android.material.datepicker.MaterialDatePicker
import de.rki.coronawarnapp.R
import de.rki.coronawarnapp.contactdiary.util.hideKeyboard
import de.rki.coronawarnapp.databinding.RatProfileCreateFragmentBinding
import de.rki.coronawarnapp.util.TimeAndDateExtensions.toDayFormat
import de.rki.coronawarnapp.util.di.AutoInject
import de.rki.coronawarnapp.util.ui.doNavigate
import de.rki.coronawarnapp.util.ui.popBackStack
Expand Down Expand Up @@ -80,7 +81,7 @@ class RATProfileCreateFragment : Fragment(R.layout.rat_profile_create_fragment),
addOnPositiveButtonClickListener { timestamp ->
val localDate = LocalDate(timestamp)
binding.birthDateInputEdit.setText(
localDate.toString("dd.MM.yyyy")
localDate.toDayFormat()
)
viewModel.birthDateChanged(localDate)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import de.rki.coronawarnapp.ui.submission.viewmodel.SubmissionDispatcherViewMode
import de.rki.coronawarnapp.ui.submission.viewmodel.SubmissionNavigationEvents
import de.rki.coronawarnapp.util.di.AutoInject
import de.rki.coronawarnapp.util.ui.doNavigate
import de.rki.coronawarnapp.util.ui.findNestedGraph
import de.rki.coronawarnapp.util.ui.observe2
import de.rki.coronawarnapp.util.ui.viewBinding
import de.rki.coronawarnapp.util.viewmodel.CWAViewModelFactoryProvider
Expand Down Expand Up @@ -61,9 +62,7 @@ class SubmissionDispatcherFragment : Fragment(R.layout.fragment_submission_dispa
}

is SubmissionNavigationEvents.NavigateToOpenProfile -> {
val ratGraph = findNavController().graph.findNode(R.id.rapid_test_profile_nav_graph) as NavGraph
ratGraph.startDestination = R.id.ratProfileQrCodeFragment

findNestedGraph(R.id.rapid_test_profile_nav_graph).startDestination = R.id.ratProfileQrCodeFragment
doNavigate(
SubmissionDispatcherFragmentDirections
.actionSubmissionDispatcherFragmentToRapidTestProfileNavGraph()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package de.rki.coronawarnapp.ui.submission.greencertificate

import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.View
import androidx.core.view.isVisible
import androidx.core.widget.doOnTextChanged
import androidx.navigation.fragment.navArgs
import com.google.android.material.datepicker.MaterialDatePicker
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import de.rki.coronawarnapp.R
import de.rki.coronawarnapp.coronatest.type.CoronaTest
import de.rki.coronawarnapp.databinding.FragmentRequestGreenCertificateBinding
import de.rki.coronawarnapp.util.TimeAndDateExtensions.toDayFormat
import de.rki.coronawarnapp.util.di.AutoInject
import de.rki.coronawarnapp.util.ui.viewBinding
import de.rki.coronawarnapp.util.viewmodel.CWAViewModelFactoryProvider
import de.rki.coronawarnapp.util.viewmodel.cwaViewModelsAssisted
import org.joda.time.LocalDate
import javax.inject.Inject

class RequestGreenCertificateFragment : Fragment(R.layout.fragment_request_green_certificate), AutoInject {

@Inject lateinit var viewModelFactory: CWAViewModelFactoryProvider.Factory
private val viewModel by cwaViewModelsAssisted<RequestGreenCertificateViewModel>(
factoryProducer = { viewModelFactory },
constructorCall = { factory, _ ->
factory as RequestGreenCertificateViewModel.Factory
factory.create(args.testType)
}
)
private val binding by viewBinding<FragmentRequestGreenCertificateBinding>()
private val args by navArgs<RequestGreenCertificateFragmentArgs>()

override fun onViewCreated(view: View, savedInstanceState: Bundle?) =
with(binding) {
val isPCR = args.testType == CoronaTest.Type.PCR
birthDateGroup.isVisible = isPCR
privacyCard.pcrExtraBullet.isVisible = isPCR

dateInputEdit.doOnTextChanged { text, _, _, _ ->
if (text.toString().isEmpty()) viewModel.birthDateChanged(null)
}

toolbar.setNavigationOnClickListener { showDialog() }
agreeButton.setOnClickListener { viewModel.onAgreeGC() }
disagreeButton.setOnClickListener { viewModel.onDisagreeGC() }
dateInputEdit.setOnClickListener { openDatePicker() }
}

private fun showDialog() {
MaterialAlertDialogBuilder(requireContext())
.setTitle(R.string.request_gc_dialog_title)
.setMessage(R.string.request_gc_dialog_message)
.setNegativeButton(R.string.request_gc_dialog_positive_button) { _, _ -> /* TODO */ }
mtwalli marked this conversation as resolved.
Show resolved Hide resolved
.setPositiveButton(R.string.request_gc_dialog_negative_button) { _, _ -> /* TODO */ }
.create()
.show()
}

private fun openDatePicker() {
MaterialDatePicker.Builder
.datePicker()
.build()
.apply {
addOnPositiveButtonClickListener { timestamp ->
val localDate = LocalDate(timestamp)
binding.dateInputEdit.setText(localDate.toDayFormat())
viewModel.birthDateChanged(localDate)
}
}
.show(childFragmentManager, "RequestGreenCertificateFragment.MaterialDatePicker")
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package de.rki.coronawarnapp.ui.submission.greencertificate

import dagger.Binds
import dagger.Module
import dagger.multibindings.IntoMap
import de.rki.coronawarnapp.util.viewmodel.CWAViewModel
import de.rki.coronawarnapp.util.viewmodel.CWAViewModelFactory
import de.rki.coronawarnapp.util.viewmodel.CWAViewModelKey

@Module
abstract class RequestGreenCertificateFragmentModule {

@Binds
@IntoMap
@CWAViewModelKey(RequestGreenCertificateViewModel::class)
abstract fun requestGreenCertificateFragment(
factory: RequestGreenCertificateViewModel.Factory
): CWAViewModelFactory<out CWAViewModel>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package de.rki.coronawarnapp.ui.submission.greencertificate

import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import de.rki.coronawarnapp.coronatest.type.CoronaTest
import de.rki.coronawarnapp.util.viewmodel.CWAViewModel
import de.rki.coronawarnapp.util.viewmodel.CWAViewModelFactory
import org.joda.time.LocalDate

class RequestGreenCertificateViewModel @AssistedInject constructor(
@Assisted private val testType: CoronaTest.Type,
) : CWAViewModel() {

fun birthDateChanged(localDate: LocalDate?) {
// TODO
}

fun onAgreeGC() {
// TODO
}

fun onDisagreeGC() {
// TODO
}

@AssistedFactory
interface Factory : CWAViewModelFactory<RequestGreenCertificateViewModel> {
fun create(type: CoronaTest.Type): RequestGreenCertificateViewModel
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,9 @@ class SubmissionQRCodeScanFragment : Fragment(R.layout.fragment_submission_qr_co
}

viewModel.registrationState.observe2(this) { state ->
binding.submissionQrCodeScanSpinner.visibility = when (state.apiRequestState) {
ApiRequestState.STARTED -> View.VISIBLE
else -> View.GONE
when (state.apiRequestState) {
ApiRequestState.STARTED -> binding.submissionQrCodeScanSpinner.show()
else -> binding.submissionQrCodeScanSpinner.hide()
}
when (state.test?.testResult) {
CoronaTestResult.PCR_POSITIVE ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ import timber.log.Timber

class SubmissionQRCodeScanViewModel @AssistedInject constructor(
dispatcherProvider: DispatcherProvider,
@Assisted private val isConsentGiven: Boolean,
private val cameraSettings: CameraSettings,
private val qrCodeRegistrationStateProcessor: QrCodeRegistrationStateProcessor,
@Assisted private val isConsentGiven: Boolean,
private val submissionRepository: SubmissionRepository,
private val qrCodeValidator: CoronaTestQrCodeValidator,
private val analyticsKeySubmissionCollector: AnalyticsKeySubmissionCollector
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import de.rki.coronawarnapp.ui.submission.fragment.SubmissionContactFragment
import de.rki.coronawarnapp.ui.submission.fragment.SubmissionDispatcherFragment
import de.rki.coronawarnapp.ui.submission.deletionwarning.SubmissionDeletionWarningFragment
import de.rki.coronawarnapp.ui.submission.deletionwarning.SubmissionDeletionWarningModule
import de.rki.coronawarnapp.ui.submission.greencertificate.RequestGreenCertificateFragment
import de.rki.coronawarnapp.ui.submission.greencertificate.RequestGreenCertificateFragmentModule
import de.rki.coronawarnapp.ui.submission.qrcode.consent.SubmissionConsentFragment
import de.rki.coronawarnapp.ui.submission.qrcode.consent.SubmissionConsentModule
import de.rki.coronawarnapp.ui.submission.qrcode.scan.SubmissionQRCodeScanFragment
Expand Down Expand Up @@ -110,4 +112,7 @@ internal abstract class SubmissionFragmentModule {

@ContributesAndroidInjector(modules = [SubmissionTestResultKeysSharedModule::class])
abstract fun submissionTestResultKeysSharedScreen(): SubmissionTestResultKeysSharedFragment

@ContributesAndroidInjector(modules = [RequestGreenCertificateFragmentModule::class])
abstract fun requestGreenCertificateFragment(): RequestGreenCertificateFragment
}
Original file line number Diff line number Diff line change
Expand Up @@ -105,29 +105,29 @@ object TimeAndDateExtensions {

val Instant.seconds get() = TimeUnit.MILLISECONDS.toSeconds(millis)

fun Instant.toUserTimeZone() = this.toDateTime(DateTimeZone.forTimeZone(TimeZone.getDefault()))
fun Instant.toUserTimeZone(): DateTime = this.toDateTime(DateTimeZone.forTimeZone(TimeZone.getDefault()))

fun Instant.toLocalDateUserTz(): LocalDate = this.toUserTimeZone().toLocalDate()

/**
* Returns a readable date String with the format "dd.MM.yyyy" like 23.05.1989 of an Instant
*/
fun Instant.toDayFormat() = toString(dayFormatter)
fun Instant.toDayFormat(): String = toString(dayFormatter)

/**
* Returns a readable date String with the format "dd.MM.yyyy" like 23.05.1989 of a LocalDate
*/
fun LocalDate.toDayFormat() = toString(dayFormatter)
fun LocalDate.toDayFormat(): String = toString(dayFormatter)

/**
* Returns a readable date String with the format "dd.MM.yy" like 23.05.89 of an Instant
*/
fun Instant.toShortDayFormat() = toString(dayFormatter2DigitYear)
fun Instant.toShortDayFormat(): String = toString(dayFormatter2DigitYear)

/**
* Returns a readable date String with the format "dd.MM.yy" like 23.05.89 of an LocalDate
*/
fun LocalDate.toShortDayFormat() = toString(dayFormatter2DigitYear)
fun LocalDate.toShortDayFormat(): String = toString(dayFormatter2DigitYear)
}

typealias HourInterval = Long