Localized formats

This commit is contained in:
Sad Ellie 2023-10-08 21:44:36 +03:00
parent cfbfd6041d
commit 08d78427d8
9 changed files with 190 additions and 66 deletions

View File

@ -25,10 +25,16 @@ import android.util.AttributeSet
import android.view.View import android.view.View
import androidx.activity.compose.setContent import androidx.activity.compose.setContent
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.app.AppCompatDelegate
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.remember
import androidx.compose.ui.platform.LocalConfiguration
import androidx.core.view.WindowCompat import androidx.core.view.WindowCompat
import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.sadellie.unitto.core.ui.LocalLocale
import com.sadellie.unitto.data.userprefs.UserPreferencesRepository import com.sadellie.unitto.data.userprefs.UserPreferencesRepository
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import java.util.Locale
import javax.inject.Inject import javax.inject.Inject
@AndroidEntryPoint @AndroidEntryPoint
@ -43,8 +49,16 @@ internal class MainActivity : AppCompatActivity() {
setContent { setContent {
val prefs = userPrefsRepository.appPrefs val prefs = userPrefsRepository.appPrefs
.collectAsStateWithLifecycle(null).value .collectAsStateWithLifecycle(null).value
val locale = remember(LocalConfiguration.current) {
val tag: String = AppCompatDelegate
.getApplicationLocales()
.toLanguageTags()
if (tag.isEmpty()) Locale.getDefault() else Locale.forLanguageTag(tag)
}
UnittoApp(prefs) CompositionLocalProvider(LocalLocale provides locale) {
UnittoApp(prefs)
}
} }
} }

View File

@ -0,0 +1,26 @@
/*
* Unitto is a unit converter for Android
* Copyright (c) 2023 Elshan Agaev
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sadellie.unitto.core.ui
import androidx.compose.runtime.compositionLocalOf
import java.util.Locale
val LocalLocale = compositionLocalOf {
Locale.getDefault()
}

View File

@ -19,60 +19,56 @@
package com.sadellie.unitto.core.ui.datetime package com.sadellie.unitto.core.ui.datetime
import java.time.format.DateTimeFormatter import java.time.format.DateTimeFormatter
import java.util.Locale
data object UnittoDateTimeFormatter { internal data object UnittoDateTimeFormatter {
/** /**
* 23:59 * 23:59
*/ */
val time24Formatter: DateTimeFormatter by lazy { DateTimeFormatter.ofPattern("HH:mm") } fun time24(locale: Locale): DateTimeFormatter = DateTimeFormatter.ofPattern("HH:mm", locale)
/** /**
* 11:59 AM * 11:59 AM
*/ */
val time12FormatterFull: DateTimeFormatter by lazy { DateTimeFormatter.ofPattern("hh:mm a") } fun time12Full(locale: Locale): DateTimeFormatter = DateTimeFormatter.ofPattern("hh:mm a", locale)
/** /**
* 11:59 * 11:59 (no AM/PM)
*/ */
val time12Formatter1: DateTimeFormatter by lazy { DateTimeFormatter.ofPattern("hh:mm") } fun time12Short(locale: Locale): DateTimeFormatter = DateTimeFormatter.ofPattern("hh:mm", locale)
/** /**
* 23 * 23
*/ */
val time24OnlyHoursFormatter: DateTimeFormatter by lazy { DateTimeFormatter.ofPattern("HH") } fun time24Hours(locale: Locale): DateTimeFormatter = DateTimeFormatter.ofPattern("HH", locale)
/** /**
* 23 * 23
*/ */
val time12OnlyHoursFormatter: DateTimeFormatter by lazy { DateTimeFormatter.ofPattern("hh") } fun time12Hours(locale: Locale): DateTimeFormatter = DateTimeFormatter.ofPattern("hh", locale)
/** /**
* 59 * 59
*/ */
val timeOnlyMinutesFormatter: DateTimeFormatter by lazy { DateTimeFormatter.ofPattern("mm") } fun timeMinutes(locale: Locale): DateTimeFormatter = DateTimeFormatter.ofPattern("mm", locale)
/**
* 59
*/
val timeOnlySecondsFormatter: DateTimeFormatter by lazy { DateTimeFormatter.ofPattern("ss") }
/** /**
* AM * AM
*/ */
val time12Formatter2: DateTimeFormatter by lazy { DateTimeFormatter.ofPattern("a") } fun time12AmPm(locale: Locale): DateTimeFormatter = DateTimeFormatter.ofPattern("a", locale)
/** /**
* 31 Dec 2077 * 31 Dec 2077
*/ */
val dayMonthYear: DateTimeFormatter by lazy { DateTimeFormatter.ofPattern("d MMM y") } fun dateDayMonthYear(locale: Locale): DateTimeFormatter = DateTimeFormatter.ofPattern("d MMM y", locale)
/** /**
* Mon, 31 Dec, 2077 * Mon, 31 Dec, 2077
*/ */
val weekDayMonthYear: DateTimeFormatter by lazy { DateTimeFormatter.ofPattern("EEE, MMM d, y") } fun dateWeekDayMonthYear(locale: Locale): DateTimeFormatter = DateTimeFormatter.ofPattern("EEE, MMM d, y", locale)
/** /**
* GMT+3 * GMT+3
*/ */
val zoneFormatPattern: DateTimeFormatter by lazy { DateTimeFormatter.ofPattern("O") } fun zone(locale: Locale): DateTimeFormatter = DateTimeFormatter.ofPattern("O", locale)
} }

View File

@ -18,13 +18,13 @@
package com.sadellie.unitto.core.ui.datetime package com.sadellie.unitto.core.ui.datetime
import android.text.format.DateFormat
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import com.sadellie.unitto.core.base.R import com.sadellie.unitto.core.base.R
import java.time.LocalDate
import java.time.ZonedDateTime import java.time.ZonedDateTime
import java.time.temporal.ChronoUnit import java.time.temporal.ChronoUnit
import java.util.Locale
import kotlin.math.absoluteValue import kotlin.math.absoluteValue
/** /**
@ -35,44 +35,105 @@ import kotlin.math.absoluteValue
* Depends on system preferences * Depends on system preferences
* *
* @return Formatted string * @return Formatted string
* @see UnittoDateTimeFormatter.time24
* @see UnittoDateTimeFormatter.time12Full
*/ */
@Composable fun ZonedDateTime.formatTime(
fun ZonedDateTime.formatLocal(): String { locale: Locale,
return if (DateFormat.is24HourFormat(LocalContext.current)) format(UnittoDateTimeFormatter.time24Formatter) is24Hour: Boolean,
else format(UnittoDateTimeFormatter.time12FormatterFull) ): String =
} if (is24Hour) {
format(UnittoDateTimeFormatter.time24(locale))
} else {
format(UnittoDateTimeFormatter.time12Full(locale))
}
@Composable /**
fun ZonedDateTime.formatOnlyHours(): String { * @see UnittoDateTimeFormatter.time12Short
return if (DateFormat.is24HourFormat(LocalContext.current)) format(UnittoDateTimeFormatter.time24OnlyHoursFormatter) */
else format(UnittoDateTimeFormatter.time12OnlyHoursFormatter) fun ZonedDateTime.formatTime12Short(
} locale: Locale,
): String =
format(UnittoDateTimeFormatter.time12Short(locale))
@Composable /**
fun ZonedDateTime.formatOnlyMinutes(): String { * Formats date time into something like:
return format(UnittoDateTimeFormatter.timeOnlyMinutesFormatter) *
} * 23 or 11
*
* Depends on system preferences
*
* @return Formatted string
* @see UnittoDateTimeFormatter.time24Hours
* @see UnittoDateTimeFormatter.time12Hours
*/
fun ZonedDateTime.formatTimeHours(
locale: Locale,
is24Hour: Boolean,
): String =
if (is24Hour)
format(UnittoDateTimeFormatter.time24Hours(locale))
else
format(UnittoDateTimeFormatter.time12Hours(locale))
@Composable /**
fun ZonedDateTime.formatOnlySeconds(): String { * @see UnittoDateTimeFormatter.timeMinutes
return format(UnittoDateTimeFormatter.timeOnlySecondsFormatter) */
} fun ZonedDateTime.formatTimeMinutes(
locale: Locale,
): String =
format(UnittoDateTimeFormatter.timeMinutes(locale))
@Composable /**
fun ZonedDateTime.formatOnlyAmPm(): String { * @see UnittoDateTimeFormatter.time12AmPm
return format(UnittoDateTimeFormatter.time12Formatter2) */
} fun ZonedDateTime.formatTimeAmPm(
locale: Locale,
): String =
format(UnittoDateTimeFormatter.time12AmPm(locale))
/**
* @see UnittoDateTimeFormatter.dateWeekDayMonthYear
*/
fun ZonedDateTime.formatDateWeekDayMonthYear(
locale: Locale,
): String =
format(UnittoDateTimeFormatter.dateWeekDayMonthYear(locale))
/**
* @see UnittoDateTimeFormatter.zone
*/
fun ZonedDateTime.formatZone(
locale: Locale,
): String =
format(UnittoDateTimeFormatter.zone(locale))
/**
* @see UnittoDateTimeFormatter.dateDayMonthYear
*/
fun ZonedDateTime.formatDateDayMonthYear(
locale: Locale,
): String =
format(UnittoDateTimeFormatter.dateDayMonthYear(locale))
/**
* @see UnittoDateTimeFormatter.dateWeekDayMonthYear
*/
fun LocalDate.formatDateWeekDayMonthYear(
locale: Locale
): String =
format(UnittoDateTimeFormatter.dateWeekDayMonthYear(locale))
/** /**
* Format offset string. Examples: * Format offset string. Examples:
* *
* 0 * 0h
* *
* +8 * +8h
* *
* +8, tomorrow * +8h, tomorrow
* *
* -8, yesterday * -8h 30m, yesterday
* *
* @receiver [ZonedDateTime] Time with offset. * @receiver [ZonedDateTime] Time with offset.
* @param currentTime Time without offset. * @param currentTime Time without offset.
@ -80,7 +141,7 @@ fun ZonedDateTime.formatOnlyAmPm(): String {
*/ */
@Composable @Composable
fun ZonedDateTime.formatOffset( fun ZonedDateTime.formatOffset(
currentTime: ZonedDateTime currentTime: ZonedDateTime,
): String? { ): String? {
val offsetFixed = ChronoUnit.SECONDS.between(currentTime, this) val offsetFixed = ChronoUnit.SECONDS.between(currentTime, this)

View File

@ -69,6 +69,7 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.sadellie.unitto.core.base.OutputFormat import com.sadellie.unitto.core.base.OutputFormat
import com.sadellie.unitto.core.base.R import com.sadellie.unitto.core.base.R
import com.sadellie.unitto.core.base.Token import com.sadellie.unitto.core.base.Token
import com.sadellie.unitto.core.ui.LocalLocale
import com.sadellie.unitto.core.ui.common.ColumnWithConstraints import com.sadellie.unitto.core.ui.common.ColumnWithConstraints
import com.sadellie.unitto.core.ui.common.MenuButton import com.sadellie.unitto.core.ui.common.MenuButton
import com.sadellie.unitto.core.ui.common.PortraitLandscape import com.sadellie.unitto.core.ui.common.PortraitLandscape
@ -78,13 +79,14 @@ import com.sadellie.unitto.core.ui.common.UnittoScreenWithTopBar
import com.sadellie.unitto.core.ui.common.textfield.ExpressionTextField import com.sadellie.unitto.core.ui.common.textfield.ExpressionTextField
import com.sadellie.unitto.core.ui.common.textfield.FormatterSymbols import com.sadellie.unitto.core.ui.common.textfield.FormatterSymbols
import com.sadellie.unitto.core.ui.common.textfield.UnformattedTextField import com.sadellie.unitto.core.ui.common.textfield.UnformattedTextField
import com.sadellie.unitto.core.ui.datetime.UnittoDateTimeFormatter import com.sadellie.unitto.core.ui.datetime.formatDateWeekDayMonthYear
import com.sadellie.unitto.data.common.format import com.sadellie.unitto.data.common.format
import com.sadellie.unitto.data.model.UnitGroup import com.sadellie.unitto.data.model.UnitGroup
import com.sadellie.unitto.data.model.unit.AbstractUnit import com.sadellie.unitto.data.model.unit.AbstractUnit
import com.sadellie.unitto.feature.converter.components.DefaultKeyboard import com.sadellie.unitto.feature.converter.components.DefaultKeyboard
import com.sadellie.unitto.feature.converter.components.NumberBaseKeyboard import com.sadellie.unitto.feature.converter.components.NumberBaseKeyboard
import com.sadellie.unitto.feature.converter.components.UnitSelectionButton import com.sadellie.unitto.feature.converter.components.UnitSelectionButton
import java.util.Locale
@Composable @Composable
internal fun ConverterRoute( internal fun ConverterRoute(
@ -257,6 +259,7 @@ private fun Default(
clearInput: () -> Unit, clearInput: () -> Unit,
refreshCurrencyRates: (AbstractUnit) -> Unit, refreshCurrencyRates: (AbstractUnit) -> Unit,
) { ) {
val locale: Locale = LocalLocale.current
var calculation by remember(uiState.calculation) { var calculation by remember(uiState.calculation) {
mutableStateOf( mutableStateOf(
TextFieldValue(uiState.calculation?.format(uiState.scale, uiState.outputFormat) ?: "") TextFieldValue(uiState.calculation?.format(uiState.scale, uiState.outputFormat) ?: "")
@ -266,7 +269,7 @@ private fun Default(
val lastUpdate by remember(uiState) { val lastUpdate by remember(uiState) {
derivedStateOf { derivedStateOf {
if (uiState.currencyRateUpdateState !is CurrencyRateUpdateState.Ready) return@derivedStateOf null if (uiState.currencyRateUpdateState !is CurrencyRateUpdateState.Ready) return@derivedStateOf null
uiState.currencyRateUpdateState.date.format(UnittoDateTimeFormatter.weekDayMonthYear) uiState.currencyRateUpdateState.date.formatDateWeekDayMonthYear(locale)
} }
} }

View File

@ -42,8 +42,12 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import com.sadellie.unitto.core.ui.LocalLocale
import com.sadellie.unitto.core.ui.common.squashable import com.sadellie.unitto.core.ui.common.squashable
import com.sadellie.unitto.core.ui.datetime.UnittoDateTimeFormatter import com.sadellie.unitto.core.ui.datetime.formatDateWeekDayMonthYear
import com.sadellie.unitto.core.ui.datetime.formatTime
import com.sadellie.unitto.core.ui.datetime.formatTime12Short
import com.sadellie.unitto.core.ui.datetime.formatTimeAmPm
import java.time.ZonedDateTime import java.time.ZonedDateTime
@Composable @Composable
@ -56,6 +60,8 @@ internal fun DateTimeSelectorBlock(
onDateClick: () -> Unit = {}, onDateClick: () -> Unit = {},
onLongClick: () -> Unit = {}, onLongClick: () -> Unit = {},
) { ) {
val locale = LocalLocale.current
Column( Column(
modifier = modifier modifier = modifier
.squashable( .squashable(
@ -72,7 +78,7 @@ internal fun DateTimeSelectorBlock(
if (DateFormat.is24HourFormat(LocalContext.current)) { if (DateFormat.is24HourFormat(LocalContext.current)) {
AnimatedContent( AnimatedContent(
targetState = dateTime.format(UnittoDateTimeFormatter.time24Formatter), targetState = dateTime,
transitionSpec = { transitionSpec = {
slideInVertically { height -> height } + fadeIn() togetherWith slideInVertically { height -> height } + fadeIn() togetherWith
slideOutVertically { height -> -height } + fadeOut() using slideOutVertically { height -> -height } + fadeOut() using
@ -86,7 +92,7 @@ internal fun DateTimeSelectorBlock(
interactionSource = remember { MutableInteractionSource() }, interactionSource = remember { MutableInteractionSource() },
onClick = onTimeClick onClick = onTimeClick
), ),
text = time, text = time.formatTime(locale, true),
style = MaterialTheme.typography.displaySmall, style = MaterialTheme.typography.displaySmall,
maxLines = 1 maxLines = 1
) )
@ -109,7 +115,7 @@ internal fun DateTimeSelectorBlock(
label = "Animated 12 hour", label = "Animated 12 hour",
) { time -> ) { time ->
Text( Text(
text = time.format(UnittoDateTimeFormatter.time12Formatter1), text = time.formatTime12Short(locale),
style = MaterialTheme.typography.displaySmall, style = MaterialTheme.typography.displaySmall,
maxLines = 1 maxLines = 1
) )
@ -125,7 +131,7 @@ internal fun DateTimeSelectorBlock(
label = "Animated am/pm", label = "Animated am/pm",
) { time -> ) { time ->
Text( Text(
text = time.format(UnittoDateTimeFormatter.time12Formatter2), text = time.formatTimeAmPm(locale),
style = MaterialTheme.typography.bodyLarge, style = MaterialTheme.typography.bodyLarge,
maxLines = 1 maxLines = 1
) )
@ -148,7 +154,7 @@ internal fun DateTimeSelectorBlock(
interactionSource = remember { MutableInteractionSource() }, interactionSource = remember { MutableInteractionSource() },
onClick = onDateClick onClick = onDateClick
), ),
text = date.format(UnittoDateTimeFormatter.weekDayMonthYear), text = date.formatDateWeekDayMonthYear(locale),
style = MaterialTheme.typography.bodySmall style = MaterialTheme.typography.bodySmall
) )
} }

View File

@ -23,6 +23,7 @@ import android.icu.text.TimeZoneNames
import android.icu.util.TimeZone import android.icu.util.TimeZone
import android.icu.util.ULocale import android.icu.util.ULocale
import android.os.Build import android.os.Build
import android.text.format.DateFormat.is24HourFormat
import androidx.annotation.RequiresApi import androidx.annotation.RequiresApi
import androidx.compose.animation.Crossfade import androidx.compose.animation.Crossfade
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
@ -37,16 +38,18 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.input.nestedscroll.nestedScroll import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.TextFieldValue import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.hilt.navigation.compose.hiltViewModel import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.sadellie.unitto.core.base.R import com.sadellie.unitto.core.base.R
import com.sadellie.unitto.core.ui.LocalLocale
import com.sadellie.unitto.core.ui.common.UnittoEmptyScreen import com.sadellie.unitto.core.ui.common.UnittoEmptyScreen
import com.sadellie.unitto.core.ui.common.UnittoListItem import com.sadellie.unitto.core.ui.common.UnittoListItem
import com.sadellie.unitto.core.ui.common.UnittoSearchBar import com.sadellie.unitto.core.ui.common.UnittoSearchBar
import com.sadellie.unitto.core.ui.datetime.formatLocal import com.sadellie.unitto.core.ui.datetime.formatTime
import com.sadellie.unitto.core.ui.theme.numberHeadlineSmall import com.sadellie.unitto.core.ui.theme.numberHeadlineSmall
import com.sadellie.unitto.data.common.displayName import com.sadellie.unitto.data.common.displayName
import com.sadellie.unitto.data.common.offset import com.sadellie.unitto.data.common.offset
@ -83,6 +86,8 @@ fun AddTimeZoneScreen(
userTime: ZonedDateTime, userTime: ZonedDateTime,
) { ) {
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState()) val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState())
val locale = LocalLocale.current
val is24Hour = is24HourFormat(LocalContext.current)
Scaffold( Scaffold(
modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection), modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
@ -113,7 +118,9 @@ fun AddTimeZoneScreen(
supportingContent = { Text(it.region) }, supportingContent = { Text(it.region) },
trailingContent = { trailingContent = {
Text( Text(
text = it.timeZone.offset(userTime).formatLocal(), text = it.timeZone
.offset(userTime)
.formatTime(locale, is24Hour),
style = MaterialTheme.typography.numberHeadlineSmall style = MaterialTheme.typography.numberHeadlineSmall
) )
} }

View File

@ -23,6 +23,7 @@ import android.icu.text.TimeZoneNames
import android.icu.util.TimeZone import android.icu.util.TimeZone
import android.icu.util.ULocale import android.icu.util.ULocale
import android.os.Build import android.os.Build
import android.text.format.DateFormat
import androidx.annotation.RequiresApi import androidx.annotation.RequiresApi
import androidx.compose.animation.AnimatedContent import androidx.compose.animation.AnimatedContent
import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.AnimatedVisibility
@ -57,6 +58,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
@ -64,8 +66,9 @@ import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.tooling.preview.PreviewParameterProvider import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import com.sadellie.unitto.core.base.R import com.sadellie.unitto.core.base.R
import com.sadellie.unitto.core.ui.datetime.formatLocal import com.sadellie.unitto.core.ui.LocalLocale
import com.sadellie.unitto.core.ui.datetime.formatOffset import com.sadellie.unitto.core.ui.datetime.formatOffset
import com.sadellie.unitto.core.ui.datetime.formatTime
import com.sadellie.unitto.core.ui.theme.numberHeadlineMedium import com.sadellie.unitto.core.ui.theme.numberHeadlineMedium
import com.sadellie.unitto.data.common.offset import com.sadellie.unitto.data.common.offset
import com.sadellie.unitto.data.common.regionName import com.sadellie.unitto.data.common.regionName
@ -88,6 +91,8 @@ internal fun FavoriteTimeZoneItem(
timeZoneNames: TimeZoneNames, timeZoneNames: TimeZoneNames,
localeDisplayNames: LocaleDisplayNames, localeDisplayNames: LocaleDisplayNames,
) { ) {
val locale = LocalLocale.current
val is24Hour = DateFormat.is24HourFormat(LocalContext.current)
var deleteAnimationRunning by remember { mutableStateOf(false) } var deleteAnimationRunning by remember { mutableStateOf(false) }
val animatedAlpha by animateFloatAsState( val animatedAlpha by animateFloatAsState(
label = "delete animation", label = "delete animation",
@ -146,7 +151,7 @@ internal fun FavoriteTimeZoneItem(
} }
} }
AnimatedContent( AnimatedContent(
targetState = offsetTime.formatLocal(), targetState = offsetTime.formatTime(locale, is24Hour),
label = "Time change", label = "Time change",
transitionSpec = { transitionSpec = {
fadeIn() togetherWith fadeOut() using (SizeTransform(clip = false)) fadeIn() togetherWith fadeOut() using (SizeTransform(clip = false))

View File

@ -18,6 +18,7 @@
package com.sadellie.unitto.feature.timezone.components package com.sadellie.unitto.feature.timezone.components
import android.text.format.DateFormat
import androidx.compose.animation.AnimatedContent import androidx.compose.animation.AnimatedContent
import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.SizeTransform import androidx.compose.animation.SizeTransform
@ -43,14 +44,17 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import com.sadellie.unitto.core.ui.LocalLocale
import com.sadellie.unitto.core.ui.common.squashable import com.sadellie.unitto.core.ui.common.squashable
import com.sadellie.unitto.core.ui.datetime.UnittoDateTimeFormatter import com.sadellie.unitto.core.ui.datetime.formatDateDayMonthYear
import com.sadellie.unitto.core.ui.datetime.formatOnlyHours import com.sadellie.unitto.core.ui.datetime.formatTimeHours
import com.sadellie.unitto.core.ui.datetime.formatOnlyMinutes import com.sadellie.unitto.core.ui.datetime.formatTimeMinutes
import com.sadellie.unitto.core.ui.datetime.formatZone
import com.sadellie.unitto.core.ui.theme.numberBodyLarge import com.sadellie.unitto.core.ui.theme.numberBodyLarge
import com.sadellie.unitto.core.ui.theme.numberDisplayLarge import com.sadellie.unitto.core.ui.theme.numberDisplayLarge
import java.time.ZonedDateTime import java.time.ZonedDateTime
@ -63,6 +67,8 @@ internal fun UserTimeZone(
onResetClick: () -> Unit, onResetClick: () -> Unit,
showReset: Boolean, showReset: Boolean,
) { ) {
val locale = LocalLocale.current
val is24Hour = DateFormat.is24HourFormat(LocalContext.current)
Row( Row(
modifier = modifier modifier = modifier
@ -77,7 +83,7 @@ internal fun UserTimeZone(
) { ) {
Column(Modifier.weight(1f)) { Column(Modifier.weight(1f)) {
Text( Text(
text = userTime.format(UnittoDateTimeFormatter.zoneFormatPattern), text = userTime.formatZone(locale),
style = MaterialTheme.typography.numberBodyLarge, style = MaterialTheme.typography.numberBodyLarge,
color = MaterialTheme.colorScheme.onTertiaryContainer color = MaterialTheme.colorScheme.onTertiaryContainer
) )
@ -85,13 +91,13 @@ internal fun UserTimeZone(
Row( Row(
verticalAlignment = Alignment.Bottom verticalAlignment = Alignment.Bottom
) { ) {
SlidingText(text = userTime.formatOnlyHours()) SlidingText(text = userTime.formatTimeHours(locale, is24Hour))
TimeSeparator() TimeSeparator()
SlidingText(text = userTime.formatOnlyMinutes()) SlidingText(text = userTime.formatTimeMinutes(locale))
} }
Text( Text(
text = userTime.format(UnittoDateTimeFormatter.dayMonthYear), text = userTime.formatDateDayMonthYear(locale),
style = MaterialTheme.typography.headlineMedium, style = MaterialTheme.typography.headlineMedium,
color = MaterialTheme.colorScheme.onTertiaryContainer color = MaterialTheme.colorScheme.onTertiaryContainer
) )