diff --git a/app/src/main/java/com/texthip/thip/ui/common/buttons/GroupVoteButton.kt b/app/src/main/java/com/texthip/thip/ui/common/buttons/GroupVoteButton.kt index f30320b7..08a5a6f0 100644 --- a/app/src/main/java/com/texthip/thip/ui/common/buttons/GroupVoteButton.kt +++ b/app/src/main/java/com/texthip/thip/ui/common/buttons/GroupVoteButton.kt @@ -31,19 +31,21 @@ import com.texthip.thip.ui.theme.ThipTheme.typography @Composable fun GroupVoteButton( + modifier: Modifier = Modifier, options: List, - voteResults: List + voteResults: List, + selectedIndex: Int?, // 외부에서 전달받은 선택 상태 + onOptionSelected: (Int?) -> Unit // 클릭 시 선택 변경 콜백 ) { - var selectedIndex by remember { mutableStateOf(null) } + val hasVoted = selectedIndex != null Column( - modifier = Modifier + modifier = modifier .fillMaxWidth(), - verticalArrangement = Arrangement.spacedBy(12.dp) + verticalArrangement = Arrangement.spacedBy(10.dp) ) { options.forEachIndexed { index, option -> val isSelected = selectedIndex == index - val hasVoted = selectedIndex != null val votePercent = if (hasVoted) voteResults.getOrNull(index)?.coerceIn(0, 100) ?: 0 else 0 val animatedPercent by animateFloatAsState( @@ -72,10 +74,13 @@ fun GroupVoteButton( .background(color = backgroundColor, shape = RoundedCornerShape(12.dp)) .height(44.dp) .clickable { - selectedIndex = if (isSelected) null else index + if (isSelected) { + onOptionSelected(null) // -1 → 취소 의미 + } else { + onOptionSelected(index) + } } ) { - // 퍼센트 채우기 if (hasVoted) { Box( modifier = Modifier @@ -102,7 +107,7 @@ fun GroupVoteButton( ) if (hasVoted) { Text( - text = "${votePercent}%", + text = "$votePercent%", color = textColor, style = fontStyle ) @@ -118,13 +123,16 @@ fun GroupVoteButton( private fun GroupVoteButtonPreview() { val options = listOf("밥", "국수", "고기") val results = listOf(20, 30, 50) + var selected by remember { mutableStateOf(null) } Column( modifier = Modifier.fillMaxSize() ) { GroupVoteButton( options = options, - voteResults = results + voteResults = results, + selectedIndex = selected, + onOptionSelected = { selected = it } ) } } \ No newline at end of file diff --git a/app/src/main/java/com/texthip/thip/ui/common/cards/CardChat.kt b/app/src/main/java/com/texthip/thip/ui/common/cards/CardChat.kt new file mode 100644 index 00000000..76efaaea --- /dev/null +++ b/app/src/main/java/com/texthip/thip/ui/common/cards/CardChat.kt @@ -0,0 +1,70 @@ +package com.texthip.thip.ui.common.cards + +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Icon +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.texthip.thip.R +import com.texthip.thip.ui.theme.ThipTheme.colors +import com.texthip.thip.ui.theme.ThipTheme.typography + +@Composable +fun CardChat( + title: String, + subtitle: String, + onClick: () -> Unit = {}, +) { + Column( + modifier = Modifier + .fillMaxWidth() + .background(color = colors.DarkGrey02, shape = RoundedCornerShape(12.dp)) + .padding(vertical = 16.dp, horizontal = 12.dp) + .clickable { onClick() }, + verticalArrangement = Arrangement.spacedBy(12.dp) + ) { + Row( + modifier = Modifier.fillMaxWidth(), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.SpaceBetween + ) { + Text( + text = title, + style = typography.smalltitle_sb600_s16_h24, + color = colors.White, + ) + + Icon( + painter = painterResource(R.drawable.ic_chevron), + contentDescription = "Chevron Icon", + tint = colors.Grey02, + ) + } + + Text( + text = subtitle, + style = typography.info_m500_s12, + color = colors.Grey, + ) + } +} + +@Preview +@Composable +private fun CardChatPreview() { + CardChat( + title = "출석체크", + subtitle = "모임방 멤버들과 간단한 인사를 나눠보세요!", + ) {} +} \ No newline at end of file diff --git a/app/src/main/java/com/texthip/thip/ui/common/cards/CardCommentGroup.kt b/app/src/main/java/com/texthip/thip/ui/common/cards/CardCommentGroup.kt new file mode 100644 index 00000000..caf7a8e1 --- /dev/null +++ b/app/src/main/java/com/texthip/thip/ui/common/cards/CardCommentGroup.kt @@ -0,0 +1,53 @@ +package com.texthip.thip.ui.common.cards + +import androidx.compose.foundation.layout.Column +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.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.texthip.thip.ui.common.header.ProfileBarWithDate +import com.texthip.thip.ui.group.room.mock.GroupRoomChatData +import com.texthip.thip.ui.theme.ThipTheme.colors +import com.texthip.thip.ui.theme.ThipTheme.typography + +@Composable +fun CardCommentGroup( + data: GroupRoomChatData +) { + Column( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 20.dp) + ) { + ProfileBarWithDate( + profileImage = data.profileImage, + nickname = data.nickname, + dateText = data.date + ) + Spacer(Modifier.height(8.dp)) + Text( + text = data.content, + style = typography.feedcopy_r400_s14_h20, + color = colors.Grey + + ) + } +} + +@Preview +@Composable +private fun CardCommentGroupPreview() { + CardCommentGroup( + data = GroupRoomChatData( + profileImage = null, + nickname = "user.01", + date = "11시간 전", + content = "이것은 그룹 채팅의 댓글입니다. 이곳에 댓글 내용을 작성할 수 있습니다. 여러 줄로 작성해도 됩니다." + ) + ) +} \ No newline at end of file diff --git a/app/src/main/java/com/texthip/thip/ui/common/cards/CardNote.kt b/app/src/main/java/com/texthip/thip/ui/common/cards/CardNote.kt new file mode 100644 index 00000000..132fb173 --- /dev/null +++ b/app/src/main/java/com/texthip/thip/ui/common/cards/CardNote.kt @@ -0,0 +1,104 @@ +package com.texthip.thip.ui.common.cards + +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Icon +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +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 com.texthip.thip.R +import com.texthip.thip.ui.theme.ThipTheme.colors +import com.texthip.thip.ui.theme.ThipTheme.typography + +@Composable +fun CardNote( + currentPage: Int, + percentage: Int, + onClick: () -> Unit = { } +) { + Column( + modifier = Modifier + .fillMaxWidth() + .background(color = colors.DarkGrey02, shape = RoundedCornerShape(12.dp)) + .padding(vertical = 16.dp, horizontal = 12.dp) + .clickable { onClick() }, + verticalArrangement = Arrangement.spacedBy(12.dp) + ) { + Row( + modifier = Modifier.fillMaxWidth(), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.SpaceBetween + ) { + Text( + text = stringResource(R.string.record_book), + style = typography.smalltitle_sb600_s16_h24, + color = colors.White, + ) + + Icon( + painter = painterResource(R.drawable.ic_chevron), + contentDescription = "Chevron Icon", + tint = colors.Grey02, + ) + } + + Text( + text = stringResource(R.string.current_page, currentPage), + style = typography.info_m500_s12, + color = colors.Grey, + ) + + Row( + verticalAlignment = Alignment.Bottom + ) { + Text( + text = percentage.toString(), + style = typography.smalltitle_sb600_s16_h20, + color = colors.Purple, + ) + Text( + text = stringResource(R.string.percent), + style = typography.menu_sb600_s12, + color = colors.Purple, + ) + } + + Box( + modifier = Modifier + .fillMaxWidth() + .height(8.dp) + .background(color = colors.Grey02, shape = RoundedCornerShape(12.dp)) + ) { + Box( + modifier = Modifier + .fillMaxWidth(fraction = percentage / 100f) + .fillMaxHeight() + .background(color = colors.Purple, shape = RoundedCornerShape(12.dp)) + ) + } + } +} + +@Preview +@Composable +private fun CardNotePreview() { + CardNote( + currentPage = 50, + percentage = 30, + onClick = { } + ) +} \ No newline at end of file diff --git a/app/src/main/java/com/texthip/thip/ui/common/cards/CardVote.kt b/app/src/main/java/com/texthip/thip/ui/common/cards/CardVote.kt new file mode 100644 index 00000000..e8c7c5ec --- /dev/null +++ b/app/src/main/java/com/texthip/thip/ui/common/cards/CardVote.kt @@ -0,0 +1,120 @@ +package com.texthip.thip.ui.common.cards + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.pager.HorizontalPager +import androidx.compose.foundation.pager.rememberPagerState +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.mutableStateMapOf +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.texthip.thip.R +import com.texthip.thip.ui.common.buttons.GroupVoteButton +import com.texthip.thip.ui.group.room.mock.VoteData +import com.texthip.thip.ui.theme.ThipTheme.colors +import com.texthip.thip.ui.theme.ThipTheme.typography + +@Composable +fun CardVote( + voteData: List +) { + val pageCount = voteData.size + val pagerState = rememberPagerState(pageCount = { pageCount }) + + // 각 투표에 따라 투표한거 기록 + val selectedIndexes = remember { mutableStateMapOf() } + + Column( + modifier = Modifier + .fillMaxWidth() + .background(color = colors.DarkGrey02, shape = RoundedCornerShape(12.dp)) + .padding(vertical = 16.dp), + verticalArrangement = Arrangement.spacedBy(12.dp), + ) { + Text( + text = stringResource(R.string.vote_title), + style = typography.smalltitle_sb600_s16_h24, + color = colors.White, + modifier = Modifier.padding(horizontal = 12.dp) + ) + + + HorizontalPager( + state = pagerState, + modifier = Modifier.fillMaxWidth() + ) { page -> + val item = voteData[page] + val selectedIndex = selectedIndexes[page] + + Column( + modifier = Modifier.padding(horizontal = 12.dp), + verticalArrangement = Arrangement.spacedBy(10.dp) + ) { + Text( + text = item.description, + style = typography.info_m500_s12, + color = colors.White, + ) + + GroupVoteButton( + options = item.options, + voteResults = item.votes, + selectedIndex = selectedIndex, + onOptionSelected = { selectedIndexes[page] = it } + ) + } + } + + Row( + Modifier + .fillMaxWidth(), + horizontalArrangement = Arrangement.Center + ) { + repeat(pageCount) { iteration -> + val color = if (pagerState.currentPage == iteration) colors.White else colors.Grey02 + Box( + modifier = Modifier + .padding(horizontal = 12.dp) + .background(color, CircleShape) + .size(4.dp) + ) + } + } + } +} + +@Preview +@Composable +private fun CardVotePreview() { + val mockVoteData = listOf( + VoteData( + description = "투표 내용입니다...", + options = listOf("김땡땡", "이땡땡", "박땡땡", "최땡땡", "정땡땡"), + votes = listOf(50, 10, 20, 15, 5) + ), + VoteData( + description = "옆으로 넘긴 다른 투표 01", + options = listOf("어쩌구", "저쩌구", "삼번", "사번"), + votes = listOf(25, 45, 20, 10) + ), + VoteData( + description = "옆으로 넘긴 다른 투표 02", + options = listOf("투표 제목과 항목 버튼이 가로 스크롤되고", "아래 캐러셀 닷은", "위치 그대로, 강조점만 바뀌도록."), + votes = listOf(40, 35, 25) + ) + ) + + CardVote(voteData = mockVoteData) +} \ No newline at end of file diff --git a/app/src/main/java/com/texthip/thip/ui/common/forms/CommentTextField.kt b/app/src/main/java/com/texthip/thip/ui/common/forms/CommentTextField.kt new file mode 100644 index 00000000..851afb5a --- /dev/null +++ b/app/src/main/java/com/texthip/thip/ui/common/forms/CommentTextField.kt @@ -0,0 +1,167 @@ +package com.texthip.thip.ui.common.forms + +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.foundation.shape.RoundedCornerShape +import androidx.compose.foundation.text.BasicTextField +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +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.SolidColor +import androidx.compose.ui.platform.LocalFocusManager +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.SpanStyle +import androidx.compose.ui.text.buildAnnotatedString +import androidx.compose.ui.text.withStyle +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.texthip.thip.R +import com.texthip.thip.ui.theme.ThipTheme +import com.texthip.thip.ui.theme.ThipTheme.colors +import com.texthip.thip.ui.theme.ThipTheme.typography + +@Composable +fun CommentTextField( + modifier: Modifier = Modifier, + hint: String, + input: String, + onInputChange: (String) -> Unit, + onSendClick: () -> Unit, + replyTo: String? = null, + onCancelReply: () -> Unit = {} +) { + val focusManager = LocalFocusManager.current + + Column( + modifier = modifier + .fillMaxWidth() + .background(color = colors.DarkGrey02) + ) { + if (replyTo != null) { + Row( + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier + .padding(start = 20.dp, end = 20.dp, top = 10.dp, bottom = 2.dp) + .height(24.dp) + ) { + Icon( + painter = painterResource(R.drawable.ic_reply), + contentDescription = "Reply Arrow", + tint = colors.Grey01, + modifier = Modifier.size(24.dp) + ) + Spacer(modifier = Modifier.width(4.dp)) + Text( + text = buildAnnotatedString { + withStyle(style = SpanStyle(color = colors.NeonGreen)) { + append("@$replyTo") + } + append(stringResource(R.string.comment_to)) + }, + style = typography.info_r400_s12_h24, + color = colors.Grey01 + ) + Spacer(modifier = Modifier.weight(1f)) + IconButton(onClick = onCancelReply) { + Icon( + painter = painterResource(R.drawable.ic_x), + contentDescription = "Cancel Reply", + tint = colors.White + ) + } + } + } + + Row( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 20.dp, vertical = 10.dp) + .height(36.dp) + .background(colors.DarkGrey, shape = RoundedCornerShape(20.dp)), + verticalAlignment = Alignment.CenterVertically + ) { + BasicTextField( + value = input, + onValueChange = onInputChange, + singleLine = true, + textStyle = typography.menu_r400_s14_h24.copy(color = colors.White), + modifier = Modifier + .weight(1f) + .padding(start = 12.dp), + cursorBrush = SolidColor(colors.NeonGreen), + decorationBox = { innerTextField -> + if (input.isEmpty()) { + Text( + text = hint, + color = colors.Grey02, + style = typography.menu_r400_s14_h24 + ) + } + innerTextField() + } + ) + + // 전송 버튼 + val isEnabled = input.isNotBlank() + Box( + modifier = Modifier + .padding(end = 4.dp) + .size(width = 42.dp, height = 28.dp) + .background( + color = if (isEnabled) colors.Purple else colors.Grey02, + shape = RoundedCornerShape(20.dp) + ) + .clickable(enabled = isEnabled) { + onSendClick() + focusManager.clearFocus() + }, + contentAlignment = Alignment.Center + ) { + Icon( + painter = painterResource(id = R.drawable.ic_send), + contentDescription = "Send", + tint = colors.White, + modifier = Modifier.size(24.dp) + ) + } + } + } +} + +@Preview +@Composable +private fun CommentTextFieldPreview() { + var input by remember { mutableStateOf("") } + var replyTo by remember { mutableStateOf("사용자") } + + ThipTheme { + CommentTextField( + input = input, + hint = "00님에게 댓글을 남겨보세요.", + onInputChange = { input = it }, + onSendClick = { + input = "" + replyTo = null + }, + replyTo = replyTo, + onCancelReply = { replyTo = null } + ) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/texthip/thip/ui/common/header/ProfileBar.kt b/app/src/main/java/com/texthip/thip/ui/common/header/ProfileBar.kt index 50eba01b..20c08449 100644 --- a/app/src/main/java/com/texthip/thip/ui/common/header/ProfileBar.kt +++ b/app/src/main/java/com/texthip/thip/ui/common/header/ProfileBar.kt @@ -2,12 +2,13 @@ package com.texthip.thip.ui.common.header import androidx.compose.foundation.Image import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement 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.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.foundation.shape.CircleShape @@ -18,7 +19,6 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.ColorFilter import androidx.compose.ui.graphics.painter.Painter import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource @@ -36,14 +36,16 @@ fun ProfileBar( profileImage: Painter?, topText: String, bottomText: String, + bottomTextColor: Color = colors.NeonGreen, // todo: 서버에서 색 보내주는걸로 받기? showSubscriberInfo: Boolean, subscriberCount: Int = 0, - hoursAgo: Int = 0 + hoursAgo: Int = 0, + onClick: () -> Unit = { } ) { Row( modifier = modifier .fillMaxWidth() - .padding(horizontal = 16.dp, vertical = 12.dp), + .clickable { onClick() }, verticalAlignment = Alignment.CenterVertically ) { if (profileImage != null) { @@ -63,7 +65,10 @@ fun ProfileBar( ) } Spacer(modifier = Modifier.width(8.dp)) - Column(modifier = Modifier.weight(1f)) { + Column( + modifier = Modifier.weight(1f), + verticalArrangement = Arrangement.spacedBy(4.dp) + ) { Text( text = topText, style = typography.view_m500_s14, @@ -72,7 +77,7 @@ fun ProfileBar( Text( text = bottomText, style = typography.info_r400_s12, - color = colors.NeonGreen + color = bottomTextColor ) } if (showSubscriberInfo) { @@ -80,11 +85,17 @@ fun ProfileBar( verticalAlignment = Alignment.CenterVertically ) { Text( - text = stringResource(R.string.subscriber_num,subscriberCount), + text = subscriberCount.toString(), style = typography.timedate_r400_s11, color = colors.Grey01 ) - Spacer(modifier = Modifier.width(4.dp)) + Spacer(modifier = Modifier.width(2.dp)) + Text( + text = stringResource(R.string.subscriber_num), + style = typography.timedate_r400_s11, + color = colors.Grey01 + ) + Spacer(modifier = Modifier.width(2.dp)) Icon( painter = painterResource(id = R.drawable.ic_chevron_right), contentDescription = "화살표", @@ -94,7 +105,7 @@ fun ProfileBar( } } else { Text( - text = stringResource(R.string.hours_ago,hoursAgo), + text = stringResource(R.string.hours_ago, hoursAgo), style = typography.timedate_r400_s11, color = colors.Grey01 ) diff --git a/app/src/main/java/com/texthip/thip/ui/common/header/ProfileBarWithDate.kt b/app/src/main/java/com/texthip/thip/ui/common/header/ProfileBarWithDate.kt index a9bef9eb..5bb9c8c0 100644 --- a/app/src/main/java/com/texthip/thip/ui/common/header/ProfileBarWithDate.kt +++ b/app/src/main/java/com/texthip/thip/ui/common/header/ProfileBarWithDate.kt @@ -3,17 +3,16 @@ package com.texthip.thip.ui.common.header import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement 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.padding +import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.foundation.shape.CircleShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.MoreVert import androidx.compose.material3.Icon import androidx.compose.material3.Text import androidx.compose.runtime.Composable @@ -39,39 +38,43 @@ fun ProfileBarWithDate( ) { Row( modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 16.dp, vertical = 8.dp), - verticalAlignment = Alignment.CenterVertically + .fillMaxWidth(), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.SpaceBetween ) { - if (profileImage != null) { - Image( - painter = profileImage, - contentDescription = "프로필 이미지", - modifier = Modifier - .size(24.dp) - .clip(CircleShape) - ) - } else { - Box( - modifier = Modifier - .size(24.dp) - .clip(CircleShape) - .background(colors.Grey) - ) - } - Spacer(modifier = Modifier.width(8.dp)) - Column(modifier = Modifier.weight(1f)) { - Text( - text = nickname, - style = typography.menu_sb600_s12, - color = colors.White - ) - Text( - text = dateText, - style = typography.timedate_r400_s11, - color = colors.Grey01 - ) + Row { + if (profileImage != null) { + Image( + painter = profileImage, + contentDescription = "프로필 이미지", + modifier = Modifier + .size(24.dp) + .clip(CircleShape) + ) + } else { + Box( + modifier = Modifier + .size(24.dp) + .clip(CircleShape) + .background(colors.Grey) + ) + } + Spacer(modifier = Modifier.width(4.dp)) + Column { + Text( + text = nickname, + style = typography.menu_sb600_s12, + color = colors.White + ) + Spacer(modifier = Modifier.height(2.dp)) + Text( + text = dateText, + style = typography.timedate_r400_s11, + color = colors.Grey01 + ) + } } + Icon( painter = painterResource(R.drawable.ic_more), contentDescription = "메뉴", @@ -82,6 +85,7 @@ fun ProfileBarWithDate( ) } } + @Preview(showBackground = true) @Composable fun PreviewProfileBarWithDate() { diff --git a/app/src/main/java/com/texthip/thip/ui/common/topappbar/BookTopAppBar.kt b/app/src/main/java/com/texthip/thip/ui/common/topappbar/BookTopAppBar.kt deleted file mode 100644 index 69e3e31f..00000000 --- a/app/src/main/java/com/texthip/thip/ui/common/topappbar/BookTopAppBar.kt +++ /dev/null @@ -1,63 +0,0 @@ -package com.texthip.thip.ui.common.topappbar - -import androidx.compose.material3.ExperimentalMaterial3Api -import androidx.compose.material3.Icon -import androidx.compose.material3.IconButton -import androidx.compose.material3.TopAppBar -import androidx.compose.material3.TopAppBarDefaults -import androidx.compose.runtime.Composable -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.tooling.preview.Preview -import com.texthip.thip.R -import com.texthip.thip.ui.common.view.CountingBar -import com.texthip.thip.ui.theme.ThipTheme - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun BookTopAppBar( - count: Int = 0, - onLeftClick: () -> Unit, - onRightClick: () -> Unit, -) { - TopAppBar( - navigationIcon = { - IconButton(onClick = onLeftClick) { - Icon( - painter = painterResource(R.drawable.ic_arrow_back), - contentDescription = "Back Button", - tint = Color.Unspecified - ) - } - }, - title = { - CountingBar( - count = count, - ) - }, - actions = { - IconButton(onClick = onRightClick) { - Icon( - painter = painterResource(R.drawable.ic_more), - contentDescription = "More Options", - tint = Color.Unspecified - ) - } - }, - colors = TopAppBarDefaults.topAppBarColors( - containerColor = Color.Transparent, - ), - ) -} - -@Preview(showBackground = false) -@Composable -private fun BookTopAppBarPreview() { - ThipTheme { - BookTopAppBar( - onLeftClick = { }, - onRightClick = { }, - count = 210 - ) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/texthip/thip/ui/common/topappbar/DefaultTopAppBar.kt b/app/src/main/java/com/texthip/thip/ui/common/topappbar/DefaultTopAppBar.kt index 8d51b534..0baeae07 100644 --- a/app/src/main/java/com/texthip/thip/ui/common/topappbar/DefaultTopAppBar.kt +++ b/app/src/main/java/com/texthip/thip/ui/common/topappbar/DefaultTopAppBar.kt @@ -1,22 +1,25 @@ package com.texthip.thip.ui.common.topappbar +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.material3.CenterAlignedTopAppBar -import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding import androidx.compose.material3.Icon -import androidx.compose.material3.IconButton import androidx.compose.material3.Text -import androidx.compose.material3.TopAppBarDefaults 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.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp import com.texthip.thip.R import com.texthip.thip.ui.theme.ThipTheme.colors import com.texthip.thip.ui.theme.ThipTheme.typography -@OptIn(ExperimentalMaterial3Api::class) @Composable fun DefaultTopAppBar( title: String = stringResource(R.string.page_name), @@ -25,40 +28,41 @@ fun DefaultTopAppBar( onLeftClick: () -> Unit, onRightClick: () -> Unit = {}, ) { - CenterAlignedTopAppBar( - navigationIcon = { - IconButton(onClick = onLeftClick) { - Icon( - painter = painterResource(R.drawable.ic_arrow_back), - contentDescription = "Back Button", - tint = Color.Unspecified - ) - } - }, - title = { - if (isTitleVisible) { - Text( - text = title, - color = colors.White, - style = typography.bigtitle_b700_s22_h24 - ) - } - }, - actions = { - if (isRightIconVisible) { - IconButton(onClick = onRightClick) { - Icon( - painter = painterResource(R.drawable.ic_more), - contentDescription = "More Options", - tint = Color.Unspecified - ) - } - } - }, - colors = TopAppBarDefaults.topAppBarColors( - containerColor = Color.Transparent, - ), - ) + Box( + modifier = Modifier + .fillMaxWidth() + .background(color = colors.Black) + .padding(horizontal = 20.dp, vertical = 16.dp) + ) { + Icon( + painter = painterResource(R.drawable.ic_arrow_back), + contentDescription = "Back Button", + tint = Color.Unspecified, + modifier = Modifier + .align(Alignment.CenterStart) + .clickable { onLeftClick() } + ) + + if (isTitleVisible) { + Text( + text = title, + color = colors.White, + style = typography.bigtitle_b700_s22_h24, + modifier = Modifier.align(Alignment.Center) + ) + } + + if (isRightIconVisible) { + Icon( + painter = painterResource(R.drawable.ic_more), + contentDescription = "More Options", + tint = Color.Unspecified, + modifier = Modifier + .align(Alignment.CenterEnd) + .clickable { onRightClick() } + ) + } + } } @Preview diff --git a/app/src/main/java/com/texthip/thip/ui/common/topappbar/FeedListTopAppBar.kt b/app/src/main/java/com/texthip/thip/ui/common/topappbar/FeedListTopAppBar.kt index aace1689..6168cb01 100644 --- a/app/src/main/java/com/texthip/thip/ui/common/topappbar/FeedListTopAppBar.kt +++ b/app/src/main/java/com/texthip/thip/ui/common/topappbar/FeedListTopAppBar.kt @@ -1,15 +1,17 @@ package com.texthip.thip.ui.common.topappbar +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.width -import androidx.compose.material3.CenterAlignedTopAppBar -import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon -import androidx.compose.material3.IconButton import androidx.compose.material3.Text -import androidx.compose.material3.TopAppBarDefaults 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.res.painterResource @@ -21,7 +23,6 @@ import com.texthip.thip.R import com.texthip.thip.ui.theme.ThipTheme.colors import com.texthip.thip.ui.theme.ThipTheme.typography -@OptIn(ExperimentalMaterial3Api::class) @Composable fun FeedListTopAppBar( nickname: String = "ThipUser 01ThipUser 01", @@ -29,54 +30,55 @@ fun FeedListTopAppBar( onLeftClick: () -> Unit, onRightClick: () -> Unit = {}, ) { - CenterAlignedTopAppBar( - navigationIcon = { - IconButton(onClick = onLeftClick) { - Icon( - painter = painterResource(R.drawable.ic_arrow_back), - contentDescription = "Back Button", - tint = Color.Unspecified - ) - } - }, - title = { - Row( - horizontalArrangement = Arrangement.spacedBy(8.dp) - ) { - Text( - text = nickname, - color = colors.White, - style = typography.bigtitle_b700_s22_h24, - modifier = Modifier.width(100.dp), - maxLines = 1, - overflow = TextOverflow.Ellipsis, - ) - Text( - text = stringResource(R.string.subscriber), - color = colors.White, - style = typography.bigtitle_b700_s22_h24, - modifier = Modifier.width(100.dp), - maxLines = 1 - ) - } - }, - actions = { - if (isRightIconVisible) { - IconButton(onClick = { - onRightClick() - }) { - Icon( - painter = painterResource(R.drawable.ic_more), - contentDescription = "More Options", - tint = Color.Unspecified - ) - } - } - }, - colors = TopAppBarDefaults.topAppBarColors( - containerColor = Color.Transparent, - ), - ) + Box( + modifier = Modifier + .fillMaxWidth() + .background(color = colors.Black) + .padding(horizontal = 20.dp, vertical = 16.dp), + contentAlignment = Alignment.Center + ) { + Icon( + painter = painterResource(R.drawable.ic_arrow_back), + contentDescription = "Back Button", + tint = Color.Unspecified, + modifier = Modifier + .align(Alignment.CenterStart) + .clickable { onLeftClick() } + ) + + Row( + modifier = Modifier.align(Alignment.Center), + horizontalArrangement = Arrangement.spacedBy(8.dp), + verticalAlignment = Alignment.CenterVertically + ) { + Text( + text = nickname, + color = colors.White, + style = typography.bigtitle_b700_s22_h24, + modifier = Modifier.width(100.dp), + maxLines = 1, + overflow = TextOverflow.Ellipsis + ) + Text( + text = stringResource(R.string.subscriber), + color = colors.White, + style = typography.bigtitle_b700_s22_h24, + modifier = Modifier.width(100.dp), + maxLines = 1 + ) + } + + if (isRightIconVisible) { + Icon( + painter = painterResource(R.drawable.ic_more), + contentDescription = "More Options", + tint = Color.Unspecified, + modifier = Modifier + .align(Alignment.CenterEnd) + .clickable { onRightClick() } + ) + } + } } @Preview diff --git a/app/src/main/java/com/texthip/thip/ui/common/topappbar/GradationTopAppBar.kt b/app/src/main/java/com/texthip/thip/ui/common/topappbar/GradationTopAppBar.kt new file mode 100644 index 00000000..5d766e07 --- /dev/null +++ b/app/src/main/java/com/texthip/thip/ui/common/topappbar/GradationTopAppBar.kt @@ -0,0 +1,90 @@ +package com.texthip.thip.ui.common.topappbar + +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.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Icon +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Brush +import androidx.compose.ui.graphics.Color +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 com.texthip.thip.R +import com.texthip.thip.ui.common.view.CountingBar +import com.texthip.thip.ui.theme.ThipTheme.colors + +@Composable +fun GradationTopAppBar( + isImageVisible: Boolean = false, + count: Int = 0, + onLeftClick: () -> Unit, + onRightClick: () -> Unit, +) { + val bgColor = Brush.verticalGradient( + colors = listOf( + colors.Black, + colors.Black00 + ) + ) + + Box( + modifier = Modifier + .fillMaxWidth() + .background(brush = bgColor) + .padding(horizontal = 20.dp) + .height(56.dp), + contentAlignment = Alignment.Center, + ) { + Icon( + painter = painterResource(R.drawable.ic_arrow_back), + contentDescription = "Back Button", + tint = Color.Unspecified, + modifier = Modifier + .align(Alignment.CenterStart) + .clickable { onLeftClick() } + ) + + if (isImageVisible) { + CountingBar( + modifier = Modifier + .align(Alignment.Center), + content = stringResource(R.string.reading_user_num, count) + ) + } + + Icon( + painter = painterResource(R.drawable.ic_more), + contentDescription = "More Options", + tint = Color.Unspecified, + modifier = Modifier + .align(Alignment.CenterEnd) + .clickable { onRightClick() } + ) + } +} + +@Preview(showBackground = true) +@Composable +private fun GradationTopAppBarPreview() { + Column { + GradationTopAppBar( + onLeftClick = { }, + onRightClick = { }, + count = 210 + ) + GradationTopAppBar( + isImageVisible = true, + onLeftClick = { }, + onRightClick = { }, + count = 210 + ) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/texthip/thip/ui/common/topappbar/InputTopAppBar.kt b/app/src/main/java/com/texthip/thip/ui/common/topappbar/InputTopAppBar.kt index 8da648f4..300d4b20 100644 --- a/app/src/main/java/com/texthip/thip/ui/common/topappbar/InputTopAppBar.kt +++ b/app/src/main/java/com/texthip/thip/ui/common/topappbar/InputTopAppBar.kt @@ -1,14 +1,16 @@ package com.texthip.thip.ui.common.topappbar +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.fillMaxWidth +import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding -import androidx.compose.material3.CenterAlignedTopAppBar -import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon -import androidx.compose.material3.IconButton import androidx.compose.material3.Text -import androidx.compose.material3.TopAppBarDefaults 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.res.painterResource @@ -20,7 +22,6 @@ import com.texthip.thip.ui.common.buttons.HeaderButton import com.texthip.thip.ui.theme.ThipTheme.colors import com.texthip.thip.ui.theme.ThipTheme.typography -@OptIn(ExperimentalMaterial3Api::class) @Composable fun InputTopAppBar( title: String = stringResource(R.string.page_name), @@ -30,41 +31,41 @@ fun InputTopAppBar( onLeftClick: () -> Unit = {}, onRightClick: () -> Unit = {}, ) { - CenterAlignedTopAppBar( - navigationIcon = { - if (isLeftIconVisible) { - IconButton(onClick = onLeftClick) { - Icon( - painter = painterResource(R.drawable.ic_arrow_back), - contentDescription = "Back Button", - tint = Color.Unspecified - ) - } - } - }, - title = { - Text( - text = title, - color = colors.White, - style = typography.bigtitle_b700_s22_h24 + Box( + modifier = Modifier + .fillMaxWidth() + .background(color = colors.Black) + .height(56.dp) + .padding(horizontal = 20.dp), + contentAlignment = Alignment.Center + ) { + if (isLeftIconVisible) { + Icon( + painter = painterResource(R.drawable.ic_arrow_back), + contentDescription = "Back Button", + tint = Color.Unspecified, + modifier = Modifier + .align(Alignment.CenterStart) + .clickable { onLeftClick() } ) - }, - actions = { - HeaderButton( - text = rightButtonName, - enabled = isRightButtonEnabled, - onClick = { - onRightClick() - }, - modifier = Modifier.padding( - end = 18.dp - ) - ) - }, - colors = TopAppBarDefaults.topAppBarColors( - containerColor = Color.Transparent, - ), - ) + } + + Text( + text = title, + color = colors.White, + style = typography.bigtitle_b700_s22_h24, + modifier = Modifier.align(Alignment.Center) + ) + + HeaderButton( + text = rightButtonName, + enabled = isRightButtonEnabled, + onClick = onRightClick, + modifier = Modifier + .align(Alignment.CenterEnd) + .padding(end = 2.dp) + ) + } } @Preview diff --git a/app/src/main/java/com/texthip/thip/ui/common/topappbar/LeftNameTopAppBar.kt b/app/src/main/java/com/texthip/thip/ui/common/topappbar/LeftNameTopAppBar.kt index fdfb0d63..3ef8ccaf 100644 --- a/app/src/main/java/com/texthip/thip/ui/common/topappbar/LeftNameTopAppBar.kt +++ b/app/src/main/java/com/texthip/thip/ui/common/topappbar/LeftNameTopAppBar.kt @@ -1,15 +1,17 @@ package com.texthip.thip.ui.common.topappbar +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement.Absolute.spacedBy +import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding -import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon -import androidx.compose.material3.IconButton import androidx.compose.material3.Text -import androidx.compose.material3.TopAppBar -import androidx.compose.material3.TopAppBarDefaults 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.graphics.painter.Painter @@ -21,66 +23,62 @@ import com.texthip.thip.R import com.texthip.thip.ui.theme.ThipTheme.colors import com.texthip.thip.ui.theme.ThipTheme.typography -@OptIn(ExperimentalMaterial3Api::class) @Composable fun LeftNameTopAppBar( title: String = stringResource(R.string.page_name), isLeftIconVisible: Boolean = false, isRightIconVisible: Boolean = false, - leftIcon: Painter, - rightIcon: Painter, + leftIcon: Painter = painterResource(R.drawable.ic_search), + rightIcon: Painter = painterResource(R.drawable.ic_plus), onLeftClick: () -> Unit = {}, onRightClick: () -> Unit = {} ) { - TopAppBar( - navigationIcon = { - Text( - text = title, - color = colors.White, - style = typography.bigtitle_b700_s22_h24, - modifier = Modifier.padding(start = 18.dp) - ) - }, - title = { - Spacer(modifier = Modifier) - }, - actions = { + Box( + modifier = Modifier + .fillMaxWidth() + .background(color = colors.Black) + .padding(horizontal = 20.dp, vertical = 20.dp), + contentAlignment = Alignment.CenterStart + ) { + Text( + text = title, + color = colors.White, + style = typography.bigtitle_b700_s22_h24, + modifier = Modifier.align(Alignment.CenterStart) + ) + + Row( + modifier = Modifier + .align(Alignment.CenterEnd), + horizontalArrangement = spacedBy(20.dp), + ) { if (isLeftIconVisible) { - IconButton(onClick = onLeftClick) { - Icon( - painter = leftIcon, - contentDescription = "Left Icon", - tint = Color.Unspecified - ) - } + Icon( + painter = leftIcon, + contentDescription = "Left Icon", + tint = Color.Unspecified, + modifier = Modifier.clickable { onLeftClick() } + ) } if (isRightIconVisible) { - IconButton(onClick = onRightClick) { - Icon( - painter = rightIcon, - contentDescription = "Right Icon", - tint = Color.Unspecified - ) - } + Icon( + painter = rightIcon, + contentDescription = "Right Icon", + tint = Color.Unspecified, + modifier = Modifier.clickable { onRightClick() } + ) } - }, - colors = TopAppBarDefaults.topAppBarColors( - containerColor = Color.Transparent, - ) - ) + } + } } + @Preview @Composable private fun LeftNameTopAppBarPreview() { Column { + LeftNameTopAppBar() LeftNameTopAppBar( - leftIcon = painterResource(R.drawable.ic_search), - rightIcon = painterResource(R.drawable.ic_plus) - ) - LeftNameTopAppBar( - leftIcon = painterResource(R.drawable.ic_search), - rightIcon = painterResource(R.drawable.ic_plus), isLeftIconVisible = true, isRightIconVisible = true ) diff --git a/app/src/main/java/com/texthip/thip/ui/common/topappbar/LogoTopAppBar.kt b/app/src/main/java/com/texthip/thip/ui/common/topappbar/LogoTopAppBar.kt index 31c5fe2b..1885b647 100644 --- a/app/src/main/java/com/texthip/thip/ui/common/topappbar/LogoTopAppBar.kt +++ b/app/src/main/java/com/texthip/thip/ui/common/topappbar/LogoTopAppBar.kt @@ -1,15 +1,17 @@ package com.texthip.thip.ui.common.topappbar import androidx.compose.foundation.Image -import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding -import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon -import androidx.compose.material3.IconButton -import androidx.compose.material3.TopAppBar -import androidx.compose.material3.TopAppBarDefaults 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.graphics.painter.Painter @@ -17,8 +19,8 @@ import androidx.compose.ui.res.painterResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.texthip.thip.R +import com.texthip.thip.ui.theme.ThipTheme.colors -@OptIn(ExperimentalMaterial3Api::class) @Composable fun LogoTopAppBar( leftIcon: Painter, @@ -32,39 +34,41 @@ fun LogoTopAppBar( painterResource(R.drawable.ic_notice) } - TopAppBar( - navigationIcon = { - Image( - painter = painterResource(R.drawable.ic_logo), - contentDescription = "Logo", - modifier = Modifier - .height(24.dp) - .padding(start = 18.dp), - ) - }, - title = { - Spacer(modifier = Modifier) - }, - actions = { - IconButton(onClick = onLeftClick) { - Icon( - painter = leftIcon, - contentDescription = "Left Icon", - tint = Color.Unspecified - ) - } - IconButton(onClick = onRightClick) { - Icon( - painter = rightIcon, - contentDescription = "Right Icon", - tint = Color.Unspecified - ) - } - }, - colors = TopAppBarDefaults.topAppBarColors( - containerColor = Color.Transparent, + Box( + modifier = Modifier + .fillMaxWidth() + .background(color = colors.Black) + .padding(horizontal = 20.dp, vertical = 16.dp), + contentAlignment = Alignment.CenterStart + ) { + Image( + painter = painterResource(R.drawable.ic_logo), + contentDescription = "Logo", + modifier = Modifier + .height(24.dp) + .align(Alignment.CenterStart) ) - ) + + Row( + modifier = Modifier + .align(Alignment.CenterEnd), + horizontalArrangement = Arrangement.spacedBy(20.dp), + verticalAlignment = Alignment.CenterVertically + ) { + Icon( + painter = leftIcon, + contentDescription = "Left Icon", + tint = Color.Unspecified, + modifier = Modifier.clickable { onLeftClick() } + ) + Icon( + painter = rightIcon, + contentDescription = "Right Icon", + tint = Color.Unspecified, + modifier = Modifier.clickable { onRightClick() } + ) + } + } } @Preview @@ -73,7 +77,7 @@ private fun LogoTopAppBarPreview() { LogoTopAppBar( leftIcon = painterResource(R.drawable.ic_search), hasNotification = true, - onLeftClick = { }, - onRightClick = { } + onLeftClick = {}, + onRightClick = {} ) } \ No newline at end of file diff --git a/app/src/main/java/com/texthip/thip/ui/common/view/CountingBar.kt b/app/src/main/java/com/texthip/thip/ui/common/view/CountingBar.kt index 3b063009..03876a9b 100644 --- a/app/src/main/java/com/texthip/thip/ui/common/view/CountingBar.kt +++ b/app/src/main/java/com/texthip/thip/ui/common/view/CountingBar.kt @@ -2,9 +2,7 @@ package com.texthip.thip.ui.common.view import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.Text @@ -21,24 +19,21 @@ import com.texthip.thip.ui.theme.ThipTheme.typography @Composable fun CountingBar( modifier: Modifier = Modifier, - count: Int + content: String, ) { - Box( + Row( modifier = modifier .background(colors.DarkGrey02, shape = RoundedCornerShape(16.dp)) - .padding(horizontal = 16.dp, vertical = 8.dp) + .padding(horizontal = 16.dp, vertical = 8.dp), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.Center, ) { - Row( - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.Center, - modifier = Modifier.fillMaxWidth() - ) { - Text( - text = stringResource(R.string.reading_user_num, count), - color = colors.NeonGreen, - style = typography.menu_r400_s14_h24 - ) - } + Text( + content, + color = colors.NeonGreen, + style = typography.menu_r400_s14_h24, + maxLines = 1 + ) } } @@ -46,7 +41,6 @@ fun CountingBar( @Composable private fun CountingBarPrev() { CountingBar( - count = 200, - modifier = Modifier.fillMaxWidth() + content = stringResource(R.string.reading_user_num, 200), ) } \ No newline at end of file diff --git a/app/src/main/java/com/texthip/thip/ui/group/room/component/GroupRoomBody.kt b/app/src/main/java/com/texthip/thip/ui/group/room/component/GroupRoomBody.kt new file mode 100644 index 00000000..0c37743e --- /dev/null +++ b/app/src/main/java/com/texthip/thip/ui/group/room/component/GroupRoomBody.kt @@ -0,0 +1,79 @@ +package com.texthip.thip.ui.group.room.component + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.padding +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.texthip.thip.R +import com.texthip.thip.ui.common.buttons.ActionBookButton +import com.texthip.thip.ui.common.cards.CardChat +import com.texthip.thip.ui.common.cards.CardNote +import com.texthip.thip.ui.common.cards.CardVote +import com.texthip.thip.ui.group.room.mock.GroupRoomBodyData +import com.texthip.thip.ui.group.room.mock.VoteData + +@Composable +fun GroupRoomBody( + modifier: Modifier = Modifier, + data: GroupRoomBodyData +) { + Column( + modifier = modifier.padding(horizontal = 20.dp), + verticalArrangement = Arrangement.spacedBy(20.dp) + ) { + ActionBookButton( + bookTitle = data.bookTitle, + bookAuthor = data.bookAuthor + ) {} + + CardNote( + currentPage = data.currentPage, + percentage = data.percentage, + ) {} + + CardChat( + title = stringResource(R.string.group_room_chat), + subtitle = stringResource(R.string.group_room_chat_description) + ) {} + + CardVote( + voteData = data.voteList + ) + } +} + +@Preview +@Composable +private fun GroupRoomBodyPreview() { + val mockVoteData = listOf( + VoteData( + description = "투표 내용입니다...", + options = listOf("김땡땡", "이땡땡", "박땡땡", "최땡땡", "정땡땡"), + votes = listOf(50, 10, 20, 15, 5) + ), + VoteData( + description = "옆으로 넘긴 다른 투표 01", + options = listOf("어쩌구", "저쩌구", "삼번", "사번"), + votes = listOf(25, 45, 20, 10) + ), + VoteData( + description = "옆으로 넘긴 다른 투표 02", + options = listOf("투표 제목과 항목 버튼이 가로 스크롤되고", "아래 캐러셀 닷은", "위치 그대로, 강조점만 바뀌도록."), + votes = listOf(40, 35, 25) + ) + ) + + GroupRoomBody( + data = GroupRoomBodyData( + bookTitle = "호르몬 체인지", + bookAuthor = "최정화", + currentPage = 100, + percentage = 50, + voteList = mockVoteData + ) + ) +} \ No newline at end of file diff --git a/app/src/main/java/com/texthip/thip/ui/group/room/component/GroupRoomHeader.kt b/app/src/main/java/com/texthip/thip/ui/group/room/component/GroupRoomHeader.kt new file mode 100644 index 00000000..5cf61e14 --- /dev/null +++ b/app/src/main/java/com/texthip/thip/ui/group/room/component/GroupRoomHeader.kt @@ -0,0 +1,181 @@ +package com.texthip.thip.ui.group.room.component + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +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.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +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.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.texthip.thip.R +import com.texthip.thip.ui.group.room.mock.GroupRoomHeaderData +import com.texthip.thip.ui.theme.ThipTheme.colors +import com.texthip.thip.ui.theme.ThipTheme.typography + +@Composable +fun GroupRoomHeader( + data: GroupRoomHeaderData +) { + Column( + modifier = Modifier.padding(horizontal = 20.dp) + ) { + Row( + horizontalArrangement = Arrangement.spacedBy(2.dp, Alignment.Start), + verticalAlignment = Alignment.CenterVertically, + ) { + Text( + text = data.groupRoomName, + style = typography.bigtitle_b700_s22_h24, + color = colors.White + ) + + if (data.isPrivate) { + Icon( + painter = painterResource(R.drawable.ic_lock), + contentDescription = "Lock Icon", + tint = Color.Unspecified + ) + } + } + + Spacer(Modifier.height(40.dp)) + + Column { + Text( + text = stringResource(R.string.introduction_content), + style = typography.menu_sb600_s14_h24, + color = colors.White + ) + + Spacer(Modifier.height(4.dp)) + + Text( + text = data.introductionContent, + style = typography.copy_r400_s12_h20, + color = colors.White + ) + } + + Spacer(Modifier.height(20.dp)) + + Row( + horizontalArrangement = Arrangement.spacedBy(40.dp, Alignment.Start), + verticalAlignment = Alignment.CenterVertically, + ) { + Column { + Row { + Icon( + painter = painterResource(R.drawable.ic_calendar), + contentDescription = "Calendar Icon", + tint = Color.Unspecified, + modifier = Modifier.size(20.dp) + ) + Spacer(Modifier.width(2.dp)) + Text( + text = stringResource(R.string.group_active_period), + style = typography.view_m500_s12_h20, + color = colors.White + ) + } + Spacer(Modifier.height(12.dp)) + Text( + text = data.period, + style = typography.timedate_r400_s11, + color = colors.White + ) + } + + Column { + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically, + ) { + Row { + Icon( + painter = painterResource(R.drawable.ic_group), + contentDescription = "Group Icon", + tint = colors.White, + modifier = Modifier.size(20.dp) + ) + Spacer(Modifier.width(2.dp)) + Text( + text = stringResource(R.string.book_mate), + style = typography.view_m500_s12_h20, + color = colors.White + ) + } + + IconButton( + onClick = { /* TODO: Navigate to participant list */ }, + modifier = Modifier.size(24.dp) + ) { + Icon( + painter = painterResource(R.drawable.ic_chevron), + contentDescription = "Participant Icon", + tint = colors.White + ) + } + } + Spacer(Modifier.height(12.dp)) + Text( + text = stringResource(R.string.participate_num, data.participantCount), + style = typography.menu_sb600_s12, + color = colors.White + ) + } + } + + Spacer(Modifier.height(20.dp)) + + Row( + modifier = Modifier + .background(color = colors.Grey03, shape = RoundedCornerShape(40.dp)) + .padding(vertical = 8.dp, horizontal = 12.dp) + ) { + Row { + Text( + text = stringResource(R.string.genre), + style = typography.info_m500_s12, + color = colors.White, + modifier = Modifier.padding(end = 4.dp) + ) + Text( + text = data.genre, + style = typography.info_m500_s12, + color = colors.Orange // TODO: 장르에 맞는 색으로 변경 + ) + } + } + } +} + +@Preview +@Composable +private fun GroupRoomHeaderPreview() { + GroupRoomHeader( + data = GroupRoomHeaderData( + groupRoomName = "호르몬 체인지 완독하는 방", + introductionContent = "‘시집만 읽는 사람들’ 3월 모임입니다. 이번 달 모임방은 심장보다 단단한 토마토 한 알 완독합니다.", + isPrivate = true, + period = "2023.10.01 ~ 2023.10.31", + participantCount = 22, + genre = "문학" + ) + ) +} \ No newline at end of file diff --git a/app/src/main/java/com/texthip/thip/ui/group/room/component/GroupRoomMatesList.kt b/app/src/main/java/com/texthip/thip/ui/group/room/component/GroupRoomMatesList.kt new file mode 100644 index 00000000..cb522094 --- /dev/null +++ b/app/src/main/java/com/texthip/thip/ui/group/room/component/GroupRoomMatesList.kt @@ -0,0 +1,81 @@ +package com.texthip.thip.ui.group.room.component + +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.material3.HorizontalDivider +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.texthip.thip.ui.common.header.ProfileBar +import com.texthip.thip.ui.group.room.mock.GroupRoomMateData +import com.texthip.thip.ui.theme.ThipTheme.colors + +@Composable +fun GroupRoomMatesList( + members: List +) { + Column( + verticalArrangement = Arrangement.spacedBy(16.dp), + modifier = Modifier + .fillMaxWidth() + .padding(20.dp) + ) { + members.forEachIndexed { index, member -> + ProfileBar( + profileImage = member.profileImageUrl, + topText = member.nickname, + bottomText = member.role, + bottomTextColor = member.roleColor, + showSubscriberInfo = true, + subscriberCount = member.subscriberCount + ) {} + + if (index != members.lastIndex) { + HorizontalDivider( + color = colors.DarkGrey02, + thickness = 1.dp + ) + } + } + } +} + +@Preview +@Composable +private fun GroupRoomMatesListPreview() { + GroupRoomMatesList( + members = listOf( + GroupRoomMateData( + profileImageUrl = null, + nickname = "Thiper", + role = "칭호칭호", + roleColor = colors.Yellow, + subscriberCount = 100 + ), + GroupRoomMateData( + profileImageUrl = null, + nickname = "thipthip", + role = "공식 인플루언서", + roleColor = colors.NeonGreen, + subscriberCount = 50 + ), + GroupRoomMateData( + profileImageUrl = null, + nickname = "Thiper", + role = "칭호칭호", + roleColor = colors.Yellow, + subscriberCount = 100 + ), + GroupRoomMateData( + profileImageUrl = null, + nickname = "thip01", + role = "작가", + roleColor = colors.NeonGreen, + subscriberCount = 100 + ), + ) + ) +} \ No newline at end of file diff --git a/app/src/main/java/com/texthip/thip/ui/group/room/mock/GroupRoomBodyData.kt b/app/src/main/java/com/texthip/thip/ui/group/room/mock/GroupRoomBodyData.kt new file mode 100644 index 00000000..6bce72ba --- /dev/null +++ b/app/src/main/java/com/texthip/thip/ui/group/room/mock/GroupRoomBodyData.kt @@ -0,0 +1,9 @@ +package com.texthip.thip.ui.group.room.mock + +data class GroupRoomBodyData( + val bookTitle: String, + val bookAuthor: String, + val currentPage: Int, + val percentage: Int, + val voteList: List +) diff --git a/app/src/main/java/com/texthip/thip/ui/group/room/mock/GroupRoomChatData.kt b/app/src/main/java/com/texthip/thip/ui/group/room/mock/GroupRoomChatData.kt new file mode 100644 index 00000000..039859bb --- /dev/null +++ b/app/src/main/java/com/texthip/thip/ui/group/room/mock/GroupRoomChatData.kt @@ -0,0 +1,10 @@ +package com.texthip.thip.ui.group.room.mock + +import androidx.compose.ui.graphics.painter.Painter + +data class GroupRoomChatData( + val profileImage: Painter?, + val nickname: String, + val date: String, + val content: String +) diff --git a/app/src/main/java/com/texthip/thip/ui/group/room/mock/GroupRoomHeaderData.kt b/app/src/main/java/com/texthip/thip/ui/group/room/mock/GroupRoomHeaderData.kt new file mode 100644 index 00000000..71d9b579 --- /dev/null +++ b/app/src/main/java/com/texthip/thip/ui/group/room/mock/GroupRoomHeaderData.kt @@ -0,0 +1,10 @@ +package com.texthip.thip.ui.group.room.mock + +data class GroupRoomHeaderData( + val groupRoomName: String, + val isPrivate: Boolean, + val introductionContent: String, + val period: String, + val participantCount: Int, + val genre: String +) diff --git a/app/src/main/java/com/texthip/thip/ui/group/room/mock/GroupRoomMateData.kt b/app/src/main/java/com/texthip/thip/ui/group/room/mock/GroupRoomMateData.kt new file mode 100644 index 00000000..5af77a32 --- /dev/null +++ b/app/src/main/java/com/texthip/thip/ui/group/room/mock/GroupRoomMateData.kt @@ -0,0 +1,12 @@ +package com.texthip.thip.ui.group.room.mock + +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.painter.Painter + +data class GroupRoomMateData( + val profileImageUrl: Painter? = null, + val nickname: String, + val role: String, + val roleColor: Color, + val subscriberCount: Int, +) \ No newline at end of file diff --git a/app/src/main/java/com/texthip/thip/ui/group/room/mock/VoteData.kt b/app/src/main/java/com/texthip/thip/ui/group/room/mock/VoteData.kt new file mode 100644 index 00000000..36f22a84 --- /dev/null +++ b/app/src/main/java/com/texthip/thip/ui/group/room/mock/VoteData.kt @@ -0,0 +1,7 @@ +package com.texthip.thip.ui.group.room.mock + +data class VoteData( + val description: String, + val options: List, + val votes: List +) \ No newline at end of file diff --git a/app/src/main/java/com/texthip/thip/ui/group/room/screen/GroupRoomChatScreen.kt b/app/src/main/java/com/texthip/thip/ui/group/room/screen/GroupRoomChatScreen.kt new file mode 100644 index 00000000..1b86cb09 --- /dev/null +++ b/app/src/main/java/com/texthip/thip/ui/group/room/screen/GroupRoomChatScreen.kt @@ -0,0 +1,118 @@ +package com.texthip.thip.ui.group.room.screen + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.itemsIndexed +import androidx.compose.material3.HorizontalDivider +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.res.stringResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.texthip.thip.R +import com.texthip.thip.ui.common.cards.CardCommentGroup +import com.texthip.thip.ui.common.forms.CommentTextField +import com.texthip.thip.ui.common.topappbar.DefaultTopAppBar +import com.texthip.thip.ui.common.view.CountingBar +import com.texthip.thip.ui.group.room.mock.GroupRoomChatData +import com.texthip.thip.ui.theme.ThipTheme +import com.texthip.thip.ui.theme.ThipTheme.colors + +@Composable +fun GroupRoomChatScreen() { + val messages = listOf( + GroupRoomChatData( + null, + "user.01", + "2024.04.29", + "공백 포함 글자 입력입니다. 공백 포함 글자 입력입니다. 공백 포함 글자 입력입니다. 공백 포함 글자 입력입니다. 공백 포함 글자 입력입니다." + ), + GroupRoomChatData( + null, + "user.01", + "2024.04.28", + "공백 포함 글자 입력입니다. 공백 포함 글자 입력입니다. 공백 포함 글자 입력입니다. 공백 포함 글자 입력입니다. 공백 포함 글자 입력입니다." + ), + GroupRoomChatData(null, "user.01", "2024.04.30", "공백 포함 글자 입력입니다."), + GroupRoomChatData(null, "user.01", "2024.04.30", "공백 포함 글자 입력입니다. 공백 포함 글자 입력입니다."), + GroupRoomChatData( + null, + "user.01", + "2024.04.30", + "공백 포함 글자 입력입니다. 공백 포함 글자 입력입니다. 공백 포함 글자 입력입니다. 공백 포함 글자 입력입니다. 공백 포함 글자 입력입니다." + ), + ).sortedByDescending { it.date } + + var input by remember { mutableStateOf("") } + var replyTo by remember { mutableStateOf(null) } + + Column( + modifier = Modifier + .fillMaxSize() + ) { + DefaultTopAppBar( + title = stringResource(R.string.group_room_chat), + onLeftClick = {}, + ) + + LazyColumn( + reverseLayout = true, + modifier = Modifier.weight(1f), + verticalArrangement = Arrangement.spacedBy(20.dp) + ) { + itemsIndexed(messages) { index, message -> + val isNewDate = when { + index == 0 -> true + messages[index - 1].date != message.date -> true + else -> false + } + + val isBottomItem = index == 0 + + Column( + verticalArrangement = Arrangement.spacedBy(20.dp), + modifier = if (isBottomItem) Modifier.padding(bottom = 20.dp) else Modifier + ) { + if (isNewDate) { + HorizontalDivider( + color = colors.DarkGrey02, + thickness = 10.dp + ) + CountingBar( + modifier = Modifier.align(Alignment.CenterHorizontally), + content = message.date + ) + } + CardCommentGroup(data = message) + } + } + } + CommentTextField( + input = input, + hint = stringResource(R.string.group_room_chat_hint), + onInputChange = { input = it }, + onSendClick = { + input = "" + replyTo = null + }, + replyTo = replyTo, + onCancelReply = { replyTo = null } + ) + } +} + +@Preview +@Composable +private fun GroupRoomChatScreenPreview() { + ThipTheme { + GroupRoomChatScreen() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/texthip/thip/ui/group/room/screen/GroupRoomMatesScreen.kt b/app/src/main/java/com/texthip/thip/ui/group/room/screen/GroupRoomMatesScreen.kt new file mode 100644 index 00000000..ae189a1c --- /dev/null +++ b/app/src/main/java/com/texthip/thip/ui/group/room/screen/GroupRoomMatesScreen.kt @@ -0,0 +1,136 @@ +package com.texthip.thip.ui.group.room.screen + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.texthip.thip.R +import com.texthip.thip.ui.common.topappbar.DefaultTopAppBar +import com.texthip.thip.ui.group.room.component.GroupRoomMatesList +import com.texthip.thip.ui.group.room.mock.GroupRoomMateData +import com.texthip.thip.ui.theme.ThipTheme +import com.texthip.thip.ui.theme.ThipTheme.colors + +@Composable +fun GroupRoomMatesScreen() { + val scrollState = rememberScrollState() + + Column( + modifier = Modifier + .fillMaxSize() + ) { + DefaultTopAppBar( + title = stringResource(R.string.group_room_mates), + onLeftClick = {}, + ) + Column( + modifier = Modifier + .verticalScroll(scrollState) + ) { + Spacer(Modifier.height(40.dp)) + GroupRoomMatesList( + members = listOf( + GroupRoomMateData( + profileImageUrl = null, + nickname = "Thiper", + role = "칭호칭호", + roleColor = colors.Yellow, + subscriberCount = 100 + ), + GroupRoomMateData( + profileImageUrl = null, + nickname = "thipthip", + role = "공식 인플루언서", + roleColor = colors.NeonGreen, + subscriberCount = 50 + ), + GroupRoomMateData( + profileImageUrl = null, + nickname = "Thiper", + role = "칭호칭호", + roleColor = colors.Yellow, + subscriberCount = 100 + ), + GroupRoomMateData( + profileImageUrl = null, + nickname = "thip01", + role = "작가", + roleColor = colors.NeonGreen, + subscriberCount = 100 + ), + GroupRoomMateData( + profileImageUrl = null, + nickname = "Thiper", + role = "칭호칭호", + roleColor = colors.Yellow, + subscriberCount = 100 + ), + GroupRoomMateData( + profileImageUrl = null, + nickname = "thipthip", + role = "공식 인플루언서", + roleColor = colors.NeonGreen, + subscriberCount = 50 + ), + GroupRoomMateData( + profileImageUrl = null, + nickname = "Thiper", + role = "칭호칭호", + roleColor = colors.Yellow, + subscriberCount = 100 + ), + GroupRoomMateData( + profileImageUrl = null, + nickname = "thip01", + role = "작가", + roleColor = colors.NeonGreen, + subscriberCount = 100 + ), + GroupRoomMateData( + profileImageUrl = null, + nickname = "Thiper", + role = "칭호칭호", + roleColor = colors.Yellow, + subscriberCount = 100 + ), + GroupRoomMateData( + profileImageUrl = null, + nickname = "thipthip", + role = "공식 인플루언서", + roleColor = colors.NeonGreen, + subscriberCount = 50 + ), + GroupRoomMateData( + profileImageUrl = null, + nickname = "Thiper", + role = "칭호칭호", + roleColor = colors.Yellow, + subscriberCount = 100 + ), + GroupRoomMateData( + profileImageUrl = null, + nickname = "thip01", + role = "작가", + roleColor = colors.NeonGreen, + subscriberCount = 100 + ), + ) + ) + } + } +} + +@Preview +@Composable +private fun GroupRoomMatesScreenPreview() { + ThipTheme { + GroupRoomMatesScreen() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/texthip/thip/ui/group/room/screen/GroupRoomScreen.kt b/app/src/main/java/com/texthip/thip/ui/group/room/screen/GroupRoomScreen.kt new file mode 100644 index 00000000..86003a6e --- /dev/null +++ b/app/src/main/java/com/texthip/thip/ui/group/room/screen/GroupRoomScreen.kt @@ -0,0 +1,110 @@ +package com.texthip.thip.ui.group.room.screen + +import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +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.rememberScrollState +import androidx.compose.foundation.verticalScroll +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.texthip.thip.R +import com.texthip.thip.ui.common.topappbar.GradationTopAppBar +import com.texthip.thip.ui.group.room.component.GroupRoomBody +import com.texthip.thip.ui.group.room.component.GroupRoomHeader +import com.texthip.thip.ui.group.room.mock.GroupRoomBodyData +import com.texthip.thip.ui.group.room.mock.GroupRoomHeaderData +import com.texthip.thip.ui.group.room.mock.VoteData +import com.texthip.thip.ui.theme.ThipTheme + +@Composable +fun GroupRoomScreen() { + val scrollState = rememberScrollState() + + Box( + modifier = Modifier + .fillMaxSize() + ) { + Box( + modifier = Modifier.verticalScroll(scrollState) + ) { + Image( + painter = painterResource(R.drawable.img_group_room), + contentDescription = null, + contentScale = ContentScale.Crop, + modifier = Modifier + .fillMaxWidth() + .height(360.dp) + ) + + Column( + modifier = Modifier + .fillMaxWidth() + .padding(top = 76.dp, bottom = 20.dp) + ) { + GroupRoomHeader( + data = GroupRoomHeaderData( + groupRoomName = "호르몬 체인지 완독하는 방", + introductionContent = "‘시집만 읽는 사람들’ 3월 모임입니다. 이번 달 모임방은 심장보다 단단한 토마토 한 알 완독합니다.", + isPrivate = true, + period = "2023.10.01 ~ 2023.10.31", + participantCount = 22, + genre = "문학" + ) + ) + + Spacer(Modifier.height(30.dp)) + + GroupRoomBody( + data = GroupRoomBodyData( + bookTitle = "호르몬 체인지", + bookAuthor = "최정화", + currentPage = 100, + percentage = 50, + voteList = listOf( + VoteData( + description = "투표 내용입니다...", + options = listOf("김땡땡", "이땡땡", "박땡땡", "최땡땡", "정땡땡"), + votes = listOf(50, 10, 20, 15, 5) + ), + VoteData( + description = "옆으로 넘긴 다른 투표 01", + options = listOf("어쩌구", "저쩌구", "삼번", "사번"), + votes = listOf(25, 45, 20, 10) + ), + VoteData( + description = "옆으로 넘긴 다른 투표 02", + options = listOf( + "투표 제목과 항목 버튼이 가로 스크롤되고", + "아래 캐러셀 닷은", + "위치 그대로, 강조점만 바뀌도록." + ), + votes = listOf(40, 35, 25) + ) + ) + ) + ) + } + } + GradationTopAppBar( + onLeftClick = {}, + onRightClick = {}, + ) + } +} + +@Preview +@Composable +private fun GroupRoomScreenPreview() { + ThipTheme { + GroupRoomScreen() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/texthip/thip/ui/theme/Color.kt b/app/src/main/java/com/texthip/thip/ui/theme/Color.kt index 3bbcdba8..c5d2f5eb 100644 --- a/app/src/main/java/com/texthip/thip/ui/theme/Color.kt +++ b/app/src/main/java/com/texthip/thip/ui/theme/Color.kt @@ -21,6 +21,7 @@ val Skyblue = Color(0xFFA1D5FF) val SkyblueSub = Color(0xFF6DB5EE) val Lavendar = Color(0xFFC8A5FF) val LavendaSub = Color(0xFFA76FFF) +val Yellow = Color(0xFFFFECA7) val PureWhite = Color(0xFFFFFFFF) val White = Color(0xFFFEFEFE) @@ -56,6 +57,7 @@ data class ThipColors( val SkyblueSub: Color, val Lavendar: Color, val LavendaSub: Color, + val Yellow: Color, val PureWhite: Color, val White: Color, val Grey50: Color, @@ -88,6 +90,7 @@ val defaultThipColors = ThipColors( SkyblueSub = SkyblueSub, Lavendar = Lavendar, LavendaSub = LavendaSub, + Yellow = Yellow, PureWhite = PureWhite, White = White, Grey50 = Grey50, diff --git a/app/src/main/res/drawable/img_group_room.png b/app/src/main/res/drawable/img_group_room.png new file mode 100644 index 00000000..c83fd486 Binary files /dev/null and b/app/src/main/res/drawable/img_group_room.png differ diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 2e461e44..09dd92ee 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -6,7 +6,7 @@ 구독 - %02d명이 구독중 + 명이 구독중 공식 인플루언서 %d시간 전 @@ -40,6 +40,8 @@ 시간 전 모임 변경 + 기록장 + 🔥모임방의 뜨거운 감자 해당 도서는 %1$dp까지만 있습니다. @@ -48,4 +50,18 @@ 님의 구독자 다음 페이지명 + 현재 페이지 %d + % + + + 소개글 + 모임 활동기간 + 독서메이트 + %d명이 참여 중 + 장르 + 오늘의 한마디 + 모임방 멤버들과 간단한 인사를 나눠보세요! + 독서메이트 + 님에게 답글 작성 + 메이트들과 간단한 인사를 나눠보세요! \ No newline at end of file