// // 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) { RefreshableScrollView( refreshing: $viewModel.isRefresh, action: { viewModel.getSummary() } ) { VStack(spacing: 0) { if viewModel.recommendLiveItems.count > 0 { SectionRecommendLiveView(items: viewModel.recommendLiveItems) .padding(.top, 13.3) } if let url = URL(string: "https://blog.naver.com/yozmlive"), UIApplication.shared.canOpenURL(url) { Image("img_how_to_use") .resizable() .frame( width: screenSize().width, height: (200 * screenSize().width) / 1080 ) .padding(.top, 21.3) .onTapGesture { UIApplication.shared.open(url) } } if viewModel.recommendChannelItems.count > 0 { SectionRecommendChannelView( items: viewModel.isFollowingList ? viewModel.followedChannelItems : viewModel.recommendChannelItems, isFollowingList: $viewModel.isFollowingList ) .padding(.top, 40) } if viewModel.liveNowItems.count > 0 { SectionLiveNowView( items: viewModel.liveNowItems, onClickParticipant: {_ in}, onTapCreateLive: { AppState.shared.setAppStep(step: .createLive(timeSettingMode: .NOW, onSuccess: onCreateSuccess)) } ) .padding(.top, 40) } 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 ) .padding(.top, 40) } if viewModel.liveReservationItems.count > 0 { 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)) } ) .padding(.top, 40) } } } .frame(width: geo.size.width, height: geo.size.height) .onAppear { viewModel.getSummary() } if !appState.isShowPlayer { 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.secretOrPasswordDialogCoin, 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: "9970ff")) .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() } }