Files
sodalive-android/docs/20260611_크리에이터_채널_홈_탭/prd.md

62 KiB

PRD: 크리에이터 채널 신규 페이지

1. Overview

크리에이터의 대표 이미지, 팔로우/알림 상태, 대화/DM 진입 버튼, 본인 페이지 전용 액션, 탭 바, 홈 탭 컨텐츠를 포함한 크리에이터 채널 신규 페이지의 1차 범위를 Figma 296:14890 기준으로 구현한다.


2. Problem

  • 크리에이터 상세 채널을 표시할 신규 페이지가 필요하다.
  • 크리에이터 채널 상단은 OS status bar 영역까지 이미지가 확장되어야 하며, 기존 일반 화면의 title bar/inset 처리와 다를 수 있다.
  • 팔로우 상태와 알림 수신 상태에 따라 title bar 우측 액션 구성이 달라져야 한다.
  • 대화하기, DM 보내기 버튼은 권한 또는 서버 상태에 따라 없을 수 있어, 버튼 노출 조합별 배치 규칙이 필요하다.
  • 로그인 사용자가 크리에이터 본인 페이지에 진입한 경우에는 타인 페이지용 팔로우/더보기/대화 액션 대신 본인 전용 확인/업로드 액션을 제공해야 한다.
  • 스크롤 시 tab-bar가 title-bar 아래에 고정되고, title-bar 배경색이 black으로 전환되는 상단 collapsing 동작이 필요하다.
  • 이번 범위는 크리에이터 채널의 전체 상단 구성과 탭에 해당하는 컨텐츠만 포함하며, 나머지 탭의 상세 화면은 후속 범위로 분리해야 한다.
  • 홈 탭 진입 즉시 사용할 API와 서버 DTO가 확정되어 Android 구현 요구사항에 반영해야 한다.

3. Goals

  • Figma 296:14890의 크리에이터 채널 신규 페이지 상단 구조를 정의한다.
  • 크리에이터 이미지 영역은 화면 최상단부터 OS status bar 영역까지 표시한다.
  • title bar에는 좌측 뒤로가기와 우측 더보기/팔로우/알림 상태 액션을 표시한다.
  • 팔로우하지 않은 상태, 팔로우 중이면서 알림 받기 중인 상태, 팔로우 중이지만 알림 받기 중이 아닌 상태를 구분해 아이콘을 표시한다.
  • 크리에이터 이미지 영역 내 대화하기, DM 보내기 버튼 노출 조합과 정렬 규칙을 정의한다.
  • 크리에이터 본인 페이지에서는 팔로우/팔로잉, 더보기, 대화하기 액션을 제거하고 DM 확인하기 및 홈 탭 Floating Button 액션을 제공한다.
  • tab-bar는 스크롤 중 title-bar 영역까지만 이동한 뒤 고정되며, 이후 아래 컨텐츠만 스크롤되도록 한다.
  • tab-bar와 title-bar가 가까워지는 스크롤 구간에서 title-bar 배경색을 black으로 변경한다.
  • tab-bar에는 , 라이브, 오디오, 시리즈, 커뮤니티, 팬Talk, 후원을 표시한다.
  • 크리에이터 채널 진입 시 GET /api/v2/creator-channels/{creatorId}/home을 호출해 상단 구성과 홈 탭 컨텐츠에 필요한 데이터를 표시한다.
  • 서버 DTO의 CreatorActivityType과 기존 홈 추천 API의 RecommendedActivityType 내용이 동일하므로, 홈 추천 전용 타입명을 공용 CreatorActivityType으로 변경하고 공용 패키지로 이동하는 요구사항을 정의한다.

4. Non-Goals

  • 라이브, 오디오, 시리즈, 커뮤니티, 팬Talk, 후원 탭을 선택했을 때의 탭별 상세 페이지와 pagination은 이번 범위에서 제외한다.
  • Frame 1707482896과 그 하위 레이어 중 탭 첫 화면 구성에 필요한 데이터 표시 외 세부 상호작용은 이번 범위에서 제외한다.
  • 팔로우/언팔로우, 알림 켜기/끄기 API는 신규 API를 만들지 않고 기존 크리에이터 팔로우 API를 사용한다.
  • 대화하기는 기존 TalkApi.createChatRoom으로 채팅방을 생성/조회한 뒤 반환된 chatRoomIdChatRoomActivity에 진입하고, DM 보내기는 신규 DmChatRoomActivity로 이동한다. 각 화면 내부 동작 변경은 이번 범위에서 제외한다.
  • 기존 크리에이터 랭킹 페이지, 채팅 탭, DM 채팅방 상세 화면의 동작을 변경하지 않는다. 단, 본인 페이지의 DM 확인하기 진입 시 메인 대화 탭과 내부 DM 필터/탭이 선택된 상태로 열리는 진입 파라미터 처리는 이번 요구에 포함한다.
  • Figma에 표시된 iOS status bar 컴포넌트 자체를 Android에 그대로 구현하지 않는다. Android system bar/inset 정책에 맞춰 이미지 확장 요구만 반영한다.

4.1 Naming Clarification

  • 크리에이터 채널 화면 Activity는 홈 탭만 담당하는 화면이 아니라 채널 내부의 , 라이브, 오디오, 시리즈, 커뮤니티, 팬Talk, 후원 탭을 담는 컨테이너이므로 CreatorChannelActivity로 명명한다.
  • Activity layout은 activity_creator_channel.xml, ViewBinding은 ActivityCreatorChannelBinding을 사용한다.
  • GET /api/v2/creator-channels/{creatorId}/home와 홈 탭 컨텐츠를 담당하는 CreatorChannelHomeViewModel, CreatorChannelHomeUiState, CreatorChannelHomeSectionAdapter, item_creator_channel_home_* 이름은 홈 탭 전용 역할이므로 유지한다.

4.2 Future Tab Architecture Decision

  • 현재 1차 구현 범위는 탭이지만, 후속 라이브, 오디오, 시리즈, 커뮤니티, 팬Talk, 후원 탭은 각각 API, 목록, UI가 다르다.
  • 따라서 tab-bar는 단일 홈 스크롤 내부의 섹션 이동용 커스텀 tab_container가 아니라, 탭별 독립 화면 전환을 담당하는 구조로 확장해야 한다.
  • 후속 탭 구현 시 크리에이터 채널 컨테이너는 TabLayout + ViewPager2 + 탭별 Fragment 구조를 우선 검토한다.
  • CreatorChannelActivity는 공통 크리에이터 헤더, title bar 액션, 탭 컨테이너 역할을 담당하고, 각 탭의 API 호출, 목록 adapter, loading/empty/error 상태, 상세 UI는 탭별 Fragment가 담당한다.
  • 탭별 Fragment 후보는 CreatorChannelHomeFragment, CreatorChannelLiveFragment, CreatorChannelAudioFragment, CreatorChannelSeriesFragment, CreatorChannelCommunityFragment, CreatorChannelFanTalkFragment, CreatorChannelDonationFragment로 둔다.
  • 탭 전환 시 목록/스크롤 상태 보존이 필요하므로 단순 커스텀 LinearLayout 탭이나 FragmentContainerView 단일 replace 방식보다 ViewPager2 기반 상태 보존 구조가 유지보수에 유리하다.
  • 공통 헤더와 tab-bar sticky/collapsing 동작은 현재 NestedScrollView 내부 단일 RecyclerView 구조와 충돌할 수 있으므로, 후속 구현 계획 수립 시 CoordinatorLayout/AppBarLayout 또는 동등한 공통 스크롤 컨테이너 구조를 재검토한다.

5. Target Users

  • 크리에이터 채널에서 크리에이터 정보와 컨텐츠 탭을 확인하려는 앱 사용자.
  • 크리에이터를 팔로우하거나 알림을 설정하려는 앱 사용자.
  • 크리에이터와 대화 또는 DM을 시작하려는 앱 사용자.
  • 본인 크리에이터 채널에서 DM을 확인하고 컨텐츠/라이브/커뮤니티 작성 진입점을 사용하려는 크리에이터.
  • kr.co.vividnext.sodalive.v2 하위 신규 페이지를 구현/유지보수하는 Android 개발자.

6. User Stories

  • 사용자는 크리에이터 채널에 진입했을 때 대표 이미지와 크리에이터 정보를 먼저 보고 싶다.
  • 사용자는 상단에서 이전 화면으로 돌아가거나 더보기 메뉴를 열 수 있어야 한다.
  • 사용자는 팔로우하지 않은 크리에이터를 바로 팔로우할 수 있어야 한다.
  • 사용자는 팔로우 중인 크리에이터의 알림 수신 상태를 상단에서 확인하고 변경할 수 있어야 한다.
  • 사용자는 가능한 경우 크리에이터와 대화하거나 DM을 보낼 수 있어야 한다.
  • 크리에이터 본인은 본인 채널에서 팔로우/신고/대화 시작 액션을 보지 않고, DM 목록 확인과 업로드/라이브 생성 액션에 접근할 수 있어야 한다.
  • 사용자는 페이지를 스크롤해도 현재 선택 가능한 tab-bar가 상단에 고정되어 계속 접근 가능하길 기대한다.

7. Core Features

Creator Channel Page Structure

크리에이터 채널 신규 페이지는 상단 이미지 영역, title bar, tab-bar, tab 하단 컨텐츠 영역으로 구성한다.

Requirements

  • 전체 페이지 기준 Figma 노드는 296:14890이다.
  • 크리에이터 이미지 영역은 Figma 296:14892banner-creater를 기준으로 한다.
  • title bar는 Figma 296:14893title-bar를 기준으로 한다.
  • tab-bar는 Figma 296:14894tab-bar를 기준으로 한다.
  • 크리에이터 이미지 영역은 OS status bar 영역까지 확장되어 표시되어야 한다.
  • title bar는 이미지 위에 overlay되는 형태로 배치한다.
  • tab-bar는 크리에이터 이미지 영역 하단에 배치한다.
  • tab-bar 하단 컨텐츠 영역 중 이번 구현 범위는 탭 컨텐츠로 한정한다.
  • 크리에이터 채널 신규 페이지 진입 시 creatorId를 기준으로 홈 API를 즉시 호출한다.
  • 홈 API 응답의 creator 정보로 상단 이미지 영역, 팔로우/알림 상태, 대화/DM 버튼 노출 여부를 표시한다.
  • 로그인 사용자가 해당 크리에이터 본인인지 판정한 뒤, 본인 페이지 전용 title bar/action button/Floating Button 노출 정책을 적용한다.
  • 홈 API 응답의 홈 탭 데이터로 현재 라이브, 최신 오디오, 후원, 공지, 일정, 오디오 컨텐츠, 시리즈, 커뮤니티, 팬Talk 요약, 소개, 활동, SNS 영역을 표시한다.

Edge Cases

  • 크리에이터 이미지 URL이 비어 있거나 로딩 실패하면 기존 이미지 로딩/placeholder 정책을 따른다.
  • status bar 높이가 기기별로 달라도 이미지가 화면 최상단까지 자연스럽게 확장되어야 한다.
  • display cutout, gesture navigation, status bar inset 환경에서 title bar의 터치 영역이 status bar와 겹쳐 조작 불가능해지면 안 된다.

Creator Channel Home API

크리에이터 채널 신규 페이지 진입 시 홈 탭과 상단 구성에 필요한 데이터를 조회한다.

API Endpoint

  • GET /api/v2/creator-channels/{creatorId}/home

Response Contract

data class CreatorChannelHomeResponse(
    val creator: CreatorChannelCreatorResponse,
    val currentLive: CreatorChannelLiveResponse?,
    val latestAudioContent: CreatorChannelAudioContentResponse?,
    val channelDonations: List<CreatorChannelDonationResponse>,
    val notices: List<CreatorChannelCommunityPostResponse>,
    val schedules: List<CreatorChannelScheduleResponse>,
    val audioContents: List<CreatorChannelAudioContentResponse>,
    val series: List<CreatorChannelSeriesResponse>,
    val communities: List<CreatorChannelCommunityPostResponse>,
    val fanTalk: CreatorChannelFanTalkSummaryResponse,
    val introduce: String,
    val activity: CreatorChannelActivityResponse,
    val sns: CreatorChannelSnsResponse
)

data class CreatorChannelCreatorResponse(
    val creatorId: Long,
    val characterId: Long?,
    val nickname: String,
    val profileImageUrl: String,
    val followerCount: Int,
    val isAiChatAvailable: Boolean,
    val isDmAvailable: Boolean,
    val isFollow: Boolean,
    val isNotify: Boolean
)

data class CreatorChannelLiveResponse(
    val liveId: Long,
    val title: String,
    val coverImageUrl: String?,
    val beginDateTimeUtc: String,
    val price: Int,
    val isAdult: Boolean
)

data class CreatorChannelAudioContentResponse(
    val audioContentId: Long,
    val title: String,
    val duration: String?,
    val imageUrl: String?,
    val price: Int,
    val isPointAvailable: Boolean,
    val isFirstContent: Boolean,
    val seriesName: String?,
    val isOriginalSeries: Boolean?
)

data class CreatorChannelDonationResponse(
    val donationId: Long,
    val memberId: Long,
    val nickname: String,
    val profileImageUrl: String,
    val can: Int,
    val isSecret: Boolean,
    val message: String,
    val createdAtUtc: String
)

data class CreatorChannelScheduleResponse(
    val scheduledAtUtc: String,
    val title: String,
    val type: CreatorActivityType,
    val targetId: Long
)

data class CreatorChannelSeriesResponse(
    val seriesId: Long,
    val title: String,
    val coverImageUrl: String,
    val publishedDaysOfWeek: String,
    val isComplete: Boolean,
    val numberOfContent: Int,
    val isNew: Boolean,
    val isPopular: Boolean,
    val isOriginal: Boolean
)

data class CreatorChannelCommunityPostResponse(
    val postId: Long,
    val creatorId: Long,
    val creatorNickname: String,
    val creatorProfileUrl: String,
    val imageUrl: String?,
    val audioUrl: String?,
    val content: String,
    val price: Int,
    val dateUtc: String,
    val existOrdered: Boolean,
    val likeCount: Int,
    val commentCount: Int
)

data class CreatorChannelFanTalkSummaryResponse(
    val totalCount: Int,
    val latestFanTalk: CreatorChannelFanTalkResponse?
)

data class CreatorChannelFanTalkResponse(
    val fanTalkId: Long,
    val memberId: Long,
    val nickname: String,
    val profileImageUrl: String,
    val content: String,
    val languageCode: String?,
    val createdAtUtc: String
)

data class CreatorChannelActivityResponse(
    val debutDateUtc: String?,
    val dDay: String,
    val liveCount: Long,
    val liveDurationHours: Long,
    val liveContributorCount: Long,
    val audioContentCount: Long,
    val seriesCount: Long
)

data class CreatorChannelSnsResponse(
    val instagramUrl: String,
    val fancimmUrl: String,
    val xUrl: String,
    val youtubeUrl: String,
    val kakaoOpenChatUrl: String
)

enum class CreatorActivityType(val code: String) {
    LIVE("LIVE"),
    AUDIO("AUDIO"),
    COMMUNITY("COMMUNITY"),
    LIVE_REPLAY("LIVE_REPLAY")
}
  • 백엔드 CreatorActivityType 원본 enum은 LIVE, AUDIO, COMMUNITY, LIVE_REPLAY 대문자 상수와 동일한 code를 내려준다.
  • Android DTO의 CreatorChannelScheduleResponse.type은 위 서버 계약을 전제로 공용 CreatorActivityType enum을 직접 사용한다.
  • 홈 추천 등 클라이언트 내부 helper에서 대소문자 무시 파싱을 지원하더라도, 크리에이터 채널 홈 API DTO 리뷰에서는 서버가 소문자/혼합 대소문자 값을 내려주는 경우를 별도 전제로 문제 제기하지 않는다.

Requirements

  • creatorId는 페이지 진입 인자로 전달받고, creatorId > 0일 때만 홈 API를 호출한다.
  • creator.nickname, creator.profileImageUrl, creator.followerCount를 크리에이터 이미지 영역의 기본 정보로 사용한다.
  • creator.characterId대화하기 버튼 터치 시 TalkApi.createChatRoom 요청의 characterId로 사용한다.
  • creator.isFollow, creator.isNotify를 title bar 팔로우/알림 상태 표시의 기준으로 사용한다.
  • creator.isAiChatAvailabletrue이고 creator.characterId가 null이 아닐 때만 대화하기 버튼을 표시한다.
  • creator.isDmAvailabletrue일 때만 DM 보내기 버튼을 표시한다.
  • 크리에이터 본인 여부는 홈 API에 isOwner 또는 동등한 필드가 제공되면 우선 사용하고, 제공되지 않으면 로그인 사용자 정보와 creator.creatorId/연결 식별자를 대조하는 방식을 구현 계획에서 확정한다.
  • 홈 탭 영역은 CreatorChannelHomeResponse의 top-level 필드를 사용해 Figma 홈 구성에 맞춰 표시한다.
  • nullable 필드인 currentLive, latestAudioContent, coverImageUrl, imageUrl, audioUrl, latestFanTalk, debutDateUtc, languageCode, duration, seriesName, isOriginalSeries는 null 가능성을 전제로 UI 표시 여부를 결정한다.

Edge Cases

  • 홈 API 실패 시 기존 네트워크 오류 처리 정책에 맞춰 crash 없이 처리한다.
  • list 필드가 빈 배열이면 해당 홈 섹션은 기존 Figma/앱 empty 정책에 맞춰 숨기거나 비어 있는 상태로 표시한다.
  • creatorId <= 0이면 API를 호출하지 않고 기존 잘못된 진입 처리 정책을 따른다.

Title Bar

상단 title bar는 뒤로가기, 팔로우/알림 상태 액션, 더보기 액션을 제공한다.

Requirements

  • 좌측 상단 뒤로가기 아이콘은 ic_new_bar_back을 사용한다.
  • 우측 상단 더보기 아이콘은 ic_new_more를 사용한다.
  • 팔로우 상태가 아닐 때는 ic_new_follow를 표시한다.
  • 팔로우 중이고 알림 받기 중일 때는 ic_new_following, ic_bar_bell_colored를 표시한다.
  • 팔로우 중이고 알림 받기 중이 아닐 때는 ic_new_following, ic_bar_bell을 표시한다.
  • 크리에이터 본인 페이지에서는 팔로우/팔로잉 capsule, 알림 아이콘, 더보기 아이콘을 표시하지 않는다.
  • 크리에이터 본인 페이지에서는 더보기 BottomSheet 또는 차단/신고 액션에 진입할 수 없어야 한다.
  • title bar 액션은 Figma 상태별 노드를 기준으로 시각 배치를 맞춘다.
  • title bar 배경이 sticky 스크롤 상태에 의해 black으로 전환되면 뒤로가기 버튼 우측에 크리에이터 닉네임을 표시한다.
  • title bar 닉네임 텍스트는 홈 API 응답의 creator.nickname을 사용한다.
  • title bar 닉네임의 font, text size, color, ellipsize, maxLines는 app/src/main/res/layout/view_title_bar_default.xmltv_title_bar_title과 동일하게 적용한다.
  • title bar 닉네임은 우측 액션 영역과 겹치지 않아야 하며, 긴 닉네임은 1줄 말줄임 처리한다.
  • 뒤로가기 터치 시 이전 화면으로 이동한다.
  • 더보기 터치 시 기존 UserProfileActivity.showOptionMenu()에서 제공하던 차단/차단 해제, 사용자 신고, 프로필 신고 액션 메뉴를 BottomSheet 방식으로 표시한다.
  • 더보기 BottomSheet의 액션 항목과 실행 동작은 기존 UserProfileActivityuser_profile_option_menu, user_profile_option_menu_2 분기와 동일한 의미를 유지한다.
  • 팔로우/알림 상태 변경은 기존에 사용하던 크리에이터 팔로우 API를 재사용한다.
  • 팔로우/알림 상태 변경 성공 후 title bar의 isFollow, isNotify 표시 상태를 갱신한다.
  • 팔로우하지 않은 상태에서 layout_follow_capsule 터치 시 기존 크리에이터 팔로우 API를 follow=true, notify=true로 바로 호출한다.
  • 팔로잉 상태에서 iv_bell 터치 시 BottomSheet를 띄우지 않고 기존 크리에이터 팔로우 API를 follow=true, notify=false로 바로 호출해 알림을 끈다.
  • 팔로잉 상태에서 알림 끄기 API 성공 시 title bar의 isNotifyfalse로 갱신하고 iv_bell 아이콘을 알림 꺼짐 상태로 변경한다.
  • 팔로잉 상태에서 layout_follow_capsule 터치 시 BottomSheet를 띄우지 않고 기존 크리에이터 팔로우 API를 follow=false, notify=false로 바로 호출해 팔로우를 취소한다.
  • 팔로우 취소 API 완료 시 완료 토스트를 표시하고, 오류 시 오류 토스트를 표시한다.
  • 팔로우/알림 변경 요청 중에는 중복 터치로 동일 API가 중복 호출되지 않아야 한다.

State References

State Figma Node Icons
팔로우 상태가 아님 296:14287 ic_new_follow
팔로우 중 + 알림 받기 중 296:14288 ic_new_following, ic_bar_bell_colored
팔로우 중 + 알림 받기 중이 아님 296:14289 ic_new_following, ic_bar_bell

Edge Cases

  • 팔로우 상태 데이터가 아직 로딩 중이면 잘못된 상태 전환이 보이지 않도록 기존 로딩 정책에 맞춰 처리한다.
  • 팔로우/알림 상태 변경 요청 중 중복 탭으로 동일 요청이 여러 번 전송되지 않도록 한다.
  • title bar 배경이 투명한 상태에서도 아이콘이 이미지 위에서 식별 가능해야 한다.
  • title bar 배경이 투명한 초기 overlay 상태에서는 크리에이터 닉네임이 대표 이미지 영역의 닉네임과 중복 노출되지 않아야 한다.
  • 알림 끄기 API 실패 시 기존 isNotify 상태와 아이콘이 잘못 변경된 상태로 남으면 안 된다.
  • 팔로우 취소 API 실패 시 기존 isFollow, isNotify 상태와 아이콘이 잘못 변경된 상태로 남으면 안 된다.

Creator Image Area Actions

크리에이터 이미지 영역에는 대화하기, DM 보내기 액션 버튼을 표시할 수 있다.

Requirements

  • 대화하기 아이콘은 ic_new_talk를 사용한다.
  • DM 보내기 아이콘은 ic_new_dm을 사용한다.
  • 대화하기, DM 보내기 버튼은 둘 다 없을 수 있다.
  • 두 버튼이 모두 보일 때는 Figma 296:14892의 버튼 영역 배치를 따른다.
  • 두 버튼 중 하나만 보일 때는 해당 버튼을 가운데 표시한다.
  • 두 버튼이 모두 보이지 않더라도 버튼 영역의 높이와 여백은 보존한다.
  • 대화하기 버튼은 creator.isAiChatAvailable=true이고 creator.characterId가 null이 아닐 때 표시한다.
  • DM 보내기 버튼은 creator.isDmAvailable=true일 때 표시한다.
  • 대화하기 버튼 터치 시 TalkApi.createChatRoomCreateChatRoomRequest(characterId)를 전달하고, 성공 응답의 chatRoomId를 사용해 ChatRoomActivity.newIntent(context, roomId)로 이동한다.
  • DM 보내기 버튼 터치 시 신규 DmChatRoomActivity로 이동한다.
  • 크리에이터 본인 페이지에서는 대화하기 버튼을 표시하지 않는다.
  • 크리에이터 본인 페이지에서는 DM 보내기 대신 DM 확인하기 버튼을 표시한다.
  • DM 확인하기 버튼 터치 시 메인 페이지의 대화 탭으로 이동하고, 대화 화면 내부 필터/탭은 DM이 선택된 상태로 표시한다.

Edge Cases

  • 버튼 문구가 현지화 또는 서버 문구로 길어져도 버튼 내부 텍스트가 잘리거나 겹치면 안 된다.
  • 하나의 버튼만 표시될 때 좌우 여백 불균형이 보이지 않도록 중앙 정렬한다.
  • 두 버튼이 모두 숨김이어도 크리에이터 이미지 영역의 하단 정보와 tab-bar 위치가 갑자기 위로 당겨지면 안 된다.
  • 본인 페이지에서 DM 확인하기 버튼만 표시되어도 버튼은 가운데 정렬되고, 기존 버튼 영역 높이와 여백은 유지한다.

Creator Owner Home Floating Button

크리에이터 본인 페이지의 탭에는 우측 하단 Floating Button을 표시하고, 터치 시 업로드/생성 액션 버튼을 펼친다.

Requirements

  • Floating Button은 크리에이터 본인 페이지의 탭에서만 표시한다.
  • 기본 Floating Button은 Figma 665:19092를 기준으로 우측 하단에 표시한다.
  • 기본 Floating Button은 화면 우측/하단 safe area를 고려한 14dp inset, soda/400 배경, 100dp radius, 14dp padding, 38dp 아이콘 영역, 0px 0px 8px rgba(0,0,0,0.12) 수준의 shadow를 따른다.
  • 기본 Floating Button 터치 시 Figma 665:19223처럼 화면 전체에 dim을 적용하고 액션 버튼 목록을 펼친다.
  • dim은 화면 전체를 덮으며 Figma 기준 rgba(0,0,0,0.4)로 적용한다.
  • 펼쳐진 액션 버튼은 우측 하단 정렬을 유지하고, 버튼 간 세로 간격은 Figma 기준 14dp를 따른다.
  • 펼쳐진 액션 버튼은 위에서부터 커뮤니티 글 올리기, 오디오 콘텐츠 올리기, 라이브 만들기, 닫기 순서로 표시한다.
  • 커뮤니티 글 올리기 버튼 아이콘은 ic_new_upload_community_post를 사용한다.
  • 오디오 콘텐츠 올리기 버튼 아이콘은 ic_new_upload_audio를 사용한다.
  • 라이브 만들기 버튼 아이콘은 ic_new_create_live를 사용한다.
  • 닫기 버튼 아이콘은 ic_new_x_black을 사용한다.
  • 닫기 버튼은 Figma 665:19223 기준 흰색 배경을 사용하고, 터치 시 dim과 펼쳐진 액션 버튼을 닫아 기본 Floating Button 상태로 복귀한다.
  • Floating Button 펼침/닫힘 Interaction Animation은 Spring easing을 사용한다.
  • Spring animation parameter는 Mass 1, Stiffness 256, Damping 24를 따른다.
  • Floating Button과 펼쳐진 버튼은 홈 탭 컨텐츠 스크롤 위에 overlay되어야 하며, tab-bar sticky 상태와 겹쳐 조작 불가능해지면 안 된다.

Edge Cases

  • 본인 페이지가 아닌 경우 Floating Button과 펼쳐진 업로드/생성 액션은 표시하지 않는다.
  • Floating Button이 표시된 상태에서도 홈 컨텐츠 마지막 영역이 버튼에 가려져 읽기 어려우면 하단 inset/padding을 보정한다.
  • dim 표시 중에는 dim 뒤의 홈 컨텐츠, tab-bar, title bar 액션이 잘못 터치되지 않아야 한다.
  • 기기 navigation bar, gesture inset, fold/cutout 환경에서도 Floating Button 터치 영역이 화면 밖으로 밀리면 안 된다.

Tab Bar And Scroll Behavior

tab-bar는 스크롤 중 title-bar 하단에 고정되는 sticky 영역으로 동작한다.

Requirements

  • tab-bar 목록은 , 라이브, 오디오, 시리즈, 커뮤니티, 팬Talk, 후원 순서로 표시한다.
  • 이번 범위에서 기본 선택 탭은 이다.
  • 이번 범위에서는 탭 컨텐츠만 구현한다.
  • 라이브, 오디오, 시리즈, 커뮤니티, 팬Talk, 후원 탭의 상세 컨텐츠 구현은 후속 범위로 둔다.
  • tab-bar는 탭 개수가 7개인 상태에서 가로 스크롤 또는 동적 item 폭 등 기존 tab 컴포넌트 정책에 맞춰 표시되어야 한다.
  • tab-bar item 텍스트는 Figma 296:14894 기준 Pretendard Variable Medium, 16sp 상당 크기, line-height 1.45, letterSpacing 0을 따른다.
  • Android 구현에서는 동일한 font/size를 보장하기 위해 @style/Typography.Body2 또는 동등한 @font/medium + 16sp 스타일을 적용한다.
  • 사용자가 페이지를 위로 스크롤하면 크리에이터 이미지 영역은 스크롤되어 사라질 수 있다.
  • tab-bar는 완전히 화면 밖으로 사라지지 않고 title-bar 영역까지만 이동한 뒤 고정된다.
  • tab-bar가 고정된 이후에는 tab-bar 아래 컨텐츠만 세로 스크롤된다.
  • 스크롤 시 title-bar와 tab-bar의 실제 거리, 그리고 프로필 이미지가 절반 이상 사라졌는지를 함께 기준으로 title bar의 배경색을 black으로 변경한다.
  • title bar 배경색이 black으로 변경되는 동일 상태에서 title bar 닉네임도 함께 표시한다.
  • 스크롤이 다시 상단으로 돌아와 title bar가 이미지 overlay 상태로 복귀하면 title bar 닉네임은 숨긴다.
  • 스크롤이 다시 상단으로 돌아오면 title-bar 배경은 Figma 초기 상태에 맞게 이미지 overlay 상태로 복귀한다.

Edge Cases

  • 빠른 fling 중에도 tab-bar 고정 위치가 흔들리거나 title-bar와 겹치면 안 된다.
  • tab-bar 고정 상태에서 탭을 변경해도 스크롤/고정 상태가 깨지면 안 된다.
  • 7개 탭이 가로 폭을 초과해도 탭 선택과 스크롤 동작이 유지되어야 한다.
  • status bar 높이와 title bar 높이를 고려해 sticky 기준 위치를 계산해야 한다.

Home Tab Content

탭은 크리에이터 채널 홈 API 응답을 사용해 Figma 전체 페이지의 홈 컨텐츠를 표시한다.

Requirements

  • currentLive가 있으면 현재 라이브 영역에 표시한다.
  • latestAudioContent가 있으면 최신 오디오 컨텐츠 영역에 표시한다.
  • latestAudioContent 영역 터치 시 기존 오디오 콘텐츠 상세 페이지로 이동한다.
  • channelDonations는 후원 요약/목록 영역에 표시한다.
  • notices는 공지 영역에 표시한다.
  • schedules는 크리에이터 일정 영역에 표시한다.
  • audioContents는 오디오 컨텐츠 섹션에 표시한다.
  • series는 시리즈 섹션에 표시한다.
  • communities는 커뮤니티 게시글 섹션에 표시한다.
  • fanTalk는 팬Talk 요약 영역에 표시한다.
  • introduce는 소개 영역에 표시한다.
  • activity는 활동 정보 영역에 표시한다.
  • sns는 SNS 링크 영역에 표시한다.
  • 홈 탭의 각 섹션은 Figma 296:14890의 홈 화면 순서와 기존 위젯/목록 패턴을 우선 따른다.

Edge Cases

  • currentLive 또는 latestAudioContent가 null이면 해당 단일 컨텐츠 영역은 표시하지 않거나 기존 empty 정책을 따른다.
  • list 필드가 빈 배열이면 섹션 자체를 숨길지 빈 상태를 표시할지는 기존 홈/크리에이터 화면 정책을 우선 따르되, channelDonations가 빈 배열인 경우에는 Figma 290:8820의 후원 empty 안내 UI를 표시한다.
  • SNS URL 문자열이 빈 값이면 해당 SNS 진입 아이콘 또는 버튼은 비활성/숨김 처리한다.

Home Tab Content Rebuild

탭 바 아래 컨텐츠는 기존 CreatorChannelHomeSectionAdapter 내부 동적 View 조립 구현을 삭제하고, Figma 296:14895에 배치된 컴포넌트 성격의 UI를 Android XML/ViewBinding 기반으로 다시 구성한다.

Requirements

  • 재구성 기준 Figma 노드는 296:14895이다.
  • 기존 item_creator_channel_home_*.xml 12개가 동일한 섹션 컨테이너만 갖는 구조는 유지하지 않는다.
  • 기존 CreatorChannelHomeSectionAdapter 내부에서 addHeroCard, createContentTile, addFeedCard, addScheduleRow, addDonationCard, addCommentCard, addActivityRow처럼 섹션별 UI를 직접 조립하던 구현은 제거 대상으로 본다.
  • 각 홈 섹션은 하나의 Task로 분리해 문서화하고, 각 Task는 해당 섹션이 사용하는 Figma Component 또는 Figma에서 확인되는 반복 구조를 Android View로 옮기는 작업만 포함한다.
  • 섹션 제목은 Figma SectionTitle 컴포넌트를 기준으로 구성한다.
  • 컨텐츠 썸네일 카드 계열은 Figma Contents 컴포넌트를 기준으로 구성한다.
  • 커뮤니티 게시글은 Figma Feed 구조를 기준으로 구성한다.
  • 팬Talk 요약은 Figma ListComment 컴포넌트를 기준으로 구성한다.
  • SNS 영역은 Figma SNS 컴포넌트를 기준으로 구성한다.
  • 공통 컴포넌트는 재사용 가능한 Android View 또는 재사용 layout으로 먼저 정의하고, 섹션 adapter는 데이터 바인딩과 view type 선택만 담당한다.
  • 기존에 만들어 둔 공용 Android View가 Figma 컴포넌트와 요구사항을 만족하면 우선 재사용한다. 바로 재사용할 수 없으면 어댑터 내부 조립 대신 해당 Figma 컴포넌트에 맞는 신규 View/layout을 만든다.
  • Figma 296:14895화보 섹션이 보이더라도 현재 홈 API 응답과 탭 범위에는 화보 데이터가 없으므로 이번 재구성 구현 범위에서는 제외한다. 추후 API 필드가 추가되면 별도 PRD/TASK로 다룬다.

Section Requirements

  • 현재 라이브 섹션은 SectionTitle과 Figma의 라이브 카드 구조를 기준으로 하며, currentLive가 null이면 표시하지 않는다.
  • 최신 오디오 섹션은 Figma의 88dp 이미지 list row 구조를 기준으로 하며, latestAudioContent가 null이면 표시하지 않는다.
  • 최신 오디오 섹션의 latestAudioContent row/card 터치 시 latestAudioContent.audioContentId를 사용해 기존 AudioContentDetailActivity로 이동한다.
  • 후원 섹션은 후원자 프로필, 닉네임, 후원 메시지, 후원 수량을 Figma list/comment 계열 스타일에 맞춰 표시한다.
  • channelDonations가 비어 있으면 후원 섹션을 숨기지 않고 Figma 290:8820 기준 empty 안내 UI를 표시한다.
  • 후원 empty 안내 UI는 SectionTitle(후원) 아래 width match_parent, height 196dp 카드, gray_900 배경, 14dp radius, 문구 처음으로 크리에이터를 / 후원해 보세요!, 하단 흰색 capsule 후원하기 버튼으로 구성한다.
  • Figma 290:8820의 카드 width는 374dp로 확인되지만, Android 구현에서는 부모 섹션의 좌우 여백 안에서 match_parent로 처리해 화면 폭 변화에 대응한다.
  • 후원 empty 안내 UI의 후원하기 버튼 터치 동작은 후원 상세 플로우/API가 확정되기 전까지 구현 계획에서 별도로 확정한다.
  • 공지 섹션은 공지 본문, 상대 날짜, 이미지/잠금 상태가 있는 경우의 표시 정책을 Figma list/feed 계열 구조에 맞춰 정의한다.
  • 공지 섹션의 날짜는 API의 dateUtc를 그대로 노출하지 않고 기존 앱의 상대 날짜 표시 방식으로 변환해 표시한다.
  • 일정 섹션은 일정 타입 label, 제목, 일시를 Figma list row 구조에 맞춰 표시한다.
  • 오디오 컨텐츠 섹션은 Figma Contents(type=audio, size=s) 또는 88dp list row 중 Figma 296:14895의 해당 섹션 구조를 따른다.
  • 오디오 아이템에서 이미지 위에 표시되는 tv_audio_content_free_tag는 텍스트 길이에 맞춰 wrap_content width로 표시한다.
  • 오디오 컨텐츠 섹션 높이는 표시되는 audioContents 개수만큼만 차지한다. 콘텐츠가 1개일 때 3개 이상 있을 때와 같은 고정 높이를 유지하면 안 된다.
  • 오디오 컨텐츠 섹션은 빈 슬롯, 고정 row count, 남는 placeholder 영역으로 높이를 채우지 않는다.
  • 시리즈 섹션은 Figma Contents(type=series, size=m) 구조를 사용하고, isOriginal, isNew, isPopular, isComplete 상태를 tag/label 표시 정책에 연결한다.
  • 시리즈 아이템 이미지 위에 표시되는 layout_series_original_tag는 width/height를 wrap_content로 적용하고, Figma Contents(type=series, size=m) 기준 margin과 padding으로 배치한다.
  • 시리즈 아이템 터치 시 series.seriesId를 사용해 기존 시리즈 상세 페이지로 이동한다.
  • 커뮤니티 섹션은 Figma Feed 구조를 사용하고, 프로필, 작성자, 상대 작성 시간, 본문, 이미지, 유료 잠금, 좋아요/댓글 reaction을 표시한다.
  • 커뮤니티 섹션의 작성 시간은 API의 dateUtc를 그대로 노출하지 않고 기존 앱의 상대 날짜 표시 방식으로 변환해 표시한다.
  • 팬Talk 섹션은 Figma ListComment 구조를 사용하고, 전체 count와 최신 댓글 1개를 표시한다.
  • 소개 섹션은 카드 배경 없이 Figma 본문 텍스트 영역처럼 표시한다.
  • 활동 섹션은 Figma 296:15001의 배경 없는 label/value row 목록을 기준으로 표시한다.
  • 활동 섹션 제목은 SectionTitle(활동) 기준 Pretendard Variable Bold, 20sp 상당 크기를 따른다.
  • 활동 섹션의 label/value row 텍스트는 Figma 296:15001 기준 Pretendard Variable Medium, 16sp 상당 크기, line-height 1.45, letterSpacing 0을 따른다.
  • 활동 섹션 label은 #939393, value는 white 색상을 사용하고, label/value 사이 8dp gap과 row 간 8dp 간격을 유지한다.
  • 데뷔 날짜는 API의 activity.debutDateUtc 원문을 그대로 표시하지 않고 yyyy.MM.dd 형식으로 변환한다.
  • 데뷔 날짜와 데뷔 후 날짜는 공백 없이 yyyy.MM.dd(D+n) 형식으로 표시한다. 예: 2026.06.11(D+1).
  • activity.dDay가 내려오면 데뷔 날짜 뒤 괄호 안에 반드시 표시한다. 날짜 파싱 실패 또는 debutDateUtc 누락 때문에 D+n 표시가 사라지면 안 된다.
  • SNS 섹션은 Figma SNS 순서와 52dp 원형 아이콘 규격을 따른다.

Edge Cases

  • API 필드가 null이거나 빈 list이면 해당 섹션은 기본적으로 숨긴다. Figma에 별도 empty UI가 확인되거나 사용자 요구가 추가되면 섹션별 Task에 명시한다.
  • Figma component와 기존 Android 공용 View의 모델 타입이 다르면 adapter 내부에서 View를 직접 조립하지 말고 mapper 또는 section 전용 bind API를 둔다.
  • 섹션별 Task는 다른 섹션의 리팩터링을 포함하지 않는다.
  • 상대 날짜 변환 실패 또는 비정상 날짜 값이 들어와도 화면이 crash 나지 않아야 하며, 기존 앱의 날짜 fallback 정책을 따른다.

CreatorActivityType Commonization

홈 추천 API에서 사용 중인 RecommendedActivityType은 크리에이터 채널 홈 API의 CreatorActivityType과 동일한 의미를 가지므로 공용 타입으로 정리한다.

Requirements

  • 기존 RecommendedActivityType의 enum/value 내용은 서버의 CreatorActivityType과 동일하게 유지한다.
  • RecommendedActivityType이 홈 추천 전용으로만 쓰이는 이름이 아니므로 CreatorActivityType으로 변경한다.
  • 변경한 CreatorActivityType은 홈 추천 패키지가 아닌 공용 패키지로 이동한다.
  • 기존 홈 추천 API DTO와 신규 크리에이터 채널 홈 API DTO는 동일한 CreatorActivityType을 참조한다.
  • 타입명 변경으로 기존 홈 추천 화면의 동작이 달라지면 안 된다.

8. UX / UI Expectations

  • 전체 배경은 Figma 296:14890과 동일한 black 계열을 유지한다.
  • 크리에이터 대표 이미지는 첫 화면에서 가장 큰 시각 요소로 노출한다.
  • title bar 초기 상태는 이미지 위 overlay로 보이며, 스크롤 임계점 이후 black 배경으로 전환된다.
  • title bar가 black 배경으로 전환된 상태에서는 뒤로가기 버튼 우측에 크리에이터 닉네임이 표시된다.
  • title bar 아이콘은 Figma에 지정된 신규 아이콘 리소스를 사용한다.
  • 팔로우/알림 상태별 아이콘 조합은 사용자가 현재 상태를 즉시 구분할 수 있어야 한다.
  • 대화하기, DM 보내기 버튼은 노출 여부와 무관하게 이미지 영역 내 레이아웃 안정성을 유지한다.
  • tab-bar는 화면 상단에 고정된 뒤에도 title bar와 시각적으로 충돌하지 않아야 한다.
  • tab-bar는 , 라이브, 오디오, 시리즈, 커뮤니티, 팬Talk, 후원 7개 탭을 자연스럽게 표시해야 한다.
  • 탭은 크리에이터 채널 진입 직후 바로 표시되는 기본 화면이다.
  • Android 기기별 status bar/inset 차이로 인해 상단 이미지, title bar, tab-bar의 수직 위치가 어긋나면 안 된다.

9. Technical Constraints

  • Android XML Views, ViewBinding, RecyclerView/NestedScroll 계열의 기존 프로젝트 구조를 우선 확인해 따른다.
  • 신규 Activity, Fragment, ViewModel 및 연결 하위 코드는 kr.co.vividnext.sodalive.v2 패키지 하위에 작성한다.
  • 구현 전 docs/20260611_크리에이터_채널_홈_탭/plan-task.md를 작성한 뒤 해당 계획에 따라 최소 구현한다.
  • 기존에 존재하는 icon drawable 리소스가 있으면 재사용하고, 없는 경우 제공된 리소스명으로 추가한다.
  • system bar 영역 확장은 Android edge-to-edge/inset 처리와 기존 앱의 status bar 정책을 확인한 뒤 적용한다.
  • tab-bar sticky 동작은 기존 화면의 app bar/collapsing/header scroll 구현 패턴이 있으면 우선 재사용한다.
  • title bar 닉네임 텍스트 스타일은 view_title_bar_default.xmltv_title_bar_title와 동일한 @style/Typography.Heading2 기반 스타일을 따른다.
  • 후속 탭별 상세 화면은 탭마다 API, 목록, UI가 독립적이므로 TabLayout + ViewPager2 + FragmentStateAdapter 기반 구조를 우선 검토한다.
  • 후속 탭별 상세 화면을 구현할 때 CreatorChannelActivity에 API 분기와 목록 adapter를 누적하지 않고, 탭별 Fragment/ViewModel로 책임을 분리한다.
  • 홈 API는 GET /api/v2/creator-channels/{creatorId}/home 계약을 따른다.
  • 홈 API의 schedule type은 백엔드 CreatorActivityType 원본 enum과 동일하게 LIVE, AUDIO, COMMUNITY, LIVE_REPLAY 중 하나로 내려오므로 Android DTO에서 공용 enum을 직접 사용한다.
  • 팔로우/알림 변경은 기존 크리에이터 팔로우 API 사용 패턴을 재사용한다.
  • 대화하기 이동은 CharacterDetailViewModel.createChatRoom과 동일하게 TalkApi.createChatRoom 호출 후 ChatRoomActivity로 이동하는 패턴을 따른다.
  • DM 보내기 이동은 신규 DmChatRoomActivity 사용 패턴을 따른다.
  • DM 확인하기 이동은 메인 화면에서 대화 탭을 선택하고 ChatMainFragmentChatRoomFilter.DM이 선택되도록 기존 메인 탭 라우팅 구조를 확인해 연결한다.
  • 본인 페이지 Floating Button의 커뮤니티 글 올리기, 오디오 콘텐츠 올리기, 라이브 만들기는 기존 작성/업로드/라이브 생성 진입점이 있으면 재사용하고, 없으면 구현 계획에서 별도 Task로 확정한다.
  • RecommendedActivityTypeCreatorActivityType으로 변경하고 공용 패키지로 이동할 때, 홈 추천 API의 기존 참조도 함께 갱신한다.
  • navigation extra 이름, analytics/logging은 근거 파일이나 별도 요구가 확인되기 전까지 임의로 추가하지 않는다.

10. Metrics

  • 크리에이터 이미지 영역이 OS status bar 영역까지 표시된다.
  • title bar 좌측에는 ic_new_bar_back, 우측에는 ic_new_more가 표시된다.
  • 팔로우하지 않은 상태에서 ic_new_follow가 표시된다.
  • 팔로우 중 + 알림 받기 중 상태에서 ic_new_following, ic_bar_bell_colored가 표시된다.
  • 팔로우 중 + 알림 받기 중이 아닌 상태에서 ic_new_following, ic_bar_bell이 표시된다.
  • 크리에이터 본인 페이지에서는 팔로우/팔로잉, 알림, 더보기 액션이 표시되지 않는다.
  • 대화하기, DM 보내기 버튼이 모두 보일 때 Figma 기준 배치를 따른다.
  • 대화하기, DM 보내기 버튼 중 하나만 보일 때 해당 버튼이 가운데 표시된다.
  • 대화하기, DM 보내기 버튼이 모두 보이지 않아도 버튼 영역 높이와 여백이 보존된다.
  • creator.isAiChatAvailable=true이고 creator.characterId가 null이 아닐 때만 대화하기 버튼이 표시된다.
  • creator.isDmAvailable=true일 때만 DM 보내기 버튼이 표시된다.
  • 대화하기 버튼 터치 시 TalkApi.createChatRoom을 호출하고, 성공 응답의 chatRoomIdChatRoomActivity에 이동한다.
  • DM 보내기 버튼 터치 시 DmChatRoomActivity로 이동한다.
  • 크리에이터 본인 페이지에서는 대화하기 버튼이 표시되지 않고 DM 확인하기 버튼만 표시된다.
  • DM 확인하기 터치 시 메인 페이지 대화 탭으로 이동하며, 대화 화면의 DM 필터/탭이 선택된 상태로 표시된다.
  • 더보기 버튼 터치 시 기존 UserProfileActivity의 프로필 액션 메뉴와 동일한 차단/차단 해제, 사용자 신고, 프로필 신고 액션을 BottomSheet로 표시한다.
  • 팔로잉 상태에서 iv_bell 터치 시 follow=true, notify=false API를 바로 호출하고 성공 후 알림 꺼짐 아이콘으로 변경된다.
  • 팔로잉 상태에서 layout_follow_capsule 터치 시 follow=false, notify=false API를 바로 호출하고 완료/오류 토스트를 표시한다.
  • 크리에이터 본인 페이지의 홈 탭 우측 하단에는 Figma 665:19092 기준 Floating Button이 표시된다.
  • Floating Button 터치 시 Figma 665:19223 기준 전체 화면 dim과 커뮤니티 글 올리기, 오디오 콘텐츠 올리기, 라이브 만들기, 닫기 버튼이 표시된다.
  • 펼침/닫힘 애니메이션은 Spring easing, Mass 1, Stiffness 256, Damping 24를 따른다.
  • Floating Button 확장 상태의 버튼 아이콘은 위에서부터 ic_new_upload_community_post, ic_new_upload_audio, ic_new_create_live, ic_new_x_black을 사용한다.
  • tab-bar에 , 라이브, 오디오, 시리즈, 커뮤니티, 팬Talk, 후원이 표시된다.
  • tab-bar item 텍스트는 모든 선택/비선택 상태에서 Figma 296:14894와 동일하게 medium weight와 16sp 크기를 유지한다.
  • 크리에이터 채널 진입 시 GET /api/v2/creator-channels/{creatorId}/home이 호출된다.
  • 홈 API 응답의 creator.isFollow, creator.isNotify가 title bar 상태 표시 기준으로 사용된다.
  • 홈 API 응답의 currentLive, latestAudioContent, channelDonations, notices, schedules, audioContents, series, communities, fanTalk, introduce, activity, sns가 홈 탭 표시 데이터로 사용된다.
  • 최신 콘텐츠 영역 터치 시 latestAudioContent.audioContentId를 사용해 기존 오디오 콘텐츠 상세 페이지로 이동한다.
  • channelDonations가 비어 있으면 Figma 290:8820 기준 후원 empty 안내 UI와 후원하기 버튼이 표시된다.
  • 공지와 커뮤니티 게시글의 날짜는 API 원본 dateUtc 문자열이 아니라 기존 앱의 상대 날짜 표시 방식으로 표시된다.
  • 오디오 아이템의 tv_audio_content_free_tag width는 wrap_content로 적용된다.
  • 오디오 컨텐츠 섹션은 표시되는 콘텐츠 개수에 비례해 필요한 높이만 차지하며, 콘텐츠가 1개일 때 불필요한 빈 높이를 차지하지 않는다.
  • 시리즈 아이템의 layout_series_original_tag width/height는 wrap_content로 적용되고, Figma 기준 margin/padding을 따른다.
  • 시리즈 아이템 터치 시 series.seriesId를 사용해 기존 시리즈 상세 페이지로 이동한다.
  • 활동 섹션은 Figma 296:15001 기준 폰트, 색상, 간격을 따른다.
  • 활동 섹션의 데뷔 값은 activity.debutDateUtcyyyy.MM.dd로 변환하고 activity.dDay를 붙여 2026.06.11(D+1) 형식으로 표시한다.
  • activity.dDay 값이 있으면 데뷔 날짜 파싱 여부와 무관하게 화면에서 누락되지 않는다.
  • 스크롤 시 tab-bar가 title-bar 영역까지 이동한 뒤 고정된다.
  • tab-bar 고정 이후 하단 컨텐츠만 스크롤된다.
  • title-bar와 tab-bar의 실제 거리 및 프로필 이미지가 절반 이상 사라진 상태를 기준으로 title-bar 배경색이 black으로 변경된다.
  • title-bar 배경색이 black으로 변경된 상태에서 뒤로가기 버튼 우측에 홈 API 응답의 creator.nickname이 표시된다.
  • title-bar 닉네임은 view_title_bar_default.xmltv_title_bar_title과 동일한 텍스트 스타일을 사용하고, 우측 액션 영역과 겹치지 않는다.
  • title-bar가 이미지 overlay 상태로 복귀하면 title-bar 닉네임은 숨겨진다.
  • RecommendedActivityType은 공용 CreatorActivityType으로 변경되고, 홈 추천 API와 크리에이터 채널 홈 API가 같은 타입을 참조한다.
  • 라이브, 오디오, 시리즈, 커뮤니티, 팬Talk, 후원 탭 상세 화면은 이번 구현 범위로 사용되지 않는다.
  • 탭 바 아래 홈 컨텐츠는 Figma 296:14895 기준으로 기존 동적 조립 UI를 삭제하고 섹션별 Figma component 기반 UI로 재구성된다.
  • 홈 컨텐츠 재구성에서 화보 섹션은 현재 API 응답에 데이터가 없으므로 구현 범위에서 제외한다.

11. Open Questions

  • 크리에이터 채널 신규 페이지의 진입점과 전달받을 Android extra 또는 navigation argument 이름은 구현 계획에서 기존 이동 패턴을 확인해 확정한다.
  • 홈 탭 각 섹션의 empty 상태를 섹션 숨김으로 처리할지, 빈 상태 UI로 처리할지는 기존 크리에이터/홈 화면 패턴 확인이 필요하다.
  • 팔로우/알림 변경 성공 후 홈 API를 재조회할지 여부는 구현 계획에서 확정하되, title bar의 isFollow, isNotify와 아이콘은 API 성공 직후 사용자 액션 결과가 즉시 반영되어야 한다.
  • 더보기 BottomSheet의 정확한 UI 레이아웃은 기존 UserProfileActivity의 메뉴 항목 의미를 유지하되, 구현 계획에서 기존 BottomSheet 컴포넌트 재사용 가능성을 확인해 확정한다.
  • 크리에이터 본인 여부를 판정할 API 필드(isOwner 등)가 제공되는지, 또는 로그인 사용자 정보와 creator.creatorId/연결 식별자를 대조해야 하는지는 구현 계획에서 확정한다.
  • DM 확인하기를 위해 MainActivity에서 대화 탭을 선택하고 ChatMainFragmentDM 필터를 선택하는 navigation extra/action 이름은 구현 계획에서 기존 메인 탭 라우팅을 확인해 확정한다.
  • Floating Button 확장 상태에서 dim 영역 터치도 닫기 동작으로 처리할지, 닫기 버튼만 닫기 동작으로 처리할지는 구현 계획에서 확정한다.
  • 커뮤니티 글 올리기, 오디오 콘텐츠 올리기, 라이브 만들기 버튼이 연결할 기존 작성/업로드/라이브 생성 화면과 전달 파라미터는 구현 계획에서 확인한다.
  • 후속 탭 구현 시 공통 헤더가 모든 탭에서 동일하게 유지될지, 탭별 화면에서 헤더 노출/스크롤 정책이 달라질지 확인이 필요하다.
  • 후속 탭 구현 시 ViewPager2 스와이프 전환을 허용할지, 탭 클릭 전환만 허용할지 확인이 필요하다.
  • 후속 탭 API의 pagination, refresh, empty/error UI 정책은 탭별 API 계약이 확정된 뒤 계획/TASK 문서에 별도로 정의한다.

12. References


13. Verification Log

  • 2026-06-11: AGENTS.md, docs/agent-guides/work-plan-docs.md, docs/prd/sample-prd.md를 확인해 신규 문서 경로와 PRD 구성 규칙을 확인했다.

  • 2026-06-11: Figma 296:14890 metadata와 screenshot을 확인해 banner-creater, title-bar, tab-bar, StatusBar / iPhone 13, 제외 대상 Frame 1707482896 구조를 확인했다.

  • 2026-06-11: 사용자 제공 요구사항에 따라 title bar 아이콘, 팔로우/알림 상태별 아이콘, 크리에이터 이미지 영역 버튼 노출 규칙, status bar 영역 이미지 표시, sticky tab-bar 및 title-bar black 전환 요구사항을 PRD에 반영했다.

  • 2026-06-11: 이번 단계는 PRD 작성만 수행했으며 구현/빌드/테스트는 실행하지 않았다.

  • 2026-06-12: 사용자 추가 제공 요구사항에 따라 이번 범위를 크리에이터 채널 전체 구성과 탭으로 한정하고, tab-bar 7개 항목, 홈 API Endpoint, 서버 DTO, 기존 크리에이터 팔로우 API 재사용, 대화하기/DM 보내기 이동 대상, CreatorActivityType 공용화, title bar black 전환 기준을 PRD에 반영했다.

  • 2026-06-12: 이번 단계는 PRD 문서 보완만 수행했으며 구현/빌드/테스트는 실행하지 않았다.

  • 2026-06-12: 문서 범위가 크리에이터 채널 신규 페이지 전체가 아니라 홈 탭 1차 범위임을 명확히 하기 위해 문서 폴더명을 docs/20260611_크리에이터_채널_신규_페이지/에서 docs/20260611_크리에이터_채널_홈_탭/으로 변경했다.

  • 2026-06-12: 사용자 추가 요구사항에 따라 CreatorChannelCreatorResponse.characterId: Long?를 추가하고, 대화하기 이동을 TalkApi.createChatRoom 호출 후 반환된 chatRoomIdChatRoomActivity에 진입하는 흐름으로 변경했다.

  • 2026-06-13: Phase 2/3 구현으로 RecommendedActivityType을 공용 CreatorActivityType으로 이동하고 홈 추천 참조를 갱신했으며, 크리에이터 채널 홈 API/DTO/Repository와 Koin API/Repository 등록을 추가했다.

  • 2026-06-13: CreatorChannelCreatorResponse.characterId: Long?, CreatorChannelScheduleResponse.type: CreatorActivityType, GET /api/v2/creator-channels/{creatorId}/home 계약이 구현 DTO/API에 반영됨을 테스트와 컴파일로 확인했다.

  • 2026-06-13: 검증으로 v2.common.*, v2.creatorchannel.*, compileDebugKotlin, mergeDebugResources, ktlintCheck는 성공했다. v2.main.home.* 전체 실행은 기존 source-path 테스트의 FileNotFoundException으로 일부 실패했으며, 타입 공용화 관련 focused 홈 테스트는 성공했다.

  • 2026-06-13: 백엔드 CreatorActivityType 원본 enum이 LIVE, AUDIO, COMMUNITY, LIVE_REPLAY 대문자 상수와 동일한 code를 사용함을 확인해 Android Gson enum 파싱용 별도 TypeAdapter는 추가하지 않기로 판단했다.

  • 2026-06-13: 사용자 추가 요청에 따라 신규 크리에이터 채널 홈 패키지를 kr.co.vividnext.sodalive.v2.creatorchannel에서 kr.co.vividnext.sodalive.v2.creator.channel로 변경했다.

  • 2026-06-13: 사용자 확인에 따라 백엔드 CreatorActivityType 원본 enum과 동일한 대문자 code 계약을 API 계약/기술 제약에 명시했다. 이후 코드리뷰에서는 별도 서버 계약 변경 근거가 없는 한 크리에이터 채널 홈 DTO의 CreatorActivityType 직접 사용과 Gson enum TypeAdapter 부재를 대소문자 대응 문제로 제기하지 않는다. 이번 단계는 문서 수정만 수행했으며 빌드/테스트는 실행하지 않았다.

  • 2026-06-15: 사용자 요청에 따라 탭 바 아래 홈 컨텐츠를 기존 동적 조립 UI에서 Figma 296:14895SectionTitle, Contents, Feed, ListComment, SNS 컴포넌트 기반 UI로 전면 재구성하는 요구사항을 추가했다. 이번 단계는 문서 수정만 수행했으며 구현/빌드/테스트는 실행하지 않았다.

  • 2026-06-15: Phase 8 최종 단위 테스트로 ./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.common.*", ./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.*", ./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.main.home.*"를 순차 실행해 모두 BUILD SUCCESSFUL을 확인했다.

  • 2026-06-15: Phase 8 리소스/컴파일/린트 검증으로 ./gradlew :app:mergeDebugResources, ./gradlew :app:compileDebugKotlin, ./gradlew :app:ktlintCheck를 순차 실행해 모두 BUILD SUCCESSFUL을 확인했다. ktlintCheck.editorconfig disabled_rules deprecation 경고와 Gradle deprecation warning은 기존 경고로 이번 변경과 무관하다.

  • 2026-06-15: Phase 8 수동 화면 검증 준비로 Figma 296:14890, 296:14892, 296:14287, 296:14288, 296:14289 스크린샷을 확인하고 구현 소스와 source test를 대조했다. ./gradlew :app:assembleDebugBUILD SUCCESSFUL이었으나, 설치/실행 시점에 연결 기기가 사라져 adb install -r "app/build/outputs/apk/debug/app-debug.apk"adb: no devices/emulators found로 실패했다. 재확인한 adb devices에도 기기가 없어 실제 전면 화면 캡처와 스크롤/클릭 육안 검증은 미완료로 남겼다.

  • 2026-06-15: 사용자 요청에 따라 크리에이터 채널 화면 컨테이너 이름을 CreatorChannelHomeActivity에서 CreatorChannelActivity로 변경하는 요구사항을 추가했다. Activity layout/ViewBinding은 각각 activity_creator_channel.xml, ActivityCreatorChannelBinding으로 정리하고, 홈 탭 전용 ViewModel/UiState/SectionAdapter/item layout 이름은 유지하는 것으로 범위를 고정했다. 이번 단계는 문서 요구사항 보완이며 구현 검증은 계획 문서에 누적한다.

  • 2026-06-15: 컨테이너 이름 변경 구현 후 CreatorChannelActivity, activity_creator_channel.xml, ActivityCreatorChannelBinding 기준으로 Manifest/진입점/source test를 갱신했다. focused test, 홈 진입점 테스트, 크리에이터 채널 전체 테스트, 리소스 merge, Kotlin compile, git diff --check는 통과했으며, ktlintCheck는 기존 audio_content 패키지명 underscore 규칙 위반으로 실패해 범위 외 이슈로 기록했다.

  • 2026-06-15: 사용자 확인에 따라 후속 라이브, 오디오, 시리즈, 커뮤니티, 팬Talk, 후원 탭은 각각 API, 목록, UI가 다른 독립 화면이라는 전제를 PRD에 추가했다. 이에 따라 후속 탭 구현 방향은 현재 커스텀 tab_container 확장이 아니라 TabLayout + ViewPager2 + 탭별 Fragment 구조를 우선 검토하는 것으로 기록했다. 이번 단계는 PRD 문서 보완만 수행했으며, 사용자 요청에 따라 plan-task.md 작성과 구현/빌드/테스트는 실행하지 않았다.

  • 2026-06-15: 사용자 요청에 따라 sticky 스크롤로 title bar 배경이 black으로 전환되면 뒤로가기 버튼 우측에 크리에이터 닉네임을 표시하는 요구사항을 PRD에 추가했다. 닉네임 텍스트 스타일은 app/src/main/res/layout/view_title_bar_default.xmltv_title_bar_title와 동일하게 적용하는 것으로 기록했다. 이번 단계는 PRD 문서 보완만 수행했으며 구현/빌드/테스트는 실행하지 않았다.

  • 2026-06-16: Figma 296:14894를 확인해 tab-bar item 텍스트가 Pretendard Variable Medium, 16px, line-height 1.45, letterSpacing 0으로 정의되어 있음을 확인했다. Android 구현에서는 @style/Typography.Body2 또는 동등한 @font/medium + 16sp 스타일을 사용해 선택/비선택 탭의 font와 크기를 동일하게 맞추는 요구사항을 추가했다.

  • 2026-06-16: 사용자 요청에 따라 더보기 버튼은 기존 UserProfileActivity.showOptionMenu()의 차단/차단 해제, 사용자 신고, 프로필 신고 액션을 BottomSheet 방식으로 표시하도록 PRD에 추가했다. 또한 팔로잉 상태에서 알림 끄기는 iv_bell 터치 즉시 follow=true, notify=false API 호출 후 아이콘을 변경하고, 팔로우 취소는 layout_follow_capsule 터치 즉시 follow=false, notify=false API 호출 후 완료/오류 토스트를 표시하도록 요구사항을 추가했다. 이번 단계는 PRD 문서 보완만 수행했으며 plan-task.md와 구현/빌드/테스트는 실행하지 않았다.

  • 2026-06-16: Figma 290:8820 metadata와 screenshot을 확인해 후원 empty 안내 UI가 SectionTitle(후원), 374dp x 196dp gray_900 카드, 처음으로 크리에이터를 / 후원해 보세요! 문구, 하단 흰색 후원하기 capsule 버튼으로 구성됨을 확인했다. Android 구현 요구는 사용자 추가 요청에 따라 카드 width를 374dp 고정이 아닌 부모 섹션 내 match_parent로 처리하도록 PRD에 반영했다. 또한 최신 콘텐츠 터치 시 오디오 콘텐츠 상세 페이지로 이동하고, 공지/커뮤니티 게시글 날짜는 기존 앱의 상대 날짜 표시 방식으로 표시하도록 요구사항을 추가했다. 이번 단계는 PRD 문서 보완만 수행했으며 plan-task.md와 구현/빌드/테스트는 실행하지 않았다.

  • 2026-06-16: 사용자 요청에 따라 오디오 아이템의 이미지 위 free tag(tv_audio_content_free_tag) width를 wrap_content로 표시하고, 오디오 컨텐츠 섹션 높이는 표시되는 콘텐츠 개수만큼만 차지하도록 PRD에 추가했다. 콘텐츠가 1개일 때 3개 이상 있을 때와 같은 고정 높이나 빈 placeholder 영역을 유지하지 않는 요구사항을 명시했다. 이번 단계는 PRD 문서 보완만 수행했으며 plan-task.md와 구현/빌드/테스트는 실행하지 않았다.

  • 2026-06-16: 사용자 요청에 따라 시리즈 아이템의 이미지 위 original tag(layout_series_original_tag) width/height를 wrap_content로 적용하고 Figma 기준 margin/padding을 따르도록 PRD에 추가했다. 또한 시리즈 아이템 터치 시 series.seriesId를 사용해 기존 시리즈 상세 페이지로 이동하는 요구사항을 추가했다. 이번 단계는 PRD 문서 보완만 수행했으며 plan-task.md와 구현/빌드/테스트는 실행하지 않았다.

  • 2026-06-16: Figma 296:15001 metadata와 screenshot을 확인해 활동 영역이 SectionTitle(활동), label/value row, Pretendard Variable Medium 16px, label #939393, value white, 데뷔 값 예시 2026.06.11(D+1) 형식으로 구성됨을 확인했다. 사용자 요청에 따라 활동 영역 폰트, 데뷔 날짜 yyyy.MM.dd(D+n) 표시 형식, activity.dDay 누락 방지 요구사항을 PRD에 추가했다. 이번 단계는 PRD 문서 보완만 수행했으며 plan-task.md와 구현/빌드/테스트는 실행하지 않았다.

  • 2026-06-16: Figma 665:19092, 665:19223 metadata와 screenshot을 확인해 크리에이터 본인 페이지 홈 탭의 기본 Floating Button과 dim 확장 상태를 확인했다. 사용자 요청에 따라 본인 페이지에서 팔로우/팔로잉, 더보기, 대화하기를 제거하고 DM 확인하기를 통해 메인 대화 탭의 DM 필터 선택 상태로 이동하는 요구사항을 추가했다. 또한 본인 페이지 홈 탭 Floating Button, 전체 dim, 4개 버튼 순서와 아이콘, Spring animation parameter를 PRD에 추가했다. 이번 단계는 PRD 문서 보완만 수행했으며 plan-task.md와 구현/빌드/테스트는 실행하지 않았다.