Skip to content
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
package com.flint.presentation.onboarding.component

import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.horizontalScroll
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.flint.core.common.extension.noRippleClickable
import com.flint.core.designsystem.theme.FlintTheme

@Composable
fun FlintGenreChip(
text: String,
isSelected: Boolean,
onClick: () -> Unit,
modifier: Modifier = Modifier,
contentPadding: PaddingValues = PaddingValues(horizontal = 12.dp, vertical = 9.dp),
) {
val shape = CircleShape

val backgroundColor =
if (isSelected) FlintTheme.colors.primary400 else FlintTheme.colors.gray800

val border: BorderStroke? =
if (isSelected) null else BorderStroke(1.dp, FlintTheme.colors.gray300)

val contentColor = FlintTheme.colors.white

Text(
text = text,
color = contentColor,
style = FlintTheme.typography.body2M14,
modifier =
modifier
.clip(shape)
.run {
if (border != null)
border(border = border, shape = shape)
else
this
}
.background(color = backgroundColor, shape = shape)
.noRippleClickable(onClick = onClick)
.padding(contentPadding),
)
}
Comment on lines +29 to +64
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

선택 칩의 접근성 상태와 터치 영역을 보완해 주세요.

현재 구현은 단순 클릭 가능한 텍스트 칩이라, 보조기기가 선택/해제 상태를 명확히 읽어주지 못할 수 있습니다. 또 기본 패딩 기준으로는 실제 터치 높이가 48dp 미만일 가능성이 커서, 온보딩 선택 UI로는 누르기 불편할 수 있습니다.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@app/src/main/java/com/flint/presentation/onboarding/component/FlintGenreChip.kt`
around lines 29 - 69, The chip lacks accessibility semantics and a guaranteed
touch target; update FlintGenreChip to expose its selected state and a toggle
role and to ensure a minimum tap size: add a semantics block on the composable
modifier (e.g., semantics { selected = isSelected; role = Role.ToggleButton;
contentDescription = text } or set a stateDescription) so assistive tech reads
selected/unselected, and ensure the modifier includes a minimum hit target such
as .sizeIn(minHeight = 48.dp) or .heightIn(min = 48.dp) (placed before padding)
while keeping the existing noRippleClickable usage; reference FlintGenreChip,
noRippleClickable, contentPadding, and shape when making changes.


@Preview
@Composable
private fun FlintGenreChipPreview() {
FlintTheme {
Box(
modifier =
Modifier
.background(FlintTheme.colors.background)
.fillMaxWidth()
.padding(20.dp),
) {
Comment on lines +75 to +81
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

이것도 마찬가지로 Box의 역할이 따로 필요 없는 부분같아요!!
Row내에 속성 합쳐주면 깔끔할거 같습니다!

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

수정완@

Row(
horizontalArrangement = Arrangement.spacedBy(16.dp),
verticalAlignment = Alignment.CenterVertically,
) {
FlintGenreChip(
text = "액션",
isSelected = false,
onClick = {},
)

FlintGenreChip(
text = "액션",
isSelected = true,
onClick = {},
)
}
}
}
}

@Preview
@Composable
private fun FlintGenreChipInteractivePreview() {
FlintTheme {
val genres = listOf("액션", "코미디", "로맨스", "스릴러", "드라마", "SF", "공포", "다큐")
var selected by remember { mutableStateOf(setOf("액션", "로맨스")) }

Box(
modifier =
Modifier
.background(FlintTheme.colors.background)
.fillMaxWidth()
.padding(20.dp),
) {
Row(
modifier = Modifier.horizontalScroll(rememberScrollState()),
horizontalArrangement = Arrangement.spacedBy(8.dp),
) {
genres.forEach { genre ->
FlintGenreChip(
text = genre,
isSelected = genre in selected,
onClick = {
selected =
if (genre in selected) {
selected - genre
} else {
selected + genre
}
},
)
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,239 @@
package com.flint.presentation.profile.component

import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.flint.R
import com.flint.core.designsystem.component.image.NetworkImage
import com.flint.core.designsystem.component.listView.OttHorizontalList
import com.flint.core.designsystem.theme.FlintTheme
import com.flint.domain.type.OttType

@Composable
fun CollectionCreateContentBookmark(
onBookmarkClick: () -> Unit,
onMoreClick: () -> Unit,
isBookmarked: Boolean,
bookmarkCount: Int,
imageUrl: String,
title: String,
director: String,
createdYear: Int,
ottList: List<OttType>,
modifier: Modifier = Modifier,
) {
Row(
modifier =
modifier
.fillMaxWidth()
.background(color = Color.Transparent)
.padding(horizontal = 16.dp, vertical = 12.dp),
verticalAlignment = Alignment.Top,
) {
CollectionCreateContentBookmarkImage(
imageUrl = imageUrl,
ottList = ottList,
modifier =
Modifier
.height(150.dp)
.width(100.dp),
)

Spacer(modifier = Modifier.width(12.dp))

CollectionCreateContentBookmarkInfo(
title = title,
director = director,
createdYear = createdYear,
onMoreClick = onMoreClick,
modifier =
Modifier
.weight(1f)
.height(150.dp),
)
Comment thread
coderabbitai[bot] marked this conversation as resolved.

Spacer(modifier = Modifier.width(8.dp))
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

여기 피그마 기준으로는 4.dp인거같습니다! 확인 부탁드려용

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

아 이거 auto 레이아웃이 걸려있고 자세히 보니까 북마크랑, 숫자 부분이 한 프레임으로 묶여있는 거 같아서 피그마 참고해서 수정했습니다! 못 볼 뻔.. 감사합니당
image
image


CollectionCreateContentBookmarkTag(
isBookmarked = isBookmarked,
bookmarkCount = bookmarkCount,
onClick = onBookmarkClick,
)
}
}

@Composable
private fun CollectionCreateContentBookmarkImage(
imageUrl: String,
ottList: List<OttType>,
modifier: Modifier = Modifier,
) {
Box(
modifier = modifier,
) {
NetworkImage(
imageUrl = imageUrl,
modifier = Modifier.fillMaxWidth().height(150.dp),
)

OttHorizontalList(
ottList = ottList,
modifier =
Modifier
.padding(top = 10.dp, start = 8.dp),
)
}
}

@Composable
private fun CollectionCreateContentBookmarkInfo(
title: String,
director: String,
createdYear: Int,
onMoreClick: () -> Unit,
modifier: Modifier = Modifier,
) {
Column(
modifier = modifier,
) {
Text(
text = title,
modifier = Modifier.fillMaxWidth(),
color = FlintTheme.colors.white,
overflow = TextOverflow.Ellipsis,
maxLines = 2,
style = FlintTheme.typography.body1M16,
)

Spacer(modifier = Modifier.height(12.dp))

Text(
text = director,
modifier = Modifier.fillMaxWidth(),
color = FlintTheme.colors.gray300,
style = FlintTheme.typography.caption1M12,
)

Text(
text = createdYear.toString(),
modifier = Modifier.fillMaxWidth(),
color = FlintTheme.colors.gray300,
style = FlintTheme.typography.body1R16,
)

Spacer(modifier = Modifier.weight(1f))

CollectionCreateContentBookmarkMore(
onClick = onMoreClick,
)
}
}

@Composable
private fun CollectionCreateContentBookmarkTag(
isBookmarked: Boolean,
bookmarkCount: Int,
onClick: () -> Unit,
modifier: Modifier = Modifier,
) {
Column(
modifier = modifier,
horizontalAlignment = Alignment.CenterHorizontally,
) {
Icon(
imageVector =
ImageVector.vectorResource(
if (isBookmarked) R.drawable.ic_bookmark_fill else R.drawable.ic_bookmark_empty,
),
contentDescription = null,
tint = Color.Unspecified,
modifier =
Modifier
.size(24.dp)
.clickable(onClick = onClick),
)

Spacer(modifier = Modifier.height(2.dp))

Text(
text = bookmarkCount.toString(),
color = FlintTheme.colors.white,
style = FlintTheme.typography.caption1M12,
)
}
}

@Composable
private fun CollectionCreateContentBookmarkMore(
onClick: () -> Unit,
modifier: Modifier = Modifier,
) {
Row(
modifier = modifier.clickable(onClick = onClick),
verticalAlignment = Alignment.CenterVertically,
) {
Text(
text = "작품 보러가기",
color = FlintTheme.colors.white,
style = FlintTheme.typography.body2R14,
)

Icon(
imageVector = ImageVector.vectorResource(R.drawable.ic_more),
contentDescription = null,
tint = Color.Unspecified,
modifier = Modifier.size(16.dp),
)
}
}




@Preview
@Composable
private fun CollectionCreateContentBookmarkPreview() {
FlintTheme {
var isBookmarked by remember { mutableStateOf(true) }
CollectionCreateContentBookmark(
onBookmarkClick = { isBookmarked = !isBookmarked },
onMoreClick = {},
isBookmarked = isBookmarked,
bookmarkCount = 413,
imageUrl = "https://buly.kr/DEaVFRZ",
title = "어바웃 타임",
director = "스파이더맨",
createdYear = 2001,
ottList =
listOf(
OttType.Netflix,
OttType.Disney,
OttType.Tving,
OttType.CoupangPlay,
),
)
}
}
10 changes: 5 additions & 5 deletions app/src/main/res/drawable/ic_background_photo.xml
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="48dp"
android:height="48dp"
android:viewportWidth="48"
android:viewportHeight="48">
android:width="30dp"
android:height="30dp"
android:viewportWidth="30"
android:viewportHeight="30">
<path
android:pathData="M29,31.455L23.688,26L12,38M34,10V18M30,14H38M12.111,19H26.889C28.055,19 29,19.945 29,21.111V35.889C29,37.055 28.055,38 26.889,38H12.111C10.945,38 10,37.055 10,35.889V21.111C10,19.945 10.945,19 12.111,19ZM17,24.5C17,25.328 16.328,26 15.5,26C14.672,26 14,25.328 14,24.5C14,23.672 14.672,23 15.5,23C16.328,23 17,23.672 17,24.5Z"
android:pathData="M20,22.455L14.688,17L3,29M25,1V9M21,5H29M3.111,10H17.889C19.055,10 20,10.945 20,12.111V26.889C20,28.055 19.055,29 17.889,29H3.111C1.945,29 1,28.055 1,26.889V12.111C1,10.945 1.945,10 3.111,10ZM8,15.5C8,16.328 7.328,17 6.5,17C5.672,17 5,16.328 5,15.5C5,14.672 5.672,14 6.5,14C7.328,14 8,14.672 8,15.5Z"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified app/src/main/res/drawable/ic_gradient_bookmark.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified app/src/main/res/drawable/ic_gradient_check.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified app/src/main/res/drawable/ic_gradient_folder.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified app/src/main/res/drawable/ic_gradient_home.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified app/src/main/res/drawable/ic_gradient_lock.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified app/src/main/res/drawable/ic_gradient_messages.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified app/src/main/res/drawable/ic_gradient_none.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified app/src/main/res/drawable/ic_gradient_pencil.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified app/src/main/res/drawable/ic_gradient_people.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified app/src/main/res/drawable/ic_gradient_picture.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added app/src/main/res/drawable/ic_gradient_save.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified app/src/main/res/drawable/ic_gradient_share.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified app/src/main/res/drawable/ic_gradient_trash.png
Binary file added app/src/main/res/drawable/ic_info.png
Binary file added app/src/main/res/drawable/ic_small_info.png
Loading