Skip to content

Commit

Permalink
[feat/#76] btn 이벤트 수정
Browse files Browse the repository at this point in the history
  • Loading branch information
Mnseo committed Feb 10, 2024
1 parent 11129fa commit 3aa81f3
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 53 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,13 @@ data class AttendInfoPayload(
val curriculumId: Int,
val curriculumName: String,
val isAttended: Boolean,
val date: String,
val time: String
val date: String
)

fun AttendInfoPayload.toModel() =
AttendInfoModel(
curriculumId = curriculumId ?: 0,
curriculumName = curriculumName ?: "",
isAttended = isAttended ?: false,
date = date ?: "2월 17일",
time = time ?: "오후 02:00"
date = date ?: "2월 17일"
)
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,4 @@ data class AttendInfoModel(
val curriculumName: String,
val isAttended: Boolean,
val date: String,
val time:String
)
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import java.time.LocalDateTime
import java.time.Year
import java.time.format.DateTimeFormatter
import java.time.format.DateTimeParseException
import java.time.temporal.ChronoUnit
import java.util.*
import javax.inject.Inject

Expand All @@ -45,7 +46,7 @@ class AttendViewModel @Inject constructor(
private val _attendListInit = MutableStateFlow<List<AttendCurrentModel>>(emptyList())
val attendListInit : StateFlow<List<AttendCurrentModel>> = _attendListInit.asStateFlow()

private val _upcomingAttend = MutableStateFlow(AttendInfoModel(0, "커리큘럼이 없습니다", false, "", ""))
private val _upcomingAttend = MutableStateFlow(AttendInfoModel(0, "커리큘럼이 없습니다", false, ""))
val upcomingAttend : StateFlow<AttendInfoModel> = _upcomingAttend.asStateFlow()

private val _attendScore = MutableStateFlow(AttendModel(0, 0, 0, 0, "수료 가능한 점수에요"))
Expand Down Expand Up @@ -135,8 +136,8 @@ class AttendViewModel @Inject constructor(
_snackbarEvent.emit(AttendSnackBarEvent.Attend_success)
_qrEnabled.value = false
}
delay(10000L) // 다음 반복까지 10초 대기
}
delay(10000L) // 다음 반복까지 10초 대기
}
}
}
Expand All @@ -154,24 +155,38 @@ class AttendViewModel @Inject constructor(
}
}


@RequiresApi(Build.VERSION_CODES.O)
fun combineDateAndTime(date: String, time: String): LocalDateTime? {
val currentYear = LocalDate.now().year
// 날짜 형식에 연도 추가
val dateFormatter = DateTimeFormatter.ofPattern("MM월 dd일", Locale.KOREAN)
val dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy년 MM월 dd일 a hh:mm", Locale.KOREAN)
val timeUntilEvent = upcomingAttend
.map { attend -> calculateTimeTerm(attend.date) }
.stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(5000L), // 스트림이 시작되는 조건
initialValue = ""
)

return try {
// 날짜와 시간 문자열을 현재 연도와 결합
val dateTimeStr = "${currentYear}$date $time"
LocalDateTime.parse(dateTimeStr, dateTimeFormatter)
} catch (e: Exception) {
null // 파싱 실패 시 null 반환
@RequiresApi(Build.VERSION_CODES.O)
fun calculateTimeTerm(date: String, durationMinutes: Long = 120): String {
if (date.isEmpty()) return ""

val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss")
val eventDate = LocalDateTime.parse(date, formatter)
val currentDate = LocalDateTime.now()
val minutesDiff = ChronoUnit.MINUTES.between(currentDate, eventDate)

return when {
minutesDiff > 1440 -> "D-${minutesDiff / 1440}" // 하루 이상
minutesDiff in 1..1439 -> {
val hours = minutesDiff / 60
val minutes = minutesDiff % 60
String.format("%02d:%02d", hours, minutes)
} // 하루 이하
minutesDiff in -30..120 -> "Soon" // 이벤트 시작 2시간 이내
minutesDiff <= -30 -> "Ended" // 이벤트 시작 후 30분 지남
else -> "No Event"
}
}

enum class Status(val displayName: String) {
enum class Status(val displayName: String) {
PRESENT("출석"),
ABSENT("결석"),
LATE("지각");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ fun AttendBtnOff(
verticalArrangement = Arrangement.Center
) {
Text(text = stringResource(R.string.attend_btn_attend_wait), style = KusitmsTypo.current.Text_Semibold, color = KusitmsColorPalette.current.Grey400)
Text(text = leftTime, style = KusitmsTypo.current.Text_Semibold, color = KusitmsColorPalette.current.Grey400)
Text(text = leftTime, style = KusitmsTypo.current.Caption1, color = KusitmsColorPalette.current.Grey400)
}
}
}
Expand All @@ -70,7 +70,7 @@ fun AttendBtnFailure() {
onClick = {},
enabled = false
) {
Text(text = stringResource(R.string.attend_btn_attend_failure), style = KusitmsTypo.current.Text_Semibold, color = KusitmsColorPalette.current.Sub2, maxLines = 1)
Text(text = stringResource(R.string.attend_btn_attend_failure), style = KusitmsTypo.current.Caption1, color = KusitmsColorPalette.current.Sub2, maxLines = 1)
}
}

Expand All @@ -85,6 +85,6 @@ fun AttendBtnSuccess() {
onClick = {},
enabled = false
) {
Text(text = stringResource(R.string.attend_btn_attend_success), style = KusitmsTypo.current.Text_Semibold, color = KusitmsColorPalette.current.Sub1, maxLines = 1)
Text(text = stringResource(R.string.attend_btn_attend_success), style = KusitmsTypo.current.Caption1, color = KusitmsColorPalette.current.Sub1, maxLines = 1)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -112,27 +112,17 @@ fun AttendTopBar() {
}
}


@RequiresApi(Build.VERSION_CODES.O)
@Composable
fun AttendPreColumn(
viewModel: AttendViewModel,
navController: NavHostController
) {
val curri by viewModel.upcomingAttend.collectAsState()
val curriculum = curri.curriculumName ?: "커리큘럼이 없습니다"
val eventDateTime = viewModel.combineDateAndTime(curri.date, curri.time)
val currentTime = remember { mutableStateOf(LocalDateTime.now()) }
val duration = eventDateTime?.let {
Duration.between(currentTime.value, eventDateTime)
} ?: Duration.ZERO
val curriculum = curri.curriculumName
val timeUntilEvent by viewModel.timeUntilEvent.collectAsState()

// 주기적으로 현재 시간 상태 업데이트
LaunchedEffect(key1 = Unit) {
while (true) {
currentTime.value = LocalDateTime.now()
delay(60000)
}
}

Box(modifier = Modifier
.fillMaxWidth()
Expand All @@ -153,25 +143,35 @@ fun AttendPreColumn(
.height(56.dp),
verticalArrangement = Arrangement.Center
) {
Text(text = stringResource(R.string.attend_box1_title), style = KusitmsTypo.current.Caption1, color = KusitmsColorPalette.current.Main500)
Text(
text = stringResource(R.string.attend_box1_title),
style = KusitmsTypo.current.Caption1,
color = KusitmsColorPalette.current.Main500
)
KusitmsMarginVerticalSpacer(size = 4)
Text(text = curriculum, style = KusitmsTypo.current.SubTitle1_Semibold, color = KusitmsColorPalette.current.White)
Text(
text = curriculum,
style = KusitmsTypo.current.SubTitle1_Semibold,
color = KusitmsColorPalette.current.White
)
}
if (duration.isNegative) {
val minutesAfterStart = duration.abs().toMinutes()
if (minutesAfterStart <= 30) {
// 이벤트 시작 후 30분 이내
AttendBtnOn(navController = navController) // 여기서 정책에 따라 AttendBtnFailure로 변경 가능
} else {
// 이벤트 시작 후 30분 초과
AttendBtnFailure()
when {
timeUntilEvent.startsWith("D-") -> {
AttendBtnOff(timeUntilEvent)
}
timeUntilEvent.matches(Regex("\\d{2}:\\d{2}")) -> {
AttendBtnOff(timeUntilEvent) // HH:MM 형식으로 남은 시간이 표시될 때
}
timeUntilEvent == "Soon" -> {
AttendBtnOn(navController)
}
timeUntilEvent == "Ended" -> {
if(curri.isAttended) {
AttendBtnSuccess()
} else {
AttendBtnFailure()
}
}
} else if (duration.isZero || (duration.toMinutes() in 1..30)) {
// 이벤트 시작 전 30분 이내
AttendBtnOn(navController = navController)
} else {
// 이벤트 시작까지 30분 이상 남음
AttendBtnOff("D-${duration.toDaysPart()} ${duration.toHoursPart()}:${duration.toMinutesPart()}")
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,16 @@ import com.kusitms.presentation.common.ui.KusitmsMarginHorizontalSpacer
import com.kusitms.presentation.common.ui.theme.KusitmsColorPalette
import com.kusitms.presentation.common.ui.theme.KusitmsTypo
import com.kusitms.presentation.model.home.attend.AttendViewModel
import com.kusitms.presentation.ui.home.attend.AttendBtnFailure
import com.kusitms.presentation.ui.home.attend.AttendBtnOff
import com.kusitms.presentation.ui.home.attend.AttendBtnSuccess

@Composable
fun CameraScreen(
viewModel: AttendViewModel,
) {
val message by viewModel.snackbarEvent.collectAsState(initial = AttendViewModel.AttendSnackBarEvent.None)
val qrEnabled by viewModel.qrEnabled.collectAsState()

ComposablePermission(
permission = Manifest.permission.CAMERA,
onGranted = {
Expand Down

0 comments on commit 3aa81f3

Please sign in to comment.