From ee68943f6aa61b2ab97734fe25ef8c27c85c971d Mon Sep 17 00:00:00 2001 From: boiledegg Date: Thu, 12 Dec 2024 16:27:09 +0900 Subject: [PATCH] =?UTF-8?q?[REFACTOR/#305]=20Calendar=20=ED=99=94=EB=A9=B4?= =?UTF-8?q?=20=EB=A6=AC=ED=8C=A9=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 요일 enum 추가 - 컴포넌트 주석 추가 - 미사용 라이브러리 제거 --- .../calendar/calendar/CalendarViewModel.kt | 2 +- .../calendar/component/ScreenTransition.kt | 10 ++ .../calendar/component/WeekDaysHeader.kt | 18 +-- .../dialog/CalendarScrapCancelDialog.kt | 28 +++++ .../dialog/CalendarScrapPatchDialog.kt | 50 ++++++++ .../calendar/model/CalendarUiState.kt | 3 - .../calendar/model/TerningCalendarModel.kt | 1 - .../feature/calendar/calendar/type/WeekDay.kt | 19 +++ .../calendar/list/CalendarListScreen.kt | 119 +++++++----------- .../calendar/week/CalendarWeekScreen.kt | 62 +-------- 10 files changed, 159 insertions(+), 153 deletions(-) create mode 100644 feature/calendar/src/main/java/com/terning/feature/calendar/calendar/component/dialog/CalendarScrapCancelDialog.kt create mode 100644 feature/calendar/src/main/java/com/terning/feature/calendar/calendar/component/dialog/CalendarScrapPatchDialog.kt create mode 100644 feature/calendar/src/main/java/com/terning/feature/calendar/calendar/type/WeekDay.kt diff --git a/feature/calendar/src/main/java/com/terning/feature/calendar/calendar/CalendarViewModel.kt b/feature/calendar/src/main/java/com/terning/feature/calendar/calendar/CalendarViewModel.kt index d1fed7a8..b8787976 100644 --- a/feature/calendar/src/main/java/com/terning/feature/calendar/calendar/CalendarViewModel.kt +++ b/feature/calendar/src/main/java/com/terning/feature/calendar/calendar/CalendarViewModel.kt @@ -1,8 +1,8 @@ package com.terning.feature.calendar.calendar import androidx.lifecycle.ViewModel -import com.terning.feature.calendar.calendar.model.DayModel import com.terning.feature.calendar.calendar.model.CalendarUiState +import com.terning.feature.calendar.calendar.model.DayModel import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow diff --git a/feature/calendar/src/main/java/com/terning/feature/calendar/calendar/component/ScreenTransition.kt b/feature/calendar/src/main/java/com/terning/feature/calendar/calendar/component/ScreenTransition.kt index 21d8acdd..8d6e9bea 100644 --- a/feature/calendar/src/main/java/com/terning/feature/calendar/calendar/component/ScreenTransition.kt +++ b/feature/calendar/src/main/java/com/terning/feature/calendar/calendar/component/ScreenTransition.kt @@ -7,6 +7,16 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.res.stringResource import com.terning.feature.calendar.R +/** + * 두 화면 간 전환을 담당하는 컴포넌트 + * + * @param targetState 전환할 상태 + * @param transitionOne 첫번째 화면에서 두번쨰 화면으로 이동할 때 발생할 전환 모션 + * @param transitionTwo 두번째 화면에서 첫번째 화면으로 이동할 때 발생할 전환 모션 + * @param contentOne 첫번째 화면 + * @param contentTwo 두번째 화면 + */ + @Composable fun ScreenTransition( targetState: Boolean, diff --git a/feature/calendar/src/main/java/com/terning/feature/calendar/calendar/component/WeekDaysHeader.kt b/feature/calendar/src/main/java/com/terning/feature/calendar/calendar/component/WeekDaysHeader.kt index be398b0c..0e7d08fa 100644 --- a/feature/calendar/src/main/java/com/terning/feature/calendar/calendar/component/WeekDaysHeader.kt +++ b/feature/calendar/src/main/java/com/terning/feature/calendar/calendar/component/WeekDaysHeader.kt @@ -8,7 +8,6 @@ import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color -import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp @@ -16,7 +15,7 @@ import com.terning.core.designsystem.theme.Black import com.terning.core.designsystem.theme.SundayRed import com.terning.core.designsystem.theme.TerningPointTheme import com.terning.core.designsystem.theme.TerningTheme -import com.terning.feature.calendar.R +import com.terning.feature.calendar.calendar.type.WeekDay @Composable fun WeekDaysHeader( @@ -31,21 +30,12 @@ fun WeekDaysHeader( vertical = 18.dp ), ) { - val dayOfWeek = listOf( - R.string.calendar_text_sunday, - R.string.calendar_text_monday, - R.string.calendar_text_tuesday, - R.string.calendar_text_wednesday, - R.string.calendar_text_thursday, - R.string.calendar_text_friday, - R.string.calendar_text_saturday, - ) - dayOfWeek.forEach { day -> + WeekDay.entries.forEach { day -> Text( modifier = Modifier.weight(1f), - text = stringResource(id = day), + text = day.nameInKorean, style = TerningTheme.typography.body7, - color = if (day == R.string.calendar_text_sunday) SundayRed else Black, + color = if (WeekDay.isSunday(day)) SundayRed else Black, textAlign = TextAlign.Center ) } diff --git a/feature/calendar/src/main/java/com/terning/feature/calendar/calendar/component/dialog/CalendarScrapCancelDialog.kt b/feature/calendar/src/main/java/com/terning/feature/calendar/calendar/component/dialog/CalendarScrapCancelDialog.kt new file mode 100644 index 00000000..60c62d54 --- /dev/null +++ b/feature/calendar/src/main/java/com/terning/feature/calendar/calendar/component/dialog/CalendarScrapCancelDialog.kt @@ -0,0 +1,28 @@ +package com.terning.feature.calendar.calendar.component.dialog + +import androidx.compose.runtime.Composable +import com.terning.feature.dialog.cancel.ScrapCancelDialog + +/** + * 달력 스크랩 취소 다이얼로그 + * + * @param scrapVisibility 스크랩 취소 다이얼로그 가시 여부 + * @param internshipAnnouncementId 스크랩 취소를 진행할 공고 ID + * @param onDismissCancelDialog 스크랩 취소 다이얼로그 끄기 + */ + +@Composable +internal fun CalendarScrapCancelDialog( + scrapVisibility: Boolean, + internshipAnnouncementId: Long?, + onDismissCancelDialog: (Boolean) -> Unit, +) { + if (scrapVisibility) { + internshipAnnouncementId?.run { + ScrapCancelDialog( + internshipAnnouncementId = this, + onDismissRequest = onDismissCancelDialog + ) + } + } +} diff --git a/feature/calendar/src/main/java/com/terning/feature/calendar/calendar/component/dialog/CalendarScrapPatchDialog.kt b/feature/calendar/src/main/java/com/terning/feature/calendar/calendar/component/dialog/CalendarScrapPatchDialog.kt new file mode 100644 index 00000000..9861c357 --- /dev/null +++ b/feature/calendar/src/main/java/com/terning/feature/calendar/calendar/component/dialog/CalendarScrapPatchDialog.kt @@ -0,0 +1,50 @@ +package com.terning.feature.calendar.calendar.component.dialog + +import androidx.compose.runtime.Composable +import androidx.compose.ui.graphics.Color +import com.terning.core.designsystem.extension.getFullDateStringInKorean +import com.terning.domain.calendar.entity.CalendarScrapDetail +import com.terning.feature.dialog.detail.ScrapDialog +import java.time.LocalDate + +/** + * 달력 스크랩 디테일 다이얼로그 + * + * @param date 선택된 날짜 + * @param dialogVisibility 스크랩 디테일 다이얼로그 가시 여부 + * @param internshipModel 스크랩 디테일 + * @param navigateToAnnouncement 공고 상세로 이동하는 이동 + * @param onDismissInternDialog 스크랩 디테일 다이얼로그 끄기 + * @param onClickChangeColor 스크랩 색상 변경 시 발생하는 이벤트 + */ + +@Composable +internal fun CalendarScrapPatchDialog( + date: LocalDate, + dialogVisibility: Boolean, + internshipModel: CalendarScrapDetail?, + navigateToAnnouncement: (Long) -> Unit, + onDismissInternDialog: (Boolean) -> Unit, + onClickChangeColor: () -> Unit, +) { + if (dialogVisibility && internshipModel != null) { + val scrapColor = Color( + android.graphics.Color.parseColor( + internshipModel.color + ) + ) + ScrapDialog( + title = internshipModel.title, + scrapColor = scrapColor, + deadline = date.getFullDateStringInKorean(), + startYearMonth = internshipModel.startYearMonth, + workingPeriod = internshipModel.workingPeriod, + internshipAnnouncementId = internshipModel.internshipAnnouncementId, + companyImage = internshipModel.companyImage, + isScrapped = true, + onDismissRequest = onDismissInternDialog, + onClickChangeColor = onClickChangeColor, + onClickNavigateButton = navigateToAnnouncement + ) + } +} diff --git a/feature/calendar/src/main/java/com/terning/feature/calendar/calendar/model/CalendarUiState.kt b/feature/calendar/src/main/java/com/terning/feature/calendar/calendar/model/CalendarUiState.kt index 7273a807..1373729b 100644 --- a/feature/calendar/src/main/java/com/terning/feature/calendar/calendar/model/CalendarUiState.kt +++ b/feature/calendar/src/main/java/com/terning/feature/calendar/calendar/model/CalendarUiState.kt @@ -1,8 +1,5 @@ package com.terning.feature.calendar.calendar.model -import androidx.compose.foundation.pager.PagerState -import androidx.compose.runtime.compositionLocalOf - data class CalendarUiState( val selectedDate: DayModel = DayModel(), val calendarModel: TerningCalendarModel = TerningCalendarModel(), diff --git a/feature/calendar/src/main/java/com/terning/feature/calendar/calendar/model/TerningCalendarModel.kt b/feature/calendar/src/main/java/com/terning/feature/calendar/calendar/model/TerningCalendarModel.kt index 3f7b5a56..6733555f 100644 --- a/feature/calendar/src/main/java/com/terning/feature/calendar/calendar/model/TerningCalendarModel.kt +++ b/feature/calendar/src/main/java/com/terning/feature/calendar/calendar/model/TerningCalendarModel.kt @@ -1,7 +1,6 @@ package com.terning.feature.calendar.calendar.model import androidx.compose.runtime.Immutable -import androidx.compose.runtime.staticCompositionLocalOf import java.time.LocalDate import java.time.YearMonth diff --git a/feature/calendar/src/main/java/com/terning/feature/calendar/calendar/type/WeekDay.kt b/feature/calendar/src/main/java/com/terning/feature/calendar/calendar/type/WeekDay.kt new file mode 100644 index 00000000..ce5de1cb --- /dev/null +++ b/feature/calendar/src/main/java/com/terning/feature/calendar/calendar/type/WeekDay.kt @@ -0,0 +1,19 @@ +package com.terning.feature.calendar.calendar.type + +enum class WeekDay( + val nameInKorean: String, +) { + SUNDAY(nameInKorean = "일"), + MONDAY(nameInKorean = "월"), + TUESDAY(nameInKorean = "화"), + WEDNESDAY(nameInKorean = "수"), + THURSDAY(nameInKorean = "목"), + FRIDAY(nameInKorean = "금"), + SATURDAY(nameInKorean = "토"); + + companion object { + fun isSunday(weekDay: WeekDay): Boolean { + return weekDay == SUNDAY + } + } +} diff --git a/feature/calendar/src/main/java/com/terning/feature/calendar/list/CalendarListScreen.kt b/feature/calendar/src/main/java/com/terning/feature/calendar/list/CalendarListScreen.kt index be99dfde..e8cf6898 100644 --- a/feature/calendar/src/main/java/com/terning/feature/calendar/list/CalendarListScreen.kt +++ b/feature/calendar/src/main/java/com/terning/feature/calendar/list/CalendarListScreen.kt @@ -18,7 +18,6 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.snapshotFlow import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource @@ -38,11 +37,11 @@ import com.terning.core.designsystem.theme.Grey400 import com.terning.core.designsystem.theme.TerningTheme import com.terning.domain.calendar.entity.CalendarScrapDetail import com.terning.feature.calendar.R +import com.terning.feature.calendar.calendar.component.dialog.CalendarScrapCancelDialog +import com.terning.feature.calendar.calendar.component.dialog.CalendarScrapPatchDialog import com.terning.feature.calendar.calendar.component.group.CalendarScrapListGroup import com.terning.feature.calendar.calendar.model.TerningCalendarModel import com.terning.feature.calendar.list.model.CalendarListUiState -import com.terning.feature.dialog.cancel.ScrapCancelDialog -import com.terning.feature.dialog.detail.ScrapDialog import okhttp3.internal.toImmutableList import java.time.LocalDate @@ -56,9 +55,10 @@ fun CalendarListRoute( viewModel: CalendarListViewModel = hiltViewModel(), ) { val lifecycleOwner = LocalLifecycleOwner.current - val uiState by viewModel.uiState.collectAsStateWithLifecycle(lifecycleOwner) val context = LocalContext.current + val uiState by viewModel.uiState.collectAsStateWithLifecycle() + LaunchedEffect(viewModel.sideEffect, lifecycleOwner) { viewModel.sideEffect.flowWithLifecycle(lifecycle = lifecycleOwner.lifecycle) .collect { sideEffect -> @@ -100,8 +100,8 @@ fun CalendarListRoute( } ) - CalendarListScrapPatchDialog( - currentDate = uiState.currentDate, + CalendarScrapPatchDialog( + date = uiState.currentDate, dialogVisibility = uiState.scrapDetailDialogVisibility, internshipModel = uiState.internshipModel, navigateToAnnouncement = { announcementId -> @@ -114,7 +114,7 @@ fun CalendarListRoute( }, ) - CalendarListScrapCancelDialog( + CalendarScrapCancelDialog( scrapVisibility = uiState.scrapCancelDialogVisibility, internshipAnnouncementId = uiState.internshipAnnouncementId, onDismissCancelDialog = { isCancelled -> @@ -140,7 +140,6 @@ private fun CalendarListScreen( state = pagerState, modifier = modifier ) { page -> - val getDate = calendarModel.getLocalDateByPage(page) LazyColumn( modifier = Modifier @@ -163,31 +162,15 @@ private fun CalendarListScreen( is UiState.Failure -> {} is UiState.Success -> { - val scrapMap = uiState.loadState.data - items(getDate.lengthOfMonth()) { day -> - val currentDate = - LocalDate.of(getDate.year, getDate.monthValue, day + 1) - val dateInKorean = currentDate.getFullDateStringInKorean() - - if (scrapMap[dateInKorean].isListNotEmpty()) { - Text( - text = dateInKorean, - style = TerningTheme.typography.title5, - color = Black, - modifier = Modifier - .padding(start = 24.dp, top = 16.dp, bottom = 15.dp) - ) - - CalendarScrapListGroup( - scrapList = scrapMap[dateInKorean].orEmpty().toImmutableList(), - onScrapButtonClicked = onClickScrapButton, - onInternshipClicked = onClickInternship, - isFromList = true, - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 24.dp) - ) - } + val date = calendarModel.getLocalDateByPage(page) + + items(date.lengthOfMonth()) { day -> + CalendarListSuccess( + date = LocalDate.of(date.year, date.monthValue, day + 1), + scrapMap = uiState.loadState.data, + onClickScrapButton = onClickScrapButton, + onClickInternship = onClickInternship, + ) } } } @@ -218,50 +201,32 @@ private fun CalendarListEmpty( } @Composable -private fun CalendarListScrapCancelDialog( - scrapVisibility: Boolean, - internshipAnnouncementId: Long?, - onDismissCancelDialog: (Boolean) -> Unit, -) { - if (scrapVisibility) { - internshipAnnouncementId?.run { - ScrapCancelDialog( - internshipAnnouncementId = this, - onDismissRequest = onDismissCancelDialog - ) - } - } -} - -@Composable -private fun CalendarListScrapPatchDialog( - currentDate: LocalDate, - dialogVisibility: Boolean, - internshipModel: CalendarScrapDetail?, - navigateToAnnouncement: (Long) -> Unit, - onDismissInternDialog: (Boolean) -> Unit, - onClickChangeColor: () -> Unit, +private fun CalendarListSuccess( + date: LocalDate, + scrapMap: Map>, + onClickScrapButton: (Long) -> Unit, + onClickInternship: (CalendarScrapDetail) -> Unit, + modifier: Modifier = Modifier, ) { - if (dialogVisibility) { - internshipModel?.let { internship -> - val scrapColor = Color( - android.graphics.Color.parseColor( - internship.color - ) - ) - ScrapDialog( - title = internship.title, - scrapColor = scrapColor, - deadline = currentDate.getFullDateStringInKorean(), - startYearMonth = internship.startYearMonth, - workingPeriod = internship.workingPeriod, - internshipAnnouncementId = internship.internshipAnnouncementId, - companyImage = internship.companyImage, - isScrapped = true, - onDismissRequest = onDismissInternDialog, - onClickChangeColor = onClickChangeColor, - onClickNavigateButton = navigateToAnnouncement - ) - } + val dateInKorean = date.getFullDateStringInKorean() + + if (scrapMap[dateInKorean].isListNotEmpty()) { + Text( + text = dateInKorean, + style = TerningTheme.typography.title5, + color = Black, + modifier = modifier + .padding(start = 24.dp, top = 16.dp, bottom = 15.dp) + ) + + CalendarScrapListGroup( + scrapList = scrapMap[dateInKorean].orEmpty().toImmutableList(), + onScrapButtonClicked = onClickScrapButton, + onInternshipClicked = onClickInternship, + isFromList = true, + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 24.dp) + ) } } diff --git a/feature/calendar/src/main/java/com/terning/feature/calendar/week/CalendarWeekScreen.kt b/feature/calendar/src/main/java/com/terning/feature/calendar/week/CalendarWeekScreen.kt index 5d0da8b0..ab22b7fe 100644 --- a/feature/calendar/src/main/java/com/terning/feature/calendar/week/CalendarWeekScreen.kt +++ b/feature/calendar/src/main/java/com/terning/feature/calendar/week/CalendarWeekScreen.kt @@ -24,7 +24,6 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.shadow -import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource @@ -35,7 +34,6 @@ import androidx.lifecycle.compose.LocalLifecycleOwner import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.flowWithLifecycle import com.terning.core.designsystem.extension.getDateStringInKorean -import com.terning.core.designsystem.extension.getFullDateStringInKorean import com.terning.core.designsystem.extension.swipableVertically import com.terning.core.designsystem.extension.toast import com.terning.core.designsystem.state.UiState @@ -47,15 +45,14 @@ import com.terning.core.designsystem.theme.TerningTheme import com.terning.core.designsystem.theme.White import com.terning.domain.calendar.entity.CalendarScrapDetail import com.terning.feature.calendar.R +import com.terning.feature.calendar.calendar.component.dialog.CalendarScrapCancelDialog +import com.terning.feature.calendar.calendar.component.dialog.CalendarScrapPatchDialog import com.terning.feature.calendar.calendar.component.group.CalendarScrapListGroup import com.terning.feature.calendar.calendar.component.pager.CalendarWeekPager import com.terning.feature.calendar.calendar.model.DayModel import com.terning.feature.calendar.calendar.model.TerningCalendarModel import com.terning.feature.calendar.week.model.CalendarWeekUiState -import com.terning.feature.dialog.cancel.ScrapCancelDialog -import com.terning.feature.dialog.detail.ScrapDialog import okhttp3.internal.toImmutableList -import java.time.LocalDate @Composable fun CalendarWeekRoute( @@ -110,8 +107,8 @@ fun CalendarWeekRoute( }, ) - CalendarWeekScrapPatchDialog( - currentDate = selectedDate.date, + CalendarScrapPatchDialog( + date = selectedDate.date, dialogVisibility = uiState.scrapDetailDialogVisibility, internshipModel = uiState.internshipModel, navigateToAnnouncement = { announcementId -> @@ -124,7 +121,7 @@ fun CalendarWeekRoute( }, ) - CalendarWeekScrapCancelDialog( + CalendarScrapCancelDialog( scrapVisibility = uiState.scrapCancelDialogVisibility, internshipAnnouncementId = uiState.internshipAnnouncementId, onDismissCancelDialog = { isCancelled -> @@ -265,55 +262,6 @@ private fun CalendarWeekSuccess( ) } -@Composable -private fun CalendarWeekScrapCancelDialog( - scrapVisibility: Boolean, - internshipAnnouncementId: Long?, - onDismissCancelDialog: (Boolean) -> Unit, -) { - if (scrapVisibility) { - internshipAnnouncementId?.run { - ScrapCancelDialog( - internshipAnnouncementId = this, - onDismissRequest = onDismissCancelDialog - ) - } - } -} - -@Composable -private fun CalendarWeekScrapPatchDialog( - currentDate: LocalDate, - dialogVisibility: Boolean, - internshipModel: CalendarScrapDetail?, - navigateToAnnouncement: (Long) -> Unit, - onDismissInternDialog: (Boolean) -> Unit, - onClickChangeColor: () -> Unit, -) { - if (dialogVisibility) { - internshipModel?.let { internship -> - val scrapColor = Color( - android.graphics.Color.parseColor( - internship.color - ) - ) - ScrapDialog( - title = internship.title, - scrapColor = scrapColor, - deadline = currentDate.getFullDateStringInKorean(), - startYearMonth = internship.startYearMonth, - workingPeriod = internship.workingPeriod, - internshipAnnouncementId = internship.internshipAnnouncementId, - companyImage = internship.companyImage, - isScrapped = true, - onDismissRequest = onDismissInternDialog, - onClickChangeColor = onClickChangeColor, - onClickNavigateButton = navigateToAnnouncement - ) - } - } -} -