// // VoiceMessageViewModel.swift // SodaLive // // Created by klaus on 2023/08/10. // import Foundation import Moya import Combine final class VoiceMessageViewModel: ObservableObject { private let repository = MessageRepository() private var subscription = Set() @Published var items = [VoiceMessageItem]() @Published var errorMessage = "" @Published var isShowPopup = false @Published var isLoading = false @Published var saveMessagePrice = 0 @Published var isShowSavePopup = false @Published var currentFilter: MessageFilterTab = .receive { didSet { refresh() } } @Published var recipientNickname: String = "" @Published var recipientId = 0 @Published var sendText = "메시지 보내기" @Published var selectedMessageId = -1 @Published var openPlayerItemIndex = -1 @Published var recordMode = RecordMode.RECORD enum RecordMode { case RECORD, PLAY } private var isLast = false private var page = 1 private let size = 10 func refresh() { page = 1 isLast = false selectedMessageId = -1 openPlayerItemIndex = -1 loadMessage() } func loadMessage() { switch currentFilter { case .receive: getReceivedVoiceMessage() case .sent: getSentVoiceMessage() case .keep: getKeepVoiceMessage() } } func deleteMessage() { if selectedMessageId <= 0 { errorMessage = "메시지를 삭제하지 못했습니다\n잠시 후 다시 시도해 주세요." isShowPopup = true return } isLoading = true repository.deleteMessage(messageId: selectedMessageId) .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 { self.errorMessage = "삭제되었습니다." self.isShowPopup = true self.refresh() } else { if let message = decoded.message { self.errorMessage = message self.isShowPopup = true } else { self.errorMessage = "메시지를 보관하지 못했습니다.\n잠시 후 다시 시도해 주세요." } self.isShowPopup = true } } catch { self.errorMessage = "메시지를 보관하지 못했습니다.\n잠시 후 다시 시도해 주세요." self.isShowPopup = true } } .store(in: &subscription) } func keepVoiceMessage() { if selectedMessageId <= 0 { errorMessage = "메시지를 저장하지 못했습니다\n잠시 후 다시 시도해 주세요." isShowPopup = true return } isLoading = true repository.keepVoiceMessage(messageId: selectedMessageId) .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 { self.errorMessage = "보관되었습니다." self.isShowPopup = true self.refresh() } else { if let message = decoded.message { self.errorMessage = message self.isShowPopup = true } else { self.errorMessage = "메시지를 보관하지 못했습니다.\n잠시 후 다시 시도해 주세요." } self.isShowPopup = true } } catch { self.errorMessage = "메시지를 보관하지 못했습니다.\n잠시 후 다시 시도해 주세요." self.isShowPopup = true } } .store(in: &subscription) } func keepTextMessage() { if selectedMessageId <= 0 { errorMessage = "메시지를 저장하지 못했습니다\n잠시 후 다시 시도해 주세요." isShowPopup = true return } isLoading = true repository.keepTextMessage(messageId: selectedMessageId) .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 { self.errorMessage = "보관되었습니다." self.isShowPopup = true self.refresh() } else { if let message = decoded.message { self.errorMessage = message self.isShowPopup = true } else { self.errorMessage = "메시지를 보관하지 못했습니다.\n잠시 후 다시 시도해 주세요." } self.isShowPopup = true } } catch { self.errorMessage = "메시지를 보관하지 못했습니다.\n잠시 후 다시 시도해 주세요." self.isShowPopup = true } } .store(in: &subscription) } func write(soundData: Data, onSuccess: @escaping () -> Void) { if recipientId <= 0 { errorMessage = "받는 사람을 선택해 주세요." isShowPopup = true return } if !isLoading { isLoading = true let request = SendVoiceMessageRequest(recipientId: recipientId) var multipartData = [MultipartFormData]() let encoder = JSONEncoder() encoder.outputFormatting = .withoutEscapingSlashes let jsonData = try? encoder.encode(request) if let jsonData = jsonData { multipartData.append( MultipartFormData( provider: .data(soundData), name: "voiceMessageFile", fileName: "\(UUID().uuidString)_\(Date().timeIntervalSince1970 * 1000).m4a", mimeType: "audio/m4a") ) multipartData.append(MultipartFormData(provider: .data(jsonData), name: "request")) repository.sendVoiceMessage(parameters: multipartData) .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 { onSuccess() self.errorMessage = "메시지 전송이 완료되었습니다." self.isShowPopup = true DispatchQueue.main.asyncAfter(deadline: .now() + 1) { AppState.shared.back() } } else { if let message = decoded.message { self.errorMessage = message } else { self.errorMessage = "음성메시지를 전송하지 못했습니다.\n다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다." } self.isShowPopup = true } } catch { self.errorMessage = "음성메시지를 전송하지 못했습니다.\n다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다." self.isShowPopup = true } } .store(in: &subscription) } else { self.errorMessage = "음성메시지를 전송하지 못했습니다.\n다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다." self.isShowPopup = true self.isLoading = false } } } private func getReceivedVoiceMessage() { if page == 1 { items.removeAll() } isLoading = true repository .getReceivedVoiceMessage(page: page, size: size) .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(ApiResponse.self, from: responseData) if let data = decoded.data, decoded.success { if data.items.count <= 0 { self.isLast = true } else { self.items.append(contentsOf: data.items) self.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) } private func getSentVoiceMessage() { if page == 1 { items.removeAll() } isLoading = true repository .getSentVoiceMessage(page: page, size: size) .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(ApiResponse.self, from: responseData) if let data = decoded.data, decoded.success { if data.items.count <= 0 { self.isLast = true } else { self.items.append(contentsOf: data.items) self.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) } private func getKeepVoiceMessage() { if page == 1 { items.removeAll() } isLoading = true repository .getKeepVoiceMessage(page: page, size: size) .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(ApiResponse.self, from: responseData) if let data = decoded.data, decoded.success { if data.items.count <= 0 { self.isLast = true } else { self.items.append(contentsOf: data.items) self.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) } }