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

DGC Detail Screen (EXPOSUREAPP-7478) (#3345)


* added menu

* removed static menu string

* added deletion message

* recentered title icon

* fixed menu icon onclick

* linting

* add code to fullscreen qr code

* linting

* Renaming - refactoring

* Renaming

* More renaming

* Dummy Qr code

* Pass args + connect to repo

* Small chunks

* Update translation_v2.json

* Bind data

* Add to covid certificate graph

* Generate Qr Code

* Certificate card subtitle

* Use sampleCollectedAt

* Unify date formatting and fix typo

* wiring

* removed from test nav graph

* lint

* lint

* lint 2

* fix crash

Co-authored-by: default avatarMohamed Metwalli <mohamed.metwalli@sap.com>
parent 6adc6bf4
No related branches found
No related tags found
No related merge requests found
Showing
with 323 additions and 199 deletions
......@@ -8,7 +8,6 @@ import de.rki.coronawarnapp.R
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
......@@ -23,15 +22,6 @@ class GreenCertificateTestFragment : Fragment(R.layout.fragment_test_green_certi
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.apply {
detailsScreen.setOnClickListener {
doNavigate(
GreenCertificateTestFragmentDirections
.actionGreenCertificateTestFragmentToGreenCertificateDetailsFragment()
)
}
}
}
companion object {
......
......@@ -17,11 +17,5 @@
android:layout_height="wrap_content"
android:text="Request DCC screen" />
<com.google.android.material.button.MaterialButton
android:id="@+id/details_screen"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Details screen" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
......@@ -194,14 +194,6 @@
android:name="de.rki.coronawarnapp.test.greencertificate.GreenCertificateTestFragment"
android:label="GreenCertificateTestFragment"
tools:layout="@layout/fragment_test_green_certificate" >
<action
android:id="@+id/action_greenCertificateTestFragment_to_greenCertificateDetailsFragment"
app:destination="@id/greenCertificateDetailsFragment" />
</fragment>
<fragment
android:id="@+id/greenCertificateDetailsFragment"
android:name="de.rki.coronawarnapp.greencertificate.ui.certificates.details.GreenCertificateDetailsFragment"
android:label="GreenCertificateDetailsFragment"
tools:layout="@layout/fragment_greencertificate_details" />
</navigation>
......@@ -4,15 +4,15 @@ import dagger.Module
import dagger.android.ContributesAndroidInjector
import de.rki.coronawarnapp.greencertificate.ui.certificates.CertificatesFragment
import de.rki.coronawarnapp.greencertificate.ui.certificates.CertificatesFragmentModule
import de.rki.coronawarnapp.greencertificate.ui.certificates.details.GreenCertificateDetailsFragment
import de.rki.coronawarnapp.greencertificate.ui.certificates.details.GreenCertificateDetailsModule
import de.rki.coronawarnapp.greencertificate.ui.certificates.details.CovidCertificateDetailsFragment
import de.rki.coronawarnapp.greencertificate.ui.certificates.details.CovidCertificateDetailsModule
@Module
abstract class GreenCertificateUIModule {
abstract class CovidCertificateUIModule {
@ContributesAndroidInjector(modules = [CertificatesFragmentModule::class])
abstract fun certificatesFragment(): CertificatesFragment
@ContributesAndroidInjector(modules = [GreenCertificateDetailsModule::class])
abstract fun certificateDetailsFragment(): GreenCertificateDetailsFragment
@ContributesAndroidInjector(modules = [CovidCertificateDetailsModule::class])
abstract fun certificateDetailsFragment(): CovidCertificateDetailsFragment
}
......@@ -47,6 +47,12 @@ class CertificatesFragment : Fragment(R.layout.fragment_certificates), AutoInjec
findNestedGraph(R.id.vaccination_nav_graph).startDestination = R.id.vaccinationQrCodeScanFragment
doNavigate(CertificatesFragmentDirections.actionCertificatesFragmentToVaccinationNavGraph())
}
is CertificatesFragmentEvents.GoToCovidCertificateDetailScreen -> {
doNavigate(
CertificatesFragmentDirections
.actionCertificatesFragmentToCovidCertificateDetailsFragment(event.identifier)
)
}
}
}
}
......
......@@ -5,4 +5,6 @@ sealed class CertificatesFragmentEvents {
data class OpenVaccinationRegistrationGraph(val registrationAcknowledged: Boolean) : CertificatesFragmentEvents()
data class GoToVaccinationList(val personIdentifierCodeSha256: String) : CertificatesFragmentEvents()
data class GoToCovidCertificateDetailScreen(val identifier: String) : CertificatesFragmentEvents()
}
......@@ -106,7 +106,14 @@ class CertificatesViewModel @AssistedInject constructor(
testDate = certificate.registeredAt,
testPerson =
certificate.toTestCertificate(null)?.firstName + " " +
certificate.toTestCertificate(null)?.lastName
certificate.toTestCertificate(null)?.lastName,
onClickAction = {
events.postValue(
CertificatesFragmentEvents.GoToCovidCertificateDetailScreen(
certificate.identifier
)
)
}
)
)
}
......
......@@ -4,9 +4,10 @@ import android.view.ViewGroup
import de.rki.coronawarnapp.R
import de.rki.coronawarnapp.databinding.CovidTestSuccessCardBinding
import de.rki.coronawarnapp.greencertificate.ui.certificates.CertificatesAdapter
import de.rki.coronawarnapp.util.TimeAndDateExtensions.toShortDayFormat
import de.rki.coronawarnapp.util.TimeAndDateExtensions.toShortTimeFormat
import de.rki.coronawarnapp.util.lists.diffutil.HasPayloadDiffer
import org.joda.time.Instant
import org.joda.time.format.DateTimeFormat
class CovidTestCertificateCard(parent: ViewGroup) :
CertificatesAdapter.CertificatesItemVH<CovidTestCertificateCard.Item, CovidTestSuccessCardBinding>(
......@@ -23,14 +24,10 @@ class CovidTestCertificateCard(parent: ViewGroup) :
payloads: List<Any>
) -> Unit = { item, _ ->
val dateTime = item.testDate.toDateTime()
val dateFormat = DateTimeFormat.shortDate()
val timeFormat = DateTimeFormat.shortTime()
testTime.text = context.getString(
R.string.test_certificate_time,
dateTime.toString(dateFormat),
dateTime.toString(timeFormat),
item.testDate.toShortDayFormat(),
item.testDate.toShortTimeFormat(),
)
personName.text = item.testPerson
......@@ -39,6 +36,7 @@ class CovidTestCertificateCard(parent: ViewGroup) :
data class Item(
override val testDate: Instant,
val testPerson: String,
val onClickAction: (Item) -> Unit,
) : CovidCertificateTestItem, HasPayloadDiffer {
override fun diffPayload(old: Any, new: Any): Any? = if (old::class == new::class) new else null
}
......
......@@ -4,9 +4,10 @@ import android.view.ViewGroup
import de.rki.coronawarnapp.R
import de.rki.coronawarnapp.databinding.CovidTestErrorCardBinding
import de.rki.coronawarnapp.greencertificate.ui.certificates.CertificatesAdapter
import de.rki.coronawarnapp.util.TimeAndDateExtensions.toShortDayFormat
import de.rki.coronawarnapp.util.TimeAndDateExtensions.toShortTimeFormat
import de.rki.coronawarnapp.util.lists.diffutil.HasPayloadDiffer
import org.joda.time.Instant
import org.joda.time.format.DateTimeFormat
class CovidTestCertificateErrorCard(parent: ViewGroup) :
CertificatesAdapter.CertificatesItemVH<CovidTestCertificateErrorCard.Item, CovidTestErrorCardBinding>(
......@@ -23,14 +24,10 @@ class CovidTestCertificateErrorCard(parent: ViewGroup) :
payloads: List<Any>
) -> Unit = { item, _ ->
val dateTime = item.testDate.toDateTime()
val dateFormat = DateTimeFormat.shortDate()
val timeFormat = DateTimeFormat.shortTime()
testTime.text = context.getString(
R.string.test_certificate_time,
dateTime.toString(dateFormat),
dateTime.toString(timeFormat),
item.testDate.toShortDayFormat(),
item.testDate.toShortTimeFormat(),
)
retryButton.setOnClickListener { item.onClickAction(item) }
......
package de.rki.coronawarnapp.greencertificate.ui.certificates.details
import android.graphics.Bitmap
import android.os.Bundle
import android.view.View
import android.widget.LinearLayout
import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.FragmentNavigatorExtras
import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs
import com.google.android.material.appbar.AppBarLayout
import de.rki.coronawarnapp.R
import de.rki.coronawarnapp.bugreporting.ui.toErrorDialogBuilder
import de.rki.coronawarnapp.covidcertificate.test.TestCertificate
import de.rki.coronawarnapp.databinding.FragmentCovidCertificateDetailsBinding
import de.rki.coronawarnapp.ui.qrcode.fullscreen.QrCodeFullScreenFragmentArgs
import de.rki.coronawarnapp.ui.view.onOffsetChange
import de.rki.coronawarnapp.util.DialogHelper
import de.rki.coronawarnapp.util.TimeAndDateExtensions.toDayFormat
import de.rki.coronawarnapp.util.TimeAndDateExtensions.toShortDayFormat
import de.rki.coronawarnapp.util.TimeAndDateExtensions.toShortTimeFormat
import de.rki.coronawarnapp.util.di.AutoInject
import de.rki.coronawarnapp.util.setUrl
import de.rki.coronawarnapp.util.ui.popBackStack
import de.rki.coronawarnapp.util.ui.viewBinding
import de.rki.coronawarnapp.util.viewmodel.CWAViewModelFactoryProvider
import de.rki.coronawarnapp.util.viewmodel.cwaViewModelsAssisted
import javax.inject.Inject
class CovidCertificateDetailsFragment : Fragment(R.layout.fragment_covid_certificate_details), AutoInject {
@Inject lateinit var viewModelFactory: CWAViewModelFactoryProvider.Factory
private val binding by viewBinding<FragmentCovidCertificateDetailsBinding>()
private val args by navArgs<CovidCertificateDetailsFragmentArgs>()
private val viewModel: CovidCertificateDetailsViewModel by cwaViewModelsAssisted(
factoryProducer = { viewModelFactory },
constructorCall = { factory, _ ->
factory as CovidCertificateDetailsViewModel.Factory
factory.create(
testCertificateIdentifier = args.testCertificateIdentifier
)
}
)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) = with(binding) {
qrCodeCard.title.setText(R.string.detail_green_certificate_card_title)
appBarLayout.onOffsetChange { titleAlpha, subtitleAlpha ->
title.alpha = titleAlpha
subtitle.alpha = subtitleAlpha
}
bindTravelNoticeViews()
bindToolbar()
setToolbarOverlay()
viewModel.qrCode.observe(viewLifecycleOwner) { onQrCodeReady(it) }
viewModel.errors.observe(viewLifecycleOwner) { onError(it) }
viewModel.events.observe(viewLifecycleOwner) { onNavEvent(it) }
viewModel.covidCertificate.observe(viewLifecycleOwner) { it?.let { onCertificateReady(it) } }
}
private fun FragmentCovidCertificateDetailsBinding.onCertificateReady(
testCertificate: TestCertificate
) {
qrCodeCard.subtitle.text = getString(
R.string.detail_green_certificate_card_subtitle,
testCertificate.sampleCollectedAt.toShortDayFormat(),
testCertificate.sampleCollectedAt.toShortTimeFormat(),
)
name.text = testCertificate.run { "$firstName $lastName" }
birthDate.text = testCertificate.dateOfBirth.toDayFormat()
diseaseType.text = testCertificate.targetName
testType.text = testCertificate.testType
testName.text = testCertificate.testName
testManufacturer.text = testCertificate.testNameAndManufactor
testDate.text = "%s %s".format(
testCertificate.sampleCollectedAt.toShortDayFormat(),
testCertificate.sampleCollectedAt.toShortTimeFormat()
)
testResult.text = testCertificate.testResult
testCenter.text = testCertificate.testCenter
certificateCountry.text = testCertificate.certificateCountry
certificateIssuer.text = testCertificate.certificateIssuer
certificateId.text = testCertificate.certificateId
}
private fun FragmentCovidCertificateDetailsBinding.onQrCodeReady(bitmap: Bitmap?) {
qrCodeCard.apply {
image.setImageBitmap(bitmap)
progressBar.hide()
bitmap?.let { image.setOnClickListener { viewModel.openFullScreen() } }
}
}
private fun FragmentCovidCertificateDetailsBinding.onError(error: Throwable) {
qrCodeCard.progressBar.hide()
error.toErrorDialogBuilder(requireContext()).show()
}
private fun FragmentCovidCertificateDetailsBinding.onNavEvent(event: CovidCertificateDetailsNavigation) {
when (event) {
CovidCertificateDetailsNavigation.Back -> popBackStack()
is CovidCertificateDetailsNavigation.FullQrCode -> findNavController().navigate(
R.id.action_global_qrCodeFullScreenFragment,
QrCodeFullScreenFragmentArgs(event.qrCodeText).toBundle(),
null,
FragmentNavigatorExtras(qrCodeCard.image to qrCodeCard.image.transitionName)
)
}
}
private fun FragmentCovidCertificateDetailsBinding.bindTravelNoticeViews() {
if (travelNoticeGerman.text ==
getString(R.string.green_certificate_attribute_certificate_travel_notice_german)
) {
travelNoticeGerman.setUrl(
R.string.green_certificate_attribute_certificate_travel_notice_german,
R.string.green_certificate_travel_notice_link_de,
R.string.green_certificate_travel_notice_link_de
)
}
if (travelNoticeEnglish.text ==
getString(R.string.green_certificate_attribute_certificate_travel_notice_english)
) {
travelNoticeEnglish.setUrl(
R.string.green_certificate_attribute_certificate_travel_notice_english,
R.string.green_certificate_travel_notice_link_en,
R.string.green_certificate_travel_notice_link_en
)
}
}
private fun FragmentCovidCertificateDetailsBinding.bindToolbar() = toolbar.apply {
setNavigationOnClickListener { popBackStack() }
setOnMenuItemClickListener {
when (it.itemId) {
R.id.menu_covid_certificate_delete -> {
DialogHelper.showDialog(deleteTestConfirmationDialog)
true
}
else -> onOptionsItemSelected(it)
}
}
}
private fun setToolbarOverlay() {
val width = requireContext().resources.displayMetrics.widthPixels
val params: CoordinatorLayout.LayoutParams = binding.scrollView.layoutParams as (CoordinatorLayout.LayoutParams)
val textParams = binding.subtitle.layoutParams as (LinearLayout.LayoutParams)
textParams.bottomMargin = (width / 3) + 170
binding.subtitle.requestLayout()
val behavior: AppBarLayout.ScrollingViewBehavior = params.behavior as (AppBarLayout.ScrollingViewBehavior)
behavior.overlayTop = (width / 3) + 170
}
private val deleteTestConfirmationDialog by lazy {
DialogHelper.DialogInstance(
requireActivity(),
R.string.green_certificate_details_dialog_remove_test_title,
R.string.green_certificate_details_dialog_remove_test_message,
R.string.green_certificate_details_dialog_remove_test_button_positive,
R.string.green_certificate_details_dialog_remove_test_button_negative,
positiveButtonFunction = {
viewModel.onDeleteTestConfirmed()
}
)
}
}
......@@ -8,12 +8,12 @@ import de.rki.coronawarnapp.util.viewmodel.CWAViewModelFactory
import de.rki.coronawarnapp.util.viewmodel.CWAViewModelKey
@Module
abstract class GreenCertificateDetailsModule {
abstract class CovidCertificateDetailsModule {
@Binds
@IntoMap
@CWAViewModelKey(GreenCertificateDetailsViewModel::class)
@CWAViewModelKey(CovidCertificateDetailsViewModel::class)
abstract fun greenCertificateDetailsFragment(
factory: GreenCertificateDetailsViewModel.Factory
factory: CovidCertificateDetailsViewModel.Factory
): CWAViewModelFactory<out CWAViewModel>
}
package de.rki.coronawarnapp.greencertificate.ui.certificates.details
sealed class GreenCertificateDetailsNavigation {
object Back : GreenCertificateDetailsNavigation()
data class FullQrCode(val qrCodeText: String) : GreenCertificateDetailsNavigation()
sealed class CovidCertificateDetailsNavigation {
object Back : CovidCertificateDetailsNavigation()
data class FullQrCode(val qrCodeText: String) : CovidCertificateDetailsNavigation()
}
package de.rki.coronawarnapp.greencertificate.ui.certificates.details
import android.graphics.Bitmap
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.asLiveData
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import de.rki.coronawarnapp.coronatest.TestCertificateRepository
import de.rki.coronawarnapp.coronatest.type.TestCertificateIdentifier
import de.rki.coronawarnapp.covidcertificate.test.TestCertificate
import de.rki.coronawarnapp.presencetracing.checkins.qrcode.QrCodeGenerator
import de.rki.coronawarnapp.util.coroutine.DispatcherProvider
import de.rki.coronawarnapp.util.ui.SingleLiveEvent
import de.rki.coronawarnapp.util.viewmodel.CWAViewModel
import de.rki.coronawarnapp.util.viewmodel.CWAViewModelFactory
import kotlinx.coroutines.flow.map
import timber.log.Timber
class CovidCertificateDetailsViewModel @AssistedInject constructor(
dispatcherProvider: DispatcherProvider,
@Assisted private val testCertificateIdentifier: TestCertificateIdentifier,
private val qrCodeGenerator: QrCodeGenerator,
private val testCertificateRepository: TestCertificateRepository
) : CWAViewModel(dispatcherProvider) {
private var qrCodeText: String? = null
private val bitmapStateData = MutableLiveData<Bitmap>()
val qrCode: LiveData<Bitmap> = bitmapStateData
val events = SingleLiveEvent<CovidCertificateDetailsNavigation>()
val errors = SingleLiveEvent<Throwable>()
val covidCertificate = testCertificateRepository.certificates.map { certificates ->
certificates.find { it.identifier == testCertificateIdentifier }?.toTestCertificate(null)
.also { generateQrCode(it) }
}.asLiveData(dispatcherProvider.Default)
fun onClose() = events.postValue(CovidCertificateDetailsNavigation.Back)
fun openFullScreen() = qrCodeText?.let { events.postValue(CovidCertificateDetailsNavigation.FullQrCode(it)) }
fun onDeleteTestConfirmed() = launch {
Timber.d("Removing Test Certificate=$testCertificateIdentifier")
testCertificateRepository.deleteCertificate(testCertificateIdentifier)
events.postValue(CovidCertificateDetailsNavigation.Back)
}
private fun generateQrCode(testCertificate: TestCertificate?) = launch {
try {
bitmapStateData.postValue(
testCertificate?.let { certificate ->
qrCodeGenerator.createQrCode(certificate.qrCode.also { qrCodeText = it })
}
)
} catch (e: Exception) {
Timber.d(e, "generateQrCode failed for covidCertificate=%s", testCertificateIdentifier)
bitmapStateData.postValue(null)
errors.postValue(e)
}
}
@AssistedFactory
interface Factory : CWAViewModelFactory<CovidCertificateDetailsViewModel> {
fun create(testCertificateIdentifier: TestCertificateIdentifier): CovidCertificateDetailsViewModel
}
}
package de.rki.coronawarnapp.greencertificate.ui.certificates.details
import android.os.Bundle
import android.view.View
import android.widget.LinearLayout
import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.fragment.app.Fragment
import com.google.android.material.appbar.AppBarLayout
import de.rki.coronawarnapp.R
import de.rki.coronawarnapp.databinding.FragmentGreencertificateDetailsBinding
import de.rki.coronawarnapp.ui.view.onOffsetChange
import de.rki.coronawarnapp.util.di.AutoInject
import de.rki.coronawarnapp.util.setUrl
import de.rki.coronawarnapp.util.ui.popBackStack
import de.rki.coronawarnapp.util.ui.viewBinding
import de.rki.coronawarnapp.util.viewmodel.CWAViewModelFactoryProvider
import de.rki.coronawarnapp.util.viewmodel.cwaViewModels
import javax.inject.Inject
class GreenCertificateDetailsFragment : Fragment(R.layout.fragment_greencertificate_details), AutoInject {
@Inject lateinit var viewModelFactory: CWAViewModelFactoryProvider.Factory
private val binding: FragmentGreencertificateDetailsBinding by viewBinding()
private val viewModel: GreenCertificateDetailsViewModel by cwaViewModels { viewModelFactory }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) =
with(binding) {
toolbar.setNavigationOnClickListener { popBackStack() }
qrCodeCard.title.text = getString(R.string.detail_green_certificate_card_title)
qrCodeCard.subtitle.text = "Test durchgeführt am 12.05.21 18:01" // will be changed
appBarLayout.onOffsetChange { titleAlpha, subtitleAlpha ->
title.alpha = titleAlpha
subtitle.alpha = subtitleAlpha
}
if (travelNoticeGerman.text ==
requireContext().getString(R.string.green_certificate_attribute_certificate_travel_notice_german)
) {
travelNoticeGerman.setUrl(
R.string.green_certificate_attribute_certificate_travel_notice_german,
R.string.green_certificate_travel_notice_link_de,
R.string.green_certificate_travel_notice_link_de
)
}
if (travelNoticeEnglish.text ==
requireContext().getString(R.string.green_certificate_attribute_certificate_travel_notice_english)
) {
travelNoticeEnglish.setUrl(
R.string.green_certificate_attribute_certificate_travel_notice_english,
R.string.green_certificate_travel_notice_link_en,
R.string.green_certificate_travel_notice_link_en
)
}
setToolbarOverlay()
viewModel.qrCode.observe(viewLifecycleOwner) {
qrCodeCard.image.setImageBitmap(it)
it?.let {
qrCodeCard.image.setOnClickListener { viewModel.openFullScreen() }
qrCodeCard.progressBar.hide()
}
}
// TODO: Will in the future be called when the data is loaded from the database
viewModel.generateQrCode()
}
private fun setToolbarOverlay() {
val width = requireContext().resources.displayMetrics.widthPixels
val params: CoordinatorLayout.LayoutParams = binding.scrollView.layoutParams
as (CoordinatorLayout.LayoutParams)
val textParams = binding.subtitle.layoutParams as (LinearLayout.LayoutParams)
textParams.bottomMargin = (width / 3) + 170
binding.subtitle.requestLayout()
val behavior: AppBarLayout.ScrollingViewBehavior = params.behavior as (AppBarLayout.ScrollingViewBehavior)
behavior.overlayTop = (width / 3) + 170
}
}
package de.rki.coronawarnapp.greencertificate.ui.certificates.details
import android.graphics.Bitmap
import androidx.lifecycle.asLiveData
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import de.rki.coronawarnapp.presencetracing.checkins.qrcode.QrCodeGenerator
import de.rki.coronawarnapp.util.coroutine.DispatcherProvider
import de.rki.coronawarnapp.util.ui.SingleLiveEvent
import de.rki.coronawarnapp.util.viewmodel.CWAViewModel
import de.rki.coronawarnapp.util.viewmodel.SimpleCWAViewModelFactory
import kotlinx.coroutines.flow.MutableStateFlow
import timber.log.Timber
class GreenCertificateDetailsViewModel @AssistedInject constructor(
private val qrCodeGenerator: QrCodeGenerator,
dispatcherProvider: DispatcherProvider,
) : CWAViewModel(dispatcherProvider) {
private var qrCodeText: String? = null
private val mutableStateFlow = MutableStateFlow<Bitmap?>(null)
val qrCode = mutableStateFlow.asLiveData(dispatcherProvider.Default)
val events = SingleLiveEvent<GreenCertificateDetailsNavigation>()
fun onClose() = events.postValue(GreenCertificateDetailsNavigation.Back)
fun openFullScreen() = qrCodeText?.let { events.postValue(GreenCertificateDetailsNavigation.FullQrCode(it)) }
/* TODO: Adapt to Green Certificate */
fun generateQrCode() = launch {
try {
mutableStateFlow.value = qrCodeGenerator.createQrCode("Sample String")
} catch (e: Exception) {
Timber.d(e, "generateQrCode failed for greenCertificate=%s", "Sample Certificate")
mutableStateFlow.value = null
}
}
@AssistedFactory
interface Factory : SimpleCWAViewModelFactory<GreenCertificateDetailsViewModel>
}
......@@ -5,7 +5,7 @@ import dagger.Module
import dagger.android.ContributesAndroidInjector
import dagger.multibindings.IntoMap
import de.rki.coronawarnapp.datadonation.analytics.ui.AnalyticsUIModule
import de.rki.coronawarnapp.greencertificate.ui.GreenCertificateUIModule
import de.rki.coronawarnapp.greencertificate.ui.CovidCertificateUIModule
import de.rki.coronawarnapp.release.NewReleaseInfoFragment
import de.rki.coronawarnapp.release.NewReleaseInfoFragmentModule
import de.rki.coronawarnapp.tracing.ui.details.TracingDetailsFragmentModule
......@@ -42,7 +42,7 @@ import de.rki.coronawarnapp.vaccination.ui.VaccinationUIModule
PresenceTracingUIModule::class,
RATProfileUIModule::class,
VaccinationUIModule::class,
GreenCertificateUIModule::class,
CovidCertificateUIModule::class,
]
)
abstract class MainActivityModule {
......
......@@ -25,6 +25,7 @@ object TimeAndDateExtensions {
private val dayFormatter = DateTimeFormat.forPattern("dd.MM.yyyy")
private val dayFormatter2DigitYear = DateTimeFormat.forPattern("dd.MM.yy")
private val shortTime = DateTimeFormat.shortTime()
fun getCurrentHourUTC(): Int = DateTime(Instant.now(), DateTimeZone.UTC).hourOfDay().get()
......@@ -119,6 +120,16 @@ object TimeAndDateExtensions {
*/
fun LocalDate.toDayFormat(): String = toString(dayFormatter)
/**
* Returns a readable time String with the format "hh:mm" like 12:00 of a LocalDate
*/
fun LocalDate.toShortTimeFormat(): String = toString(shortTime)
/**
* Returns a readable time String with the format "hh:mm" like 12:00 of a LocalDate
*/
fun Instant.toShortTimeFormat(): String = toString(shortTime)
/**
* Returns a readable date String with the format "dd.MM.yy" like 23.05.89 of an Instant
*/
......
......@@ -44,10 +44,10 @@
android:layout_marginTop="90dp"
android:layout_marginBottom="12dp"
android:gravity="center"
android:text="@string/detail_green_certificate_title"
android:textColor="@android:color/white"
android:textSize="20sp"
android:textStyle="bold"
android:text="@string/detail_green_certificate_title"/>
android:textStyle="bold" />
<TextView
android:id="@+id/subtitle"
......@@ -59,7 +59,7 @@
android:gravity="center"
android:text="@string/detail_green_certificate_test_type"
android:textColor="@android:color/white"
android:textSize="18sp"/>
android:textSize="18sp" />
</LinearLayout>
......@@ -67,8 +67,10 @@
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:theme="@style/CWAToolbar.Theme"
app:layout_collapseMode="pin"
app:layout_scrollFlags="scroll|enterAlways"
app:menu="@menu/menu_covid_certificate_detail"
app:navigationIcon="@drawable/ic_back"
app:navigationIconTint="@android:color/white">
......@@ -82,7 +84,7 @@
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="72dp"
android:layout_marginEnd="32dp"
android:importantForAccessibility="no"
app:srcCompat="@drawable/ic_cwa_logo_white" />
......@@ -115,7 +117,7 @@
android:layout_marginBottom="6dp" />
<LinearLayout
style="@style/Card.Greencertificate"
style="@style/Card.GreenCertificate"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
......@@ -134,7 +136,6 @@
style="@style/body1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Andrea Schneider"
tools:text="Andrea Schneider" />
<TextView
......@@ -150,7 +151,6 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:text="18.04.1943"
tools:text="18.04.1943" />
<TextView
......@@ -166,7 +166,6 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:text="SARS-CoV-2"
tools:text="SARS-CoV-2" />
<TextView
......@@ -182,7 +181,6 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:text="Rapid Antigen Test"
tools:text="Rapid Antigen Test" />
<TextView
......@@ -193,12 +191,11 @@
android:text="@string/green_certificate_attribute_test_name" />
<TextView
android:id="@+id/medical_product_name"
android:id="@+id/test_name"
style="@style/body1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:text="Xep"
tools:text="Xep" />
<TextView
......@@ -214,7 +211,6 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:text="Xup"
tools:text="Xup" />
<TextView
......@@ -230,7 +226,6 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:text="12.05.21 19:00"
tools:text="12.05.21 19:00" />
<TextView
......@@ -246,7 +241,6 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:text="negative"
tools:text="negative" />
<TextView
......@@ -262,7 +256,6 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:text="AB123"
tools:text="AB123" />
<TextView
......@@ -273,12 +266,11 @@
android:text="@string/green_certificate_attribute_state_of_testing" />
<TextView
android:id="@+id/test_country"
android:id="@+id/certificate_country"
style="@style/body1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:text="Germany"
tools:text="Germany" />
<TextView
......@@ -294,7 +286,6 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:text="G05930482748454836478695764787840"
tools:text="G05930482748454836478695764787840" />
......@@ -311,14 +302,13 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:text="05930482748454836478695764787840"
tools:text="05930482748454836478695764787840" />
</LinearLayout>
<LinearLayout
style="@style/Card.Greencertificate"
style="@style/Card.GreenCertificate"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
......@@ -332,7 +322,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:text="@string/green_certificate_attribute_certificate_travel_notice_german"/>
android:text="@string/green_certificate_attribute_certificate_travel_notice_german" />
<TextView
android:id="@+id/travel_notice_english"
......@@ -340,7 +330,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:text="@string/green_certificate_attribute_certificate_travel_notice_english"/>
android:text="@string/green_certificate_attribute_certificate_travel_notice_english" />
</LinearLayout>
</LinearLayout>
......
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/menu_covid_certificate_delete"
android:title="@string/green_certificate_details_menu_item_delete" />
</menu>
......@@ -9,11 +9,14 @@
android:id="@+id/certificatesFragment"
android:name="de.rki.coronawarnapp.greencertificate.ui.certificates.CertificatesFragment"
android:label="fragment_certificates"
tools:layout="@layout/fragment_certificates" >
tools:layout="@layout/fragment_certificates">
<action
android:id="@+id/action_certificatesFragment_to_vaccinationNavGraph"
app:destination="@id/vaccination_nav_graph" />
<action
android:id="@+id/action_certificatesFragment_to_covidCertificateDetailsFragment"
app:destination="@id/covidCertificateDetailsFragment" />
</fragment>
......@@ -21,7 +24,7 @@
android:id="@+id/vaccinationConsentFragment"
android:name="de.rki.coronawarnapp.vaccination.ui.consent.VaccinationConsentFragment"
android:label="vaccination_consent_fragment"
tools:layout="@layout/vaccination_consent_fragment" >
tools:layout="@layout/vaccination_consent_fragment">
<argument
android:name="showBottomNav"
android:defaultValue="true"
......@@ -42,4 +45,14 @@
android:label="privacyFragment"
tools:layout="@layout/fragment_information_privacy" />
<fragment
android:id="@+id/covidCertificateDetailsFragment"
android:name="de.rki.coronawarnapp.greencertificate.ui.certificates.details.CovidCertificateDetailsFragment"
android:label="CovidCertificateDetailsFragment"
tools:layout="@layout/fragment_covid_certificate_details">
<argument
android:name="testCertificateIdentifier"
app:argType="string" />
</fragment>
</navigation>
\ No newline at end of file
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