11package com.terning.feature.calendar.calendar
22
3+ import androidx.compose.animation.core.Transition
34import androidx.compose.animation.core.tween
5+ import androidx.compose.animation.core.updateTransition
46import androidx.compose.animation.slideInHorizontally
57import androidx.compose.animation.slideInVertically
68import androidx.compose.animation.slideOutHorizontally
79import androidx.compose.animation.slideOutVertically
810import androidx.compose.animation.togetherWith
9- import androidx.compose.foundation.background
1011import androidx.compose.foundation.layout.Column
1112import androidx.compose.foundation.layout.fillMaxSize
13+ import androidx.compose.foundation.pager.PagerState
1214import androidx.compose.foundation.pager.rememberPagerState
1315import androidx.compose.material3.HorizontalDivider
1416import androidx.compose.runtime.Composable
15- import androidx.compose.runtime.CompositionLocalProvider
1617import androidx.compose.runtime.LaunchedEffect
1718import androidx.compose.runtime.getValue
1819import androidx.compose.runtime.rememberCoroutineScope
1920import androidx.compose.runtime.snapshotFlow
2021import androidx.compose.ui.Modifier
2122import androidx.compose.ui.unit.dp
2223import androidx.hilt.navigation.compose.hiltViewModel
23- import androidx.lifecycle.compose.LocalLifecycleOwner
2424import androidx.lifecycle.compose.collectAsStateWithLifecycle
2525import com.terning.core.analytics.EventType
2626import com.terning.core.analytics.LocalTracker
2727import com.terning.core.designsystem.component.topappbar.CalendarTopAppBar
28+ import com.terning.core.designsystem.extension.getWeekIndexContainingSelectedDate
2829import com.terning.core.designsystem.theme.Grey200
29- import com.terning.core.designsystem.theme.White
3030import com.terning.feature.calendar.calendar.component.ScreenTransition
3131import com.terning.feature.calendar.calendar.component.WeekDaysHeader
32- import com.terning.feature.calendar.calendar.model.CalendarModel.Companion.getLocalDateByPage
33- import com.terning.feature.calendar.calendar.model.CalendarModel.Companion.getYearMonthByPage
3432import com.terning.feature.calendar.calendar.model.CalendarUiState
35- import com.terning.feature.calendar.calendar.model.LocalPagerState
33+ import com.terning.feature.calendar.calendar.model.DayModel
34+ import com.terning.feature.calendar.calendar.model.TerningCalendarModel
3635import com.terning.feature.calendar.list.CalendarListRoute
3736import com.terning.feature.calendar.month.CalendarMonthRoute
3837import com.terning.feature.calendar.week.CalendarWeekRoute
@@ -45,12 +44,10 @@ fun CalendarRoute(
4544 modifier : Modifier = Modifier ,
4645 viewModel : CalendarViewModel = hiltViewModel()
4746) {
48- val lifecycleOwner = LocalLifecycleOwner .current
49- val uiState by viewModel.uiState.collectAsStateWithLifecycle(lifecycleOwner = lifecycleOwner)
47+ val uiState by viewModel.uiState.collectAsStateWithLifecycle()
5048 val amplitudeTracker = LocalTracker .current
5149
5250 CalendarScreen (
53- modifier = modifier,
5451 uiState = uiState,
5552 navigateToAnnouncement = navigateToAnnouncement,
5653 onClickNewDate = viewModel::onSelectNewDate,
@@ -65,23 +62,29 @@ fun CalendarRoute(
6562 )
6663 }
6764 viewModel.updateListVisibility(! uiState.isListEnabled)
68- }
65+ },
66+ modifier = modifier,
6967 )
7068}
7169
7270@Composable
7371private fun CalendarScreen (
7472 uiState : CalendarUiState ,
7573 navigateToAnnouncement : (Long ) -> Unit ,
76- onClickNewDate : (LocalDate ) -> Unit ,
77- updateSelectedDate : (LocalDate ) -> Unit ,
74+ onClickNewDate : (DayModel ) -> Unit ,
75+ updateSelectedDate : (DayModel ) -> Unit ,
7876 disableListVisibility : () -> Unit ,
7977 disableWeekVisibility : () -> Unit ,
8078 onClickListButton : () -> Unit ,
8179 modifier : Modifier = Modifier ,
8280) {
8381 val coroutineScope = rememberCoroutineScope()
8482
83+ val calendarListTransition =
84+ updateTransition(! uiState.isListEnabled, label = " calendarListTransition" )
85+ val monthWeekTransition =
86+ updateTransition(! uiState.isWeekEnabled, label = " monthWeekTransition" )
87+
8588 val pagerState = rememberPagerState(
8689 initialPage = uiState.calendarModel.initialPage,
8790 pageCount = { uiState.calendarModel.pageCount }
@@ -90,95 +93,148 @@ private fun CalendarScreen(
9093 LaunchedEffect (key1 = pagerState, key2 = uiState.selectedDate) {
9194 snapshotFlow { pagerState.currentPage }
9295 .collect { current ->
93- val date = getLocalDateByPage(current)
96+ val date = uiState.calendarModel.getLocalDateByPage(current)
97+ val month = uiState.calendarModel.getMonthModelByPage(current)
9498
9599 val newDate = LocalDate .of(
96100 date.year,
97101 date.month,
98- uiState.selectedDate.dayOfMonth.coerceAtMost(date.month.minLength())
102+ uiState.selectedDate.date. dayOfMonth.coerceAtMost(date.month.minLength())
99103 )
100- updateSelectedDate(newDate)
104+
105+ val currentWeek = newDate.getWeekIndexContainingSelectedDate(month.inDays)
106+ updateSelectedDate(DayModel (newDate, currentWeek))
101107 }
102108 }
103109
104- CompositionLocalProvider (
105- LocalPagerState provides pagerState
110+
111+ Column (
112+ modifier = modifier,
106113 ) {
107- Column (
108- modifier = modifier,
109- ) {
110- CalendarTopAppBar (
111- date = getYearMonthByPage(pagerState.settledPage),
112- isListExpanded = uiState.isListEnabled,
113- onListButtonClicked = onClickListButton,
114- onMonthNavigationButtonClicked = { direction ->
115- coroutineScope.launch {
116- pagerState.animateScrollToPage(
117- page = pagerState.settledPage + direction,
118- animationSpec = tween(500 )
119- )
120- }
114+ CalendarTopAppBar (
115+ date = uiState.calendarModel.getYearMonthByPage(pagerState.settledPage),
116+ isListExpanded = uiState.isListEnabled,
117+ onListButtonClicked = {
118+ if (! calendarListTransition.isRunning)
119+ onClickListButton()
120+ },
121+ onMonthNavigationButtonClicked = { direction ->
122+ coroutineScope.launch {
123+ pagerState.animateScrollToPage(
124+ page = pagerState.settledPage + direction,
125+ animationSpec = tween(500 )
126+ )
121127 }
122- )
123- ScreenTransition (
124- targetState = ! uiState.isListEnabled,
125- transitionOne = slideInHorizontally { fullWidth -> - fullWidth } togetherWith
126- slideOutHorizontally { fullWidth -> fullWidth },
127- transitionTwo = slideInHorizontally { fullWidth -> fullWidth } togetherWith
128- slideOutHorizontally { fullWidth -> - fullWidth },
129- contentOne = {
130- Column (
131- modifier = Modifier
132- .fillMaxSize()
133- ) {
134- WeekDaysHeader ()
135-
136- HorizontalDivider (
137- thickness = 1 .dp,
138- color = Grey200
139- )
140-
141- ScreenTransition (
142- targetState = ! uiState.isWeekEnabled,
143- transitionOne = slideInVertically { fullHeight -> - fullHeight } togetherWith
144- slideOutVertically { fullHeight -> fullHeight },
145- transitionTwo = slideInVertically { fullHeight -> fullHeight } togetherWith
146- slideOutVertically { fullHeight -> - fullHeight },
147- contentOne = {
148- CalendarMonthRoute (
149- selectedDate = uiState.selectedDate,
150- updateSelectedDate = { newDate ->
151- if (! pagerState.isScrollInProgress)
152- onClickNewDate(newDate)
153- },
154- modifier = Modifier
155- .fillMaxSize()
156- .background(White ),
157- )
158- },
159- contentTwo = {
160- CalendarWeekRoute (
161- calendarUiState = uiState,
162- modifier = Modifier
163- .fillMaxSize(),
164- navigateUp = disableWeekVisibility,
165- navigateToAnnouncement = navigateToAnnouncement,
166- updateSelectedDate = onClickNewDate
167- )
168- }
169- )
170- }
171- },
172- contentTwo = {
173- CalendarListRoute (
174- navigateToAnnouncement = navigateToAnnouncement,
175- navigateUp = disableListVisibility,
176- modifier = Modifier
177- .fillMaxSize()
128+ }
129+ )
130+
131+ CalendarListTransition (
132+ transition = calendarListTransition,
133+ calendarModel = uiState.calendarModel,
134+ pagerState = pagerState,
135+ onNavigateToAnnouncement = navigateToAnnouncement,
136+ onNavigateUpToCalendar = disableListVisibility,
137+ calendarContent = {
138+ Column (
139+ modifier = Modifier
140+ .fillMaxSize()
141+ ) {
142+ WeekDaysHeader ()
143+
144+ HorizontalDivider (
145+ thickness = 1 .dp,
146+ color = Grey200
178147 )
148+
149+ MonthWeekTransition (
150+ transition = monthWeekTransition,
151+ selectedDate = uiState.selectedDate,
152+ calendarModel = uiState.calendarModel,
153+ pagerState = pagerState,
154+ onSelectDate = { newDate -> onClickNewDate(newDate) },
155+ onNavigateToAnnouncement = navigateToAnnouncement,
156+ onNavigateUpToMonth = disableWeekVisibility
157+ )
158+ }
159+ }
160+ )
161+ }
162+ }
163+
164+
165+ /* * ๋ฌ๋ ฅ <-> ๋ชฉ๋ก ์ ํ ์ปดํฌ์ ๋ธ */
166+ @Composable
167+ private fun CalendarListTransition (
168+ transition : Transition <Boolean >,
169+ calendarModel : TerningCalendarModel ,
170+ pagerState : PagerState ,
171+ onNavigateToAnnouncement : (Long ) -> Unit ,
172+ onNavigateUpToCalendar : () -> Unit ,
173+ calendarContent : @Composable () -> Unit ,
174+ ) {
175+ ScreenTransition (
176+ transition = transition,
177+ transitionOne = slideInHorizontally { fullWidth -> - fullWidth } togetherWith
178+ slideOutHorizontally { fullWidth -> fullWidth },
179+ transitionTwo = slideInHorizontally { fullWidth -> fullWidth } togetherWith
180+ slideOutHorizontally { fullWidth -> - fullWidth },
181+ contentOne = {
182+ calendarContent()
183+ },
184+ contentTwo = {
185+ CalendarListRoute (
186+ calendarModel = calendarModel,
187+ navigateToAnnouncement = onNavigateToAnnouncement,
188+ navigateUp = onNavigateUpToCalendar,
189+ pagerState = pagerState,
190+ modifier = Modifier
191+ .fillMaxSize()
192+ )
193+ },
194+ )
195+ }
196+
197+ /* *์๊ฐ <-> ์ฃผ๊ฐ ์ ํ ์ปดํฌ์ ๋ธ*/
198+ @Composable
199+ private fun MonthWeekTransition (
200+ transition : Transition <Boolean >,
201+ selectedDate : DayModel ,
202+ calendarModel : TerningCalendarModel ,
203+ pagerState : PagerState ,
204+ onSelectDate : (DayModel ) -> Unit ,
205+ onNavigateToAnnouncement : (Long ) -> Unit ,
206+ onNavigateUpToMonth : () -> Unit ,
207+ ) {
208+ ScreenTransition (
209+ transition = transition,
210+ transitionOne = slideInVertically { fullHeight -> - fullHeight } togetherWith
211+ slideOutVertically { fullHeight -> fullHeight },
212+ transitionTwo = slideInVertically { fullHeight -> fullHeight } togetherWith
213+ slideOutVertically { fullHeight -> - fullHeight },
214+ contentOne = {
215+ CalendarMonthRoute (
216+ selectedDate = selectedDate,
217+ updateSelectedDate = { newDate ->
218+ if (! pagerState.isScrollInProgress)
219+ onSelectDate(newDate)
179220 },
221+ pagerState = pagerState,
222+ calendarModel = calendarModel
223+ )
224+ },
225+ contentTwo = {
226+ CalendarWeekRoute (
227+ modifier = Modifier
228+ .fillMaxSize(),
229+ navigateUp = onNavigateUpToMonth,
230+ navigateToAnnouncement = onNavigateToAnnouncement,
231+ updateSelectedDate = onSelectDate,
232+ selectedDate = selectedDate,
233+ calendarModel = calendarModel,
234+ pagerState = pagerState,
180235 )
181236 }
182- }
237+ )
183238}
184239
240+
0 commit comments