@@ -4,36 +4,44 @@ import androidx.compose.foundation.background
44import androidx.compose.foundation.layout.Arrangement
55import androidx.compose.foundation.layout.Box
66import androidx.compose.foundation.layout.Column
7+ import androidx.compose.foundation.layout.PaddingValues
78import androidx.compose.foundation.layout.Row
8- import androidx.compose.foundation.layout.Spacer
99import androidx.compose.foundation.layout.fillMaxSize
1010import androidx.compose.foundation.layout.fillMaxWidth
1111import androidx.compose.foundation.layout.height
1212import androidx.compose.foundation.layout.padding
13+ import androidx.compose.foundation.layout.statusBarsPadding
1314import androidx.compose.foundation.lazy.LazyColumn
1415import androidx.compose.foundation.lazy.items
16+ import androidx.compose.foundation.rememberScrollState
1517import androidx.compose.foundation.shape.RoundedCornerShape
18+ import androidx.compose.foundation.verticalScroll
1619import androidx.compose.material3.Text
1720import androidx.compose.runtime.Composable
1821import androidx.compose.runtime.getValue
1922import androidx.compose.ui.Alignment
2023import androidx.compose.ui.Modifier
24+ import androidx.compose.ui.draw.clip
25+ import androidx.compose.ui.graphics.graphicsLayer
2126import androidx.compose.ui.input.nestedscroll.nestedScroll
2227import androidx.compose.ui.tooling.preview.Preview
2328import androidx.compose.ui.unit.dp
2429import androidx.hilt.navigation.compose.hiltViewModel
2530import com.threegap.bitnagil.designsystem.BitnagilTheme
2631import com.threegap.bitnagil.designsystem.modifier.clickableWithoutRipple
27- import com.threegap.bitnagil.presentation.home.component.template.CollapsibleHomeHeader
32+ import com.threegap.bitnagil.presentation.home.component.template.CollapsibleHeader
2833import com.threegap.bitnagil.presentation.home.component.template.EmptyRoutineView
2934import com.threegap.bitnagil.presentation.home.component.template.RoutineSection
35+ import com.threegap.bitnagil.presentation.home.component.template.StickyHeader
3036import com.threegap.bitnagil.presentation.home.component.template.WeeklyDatePicker
3137import com.threegap.bitnagil.presentation.home.contract.HomeSideEffect
3238import com.threegap.bitnagil.presentation.home.contract.HomeState
33- import com.threegap.bitnagil.presentation.home.util.rememberCollapsibleHeaderState
39+ import com.threegap.bitnagil.presentation.home.model.DailyEmotionUiModel
40+ import com.threegap.bitnagil.presentation.home.model.rememberCollapsibleHeaderState
3441import org.orbitmvi.orbit.compose.collectAsState
3542import org.orbitmvi.orbit.compose.collectSideEffect
3643import java.time.LocalDate
44+ import kotlin.math.pow
3745
3846@Composable
3947fun HomeScreenContainer (
@@ -71,6 +79,7 @@ fun HomeScreenContainer(
7179@Composable
7280private fun HomeScreen (
7381 uiState : HomeState ,
82+ modifier : Modifier = Modifier ,
7483 onDateSelect : (LocalDate ) -> Unit ,
7584 onPreviousWeekClick : () -> Unit ,
7685 onNextWeekClick : () -> Unit ,
@@ -80,48 +89,63 @@ private fun HomeScreen(
8089 onRegisterRoutineClick : () -> Unit ,
8190 onRegisterEmotionClick : () -> Unit ,
8291 onShowMoreRoutinesClick : () -> Unit ,
83- modifier : Modifier = Modifier ,
8492) {
8593 val collapsibleHeaderState = rememberCollapsibleHeaderState()
8694
8795 Box (
8896 modifier = modifier
8997 .fillMaxSize()
90- .background(BitnagilTheme .colors.coolGray10),
98+ .background(BitnagilTheme .colors.coolGray10)
99+ .statusBarsPadding()
100+ .nestedScroll(collapsibleHeaderState.nestedScrollConnection),
91101 ) {
92- Column {
93- Spacer (modifier = Modifier .height(collapsibleHeaderState.currentHeaderHeight))
102+ StickyHeader (
103+ modifier = Modifier
104+ .padding(top = 14 .dp)
105+ .height(collapsibleHeaderState.stickyHeaderHeightDp),
106+ onHelpClick = onHelpClick,
107+ )
108+
109+ CollapsibleHeader (
110+ modifier = Modifier
111+ .fillMaxWidth()
112+ .padding(top = 80 .dp, start = 18 .dp, end = 18 .dp)
113+ .height(collapsibleHeaderState.expandedHeaderHeightDp)
114+ .graphicsLayer { alpha = collapsibleHeaderState.expansionProgress.pow(3 ) },
115+ welcomeMessage = " ${uiState.userNickname}${uiState.dailyEmotion.homeMessage} " ,
116+ dailyEmotion = uiState.dailyEmotion,
117+ onRegisterEmotionClick = onRegisterEmotionClick,
118+ )
94119
120+ Column (
121+ modifier = Modifier
122+ .fillMaxSize()
123+ .padding(top = collapsibleHeaderState.collapsedContentOffsetDp)
124+ .graphicsLayer { translationY = collapsibleHeaderState.currentHeightPx }
125+ .clip(RoundedCornerShape (topStart = 20 .dp, topEnd = 20 .dp))
126+ .background(color = BitnagilTheme .colors.coolGray99),
127+ ) {
95128 WeeklyDatePicker (
96129 selectedDate = uiState.selectedDate,
97130 weeklyDates = uiState.currentWeeks,
98131 routines = uiState.routineSchedule,
99132 onDateSelect = onDateSelect,
100133 onPreviousWeekClick = onPreviousWeekClick,
101134 onNextWeekClick = onNextWeekClick,
102- modifier = Modifier
103- .background(
104- color = BitnagilTheme .colors.coolGray99,
105- shape = RoundedCornerShape (
106- topStart = 20 .dp,
107- topEnd = 20 .dp,
108- ),
109- ),
110135 )
111136
112137 if (uiState.selectedDateRoutines.isEmpty()) {
113138 EmptyRoutineView (
114- onRegisterRoutineClick = onRegisterRoutineClick,
115139 modifier = Modifier
116140 .fillMaxSize()
117- .background(BitnagilTheme .colors.coolGray99)
118- .padding(top = 62 .dp),
141+ .padding(top = 62 .dp)
142+ .verticalScroll(rememberScrollState()),
143+ onRegisterRoutineClick = onRegisterRoutineClick,
119144 )
120145 } else {
121146 Row (
122147 modifier = Modifier
123148 .fillMaxWidth()
124- .background(BitnagilTheme .colors.coolGray99)
125149 .padding(start = 16 .dp, end = 4 .dp),
126150 horizontalArrangement = Arrangement .SpaceBetween ,
127151 verticalAlignment = Alignment .Top ,
@@ -145,15 +169,13 @@ private fun HomeScreen(
145169 LazyColumn (
146170 modifier = Modifier
147171 .fillMaxSize()
148- .background(BitnagilTheme .colors.coolGray99)
149- .nestedScroll(collapsibleHeaderState.nestedScrollConnection)
150172 .padding(horizontal = 16 .dp),
151- state = collapsibleHeaderState.lazyListState,
152173 verticalArrangement = Arrangement .spacedBy(12 .dp),
174+ contentPadding = PaddingValues (bottom = 48 .dp),
153175 ) {
154176 items(
155177 items = uiState.selectedDateRoutines,
156- key = { routine -> " ${ routine.id} _ ${uiState.selectedDate} " },
178+ key = { routine -> routine.id },
157179 ) { routine ->
158180 RoutineSection (
159181 routine = routine,
@@ -166,22 +188,19 @@ private fun HomeScreen(
166188 }
167189 }
168190 }
169-
170- CollapsibleHomeHeader (
171- userName = uiState.userNickname,
172- dailyEmotion = uiState.dailyEmotion,
173- collapsibleHeaderState = collapsibleHeaderState,
174- onHelpClick = onHelpClick,
175- onRegisterEmotion = onRegisterEmotionClick,
176- )
177191 }
178192}
179193
180194@Preview
181195@Composable
182196private fun HomeScreenPreview () {
183197 HomeScreen (
184- uiState = HomeState .INIT ,
198+ uiState = HomeState .INIT .copy(
199+ userNickname = " 홍길동" ,
200+ dailyEmotion = DailyEmotionUiModel .INIT .copy(
201+ homeMessage = " 님, 오셨군요!\n 오늘 기분은 어떤가요?" ,
202+ ),
203+ ),
185204 onDateSelect = {},
186205 onPreviousWeekClick = {},
187206 onNextWeekClick = {},
0 commit comments