// // AuditionRoleDetailViewModel.swift // SodaLive // // Created by klaus on 1/6/25. // import Foundation import Combine final class AuditionRoleDetailViewModel: ObservableObject { private let repository = AuditionRepository() private var subscription = Set() @Published var errorMessage = "" @Published var isShowPopup = false @Published var isLoading = false @Published var totalCount = 0 @Published var applicantList = [GetAuditionRoleApplicantItem]() @Published var name = "보이스온" @Published var auditionRoleDetail: GetAuditionRoleDetailResponse? = nil @Published var sortType = AuditionApplicantSortType.NEWEST { didSet { page = 1 isLast = false getAuditionRoleDetail() } } var page = 1 var isLast = false private var pageSize = 10 var auditionRoleId = -1 { didSet { if auditionRoleId > 0 { getAuditionRoleDetail() } else { onFailure() } } } var onFailure: () -> Void = {} func getAuditionRoleDetail() { isLoading = true let auditionRoleDetail = repository.getAuditionRoleDetail(auditionRoleId: auditionRoleId) let auditionApplicantList = repository.getAuditionApplicantList(auditionRoleId: auditionRoleId, sortType: sortType, page: page, size: pageSize) Publishers .CombineLatest(auditionRoleDetail, auditionApplicantList) .sink { result in switch result { case .finished: DEBUG_LOG("finish") case .failure(let error): ERROR_LOG(error.localizedDescription) } } receiveValue: { [unowned self] (roleDetailResponse, applicantListResponse) in let roleDetail = roleDetailResponse.data let applicantList = applicantListResponse.data let jsonDecoder = JSONDecoder() do { let roleDetailDecoded = try jsonDecoder.decode(ApiResponse.self, from: roleDetail) if let data = roleDetailDecoded.data, roleDetailDecoded.success { self.name = data.name self.auditionRoleDetail = data } else { if let message = roleDetailDecoded.message { self.errorMessage = message } else { self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다." } self.isShowPopup = true } } catch { self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다." self.isShowPopup = true } do { let applicantListDecoded = try jsonDecoder.decode(ApiResponse.self, from: applicantList) if let data = applicantListDecoded.data, applicantListDecoded.success { self.totalCount = data.totalCount self.applicantList.append(contentsOf: data.items) if data.items.isEmpty { isLast = true } else { page += 1 } } else { if let message = applicantListDecoded.message { self.errorMessage = message } else { self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다." } self.isShowPopup = true DispatchQueue.main.asyncAfter(deadline: .now() + 2) { self.onFailure() } } } catch { self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다." self.isShowPopup = true DispatchQueue.main.asyncAfter(deadline: .now() + 2) { self.onFailure() } } self.isLoading = false } .store(in: &subscription) } func getAuditionApplicantList() { if !isLoading && !isLast { isLoading = true repository.getAuditionApplicantList(auditionRoleId: auditionRoleId, sortType: sortType, page: page, size: pageSize) .sink { result in switch result { case .finished: DEBUG_LOG("finish") case .failure(let error): ERROR_LOG(error.localizedDescription) } } receiveValue: { [unowned self] response in let responseData = response.data self.isLoading = false do { let jsonDecoder = JSONDecoder() let decoded = try jsonDecoder.decode(ApiResponse.self, from: responseData) if let data = decoded.data, decoded.success { self.totalCount = data.totalCount self.applicantList.append(contentsOf: data.items) if data.items.isEmpty { isLast = true } else { page += 1 } } else { if let message = decoded.message { self.errorMessage = message } else { self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다." } self.isShowPopup = true } } catch { self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다." self.isShowPopup = true } } .store(in: &subscription) } } }