64 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으로 채팅방을 생성/조회한 뒤 반환된chatRoomId로ChatRoomActivity에 진입하고,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:14892의banner-creater를 기준으로 한다. - title bar는 Figma
296:14893의title-bar를 기준으로 한다. - tab-bar는 Figma
296:14894의tab-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은 위 서버 계약을 전제로 공용CreatorActivityTypeenum을 직접 사용한다. - 홈 추천 등 클라이언트 내부 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.isAiChatAvailable이true이고creator.characterId가 null이 아닐 때만대화하기버튼을 표시한다.creator.isDmAvailable이true일 때만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.xml의tv_title_bar_title과 동일하게 적용한다. - title bar 닉네임은 우측 액션 영역과 겹치지 않아야 하며, 긴 닉네임은 1줄 말줄임 처리한다.
- 뒤로가기 터치 시 이전 화면으로 이동한다.
- 더보기 터치 시 기존
UserProfileActivity.showOptionMenu()에서 제공하던 차단/차단 해제, 사용자 신고, 프로필 신고 액션 메뉴를 BottomSheet 방식으로 표시한다. - 더보기 BottomSheet의 액션 항목과 실행 동작은 기존
UserProfileActivity의user_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의
isNotify를false로 갱신하고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.createChatRoom에CreateChatRoomRequest(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:19221를 기준으로 우측 하단에 표시한다. - 기본 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:19352처럼 화면 전체에 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을 사용한다.닫기버튼은 Figma665:19352기준 흰색 배경을 사용하고, 터치 시 dim과 펼쳐진 액션 버튼을 닫아 기본 Floating Button 상태로 복귀한다.- Floating Button 펼침/닫힘 Interaction Animation은 Spring easing을 사용한다.
- Spring animation parameter는 Mass
1, Stiffness256, Damping24를 따른다. - 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가 빈 배열인 경우에는 Figma290: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_*.xml12개가 동일한 섹션 컨테이너만 갖는 구조는 유지하지 않는다. - 기존
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이면 표시하지 않는다. - 최신 오디오 섹션의
latestAudioContentrow/card 터치 시latestAudioContent.audioContentId를 사용해 기존AudioContentDetailActivity로 이동한다. - 후원 섹션은 후원자 프로필, 닉네임, 후원 메시지, 후원 수량을 Figma list/comment 계열 스타일에 맞춰 표시한다.
channelDonations가 비어 있으면 후원 섹션을 숨기지 않고 Figma290:8820기준 empty 안내 UI를 표시한다.- 후원 empty 안내 UI는
SectionTitle(후원)아래 widthmatch_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 중 Figma296:14895의 해당 섹션 구조를 따른다. - 오디오 아이템에서 이미지 위에 표시되는
tv_audio_content_free_tag는 텍스트 길이에 맞춰wrap_contentwidth로 표시한다. - 오디오 컨텐츠 섹션 높이는 표시되는
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로 적용하고, FigmaContents(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.xml의tv_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 확인하기이동은 메인 화면에서대화탭을 선택하고ChatMainFragment의ChatRoomFilter.DM이 선택되도록 기존 메인 탭 라우팅 구조를 확인해 연결한다.- 본인 페이지 Floating Button의
커뮤니티 글 올리기,오디오 콘텐츠 올리기,라이브 만들기는 기존 작성/업로드/라이브 생성 진입점이 있으면 재사용하고, 없으면 구현 계획에서 별도 Task로 확정한다. RecommendedActivityType을CreatorActivityType으로 변경하고 공용 패키지로 이동할 때, 홈 추천 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을 호출하고, 성공 응답의chatRoomId로ChatRoomActivity에 이동한다.DM 보내기버튼 터치 시DmChatRoomActivity로 이동한다.- 크리에이터 본인 페이지에서는
대화하기버튼이 표시되지 않고DM 확인하기버튼만 표시된다. DM 확인하기터치 시 메인 페이지대화탭으로 이동하며, 대화 화면의DM필터/탭이 선택된 상태로 표시된다.- 더보기 버튼 터치 시 기존
UserProfileActivity의 프로필 액션 메뉴와 동일한 차단/차단 해제, 사용자 신고, 프로필 신고 액션을 BottomSheet로 표시한다. - 팔로잉 상태에서
iv_bell터치 시follow=true,notify=falseAPI를 바로 호출하고 성공 후 알림 꺼짐 아이콘으로 변경된다. - 팔로잉 상태에서
layout_follow_capsule터치 시follow=false,notify=falseAPI를 바로 호출하고 완료/오류 토스트를 표시한다. - 크리에이터 본인 페이지의 홈 탭 우측 하단에는 Figma
665:19221기준 Floating Button이 표시된다. - Floating Button 터치 시 Figma
665:19352기준 전체 화면 dim과커뮤니티 글 올리기,오디오 콘텐츠 올리기,라이브 만들기,닫기버튼이 표시된다. - 펼침/닫힘 애니메이션은 Spring easing, Mass
1, Stiffness256, Damping24를 따른다. - 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가 비어 있으면 Figma290:8820기준 후원 empty 안내 UI와후원하기버튼이 표시된다.- 공지와 커뮤니티 게시글의 날짜는 API 원본
dateUtc문자열이 아니라 기존 앱의 상대 날짜 표시 방식으로 표시된다. - 오디오 아이템의
tv_audio_content_free_tagwidth는wrap_content로 적용된다. - 오디오 컨텐츠 섹션은 표시되는 콘텐츠 개수에 비례해 필요한 높이만 차지하며, 콘텐츠가 1개일 때 불필요한 빈 높이를 차지하지 않는다.
- 시리즈 아이템의
layout_series_original_tagwidth/height는wrap_content로 적용되고, Figma 기준 margin/padding을 따른다. - 시리즈 아이템 터치 시
series.seriesId를 사용해 기존 시리즈 상세 페이지로 이동한다. - 활동 섹션은 Figma
296:15001기준 폰트, 색상, 간격을 따른다. - 활동 섹션의 데뷔 값은
activity.debutDateUtc를yyyy.MM.dd로 변환하고activity.dDay를 붙여2026.06.11(D+1)형식으로 표시한다. activity.dDay값이 있으면 데뷔 날짜 파싱 여부와 무관하게 화면에서 누락되지 않는다.- 기존 활동 요약 단일 문자열은 현재 활동 섹션의 label/value row 구조에서 사용하지 않으므로
creator_channel_activity_summarystring resource를 제거한다. - 스크롤 시 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.xml의tv_title_bar_title과 동일한 텍스트 스타일을 사용하고, 우측 액션 영역과 겹치지 않는다. - title-bar가 이미지 overlay 상태로 복귀하면 title-bar 닉네임은 숨겨진다.
RecommendedActivityType은 공용CreatorActivityType으로 변경되고, 홈 추천 API와 크리에이터 채널 홈 API가 같은 타입을 참조한다.라이브,오디오,시리즈,커뮤니티,팬Talk,후원탭 상세 화면은 이번 구현 범위로 사용되지 않는다.- 탭 바 아래 홈 컨텐츠는 Figma
296:14895기준으로 기존 동적 조립 UI를 삭제하고 섹션별 Figma component 기반 UI로 재구성된다. - 홈 컨텐츠 재구성에서
화보섹션은 현재 API 응답에 데이터가 없으므로 구현 범위에서 제외한다.
Creator Channel Home Intro Typography Follow-up
Requirements
- 소개 섹션 본문은 Figma node
296:14998기준으로Pretendard Regular,16sp, white, line-height1.45를 사용한다. - Android XML에서는 raw
textSize만 지정하지 않고@style/Typography.Body3를 적용해@font/regular계약을 보장한다. - 소개 섹션의 title/body gap은 기존
@dimen/spacing_14, body horizontal padding은 기존@dimen/spacing_20, body width는match_parent를 유지한다. - 소개 섹션은 카드 배경이나 고정
362dpwidth를 사용하지 않는다.
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에서대화탭을 선택하고ChatMainFragment의DM필터를 선택하는 navigation extra/action 이름은 구현 계획에서 기존 메인 탭 라우팅을 확인해 확정한다.- Floating Button 확장 상태에서 dim 영역 터치도 닫기 동작으로 처리할지,
닫기버튼만 닫기 동작으로 처리할지는 구현 계획에서 확정한다. 커뮤니티 글 올리기,오디오 콘텐츠 올리기,라이브 만들기버튼이 연결할 기존 작성/업로드/라이브 생성 화면과 전달 파라미터는 구현 계획에서 확인한다.- 후속 탭 구현 시 공통 헤더가 모든 탭에서 동일하게 유지될지, 탭별 화면에서 헤더 노출/스크롤 정책이 달라질지 확인이 필요하다.
- 후속 탭 구현 시
ViewPager2스와이프 전환을 허용할지, 탭 클릭 전환만 허용할지 확인이 필요하다. - 후속 탭 API의 pagination, refresh, empty/error UI 정책은 탭별 API 계약이 확정된 뒤 계획/TASK 문서에 별도로 정의한다.
12. References
- 전체 페이지 Figma: https://www.figma.com/design/HmN1yNdJ3EIpqknFL0Hkab/-%EA%B3%B5%EC%9C%A0%EC%9A%A9-%EB%B3%B4%EC%9D%B4%EC%8A%A4%EC%98%A8-UI-UX-%EA%B8%B0%ED%9A%8D%EB%AC%B8%EC%84%9C?node-id=296-14890&m=dev
- 홈 탭 컨텐츠 Figma: https://www.figma.com/design/HmN1yNdJ3EIpqknFL0Hkab/-%EA%B3%B5%EC%9C%A0%EC%9A%A9-%EB%B3%B4%EC%9D%B4%EC%8A%A4%EC%98%A8-UI-UX-%EA%B8%B0%ED%9A%8D%EB%AC%B8%EC%84%9C?node-id=296-14895&m=dev
- 본인 페이지 홈 탭 Floating Button Figma: https://www.figma.com/design/HmN1yNdJ3EIpqknFL0Hkab/-%EA%B3%B5%EC%9C%A0%EC%9A%A9-%EB%B3%B4%EC%9D%B4%EC%8A%A4%EC%98%A8-UI-UX-%EA%B8%B0%ED%9A%8D%EB%AC%B8%EC%84%9C?node-id=665-19092&m=dev
- 본인 페이지 Floating Button 확장 상태 Figma: https://www.figma.com/design/HmN1yNdJ3EIpqknFL0Hkab/-%EA%B3%B5%EC%9C%A0%EC%9A%A9-%EB%B3%B4%EC%9D%B4%EC%8A%A4%EC%98%A8-UI-UX-%EA%B8%B0%ED%9A%8D%EB%AC%B8%EC%84%9C?node-id=665-19223&m=dev
- 활동 영역 Figma: https://www.figma.com/design/HmN1yNdJ3EIpqknFL0Hkab/-%EA%B3%B5%EC%9C%A0%EC%9A%A9-%EB%B3%B4%EC%9D%B4%EC%8A%A4%EC%98%A8-UI-UX-%EA%B8%B0%ED%9A%8D%EB%AC%B8%EC%84%9C?node-id=296-15001&m=dev
- 후원 empty 안내 UI Figma: https://www.figma.com/design/HmN1yNdJ3EIpqknFL0Hkab/-%EA%B3%B5%EC%9C%A0%EC%9A%A9-%EB%B3%B4%EC%9D%B4%EC%8A%A4%EC%98%A8-UI-UX-%EA%B8%B0%ED%9A%8D%EB%AC%B8%EC%84%9C?node-id=290-8820&m=dev
- 팔로우 상태가 아닐 때 Figma: https://www.figma.com/design/HmN1yNdJ3EIpqknFL0Hkab/-%EA%B3%B5%EC%9C%A0%EC%9A%A9-%EB%B3%B4%EC%9D%B4%EC%8A%A4%EC%98%A8-UI-UX-%EA%B8%B0%ED%9A%8D%EB%AC%B8%EC%84%9C?node-id=296-14287&m=dev
- 팔로우 중 + 알림 받기 중 Figma: https://www.figma.com/design/HmN1yNdJ3EIpqknFL0Hkab/-%EA%B3%B5%EC%9C%A0%EC%9A%A9-%EB%B3%B4%EC%9D%B4%EC%8A%A4%EC%98%A8-UI-UX-%EA%B8%B0%ED%9A%8D%EB%AC%B8%EC%84%9C?node-id=296-14288&m=dev
- 팔로우 중 + 알림 받기 중이 아닐 때 Figma: https://www.figma.com/design/HmN1yNdJ3EIpqknFL0Hkab/-%EA%B3%B5%EC%9C%A0%EC%9A%A9-%EB%B3%B4%EC%9D%B4%EC%8A%A4%EC%98%A8-UI-UX-%EA%B8%B0%ED%9A%8D%EB%AC%B8%EC%84%9C?node-id=296-14289&m=dev
- 크리에이터 이미지 영역 Figma: https://www.figma.com/design/HmN1yNdJ3EIpqknFL0Hkab/-%EA%B3%B5%EC%9C%A0%EC%9A%A9-%EB%B3%B4%EC%9D%B4%EC%8A%A4%EC%98%A8-UI-UX-%EA%B8%B0%ED%9A%8D%EB%AC%B8%EC%84%9C?node-id=296-14892&m=dev
- 사용자 제공 홈 API Endpoint:
GET /api/v2/creator-channels/{creatorId}/home - PRD 샘플:
docs/prd/sample-prd.md - 문서 작성 규칙:
docs/agent-guides/work-plan-docs.md
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:14890metadata와 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호출 후 반환된chatRoomId로ChatRoomActivity에 진입하는 흐름으로 변경했다. -
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:14895의SectionTitle,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_rulesdeprecation 경고와 Gradle deprecation warning은 기존 경고로 이번 변경과 무관하다. -
2026-06-15: Phase 8 수동 화면 검증 준비로 Figma
296:14890,296:14892,296:14287,296:14288,296:14289스크린샷을 확인하고 구현 소스와 source test를 대조했다../gradlew :app:assembleDebug는BUILD 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.xml의tv_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=falseAPI 호출 후 아이콘을 변경하고, 팔로우 취소는layout_follow_capsule터치 즉시follow=false,notify=falseAPI 호출 후 완료/오류 토스트를 표시하도록 요구사항을 추가했다. 이번 단계는 PRD 문서 보완만 수행했으며plan-task.md와 구현/빌드/테스트는 실행하지 않았다. -
2026-06-16: Figma
290:8820metadata와 screenshot을 확인해 후원 empty 안내 UI가SectionTitle(후원), 374dp x 196dpgray_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:15001metadata와 screenshot을 확인해 활동 영역이SectionTitle(활동), label/value row,Pretendard Variable Medium16px, 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:19221,665:19352metadata와 screenshot을 확인해 크리에이터 본인 페이지 홈 탭의 기본 Floating Button과 dim 확장 상태를 확인했다. 사용자 요청에 따라 본인 페이지에서 팔로우/팔로잉, 더보기,대화하기를 제거하고DM 확인하기를 통해 메인대화탭의DM필터 선택 상태로 이동하는 요구사항을 추가했다. 또한 본인 페이지 홈 탭 Floating Button, 전체 dim, 4개 버튼 순서와 아이콘, Spring animation parameter를 PRD에 추가했다. 이번 단계는 PRD 문서 보완만 수행했으며plan-task.md와 구현/빌드/테스트는 실행하지 않았다. -
2026-06-25: 사용자 후속 요구사항에 따라 소개 섹션 본문을 Figma
296:14998기준Typography.Body3/white/line-height 1.45로 보정하고,spacing_14gap과spacing_20horizontal padding 및match_parent폭 유지 요구를 문서화했다. -
2026-06-25: 후속 UI 보정 검증으로
./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.CreatorChannelActivitySourceTest" --tests "kr.co.vividnext.sodalive.v2.main.content.ContentMainFragmentSourceTest" --tests "kr.co.vividnext.sodalive.v2.widget.SeriesContentCardViewTest" --tests "kr.co.vividnext.sodalive.v2.widget.AudioContentCardViewTest",./gradlew :app:mergeDebugResources,./gradlew :app:compileDebugKotlin,./gradlew :app:ktlintCheck,git diff --check를 실행해 모두BUILD SUCCESSFUL또는 출력 없음으로 PASS했다.ktlintCheck의.editorconfig disabled_rulesdeprecation warning과 Gradle deprecation warning은 기존 경고로 이번 변경과 무관하다.