From c38c8656e3c40be2af5df7b13afa630935b26e4c Mon Sep 17 00:00:00 2001 From: Yu Sung Date: Sun, 12 Jul 2026 17:33:05 +0900 Subject: [PATCH] =?UTF-8?q?fix(main):=20=EB=B3=B4=EC=9D=B4=EC=8A=A4?= =?UTF-8?q?=EC=98=A8=20=EC=A0=84=EC=9A=A9=20=EC=B9=B4=EB=93=9C=20=ED=81=AC?= =?UTF-8?q?=EA=B8=B0=EB=A5=BC=20=EC=A1=B0=EC=A0=95=ED=95=9C=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Components/MainContentVoiceOnOnlySection.swift | 13 +++++++++++-- docs/20260705_메인_콘텐츠_내부_추천_탭/prd.md | 3 +++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/SodaLive/Sources/V2/Main/Content/Recommendation/Components/MainContentVoiceOnOnlySection.swift b/SodaLive/Sources/V2/Main/Content/Recommendation/Components/MainContentVoiceOnOnlySection.swift index 0e77fe6b..f5e26ea6 100644 --- a/SodaLive/Sources/V2/Main/Content/Recommendation/Components/MainContentVoiceOnOnlySection.swift +++ b/SodaLive/Sources/V2/Main/Content/Recommendation/Components/MainContentVoiceOnOnlySection.swift @@ -6,6 +6,15 @@ struct MainContentVoiceOnOnlySection: View { let action: (() -> Void)? let onTapSeries: (Int) -> Void + private let baseDeviceWidth: CGFloat = 402 + private let maxItemWidth: CGFloat = 163 + private let maxItemHeight: CGFloat = 230 + + private var itemSize: CGSize { + let scale = min(1, UIScreen.main.bounds.width / baseDeviceWidth) + return CGSize(width: maxItemWidth * scale, height: maxItemHeight * scale) + } + var body: some View { if !items.isEmpty { VStack(alignment: .leading, spacing: SodaSpacing.s12) { @@ -20,13 +29,13 @@ struct MainContentVoiceOnOnlySection: View { ZStack(alignment: .topLeading) { DownsampledKFImage( url: URL(string: item.coverImageUrl), - size: CGSize(width: 122, height: 172) + size: itemSize ) .background(Color.gray800) originalTag } - .frame(width: 122, height: 172) + .frame(width: itemSize.width, height: itemSize.height) .clipShape(RoundedRectangle(cornerRadius: SodaSpacing.s14, style: .continuous)) } .buttonStyle(.plain) diff --git a/docs/20260705_메인_콘텐츠_내부_추천_탭/prd.md b/docs/20260705_메인_콘텐츠_내부_추천_탭/prd.md index f5e33b39..682d81f3 100644 --- a/docs/20260705_메인_콘텐츠_내부_추천_탭/prd.md +++ b/docs/20260705_메인_콘텐츠_내부_추천_탭/prd.md @@ -142,6 +142,7 @@ Swift 모델은 기존 V2 관례에 맞춰 `Decodable` 구조체로 선언한다 - `추천 오디오`는 2열 grid로 표시한다. - 텍스트가 길면 한 줄 또는 Figma 기준 line limit로 말줄임 처리한다. - 카드/row의 루트 레이아웃은 가능한 부모 width, grid column, aspect ratio 기반으로 구성한다. +- `오직 보이스온에서만!` 섹션 item은 Figma `24:6745` 기준 device width가 402 이상이면 `163x230`으로 표시하고, 402 미만이면 `deviceWidth / 402` 비율로 동일하게 축소한다. ## 9. Technical Constraints - 신규 기능 파일은 `SodaLive/Sources/V2/Main/Content/Recommendation/**` 하위에 둔다. @@ -161,6 +162,7 @@ Swift 모델은 기존 V2 관례에 맞춰 `Decodable` 구조체로 선언한다 - API 응답의 구현 대상 배열이 각 Figma 섹션에 매핑된다. - `추천 시리즈`, `#키워드의 오디오` 섹션은 구현되지 않는다. - `오직 보이스온에서만!` 섹션은 `ic_series_original` + `img_new_only` 조합으로 `ONLY` 표시를 노출한다. +- `오직 보이스온에서만!` 섹션 item 크기는 402 이상 device width에서 `163x230`이고, 402 미만 device width에서는 같은 비율로 축소된다. - 오디오 item 탭 시 기존 content detail guard 흐름을 통해 상세로 이동한다. - `AudioBannerResponse.seriesId`와 `OriginalSeriesResponse.seriesId` 탭 시 `seriesDetail`로 이동한다. - `AudioBannerResponse.link`는 deep link 우선 처리 후, deep link가 아니면 외부 브라우저로 열린다. @@ -177,3 +179,4 @@ Swift 모델은 기존 V2 관례에 맞춰 `Decodable` 구조체로 선언한다 - 2026-07-05: 사용자 확인으로 댓글 preview bubble에는 nickname을 표시하지 않고, 배너 `link`는 deep link 우선 후 외부 브라우저로 열며, `seriesId`는 `seriesDetail` route로 이동하도록 확정했다. - 2026-07-08: Figma `24:6738` 기준으로 콘텐츠 탭 title bar가 홈 탭 로고/bell 구성이 아니라 좌측 고정 title `콘텐츠`와 우측 `ic_bar_cash`/`ic_bar_search`/`ic_bar_storage` 구성을 사용하도록 요구사항을 보완했다. - 2026-07-12: 요청에 따라 `최근 댓글이 많은 오디오` 섹션 타이틀을 `크리에이터의 댓글 많은 오디오`로 변경했다. +- 2026-07-12: Figma `24:6745` 기준으로 `오직 보이스온에서만!` 섹션 item 크기를 402 이상 device width에서는 `163x230`, 402 미만 device width에서는 `deviceWidth / 402` 비율 축소로 확정했다.