// // LiveNowAllView.swift // SodaLive // // Created by klaus on 2023/08/14. // import SwiftUI import RefreshableScrollView import Bootpay import BootpayUI struct LiveNowAllView: View { @StateObject var viewModel = LiveViewModel() @StateObject var liveAllViewModel = LiveAllViewModel() @StateObject var mypageViewModel = MyPageViewModel() let spacing: CGFloat = 16 @AppStorage("token") private var token: String = UserDefaults.string(forKey: UserDefaultsKey.token) @AppStorage("auth") private var auth: Bool = UserDefaults.bool(forKey: UserDefaultsKey.auth) @State private var isShowAuthView = false @State private var isShowAuthConfirmView = false @State private var pendingAction: (() -> Void)? = nil @State private var payload = Payload() var columns: [GridItem] { [ GridItem(.flexible(), spacing: spacing, alignment: .top), GridItem(.flexible(), spacing: spacing, alignment: .top) ] } let onClickParticipant: (Int) -> Void var body: some View { BaseView(isLoading: $viewModel.isLoading) { ZStack { GeometryReader { proxy in VStack(spacing: 0) { DetailNavigationBar(title: I18n.LiveNow.allTitle) RefreshableScrollView( refreshing: $viewModel.isRefresh, action: { viewModel.page = 1 viewModel.isLast = false viewModel.getLiveNowList() }, content: { let itemWidth = (proxy.size.width - (spacing * 3)) / 2 LazyVGrid(columns: columns, spacing: spacing) { ForEach(0.. 0 { Rectangle() .foregroundColor(Color.black.opacity(0)) .frame(width: screenSize().width, height: 15.3) } } .edgesIgnoringSafeArea(.bottom) } if liveAllViewModel.isShowLiveDetail { LiveDetailView( roomId: liveAllViewModel.selectedRoomId, onClickParticipant: { AppState.shared.isShowPlayer = false onClickParticipant(liveAllViewModel.selectedRoomId) }, onClickReservation: {}, onClickStart: {}, onClickCancel: {}, onClickClose: { withAnimation { liveAllViewModel.isShowLiveDetail = false } } ) } if isShowAuthConfirmView { SodaDialog( title: "본인인증", desc: "청소년 보호를 위해\n본인인증을 완료한\n성인만 라이브 입장이 가능합니다.\n" + "라이브 입장을 위해\n본인인증을 진행해 주세요.", confirmButtonTitle: "본인인증 하러가기", confirmButtonAction: { isShowAuthConfirmView = false isShowAuthView = true }, cancelButtonTitle: "취소", cancelButtonAction: { isShowAuthConfirmView = false pendingAction = nil }, textAlignment: .center ) } } } .onAppear { payload.applicationId = BOOTPAY_APP_ID payload.price = 0 payload.pg = "다날" payload.method = "본인인증" payload.orderName = "본인인증" payload.authenticationId = "\(UserDefaults.string(forKey: .nickname))__\(String(NSTimeIntervalSince1970))" viewModel.getLiveNowList() } .fullScreenCover(isPresented: $isShowAuthView) { BootpayUI(payload: payload, requestType: BootpayRequest.TYPE_AUTHENTICATION) .onConfirm { _ in true } .onCancel { _ in isShowAuthView = false } .onError { _ in AppState.shared.errorMessage = "본인인증 중 오류가 발생했습니다." AppState.shared.isShowErrorPopup = true isShowAuthView = false } .onDone { DEBUG_LOG("onDone: \($0)") mypageViewModel.authVerify($0) { auth = true isShowAuthView = false if let action = pendingAction { pendingAction = nil action() } } } .onClose { isShowAuthView = false } } } private func handleLiveNowItemTap(roomId: Int, isAdult: Bool) { let trimmed = token.trimmingCharacters(in: .whitespacesAndNewlines) guard !trimmed.isEmpty else { AppState.shared.setAppStep(step: .login) return } if isAdult && auth == false { pendingAction = { openLiveDetail(roomId: roomId) } isShowAuthConfirmView = true return } openLiveDetail(roomId: roomId) } private func openLiveDetail(roomId: Int) { liveAllViewModel.selectedRoomId = roomId withAnimation { liveAllViewModel.isShowLiveDetail = true } } }