feat(home): 팔로잉 크리에이터 섹션을 추가한다
This commit is contained in:
@@ -258,6 +258,9 @@
|
|||||||
401C10322FEF300000A5BBA3 /* MainHomeFollowingApi.swift in Sources */ = {isa = PBXBuildFile; fileRef = 401C10022FEF300000A5BBA3 /* MainHomeFollowingApi.swift */; };
|
401C10322FEF300000A5BBA3 /* MainHomeFollowingApi.swift in Sources */ = {isa = PBXBuildFile; fileRef = 401C10022FEF300000A5BBA3 /* MainHomeFollowingApi.swift */; };
|
||||||
401C10332FEF300000A5BBA3 /* MainHomeFollowingRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 401C10032FEF300000A5BBA3 /* MainHomeFollowingRepository.swift */; };
|
401C10332FEF300000A5BBA3 /* MainHomeFollowingRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 401C10032FEF300000A5BBA3 /* MainHomeFollowingRepository.swift */; };
|
||||||
401C10342FEF300000A5BBA3 /* MainHomeFollowingViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 401C10042FEF300000A5BBA3 /* MainHomeFollowingViewModel.swift */; };
|
401C10342FEF300000A5BBA3 /* MainHomeFollowingViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 401C10042FEF300000A5BBA3 /* MainHomeFollowingViewModel.swift */; };
|
||||||
|
401C10412FEF500000A5BBA3 /* MainHomeFollowingCreatorSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 401C10442FEF500000A5BBA3 /* MainHomeFollowingCreatorSection.swift */; };
|
||||||
|
401C10422FEF500000A5BBA3 /* MainHomeFollowingCreatorSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 401C10442FEF500000A5BBA3 /* MainHomeFollowingCreatorSection.swift */; };
|
||||||
|
401C10432FEF500000A5BBA3 /* MainHomeFollowingCreatorSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 401C10442FEF500000A5BBA3 /* MainHomeFollowingCreatorSection.swift */; };
|
||||||
40235DED2E3797EB00B09A87 /* RecentContent+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40235DEC2E3797EB00B09A87 /* RecentContent+CoreDataClass.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 */; };
|
40235DEE2E3797EB00B09A87 /* RecentContent+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40235DEC2E3797EB00B09A87 /* RecentContent+CoreDataClass.swift */; };
|
||||||
40235DF02E37983D00B09A87 /* PersistenceController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40235DEF2E37983D00B09A87 /* PersistenceController.swift */; };
|
40235DF02E37983D00B09A87 /* PersistenceController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40235DEF2E37983D00B09A87 /* PersistenceController.swift */; };
|
||||||
@@ -1796,6 +1799,7 @@
|
|||||||
401C10022FEF300000A5BBA3 /* MainHomeFollowingApi.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainHomeFollowingApi.swift; sourceTree = "<group>"; };
|
401C10022FEF300000A5BBA3 /* MainHomeFollowingApi.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainHomeFollowingApi.swift; sourceTree = "<group>"; };
|
||||||
401C10032FEF300000A5BBA3 /* MainHomeFollowingRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainHomeFollowingRepository.swift; sourceTree = "<group>"; };
|
401C10032FEF300000A5BBA3 /* MainHomeFollowingRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainHomeFollowingRepository.swift; sourceTree = "<group>"; };
|
||||||
401C10042FEF300000A5BBA3 /* MainHomeFollowingViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainHomeFollowingViewModel.swift; sourceTree = "<group>"; };
|
401C10042FEF300000A5BBA3 /* MainHomeFollowingViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainHomeFollowingViewModel.swift; sourceTree = "<group>"; };
|
||||||
|
401C10442FEF500000A5BBA3 /* MainHomeFollowingCreatorSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainHomeFollowingCreatorSection.swift; sourceTree = "<group>"; };
|
||||||
40235DEC2E3797EB00B09A87 /* RecentContent+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RecentContent+CoreDataClass.swift"; sourceTree = "<group>"; };
|
40235DEC2E3797EB00B09A87 /* RecentContent+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RecentContent+CoreDataClass.swift"; sourceTree = "<group>"; };
|
||||||
40235DEF2E37983D00B09A87 /* PersistenceController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PersistenceController.swift; sourceTree = "<group>"; };
|
40235DEF2E37983D00B09A87 /* PersistenceController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PersistenceController.swift; sourceTree = "<group>"; };
|
||||||
40235DF22E37987300B09A87 /* RecentContentService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecentContentService.swift; sourceTree = "<group>"; };
|
40235DF22E37987300B09A87 /* RecentContentService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecentContentService.swift; sourceTree = "<group>"; };
|
||||||
@@ -2797,12 +2801,21 @@
|
|||||||
children = (
|
children = (
|
||||||
401C10052FEF300000A5BBA3 /* Models */,
|
401C10052FEF300000A5BBA3 /* Models */,
|
||||||
401C10062FEF300000A5BBA3 /* Repository */,
|
401C10062FEF300000A5BBA3 /* Repository */,
|
||||||
|
401C10402FEF500000A5BBA3 /* Components */,
|
||||||
401C10042FEF300000A5BBA3 /* MainHomeFollowingViewModel.swift */,
|
401C10042FEF300000A5BBA3 /* MainHomeFollowingViewModel.swift */,
|
||||||
401A3FB72FEEAFA000A5BBA3 /* MainHomeFollowingView.swift */,
|
401A3FB72FEEAFA000A5BBA3 /* MainHomeFollowingView.swift */,
|
||||||
);
|
);
|
||||||
path = Following;
|
path = Following;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
401C10402FEF500000A5BBA3 /* Components */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
401C10442FEF500000A5BBA3 /* MainHomeFollowingCreatorSection.swift */,
|
||||||
|
);
|
||||||
|
path = Components;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
401A3FC02FEEB00100A5BBA3 /* Components */ = {
|
401A3FC02FEEB00100A5BBA3 /* Components */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@@ -5467,6 +5480,7 @@
|
|||||||
401C10122FEF300000A5BBA3 /* MainHomeFollowingApi.swift in Sources */,
|
401C10122FEF300000A5BBA3 /* MainHomeFollowingApi.swift in Sources */,
|
||||||
401C10132FEF300000A5BBA3 /* MainHomeFollowingRepository.swift in Sources */,
|
401C10132FEF300000A5BBA3 /* MainHomeFollowingRepository.swift in Sources */,
|
||||||
401C10142FEF300000A5BBA3 /* MainHomeFollowingViewModel.swift in Sources */,
|
401C10142FEF300000A5BBA3 /* MainHomeFollowingViewModel.swift in Sources */,
|
||||||
|
401C10412FEF500000A5BBA3 /* MainHomeFollowingCreatorSection.swift in Sources */,
|
||||||
409143302A85652F00EEBFB1 /* CanChargeView.swift in Sources */,
|
409143302A85652F00EEBFB1 /* CanChargeView.swift in Sources */,
|
||||||
40975CA32B572298004E2F1B /* LiveRoomOverlayStrokeTextButton.swift in Sources */,
|
40975CA32B572298004E2F1B /* LiveRoomOverlayStrokeTextButton.swift in Sources */,
|
||||||
40235DED2E3797EB00B09A87 /* RecentContent+CoreDataClass.swift in Sources */,
|
40235DED2E3797EB00B09A87 /* RecentContent+CoreDataClass.swift in Sources */,
|
||||||
@@ -6231,6 +6245,7 @@
|
|||||||
401C10222FEF300000A5BBA3 /* MainHomeFollowingApi.swift in Sources */,
|
401C10222FEF300000A5BBA3 /* MainHomeFollowingApi.swift in Sources */,
|
||||||
401C10232FEF300000A5BBA3 /* MainHomeFollowingRepository.swift in Sources */,
|
401C10232FEF300000A5BBA3 /* MainHomeFollowingRepository.swift in Sources */,
|
||||||
401C10242FEF300000A5BBA3 /* MainHomeFollowingViewModel.swift in Sources */,
|
401C10242FEF300000A5BBA3 /* MainHomeFollowingViewModel.swift in Sources */,
|
||||||
|
401C10422FEF500000A5BBA3 /* MainHomeFollowingCreatorSection.swift in Sources */,
|
||||||
B3AF650899B8FC84E0C0CDA0 /* MainPlaceholderTabView.swift in Sources */,
|
B3AF650899B8FC84E0C0CDA0 /* MainPlaceholderTabView.swift in Sources */,
|
||||||
CA65AD0D677B4A8E9CAC0E15 /* MainTab.swift in Sources */,
|
CA65AD0D677B4A8E9CAC0E15 /* MainTab.swift in Sources */,
|
||||||
A0643C829BE7377DC09112CB /* MainTabBarButton.swift in Sources */,
|
A0643C829BE7377DC09112CB /* MainTabBarButton.swift in Sources */,
|
||||||
@@ -7025,6 +7040,7 @@
|
|||||||
401C10322FEF300000A5BBA3 /* MainHomeFollowingApi.swift in Sources */,
|
401C10322FEF300000A5BBA3 /* MainHomeFollowingApi.swift in Sources */,
|
||||||
401C10332FEF300000A5BBA3 /* MainHomeFollowingRepository.swift in Sources */,
|
401C10332FEF300000A5BBA3 /* MainHomeFollowingRepository.swift in Sources */,
|
||||||
401C10342FEF300000A5BBA3 /* MainHomeFollowingViewModel.swift in Sources */,
|
401C10342FEF300000A5BBA3 /* MainHomeFollowingViewModel.swift in Sources */,
|
||||||
|
401C10432FEF500000A5BBA3 /* MainHomeFollowingCreatorSection.swift in Sources */,
|
||||||
ACD71056E97E13E48941ABBB /* MainPlaceholderTabView.swift in Sources */,
|
ACD71056E97E13E48941ABBB /* MainPlaceholderTabView.swift in Sources */,
|
||||||
33BA3AB731849284E62AE04B /* MainTab.swift in Sources */,
|
33BA3AB731849284E62AE04B /* MainTab.swift in Sources */,
|
||||||
B11681AC02BF51C6E2FA6FF3 /* MainTabBarButton.swift in Sources */,
|
B11681AC02BF51C6E2FA6FF3 /* MainTabBarButton.swift in Sources */,
|
||||||
|
|||||||
@@ -0,0 +1,68 @@
|
|||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct MainHomeFollowingCreatorSection: View {
|
||||||
|
let followingCreators: [FollowingCreatorResponse]
|
||||||
|
let onTapCreator: (Int) -> Void
|
||||||
|
let onTapAll: () -> Void
|
||||||
|
|
||||||
|
init(
|
||||||
|
followingCreators: [FollowingCreatorResponse],
|
||||||
|
onTapCreator: @escaping (Int) -> Void = { _ in },
|
||||||
|
onTapAll: @escaping () -> Void = {}
|
||||||
|
) {
|
||||||
|
self.followingCreators = followingCreators
|
||||||
|
self.onTapCreator = onTapCreator
|
||||||
|
self.onTapAll = onTapAll
|
||||||
|
}
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
ScrollView(.horizontal, showsIndicators: false) {
|
||||||
|
LazyHStack(alignment: .top, spacing: SodaSpacing.s12) {
|
||||||
|
ForEach(followingCreators) { creator in
|
||||||
|
CreatorProfileItem(
|
||||||
|
imageUrl: creator.creatorProfileImageUrl,
|
||||||
|
name: creator.creatorNickname,
|
||||||
|
imageSize: CGSize(width: 72, height: 72),
|
||||||
|
spacing: SodaSpacing.s8
|
||||||
|
) {
|
||||||
|
onTapCreator(creator.creatorId)
|
||||||
|
}
|
||||||
|
.frame(width: 72)
|
||||||
|
}
|
||||||
|
|
||||||
|
Button(action: onTapAll) {
|
||||||
|
Text(I18n.HomeFollowing.allButtonTitle)
|
||||||
|
.appFont(.body4)
|
||||||
|
.foregroundColor(Color.soda400)
|
||||||
|
.padding(.horizontal, 16)
|
||||||
|
.frame(height: allButtonHeight)
|
||||||
|
}
|
||||||
|
.buttonStyle(.plain)
|
||||||
|
}
|
||||||
|
.padding(.horizontal, SodaSpacing.s20)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private var allButtonHeight: CGFloat { 72 + SodaSpacing.s8 + 20 }
|
||||||
|
}
|
||||||
|
|
||||||
|
struct MainHomeFollowingCreatorSection_Previews: PreviewProvider {
|
||||||
|
static var previews: some View {
|
||||||
|
VStack(spacing: SodaSpacing.s20) {
|
||||||
|
MainHomeFollowingCreatorSection(
|
||||||
|
followingCreators: [
|
||||||
|
FollowingCreatorResponse(
|
||||||
|
creatorId: 1,
|
||||||
|
creatorNickname: "크리에이터",
|
||||||
|
creatorProfileImageUrl: "https://picsum.photos/200/200"
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
MainHomeFollowingCreatorSection(followingCreators: [])
|
||||||
|
}
|
||||||
|
.padding(.vertical, SodaSpacing.s20)
|
||||||
|
.background(Color.black)
|
||||||
|
.previewLayout(.sizeThatFits)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,8 +1,21 @@
|
|||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
struct MainHomeFollowingView: View {
|
struct MainHomeFollowingView: View {
|
||||||
|
let onTapFollowingAll: () -> Void
|
||||||
|
|
||||||
|
init(onTapFollowingAll: @escaping () -> Void = {}) {
|
||||||
|
self.onTapFollowingAll = onTapFollowingAll
|
||||||
|
}
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
MainPlaceholderTabView(title: "팔로잉")
|
VStack(spacing: 0) {
|
||||||
|
MainHomeFollowingCreatorSection(
|
||||||
|
followingCreators: [],
|
||||||
|
onTapAll: onTapFollowingAll
|
||||||
|
)
|
||||||
|
|
||||||
|
MainPlaceholderTabView(title: "팔로잉")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ struct MainHomeView: View {
|
|||||||
let onTapBanner: (RecommendationBannerResponse) -> Void
|
let onTapBanner: (RecommendationBannerResponse) -> Void
|
||||||
let onTapFollowAll: (@escaping () -> Void) -> Void
|
let onTapFollowAll: (@escaping () -> Void) -> Void
|
||||||
let onSelectFollowingTab: () -> Bool
|
let onSelectFollowingTab: () -> Bool
|
||||||
|
let onTapFollowingAll: () -> Void
|
||||||
|
|
||||||
@State private var selectedTab: MainHomeTab = .recommendation
|
@State private var selectedTab: MainHomeTab = .recommendation
|
||||||
|
|
||||||
@@ -71,7 +72,7 @@ struct MainHomeView: View {
|
|||||||
case .ranking:
|
case .ranking:
|
||||||
MainHomeRankingView(onTapCreator: onTapCreator)
|
MainHomeRankingView(onTapCreator: onTapCreator)
|
||||||
case .following:
|
case .following:
|
||||||
MainHomeFollowingView()
|
MainHomeFollowingView(onTapFollowingAll: onTapFollowingAll)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -106,7 +107,8 @@ struct MainHomeView_Previews: PreviewProvider {
|
|||||||
onTapCommunity: { _ in },
|
onTapCommunity: { _ in },
|
||||||
onTapBanner: { _ in },
|
onTapBanner: { _ in },
|
||||||
onTapFollowAll: { action in action() },
|
onTapFollowAll: { action in action() },
|
||||||
onSelectFollowingTab: { true }
|
onSelectFollowingTab: { true },
|
||||||
|
onTapFollowingAll: {}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -164,7 +164,8 @@ struct MainView: View {
|
|||||||
onTapCommunity: handleRecommendationCommunityTap,
|
onTapCommunity: handleRecommendationCommunityTap,
|
||||||
onTapBanner: handleRecommendationBannerTap,
|
onTapBanner: handleRecommendationBannerTap,
|
||||||
onTapFollowAll: handleRecommendationFollowAllTap,
|
onTapFollowAll: handleRecommendationFollowAllTap,
|
||||||
onSelectFollowingTab: handleFollowingTabSelection
|
onSelectFollowingTab: handleFollowingTabSelection,
|
||||||
|
onTapFollowingAll: handleFollowingAllTap
|
||||||
)
|
)
|
||||||
case .content:
|
case .content:
|
||||||
MainPlaceholderTabView(title: MainTab.content.title)
|
MainPlaceholderTabView(title: MainTab.content.title)
|
||||||
@@ -485,6 +486,10 @@ struct MainView: View {
|
|||||||
performRecommendationDetailAction(action: action)
|
performRecommendationDetailAction(action: action)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func handleFollowingAllTap() {
|
||||||
|
appState.setAppStep(step: .followingList)
|
||||||
|
}
|
||||||
|
|
||||||
private func handleFollowingTabSelection() -> Bool {
|
private func handleFollowingTabSelection() -> Bool {
|
||||||
let trimmed = token.trimmingCharacters(in: .whitespacesAndNewlines)
|
let trimmed = token.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||||
guard !trimmed.isEmpty else {
|
guard !trimmed.isEmpty else {
|
||||||
|
|||||||
@@ -174,7 +174,7 @@
|
|||||||
|
|
||||||
### Phase 3: 팔로잉 크리에이터 섹션과 전체 버튼
|
### Phase 3: 팔로잉 크리에이터 섹션과 전체 버튼
|
||||||
|
|
||||||
- [ ] **Task 3.1: 팔로잉 크리에이터 섹션 생성**
|
- [x] **Task 3.1: 팔로잉 크리에이터 섹션 생성**
|
||||||
- 대상 파일:
|
- 대상 파일:
|
||||||
- 생성: `SodaLive/Sources/V2/Main/Home/Following/Components/MainHomeFollowingCreatorSection.swift`
|
- 생성: `SodaLive/Sources/V2/Main/Home/Following/Components/MainHomeFollowingCreatorSection.swift`
|
||||||
- 확인: `SodaLive/Sources/V2/Component/Creator/CreatorProfileItem.swift`
|
- 확인: `SodaLive/Sources/V2/Component/Creator/CreatorProfileItem.swift`
|
||||||
@@ -193,7 +193,7 @@
|
|||||||
- 실행 명령: `rg "struct MainHomeFollowingCreatorSection|ScrollView\\(\\.horizontal|followingCreators|onTapCreator|onTapAll|allButtonTitle|Color.soda400|padding\\(\\.horizontal, 16\\)" SodaLive/Sources/V2/Main/Home/Following/Components/MainHomeFollowingCreatorSection.swift`
|
- 실행 명령: `rg "struct MainHomeFollowingCreatorSection|ScrollView\\(\\.horizontal|followingCreators|onTapCreator|onTapAll|allButtonTitle|Color.soda400|padding\\(\\.horizontal, 16\\)" SodaLive/Sources/V2/Main/Home/Following/Components/MainHomeFollowingCreatorSection.swift`
|
||||||
- 기대 결과: 가로 creator 목록과 마지막 `전체` 버튼 요구사항이 확인된다.
|
- 기대 결과: 가로 creator 목록과 마지막 `전체` 버튼 요구사항이 확인된다.
|
||||||
|
|
||||||
- [ ] **Task 3.2: 전체 팔로잉 목록 진입 연결**
|
- [x] **Task 3.2: 전체 팔로잉 목록 진입 연결**
|
||||||
- 대상 파일:
|
- 대상 파일:
|
||||||
- 수정: `SodaLive/Sources/V2/Main/Home/MainHomeView.swift`
|
- 수정: `SodaLive/Sources/V2/Main/Home/MainHomeView.swift`
|
||||||
- 수정: `SodaLive/Sources/V2/Main/MainView.swift`
|
- 수정: `SodaLive/Sources/V2/Main/MainView.swift`
|
||||||
@@ -472,3 +472,7 @@
|
|||||||
- 2026-06-30: `rg "struct HomeFollowingTabResponse|struct ChatRoomListItemResponse|enum CreatorActivityType|struct FollowingNewsResponse|struct FollowingCreatorRankingNewsResponse|struct FollowingContentNewsResponse|struct FollowingContentRankingNewsResponse|struct FollowingCommunityPostNewsResponse|enum FollowingNewsType|unknown\(" SodaLive/Sources/V2/Main/Home/Following/Models/HomeFollowingTabResponse.swift`로 Phase 2 응답 모델과 unknown enum 처리를 확인했다.
|
- 2026-06-30: `rg "struct HomeFollowingTabResponse|struct ChatRoomListItemResponse|enum CreatorActivityType|struct FollowingNewsResponse|struct FollowingCreatorRankingNewsResponse|struct FollowingContentNewsResponse|struct FollowingContentRankingNewsResponse|struct FollowingCommunityPostNewsResponse|enum FollowingNewsType|unknown\(" SodaLive/Sources/V2/Main/Home/Following/Models/HomeFollowingTabResponse.swift`로 Phase 2 응답 모델과 unknown enum 처리를 확인했다.
|
||||||
- 2026-06-30: `rg "enum MainHomeFollowingApi|getFollowing|/api/v2/home/following|Authorization|requestPlain|TargetType|final class MainHomeFollowingRepository|MoyaProvider<MainHomeFollowingApi>|AnyPublisher<Response, MoyaError>" SodaLive/Sources/V2/Main/Home/Following/Repository`로 API/Repository 패턴을 확인했다.
|
- 2026-06-30: `rg "enum MainHomeFollowingApi|getFollowing|/api/v2/home/following|Authorization|requestPlain|TargetType|final class MainHomeFollowingRepository|MoyaProvider<MainHomeFollowingApi>|AnyPublisher<Response, MoyaError>" SodaLive/Sources/V2/Main/Home/Following/Repository`로 API/Repository 패턴을 확인했다.
|
||||||
- 2026-06-30: `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive" -configuration Debug build`를 실행해 빌드 성공을 확인했다. 기존 프로젝트의 duplicate build file/run script warning은 남아 있으나 Phase 1-2 컴파일 오류는 없었다.
|
- 2026-06-30: `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive" -configuration Debug build`를 실행해 빌드 성공을 확인했다. 기존 프로젝트의 duplicate build file/run script warning은 남아 있으나 Phase 1-2 컴파일 오류는 없었다.
|
||||||
|
- 2026-06-30: Phase 3 구현을 진행해 `MainHomeFollowingCreatorSection`을 추가하고, `MainHomeView -> MainHomeFollowingView -> MainView.handleFollowingAllTap()` 경로로 `전체` 버튼을 `.followingList` 라우팅에 연결했다.
|
||||||
|
- 2026-06-30: `rg "struct MainHomeFollowingCreatorSection|ScrollView\(\.horizontal|followingCreators|onTapCreator|onTapAll|allButtonTitle|Color\.soda400|padding\(\.horizontal, 16\)" SodaLive/Sources/V2/Main/Home/Following/Components/MainHomeFollowingCreatorSection.swift`로 팔로잉 크리에이터 섹션 요구사항을 확인했다.
|
||||||
|
- 2026-06-30: `rg "onTapFollowingAll|followingList|FollowCreatorView" SodaLive/Sources/V2/Main/Home/MainHomeView.swift SodaLive/Sources/V2/Main/MainView.swift SodaLive/Sources/App/AppStep.swift SodaLive/Sources/ContentView.swift`로 `전체` 버튼 라우팅 연결을 확인했다.
|
||||||
|
- 2026-06-30: `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive" -configuration Debug build`를 재실행해 Phase 3 신규 Swift 파일 target 등록과 컴파일 성공을 확인했다.
|
||||||
|
|||||||
Reference in New Issue
Block a user