From c2f358ee507320f96828619268a5eb6a96cd7cc4 Mon Sep 17 00:00:00 2001 From: Yu Sung Date: Mon, 29 Jun 2026 17:22:52 +0900 Subject: [PATCH] =?UTF-8?q?feat(home):=20=EC=B5=9C=EA=B7=BC=20=EB=8D=B0?= =?UTF-8?q?=EB=B7=94=20=ED=81=AC=EB=A6=AC=EC=97=90=EC=9D=B4=ED=84=B0=20?= =?UTF-8?q?=EC=84=B9=EC=85=98=EC=9D=84=20=EC=97=B0=EA=B2=B0=ED=95=9C?= =?UTF-8?q?=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SodaLive.xcodeproj/project.pbxproj | 54 ++++++----- .../MainHomeRecentDebutCreatorSection.swift | 97 +++++++++++++++++++ .../MainHomeRecommendationView.swift | 5 + .../plan-task.md | 19 +++- 4 files changed, 151 insertions(+), 24 deletions(-) create mode 100644 SodaLive/Sources/V2/Main/Home/Recommendation/Components/MainHomeRecentDebutCreatorSection.swift diff --git a/SodaLive.xcodeproj/project.pbxproj b/SodaLive.xcodeproj/project.pbxproj index b0e2e55f..c7e92a85 100644 --- a/SodaLive.xcodeproj/project.pbxproj +++ b/SodaLive.xcodeproj/project.pbxproj @@ -195,16 +195,15 @@ 401A3FA02FEEAFA000A5BBA3 /* FollowRecommendedCreatorsRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 401A3F962FEEAFA000A5BBA3 /* FollowRecommendedCreatorsRequest.swift */; }; 401A3FA12FEEAFA000A5BBA3 /* MainHomeRecommendationRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 401A3F9B2FEEAFA000A5BBA3 /* MainHomeRecommendationRepository.swift */; }; 401A3FA22FEEAFA000A5BBA3 /* RecommendedActivityType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 401A3F982FEEAFA000A5BBA3 /* RecommendedActivityType.swift */; }; - 401A3FBA2FEEAFA000A5BBA3 /* MainHomeRecommendationViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 76506E56D017236824FE9B8F /* MainHomeRecommendationViewModel.swift */; }; - 401A3FA82FEEAFA000A5BBA3 /* MainHomeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 401A3FB42FEEAFA000A5BBA3 /* MainHomeView.swift */; }; - 401A3FA92FEEAFA000A5BBA3 /* MainHomeRecommendationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 401A3FB52FEEAFA000A5BBA3 /* MainHomeRecommendationView.swift */; }; - 401A3FAA2FEEAFA000A5BBA3 /* MainHomeRankingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 401A3FB62FEEAFA000A5BBA3 /* MainHomeRankingView.swift */; }; - 401A3FAB2FEEAFA000A5BBA3 /* MainHomeFollowingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 401A3FB72FEEAFA000A5BBA3 /* MainHomeFollowingView.swift */; }; 401A3FA32FEEAFA000A5BBA3 /* MainHomeRecommendationApi.swift in Sources */ = {isa = PBXBuildFile; fileRef = 401A3F9A2FEEAFA000A5BBA3 /* MainHomeRecommendationApi.swift */; }; 401A3FA42FEEAFA000A5BBA3 /* MainHomeRecommendationResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 401A3F972FEEAFA000A5BBA3 /* MainHomeRecommendationResponse.swift */; }; 401A3FA52FEEAFA000A5BBA3 /* FollowRecommendedCreatorsRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 401A3F962FEEAFA000A5BBA3 /* FollowRecommendedCreatorsRequest.swift */; }; 401A3FA62FEEAFA000A5BBA3 /* MainHomeRecommendationRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 401A3F9B2FEEAFA000A5BBA3 /* MainHomeRecommendationRepository.swift */; }; 401A3FA72FEEAFA000A5BBA3 /* RecommendedActivityType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 401A3F982FEEAFA000A5BBA3 /* RecommendedActivityType.swift */; }; + 401A3FA82FEEAFA000A5BBA3 /* MainHomeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 401A3FB42FEEAFA000A5BBA3 /* MainHomeView.swift */; }; + 401A3FA92FEEAFA000A5BBA3 /* MainHomeRecommendationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 401A3FB52FEEAFA000A5BBA3 /* MainHomeRecommendationView.swift */; }; + 401A3FAA2FEEAFA000A5BBA3 /* MainHomeRankingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 401A3FB62FEEAFA000A5BBA3 /* MainHomeRankingView.swift */; }; + 401A3FAB2FEEAFA000A5BBA3 /* MainHomeFollowingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 401A3FB72FEEAFA000A5BBA3 /* MainHomeFollowingView.swift */; }; 401A3FAC2FEEAFA000A5BBA3 /* MainHomeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 401A3FB42FEEAFA000A5BBA3 /* MainHomeView.swift */; }; 401A3FAD2FEEAFA000A5BBA3 /* MainHomeRecommendationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 401A3FB52FEEAFA000A5BBA3 /* MainHomeRecommendationView.swift */; }; 401A3FAE2FEEAFA000A5BBA3 /* MainHomeRankingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 401A3FB62FEEAFA000A5BBA3 /* MainHomeRankingView.swift */; }; @@ -213,15 +212,19 @@ 401A3FB12FEEAFA000A5BBA3 /* MainHomeRecommendationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 401A3FB52FEEAFA000A5BBA3 /* MainHomeRecommendationView.swift */; }; 401A3FB22FEEAFA000A5BBA3 /* MainHomeRankingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 401A3FB62FEEAFA000A5BBA3 /* MainHomeRankingView.swift */; }; 401A3FB32FEEAFA000A5BBA3 /* MainHomeFollowingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 401A3FB72FEEAFA000A5BBA3 /* MainHomeFollowingView.swift */; }; + 401A3FBA2FEEAFA000A5BBA3 /* MainHomeRecommendationViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 76506E56D017236824FE9B8F /* MainHomeRecommendationViewModel.swift */; }; 401A3FC22FEEB00100A5BBA3 /* MainHomeLiveSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 401A3FC12FEEB00100A5BBA3 /* MainHomeLiveSection.swift */; }; - 401A3FC62FEEB00200A5BBA3 /* MainHomeBannerSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 401A3FC52FEEB00200A5BBA3 /* MainHomeBannerSection.swift */; }; - 401A3FC92FEEB00300A5BBA3 /* MainHomeActiveCreatorSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 401A3FCC2FEEB00300A5BBA3 /* MainHomeActiveCreatorSection.swift */; }; 401A3FC32FEEB00100A5BBA3 /* MainHomeLiveSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 401A3FC12FEEB00100A5BBA3 /* MainHomeLiveSection.swift */; }; - 401A3FC72FEEB00200A5BBA3 /* MainHomeBannerSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 401A3FC52FEEB00200A5BBA3 /* MainHomeBannerSection.swift */; }; - 401A3FCA2FEEB00300A5BBA3 /* MainHomeActiveCreatorSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 401A3FCC2FEEB00300A5BBA3 /* MainHomeActiveCreatorSection.swift */; }; 401A3FC42FEEB00100A5BBA3 /* MainHomeLiveSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 401A3FC12FEEB00100A5BBA3 /* MainHomeLiveSection.swift */; }; + 401A3FC62FEEB00200A5BBA3 /* MainHomeBannerSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 401A3FC52FEEB00200A5BBA3 /* MainHomeBannerSection.swift */; }; + 401A3FC72FEEB00200A5BBA3 /* MainHomeBannerSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 401A3FC52FEEB00200A5BBA3 /* MainHomeBannerSection.swift */; }; 401A3FC82FEEB00200A5BBA3 /* MainHomeBannerSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 401A3FC52FEEB00200A5BBA3 /* MainHomeBannerSection.swift */; }; + 401A3FC92FEEB00300A5BBA3 /* MainHomeActiveCreatorSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 401A3FCC2FEEB00300A5BBA3 /* MainHomeActiveCreatorSection.swift */; }; + 401A3FCA2FEEB00300A5BBA3 /* MainHomeActiveCreatorSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 401A3FCC2FEEB00300A5BBA3 /* MainHomeActiveCreatorSection.swift */; }; 401A3FCB2FEEB00300A5BBA3 /* MainHomeActiveCreatorSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 401A3FCC2FEEB00300A5BBA3 /* MainHomeActiveCreatorSection.swift */; }; + 401A3FCE2FEEB00400A5BBA3 /* MainHomeRecentDebutCreatorSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 401A3FCD2FEEB00400A5BBA3 /* MainHomeRecentDebutCreatorSection.swift */; }; + 401A3FCF2FEEB00400A5BBA3 /* MainHomeRecentDebutCreatorSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 401A3FCD2FEEB00400A5BBA3 /* MainHomeRecentDebutCreatorSection.swift */; }; + 401A3FD02FEEB00400A5BBA3 /* MainHomeRecentDebutCreatorSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 401A3FCD2FEEB00400A5BBA3 /* MainHomeRecentDebutCreatorSection.swift */; }; 40235DED2E3797EB00B09A87 /* RecentContent+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40235DEC2E3797EB00B09A87 /* RecentContent+CoreDataClass.swift */; }; 40235DEE2E3797EB00B09A87 /* RecentContent+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40235DEC2E3797EB00B09A87 /* RecentContent+CoreDataClass.swift */; }; 40235DF02E37983D00B09A87 /* PersistenceController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40235DEF2E37983D00B09A87 /* PersistenceController.swift */; }; @@ -1738,6 +1741,7 @@ 401A3FC12FEEB00100A5BBA3 /* MainHomeLiveSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainHomeLiveSection.swift; sourceTree = ""; }; 401A3FC52FEEB00200A5BBA3 /* MainHomeBannerSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainHomeBannerSection.swift; sourceTree = ""; }; 401A3FCC2FEEB00300A5BBA3 /* MainHomeActiveCreatorSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainHomeActiveCreatorSection.swift; sourceTree = ""; }; + 401A3FCD2FEEB00400A5BBA3 /* MainHomeRecentDebutCreatorSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainHomeRecentDebutCreatorSection.swift; sourceTree = ""; }; 40235DEC2E3797EB00B09A87 /* RecentContent+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RecentContent+CoreDataClass.swift"; sourceTree = ""; }; 40235DEF2E37983D00B09A87 /* PersistenceController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PersistenceController.swift; sourceTree = ""; }; 40235DF22E37987300B09A87 /* RecentContentService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecentContentService.swift; sourceTree = ""; }; @@ -2706,16 +2710,6 @@ path = Repository; sourceTree = ""; }; - 401A3FC02FEEB00100A5BBA3 /* Components */ = { - isa = PBXGroup; - children = ( - 401A3FC12FEEB00100A5BBA3 /* MainHomeLiveSection.swift */, - 401A3FC52FEEB00200A5BBA3 /* MainHomeBannerSection.swift */, - 401A3FCC2FEEB00300A5BBA3 /* MainHomeActiveCreatorSection.swift */, - ); - path = Components; - sourceTree = ""; - }; 401A3F9D2FEEAFA000A5BBA3 /* Recommendation */ = { isa = PBXGroup; children = ( @@ -2744,6 +2738,17 @@ path = Following; sourceTree = ""; }; + 401A3FC02FEEB00100A5BBA3 /* Components */ = { + isa = PBXGroup; + children = ( + 401A3FC12FEEB00100A5BBA3 /* MainHomeLiveSection.swift */, + 401A3FC52FEEB00200A5BBA3 /* MainHomeBannerSection.swift */, + 401A3FCC2FEEB00300A5BBA3 /* MainHomeActiveCreatorSection.swift */, + 401A3FCD2FEEB00400A5BBA3 /* MainHomeRecentDebutCreatorSection.swift */, + ); + path = Components; + sourceTree = ""; + }; 40235DEA2E3797B000B09A87 /* Recent */ = { isa = PBXGroup; children = ( @@ -5340,6 +5345,7 @@ 401A3FC22FEEB00100A5BBA3 /* MainHomeLiveSection.swift in Sources */, 401A3FC62FEEB00200A5BBA3 /* MainHomeBannerSection.swift in Sources */, 401A3FC92FEEB00300A5BBA3 /* MainHomeActiveCreatorSection.swift in Sources */, + 401A3FCE2FEEB00400A5BBA3 /* MainHomeRecentDebutCreatorSection.swift in Sources */, 401A3FAA2FEEAFA000A5BBA3 /* MainHomeRankingView.swift in Sources */, 401A3FAB2FEEAFA000A5BBA3 /* MainHomeFollowingView.swift in Sources */, 409143302A85652F00EEBFB1 /* CanChargeView.swift in Sources */, @@ -6089,6 +6095,7 @@ 401A3FC32FEEB00100A5BBA3 /* MainHomeLiveSection.swift in Sources */, 401A3FC72FEEB00200A5BBA3 /* MainHomeBannerSection.swift in Sources */, 401A3FCA2FEEB00300A5BBA3 /* MainHomeActiveCreatorSection.swift in Sources */, + 401A3FCF2FEEB00400A5BBA3 /* MainHomeRecentDebutCreatorSection.swift in Sources */, 401A3FAE2FEEAFA000A5BBA3 /* MainHomeRankingView.swift in Sources */, 401A3FAF2FEEAFA000A5BBA3 /* MainHomeFollowingView.swift in Sources */, B3AF650899B8FC84E0C0CDA0 /* MainPlaceholderTabView.swift in Sources */, @@ -6865,6 +6872,7 @@ 401A3FC42FEEB00100A5BBA3 /* MainHomeLiveSection.swift in Sources */, 401A3FC82FEEB00200A5BBA3 /* MainHomeBannerSection.swift in Sources */, 401A3FCB2FEEB00300A5BBA3 /* MainHomeActiveCreatorSection.swift in Sources */, + 401A3FD02FEEB00400A5BBA3 /* MainHomeRecentDebutCreatorSection.swift in Sources */, 401A3FB22FEEAFA000A5BBA3 /* MainHomeRankingView.swift in Sources */, 401A3FB32FEEAFA000A5BBA3 /* MainHomeFollowingView.swift in Sources */, ACD71056E97E13E48941ABBB /* MainPlaceholderTabView.swift in Sources */, @@ -7016,7 +7024,7 @@ CODE_SIGN_ENTITLEMENTS = SodaLive/SodaLive.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 2; + CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_ASSET_PATHS = "\"SodaLive/Preview Content\""; DEVELOPMENT_TEAM = 3A8QGPMRXM; ENABLE_PREVIEWS = YES; @@ -7038,7 +7046,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.46.0; + MARKETING_VERSION = 1.55.0; PRODUCT_BUNDLE_IDENTIFIER = kr.co.vividnext.sodalive; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -7057,7 +7065,7 @@ CODE_SIGN_ENTITLEMENTS = SodaLive/SodaLive.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 2; + CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_ASSET_PATHS = "\"SodaLive/Preview Content\""; DEVELOPMENT_TEAM = 3A8QGPMRXM; ENABLE_PREVIEWS = YES; @@ -7079,7 +7087,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.46.0; + MARKETING_VERSION = 1.55.0; PRODUCT_BUNDLE_IDENTIFIER = kr.co.vividnext.sodalive; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; diff --git a/SodaLive/Sources/V2/Main/Home/Recommendation/Components/MainHomeRecentDebutCreatorSection.swift b/SodaLive/Sources/V2/Main/Home/Recommendation/Components/MainHomeRecentDebutCreatorSection.swift new file mode 100644 index 00000000..066a349e --- /dev/null +++ b/SodaLive/Sources/V2/Main/Home/Recommendation/Components/MainHomeRecentDebutCreatorSection.swift @@ -0,0 +1,97 @@ +import SwiftUI + +struct MainHomeRecentDebutCreatorSection: View { + let items: [HomeCreatorItem] + let onTapCreator: (Int) -> Void + + init( + items: [HomeCreatorItem], + onTapCreator: @escaping (Int) -> Void = { _ in } + ) { + self.items = items + self.onTapCreator = onTapCreator + } + + var body: some View { + if !items.isEmpty { + VStack(alignment: .leading, spacing: SodaSpacing.s14) { + SectionTitle(title: I18n.HomeRecommendation.recentDebutCreatorSectionTitle) + + ScrollView(.horizontal, showsIndicators: false) { + LazyHStack(alignment: .center, spacing: SodaSpacing.s4) { + ForEach(items, id: \.self) { item in + MainHomeRecentDebutCreatorItemView(item: item) { + onTapCreator(item.creatorId) + } + } + } + .padding(.horizontal, SodaSpacing.s14) + } + } + } + } +} + +private struct MainHomeRecentDebutCreatorItemView: View { + private static let itemWidth: CGFloat = 185 + private static let itemHeight: CGFloat = 234 + + let item: HomeCreatorItem + let action: () -> Void + + var body: some View { + Button(action: action) { + ZStack(alignment: .bottom) { + DownsampledKFImage( + url: URL(string: item.creatorProfileImage), + size: CGSize(width: Self.itemWidth, height: Self.itemHeight) + ) + .frame(width: Self.itemWidth, height: Self.itemHeight) + .background(Color.gray800) + .clipShape(RoundedRectangle(cornerRadius: SodaSpacing.s14, style: .continuous)) + + LinearGradient( + colors: [Color.black.opacity(0), Color.black.opacity(0.7)], + startPoint: .top, + endPoint: .bottom + ) + .frame(height: 80) + + Text(item.creatorNickname) + .appFont(.heading4) + .foregroundColor(.white) + .lineLimit(1) + .truncationMode(.tail) + .padding(.horizontal, SodaSpacing.s12) + .padding(.bottom, SodaSpacing.s20) + } + .frame(width: Self.itemWidth, height: Self.itemHeight) + .clipShape(RoundedRectangle(cornerRadius: SodaSpacing.s14, style: .continuous)) + } + .buttonStyle(.plain) + } +} + +struct MainHomeRecentDebutCreatorSection_Previews: PreviewProvider { + private static let previewImageUrl = "https://picsum.photos/500/700" + + static var previews: some View { + MainHomeRecentDebutCreatorSection( + items: [ + HomeCreatorItem( + creatorId: 1, + creatorNickname: "크리에이터 이름", + creatorProfileImage: previewImageUrl + ), + HomeCreatorItem( + creatorId: 2, + creatorNickname: "크리에이터 이름", + creatorProfileImage: previewImageUrl + ) + ] + ) + .padding(.vertical, SodaSpacing.s20) + .background(Color.black) + .previewLayout(.sizeThatFits) + } +} diff --git a/SodaLive/Sources/V2/Main/Home/Recommendation/MainHomeRecommendationView.swift b/SodaLive/Sources/V2/Main/Home/Recommendation/MainHomeRecommendationView.swift index cd7f67fa..f3694ea7 100644 --- a/SodaLive/Sources/V2/Main/Home/Recommendation/MainHomeRecommendationView.swift +++ b/SodaLive/Sources/V2/Main/Home/Recommendation/MainHomeRecommendationView.swift @@ -37,6 +37,11 @@ struct MainHomeRecommendationView: View { onTapContent: onTapContent, onTapCommunity: onTapCommunity ) + + MainHomeRecentDebutCreatorSection( + items: viewModel.recommendations?.recentDebutCreators ?? [], + onTapCreator: onTapCreator + ) } .padding(.vertical, SodaSpacing.s20) } diff --git a/docs/20260602_메인_홈_추천_UI_API_연동/plan-task.md b/docs/20260602_메인_홈_추천_UI_API_연동/plan-task.md index da58a1ad..0955cf22 100644 --- a/docs/20260602_메인_홈_추천_UI_API_연동/plan-task.md +++ b/docs/20260602_메인_홈_추천_UI_API_연동/plan-task.md @@ -322,7 +322,7 @@ ### Phase 11: 최근 데뷔한 크리에이터 섹션 UI -- [ ] **Task 11.1: 최근 데뷔 크리에이터 섹션 작성/보완** +- [x] **Task 11.1: 최근 데뷔 크리에이터 섹션 작성/보완** - 대상 파일: - 생성/보완: `SodaLive/Sources/V2/Main/Home/Recommendation/Components/MainHomeRecentDebutCreatorSection.swift` - 확인/보완: `SodaLive/Sources/V2/Component/Creator/CreatorProfileGrid.swift` @@ -496,6 +496,23 @@ ## 검증 기록 +### 2026-06-29 Phase 11 최근 데뷔 크리에이터 섹션 구현 완료 + +- 목적: V2 Main Home 추천 탭에 Figma `24:5534`, `24:5537` 기준 최근 데뷔한 크리에이터 섹션을 연결 +- 수행 내용: + - `MainHomeRecentDebutCreatorSection`을 추가해 `HomeCreatorItem.creatorId`, `creatorNickname`, `creatorProfileImage` 기반 가로 카드 목록을 표시 + - Figma 아이템 원본 `205x259`를 요청 기준에 맞춰 `185x234` 고정 크기로 표시하고, radius 14, 하단 dim gradient, 중앙 하단 크리에이터명을 적용 + - 데이터가 비어 있으면 섹션 제목과 목록을 렌더링하지 않도록 구성 + - `MainHomeRecommendationView`에서 현재 라이브, 배너, 최근 활동 다음 순서로 최근 데뷔 크리에이터 섹션을 배치 + - 신규 `MainHomeRecentDebutCreatorSection.swift`를 `SodaLive.xcodeproj/project.pbxproj` 빌드 대상에 포함 +- 검증: + - Figma `24:5534`, `24:5537` 디자인 컨텍스트와 스크린샷 확인, 섹션 제목/간격 14/리스트 좌측 inset 14/아이템 간격 4/아이템 `185x234` 구조 확인 + - `rg -n "itemWidth|itemHeight|frame\(width: Self\.itemWidth, height: Self\.itemHeight\)|MainHomeRecentDebutCreatorSection|recentDebutCreators|localhost:3845|figma.com" SodaLive/Sources/V2/Main/Home/Recommendation` 실행, `itemWidth 185`, `itemHeight 234`, 추천 응답 연결 확인 및 forbidden URL 미포함 확인 + - `plutil -lint SodaLive.xcodeproj/project.pbxproj` 실행, `OK` 확인 + - `git diff --check` 실행, 출력 없이 성공 확인 + - `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive-dev" -configuration Debug build` 실행, `BUILD SUCCEEDED` 확인 + - 리뷰어 게이트 재검토 결과 `Unconditional Approval` 확인 + ### 2026-06-29 Phase 10 최근 활동 크리에이터 섹션 구현 완료 - 목적: V2 Main Home 추천 탭에 Figma `24:5529`, `24:5532` 기준 최근 활동 크리에이터 섹션을 연결