Files
sodalive-android/docs/prd/20260520_시리즈컴포넌트_prd.md

8.8 KiB

PRD: 시리즈 컴포넌트

1. Overview

Figma 20:3875, 20:3887, 20:3906, 20:3914 디자인을 기준으로 Android XML Views 기반 화면에서 재사용할 수 있는 Series Content Card Component와 ORIGINAL series tag를 개발한다.


2. Problem

  • 시리즈 콘텐츠 카드는 기존 오디오 콘텐츠 카드와 텍스트 구조는 유사하지만 썸네일이 정사각형이 아니라 세로형 poster ratio다.
  • 시리즈 카드가 화면마다 개별 구현되면 poster 크기, radius, label 폭, typography, ORIGINAL 태그 위치가 달라질 수 있다.
  • ORIGINAL 태그는 시리즈 카드 위에 overlay로 쓰이고 단독 태그 컴포넌트로도 관리되어야 하므로, 카드와 태그의 계약을 분리해야 한다.
  • ORIGINAL tag node는 20:3906이다.

3. Goals

  • 동일한 구조를 갖는 시리즈 콘텐츠 카드의 large, small 크기 변형을 제공한다.
  • 썸네일은 Figma 기준 세로형 poster ratio를 유지하고, corner radius 14dp, centerCrop 기준으로 표시한다.
  • 제목과 크리에이터명은 한 줄 말줄임 처리하고, 크기별 Figma typography에 맞춘다.
  • ORIGINAL 태그는 ic_series_original 아이콘, ORIGINAL 텍스트, gray_900 배경, 24dp 높이를 가진 재사용 가능한 tag view 또는 include layout으로 제공한다.
  • 시리즈 카드에는 ORIGINAL 태그 overlay 표시 여부를 선택할 수 있는 API를 제공한다.
  • 기존 오디오 콘텐츠 카드와 기존 화면 일괄 적용은 변경하지 않고, 컴포넌트 추가와 사용 계약 문서화에 한정한다.

4. Non-Goals

  • 이번 범위에서는 기존 AudioContentCardView를 시리즈 카드로 리팩터링하거나 통합하지 않는다.
  • 기존 RecyclerView adapter나 기존 콘텐츠 목록 화면에 신규 시리즈 카드를 일괄 적용하지 않는다.
  • 신규 Activity, Fragment, ViewModel을 만들지 않는다.
  • Compose 컴포넌트 또는 Compose Theme를 추가하지 않는다.
  • Figma에 표시된 하단 유료/무료 태그는 이번 범위에서 구현하지 않는다. 사용자 요청은 ORIGINAL 태그에 한정한다.
  • Figma에 없는 그림자, dim overlay 색상, pressed animation, skeleton loading, placeholder 정책은 추가하지 않는다.
  • 이미지 로딩 라이브러리 선택이나 실제 URL 로딩 정책을 컴포넌트 내부에 고정하지 않는다.

5. Target Users

  • XML 레이아웃을 작성하거나 유지보수하는 Android 개발자.
  • v2 화면에서 시리즈 콘텐츠 카드 UI를 리스트/캐러셀/그리드에 재사용하려는 개발자.

6. User Stories

  • 개발자는 같은 시리즈 카드 형태를 크기만 바꿔 재사용하고 싶다.
  • 개발자는 시리즈 콘텐츠가 ORIGINAL인지 여부에 따라 상단 태그를 표시하고 싶다.
  • 개발자는 썸네일, 콘텐츠 제목, 크리에이터명을 ViewBinding 또는 custom view API로 바인딩하고 싶다.
  • 개발자는 긴 제목과 크리에이터명이 레이아웃을 밀어내지 않고 한 줄 말줄임되기를 원한다.

7. Core Features

Series Content Card Component

Figma 2개 카드 크기와 ORIGINAL tag 사용 예시를 하나의 XML + Kotlin custom view 컴포넌트로 제공한다.

Figma References

Requirements

  • 공통 구조: 세로형 thumbnail + 하단 label contents 영역.
  • Thumbnail corner radius: radius_14.
  • Thumbnail scale type: centerCrop.
  • Thumbnail과 label 영역 사이 gap은 spacing_8 기준으로 맞춘다.
  • Title: maxLines=1, ellipsize=end, text color white.
  • Creator name: maxLines=1, ellipsize=end, text color gray_500.
  • Title과 creator name 사이 gap은 2dp로 맞춘다. 기존 spacing_2 토큰이 없으므로 구현 단계에서 XML 직접값 또는 컴포넌트 내부 상수로 처리한다.
  • ORIGINAL 태그는 thumbnail 좌상단에 붙고, 태그 container는 thumbnail radius와 충돌하지 않도록 우하단 corner radius 8dp를 가진다.
  • ORIGINAL 태그는 ic_series_original 아이콘을 사용한다.

Size Variants

Size Figma node Card width Thumbnail Label width Title style Creator style Thumbnail-label gap
large 20:3875 163dp 163dp x 230dp 151dp Typography.Heading4 Typography.Body5 spacing_8
small 20:3887 122dp 122dp x 172dp 114dp Typography.Body1 Typography.Caption2 spacing_8

ORIGINAL Tag Contract

Property Value
Figma node 20:3906
Width 101dp
Height 24dp
Background gray_900 (#202020)
Icon ic_series_original, 14dp x 14dp, left 8dp, vertically centered
Text ORIGINAL, white, Phosphate Solid style if available
Text fallback 프로젝트에 Phosphate font가 없으면 이미지/폰트 자산 추가 여부를 확인하고, 없을 때는 기존 font 리소스 중 가장 가까운 bold 스타일을 사용한다
Text position left 26dp, top 2dp 기준
Overlay position thumbnail top-left
Overlay corner bottomEnd radius 8dp

Edge Cases

  • 제목이 길면 한 줄 말줄임 처리한다.
  • 크리에이터명이 길면 한 줄 말줄임 처리한다.
  • 제목 또는 크리에이터명이 비어 있으면 호출부 데이터 문제로 간주하고 컴포넌트는 전달된 값을 그대로 표시한다.
  • 썸네일 이미지가 없거나 로딩 실패한 경우의 placeholder 정책은 호출부 또는 이미지 로딩 계층에서 결정한다.
  • size가 지정되지 않으면 large를 기본값으로 사용한다.
  • ORIGINAL 여부가 false이면 태그 영역은 gone 처리되어 thumbnail만 표시된다.

8. UX / UI Expectations

  • 두 크기 모두 같은 카드 구조와 세로형 poster thumbnail 형태를 유지한다.
  • 썸네일 radius는 모든 크기에서 14dp로 동일하다.
  • large 카드는 카드 폭 163dp, thumbnail 163dp x 230dp, label 폭 151dp로 사용한다.
  • small 카드는 카드 폭 122dp, thumbnail 122dp x 172dp, label 폭 114dp로 사용한다.
  • 텍스트는 어두운 배경 위 사용을 전제로 white/gray_500 색상 대비를 유지한다.
  • ORIGINAL 태그는 thumbnail 좌상단에 고정되어 Figma 20:3914처럼 이미지 위에 overlay된다.

9. Technical Constraints

  • 현재 프로젝트는 XML Views + ViewBinding 기반이므로 XML 레이아웃과 Kotlin custom view 패턴을 우선한다.
  • 신규 Kotlin 코드는 kr.co.vividnext.sodalive.v2.widget 패키지 하위에 둔다.
  • 재사용 레이아웃은 app/src/main/res/layout 아래에 둔다.
  • 색상, spacing, radius, typography는 기존 colors.xml, dimens.xml, typography.xml 토큰을 우선 사용한다.
  • 기존 AudioContentCardSize처럼 size contract는 순수 Kotlin 객체 또는 enum으로 분리해 단위 테스트 가능하게 한다.
  • ic_series_original.png 리소스가 이미 존재하면 그대로 사용하고, 없으면 구현 전 디자인 에셋을 추가한다.
  • 기존 화면의 동작이나 레이아웃을 요청 없이 변경하지 않는다.

10. Metrics

  • large, small 2개 size variant의 카드 폭, 썸네일 크기, label 폭이 문서와 구현에서 일치한다.
  • 제목과 크리에이터명은 한 줄 말줄임 처리된다.
  • ORIGINAL 태그는 ic_series_original 아이콘과 ORIGINAL 텍스트를 표시한다.
  • ORIGINAL 태그 표시 여부를 호출부에서 제어할 수 있다.
  • size contract 단위 테스트가 통과한다.
  • Android 리소스 병합 및 디버그 빌드가 성공한다.
  • 기존 오디오 콘텐츠 카드와 기존 화면 파일은 변경되지 않는다.

11. Open Questions

  • 사용자가 20:3096은 오타이고 20:3906이 맞다고 정정했으므로, 이 문서는 20:3906을 ORIGINAL 태그 구현 기준으로 삼는다.
  • Figma의 ORIGINAL 텍스트는 Phosphate Solid이며, 프로젝트의 @font/phosphate_solid 리소스를 사용한다.
  • 하단 유료/무료 태그는 Figma generated code에 포함되지만 사용자 요청에 없으므로 제외한다.