diff --git a/domain/src/main/java/com/nexters/boolti/domain/model/Show.kt b/domain/src/main/java/com/nexters/boolti/domain/model/Show.kt index 4c01968b..b1cff77a 100644 --- a/domain/src/main/java/com/nexters/boolti/domain/model/Show.kt +++ b/domain/src/main/java/com/nexters/boolti/domain/model/Show.kt @@ -14,11 +14,10 @@ data class Show( val state: ShowState get() { val now = LocalDate.now() - val dDay = salesStartDate.toEpochDay() - now.toEpochDay() return when { now > date.toLocalDate() -> ShowState.FinishedShow - now < salesStartDate -> ShowState.WaitingTicketing(dDay.toInt()) + now < salesStartDate -> ShowState.WaitingTicketing(salesStartDate.atStartOfDay()) now <= salesEndDate -> ShowState.TicketingInProgress now > salesEndDate -> ShowState.ClosedTicketing else -> ShowState.FinishedShow diff --git a/domain/src/main/java/com/nexters/boolti/domain/model/ShowDetail.kt b/domain/src/main/java/com/nexters/boolti/domain/model/ShowDetail.kt index 0b4ff3cb..bd22dfda 100644 --- a/domain/src/main/java/com/nexters/boolti/domain/model/ShowDetail.kt +++ b/domain/src/main/java/com/nexters/boolti/domain/model/ShowDetail.kt @@ -23,11 +23,10 @@ data class ShowDetail( val state: ShowState get() { val now = LocalDate.now() - val dDay = salesStartDate.toEpochDay() - now.toEpochDay() return when { now > date.toLocalDate() -> ShowState.FinishedShow - now < salesStartDate -> ShowState.WaitingTicketing(dDay.toInt()) + now < salesStartDate -> ShowState.WaitingTicketing(salesStartDate.atStartOfDay()) now <= salesEndDate -> ShowState.TicketingInProgress now > salesEndDate -> ShowState.ClosedTicketing else -> ShowState.FinishedShow diff --git a/domain/src/main/java/com/nexters/boolti/domain/model/ShowState.kt b/domain/src/main/java/com/nexters/boolti/domain/model/ShowState.kt index 3eb77b5a..7057e682 100644 --- a/domain/src/main/java/com/nexters/boolti/domain/model/ShowState.kt +++ b/domain/src/main/java/com/nexters/boolti/domain/model/ShowState.kt @@ -1,7 +1,9 @@ package com.nexters.boolti.domain.model +import java.time.LocalDateTime + sealed interface ShowState { - data class WaitingTicketing(val dDay: Int) : ShowState + data class WaitingTicketing(val startDateTime: LocalDateTime) : ShowState data object TicketingInProgress : ShowState data object ClosedTicketing : ShowState data object FinishedShow : ShowState diff --git a/presentation/src/main/java/com/nexters/boolti/presentation/component/ShowFeed.kt b/presentation/src/main/java/com/nexters/boolti/presentation/component/ShowFeed.kt index b37ffaaf..56b216ca 100644 --- a/presentation/src/main/java/com/nexters/boolti/presentation/component/ShowFeed.kt +++ b/presentation/src/main/java/com/nexters/boolti/presentation/component/ShowFeed.kt @@ -20,14 +20,17 @@ import androidx.compose.ui.graphics.SolidColor import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import coil.compose.AsyncImage import com.nexters.boolti.domain.model.Show import com.nexters.boolti.domain.model.ShowState import com.nexters.boolti.presentation.R import com.nexters.boolti.presentation.constants.posterRatio +import com.nexters.boolti.presentation.extension.dDay import com.nexters.boolti.presentation.extension.showDateTimeString import com.nexters.boolti.presentation.extension.toPx +import com.nexters.boolti.presentation.theme.BooltiTheme import com.nexters.boolti.presentation.theme.Grey05 import com.nexters.boolti.presentation.theme.Grey20 import com.nexters.boolti.presentation.theme.Grey30 @@ -35,6 +38,7 @@ import com.nexters.boolti.presentation.theme.Grey40 import com.nexters.boolti.presentation.theme.Grey80 import com.nexters.boolti.presentation.theme.Grey95 import com.nexters.boolti.presentation.theme.point1 +import java.time.LocalDateTime @Composable fun ShowFeed( @@ -120,7 +124,7 @@ private fun ShowBadge( var dDay: Int? = null val (color, containerColor, labelId) = when (showState) { is ShowState.WaitingTicketing -> { - dDay = showState.dDay + dDay = showState.startDateTime.dDay.toInt() Triple( MaterialTheme.colorScheme.primary, Grey80, @@ -148,4 +152,12 @@ private fun ShowBadge( .padding(horizontal = 12.dp, vertical = 3.dp), style = MaterialTheme.typography.labelMedium.copy(color = color), ) +} + +@Preview +@Composable +private fun ShowBadgePreview() { + BooltiTheme { + ShowBadge(ShowState.WaitingTicketing(LocalDateTime.now().plusDays(3).plusHours(1))) + } } \ No newline at end of file diff --git a/presentation/src/main/java/com/nexters/boolti/presentation/extension/LocalDateTime.kt b/presentation/src/main/java/com/nexters/boolti/presentation/extension/LocalDateTime.kt index e4b5afd1..d456d776 100644 --- a/presentation/src/main/java/com/nexters/boolti/presentation/extension/LocalDateTime.kt +++ b/presentation/src/main/java/com/nexters/boolti/presentation/extension/LocalDateTime.kt @@ -2,9 +2,13 @@ package com.nexters.boolti.presentation.extension import androidx.compose.runtime.Composable import androidx.compose.ui.res.stringArrayResource +import androidx.compose.ui.res.stringResource import com.nexters.boolti.presentation.R +import java.time.Duration +import java.time.LocalDate import java.time.LocalDateTime import java.time.format.DateTimeFormatter +import java.time.temporal.ChronoUnit /** * ## 요일 @@ -29,3 +33,24 @@ val LocalDateTime.showDateTimeString: String } fun LocalDateTime.format(pattern: String): String = format(DateTimeFormatter.ofPattern(pattern)) + +val LocalDateTime.dDay: Long + get() = run { + val today = LocalDate.now() + ChronoUnit.DAYS.between(today, toLocalDate()) + } + +val LocalDateTime.countDownString: String + @Composable + get() = run { + val now = LocalDateTime.now() + + val duration = Duration.between(now, this) + + val days = duration.toDays() + val hours = duration.toHours() % 24 + val minutes = duration.toMinutes() % 60 + + stringResource(id = R.string.ticketing_button_ticket_countdown, days) + + " ${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}" + } \ No newline at end of file diff --git a/presentation/src/main/java/com/nexters/boolti/presentation/screen/showdetail/ShowDetailButtons.kt b/presentation/src/main/java/com/nexters/boolti/presentation/screen/showdetail/ShowDetailButtons.kt index 9cb6d62e..66cbe223 100644 --- a/presentation/src/main/java/com/nexters/boolti/presentation/screen/showdetail/ShowDetailButtons.kt +++ b/presentation/src/main/java/com/nexters/boolti/presentation/screen/showdetail/ShowDetailButtons.kt @@ -21,10 +21,12 @@ import com.nexters.boolti.domain.model.ShowState import com.nexters.boolti.presentation.R import com.nexters.boolti.presentation.component.MainButton import com.nexters.boolti.presentation.component.MainButtonDefaults +import com.nexters.boolti.presentation.extension.countDownString import com.nexters.boolti.presentation.theme.BooltiTheme import com.nexters.boolti.presentation.theme.Grey50 import com.nexters.boolti.presentation.theme.Grey80 import com.nexters.boolti.presentation.theme.marginHorizontal +import java.time.LocalDateTime @Composable fun ShowDetailButtons( @@ -93,10 +95,7 @@ private fun TicketingButton( ) { val enabled = showState is ShowState.TicketingInProgress val text = when (showState) { - is ShowState.WaitingTicketing -> stringResource( - id = R.string.ticketing_button_upcoming_ticket, showState.dDay - ) - + is ShowState.WaitingTicketing -> showState.startDateTime.countDownString ShowState.TicketingInProgress -> stringResource(id = R.string.ticketing_button_label) ShowState.ClosedTicketing -> stringResource(id = R.string.ticketing_button_closed_ticket) ShowState.FinishedShow -> stringResource(id = R.string.ticketing_button_finished_show) @@ -125,3 +124,17 @@ fun ShowDetailButtonsPreview() { ) } } + +@Preview(heightDp = 100) +@Composable +fun ShowDetailButtonsBeforeTicketingPreview() { + BooltiTheme { + ShowDetailButtons( + showState = ShowState.WaitingTicketing( + LocalDateTime.now().plusDays(3).plusHours(2).plusMinutes(17) + ), + onTicketingClicked = {}, + onGiftClicked = {} + ) + } +} \ No newline at end of file diff --git a/presentation/src/main/res/values/strings.xml b/presentation/src/main/res/values/strings.xml index fba54f5a..42c5e0c1 100644 --- a/presentation/src/main/res/values/strings.xml +++ b/presentation/src/main/res/values/strings.xml @@ -138,6 +138,7 @@ 이미 예매한 공연 1인 1매만 예매할 수 있어요 예매 시작 D-%d + 판매 시작까지 %d일 예매 종료 공연 종료 1인 %d매