From 7c98af0c7d0a433d8b0dbafafc3d82c5fef67537 Mon Sep 17 00:00:00 2001 From: Yu Sung Date: Sat, 4 Jul 2026 22:45:07 +0900 Subject: [PATCH] =?UTF-8?q?feat(creator):=20=ED=9B=84=EC=9B=90=20=ED=83=AD?= =?UTF-8?q?=EC=9D=84=20=EC=97=B0=EA=B2=B0=ED=95=9C=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SodaLive.xcodeproj/project.pbxproj | 112 ++++++++++++++++++ .../CreatorChannel/CreatorChannelView.swift | 25 ++++ .../CreatorChannelViewModel.swift | 1 - .../CreatorChannelDonationTabView.swift | 76 ++++++++++++ 4 files changed, 213 insertions(+), 1 deletion(-) create mode 100644 SodaLive/Sources/V2/CreatorChannel/Donation/CreatorChannelDonationTabView.swift diff --git a/SodaLive.xcodeproj/project.pbxproj b/SodaLive.xcodeproj/project.pbxproj index 5b893292..b5adb032 100644 --- a/SodaLive.xcodeproj/project.pbxproj +++ b/SodaLive.xcodeproj/project.pbxproj @@ -1830,6 +1830,36 @@ CC0403052FF0400000A5BBA3 /* CreatorChannelSeriesOwnershipRateView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC0400052FF0400000A5BBA3 /* CreatorChannelSeriesOwnershipRateView.swift */; }; CC0403062FF0400000A5BBA3 /* CreatorChannelSeriesListItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC0400062FF0400000A5BBA3 /* CreatorChannelSeriesListItem.swift */; }; CC0403072FF0400000A5BBA3 /* CreatorChannelSeriesTabView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC0400072FF0400000A5BBA3 /* CreatorChannelSeriesTabView.swift */; }; + CC0510012FF0500000A5BBA3 /* CreatorChannelDonationTabResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC0500012FF0500000A5BBA3 /* CreatorChannelDonationTabResponse.swift */; }; + CC0510022FF0500000A5BBA3 /* CreatorChannelDonationApi.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC0500022FF0500000A5BBA3 /* CreatorChannelDonationApi.swift */; }; + CC0510032FF0500000A5BBA3 /* CreatorChannelDonationRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC0500032FF0500000A5BBA3 /* CreatorChannelDonationRepository.swift */; }; + CC0510042FF0500000A5BBA3 /* CreatorChannelDonationViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC0500042FF0500000A5BBA3 /* CreatorChannelDonationViewModel.swift */; }; + CC0510052FF0500000A5BBA3 /* CreatorChannelDonationTabView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC0500052FF0500000A5BBA3 /* CreatorChannelDonationTabView.swift */; }; + CC0510062FF0500000A5BBA3 /* CreatorChannelDonationRankingSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC0500062FF0500000A5BBA3 /* CreatorChannelDonationRankingSection.swift */; }; + CC0510072FF0500000A5BBA3 /* CreatorChannelDonationCountBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC0500072FF0500000A5BBA3 /* CreatorChannelDonationCountBar.swift */; }; + CC0510082FF0500000A5BBA3 /* CreatorChannelDonationEmptyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC0500082FF0500000A5BBA3 /* CreatorChannelDonationEmptyView.swift */; }; + CC0510092FF0500000A5BBA3 /* CreatorChannelDonationFloatingButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC0500092FF0500000A5BBA3 /* CreatorChannelDonationFloatingButton.swift */; }; + CC05100A2FF0500000A5BBA3 /* CreatorChannelDonationCard.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC05000A2FF0500000A5BBA3 /* CreatorChannelDonationCard.swift */; }; + CC0520012FF0500000A5BBA3 /* CreatorChannelDonationTabResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC0500012FF0500000A5BBA3 /* CreatorChannelDonationTabResponse.swift */; }; + CC0520022FF0500000A5BBA3 /* CreatorChannelDonationApi.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC0500022FF0500000A5BBA3 /* CreatorChannelDonationApi.swift */; }; + CC0520032FF0500000A5BBA3 /* CreatorChannelDonationRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC0500032FF0500000A5BBA3 /* CreatorChannelDonationRepository.swift */; }; + CC0520042FF0500000A5BBA3 /* CreatorChannelDonationViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC0500042FF0500000A5BBA3 /* CreatorChannelDonationViewModel.swift */; }; + CC0520052FF0500000A5BBA3 /* CreatorChannelDonationTabView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC0500052FF0500000A5BBA3 /* CreatorChannelDonationTabView.swift */; }; + CC0520062FF0500000A5BBA3 /* CreatorChannelDonationRankingSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC0500062FF0500000A5BBA3 /* CreatorChannelDonationRankingSection.swift */; }; + CC0520072FF0500000A5BBA3 /* CreatorChannelDonationCountBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC0500072FF0500000A5BBA3 /* CreatorChannelDonationCountBar.swift */; }; + CC0520082FF0500000A5BBA3 /* CreatorChannelDonationEmptyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC0500082FF0500000A5BBA3 /* CreatorChannelDonationEmptyView.swift */; }; + CC0520092FF0500000A5BBA3 /* CreatorChannelDonationFloatingButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC0500092FF0500000A5BBA3 /* CreatorChannelDonationFloatingButton.swift */; }; + CC05200A2FF0500000A5BBA3 /* CreatorChannelDonationCard.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC05000A2FF0500000A5BBA3 /* CreatorChannelDonationCard.swift */; }; + CC0530012FF0500000A5BBA3 /* CreatorChannelDonationTabResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC0500012FF0500000A5BBA3 /* CreatorChannelDonationTabResponse.swift */; }; + CC0530022FF0500000A5BBA3 /* CreatorChannelDonationApi.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC0500022FF0500000A5BBA3 /* CreatorChannelDonationApi.swift */; }; + CC0530032FF0500000A5BBA3 /* CreatorChannelDonationRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC0500032FF0500000A5BBA3 /* CreatorChannelDonationRepository.swift */; }; + CC0530042FF0500000A5BBA3 /* CreatorChannelDonationViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC0500042FF0500000A5BBA3 /* CreatorChannelDonationViewModel.swift */; }; + CC0530052FF0500000A5BBA3 /* CreatorChannelDonationTabView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC0500052FF0500000A5BBA3 /* CreatorChannelDonationTabView.swift */; }; + CC0530062FF0500000A5BBA3 /* CreatorChannelDonationRankingSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC0500062FF0500000A5BBA3 /* CreatorChannelDonationRankingSection.swift */; }; + CC0530072FF0500000A5BBA3 /* CreatorChannelDonationCountBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC0500072FF0500000A5BBA3 /* CreatorChannelDonationCountBar.swift */; }; + CC0530082FF0500000A5BBA3 /* CreatorChannelDonationEmptyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC0500082FF0500000A5BBA3 /* CreatorChannelDonationEmptyView.swift */; }; + CC0530092FF0500000A5BBA3 /* CreatorChannelDonationFloatingButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC0500092FF0500000A5BBA3 /* CreatorChannelDonationFloatingButton.swift */; }; + CC05300A2FF0500000A5BBA3 /* CreatorChannelDonationCard.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC05000A2FF0500000A5BBA3 /* CreatorChannelDonationCard.swift */; }; D1C65856889B16DFDB69A004 /* PushNotificationRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FDDF6BBD0192819B1F5B3FE /* PushNotificationRepository.swift */; }; D2A268C7346E84E6B455E25A /* Pods_SodaLive_dev.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6F4E5BB7961B7E6BB68C3379 /* Pods_SodaLive_dev.framework */; }; DD202E48D61F1CE8108AD164 /* LineSDK in Frameworks */ = {isa = PBXBuildFile; productRef = 6DBA0C325ACEC3FCDB22490D /* LineSDK */; }; @@ -2713,6 +2743,16 @@ CC0400052FF0400000A5BBA3 /* CreatorChannelSeriesOwnershipRateView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreatorChannelSeriesOwnershipRateView.swift; sourceTree = ""; }; CC0400062FF0400000A5BBA3 /* CreatorChannelSeriesListItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreatorChannelSeriesListItem.swift; sourceTree = ""; }; CC0400072FF0400000A5BBA3 /* CreatorChannelSeriesTabView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreatorChannelSeriesTabView.swift; sourceTree = ""; }; + CC0500012FF0500000A5BBA3 /* CreatorChannelDonationTabResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreatorChannelDonationTabResponse.swift; sourceTree = ""; }; + CC0500022FF0500000A5BBA3 /* CreatorChannelDonationApi.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreatorChannelDonationApi.swift; sourceTree = ""; }; + CC0500032FF0500000A5BBA3 /* CreatorChannelDonationRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreatorChannelDonationRepository.swift; sourceTree = ""; }; + CC0500042FF0500000A5BBA3 /* CreatorChannelDonationViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreatorChannelDonationViewModel.swift; sourceTree = ""; }; + CC0500052FF0500000A5BBA3 /* CreatorChannelDonationTabView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreatorChannelDonationTabView.swift; sourceTree = ""; }; + CC0500062FF0500000A5BBA3 /* CreatorChannelDonationRankingSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreatorChannelDonationRankingSection.swift; sourceTree = ""; }; + CC0500072FF0500000A5BBA3 /* CreatorChannelDonationCountBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreatorChannelDonationCountBar.swift; sourceTree = ""; }; + CC0500082FF0500000A5BBA3 /* CreatorChannelDonationEmptyView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreatorChannelDonationEmptyView.swift; sourceTree = ""; }; + CC0500092FF0500000A5BBA3 /* CreatorChannelDonationFloatingButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreatorChannelDonationFloatingButton.swift; sourceTree = ""; }; + CC05000A2FF0500000A5BBA3 /* CreatorChannelDonationCard.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreatorChannelDonationCard.swift; sourceTree = ""; }; CC73FFC54CB1D988053059D1 /* LanguageEnvironment.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = LanguageEnvironment.swift; sourceTree = ""; }; CE82912F2F111593BE42E33C /* CommunityPostCard.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = CommunityPostCard.swift; sourceTree = ""; }; D03CBA8005C81F7C31F59A89 /* Pods-SodaLive.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SodaLive.release.xcconfig"; path = "Target Support Files/Pods-SodaLive/Pods-SodaLive.release.xcconfig"; sourceTree = ""; }; @@ -5319,6 +5359,7 @@ CC0100332FF0100000A5BBA3 /* Live */, CC0300112FF0300000A5BBA3 /* Audio */, CC0400112FF0400000A5BBA3 /* Series */, + CC05001B2FF0500000A5BBA3 /* Donation */, CC0100082FF0100000A5BBA3 /* CreatorChannelView.swift */, CC0100092FF0100000A5BBA3 /* CreatorChannelViewModel.swift */, ); @@ -5461,6 +5502,47 @@ path = Series; sourceTree = ""; }; + CC0500182FF0500000A5BBA3 /* Models */ = { + isa = PBXGroup; + children = ( + CC0500012FF0500000A5BBA3 /* CreatorChannelDonationTabResponse.swift */, + ); + path = Models; + sourceTree = ""; + }; + CC0500192FF0500000A5BBA3 /* Repository */ = { + isa = PBXGroup; + children = ( + CC0500022FF0500000A5BBA3 /* CreatorChannelDonationApi.swift */, + CC0500032FF0500000A5BBA3 /* CreatorChannelDonationRepository.swift */, + ); + path = Repository; + sourceTree = ""; + }; + CC05001A2FF0500000A5BBA3 /* Components */ = { + isa = PBXGroup; + children = ( + CC0500062FF0500000A5BBA3 /* CreatorChannelDonationRankingSection.swift */, + CC0500072FF0500000A5BBA3 /* CreatorChannelDonationCountBar.swift */, + CC0500082FF0500000A5BBA3 /* CreatorChannelDonationEmptyView.swift */, + CC0500092FF0500000A5BBA3 /* CreatorChannelDonationFloatingButton.swift */, + CC05000A2FF0500000A5BBA3 /* CreatorChannelDonationCard.swift */, + ); + path = Components; + sourceTree = ""; + }; + CC05001B2FF0500000A5BBA3 /* Donation */ = { + isa = PBXGroup; + children = ( + CC0500182FF0500000A5BBA3 /* Models */, + CC0500192FF0500000A5BBA3 /* Repository */, + CC05001A2FF0500000A5BBA3 /* Components */, + CC0500042FF0500000A5BBA3 /* CreatorChannelDonationViewModel.swift */, + CC0500052FF0500000A5BBA3 /* CreatorChannelDonationTabView.swift */, + ); + path = Donation; + sourceTree = ""; + }; D37878F5929361B43B1E3C5C /* Card */ = { isa = PBXGroup; children = ( @@ -5935,6 +6017,16 @@ CC0401052FF0400000A5BBA3 /* CreatorChannelSeriesOwnershipRateView.swift in Sources */, CC0401062FF0400000A5BBA3 /* CreatorChannelSeriesListItem.swift in Sources */, CC0401072FF0400000A5BBA3 /* CreatorChannelSeriesTabView.swift in Sources */, + CC0510012FF0500000A5BBA3 /* CreatorChannelDonationTabResponse.swift in Sources */, + CC0510022FF0500000A5BBA3 /* CreatorChannelDonationApi.swift in Sources */, + CC0510032FF0500000A5BBA3 /* CreatorChannelDonationRepository.swift in Sources */, + CC0510042FF0500000A5BBA3 /* CreatorChannelDonationViewModel.swift in Sources */, + CC0510052FF0500000A5BBA3 /* CreatorChannelDonationTabView.swift in Sources */, + CC0510062FF0500000A5BBA3 /* CreatorChannelDonationRankingSection.swift in Sources */, + CC0510072FF0500000A5BBA3 /* CreatorChannelDonationCountBar.swift in Sources */, + CC0510082FF0500000A5BBA3 /* CreatorChannelDonationEmptyView.swift in Sources */, + CC0510092FF0500000A5BBA3 /* CreatorChannelDonationFloatingButton.swift in Sources */, + CC05100A2FF0500000A5BBA3 /* CreatorChannelDonationCard.swift in Sources */, 409E35082B0759DE00CCB985 /* MoyaProviderExtension.swift in Sources */, 40DDBD772B2B4FD700A2E8DA /* CreatorCommunityMoreItemView.swift in Sources */, 400EA7742A89C42C004992CF /* StartLiveRequest.swift in Sources */, @@ -6771,6 +6863,16 @@ CC0402052FF0400000A5BBA3 /* CreatorChannelSeriesOwnershipRateView.swift in Sources */, CC0402062FF0400000A5BBA3 /* CreatorChannelSeriesListItem.swift in Sources */, CC0402072FF0400000A5BBA3 /* CreatorChannelSeriesTabView.swift in Sources */, + CC0520012FF0500000A5BBA3 /* CreatorChannelDonationTabResponse.swift in Sources */, + CC0520022FF0500000A5BBA3 /* CreatorChannelDonationApi.swift in Sources */, + CC0520032FF0500000A5BBA3 /* CreatorChannelDonationRepository.swift in Sources */, + CC0520042FF0500000A5BBA3 /* CreatorChannelDonationViewModel.swift in Sources */, + CC0520052FF0500000A5BBA3 /* CreatorChannelDonationTabView.swift in Sources */, + CC0520062FF0500000A5BBA3 /* CreatorChannelDonationRankingSection.swift in Sources */, + CC0520072FF0500000A5BBA3 /* CreatorChannelDonationCountBar.swift in Sources */, + CC0520082FF0500000A5BBA3 /* CreatorChannelDonationEmptyView.swift in Sources */, + CC0520092FF0500000A5BBA3 /* CreatorChannelDonationFloatingButton.swift in Sources */, + CC05200A2FF0500000A5BBA3 /* CreatorChannelDonationCard.swift in Sources */, 401B3F092FEEF10000A5BBA3 /* MainHomeRankingViewModel.swift in Sources */, 401A3FAC2FEEAFA000A5BBA3 /* MainHomeView.swift in Sources */, 401A3FAD2FEEAFA000A5BBA3 /* MainHomeRecommendationView.swift in Sources */, @@ -7623,6 +7725,16 @@ CC0403052FF0400000A5BBA3 /* CreatorChannelSeriesOwnershipRateView.swift in Sources */, CC0403062FF0400000A5BBA3 /* CreatorChannelSeriesListItem.swift in Sources */, CC0403072FF0400000A5BBA3 /* CreatorChannelSeriesTabView.swift in Sources */, + CC0530012FF0500000A5BBA3 /* CreatorChannelDonationTabResponse.swift in Sources */, + CC0530022FF0500000A5BBA3 /* CreatorChannelDonationApi.swift in Sources */, + CC0530032FF0500000A5BBA3 /* CreatorChannelDonationRepository.swift in Sources */, + CC0530042FF0500000A5BBA3 /* CreatorChannelDonationViewModel.swift in Sources */, + CC0530052FF0500000A5BBA3 /* CreatorChannelDonationTabView.swift in Sources */, + CC0530062FF0500000A5BBA3 /* CreatorChannelDonationRankingSection.swift in Sources */, + CC0530072FF0500000A5BBA3 /* CreatorChannelDonationCountBar.swift in Sources */, + CC0530082FF0500000A5BBA3 /* CreatorChannelDonationEmptyView.swift in Sources */, + CC0530092FF0500000A5BBA3 /* CreatorChannelDonationFloatingButton.swift in Sources */, + CC05300A2FF0500000A5BBA3 /* CreatorChannelDonationCard.swift in Sources */, 401B3F082FEEF10000A5BBA3 /* MainHomeRankingViewModel.swift in Sources */, 401A3FB02FEEAFA000A5BBA3 /* MainHomeView.swift in Sources */, 401A3FB12FEEAFA000A5BBA3 /* MainHomeRecommendationView.swift in Sources */, diff --git a/SodaLive/Sources/V2/CreatorChannel/CreatorChannelView.swift b/SodaLive/Sources/V2/CreatorChannel/CreatorChannelView.swift index e2a2e17a..d9a69b3e 100644 --- a/SodaLive/Sources/V2/CreatorChannel/CreatorChannelView.swift +++ b/SodaLive/Sources/V2/CreatorChannel/CreatorChannelView.swift @@ -7,6 +7,7 @@ struct CreatorChannelView: View { @StateObject private var viewModel = CreatorChannelViewModel() @StateObject private var channelDonationViewModel = ChannelDonationViewModel() + @StateObject private var donationViewModel = CreatorChannelDonationViewModel() @StateObject private var liveViewModel = LiveViewModel() @StateObject private var mypageViewModel = MyPageViewModel() @AppStorage("token") private var token: String = UserDefaults.string(forKey: UserDefaultsKey.token) @@ -113,6 +114,13 @@ struct CreatorChannelView: View { .ignoresSafeArea(.container, edges: .bottom) } + if viewModel.selectedTab == .donation && shouldShowDonationFloatingButton && !viewModel.isLoading { + CreatorChannelDonationFloatingButton(action: showDonationDialog) + .ignoresSafeArea(.container, edges: .bottom) + .padding(.bottom, SodaSpacing.s14) + .padding(.trailing, SodaSpacing.s14) + } + if isShowAuthConfirmView { authConfirmDialog } @@ -133,6 +141,7 @@ struct CreatorChannelView: View { reloadAfterSuccess: false, onSuccess: { viewModel.fetchHome(creatorId: creatorId) + donationViewModel.fetchFirstPage(creatorId: creatorId) } ) } @@ -207,6 +216,10 @@ struct CreatorChannelView: View { } } + private var shouldShowDonationFloatingButton: Bool { + isOwnCreatorChannel == false && (donationViewModel.donationCount != 0 || donationViewModel.rankings.isEmpty == false) + } + @ViewBuilder private var selectedTabContent: some View { if viewModel.selectedTab == .live { @@ -228,6 +241,14 @@ struct CreatorChannelView: View { isOwnCreatorChannel: isOwnCreatorChannel, onTapSeries: showSeriesDetail ) + } else if viewModel.selectedTab == .donation { + CreatorChannelDonationTabView( + creatorId: creatorId, + isOwnCreatorChannel: isOwnCreatorChannel, + viewModel: donationViewModel, + onTapViewAll: showDonationRankingAll, + onTapDonate: showDonationDialog + ) } else if viewModel.selectedTab != .home { CreatorChannelPlaceholderTabView(title: viewModel.selectedTab.title) } else if let response = viewModel.response { @@ -337,6 +358,10 @@ struct CreatorChannelView: View { AppState.shared.setAppStep(step: .seriesDetail(seriesId: seriesId)) } + private func showDonationRankingAll() { + AppState.shared.setAppStep(step: .userProfileDonationAll(userId: creatorId)) + } + private func showCommunity(_ creatorId: Int) { guard creatorId > 0 else { return } AppState.shared.setAppStep(step: .creatorCommunityAll(creatorId: creatorId)) diff --git a/SodaLive/Sources/V2/CreatorChannel/CreatorChannelViewModel.swift b/SodaLive/Sources/V2/CreatorChannel/CreatorChannelViewModel.swift index 41f6ceba..555a9cd9 100644 --- a/SodaLive/Sources/V2/CreatorChannel/CreatorChannelViewModel.swift +++ b/SodaLive/Sources/V2/CreatorChannel/CreatorChannelViewModel.swift @@ -43,7 +43,6 @@ final class CreatorChannelViewModel: ObservableObject { if let data = decoded.data, decoded.success { self.response = data - self.selectedTab = .home self.isApiFailedPlaceholderVisible = false } else { if let message = decoded.message { diff --git a/SodaLive/Sources/V2/CreatorChannel/Donation/CreatorChannelDonationTabView.swift b/SodaLive/Sources/V2/CreatorChannel/Donation/CreatorChannelDonationTabView.swift new file mode 100644 index 00000000..ca6ada3d --- /dev/null +++ b/SodaLive/Sources/V2/CreatorChannel/Donation/CreatorChannelDonationTabView.swift @@ -0,0 +1,76 @@ +import SwiftUI + +struct CreatorChannelDonationTabView: View { + let creatorId: Int + let isOwnCreatorChannel: Bool + @ObservedObject var viewModel: CreatorChannelDonationViewModel + let onTapViewAll: () -> Void + let onTapDonate: () -> Void + + var body: some View { + content + .background(Color.black) + .onAppear { + if viewModel.hasLoaded == false { + viewModel.fetchFirstPage(creatorId: creatorId) + } + } + .sodaToast(isPresented: $viewModel.isShowPopup, message: viewModel.errorMessage, autohideIn: 1) + } + + private var content: some View { + VStack(spacing: 0) { + CreatorChannelDonationCountBar(donationCount: viewModel.donationCount) + + if isEmptyState { + CreatorChannelDonationEmptyView( + showsDonateButton: isOwnCreatorChannel == false, + onTapDonate: onTapDonate + ) + } else { + CreatorChannelDonationRankingSection( + rankings: viewModel.rankings, + onTapViewAll: onTapViewAll + ) + + LazyVStack(spacing: SodaSpacing.s8) { + ForEach(viewModel.donations.indices, id: \.self) { index in + CreatorChannelDonationCard(donation: viewModel.donations[index]) + .padding(.horizontal, SodaSpacing.s14) + .onAppear { + viewModel.fetchNextPageIfNeeded( + creatorId: creatorId, + currentItem: viewModel.donations[index] + ) + } + } + + if viewModel.isLoadingNextPage { + ProgressView() + .padding(.vertical, SodaSpacing.s20) + } + } + .padding(.bottom, SodaSpacing.s20) + } + } + } + + private var isEmptyState: Bool { + guard viewModel.hasLoaded else { return false } + return viewModel.rankings.isEmpty && viewModel.donationCount == 0 + } +} + +struct CreatorChannelDonationTabView_Previews: PreviewProvider { + static var previews: some View { + CreatorChannelDonationTabView( + creatorId: 1, + isOwnCreatorChannel: false, + viewModel: CreatorChannelDonationViewModel(), + onTapViewAll: {}, + onTapDonate: {} + ) + .background(Color.black) + .previewLayout(.sizeThatFits) + } +}