Skip to content

Commit

Permalink
[REFACTOR/#305] CalendarRoute 리팩토링
Browse files Browse the repository at this point in the history
  • Loading branch information
boiledEgg-s committed Dec 11, 2024
1 parent fb39552 commit 64a1152
Show file tree
Hide file tree
Showing 6 changed files with 151 additions and 119 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.terning.feature.calendar.calendar

import androidx.activity.compose.BackHandler
import androidx.compose.animation.core.tween
import androidx.compose.animation.slideInHorizontally
import androidx.compose.animation.slideInVertically
Expand All @@ -9,10 +8,10 @@ import androidx.compose.animation.slideOutVertically
import androidx.compose.animation.togetherWith
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.pager.PagerState
import androidx.compose.foundation.pager.rememberPagerState
import androidx.compose.material3.HorizontalDivider
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.rememberCoroutineScope
Expand All @@ -28,10 +27,9 @@ import com.terning.core.designsystem.extension.getWeekIndexContainingSelectedDat
import com.terning.core.designsystem.theme.Grey200
import com.terning.feature.calendar.calendar.component.ScreenTransition
import com.terning.feature.calendar.calendar.component.WeekDaysHeader
import com.terning.feature.calendar.calendar.model.DayModel
import com.terning.feature.calendar.calendar.model.TerningCalendarModel.Companion.LocalCalendarModel
import com.terning.feature.calendar.calendar.model.CalendarUiState
import com.terning.feature.calendar.calendar.model.LocalPagerState
import com.terning.feature.calendar.calendar.model.DayModel
import com.terning.feature.calendar.calendar.model.TerningCalendarModel
import com.terning.feature.calendar.list.CalendarListRoute
import com.terning.feature.calendar.month.CalendarMonthRoute
import com.terning.feature.calendar.week.CalendarWeekRoute
Expand All @@ -48,7 +46,6 @@ fun CalendarRoute(
val amplitudeTracker = LocalTracker.current

CalendarScreen(
modifier = modifier,
uiState = uiState,
navigateToAnnouncement = navigateToAnnouncement,
onClickNewDate = viewModel::onSelectNewDate,
Expand All @@ -63,7 +60,8 @@ fun CalendarRoute(
)
}
viewModel.updateListVisibility(!uiState.isListEnabled)
}
},
modifier = modifier,
)
}

Expand All @@ -85,17 +83,12 @@ private fun CalendarScreen(
pageCount = { uiState.calendarModel.pageCount }
)

BackHandler(enabled = uiState.isWeekEnabled) {
disableWeekVisibility()
}

LaunchedEffect(key1 = pagerState, key2 = uiState.selectedDate) {
snapshotFlow { pagerState.currentPage }
.collect { current ->
val date = uiState.calendarModel.getLocalDateByPage(current)
val month = uiState.calendarModel.getMonthModelByPage(current)


val newDate = LocalDate.of(
date.year,
date.month,
Expand All @@ -107,83 +100,131 @@ private fun CalendarScreen(
}
}

CompositionLocalProvider(
LocalPagerState provides pagerState,
LocalCalendarModel provides uiState.calendarModel

Column(
modifier = modifier,
) {
Column(
modifier = modifier,
) {
CalendarTopAppBar(
date = uiState.calendarModel.getYearMonthByPage(pagerState.settledPage),
isListExpanded = uiState.isListEnabled,
onListButtonClicked = onClickListButton,
onMonthNavigationButtonClicked = { direction ->
coroutineScope.launch {
pagerState.animateScrollToPage(
page = pagerState.settledPage + direction,
animationSpec = tween(500)
)
}
CalendarTopAppBar(
date = uiState.calendarModel.getYearMonthByPage(pagerState.settledPage),
isListExpanded = uiState.isListEnabled,
onListButtonClicked = onClickListButton,
onMonthNavigationButtonClicked = { direction ->
coroutineScope.launch {
pagerState.animateScrollToPage(
page = pagerState.settledPage + direction,
animationSpec = tween(500)
)
}
)
ScreenTransition(
targetState = !uiState.isListEnabled,
transitionOne = slideInHorizontally { fullWidth -> -fullWidth } togetherWith
slideOutHorizontally { fullWidth -> fullWidth },
transitionTwo = slideInHorizontally { fullWidth -> fullWidth } togetherWith
slideOutHorizontally { fullWidth -> -fullWidth },
contentOne = {
Column(
modifier = Modifier
.fillMaxSize()
) {
WeekDaysHeader()

HorizontalDivider(
thickness = 1.dp,
color = Grey200
)

ScreenTransition(
targetState = !uiState.isWeekEnabled,
transitionOne = slideInVertically { fullHeight -> -fullHeight } togetherWith
slideOutVertically { fullHeight -> fullHeight },
transitionTwo = slideInVertically { fullHeight -> fullHeight } togetherWith
slideOutVertically { fullHeight -> -fullHeight },
contentOne = {
CalendarMonthRoute(
selectedDate = uiState.selectedDate,
updateSelectedDate = { newDate ->
if (!pagerState.isScrollInProgress)
onClickNewDate(newDate)
}
)
},
contentTwo = {
CalendarWeekRoute(
calendarUiState = uiState,
modifier = Modifier
.fillMaxSize(),
navigateUp = disableWeekVisibility,
navigateToAnnouncement = navigateToAnnouncement,
updateSelectedDate = onClickNewDate

)
}
)
}
},
contentTwo = {
CalendarListRoute(
navigateToAnnouncement = navigateToAnnouncement,
navigateUp = disableListVisibility,
modifier = Modifier
.fillMaxSize()
}
)

CalendarListTransition(
isCalendarEnabled = !uiState.isListEnabled,
calendarModel = uiState.calendarModel,
pagerState = pagerState,
onNavigateToAnnouncement = navigateToAnnouncement,
onNavigateUpToCalendar = disableListVisibility,
calendarContent = {
Column(
modifier = Modifier
.fillMaxSize()
) {
WeekDaysHeader()

HorizontalDivider(
thickness = 1.dp,
color = Grey200
)

MonthWeekTransition(
isMonthEnabled = !uiState.isWeekEnabled,
selectedDate = uiState.selectedDate,
calendarModel = uiState.calendarModel,
pagerState = pagerState,
onSelectDate = { newDate -> onClickNewDate(newDate) },
onNavigateToAnnouncement = navigateToAnnouncement,
onNavigateUpToMonth = disableWeekVisibility
)
}
}
)
}
}


/** 달력 <-> 목록 전환 컴포저블 */
@Composable
private fun CalendarListTransition(
isCalendarEnabled: Boolean,
calendarModel: TerningCalendarModel,
pagerState: PagerState,
onNavigateToAnnouncement: (Long) -> Unit,
onNavigateUpToCalendar: () -> Unit,
calendarContent: @Composable () -> Unit,
) {
ScreenTransition(
targetState = isCalendarEnabled,
transitionOne = slideInHorizontally { fullWidth -> -fullWidth } togetherWith
slideOutHorizontally { fullWidth -> fullWidth },
transitionTwo = slideInHorizontally { fullWidth -> fullWidth } togetherWith
slideOutHorizontally { fullWidth -> -fullWidth },
contentOne = {
calendarContent()
},
contentTwo = {
CalendarListRoute(
calendarModel = calendarModel,
navigateToAnnouncement = onNavigateToAnnouncement,
navigateUp = onNavigateUpToCalendar,
pagerState = pagerState,
modifier = Modifier
.fillMaxSize()
)
},
)
}

/**월간 <-> 주간 전환 컴포저블*/
@Composable
private fun MonthWeekTransition(
isMonthEnabled: Boolean,
selectedDate: DayModel,
calendarModel: TerningCalendarModel,
pagerState: PagerState,
onSelectDate: (DayModel) -> Unit,
onNavigateToAnnouncement: (Long) -> Unit,
onNavigateUpToMonth: () -> Unit,
) {
ScreenTransition(
targetState = isMonthEnabled,
transitionOne = slideInVertically { fullHeight -> -fullHeight } togetherWith
slideOutVertically { fullHeight -> fullHeight },
transitionTwo = slideInVertically { fullHeight -> fullHeight } togetherWith
slideOutVertically { fullHeight -> -fullHeight },
contentOne = {
CalendarMonthRoute(
selectedDate = selectedDate,
updateSelectedDate = { newDate ->
if (!pagerState.isScrollInProgress)
onSelectDate(newDate)
},
pagerState = pagerState,
calendarModel = calendarModel
)
},
contentTwo = {
CalendarWeekRoute(
modifier = Modifier
.fillMaxSize(),
navigateUp = onNavigateUpToMonth,
navigateToAnnouncement = onNavigateToAnnouncement,
updateSelectedDate = onSelectDate,
selectedDate = selectedDate,
calendarModel = calendarModel,
pagerState = pagerState,
)
}
}
)
}


Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,4 @@ data class CalendarUiState(
val calendarModel: TerningCalendarModel = TerningCalendarModel(),
val isListEnabled: Boolean = false,
val isWeekEnabled: Boolean = false,
)

val LocalPagerState = compositionLocalOf<PagerState> {
error("No PagerState provided")
}
)
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,5 @@ class TerningCalendarModel (
companion object {
private const val DEFAULT_START_YEAR = 2020
private const val DEFAULT_END_YEAR = 2030

val LocalCalendarModel = staticCompositionLocalOf<TerningCalendarModel> {
error("No CalendarModel provided")
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,19 +28,18 @@ import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.LocalLifecycleOwner
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.flowWithLifecycle
import com.terning.core.designsystem.state.UiState
import com.terning.core.designsystem.extension.getFullDateStringInKorean
import com.terning.core.designsystem.extension.isListNotEmpty
import com.terning.core.designsystem.extension.toast
import com.terning.core.designsystem.state.UiState
import com.terning.core.designsystem.theme.Back
import com.terning.core.designsystem.theme.Black
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.model.TerningCalendarModel.Companion.LocalCalendarModel
import com.terning.feature.calendar.calendar.model.LocalPagerState
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
Expand All @@ -50,12 +49,12 @@ import java.time.LocalDate
@Composable
fun CalendarListRoute(
modifier: Modifier = Modifier,
calendarModel: TerningCalendarModel,
pagerState: PagerState,
navigateUp: () -> Unit,
navigateToAnnouncement: (Long) -> Unit,
viewModel: CalendarListViewModel = hiltViewModel(),
) {
val pagerState = LocalPagerState.current
val calendarModel = LocalCalendarModel.current
val lifecycleOwner = LocalLifecycleOwner.current
val uiState by viewModel.uiState.collectAsStateWithLifecycle(lifecycleOwner)
val context = LocalContext.current
Expand Down Expand Up @@ -85,6 +84,7 @@ fun CalendarListRoute(
CalendarListScreen(
pagerState = pagerState,
uiState = uiState,
calendarModel = calendarModel,
modifier = modifier,
onClickScrapButton = { scrapId ->
with(viewModel) {
Expand Down Expand Up @@ -129,12 +129,12 @@ fun CalendarListRoute(
@Composable
private fun CalendarListScreen(
pagerState: PagerState,
calendarModel: TerningCalendarModel,
uiState: CalendarListUiState,
onClickInternship: (CalendarScrapDetail) -> Unit,
onClickScrapButton: (Long) -> Unit,
modifier: Modifier = Modifier,
) {
val calendarModel = LocalCalendarModel.current

HorizontalPager(
state = pagerState,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.terning.feature.calendar.month

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.pager.PagerState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
Expand All @@ -16,23 +17,22 @@ import com.terning.core.designsystem.extension.toast
import com.terning.core.designsystem.state.UiState
import com.terning.core.designsystem.theme.White
import com.terning.domain.calendar.entity.CalendarScrap
import com.terning.feature.calendar.calendar.model.DayModel
import com.terning.feature.calendar.calendar.model.LocalPagerState
import com.terning.feature.calendar.calendar.model.TerningCalendarModel.Companion.LocalCalendarModel
import com.terning.feature.calendar.calendar.component.pager.CalendarMonthPager
import com.terning.feature.calendar.calendar.model.DayModel
import com.terning.feature.calendar.calendar.model.TerningCalendarModel

@Composable
fun CalendarMonthRoute(
selectedDate: DayModel,
calendarModel: TerningCalendarModel,
pagerState: PagerState,
updateSelectedDate: (DayModel) -> Unit,
modifier: Modifier = Modifier,
viewModel: CalendarMonthViewModel = hiltViewModel()
) {
val calendarModel = LocalCalendarModel.current
val pagerState = LocalPagerState.current
val context = LocalContext.current
val lifecycleOwner = LocalLifecycleOwner.current
val uiState by viewModel.uiState.collectAsStateWithLifecycle(lifecycleOwner)
val uiState by viewModel.uiState.collectAsStateWithLifecycle()

LaunchedEffect(viewModel.sideEffect, lifecycleOwner) {
viewModel.sideEffect.flowWithLifecycle(lifecycle = lifecycleOwner.lifecycle)
Expand Down
Loading

0 comments on commit 64a1152

Please sign in to comment.