From 4131fcfeac7ba5447f53d6fdbe8282c81e2cd9a7 Mon Sep 17 00:00:00 2001 From: Publiccode bot <> Date: Tue, 2 Nov 2021 17:42:39 +0000 Subject: [PATCH 01/10] feat: bump publiccode.yml to version 1.1.6 --- publiccode.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/publiccode.yml b/publiccode.yml index e63d1de1..9f436f47 100644 --- a/publiccode.yml +++ b/publiccode.yml @@ -2,9 +2,9 @@ publiccodeYmlVersion: "0.2" applicationSuite: it-dgc url: "https://github.com/ministero-salute/it-dgc-verificaC19-android" name: VerificaC19 -releaseDate: '2021-10-19' +releaseDate: '2021-10-21' softwareType: standalone/mobile -softwareVersion: 1.1.3 +softwareVersion: 1.1.6 developmentStatus: stable logo: logo.png platforms: From 2b03140bfb3f13ef63027527723f0bff213717cc Mon Sep 17 00:00:00 2001 From: Andrea Stagi Date: Wed, 3 Nov 2021 11:49:50 +0100 Subject: [PATCH 02/10] fix: setting urls --- .../ministerodellasalute/verificaC19/ui/SettingsActivity.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/it/ministerodellasalute/verificaC19/ui/SettingsActivity.kt b/app/src/main/java/it/ministerodellasalute/verificaC19/ui/SettingsActivity.kt index 5fba2452..bd2e5705 100644 --- a/app/src/main/java/it/ministerodellasalute/verificaC19/ui/SettingsActivity.kt +++ b/app/src/main/java/it/ministerodellasalute/verificaC19/ui/SettingsActivity.kt @@ -64,12 +64,12 @@ class SettingsActivity : AppCompatActivity(), View.OnClickListener { viewModel.setTotemMode(binding.totemSwitch.isChecked) } else if (v?.id == R.id.faq_card) { val browserIntent = - Intent(Intent.ACTION_VIEW, Uri.parse("https://www.dgc.gov.it/web/pn.html")) + Intent(Intent.ACTION_VIEW, Uri.parse("https://www.dgc.gov.it/web/faq.html")) startActivity(browserIntent) } else if (v?.id == R.id.privacy_policy_card) { val browserIntent = - Intent(Intent.ACTION_VIEW, Uri.parse("https://www.dgc.gov.it/web/faq.html")) + Intent(Intent.ACTION_VIEW, Uri.parse("https://www.dgc.gov.it/web/pn.html")) startActivity(browserIntent) } } -} \ No newline at end of file +} From b5921094d2b49b0e7aee364e7d0e7263dc106f0b Mon Sep 17 00:00:00 2001 From: Giuseppe Criscione Date: Thu, 4 Nov 2021 16:53:48 +0100 Subject: [PATCH 03/10] fix: typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5f50dcef..7dc09e9a 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ android-app #### Android Studio based build -Modifiy `app\build.gradle` file, changing `BASE_URL`, `SERVER_HOST` and `CERTIFICATE_SHA` `debug` config values with `release` config values. [Here](https://github.com/ministero-salute/it-dgc-documentation/blob/master/openapi.yaml) you can find more info on app's endpoints. +Modify `app\build.gradle` file, changing `BASE_URL`, `SERVER_HOST` and `CERTIFICATE_SHA` `debug` config values with `release` config values. [Here](https://github.com/ministero-salute/it-dgc-documentation/blob/master/openapi.yaml) you can find more info on app's endpoints. This project uses the Gradle build system. To build this project, use the `gradlew build` command or use `"Run"` in Android Studio. From 400f5d23cdccd81b663d7a722c76d8215ea91e96 Mon Sep 17 00:00:00 2001 From: Light2288 Date: Tue, 9 Nov 2021 15:11:27 +0100 Subject: [PATCH 04/10] target sdk 30 --- buildSrc/src/main/java/AppConfig.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/java/AppConfig.kt b/buildSrc/src/main/java/AppConfig.kt index c46bced7..0a45709a 100644 --- a/buildSrc/src/main/java/AppConfig.kt +++ b/buildSrc/src/main/java/AppConfig.kt @@ -25,7 +25,7 @@ import org.gradle.api.JavaVersion object Config { const val minSdk = 24 const val compileSdk = 29 - const val targetSdk = 29 + const val targetSdk = 30 val javaVersion = JavaVersion.VERSION_1_8 const val versionCode = 13 From 3ec071528d85d7fc6854d49402d7940bab1c71f9 Mon Sep 17 00:00:00 2001 From: "Nicola M. Cornelio" <80268479+nicola-95@users.noreply.github.com> Date: Thu, 11 Nov 2021 14:33:17 +0100 Subject: [PATCH 05/10] feat: add revokes with sdk * Modify WIP added external project * WIP * WIP * WIP * WIP initial build * WIP modify added time methods * Modify changed in gradle * WIP added back workmanager * Modify added Workmanager method * Modify added gitignore * Modify dir path * Delete TimeExt.kt from app. * Modify handle MinSDKversionException Add createForceUpdateDialog if version is below REST response * Modify remove configs * Modify disable signingconfigs * Modify use simple cer model from SDK * Modify added required realm classpath * Add progress bar. * Update the progress bar. * Improve progress bar behaviour. * Modify add max value to progress bar from API * Modify WIP * Modify call workmanager from firstactivity * Modify WIP resume button * Modify fix progress bar max. * Modify add last chunk in init * Modify WIP resume button. * Modify resume button logic * Modify WIP progress bar and buttons. * Modify WIP first activity. * Modify isPendingDL controls * Optimize first activity code. * Update first activity code. * Modify handle network down situation * Add Alert Dialog for big download * Add certificate revoked text * refractor: change strings and texts initialization * feature: add drl last sync date check * refactor: change alert dialog initialization * refactor: change total chunks size initialization * refactor: simplify alert dialog initialization * feature: check for debug variant * feature: show dialog for drl inconsistency * fix: modify chunk_size string placeholder type * Add check drl sync active * Fix byte to megabyte conversion * fix: modify first activity for resuming revokes download * fix: revokes download progress * fix: modify download button attributes * refactor and fix * Refactor & fix starting chunk status * PrefKeys refactor * Duplicated FAQ issue * Current Chunk fix * CurrentChunk fix * feature: add max retry check * refactor: modify drl download check * feature: add internet connection check * feature: add no internet alert dialog * feat revokes fix to perform last consistency check * refactor: create strings values * feat: increase min app version Co-authored-by: daniels <> Co-authored-by: danielsp3000 Co-authored-by: Simone Co-authored-by: ios-developer-123 <84391009+ios-developer-123@users.noreply.github.com> Co-authored-by: Light2288 --- .../verificaC19/VerificaApplication.kt | 3 +- .../verificaC19/ui/FirstActivity.kt | 274 ++++++++++++++++-- .../main/verification/VerificationFragment.kt | 49 ++-- app/src/main/res/layout/activity_first.xml | 110 ++++++- app/src/main/res/values/strings.xml | 17 ++ build.gradle | 2 +- 6 files changed, 399 insertions(+), 56 deletions(-) diff --git a/app/src/main/java/it/ministerodellasalute/verificaC19/VerificaApplication.kt b/app/src/main/java/it/ministerodellasalute/verificaC19/VerificaApplication.kt index e349ea0a..00fc71d6 100644 --- a/app/src/main/java/it/ministerodellasalute/verificaC19/VerificaApplication.kt +++ b/app/src/main/java/it/ministerodellasalute/verificaC19/VerificaApplication.kt @@ -23,6 +23,7 @@ package it.ministerodellasalute.verificaC19 import android.app.Application +import android.content.SharedPreferences import androidx.hilt.work.HiltWorkerFactory import androidx.work.* import dagger.hilt.android.HiltAndroidApp @@ -48,7 +49,7 @@ class VerificaApplication : Application(), Configuration.Provider { setWorkManager() } - private fun setWorkManager(){ + fun setWorkManager(){ val uploadWorkRequest: WorkRequest = PeriodicWorkRequestBuilder(1, TimeUnit.DAYS) .setConstraints(Constraints.Builder() diff --git a/app/src/main/java/it/ministerodellasalute/verificaC19/ui/FirstActivity.kt b/app/src/main/java/it/ministerodellasalute/verificaC19/ui/FirstActivity.kt index 4ec5b8c7..7967aafb 100644 --- a/app/src/main/java/it/ministerodellasalute/verificaC19/ui/FirstActivity.kt +++ b/app/src/main/java/it/ministerodellasalute/verificaC19/ui/FirstActivity.kt @@ -23,7 +23,9 @@ package it.ministerodellasalute.verificaC19.ui import android.Manifest import android.content.ActivityNotFoundException +import android.content.Context import android.content.Intent +import android.content.SharedPreferences import android.content.pm.PackageManager import android.graphics.Typeface import android.net.Uri @@ -31,6 +33,7 @@ import android.os.Bundle import android.text.SpannableString import android.text.style.StyleSpan import android.text.style.UnderlineSpan +import android.util.Log import android.view.View import android.view.WindowManager import androidx.activity.result.contract.ActivityResultContracts @@ -42,20 +45,28 @@ import androidx.lifecycle.observe import dagger.hilt.android.AndroidEntryPoint import it.ministerodellasalute.verificaC19.BuildConfig import it.ministerodellasalute.verificaC19.R +import it.ministerodellasalute.verificaC19.VerificaApplication import it.ministerodellasalute.verificaC19.databinding.ActivityFirstBinding import it.ministerodellasalute.verificaC19.ui.main.MainActivity -import it.ministerodellasalute.verificaC19sdk.util.Utility +import it.ministerodellasalute.verificaC19sdk.data.local.PrefKeys import it.ministerodellasalute.verificaC19sdk.model.FirstViewModel +import it.ministerodellasalute.verificaC19sdk.util.ConversionUtility import it.ministerodellasalute.verificaC19sdk.util.FORMATTED_DATE_LAST_SYNC import it.ministerodellasalute.verificaC19sdk.util.TimeUtility.parseTo +import it.ministerodellasalute.verificaC19sdk.util.Utility + @AndroidEntryPoint -class FirstActivity : AppCompatActivity(), View.OnClickListener { +class FirstActivity : AppCompatActivity(), View.OnClickListener, + SharedPreferences.OnSharedPreferenceChangeListener { private lateinit var binding: ActivityFirstBinding + private lateinit var shared: SharedPreferences private val viewModel by viewModels() + private val verificaApplication = VerificaApplication() + private val requestPermissionLauncher = registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted: Boolean -> if (isGranted) { @@ -82,32 +93,63 @@ class FirstActivity : AppCompatActivity(), View.OnClickListener { it.setSpan(StyleSpan(Typeface.BOLD), 0, it.length, 0) } binding.versionText.text = spannableString + binding.dateLastSyncText.text = getString(R.string.loading) - viewModel.getDateLastSync().let { - binding.dateLastSyncText.text = getString( - R.string.lastSyncDate, - if (it == -1L) getString(R.string.notAvailable) else it.parseTo( - FORMATTED_DATE_LAST_SYNC - ) - ) + binding.updateProgressBar.max = viewModel.getTotalChunk().toInt() + updateDownloadedPackagesCount() + Log.i("viewModel.getauthorizedToDownload()", viewModel.getDownloadAvailable().toString()) + viewModel.getDownloadAvailable().let { isAuthorizedToDownload -> + + if (isAuthorizedToDownload == 0L && !viewModel.getIsPendingDownload()) + binding.initDownload.visibility = View.VISIBLE + else { + binding.initDownload.visibility = View.GONE + } } + Log.i("viewModel.getAuthResume()", viewModel.getResumeAvailable().toString()) + + viewModel.getResumeAvailable().let { + if (it == 0.toLong() || viewModel.getIsPendingDownload()) { + binding.resumeDownload.visibility = View.VISIBLE + binding.dateLastSyncText.text = getString(R.string.incompleteDownload) + binding.chunkCount.visibility = View.VISIBLE + binding.chunkSize.visibility = View.VISIBLE + binding.updateProgressBar.visibility = View.VISIBLE + } else { + binding.resumeDownload.visibility = View.GONE + } + } + + shared = this.getSharedPreferences("dgca.verifier.app.pref", Context.MODE_PRIVATE) + Log.i("Shared Preferences Info", shared.toString()) viewModel.fetchStatus.observe(this) { if (it) { - binding.qrButton.isEnabled = false - binding.dateLastSyncText.text = getString(R.string.loading) + //binding.qrButton.isEnabled = false + binding.qrButton.background.alpha = 128 } else { - binding.qrButton.isEnabled = true - viewModel.getDateLastSync().let { date -> - binding.dateLastSyncText.text = getString( - R.string.lastSyncDate, - if (date == -1L) getString(R.string.notAvailable) else date.parseTo( - FORMATTED_DATE_LAST_SYNC + if (!viewModel.getIsPendingDownload() && viewModel.maxRetryReached.value == false) { + viewModel.getDateLastSync().let { date -> + binding.dateLastSyncText.text = getString( + R.string.lastSyncDate, + if (date == -1L) getString(R.string.notAvailable) else date.parseTo( + FORMATTED_DATE_LAST_SYNC + ) ) - ) + } + //binding.qrButton.isEnabled = true + binding.qrButton.background.alpha = 255 + hideRevokesDownloadViews() } } } + + viewModel.maxRetryReached.observe(this) { + if (it) { + enableInitDownload() + } + } + binding.privacyPolicyCard.setOnClickListener { val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse("https://www.dgc.gov.it/web/pn.html")) @@ -118,8 +160,44 @@ class FirstActivity : AppCompatActivity(), View.OnClickListener { Intent(Intent.ACTION_VIEW, Uri.parse("https://www.dgc.gov.it/web/faq.html")) startActivity(browserIntent) } + binding.initDownload.setOnClickListener { + if (Utility.isOnline(this)) { + prepareForDownload() + binding.initDownload.visibility = View.GONE + binding.dateLastSyncText.text = getString(R.string.updatingRevokedPass) + startSyncData() + } else { + createCheckConnectionAlertDialog() + } + } + + binding.resumeDownload.setOnClickListener { + if (Utility.isOnline(this)) { + viewModel.setResumeAsAvailable() + binding.resumeDownload.visibility = View.GONE + binding.dateLastSyncText.text = getString(R.string.updatingRevokedPass) + startSyncData() + } else { + createCheckConnectionAlertDialog() + } + } + + + } + + private fun createCheckConnectionAlertDialog() { + val builder = AlertDialog.Builder(this) + var dialog: AlertDialog? = null + builder.setTitle( + getString(R.string.no_internet_title) + ) + builder.setMessage(getString(R.string.no_internet_message)) + builder.setPositiveButton(getString(R.string.ok_label)) { _, _ -> } + dialog = builder.create() + dialog.show() } + private fun checkCameraPermission() { if (ContextCompat.checkSelfPermission( this, @@ -149,11 +227,75 @@ class FirstActivity : AppCompatActivity(), View.OnClickListener { } } + private fun createDownloadAlert() { + try { + val builder = AlertDialog.Builder(this) + var dialog: AlertDialog? = null + builder.setTitle( + getString( + R.string.titleDownloadAlert, + ConversionUtility.byteToMegaByte(viewModel.getTotalSizeInByte().toFloat()) + ) + ) + builder.setMessage(getString(R.string.messageDownloadAlert)) + builder.setPositiveButton(getString(R.string.label_download)) { _, _ -> + dialog?.dismiss() + if (Utility.isOnline(this)) { + prepareForDownload() + binding.dateLastSyncText.text = getString(R.string.updatingRevokedPass) + startSyncData() + } else { + createCheckConnectionAlertDialog() + enableInitDownload() + } + } + builder.setNegativeButton(getString(R.string.after_download)) { _, _ -> + enableInitDownload() + dialog?.dismiss() + } + dialog = builder.create() + dialog.setCanceledOnTouchOutside(false) + dialog.setCancelable(false) + dialog.show() + } catch (e: Exception) { + } + } + + private fun prepareForDownload() { + viewModel.resetCurrentRetry() + viewModel.setShouldInitDownload(true) + viewModel.setDownloadAsAvailable() + } + + private fun startSyncData() { + verificaApplication.setWorkManager() + } + + private fun enableInitDownload() { + binding.resumeDownload.visibility = View.GONE + binding.initDownload.visibility = View.VISIBLE + hideRevokesDownloadViews() + binding.dateLastSyncText.text = when (viewModel.getTotalSizeInByte()) { + 0L -> getString( + R.string.label_download_alert_simple + ) + + else -> + getString( + R.string.titleDownloadAlert, + ConversionUtility.byteToMegaByte(viewModel.getTotalSizeInByte().toFloat()) + ) + } + } override fun onResume() { super.onResume() viewModel.getAppMinVersion().let { - if (Utility.versionCompare(it, BuildConfig.VERSION_NAME) > 0 || viewModel.isSDKVersionObsoleted()) { + if (Utility.versionCompare( + it, + BuildConfig.VERSION_NAME + ) > 0 || viewModel.isSDKVersionObsoleted() + ) { createForceUpdateDialog() } } @@ -172,7 +314,16 @@ class FirstActivity : AppCompatActivity(), View.OnClickListener { override fun onClick(v: View?) { viewModel.getDateLastSync().let { if (it == -1L) { - createNoKeyAlert() + createNoSyncAlertDialog(getString(R.string.noKeyAlertMessage)) + return + } + } + viewModel.getDrlDateLastSync().let { + if (viewModel.getIsDrlSyncActive() && it == -1L) { + createNoSyncAlertDialog(getString(R.string.messageDownloadStarted)) + return + } else if (viewModel.getIsDrlSyncActive() && System.currentTimeMillis() >= it + 24 * 60 * 60 * 1000) { + createNoSyncAlertDialog(getString(R.string.noKeyAlertMessageForDrl)) return } } @@ -182,10 +333,10 @@ class FirstActivity : AppCompatActivity(), View.OnClickListener { } } - private fun createNoKeyAlert() { + private fun createNoSyncAlertDialog(alertMessage: String) { val builder = AlertDialog.Builder(this) builder.setTitle(getString(R.string.noKeyAlertTitle)) - builder.setMessage(getString(R.string.noKeyAlertMessage)) + builder.setMessage(alertMessage) builder.setPositiveButton(getString(R.string.ok)) { dialog, which -> } val dialog = builder.create() @@ -218,4 +369,81 @@ class FirstActivity : AppCompatActivity(), View.OnClickListener { } } -} \ No newline at end of file + override fun onStart() { + super.onStart() + shared.registerOnSharedPreferenceChangeListener(this) + } + + override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) { + if (key != null) { + when (key) { + PrefKeys.CURRENT_CHUNK -> { + updateDownloadedPackagesCount() + Log.i(key.toString(), viewModel.getCurrentChunk().toString()) + } + PrefKeys.KEY_TOTAL_CHUNK -> { + val totalChunk = viewModel.getTotalChunk().toInt() + binding.updateProgressBar.max = totalChunk + binding.updateProgressBar.visibility = View.VISIBLE + binding.chunkCount.visibility = View.VISIBLE + binding.chunkSize.visibility = View.VISIBLE + updateDownloadedPackagesCount() + Log.i("total_chunk", totalChunk.toString()) + } + PrefKeys.AUTH_TO_RESUME -> { + val authToResume = viewModel.getResumeAvailable().toInt() + Log.i("auth_to_resume", authToResume.toString()) + + if (viewModel.getResumeAvailable() == 0L) { + binding.resumeDownload.visibility = View.VISIBLE + } + } + PrefKeys.KEY_SIZE_OVER_THRESHOLD -> { + val isSizeOverThreshold = viewModel.getIsSizeOverThreshold() + if (isSizeOverThreshold) { + createDownloadAlert() + } + } + PrefKeys.KEY_DRL_DATE_LAST_FETCH -> { + viewModel.getDateLastSync().let { date -> + binding.dateLastSyncText.text = getString( + R.string.lastSyncDate, + if (date == -1L) getString(R.string.notAvailable) else date.parseTo( + FORMATTED_DATE_LAST_SYNC + ) + ) + } + hideRevokesDownloadViews() + } + else -> { + + } + } + } + } + + private fun hideRevokesDownloadViews() { + binding.updateProgressBar.visibility = View.GONE + binding.chunkCount.visibility = View.GONE + binding.chunkSize.visibility = View.GONE + } + + override fun onDestroy() { + super.onDestroy() + shared.unregisterOnSharedPreferenceChangeListener(this) + } + + private fun updateDownloadedPackagesCount() { + val lastDownloadedChunk = viewModel.getCurrentChunk().toInt() + val lastChunk = viewModel.getTotalChunk().toInt() + val singleChunkSize = viewModel.getSizeSingleChunkInByte() + + binding.updateProgressBar.progress = lastDownloadedChunk + binding.chunkCount.text = getString(R.string.chunk_count, lastDownloadedChunk, lastChunk) + binding.chunkSize.text = getString( + R.string.chunk_size, + ConversionUtility.byteToMegaByte((lastDownloadedChunk * singleChunkSize.toFloat())), + ConversionUtility.byteToMegaByte(viewModel.getTotalSizeInByte().toFloat()) + ) + } +} diff --git a/app/src/main/java/it/ministerodellasalute/verificaC19/ui/main/verification/VerificationFragment.kt b/app/src/main/java/it/ministerodellasalute/verificaC19/ui/main/verification/VerificationFragment.kt index 7668912f..492bd128 100644 --- a/app/src/main/java/it/ministerodellasalute/verificaC19/ui/main/verification/VerificationFragment.kt +++ b/app/src/main/java/it/ministerodellasalute/verificaC19/ui/main/verification/VerificationFragment.kt @@ -20,9 +20,6 @@ package it.ministerodellasalute.verificaC19.ui.main.verification -import android.content.ActivityNotFoundException -import android.content.Intent -import android.net.Uri import android.os.Bundle import android.os.Handler import android.util.Log @@ -38,13 +35,11 @@ import androidx.lifecycle.observe import androidx.navigation.fragment.findNavController import androidx.navigation.fragment.navArgs import dagger.hilt.android.AndroidEntryPoint -import it.ministerodellasalute.verificaC19.* +import it.ministerodellasalute.verificaC19.BuildConfig +import it.ministerodellasalute.verificaC19.R import it.ministerodellasalute.verificaC19.databinding.FragmentVerificationBinding -import it.ministerodellasalute.verificaC19.ui.FirstActivity import it.ministerodellasalute.verificaC19.ui.compounds.QuestionCompound -import it.ministerodellasalute.verificaC19.ui.main.MainActivity -import it.ministerodellasalute.verificaC19sdk.VerificaMinSDKVersionException -import it.ministerodellasalute.verificaC19sdk.VerificaMinVersionException +import it.ministerodellasalute.verificaC19sdk.* import it.ministerodellasalute.verificaC19sdk.model.CertificateSimple import it.ministerodellasalute.verificaC19sdk.model.CertificateStatus import it.ministerodellasalute.verificaC19sdk.model.SimplePersonModel @@ -84,7 +79,8 @@ class VerificationFragment : Fragment(), View.OnClickListener { setupCertStatusView(it) setupTimeStamp(it) if (viewModel.getTotemMode() && (certificate.certificateStatus == CertificateStatus.VALID - || certificate.certificateStatus == CertificateStatus.PARTIALLY_VALID)) { + || certificate.certificateStatus == CertificateStatus.PARTIALLY_VALID) + ) { Handler().postDelayed({ activity?.onBackPressed() }, 5000) @@ -94,26 +90,24 @@ class VerificationFragment : Fragment(), View.OnClickListener { viewModel.inProgress.observe(viewLifecycleOwner) { binding.progressBar.isVisible = it } + try { viewModel.init(args.qrCodeText, true) - } - catch (e: VerificaMinSDKVersionException) - { + } catch (e: VerificaMinSDKVersionException) { Log.d("VerificationFragment", "Min SDK Version Exception") - createForceUpdateDialog() - } - catch (e: VerificaMinVersionException) - { + createForceUpdateDialog(getString(R.string.updateMessage)) + } catch (e: VerificaMinVersionException) { Log.d("VerificationFragment", "Min App Version Exception") - createForceUpdateDialog() + createForceUpdateDialog(getString(R.string.updateMessage)) + } catch (e: VerificaDownloadInProgressException) { + Log.d("VerificationFragment", "Download In Progress Exception") + createForceUpdateDialog(getString(R.string.messageDownloadStarted)) } - } private fun setupCertStatusView(cert: CertificateSimple) { - //val certStatus = viewModel.getCertificateStatus(cert) val certStatus = cert.certificateStatus - if (certStatus !=null) { + if (certStatus != null) { setBackgroundColor(certStatus) setPersonDetailsVisibility(certStatus) setValidationIcon(certStatus) @@ -130,10 +124,11 @@ class VerificationFragment : Fragment(), View.OnClickListener { FORMATTED_VALIDATION_DATE ) ) - binding.validationDate.visibility =View.VISIBLE + binding.validationDate.visibility = View.VISIBLE } private fun setLinkViews(certStatus: CertificateStatus) { + binding.questionContainer.removeAllViews() val questionMap: Map = when (certStatus) { CertificateStatus.VALID, CertificateStatus.PARTIALLY_VALID -> mapOf(getString(R.string.label_what_can_be_done) to "https://www.dgc.gov.it/web/faq.html#verifica19") CertificateStatus.NOT_VALID_YET -> mapOf(getString(R.string.label_when_qr_valid) to "https://www.dgc.gov.it/web/faq.html#verifica19") @@ -169,7 +164,13 @@ class VerificationFragment : Fragment(), View.OnClickListener { CertificateStatus.VALID -> getString(R.string.certificateValid) CertificateStatus.PARTIALLY_VALID -> getString(R.string.certificatePartiallyValid) CertificateStatus.NOT_EU_DCC -> getString(R.string.certificateNotDCC) - CertificateStatus.NOT_VALID -> getString(R.string.certificateNonValid) + CertificateStatus.NOT_VALID -> { + if (VerificaApplication.isCertificateRevoked && BuildConfig.DEBUG) { + getString(R.string.certificateRevoked) + } else { + getString(R.string.certificateNonValid) + } + } CertificateStatus.NOT_VALID_YET -> getString(R.string.certificateNonValidYet) } } @@ -224,10 +225,10 @@ class VerificationFragment : Fragment(), View.OnClickListener { _binding = null } - private fun createForceUpdateDialog() { + private fun createForceUpdateDialog(message: String) { val builder = this.activity?.let { AlertDialog.Builder(requireContext()) } builder!!.setTitle(getString(R.string.updateTitle)) - builder!!.setMessage(getString(R.string.updateMessage)) + builder!!.setMessage(message) builder.setPositiveButton(getString(R.string.ok)) { dialog, which -> findNavController().popBackStack() } diff --git a/app/src/main/res/layout/activity_first.xml b/app/src/main/res/layout/activity_first.xml index 54a1a772..a98b8bcf 100644 --- a/app/src/main/res/layout/activity_first.xml +++ b/app/src/main/res/layout/activity_first.xml @@ -117,15 +117,111 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="@id/spacing"> - + android:orientation="vertical"> + + + + + + + + + +