- 룰렛 돌리기 API 연동

- 룰렛 돌린 결과 전송
This commit is contained in:
Yu Sung
2023-12-07 04:29:03 +09:00
parent 5682adf967
commit 0af16ac000
8 changed files with 333 additions and 3 deletions

View File

@@ -21,6 +21,7 @@ final class LiveRoomViewModel: NSObject, ObservableObject {
private let repository = LiveRepository()
private let userRepository = UserRepository()
private let reportRepository = ReportRepository()
private let rouletteRepository = RouletteRepository()
private var subscription = Set<AnyCancellable>()
@Published var chatMessage = ""
@@ -136,6 +137,14 @@ final class LiveRoomViewModel: NSObject, ObservableObject {
@Published var isShowRouletteSettings = false
@Published var isShowRoulettePreview = false
@Published var roulettePreview: RoulettePreview? = nil
@Published var isShowRoulette = false
@Published var rouletteItems = [RouletteItem]()
@Published var rouletteSelectedItem = ""
var rouletteCan = 0
var timer: DispatchSourceTimer?
func setOriginOffset(_ offset: CGFloat) {
@@ -1342,6 +1351,196 @@ final class LiveRoomViewModel: NSObject, ObservableObject {
)
)
}
func showRoulette() {
if let liveRoomInfo = liveRoomInfo, !isLoading {
isLoading = true
rouletteRepository.getRoulette(creatorId: liveRoomInfo.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<GetRouletteResponse>.self, from: responseData)
if let data = decoded.data, decoded.success, !data.items.isEmpty {
self.roulettePreview = RoulettePreview(can: data.can, items: calculatePercentages(options: data.items))
self.isShowRoulettePreview = true
} else {
if let message = decoded.message {
self.errorMessage = message
} else {
self.errorMessage = "룰렛을 사용할 수 없습니다. 다시 시도해 주세요."
}
self.isShowErrorPopup = true
}
} catch {
self.errorMessage = "룰렛을 사용할 수 없습니다. 다시 시도해 주세요."
self.isShowErrorPopup = true
}
}
.store(in: &subscription)
}
}
func spinRoulette() {
if !isLoading {
isLoading = true
rouletteRepository.spinRoulette(request: SpinRouletteRequest(roomId: AppState.shared.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(ApiResponse<GetRouletteResponse>.self, from: responseData)
if let data = decoded.data, decoded.success, !data.items.isEmpty {
UserDefaults.set(UserDefaults.int(forKey: .can) - data.can, forKey: .can)
randomSelectRouletteItem(can: data.can, items: data.items)
} else {
if let message = decoded.message {
self.errorMessage = message
} else {
self.errorMessage = "룰렛을 사용할 수 없습니다. 다시 시도해 주세요."
}
self.isShowErrorPopup = true
}
} catch {
self.errorMessage = "룰렛을 사용할 수 없습니다. 다시 시도해 주세요."
self.isShowErrorPopup = true
}
}
.store(in: &subscription)
}
}
func sendRouletteDonation() {
let rawMessage = rouletteSelectedItem
let rouletteRawMessage = LiveRoomChatRawMessage(
type: .ROULETTE_DONATION,
message: rawMessage,
can: rouletteCan,
donationMessage: ""
)
self.agora.sendRawMessageToGroup(
rawMessage: rouletteRawMessage,
completion: { [unowned self] errorCode in
if errorCode == .errorOk {
let (nickname, profileUrl) = self.getUserNicknameAndProfileUrl(accountId: UserDefaults.int(forKey: .userId))
self.messages.append(
LiveRoomRouletteDonationChat(
profileUrl: profileUrl,
nickname: nickname,
rouletteResult: rawMessage
)
)
totalDonationCan += rouletteCan
self.rouletteItems.removeAll()
self.rouletteSelectedItem = ""
self.rouletteCan = 0
self.messageChangeFlag.toggle()
if self.messages.count > 100 {
self.messages.remove(at: 0)
}
} else {
self.refundRouletteDonation()
}
},
fail: { [unowned self] in
self.refundRouletteDonation()
}
)
}
private func calculatePercentages(options: [RouletteItem]) -> [RoulettePreviewItem] {
let totalWeight = options.reduce(0) { $0 + $1.weight }
let updatedOptions = options.map { option in
RoulettePreviewItem(title: option.title, percent: "\(Int(Float(option.weight) / Float(totalWeight) * Float(100)))%")
}
return updatedOptions
}
private func randomSelectRouletteItem(can: Int, items: [RouletteItem]) {
isLoading = true
var rouletteItems = [String]()
items.forEach {
var i = 1
while (i < $0.weight * 10) {
rouletteItems.append($0.title)
i += 1
}
}
isLoading = false
self.rouletteItems.removeAll()
self.rouletteItems.append(contentsOf: items)
self.rouletteSelectedItem = rouletteItems[Int(arc4random_uniform(UInt32(rouletteItems.count)))]
self.rouletteCan = can
sendRouletteDonation()
}
private func refundRouletteDonation() {
isLoading = true
rouletteRepository.refundRouletteDonation(roomId: AppState.shared.roomId)
.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
do {
let jsonDecoder = JSONDecoder()
let decoded = try jsonDecoder.decode(ApiResponseWithoutData.self, from: responseData)
self.isLoading = false
if decoded.success {
self.popupContent = "후원에 실패했습니다.\n다시 후원해주세요.\n계속 같은 문제가 발생할 경우 고객센터로 문의 주시기 바랍니다."
self.isShowPopup = true
} else {
if let message = decoded.message {
self.errorMessage = message
} else {
self.popupContent = "후원에 실패한 캔이 환불되지 않았습니다\n고객센터로 문의해주세요."
}
self.isShowPopup = true
}
} catch {
self.isLoading = false
self.popupContent = "후원에 실패한 캔이 환불되지 않았습니다\n고객센터로 문의해주세요."
self.isShowPopup = true
}
}
.store(in: &subscription)
}
}
extension LiveRoomViewModel: AgoraRtcEngineDelegate {