diff --git a/app/src/main/java/com/ivy/wallet/RootActivity.kt b/app/src/main/java/com/ivy/wallet/RootActivity.kt index a83fbf993b..4399d48f3a 100644 --- a/app/src/main/java/com/ivy/wallet/RootActivity.kt +++ b/app/src/main/java/com/ivy/wallet/RootActivity.kt @@ -40,10 +40,8 @@ import com.ivy.legacy.Constants import com.ivy.legacy.IvyWalletCtx import com.ivy.legacy.appDesign import com.ivy.legacy.utils.activityForResultLauncher -import com.ivy.legacy.utils.convertLocalToUTC import com.ivy.legacy.utils.sendToCrashlytics import com.ivy.legacy.utils.simpleActivityForResultLauncher -import com.ivy.legacy.utils.timeNowLocal import com.ivy.navigation.Navigation import com.ivy.navigation.NavigationRoot import com.ivy.ui.R @@ -210,7 +208,7 @@ class RootActivity : AppCompatActivity(), RootScreen { private fun setupTimePicker() { ivyContext.onShowTimePicker = { initialTime, onTimePicked -> - val nowLocal = initialTime ?: timeNowLocal().toLocalTime() + val nowLocal = initialTime ?: timeProvider.localTimeNow() val is24Hour = android.text.format.DateFormat.is24HourFormat(this) val timeFormat = if (is24Hour) TimeFormat.CLOCK_24H else TimeFormat.CLOCK_12H @@ -223,7 +221,7 @@ class RootActivity : AppCompatActivity(), RootScreen { picker.show(supportFragmentManager, "timePicker") picker.addOnPositiveButtonClickListener { onTimePicked( - LocalTime.of(picker.hour, picker.minute).convertLocalToUTC().withSecond(0) + LocalTime.of(picker.hour, picker.minute).withSecond(0) ) } } diff --git a/screen/loans/src/main/java/com/ivy/loans/loan/LoanScreenEvent.kt b/screen/loans/src/main/java/com/ivy/loans/loan/LoanScreenEvent.kt index b424268d84..53582ea293 100644 --- a/screen/loans/src/main/java/com/ivy/loans/loan/LoanScreenEvent.kt +++ b/screen/loans/src/main/java/com/ivy/loans/loan/LoanScreenEvent.kt @@ -11,6 +11,8 @@ sealed interface LoanScreenEvent { data class OnReOrderModalShow(val show: Boolean) : LoanScreenEvent data object OnAddLoan : LoanScreenEvent data object OnLoanModalDismiss : LoanScreenEvent + data object OnChangeDate : LoanScreenEvent + data object OnChangeTime : LoanScreenEvent /** Toggles paid off loans visibility */ data object OnTogglePaidOffLoanVisibility : LoanScreenEvent diff --git a/screen/loans/src/main/java/com/ivy/loans/loan/LoanScreenState.kt b/screen/loans/src/main/java/com/ivy/loans/loan/LoanScreenState.kt index cea675b131..69ec6eb00b 100644 --- a/screen/loans/src/main/java/com/ivy/loans/loan/LoanScreenState.kt +++ b/screen/loans/src/main/java/com/ivy/loans/loan/LoanScreenState.kt @@ -4,6 +4,7 @@ import com.ivy.legacy.datamodel.Account import com.ivy.loans.loan.data.DisplayLoan import com.ivy.wallet.ui.theme.modal.LoanModalData import kotlinx.collections.immutable.ImmutableList +import java.time.Instant data class LoanScreenState( val baseCurrency: String, @@ -15,4 +16,5 @@ data class LoanScreenState( val totalOweAmount: String, val totalOwedAmount: String, val paidOffLoanVisibility: Boolean, + val dateTime: Instant ) diff --git a/screen/loans/src/main/java/com/ivy/loans/loan/LoanViewModel.kt b/screen/loans/src/main/java/com/ivy/loans/loan/LoanViewModel.kt index 4b5a4ae83f..e584b940d1 100644 --- a/screen/loans/src/main/java/com/ivy/loans/loan/LoanViewModel.kt +++ b/screen/loans/src/main/java/com/ivy/loans/loan/LoanViewModel.kt @@ -7,6 +7,8 @@ import androidx.compose.runtime.mutableStateOf import androidx.lifecycle.viewModelScope import com.ivy.base.legacy.SharedPrefs import com.ivy.base.model.processByType +import com.ivy.base.time.TimeConverter +import com.ivy.base.time.TimeProvider import com.ivy.data.db.dao.read.LoanRecordDao import com.ivy.data.db.dao.read.SettingsDao import com.ivy.data.db.dao.write.WriteLoanDao @@ -20,6 +22,7 @@ import com.ivy.legacy.utils.getDefaultFIATCurrency import com.ivy.legacy.utils.ioThread import com.ivy.loans.loan.data.DisplayLoan import com.ivy.ui.ComposeViewModel +import com.ivy.ui.time.impl.DateTimePicker import com.ivy.wallet.domain.action.account.AccountsAct import com.ivy.wallet.domain.action.loan.LoansAct import com.ivy.wallet.domain.deprecated.logic.LoanCreator @@ -33,6 +36,8 @@ import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch +import java.time.Instant +import java.time.LocalDateTime import java.util.UUID import javax.inject.Inject @@ -48,6 +53,9 @@ class LoanViewModel @Inject constructor( private val loansAct: LoansAct, private val accountsAct: AccountsAct, private val loanWriter: WriteLoanDao, + private val timeConverter: TimeConverter, + private val timeProvider: TimeProvider, + private val dateTimePicker: DateTimePicker, ) : ComposeViewModel() { private val baseCurrencyCode = mutableStateOf(getDefaultFIATCurrency().currencyCode) @@ -56,6 +64,7 @@ class LoanViewModel @Inject constructor( private val selectedAccount = mutableStateOf(null) private val loanModalData = mutableStateOf(null) private val reorderModalVisible = mutableStateOf(false) + private var dateTime = mutableStateOf(timeProvider.utcNow()) /** If true paid off loans will be visible */ private val paidOffLoanVisibility = mutableStateOf(true) @@ -81,7 +90,8 @@ class LoanViewModel @Inject constructor( reorderModalVisible = getReorderModalVisible(), totalOweAmount = getTotalOweAmount(totalOweAmount, defaultCurrencyCode), totalOwedAmount = getTotalOwedAmount(totalOwedAmount, defaultCurrencyCode), - paidOffLoanVisibility = getPaidOffLoanVisibility() + paidOffLoanVisibility = getPaidOffLoanVisibility(), + dateTime = dateTime.value ) } @@ -126,6 +136,7 @@ class LoanViewModel @Inject constructor( is LoanScreenEvent.OnLoanModalDismiss -> { loanModalData.value = null + dateTime.value = timeProvider.utcNow() } is LoanScreenEvent.OnReOrderModalShow -> { @@ -143,6 +154,13 @@ class LoanViewModel @Inject constructor( LoanScreenEvent.OnTogglePaidOffLoanVisibility -> { updatePaidOffLoanVisibility() } + + is LoanScreenEvent.OnChangeDate -> { + handleChangeDate() + } + is LoanScreenEvent.OnChangeTime -> { + handleChangeTime() + } } } @@ -150,6 +168,8 @@ class LoanViewModel @Inject constructor( viewModelScope.launch(Dispatchers.Default) { TestIdlingResource.increment() + dateTime.value = timeProvider.utcNow() + defaultCurrencyCode = ioThread { settingsDao.findFirst().currency }.also { @@ -226,6 +246,46 @@ class LoanViewModel @Inject constructor( } } + private fun handleChangeDate() { + dateTimePicker.pickDate( + initialDate = loanModalData.value?.loan?.dateTime?.let { + with(timeConverter) { it.toUTC() } + } ?: timeProvider.utcNow() + ) { localDate -> + val localTime = loanModalData.value?.loan?.dateTime?.let { + with(timeConverter) { it.toLocalTime() } + } ?: timeProvider.localTimeNow() + + updateDateTime(localDate.atTime(localTime)) + } + } + + private fun handleChangeTime() { + dateTimePicker.pickTime( + initialTime = loanModalData.value?.loan?.dateTime?.let { + with(timeConverter) { it.toLocalTime() } + } ?: timeProvider.localTimeNow() + ) { localTime -> + val localDate = loanModalData.value?.loan?.dateTime?.let { + with(timeConverter) { it.toLocalDate() } + } ?: timeProvider.localDateNow() + + updateDateTime(localDate.atTime(localTime)) + } + } + + private fun updateDateTime(newDateTime: LocalDateTime) { + val newDateTimeUtc = with(timeConverter) { newDateTime.toUTC() } + loanModalData.value?.let { currentData -> + loanModalData.value = currentData.copy( + loan = currentData.loan?.copy( + dateTime = newDateTime + ) + ) + dateTime.value = newDateTimeUtc + } + } + private fun createLoan(data: CreateLoanData) { viewModelScope.launch { TestIdlingResource.increment() diff --git a/screen/loans/src/main/java/com/ivy/loans/loan/LoansScreen.kt b/screen/loans/src/main/java/com/ivy/loans/loan/LoansScreen.kt index 6b937efb5b..1ff99e96a0 100644 --- a/screen/loans/src/main/java/com/ivy/loans/loan/LoansScreen.kt +++ b/screen/loans/src/main/java/com/ivy/loans/loan/LoansScreen.kt @@ -62,6 +62,7 @@ import com.ivy.wallet.ui.theme.modal.LoanModal import com.ivy.wallet.ui.theme.modal.LoanModalData import com.ivy.wallet.ui.theme.toComposeColor import kotlinx.collections.immutable.persistentListOf +import java.time.Instant import java.time.LocalDateTime @Composable @@ -176,6 +177,13 @@ private fun BoxWithConstraintsScope.UI( dismiss = { onEventHandler.invoke(LoanScreenEvent.OnLoanModalDismiss) }, + dateTime = state.dateTime, + onSetDate = { + onEventHandler.invoke(LoanScreenEvent.OnChangeDate) + }, + onSetTime = { + onEventHandler.invoke(LoanScreenEvent.OnChangeTime) + } ) } @@ -460,7 +468,8 @@ private fun Preview(theme: Theme = Theme.LIGHT) { ), reorderModalVisible = false, selectedAccount = null, - paidOffLoanVisibility = true + paidOffLoanVisibility = true, + dateTime = Instant.now() ) IvyWalletPreview(theme) { UI( diff --git a/screen/loans/src/main/java/com/ivy/loans/loandetails/LoanDetailsScreen.kt b/screen/loans/src/main/java/com/ivy/loans/loandetails/LoanDetailsScreen.kt index b7dff8a4d7..9cbb4bc7f2 100644 --- a/screen/loans/src/main/java/com/ivy/loans/loandetails/LoanDetailsScreen.kt +++ b/screen/loans/src/main/java/com/ivy/loans/loandetails/LoanDetailsScreen.kt @@ -52,7 +52,6 @@ import com.ivy.legacy.utils.clickableNoIndication import com.ivy.legacy.utils.drawColoredShadow import com.ivy.legacy.utils.format import com.ivy.legacy.utils.formatNicely -import com.ivy.legacy.utils.formatNicelyWithTime import com.ivy.legacy.utils.isNotNullOrBlank import com.ivy.legacy.utils.rememberInteractionSource import com.ivy.legacy.utils.setStatusBarDarkTextCompat @@ -86,6 +85,7 @@ import com.ivy.wallet.ui.theme.modal.LoanRecordModal import com.ivy.wallet.ui.theme.modal.ProgressModal import com.ivy.wallet.ui.theme.toComposeColor import kotlinx.collections.immutable.persistentListOf +import java.time.Instant import java.time.LocalDateTime import java.time.ZoneOffset import java.util.UUID @@ -105,7 +105,7 @@ fun BoxWithConstraintsScope.LoanDetailsScreen(screen: LoanDetailsScreen) { @Composable private fun BoxWithConstraintsScope.UI( state: LoanDetailsScreenState, - onEventHandler: (LoanDetailsScreenEvent) -> Unit = {}, + onEventHandler: (LoanDetailsScreenEvent) -> Unit = {} ) { val itemColor = state.loan?.color?.toComposeColor() ?: Gray @@ -201,7 +201,8 @@ private fun BoxWithConstraintsScope.UI( } } - LoanModal(modal = state.loanModalData, onCreateLoan = { + LoanModal( + modal = state.loanModalData, onCreateLoan = { // do nothing }, onEditLoan = { loan, createLoanTransaction -> onEventHandler.invoke(LoanModalEvent.OnEditLoanModal(loan, createLoanTransaction)) @@ -211,9 +212,17 @@ private fun BoxWithConstraintsScope.UI( onEventHandler.invoke(LoanDetailsScreenEvent.OnCreateAccount(createAccountData)) }, accounts = state.accounts, onPerformCalculations = { onEventHandler.invoke(LoanModalEvent.PerformCalculation) - }) + }, dateTime = state.dateTime, + onSetDate = { + onEventHandler.invoke(LoanModalEvent.OnChangeDate) + }, + onSetTime = { + onEventHandler.invoke(LoanModalEvent.OnChangeTime) + }, + ) - LoanRecordModal(modal = state.loanRecordModalData, onCreate = { + LoanRecordModal( + modal = state.loanRecordModalData, onCreate = { onEventHandler.invoke(LoanRecordModalEvent.OnCreateLoanRecord(it)) }, onEdit = { onEventHandler.invoke(LoanRecordModalEvent.OnEditLoanRecord(it)) @@ -223,7 +232,15 @@ private fun BoxWithConstraintsScope.UI( onEventHandler.invoke(LoanRecordModalEvent.OnDismissLoanRecord) }, onCreateAccount = { createAccountData -> onEventHandler.invoke(LoanDetailsScreenEvent.OnCreateAccount(createAccountData)) - }) + }, + dateTime = state.dateTime, + onSetDate = { + onEventHandler.invoke(LoanRecordModalEvent.OnChangeDate) + }, + onSetTime = { + onEventHandler.invoke(LoanRecordModalEvent.OnChangeTime) + }, + ) DeleteModal( visible = state.isDeleteModalVisible, @@ -793,12 +810,16 @@ private fun InitialRecordItem( padding = 8.dp, ) {} - loan.dateTime?.formatNicelyWithTime( - noWeekDay = false - )?.let { nicelyFormattedDate -> + val timeFormatter = LocalTimeFormatter.current + + loan.dateTime?.let { dateTime -> Text( modifier = Modifier.padding(horizontal = 24.dp), - text = nicelyFormattedDate.uppercase(), + text = with(timeFormatter) { + dateTime.format( + TimeFormatter.Style.DateAndTime(includeWeekDay = true) + ).uppercase() + }, style = UI.typo.nC.style( color = Gray, fontWeight = FontWeight.Bold @@ -892,7 +913,8 @@ private fun Preview_Empty() { isDeleteModalVisible = false, loanModalData = null, loanRecordModalData = null, - waitModalVisible = false + waitModalVisible = false, + dateTime = Instant.now() ) ) {} } @@ -952,7 +974,8 @@ private fun Preview_Records(theme: Theme = Theme.LIGHT) { isDeleteModalVisible = false, loanModalData = null, loanRecordModalData = null, - waitModalVisible = false + waitModalVisible = false, + dateTime = Instant.now() ) ) {} } diff --git a/screen/loans/src/main/java/com/ivy/loans/loandetails/LoanDetailsScreenState.kt b/screen/loans/src/main/java/com/ivy/loans/loandetails/LoanDetailsScreenState.kt index d4d051b614..279eef8052 100644 --- a/screen/loans/src/main/java/com/ivy/loans/loandetails/LoanDetailsScreenState.kt +++ b/screen/loans/src/main/java/com/ivy/loans/loandetails/LoanDetailsScreenState.kt @@ -6,6 +6,7 @@ import com.ivy.loans.loan.data.DisplayLoanRecord import com.ivy.wallet.ui.theme.modal.LoanModalData import com.ivy.wallet.ui.theme.modal.LoanRecordModalData import kotlinx.collections.immutable.ImmutableList +import java.time.Instant data class LoanDetailsScreenState( val baseCurrency: String, @@ -20,5 +21,6 @@ data class LoanDetailsScreenState( val loanModalData: LoanModalData?, val loanRecordModalData: LoanRecordModalData?, val waitModalVisible: Boolean, - val isDeleteModalVisible: Boolean + val isDeleteModalVisible: Boolean, + val dateTime: Instant ) diff --git a/screen/loans/src/main/java/com/ivy/loans/loandetails/LoanDetailsViewModel.kt b/screen/loans/src/main/java/com/ivy/loans/loandetails/LoanDetailsViewModel.kt index f0cd4f45bf..2d40568498 100644 --- a/screen/loans/src/main/java/com/ivy/loans/loandetails/LoanDetailsViewModel.kt +++ b/screen/loans/src/main/java/com/ivy/loans/loandetails/LoanDetailsViewModel.kt @@ -8,6 +8,8 @@ import androidx.compose.runtime.mutableStateOf import androidx.lifecycle.viewModelScope import com.ivy.base.legacy.Transaction import com.ivy.base.model.LoanRecordType +import com.ivy.base.time.TimeConverter +import com.ivy.base.time.TimeProvider import com.ivy.data.db.dao.read.LoanRecordDao import com.ivy.data.db.dao.read.SettingsDao import com.ivy.data.repository.TransactionRepository @@ -29,6 +31,7 @@ import com.ivy.loans.loandetails.events.LoanRecordModalEvent import com.ivy.navigation.LoanDetailsScreen import com.ivy.navigation.Navigation import com.ivy.ui.ComposeViewModel +import com.ivy.ui.time.impl.DateTimePicker import com.ivy.wallet.domain.action.account.AccountsAct import com.ivy.wallet.domain.action.loan.LoanByIdAct import com.ivy.wallet.domain.deprecated.logic.LoanCreator @@ -44,6 +47,8 @@ import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.launch +import java.time.Instant +import java.time.LocalDateTime import java.util.UUID import javax.inject.Inject @@ -61,6 +66,9 @@ class LoanDetailsViewModel @Inject constructor( private val nav: Navigation, private val accountsAct: AccountsAct, private val loanByIdAct: LoanByIdAct, + private val timeConverter: TimeConverter, + private val timeProvider: TimeProvider, + private val dateTimePicker: DateTimePicker, ) : ComposeViewModel() { private val baseCurrency = mutableStateOf("") @@ -79,6 +87,7 @@ class LoanDetailsViewModel @Inject constructor( private val loanRecordModalData = mutableStateOf(null) private val waitModalVisible = mutableStateOf(false) private val isDeleteModalVisible = mutableStateOf(false) + private var dateTime = mutableStateOf(timeProvider.utcNow()) lateinit var screen: LoanDetailsScreen @Composable @@ -100,7 +109,8 @@ class LoanDetailsViewModel @Inject constructor( loanModalData = loanModalData.value, loanRecordModalData = loanRecordModalData.value, waitModalVisible = waitModalVisible.value, - isDeleteModalVisible = isDeleteModalVisible.value + isDeleteModalVisible = isDeleteModalVisible.value, + dateTime = dateTime.value ) } @@ -136,12 +146,19 @@ class LoanDetailsViewModel @Inject constructor( LoanRecordModalEvent.OnDismissLoanRecord -> { loanRecordModalData.value = null + dateTime.value = timeProvider.utcNow() } is LoanRecordModalEvent.OnEditLoanRecord -> { editLoanRecord(event.loanRecordData) } + is LoanRecordModalEvent.OnChangeDate -> { + handleChangeDate() + } + is LoanRecordModalEvent.OnChangeTime -> { + handleChangeTime() + } else -> {} } } @@ -150,6 +167,7 @@ class LoanDetailsViewModel @Inject constructor( when (event) { LoanModalEvent.OnDismissLoanModal -> { loanModalData.value = null + dateTime.value = timeProvider.utcNow() } is LoanModalEvent.OnEditLoanModal -> { @@ -160,6 +178,14 @@ class LoanDetailsViewModel @Inject constructor( waitModalVisible.value = true } + LoanModalEvent.OnChangeDate -> { + handleLoanChangeDate() + } + + LoanModalEvent.OnChangeTime -> { + handleLoanChangeTime() + } + else -> {} } } @@ -226,6 +252,8 @@ class LoanDetailsViewModel @Inject constructor( viewModelScope.launch { TestIdlingResource.increment() + dateTime.value = timeProvider.utcNow() + defaultCurrencyCode = ioThread { settingsDao.findFirst().currency }.also { @@ -449,6 +477,88 @@ class LoanDetailsViewModel @Inject constructor( } } + private fun handleChangeDate() { + dateTimePicker.pickDate( + initialDate = loanRecordModalData.value?.loanRecord?.dateTime?.let { + with(timeConverter) { it.toLocalDateTime().toUTC() } + } ?: timeProvider.utcNow() + ) { localDate -> + + val localTime = loanRecordModalData.value?.loanRecord?.dateTime?.let { + with(timeConverter) { it.toLocalTime() } + } ?: timeProvider.localTimeNow() + + updateDateTime(localDate.atTime(localTime)) + } + } + + private fun handleChangeTime() { + dateTimePicker.pickTime( + initialTime = loanRecordModalData.value?.loanRecord?.dateTime?.let { + with(timeConverter) { it.toLocalTime() } + } ?: timeProvider.localTimeNow() + ) { localTime -> + val localDate = loanRecordModalData.value?.loanRecord?.dateTime?.let { + with(timeConverter) { it.toLocalDate() } + } ?: timeProvider.localDateNow() + + updateDateTime(localDate.atTime(localTime)) + } + } + + private fun updateDateTime(newDateTime: LocalDateTime) { + val newDateTimeUtc = with(timeConverter) { newDateTime.toUTC() } + loanRecordModalData.value?.let { currentData -> + loanRecordModalData.value = currentData.copy( + loanRecord = currentData.loanRecord?.copy( + dateTime = newDateTimeUtc + ) + ) + dateTime.value = newDateTimeUtc + } + } + + private fun handleLoanChangeDate() { + dateTimePicker.pickDate( + initialDate = loanModalData.value?.loan?.dateTime?.let { + with(timeConverter) { it.toUTC() } + } ?: timeProvider.utcNow() + ) { localDate -> + + val localTime = loanModalData.value?.loan?.dateTime?.let { + with(timeConverter) { it.toLocalTime() } + } ?: timeProvider.localTimeNow() + + updateLoanDateTime(localDate.atTime(localTime)) + } + } + + private fun handleLoanChangeTime() { + dateTimePicker.pickTime( + initialTime = loanModalData.value?.loan?.dateTime?.let { + with(timeConverter) { it.toLocalTime() } + } ?: timeProvider.localTimeNow() + ) { localTime -> + val localDate = loanModalData.value?.loan?.dateTime?.let { + with(timeConverter) { it.toLocalDate() } + } ?: timeProvider.localDateNow() + + updateLoanDateTime(localDate.atTime(localTime)) + } + } + + private fun updateLoanDateTime(newDateTime: LocalDateTime) { + val newDateTimeUtc = with(timeConverter) { newDateTime.toUTC() } + loanModalData.value?.let { currentData -> + loanModalData.value = currentData.copy( + loan = currentData.loan?.copy( + dateTime = newDateTime + ) + ) + dateTime.value = newDateTimeUtc + } + } + fun onLoanTransactionChecked(boolean: Boolean) { createLoanTransaction.value = boolean } diff --git a/screen/loans/src/main/java/com/ivy/loans/loandetails/events/LoanModalEvent.kt b/screen/loans/src/main/java/com/ivy/loans/loandetails/events/LoanModalEvent.kt index da40c1f26b..914725fd07 100644 --- a/screen/loans/src/main/java/com/ivy/loans/loandetails/events/LoanModalEvent.kt +++ b/screen/loans/src/main/java/com/ivy/loans/loandetails/events/LoanModalEvent.kt @@ -8,4 +8,6 @@ sealed interface LoanModalEvent : LoanDetailsScreenEvent { LoanModalEvent data object PerformCalculation : LoanModalEvent + data object OnChangeDate : LoanModalEvent + data object OnChangeTime : LoanModalEvent } diff --git a/screen/loans/src/main/java/com/ivy/loans/loandetails/events/LoanRecordModalEvent.kt b/screen/loans/src/main/java/com/ivy/loans/loandetails/events/LoanRecordModalEvent.kt index 6ffba3da2b..8580900610 100644 --- a/screen/loans/src/main/java/com/ivy/loans/loandetails/events/LoanRecordModalEvent.kt +++ b/screen/loans/src/main/java/com/ivy/loans/loandetails/events/LoanRecordModalEvent.kt @@ -13,4 +13,7 @@ sealed interface LoanRecordModalEvent : LoanDetailsScreenEvent { data class OnDeleteLoanRecord(val loanRecord: LoanRecord) : LoanRecordModalEvent data class OnEditLoanRecord(val loanRecordData: EditLoanRecordData) : LoanRecordModalEvent data object OnDismissLoanRecord : LoanRecordModalEvent + + data object OnChangeDate : LoanRecordModalEvent + data object OnChangeTime : LoanRecordModalEvent } diff --git a/temp/legacy-code/src/main/java/com/ivy/legacy/legacy/ui/theme/components/DateTimeRow.kt b/temp/legacy-code/src/main/java/com/ivy/legacy/legacy/ui/theme/components/DateTimeRow.kt index 43662c5172..f60f4a3987 100644 --- a/temp/legacy-code/src/main/java/com/ivy/legacy/legacy/ui/theme/components/DateTimeRow.kt +++ b/temp/legacy-code/src/main/java/com/ivy/legacy/legacy/ui/theme/components/DateTimeRow.kt @@ -8,11 +8,9 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp -import com.ivy.legacy.ivyWalletCtx +import com.ivy.design.api.LocalTimeFormatter import com.ivy.legacy.utils.convertLocalToUTC import com.ivy.legacy.utils.convertUTCToLocal -import com.ivy.legacy.utils.convertUTCtoLocal -import com.ivy.legacy.utils.formatLocalTime import com.ivy.legacy.utils.formatNicely import com.ivy.legacy.utils.timeNowUTC import com.ivy.ui.R @@ -24,10 +22,11 @@ import java.time.LocalTime @Composable fun DateTimeRow( dateTime: LocalDateTime, - onSetDateTime: (LocalDateTime) -> Unit, + onEditDate: () -> Unit, + onEditTime: () -> Unit, modifier: Modifier = Modifier ) { - val ivyContext = ivyWalletCtx() + val timeFormatter = LocalTimeFormatter.current Row( modifier = modifier.fillMaxWidth(), @@ -37,27 +36,19 @@ fun DateTimeRow( IvyOutlinedButton( text = dateTime.formatNicely(), - iconStart = R.drawable.ic_date - ) { - ivyContext.datePicker( - initialDate = dateTime.convertUTCtoLocal().toLocalDate() - ) { - onSetDateTime(getTrueDate(it, dateTime.toLocalTime())) - } - } + iconStart = R.drawable.ic_date, + onClick = onEditDate + ) Spacer(Modifier.weight(1f)) IvyOutlinedButton( - text = dateTime.formatLocalTime(), - iconStart = R.drawable.ic_date - ) { - ivyContext.timePicker( - initialTime = dateTime.convertUTCtoLocal().toLocalTime() - ) { - onSetDateTime(getTrueDate(dateTime.convertUTCtoLocal().toLocalDate(), it)) - } - } + text = with(timeFormatter) { + dateTime.toLocalTime().format() + }, + iconStart = R.drawable.ic_date, + onClick = onEditTime + ) Spacer(Modifier.width(24.dp)) } diff --git a/temp/legacy-code/src/main/java/com/ivy/legacy/legacy/ui/theme/modal/LoanModal.kt b/temp/legacy-code/src/main/java/com/ivy/legacy/legacy/ui/theme/modal/LoanModal.kt index 31e0649c42..4f68b5b550 100644 --- a/temp/legacy-code/src/main/java/com/ivy/legacy/legacy/ui/theme/modal/LoanModal.kt +++ b/temp/legacy-code/src/main/java/com/ivy/legacy/legacy/ui/theme/modal/LoanModal.kt @@ -36,6 +36,7 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.ivy.data.model.LoanType import com.ivy.data.model.primitive.NotBlankTrimmedString +import com.ivy.design.api.LocalTimeConverter import com.ivy.design.l0_system.UI import com.ivy.design.l0_system.style import com.ivy.domain.legacy.ui.IvyColorPicker @@ -50,7 +51,6 @@ import com.ivy.legacy.utils.onScreenStart import com.ivy.legacy.utils.selectEndTextFieldValue import com.ivy.design.utils.thenIf import com.ivy.legacy.legacy.ui.theme.modal.ModalNameInput -import com.ivy.legacy.utils.timeNowUTC import com.ivy.ui.R import com.ivy.wallet.domain.data.IvyCurrency import com.ivy.wallet.domain.deprecated.logic.model.CreateAccountData @@ -69,6 +69,7 @@ import com.ivy.wallet.ui.theme.modal.edit.AmountModal import com.ivy.wallet.ui.theme.modal.edit.IconNameRow import com.ivy.wallet.ui.theme.toComposeColor import kotlinx.coroutines.launch +import java.time.Instant import java.time.LocalDateTime import java.util.UUID @@ -83,24 +84,29 @@ data class LoanModalData( val id: UUID = UUID.randomUUID() ) +@Suppress("CyclomaticComplexMethod", "LongMethod") @Deprecated("Old design system. Use `:ivy-design` and Material3") @Composable fun BoxWithConstraintsScope.LoanModal( - accounts: List = emptyList(), - onCreateAccount: (CreateAccountData) -> Unit = {}, - modal: LoanModalData?, + dateTime: Instant, + onSetDate: () -> Unit, + onSetTime: () -> Unit, onCreateLoan: (CreateLoanData) -> Unit, onEditLoan: (Loan, Boolean) -> Unit, + accounts: List = emptyList(), + onCreateAccount: (CreateAccountData) -> Unit = {}, onPerformCalculations: () -> Unit = {}, dismiss: () -> Unit, ) { val loan = modal?.loan + val timeConverter = LocalTimeConverter.current + var nameTextFieldValue by remember(modal) { mutableStateOf(selectEndTextFieldValue(loan?.name)) } - var dateTime by remember(modal) { - mutableStateOf(modal?.loan?.dateTime ?: timeNowUTC()) + var dateTime = modal?.loan?.dateTime ?: with(timeConverter) { + dateTime.toLocalDateTime() } var type by remember(modal) { mutableStateOf(modal?.loan?.type ?: LoanType.BORROW) @@ -209,9 +215,8 @@ fun BoxWithConstraintsScope.LoanModal( DateTimeRow( dateTime = dateTime, - onSetDateTime = { - dateTime = it - } + onEditDate = onSetDate, + onEditTime = onSetTime ) Spacer(Modifier.height(24.dp)) @@ -655,7 +660,10 @@ private fun Preview() { baseCurrency = "BGN", ), onCreateLoan = { }, - onEditLoan = { _, _ -> } + onEditLoan = { _, _ -> }, + onSetTime = { }, + onSetDate = { }, + dateTime = Instant.now() ) { } } diff --git a/temp/legacy-code/src/main/java/com/ivy/legacy/legacy/ui/theme/modal/LoanRecordModal.kt b/temp/legacy-code/src/main/java/com/ivy/legacy/legacy/ui/theme/modal/LoanRecordModal.kt index ef25b22c30..d048c6e615 100644 --- a/temp/legacy-code/src/main/java/com/ivy/legacy/legacy/ui/theme/modal/LoanRecordModal.kt +++ b/temp/legacy-code/src/main/java/com/ivy/legacy/legacy/ui/theme/modal/LoanRecordModal.kt @@ -34,7 +34,6 @@ import androidx.compose.ui.unit.dp import com.ivy.base.model.LoanRecordType import com.ivy.data.model.primitive.NotBlankTrimmedString import com.ivy.design.api.LocalTimeConverter -import com.ivy.design.api.LocalTimeProvider import com.ivy.design.l0_system.UI import com.ivy.design.l0_system.style import com.ivy.design.utils.thenIf @@ -80,7 +79,9 @@ data class LoanRecordModalData( @Composable fun BoxWithConstraintsScope.LoanRecordModal( modal: LoanRecordModalData?, - + dateTime: Instant, + onSetDate: () -> Unit, + onSetTime: () -> Unit, onCreate: (CreateLoanRecordData) -> Unit, onEdit: (EditLoanRecordData) -> Unit, onDelete: (LoanRecord) -> Unit, @@ -88,8 +89,8 @@ fun BoxWithConstraintsScope.LoanRecordModal( accounts: List = emptyList(), onCreateAccount: (CreateAccountData) -> Unit = {}, ) { - val timeProvider = LocalTimeProvider.current val initialRecord = modal?.loanRecord + var noteTextFieldValue by remember(modal) { mutableStateOf(selectEndTextFieldValue(initialRecord?.note)) } @@ -99,9 +100,6 @@ fun BoxWithConstraintsScope.LoanRecordModal( var amount by remember(modal) { mutableStateOf(modal?.loanRecord?.amount ?: 0.0) } - var dateTime by remember(modal) { - mutableStateOf(modal?.loanRecord?.dateTime ?: timeProvider.utcNow()) - } var selectedAcc by remember(modal) { mutableStateOf(modal?.selectedAccount) } @@ -121,6 +119,7 @@ fun BoxWithConstraintsScope.LoanRecordModal( mutableStateOf(modal?.loanRecord?.loanRecordType ?: LoanRecordType.DECREASE) } + var dateTime = modal?.loanRecord?.dateTime ?: dateTime var amountModalVisible by remember { mutableStateOf(false) } var deleteModalVisible by remember(modal) { mutableStateOf(false) } var accountModalData: AccountModalData? by remember { mutableStateOf(null) } @@ -209,9 +208,8 @@ fun BoxWithConstraintsScope.LoanRecordModal( val timeConverter = LocalTimeConverter.current DateTimeRow( dateTime = with(timeConverter) { dateTime.toLocalDateTime() }, - onSetDateTime = { - dateTime = with(timeConverter) { it.toUTC() } - } + onEditDate = onSetDate, + onEditTime = onSetTime, ) Spacer(Modifier.height(24.dp)) @@ -675,6 +673,9 @@ private fun Preview() { onEdit = {}, onDelete = {}, dismiss = {}, + onSetDate = {}, + onSetTime = {}, + dateTime = Instant.now() ) } }