327 lines
11 KiB
Swift
327 lines
11 KiB
Swift
//
|
|
// RouletteSettingsViewModel.swift
|
|
// SodaLive
|
|
//
|
|
// Created by klaus on 2023/12/05.
|
|
//
|
|
|
|
import Foundation
|
|
import Combine
|
|
|
|
enum SelectedRoulette: Int {
|
|
case ROULETTE_1 = 0
|
|
case ROULETTE_2 = 1
|
|
case ROULETTE_3 = 2
|
|
}
|
|
|
|
final class RouletteSettingsViewModel: ObservableObject {
|
|
private let repository = RouletteRepository()
|
|
private var subscription = Set<AnyCancellable>()
|
|
|
|
@Published var isLoading = false
|
|
|
|
@Published var errorMessage = ""
|
|
@Published var isShowErrorPopup = false
|
|
|
|
@Published var canText = "" {
|
|
didSet {
|
|
can = Int(canText) ?? 0
|
|
}
|
|
}
|
|
@Published var isActive = false
|
|
@Published var options = [RouletteOption]()
|
|
|
|
@Published var isShowPreview = false {
|
|
didSet {
|
|
if !isShowPreview {
|
|
previewData = nil
|
|
}
|
|
}
|
|
}
|
|
@Published var previewData: RoulettePreview? = nil
|
|
|
|
@Published var selectedRoulette: SelectedRoulette? = nil
|
|
|
|
var can = 0
|
|
private var rouletteId = 0
|
|
@Published var rouletteList = [GetNewRouletteResponse]()
|
|
|
|
func addOption() {
|
|
if (options.count >= 10) {
|
|
return
|
|
}
|
|
options.append(RouletteOption(title: "", percentage: ""))
|
|
}
|
|
|
|
func deleteOption(index: Int) {
|
|
options.remove(at: index)
|
|
}
|
|
|
|
private func removeAllAndAddOptions(options: [RouletteOption]) {
|
|
self.options.removeAll()
|
|
self.options.append(contentsOf: options)
|
|
}
|
|
|
|
func getAllRoulette(creatorId: Int) {
|
|
self.isLoading = true
|
|
repository.getAllRoulette(creatorId: creatorId)
|
|
.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<[GetNewRouletteResponse]>.self, from: responseData)
|
|
|
|
if let data = decoded.data, decoded.success {
|
|
rouletteList.removeAll()
|
|
rouletteList.append(contentsOf: data)
|
|
selectRoulette(selectedRoulette: .ROULETTE_1)
|
|
} else {
|
|
self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
|
self.isShowErrorPopup = true
|
|
}
|
|
} catch {
|
|
self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
|
self.isShowErrorPopup = true
|
|
}
|
|
}
|
|
.store(in: &subscription)
|
|
}
|
|
|
|
func onClickPreview() {
|
|
isLoading = true
|
|
|
|
var items = [RoulettePreviewItem]()
|
|
for option in options {
|
|
if option.title.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
|
|
isLoading = false
|
|
errorMessage = "옵션은 빈칸일 수 없습니다."
|
|
isShowErrorPopup = true
|
|
return
|
|
}
|
|
|
|
items.append(RoulettePreviewItem(title: option.title, percent: "\(option.percentage)%"))
|
|
}
|
|
|
|
previewData = RoulettePreview(id: 0, can: self.can, items: items)
|
|
isLoading = false
|
|
isShowPreview = true
|
|
}
|
|
|
|
func createOrUpdateRoulette(onSuccess: @escaping (Bool, String) -> Void) {
|
|
if !isLoading {
|
|
isLoading = true
|
|
|
|
if validationOptions() {
|
|
if rouletteId > 0 {
|
|
updateRoulette(onSuccess: onSuccess)
|
|
} else {
|
|
createRoulette(onSuccess: onSuccess)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private func validationOptions() -> Bool {
|
|
var totalPercentage = Float(0)
|
|
|
|
for option in options {
|
|
if option.title.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
|
|
isLoading = false
|
|
errorMessage = "옵션은 빈칸일 수 없습니다."
|
|
isShowErrorPopup = true
|
|
return false
|
|
}
|
|
|
|
if let percentage = Float(option.percentage) {
|
|
totalPercentage += percentage
|
|
}
|
|
}
|
|
|
|
if totalPercentage != Float(100) {
|
|
isLoading = false
|
|
errorMessage = "확률이 100%가 아닙니다"
|
|
isShowErrorPopup = true
|
|
return false
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
private func createRoulette(onSuccess: @escaping (Bool, String) -> Void) {
|
|
var items = [RouletteItem]()
|
|
for option in options {
|
|
if let percentage = Float(option.percentage) {
|
|
items.append(RouletteItem(title: option.title, percentage: percentage))
|
|
}
|
|
}
|
|
|
|
let selectedRouletteTitle: String
|
|
let successMessage: String
|
|
|
|
switch (self.selectedRoulette) {
|
|
case .ROULETTE_2:
|
|
selectedRouletteTitle = "룰렛 2"
|
|
|
|
case .ROULETTE_3:
|
|
selectedRouletteTitle = "룰렛 3"
|
|
|
|
default:
|
|
selectedRouletteTitle = "룰렛 1"
|
|
}
|
|
|
|
if isActive {
|
|
successMessage = "\(selectedRouletteTitle)로 설정하였습니다."
|
|
} else {
|
|
successMessage = "\(selectedRouletteTitle)을 설정했습니다."
|
|
}
|
|
|
|
let request = CreateRouletteRequest(can: can, isActive: isActive, items: items)
|
|
repository.createRoulette(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 {
|
|
onSuccess(isActive, successMessage)
|
|
} else {
|
|
self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
|
self.isShowErrorPopup = true
|
|
}
|
|
} catch {
|
|
self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
|
self.isShowErrorPopup = true
|
|
}
|
|
}
|
|
.store(in: &subscription)
|
|
}
|
|
|
|
private func updateRoulette(onSuccess: @escaping (Bool, String) -> Void) {
|
|
var items = [RouletteItem]()
|
|
for option in options {
|
|
if let percentage = Float(option.percentage) {
|
|
items.append(RouletteItem(title: option.title, percentage: percentage))
|
|
}
|
|
}
|
|
|
|
let selectedRoulette = rouletteList[selectedRoulette!.rawValue]
|
|
if selectedRoulette.isActive == isActive && selectedRoulette.can == can && selectedRoulette.items == items {
|
|
self.errorMessage = "변동사항이 없습니다."
|
|
self.isShowErrorPopup = true
|
|
self.isLoading = false
|
|
return
|
|
}
|
|
|
|
let selectedRouletteTitle: String
|
|
let successMessage: String
|
|
|
|
switch (self.selectedRoulette) {
|
|
case .ROULETTE_2:
|
|
selectedRouletteTitle = "룰렛 2"
|
|
|
|
case .ROULETTE_3:
|
|
selectedRouletteTitle = "룰렛 3"
|
|
|
|
default:
|
|
selectedRouletteTitle = "룰렛 1"
|
|
}
|
|
|
|
if isActive {
|
|
successMessage = "\(selectedRouletteTitle)을 활성화 했습니다."
|
|
} else {
|
|
successMessage = "\(selectedRouletteTitle)을 비활성화 했습니다."
|
|
}
|
|
|
|
let request = UpdateRouletteRequest(id: rouletteId, can: can, isActive: isActive, items: items)
|
|
repository.updateRoulette(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 {
|
|
onSuccess(isActive, successMessage)
|
|
} else {
|
|
self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
|
self.isShowErrorPopup = true
|
|
}
|
|
} catch {
|
|
self.errorMessage = "다시 시도해 주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
|
|
self.isShowErrorPopup = true
|
|
}
|
|
}
|
|
.store(in: &subscription)
|
|
}
|
|
|
|
func selectRoulette(selectedRoulette: SelectedRoulette) {
|
|
if rouletteList.isEmpty && (selectedRoulette == .ROULETTE_2 || selectedRoulette == .ROULETTE_3) {
|
|
errorMessage = "룰렛 1을 먼저 설정하세요"
|
|
isShowErrorPopup = true
|
|
return
|
|
}
|
|
|
|
if rouletteList.count == 1 && selectedRoulette == .ROULETTE_3 {
|
|
errorMessage = "룰렛 1과 룰렛 2를 먼저 설정하세요"
|
|
isShowErrorPopup = true
|
|
return
|
|
}
|
|
|
|
if self.selectedRoulette != selectedRoulette {
|
|
self.selectedRoulette = selectedRoulette
|
|
|
|
if rouletteList.count > selectedRoulette.rawValue {
|
|
let roulette = rouletteList[selectedRoulette.rawValue]
|
|
if roulette.can > 0 {
|
|
self.canText = String(roulette.can)
|
|
} else {
|
|
self.canText = ""
|
|
}
|
|
|
|
self.rouletteId = roulette.id
|
|
self.isActive = roulette.isActive
|
|
let options = roulette.items.map {
|
|
RouletteOption(title: $0.title, percentage: String($0.percentage))
|
|
}
|
|
removeAllAndAddOptions(options: options)
|
|
} else {
|
|
self.canText = ""
|
|
self.isActive = false
|
|
self.rouletteId = 0
|
|
|
|
options.removeAll()
|
|
self.addOption()
|
|
self.addOption()
|
|
}
|
|
}
|
|
}
|
|
}
|