17 KiB
17 KiB
크리에이터 채널 본인 진입 플로팅 버튼 구현 계획
기준 문서
- PRD:
docs/20260703_크리에이터_채널_본인_진입_플로팅_버튼/prd.md - 기존 PRD:
docs/20260701_크리에이터_채널_홈/prd.md - 기존 구현 계획:
docs/20260701_크리에이터_채널_홈/plan-task.md - 코드 스타일:
docs/agent-guides/code-style.md - 빌드/검증:
docs/agent-guides/build-test-verification.md - Figma 닫힘 상태 floating button:
665:19092 - Figma 열림 상태 floating menu:
665:19223
구현 원칙
- 기존 크리에이터 채널 홈 구조를 유지하고, 본인 채널 전용 UI만 추가한다.
- 본인 채널 판별은
CreatorChannelHomeResponse.creator.creatorId와UserDefaults.int(forKey: .userId)비교로 처리한다. - 기존 팔로우/알림 mutation, 홈 섹션, sticky tab-bar 동작은 본인 채널 조건 외에는 수정하지 않는다.
- Floating menu는 크리에이터 채널 전용 컴포넌트로 만들고
CreatorChannelView의 최상위ZStackoverlay에서 표시한다. - 신규 라우팅 case는 만들지 않고 기존
AppStep.creatorCommunityWrite,AppStep.createContent,AppStep.createLive를 우선 재사용한다. - 지정 asset
ic_new_upload_community_post,ic_new_upload_audio,ic_new_create_live,ic_new_x_black을 사용한다. - Figma localhost asset URL은 앱 코드에 사용하지 않는다.
주요 대상 파일
생성
SodaLive/Sources/V2/CreatorChannel/Components/CreatorChannelFloatingActionMenu.swift
수정
SodaLive/Sources/V2/CreatorChannel/CreatorChannelView.swiftSodaLive/Sources/V2/CreatorChannel/Components/CreatorChannelTitleBar.swiftSodaLive/Sources/App/AppStep.swiftSodaLive/Sources/ContentView.swiftSodaLive/Sources/Content/Create/ContentCreateView.swiftSodaLive/Sources/I18n/I18n.swift
확인
SodaLive/Sources/Live/LiveView.swiftSodaLive/Sources/Content/Create/ContentCreateViewModel.swiftSodaLive/Resources/Assets.xcassets/v2/ic_new_upload_community_post.imagesetSodaLive/Resources/Assets.xcassets/v2/ic_new_upload_audio.imagesetSodaLive/Resources/Assets.xcassets/v2/ic_new_create_live.imagesetSodaLive/Resources/Assets.xcassets/v2/ic_new_x_black.imageset
TASK 체크리스트
Phase 1: 본인 채널 판별과 title bar 조건
-
Task 1.1: 본인 채널 판별값 추가
- 대상 파일:
- 수정:
SodaLive/Sources/V2/CreatorChannel/CreatorChannelView.swift
- 수정:
- 작업 내용:
CreatorChannelView에private var isOwnCreatorChannel: Bool계산 프로퍼티를 추가한다.viewModel.response?.creator.creatorId가 없으면false를 반환한다.UserDefaults.int(forKey: .userId)가0이하이면false를 반환한다.- 두 값이 같을 때만
true를 반환한다.
- 검증 기준:
- 실행 명령:
rg "isOwnCreatorChannel|UserDefaults\\.int\\(forKey: \\.userId\\)|creator\\.creatorId" SodaLive/Sources/V2/CreatorChannel/CreatorChannelView.swift - 기대 결과: 본인 채널 판별 계산 프로퍼티가 확인된다.
- 실행 명령:
- 대상 파일:
-
Task 1.2: title bar 우측 액션 숨김 옵션 추가
- 대상 파일:
- 수정:
SodaLive/Sources/V2/CreatorChannel/Components/CreatorChannelTitleBar.swift
- 수정:
- 작업 내용:
CreatorChannelTitleBar에showsCreatorActions: Bool = true성격의 프로퍼티를 추가한다.showsCreatorActions == false이면 팔로우 버튼, 알림 버튼, 더보기 버튼을 포함한 우측HStack을 표시하지 않는다.- back 버튼, nickname, background progress 동작은 유지한다.
- Preview에
showsCreatorActions: false케이스를 추가한다.
- 검증 기준:
- 실행 명령:
rg "showsCreatorActions|if showsCreatorActions|CreatorChannelTitleBar\\(" SodaLive/Sources/V2/CreatorChannel/Components/CreatorChannelTitleBar.swift - 기대 결과: title bar 우측 액션 표시 여부를 제어하는 조건이 확인된다.
- 실행 명령:
- 대상 파일:
-
Task 1.3: 본인 채널이면 title bar 우측 액션 숨김 연결
- 대상 파일:
- 수정:
SodaLive/Sources/V2/CreatorChannel/CreatorChannelView.swift
- 수정:
- 작업 내용:
titleBar(backgroundProgress:)에서CreatorChannelTitleBar에showsCreatorActions: !isOwnCreatorChannel을 전달한다.- 본인 채널에서 follow/notify/more closure가 UI로 호출되지 않는지 확인한다.
- 검증 기준:
- 실행 명령:
rg "showsCreatorActions: !isOwnCreatorChannel|CreatorChannelTitleBar" SodaLive/Sources/V2/CreatorChannel/CreatorChannelView.swift - 기대 결과: 본인 채널 조건이 title bar에 전달된다.
- 실행 명령:
- 대상 파일:
Phase 2: Floating action menu 컴포넌트
-
Task 2.1: floating menu 문구 추가
- 대상 파일:
- 수정:
SodaLive/Sources/I18n/I18n.swift
- 수정:
- 작업 내용:
I18n.CreatorChannelHome에 접근성 label용 문구를 추가한다.- 추가 문구:
uploadCommunityPost: ko커뮤니티 글 올리기, enUpload community post, jaコミュニティ投稿を作成uploadAudioContent: ko오디오 콘텐츠 올리기, enUpload audio content, jaオーディオコンテンツを投稿createLive: ko라이브 만들기, enCreate live, jaライブを作成closeFloatingMenu: ko닫기, enClose, ja閉じる
- 검증 기준:
- 실행 명령:
rg "uploadCommunityPost|uploadAudioContent|closeFloatingMenu" SodaLive/Sources/I18n/I18n.swift - 기대 결과: 접근성 label용 다국어 문구가 존재한다.
- 실행 명령:
- 대상 파일:
-
Task 2.2: floating menu 컴포넌트 생성
- 대상 파일:
- 생성:
SodaLive/Sources/V2/CreatorChannel/Components/CreatorChannelFloatingActionMenu.swift - 확인:
SodaLive/Resources/Assets.xcassets/v2/ic_new_upload_community_post.imageset - 확인:
SodaLive/Resources/Assets.xcassets/v2/ic_new_upload_audio.imageset - 확인:
SodaLive/Resources/Assets.xcassets/v2/ic_new_create_live.imageset - 확인:
SodaLive/Resources/Assets.xcassets/v2/ic_new_x_black.imageset
- 생성:
- 작업 내용:
CreatorChannelFloatingActionMenu를View로 생성한다.- 입력값은
isPresented: Binding<Bool>,onTapCommunityPost,onTapAudioContent,onTapCreateLiveclosure로 둔다. - 닫힘 상태에서는
ic_plus_no_bg를 사용하는 plus 버튼 하나만 표시한다. - 열림 상태에서는
Color.black.opacity(0.4).ignoresSafeArea()dim과 4개 floating button을 표시한다. - 버튼 순서는 화면 위에서 아래로 커뮤니티 글 올리기, 오디오 콘텐츠 올리기, 라이브 만들기, 닫기 순서로 구성한다.
- 지정 asset을
Image(...)로 사용한다. - 닫기 버튼은 white background, 나머지는 Figma 기준 soda blue 계열 background를 사용한다.
- spring animation은
.interpolatingSpring(mass: 1, stiffness: 256, damping: 24, initialVelocity: 0)를 사용한다.
- 검증 기준:
- 실행 명령:
rg "struct CreatorChannelFloatingActionMenu|isPresented|interpolatingSpring\\(mass: 1, stiffness: 256, damping: 24|ic_plus_no_bg|ic_new_upload_community_post|ic_new_upload_audio|ic_new_create_live|ic_new_x_black|opacity\\(0.4\\)" SodaLive/Sources/V2/CreatorChannel/Components/CreatorChannelFloatingActionMenu.swift - 기대 결과: dim, spring animation, plus icon, 지정 asset, 4개 버튼이 확인된다.
- 실행 명령:
- 대상 파일:
-
Task 2.3: 닫힘 상태 plus icon 적용 확인
- 대상 파일:
- 수정:
SodaLive/Sources/V2/CreatorChannel/Components/CreatorChannelFloatingActionMenu.swift - 확인:
SodaLive/Resources/Assets.xcassets/ic_plus_no_bg.imageset
- 수정:
- 작업 내용:
- 닫힘 상태 plus icon으로
ic_plus_no_bg를 사용한다. - 버튼 배경, 크기, padding은 Task 2.2의 Figma 기준을 따른다.
- 닫힘 상태 plus icon으로
- 검증 기준:
- 실행 명령:
rg "ic_plus_no_bg" SodaLive/Sources/V2/CreatorChannel/Components/CreatorChannelFloatingActionMenu.swift SodaLive/Resources/Assets.xcassets - 기대 결과: 닫힘 상태 plus icon이
ic_plus_no_bg로 고정되어 있다.
- 실행 명령:
- 대상 파일:
Phase 3: CreatorChannelView overlay 연결과 액션 라우팅
-
Task 3.1: floating menu 표시 상태 연결
- 대상 파일:
- 수정:
SodaLive/Sources/V2/CreatorChannel/CreatorChannelView.swift
- 수정:
- 작업 내용:
@State private var isCreatorActionMenuPresented = false를 추가한다.- 최상위
ZStack에CreatorChannelFloatingActionMenuoverlay를 추가한다. - 표시 조건은
isOwnCreatorChannel && viewModel.selectedTab == .home && !viewModel.isLoading으로 한다. - 홈 외 탭으로 변경되면
isCreatorActionMenuPresented = false가 되도록 처리한다.
- 검증 기준:
- 실행 명령:
rg "isCreatorActionMenuPresented|CreatorChannelFloatingActionMenu|isOwnCreatorChannel && viewModel\\.selectedTab == \\.home" SodaLive/Sources/V2/CreatorChannel/CreatorChannelView.swift - 기대 결과: 본인 채널 홈 탭에서만 floating menu가 연결된다.
- 실행 명령:
- 대상 파일:
-
Task 3.2: 오디오 콘텐츠 업로드 성공 callback 확장
- 대상 파일:
- 수정:
SodaLive/Sources/App/AppStep.swift - 수정:
SodaLive/Sources/ContentView.swift - 수정:
SodaLive/Sources/Content/Create/ContentCreateView.swift - 확인:
SodaLive/Sources/Content/Create/ContentCreateViewModel.swift
- 수정:
- 작업 내용:
AppStep.createContent를case createContent(onSuccess: (() -> Void)? = nil)형태로 변경한다.- 기존
.createContent호출부가 컴파일되지 않으면.createContent()로만 바꾸고, 동작은 그대로 유지한다. ContentView의.createContent(let onSuccess)destination에서ContentCreateView(onSuccess: onSuccess)로 전달한다.ContentCreateView에onSuccess: (() -> Void)?를 추가한다.- 기존 업로드 화면의 입력 항목, 검증, 업로드 API, 완료 팝업 문구는 변경하지 않는다.
viewModel.isShowCompletePopup의 확인 액션에서 기존AppState.shared.back()을 유지하고, back 직전 또는 직후에onSuccess?()를 호출한다.
- 검증 기준:
- 실행 명령:
rg "createContent|ContentCreateView\\(|onSuccess|isShowCompletePopup|AppState\\.shared\\.back\\(\\)" SodaLive/Sources/App/AppStep.swift SodaLive/Sources/ContentView.swift SodaLive/Sources/Content/Create/ContentCreateView.swift - 기대 결과: 기존 create content 진입은 유지되고, 업로드 성공 callback 전달과 호출 지점이 확인된다.
- 실행 명령:
- 대상 파일:
-
Task 3.3: 커뮤니티 글 올리기 액션 연결
- 대상 파일:
- 수정:
SodaLive/Sources/V2/CreatorChannel/CreatorChannelView.swift - 확인:
SodaLive/Sources/App/AppStep.swift - 확인:
SodaLive/Sources/ContentView.swift
- 수정:
- 작업 내용:
showCommunityWrite()helper를 추가한다.- helper에서 menu를 닫고
AppState.shared.setAppStep(step: .creatorCommunityWrite(onSuccess: { viewModel.fetchHome(creatorId: creatorId) }))를 호출한다.
- 검증 기준:
- 실행 명령:
rg "showCommunityWrite|creatorCommunityWrite\\(onSuccess:|fetchHome\\(creatorId: creatorId\\)" SodaLive/Sources/V2/CreatorChannel/CreatorChannelView.swift - 기대 결과: 커뮤니티 글 작성 진입과 작성 성공 후 홈 갱신이 확인된다.
- 실행 명령:
- 대상 파일:
-
Task 3.4: 오디오 콘텐츠 올리기 액션 연결
- 대상 파일:
- 수정:
SodaLive/Sources/V2/CreatorChannel/CreatorChannelView.swift - 확인:
SodaLive/Sources/App/AppStep.swift - 확인:
SodaLive/Sources/Content/Create/ContentCreateView.swift
- 수정:
- 작업 내용:
showAudioContentUpload()helper를 추가한다.- helper에서 menu를 닫고 기존 진입을 유지한
AppState.shared.setAppStep(step: .createContent(onSuccess: { viewModel.fetchHome(creatorId: creatorId) }))형태로 호출한다. - 기존
createContent진입과 업로드 화면 자체의 UX/검증 로직은 변경하지 않는다.
- 검증 기준:
- 실행 명령:
rg "showAudioContentUpload|createContent\\(onSuccess:|fetchHome\\(creatorId: creatorId\\)" SodaLive/Sources/V2/CreatorChannel/CreatorChannelView.swift - 기대 결과: 오디오 콘텐츠 업로드 진입과 업로드 성공 후 홈 갱신 연결이 확인된다.
- 실행 명령:
- 대상 파일:
-
Task 3.5: 라이브 만들기 액션 연결
- 대상 파일:
- 수정:
SodaLive/Sources/V2/CreatorChannel/CreatorChannelView.swift - 확인:
SodaLive/Sources/Live/LiveView.swift - 확인:
SodaLive/Sources/App/AppStep.swift
- 수정:
- 작업 내용:
CreatorChannelView에 기존LiveView.onCreateSuccess와 동일한 처리를 위한@StateObject private var liveViewModel = LiveViewModel()을 추가한다.showCreateLive()helper를 추가한다.- helper에서 menu를 닫고
AppState.shared.setAppStep(step: .createLive(timeSettingMode: .NOW, onSuccess: handleCreateLiveSuccess))를 호출한다. handleCreateLiveSuccess(response:)는 기존LiveView.onCreateSuccess(response:)와 동일하게 처리한다.- 기존 처리 기준으로
liveViewModel.getLiveMain()을 호출하고,response.channelName이 있으면liveViewModel.enterRoom(roomId: response.id!)를 호출한다. - 크리에이터 채널로 돌아왔을 때 최신 상태가 보이도록
viewModel.fetchHome(creatorId: creatorId)도 호출한다.
- 검증 기준:
- 실행 명령:
rg "LiveViewModel|showCreateLive|handleCreateLiveSuccess|createLive\\(timeSettingMode: \\.NOW|channelName|getLiveMain\\(\\)|enterRoom\\(roomId:|fetchHome\\(creatorId: creatorId\\)" SodaLive/Sources/V2/CreatorChannel/CreatorChannelView.swift - 기대 결과: 라이브 만들기 진입, 기존
LiveView.onCreateSuccess와 동일한 생성 성공 처리, 크리에이터 채널 홈 갱신이 확인된다.
- 실행 명령:
- 대상 파일:
Phase 4: 검증
-
Task 4.1: 정적 검색 검증
- 대상 파일:
- 확인:
SodaLive/Sources/V2/CreatorChannel/CreatorChannelView.swift - 확인:
SodaLive/Sources/V2/CreatorChannel/Components/CreatorChannelTitleBar.swift - 확인:
SodaLive/Sources/V2/CreatorChannel/Components/CreatorChannelFloatingActionMenu.swift
- 확인:
- 작업 내용:
- 본인 채널 조건, title bar 숨김, floating menu 표시 조건, 지정 asset, spring animation을 검색한다.
- 검증 기준:
- 실행 명령:
rg "isOwnCreatorChannel|showsCreatorActions|CreatorChannelFloatingActionMenu|ic_plus_no_bg|ic_new_upload_community_post|ic_new_upload_audio|ic_new_create_live|ic_new_x_black|interpolatingSpring\\(mass: 1, stiffness: 256, damping: 24" SodaLive/Sources/V2/CreatorChannel - 기대 결과: 모든 핵심 변경 지점이 검색된다.
- 실행 명령:
- 대상 파일:
-
Task 4.2: 빌드 검증
- 대상 파일:
- 확인:
SodaLive.xcworkspace
- 확인:
- 작업 내용:
- Debug 빌드를 실행한다.
- 검증 기준:
- 실행 명령:
xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive-dev" -configuration Debug build - 기대 결과: build succeeded.
- 실행 명령:
- 대상 파일:
-
Task 4.3: 수동 동작 검증
- 대상 화면:
- 본인 크리에이터 채널 홈
- 타인 크리에이터 채널 홈
- 작업 내용:
- 본인 채널 title bar 우측 액션이 숨겨지는지 확인한다.
- 타인 채널 title bar 팔로우/알림/더보기 액션이 기존처럼 보이는지 확인한다.
- 본인 채널 홈 탭에서 floating button이 보이고 홈 외 탭에서는 숨겨지는지 확인한다.
- Floating button 터치 시 dim과 4개 버튼이 표시되는지 확인한다.
- dim 탭/닫기 버튼으로 menu가 닫히는지 확인한다.
- 커뮤니티 글 올리기, 오디오 콘텐츠 올리기, 라이브 만들기 버튼이 각각 기존 화면으로 이동하는지 확인한다.
- 커뮤니티 글 작성 성공 후 크리에이터 채널 홈이 갱신되는지 확인한다.
- 오디오 콘텐츠 업로드 성공 후 크리에이터 채널 홈이 갱신되는지 확인한다.
- 라이브 만들기 성공 후 기존
LiveView.onCreateSuccess와 동일한 이동/갱신 흐름이 동작하는지 확인한다.
- 검증 기준:
- 기대 결과: PRD Success Criteria를 모두 만족한다.
- 대상 화면:
검증 기록
- 2026-07-03: 문서 작성 단계. 구현/빌드 검증은 아직 수행하지 않음.
- 2026-07-03: Open Questions 결정 사항을 반영함.
ic_plus_no_bg, 기존AppStep.createContent, 기존LiveView.onCreateSuccess동일 처리, 커뮤니티/오디오 성공 후 홈 갱신 기준을 문서화함. - 2026-07-03: Phase 1, 2 구현 완료. 계획서의 Task 1.1~2.3
rg검증을 수행했고,xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive-dev" -configuration Debug build성공을 확인함. 자동화 테스트 타깃은rg "Tests|XCTest|testTarget|PBXNativeTarget.*Tests|\.xctest|unit test|swift test" "SodaLive.xcodeproj" "SodaLive"검색 결과 확인되지 않아 별도 RED/GREEN 테스트는 추가하지 않음. - 2026-07-03: Phase 3 구현 완료. Task 3.1~3.5
rg검증을 수행했고,xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive-dev" -configuration Debug build성공을 확인함. 자동화 테스트 타깃 부재로 별도 RED/GREEN 테스트는 추가하지 않았으며, 실제 화면 수동 검증은 Phase 4.3에 남김.