-
Notifications
You must be signed in to change notification settings - Fork 1
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/#11] 탐색 뷰 / 탐색 기본 화면 구현 #30
Changes from 19 commits
8dd453c
2c4c070
9819c4e
78c8b3a
e7cf63f
7340cdd
ed2c94b
42819ec
7c3dee4
9d393a4
7d0e855
eed08f5
6846986
8f2970c
314d592
7641fd4
628c9a6
4d5a569
cb73920
3b353e6
8321ae2
3066940
cf2c328
872c4a9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,12 @@ | ||
package com.terning.feature.search | ||
|
||
import androidx.compose.foundation.layout.Box | ||
import androidx.compose.foundation.layout.Column | ||
import androidx.compose.foundation.layout.Spacer | ||
import androidx.compose.foundation.layout.fillMaxWidth | ||
import androidx.compose.foundation.layout.padding | ||
import androidx.compose.material3.HorizontalDivider | ||
import androidx.compose.material3.Text | ||
import androidx.compose.runtime.Composable | ||
import androidx.compose.runtime.getValue | ||
import androidx.compose.runtime.mutableStateOf | ||
|
@@ -11,12 +15,13 @@ import androidx.compose.runtime.setValue | |
import androidx.compose.ui.Modifier | ||
import androidx.compose.ui.res.stringResource | ||
import androidx.compose.ui.unit.dp | ||
import com.terning.core.designsystem.component.textfield.NameTextField | ||
import com.terning.core.designsystem.component.textfield.SearchTextField | ||
import com.terning.core.designsystem.theme.Grey400 | ||
import com.terning.core.designsystem.theme.TerningMain | ||
import com.terning.core.designsystem.theme.WarningRed | ||
import com.terning.core.designsystem.theme.Black | ||
import com.terning.core.designsystem.theme.Grey100 | ||
import com.terning.core.designsystem.theme.TerningTheme | ||
import com.terning.feature.R | ||
import com.terning.feature.search.component.ImageSlider | ||
import com.terning.feature.search.component.SearchInternList | ||
|
||
@Composable | ||
fun SearchRoute() { | ||
|
@@ -26,61 +31,47 @@ fun SearchRoute() { | |
@Composable | ||
fun SearchScreen() { | ||
var text by remember { mutableStateOf("") } | ||
|
||
// TODO 프로필 스크린 TextField로, 삭제될 코드입니다 | ||
var helperMessage by remember { mutableStateOf(R.string.profile_text_field_helper) } | ||
var helperIcon by remember { mutableStateOf<Int?>(null) } | ||
var helperColor by remember { mutableStateOf(Grey400) } | ||
val specialCharacterPattern = Regex("[!@#\$%^&*(),.?\":{}|<>\\[\\]\\\\/]") | ||
|
||
// TODO 프로필 스크린 TextField로, 삭제될 코드입니다 | ||
fun updateHelper(text: String) { | ||
helperMessage = when { | ||
text.isEmpty() -> R.string.profile_text_field_helper | ||
specialCharacterPattern.containsMatchIn(text) -> R.string.profile_text_field_warning | ||
text.length <= 12 -> R.string.profile_text_field_check | ||
else -> R.string.profile_text_field_helper | ||
} | ||
helperIcon = when { | ||
text.isEmpty() -> null | ||
specialCharacterPattern.containsMatchIn(text) -> R.drawable.ic_warning | ||
text.length <= 12 -> R.drawable.ic_check | ||
else -> null | ||
} | ||
helperColor = when { | ||
text.isEmpty() -> Grey400 | ||
specialCharacterPattern.containsMatchIn(text) -> WarningRed | ||
text.length <= 12 -> TerningMain | ||
else -> Grey400 | ||
} | ||
} | ||
val images = listOf( | ||
R.drawable.ic_nav_search, | ||
R.drawable.ic_check, | ||
R.drawable.ic_nav_my_page, | ||
) | ||
|
||
Column( | ||
modifier = Modifier | ||
.fillMaxWidth() | ||
.padding(horizontal = 16.dp) | ||
) { | ||
Box(modifier = Modifier.padding(16.dp)) { | ||
SearchTextField( | ||
text = text, | ||
onValueChange = { newText -> | ||
text = newText | ||
}, | ||
readOnly = true, | ||
hint = stringResource(R.string.search_text_field_hint), | ||
leftIcon = R.drawable.ic_nav_search, | ||
) | ||
} | ||
|
||
SearchTextField( | ||
text = text, | ||
onValueChange = { newText -> | ||
text = newText | ||
}, | ||
hint = stringResource(R.string.search_text_field_hint), | ||
leftIcon = R.drawable.ic_nav_search | ||
ImageSlider( | ||
images = images | ||
) | ||
|
||
// TODO 프로필 스크린 TextField로, 삭제될 코드입니다 | ||
NameTextField( | ||
text = text, | ||
onValueChange = { newText -> | ||
text = newText | ||
updateHelper(newText) | ||
}, | ||
hint = stringResource(R.string.profile_text_field_hint), | ||
helperMessage = stringResource(helperMessage), | ||
helperIcon = helperIcon, | ||
helperColor = helperColor | ||
Spacer(modifier = Modifier.padding(8.dp)) | ||
|
||
Text( | ||
text = stringResource(id = R.string.search_today_popular), | ||
modifier = Modifier.padding(horizontal = 16.dp, vertical = 4.dp), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 여기 padding There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 전체 패딩값이 24.dp 였군요 ㅠ ㅠ 당장 수정할게욥 |
||
style = TerningTheme.typography.title1, | ||
color = Black | ||
) | ||
|
||
SearchInternList(type = "view") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "view"와 "scrap"이 화면에 표시할 인턴 공고 타입을 나타내는 문자열 같은데 이건 enum과 같은 것으로 카테고리화하는게 좋아보이네요!! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 꺅!!!!!!!섬세하시다. 적용킵고잉하겠습니다 |
||
HorizontalDivider( | ||
thickness = 4.dp, | ||
modifier = Modifier.padding(vertical = 8.dp), | ||
color = Grey100, | ||
) | ||
SearchInternList(type = "scrap") | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package com.terning.feature.search.component | ||
|
||
import androidx.compose.foundation.layout.Arrangement | ||
import androidx.compose.foundation.layout.Row | ||
import androidx.compose.foundation.layout.padding | ||
import androidx.compose.runtime.Composable | ||
import androidx.compose.ui.Alignment | ||
import androidx.compose.ui.Modifier | ||
import androidx.compose.ui.unit.dp | ||
|
||
@Composable | ||
fun DotsIndicator( | ||
modifier: Modifier = Modifier, | ||
pageCount: Int, | ||
currentPage: Int, | ||
) { | ||
Row( | ||
horizontalArrangement = Arrangement.SpaceBetween, | ||
verticalAlignment = Alignment.CenterVertically, | ||
modifier = Modifier.padding(8.dp) | ||
) { | ||
repeat(pageCount) { index -> | ||
IndicatorDots( | ||
isSelected = index == currentPage, | ||
modifier = modifier | ||
) | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
package com.terning.feature.search.component | ||
|
||
import androidx.compose.foundation.Image | ||
import androidx.compose.foundation.background | ||
import androidx.compose.foundation.layout.Box | ||
import androidx.compose.foundation.layout.Column | ||
import androidx.compose.foundation.layout.fillMaxWidth | ||
import androidx.compose.foundation.layout.height | ||
import androidx.compose.foundation.layout.padding | ||
import androidx.compose.foundation.layout.wrapContentSize | ||
import androidx.compose.foundation.pager.HorizontalPager | ||
import androidx.compose.foundation.pager.rememberPagerState | ||
import androidx.compose.material3.Card | ||
import androidx.compose.runtime.Composable | ||
import androidx.compose.runtime.LaunchedEffect | ||
import androidx.compose.ui.Alignment | ||
import androidx.compose.ui.Modifier | ||
import androidx.compose.ui.res.painterResource | ||
import androidx.compose.ui.unit.dp | ||
import com.terning.core.designsystem.theme.Grey200 | ||
import kotlinx.coroutines.delay | ||
|
||
@Composable | ||
fun ImageSlider( | ||
modifier: Modifier = Modifier, | ||
images: List<Int>, | ||
) { | ||
val pagerState = rememberPagerState(pageCount = { images.size }) | ||
|
||
LaunchedEffect(Unit) { | ||
while (true) { | ||
delay(3000) | ||
val nextPage = (pagerState.currentPage + 1) % pagerState.pageCount | ||
pagerState.scrollToPage(nextPage) | ||
} | ||
} | ||
Comment on lines
+30
to
+36
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이건 자동 스크롤 로직인가요?? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 우왕 자동 스크롤까지 구현하다니!!! 진짜 최고최고 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 기디에서 3초마다 넘어가게 해달라고 하셔서 반영했습니당....... 🫶🏻 |
||
Column( | ||
modifier | ||
.fillMaxWidth() | ||
.background(Grey200), | ||
horizontalAlignment = Alignment.CenterHorizontally | ||
) { | ||
Box( | ||
modifier = modifier | ||
.wrapContentSize(), | ||
contentAlignment = Alignment.BottomCenter | ||
) { | ||
HorizontalPager( | ||
state = pagerState, | ||
modifier = modifier.wrapContentSize() | ||
) { currentPage -> | ||
Card( | ||
modifier | ||
.wrapContentSize() | ||
) { | ||
Image( | ||
painter = painterResource(id = images[currentPage]), | ||
contentDescription = null, | ||
modifier = modifier | ||
.fillMaxWidth() | ||
.height(112.dp) | ||
.padding(16.dp) | ||
) | ||
Comment on lines
+58
to
+63
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 나중에 실제 광고 화면 들어가면 요거 고정 디피는 지양하면 좋을 것 가타요! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 넵 !!! |
||
} | ||
} | ||
DotsIndicator( | ||
pageCount = images.size, | ||
currentPage = pagerState.currentPage | ||
) | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package com.terning.feature.search.component | ||
|
||
import androidx.compose.foundation.background | ||
import androidx.compose.foundation.layout.Box | ||
import androidx.compose.foundation.layout.padding | ||
import androidx.compose.foundation.layout.size | ||
import androidx.compose.foundation.shape.CircleShape | ||
import androidx.compose.runtime.Composable | ||
import androidx.compose.ui.Modifier | ||
import androidx.compose.ui.draw.clip | ||
import androidx.compose.ui.unit.dp | ||
import com.terning.core.designsystem.theme.TerningMain | ||
import com.terning.core.designsystem.theme.White | ||
|
||
@Composable | ||
fun IndicatorDots( | ||
isSelected: Boolean, modifier: Modifier, | ||
) { | ||
Box( | ||
modifier = modifier | ||
.padding(2.dp) | ||
.clip(CircleShape) | ||
.size(6.dp) | ||
.background(if (isSelected) TerningMain else White) | ||
) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
package com.terning.feature.search.component | ||
|
||
import androidx.compose.foundation.Image | ||
import androidx.compose.foundation.background | ||
import androidx.compose.foundation.layout.Arrangement | ||
import androidx.compose.foundation.layout.Column | ||
import androidx.compose.foundation.layout.fillMaxWidth | ||
import androidx.compose.foundation.layout.padding | ||
import androidx.compose.foundation.shape.RoundedCornerShape | ||
import androidx.compose.material3.Text | ||
import androidx.compose.runtime.Composable | ||
import androidx.compose.ui.Alignment | ||
import androidx.compose.ui.Modifier | ||
import androidx.compose.ui.draw.shadow | ||
import androidx.compose.ui.graphics.Color | ||
import androidx.compose.ui.res.painterResource | ||
import androidx.compose.ui.text.style.TextOverflow | ||
import androidx.compose.ui.unit.dp | ||
import com.terning.core.designsystem.theme.Black | ||
import com.terning.core.designsystem.theme.Grey400 | ||
import com.terning.core.designsystem.theme.TerningTheme | ||
import com.terning.core.designsystem.theme.White | ||
import com.terning.feature.R | ||
|
||
@Composable | ||
fun SearchIntern() { | ||
Column( | ||
verticalArrangement = Arrangement.spacedBy( | ||
10.dp, | ||
Alignment.Top | ||
), | ||
horizontalAlignment = Alignment.CenterHorizontally, | ||
modifier = Modifier | ||
.shadow( | ||
elevation = 4.dp, | ||
// TODO 효빈 그림자 PR 풀 받아서 바꾸기 | ||
spotColor = Color(0x26DDDDDD), | ||
ambientColor = Color(0x26DDDDDD) | ||
) | ||
.background( | ||
color = White, | ||
shape = RoundedCornerShape(size = 5.dp) | ||
) | ||
.padding(vertical = 8.dp) | ||
) { | ||
Image( | ||
painter = painterResource(id = R.drawable.ic_nav_search), | ||
contentDescription = null, | ||
modifier = Modifier | ||
.fillMaxWidth() | ||
.padding(16.dp) | ||
.background(Grey400) | ||
) | ||
Text( | ||
text = "[유한킴벌리]\n그린캠프 w. 대학생 숲 \n활동가 모집", | ||
modifier = Modifier.padding(horizontal = 8.dp), | ||
style = TerningTheme.typography.body6, | ||
color = Black, | ||
overflow = TextOverflow.Ellipsis, | ||
maxLines = 3 | ||
) | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
package com.terning.feature.search.component | ||
|
||
import androidx.compose.foundation.layout.Arrangement | ||
import androidx.compose.foundation.layout.Column | ||
import androidx.compose.foundation.layout.padding | ||
import androidx.compose.foundation.lazy.LazyRow | ||
import androidx.compose.material3.Text | ||
import androidx.compose.runtime.Composable | ||
import androidx.compose.ui.Modifier | ||
import androidx.compose.ui.res.stringResource | ||
import androidx.compose.ui.unit.dp | ||
import com.terning.core.designsystem.theme.Grey400 | ||
import com.terning.core.designsystem.theme.TerningTheme | ||
import com.terning.feature.R | ||
|
||
@Composable | ||
fun SearchInternList( | ||
type: String, | ||
) { | ||
Column(modifier = Modifier.padding(horizontal = 16.dp)) { | ||
Text( | ||
text = stringResource( | ||
id = if (type == "view") R.string.search_most_view_intern | ||
else R.string.search_most_scrap_intern | ||
), | ||
style = TerningTheme.typography.title5, | ||
color = Grey400 | ||
) | ||
|
||
LazyRow( | ||
modifier = Modifier.padding(vertical = 8.dp), | ||
horizontalArrangement = Arrangement.spacedBy(12.dp), | ||
) { | ||
items(5) { | ||
SearchIntern() | ||
} | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
요거 readOnly를 젤 아래로 내려줘야 할 것 같아용