Skip to content

Commit

Permalink
Merge pull request #61 from TeamHY2/Feature/#57-stars-component
Browse files Browse the repository at this point in the history
[Feature] MainScreen stars 컴포넌트를 구현합니다.
  • Loading branch information
librarywon authored Sep 4, 2024
2 parents 9e04183 + c692093 commit 976edbb
Show file tree
Hide file tree
Showing 10 changed files with 241 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ fun MainRoute(
updateSelectedTime(selectedTime)
updateTimePickerVisibility(false)
updateTimerRunning(true)
updateTodayStudyCount()
}
startTimer(selectedTime, mainViewModel, timerViewModel, onSendNotification)
},
Expand Down Expand Up @@ -255,6 +256,7 @@ private fun MainBody(
startTime = uiState.startTime,
endTime = uiState.endTime,
leftTime = uiState.leftTime,
starCount = uiState.starCount,
onStudyRoomExtendClick = onStudyRoomExtendClick,
onStudyRoomEndClick = onStudyRoomEndClick,
modifier = Modifier.height(308.dp),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import androidx.lifecycle.viewModelScope
import com.google.firebase.Firebase
import com.google.firebase.auth.auth
import com.hongikyeolgong2.calendar.model.StudyDay
import com.hongikyeolgong2.calendar.model.StudyRoomUsage
import com.teamhy2.feature.main.mapper.StudyDayMapper
import com.teamhy2.feature.main.model.MainUiState
import com.teamhy2.hongikyeolgong2.timer.prsentation.model.TimerUiModel
Expand All @@ -26,6 +27,7 @@ class MainViewModel
private val wiseSayingRepository: WiseSayingRepository,
private val studyDayRepository: StudyDayRepository,
) : ViewModel() {
private val today = LocalDate.now()
private val _mainUiState = MutableStateFlow(MainUiState())
val mainUiState: StateFlow<MainUiState> = _mainUiState.asStateFlow()

Expand Down Expand Up @@ -57,7 +59,15 @@ class MainViewModel
}
},
)
updateCurrentMonthStudyDays(LocalDate.now().year, LocalDate.now().monthValue)
updateCurrentMonthStudyDays(today.year, today.monthValue)

val yearMonthKey = "${today.year}-${String.format("%02d", today.monthValue)}"
val todayStudyDay = studyDays[yearMonthKey]?.find { it.date == today }

_mainUiState.value =
_mainUiState.value.copy(
starCount = calculateTodayStarCount(todayStudyDay),
)
}
}

Expand All @@ -66,11 +76,54 @@ class MainViewModel
month: Int,
) {
val yearMonthKey = "$year-${String.format("%02d", month)}"
val studyDays = studyDays[yearMonthKey] ?: emptyList()
val updatedCalendar = _mainUiState.value.calendar.copy(studyDays = studyDays)
val studyDaysForMonth = studyDays[yearMonthKey] ?: emptyList()
val updatedCalendar = _mainUiState.value.calendar.copy(studyDays = studyDaysForMonth)
_mainUiState.value = _mainUiState.value.copy(calendar = updatedCalendar)
}

fun updateTodayStudyCount() {
val yearMonthKey = "${today.year}-${String.format("%02d", today.monthValue)}"
val studyDaysForMonth = studyDays[yearMonthKey]?.toMutableList() ?: mutableListOf()

val todayStudyDayIndex = studyDaysForMonth.indexOfFirst { it.date == today }
if (todayStudyDayIndex != -1) {
val updatedStudyRoomUsage =
StudyDayMapper.getNextStudyRoomUsage(studyDaysForMonth[todayStudyDayIndex].studyRoomUsage)
studyDaysForMonth[todayStudyDayIndex] =
studyDaysForMonth[todayStudyDayIndex].copy(
studyRoomUsage = updatedStudyRoomUsage,
)
} else {
studyDaysForMonth.add(
StudyDay(date = today, studyRoomUsage = StudyRoomUsage.USED_ONCE),
)
}

studyDays[yearMonthKey] = studyDaysForMonth

val starCount = calculateTodayStarCount(studyDaysForMonth.find { it.date == today })

if (mainUiState.value.calendar.date.year == today.year && mainUiState.value.calendar.date.monthValue == today.monthValue) {
val updatedCalendar = _mainUiState.value.calendar.copy(studyDays = studyDaysForMonth)
_mainUiState.value =
_mainUiState.value.copy(
calendar = updatedCalendar,
starCount = starCount,
)
} else {
_mainUiState.value =
_mainUiState.value.copy(
starCount = starCount,
)
}
}

private fun calculateTodayStarCount(todayStudyDay: StudyDay?): Int {
return StudyDayMapper.mapStudyRoomUsageToStarCount(
todayStudyDay?.studyRoomUsage ?: StudyRoomUsage.NEVER_USED,
)
}

fun updateCalendarMonth(isNextMonth: Boolean) {
val updatedCalendar =
_mainUiState.value.calendar.apply {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package com.teamhy2.feature.main.component

import StarsComponent
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.height
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
Expand All @@ -22,6 +25,7 @@ fun RunningTimerComponent(
startTime: String,
endTime: String,
leftTime: String,
starCount: Int,
onStudyRoomExtendClick: () -> Unit,
onStudyRoomEndClick: () -> Unit,
extendThreshold: String = "00:30:00",
Expand All @@ -31,11 +35,17 @@ fun RunningTimerComponent(
modifier = modifier,
) {
Spacer(modifier = Modifier.height(20.dp))
HY2Timer(
leftTime = leftTime,
startTime = startTime,
endTime = endTime,
)
Box {
HY2Timer(
leftTime = leftTime,
startTime = startTime,
endTime = endTime,
)
StarsComponent(
starCount = starCount,
modifier = Modifier.align(Alignment.BottomEnd),
)
}
Spacer(modifier = Modifier.height(16.dp))

if (leftTime <= extendThreshold) {
Expand Down Expand Up @@ -63,6 +73,7 @@ fun TimerScreenPreview_LessThanExtendThreshold() {
startTime = "11:30",
endTime = "12:00",
leftTime = "00:14:03",
starCount = 0,
onStudyRoomExtendClick = { },
onStudyRoomEndClick = { },
modifier = Modifier.background(Black),
Expand All @@ -78,6 +89,7 @@ fun TimerScreenPreview_MoreThanExtendThreshold() {
startTime = "11:30",
endTime = "12:00",
leftTime = "00:45:00",
starCount = 0,
onStudyRoomExtendClick = { },
onStudyRoomEndClick = { },
modifier = Modifier.background(Black),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.size
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.teamhy2.hongikyeolgong2.main.presentation.R

private const val STAR_IMAGE_SIZE = 40

@Composable
fun StarsComponent(
starCount: Int,
modifier: Modifier = Modifier,
) {
Row(
modifier = modifier,
) {
repeat(3) { position ->
Image(
painter = getStarPainter(starCount, position + 1),
contentDescription = null,
modifier = Modifier.size(STAR_IMAGE_SIZE.dp),
)
}
}
}

@Composable
fun getStarPainter(
starCount: Int,
position: Int,
): Painter {
return when {
starCount >= position -> painterResource(id = getStarDrawableId(position))
else -> painterResource(id = R.drawable.ic_star_0)
}
}

private fun getStarDrawableId(position: Int): Int {
return when (position) {
1 -> R.drawable.ic_star_1
2 -> R.drawable.ic_star_2
3 -> R.drawable.ic_star_3
else -> R.drawable.ic_star_0
}
}

@Preview(showBackground = true)
@Composable
private fun StarCount1ComponentPreview() {
StarsComponent(starCount = 1)
}

@Preview(showBackground = true)
@Composable
private fun StarsCount2ComponentPreview() {
StarsComponent(starCount = 2)
}

@Preview(showBackground = true)
@Composable
private fun StarsCount3ComponentPreview() {
StarsComponent(starCount = 3)
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,34 @@ import com.teamhy2.main.domain.model.StudyDayResponse

object StudyDayMapper {
fun mapToStudyDay(studyDayResponse: StudyDayResponse): StudyDay {
val studyRoomUsage =
when (studyDayResponse.studyStartTimes.size) {
1 -> StudyRoomUsage.USED_ONCE
2 -> StudyRoomUsage.USED_ONCE_EXTENDED_ONCE
3 -> StudyRoomUsage.USED_ONCE_EXTENDED_TWICE
else -> StudyRoomUsage.NEVER_USED
}
val studyRoomUsage = mapToStudyRoomUsage(studyDayResponse.studyStartTimes.size)
return StudyDay(date = studyDayResponse.date, studyRoomUsage = studyRoomUsage)
}

private fun mapToStudyRoomUsage(studyStartTimesCount: Int): StudyRoomUsage {
return when (studyStartTimesCount) {
1 -> StudyRoomUsage.USED_ONCE
2 -> StudyRoomUsage.USED_ONCE_EXTENDED_ONCE
3 -> StudyRoomUsage.USED_ONCE_EXTENDED_TWICE
else -> StudyRoomUsage.NEVER_USED
}
}

fun mapStudyRoomUsageToStarCount(studyRoomUsage: StudyRoomUsage): Int {
return when (studyRoomUsage) {
StudyRoomUsage.USED_ONCE -> 1
StudyRoomUsage.USED_ONCE_EXTENDED_ONCE -> 2
StudyRoomUsage.USED_ONCE_EXTENDED_TWICE -> 3
StudyRoomUsage.NEVER_USED -> 0
}
}

fun getNextStudyRoomUsage(studyRoomUsage: StudyRoomUsage): StudyRoomUsage {
return when (studyRoomUsage) {
StudyRoomUsage.USED_ONCE -> StudyRoomUsage.USED_ONCE_EXTENDED_ONCE
StudyRoomUsage.USED_ONCE_EXTENDED_ONCE -> StudyRoomUsage.USED_ONCE_EXTENDED_TWICE
StudyRoomUsage.USED_ONCE_EXTENDED_TWICE -> StudyRoomUsage.USED_ONCE_EXTENDED_TWICE
StudyRoomUsage.NEVER_USED -> StudyRoomUsage.USED_ONCE
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@ data class MainUiState(
val startTime: String = "",
val endTime: String = "",
val leftTime: String = "",
val starCount: Int = 0,
)
9 changes: 9 additions & 0 deletions main-presentation/src/main/res/drawable/ic_star_0.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="32dp"
android:height="32dp"
android:viewportWidth="32"
android:viewportHeight="32">
<path
android:pathData="M16.631,9.847L18.779,13.756C18.833,13.854 18.913,13.934 19.011,13.987L22.928,16.119C23.334,16.34 23.335,16.922 22.93,17.144L19.022,19.292C18.924,19.346 18.843,19.427 18.79,19.525L16.658,23.442C16.438,23.847 15.855,23.849 15.633,23.444L13.485,19.535C13.431,19.437 13.351,19.357 13.253,19.304L9.336,17.171C8.93,16.951 8.929,16.369 9.334,16.147L13.242,13.999C13.34,13.945 13.421,13.864 13.474,13.766L15.606,9.849C15.827,9.444 16.409,9.442 16.631,9.847Z"
android:fillColor="#3A3E49"/>
</vector>
20 changes: 20 additions & 0 deletions main-presentation/src/main/res/drawable/ic_star_1.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="32dp"
android:height="32dp"
android:viewportWidth="32"
android:viewportHeight="32">
<path
android:pathData="M16.631,9.847L18.779,13.756C18.833,13.854 18.913,13.934 19.011,13.987L22.928,16.119C23.334,16.34 23.335,16.922 22.93,17.144L19.022,19.292C18.924,19.346 18.843,19.427 18.79,19.525L16.658,23.442C16.438,23.847 15.855,23.849 15.633,23.444L13.485,19.535C13.431,19.437 13.351,19.357 13.253,19.304L9.336,17.171C8.93,16.951 8.929,16.369 9.334,16.147L13.242,13.999C13.34,13.945 13.421,13.864 13.474,13.766L15.606,9.849C15.827,9.444 16.409,9.442 16.631,9.847Z">
<aapt:attr name="android:fillColor">
<gradient
android:centerX="16.132"
android:centerY="16.646"
android:gradientRadius="6.043"
android:type="radial">
<item android:offset="0" android:color="#FF18275D"/>
<item android:offset="1" android:color="#FF263B85"/>
</gradient>
</aapt:attr>
</path>
</vector>
20 changes: 20 additions & 0 deletions main-presentation/src/main/res/drawable/ic_star_2.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="32dp"
android:height="32dp"
android:viewportWidth="32"
android:viewportHeight="32">
<path
android:pathData="M16.631,9.847L18.779,13.756C18.833,13.854 18.913,13.934 19.011,13.987L22.928,16.119C23.334,16.34 23.335,16.922 22.93,17.144L19.022,19.292C18.924,19.346 18.843,19.427 18.79,19.525L16.658,23.442C16.438,23.847 15.855,23.849 15.633,23.444L13.485,19.535C13.431,19.437 13.351,19.357 13.253,19.304L9.336,17.171C8.93,16.951 8.929,16.369 9.334,16.147L13.242,13.999C13.34,13.945 13.421,13.864 13.474,13.766L15.606,9.849C15.827,9.444 16.409,9.442 16.631,9.847Z">
<aapt:attr name="android:fillColor">
<gradient
android:centerX="16.132"
android:centerY="16.646"
android:gradientRadius="6.043"
android:type="radial">
<item android:offset="0" android:color="#FF334FB2"/>
<item android:offset="1" android:color="#FF6384FA"/>
</gradient>
</aapt:attr>
</path>
</vector>
20 changes: 20 additions & 0 deletions main-presentation/src/main/res/drawable/ic_star_3.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="32dp"
android:height="32dp"
android:viewportWidth="32"
android:viewportHeight="32">
<path
android:pathData="M16.631,9.847L18.779,13.756C18.833,13.854 18.913,13.934 19.011,13.987L22.928,16.119C23.334,16.34 23.335,16.922 22.93,17.144L19.022,19.292C18.924,19.346 18.843,19.427 18.79,19.525L16.658,23.442C16.438,23.847 15.855,23.849 15.633,23.444L13.485,19.535C13.431,19.437 13.351,19.357 13.253,19.304L9.336,17.171C8.93,16.951 8.929,16.369 9.334,16.147L13.242,13.999C13.34,13.945 13.421,13.864 13.474,13.766L15.606,9.849C15.827,9.444 16.409,9.442 16.631,9.847Z">
<aapt:attr name="android:fillColor">
<gradient
android:centerX="16.542"
android:centerY="16.486"
android:gradientRadius="7.661"
android:type="radial">
<item android:offset="0" android:color="#FFBAFF28"/>
<item android:offset="1" android:color="#FFFFFF40"/>
</gradient>
</aapt:attr>
</path>
</vector>

0 comments on commit 976edbb

Please sign in to comment.