Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[UI/#218] 온보딩 / UI 수정 #219

Merged
merged 21 commits into from
Sep 7, 2024
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,11 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import com.terning.core.R
import com.terning.core.designsystem.theme.Grey400
import com.terning.core.designsystem.theme.Grey150
import com.terning.core.designsystem.theme.Grey200
import com.terning.core.designsystem.theme.Grey375
import com.terning.core.designsystem.theme.TerningMain
import com.terning.core.designsystem.theme.TerningPointTheme
import com.terning.core.designsystem.theme.TerningSub1
import com.terning.core.designsystem.theme.TerningSub3
import com.terning.core.designsystem.theme.TerningSub4
import com.terning.core.designsystem.theme.TerningSub5
import com.terning.core.designsystem.theme.TerningTheme
import com.terning.core.designsystem.theme.White
import com.terning.core.util.NoRippleTheme
Expand Down Expand Up @@ -58,19 +56,16 @@ fun FilteringButton(
) {
val interactionSource = remember { MutableInteractionSource() }
val isPressed by interactionSource.collectIsPressedAsState()
val backgroundColor = when {
!isSelected && !isPressed -> White
!isSelected && isPressed -> TerningSub5
isSelected && !isPressed -> TerningSub4
else -> TerningSub3
}
val backgroundColor = White
val textColor = when {
!isSelected -> Grey400
!isSelected -> Grey375
isPressed -> Grey375
else -> TerningMain
}
val borderColor = when {
!isSelected -> TerningMain
else -> TerningSub1
!isSelected && !isPressed -> Grey150
isPressed -> Grey200
else -> TerningMain
}

CompositionLocalProvider(LocalRippleTheme provides NoRippleTheme) {
Expand All @@ -87,7 +82,7 @@ fun FilteringButton(
color = borderColor
),
shape = RoundedCornerShape(cornerRadius),
onClick = { onButtonClick() }
onClick = onButtonClick
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

편-안

) {
Text(
text = stringResource(id = text),
Expand All @@ -104,14 +99,14 @@ fun FilteringButtonPreview() {
TerningPointTheme {
Column {
FilteringButton(
isSelected = true,
isSelected = false,
text = R.string.button_preview,
cornerRadius = 15.dp,
paddingVertical = 10.dp,
onButtonClick = {}
)
FilteringButton(
isSelected = false,
isSelected = true,
text = R.string.button_preview,
cornerRadius = 15.dp,
paddingVertical = 10.dp,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ val Grey150 = Color(0xFFE9E9E9)
val Grey200 = Color(0xFFDDDDDD)
val Grey300 = Color(0xFFBCBCBC)
val Grey350 = Color(0xFFADADAD)
val Grey375 = Color(0xFF898989)
val Grey400 = Color(0xFF666666)
val Grey500 = Color(0xFF373737)
val Black = Color(0xFF171717)
Expand Down
7 changes: 7 additions & 0 deletions core/src/main/java/com/terning/core/extension/CalendarExt.kt
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

확인했습니당!! 최고최고💚

Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.terning.core.extension

import java.util.Calendar

val Calendar.currentYear: Int get() = get(Calendar.YEAR)

val Calendar.currentMonth: Int get() = get(Calendar.MONTH) + 1
8 changes: 8 additions & 0 deletions core/src/main/java/com/terning/core/util/CalendarDefaults.kt
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

상수로 저장한거 좋네욤!!

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.terning.core.util

object CalendarDefaults {
const val START_YEAR = 2010
const val END_YEAR = 2030
const val START_MONTH = 1
const val END_MONTH = 12
}
1 change: 0 additions & 1 deletion feature/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -100,5 +100,4 @@ dependencies {

// KakaoDependencies
implementation(libs.kakao.user)

}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,65 +1,98 @@
package com.terning.feature.filtering.filtering
package com.terning.feature.filtering.filteringone

import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
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.component.button.RectangleButton
import com.terning.core.designsystem.component.image.TerningImage
import com.terning.core.designsystem.component.topappbar.BackButtonTopAppBar
import com.terning.core.designsystem.theme.Grey300
import com.terning.core.designsystem.theme.TerningPointTheme
import com.terning.core.designsystem.theme.TerningTheme
import com.terning.feature.R
import com.terning.feature.filtering.filtering.component.StatusOneRadioGroup
import com.terning.feature.filtering.filteringone.component.StatusOneRadioGroup

@Composable
fun FilteringOneScreen(
fun FilteringOneRoute(
name: String,
onNextClick: (Int) -> Unit,
navigateUp: () -> Unit,
modifier: Modifier = Modifier,
onButtonClick: (Int) -> Unit = {},
viewModel: FilteringOneViewModel = hiltViewModel()
) {
val isButtonValid = remember { mutableStateOf(false) }
val state by viewModel.state.collectAsStateWithLifecycle()

val lifecycleOwner = LocalLifecycleOwner.current

LaunchedEffect(viewModel.sideEffects, lifecycleOwner) {
viewModel.sideEffects.flowWithLifecycle(lifecycle = lifecycleOwner.lifecycle)
.collect { sideEffect ->
when (sideEffect) {
is FilteringOneSideEffect.NavigateUp -> navigateUp()
}
}
}

var grade by remember { mutableIntStateOf(-1) }
FilteringOneScreen(
name = name,
onButtonClick = { index ->
viewModel.updateGrade(index)
viewModel.updateButtonValidation()
},
onNextClick = onNextClick,
navigateUp = viewModel::navigateUp,
buttonState = state.isButtonValid,
gradeState = state.grade
)
}

@Composable
fun FilteringOneScreen(
name: String,
onNextClick: (Int) -> Unit,
navigateUp: () -> Unit,
onButtonClick: (Int) -> Unit,
buttonState: Boolean,
gradeState: Int
) {
Column(
modifier = modifier
modifier = Modifier
) {
BackButtonTopAppBar(
onBackButtonClick = { navigateUp() }
onBackButtonClick = navigateUp
)
Column(
modifier = Modifier.fillMaxSize()
) {
TerningImage(
painter = R.drawable.ic_filtering_status1,
modifier = modifier.padding(
top = 20.dp,
Image(
painter = painterResource(id = R.drawable.ic_filtering_status1),
modifier = Modifier.padding(
top = 28.dp,
start = 24.dp
)
),
contentDescription = "filtering one status"
)
Text(
text = stringResource(
id = R.string.filtering_status1_title,
name
),
style = TerningTheme.typography.title3,
modifier = modifier.padding(
top = 19.dp,
modifier = Modifier.padding(
top = 20.dp,
start = 24.dp
)
)
Expand All @@ -70,35 +103,33 @@ fun FilteringOneScreen(
),
style = TerningTheme.typography.body5,
color = Grey300,
modifier = modifier.padding(
top = 3.dp,
modifier = Modifier.padding(
top = 4.dp,
start = 24.dp,
bottom = 25.dp
bottom = 24.dp
)
)
StatusOneRadioGroup(
onButtonClick = { index ->
onButtonClick(index)
isButtonValid.value = true
grade = index
}
)
Text(
text = stringResource(id = R.string.filtering_status1_warning),
style = TerningTheme.typography.detail3,
modifier = modifier.padding(
modifier = Modifier.padding(
start = 24.dp,
top = 9.dp
)
)
Spacer(modifier = modifier.weight(1f))
Spacer(modifier = Modifier.weight(1f))
RectangleButton(
style = TerningTheme.typography.button0,
paddingVertical = 20.dp,
text = R.string.filtering_button,
onButtonClick = { onNextClick(grade) },
modifier = modifier.padding(bottom = 12.dp),
isEnabled = isButtonValid.value
onButtonClick = { onNextClick(gradeState) },
modifier = Modifier.padding(bottom = 12.dp),
isEnabled = buttonState
)
}
}
Expand All @@ -112,7 +143,9 @@ fun FilteringOneScreenPreview() {
name = "터닝이",
onButtonClick = {},
onNextClick = {},
navigateUp = {}
navigateUp = {},
buttonState = true,
gradeState = 1
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.terning.feature.filtering.filteringone

sealed class FilteringOneSideEffect {
data object NavigateUp : FilteringOneSideEffect()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.terning.feature.filtering.filteringone

data class FilteringOneState(
val isButtonValid: Boolean = false,
val grade: Int = -1
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.terning.feature.filtering.filteringone

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch

class FilteringOneViewModel : ViewModel() {

private val _state: MutableStateFlow<FilteringOneState> = MutableStateFlow(FilteringOneState())
val state: StateFlow<FilteringOneState> get() = _state.asStateFlow()

private val _sideEffects = MutableSharedFlow<FilteringOneSideEffect>()
val sideEffects: SharedFlow<FilteringOneSideEffect> get() = _sideEffects.asSharedFlow()

fun updateButtonValidation() {
_state.value = _state.value.copy(isButtonValid = true)
}

fun updateGrade(grade: Int) {
_state.value = _state.value.copy(grade = grade)
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

최근에 든 의문인데, 예를 들어 어떤 버튼을 누르면 두 함수를 모두 호출하는 상황이 존재한다면 이렇게 나눠서 관리하는게 좋을까요 아니면 용도에 맞게 합쳐서 관리하는게 좋을까요..?
뭔가 이런 사소한 부분 때문에 리컴포지션이 한번이라도 더 발생할 수 있다는 생각이 드는데 맞는지는 모르겠네요..ㅎㅎ 어렵다

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

저도 관련해서 고민중이었는데 추후에 개별적으로 사용될 가능성을 고려해서 나눠놓는게 좋을까 싶다가도 확실하게 항상 같이 호출하는 상황이라면 합쳐서 관리하는게 더 효율적일 것 같기도 하고... 진짜 어렵다

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

사실 저도 그 고민이 들긴 했습니다..
하나하나 나누기에는 비효율적인가 싶으면서도 따로 관리해주기엔 용이할 것 같아서..
일단은 상황에 맞게 가져가는 게 좋을 것 같은데 위 화면에서는 둘 다 호출하는 경우만 있기 때문에 합쳐놓도록 하겠습니다!


fun navigateUp() =
viewModelScope.launch { _sideEffects.emit(FilteringOneSideEffect.NavigateUp) }
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.terning.feature.filtering.filtering.component
package com.terning.feature.filtering.filteringone.component

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.fillMaxWidth
Expand Down Expand Up @@ -55,7 +55,7 @@ fun StatusOneRadioGroup(
onButtonClick(index)
},
cornerRadius = 15.dp,
paddingVertical = 15.dp
paddingVertical = 14.dp
)
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.terning.feature.filtering.filtering.navigation
package com.terning.feature.filtering.filteringone.navigation

import androidx.navigation.NavController
import androidx.navigation.NavGraphBuilder
Expand All @@ -7,7 +7,8 @@ import androidx.navigation.NavOptions
import androidx.navigation.compose.composable
import androidx.navigation.toRoute
import com.terning.core.navigation.Route
import com.terning.feature.filtering.filtering.FilteringOneScreen
import com.terning.feature.filtering.filteringone.FilteringOneRoute
import com.terning.feature.filtering.filteringtwo.navigation.navigateFilteringTwo
import kotlinx.serialization.Serializable

fun NavController.navigateFilteringOne(
Expand All @@ -25,7 +26,7 @@ fun NavGraphBuilder.filteringOneNavGraph(
) {
composable<FilteringOne> {
val args = it.toRoute<FilteringOne>()
FilteringOneScreen(
FilteringOneRoute(
name = args.name,
onNextClick = { grade -> navHostController.navigateFilteringTwo(grade) },
navigateUp = { navHostController.navigateUp() }
Expand Down
Loading
Loading