From e7081e52e5cb1c0d2eb2080d38fa58e5dcbeb68b Mon Sep 17 00:00:00 2001 From: Iliyan Germanov Date: Sat, 31 Aug 2024 23:46:35 +0300 Subject: [PATCH] Fix updating transactions's time (#3453) * Implement a proper DateTimePicker * Fix updating date & time on transaction * Improve the time picker UI * Fix Detekt errors --- .../main/java/com/ivy/wallet/RootActivity.kt | 6 + .../ivy/transaction/EditTransactionScreen.kt | 30 +--- .../transaction/EditTransactionViewEvent.kt | 11 +- .../transaction/EditTransactionViewModel.kt | 77 +++++----- .../java/com/ivy/base/time/TimeProvider.kt | 2 + .../ivy/base/time/impl/DeviceTimeProvider.kt | 3 + .../main/java/com/ivy/ui/di/IvyUiBindings.kt | 11 +- ...imePreferences.kt => DevicePreferences.kt} | 2 +- .../ivy/ui/time/impl/AndroidDateTimePicker.kt | 142 ++++++++++++++++++ ...erences.kt => AndroidDevicePreferences.kt} | 6 +- .../com/ivy/ui/time/impl/DateTimePicker.kt | 23 +++ .../com/ivy/ui/time/impl/IvyTimeFormatter.kt | 10 +- .../ivy/ui/time/impl/IvyTimeFormatterTest.kt | 10 +- .../main/java/com/ivy/design/utils/Preview.kt | 4 +- 14 files changed, 249 insertions(+), 88 deletions(-) rename shared/ui/core/src/main/java/com/ivy/ui/time/{DeviceTimePreferences.kt => DevicePreferences.kt} (76%) create mode 100644 shared/ui/core/src/main/java/com/ivy/ui/time/impl/AndroidDateTimePicker.kt rename shared/ui/core/src/main/java/com/ivy/ui/time/impl/{AndroidDeviceTimePreferences.kt => AndroidDevicePreferences.kt} (75%) create mode 100644 shared/ui/core/src/main/java/com/ivy/ui/time/impl/DateTimePicker.kt diff --git a/app/src/main/java/com/ivy/wallet/RootActivity.kt b/app/src/main/java/com/ivy/wallet/RootActivity.kt index 9809a14664..a83fbf993b 100644 --- a/app/src/main/java/com/ivy/wallet/RootActivity.kt +++ b/app/src/main/java/com/ivy/wallet/RootActivity.kt @@ -48,6 +48,7 @@ import com.ivy.navigation.Navigation import com.ivy.navigation.NavigationRoot import com.ivy.ui.R import com.ivy.ui.time.TimeFormatter +import com.ivy.ui.time.impl.DateTimePicker import com.ivy.wallet.ui.applocked.AppLockedScreen import com.ivy.widget.balance.WalletBalanceWidgetReceiver import com.ivy.widget.transaction.AddTransactionWidget @@ -78,6 +79,9 @@ class RootActivity : AppCompatActivity(), RootScreen { @Inject lateinit var timeFormatter: TimeFormatter + @Inject + lateinit var dateTimePicker: DateTimePicker + private lateinit var createFileLauncher: ActivityResultLauncher private lateinit var onFileCreated: (fileUri: Uri) -> Unit @@ -154,6 +158,8 @@ class RootActivity : AppCompatActivity(), RootScreen { } } } + + dateTimePicker.Content() } } diff --git a/screen/edit-transaction/src/main/java/com/ivy/transaction/EditTransactionScreen.kt b/screen/edit-transaction/src/main/java/com/ivy/transaction/EditTransactionScreen.kt index 7aa6e97723..dac4dabc1c 100644 --- a/screen/edit-transaction/src/main/java/com/ivy/transaction/EditTransactionScreen.kt +++ b/screen/edit-transaction/src/main/java/com/ivy/transaction/EditTransactionScreen.kt @@ -84,9 +84,7 @@ import kotlinx.collections.immutable.ImmutableSet import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentSetOf import java.time.Instant -import java.time.LocalDate import java.time.LocalDateTime -import java.time.LocalTime import java.time.ZoneOffset import java.util.UUID import kotlin.math.roundToInt @@ -126,10 +124,10 @@ fun BoxWithConstraintsScope.EditTransactionScreen(screen: EditTransactionScreen) transactionAssociatedTags = uiState.transactionAssociatedTags, hasChanges = uiState.hasChanges, onSetDate = { - viewModel.onEvent(EditTransactionViewEvent.OnSetDate(it)) + viewModel.onEvent(EditTransactionViewEvent.OnChangeDate) }, onSetTime = { - viewModel.onEvent(EditTransactionViewEvent.OnSetTime(it)) + viewModel.onEvent(EditTransactionViewEvent.OnChangeTime) }, onTitleChange = { viewModel.onEvent(EditTransactionViewEvent.OnTitleChanged(it)) @@ -218,8 +216,8 @@ private fun BoxWithConstraintsScope.UI( onAccountChange: (Account) -> Unit, onToAccountChange: (Account) -> Unit, onDueDateChange: (LocalDateTime?) -> Unit, - onSetDate: (LocalDate) -> Unit, - onSetTime: (LocalTime) -> Unit, + onSetDate: () -> Unit, + onSetTime: () -> Unit, onSetTransactionType: (TransactionType) -> Unit, onCreateCategory: (CreateCategoryData) -> Unit, @@ -382,24 +380,8 @@ private fun BoxWithConstraintsScope.UI( TransactionDateTime( dateTime = dateTime, dueDateTime = dueDate, - onEditDate = { - ivyContext.datePicker( - initialDate = with(timeConverter) { - dateTime?.toLocalDate() - } - ) { date -> - onSetDate((date)) - } - }, - onEditTime = { - ivyContext.timePicker( - initialTime = with(timeConverter) { - dateTime?.toLocalTime() - } - ) { time -> - onSetTime(time) - } - } + onEditDate = onSetDate, + onEditTime = onSetTime, ) if (transactionType == TransactionType.TRANSFER && customExchangeRateState.showCard) { diff --git a/screen/edit-transaction/src/main/java/com/ivy/transaction/EditTransactionViewEvent.kt b/screen/edit-transaction/src/main/java/com/ivy/transaction/EditTransactionViewEvent.kt index 3a5357aa4f..4eba08d963 100644 --- a/screen/edit-transaction/src/main/java/com/ivy/transaction/EditTransactionViewEvent.kt +++ b/screen/edit-transaction/src/main/java/com/ivy/transaction/EditTransactionViewEvent.kt @@ -13,9 +13,7 @@ import com.ivy.wallet.domain.deprecated.logic.model.CreateCategoryData import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableSet import java.time.Instant -import java.time.LocalDate import java.time.LocalDateTime -import java.time.LocalTime @Immutable data class EditTransactionViewState( @@ -48,10 +46,11 @@ sealed interface EditTransactionViewEvent { data class OnAccountChanged(val newAccount: Account) : EditTransactionViewEvent data class OnToAccountChanged(val newAccount: Account) : EditTransactionViewEvent data class OnDueDateChanged(val newDueDate: LocalDateTime?) : EditTransactionViewEvent - data class OnSetDateTime(val newDateTime: LocalDateTime) : EditTransactionViewEvent - data class OnSetDate(val newDate: LocalDate) : EditTransactionViewEvent - data class OnSetTime(val newTime: LocalTime) : EditTransactionViewEvent - data class OnSetTransactionType(val newTransactionType: TransactionType) : EditTransactionViewEvent + data object OnChangeDate : EditTransactionViewEvent + data object OnChangeTime : EditTransactionViewEvent + data class OnSetTransactionType(val newTransactionType: TransactionType) : + EditTransactionViewEvent + data object OnPayPlannedPayment : EditTransactionViewEvent data object Delete : EditTransactionViewEvent data object Duplicate : EditTransactionViewEvent diff --git a/screen/edit-transaction/src/main/java/com/ivy/transaction/EditTransactionViewModel.kt b/screen/edit-transaction/src/main/java/com/ivy/transaction/EditTransactionViewModel.kt index eb3e0b2220..339684a8f8 100644 --- a/screen/edit-transaction/src/main/java/com/ivy/transaction/EditTransactionViewModel.kt +++ b/screen/edit-transaction/src/main/java/com/ivy/transaction/EditTransactionViewModel.kt @@ -34,7 +34,6 @@ import com.ivy.legacy.datamodel.Account import com.ivy.legacy.datamodel.temp.toDomain import com.ivy.legacy.domain.deprecated.logic.AccountCreator import com.ivy.legacy.utils.computationThread -import com.ivy.legacy.utils.convertUTCToLocal import com.ivy.legacy.utils.ioThread import com.ivy.legacy.utils.toLowerCaseLocal import com.ivy.legacy.utils.uiThread @@ -43,6 +42,7 @@ import com.ivy.navigation.MainScreen import com.ivy.navigation.Navigation import com.ivy.ui.ComposeViewModel import com.ivy.ui.R +import com.ivy.ui.time.impl.DateTimePicker import com.ivy.wallet.domain.action.account.AccountByIdAct import com.ivy.wallet.domain.action.account.AccountsAct import com.ivy.wallet.domain.action.transaction.TrnByIdAct @@ -71,9 +71,7 @@ import kotlinx.coroutines.delay import kotlinx.coroutines.launch import java.math.BigDecimal import java.time.Instant -import java.time.LocalDate import java.time.LocalDateTime -import java.time.LocalTime import java.util.UUID import javax.inject.Inject @@ -106,6 +104,7 @@ class EditTransactionViewModel @Inject constructor( private val features: Features, private val timeConverter: TimeConverter, private val timeProvider: TimeProvider, + private val dateTimePicker: DateTimePicker, ) : ComposeViewModel() { private val transactionType = mutableStateOf(TransactionType.EXPENSE) @@ -322,9 +321,8 @@ class EditTransactionViewModel @Inject constructor( is EditTransactionViewEvent.OnDueDateChanged -> onDueDateChanged(event.newDueDate) EditTransactionViewEvent.OnPayPlannedPayment -> onPayPlannedPayment() - is EditTransactionViewEvent.OnSetDateTime -> onSetDateTime(event.newDateTime) - is EditTransactionViewEvent.OnSetDate -> onSetDate(event.newDate) - is EditTransactionViewEvent.OnSetTime -> onSetTime(event.newTime) + is EditTransactionViewEvent.OnChangeDate -> handleChangeDate() + is EditTransactionViewEvent.OnChangeTime -> handleChangeTime() is EditTransactionViewEvent.OnSetTransactionType -> onSetTransactionType(event.newTransactionType) @@ -536,45 +534,46 @@ class EditTransactionViewModel @Inject constructor( saveIfEditMode() } - private fun onSetDateTime(newDateTime: LocalDateTime) { - val newDateTimeUtc = with(timeConverter) { newDateTime.toUTC() } - loadedTransaction = loadedTransaction().copy( - dateTime = newDateTimeUtc - ) - dateTime.value = newDateTimeUtc - - saveIfEditMode() + private fun handleChangeDate() { + dateTimePicker.pickDate( + initialDate = loadedTransaction?.dateTime, + ) { localDate -> + val localTime = loadedTransaction().dateTime?.let { + with(timeConverter) { it.toLocalTime() } + } ?: timeProvider.localTimeNow() + loadedTransaction = loadedTransaction().copy( + date = localDate, + ) + updateDateTime(localDate.atTime(localTime)) + } } - private fun onSetDate(newDate: LocalDate) { - loadedTransaction = loadedTransaction().copy( - date = newDate - ) - val localDateTime = with(timeConverter) { - (dateTime.value ?: timeProvider.utcNow()).toLocalDateTime() - } - onSetDateTime( - localDateTime - .withDayOfMonth(newDate.dayOfMonth) - .withMonth(newDate.monthValue) - .withYear(newDate.year) - ) + private fun handleChangeTime() { + dateTimePicker.pickTime( + initialTime = loadedTransaction?.dateTime?.let { + with(timeConverter) { + it.toLocalDateTime() + } + }?.toLocalTime() + ) { localTime -> + val localDate = loadedTransaction().dateTime?.let { + with(timeConverter) { it.toLocalDate() } + } ?: timeProvider.localDateNow() + loadedTransaction = loadedTransaction().copy( + time = localTime, + ) + updateDateTime(localDate.atTime(localTime)) + } } - private fun onSetTime(newTime: LocalTime) { + private fun updateDateTime(newDateTime: LocalDateTime) { + val newDateTimeUtc = with(timeConverter) { newDateTime.toUTC() } loadedTransaction = loadedTransaction().copy( - time = newTime.convertUTCToLocal() - ) - val localDateTime = with(timeConverter) { - (dateTime.value ?: timeProvider.utcNow()).toLocalDateTime() - } - onSetDateTime( - localDateTime - .withHour(newTime.hour) - .withMinute(newTime.minute) - .withSecond(0) - .withNano(0) + dateTime = newDateTimeUtc, ) + dateTime.value = newDateTimeUtc + + saveIfEditMode() } private fun onSetTransactionType(newTransactionType: TransactionType) { diff --git a/shared/base/src/main/java/com/ivy/base/time/TimeProvider.kt b/shared/base/src/main/java/com/ivy/base/time/TimeProvider.kt index df2ce282de..0472218a3d 100644 --- a/shared/base/src/main/java/com/ivy/base/time/TimeProvider.kt +++ b/shared/base/src/main/java/com/ivy/base/time/TimeProvider.kt @@ -3,6 +3,7 @@ package com.ivy.base.time import java.time.Instant import java.time.LocalDate import java.time.LocalDateTime +import java.time.LocalTime import java.time.ZoneId interface TimeProvider { @@ -10,4 +11,5 @@ interface TimeProvider { fun utcNow(): Instant fun localNow(): LocalDateTime fun localDateNow(): LocalDate + fun localTimeNow(): LocalTime } diff --git a/shared/base/src/main/java/com/ivy/base/time/impl/DeviceTimeProvider.kt b/shared/base/src/main/java/com/ivy/base/time/impl/DeviceTimeProvider.kt index 907257b129..726d595653 100644 --- a/shared/base/src/main/java/com/ivy/base/time/impl/DeviceTimeProvider.kt +++ b/shared/base/src/main/java/com/ivy/base/time/impl/DeviceTimeProvider.kt @@ -4,6 +4,7 @@ import com.ivy.base.time.TimeProvider import java.time.Instant import java.time.LocalDate import java.time.LocalDateTime +import java.time.LocalTime import java.time.ZoneId import javax.inject.Inject @@ -17,4 +18,6 @@ class DeviceTimeProvider @Inject constructor() : TimeProvider { override fun localNow(): LocalDateTime = LocalDateTime.now() override fun localDateNow(): LocalDate = localNow().toLocalDate() + + override fun localTimeNow(): LocalTime = localNow().toLocalTime() } \ No newline at end of file diff --git a/shared/ui/core/src/main/java/com/ivy/ui/di/IvyUiBindings.kt b/shared/ui/core/src/main/java/com/ivy/ui/di/IvyUiBindings.kt index da313ad1d6..17e88820b6 100644 --- a/shared/ui/core/src/main/java/com/ivy/ui/di/IvyUiBindings.kt +++ b/shared/ui/core/src/main/java/com/ivy/ui/di/IvyUiBindings.kt @@ -1,8 +1,10 @@ package com.ivy.ui.di -import com.ivy.ui.time.DeviceTimePreferences +import com.ivy.ui.time.DevicePreferences import com.ivy.ui.time.TimeFormatter -import com.ivy.ui.time.impl.AndroidDeviceTimePreferences +import com.ivy.ui.time.impl.AndroidDateTimePicker +import com.ivy.ui.time.impl.AndroidDevicePreferences +import com.ivy.ui.time.impl.DateTimePicker import com.ivy.ui.time.impl.IvyTimeFormatter import dagger.Binds import dagger.Module @@ -16,5 +18,8 @@ interface IvyUiBindings { fun timeFormatter(impl: IvyTimeFormatter): TimeFormatter @Binds - fun deviceTimePreferences(impl: AndroidDeviceTimePreferences): DeviceTimePreferences + fun deviceTimePreferences(impl: AndroidDevicePreferences): DevicePreferences + + @Binds + fun dateTimePicker(impl: AndroidDateTimePicker): DateTimePicker } \ No newline at end of file diff --git a/shared/ui/core/src/main/java/com/ivy/ui/time/DeviceTimePreferences.kt b/shared/ui/core/src/main/java/com/ivy/ui/time/DevicePreferences.kt similarity index 76% rename from shared/ui/core/src/main/java/com/ivy/ui/time/DeviceTimePreferences.kt rename to shared/ui/core/src/main/java/com/ivy/ui/time/DevicePreferences.kt index 4139a84a90..6b7a19e7b4 100644 --- a/shared/ui/core/src/main/java/com/ivy/ui/time/DeviceTimePreferences.kt +++ b/shared/ui/core/src/main/java/com/ivy/ui/time/DevicePreferences.kt @@ -2,7 +2,7 @@ package com.ivy.ui.time import java.util.Locale -interface DeviceTimePreferences { +interface DevicePreferences { fun is24HourFormat(): Boolean fun locale(): Locale } \ No newline at end of file diff --git a/shared/ui/core/src/main/java/com/ivy/ui/time/impl/AndroidDateTimePicker.kt b/shared/ui/core/src/main/java/com/ivy/ui/time/impl/AndroidDateTimePicker.kt new file mode 100644 index 0000000000..126bf6bde4 --- /dev/null +++ b/shared/ui/core/src/main/java/com/ivy/ui/time/impl/AndroidDateTimePicker.kt @@ -0,0 +1,142 @@ +package com.ivy.ui.time.impl + +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Button +import androidx.compose.material3.DatePicker +import androidx.compose.material3.DatePickerDialog +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.Text +import androidx.compose.material3.TimePicker +import androidx.compose.material3.rememberDatePickerState +import androidx.compose.material3.rememberTimePickerState +import androidx.compose.runtime.Composable +import androidx.compose.runtime.Immutable +import androidx.compose.runtime.Stable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import com.ivy.base.time.TimeConverter +import com.ivy.base.time.TimeProvider +import java.time.Instant +import java.time.LocalDate +import java.time.LocalTime +import javax.inject.Inject +import javax.inject.Singleton + +@Stable +@Singleton +class AndroidDateTimePicker @Inject constructor( + private val timeProvider: TimeProvider, + private val timeConverter: TimeConverter, +) : DateTimePicker { + private var datePickerViewState by mutableStateOf(null) + private var timePickerViewState by mutableStateOf(null) + + @Composable + override fun Content() { + datePickerViewState?.let { DatePicker(it) } + timePickerViewState?.let { TimePicker(it) } + } + + @OptIn(ExperimentalMaterial3Api::class) + @Composable + fun DatePicker( + viewState: DatePickerViewState, + modifier: Modifier = Modifier + ) { + val pickerState = rememberDatePickerState( + initialSelectedDateMillis = viewState.initialDate?.toEpochMilli(), + ) + DatePickerDialog( + modifier = modifier, + onDismissRequest = { datePickerViewState = null }, + confirmButton = { + ConfirmButton( + onClick = { + datePickerViewState = null + pickerState.selectedDateMillis + ?.let(Instant::ofEpochMilli) + ?.let { + with(timeConverter) { it.toLocalDate() } + }?.let(viewState.onDatePicked) + } + ) + } + ) { + DatePicker(state = pickerState) + } + } + + @OptIn(ExperimentalMaterial3Api::class) + @Composable + fun TimePicker( + viewState: TimePickerViewState, + modifier: Modifier = Modifier + ) { + val time = viewState.initialTime ?: timeProvider.localNow().toLocalTime() + val pickerState = rememberTimePickerState( + initialHour = time.hour, + initialMinute = time.minute, + ) + DatePickerDialog( + modifier = modifier, + onDismissRequest = { timePickerViewState = null }, + confirmButton = { + ConfirmButton( + onClick = { + timePickerViewState = null + viewState.onTimePicked( + LocalTime.of(pickerState.hour, pickerState.minute) + ) + } + ) + } + ) { + TimePicker( + modifier = Modifier.padding(16.dp), + state = pickerState + ) + } + } + + @Composable + fun ConfirmButton( + modifier: Modifier = Modifier, + onClick: () -> Unit, + ) { + Button( + modifier = modifier, + onClick = onClick + ) { + Text(text = "Select") + } + } + + override fun pickDate(initialDate: Instant?, onDatePick: (LocalDate) -> Unit) { + datePickerViewState = DatePickerViewState( + initialDate = initialDate, + onDatePicked = onDatePick + ) + } + + override fun pickTime(initialTime: LocalTime?, onTimePick: (LocalTime) -> Unit) { + timePickerViewState = TimePickerViewState( + initialTime = initialTime, + onTimePicked = onTimePick + ) + } + + @Immutable + data class DatePickerViewState( + val initialDate: Instant?, + val onDatePicked: (LocalDate) -> Unit + ) + + @Immutable + data class TimePickerViewState( + val initialTime: LocalTime?, + val onTimePicked: (LocalTime) -> Unit + ) +} \ No newline at end of file diff --git a/shared/ui/core/src/main/java/com/ivy/ui/time/impl/AndroidDeviceTimePreferences.kt b/shared/ui/core/src/main/java/com/ivy/ui/time/impl/AndroidDevicePreferences.kt similarity index 75% rename from shared/ui/core/src/main/java/com/ivy/ui/time/impl/AndroidDeviceTimePreferences.kt rename to shared/ui/core/src/main/java/com/ivy/ui/time/impl/AndroidDevicePreferences.kt index 0c5b2be115..facc185ee1 100644 --- a/shared/ui/core/src/main/java/com/ivy/ui/time/impl/AndroidDeviceTimePreferences.kt +++ b/shared/ui/core/src/main/java/com/ivy/ui/time/impl/AndroidDevicePreferences.kt @@ -2,15 +2,15 @@ package com.ivy.ui.time.impl import android.content.Context import android.text.format.DateFormat -import com.ivy.ui.time.DeviceTimePreferences +import com.ivy.ui.time.DevicePreferences import dagger.hilt.android.qualifiers.ApplicationContext import java.util.Locale import javax.inject.Inject -class AndroidDeviceTimePreferences @Inject constructor( +class AndroidDevicePreferences @Inject constructor( @ApplicationContext private val context: Context, -) : DeviceTimePreferences { +) : DevicePreferences { override fun is24HourFormat(): Boolean = DateFormat.is24HourFormat(context) override fun locale(): Locale = Locale.getDefault() } \ No newline at end of file diff --git a/shared/ui/core/src/main/java/com/ivy/ui/time/impl/DateTimePicker.kt b/shared/ui/core/src/main/java/com/ivy/ui/time/impl/DateTimePicker.kt new file mode 100644 index 0000000000..d3fd114bb3 --- /dev/null +++ b/shared/ui/core/src/main/java/com/ivy/ui/time/impl/DateTimePicker.kt @@ -0,0 +1,23 @@ +package com.ivy.ui.time.impl + +import androidx.compose.runtime.Composable +import androidx.compose.runtime.Stable +import java.time.Instant +import java.time.LocalDate +import java.time.LocalTime + +@Stable +interface DateTimePicker { + @Composable + fun Content() + + fun pickDate( + initialDate: Instant?, + onDatePick: (LocalDate) -> Unit + ) + + fun pickTime( + initialTime: LocalTime?, + onTimePick: (LocalTime) -> Unit + ) +} \ No newline at end of file diff --git a/shared/ui/core/src/main/java/com/ivy/ui/time/impl/IvyTimeFormatter.kt b/shared/ui/core/src/main/java/com/ivy/ui/time/impl/IvyTimeFormatter.kt index cbf20687d5..e73a6cf3f2 100644 --- a/shared/ui/core/src/main/java/com/ivy/ui/time/impl/IvyTimeFormatter.kt +++ b/shared/ui/core/src/main/java/com/ivy/ui/time/impl/IvyTimeFormatter.kt @@ -4,7 +4,7 @@ import com.ivy.base.resource.ResourceProvider import com.ivy.base.time.TimeConverter import com.ivy.base.time.TimeProvider import com.ivy.ui.R -import com.ivy.ui.time.DeviceTimePreferences +import com.ivy.ui.time.DevicePreferences import com.ivy.ui.time.TimeFormatter import java.time.Instant import java.time.LocalDate @@ -18,7 +18,7 @@ class IvyTimeFormatter @Inject constructor( private val resourceProvider: ResourceProvider, private val timeProvider: TimeProvider, private val converter: TimeConverter, - private val deviceTimePreferences: DeviceTimePreferences, + private val devicePreferences: DevicePreferences, ) : TimeFormatter { override fun LocalDateTime.format(style: TimeFormatter.Style): String { @@ -43,7 +43,7 @@ class IvyTimeFormatter @Inject constructor( } } val formatted = dateTime.format( - DateTimeFormatter.ofPattern(pattern, deviceTimePreferences.locale()) + DateTimeFormatter.ofPattern(pattern, devicePreferences.locale()) ) val prefix = when (relativeDay) { RelativeDay.Yesterday -> resourceProvider.getString(R.string.yesterday) @@ -60,10 +60,10 @@ class IvyTimeFormatter @Inject constructor( } override fun LocalTime.format(): String = this.format( - DateTimeFormatter.ofPattern(localeTimeFormat(), deviceTimePreferences.locale()) + DateTimeFormatter.ofPattern(localeTimeFormat(), devicePreferences.locale()) ) - private fun localeTimeFormat(): String = if (deviceTimePreferences.is24HourFormat()) { + private fun localeTimeFormat(): String = if (devicePreferences.is24HourFormat()) { "HH:mm" } else { "h:mm a" diff --git a/shared/ui/core/src/test/java/com/ivy/ui/time/impl/IvyTimeFormatterTest.kt b/shared/ui/core/src/test/java/com/ivy/ui/time/impl/IvyTimeFormatterTest.kt index 0681acefd7..86b2970c46 100644 --- a/shared/ui/core/src/test/java/com/ivy/ui/time/impl/IvyTimeFormatterTest.kt +++ b/shared/ui/core/src/test/java/com/ivy/ui/time/impl/IvyTimeFormatterTest.kt @@ -6,7 +6,7 @@ import com.ivy.base.resource.TestResourceProvider import com.ivy.base.time.TimeConverter import com.ivy.base.time.TimeProvider import com.ivy.ui.R -import com.ivy.ui.time.DeviceTimePreferences +import com.ivy.ui.time.DevicePreferences import com.ivy.ui.time.TimeFormatter.Style import io.kotest.matchers.shouldBe import io.mockk.every @@ -26,7 +26,7 @@ class IvyTimeFormatterTest { private val timeProvider = mockk() private val converter = mockk() - private val deviceTimePreferences = mockk { + private val devicePreferences = mockk { every { locale() } returns Locale.ENGLISH } @@ -42,7 +42,7 @@ class IvyTimeFormatterTest { }, timeProvider = timeProvider, converter = converter, - deviceTimePreferences = deviceTimePreferences + devicePreferences = devicePreferences ) } @@ -179,7 +179,7 @@ class IvyTimeFormatterTest { ) { // Given every { timeProvider.localDateNow() } returns testCase.today - every { deviceTimePreferences.is24HourFormat() } returns testCase.is24HourFormat + every { devicePreferences.is24HourFormat() } returns testCase.is24HourFormat val date = testCase.date // When @@ -221,7 +221,7 @@ class IvyTimeFormatterTest { @TestParameter testCase: TimeFormattingTestCase ) { // Given - every { deviceTimePreferences.is24HourFormat() } returns testCase.is24HourFormat + every { devicePreferences.is24HourFormat() } returns testCase.is24HourFormat val time = testCase.time // When diff --git a/temp/old-design/src/main/java/com/ivy/design/utils/Preview.kt b/temp/old-design/src/main/java/com/ivy/design/utils/Preview.kt index 8711a170ee..6669ac31a4 100644 --- a/temp/old-design/src/main/java/com/ivy/design/utils/Preview.kt +++ b/temp/old-design/src/main/java/com/ivy/design/utils/Preview.kt @@ -18,7 +18,7 @@ import com.ivy.design.api.IvyDesign import com.ivy.design.api.IvyUI import com.ivy.design.api.systems.IvyWalletDesign import com.ivy.design.l0_system.UI -import com.ivy.ui.time.impl.AndroidDeviceTimePreferences +import com.ivy.ui.time.impl.AndroidDevicePreferences import com.ivy.ui.time.impl.IvyTimeFormatter @Deprecated("Old design system. Use `:ivy-design` and Material3") @@ -63,7 +63,7 @@ fun IvyPreview( resourceProvider = AndroidResourceProvider(LocalContext.current), timeProvider = timeProvider, converter = timeConverter, - deviceTimePreferences = AndroidDeviceTimePreferences(LocalContext.current) + devicePreferences = AndroidDevicePreferences(LocalContext.current) ) ) }