diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/SubmissionRepository.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/SubmissionRepository.kt index a81018bd088121ed7bc25eca0b133c732ef5e7c7..3190d0e48d53526dc44393b0a31e190ea60cd90d 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/SubmissionRepository.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/SubmissionRepository.kt @@ -58,6 +58,7 @@ object SubmissionRepository { TestResult.POSITIVE -> DeviceUIState.PAIRED_POSITIVE TestResult.PENDING -> DeviceUIState.PAIRED_NO_RESULT TestResult.INVALID -> DeviceUIState.PAIRED_ERROR + TestResult.REDEEMED -> DeviceUIState.PAIRED_REDEEMED } } catch (err: NoRegistrationTokenSetException) { return DeviceUIState.UNPAIRED diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/SubmissionTestResultFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/SubmissionTestResultFragment.kt index 41c8ace277433609dc6740c2fa531be9a8ca0273..03aecc8b20e2803224d0dcdb03772e76f2a3c42d 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/SubmissionTestResultFragment.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/SubmissionTestResultFragment.kt @@ -9,6 +9,7 @@ import android.view.accessibility.AccessibilityEvent import androidx.activity.OnBackPressedCallback import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels +import androidx.lifecycle.Observer import androidx.navigation.fragment.findNavController import de.rki.coronawarnapp.R import de.rki.coronawarnapp.databinding.FragmentSubmissionTestResultBinding @@ -18,6 +19,7 @@ import de.rki.coronawarnapp.exception.http.CwaWebException import de.rki.coronawarnapp.ui.doNavigate import de.rki.coronawarnapp.ui.viewmodel.SubmissionViewModel import de.rki.coronawarnapp.ui.viewmodel.TracingViewModel +import de.rki.coronawarnapp.util.DeviceUIState import de.rki.coronawarnapp.util.DialogHelper import de.rki.coronawarnapp.util.observeEvent @@ -115,6 +117,23 @@ class SubmissionTestResultFragment : Fragment() { submissionViewModel.uiStateError.observeEvent(viewLifecycleOwner) { DialogHelper.showDialog(buildErrorDialog(it)) } + + submissionViewModel.deviceUiState.observe(viewLifecycleOwner, Observer { uiState -> + if (uiState == DeviceUIState.PAIRED_REDEEMED) { + showRedeemedTokenWarningDialog() + } + }) + } + + private fun showRedeemedTokenWarningDialog() { + val dialog = DialogHelper.DialogInstance( + requireActivity(), + R.string.submission_error_dialog_web_tan_redeemed_title, + R.string.submission_error_dialog_web_tan_redeemed_body, + R.string.submission_error_dialog_web_tan_redeemed_button_positive + ) + + DialogHelper.showDialog(dialog) } override fun onResume() { diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/DeviceUIState.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/DeviceUIState.kt index 6049195d48cd55a2a46cdba6440d145f6c6f8e2c..bc304ab27c4a7eadac06adb6decadd14c4c97fac 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/DeviceUIState.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/DeviceUIState.kt @@ -7,6 +7,7 @@ enum class DeviceUIState { PAIRED_POSITIVE_TELETAN, PAIRED_NEGATIVE, PAIRED_ERROR, + PAIRED_REDEEMED, SUBMITTED_INITIAL, SUBMITTED_FINAL } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/formatter/FormatterSubmissionHelper.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/formatter/FormatterSubmissionHelper.kt index 5d93578b11d500499650e901cb517d0b087e4cb7..fb6de1ec97bf660e2481d4512f269fd44966a962 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/formatter/FormatterSubmissionHelper.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/formatter/FormatterSubmissionHelper.kt @@ -64,7 +64,8 @@ fun formatTestResultCardContent(uiState: DeviceUIState?): Spannable { return when (uiState) { DeviceUIState.PAIRED_NO_RESULT -> SpannableString(appContext.getString(R.string.test_result_card_status_pending)) - DeviceUIState.PAIRED_ERROR -> + DeviceUIState.PAIRED_ERROR, + DeviceUIState.PAIRED_REDEEMED -> SpannableString(appContext.getString(R.string.test_result_card_status_invalid)) DeviceUIState.PAIRED_POSITIVE, @@ -81,7 +82,8 @@ fun formatTestStatusIcon(uiState: DeviceUIState?): Drawable? { DeviceUIState.PAIRED_POSITIVE_TELETAN, DeviceUIState.PAIRED_POSITIVE -> appContext.getDrawable(R.drawable.ic_test_result_illustration_positive) DeviceUIState.PAIRED_NEGATIVE -> appContext.getDrawable(R.drawable.ic_test_result_illustration_negative) - DeviceUIState.PAIRED_ERROR -> appContext.getDrawable(R.drawable.ic_test_result_illustration_invalid) + DeviceUIState.PAIRED_ERROR, + DeviceUIState.PAIRED_REDEEMED -> appContext.getDrawable(R.drawable.ic_test_result_illustration_invalid) else -> appContext.getDrawable(R.drawable.ic_test_result_illustration_invalid) } } @@ -102,13 +104,14 @@ fun formatTestResultPositiveStepsVisible(uiState: DeviceUIState?): Int = formatVisibility(uiState == DeviceUIState.PAIRED_POSITIVE || uiState == DeviceUIState.PAIRED_POSITIVE_TELETAN) fun formatTestResultInvalidStepsVisible(uiState: DeviceUIState?): Int = - formatVisibility(uiState == DeviceUIState.PAIRED_ERROR) + formatVisibility(uiState == DeviceUIState.PAIRED_ERROR || uiState == DeviceUIState.PAIRED_REDEEMED) fun formatSubmissionStatusCardSubtitleColor(uiState: DeviceUIState?): Int { val appContext = CoronaWarnApplication.getAppContext() return when (uiState) { DeviceUIState.PAIRED_NEGATIVE -> appContext.getColor(R.color.colorTextSemanticGreen) - DeviceUIState.PAIRED_ERROR -> appContext.getColor(R.color.colorTextSemanticNeutral) + DeviceUIState.PAIRED_ERROR, + DeviceUIState.PAIRED_REDEEMED -> appContext.getColor(R.color.colorTextSemanticNeutral) else -> appContext.getColor(R.color.colorTextPrimary1) } } @@ -117,7 +120,8 @@ fun formatSubmissionStatusCardSubtitleText(uiState: DeviceUIState?): String { val appContext = CoronaWarnApplication.getAppContext() return when (uiState) { DeviceUIState.PAIRED_NEGATIVE -> appContext.getString(R.string.submission_status_card_subtitle_negative) - DeviceUIState.PAIRED_ERROR -> appContext.getString(R.string.submission_status_card_subtitle_invalid) + DeviceUIState.PAIRED_ERROR, + DeviceUIState.PAIRED_REDEEMED -> appContext.getString(R.string.submission_status_card_subtitle_invalid) else -> "" } } @@ -126,6 +130,7 @@ fun formatSubmissionStatusCardContentTitleText(uiState: DeviceUIState?): String val appContext = CoronaWarnApplication.getAppContext() return when (uiState) { DeviceUIState.PAIRED_ERROR, + DeviceUIState.PAIRED_REDEEMED, DeviceUIState.PAIRED_NEGATIVE -> appContext.getString(R.string.submission_status_card_title_available) DeviceUIState.PAIRED_NO_RESULT -> appContext.getString(R.string.submission_status_card_title_pending) else -> appContext.getString(R.string.submission_status_card_title_pending) @@ -135,7 +140,8 @@ fun formatSubmissionStatusCardContentTitleText(uiState: DeviceUIState?): String fun formatSubmissionStatusCardContentBodyText(uiState: DeviceUIState?): String { val appContext = CoronaWarnApplication.getAppContext() return when (uiState) { - DeviceUIState.PAIRED_ERROR -> appContext.getString(R.string.submission_status_card_body_invalid) + DeviceUIState.PAIRED_ERROR, + DeviceUIState.PAIRED_REDEEMED -> appContext.getString(R.string.submission_status_card_body_invalid) DeviceUIState.PAIRED_NEGATIVE -> appContext.getString(R.string.submission_status_card_body_negative) DeviceUIState.PAIRED_NO_RESULT -> appContext.getString(R.string.submission_status_card_body_pending) else -> appContext.getString(R.string.submission_status_card_body_pending) @@ -145,6 +151,7 @@ fun formatSubmissionStatusCardContentBodyText(uiState: DeviceUIState?): String { fun formatSubmissionStatusCardContentStatusTextVisible(uiState: DeviceUIState?): Int { return when (uiState) { DeviceUIState.PAIRED_NEGATIVE, + DeviceUIState.PAIRED_REDEEMED, DeviceUIState.PAIRED_ERROR -> View.VISIBLE else -> View.GONE } @@ -157,7 +164,8 @@ fun formatSubmissionStatusCardContentIcon(uiState: DeviceUIState?): Drawable? { DeviceUIState.PAIRED_POSITIVE, DeviceUIState.PAIRED_POSITIVE_TELETAN -> appContext.getDrawable(R.drawable.ic_main_illustration_pending) DeviceUIState.PAIRED_NEGATIVE -> appContext.getDrawable(R.drawable.ic_main_illustration_negative) - DeviceUIState.PAIRED_ERROR -> appContext.getDrawable(R.drawable.ic_main_illustration_invalid) + DeviceUIState.PAIRED_ERROR, + DeviceUIState.PAIRED_REDEEMED -> appContext.getDrawable(R.drawable.ic_main_illustration_invalid) else -> appContext.getDrawable(R.drawable.ic_main_illustration_invalid) } } @@ -180,7 +188,8 @@ fun formatSubmissionStatusCardContentVisible( ): Int = formatVisibility( deviceUiState == DeviceUIState.PAIRED_ERROR || deviceUiState == DeviceUIState.PAIRED_NEGATIVE || - deviceUiState == DeviceUIState.PAIRED_NO_RESULT + deviceUiState == DeviceUIState.PAIRED_NO_RESULT || + deviceUiState == DeviceUIState.PAIRED_REDEEMED ) fun formatShowSubmissionStatusPositiveCard(deviceUiState: DeviceUIState?): Int = diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/formatter/TestResult.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/formatter/TestResult.kt index 31ec1a64d5ebf138836d478eff3a642000ee6ced..c0cacc40a79d73c32ce47d9f4863df2c6f8bc1e9 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/formatter/TestResult.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/formatter/TestResult.kt @@ -5,7 +5,8 @@ enum class TestResult(val value: Int) { PENDING(0), NEGATIVE(1), POSITIVE(2), - INVALID(3); + INVALID(3), + REDEEMED(4); companion object { fun fromInt(value: Int) = values().first { it.value == value } diff --git a/Corona-Warn-App/src/main/res/values-de/strings.xml b/Corona-Warn-App/src/main/res/values-de/strings.xml index 599eb7de369d68434332d8d51a5d05510b76fd33..227eb515bec4b635fded2e0e3e7b2ddfc943dfc3 100644 --- a/Corona-Warn-App/src/main/res/values-de/strings.xml +++ b/Corona-Warn-App/src/main/res/values-de/strings.xml @@ -726,6 +726,13 @@ <!-- XBUT: Positive button for submission tan invalid --> <string name="submission_error_dialog_web_tan_invalid_button_positive">"Zurück"</string> + <!-- XHED: Dialog title for submission tan redeemed --> + <string name="submission_error_dialog_web_tan_redeemed_title">"Test fehlerhaft"</string> + <!-- XMSG: Dialog body for submission tan redeemed --> + <string name="submission_error_dialog_web_tan_redeemed_body">"Es gab ein Problem bei der Auswertung Ihres Tests. Ihr QR Code ist bereits abgelaufen."</string> + <!-- XBUT: Positive button for submission tan redeemed --> + <string name="submission_error_dialog_web_tan_redeemed_button_positive">"OK"</string> + <!-- Permission Rationale Dialog --> <!-- XHED: Dialog headline QR Scan permission rationale --> <string name="submission_qr_code_scan_permission_rationale_dialog_headline">"Kamera-Zugriff benötigt"</string> diff --git a/Corona-Warn-App/src/main/res/values/strings.xml b/Corona-Warn-App/src/main/res/values/strings.xml index 82541082b881b092b1896af6a2d3939b7b4be3d0..60485feb00b45074a4caf7a71f12c0b856ad5f59 100644 --- a/Corona-Warn-App/src/main/res/values/strings.xml +++ b/Corona-Warn-App/src/main/res/values/strings.xml @@ -728,6 +728,13 @@ <!-- XBUT: Positive button for submission tan invalid --> <string name="submission_error_dialog_web_tan_invalid_button_positive">"Back"</string> + <!-- XHED: Dialog title for submission tan redeemed --> + <string name="submission_error_dialog_web_tan_redeemed_title">"Test has errors"</string> + <!-- XMSG: Dialog body for submission tan redeemed --> + <string name="submission_error_dialog_web_tan_redeemed_body">"There was a problem evaluating your test. Your QR Code has already expired."</string> + <!-- XBUT: Positive button for submission tan redeemed --> + <string name="submission_error_dialog_web_tan_redeemed_button_positive">"OK"</string> + <!-- Permission Rationale Dialog --> <!-- XHED: Dialog headline QR Scan permission rationale --> <string name="submission_qr_code_scan_permission_rationale_dialog_headline">"Camera authorization required"</string>