From cca45639c612a08838a9e642ea6e1c91166c309c Mon Sep 17 00:00:00 2001 From: Phillip Thelen Date: Mon, 22 Jul 2024 17:50:13 +0200 Subject: [PATCH] locale improvements --- .../android/habitica/extensions/LocaleExtensions.kt | 10 ++++++++++ .../habitica/extensions/ZonedDateExtensions.kt | 7 ------- .../habitica/helpers/TaskDescriptionBuilder.kt | 3 ++- .../habitrpg/android/habitica/prefs/TimePreference.kt | 3 ++- .../android/habitica/ui/activities/ArmoireActivity.kt | 2 +- .../habitica/ui/activities/FullProfileActivity.kt | 4 +++- .../habitica/ui/activities/TaskSummaryActivity.kt | 3 ++- .../ui/adapter/social/ChatRecyclerViewAdapter.kt | 4 +++- .../habitica/ui/viewHolders/tasks/DailyViewHolder.kt | 3 ++- .../habitrpg/android/habitica/ui/views/CompletedAt.kt | 5 +++-- .../ui/views/tasks/form/ReminderItemFormView.kt | 5 +++-- .../ui/views/tasks/form/TaskSchedulingControls.kt | 11 ++++++----- .../common/habitica/helpers/LanguageHelper.kt | 7 +++++++ version.properties | 2 +- 14 files changed, 45 insertions(+), 24 deletions(-) create mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/extensions/LocaleExtensions.kt diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/extensions/LocaleExtensions.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/extensions/LocaleExtensions.kt new file mode 100644 index 000000000..c6691a7d0 --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/extensions/LocaleExtensions.kt @@ -0,0 +1,10 @@ +package com.habitrpg.android.habitica.extensions + +import com.habitrpg.common.habitica.helpers.LanguageHelper +import java.util.Locale + + + +fun Locale.getSystemDefault(): Locale { + return LanguageHelper.systemLocale +} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/extensions/ZonedDateExtensions.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/extensions/ZonedDateExtensions.kt index 7d4ff050c..deb8fdbc3 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/extensions/ZonedDateExtensions.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/extensions/ZonedDateExtensions.kt @@ -31,13 +31,6 @@ fun Date.toZonedDateTime(): ZonedDateTime? { return this.toInstant().atZone(ZoneId.systemDefault()) } -/** - * Returns full display name in default Locale (Monday, Tuesday, Wednesday, etc.) - */ -fun ZonedDateTime.dayOfWeekString(): String { - return DayOfWeek.from(this).getDisplayName(TextStyle.FULL, Locale.getDefault()) -} - fun formatter(): DateTimeFormatter = DateTimeFormatterBuilder().append(DateTimeFormatter.ISO_LOCAL_DATE) .appendPattern("['T'][' ']") diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/TaskDescriptionBuilder.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/TaskDescriptionBuilder.kt index 24863fd1a..f55f7561d 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/TaskDescriptionBuilder.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/TaskDescriptionBuilder.kt @@ -7,6 +7,7 @@ import android.text.format.DateUtils import com.habitrpg.android.habitica.R import com.habitrpg.android.habitica.models.tasks.Task import com.habitrpg.common.habitica.extensions.nameSentenceRes +import com.habitrpg.common.habitica.helpers.LanguageHelper import com.habitrpg.shared.habitica.models.tasks.Frequency import com.habitrpg.shared.habitica.models.tasks.TaskDifficulty import com.habitrpg.shared.habitica.models.tasks.TaskType @@ -131,7 +132,7 @@ class TaskDescriptionBuilder(private val context: Context) { private fun withOrdinal(day: Int): String { return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - val formatter = MessageFormat("{0,ordinal}", Locale.getDefault()) + val formatter = MessageFormat("{0,ordinal}", LanguageHelper.systemLocale) formatter.format(arrayOf(day)) } else { day.toString() diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/prefs/TimePreference.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/prefs/TimePreference.kt index c54df3532..b12d4fd4a 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/prefs/TimePreference.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/prefs/TimePreference.kt @@ -4,6 +4,7 @@ import android.content.Context import android.content.res.TypedArray import android.util.AttributeSet import androidx.preference.DialogPreference +import com.habitrpg.common.habitica.helpers.LanguageHelper import java.text.DateFormat import java.util.Calendar import java.util.Locale @@ -49,7 +50,7 @@ class TimePreference(ctxt: Context, attrs: AttributeSet?) : DialogPreference(ctx val calendar = Calendar.getInstance(Locale.getDefault()) calendar.set(Calendar.HOUR_OF_DAY, getHour(timeval)) calendar.set(Calendar.MINUTE, getMinute(timeval)) - val formatter = DateFormat.getTimeInstance(DateFormat.SHORT) + val formatter = DateFormat.getTimeInstance(DateFormat.SHORT, LanguageHelper.systemLocale) super.setSummary(formatter.format(calendar.time)) } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/ArmoireActivity.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/ArmoireActivity.kt index 536af2e26..6732640c2 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/ArmoireActivity.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/ArmoireActivity.kt @@ -370,7 +370,7 @@ class ArmoireActivity : BaseActivity() { lastValue = value binding.titleView.text = - text.replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString() } + text.replaceFirstChar { if (it.isLowerCase()) it.titlecase() else it.toString() } binding.equipButton.visibility = if (type == "gear") View.VISIBLE else View.GONE when (type) { "gear" -> { diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/FullProfileActivity.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/FullProfileActivity.kt index 9d27382c3..632611ca5 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/FullProfileActivity.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/FullProfileActivity.kt @@ -45,6 +45,7 @@ import com.habitrpg.android.habitica.ui.views.HabiticaSnackbar import com.habitrpg.android.habitica.ui.views.HabiticaSnackbar.SnackbarDisplayType import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaAlertDialog import com.habitrpg.common.habitica.extensions.loadImage +import com.habitrpg.common.habitica.helpers.LanguageHelper import com.habitrpg.common.habitica.helpers.MainNavigationController import com.habitrpg.common.habitica.helpers.RecyclerViewState import com.habitrpg.common.habitica.helpers.launchCatching @@ -57,6 +58,7 @@ import kotlinx.coroutines.MainScope import kotlinx.coroutines.delay import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.launch +import java.text.DateFormat import java.text.SimpleDateFormat import javax.inject.Inject import kotlin.math.floor @@ -96,7 +98,7 @@ class FullProfileActivity : BaseActivity() { private var attributePerSum = 0f private var attributeDetailsHidden = true private val attributeRows = ArrayList() - private val dateFormatter = SimpleDateFormat.getDateInstance() + private val dateFormatter = SimpleDateFormat.getDateInstance(DateFormat.MEDIUM, LanguageHelper.systemLocale) private lateinit var binding: ActivityFullProfileBinding override fun onCreate(savedInstanceState: Bundle?) { diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/TaskSummaryActivity.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/TaskSummaryActivity.kt index ef32de50e..ee7ac7744 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/TaskSummaryActivity.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/TaskSummaryActivity.kt @@ -61,6 +61,7 @@ import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel import com.habitrpg.android.habitica.ui.views.CompletedAt import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper import com.habitrpg.android.habitica.ui.views.UserRow +import com.habitrpg.common.habitica.helpers.LanguageHelper import com.habitrpg.common.habitica.helpers.MainNavigationController import com.habitrpg.common.habitica.theme.HabiticaTheme import com.habitrpg.shared.habitica.models.tasks.TaskType @@ -321,7 +322,7 @@ fun TaskSummaryView(viewModel: TaskSummaryViewModel) { Text("") } task?.group?.assignedDetailsFor(viewModel.userViewModel.userID)?.let { - val formatter = DateFormat.getDateInstance(DateFormat.SHORT) + val formatter = DateFormat.getDateInstance(DateFormat.SHORT, LanguageHelper.systemLocale) Text( stringResource( R.string.assigned_to_you_by, diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/ChatRecyclerViewAdapter.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/ChatRecyclerViewAdapter.kt index 4f69ca1c1..104b130a4 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/ChatRecyclerViewAdapter.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/social/ChatRecyclerViewAdapter.kt @@ -13,6 +13,8 @@ import com.habitrpg.android.habitica.models.user.User import com.habitrpg.android.habitica.ui.adapter.BaseRecyclerViewAdapter import com.habitrpg.android.habitica.ui.adapter.DiffCallback import com.habitrpg.android.habitica.ui.viewHolders.ChatRecyclerMessageViewHolder +import com.habitrpg.common.habitica.helpers.LanguageHelper +import java.text.SimpleDateFormat class ChatDiffCallback(oldList: List, newList: List) : DiffCallback(oldList, newList) { @@ -124,7 +126,7 @@ class ChatRecyclerViewAdapter(user: User?, private val isTavern: Boolean) : } class SystemChatMessageViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { - private val dateTime = java.text.SimpleDateFormat.getDateTimeInstance() + private val dateTime = java.text.SimpleDateFormat.getDateInstance(SimpleDateFormat.MEDIUM, LanguageHelper.systemLocale) val binding = SystemChatMessageBinding.bind(itemView) var onShouldExpand: (() -> Unit)? = null diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/tasks/DailyViewHolder.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/tasks/DailyViewHolder.kt index 67602bd58..758ba001a 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/tasks/DailyViewHolder.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/tasks/DailyViewHolder.kt @@ -4,6 +4,7 @@ import android.view.View import com.habitrpg.android.habitica.helpers.GroupPlanInfoProvider import com.habitrpg.android.habitica.models.tasks.ChecklistItem import com.habitrpg.android.habitica.models.tasks.Task +import com.habitrpg.common.habitica.helpers.LanguageHelper import com.habitrpg.shared.habitica.models.responses.TaskDirection import java.text.DateFormat import java.util.Calendar @@ -91,7 +92,7 @@ class DailyViewHolder( companion object { private val formatter: DateFormat get() { - return DateFormat.getTimeInstance(DateFormat.SHORT) + return DateFormat.getTimeInstance(DateFormat.SHORT, LanguageHelper.systemLocale) } } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/CompletedAt.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/CompletedAt.kt index ee8b2fde3..31c6f17d6 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/CompletedAt.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/CompletedAt.kt @@ -14,12 +14,13 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import com.habitrpg.android.habitica.R +import com.habitrpg.common.habitica.helpers.LanguageHelper import java.text.DateFormat import java.util.Date -val completedTimeFormatToday: DateFormat = DateFormat.getTimeInstance(DateFormat.SHORT) +val completedTimeFormatToday: DateFormat = DateFormat.getTimeInstance(DateFormat.SHORT, LanguageHelper.systemLocale) val completedTimeFormat: DateFormat = - DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT) + DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, LanguageHelper.systemLocale) @Composable fun CompletedAt( diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/tasks/form/ReminderItemFormView.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/tasks/form/ReminderItemFormView.kt index 787959b6c..92238cf2e 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/tasks/form/ReminderItemFormView.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/tasks/form/ReminderItemFormView.kt @@ -20,6 +20,7 @@ import com.habitrpg.android.habitica.models.tasks.RemindersItem import com.habitrpg.common.habitica.extensions.dpToPx import com.habitrpg.common.habitica.extensions.getThemeColor import com.habitrpg.common.habitica.extensions.layoutInflater +import com.habitrpg.common.habitica.helpers.LanguageHelper import com.habitrpg.shared.habitica.models.tasks.TaskType import java.text.DateFormat import java.time.ZonedDateTime @@ -51,12 +52,12 @@ class ReminderItemFormView private val formatter: DateFormat get() { return if (taskType == TaskType.DAILY) { - DateFormat.getTimeInstance(DateFormat.SHORT, Locale.getDefault()) + DateFormat.getTimeInstance(DateFormat.SHORT, LanguageHelper.systemLocale) } else { DateFormat.getDateTimeInstance( DateFormat.SHORT, DateFormat.SHORT, - Locale.getDefault(), + LanguageHelper.systemLocale, ) } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/tasks/form/TaskSchedulingControls.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/tasks/form/TaskSchedulingControls.kt index a192c77da..8bce9d916 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/tasks/form/TaskSchedulingControls.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/tasks/form/TaskSchedulingControls.kt @@ -24,6 +24,7 @@ import com.habitrpg.android.habitica.ui.adapter.SimpleSpinnerAdapter import com.habitrpg.common.habitica.extensions.dpToPx import com.habitrpg.common.habitica.extensions.getThemeColor import com.habitrpg.common.habitica.extensions.layoutInflater +import com.habitrpg.common.habitica.helpers.LanguageHelper import com.habitrpg.shared.habitica.models.tasks.Frequency import com.habitrpg.shared.habitica.models.tasks.TaskType import java.text.DateFormat @@ -43,7 +44,7 @@ class TaskSchedulingControls private val binding = TaskFormTaskSchedulingBinding.inflate(context.layoutInflater, this) var tintColor: Int = ContextCompat.getColor(context, R.color.brand_300) - private val dateFormatter = DateFormat.getDateInstance(DateFormat.MEDIUM) + private val dateFormatter = DateFormat.getDateInstance(DateFormat.MEDIUM, LanguageHelper.systemLocale) private val frequencyAdapter = SimpleSpinnerAdapter(context, R.array.repeatables_frequencies) var taskType = TaskType.DAILY @@ -61,7 +62,7 @@ class TaskSchedulingControls startDateCalendar.time = value generateSummary() } - private var startDateCalendar = Calendar.getInstance() + private var startDateCalendar = Calendar.getInstance(LanguageHelper.systemLocale) var dueDate: Date? = null set(value) { field = value @@ -422,7 +423,7 @@ class TaskSchedulingControls val date = startDateCalendar.get(Calendar.DATE) val formattedDate = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - val formatter = MessageFormat("{0,ordinal}", Locale.getDefault()) + val formatter = MessageFormat("{0,ordinal}", LanguageHelper.systemLocale) formatter.format(arrayOf(date)) } else { date.toString() @@ -432,7 +433,7 @@ class TaskSchedulingControls val week = startDateCalendar.get(Calendar.WEEK_OF_MONTH) val formattedWeek = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - val formatter = MessageFormat("{0,ordinal}", Locale.getDefault()) + val formatter = MessageFormat("{0,ordinal}", LanguageHelper.systemLocale) formatter.format(arrayOf(week)) } else { week.toString() @@ -441,7 +442,7 @@ class TaskSchedulingControls startDateCalendar.getDisplayName( Calendar.DAY_OF_WEEK, Calendar.LONG, - Locale.getDefault(), + LanguageHelper.systemLocale, ) " on the $formattedWeek week on $dayLongName" } diff --git a/common/src/main/java/com/habitrpg/common/habitica/helpers/LanguageHelper.kt b/common/src/main/java/com/habitrpg/common/habitica/helpers/LanguageHelper.kt index f9d64cb5a..70ac35e89 100644 --- a/common/src/main/java/com/habitrpg/common/habitica/helpers/LanguageHelper.kt +++ b/common/src/main/java/com/habitrpg/common/habitica/helpers/LanguageHelper.kt @@ -1,5 +1,6 @@ package com.habitrpg.common.habitica.helpers +import android.annotation.SuppressLint import java.util.Locale class LanguageHelper(languageSharedPref: String?) { @@ -38,4 +39,10 @@ class LanguageHelper(languageSharedPref: String?) { } } } + + companion object { + // Intentional, we want the system locale, not the app locale + @SuppressLint("ConstantLocale") + val systemLocale = Locale.getAvailableLocales().firstOrNull() ?: Locale.getDefault() + } } diff --git a/version.properties b/version.properties index 9d8d15aeb..71396ca9c 100644 --- a/version.properties +++ b/version.properties @@ -1,2 +1,2 @@ NAME=4.5.0 -CODE=8021 +CODE=8031 \ No newline at end of file