// // LiveView.swift // SodaLive // // Created by klaus on 2023/08/09. // import SwiftUI import RefreshableScrollView struct LiveView: View { @StateObject var viewModel = LiveViewModel() @StateObject var appState = AppState.shared var body: some View { ZStack { Color.black.ignoresSafeArea() GeometryReader { geo in ZStack(alignment: .bottomTrailing) { ScrollView(.vertical, showsIndicators: false) { LazyVStack(spacing: 40) { if viewModel.recommendLiveItems.count > 0 { SectionRecommendLiveView(items: viewModel.recommendLiveItems) .padding(.top, 13.3) } if viewModel.recommendChannelItems.count > 0 { SectionRecommendChannelView( items: viewModel.isFollowingList ? viewModel.followedChannelItems : viewModel.recommendChannelItems, isFollowingList: $viewModel.isFollowingList ) } SectionLiveNowView( items: viewModel.liveNowItems, onClickParticipant: { viewModel.enterLiveRoom(roomId: $0) }, onTapCreateLive: { AppState.shared.setAppStep(step: .createLive(timeSettingMode: .NOW, onSuccess: onCreateSuccess)) }, onClickRefresh: { viewModel.getSummary() } ) if viewModel.eventBannerItems.count > 0 { SectionEventBannerView(items: viewModel.eventBannerItems) .frame( width: viewModel.eventBannerItems.count > 0 ? screenSize().width : 0, height: viewModel.eventBannerItems.count > 0 ? screenSize().width * 300 / 1000 : 0, alignment: .center ) } if viewModel.communityPostItems.count > 0 { SectionCommunityPostView(items: viewModel.communityPostItems) } SectionLiveReservationView( items: viewModel.liveReservationItems, onClickCancel: { viewModel.getSummary() }, onClickStart: { roomId in processStart(roomId: roomId) }, onClickReservation: { roomId in viewModel.reservationLiveRoom(roomId: roomId) }, onTapCreateLive: { AppState.shared.setAppStep(step: .createLive(timeSettingMode: .RESERVATION, onSuccess: onCreateSuccess)) } ) } } .frame(width: geo.size.width, height: geo.size.height) .onAppear { viewModel.getSummary() } if !appState.isShowPlayer && UserDefaults.string(forKey: .role) == MemberRole.CREATOR.rawValue { Image("btn_make_live") .padding(.trailing, 16) .padding(.bottom, 16) .onTapGesture { AppState.shared.setAppStep(step: .createLive(timeSettingMode: .NOW, onSuccess: onCreateSuccess)) } } } } if viewModel.isShowPaymentDialog { SodaDialog( title: viewModel.paymentDialogTitle, desc: viewModel.paymentDialogDesc, confirmButtonTitle: viewModel.paymentDialogConfirmTitle, confirmButtonAction: viewModel.paymentDialogConfirmAction, cancelButtonTitle: viewModel.paymentDialogCancelTitle, cancelButtonAction: viewModel.hidePopup ) } if viewModel.isShowPasswordDialog { LiveRoomPasswordDialog( isShowing: $viewModel.isShowPasswordDialog, can: viewModel.secretOrPasswordDialogCan, confirmAction: viewModel.passwordDialogConfirmAction ) } if viewModel.isFollowedChannelLoading || viewModel.isRecommendChannelLoading || viewModel.isRecommendLiveLoading || viewModel.isLoading { LoadingView() } } .popup(isPresented: $viewModel.isShowPopup, type: .toast, position: .top, autohideIn: 2) { GeometryReader { geo in HStack { Spacer() Text(viewModel.errorMessage) .padding(.vertical, 13.3) .padding(.horizontal, 6.7) .frame(width: geo.size.width - 66.7, alignment: .center) .font(.custom(Font.medium.rawValue, size: 12)) .background(Color(hex: "3bb9f1")) .foregroundColor(Color.white) .multilineTextAlignment(.leading) .fixedSize(horizontal: false, vertical: true) .cornerRadius(20) .padding(.top, 66.7) Spacer() } } } } private func onCreateSuccess(response: CreateLiveRoomResponse) { viewModel.getSummary() if let _ = response.channelName { viewModel.enterRoom(roomId: response.id!) } } private func processStart(roomId: Int) { viewModel.startLive(roomId: roomId) } } struct LiveView_Previews: PreviewProvider { static var previews: some View { LiveView() } }