Skip to content

Commit d2fbf5c

Browse files
authored
Merge pull request #25 from amirchi007/master
fix: prevent crash when flash sale expiry date is null or empty
2 parents ef77436 + 7da8077 commit d2fbf5c

File tree

4 files changed

+33
-23
lines changed

4 files changed

+33
-23
lines changed

shared/src/commonMain/kotlin/presentation/ui/main/home/HomeScreen.kt

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package presentation.ui.main.home
22

33
import androidx.compose.animation.Animatable
4+
import androidx.compose.animation.AnimatedVisibility
45
import androidx.compose.animation.core.animateDpAsState
56
import androidx.compose.animation.core.tween
67
import androidx.compose.foundation.Image
@@ -67,6 +68,7 @@ import presentation.theme.DefaultCardColorsTheme
6768
import presentation.theme.PagerDotColor
6869
import presentation.ui.main.home.view_model.HomeEvent
6970
import presentation.ui.main.home.view_model.HomeState
71+
import presentation.util.toLocalDateTimeOrNull
7072
import shoping_by_kmp.shared.generated.resources.Res
7173
import shoping_by_kmp.shared.generated.resources.bell
7274
import shoping_by_kmp.shared.generated.resources.category
@@ -278,27 +280,30 @@ fun HomeScreen(
278280

279281
Spacer_16dp()
280282

281-
282-
Row(
283-
modifier = Modifier.fillMaxWidth().padding(16.dp),
284-
verticalAlignment = Alignment.CenterVertically,
285-
horizontalArrangement = Arrangement.Start
286-
) {
283+
AnimatedVisibility(visible = state.home.flashSale.expiredAt.toLocalDateTimeOrNull() != null) {
287284
Row(
285+
modifier = Modifier.fillMaxWidth().padding(16.dp),
288286
verticalAlignment = Alignment.CenterVertically,
289-
horizontalArrangement = Arrangement.spacedBy(8.dp)
287+
horizontalArrangement = Arrangement.Start
290288
) {
291-
Text(
292-
stringResource(Res.string.flash_sale),
293-
style = MaterialTheme.typography.titleLarge
294-
)
295-
TimerBox(state = state)
289+
Row(
290+
verticalAlignment = Alignment.CenterVertically,
291+
horizontalArrangement = Arrangement.spacedBy(8.dp)
292+
) {
293+
Text(
294+
stringResource(Res.string.flash_sale),
295+
style = MaterialTheme.typography.titleLarge
296+
)
297+
298+
TimerBox(state = state)
299+
300+
}
301+
/* Text(
302+
"See All",
303+
style = MaterialTheme.typography.labelMedium,
304+
color = MaterialTheme.colorScheme.primary
305+
)*/
296306
}
297-
/* Text(
298-
"See All",
299-
style = MaterialTheme.typography.labelMedium,
300-
color = MaterialTheme.colorScheme.primary
301-
)*/
302307
}
303308

304309
LazyRow(
@@ -393,6 +398,7 @@ fun HomeScreen(
393398

394399
@Composable
395400
fun TimerBox(state: HomeState) {
401+
396402
Row(
397403
modifier = Modifier,
398404
verticalAlignment = Alignment.CenterVertically,

shared/src/commonMain/kotlin/presentation/ui/main/home/view_model/HomeState.kt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@ package presentation.ui.main.home.view_model
22

33
import business.core.NetworkState
44
import business.core.ProgressBarState
5-
import business.core.Queue
6-
import business.core.UIComponent
75
import business.core.ViewState
86
import business.domain.main.Home
97
import kotlinx.datetime.Clock

shared/src/commonMain/kotlin/presentation/ui/main/home/view_model/HomeViewModel.kt

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@ import business.core.BaseViewModel
44
import business.core.NetworkState
55
import business.interactors.main.HomeUseCase
66
import business.interactors.main.LikeUseCase
7-
import kotlinx.datetime.Instant
7+
import kotlinx.datetime.Clock
88
import kotlinx.datetime.TimeZone
99
import kotlinx.datetime.toLocalDateTime
10+
import presentation.util.toLocalDateTimeOrNull
1011

1112
class HomeViewModel(
1213
private val homeUseCase: HomeUseCase,
@@ -133,9 +134,13 @@ class HomeViewModel(
133134
private fun getHome() {
134135
executeUseCase(homeUseCase.execute(Unit), onSuccess = {
135136
it?.let {
136-
val currentDateTime =
137-
Instant.parse(it.flashSale.expiredAt).toLocalDateTime(TimeZone.UTC)
138-
setState { copy(home = it, time = currentDateTime) }
137+
val dateTime = it.flashSale.expiredAt.toLocalDateTimeOrNull()
138+
setState {
139+
copy(
140+
home = it,
141+
time = dateTime ?: Clock.System.now().toLocalDateTime(TimeZone.UTC)
142+
)
143+
}
139144
}
140145
}, onLoading = {
141146
setState { copy(progressBarState = it) }

shared/src/commonMain/kotlin/presentation/util/DateTimeConverter.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
package presentation.utilimport kotlinx.datetime.Instantimport kotlinx.datetime.LocalDateTimeimport kotlinx.datetime.TimeZoneimport kotlinx.datetime.toLocalDateTimefun String?.toLocalDateTimeOrNull(): LocalDateTime? { return if (!this.isNullOrBlank()) { try { Instant.parse(this).toLocalDateTime(TimeZone.UTC) } catch (e: Exception) { null } } else null}/** * Converts a nullable ISO-8601 formatted string to a [LocalDateTime] (UTC timezone). * Returns `null` if: * - The input is `null`/blank, or * - Parsing fails (e.g., invalid format). * * Note: Consider logging parse failures in debug mode if invalid inputs are unexpected. * Example valid input: "2024-01-01T12:00:00Z". */

0 commit comments

Comments
 (0)