mirror of
https://github.com/Myzel394/NumberHub.git
synced 2025-06-19 00:35:26 +02:00
Localized formats
This commit is contained in:
parent
cfbfd6041d
commit
08d78427d8
@ -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,10 +49,18 @@ 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)
|
||||||
|
}
|
||||||
|
|
||||||
|
CompositionLocalProvider(LocalLocale provides locale) {
|
||||||
UnittoApp(prefs)
|
UnittoApp(prefs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
parent: View?,
|
parent: View?,
|
||||||
|
@ -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()
|
||||||
|
}
|
@ -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)
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -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))
|
||||||
|
@ -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
|
||||||
)
|
)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user