sodalive-ios/SodaLive/Sources/Message/Voice/VoiceMessageViewModel.swift

429 lines
16 KiB
Swift

//
// 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<AnyCancellable>()
@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() {
if !isLast {
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<GetVoiceMessageResponse>.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<GetVoiceMessageResponse>.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<GetVoiceMessageResponse>.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)
}
}