import SwiftUI struct MainHomeFollowingView: View { let onTapLive: (Int) -> Void let onTapCreator: (Int) -> Void let onTapContent: (Int) -> Void let onTapLogin: () -> Void let onTapFollowingAll: () -> Void let onTapChatTab: () -> Void let onTapChatRoom: (Int, String) -> Void let onTapSchedule: (CreatorActivityType, Int) -> Void let onTapCommunityPost: (Int) -> Void @StateObject private var viewModel = MainHomeFollowingViewModel() init( onTapLive: @escaping (Int) -> Void = { _ in }, onTapCreator: @escaping (Int) -> Void = { _ in }, onTapContent: @escaping (Int) -> Void = { _ in }, onTapLogin: @escaping () -> Void = {}, onTapFollowingAll: @escaping () -> Void = {}, onTapChatTab: @escaping () -> Void = {}, onTapChatRoom: @escaping (Int, String) -> Void = { _, _ in }, onTapSchedule: @escaping (CreatorActivityType, Int) -> Void = { _, _ in }, onTapCommunityPost: @escaping (Int) -> Void = { _ in } ) { self.onTapLive = onTapLive self.onTapCreator = onTapCreator self.onTapContent = onTapContent self.onTapLogin = onTapLogin self.onTapFollowingAll = onTapFollowingAll self.onTapChatTab = onTapChatTab self.onTapChatRoom = onTapChatRoom self.onTapSchedule = onTapSchedule self.onTapCommunityPost = onTapCommunityPost } var body: some View { content .onAppear { if viewModel.hasLoaded == false { viewModel.fetchFollowing() } } } @ViewBuilder private var content: some View { if viewModel.isLoading && !viewModel.hasLoaded { loadingContent } else if viewModel.isLoginRequired { emptyContent( message: I18n.HomeFollowing.loginRequiredMessage, loginAction: onTapLogin ) } else if !viewModel.message.isEmpty { emptyContent(message: viewModel.message) } else if let response = viewModel.response { ScrollView(.vertical, showsIndicators: false) { VStack(spacing: 0) { if !response.followingCreators.isEmpty { MainHomeFollowingCreatorSection( followingCreators: response.followingCreators, onTapCreator: onTapCreator, onTapAll: onTapFollowingAll ) } if !response.onAirLives.isEmpty { MainHomeFollowingLiveSection( onAirLives: response.onAirLives, onTapLive: onTapLive ) .padding(.top, 28) } if !response.recentChats.isEmpty { MainHomeFollowingChatSection( recentChats: response.recentChats, onTapTitle: onTapChatTab, onTapChatRoom: onTapChatRoom ) .padding(.top, 48) } if !response.monthlySchedules.isEmpty { MainHomeFollowingScheduleSection( monthlySchedules: response.monthlySchedules, onTapSchedule: onTapSchedule ) .padding(.top, 48) } if !response.recentNews.isEmpty { MainHomeFollowingNewsSection( recentNews: response.recentNews, onTapCreator: onTapCreator, onTapContent: onTapContent, onTapCommunityPost: onTapCommunityPost ) .padding(.top, 48) } } .padding(.bottom, SodaSpacing.s20) } .background(Color.black) .refreshable { await viewModel.refresh() } } else { emptyContent(message: I18n.HomeFollowing.emptyStateMessage) } } private var loadingContent: some View { GeometryReader { geometry in ScrollView(showsIndicators: false) { ProgressView() .tint(.white) .frame(maxWidth: .infinity) .frame(minHeight: geometry.size.height) } .background(Color.black) .refreshable { await viewModel.refresh() } } } private func emptyContent(message: String, loginAction: (() -> Void)? = nil) -> some View { GeometryReader { geometry in ScrollView(showsIndicators: false) { MainHomeFollowingEmptyStateView( message: message, loginAction: loginAction ) .frame(minHeight: geometry.size.height) } .refreshable { await viewModel.refresh() } } } } struct MainHomeFollowingView_Previews: PreviewProvider { static var previews: some View { MainHomeFollowingView() } }