parent
81846f7f7b
commit
534a6e737e
|
@ -111,6 +111,23 @@ final class Agora {
|
||||||
rtmKit?.send(message, toPeer: peerId, completion: completion)
|
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) {
|
func mute(_ isMute: Bool) {
|
||||||
rtcEngine?.muteLocalAudioStream(isMute)
|
rtcEngine?.muteLocalAudioStream(isMute)
|
||||||
}
|
}
|
||||||
|
|
|
@ -323,7 +323,7 @@ struct ContentDetailView: View {
|
||||||
}
|
}
|
||||||
|
|
||||||
if viewModel.isShowDonationPopup {
|
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)
|
viewModel.donation(can: can, comment: comment)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,10 +18,11 @@ struct LiveRoomDonationDialogView: View {
|
||||||
@State private var donationMessage = ""
|
@State private var donationMessage = ""
|
||||||
@State private var isShowErrorPopup = false
|
@State private var isShowErrorPopup = false
|
||||||
@State private var errorMessage = ""
|
@State private var errorMessage = ""
|
||||||
|
@State private var isSecret = false
|
||||||
|
|
||||||
@Binding var isShowing: Bool
|
@Binding var isShowing: Bool
|
||||||
let isAudioContentDonation: Bool
|
let isAudioContentDonation: Bool
|
||||||
let onClickDonation: (Int, String) -> Void
|
let onClickDonation: (Int, String, Bool) -> Void
|
||||||
|
|
||||||
@StateObject var keyboardHandler = KeyboardHandler()
|
@StateObject var keyboardHandler = KeyboardHandler()
|
||||||
|
|
||||||
|
@ -82,6 +83,27 @@ struct LiveRoomDonationDialogView: View {
|
||||||
.foregroundColor(Color.gray90)
|
.foregroundColor(Color.gray90)
|
||||||
.padding(.top, 16)
|
.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)
|
TextField("몇 캔을 후원할까요?", text: $donationCan)
|
||||||
.font(.custom(Font.medium.rawValue, size: 13.3))
|
.font(.custom(Font.medium.rawValue, size: 13.3))
|
||||||
.foregroundColor(Color.grayee)
|
.foregroundColor(Color.grayee)
|
||||||
|
@ -221,7 +243,7 @@ struct LiveRoomDonationDialogView: View {
|
||||||
.onTapGesture {
|
.onTapGesture {
|
||||||
if !donationCan.trimmingCharacters(in: .whitespaces).isEmpty,
|
if !donationCan.trimmingCharacters(in: .whitespaces).isEmpty,
|
||||||
let can = Int(donationCan) {
|
let can = Int(donationCan) {
|
||||||
onClickDonation(can, donationMessage)
|
onClickDonation(can, donationMessage, isSecret)
|
||||||
isShowing = false
|
isShowing = false
|
||||||
} else {
|
} else {
|
||||||
errorMessage = "1캔 이상 후원하실 수 있습니다."
|
errorMessage = "1캔 이상 후원하실 수 있습니다."
|
||||||
|
|
|
@ -73,8 +73,8 @@ final class LiveRepository {
|
||||||
return api.requestPublisher(.getRoomInfo(roomId: roomId))
|
return api.requestPublisher(.getRoomInfo(roomId: roomId))
|
||||||
}
|
}
|
||||||
|
|
||||||
func donation(roomId: Int, can: Int, message: String = "") -> AnyPublisher<Response, MoyaError> {
|
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)))
|
return api.requestPublisher(.donation(request: LiveRoomDonationRequest(roomId: roomId, can: can, message: message, isSecret: isSecret)))
|
||||||
}
|
}
|
||||||
|
|
||||||
func refundDonation(roomId: Int) -> AnyPublisher<Response, MoyaError> {
|
func refundDonation(roomId: Int) -> AnyPublisher<Response, MoyaError> {
|
||||||
|
|
|
@ -9,7 +9,7 @@ import Foundation
|
||||||
|
|
||||||
struct LiveRoomChatRawMessage: Codable {
|
struct LiveRoomChatRawMessage: Codable {
|
||||||
enum LiveRoomChatRawMessageType: String, 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
|
let type: LiveRoomChatRawMessageType
|
||||||
|
|
|
@ -43,7 +43,7 @@ struct LiveRoomDonationChatItemView: View {
|
||||||
.font(.system(size: 15))
|
.font(.system(size: 15))
|
||||||
.foregroundColor(Color(hex: "fdca2f"))
|
.foregroundColor(Color(hex: "fdca2f"))
|
||||||
|
|
||||||
Text("을 후원하셨습니다.")
|
Text(chatMessage.chat.contains("비밀") ? "을 비밀후원하셨습니다.💰🪙" : "을 후원하셨습니다.💰🪙")
|
||||||
.font(.system(size: 15))
|
.font(.system(size: 15))
|
||||||
.foregroundColor(.white)
|
.foregroundColor(.white)
|
||||||
}
|
}
|
||||||
|
@ -58,6 +58,7 @@ struct LiveRoomDonationChatItemView: View {
|
||||||
.padding(13)
|
.padding(13)
|
||||||
.frame(width: screenSize().width - 86, alignment: .leading)
|
.frame(width: screenSize().width - 86, alignment: .leading)
|
||||||
.background(
|
.background(
|
||||||
|
chatMessage.chat.contains("비밀") ? Color(hex: "333333").opacity(0.8) :
|
||||||
chatMessage.can >= 10000 ? Color(hex: "c25264").opacity(0.8) :
|
chatMessage.can >= 10000 ? Color(hex: "c25264").opacity(0.8) :
|
||||||
chatMessage.can >= 5000 ? Color(hex: "d85e37").opacity(0.8) :
|
chatMessage.can >= 5000 ? Color(hex: "d85e37").opacity(0.8) :
|
||||||
chatMessage.can >= 1000 ? Color(hex: "d38c38").opacity(0.8) :
|
chatMessage.can >= 1000 ? Color(hex: "d38c38").opacity(0.8) :
|
||||||
|
|
|
@ -11,5 +11,6 @@ struct LiveRoomDonationRequest: Encodable {
|
||||||
let roomId: Int
|
let roomId: Int
|
||||||
let can: Int
|
let can: Int
|
||||||
let message: String
|
let message: String
|
||||||
|
var isSecret: Bool = false
|
||||||
let container: String = "ios"
|
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 {
|
if can > 0 {
|
||||||
isLoading = true
|
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
|
.sink { result in
|
||||||
switch result {
|
switch result {
|
||||||
case .finished:
|
case .finished:
|
||||||
|
@ -402,9 +402,16 @@ final class LiveRoomViewModel: NSObject, ObservableObject {
|
||||||
self.isLoading = false
|
self.isLoading = false
|
||||||
|
|
||||||
if decoded.success {
|
if decoded.success {
|
||||||
let rawMessage = "\(can)캔을 후원하셨습니다."
|
var rawMessage = ""
|
||||||
|
|
||||||
|
if isSecret {
|
||||||
|
rawMessage = "\(can)캔을 비밀후원하셨습니다.💰🪙"
|
||||||
|
} else {
|
||||||
|
rawMessage = "\(can)캔을 후원하셨습니다.💰🪙"
|
||||||
|
}
|
||||||
|
|
||||||
let donationRawMessage = LiveRoomChatRawMessage(
|
let donationRawMessage = LiveRoomChatRawMessage(
|
||||||
type: .DONATION,
|
type: isSecret ? .SECRET_DONATION : .DONATION,
|
||||||
message: rawMessage,
|
message: rawMessage,
|
||||||
can: can,
|
can: can,
|
||||||
signature: decoded.data,
|
signature: decoded.data,
|
||||||
|
@ -414,6 +421,37 @@ final class LiveRoomViewModel: NSObject, ObservableObject {
|
||||||
|
|
||||||
UserDefaults.set(UserDefaults.int(forKey: .can) - can, forKey: .can)
|
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(
|
agora.sendRawMessageToGroup(
|
||||||
rawMessage: donationRawMessage,
|
rawMessage: donationRawMessage,
|
||||||
completion: { [unowned self] errorCode in
|
completion: { [unowned self] errorCode in
|
||||||
|
@ -444,6 +482,7 @@ final class LiveRoomViewModel: NSObject, ObservableObject {
|
||||||
refundDonation()
|
refundDonation()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if let message = decoded.message {
|
if let message = decoded.message {
|
||||||
self.popupContent = message
|
self.popupContent = message
|
||||||
|
@ -1858,6 +1897,31 @@ extension LiveRoomViewModel: AgoraRtmDelegate {
|
||||||
self.startNoChatting()
|
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(
|
LiveRoomRightBottomButton(
|
||||||
imageName: "ic_donation",
|
imageName: "ic_donation",
|
||||||
onClick: { viewModel.isShowDonationPopup = true }
|
onClick: { viewModel.isShowDonationPopup = true }
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
|
||||||
LiveRoomRightBottomButton(
|
LiveRoomRightBottomButton(
|
||||||
imageName: "ic_donation_message_list",
|
imageName: "ic_donation_message_list",
|
||||||
|
@ -390,8 +392,8 @@ struct LiveRoomViewV2: View {
|
||||||
}
|
}
|
||||||
|
|
||||||
if viewModel.isShowDonationPopup {
|
if viewModel.isShowDonationPopup {
|
||||||
LiveRoomDonationDialogView(isShowing: $viewModel.isShowDonationPopup, isAudioContentDonation: false) { can, message in
|
LiveRoomDonationDialogView(isShowing: $viewModel.isShowDonationPopup, isAudioContentDonation: false) { can, message, isSecret in
|
||||||
viewModel.donation(can: can, message: message)
|
viewModel.donation(can: can, message: message, isSecret: isSecret)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue