diff --git a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/main/home/HomeData.kt b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/main/home/HomeData.kt index 97a76ddf8297d79305f7382d0a3576c5fd0e30e2..f01455f4629f4a205acd1a12b23f5bb5437215a2 100644 --- a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/main/home/HomeData.kt +++ b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/main/home/HomeData.kt @@ -38,6 +38,7 @@ object HomeData { riskState = RiskState.LOW_RISK, isInDetailsMode = false, lastExposureDetectionTime = Instant.now(), + lastEncounterAt = Instant.now(), allowManualUpdate = false, daysWithEncounters = 1, activeTracingDays = 1 diff --git a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/tracing/TracingData.kt b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/tracing/TracingData.kt index e02ca5fad8d6d499fc9101c734776fda06b77f2b..49ee8fe72c5280e320ab5b6cb0b49ef5250ab3c5 100644 --- a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/tracing/TracingData.kt +++ b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/tracing/TracingData.kt @@ -59,7 +59,8 @@ object TracingData { lastExposureDetectionTime = Instant.now(), allowManualUpdate = false, daysWithEncounters = 0, - activeTracingDays = 0 + activeTracingDays = 0, + lastEncounterAt = Instant.now() ) ), BehaviorNormalRiskBox.Item( diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/tracing/states/TracingState.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/tracing/states/TracingState.kt index 9b31155750aa514f3de3ae3b345015be161c77b1..8bf8482ae23e6ecf992c5af41aa5368ec076f0a6 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/tracing/states/TracingState.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/tracing/states/TracingState.kt @@ -103,6 +103,7 @@ data class LowRisk( override val riskState: RiskState, override val isInDetailsMode: Boolean, val lastExposureDetectionTime: Instant?, + val lastEncounterAt: Instant?, val allowManualUpdate: Boolean, val daysWithEncounters: Int, val activeTracingDays: Int @@ -110,33 +111,60 @@ data class LowRisk( val showUpdateButton: Boolean = allowManualUpdate && !isInDetailsMode - fun getTimeFetched(c: Context): String = if (lastExposureDetectionTime != null) { - c.getString( + fun getTimeFetched(context: Context): String = if (lastExposureDetectionTime != null) { + context.getString( R.string.risk_card_body_time_fetched, - formatRelativeDateTimeString(c, lastExposureDetectionTime) + formatRelativeDateTimeString(context, lastExposureDetectionTime) ) } else { - c.getString(R.string.risk_card_body_not_yet_fetched) + context.getString(R.string.risk_card_body_not_yet_fetched) } - fun getRiskContactBody(c: Context): String = if (daysWithEncounters == 0) { + fun getRiskContactBody(context: Context): String = if (daysWithEncounters == 0) { // caution! is 0 after migration from 1.7.x -> 1.8.x // see RiskLevelResultMigrator.kt - c.getString(R.string.risk_card_low_risk_no_encounters_body) + context.getString(R.string.risk_card_low_risk_no_encounters_body) } else { - c.resources.getQuantityString( + context.resources.getQuantityString( R.plurals.risk_card_low_risk_encounter_days_body, daysWithEncounters, daysWithEncounters ) } - fun getRiskActiveTracingDaysInRetentionPeriod(c: Context): String = + fun getRiskContactBodyDescription(context: Context): String = if (daysWithEncounters == 0) { + context.getString(R.string.risk_card_low_risk_no_encounters_body) + } else { + context.resources.getQuantityString( + R.plurals.risk_card_low_risk_encounter_days_body_description, + daysWithEncounters, + daysWithEncounters + ) + } + + fun getRiskActiveTracingDaysInRetentionPeriod(context: Context): String = if (activeTracingDays < TimeVariables.getDefaultRetentionPeriodInDays()) { - c.getString(R.string.risk_card_body_saved_days).format(activeTracingDays) + context.getString(R.string.risk_card_body_saved_days).format(activeTracingDays) + } else { + context.getString(R.string.risk_card_body_saved_days_full) + } + + fun getRiskContactLast(context: Context): String? { + if (lastEncounterAt == null) return null + // caution! lastEncounterAt is null after migration from 1.7.x -> 1.8.x + // see RiskLevelResultMigrator.kt + + val stringRes = if (daysWithEncounters == 1) { + R.string.risk_card_low_risk_most_recent_body_encounter_on_single_day } else { - c.getString(R.string.risk_card_body_saved_days_full) + R.string.risk_card_low_risk_most_recent_body_encounters_on_more_than_one_day } + + return context.getString( + stringRes, + lastEncounterAt.toLocalDate().toString(DateTimeFormat.mediumDate()) + ) + } } // tracing_content_failed_view diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/tracing/states/TracingStateProvider.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/tracing/states/TracingStateProvider.kt index a21a5486700a3f9249a3480c4bf2095ecc15e2b0..cb94ae132c27493a2fd52f84207670d1529f868f 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/tracing/states/TracingStateProvider.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/tracing/states/TracingStateProvider.kt @@ -74,6 +74,7 @@ class TracingStateProvider @AssistedInject constructor( isInDetailsMode = isDetailsMode, riskState = latestCalc.riskState, lastExposureDetectionTime = latestSubmission?.startedAt, + lastEncounterAt = latestCalc.lastRiskEncounterAt, daysWithEncounters = latestCalc.daysWithEncounters, activeTracingDays = activeTracingDaysInRetentionPeriod.toInt(), allowManualUpdate = !isBackgroundJobEnabled diff --git a/Corona-Warn-App/src/main/res/layout/tracing_content_low_view.xml b/Corona-Warn-App/src/main/res/layout/tracing_content_low_view.xml index a73f7d0c409a4c83d3c84132ec949a0db3763b62..b84c232d43226203c0a7f9e9cc864bd66e709ad6 100644 --- a/Corona-Warn-App/src/main/res/layout/tracing_content_low_view.xml +++ b/Corona-Warn-App/src/main/res/layout/tracing_content_low_view.xml @@ -48,6 +48,7 @@ android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginTop="16dp" + android:contentDescription="@{state.getRiskContactBodyDescription(context)}" android:icon="@drawable/ic_risk_card_contact" android:text="@{state.getRiskContactBody(context)}" android:textColor="@color/colorTextPrimary1InvertedStable" @@ -57,13 +58,28 @@ app:layout_constraintTop_toBottomOf="@+id/headline" tools:text="@plurals/risk_card_low_risk_encounter_days_body" /> + <de.rki.coronawarnapp.ui.view.TracingCardInfoRow + android:id="@+id/row_contact_last" + gone="@{state.getRiskContactLast(context) == null}" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:icon="@drawable/ic_risk_card_calendar" + android:text="@{state.getRiskContactLast(context) ?? ``}" + android:textColor="@color/colorTextPrimary1InvertedStable" + app:compatIconTint="@color/colorStableLight" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/row_contact" + tools:text="@string/risk_card_low_risk_most_recent_body_encounters_on_more_than_one_day" /> + <androidx.constraintlayout.widget.ConstraintLayout android:id="@+id/row_saved_days" + gone="@{state.getRiskContactLast(context) != null}" android:layout_width="0dp" android:layout_height="wrap_content" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toBottomOf="@+id/row_contact"> + app:layout_constraintTop_toBottomOf="@+id/row_contact_last"> <de.rki.coronawarnapp.ui.view.CircleProgress android:id="@+id/risk_card_row_saved_days_circle_progress" 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 fd2877edb0b14c6e5c05d840a8705340de257525..39cf5f056ab4d775f21bd3ebc387595e72dfa066 100644 --- a/Corona-Warn-App/src/main/res/values-de/strings.xml +++ b/Corona-Warn-App/src/main/res/values-de/strings.xml @@ -151,13 +151,26 @@ <string name="risk_card_low_risk_no_encounters_body">Keine Risiko-Begegnungen</string> <!-- XTXT: risk card - Low risk state - Days with low risk encounters --> <plurals name="risk_card_low_risk_encounter_days_body"> + <item quantity="one">"Begegnungen mit niedrigem Risiko an %1$d Tag"</item> + <item quantity="other">"Begegnungen mit niedrigem Risiko an %1$d Tagen"</item> + <item quantity="zero">"Keine Risiko-Begegnungen"</item> + <item quantity="two">"Begegnungen mit niedrigem Risiko an %1$d Tagen"</item> + <item quantity="few">"Begegnungen mit niedrigem Risiko an %1$d Tagen"</item> + <item quantity="many">"Begegnungen mit niedrigem Risiko an %1$d Tagen"</item> + </plurals> + <!-- XACT: risk card - Low risk state - Days with low risk encounters description --> + <plurals name="risk_card_low_risk_encounter_days_body_description"> <item quantity="one">"Begegnungen mit niedrigem Risiko an einem Tag"</item> <item quantity="other">"Begegnungen mit niedrigem Risiko an %1$d Tagen"</item> - <item quantity="zero">"Begegnungen mit niedrigem Risiko an %1$d Tagen"</item> + <item quantity="zero">"Keine Risiko-Begegnungen"</item> <item quantity="two">"Begegnungen mit niedrigem Risiko an %1$d Tagen"</item> <item quantity="few">"Begegnungen mit niedrigem Risiko an %1$d Tagen"</item> <item quantity="many">"Begegnungen mit niedrigem Risiko an %1$d Tagen"</item> </plurals> + <!-- XTXT: risk card - Low risk state - Most recent date with low risk and single day of encounters --> + <string name="risk_card_low_risk_most_recent_body_encounter_on_single_day">"Am %1$s"</string> + <!-- XTXT: risk card - Low risk state - Most recent date with low risk and more than one day of encounters --> + <string name="risk_card_low_risk_most_recent_body_encounters_on_more_than_one_day">"Zuletzt am %1$s"</string> <!-- XTXT: risk card - High risk state - Days with high risk encounters --> <plurals name="risk_card_high_risk_encounter_days_body"> diff --git a/Corona-Warn-App/src/main/res/values/strings.xml b/Corona-Warn-App/src/main/res/values/strings.xml index f0b8fd57d12cef0902d9a1de26c6b05783283d50..18854057f283c8870c8b6b8a3f95142e4f6ab560 100644 --- a/Corona-Warn-App/src/main/res/values/strings.xml +++ b/Corona-Warn-App/src/main/res/values/strings.xml @@ -161,13 +161,26 @@ <string name="risk_card_low_risk_no_encounters_body">"No exposures"</string> <!-- XTXT: risk card - Low risk state - Days with low risk encounters --> <plurals name="risk_card_low_risk_encounter_days_body"> - <item quantity="one">"Exposures with low risk on one day"</item> + <item quantity="one">"Exposures with low risk on %1$d day"</item> <item quantity="other">"Exposures with low risk on %1$d days"</item> - <item quantity="zero">"Exposures with low risk on %1$d days"</item> + <item quantity="zero">"No exposures"</item> <item quantity="two">"Exposures with low risk on %1$d days"</item> <item quantity="few">"Exposures with low risk on %1$d days"</item> <item quantity="many">"Exposures with low risk on %1$d days"</item> </plurals> + <!-- XACT: risk card - Low risk state - Days with low risk encounters description --> + <plurals name="risk_card_low_risk_encounter_days_body_description"> + <item quantity="one">"Exposures with low risk on %1$d day"</item> + <item quantity="other">"Exposures with low risk on %1$d days"</item> + <item quantity="zero">"No exposures"</item> + <item quantity="two">"Exposures with low risk on %1$d days"</item> + <item quantity="few">"Exposures with low risk on %1$d days"</item> + <item quantity="many">"Exposures with low risk on %1$d days"</item> + </plurals> + <!-- XTXT: risk card - Low risk state - Most recent date with low risk and single day of encounters --> + <string name="risk_card_low_risk_most_recent_body_encounter_on_single_day">"Am %1$s"</string> + <!-- XTXT: risk card - Low risk state - Most recent date with low risk and more than one day of encounters --> + <string name="risk_card_low_risk_most_recent_body_encounters_on_more_than_one_day">"Zuletzt am %1$s"</string> <!-- XTXT: risk card - High risk state - Days with high risk encounters --> <plurals name="risk_card_high_risk_encounter_days_body">