Repository: Team-WSS/WSS-Android
Pull request #685: feat: 피드 상세 이미지 컨테이너 UI 구현
Author: login: junseo511
Labels: name: 🍯 [FEAT]
description: 새로운 기능을 개발합니다.
Created: 2025-05-14T16:02:19Z | Merged: 2025-05-23T01:31:22Z

## 📌𝘐𝘴𝘴𝘶𝘦𝘴
- closed #684 

## 📎𝘞𝘰𝘳𝘬 𝘋𝘦𝘴𝘤𝘳𝘪𝘱𝘵𝘪𝘰𝘯
- 이미지 컨테이너 UI 구현

## 📷𝘚𝘤𝘳𝘦𝘦𝘯𝘴𝘩𝘰𝘵

https://github.com/user-attachments/assets/6b1d1ce3-1861-4a5b-8637-b7b82e3029b9

## 💬𝘛𝘰 𝘙𝘦𝘷𝘪𝘦𝘸𝘦𝘳𝘴

오랜만에 컴포즈하니 재밌네요
좀 커질까봐 한턴 끊어가요~

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **신규 기능**
    - 피드 상세 화면에서 이미지 개수에 따라 1개, 2개, 3개, 다중 이미지 레이아웃을 자동으로 적용합니다.
    - 이미지 클릭 시 확장된 이미지 보기로 이동하는 기능이 추가되었습니다.
- **스타일**
    - 피드 이미지 영역 및 관련 UI 요소의 여백과 배치가 개선되었습니다.
    - 이미지에 둥근 모서리와 크롭 스케일이 적용되어 시각적 완성도가 향상되었습니다.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Linked issue #684: feat: 피드 상세 이미지 관련 UI 구현
## 📜 Overview (Required)    
<!-- 이슈에 대해 간략하게 설명해주세요 -->  
피드 이미지 관련 UI 구현

## 📌 Child Issue(Optional)  
<!-- 자식 이슈를 연결해주세요(ex: - #32) -->
No response  

## 📍 Note (Optional) <!-- 특이사항을 적어주세요 -->
No response  

<!--  ## Issue Convention
- 제목 예시는 다음과 같다.
    - 예시) `feat: library view 횡스크롤 구현`
- 제목에 사용할 prefix는 커밋 컨벤션에 사용하는 타입과 동일하다.
    - 해당 이슈의 주 역할에 맞게 설정할 것.
        - feat: 새로운 기능(새로운 기능 개발이 아니여도, 변경 사항이 클 경우 feat에 해당한다.)
        - refactor: 코드 리팩터링
        - fix: 예상하지 못한 문제를 해결
        - build: 빌드 업무 수정
- 이슈는 뷰 단위가 아닌 기능 단위로 발행할 것
    - 해당 기능이 너무 클 경우(PR Diff 고려), 자식 이슈로 분리할 것 -->


Diff:
diff --git a/app/src/main/java/com/into/websoso/ui/createFeed/component/CreateFeedImageContainer.kt b/app/src/main/java/com/into/websoso/ui/createFeed/component/CreateFeedImageContainer.kt
index 7a934f974..6f66cc676 100644
--- a/app/src/main/java/com/into/websoso/ui/createFeed/component/CreateFeedImageContainer.kt
+++ b/app/src/main/java/com/into/websoso/ui/createFeed/component/CreateFeedImageContainer.kt
@@ -5,6 +5,7 @@ import androidx.compose.foundation.layout.Arrangement
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.PaddingValues
 import androidx.compose.foundation.layout.aspectRatio
+import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.foundation.layout.fillMaxWidth
 import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.layout.size
@@ -18,7 +19,6 @@ 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.into.websoso.core.common.ui.component.AdaptationImage
 import com.into.websoso.core.common.util.clickableWithoutRipple
 import com.into.websoso.core.designsystem.component.NetworkImage
 import com.into.websoso.core.designsystem.theme.WebsosoTheme
@@ -57,31 +57,42 @@ private fun CreateFeedImageBox(
             .aspectRatio(1f)
             .clip(RoundedCornerShape(8.dp)),
     ) {
-        Image(
-            painter = painterResource(ic_feed_remove_image),
-            contentDescription = null,
-            modifier = Modifier
-                .size(38.dp)
-                .padding(10.dp)
-                .align(Alignment.TopEnd)
-                .clickableWithoutRipple { onRemoveClick() },
-        )
         NetworkImage(
             imageUrl = imageUrl,
             contentScale = ContentScale.Crop,
+            modifier = Modifier.fillMaxSize(),
+        )
+        ImageRemoveButton(
+            modifier = Modifier.align(Alignment.TopEnd),
+            onRemoveClick = onRemoveClick,
         )
     }
 }
 
+@Composable
+private fun ImageRemoveButton(
+    modifier: Modifier,
+    onRemoveClick: () -> Unit,
+) {
+    Image(
+        painter = painterResource(ic_feed_remove_image),
+        contentDescription = null,
+        modifier = modifier
+            .size(38.dp)
+            .padding(10.dp)
+            .clickableWithoutRipple { onRemoveClick() },
+    )
+}
+
 @Preview
 @Composable
 private fun CreateFeedImageContainerPreview() {
     WebsosoTheme {
         CreateFeedImageContainer(
             imageUrls = listOf(
-                "https://github.com/user-attachments/assets/e89a02bb-549f-414d-809f-0ab1e8f72c5f",
-                "https://github.com/user-attachments/assets/e89a02bb-549f-414d-809f-0ab1e8f72c5f",
-                "https://github.com/user-attachments/assets/e89a02bb-549f-414d-809f-0ab1e8f72c5f",
+                "https://product-image.kurly.com/hdims/resize/%5E%3E360x%3E468/cropcenter/360x468/quality/85/src/product/image/00fb05f8-cb19-4d21-84b1-5cf6b9988749.jpg",
+                "https://product-image.kurly.com/hdims/resize/%5E%3E360x%3E468/cropcenter/360x468/quality/85/src/product/image/00fb05f8-cb19-4d21-84b1-5cf6b9988749.jpg",
+                "https://product-image.kurly.com/hdims/resize/%5E%3E360x%3E468/cropcenter/360x468/quality/85/src/product/image/00fb05f8-cb19-4d21-84b1-5cf6b9988749.jpg",
             ),
             onRemoveClick = {},
         )
diff --git a/app/src/main/java/com/into/websoso/ui/feedDetail/FeedDetailActivity.kt b/app/src/main/java/com/into/websoso/ui/feedDetail/FeedDetailActivity.kt
index fc93e4916..4e9a140b8 100644
--- a/app/src/main/java/com/into/websoso/ui/feedDetail/FeedDetailActivity.kt
+++ b/app/src/main/java/com/into/websoso/ui/feedDetail/FeedDetailActivity.kt
@@ -139,6 +139,13 @@ class FeedDetailActivity : BaseActivity<ActivityFeedDetailBinding>(activity_feed
             override fun onFeedDetailClick(view: View) {
                 view.hideKeyboard()
             }
+
+            override fun onFeedImageClick(
+                imageUrls: List<String>,
+                index: Int,
+            ) {
+                navigateToExpandedImage(imageUrls, index)
+            }
         }
 
     private fun navigateToNovelDetail(novelId: Long) {
@@ -177,6 +184,13 @@ class FeedDetailActivity : BaseActivity<ActivityFeedDetailBinding>(activity_feed
         )
     }
 
+    private fun navigateToExpandedImage(
+        imageUrls: List<String>,
+        index: Int,
+    ) {
+        // TODO("Not yet implemented")
+    }
+
     private fun bindMenuByIsMine(
         id: Long,
         isMine: Boolean,
diff --git a/app/src/main/java/com/into/websoso/ui/feedDetail/FeedDetailClickListener.kt b/app/src/main/java/com/into/websoso/ui/feedDetail/FeedDetailClickListener.kt
index 1bf93a662..033851c61 100644
--- a/app/src/main/java/com/into/websoso/ui/feedDetail/FeedDetailClickListener.kt
+++ b/app/src/main/java/com/into/websoso/ui/feedDetail/FeedDetailClickListener.kt
@@ -16,4 +16,9 @@ interface FeedDetailClickListener {
     )
 
     fun onFeedDetailClick(view: View)
+
+    fun onFeedImageClick(
+        imageUrls: List<String>,
+        index: Int,
+    )
 }
diff --git a/app/src/main/java/com/into/websoso/ui/feedDetail/adapter/FeedDetailContentViewHolder.kt b/app/src/main/java/com/into/websoso/ui/feedDetail/adapter/FeedDetailContentViewHolder.kt
index 4c4f1c6f8..0bb067b9b 100644
--- a/app/src/main/java/com/into/websoso/ui/feedDetail/adapter/FeedDetailContentViewHolder.kt
+++ b/app/src/main/java/com/into/websoso/ui/feedDetail/adapter/FeedDetailContentViewHolder.kt
@@ -6,10 +6,11 @@ import androidx.recyclerview.widget.RecyclerView
 import com.into.websoso.core.common.util.getS3ImageUrl
 import com.into.websoso.databinding.ItemFeedDetailHeaderBinding
 import com.into.websoso.ui.feedDetail.FeedDetailClickListener
+import com.into.websoso.ui.feedDetail.component.AdaptationFeedImageContainer
 import com.into.websoso.ui.main.feed.model.FeedModel
 
 class FeedDetailContentViewHolder(
-    feedDetailClickListener: FeedDetailClickListener,
+    private val feedDetailClickListener: FeedDetailClickListener,
     private val binding: ItemFeedDetailHeaderBinding,
 ) : RecyclerView.ViewHolder(binding.root) {
     init {
@@ -21,6 +22,15 @@ class FeedDetailContentViewHolder(
             user = feed.user.copy(avatarImage = itemView.getS3ImageUrl(feed.user.avatarImage)),
         )
         binding.clFeedLike.isSelected = feed.isLiked
+        binding.cvFeedImage.setContent {
+            // TODO: 이미지 존재 여부에 따른 가시성 설정
+            val imageUrls = List<String>(5) {
+                "https://upload.wikimedia.org/wikipedia/ko/9/9e/%EB%A0%88%EB%94%94_%ED%94%8C%EB%A0%88%EC%9D%B4%EC%96%B4_%EC%9B%90_%EC%98%81%ED%99%94.jpg"
+            }
+            AdaptationFeedImageContainer(imageUrls) { index ->
+                feedDetailClickListener.onFeedImageClick(imageUrls, index)
+            }
+        }
     }
 
     companion object {
diff --git a/app/src/main/java/com/into/websoso/ui/feedDetail/component/AdaptationFeedImageContainer.kt b/app/src/main/java/com/into/websoso/ui/feedDetail/component/AdaptationFeedImageContainer.kt
new file mode 100644
index 000000000..d369c33ba
--- /dev/null
+++ b/app/src/main/java/com/into/websoso/ui/feedDetail/component/AdaptationFeedImageContainer.kt
@@ -0,0 +1,21 @@
+package com.into.websoso.ui.feedDetail.component
+
+import androidx.compose.runtime.Composable
+import com.into.websoso.ui.feedDetail.model.ImageContainerType
+import com.into.websoso.ui.feedDetail.model.ImageContainerType.DOUBLE
+import com.into.websoso.ui.feedDetail.model.ImageContainerType.MULTIPLE
+import com.into.websoso.ui.feedDetail.model.ImageContainerType.SINGLE
+import com.into.websoso.ui.feedDetail.model.ImageContainerType.TRIPLE
+
+@Composable
+fun AdaptationFeedImageContainer(
+    imageUrls: List<String>,
+    onImageClick: (index: Int) -> Unit,
+) {
+    when (ImageContainerType.from(imageUrls.size)) {
+        SINGLE -> SingleImageContainer(imageUrls.first()) { onImageClick(0) }
+        DOUBLE -> DoubleImageContainer(imageUrls, onImageClick)
+        TRIPLE -> TripleImageContainer(imageUrls, onImageClick)
+        MULTIPLE -> MultipleImageContainer(imageUrls, onImageClick)
+    }
+}
diff --git a/app/src/main/java/com/into/websoso/ui/feedDetail/component/DoubleImageContainer.kt b/app/src/main/java/com/into/websoso/ui/feedDetail/component/DoubleImageContainer.kt
new file mode 100644
index 000000000..6a6015e49
--- /dev/null
+++ b/app/src/main/java/com/into/websoso/ui/feedDetail/component/DoubleImageContainer.kt
@@ -0,0 +1,43 @@
+package com.into.websoso.ui.feedDetail.component
+
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.aspectRatio
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
+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.layout.ContentScale
+import androidx.compose.ui.unit.dp
+import com.into.websoso.core.common.ui.component.AdaptationImage
+import com.into.websoso.core.common.util.clickableWithoutRipple
+import com.into.websoso.ui.feedDetail.model.ImageContainerType.DOUBLE
+
+@Composable
+fun DoubleImageContainer(
+    imageUrls: List<String>,
+    onImageClick: (index: Int) -> Unit,
+) {
+    Row(
+        modifier = Modifier
+            .fillMaxWidth()
+            .padding(horizontal = 20.dp),
+        horizontalArrangement = Arrangement.spacedBy(8.dp),
+    ) {
+        imageUrls.take(DOUBLE.size).forEach { imageUrl ->
+            AdaptationImage(
+                imageUrl = imageUrl,
+                contentScale = ContentScale.Crop,
+                modifier = Modifier
+                    .weight(1f)
+                    .aspectRatio(1f)
+                    .clip(RoundedCornerShape(8.dp))
+                    .clickableWithoutRipple {
+                        onImageClick(imageUrls.indexOf(imageUrl))
+                    },
+            )
+        }
+    }
+}
diff --git a/app/src/main/java/com/into/websoso/ui/feedDetail/component/MultipleImageContainer.kt b/app/src/main/java/com/into/websoso/ui/feedDetail/component/MultipleImageContainer.kt
new file mode 100644
index 000000000..ce5d90735
--- /dev/null
+++ b/app/src/main/java/com/into/websoso/ui/feedDetail/component/MultipleImageContainer.kt
@@ -0,0 +1,43 @@
+package com.into.websoso.ui.feedDetail.component
+
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.PaddingValues
+import androidx.compose.foundation.layout.aspectRatio
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.lazy.LazyRow
+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.layout.ContentScale
+import androidx.compose.ui.unit.dp
+import com.into.websoso.core.common.ui.component.AdaptationImage
+import com.into.websoso.core.common.util.clickableWithoutRipple
+
+@Composable
+fun MultipleImageContainer(
+    imageUrls: List<String>,
+    onImageClick: (index: Int) -> Unit,
+) {
+    LazyRow(
+        modifier = Modifier
+            .fillMaxWidth(),
+        horizontalArrangement = Arrangement.spacedBy(6.dp),
+        contentPadding = PaddingValues(horizontal = 20.dp),
+    ) {
+        items(imageUrls.size) { index ->
+            AdaptationImage(
+                imageUrl = imageUrls[index],
+                contentScale = ContentScale.Crop,
+                modifier = Modifier
+                    .size(100.dp)
+                    .aspectRatio(1f)
+                    .clip(RoundedCornerShape(8.dp))
+                    .clickableWithoutRipple {
+                        onImageClick(index)
+                    },
+            )
+        }
+    }
+}
diff --git a/app/src/main/java/com/into/websoso/ui/feedDetail/component/SingleImageContainer.kt b/app/src/main/java/com/into/websoso/ui/feedDetail/component/SingleImageContainer.kt
new file mode 100644
index 000000000..8ce5f04a2
--- /dev/null
+++ b/app/src/main/java/com/into/websoso/ui/feedDetail/component/SingleImageContainer.kt
@@ -0,0 +1,32 @@
+package com.into.websoso.ui.feedDetail.component
+
+import androidx.compose.foundation.layout.aspectRatio
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
+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.layout.ContentScale
+import androidx.compose.ui.unit.dp
+import com.into.websoso.core.common.ui.component.AdaptationImage
+import com.into.websoso.core.common.util.clickableWithoutRipple
+
+@Composable
+fun SingleImageContainer(
+    imageUrl: String,
+    onImageClick: () -> Unit,
+) {
+    AdaptationImage(
+        imageUrl = imageUrl,
+        contentScale = ContentScale.Crop,
+        modifier = Modifier
+            .fillMaxWidth()
+            .padding(horizontal = 20.dp)
+            .aspectRatio(1f)
+            .clip(RoundedCornerShape(8.dp))
+            .clickableWithoutRipple {
+                onImageClick()
+            },
+    )
+}
diff --git a/app/src/main/java/com/into/websoso/ui/feedDetail/component/TripleImageContainer.kt b/app/src/main/java/com/into/websoso/ui/feedDetail/component/TripleImageContainer.kt
new file mode 100644
index 000000000..73ca82de4
--- /dev/null
+++ b/app/src/main/java/com/into/websoso/ui/feedDetail/component/TripleImageContainer.kt
@@ -0,0 +1,42 @@
+package com.into.websoso.ui.feedDetail.component
+
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.aspectRatio
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
+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.layout.ContentScale
+import androidx.compose.ui.unit.dp
+import com.into.websoso.core.common.ui.component.AdaptationImage
+import com.into.websoso.core.common.util.clickableWithoutRipple
+
+@Composable
+fun TripleImageContainer(
+    imageUrls: List<String>,
+    onImageClick: (index: Int) -> Unit,
+) {
+    Row(
+        modifier = Modifier
+            .fillMaxWidth()
+            .padding(horizontal = 20.dp),
+        horizontalArrangement = Arrangement.spacedBy(8.dp),
+    ) {
+        imageUrls.take(3).forEach { imageUrl ->
+            AdaptationImage(
+                imageUrl = imageUrl,
+                contentScale = ContentScale.Crop,
+                modifier = Modifier
+                    .weight(1f)
+                    .aspectRatio(1f)
+                    .clip(RoundedCornerShape(8.dp))
+                    .clickableWithoutRipple {
+                        onImageClick(imageUrls.indexOf(imageUrl))
+                    },
+            )
+        }
+    }
+}
diff --git a/app/src/main/java/com/into/websoso/ui/feedDetail/model/ImageContainerType.kt b/app/src/main/java/com/into/websoso/ui/feedDetail/model/ImageContainerType.kt
new file mode 100644
index 000000000..48c14e2af
--- /dev/null
+++ b/app/src/main/java/com/into/websoso/ui/feedDetail/model/ImageContainerType.kt
@@ -0,0 +1,15 @@
+package com.into.websoso.ui.feedDetail.model
+
+enum class ImageContainerType(
+    val size: Int,
+) {
+    SINGLE(1),
+    DOUBLE(2),
+    TRIPLE(3),
+    MULTIPLE(4),
+    ;
+
+    companion object {
+        fun from(size: Int): ImageContainerType = ImageContainerType.entries.find { it.size == size } ?: MULTIPLE
+    }
+}
diff --git a/app/src/main/res/drawable/bg_feed_gray_toast_radius_24dp.xml b/app/src/main/res/drawable/bg_feed_gray_toast_radius_24dp.xml
new file mode 100644
index 000000000..5c219ed0c
--- /dev/null
+++ b/app/src/main/res/drawable/bg_feed_gray_toast_radius_24dp.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="@color/gray_toast_CC_394258" />
+    <corners android:radius="24dp" />
+</shape>
diff --git a/app/src/main/res/layout/item_feed.xml b/app/src/main/res/layout/item_feed.xml
index f020fcd0d..d9fd3d355 100644
--- a/app/src/main/res/layout/item_feed.xml
+++ b/app/src/main/res/layout/item_feed.xml
@@ -123,6 +123,33 @@
             app:layout_constraintTop_toBottomOf="@+id/tv_feed_spoiler_warning"
             tools:text="최근 잼께 봤던 무협 소설 목록 진짜들만 골라봤어요 애매한 건 빼고 주로 무협 중에서도 회귀물로 골라봤어요 왜냐면 내가 회귀물을 좋아하기 때문에 최근 잼께 봤던 무협 소설 목록 진짜들만 골라봤어요최근 잼께 봤던 무협 소설 목록 진짜들을 가 회귀물을 좋아하기 때문에 최근 잼께 봤습니다 몇글자 까지 될지 모르겠네요" />
 
+        <ImageView
+            android:id="@+id/iv_feed_image"
+            android:layout_width="0dp"
+            android:layout_height="0dp"
+            android:layout_marginHorizontal="12dp"
+            android:layout_marginTop="20dp"
+            app:layout_constraintBottom_toTopOf="@id/cl_feed_novel_info"
+            app:layout_constraintDimensionRatio="334:236"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@id/tv_feed_content"
+            tools:src="@color/black" />
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginEnd="12dp"
+            android:layout_marginBottom="10dp"
+            android:background="@drawable/bg_feed_gray_toast_radius_24dp"
+            android:paddingHorizontal="10dp"
+            android:paddingVertical="4dp"
+            android:textAppearance="@style/body3"
+            android:textColor="@color/white"
+            app:layout_constraintBottom_toBottomOf="@id/iv_feed_image"
+            app:layout_constraintEnd_toEndOf="@id/iv_feed_image"
+            tools:text="0" />
+
         <androidx.constraintlayout.widget.ConstraintLayout
             android:id="@+id/cl_feed_novel_info"
             isVisible="@{!feed.novel.nothing}"
@@ -135,7 +162,7 @@
             android:onClick="@{() -> onClick.onNovelInfoClick(feed.novel.id)}"
             app:layout_constraintEnd_toEndOf="parent"
             app:layout_constraintStart_toStartOf="parent"
-            app:layout_constraintTop_toBottomOf="@+id/tv_feed_content">
+            app:layout_constraintTop_toBottomOf="@+id/iv_feed_image">
 
             <ImageView
                 android:id="@+id/iv_feed_link"
diff --git a/app/src/main/res/layout/item_feed_detail_header.xml b/app/src/main/res/layout/item_feed_detail_header.xml
index cf3f0f765..83b3ce64e 100644
--- a/app/src/main/res/layout/item_feed_detail_header.xml
+++ b/app/src/main/res/layout/item_feed_detail_header.xml
@@ -103,6 +103,15 @@
                 app:layout_constraintTop_toBottomOf="@+id/cl_feed_profile"
                 tools:text="최근 잼께 봤던 무협 소설 목록 진짜들만 골라봤어요 애매한 건 빼고 주로 무협 중에서도 회귀물로 골라봤어요 왜냐면 내가 회귀물을 좋아하기 때문에 최근 잼께 봤던 무협 소설 목록 진짜들만 골라봤어요최근 잼께 봤던 무협 소설 목록 진짜들을 가 회귀물을 좋아하기 때문에 최근 잼께 봤습니다 몇글자 까지 될지 모르겠네요" />
 
+            <androidx.compose.ui.platform.ComposeView
+                android:id="@+id/cv_feed_image"
+                android:layout_width="0dp"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="20dp"
+                app:layout_constraintEnd_toEndOf="parent"
+                app:layout_constraintStart_toStartOf="parent"
+                app:layout_constraintTop_toBottomOf="@id/tv_feed_content" />
+
             <androidx.constraintlayout.widget.ConstraintLayout
                 android:id="@+id/cl_feed_novel_info"
                 isVisible="@{!feed.novel.nothing}"
@@ -115,7 +124,7 @@
                 android:onClick="@{() -> onClick.onNovelInfoClick(feed.novel.id)}"
                 app:layout_constraintEnd_toEndOf="parent"
                 app:layout_constraintStart_toStartOf="parent"
-                app:layout_constraintTop_toBottomOf="@+id/tv_feed_content">
+                app:layout_constraintTop_toBottomOf="@+id/cv_feed_image">
 
                 <ImageView
                     android:id="@+id/iv_feed_link"
@@ -186,8 +195,8 @@
                 android:id="@+id/cl_feed_like"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:layout_marginStart="12dp"
                 android:layout_marginVertical="10dp"
+                android:layout_marginStart="12dp"
                 android:onClick="@{(cl_feed_like) -> onClick.onLikeButtonClick(cl_feed_like, feed.id)}"
                 app:layout_constraintBottom_toTopOf="@+id/view_feed_indicator"
                 app:layout_constraintStart_toStartOf="parent"


Reviews:
user: login: coderabbitai[bot]
body: **Actionable comments posted: 1**

<details>
<summary>🧹 Nitpick comments (6)</summary><blockquote>

<details>
<summary>app/src/main/java/com/into/websoso/ui/feedDetail/component/DoubleImageContainer.kt (1)</summary><blockquote>

`17-42`: **인덱싱 방식 개선 필요**

현재 구현에서는 `imageUrls.indexOf(imageUrl)`를 사용하여 클릭된 이미지의 인덱스를 찾고 있습니다. 이 방식은 중복된 URL이 있거나 목록이 큰 경우 비효율적일 수 있습니다. 인덱스를 직접 사용하는 방식으로 개선하면 더 효율적일 것입니다.


```diff
-    imageUrls.take(2).forEach { imageUrl ->
-        AdaptationImage(
-            imageUrl = imageUrl,
-            contentScale = ContentScale.Crop,
-            modifier = Modifier
-                .weight(1f)
-                .aspectRatio(1f)
-                .clip(RoundedCornerShape(8.dp))
-                .clickableWithoutRipple {
-                    onImageClick(imageUrls.indexOf(imageUrl))
-                },
-        )
-    }
+    imageUrls.take(2).forEachIndexed { index, imageUrl ->
+        AdaptationImage(
+            imageUrl = imageUrl,
+            contentScale = ContentScale.Crop,
+            modifier = Modifier
+                .weight(1f)
+                .aspectRatio(1f)
+                .clip(RoundedCornerShape(8.dp))
+                .clickableWithoutRipple {
+                    onImageClick(index)
+                },
+        )
+    }
```

그외에는 UI 구현이 깔끔하고 Compose 모범 사례를 잘 따르고 있습니다. 두 이미지를 동일한 너비로 표시하고 적절한 간격과 모서리 처리를 통해 일관된 디자인을 제공합니다.

</blockquote></details>
<details>
<summary>app/src/main/java/com/into/websoso/ui/feedDetail/component/MultipleImageContainer.kt (1)</summary><blockquote>

`18-43`: **반응형 UI 및 성능 최적화 개선 필요**

현재 구현에서는 이미지 크기가 고정값(100.dp)으로 설정되어 있어 다양한 화면 크기에서 최적화되지 않을 수 있습니다. 또한 이미지 수가 많을 경우 성능 문제가 발생할 수 있습니다.


다음과 같은 개선 사항을 고려해보세요:

1. 반응형 이미지 크기 사용:
```diff
-    .size(100.dp)
+    .size(dimensionResource(R.dimen.feed_image_thumbnail_size))
```

2. 표시할 최대 이미지 수 제한:
```diff
-items(imageUrls.size) { position ->
+items(min(imageUrls.size, 10)) { position ->
```

3. 마지막 이미지에 더 많은 이미지가 있음을 표시하는 오버레이 추가:
```kotlin
if (position == 9 && imageUrls.size > 10) {
    Box(
        modifier = Modifier.matchParentSize(),
        contentAlignment = Alignment.Center
    ) {
        Text(
            text = "+${imageUrls.size - 10}",
            color = Color.White,
            fontWeight = FontWeight.Bold
        )
    }
}
```

이미지를 가로 스크롤로 표시하는 LazyRow 사용은 적절하며, 이미지 간 간격과 패딩 설정도 UI 디자인에 일관성을 제공합니다.

</blockquote></details>
<details>
<summary>app/src/main/java/com/into/websoso/ui/feedDetail/model/ImageContainerType.kt (1)</summary><blockquote>

`1-15`: **Enum 정의 명확화 필요**

Enum 클래스 구현은 깔끔하나, `MULTIPLE` 값의 정의와 사용 방식에 불일치가 있습니다. `MULTIPLE`은 size가 4로 정의되어 있지만, `from` 메서드에서는 일치하는 값이 없을 경우 기본값으로 사용됩니다. 이는 4개 이상의 이미지를 모두 `MULTIPLE`로 처리하겠다는 의도로 보이나, 코드만으로는 이해하기 어려울 수 있습니다.


개선 방안:
1. 문서화를 통한 명확화:

```diff
enum class ImageContainerType(
    private val size: Int,
) {
    SINGLE(1),
    DOUBLE(2),
    TRIPLE(3),
-   MULTIPLE(4),
+   MULTIPLE(4), // 4개 이상의 이미지를 위한 컨테이너 타입
    ;

    companion object {
-       fun from(size: Int): ImageContainerType = ImageContainerType.entries.find { it.size == size } ?: MULTIPLE
+       /**
+        * 이미지 개수에 따라 적절한 컨테이너 타입을 반환합니다.
+        * 1~3개의 이미지는 각각 SINGLE, DOUBLE, TRIPLE 타입을 반환하고,
+        * 4개 이상의 이미지는 MULTIPLE 타입을 반환합니다.
+        */
+       fun from(size: Int): ImageContainerType = when {
+           size <= 0 -> throw IllegalArgumentException("이미지 개수는 1개 이상이어야 합니다.")
+           size <= 3 -> ImageContainerType.entries.find { it.size == size }!!
+           else -> MULTIPLE
+       }
    }
}
```

이 enum 클래스는 이미지 개수에 따라 적절한 컨테이너 타입을 결정하는 역할을 잘 수행하고 있습니다.

</blockquote></details>
<details>
<summary>app/src/main/java/com/into/websoso/ui/feedDetail/component/TripleImageContainer.kt (2)</summary><blockquote>

`28-40`: **이미지 인덱스 검색 방식 개선 제안**

`imageUrls.indexOf(imageUrl)`는 리스트에서 중복된 이미지가 있을 경우 항상 첫 번째 발견된 이미지의 인덱스를 반환합니다. 이는 의도하지 않은 동작을 유발할 수 있습니다.


다음과 같이 수정하여 인덱스를 직접 사용하는 것이 더 효율적입니다:

```diff
-        imageUrls.take(3).forEach { imageUrl ->
+        imageUrls.take(3).forEachIndexed { index, imageUrl ->
             AdaptationImage(
                 imageUrl = imageUrl,
                 contentScale = ContentScale.Crop,
                 modifier = Modifier
                     .weight(1f)
                     .aspectRatio(1f)
                     .clip(RoundedCornerShape(8.dp))
                     .clickableWithoutRipple {
-                        onImageClick(imageUrls.indexOf(imageUrl))
+                        onImageClick(index)
                     },
             )
         }
```

---

`28-40`: **코드 중복 검토 필요**

`DoubleImageContainer`와 `TripleImageContainer`의 구현이 매우 유사합니다. 이미지 수만 다를 뿐 대부분의 코드가 중복됩니다.


다음과 같이 공통 컴포넌트를 추출하여 재사용할 수 있습니다:

```kotlin
@Composable
private fun RowImagesContainer(
    imageUrls: List<String>,
    maxImages: Int,
    onImageClick: (Int) -> Unit,
) {
    Row(
        modifier = Modifier
            .fillMaxWidth()
            .padding(horizontal = 20.dp),
        horizontalArrangement = Arrangement.spacedBy(8.dp),
    ) {
        imageUrls.take(maxImages).forEachIndexed { index, imageUrl ->
            AdaptationImage(
                imageUrl = imageUrl,
                contentScale = ContentScale.Crop,
                modifier = Modifier
                    .weight(1f)
                    .aspectRatio(1f)
                    .clip(RoundedCornerShape(8.dp))
                    .clickableWithoutRipple {
                        onImageClick(index)
                    },
            )
        }
    }
}

@Composable
fun DoubleImageContainer(
    imageUrls: List<String>,
    onImageClick: (Int) -> Unit,
) {
    RowImagesContainer(imageUrls, 2, onImageClick)
}

@Composable
fun TripleImageContainer(
    imageUrls: List<String>,
    onImageClick: (Int) -> Unit,
) {
    RowImagesContainer(imageUrls, 3, onImageClick)
}
```

</blockquote></details>
<details>
<summary>app/src/main/java/com/into/websoso/ui/feedDetail/component/AdaptationFeedImageContainer.kt (1)</summary><blockquote>

`16-16`: **첫 번째 이미지 처리 방식 개선**

단일 이미지 케이스에서 `imageUrls.first()`를 사용하고 있습니다. 람다 표현식 내에서 인덱스를 하드코딩하는 것보다 더 명확한 방식이 있을 수 있습니다.


다음과 같이 수정을 고려해 보세요:

```diff
-        SINGLE -> SingleImageContainer(imageUrls.first()) { onImageClick(0) }
+        SINGLE -> {
+            val imageIndex = 0
+            SingleImageContainer(imageUrls[imageIndex]) { onImageClick(imageIndex) }
+        }
```

또는 간결하게:

```diff
-        SINGLE -> SingleImageContainer(imageUrls.first()) { onImageClick(0) }
+        SINGLE -> SingleImageContainer(imageUrls[0]) { onImageClick(0) }
```

</blockquote></details>

</blockquote></details>

<details>
<summary>📜 Review details</summary>

**Configuration used: CodeRabbit UI**
**Review profile: CHILL**
**Plan: Pro**

<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between f4e28267dcb7737ddd7c399852b0a3c630e21305 and 0a83d7c70fb8a75b61a8b63218f2355d2544021d.

</details>

<details>
<summary>📒 Files selected for processing (10)</summary>

* `app/src/main/java/com/into/websoso/ui/feedDetail/FeedDetailActivity.kt` (2 hunks)
* `app/src/main/java/com/into/websoso/ui/feedDetail/FeedDetailClickListener.kt` (1 hunks)
* `app/src/main/java/com/into/websoso/ui/feedDetail/adapter/FeedDetailContentViewHolder.kt` (2 hunks)
* `app/src/main/java/com/into/websoso/ui/feedDetail/component/AdaptationFeedImageContainer.kt` (1 hunks)
* `app/src/main/java/com/into/websoso/ui/feedDetail/component/DoubleImageContainer.kt` (1 hunks)
* `app/src/main/java/com/into/websoso/ui/feedDetail/component/MultipleImageContainer.kt` (1 hunks)
* `app/src/main/java/com/into/websoso/ui/feedDetail/component/SingleImageContainer.kt` (1 hunks)
* `app/src/main/java/com/into/websoso/ui/feedDetail/component/TripleImageContainer.kt` (1 hunks)
* `app/src/main/java/com/into/websoso/ui/feedDetail/model/ImageContainerType.kt` (1 hunks)
* `app/src/main/res/layout/item_feed_detail_header.xml` (3 hunks)

</details>

<details>
<summary>🧰 Additional context used</summary>

<details>
<summary>🧬 Code Graph Analysis (6)</summary>

<details>
<summary>app/src/main/java/com/into/websoso/ui/feedDetail/component/DoubleImageContainer.kt (1)</summary><blockquote>

<details>
<summary>app/src/main/java/com/into/websoso/core/common/ui/component/AdaptationImage.kt (1)</summary>

* `AdaptationImage` (11-32)

</details>

</blockquote></details>
<details>
<summary>app/src/main/java/com/into/websoso/ui/feedDetail/component/SingleImageContainer.kt (1)</summary><blockquote>

<details>
<summary>app/src/main/java/com/into/websoso/core/common/ui/component/AdaptationImage.kt (1)</summary>

* `AdaptationImage` (11-32)

</details>

</blockquote></details>
<details>
<summary>app/src/main/java/com/into/websoso/ui/feedDetail/adapter/FeedDetailContentViewHolder.kt (1)</summary><blockquote>

<details>
<summary>app/src/main/java/com/into/websoso/ui/feedDetail/component/AdaptationFeedImageContainer.kt (1)</summary>

* `AdaptationFeedImageContainer` (10-21)

</details>

</blockquote></details>
<details>
<summary>app/src/main/java/com/into/websoso/ui/feedDetail/component/AdaptationFeedImageContainer.kt (4)</summary><blockquote>

<details>
<summary>app/src/main/java/com/into/websoso/ui/feedDetail/component/SingleImageContainer.kt (1)</summary>

* `SingleImageContainer` (15-32)

</details>
<details>
<summary>app/src/main/java/com/into/websoso/ui/feedDetail/component/DoubleImageContainer.kt (1)</summary>

* `DoubleImageContainer` (17-42)

</details>
<details>
<summary>app/src/main/java/com/into/websoso/ui/feedDetail/component/TripleImageContainer.kt (1)</summary>

* `TripleImageContainer` (17-42)

</details>
<details>
<summary>app/src/main/java/com/into/websoso/ui/feedDetail/component/MultipleImageContainer.kt (1)</summary>

* `MultipleImageContainer` (18-43)

</details>

</blockquote></details>
<details>
<summary>app/src/main/java/com/into/websoso/ui/feedDetail/component/MultipleImageContainer.kt (1)</summary><blockquote>

<details>
<summary>app/src/main/java/com/into/websoso/core/common/ui/component/AdaptationImage.kt (1)</summary>

* `AdaptationImage` (11-32)

</details>

</blockquote></details>
<details>
<summary>app/src/main/java/com/into/websoso/ui/feedDetail/component/TripleImageContainer.kt (1)</summary><blockquote>

<details>
<summary>app/src/main/java/com/into/websoso/core/common/ui/component/AdaptationImage.kt (1)</summary>

* `AdaptationImage` (11-32)

</details>

</blockquote></details>

</details>

</details>

<details>
<summary>⏰ Context from checks skipped due to timeout of 90000ms (1)</summary>

* GitHub Check: build

</details>

<details>
<summary>🔇 Additional comments (10)</summary><blockquote>

<details>
<summary>app/src/main/java/com/into/websoso/ui/feedDetail/FeedDetailClickListener.kt (1)</summary>

`19-23`: **이미지 클릭 이벤트 처리를 위한 인터페이스 메서드가 잘 추가되었습니다.**

이미지 목록과 클릭 위치를 매개변수로 받는 방식으로 설계되어 확장 이미지 뷰로의 네비게이션을 위한 충분한 정보를 제공합니다.

</details>
<details>
<summary>app/src/main/res/layout/item_feed_detail_header.xml (3)</summary>

`106-113`: **이미지 컨테이너를 위한 ComposeView가 적절하게 추가되었습니다.**

ComposeView의 배치와 제약 조건이 적절하게 설정되어 있어 UI 레이아웃에 자연스럽게 통합됩니다. 상위 TextView와 하위 요소들 사이에 올바르게 배치되었습니다.

---

`127-127`: **제약 조건 업데이트가 정확히 이루어졌습니다.**

새로 추가된 ComposeView를 참조하도록 제약 조건이 올바르게 업데이트되었습니다.

---

`198-199`: **마진 값이 일관성 있게 조정되었습니다.**

세로 마진은 통일되고 좌측 마진이 감소되어 UI 레이아웃이 개선되었습니다.

</details>
<details>
<summary>app/src/main/java/com/into/websoso/ui/feedDetail/component/SingleImageContainer.kt (1)</summary>

`15-32`: **이미지 컨테이너 컴포저블이 잘 구현되었습니다.**

단일 이미지 컨테이너 구현이 깔끔하고 현대적인 Compose 패턴을 따르고 있습니다. 적절한 스타일링과 사용자 상호작용을 위한 클릭 처리가 잘 구현되어 있습니다.

1:1 비율과 균일한 패딩, 모서리 둥글기 등의 디자인 요소가 일관성 있게 적용되었습니다.

</details>
<details>
<summary>app/src/main/java/com/into/websoso/ui/feedDetail/FeedDetailActivity.kt (2)</summary>

`143-148`: **이미지 클릭 이벤트 처리가 적절히 구현되었습니다.**

인터페이스의 새 메서드가 적절히 구현되어 확장 이미지 뷰로의 네비게이션 메서드를 호출합니다.

---

`187-192`: **확장 이미지 뷰 네비게이션 기능 구현이 필요합니다.**

현재는 TODO 주석으로 구현되지 않았음을 표시하고 있습니다. 이는 향후 작업 항목으로 적절히 식별되어 있습니다.

이미지 확장 기능을 위한 후속 작업 일정이 있나요? 관련 이슈 번호를 주석에 추가하면 추적이 용이할 것 같습니다.

</details>
<details>
<summary>app/src/main/java/com/into/websoso/ui/feedDetail/component/TripleImageContainer.kt (1)</summary>

`17-42`: **TripleImageContainer 구현이 잘 되었습니다.**

Row 레이아웃을 사용하여 세 개의 이미지를 동일한 너비로 표시하는 방식이 적절합니다. 각 이미지가 1:1 비율을 유지하고 둥근 모서리 처리가 되어 있어 UI가 깔끔해 보입니다.

</details>
<details>
<summary>app/src/main/java/com/into/websoso/ui/feedDetail/component/AdaptationFeedImageContainer.kt (2)</summary>

`10-21`: **이미지 컨테이너 선택 로직이 명확하게 구현되었습니다.**

이미지 개수에 따라 적절한 컨테이너를 선택하는 로직이 깔끔하게 구현되어 있습니다. 각 케이스별로 적합한 컴포넌트를 호출하고 있어 가독성이 좋습니다.

---

`15-16`: <details>
<summary>❌ Incorrect review comment</summary>

**빈 이미지 리스트 처리 필요**

현재 구현에서는 `imageUrls`가 비어있을 경우 `imageUrls.first()`에서 `NoSuchElementException`이 발생할 수 있습니다.


빈 리스트 상황을 처리하기 위해 다음과 같이 수정을 고려해 보세요:

```diff
-    when (ImageContainerType.from(imageUrls.size)) {
-        SINGLE -> SingleImageContainer(imageUrls.first()) { onImageClick(0) }
+    when {
+        imageUrls.isEmpty() -> { /* 빈 이미지 처리 - 아무것도 표시하지 않거나 기본 이미지 표시 */ }
+        else -> when (ImageContainerType.from(imageUrls.size)) {
+            SINGLE -> SingleImageContainer(imageUrls.first()) { onImageClick(0) }
+            DOUBLE -> DoubleImageContainer(imageUrls, onImageClick)
+            TRIPLE -> TripleImageContainer(imageUrls, onImageClick)
+            MULTIPLE -> MultipleImageContainer(imageUrls, onImageClick)
+        }
```

다음 검증 스크립트로 빈 리스트 처리 방식을 확인해보세요:

---

🏁 Script executed:

```shell
#!/bin/bash
# ImageContainerType에서 빈 리스트 처리 방식 확인
rg "from\(" --include="*.kt" -A 5 -B 5
```

Length of output: 482

---

아래 스크립트로 `ImageContainerType.from()` 구현부가 어떻게 처리되고 있는지 확인해 주세요.

---

🏁 Script executed:

```shell
#!/bin/bash
# ImageContainerType 선언 위치 확인
rg -n "class ImageContainerType" -g "*.kt"
# 'from' 함수 구현부 확인
rg -n "fun from" -g "*.kt" -A5 -B5
```

Length of output: 31945

---

빈 리스트 처리 로직 확인을 위해 `AdaptationFeedImageContainer.kt` 전체 구조를 확인해 주세요.

---

🏁 Script executed:

```shell
#!/bin/bash
# 파일 경로 확인
FILE=$(rg -l "class AdaptationFeedImageContainer" -g "*.kt")
echo "Found: $FILE"
# 앞쪽 100줄 출력
sed -n '1,100p' "$FILE"
```

Length of output: 151

---

아래 스크립트로 `AdaptationFeedImageContainer.kt` 파일 위치와 내용을 확인해주세요.


```bash
#!/bin/bash
# 파일 경로 찾기
FILE_PATH=$(fd -e kt AdaptationFeedImageContainer.kt)
echo "Found: $FILE_PATH"
# 파일 앞 200줄 출력
sed -n '1,200p' "$FILE_PATH"
```

---

빈 리스트 처리 확인을 위해 `AdaptationFeedImageContainer.kt` 파일 경로와 핵심 코드를 출력해 주세요.


```bash
#!/bin/bash
# 파일 경로 검색
FILE=$(rg -l "AdaptationFeedImageContainer" -g "*.kt" | head -n1)
echo "Found: $FILE"
# 파일 상위 50줄 및 10~30라인 출력
sed -n '1,50p' "$FILE"
echo "---- lines 10–30 ----"
sed -n '10,30p' "$FILE"
```

---

빈 리스트 처리 로직 확인을 위해 `imageUrls.first()` 호출 위치를 검색해 주세요.


```bash
#!/bin/bash
# imageUrls.first() 호출 위치 찾기
rg -n "imageUrls.first" -g "*.kt"
```

---



</details>

**imageUrls.first()는 빈 리스트에서 호출되지 않습니다**  
현재 `ImageContainerType.from(0)`은 `MULTIPLE`을 반환하므로, `imageUrls.size == 0`일 때는 `SINGLE` 분기에 진입하지 않아 `imageUrls.first()`가 실행되지 않습니다.  
결과적으로 빈 리스트에서 `NoSuchElementException`이 발생하지 않으므로 별도의 수정이 필요 없습니다.  


> Likely an incorrect or invalid review comment.

</details>

</blockquote></details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->
state: COMMENTED
author_association: NONE
submitted_at: 2025-05-14T16:06:34Z
user: login: s9hn
state: APPROVED
author_association: MEMBER
submitted_at: 2025-05-15T17:24:19Z
user: login: junseo511
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-22T11:57:48Z
user: login: junseo511
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-22T11:58:05Z
user: login: junseo511
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-22T11:58:22Z
user: login: coderabbitai[bot]
body: **Actionable comments posted: 2**

<details>
<summary>📜 Review details</summary>

**Configuration used: CodeRabbit UI**
**Review profile: CHILL**
**Plan: Pro**


<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between 0a83d7c70fb8a75b61a8b63218f2355d2544021d and 490eb8e792d1dc1cb8270ae5cd182ae066f54bbd.

</details>

<details>
<summary>📒 Files selected for processing (2)</summary>

* `app/src/main/res/drawable/bg_feed_gray_toast_radius_24dp.xml` (1 hunks)
* `app/src/main/res/layout/item_feed.xml` (2 hunks)

</details>

<details>
<summary>✅ Files skipped from review due to trivial changes (1)</summary>

* app/src/main/res/drawable/bg_feed_gray_toast_radius_24dp.xml

</details>

<details>
<summary>⏰ Context from checks skipped due to timeout of 90000ms (1)</summary>

* GitHub Check: build

</details>

<details>
<summary>🔇 Additional comments (1)</summary><blockquote>

<details>
<summary>app/src/main/res/layout/item_feed.xml (1)</summary>

`165-165`: **`cl_feed_novel_info` 의 제약 검토**  
`cl_feed_novel_info` 의 `app:layout_constraintTop_toBottomOf="@+id/iv_feed_image"` 로 변경된 것은 의도에 부합하지만, 기존 `android:layout_marginTop="20dp"` 와 결합 시 여백이 과도해질 수 있습니다.  
레이아웃 Preview 를 통해 실제 간격을 확인하고, 필요 시 `marginTop` 값을 조정하세요.

</details>

</blockquote></details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->
state: COMMENTED
author_association: NONE
submitted_at: 2025-05-22T15:35:54Z
user: login: m6z1
state: APPROVED
author_association: MEMBER
submitted_at: 2025-05-23T01:01:27Z
user: login: junseo511
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-23T01:15:02Z
user: login: s9hn
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-23T01:22:55Z

Review comments:
diff_hunk: @@ -21,6 +22,15 @@ class FeedDetailContentViewHolder(
             user = feed.user.copy(avatarImage = itemView.getS3ImageUrl(feed.user.avatarImage)),
         )
         binding.clFeedLike.isSelected = feed.isLiked
+        binding.cvFeedImage.setContent {
+            // TODO: 이미지 존재 여부에 따른 가시성 설정
+            val imageUrls = List<String>(5) {
+                "https://upload.wikimedia.org/wikipedia/ko/9/9e/%EB%A0%88%EB%94%94_%ED%94%8C%EB%A0%88%EC%9D%B4%EC%96%B4_%EC%9B%90_%EC%98%81%ED%99%94.jpg"
+            }
+            AdaptationFeedImageContainer(imageUrls) { position ->
+                feedDetailClickListener.onFeedImageClick(imageUrls, position)
+            }
+        }
path: app/src/main/java/com/into/websoso/ui/feedDetail/adapter/FeedDetailContentViewHolder.kt
user: login: coderabbitai[bot]
body: _🛠️ Refactor suggestion_

**이미지 데이터 연동 및 가시성 처리 필요**

현재 구현에서는 하드코딩된 이미지 URL을 사용하고 있습니다. 실제 피드 데이터의 이미지를 사용하도록 연동이 필요합니다. 또한 TODO 주석에 언급된 대로 이미지 존재 여부에 따른 가시성 처리가 필요합니다.


```diff
-        binding.cvFeedImage.setContent {
-            // TODO: 이미지 존재 여부에 따른 가시성 설정
-            val imageUrls = List<String>(5) {
-                "https://upload.wikimedia.org/wikipedia/ko/9/9e/%EB%A0%88%EB%94%94_%ED%94%8C%EB%A0%88%EC%9D%B4%EC%96%B4_%EC%9B%90_%EC%98%81%ED%99%94.jpg"
-            }
-            AdaptationFeedImageContainer(imageUrls) { position ->
-                feedDetailClickListener.onFeedImageClick(imageUrls, position)
-            }
+        // 피드에 이미지가 있는 경우에만 이미지 컨테이너 표시
+        binding.cvFeedImage.setContent {
+            feed.imageUrls?.let { imageUrls ->
+                if (imageUrls.isNotEmpty()) {
+                    AdaptationFeedImageContainer(imageUrls) { position ->
+                        feedDetailClickListener.onFeedImageClick(imageUrls, position)
+                    }
+                }
+            }
        }
```

또한 Compose의 라이프사이클을 관리하기 위해 `setViewCompositionStrategy`를 설정하는 것이 좋습니다:

```kotlin
binding.cvFeedImage.setViewCompositionStrategy(
    ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed
)
```

<!-- This is an auto-generated comment by CodeRabbit -->
created_at: 2025-05-14T16:06:34Z
author_association: NONE
diff_hunk: @@ -139,6 +139,13 @@ class FeedDetailActivity : BaseActivity<ActivityFeedDetailBinding>(activity_feed
             override fun onFeedDetailClick(view: View) {
                 view.hideKeyboard()
             }
+
+            override fun onFeedImageClick(
+                imageUrls: List<String>,
+                position: Int,
path: app/src/main/java/com/into/websoso/ui/feedDetail/FeedDetailActivity.kt
user: login: s9hn
body: a: 피드 이미지 클릭이란 함수명과 어색한 파라미터같아요! 하나의 이미지 url만 넘겨받도록 구현하는 것은 어떤가요?
created_at: 2025-05-15T17:19:26Z
author_association: MEMBER
diff_hunk: @@ -21,6 +22,15 @@ class FeedDetailContentViewHolder(
             user = feed.user.copy(avatarImage = itemView.getS3ImageUrl(feed.user.avatarImage)),
         )
         binding.clFeedLike.isSelected = feed.isLiked
+        binding.cvFeedImage.setContent {
+            // TODO: 이미지 존재 여부에 따른 가시성 설정
+            val imageUrls = List<String>(5) {
path: app/src/main/java/com/into/websoso/ui/feedDetail/adapter/FeedDetailContentViewHolder.kt
user: login: s9hn
body: a: 당장은 테스트용이죠?
created_at: 2025-05-15T17:20:27Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,42 @@
+package com.into.websoso.ui.feedDetail.component
+
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.aspectRatio
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
+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.layout.ContentScale
+import androidx.compose.ui.unit.dp
+import com.into.websoso.core.common.ui.component.AdaptationImage
+import com.into.websoso.core.common.util.clickableWithoutRipple
+
+@Composable
+fun DoubleImageContainer(
+    imageUrls: List<String>,
+    onImageClick: (Int) -> Unit,
+) {
+    Row(
+        modifier = Modifier
+            .fillMaxWidth()
+            .padding(horizontal = 20.dp),
+        horizontalArrangement = Arrangement.spacedBy(8.dp),
+    ) {
+        imageUrls.take(2).forEach { imageUrl ->
+            AdaptationImage(
+                imageUrl = imageUrl,
+                contentScale = ContentScale.Crop,
+                modifier = Modifier
+                    .weight(1f)
+                    .aspectRatio(1f)
+                    .clip(RoundedCornerShape(8.dp))
+                    .clickableWithoutRipple {
+                        onImageClick(imageUrls.indexOf(imageUrl))
path: app/src/main/java/com/into/websoso/ui/feedDetail/component/DoubleImageContainer.kt
user: login: s9hn
body: a: 인덱스를 넘겨주는 이유가 있나요?
created_at: 2025-05-15T17:23:15Z
author_association: MEMBER
diff_hunk: @@ -139,6 +139,13 @@ class FeedDetailActivity : BaseActivity<ActivityFeedDetailBinding>(activity_feed
             override fun onFeedDetailClick(view: View) {
                 view.hideKeyboard()
             }
+
+            override fun onFeedImageClick(
+                imageUrls: List<String>,
+                position: Int,
path: app/src/main/java/com/into/websoso/ui/feedDetail/FeedDetailActivity.kt
user: login: junseo511
body: > a: 피드 이미지 클릭이란 함수명과 어색한 파라미터같아요! 하나의 이미지 url만 넘겨받도록 구현하는 것은 어떤가요?

좌우로 넘어가는 페이지네이션 화면이 필요해서 이동시 전부 받아야 할 것 같습니다!
created_at: 2025-05-22T11:57:48Z
author_association: MEMBER
diff_hunk: @@ -21,6 +22,15 @@ class FeedDetailContentViewHolder(
             user = feed.user.copy(avatarImage = itemView.getS3ImageUrl(feed.user.avatarImage)),
         )
         binding.clFeedLike.isSelected = feed.isLiked
+        binding.cvFeedImage.setContent {
+            // TODO: 이미지 존재 여부에 따른 가시성 설정
+            val imageUrls = List<String>(5) {
path: app/src/main/java/com/into/websoso/ui/feedDetail/adapter/FeedDetailContentViewHolder.kt
user: login: junseo511
body: > a: 당장은 테스트용이죠?

넵! 추후 정리를 위해 TODO 주석을 달아놓았습니다 :)
created_at: 2025-05-22T11:58:05Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,42 @@
+package com.into.websoso.ui.feedDetail.component
+
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.aspectRatio
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
+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.layout.ContentScale
+import androidx.compose.ui.unit.dp
+import com.into.websoso.core.common.ui.component.AdaptationImage
+import com.into.websoso.core.common.util.clickableWithoutRipple
+
+@Composable
+fun DoubleImageContainer(
+    imageUrls: List<String>,
+    onImageClick: (Int) -> Unit,
+) {
+    Row(
+        modifier = Modifier
+            .fillMaxWidth()
+            .padding(horizontal = 20.dp),
+        horizontalArrangement = Arrangement.spacedBy(8.dp),
+    ) {
+        imageUrls.take(2).forEach { imageUrl ->
+            AdaptationImage(
+                imageUrl = imageUrl,
+                contentScale = ContentScale.Crop,
+                modifier = Modifier
+                    .weight(1f)
+                    .aspectRatio(1f)
+                    .clip(RoundedCornerShape(8.dp))
+                    .clickableWithoutRipple {
+                        onImageClick(imageUrls.indexOf(imageUrl))
path: app/src/main/java/com/into/websoso/ui/feedDetail/component/DoubleImageContainer.kt
user: login: junseo511
body: > a: 인덱스를 넘겨주는 이유가 있나요?

페이지네이션 적용시 초기에 보여줄 페이지를 확인시켜주기 위함입니다!
created_at: 2025-05-22T11:58:21Z
author_association: MEMBER
diff_hunk: @@ -123,6 +123,33 @@
             app:layout_constraintTop_toBottomOf="@+id/tv_feed_spoiler_warning"
             tools:text="최근 잼께 봤던 무협 소설 목록 진짜들만 골라봤어요 애매한 건 빼고 주로 무협 중에서도 회귀물로 골라봤어요 왜냐면 내가 회귀물을 좋아하기 때문에 최근 잼께 봤던 무협 소설 목록 진짜들만 골라봤어요최근 잼께 봤던 무협 소설 목록 진짜들을 가 회귀물을 좋아하기 때문에 최근 잼께 봤습니다 몇글자 까지 될지 모르겠네요" />
 
+        <ImageView
+            android:id="@+id/iv_feed_image"
+            android:layout_width="0dp"
+            android:layout_height="0dp"
+            android:layout_marginHorizontal="12dp"
+            android:layout_marginTop="20dp"
+            app:layout_constraintBottom_toTopOf="@id/cl_feed_novel_info"
+            app:layout_constraintDimensionRatio="334:236"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@id/tv_feed_content"
+            tools:src="@color/black" />
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginEnd="12dp"
+            android:layout_marginBottom="10dp"
+            android:background="@drawable/bg_feed_gray_toast_radius_24dp"
+            android:paddingHorizontal="10dp"
+            android:paddingVertical="4dp"
+            android:textAppearance="@style/body3"
+            android:textColor="@color/white"
+            app:layout_constraintBottom_toBottomOf="@id/iv_feed_image"
+            app:layout_constraintEnd_toEndOf="@id/iv_feed_image"
+            tools:text="0" />
+
path: app/src/main/res/layout/item_feed.xml
user: login: coderabbitai[bot]
body: _🛠️ Refactor suggestion_

**오버레이 텍스트뷰에 id·바인딩·조건부 노출 추가 필요**  
현재 오버레이 `TextView` 에는 ID가 없고, `tools:text` 만 있어 런타임 바인딩이 불가하며 항상 노출됩니다.  
- `@+id/tv_feed_image_count` 와 같은 ID 를 부여하세요.  
- `feed.images.size() > 1` 일 때만 보이도록 `app:isVisible` 을 설정하세요.  
- 남은 이미지 수(예: `feed.images.size() - 1`) 를 표시할 수 있도록 `android:text="@{String.valueOf(feed.images.size() - 1)}"` 바인딩을 추가하세요.  



예시 제안 diff:
```diff
-<TextView
+<TextView
+    android:id="@+id/tv_feed_image_count"
+    app:isVisible="@{feed.images.size() > 1}"
+    android:text="@{String.valueOf(feed.images.size() - 1)}"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:layout_marginEnd="12dp"
     android:layout_marginBottom="10dp"
     android:background="@drawable/bg_feed_gray_toast_radius_24dp"
     android:paddingHorizontal="10dp"
     android:paddingVertical="4dp"
     android:textAppearance="@style/body3"
     android:textColor="@color/white"
     app:layout_constraintBottom_toBottomOf="@id/iv_feed_image"
     app:layout_constraintEnd_toEndOf="@id/iv_feed_image"
-    tools:text="0" />
+    tools:text="0" />
```

<details>
<summary>🤖 Prompt for AI Agents</summary>

```
In app/src/main/res/layout/item_feed.xml around lines 139 to 152, the overlay
TextView lacks an ID and runtime binding, causing it to always be visible and
unbindable. Add an ID attribute such as @+id/tv_feed_image_count, set
app:isVisible to true only when feed.images.size() > 1, and bind android:text to
display the remaining image count using @{String.valueOf(feed.images.size() -
1)}. This will enable conditional visibility and dynamic text based on the image
count.
```

</details>

<!-- This is an auto-generated comment by CodeRabbit -->
created_at: 2025-05-22T15:35:53Z
author_association: NONE
diff_hunk: @@ -123,6 +123,33 @@
             app:layout_constraintTop_toBottomOf="@+id/tv_feed_spoiler_warning"
             tools:text="최근 잼께 봤던 무협 소설 목록 진짜들만 골라봤어요 애매한 건 빼고 주로 무협 중에서도 회귀물로 골라봤어요 왜냐면 내가 회귀물을 좋아하기 때문에 최근 잼께 봤던 무협 소설 목록 진짜들만 골라봤어요최근 잼께 봤던 무협 소설 목록 진짜들을 가 회귀물을 좋아하기 때문에 최근 잼께 봤습니다 몇글자 까지 될지 모르겠네요" />
 
+        <ImageView
+            android:id="@+id/iv_feed_image"
+            android:layout_width="0dp"
+            android:layout_height="0dp"
+            android:layout_marginHorizontal="12dp"
+            android:layout_marginTop="20dp"
+            app:layout_constraintBottom_toTopOf="@id/cl_feed_novel_info"
+            app:layout_constraintDimensionRatio="334:236"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toBottomOf="@id/tv_feed_content"
+            tools:src="@color/black" />
path: app/src/main/res/layout/item_feed.xml
user: login: coderabbitai[bot]
body: _🛠️ Refactor suggestion_

**이미지 로드를 위한 바인딩 누락 및 접근성 이슈**  
현재 `iv_feed_image` 에는 `tools:src` 만 있어 실제로 이미지를 불러오지 않습니다.  
- `loadImageUrl` (또는 프로젝트의 커스텀 BindingAdapter) 를 이용해 `feed` 모델의 이미지 URL 을 바인딩하세요.  
- `feed.images` 가 비어 있을 때 `isVisible` 을 통해 뷰를 GONE 처리해야 합니다.  
- 접근성 향상을 위해 `contentDescription` 속성도 추가가 필요합니다.  



예시 제안 diff:
```diff
 <ImageView
     android:id="@+id/iv_feed_image"
     android:layout_width="0dp"
     android:layout_height="0dp"
     android:layout_marginHorizontal="12dp"
     android:layout_marginTop="20dp"
-    tools:src="@color/black" />
+    app:loadImageUrl="@{feed.images.size() > 0 ? feed.images.get(0) : null}"
+    app:cornerRadius="@{8f}"
+    android:contentDescription="@{feed.content}"
+    app:isVisible="@{feed.images.size() > 0}" />
```


<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

```suggestion
        <ImageView
            android:id="@+id/iv_feed_image"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:layout_marginHorizontal="12dp"
            android:layout_marginTop="20dp"
            app:layout_constraintBottom_toTopOf="@id/cl_feed_novel_info"
            app:layout_constraintDimensionRatio="334:236"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@id/tv_feed_content"
            app:loadImageUrl="@{feed.images.size() > 0 ? feed.images.get(0) : null}"
            app:cornerRadius="@{8f}"
            android:contentDescription="@{feed.content}"
            app:isVisible="@{feed.images.size() > 0}" />
```

</details>

<!-- suggestion_end -->

<details>
<summary>🤖 Prompt for AI Agents</summary>

```
In app/src/main/res/layout/item_feed.xml around lines 126 to 137, the ImageView
with id iv_feed_image only has a tools:src attribute and does not bind the
actual image URL from the feed model. To fix this, add a data binding expression
using the project's loadImageUrl BindingAdapter to bind feed.images URL to the
ImageView. Also, use isVisible binding to set the view's visibility to GONE when
feed.images is empty. Finally, add a contentDescription attribute bound to a
descriptive text from the feed model to improve accessibility.
```

</details>

<!-- This is an auto-generated comment by CodeRabbit -->
created_at: 2025-05-22T15:35:53Z
author_association: NONE
diff_hunk: @@ -0,0 +1,21 @@
+package com.into.websoso.ui.feedDetail.component
+
+import androidx.compose.runtime.Composable
+import com.into.websoso.ui.feedDetail.model.ImageContainerType
+import com.into.websoso.ui.feedDetail.model.ImageContainerType.DOUBLE
+import com.into.websoso.ui.feedDetail.model.ImageContainerType.MULTIPLE
+import com.into.websoso.ui.feedDetail.model.ImageContainerType.SINGLE
+import com.into.websoso.ui.feedDetail.model.ImageContainerType.TRIPLE
+
+@Composable
+fun AdaptationFeedImageContainer(
+    imageUrls: List<String>,
+    onImageClick: (Int) -> Unit,
path: app/src/main/java/com/into/websoso/ui/feedDetail/component/AdaptationFeedImageContainer.kt
user: login: m6z1
body: c: 이 int 값이 어떤 값인지 명시해주면 좋을 것 같아요 
created_at: 2025-05-23T00:57:41Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,42 @@
+package com.into.websoso.ui.feedDetail.component
+
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.aspectRatio
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
+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.layout.ContentScale
+import androidx.compose.ui.unit.dp
+import com.into.websoso.core.common.ui.component.AdaptationImage
+import com.into.websoso.core.common.util.clickableWithoutRipple
+
+@Composable
+fun DoubleImageContainer(
+    imageUrls: List<String>,
+    onImageClick: (Int) -> Unit,
path: app/src/main/java/com/into/websoso/ui/feedDetail/component/DoubleImageContainer.kt
user: login: m6z1
body: c: 여기도 마찬가지
created_at: 2025-05-23T00:58:04Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,42 @@
+package com.into.websoso.ui.feedDetail.component
+
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.aspectRatio
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
+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.layout.ContentScale
+import androidx.compose.ui.unit.dp
+import com.into.websoso.core.common.ui.component.AdaptationImage
+import com.into.websoso.core.common.util.clickableWithoutRipple
+
+@Composable
+fun DoubleImageContainer(
+    imageUrls: List<String>,
+    onImageClick: (Int) -> Unit,
+) {
+    Row(
+        modifier = Modifier
+            .fillMaxWidth()
+            .padding(horizontal = 20.dp),
+        horizontalArrangement = Arrangement.spacedBy(8.dp),
+    ) {
+        imageUrls.take(2).forEach { imageUrl ->
path: app/src/main/java/com/into/websoso/ui/feedDetail/component/DoubleImageContainer.kt
user: login: m6z1
body: c: 이 take 하는 값들 상수화 해주면 좋을 것 같아요
created_at: 2025-05-23T00:58:35Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,43 @@
+package com.into.websoso.ui.feedDetail.component
+
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.PaddingValues
+import androidx.compose.foundation.layout.aspectRatio
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.lazy.LazyRow
+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.layout.ContentScale
+import androidx.compose.ui.unit.dp
+import com.into.websoso.core.common.ui.component.AdaptationImage
+import com.into.websoso.core.common.util.clickableWithoutRipple
+
+@Composable
+fun MultipleImageContainer(
+    imageUrls: List<String>,
+    onImageClick: (Int) -> Unit,
path: app/src/main/java/com/into/websoso/ui/feedDetail/component/MultipleImageContainer.kt
user: login: m6z1
body: c: 여기도 명시
created_at: 2025-05-23T01:00:20Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,15 @@
+package com.into.websoso.ui.feedDetail.model
+
+enum class ImageContainerType(
+    private val size: Int,
path: app/src/main/java/com/into/websoso/ui/feedDetail/model/ImageContainerType.kt
user: login: m6z1
body: a: 아니면 차라리 얘를 public 으로 열어서 take 값으로 사용하면 안 되나요 ?
created_at: 2025-05-23T01:01:14Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,15 @@
+package com.into.websoso.ui.feedDetail.model
+
+enum class ImageContainerType(
+    private val size: Int,
path: app/src/main/java/com/into/websoso/ui/feedDetail/model/ImageContainerType.kt
user: login: junseo511
body: > a: 아니면 차라리 얘를 public 으로 열어서 take 값으로 사용하면 안 되나요 ?

아니 맞네 왜 private인거죠
created_at: 2025-05-23T01:15:02Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,42 @@
+package com.into.websoso.ui.feedDetail.component
+
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.aspectRatio
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
+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.layout.ContentScale
+import androidx.compose.ui.unit.dp
+import com.into.websoso.core.common.ui.component.AdaptationImage
+import com.into.websoso.core.common.util.clickableWithoutRipple
+
+@Composable
+fun DoubleImageContainer(
+    imageUrls: List<String>,
+    onImageClick: (Int) -> Unit,
+) {
+    Row(
+        modifier = Modifier
+            .fillMaxWidth()
+            .padding(horizontal = 20.dp),
+        horizontalArrangement = Arrangement.spacedBy(8.dp),
+    ) {
+        imageUrls.take(2).forEach { imageUrl ->
+            AdaptationImage(
+                imageUrl = imageUrl,
+                contentScale = ContentScale.Crop,
+                modifier = Modifier
+                    .weight(1f)
+                    .aspectRatio(1f)
+                    .clip(RoundedCornerShape(8.dp))
+                    .clickableWithoutRipple {
+                        onImageClick(imageUrls.indexOf(imageUrl))
path: app/src/main/java/com/into/websoso/ui/feedDetail/component/DoubleImageContainer.kt
user: login: s9hn
body: forEachIndexed를 쓰면 바로 index를 넘겨줄 수 있어보여요!
created_at: 2025-05-23T01:21:26Z
author_association: MEMBER

PR comments:
user: login: coderabbitai[bot]
created_at: 2025-05-14T16:02:27Z
body: <!-- This is an auto-generated comment: summarize by coderabbit.ai -->
<!-- This is an auto-generated comment: failure by coderabbit.ai -->

> [!CAUTION]
> ## Review failed
> 
> The pull request is closed.

<!-- end of auto-generated comment: failure by coderabbit.ai -->
<!-- walkthrough_start -->

"""
## Walkthrough

피드 상세 화면에서 이미지 관련 UI가 전면적으로 도입되었습니다. 이미지 개수에 따라 적절한 이미지 컨테이너(1~3개, 다수) 컴포저블이 동적으로 렌더링되며, 이미지를 클릭하면 콜백이 트리거됩니다. 관련 인터페이스 및 레이아웃, 뷰홀더, Enum 등이 추가 및 수정되었습니다.

## Changes

| 파일/경로 요약 | 변경 내용 요약 |
|---|---|
| .../ui/feedDetail/FeedDetailActivity.kt, .../ui/feedDetail/FeedDetailClickListener.kt | `FeedDetailClickListener` 인터페이스에 `onFeedImageClick` 메서드 추가 및 구현. `FeedDetailActivity`에 해당 메서드와 연결된 네비게이션 메서드(미구현) 추가. |
| .../ui/feedDetail/adapter/FeedDetailContentViewHolder.kt | `feedDetailClickListener`를 private property로 변경. 이미지 리스트를 받아 `AdaptationFeedImageContainer` 컴포저블로 전달, 클릭 시 콜백 트리거. |
| .../ui/feedDetail/component/AdaptationFeedImageContainer.kt | 이미지 개수에 따라 적절한 이미지 컨테이너를 선택해 렌더링하는 컴포저블 함수 추가. |
| .../ui/feedDetail/component/SingleImageContainer.kt, .../DoubleImageContainer.kt, .../TripleImageContainer.kt, .../MultipleImageContainer.kt | 각각 1, 2, 3, 다수의 이미지를 표시하는 새로운 컴포저블 함수 추가. 클릭 시 인덱스와 함께 콜백 트리거. |
| .../ui/feedDetail/model/ImageContainerType.kt | 이미지 개수에 따라 컨테이너 타입을 반환하는 Enum 클래스 및 매핑 함수 추가. |
| .../res/layout/item_feed_detail_header.xml | 이미지용 ComposeView 추가 및 레이아웃 제약 조건 수정, 마진 조정. |
| .../res/layout/item_feed.xml | 이미지뷰 및 오버레이 텍스트뷰 추가, 레이아웃 제약 조건 수정. |
| .../res/drawable/bg_feed_gray_toast_radius_24dp.xml | 회색 배경과 둥근 모서리를 가진 새로운 drawable 리소스 추가. |

## Sequence Diagram(s)

```mermaid
sequenceDiagram
    participant User
    participant FeedDetailContentViewHolder
    participant AdaptationFeedImageContainer
    participant ImageContainer (Single/Double/Triple/Multiple)
    participant FeedDetailClickListener
    participant FeedDetailActivity

    User->>FeedDetailContentViewHolder: 이미지 클릭
    FeedDetailContentViewHolder->>AdaptationFeedImageContainer: 이미지 클릭 이벤트 위임
    AdaptationFeedImageContainer->>ImageContainer: 클릭 이벤트 위임 (with index)
    ImageContainer->>FeedDetailClickListener: onFeedImageClick(imageUrls, position)
    FeedDetailClickListener->>FeedDetailActivity: onFeedImageClick 호출
    FeedDetailActivity->>FeedDetailActivity: navigateToExpandedImage (미구현)
```

## Assessment against linked issues

| Objective | Addressed | Explanation |
|---|---|---|
| 피드 상세 이미지 관련 UI 구현 (#684) | ✅ |  |

## Possibly related PRs

- Team-WSS/WSS-Android#685: 동일한 `onFeedImageClick` 메서드 추가 및 이미지 컨테이너 UI 구현 관련 변경 포함, 본 PR과 직접적인 연관성 있음.

## Suggested reviewers

- yeonjeen
- s9hn

## Poem

> 🐰  
> 이미지는 한 줄, 두 줄, 세 줄,  
> 많아지면 스크롤도 줄줄!  
> 클릭하면 콜백이 깡총,  
> 토끼는 기뻐서 춤을 춘다,  
> 피드 상세, 이제 더 풍성하다!  
> 🌸
"""

<!-- walkthrough_end -->
<!-- internal state start -->


<!-- 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 -->

<!-- internal state end -->
<!-- announcements_start -->

> [!NOTE]
> <details>
> <summary>⚡️ AI Code Reviews for VS Code, Cursor, Windsurf</summary>
> 
> CodeRabbit now has a plugin for VS Code, Cursor and Windsurf. This brings AI code reviews directly in the code editor. Each commit is reviewed immediately, finding bugs before the PR is raised. Seamless context handoff to your AI code agent ensures that you can easily incorporate review feedback.
> Learn more [here](http://coderabbit.ai/ide).
> 
> </details>

<!-- announcements_end -->

---

<details>
<summary>📜 Recent review details</summary>

**Configuration used: CodeRabbit UI**
**Review profile: CHILL**
**Plan: Pro**


<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between b921f9747dc84ac9f46338c1c69867127959dfad and 0e14688f6ab6690a07656c1333c3d998cd779d1d.

</details>

<details>
<summary>📒 Files selected for processing (1)</summary>

* `app/src/main/java/com/into/websoso/ui/createFeed/component/CreateFeedImageContainer.kt` (2 hunks)

</details>

</details>
<!-- finishing_touch_checkbox_start -->

<details open="true">
<summary>✨ Finishing Touches</summary>

- [ ] <!-- {"checkboxId": "7962f53c-55bc-4827-bfbf-6a18da830691"} --> 📝 Generate Docstrings

</details>

<!-- finishing_touch_checkbox_end -->
<!-- tips_start -->

---



<details>
<summary>🪧 Tips</summary>

### Chat

There are 3 ways to chat with [CodeRabbit](https://coderabbit.ai?utm_source=oss&utm_medium=github&utm_campaign=Team-WSS/WSS-Android&utm_content=685):

- Review comments: Directly reply to a review comment made by CodeRabbit. Example:
  - `I pushed a fix in commit <commit_id>, please review it.`
  - `Explain this complex logic.`
  - `Open a follow-up GitHub issue for this discussion.`
- Files and specific lines of code (under the "Files changed" tab): Tag `@coderabbitai` in a new review comment at the desired location with your query. Examples:
  - `@coderabbitai explain this code block.`
  -	`@coderabbitai modularize this function.`
- PR comments: Tag `@coderabbitai` in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
  - `@coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.`
  - `@coderabbitai read src/utils.ts and explain its main purpose.`
  - `@coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.`
  - `@coderabbitai help me debug CodeRabbit configuration file.`

### Support

Need help? Create a ticket on our [support page](https://www.coderabbit.ai/contact-us/support) for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

### CodeRabbit Commands (Invoked using PR comments)

- `@coderabbitai pause` to pause the reviews on a PR.
- `@coderabbitai resume` to resume the paused reviews.
- `@coderabbitai review` to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
- `@coderabbitai full review` to do a full review from scratch and review all the files again.
- `@coderabbitai summary` to regenerate the summary of the PR.
- `@coderabbitai generate docstrings` to [generate docstrings](https://docs.coderabbit.ai/finishing-touches/docstrings) for this PR.
- `@coderabbitai generate sequence diagram` to generate a sequence diagram of the changes in this PR.
- `@coderabbitai resolve` resolve all the CodeRabbit review comments.
- `@coderabbitai configuration` to show the current CodeRabbit configuration for the repository.
- `@coderabbitai help` to get help.

### Other keywords and placeholders

- Add `@coderabbitai ignore` anywhere in the PR description to prevent this PR from being reviewed.
- Add `@coderabbitai summary` to generate the high-level summary at a specific location in the PR description.
- Add `@coderabbitai` anywhere in the PR title to generate the title automatically.

### CodeRabbit Configuration File (`.coderabbit.yaml`)

- You can programmatically configure CodeRabbit by adding a `.coderabbit.yaml` file to the root of your repository.
- Please see the [configuration documentation](https://docs.coderabbit.ai/guides/configure-coderabbit) for more information.
- If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: `# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json`

### Documentation and Community

- Visit our [Documentation](https://docs.coderabbit.ai) for detailed information on how to use CodeRabbit.
- Join our [Discord Community](http://discord.gg/coderabbit) to get help, request features, and share feedback.
- Follow us on [X/Twitter](https://twitter.com/coderabbitai) for updates and announcements.

</details>

<!-- tips_end -->
author_association: NONE