- 룰렛 돌리기 API 연동
- 룰렛 돌린 결과 전송
This commit is contained in:
@@ -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 {
|
||||
|
Reference in New Issue
Block a user