라이브 후원
- 비밀 후원 기능 추가
This commit is contained in:
		| @@ -111,6 +111,23 @@ final class Agora { | ||||
|         rtmKit?.send(message, toPeer: peerId, completion: completion) | ||||
|     } | ||||
|      | ||||
|     func sendRawMessageToPeer(peerId: String, rawMessage: LiveRoomChatRawMessage, completion: AgoraRtmSendPeerMessageBlock? = nil, fail: (() -> Void)? = nil) { | ||||
|         let encoder = JSONEncoder() | ||||
|         let jsonMessageData = try? encoder.encode(rawMessage) | ||||
|         let option = AgoraRtmSendMessageOptions() | ||||
|         option.enableOfflineMessaging = false | ||||
|         option.enableHistoricalMessaging = false | ||||
|          | ||||
|         if let jsonMessageData = jsonMessageData { | ||||
|             let message = AgoraRtmRawMessage(rawData: jsonMessageData, description: "") | ||||
|             rtmKit?.send(message, toPeer: peerId, sendMessageOptions: option, completion: completion) | ||||
|         } else { | ||||
|             if let fail = fail { | ||||
|                 fail() | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     func mute(_ isMute: Bool) { | ||||
|         rtcEngine?.muteLocalAudioStream(isMute) | ||||
|     } | ||||
|   | ||||
| @@ -323,7 +323,7 @@ struct ContentDetailView: View { | ||||
|                     } | ||||
|                      | ||||
|                     if viewModel.isShowDonationPopup { | ||||
|                         LiveRoomDonationDialogView(isShowing: $viewModel.isShowDonationPopup, isAudioContentDonation: true) { can, comment in | ||||
|                         LiveRoomDonationDialogView(isShowing: $viewModel.isShowDonationPopup, isAudioContentDonation: true) { can, comment, _ in | ||||
|                             viewModel.donation(can: can, comment: comment) | ||||
|                         } | ||||
|                     } | ||||
|   | ||||
| @@ -18,10 +18,11 @@ struct LiveRoomDonationDialogView: View { | ||||
|     @State private var donationMessage = "" | ||||
|     @State private var isShowErrorPopup = false | ||||
|     @State private var errorMessage = "" | ||||
|     @State private var isSecret = false | ||||
|      | ||||
|     @Binding var isShowing: Bool | ||||
|     let isAudioContentDonation: Bool | ||||
|     let onClickDonation: (Int, String) -> Void | ||||
|     let onClickDonation: (Int, String, Bool) -> Void | ||||
|      | ||||
|     @StateObject var keyboardHandler = KeyboardHandler() | ||||
|      | ||||
| @@ -82,6 +83,27 @@ struct LiveRoomDonationDialogView: View { | ||||
|                         .foregroundColor(Color.gray90) | ||||
|                         .padding(.top, 16) | ||||
|                      | ||||
|                     if !isAudioContentDonation { | ||||
|                         HStack(spacing: 0) { | ||||
|                             Spacer() | ||||
|                              | ||||
|                             HStack(spacing: 8) { | ||||
|                                 Image(isSecret ? "btn_select_checked" : "btn_select_normal") | ||||
|                                     .resizable() | ||||
|                                     .frame(width: 20, height: 20) | ||||
|                                  | ||||
|                                 Text("비밀후원") | ||||
|                                     .font(.custom(Font.medium.rawValue, size: 14.7)) | ||||
|                                     .foregroundColor(Color.grayee) | ||||
|                             } | ||||
|                             .onTapGesture { | ||||
|                                 isSecret.toggle() | ||||
|                             } | ||||
|                         } | ||||
|                         .padding(.horizontal, 20) | ||||
|                         .padding(.top, 16) | ||||
|                     } | ||||
|                      | ||||
|                     TextField("몇 캔을 후원할까요?", text: $donationCan) | ||||
|                         .font(.custom(Font.medium.rawValue, size: 13.3)) | ||||
|                         .foregroundColor(Color.grayee) | ||||
| @@ -221,7 +243,7 @@ struct LiveRoomDonationDialogView: View { | ||||
|                             .onTapGesture { | ||||
|                                 if !donationCan.trimmingCharacters(in: .whitespaces).isEmpty, | ||||
|                                    let can = Int(donationCan) { | ||||
|                                     onClickDonation(can, donationMessage) | ||||
|                                     onClickDonation(can, donationMessage, isSecret) | ||||
|                                     isShowing = false | ||||
|                                 } else { | ||||
|                                     errorMessage = "1캔 이상 후원하실 수 있습니다." | ||||
|   | ||||
| @@ -73,8 +73,8 @@ final class LiveRepository { | ||||
|         return api.requestPublisher(.getRoomInfo(roomId: roomId)) | ||||
|     } | ||||
|      | ||||
|     func donation(roomId: Int, can: Int, message: String = "") -> AnyPublisher<Response, MoyaError> { | ||||
|         return api.requestPublisher(.donation(request: LiveRoomDonationRequest(roomId: roomId, can: can, message: message))) | ||||
|     func donation(roomId: Int, can: Int, message: String = "", isSecret: Bool = false) -> AnyPublisher<Response, MoyaError> { | ||||
|         return api.requestPublisher(.donation(request: LiveRoomDonationRequest(roomId: roomId, can: can, message: message, isSecret: isSecret))) | ||||
|     } | ||||
|      | ||||
|     func refundDonation(roomId: Int) -> AnyPublisher<Response, MoyaError> { | ||||
|   | ||||
| @@ -9,7 +9,7 @@ import Foundation | ||||
|  | ||||
| struct LiveRoomChatRawMessage: Codable { | ||||
|     enum LiveRoomChatRawMessageType: String, Codable { | ||||
|         case DONATION, EDIT_ROOM_INFO, SET_MANAGER, TOGGLE_ROULETTE, ROULETTE_DONATION | ||||
|         case DONATION, SECRET_DONATION, EDIT_ROOM_INFO, SET_MANAGER, TOGGLE_ROULETTE, ROULETTE_DONATION | ||||
|     } | ||||
|      | ||||
|     let type: LiveRoomChatRawMessageType | ||||
|   | ||||
| @@ -43,7 +43,7 @@ struct LiveRoomDonationChatItemView: View { | ||||
|                         .font(.system(size: 15)) | ||||
|                         .foregroundColor(Color(hex: "fdca2f")) | ||||
|                      | ||||
|                     Text("을 후원하셨습니다.") | ||||
|                     Text(chatMessage.chat.contains("비밀") ? "을 비밀후원하셨습니다.💰🪙" : "을 후원하셨습니다.💰🪙") | ||||
|                         .font(.system(size: 15)) | ||||
|                         .foregroundColor(.white) | ||||
|                 } | ||||
| @@ -58,6 +58,7 @@ struct LiveRoomDonationChatItemView: View { | ||||
|         .padding(13) | ||||
|         .frame(width: screenSize().width - 86, alignment: .leading) | ||||
|         .background( | ||||
|             chatMessage.chat.contains("비밀") ? Color(hex: "333333").opacity(0.8) : | ||||
|             chatMessage.can >= 10000 ? Color(hex: "c25264").opacity(0.8) : | ||||
|                 chatMessage.can >= 5000 ? Color(hex: "d85e37").opacity(0.8) : | ||||
|                 chatMessage.can >= 1000 ? Color(hex: "d38c38").opacity(0.8) : | ||||
|   | ||||
| @@ -11,5 +11,6 @@ struct LiveRoomDonationRequest: Encodable { | ||||
|     let roomId: Int | ||||
|     let can: Int | ||||
|     let message: String | ||||
|     var isSecret: Bool = false | ||||
|     let container: String = "ios" | ||||
| } | ||||
|   | ||||
| @@ -380,11 +380,11 @@ final class LiveRoomViewModel: NSObject, ObservableObject { | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     func donation(can: Int, message: String = "") { | ||||
|     func donation(can: Int, message: String = "", isSecret: Bool = false) { | ||||
|         if can > 0 { | ||||
|             isLoading = true | ||||
|              | ||||
|             repository.donation(roomId: AppState.shared.roomId, can: can, message: message) | ||||
|             repository.donation(roomId: AppState.shared.roomId, can: can, message: message, isSecret: isSecret) | ||||
|                 .sink { result in | ||||
|                     switch result { | ||||
|                     case .finished: | ||||
| @@ -402,9 +402,16 @@ final class LiveRoomViewModel: NSObject, ObservableObject { | ||||
|                         self.isLoading = false | ||||
|                          | ||||
|                         if decoded.success { | ||||
|                             let rawMessage = "\(can)캔을 후원하셨습니다." | ||||
|                             var rawMessage = "" | ||||
|                              | ||||
|                             if isSecret { | ||||
|                                 rawMessage = "\(can)캔을 비밀후원하셨습니다.💰🪙" | ||||
|                             } else { | ||||
|                                 rawMessage = "\(can)캔을 후원하셨습니다.💰🪙" | ||||
|                             } | ||||
|                              | ||||
|                             let donationRawMessage = LiveRoomChatRawMessage( | ||||
|                                 type: .DONATION, | ||||
|                                 type: isSecret ? .SECRET_DONATION : .DONATION, | ||||
|                                 message: rawMessage, | ||||
|                                 can: can, | ||||
|                                 signature: decoded.data, | ||||
| @@ -414,6 +421,37 @@ final class LiveRoomViewModel: NSObject, ObservableObject { | ||||
|                              | ||||
|                             UserDefaults.set(UserDefaults.int(forKey: .can) - can, forKey: .can) | ||||
|                              | ||||
|                             if isSecret { | ||||
|                                 agora.sendRawMessageToPeer( | ||||
|                                     peerId: String(liveRoomInfo!.creatorId), rawMessage: donationRawMessage, | ||||
|                                     completion: { [unowned self] errorCode in | ||||
|                                         if errorCode == .ok { | ||||
|                                             let (nickname, profileUrl) = self.getUserNicknameAndProfileUrl(accountId: UserDefaults.int(forKey: .userId)) | ||||
|                                             self.messages.append( | ||||
|                                                 LiveRoomDonationChat( | ||||
|                                                     profileUrl: profileUrl, | ||||
|                                                     nickname: nickname, | ||||
|                                                     chat: rawMessage, | ||||
|                                                     can: can, | ||||
|                                                     donationMessage: message | ||||
|                                                 ) | ||||
|                                             ) | ||||
|                                              | ||||
|                                             addSignature(signature: decoded.data) | ||||
|                                              | ||||
|                                             self.messageChangeFlag.toggle() | ||||
|                                             if self.messages.count > 100 { | ||||
|                                                 self.messages.remove(at: 0) | ||||
|                                             } | ||||
|                                         } else { | ||||
|                                             refundDonation() | ||||
|                                         } | ||||
|                                     }, | ||||
|                                     fail: { [unowned self] in | ||||
|                                         refundDonation() | ||||
|                                     } | ||||
|                                 ) | ||||
|                             } else { | ||||
|                                 agora.sendRawMessageToGroup( | ||||
|                                     rawMessage: donationRawMessage, | ||||
|                                     completion: { [unowned self] errorCode in | ||||
| @@ -444,6 +482,7 @@ final class LiveRoomViewModel: NSObject, ObservableObject { | ||||
|                                         refundDonation() | ||||
|                                     } | ||||
|                                 ) | ||||
|                             } | ||||
|                         } else { | ||||
|                             if let message = decoded.message { | ||||
|                                 self.popupContent = message | ||||
| @@ -1858,6 +1897,31 @@ extension LiveRoomViewModel: AgoraRtmDelegate { | ||||
|                         self.startNoChatting() | ||||
|                     } | ||||
|                 } | ||||
|                  | ||||
|                 do { | ||||
|                     let jsonDecoder = JSONDecoder() | ||||
|                     let decoded = try jsonDecoder.decode(LiveRoomChatRawMessage.self, from: rawMessage.rawData) | ||||
|                     let (nickname, profileUrl) = getUserNicknameAndProfileUrl(accountId: Int(peerId)!) | ||||
|                      | ||||
|                     if decoded.type == .SECRET_DONATION { | ||||
|                         self.messages.append( | ||||
|                             LiveRoomDonationChat( | ||||
|                                 profileUrl: profileUrl, | ||||
|                                 nickname: nickname, | ||||
|                                 chat: decoded.message, | ||||
|                                 can: decoded.can, | ||||
|                                 donationMessage: decoded.donationMessage ?? "" | ||||
|                             ) | ||||
|                         ) | ||||
|                          | ||||
|                         if let signature = decoded.signature { | ||||
|                             self.addSignature(signature: signature) | ||||
|                         } else if let imageUrl = decoded.signatureImageUrl { | ||||
|                             self.addSignatureImage(imageUrl: imageUrl) | ||||
|                         } | ||||
|                     } | ||||
|                 } catch { | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|   | ||||
| @@ -203,10 +203,12 @@ struct LiveRoomViewV2: View { | ||||
|                                             ) | ||||
|                                         } | ||||
|                                          | ||||
|                                         if liveRoomInfo.creatorId != UserDefaults.int(forKey: .userId) { | ||||
|                                             LiveRoomRightBottomButton( | ||||
|                                                 imageName: "ic_donation", | ||||
|                                                 onClick: { viewModel.isShowDonationPopup = true } | ||||
|                                             ) | ||||
|                                         } | ||||
|                                          | ||||
|                                         LiveRoomRightBottomButton( | ||||
|                                             imageName: "ic_donation_message_list", | ||||
| @@ -390,8 +392,8 @@ struct LiveRoomViewV2: View { | ||||
|                 } | ||||
|                  | ||||
|                 if viewModel.isShowDonationPopup { | ||||
|                     LiveRoomDonationDialogView(isShowing: $viewModel.isShowDonationPopup, isAudioContentDonation: false) { can, message in | ||||
|                         viewModel.donation(can: can, message: message) | ||||
|                     LiveRoomDonationDialogView(isShowing: $viewModel.isShowDonationPopup, isAudioContentDonation: false) { can, message, isSecret in | ||||
|                         viewModel.donation(can: can, message: message, isSecret: isSecret) | ||||
|                     } | ||||
|                 } | ||||
|                  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Yu Sung
					Yu Sung