From 458cdc3280e477633987d0449a2e8ce200379da4 Mon Sep 17 00:00:00 2001 From: klaus Date: Tue, 16 Jun 2026 12:13:10 +0900 Subject: [PATCH] =?UTF-8?q?docs(creator):=20=EC=B1=84=EB=84=90=20=ED=99=88?= =?UTF-8?q?=20=ED=9B=84=EC=86=8D=20=EC=9A=94=EA=B5=AC=EC=82=AC=ED=95=AD?= =?UTF-8?q?=EC=9D=84=20=EC=A0=95=EB=A6=AC=ED=95=9C=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../plan-task.md | 288 ++++++++++++++++++ docs/20260611_크리에이터_채널_홈_탭/prd.md | 152 ++++++++- 2 files changed, 432 insertions(+), 8 deletions(-) diff --git a/docs/20260611_크리에이터_채널_홈_탭/plan-task.md b/docs/20260611_크리에이터_채널_홈_탭/plan-task.md index bdac79f5..c92692c2 100644 --- a/docs/20260611_크리에이터_채널_홈_탭/plan-task.md +++ b/docs/20260611_크리에이터_채널_홈_탭/plan-task.md @@ -54,6 +54,15 @@ - 팔로우/알림 API 연결은 Figma가 필요 없지만, tab-bar 7개 항목의 시각 표시와 title-bar 아이콘 click target 배치는 Figma 기준을 확인한다. - Phase 8: 필수 참조 - 수동 화면 검증은 Figma와 실제 구현 화면을 비교해 PRD Metrics를 확인한다. +- Phase 10: 부분 참조 + - title-bar 닉네임, tab-bar typography, 더보기 BottomSheet, 팔로우/알림 직접 액션은 PRD와 기존 구현 패턴을 기준으로 한다. + - tab-bar item font/size는 Figma `296:14894`를 확인한다. +- Phase 11: 필수 참조 + - 후원 empty UI는 Figma `290:8820`, 활동 영역은 Figma `296:15001`, 홈 컨텐츠 보정은 Figma `296:14895`를 기준으로 한다. +- Phase 12: 필수 참조 + - 크리에이터 본인 페이지 Floating Button 기본 상태는 Figma `665:19092`, 확장/dim 상태는 Figma `665:19223`을 기준으로 한다. +- Phase 13: 필수 참조 + - 최종 수동 검증은 Figma `296:14890`, `296:14894`, `296:14895`, `290:8820`, `296:15001`, `665:19092`, `665:19223`을 함께 대조한다. --- @@ -986,6 +995,284 @@ --- +### Phase 10: 상단 상태/탭/액션 후속 보강 + +> 2026-06-16 PRD 보강분을 반영하는 Phase다. title-bar sticky 닉네임, tab-bar typography, 더보기 BottomSheet, 팔로우/알림 직접 액션, 본인 페이지 상단 액션 정책을 한 묶음으로 처리한다. + +- [ ] **Task 10.1: title-bar sticky 닉네임과 tab-bar typography 보정** + - 수정: + - `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelActivity.kt` + - `app/src/main/res/layout/activity_creator_channel.xml` + - `app/src/test/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelActivitySourceTest.kt` + - Figma 기준: + - tab-bar item text: Figma `296:14894` + - 작업: + - title-bar가 black 배경으로 전환된 상태에서 뒤로가기 버튼 우측에 `creator.nickname`을 표시한다. + - title-bar가 이미지 overlay 상태로 복귀하면 닉네임을 숨긴다. + - 닉네임 TextView의 font/textSize/color/ellipsize/maxLines는 `app/src/main/res/layout/view_title_bar_default.xml`의 `tv_title_bar_title`와 동일하게 맞춘다. + - 긴 닉네임은 우측 액션 영역과 겹치지 않도록 1줄 말줄임 처리한다. + - tab-bar item 텍스트는 선택/비선택 상태 모두 Figma `296:14894` 기준 `Pretendard Variable Medium`, 16sp 상당 크기, line-height 1.45, letterSpacing 0을 유지한다. + - 선택 상태에서만 font/size가 달라지는 구현이 있으면 제거하고 색상/indicator로만 선택 상태를 구분한다. + - 검증 명령: + - `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.CreatorChannelActivitySourceTest"` + - `./gradlew :app:mergeDebugResources` + - `./gradlew :app:compileDebugKotlin` + +- [ ] **Task 10.2: 더보기 BottomSheet와 팔로우/알림 직접 액션 보정** + - 수정: + - `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelActivity.kt` + - `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelHomeViewModel.kt` + - `app/src/test/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelActivitySourceTest.kt` + - `app/src/test/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelHomeViewModelTest.kt` + - 확인: + - `app/src/main/java/kr/co/vividnext/sodalive/explorer/profile/UserProfileActivity.kt` + - 기존 `UserProfileActivity.showOptionMenu()`의 `user_profile_option_menu`, `user_profile_option_menu_2` 분기 + - 기존 `BottomSheetDialog` 또는 프로젝트 내 유사 BottomSheet 메뉴 구현 + - 작업: + - 더보기 버튼 터치 시 기존 `UserProfileActivity.showOptionMenu()`와 동일한 의미의 차단/차단 해제, 사용자 신고, 프로필 신고 액션을 BottomSheet로 표시한다. + - 팔로우하지 않은 상태의 `layout_follow_capsule` 터치 시 기존 크리에이터 팔로우 API를 `follow=true`, `notify=true`로 바로 호출한다. + - 팔로잉 상태에서 `iv_bell` 터치 시 BottomSheet 없이 `follow=true`, `notify=false` API를 바로 호출하고 성공 후 알림 꺼짐 아이콘으로 변경한다. + - 팔로잉 상태에서 `layout_follow_capsule` 터치 시 BottomSheet 없이 `follow=false`, `notify=false` API를 바로 호출하고 완료/오류 토스트를 표시한다. + - 팔로우/알림 요청 중에는 중복 터치로 같은 API가 중복 호출되지 않게 한다. + - 기존 `CreatorFollowNotifyFragment`를 띄우는 흐름이 남아 있으면 이번 요구에 맞게 제거한다. + - 검증 명령: + - `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.CreatorChannelHomeViewModelTest"` + - `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.CreatorChannelActivitySourceTest"` + - `./gradlew :app:compileDebugKotlin` + +- [ ] **Task 10.3: 크리에이터 본인 페이지 상단 액션 정책 추가** + - 수정: + - `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/data/CreatorChannelHomeModels.kt` + - `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/model/CreatorChannelHomeUiModels.kt` + - `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/model/CreatorChannelHomeMappers.kt` + - `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/model/CreatorChannelTitleBarState.kt` + - `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelActivity.kt` + - `app/src/test/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelHomeMapperTest.kt` + - `app/src/test/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelTitleBarStateTest.kt` + - `app/src/test/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelActivitySourceTest.kt` + - 확인: + - 홈 API에 `isOwner` 또는 동등한 필드가 제공되는지 확인한다. + - API 필드가 없으면 로그인 사용자 정보와 `creator.creatorId`/연결 식별자를 대조할 수 있는 기존 저장소/세션 정보를 확인한다. + - 작업: + - 크리에이터 본인 여부를 UI model에 포함한다. + - 본인 페이지에서는 title-bar의 팔로우/팔로잉 capsule, 알림 아이콘, 더보기 아이콘을 표시하지 않는다. + - 본인 페이지에서는 더보기 BottomSheet 또는 차단/신고 액션에 진입할 수 없게 한다. + - 본인 페이지가 아닌 경우 기존 팔로우/더보기 동작은 유지한다. + - 본인 여부 판정에 API 필드가 필요하지만 제공되지 않는 경우, 구현을 막지 말고 해당 필드 추가 필요성을 Task 검증 기록에 남긴다. + - 검증 명령: + - `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.CreatorChannelHomeMapperTest"` + - `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.CreatorChannelTitleBarStateTest"` + - `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.CreatorChannelActivitySourceTest"` + - `./gradlew :app:compileDebugKotlin` + +- [ ] **Task 10.4: 본인 페이지 `DM 확인하기` 진입 추가** + - 수정: + - `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelActivity.kt` + - `app/src/main/java/kr/co/vividnext/sodalive/main/MainActivity.kt` + - `app/src/main/java/kr/co/vividnext/sodalive/v2/main/chat/ChatMainFragment.kt` + - `app/src/main/java/kr/co/vividnext/sodalive/v2/main/chat/model/ChatRoomFilter.kt` + - `app/src/test/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelActivitySourceTest.kt` + - 필요 시 메인/채팅 탭 source test + - 확인: + - `MainActivity`의 bottom tab 선택 구조 + - `ChatMainFragment`의 필터 선택 구조 + - `ChatRoomFilter.DM` + - 작업: + - 본인 페이지에서는 `대화하기` 버튼을 표시하지 않는다. + - 본인 페이지에서는 `DM 보내기` 대신 `DM 확인하기` 버튼을 표시한다. + - `DM 확인하기` 터치 시 `MainActivity`로 이동하거나 기존 MainActivity instance를 재사용해 메인 `대화` 탭을 선택한다. + - `ChatMainFragment`는 진입 파라미터를 받아 `ChatRoomFilter.DM`이 선택된 상태로 표시한다. + - 기존 타인 페이지의 `DM 보내기`는 `DmChatRoomActivity.newIntentByCreatorId(context, creatorId)` 이동을 유지한다. + - 검증 명령: + - `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.CreatorChannelActivitySourceTest"` + - `./gradlew :app:compileDebugKotlin` + +--- + +### Phase 11: 홈 탭 섹션 후속 UI/액션 보강 + +> 후원 empty, 최신 콘텐츠 터치, 날짜 표시, 오디오/시리즈/활동 영역의 세부 Figma 정합성을 묶어서 처리한다. 섹션 하나당 Phase를 나누지 않고 관련 홈 컨텐츠 보정 Task로 묶는다. + +- [ ] **Task 11.1: 후원 empty UI와 최신 콘텐츠/날짜 표시 보강** + - 수정: + - `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/model/CreatorChannelHomeMappers.kt` + - `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/ui/CreatorChannelHomeSectionAdapter.kt` + - `app/src/main/res/layout/item_creator_channel_home_donation.xml` + - `app/src/main/res/layout/item_creator_channel_home_latest_audio.xml` + - `app/src/main/res/layout/item_creator_channel_home_notice.xml` + - `app/src/main/res/layout/item_creator_channel_home_community.xml` + - `app/src/test/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelHomeMapperTest.kt` + - `app/src/test/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelActivitySourceTest.kt` + - Figma 기준: + - 후원 empty UI: `290:8820` + - 작업: + - `channelDonations`가 비어 있으면 후원 섹션을 숨기지 않고 empty 안내 UI를 표시한다. + - empty card width는 374dp 고정이 아니라 부모 섹션 좌우 여백 안에서 `match_parent`로 처리한다. + - empty card는 height 196dp, `gray_900` 배경, 14dp radius, `처음으로 크리에이터를` / `후원해 보세요!`, 흰색 `후원하기` capsule을 표시한다. + - 최신 오디오 row/card 터치 시 `latestAudioContent.audioContentId`로 기존 `AudioContentDetailActivity`에 이동한다. + - 공지/커뮤니티 게시글 날짜는 API `dateUtc` 원문 대신 기존 앱의 상대 날짜 표시 방식으로 변환한다. + - 검증 명령: + - `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.CreatorChannelHomeMapperTest"` + - `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.CreatorChannelActivitySourceTest"` + - `./gradlew :app:mergeDebugResources` + - `./gradlew :app:compileDebugKotlin` + +- [ ] **Task 11.2: 오디오/시리즈 아이템 세부 UI와 터치 액션 보강** + - 수정: + - `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/ui/CreatorChannelHomeSectionAdapter.kt` + - `app/src/main/res/layout/item_creator_channel_home_audio.xml` + - `app/src/main/res/layout/item_creator_channel_home_audio_content.xml` + - `app/src/main/res/layout/item_creator_channel_home_series.xml` + - 시리즈 card custom view 파일 + - `app/src/test/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelActivitySourceTest.kt` + - Figma 기준: + - 홈 컨텐츠: `296:14895` + - 시리즈 `Contents(type=series, size=m)` + - 작업: + - 오디오 이미지 위 `tv_audio_content_free_tag` width를 `wrap_content`로 수정한다. + - 오디오 영역은 표시되는 `audioContents` 개수만큼만 높이를 차지한다. + - 오디오 콘텐츠가 1개일 때 3개 이상 있을 때와 같은 고정 높이, 빈 슬롯, placeholder 영역을 만들지 않는다. + - 시리즈 이미지 위 `layout_series_original_tag` width/height를 `wrap_content`로 수정한다. + - 시리즈 original tag margin/padding은 Figma `Contents(type=series, size=m)` 기준으로 맞춘다. + - 시리즈 아이템 터치 시 `series.seriesId`를 사용해 기존 `SeriesDetailActivity`로 이동한다. + - 검증 명령: + - `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.CreatorChannelActivitySourceTest"` + - `./gradlew :app:mergeDebugResources` + - `./gradlew :app:compileDebugKotlin` + +- [ ] **Task 11.3: 활동 영역 Figma 정합성과 데뷔 날짜/D+n 버그 수정** + - 수정: + - `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/ui/CreatorChannelHomeSectionAdapter.kt` + - `app/src/main/res/layout/item_creator_channel_home_activity.xml` + - `app/src/main/res/values/strings.xml` + - `app/src/main/res/values-en/strings.xml` + - `app/src/main/res/values-ja/strings.xml` + - `app/src/test/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelActivitySourceTest.kt` + - Figma 기준: + - 활동 영역: `296:15001` + - 작업: + - 활동 섹션 제목은 `SectionTitle(활동)` 기준 `Pretendard Variable Bold`, 20sp 상당 크기를 따른다. + - 활동 label/value row는 `Pretendard Variable Medium`, 16sp 상당 크기, line-height 1.45, letterSpacing 0을 따른다. + - label 색상은 `#939393`, value 색상은 white로 맞춘다. + - label/value 사이 8dp gap, row 간 8dp 간격을 유지한다. + - `activity.debutDateUtc`는 원문 ISO 문자열을 그대로 표시하지 않고 `yyyy.MM.dd`로 변환한다. + - 데뷔 값은 `yyyy.MM.dd(D+n)` 형식으로 표시한다. 예: `2026.06.11(D+1)`. + - `activity.dDay` 값이 있으면 날짜 파싱 실패 또는 `debutDateUtc` 누락 상황에서도 D+n이 누락되지 않게 한다. + - 검증 명령: + - `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.CreatorChannelActivitySourceTest"` + - `./gradlew :app:mergeDebugResources` + - `./gradlew :app:compileDebugKotlin` + +--- + +### Phase 12: 크리에이터 본인 페이지 Floating Button + +> 본인 페이지 전용 홈 탭 FAB와 확장 액션을 추가한다. 상단 액션 정책은 Phase 10에서 처리하고, FAB overlay/animation/버튼 액션은 이 Phase에서 처리한다. + +- [ ] **Task 12.1: Floating Button 기본/확장 layout 추가** + - 수정: + - `app/src/main/res/layout/activity_creator_channel.xml` + - `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelActivity.kt` + - `app/src/test/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelActivitySourceTest.kt` + - 생성 후보: + - `app/src/main/res/drawable/bg_creator_channel_owner_fab.xml` + - `app/src/main/res/drawable/bg_creator_channel_owner_fab_close.xml` + - Figma 기준: + - 기본 상태: `665:19092` + - 확장/dim 상태: `665:19223` + - 작업: + - Floating Button은 크리에이터 본인 페이지의 `홈` 탭에서만 표시한다. + - 기본 FAB는 우측/하단 safe area를 고려해 14dp inset으로 배치한다. + - 기본 FAB는 `soda/400` 배경, 100dp radius, 14dp padding, 38dp icon 영역, shadow를 따른다. + - FAB 터치 시 전체 화면 dim overlay를 표시한다. + - dim 색상은 Figma 기준 `rgba(0,0,0,0.4)`로 적용한다. + - 확장 상태에서 버튼은 우측 하단 정렬을 유지하고 세로 간격 14dp로 배치한다. + - 확장 버튼 순서는 위에서부터 `커뮤니티 글 올리기`, `오디오 콘텐츠 올리기`, `라이브 만들기`, `닫기`다. + - 아이콘은 순서대로 `ic_new_upload_community_post`, `ic_new_upload_audio`, `ic_new_create_live`, `ic_new_x_black`을 사용한다. + - 닫기 버튼은 흰색 배경을 사용하고 터치 시 dim과 확장 버튼을 닫는다. + - dim 뒤 홈 컨텐츠, tab-bar, title-bar 액션이 잘못 터치되지 않게 한다. + - 검증 명령: + - `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.CreatorChannelActivitySourceTest"` + - `./gradlew :app:mergeDebugResources` + - `./gradlew :app:compileDebugKotlin` + +- [ ] **Task 12.2: Floating Button Spring animation과 하단 inset 보정** + - 수정: + - `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelActivity.kt` + - `app/src/test/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelActivitySourceTest.kt` + - 작업: + - FAB 펼침/닫힘 animation은 Spring easing을 사용한다. + - Spring parameter는 Mass `1`, Stiffness `256`, Damping `24`를 따른다. + - 확장/닫힘 중 중복 터치로 상태가 꼬이지 않게 한다. + - navigation bar/gesture inset을 반영해 FAB touch area가 화면 밖으로 밀리지 않도록 한다. + - 홈 컨텐츠 마지막 영역이 FAB에 가려져 읽기 어려우면 RecyclerView/NestedScroll 하단 padding을 보정한다. + - 검증 명령: + - `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.CreatorChannelActivitySourceTest"` + - `./gradlew :app:compileDebugKotlin` + +- [ ] **Task 12.3: Floating Button 3개 액션 진입점 연결** + - 수정: + - `app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelActivity.kt` + - `app/src/test/java/kr/co/vividnext/sodalive/v2/creator/channel/CreatorChannelActivitySourceTest.kt` + - 필요 시 기존 커뮤니티 작성/오디오 업로드/라이브 생성 화면 route 파일 + - 확인: + - 커뮤니티 글 작성 기존 Activity/Fragment/route + - 오디오 콘텐츠 업로드 기존 Activity/Fragment/route + - 라이브 만들기 기존 Activity/Fragment/route + - 작업: + - `커뮤니티 글 올리기`는 기존 커뮤니티 작성 화면으로 이동한다. + - `오디오 콘텐츠 올리기`는 기존 오디오 콘텐츠 업로드 화면으로 이동한다. + - `라이브 만들기`는 기존 라이브 생성 화면으로 이동한다. + - 기존 진입점이 없거나 필요한 파라미터가 불명확하면 임의 구현하지 않고 해당 액션은 검증 기록에 “진입점 미확정”으로 남긴다. + - 각 액션 터치 후에는 FAB 확장 상태를 닫는다. + - 검증 명령: + - `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.CreatorChannelActivitySourceTest"` + - `./gradlew :app:compileDebugKotlin` + +--- + +### Phase 13: 후속 보강 최종 검증과 문서 기록 + +- [ ] **Task 13.1: 후속 보강 단위/source 테스트 실행** + - 실행: + - `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.creator.channel.*"` + - `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.main.home.*"` + - 기대 결과: + - 크리에이터 채널 후속 보강 테스트와 기존 홈 진입점 테스트가 `BUILD SUCCESSFUL`로 통과한다. + +- [ ] **Task 13.2: 리소스/컴파일/린트 검증** + - 실행: + - `./gradlew :app:mergeDebugResources` + - `./gradlew :app:compileDebugKotlin` + - `./gradlew :app:ktlintCheck` + - `git diff --check` + - 기대 결과: + - `mergeDebugResources`, `compileDebugKotlin`, `git diff --check`는 통과한다. + - `ktlintCheck`가 기존 `audio_content` 패키지명 underscore 문제로 실패하면, 이번 변경 파일에서 발생한 실패인지 구분해 검증 기록에 남긴다. + +- [ ] **Task 13.3: 수동 화면 검증** + - 확인: + - 타인 페이지에서 팔로우/알림/더보기/대화/DM 동작이 PRD와 일치한다. + - 본인 페이지에서 팔로우/알림/더보기/대화가 제거되고 `DM 확인하기`와 FAB가 표시된다. + - `DM 확인하기` 터치 시 메인 `대화` 탭과 `DM` 필터가 선택된다. + - FAB 기본/확장/dim/닫기/3개 액션이 Figma `665:19092`, `665:19223`과 일치한다. + - 후원 empty, 최신 콘텐츠 터치, 상대 날짜, 오디오 높이, 시리즈 original tag, 활동 날짜/D+n이 PRD와 일치한다. + - sticky title-bar nickname과 tab typography가 Figma/PRD와 일치한다. + - 기대 결과: + - 2026-06-16 이후 추가 PRD Metrics를 모두 만족한다. + +- [ ] **Task 13.4: 검증 기록 누적** + - 수정: + - `docs/20260611_크리에이터_채널_홈_탭/plan-task.md` + - `docs/20260611_크리에이터_채널_홈_탭/prd.md` + - 작업: + - 실행한 테스트/빌드/린트/수동 검증 결과를 문서 하단에 누적한다. + - 실패 기록은 삭제하지 않고 후속 성공/차단 기록을 추가한다. + - 기대 결과: + - 후속 보강 구현과 검증 이력이 문서에 남는다. + +--- + ## Verification Log - 2026-06-12: `docs/20260611_크리에이터_채널_홈_탭/prd.md`, `docs/agent-guides/work-plan-docs.md`, `docs/agent-guides/build-test-style.md`, `docs/agent-guides/code-style.md`를 확인해 계획 문서 작성 규칙과 검증 명령 규칙을 확인했다. - 2026-06-12: 기존 `HomeRecommendationApi`, `HomeRecommendationModels`, `HomeRecommendationRepository`, `HomeRecommendationViewModel`, `RecommendedActivityType`, `HomeRecommendationMappers`, `HomeRecommendationUiModels`, `AppDI`, `ChatRoomActivity`, `DmChatRoomActivity`를 확인해 신규 크리에이터 채널 홈 구현 계획의 파일 경계와 재사용 지점을 정리했다. @@ -1066,3 +1353,4 @@ - 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` 스크린샷을 확인하고, `CreatorChannelHomeActivity.kt`, `activity_creator_channel_home.xml`, `CreatorChannelTitleBarState.kt`, `CreatorChannelScrollState.kt`, `CreatorChannelHomeSectionAdapter.kt`, `CreatorChannelHomeActivitySourceTest.kt`를 대조했다. `./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: Phase 9 이름 변경으로 `CreatorChannelHomeActivity`/`activity_creator_channel_home.xml`/`ActivityCreatorChannelHomeBinding`을 `CreatorChannelActivity`/`activity_creator_channel.xml`/`ActivityCreatorChannelBinding`으로 정리하고, Manifest와 모든 진입점 및 source test를 새 이름으로 갱신했다. focused source test, 홈 진입점 테스트, 크리에이터 채널 전체 테스트, 리소스 merge, Kotlin compile, `git diff --check`는 통과했다. `ktlintCheck`는 기존 `audio_content` 패키지명 underscore 규칙 위반으로 실패했으며 이번 변경 범위 밖이라 수정하지 않았다. +- 2026-06-16: PRD에 신규 추가된 요구사항을 바탕으로 plan-task 문서를 보강했다. Phase는 섹션 단위로 과도하게 쪼개지 않고 `상단 상태/탭/액션`, `홈 탭 섹션 후속 UI/액션`, `크리에이터 본인 페이지 Floating Button`, `후속 보강 최종 검증`으로 묶었으며, 세부 변경은 Task 체크리스트에 배치했다. 이번 단계는 계획 문서 보강만 수행했으며 구현/빌드/테스트는 실행하지 않았다. diff --git a/docs/20260611_크리에이터_채널_홈_탭/prd.md b/docs/20260611_크리에이터_채널_홈_탭/prd.md index 83dd68a3..5b51023f 100644 --- a/docs/20260611_크리에이터_채널_홈_탭/prd.md +++ b/docs/20260611_크리에이터_채널_홈_탭/prd.md @@ -1,7 +1,7 @@ # PRD: 크리에이터 채널 신규 페이지 ## 1. Overview -크리에이터의 대표 이미지, 팔로우/알림 상태, 대화/DM 진입 버튼, 탭 바, 홈 탭 컨텐츠를 포함한 크리에이터 채널 신규 페이지의 1차 범위를 Figma `296:14890` 기준으로 구현한다. +크리에이터의 대표 이미지, 팔로우/알림 상태, 대화/DM 진입 버튼, 본인 페이지 전용 액션, 탭 바, 홈 탭 컨텐츠를 포함한 크리에이터 채널 신규 페이지의 1차 범위를 Figma `296:14890` 기준으로 구현한다. --- @@ -10,6 +10,7 @@ - 크리에이터 채널 상단은 OS status bar 영역까지 이미지가 확장되어야 하며, 기존 일반 화면의 title bar/inset 처리와 다를 수 있다. - 팔로우 상태와 알림 수신 상태에 따라 title bar 우측 액션 구성이 달라져야 한다. - `대화하기`, `DM 보내기` 버튼은 권한 또는 서버 상태에 따라 없을 수 있어, 버튼 노출 조합별 배치 규칙이 필요하다. +- 로그인 사용자가 크리에이터 본인 페이지에 진입한 경우에는 타인 페이지용 팔로우/더보기/대화 액션 대신 본인 전용 확인/업로드 액션을 제공해야 한다. - 스크롤 시 tab-bar가 title-bar 아래에 고정되고, title-bar 배경색이 black으로 전환되는 상단 collapsing 동작이 필요하다. - 이번 범위는 크리에이터 채널의 전체 상단 구성과 `홈` 탭에 해당하는 컨텐츠만 포함하며, 나머지 탭의 상세 화면은 후속 범위로 분리해야 한다. - 홈 탭 진입 즉시 사용할 API와 서버 DTO가 확정되어 Android 구현 요구사항에 반영해야 한다. @@ -22,6 +23,7 @@ - title bar에는 좌측 뒤로가기와 우측 더보기/팔로우/알림 상태 액션을 표시한다. - 팔로우하지 않은 상태, 팔로우 중이면서 알림 받기 중인 상태, 팔로우 중이지만 알림 받기 중이 아닌 상태를 구분해 아이콘을 표시한다. - 크리에이터 이미지 영역 내 `대화하기`, `DM 보내기` 버튼 노출 조합과 정렬 규칙을 정의한다. +- 크리에이터 본인 페이지에서는 팔로우/팔로잉, 더보기, `대화하기` 액션을 제거하고 `DM 확인하기` 및 홈 탭 Floating Button 액션을 제공한다. - tab-bar는 스크롤 중 title-bar 영역까지만 이동한 뒤 고정되며, 이후 아래 컨텐츠만 스크롤되도록 한다. - tab-bar와 title-bar가 가까워지는 스크롤 구간에서 title-bar 배경색을 black으로 변경한다. - tab-bar에는 `홈`, `라이브`, `오디오`, `시리즈`, `커뮤니티`, `팬Talk`, `후원`을 표시한다. @@ -35,7 +37,7 @@ - `Frame 1707482896`과 그 하위 레이어 중 `홈` 탭 첫 화면 구성에 필요한 데이터 표시 외 세부 상호작용은 이번 범위에서 제외한다. - 팔로우/언팔로우, 알림 켜기/끄기 API는 신규 API를 만들지 않고 기존 크리에이터 팔로우 API를 사용한다. - `대화하기`는 기존 `TalkApi.createChatRoom`으로 채팅방을 생성/조회한 뒤 반환된 `chatRoomId`로 `ChatRoomActivity`에 진입하고, `DM 보내기`는 신규 `DmChatRoomActivity`로 이동한다. 각 화면 내부 동작 변경은 이번 범위에서 제외한다. -- 기존 크리에이터 랭킹 페이지, 채팅 탭, DM 채팅방 상세 화면의 동작을 변경하지 않는다. +- 기존 크리에이터 랭킹 페이지, 채팅 탭, DM 채팅방 상세 화면의 동작을 변경하지 않는다. 단, 본인 페이지의 `DM 확인하기` 진입 시 메인 `대화` 탭과 내부 `DM` 필터/탭이 선택된 상태로 열리는 진입 파라미터 처리는 이번 요구에 포함한다. - Figma에 표시된 iOS status bar 컴포넌트 자체를 Android에 그대로 구현하지 않는다. Android system bar/inset 정책에 맞춰 이미지 확장 요구만 반영한다. --- @@ -45,12 +47,22 @@ - 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 개발자. --- @@ -61,6 +73,7 @@ - 사용자는 팔로우하지 않은 크리에이터를 바로 팔로우할 수 있어야 한다. - 사용자는 팔로우 중인 크리에이터의 알림 수신 상태를 상단에서 확인하고 변경할 수 있어야 한다. - 사용자는 가능한 경우 크리에이터와 대화하거나 DM을 보낼 수 있어야 한다. +- 크리에이터 본인은 본인 채널에서 팔로우/신고/대화 시작 액션을 보지 않고, DM 목록 확인과 업로드/라이브 생성 액션에 접근할 수 있어야 한다. - 사용자는 페이지를 스크롤해도 현재 선택 가능한 tab-bar가 상단에 고정되어 계속 접근 가능하길 기대한다. --- @@ -81,6 +94,7 @@ - tab-bar 하단 컨텐츠 영역 중 이번 구현 범위는 `홈` 탭 컨텐츠로 한정한다. - 크리에이터 채널 신규 페이지 진입 시 `creatorId`를 기준으로 홈 API를 즉시 호출한다. - 홈 API 응답의 `creator` 정보로 상단 이미지 영역, 팔로우/알림 상태, 대화/DM 버튼 노출 여부를 표시한다. +- 로그인 사용자가 해당 크리에이터 본인인지 판정한 뒤, 본인 페이지 전용 title bar/action button/Floating Button 노출 정책을 적용한다. - 홈 API 응답의 홈 탭 데이터로 현재 라이브, 최신 오디오, 후원, 공지, 일정, 오디오 컨텐츠, 시리즈, 커뮤니티, 팬Talk 요약, 소개, 활동, SNS 영역을 표시한다. #### Edge Cases @@ -242,6 +256,7 @@ enum class CreatorActivityType(val code: String) { - `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 표시 여부를 결정한다. @@ -259,11 +274,24 @@ enum class CreatorActivityType(val code: String) { - 팔로우 상태가 아닐 때는 `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 | @@ -276,6 +304,9 @@ enum class CreatorActivityType(val code: String) { - 팔로우 상태 데이터가 아직 로딩 중이면 잘못된 상태 전환이 보이지 않도록 기존 로딩 정책에 맞춰 처리한다. - 팔로우/알림 상태 변경 요청 중 중복 탭으로 동일 요청이 여러 번 전송되지 않도록 한다. - title bar 배경이 투명한 상태에서도 아이콘이 이미지 위에서 식별 가능해야 한다. +- title bar 배경이 투명한 초기 overlay 상태에서는 크리에이터 닉네임이 대표 이미지 영역의 닉네임과 중복 노출되지 않아야 한다. +- 알림 끄기 API 실패 시 기존 `isNotify` 상태와 아이콘이 잘못 변경된 상태로 남으면 안 된다. +- 팔로우 취소 API 실패 시 기존 `isFollow`, `isNotify` 상태와 아이콘이 잘못 변경된 상태로 남으면 안 된다. ### Creator Image Area Actions 크리에이터 이미지 영역에는 `대화하기`, `DM 보내기` 액션 버튼을 표시할 수 있다. @@ -291,11 +322,41 @@ enum class CreatorActivityType(val code: String) { - `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: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 영역으로 동작한다. @@ -306,10 +367,14 @@ tab-bar는 스크롤 중 title-bar 하단에 고정되는 sticky 영역으로 - 이번 범위에서는 `홈` 탭 컨텐츠만 구현한다. - `라이브`, `오디오`, `시리즈`, `커뮤니티`, `팬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 @@ -324,6 +389,7 @@ tab-bar는 스크롤 중 title-bar 하단에 고정되는 sticky 영역으로 #### Requirements - `currentLive`가 있으면 현재 라이브 영역에 표시한다. - `latestAudioContent`가 있으면 최신 오디오 컨텐츠 영역에 표시한다. +- `latestAudioContent` 영역 터치 시 기존 오디오 콘텐츠 상세 페이지로 이동한다. - `channelDonations`는 후원 요약/목록 영역에 표시한다. - `notices`는 공지 영역에 표시한다. - `schedules`는 크리에이터 일정 영역에 표시한다. @@ -338,7 +404,7 @@ tab-bar는 스크롤 중 title-bar 하단에 고정되는 sticky 영역으로 #### Edge Cases - `currentLive` 또는 `latestAudioContent`가 null이면 해당 단일 컨텐츠 영역은 표시하지 않거나 기존 empty 정책을 따른다. -- list 필드가 빈 배열이면 섹션 자체를 숨길지 빈 상태를 표시할지는 기존 홈/크리에이터 화면 정책을 우선 따른다. +- list 필드가 빈 배열이면 섹션 자체를 숨길지 빈 상태를 표시할지는 기존 홈/크리에이터 화면 정책을 우선 따르되, `channelDonations`가 빈 배열인 경우에는 Figma `290:8820`의 후원 empty 안내 UI를 표시한다. - SNS URL 문자열이 빈 값이면 해당 SNS 진입 아이콘 또는 버튼은 비활성/숨김 처리한다. ### Home Tab Content Rebuild @@ -361,21 +427,40 @@ tab-bar는 스크롤 중 title-bar 하단에 고정되는 sticky 영역으로 #### Section Requirements - 현재 라이브 섹션은 `SectionTitle`과 Figma의 라이브 카드 구조를 기준으로 하며, `currentLive`가 null이면 표시하지 않는다. - 최신 오디오 섹션은 Figma의 88dp 이미지 list row 구조를 기준으로 하며, `latestAudioContent`가 null이면 표시하지 않는다. +- 최신 오디오 섹션의 `latestAudioContent` row/card 터치 시 `latestAudioContent.audioContentId`를 사용해 기존 `AudioContentDetailActivity`로 이동한다. - 후원 섹션은 후원자 프로필, 닉네임, 후원 메시지, 후원 수량을 Figma list/comment 계열 스타일에 맞춰 표시한다. -- 공지 섹션은 공지 본문, 날짜, 이미지/잠금 상태가 있는 경우의 표시 정책을 Figma list/feed 계열 구조에 맞춰 정의한다. +- `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 표시 정책에 연결한다. -- 커뮤니티 섹션은 Figma `Feed` 구조를 사용하고, 프로필, 작성자, 작성 시간, 본문, 이미지, 유료 잠금, 좋아요/댓글 reaction을 표시한다. +- 시리즈 아이템 이미지 위에 표시되는 `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의 배경 없는 label/value row 목록을 기준으로 표시한다. +- 활동 섹션은 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`과 동일한 의미를 가지므로 공용 타입으로 정리한다. @@ -393,6 +478,7 @@ tab-bar는 스크롤 중 title-bar 하단에 고정되는 sticky 영역으로 - 전체 배경은 Figma `296:14890`과 동일한 black 계열을 유지한다. - 크리에이터 대표 이미지는 첫 화면에서 가장 큰 시각 요소로 노출한다. - title bar 초기 상태는 이미지 위 overlay로 보이며, 스크롤 임계점 이후 black 배경으로 전환된다. +- title bar가 black 배경으로 전환된 상태에서는 뒤로가기 버튼 우측에 크리에이터 닉네임이 표시된다. - title bar 아이콘은 Figma에 지정된 신규 아이콘 리소스를 사용한다. - 팔로우/알림 상태별 아이콘 조합은 사용자가 현재 상태를 즉시 구분할 수 있어야 한다. - `대화하기`, `DM 보내기` 버튼은 노출 여부와 무관하게 이미지 영역 내 레이아웃 안정성을 유지한다. @@ -410,11 +496,16 @@ tab-bar는 스크롤 중 title-bar 하단에 고정되는 sticky 영역으로 - 기존에 존재하는 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은 근거 파일이나 별도 요구가 확인되기 전까지 임의로 추가하지 않는다. @@ -426,6 +517,7 @@ tab-bar는 스크롤 중 title-bar 하단에 고정되는 sticky 영역으로 - 팔로우하지 않은 상태에서 `ic_new_follow`가 표시된다. - 팔로우 중 + 알림 받기 중 상태에서 `ic_new_following`, `ic_bar_bell_colored`가 표시된다. - 팔로우 중 + 알림 받기 중이 아닌 상태에서 `ic_new_following`, `ic_bar_bell`이 표시된다. +- 크리에이터 본인 페이지에서는 팔로우/팔로잉, 알림, 더보기 액션이 표시되지 않는다. - `대화하기`, `DM 보내기` 버튼이 모두 보일 때 Figma 기준 배치를 따른다. - `대화하기`, `DM 보내기` 버튼 중 하나만 보일 때 해당 버튼이 가운데 표시된다. - `대화하기`, `DM 보내기` 버튼이 모두 보이지 않아도 버튼 영역 높이와 여백이 보존된다. @@ -433,13 +525,36 @@ tab-bar는 스크롤 중 title-bar 하단에 고정되는 sticky 영역으로 - `creator.isDmAvailable=true`일 때만 `DM 보내기` 버튼이 표시된다. - `대화하기` 버튼 터치 시 `TalkApi.createChatRoom`을 호출하고, 성공 응답의 `chatRoomId`로 `ChatRoomActivity`에 이동한다. - `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.debutDateUtc`를 `yyyy.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.xml`의 `tv_title_bar_title`과 동일한 텍스트 스타일을 사용하고, 우측 액션 영역과 겹치지 않는다. +- title-bar가 이미지 overlay 상태로 복귀하면 title-bar 닉네임은 숨겨진다. - `RecommendedActivityType`은 공용 `CreatorActivityType`으로 변경되고, 홈 추천 API와 크리에이터 채널 홈 API가 같은 타입을 참조한다. - `라이브`, `오디오`, `시리즈`, `커뮤니티`, `팬Talk`, `후원` 탭 상세 화면은 이번 구현 범위로 사용되지 않는다. - 탭 바 아래 홈 컨텐츠는 Figma `296:14895` 기준으로 기존 동적 조립 UI를 삭제하고 섹션별 Figma component 기반 UI로 재구성된다. @@ -450,13 +565,25 @@ tab-bar는 스크롤 중 title-bar 하단에 고정되는 sticky 영역으로 ## 11. Open Questions - 크리에이터 채널 신규 페이지의 진입점과 전달받을 Android extra 또는 navigation argument 이름은 구현 계획에서 기존 이동 패턴을 확인해 확정한다. - 홈 탭 각 섹션의 empty 상태를 섹션 숨김으로 처리할지, 빈 상태 UI로 처리할지는 기존 크리에이터/홈 화면 패턴 확인이 필요하다. -- 팔로우/알림 변경 성공 후 홈 API를 재조회할지, 로컬 상태만 갱신할지는 기존 크리에이터 팔로우 API 사용 패턴 확인이 필요하다. +- 팔로우/알림 변경 성공 후 홈 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 @@ -489,3 +616,12 @@ tab-bar는 스크롤 중 title-bar 하단에 고정되는 sticky 영역으로 - 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=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`와 구현/빌드/테스트는 실행하지 않았다.