From 30b500a9871e6a29d61f214af50ef3d6aea6a58f Mon Sep 17 00:00:00 2001
From: Lukas Lechner <lukas.lechner@sap.com>
Date: Tue, 2 Feb 2021 14:59:53 +0100
Subject: [PATCH] Adjust low risk card (EXPOSUREAPP-4836) #2238

* Replace strings "on one day" to "on 1 day" for low risk card

* Change content description of low risk card

* Adapt low risk card - display date when last encounter occurred - similar to high risk card

* Update Corona-Warn-App/src/main/res/values-de/strings.xml

Co-authored-by: Sabine Loss <44154356+SabineLoss@users.noreply.github.com>

* Update Corona-Warn-App/src/main/res/values/strings.xml

Co-authored-by: Sabine Loss <44154356+SabineLoss@users.noreply.github.com>

* Update strings.xml

* Rename input parameters of LowRisk data class from c to context

* Fix instrumentation tests

Co-authored-by: Sabine Loss <44154356+SabineLoss@users.noreply.github.com>
Co-authored-by: harambasicluka <64483219+harambasicluka@users.noreply.github.com>
---
 .../coronawarnapp/ui/main/home/HomeData.kt    |  1 +
 .../coronawarnapp/ui/tracing/TracingData.kt   |  3 +-
 .../tracing/states/TracingState.kt            | 48 +++++++++++++++----
 .../tracing/states/TracingStateProvider.kt    |  1 +
 .../res/layout/tracing_content_low_view.xml   | 18 ++++++-
 .../src/main/res/values-de/strings.xml        | 15 +++++-
 .../src/main/res/values/strings.xml           | 17 ++++++-
 7 files changed, 88 insertions(+), 15 deletions(-)

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 97a76ddf8..f01455f46 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 e02ca5fad..49ee8fe72 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 9b3115575..8bf8482ae 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 a21a54867..cb94ae132 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 a73f7d0c4..b84c232d4 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 fd2877edb..39cf5f056 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 f0b8fd57d..18854057f 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">
-- 
GitLab