Skip to content
Snippets Groups Projects
Unverified Commit 5f327de1 authored by Philipp Nowak's avatar Philipp Nowak Committed by GitHub
Browse files

Localize dates in contact diary (EXPOSUREAPP-4485) (closes #2009) #2021


* Localize dates in contact diary (EXPOSUREAPP-4485) (#2009)

* Add additional unit test to cover US and UK for english date formatting (EXPOSUREAPP-4485) (#2009)

* Adjust expected date strings (EXPOSUREAPP-4485) (#2009)

* Correct the suffix for "year" for bulgarian dates in unit tests (EXPOSUREAPP-4485) (#2009)

* Use SystemInfoProvider implementation instead of static Locale.getDefault (EXPOSUREAPP-4485) (#2009)

* - Revert usage of SystemInfoProvider
- Introduce Context.getLocale() extension function
- Adjust unit tests to use kotest matchers

(EXPOSUREAPP-4485) (#2009)

* (Add accidentally missing files of the previous commit)

- Revert usage of SystemInfoProvider
- Introduce Context.getLocale() extension function
- Adjust unit tests to use kotest matchers

(EXPOSUREAPP-4485) (#2009)

Co-authored-by: default avatarI502720 <axel.herbstreith@sap.com>
parent 5c7ec06d
No related branches found
No related tags found
No related merge requests found
......@@ -62,8 +62,8 @@ class ContactDiaryDayFragment : Fragment(R.layout.contact_diary_day_fragment), A
}
viewModel.uiState.observe2(this) {
binding.contactDiaryDayHeader.title = it.dayText
binding.contentContainer.contentDescription = it.dayText
binding.contactDiaryDayHeader.title = it.dayText(requireContext())
binding.contentContainer.contentDescription = it.dayText(requireContext())
}
viewModel.routeToScreen.observe2(this) {
......
package de.rki.coronawarnapp.contactdiary.ui.day
import android.content.Context
import androidx.lifecycle.asLiveData
import com.squareup.inject.assisted.Assisted
import com.squareup.inject.assisted.AssistedInject
import de.rki.coronawarnapp.contactdiary.ui.day.tabs.ContactDiaryDayTab
import de.rki.coronawarnapp.contactdiary.util.getLocale
import de.rki.coronawarnapp.contactdiary.util.toFormattedDay
import de.rki.coronawarnapp.ui.SingleLiveEvent
import de.rki.coronawarnapp.util.coroutine.DispatcherProvider
......@@ -22,7 +24,7 @@ class ContactDiaryDayViewModel @AssistedInject constructor(
val routeToScreen: SingleLiveEvent<ContactDiaryDayNavigationEvents> = SingleLiveEvent()
val uiState = displayedDay.map { day ->
UIState(dayText = day.toFormattedDay())
UIState(dayText = { day.toFormattedDay(it.getLocale()) })
}.asLiveData()
fun onCreateButtonClicked(activeTab: ContactDiaryDayTab) {
......@@ -39,7 +41,7 @@ class ContactDiaryDayViewModel @AssistedInject constructor(
}
data class UIState(
val dayText: String
val dayText: (Context) -> String
)
@AssistedInject.Factory
......
......@@ -7,6 +7,8 @@ import androidx.core.app.ShareCompat
import androidx.fragment.app.Fragment
import de.rki.coronawarnapp.R
import de.rki.coronawarnapp.contactdiary.ui.overview.adapter.ContactDiaryOverviewAdapter
import de.rki.coronawarnapp.contactdiary.util.getLocale
import de.rki.coronawarnapp.contactdiary.util.toFormattedDay
import de.rki.coronawarnapp.databinding.ContactDiaryOverviewFragmentBinding
import de.rki.coronawarnapp.util.di.AutoInject
import de.rki.coronawarnapp.util.ui.doNavigate
......@@ -26,9 +28,10 @@ class ContactDiaryOverviewFragment : Fragment(R.layout.contact_diary_overview_fr
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val adapter = ContactDiaryOverviewAdapter {
vm.onItemPress(it)
}
val adapter = ContactDiaryOverviewAdapter(
{ it.toFormattedDay(requireContext().getLocale()) },
{ vm.onItemPress(it) }
)
setupToolbar()
......
......@@ -4,10 +4,13 @@ import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.core.view.isGone
import androidx.recyclerview.widget.RecyclerView
import de.rki.coronawarnapp.contactdiary.util.toFormattedDay
import de.rki.coronawarnapp.databinding.ContactDiaryOverviewListItemBinding
import org.joda.time.LocalDate
class ContactDiaryOverviewAdapter(private val onItemSelectionListener: (ListItem) -> Unit) :
class ContactDiaryOverviewAdapter(
private val dateFormatter: (LocalDate) -> String,
private val onItemSelectionListener: (ListItem) -> Unit
) :
RecyclerView.Adapter<ContactDiaryOverviewAdapter.OverviewElementHolder>() {
private val elements: MutableList<ListItem> = mutableListOf()
......@@ -31,7 +34,7 @@ class ContactDiaryOverviewAdapter(private val onItemSelectionListener: (ListItem
override fun getItemCount() = elements.size
override fun onBindViewHolder(holder: OverviewElementHolder, position: Int) {
holder.bind(elements[position], onItemSelectionListener)
holder.bind(elements[position], dateFormatter, onItemSelectionListener)
}
class OverviewElementHolder(private val viewDataBinding: ContactDiaryOverviewListItemBinding) :
......@@ -44,10 +47,10 @@ class ContactDiaryOverviewAdapter(private val onItemSelectionListener: (ListItem
fun bind(
item: ListItem,
dateFormatter: (LocalDate) -> String,
onElementSelectionListener: (ListItem) -> Unit
) {
viewDataBinding.contactDiaryOverviewElementName.text =
item.date.toFormattedDay()
viewDataBinding.contactDiaryOverviewElementName.text = dateFormatter(item.date)
viewDataBinding.contactDiaryOverviewElementBody.setOnClickListener { onElementSelectionListener(item) }
......
package de.rki.coronawarnapp.contactdiary.util
import android.content.Context
import android.os.Build
import android.view.View
import android.view.ViewTreeObserver
import android.view.inputmethod.InputMethodManager
......@@ -9,6 +10,7 @@ import androidx.core.view.ViewCompat
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat
import androidx.viewpager2.widget.ViewPager2
import org.joda.time.LocalDate
import org.joda.time.format.DateTimeFormat
import java.util.Locale
fun ViewPager2.registerOnPageChangeCallback(cb: (position: Int) -> Unit) {
......@@ -19,8 +21,22 @@ fun ViewPager2.registerOnPageChangeCallback(cb: (position: Int) -> Unit) {
})
}
// According to tech spec german locale only
fun LocalDate.toFormattedDay(): String = toString("EEEE, dd.MM.yy", Locale.GERMAN)
fun Context.getLocale(): Locale {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
@Suppress("NewApi")
resources.configuration.locales[0]
} else {
@Suppress("DEPRECATION")
resources.configuration.locale
}
}
fun LocalDate.toFormattedDay(locale: Locale): String {
// Use two different methods to get the final date format (Weekday, Shortdate)
// because the custom pattern of toString() does not localize characters like "/" or "."
return "${toString("EEEE", locale)}, " +
DateTimeFormat.shortDate().withLocale(locale).print(this)
}
fun String.formatContactDiaryNameField(maxLength: Int): String {
val newName = if (isNotBlank()) {
......
package de.rki.coronawarnapp.contactdiary.util
import io.kotest.matchers.shouldBe
import org.joda.time.LocalDate
import org.junit.jupiter.api.Test
import java.util.Locale
class ContactDiaryDateFormatterExtensionTest {
@Test
fun `format bulgarian date`() {
LocalDate("2021-01-01").toFormattedDay(
Locale("bg", "BG")
) shouldBe "петък, 1.01.21 г."
}
@Test
fun `format german date`() {
LocalDate("2021-01-02").toFormattedDay(Locale.GERMANY) shouldBe "Samstag, 02.01.21"
}
@Test
fun `format english (us) date`() {
LocalDate("2021-01-03").toFormattedDay(Locale.US) shouldBe "Sunday, 1/3/21"
}
@Test
fun `format english (uk) date`() {
LocalDate("2021-01-03").toFormattedDay(Locale.UK) shouldBe "Sunday, 03/01/2021"
}
@Test
fun `format polish date`() {
LocalDate("2021-01-04").toFormattedDay(
Locale("pl", "PL")
) shouldBe "poniedziałek, 04.01.2021"
}
@Test
fun `format romanian date`() {
LocalDate("2021-01-05").toFormattedDay(
Locale("ro", "RO")
) shouldBe "marți, 05.01.2021"
}
@Test
fun `format turkish date`() {
LocalDate("2021-01-06").toFormattedDay(
Locale("tr", "TR")
) shouldBe "Çarşamba, 6.01.2021"
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment