Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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 @@ -11,34 +11,40 @@ data class KeywordListModel(
val FakeList1 = KeywordListModel(
keywords = persistentListOf(
KeywordItemModel(
name = "추리",
name = "애니메이션",
color = "BLUE",
rank = 1
rank = 1,
percentage = 75f,
),
KeywordItemModel(
name = "슬픈",
color = "GREEN",
rank = 4
rank = 4,
percentage = 35f,
),
KeywordItemModel(
name = "SF",
color = "PINK",
rank = 2,
percentage = 60f,
),
KeywordItemModel(
name = "액션",
color = "ORANGE",
rank = 5,
percentage = 25f,
),
KeywordItemModel(
name = "슬픈",
name = "몽환적인",
color = "YELLOW",
rank = 3,
percentage = 48f,
),
KeywordItemModel(
name = "성장",
color = "YELLOW",
rank = 6,
percentage = 15f,
),
)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.ui.Alignment
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
Expand All @@ -32,13 +31,17 @@ import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.flint.core.common.extension.findActivity
import com.flint.core.common.extension.noRippleClickable
import com.flint.R
import androidx.compose.material3.Icon
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.vectorResource
import com.flint.core.common.util.UiState
import com.flint.core.designsystem.component.bottomsheet.OttListBottomSheet
import com.flint.core.designsystem.component.indicator.FlintLoadingIndicator
import com.flint.core.designsystem.component.listView.CollectionSection
import com.flint.core.designsystem.component.listView.SavedContentsSection
import com.flint.core.designsystem.component.topappbar.FlintBackTopAppbar
import com.flint.core.designsystem.theme.Colors
import com.flint.core.designsystem.component.topappbar.FlintBasicTopAppbar
import com.flint.core.designsystem.theme.FlintTheme
import com.flint.core.designsystem.theme.FlintTheme.colors
import com.flint.core.navigation.model.CollectionListRouteType
Expand Down Expand Up @@ -138,6 +141,7 @@ private fun ProfileScreen(
modifier: Modifier = Modifier,
onRefreshClick: () -> Unit = {},
onBackClick: () -> Unit = {},
onSettingsClick: () -> Unit = {},
onCollectionItemClick: (collectionId: String) -> Unit,
onContentItemClick: (contentId: String) -> Unit = {},
onContentMoreClick: () -> Unit = {},
Expand All @@ -149,6 +153,7 @@ private fun ProfileScreen(
var topHeightPx by remember { mutableIntStateOf(0) }
val density = LocalDensity.current
val topHeightDp = with(density) { topHeightPx.toDp() }
var showInfoModal by remember { mutableStateOf(false) }

Box(
modifier = modifier
Expand Down Expand Up @@ -198,6 +203,9 @@ private fun ProfileScreen(
ProfileKeywordSection(
nickname = uiState.profile.nickname,
keywordList = sectionData.data.keywords,
isMyProfile = uiState.userId == null,
showInfoModal = showInfoModal,
onInfoClick = { showInfoModal = !showInfoModal },
onRefreshClick = onRefreshClick,
modifier = Modifier.fillMaxWidth(),
)
Expand All @@ -208,7 +216,7 @@ private fun ProfileScreen(
Spacer(Modifier.height(48.dp))

CollectionSection(
title = "생성한 컬렉션",
title = "${userName}님의 컬렉션",
description = "${userName}님이 생성한 컬렉션이에요",
onItemClick = onCollectionItemClick,
isAllVisible = true,
Expand Down Expand Up @@ -250,11 +258,36 @@ private fun ProfileScreen(
else -> {}
}
}
if (uiState.userId != null) {
FlintBackTopAppbar(
onClick = onBackClick,
if (showInfoModal) {
Box(
modifier = Modifier
.fillMaxSize()
.noRippleClickable { showInfoModal = false },
)
}
FlintBasicTopAppbar(
backgroundColor = Color.Transparent,
navigationIcon = {
if (uiState.userId != null) {
Icon(
imageVector = ImageVector.vectorResource(R.drawable.ic_back),
contentDescription = null,
tint = FlintTheme.colors.white,
modifier = Modifier.noRippleClickable { onBackClick() },
)
}
},
action = {
if (uiState.userId == null) {
Icon(
imageVector = ImageVector.vectorResource(R.drawable.ic_setting),
contentDescription = "설정",
tint = FlintTheme.colors.white,
modifier = Modifier.noRippleClickable { onSettingsClick() },
)
}
},
)
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package com.flint.presentation.profile.component

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
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.graphics.Color
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.flint.core.designsystem.theme.FlintTheme

@Composable
fun InfoModalTrigger(
text: String,
modifier: Modifier = Modifier,
) {
Box(
contentAlignment = Alignment.Center,
modifier = modifier
.background(
color = FlintTheme.colors.gray800,
shape = RoundedCornerShape(size = 12.dp),
)
.padding(horizontal = 12.dp, vertical = 14.dp),
) {
Text(
text = text,
style = FlintTheme.typography.body2R14,
color = FlintTheme.colors.gray300,
)
}
}

@Preview(showBackground = true, backgroundColor = 0xFF141417)
@Composable
private fun InfoModalTriggerPreview() {
FlintTheme {
InfoModalTrigger(text = "저장한 작품들에서 반복되는 키워드를 분석해 취향 키워드를 만들어요. n개 이상 작품이 쌓이면 업데이트할 수 있어요.")
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.flint.presentation.profile.component

import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Row
Expand All @@ -20,6 +21,9 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
Expand Down Expand Up @@ -80,20 +84,48 @@ private fun ProfileKeywordProgressBar(
percent: Float,
modifier: Modifier = Modifier,
Comment thread
coderabbitai[bot] marked this conversation as resolved.
) {
val safePercent = percent.coerceIn(0f, 1f)
val shape = RoundedCornerShape(4.dp)

// Track: #4F5669, stop 20%→100% alpha, 레이어 전체 44% opacity
val trackBrush = Brush.linearGradient(
colors = listOf(
Color(0xFF4F5669).copy(alpha = 0.20f * 0.44f),
Color(0xFF4F5669).copy(alpha = 0.44f),
)
)

// Fill: 키워드 색상, stop 20%→100% alpha
val fillBrush = Brush.linearGradient(
colors = listOf(
preferenceType.color.copy(alpha = 0.20f),
preferenceType.color,
)
)

// Border: white→transparent, 상→하 방향 (유리 효과 - 오른쪽 끝까지 border 보임)
val borderBrush = Brush.linearGradient(
colors = listOf(
Color.White.copy(alpha = 0.30f),
Color.Transparent,
),
start = Offset(0f, 0f),
end = Offset(0f, Float.POSITIVE_INFINITY),
)

Box(
modifier =
modifier
.height(12.dp)
.clip(RoundedCornerShape(4.dp))
.background(FlintTheme.colors.gray500),
modifier = modifier
.height(12.dp)
.background(trackBrush, shape)
.border(1.dp, borderBrush, shape)
.clip(shape),
) {
Box(
modifier =
Modifier
.fillMaxWidth(percent)
.fillMaxHeight()
.clip(RoundedCornerShape(4.dp))
.background(preferenceType.color),
modifier = Modifier
.fillMaxWidth(safePercent)
.fillMaxHeight()
.clip(shape)
.background(fillBrush),
)
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,28 @@
package com.flint.presentation.profile.component

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
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.vector.ImageVector
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
Expand All @@ -33,9 +41,13 @@ import kotlinx.collections.immutable.toPersistentList
fun ProfileKeywordSection(
nickname: String,
keywordList: KeywordListModel,
isMyProfile: Boolean,
showInfoModal: Boolean,
onInfoClick: () -> Unit,
onRefreshClick: () -> Unit,
modifier: Modifier = Modifier,
) {

Column(
modifier =
modifier
Expand All @@ -49,21 +61,53 @@ fun ProfileKeywordSection(
modifier = Modifier.fillMaxWidth(),
) {
Column {
Text(
text = "${nickname}님의 취향키워드",
style = FlintTheme.typography.head3Sb18,
color = FlintTheme.colors.white,
)
Row(verticalAlignment = Alignment.CenterVertically) {
Text(
text = "${nickname}님의 취향키워드",
style = FlintTheme.typography.head3Sb18,
color = FlintTheme.colors.white,
)
if (isMyProfile) {
Spacer(Modifier.width(4.dp))
Icon(
painter = painterResource(R.drawable.ic_info),
contentDescription = "취향키워드 정보",
tint = FlintTheme.colors.gray300,
modifier = Modifier
.size(20.dp)
.noRippleClickable { onInfoClick() },
)
}
}
Spacer(Modifier.height(4.dp))
Text(
text = "${nickname}님이 관심있어하는 키워드예요",
style = FlintTheme.typography.body2R14,
color = FlintTheme.colors.gray100,
)
}
if (isMyProfile) {
ProfileRefreshButton(onRefreshClick = onRefreshClick)
}
}
Spacer(Modifier.height(32.dp))
KeywordChipsGridLayout(
Box {
KeywordChipsGridLayout(
keywordList = keywordList.keywords,
modifier = Modifier.fillMaxWidth(),
)
if (isMyProfile && showInfoModal) {
InfoModalTrigger(
text = "저장한 작품들에서 반복되는 키워드를 분석해 취향 키워드를 만들어요. 10개 이상 작품이 쌓이면 업데이트할 수 있어요.",
modifier = Modifier
.fillMaxWidth()
.offset(y = (-20).dp),
)
}
}

Spacer(Modifier.height(32.dp))
KeywordGraphLayout(
keywordList = keywordList.keywords,
modifier = Modifier.fillMaxWidth(),
)
Expand Down Expand Up @@ -143,9 +187,9 @@ private fun KeywordGraphLayout(
) {
Column(
modifier = modifier.fillMaxWidth(),
verticalArrangement = Arrangement.spacedBy(16.dp),
verticalArrangement = Arrangement.spacedBy(12.dp),
) {
keywordList.forEach {
keywordList.take(3).forEach {
with(it) {
ProfileKeywordGraphItem(
keyword = name,
Expand Down Expand Up @@ -192,6 +236,9 @@ private fun ProfileKeywordSectionPreview() {
nickname = "안두콩",
keywordList = KeywordListModel.FakeList3,
modifier = Modifier.fillMaxSize(),
isMyProfile = true,
showInfoModal = false,
onInfoClick = {},
onRefreshClick = {},
)
}
Expand Down
Loading