sodalive-ios/SodaLive/Sources/Live/LiveViewModel.swift

377 lines
16 KiB
Swift

//
// LiveViewModel.swift
// SodaLive
//
// Created by klaus on 2023/08/09.
//
import Foundation
import Combine
final class LiveViewModel: ObservableObject {
private let repository = LiveRepository()
private let eventRepository = EventRepository()
private let liveRecommendRepository = LiveRecommendRepository()
private var subscription = Set<AnyCancellable>()
@Published private(set) var eventBannerItems = [EventItem]()
@Published private(set) var liveNowItems = [GetRoomListResponse]()
@Published private(set) var liveReservationItems = [GetRoomListResponse]()
@Published private(set) var recommendLiveItems: [GetRecommendLiveResponse] = []
@Published private(set) var recommendChannelItems: [GetRecommendChannelResponse] = []
@Published private(set) var followedChannelItems: [GetRecommendChannelResponse] = []
@Published var errorMessage = ""
@Published var isShowPopup = false
@Published var isRefresh = false
@Published var isLoading = false
@Published var isRecommendLiveLoading = false
@Published var isRecommendChannelLoading = false
@Published var isFollowedChannelLoading = false
@Published var paymentDialogTitle = ""
@Published var paymentDialogDesc = ""
@Published var isShowPaymentDialog = false
@Published var paymentDialogConfirmAction = {}
@Published var paymentDialogConfirmTitle = ""
@Published var secretOrPasswordDialogCoin = 0
@Published var passwordDialogConfirmAction: (Int) -> Void = { _ in }
@Published var isShowPasswordDialog = false
@Published var isFollowingList = UserDefaults.bool(forKey: .isFollowedChannel) {
didSet {
UserDefaults.set(isFollowingList, forKey: .isFollowedChannel)
}
}
let paymentDialogCancelTitle = "취소"
var page = 1
var isLast = false
private let pageSize = 10
func hidePopup() {
isShowPaymentDialog = false
isShowPasswordDialog = false
paymentDialogTitle = ""
paymentDialogDesc = ""
paymentDialogConfirmAction = {}
secretOrPasswordDialogCoin = 0
passwordDialogConfirmAction = { _ in }
}
func getSummary() {
getFollowedChannelList()
getRecommendChannelList()
getRecommendLive()
isLoading = true
eventBannerItems.removeAll()
liveNowItems.removeAll()
liveReservationItems.removeAll()
let liveNow = repository.roomList(
request: GetRoomListRequest(
timezone: TimeZone.current.identifier,
dateString: nil,
status: .NOW,
page: 1,
size: 10
)
)
let liveReservation = repository.roomList(
request: GetRoomListRequest(
timezone: TimeZone.current.identifier,
dateString: nil,
status: .RESERVATION,
page: 1,
size: 10
)
)
let event = eventRepository.getEvents()
Publishers
.CombineLatest3(liveNow, liveReservation, event)
.sink { result in
switch result {
case .finished:
DEBUG_LOG("finish")
case .failure(let error):
ERROR_LOG(error.localizedDescription)
}
} receiveValue: { (now, reservation, eventResponse) in
let nowData = now.data
let reservationData = reservation.data
let eventData = eventResponse.data
let jsonDecoder = JSONDecoder()
do {
let nowDecoded = try jsonDecoder.decode(ApiResponse<[GetRoomListResponse]>.self, from: nowData)
if let data = nowDecoded.data, nowDecoded.success {
self.liveNowItems.removeAll()
self.liveNowItems.append(contentsOf: data)
} else {
if let message = nowDecoded.message {
self.errorMessage = message
} else {
self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
}
self.isShowPopup = true
}
} catch {
self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
self.isShowPopup = true
}
do {
let reservationDecoded = try jsonDecoder.decode(ApiResponse<[GetRoomListResponse]>.self, from: reservationData)
if let data = reservationDecoded.data, reservationDecoded.success {
self.liveReservationItems.removeAll()
self.liveReservationItems.append(contentsOf: data)
} else {
if let message = reservationDecoded.message {
self.errorMessage = message
} else {
self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
}
self.isShowPopup = true
}
} catch {
self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
self.isShowPopup = true
}
do {
let eventDecoded = try jsonDecoder.decode(ApiResponse<GetEventResponse>.self, from: eventData)
if let data = eventDecoded.data, eventDecoded.success {
self.eventBannerItems.removeAll()
self.eventBannerItems.append(contentsOf: data.eventList)
} else {
if let message = eventDecoded.message {
self.errorMessage = message
} else {
self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
}
self.isShowPopup = true
}
} catch {
self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
self.isShowPopup = true
}
self.isLoading = false
self.isRefresh = false
}
.store(in: &subscription)
}
func enterRoom(roomId: Int, onSuccess: (() -> Void)? = nil, password: Int? = nil) {
isLoading = true
let request = EnterOrQuitLiveRoomRequest(roomId: roomId, password: password)
repository.enterRoom(request: request)
.sink { result in
switch result {
case .finished:
DEBUG_LOG("finish")
case .failure(let error):
ERROR_LOG(error.localizedDescription)
}
} receiveValue: { [unowned self] response in
self.isLoading = false
let responseData = response.data
do {
let jsonDecoder = JSONDecoder()
let decoded = try jsonDecoder.decode(ApiResponseWithoutData.self, from: responseData)
if decoded.success {
AppState.shared.roomId = roomId
if let onSuccess = onSuccess {
onSuccess()
} else {
if roomId > 0 {
AppState.shared.isShowPlayer = true
}
}
} 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)
}
func startLive(roomId: Int) {
isLoading = true
repository.startLive(roomId: roomId)
.sink { result in
switch result {
case .finished:
DEBUG_LOG("finish")
case .failure(let error):
ERROR_LOG(error.localizedDescription)
}
} receiveValue: { [unowned self] response in
self.isLoading = false
let responseData = response.data
do {
let jsonDecoder = JSONDecoder()
let decoded = try jsonDecoder.decode(ApiResponseWithoutData.self, from: responseData)
if decoded.success {
getSummary()
enterRoom(roomId: roomId)
} 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)
}
private func getFollowedChannelList() {
followedChannelItems.removeAll()
isFollowedChannelLoading = true
liveRecommendRepository.getFollowedChannelList()
.sink { result in
switch result {
case .finished:
DEBUG_LOG("finish")
case .failure(let error):
ERROR_LOG(error.localizedDescription)
}
} receiveValue: { [unowned self] response in
self.isFollowedChannelLoading = false
let responseData = response.data
do {
let jsonDecoder = JSONDecoder()
let decoded = try jsonDecoder.decode(ApiResponse<[GetRecommendChannelResponse]>.self, from: responseData)
if let data = decoded.data, decoded.success {
self.followedChannelItems.append(contentsOf: data)
} 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)
}
private func getRecommendChannelList() {
recommendChannelItems.removeAll()
isRecommendChannelLoading = true
liveRecommendRepository.getRecommendChannelList()
.sink { result in
switch result {
case .finished:
DEBUG_LOG("finish")
case .failure(let error):
ERROR_LOG(error.localizedDescription)
}
} receiveValue: { [unowned self] response in
self.isRecommendChannelLoading = false
let responseData = response.data
do {
let jsonDecoder = JSONDecoder()
let decoded = try jsonDecoder.decode(ApiResponse<[GetRecommendChannelResponse]>.self, from: responseData)
if let data = decoded.data, decoded.success {
self.recommendChannelItems.append(contentsOf: data)
} 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)
}
private func getRecommendLive() {
recommendLiveItems.removeAll()
isRecommendLiveLoading = true
liveRecommendRepository.getRecommendLive()
.sink { result in
switch result {
case .finished:
DEBUG_LOG("finish")
case .failure(let error):
ERROR_LOG(error.localizedDescription)
}
} receiveValue: { [unowned self] response in
self.isRecommendLiveLoading = false
let responseData = response.data
do {
let jsonDecoder = JSONDecoder()
let decoded = try jsonDecoder.decode(ApiResponse<[GetRecommendLiveResponse]>.self, from: responseData)
if let data = decoded.data, decoded.success {
self.recommendLiveItems.append(contentsOf: data)
} 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)
}
}