Skip to content

Commit 19a26ed

Browse files
authored
Merge branch 'develop' into ui/#23-onboarding-timeofbirth-and-name
2 parents 09bc9c9 + ff035a0 commit 19a26ed

File tree

5 files changed

+117
-18
lines changed

5 files changed

+117
-18
lines changed

โ€Žcore/ui/src/main/java/com/yapp/ui/component/timepicker/OrbitPickerItem.ktโ€Ž

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import androidx.compose.ui.tooling.preview.Preview
2525
import androidx.compose.ui.unit.Dp
2626
import androidx.compose.ui.unit.dp
2727
import com.yapp.designsystem.theme.OrbitTheme
28+
import com.yapp.ui.utils.toPx
2829
import kotlinx.coroutines.flow.distinctUntilChanged
2930
import kotlinx.coroutines.flow.map
3031
import kotlin.math.abs
@@ -51,19 +52,28 @@ fun OrbitPickerItem(
5152
visibleItemsMiddle,
5253
startIndex,
5354
)
54-
55-
fun getItem(index: Int) = items.getOrNull(index % items.size) ?: ""
56-
5755
val listState = rememberLazyListState(initialFirstVisibleItemIndex = listStartIndex)
5856
val flingBehavior = rememberSnapFlingBehavior(lazyListState = listState)
5957
val itemHeightPixels = remember { mutableIntStateOf(0) }
6058
val itemHeightDp = with(LocalDensity.current) { itemHeightPixels.intValue.toDp() }
6159

6260
LaunchedEffect(listState) {
63-
snapshotFlow { listState.firstVisibleItemIndex }
64-
.map { index -> getItem(index + visibleItemsMiddle) }
61+
snapshotFlow { listState.layoutInfo }
62+
.map { layoutInfo ->
63+
val centerOffset = layoutInfo.viewportStartOffset + (layoutInfo.viewportEndOffset - layoutInfo.viewportStartOffset) / 2
64+
65+
layoutInfo.visibleItemsInfo.minByOrNull { item ->
66+
val itemCenter = item.offset + (item.size / 2)
67+
abs(itemCenter - centerOffset)
68+
}?.index
69+
}
6570
.distinctUntilChanged()
66-
.collect { item -> state.selectedItem = item }
71+
.collect { centerIndex ->
72+
if (centerIndex != null) {
73+
val adjustedIndex = centerIndex % items.size
74+
state.selectedItem = items[adjustedIndex]
75+
}
76+
}
6777
}
6878

6979
val totalItemHeight = itemHeightDp + itemSpacing
@@ -79,17 +89,24 @@ fun OrbitPickerItem(
7989
.pointerInput(Unit) { detectVerticalDragGestures { change, _ -> change.consume() } },
8090
) {
8191
items(listScrollCount) { index ->
82-
val centerIndex = listState.firstVisibleItemIndex + visibleItemsMiddle
83-
val distanceFromCenter = abs(index - centerIndex)
84-
val maxDistance = visibleItemsMiddle.toFloat()
92+
val layoutInfo = listState.layoutInfo
93+
val viewportCenterOffset = layoutInfo.viewportStartOffset +
94+
(layoutInfo.viewportEndOffset - layoutInfo.viewportStartOffset) / 2
95+
96+
val itemInfo = layoutInfo.visibleItemsInfo.find { it.index == index }
97+
val itemCenterOffset = itemInfo?.offset?.let { it + (itemInfo.size / 2) } ?: 0
98+
99+
val distanceFromCenter = abs(viewportCenterOffset - itemCenterOffset)
100+
val maxDistance = totalItemHeight.toPx() * visibleItemsMiddle
85101
val alpha = ((maxDistance - distanceFromCenter) / maxDistance).coerceIn(0.2f, 1f)
86102
val scaleY = 1f - (0.4f * (distanceFromCenter / maxDistance)).coerceIn(0f, 0.4f)
103+
val isSelected = getItemForIndex(index, items, infiniteScroll, visibleItemsMiddle) == state.selectedItem
87104

88105
Text(
89106
text = getItemForIndex(index, items, infiniteScroll, visibleItemsMiddle),
90107
maxLines = 1,
91108
style = textStyle,
92-
color = OrbitTheme.colors.white.copy(alpha = alpha),
109+
color = if (isSelected) OrbitTheme.colors.white else OrbitTheme.colors.white.copy(alpha = alpha),
93110
modifier = Modifier
94111
.padding(vertical = itemSpacing / 2)
95112
.graphicsLayer(scaleY = scaleY)

โ€Žcore/ui/src/main/java/com/yapp/ui/component/timepicker/OrbitYearMonthPicker.ktโ€Ž

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import androidx.compose.foundation.layout.Row
88
import androidx.compose.foundation.layout.fillMaxWidth
99
import androidx.compose.foundation.layout.height
1010
import androidx.compose.foundation.layout.padding
11+
import androidx.compose.foundation.layout.width
1112
import androidx.compose.foundation.layout.wrapContentHeight
1213
import androidx.compose.foundation.layout.wrapContentSize
1314
import androidx.compose.foundation.shape.RoundedCornerShape
@@ -16,6 +17,7 @@ import androidx.compose.runtime.Composable
1617
import androidx.compose.runtime.remember
1718
import androidx.compose.ui.Alignment
1819
import androidx.compose.ui.Modifier
20+
import androidx.compose.ui.platform.LocalConfiguration
1921
import androidx.compose.ui.tooling.preview.Preview
2022
import androidx.compose.ui.unit.Dp
2123
import androidx.compose.ui.unit.dp
@@ -27,6 +29,8 @@ fun OrbitYearMonthPicker(
2729
modifier: Modifier = Modifier,
2830
itemSpacing: Dp = 12.dp,
2931
) {
32+
val screenWidth = LocalConfiguration.current.screenWidthDp.dp
33+
3034
Surface(
3135
modifier = modifier
3236
.fillMaxWidth()
@@ -54,26 +58,27 @@ fun OrbitYearMonthPicker(
5458
Box(
5559
modifier = Modifier.fillMaxWidth(),
5660
) {
61+
val totalItemHeight = screenWidth * 0.15f
5762
Box(
5863
modifier = Modifier
5964
.fillMaxWidth()
6065
.align(Alignment.Center)
61-
.padding(horizontal = 20.dp)
62-
.height(50.dp)
66+
.padding(horizontal = screenWidth * 0.05f)
67+
.height(totalItemHeight)
6368
.background(OrbitTheme.colors.gray_700, shape = RoundedCornerShape(12.dp)),
6469
)
6570
Row(
6671
modifier = Modifier
6772
.fillMaxWidth()
68-
.padding(horizontal = 50.dp),
73+
.padding(horizontal = screenWidth * 0.1f),
6974
verticalAlignment = Alignment.CenterVertically,
7075
) {
7176
OrbitPickerItem(
7277
state = lunarPickerState,
7378
items = lunarItems,
7479
visibleItemsCount = 3,
7580
infiniteScroll = false,
76-
modifier = Modifier.weight(1f),
81+
modifier = Modifier.width(screenWidth * 0.2f),
7782
textModifier = Modifier.padding(8.dp),
7883
textStyle = OrbitTheme.typography.title2SemiBold,
7984
itemSpacing = itemSpacing,
@@ -84,7 +89,7 @@ fun OrbitYearMonthPicker(
8489
visibleItemsCount = 5,
8590
infiniteScroll = true,
8691
startIndex = 90,
87-
modifier = Modifier.weight(1.5f),
92+
modifier = Modifier.width(screenWidth * 0.25f),
8893
textModifier = Modifier.padding(8.dp),
8994
textStyle = OrbitTheme.typography.title2SemiBold,
9095
itemSpacing = itemSpacing,
@@ -94,7 +99,7 @@ fun OrbitYearMonthPicker(
9499
items = monthItems,
95100
visibleItemsCount = 5,
96101
infiniteScroll = true,
97-
modifier = Modifier.weight(1f),
102+
modifier = Modifier.width(screenWidth * 0.16f),
98103
textModifier = Modifier.padding(8.dp),
99104
textStyle = OrbitTheme.typography.title2SemiBold,
100105
itemSpacing = itemSpacing,
@@ -104,7 +109,7 @@ fun OrbitYearMonthPicker(
104109
items = dayItems,
105110
visibleItemsCount = 5,
106111
infiniteScroll = true,
107-
modifier = Modifier.weight(1f),
112+
modifier = Modifier.width(screenWidth * 0.16f),
108113
textModifier = Modifier.padding(8.dp),
109114
textStyle = OrbitTheme.typography.title2SemiBold,
110115
itemSpacing = itemSpacing,
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package com.yapp.ui.utils
2+
3+
import androidx.compose.runtime.Composable
4+
import androidx.compose.ui.platform.LocalDensity
5+
import androidx.compose.ui.unit.Dp
6+
7+
@Composable
8+
fun Dp.toPx(): Float {
9+
return with(LocalDensity.current) { this@toPx.toPx() }
10+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package com.kms.onboarding
2+
3+
import androidx.compose.foundation.layout.Column
4+
import androidx.compose.foundation.layout.Spacer
5+
import androidx.compose.foundation.layout.fillMaxSize
6+
import androidx.compose.foundation.layout.fillMaxWidth
7+
import androidx.compose.foundation.layout.padding
8+
import androidx.compose.material3.Text
9+
import androidx.compose.runtime.Composable
10+
import androidx.compose.ui.Modifier
11+
import androidx.compose.ui.res.stringResource
12+
import androidx.compose.ui.text.style.TextAlign
13+
import androidx.compose.ui.tooling.preview.Preview
14+
import androidx.compose.ui.unit.dp
15+
import com.yapp.designsystem.theme.OrbitTheme
16+
import com.yapp.ui.component.timepicker.OrbitYearMonthPicker
17+
import com.yapp.ui.utils.heightForScreenPercentage
18+
import feature.onboarding.R
19+
20+
@Composable
21+
fun OnboardingBirthdayScreen(
22+
state: OnboardingContract.State,
23+
currentStep: Int,
24+
totalSteps: Int,
25+
onNextClick: () -> Unit,
26+
onBackClick: () -> Unit,
27+
) {
28+
OnboardingScreen(
29+
currentStep = currentStep,
30+
totalSteps = totalSteps,
31+
isButtonEnabled = true,
32+
onNextClick = onNextClick,
33+
onBackClick = onBackClick,
34+
) {
35+
Column(modifier = Modifier.fillMaxSize()) {
36+
Spacer(modifier = Modifier.heightForScreenPercentage(0.05f))
37+
Text(
38+
text = stringResource(id = R.string.onboarding_step3_text_title),
39+
style = OrbitTheme.typography.heading1SemiBold,
40+
color = OrbitTheme.colors.white,
41+
modifier = Modifier.fillMaxWidth(),
42+
textAlign = TextAlign.Center,
43+
)
44+
OrbitYearMonthPicker(
45+
modifier = Modifier.padding(top = 60.dp),
46+
)
47+
}
48+
}
49+
}
50+
51+
@Composable
52+
@Preview
53+
fun OnboardingBirthdayScreenPreview() {
54+
OrbitTheme {
55+
OnboardingBirthdayScreen(
56+
state = OnboardingContract.State(),
57+
currentStep = 3,
58+
totalSteps = 3,
59+
onNextClick = {},
60+
onBackClick = {},
61+
)
62+
}
63+
}

โ€Žfeature/onboarding/src/main/java/com/kms/onboarding/navigation/OnboardingNavGraph.ktโ€Ž

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ import com.kms.onboarding.OnboardingContract
88
import com.kms.onboarding.OnboardingExplainScreen
99
import com.kms.onboarding.OnboardingNameScreen
1010
import com.kms.onboarding.OnboardingTimeOfBirthScreen
11+
import com.kms.onboarding.OnboardingAlarmTimeSelectionScreen
12+
import com.kms.onboarding.OnboardingBirthdayScreen
13+
import com.kms.onboarding.OnboardingContract
14+
import com.kms.onboarding.OnboardingExplainScreen
1115

1216
fun NavGraphBuilder.onboardingNavGraph(
1317
stateProvider: () -> OnboardingContract.State,
@@ -38,7 +42,7 @@ fun NavGraphBuilder.onboardingNavGraph(
3842
}
3943

4044
composable(OnboardingDestination.Birthday.route) {
41-
BirthdayScreen(
45+
OnboardingBirthdayScreen(
4246
state = stateProvider(),
4347
currentStep = 2,
4448
totalSteps = 4,

0 commit comments

Comments
ย (0)