From 23bbdde926d6e6501bae459ca3579fa9661186f6 Mon Sep 17 00:00:00 2001
From: Alex Paulescu <alex.paulescu@gmail.com>
Date: Tue, 23 Feb 2021 13:09:26 +0200
Subject: [PATCH] Extend diary homescreen items with new attributes
 (EXPOSUREAPP-4741) (#2421)

* Added arguments for persons and locations on the diary homescreen.

* Adjusted instrumentation test.

* Cleaned up code.

* Changed textview to self closing.
---
 .../ui/contactdiary/DiaryData.kt              | 33 ++++++++-
 .../overview/ContactDiaryOverviewViewModel.kt | 38 ++++++++--
 .../ContactDiaryOverviewNestedAdapter.kt      | 16 ++++-
 .../ui/overview/adapter/ListItem.kt           |  6 +-
 ...ontact_diary_overview_nested_list_item.xml | 72 +++++++++----------
 5 files changed, 118 insertions(+), 47 deletions(-)

diff --git a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/contactdiary/DiaryData.kt b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/contactdiary/DiaryData.kt
index dc77cd96c..55b95459e 100644
--- a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/contactdiary/DiaryData.kt
+++ b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/contactdiary/DiaryData.kt
@@ -10,6 +10,7 @@ import de.rki.coronawarnapp.contactdiary.model.DefaultContactDiaryPersonEncounte
 import de.rki.coronawarnapp.contactdiary.ui.day.tabs.location.DiaryLocationListItem
 import de.rki.coronawarnapp.contactdiary.ui.day.tabs.person.DiaryPersonListItem
 import de.rki.coronawarnapp.contactdiary.ui.overview.adapter.ListItem
+import org.joda.time.Duration
 import org.joda.time.LocalDate
 
 object DiaryData {
@@ -18,24 +19,42 @@ object DiaryData {
         ListItem.Data(
             R.drawable.ic_contact_diary_person_item,
             "Max Mustermann",
+            null,
+            listOf(
+                R.string.contact_diary_person_encounter_duration_below_15_min,
+                R.string.contact_diary_person_encounter_mask_with,
+                R.string.contact_diary_person_encounter_environment_inside
+            ),
+            "Notizen notizen",
             ListItem.Type.PERSON
         ),
 
         ListItem.Data(
             R.drawable.ic_contact_diary_person_item,
             "Erika Mustermann",
+            null,
+            listOf(
+                R.string.contact_diary_person_encounter_environment_inside
+            ),
+            "Notizen notizen",
             ListItem.Type.PERSON
         ),
 
         ListItem.Data(
             R.drawable.ic_contact_diary_location,
             "Fitnessstudio",
+            Duration.millis(1800000),
+            null,
+            "Notizen notizen",
             ListItem.Type.LOCATION
         ),
 
         ListItem.Data(
             R.drawable.ic_contact_diary_location,
             "Supermarket",
+            null,
+            null,
+            null,
             ListItem.Type.LOCATION
         )
     )
@@ -126,13 +145,21 @@ object DiaryData {
 
     val LOCATIONS_EDIT_LIST: List<ContactDiaryLocation> = listOf(
         DefaultContactDiaryLocation(locationName = "Sport"),
-        DefaultContactDiaryLocation(locationName = "Büro"),
+        DefaultContactDiaryLocation(
+            locationName = "Büro",
+            phoneNumber = "+49153397029",
+            emailAddress = "office@work.com"
+        ),
         DefaultContactDiaryLocation(locationName = "Supermarkt")
     )
 
     val PERSONS_EDIT_LIST: List<ContactDiaryPerson> = listOf(
-        DefaultContactDiaryPerson(fullName = "Max Mustermann"),
-        DefaultContactDiaryPerson(fullName = "Erika Mustermann"),
+        DefaultContactDiaryPerson(
+            fullName = "Max Mustermann",
+            phoneNumber = "+49151237865",
+            emailAddress = "max.musterman@me.com"
+        ),
+        DefaultContactDiaryPerson(fullName = "Erika Mustermann", emailAddress = "erika.mustermann@me.com"),
         DefaultContactDiaryPerson(fullName = "John Doe")
     )
 }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/ContactDiaryOverviewViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/ContactDiaryOverviewViewModel.kt
index 98db07ac3..f2c304ca1 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/ContactDiaryOverviewViewModel.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/ContactDiaryOverviewViewModel.kt
@@ -9,6 +9,8 @@ import dagger.assisted.AssistedInject
 import de.rki.coronawarnapp.R
 import de.rki.coronawarnapp.contactdiary.model.ContactDiaryLocationVisit
 import de.rki.coronawarnapp.contactdiary.model.ContactDiaryPersonEncounter
+import de.rki.coronawarnapp.contactdiary.model.ContactDiaryPersonEncounter.DurationClassification.LESS_THAN_15_MINUTES
+import de.rki.coronawarnapp.contactdiary.model.ContactDiaryPersonEncounter.DurationClassification.MORE_THAN_15_MINUTES
 import de.rki.coronawarnapp.contactdiary.retention.ContactDiaryCleanTask
 import de.rki.coronawarnapp.contactdiary.storage.repo.ContactDiaryRepository
 import de.rki.coronawarnapp.contactdiary.ui.overview.adapter.ListItem
@@ -117,7 +119,10 @@ class ContactDiaryOverviewViewModel @AssistedInject constructor(
             .map { personEncounter ->
                 ListItem.Data(
                     R.drawable.ic_contact_diary_person_item,
-                    personEncounter.contactDiaryPerson.fullName,
+                    name = personEncounter.contactDiaryPerson.fullName,
+                    duration = null,
+                    attributes = getPersonAttributes(personEncounter),
+                    circumstances = personEncounter.circumstances,
                     ListItem.Type.PERSON
                 )
             }
@@ -133,6 +138,9 @@ class ContactDiaryOverviewViewModel @AssistedInject constructor(
                 ListItem.Data(
                     R.drawable.ic_contact_diary_location_item,
                     locationVisit.contactDiaryLocation.locationName,
+                    duration = locationVisit.duration,
+                    attributes = null,
+                    circumstances = locationVisit.circumstances,
                     ListItem.Type.LOCATION
                 )
             }
@@ -146,6 +154,24 @@ class ContactDiaryOverviewViewModel @AssistedInject constructor(
         routeToScreen.postValue(ContactDiaryOverviewNavigationEvents.NavigateToContactDiaryDayFragment(listItem.date))
     }
 
+    private fun getPersonAttributes(personEncounter: ContactDiaryPersonEncounter): List<Int> =
+        mutableListOf<Int>().apply {
+            when (personEncounter.durationClassification) {
+                LESS_THAN_15_MINUTES -> add(R.string.contact_diary_person_encounter_duration_below_15_min)
+                MORE_THAN_15_MINUTES -> add(R.string.contact_diary_person_encounter_duration_above_15_min)
+            }
+
+            when (personEncounter.withMask) {
+                true -> add(R.string.contact_diary_person_encounter_mask_with)
+                false -> add(R.string.contact_diary_person_encounter_mask_without)
+            }
+
+            when (personEncounter.wasOutside) {
+                true -> add(R.string.contact_diary_person_encounter_environment_outside)
+                false -> add(R.string.contact_diary_person_encounter_environment_inside)
+            }
+        }
+
     fun onExportPress(ctx: Context) {
         Timber.d("Exporting person and location entries")
         launch {
@@ -158,9 +184,13 @@ class ContactDiaryOverviewViewModel @AssistedInject constructor(
                 .groupBy({ it.date }, { it.contactDiaryPerson.fullName })
 
             val sb = StringBuilder()
-                .appendLine(ctx.getString(R.string.contact_diary_export_intro_one,
-                    dates.last().toFormattedString(),
-                    dates.first().toFormattedString()))
+                .appendLine(
+                    ctx.getString(
+                        R.string.contact_diary_export_intro_one,
+                        dates.last().toFormattedString(),
+                        dates.first().toFormattedString()
+                    )
+                )
                 .appendLine(ctx.getString(R.string.contact_diary_export_intro_two))
                 .appendLine()
 
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/adapter/ContactDiaryOverviewNestedAdapter.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/adapter/ContactDiaryOverviewNestedAdapter.kt
index 3cd03fb89..2282baafb 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/adapter/ContactDiaryOverviewNestedAdapter.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/adapter/ContactDiaryOverviewNestedAdapter.kt
@@ -6,6 +6,7 @@ import de.rki.coronawarnapp.contactdiary.util.clearAndAddAll
 import de.rki.coronawarnapp.databinding.ContactDiaryOverviewNestedListItemBinding
 import de.rki.coronawarnapp.ui.lists.BaseAdapter
 import de.rki.coronawarnapp.util.lists.BindableVH
+import org.joda.time.Duration
 
 class ContactDiaryOverviewNestedAdapter : BaseAdapter<ContactDiaryOverviewNestedAdapter.NestedItemViewHolder>() {
 
@@ -35,11 +36,20 @@ class ContactDiaryOverviewNestedAdapter : BaseAdapter<ContactDiaryOverviewNested
             ContactDiaryOverviewNestedListItemBinding.(item: ListItem.Data, payloads: List<Any>) -> Unit =
             { key, _ ->
                 contactDiaryOverviewElementImage.setImageResource(key.drawableId)
-                contactDiaryOverviewElementName.text = key.text
+                contactDiaryOverviewElementName.text = key.name
                 contactDiaryOverviewElementName.contentDescription = when (key.type) {
-                    ListItem.Type.LOCATION -> context.getString(R.string.accessibility_location, key.text)
-                    ListItem.Type.PERSON -> context.getString(R.string.accessibility_person, key.text)
+                    ListItem.Type.LOCATION -> context.getString(R.string.accessibility_location, key.name)
+                    ListItem.Type.PERSON -> context.getString(R.string.accessibility_person, key.name)
                 }
+                contactDiaryOverviewElementAttributes.text =
+                    getAttributes(key.duration, key.attributes, key.circumstances)
             }
+
+        private fun getAttributes(duration: Duration?, resources: List<Int>?, circumstances: String?): String =
+            mutableListOf<String>().apply {
+                duration?.run { add(toStandardHours().toString()) }
+                resources?.run { forEach { add(context.getString(it)) } }
+                circumstances?.run { add(this) }
+            }.joinToString()
     }
 }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/adapter/ListItem.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/adapter/ListItem.kt
index f45c87041..525d988f5 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/adapter/ListItem.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/adapter/ListItem.kt
@@ -2,6 +2,7 @@ package de.rki.coronawarnapp.contactdiary.ui.overview.adapter
 
 import androidx.annotation.DrawableRes
 import androidx.annotation.StringRes
+import org.joda.time.Duration
 import org.joda.time.LocalDate
 
 data class ListItem(
@@ -12,7 +13,10 @@ data class ListItem(
 
     data class Data(
         @DrawableRes val drawableId: Int,
-        val text: String,
+        val name: String,
+        val duration: Duration?,
+        val attributes: List<Int>?,
+        val circumstances: String?,
         val type: Type
     )
 
diff --git a/Corona-Warn-App/src/main/res/layout/contact_diary_overview_nested_list_item.xml b/Corona-Warn-App/src/main/res/layout/contact_diary_overview_nested_list_item.xml
index e05f8779d..cce965122 100644
--- a/Corona-Warn-App/src/main/res/layout/contact_diary_overview_nested_list_item.xml
+++ b/Corona-Warn-App/src/main/res/layout/contact_diary_overview_nested_list_item.xml
@@ -2,54 +2,54 @@
 <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
     xmlns:tools="http://schemas.android.com/tools"
-    android:id="@+id/contact_diary_overview_element_nested_container"
+    android:id="@+id/contact_diary_overview_element_nested_body"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
+    android:layout_marginVertical="@dimen/spacing_tiny"
     android:focusable="true"
     app:layout_constraintBottom_toBottomOf="parent"
     app:layout_constraintEnd_toEndOf="parent"
     app:layout_constraintStart_toStartOf="parent"
     app:layout_constraintTop_toTopOf="parent">
 
-    <androidx.constraintlayout.widget.ConstraintLayout
-        android:id="@+id/contact_diary_overview_element_nested_body"
-        android:layout_width="match_parent"
+    <ImageView
+        android:id="@+id/contact_diary_overview_element_image"
+        android:layout_width="wrap_content"
+        android:layout_height="0dp"
+        android:layout_marginStart="@dimen/spacing_small"
+        android:importantForAccessibility="no"
+        android:scaleType="centerInside"
+        android:src="@drawable/ic_contact_diary_person_item"
+        app:layout_constraintBottom_toBottomOf="@+id/contact_diary_overview_element_name"
+        app:layout_constraintEnd_toStartOf="@id/contact_diary_overview_element_name"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="@+id/contact_diary_overview_element_name" />
+
+    <TextView
+        android:id="@+id/contact_diary_overview_element_name"
+        style="@style/subtitle"
+        android:layout_width="0dp"
         android:layout_height="wrap_content"
-        android:layout_marginVertical="@dimen/spacing_tiny"
+        android:layout_marginStart="@dimen/spacing_small"
+        android:layout_marginEnd="@dimen/spacing_small"
+        android:ellipsize="end"
         android:focusable="true"
-        app:layout_constraintBottom_toBottomOf="parent"
+        android:maxLines="3"
         app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintTop_toTopOf="parent">
+        app:layout_constraintStart_toEndOf="@+id/contact_diary_overview_element_image"
+        app:layout_constraintTop_toTopOf="parent"
+        tools:text="Andrea Steinhauer" />
 
-        <ImageView
-            android:id="@+id/contact_diary_overview_element_image"
-            android:layout_width="wrap_content"
-            android:layout_height="0dp"
-            android:layout_marginStart="@dimen/spacing_small"
-            android:importantForAccessibility="no"
-            android:scaleType="centerInside"
-            android:src="@drawable/ic_contact_diary_person_item"
-            app:layout_constraintBaseline_toBaselineOf="@id/contact_diary_overview_element_name"
-            app:layout_constraintEnd_toStartOf="@id/contact_diary_overview_element_name"
-            app:layout_constraintStart_toStartOf="parent" />
+    <TextView
+        android:id="@+id/contact_diary_overview_element_attributes"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:maxLines="3"
+        android:text="unter 15 Min, im Freien"
+        app:layout_constraintEnd_toEndOf="@+id/contact_diary_overview_element_name"
+        app:layout_constraintStart_toStartOf="@+id/contact_diary_overview_element_name"
+        app:layout_constraintTop_toBottomOf="@+id/contact_diary_overview_element_name" />
 
-        <TextView
-            android:id="@+id/contact_diary_overview_element_name"
-            style="@style/subtitle"
-            android:layout_width="0dp"
-            android:layout_height="wrap_content"
-            android:layout_marginStart="@dimen/spacing_small"
-            android:layout_marginEnd="@dimen/spacing_small"
-            android:ellipsize="end"
-            android:focusable="true"
-            android:maxLines="3"
-            app:layout_constraintBottom_toBottomOf="parent"
-            app:layout_constraintEnd_toEndOf="parent"
-            app:layout_constraintStart_toEndOf="@+id/contact_diary_overview_element_image"
-            app:layout_constraintTop_toTopOf="parent"
-            tools:text="Andrea Steinhauer" />
+</androidx.constraintlayout.widget.ConstraintLayout>
 
-    </androidx.constraintlayout.widget.ConstraintLayout>
 
-</androidx.constraintlayout.widget.ConstraintLayout>
-- 
GitLab