diff --git a/app/src/main/java/kr/co/vividnext/sodalive/v2/widget/feed/FeedContentImageSize.kt b/app/src/main/java/kr/co/vividnext/sodalive/v2/widget/feed/FeedContentImageSize.kt new file mode 100644 index 00000000..e280e42a --- /dev/null +++ b/app/src/main/java/kr/co/vividnext/sodalive/v2/widget/feed/FeedContentImageSize.kt @@ -0,0 +1,14 @@ +package kr.co.vividnext.sodalive.v2.widget.feed + +data class FeedContentImageSize( + val widthDp: Int, + val heightDp: Int +) { + companion object { + fun from(widthDp: Int, category: FeedContentCategory): FeedContentImageSize { + require(widthDp > 0) { "widthDp must be greater than 0." } + val height = (widthDp * category.ratioHeight.toFloat() / category.ratioWidth).toInt() + return FeedContentImageSize(widthDp = widthDp, heightDp = height) + } + } +} diff --git a/app/src/main/java/kr/co/vividnext/sodalive/v2/widget/feed/FeedSize.kt b/app/src/main/java/kr/co/vividnext/sodalive/v2/widget/feed/FeedSize.kt new file mode 100644 index 00000000..a7446f9d --- /dev/null +++ b/app/src/main/java/kr/co/vividnext/sodalive/v2/widget/feed/FeedSize.kt @@ -0,0 +1,27 @@ +package kr.co.vividnext.sodalive.v2.widget.feed + +data class FeedSize( + val rootWidthDp: Int +) { + companion object { + private const val FIGMA_ROOT_WIDTH_DP = 374 + + fun from( + variant: FeedVariant, + widthMode: FeedWidthMode, + parentAvailableWidthDp: Int, + horizontalItemDecorationDp: Int = 0 + ): FeedSize { + val width = when (widthMode) { + FeedWidthMode.FigmaFixed -> FIGMA_ROOT_WIDTH_DP + FeedWidthMode.ParentAvailable -> { + require(parentAvailableWidthDp > 0) { "parentAvailableWidthDp must be greater than 0." } + require(horizontalItemDecorationDp >= 0) { "horizontalItemDecorationDp must be 0 or greater." } + parentAvailableWidthDp - horizontalItemDecorationDp + } + } + require(width > 0) { "rootWidthDp must be greater than 0." } + return FeedSize(rootWidthDp = width) + } + } +} diff --git a/app/src/main/java/kr/co/vividnext/sodalive/v2/widget/feed/FeedWidthMode.kt b/app/src/main/java/kr/co/vividnext/sodalive/v2/widget/feed/FeedWidthMode.kt new file mode 100644 index 00000000..8993125e --- /dev/null +++ b/app/src/main/java/kr/co/vividnext/sodalive/v2/widget/feed/FeedWidthMode.kt @@ -0,0 +1,6 @@ +package kr.co.vividnext.sodalive.v2.widget.feed + +enum class FeedWidthMode { + FigmaFixed, + ParentAvailable +} diff --git a/app/src/test/java/kr/co/vividnext/sodalive/v2/widget/feed/FeedContentImageSizeTest.kt b/app/src/test/java/kr/co/vividnext/sodalive/v2/widget/feed/FeedContentImageSizeTest.kt new file mode 100644 index 00000000..75302617 --- /dev/null +++ b/app/src/test/java/kr/co/vividnext/sodalive/v2/widget/feed/FeedContentImageSizeTest.kt @@ -0,0 +1,40 @@ +package kr.co.vividnext.sodalive.v2.widget.feed + +import org.junit.Assert.assertEquals +import kr.co.vividnext.sodalive.R +import org.junit.Test + +class FeedContentImageSizeTest { + + @Test + fun `content category keeps one to one ratio`() { + val size = FeedContentImageSize.from(widthDp = 163, category = FeedContentCategory.Content) + + assertEquals(163, size.widthDp) + assertEquals(163, size.heightDp) + assertEquals(R.string.feed_content_category_content, FeedContentCategory.Content.labelResId) + } + + @Test + fun `series category keeps configured width and uses 163 by 230 ratio`() { + val size = FeedContentImageSize.from(widthDp = 163, category = FeedContentCategory.Series) + + assertEquals(163, size.widthDp) + assertEquals(230, size.heightDp) + assertEquals(R.string.feed_content_category_series, FeedContentCategory.Series.labelResId) + } + + @Test + fun `magazine category keeps configured width and uses 163 by 218 ratio`() { + val size = FeedContentImageSize.from(widthDp = 163, category = FeedContentCategory.Magazine) + + assertEquals(163, size.widthDp) + assertEquals(218, size.heightDp) + assertEquals(R.string.feed_content_category_magazine, FeedContentCategory.Magazine.labelResId) + } + + @Test(expected = IllegalArgumentException::class) + fun `image width must be positive`() { + FeedContentImageSize.from(widthDp = 0, category = FeedContentCategory.Content) + } +} diff --git a/app/src/test/java/kr/co/vividnext/sodalive/v2/widget/feed/FeedSizeTest.kt b/app/src/test/java/kr/co/vividnext/sodalive/v2/widget/feed/FeedSizeTest.kt new file mode 100644 index 00000000..5298326f --- /dev/null +++ b/app/src/test/java/kr/co/vividnext/sodalive/v2/widget/feed/FeedSizeTest.kt @@ -0,0 +1,61 @@ +package kr.co.vividnext.sodalive.v2.widget.feed + +import org.junit.Assert.assertEquals +import org.junit.Test + +class FeedSizeTest { + + @Test + fun `horizontal scroll uses figma width`() { + val size = FeedSize.from( + variant = FeedVariant.Rank, + widthMode = FeedWidthMode.FigmaFixed, + parentAvailableWidthDp = 320 + ) + + assertEquals(374, size.rootWidthDp) + } + + @Test + fun `multi item row uses figma width`() { + val size = FeedSize.from( + variant = FeedVariant.Content, + widthMode = FeedWidthMode.FigmaFixed, + parentAvailableWidthDp = 720 + ) + + assertEquals(374, size.rootWidthDp) + } + + @Test + fun `single item row uses parent available width`() { + val size = FeedSize.from( + variant = FeedVariant.Live, + widthMode = FeedWidthMode.ParentAvailable, + parentAvailableWidthDp = 328 + ) + + assertEquals(328, size.rootWidthDp) + } + + @Test + fun `single item row subtracts horizontal item decoration from parent available width`() { + val size = FeedSize.from( + variant = FeedVariant.Live, + widthMode = FeedWidthMode.ParentAvailable, + parentAvailableWidthDp = 328, + horizontalItemDecorationDp = 24 + ) + + assertEquals(304, size.rootWidthDp) + } + + @Test(expected = IllegalArgumentException::class) + fun `parent available width must be positive for parent available mode`() { + FeedSize.from( + variant = FeedVariant.Community, + widthMode = FeedWidthMode.ParentAvailable, + parentAvailableWidthDp = 0 + ) + } +}