diff --git a/common/resource/src/main/res/drawable/ic_detail_rigt.xml b/common/resource/src/main/res/drawable/ic_detail_rigt.xml new file mode 100644 index 0000000..4154c37 --- /dev/null +++ b/common/resource/src/main/res/drawable/ic_detail_rigt.xml @@ -0,0 +1,20 @@ + + + + diff --git a/common/resource/src/main/res/drawable/img_close.xml b/common/resource/src/main/res/drawable/img_close.xml new file mode 100644 index 0000000..86107b3 --- /dev/null +++ b/common/resource/src/main/res/drawable/img_close.xml @@ -0,0 +1,14 @@ + + + + diff --git a/common/resource/src/main/res/drawable/img_management.xml b/common/resource/src/main/res/drawable/img_management.xml new file mode 100644 index 0000000..da21105 --- /dev/null +++ b/common/resource/src/main/res/drawable/img_management.xml @@ -0,0 +1,13 @@ + + + + diff --git a/core/designsystem/src/main/java/com/idiotfrogs/designsystem/component/MSDialog.kt b/core/designsystem/src/main/java/com/idiotfrogs/designsystem/component/MSDialog.kt new file mode 100644 index 0000000..b523085 --- /dev/null +++ b/core/designsystem/src/main/java/com/idiotfrogs/designsystem/component/MSDialog.kt @@ -0,0 +1,119 @@ +package com.idiotfrogs.designsystem.component + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues +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.width +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.ButtonDefaults +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp +import androidx.compose.ui.window.Dialog +import com.idiotfrogs.designsystem.component.button.MSButton +import com.idiotfrogs.designsystem.theme.MSTheme + +@Composable +fun MSDialog( + title: String, + content: String, + onConfirm: () -> Unit, + onCancel: () -> Unit, + modifier: Modifier = Modifier, + confirmText: String = "확인", + cancelText: String = "취소", + radius: Dp = 24.dp, + confirmButtonColor: Color = MSTheme.color.primaryNormal, // 기본 초록색 + cancelButtonColor: Color = MSTheme.color.greyG1, // 기본 회색 + confirmTextColor: Color = MSTheme.color.white, + cancelTextColor: Color = MSTheme.color.greyG4, +) { + Dialog(onDismissRequest = onCancel) { + Box(modifier = modifier.fillMaxWidth()) { + Column( + modifier = Modifier + .clip(RoundedCornerShape(radius)) + .background(MSTheme.color.white) + .padding(20.dp) + ) { + MSText( + text = title, + fontSize = 20.dp, + ) + Spacer(modifier = Modifier.height(8.dp)) + MSText( + text = content, + fontSize = 16.dp, + fontWeight = FontWeight.Normal + ) + Spacer(modifier = Modifier.height(24.dp)) + Row(modifier = Modifier.fillMaxWidth()) { + MSButton( + modifier = Modifier.weight(1f), + onClick = onCancel, + colors = ButtonDefaults.buttonColors( + containerColor = cancelButtonColor + ), + pressColors = ButtonDefaults.buttonColors( + containerColor = cancelButtonColor + ), + contentPadding = PaddingValues(11.dp) + ) { + MSText( + text = cancelText, + fontSize = 16.dp, + color = cancelTextColor + ) + } + Spacer(Modifier.width(8.dp)) + MSButton( + modifier = Modifier.weight(1f), + onClick = onConfirm, + colors = ButtonDefaults.buttonColors( + containerColor = confirmButtonColor + ), + pressColors = ButtonDefaults.buttonColors( + containerColor = confirmButtonColor + ), + contentPadding = PaddingValues(11.dp) + ) { + MSText( + text = confirmText, + fontSize = 16.dp, + color = confirmTextColor + ) + } + } + } + } + } +} + +@Preview +@Composable +fun MSDialogPreview() { + Column( + modifier = Modifier + .fillMaxSize() + .background(MSTheme.color.white) + ) { + MSDialog( + title = "제목", + content = "내용", + onCancel = {}, + onConfirm = {} + ) + } +} diff --git a/core/designsystem/src/main/java/com/idiotfrogs/designsystem/component/MSGalleryLayout.kt b/core/designsystem/src/main/java/com/idiotfrogs/designsystem/component/MSGalleryLayout.kt new file mode 100644 index 0000000..677af7e --- /dev/null +++ b/core/designsystem/src/main/java/com/idiotfrogs/designsystem/component/MSGalleryLayout.kt @@ -0,0 +1,126 @@ +package com.idiotfrogs.designsystem.component + +import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.* +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.blur +import androidx.compose.ui.draw.clip +import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.unit.dp +import com.skydoves.landscapist.glide.GlideImage +import com.idiotfrogs.resource.R + +@Composable +fun MSGalleryLayout(images: List, isSeal: Boolean) { + Box( + modifier = Modifier + .width(if (images.size != 1) 284.dp else 142.dp) + .clip(RoundedCornerShape(16.dp)) + .blur(if (isSeal) 8.dp else 0.dp) + ) { + when (images.size) { + 1 -> SingleImage(images[0]) + 2 -> RowImages(images, isFirstRow = true) + 3 -> RowImages(images, isFirstRow = false) + 4 -> TwoByTwo(images) + else -> PatternRowsBigFirst(images) + } + } +} + +@Composable +fun SingleImage(image: String) { + GlideImage( + imageModel = { image }, + modifier = Modifier + .fillMaxWidth() + .height(160.dp), + loading = { + Image( + painter = painterResource(R.drawable.img_sample), + contentDescription = "Loading", + contentScale = ContentScale.Crop, + ) + }, + failure = { + Image( + painter = painterResource(R.drawable.img_sample), + contentDescription = "Failure", + contentScale = ContentScale.Crop, + ) + } + ) +} + +@Composable +fun RowImages(images: List, isFirstRow: Boolean) { + val width = when (images.size) { + 1 -> 284.dp + 2 -> 142.dp + 3 -> (284f / 3f).dp + else -> 0.dp + } + val height = if (isFirstRow) 160.dp else 107.dp + + Row(modifier = Modifier.fillMaxWidth()) { + images.forEach { image -> + GlideImage( + imageModel = { image }, + modifier = Modifier + .width(width) + .height(height), + loading = { + Image( + painter = painterResource(R.drawable.img_sample), + contentDescription = "Loading", + contentScale = ContentScale.Crop, + ) + }, + failure = { + Image( + painter = painterResource(R.drawable.img_sample), + contentDescription = "Failure", + contentScale = ContentScale.Crop, + ) + } + ) + } + } +} + +@Composable +fun TwoByTwo(images: List) { + Column(modifier = Modifier.fillMaxWidth()) { + for (row in 0 until 2) { + RowImages(images.subList(row * 2, row * 2 + 2), isFirstRow = false) + } + } +} + +@Composable +fun PatternRowsBigFirst(images: List) { + Column( + modifier = Modifier.fillMaxWidth()) { + var index = 0 + val total = images.size + var rowIndex = 0 + + while (index < total) { + val remaining = total - index + val rowSize = when { + remaining == 4 -> 2 + remaining >= 3 -> 3 + else -> remaining + } + + val subList = images.subList(index, index + rowSize) + RowImages(subList, isFirstRow = false) + + index += rowSize + rowIndex++ + } + } +} \ No newline at end of file diff --git a/core/designsystem/src/main/java/com/idiotfrogs/designsystem/component/MSMessageItem.kt b/core/designsystem/src/main/java/com/idiotfrogs/designsystem/component/MSMessageItem.kt new file mode 100644 index 0000000..f0c663c --- /dev/null +++ b/core/designsystem/src/main/java/com/idiotfrogs/designsystem/component/MSMessageItem.kt @@ -0,0 +1,103 @@ +package com.idiotfrogs.designsystem.component + +import androidx.compose.foundation.background +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.rememberScrollState +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.foundation.verticalScroll +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.blur +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.idiotfrogs.designsystem.theme.MSTheme + +@Composable +fun MSMessageItem( + type: MessageType, + text: String = "", + imageList: List = emptyList(), + isSeal: Boolean = false, +) { + if (type == MessageType.TEXT) { + MSText( + modifier = Modifier + .background( + color = MSTheme.color.primaryLight, + shape = RoundedCornerShape(16.dp) + ) + .blur(if (isSeal) 8.dp else 0.dp) + .padding(16.dp), + text = text, + fontSize = 16.dp, + fontWeight = FontWeight.Normal + ) + } else { + MSGalleryLayout(imageList, isSeal) + } +} + + + +@Preview +@Composable +fun MSMessageItemPreview() { + val scrollState = rememberScrollState() + + Column( + modifier = Modifier + .fillMaxSize() + .padding(8.dp) + .verticalScroll(scrollState), + verticalArrangement = Arrangement.spacedBy(8.dp), + ) { + MSMessageItem( + type = MessageType.TEXT, + text = "별거 아닌 대화, 별거 아닌 하루가 이렇게 기억에 남을 줄이야. 고마워, 다음에도 함께하자." + ) + MSMessageItem( + type = MessageType.TEXT, + text = "별거 아닌 대화, 별거 아닌 하루가 이렇게 기억에 남을 줄이야. 고마워, 다음에도 함께하자.", + isSeal = true + ) + MSMessageItem( + type = MessageType.PHOTO, + imageList = listOf("", "") + ) + MSMessageItem( + type = MessageType.PHOTO, + isSeal = true, + imageList = listOf("") + ) + MSMessageItem( + type = MessageType.PHOTO, + imageList = listOf("", "", "") + ) + MSMessageItem( + type = MessageType.PHOTO, + isSeal = true, + imageList = listOf("", "", "", "") + ) + MSMessageItem( + type = MessageType.PHOTO, + imageList = listOf("", "", "", "", "") + ) + MSMessageItem( + type = MessageType.PHOTO, + isSeal = true, + imageList = listOf("", "", "", "", "", "") + ) + MSMessageItem( + type = MessageType.PHOTO, + imageList = listOf("", "", "", "", "", "", "") + ) + } +} + +enum class MessageType { + TEXT, PHOTO +} \ No newline at end of file diff --git a/core/designsystem/src/main/java/com/idiotfrogs/designsystem/component/MSText.kt b/core/designsystem/src/main/java/com/idiotfrogs/designsystem/component/MSText.kt index 9afc647..108849a 100644 --- a/core/designsystem/src/main/java/com/idiotfrogs/designsystem/component/MSText.kt +++ b/core/designsystem/src/main/java/com/idiotfrogs/designsystem/component/MSText.kt @@ -5,6 +5,7 @@ import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.AnnotatedString import androidx.compose.ui.text.TextLayoutResult import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.font.FontFamily @@ -22,8 +23,8 @@ import com.idiotfrogs.resource.pretendard @Composable fun MSText( text: String, - fontSize: Dp = 14.dp, // @Preview를 위한 디폴트 값 (사용할 때는 똑같이 14.dp 여도 해당 속성은 무조건 입력하기) modifier: Modifier = Modifier, + fontSize: Dp = 14.dp, // @Preview를 위한 디폴트 값 (사용할 때는 똑같이 14.dp 여도 해당 속성은 무조건 입력하기) color: Color = MSTheme.color.black, fontFamily: FontFamily = pretendard, fontWeight: FontWeight = FontWeight.Bold, @@ -56,4 +57,41 @@ fun MSText( style = style, modifier = modifier ) +} + +@Composable +fun MSAnnotatedText( + text: AnnotatedString, + modifier: Modifier = Modifier, + fontSize: Dp = 14.dp, // @Preview를 위한 디폴트 값 (사용할 때는 똑같이 14.dp 여도 해당 속성은 무조건 입력하기) + color: Color = MSTheme.color.black, + fontFamily: FontFamily = pretendard, + fontWeight: FontWeight = FontWeight.Bold, + letterSpacing: TextUnit = TextUnit.Unspecified, + textDecoration: TextDecoration? = null, + textAlign: TextAlign? = null, + lineHeight: TextUnit = TextUnit.Unspecified, + overflow: TextOverflow = TextOverflow.Clip, + softWrap: Boolean = true, + maxLines: Int = Int.MAX_VALUE, + minLines: Int = 1, + style: TextStyle = LocalTextStyle.current +) { + Text( + text = text, + color = color, + fontSize = fontSize.toSp(), + fontFamily = fontFamily, + fontWeight = fontWeight, + letterSpacing = letterSpacing, + textDecoration = textDecoration, + textAlign = textAlign, + lineHeight = lineHeight, + overflow = overflow, + softWrap = softWrap, + maxLines = maxLines, + minLines = minLines, + style = style, + modifier = modifier + ) } \ No newline at end of file diff --git a/feature/detail/src/main/java/com/idiotfrogs/detail/DetailScreen.kt b/feature/detail/src/main/java/com/idiotfrogs/detail/DetailScreen.kt new file mode 100644 index 0000000..11780a0 --- /dev/null +++ b/feature/detail/src/main/java/com/idiotfrogs/detail/DetailScreen.kt @@ -0,0 +1,340 @@ +package com.idiotfrogs.detail + +import androidx.compose.foundation.Image +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.PaddingValues +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.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +import androidx.compose.material3.ButtonDefaults +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.layout.ContentScale +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.text.SpanStyle +import androidx.compose.ui.text.buildAnnotatedString +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.withStyle +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.idiotfrogs.designsystem.component.MSAnnotatedText +import com.idiotfrogs.designsystem.component.MSDialog +import com.idiotfrogs.designsystem.component.MSMessageItem +import com.idiotfrogs.designsystem.component.MSText +import com.idiotfrogs.designsystem.component.MessageType +import com.idiotfrogs.designsystem.component.button.MSButton +import com.idiotfrogs.designsystem.theme.MSTheme +import com.idiotfrogs.detail.component.MembarListItem +import com.idiotfrogs.detail.component.RoundedProgressBar +import com.idiotfrogs.resource.R + +@Composable +fun DetailScreen( + title: String, + date: String, // TODO 추 후 날짜 로직 설계 후 변경 필요 + isMember: Boolean, + isVoteStart: Boolean, + iSSeal: Boolean, + onSealClicked: () -> Unit, + onVoteClicked: (Boolean) -> Unit, + modifier: Modifier = Modifier +) { + val scrollState = rememberScrollState() + var showVoteDialog by remember { mutableStateOf(false) } + val messageList = listOf("") + + if (showVoteDialog) { + MSDialog( + title = "봉인 투표에 반대 하시겠습니까?", + content = "투표를 반대하면 투표를 다시 시작해야 합니다.", + onConfirm = { + onVoteClicked(false) + showVoteDialog = false + }, + onCancel = { showVoteDialog = false }, + confirmText = "반대", + confirmButtonColor = MSTheme.color.black + ) + } + + Column ( + modifier = modifier + .fillMaxSize() + .background(MSTheme.color.bgNormal) + .padding(0.dp) + .verticalScroll(scrollState) + ) { + Box( + modifier = Modifier + .fillMaxWidth() + .height(420.dp) + ) { + Image( // TODO 추 후 AsyncImage로 수정 필요 + modifier = Modifier.matchParentSize(), + painter = painterResource(R.drawable.img_sample), + contentDescription = "Thumbnail", + contentScale = ContentScale.Crop + ) + Image( + modifier = Modifier + .align(Alignment.TopStart) + .padding(top = 20.dp, start = 20.dp), + painter = painterResource(R.drawable.img_close), + contentDescription = "Close" + ) + Image( + modifier = Modifier + .align(Alignment.TopEnd) + .padding(top = 20.dp, end = 20.dp), + painter = painterResource(R.drawable.img_management), + contentDescription = "Management" + ) + MSText( + modifier = Modifier + .align(Alignment.BottomStart) + .padding(start = 20.dp, bottom = 38.dp), + text = title, + fontSize = 40.dp, + color = MSTheme.color.white + ) + MSText( + modifier = Modifier + .align(Alignment.BottomStart) + .padding(start = 20.dp, bottom = 24.dp), + text = date, + fontSize = 12.dp, + color = MSTheme.color.white + ) + } + + Column( + modifier = Modifier + .fillMaxWidth() + .background(MSTheme.color.white) + .padding(horizontal = 20.dp, vertical = 24.dp) + ) { + MSText( + text = "첫 여행, 첫 추억", + fontSize = 20.dp, + ) + Spacer(Modifier.height(8.dp)) + MSText( + text = "처음 함께 떠났던 여행의 순간들을 담은 우리의 작은 시간 저장소.", + fontSize = 16.dp, + fontWeight = FontWeight.Normal + ) + if (!iSSeal) { + Spacer(Modifier.height(24.dp)) + MSText(text = "티켓 봉인 투표") + Spacer(Modifier.height(8.dp)) + if (isMember) { + if (isVoteStart) { // TODO isVoteStart 변수 관리 방법 고민 필요 + Spacer(Modifier.height(8.dp)) + RoundedProgressBar(0.2f) + Spacer(Modifier.height(24.dp)) + Row { + MSButton( + modifier = Modifier.weight(1f), + onClick = { showVoteDialog = true }, + colors = ButtonDefaults.buttonColors( + containerColor = MSTheme.color.greyG1 + ), + contentPadding = PaddingValues(11.dp) + ) { + MSText( + text = "반대", + fontSize = 16.dp, + color = MSTheme.color.greyG4 + ) + } + Spacer(Modifier.width(8.dp)) + MSButton( + modifier = Modifier.weight(3f), + onClick = { onVoteClicked(true) }, + contentPadding = PaddingValues(11.dp) + ) { + MSText( + text = "찬성", + fontSize = 16.dp, + color = MSTheme.color.white + ) + } + } + } else { + MSText( + text = "티켓 봉인을 봉인하려면 방장이 투표를 시작하고, 모든 맴버의 동의가 필요합니다.", + fontSize = 16.dp, + fontWeight = FontWeight.Normal + ) + } + } else { + if (isVoteStart) { + Spacer(Modifier.height(8.dp)) + RoundedProgressBar(0.2f) + Spacer(Modifier.height(24.dp)) + Row { + MSButton( + modifier = Modifier.weight(1f), + onClick = { showVoteDialog = true }, + colors = ButtonDefaults.buttonColors( + containerColor = MSTheme.color.greyG1 + ), + contentPadding = PaddingValues(11.dp) + ) { + MSText( + text = "투표 취소", + fontSize = 16.dp, + color = MSTheme.color.greyG4 + ) + } + } + } else { + MSButton( + modifier = Modifier.fillMaxWidth(), + onClick = onSealClicked, + colors = ButtonDefaults.buttonColors( + containerColor = MSTheme.color.greyG5 + ), + contentPadding = PaddingValues(11.dp) + ) { + MSText( + text = "티켓 봉인하기", + fontSize = 16.dp, + color = MSTheme.color.white + ) + } + } + } + } + } + + Spacer(Modifier.height(16.dp)) + + Column( + modifier = Modifier + .fillMaxWidth() + .background(MSTheme.color.white) + .padding(horizontal = 20.dp, vertical = 24.dp) + ) { + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.SpaceBetween + ) { + MSText( + text = "추억 메시지", + color = MSTheme.color.greyG4 + ) + Image( + modifier = Modifier.size(16.dp), + painter = painterResource(R.drawable.ic_detail_rigt), + contentDescription = "추억 메시지 상세 아이콘" + ) + } + Spacer(Modifier.height(24.dp)) + if (messageList.isEmpty()) { + MSButton( + modifier = Modifier.fillMaxWidth(), + onClick = {}, + contentPadding = PaddingValues(11.dp) + ) { + MSText( + text = "시작하기", + fontSize = 16.dp, + color = MSTheme.color.white + ) + } + } else { + MSMessageItem( + type = MessageType.TEXT, + text = "테스트 문구 입니다.", + isSeal = iSSeal + ) + Spacer(Modifier.height(8.dp)) + MSMessageItem( + type = MessageType.PHOTO, + imageList = messageList, + isSeal = iSSeal + ) + } + } + + Spacer(Modifier.height(16.dp)) + + Column( + modifier = Modifier + .fillMaxWidth() + .background(MSTheme.color.white) + .padding(horizontal = 20.dp, vertical = 24.dp) + ) { + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.SpaceBetween + ) { + MSAnnotatedText( + text = buildAnnotatedString { + append("멤버 ") + withStyle( + SpanStyle(color = MSTheme.color.primaryNormal) + ) { append("7") } + }, + color = MSTheme.color.greyG4 + ) + Image( + modifier = Modifier.size(16.dp), + painter = painterResource(R.drawable.ic_detail_rigt), + contentDescription = "추억 메시지 상세 아이콘" + ) + } + Spacer(Modifier.height(24.dp)) + MembarListItem("파란 바나나 (나)", isMembar = false) // TODO 실제 본인 nickName 필요 + Spacer(Modifier.height(16.dp)) + HorizontalDivider( + thickness = 1.dp, + color = MSTheme.color.greyG1 + ) + repeat(6) { // TODO 테스트용 코드 -> 추 후 실제 list 변경 필요 + Spacer(Modifier.height(16.dp)) + MembarListItem( + nickName = when (it) { + 0 -> "파란 바나나" + 1 -> "검정 복숭아" + 2 -> "별 모양 파인애플" + 3 -> "초코 체리" + 4 -> "자두 수박" + else -> "민트 네모 수박" + } + ) + } + } + } +} + +@Preview +@Composable +fun DetailScreenPreview() { + DetailScreen( + "D-60", + "2025. 02. 20. (목) ~ 2025. 04. 20. (일)", + true, + true, + false, + {}, + {} + ) +} \ No newline at end of file diff --git a/feature/detail/src/main/java/com/idiotfrogs/detail/component/MembarListItem.kt b/feature/detail/src/main/java/com/idiotfrogs/detail/component/MembarListItem.kt new file mode 100644 index 0000000..c9dde3b --- /dev/null +++ b/feature/detail/src/main/java/com/idiotfrogs/detail/component/MembarListItem.kt @@ -0,0 +1,58 @@ +package com.idiotfrogs.detail.component + +import androidx.compose.foundation.Image +import androidx.compose.foundation.background +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.width +import androidx.compose.foundation.shape.RoundedCornerShape +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.text.font.FontWeight +import androidx.compose.ui.unit.dp +import com.idiotfrogs.designsystem.component.MSText +import com.idiotfrogs.designsystem.theme.MSTheme +import com.idiotfrogs.resource.R + +@Composable +fun MembarListItem( + nickName: String, + modifier: Modifier = Modifier, + isMembar: Boolean = true, +) { + Row( + modifier = modifier.fillMaxWidth(), + verticalAlignment = Alignment.CenterVertically + ) { + Image( // TODO 추 후 AsyncImage 변경 필요 + painter = painterResource(R.drawable.img_profile), + contentDescription = "프로필" + ) + Spacer(Modifier.width(8.dp)) + MSText( + text = nickName, + color = MSTheme.color.greyG5, + fontSize = 16.dp, + fontWeight = FontWeight.Normal, + ) + + if (!isMembar) { + Spacer(Modifier.weight(1f)) + MSText( + modifier = Modifier + .background( + color = MSTheme.color.greyG5.copy(0.1f), + shape = RoundedCornerShape(6.dp) + ) + .padding(5.dp), + text = "방장", + color = MSTheme.color.greyG5, + fontSize = 12.dp, + ) + } + } +} \ No newline at end of file diff --git a/feature/detail/src/main/java/com/idiotfrogs/detail/component/RoundedProgressBar.kt b/feature/detail/src/main/java/com/idiotfrogs/detail/component/RoundedProgressBar.kt new file mode 100644 index 0000000..dc5540a --- /dev/null +++ b/feature/detail/src/main/java/com/idiotfrogs/detail/component/RoundedProgressBar.kt @@ -0,0 +1,35 @@ +package com.idiotfrogs.detail.component + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.unit.dp +import com.idiotfrogs.designsystem.theme.MSTheme + +@Composable +fun RoundedProgressBar( + progress: Float, // TODO 현재는 퍼센트로 했지만 인원수에 따른 로직 추가 필요 + modifier: Modifier = Modifier, +) { + Box( + modifier = modifier + .fillMaxWidth() + .height(16.dp) + .clip(RoundedCornerShape(4.dp)) + .background(MSTheme.color.bgNormal) + ) { + Box( + modifier = Modifier + .fillMaxWidth(progress.coerceIn(0f, 1f)) + .fillMaxHeight() + .clip(RoundedCornerShape(4.dp)) + .background(MSTheme.color.primaryNormal) + ) + } +}