feat(live-room): 하트를 길게(2초)간 누르면 표시 되는 왕하트(100캔) 추가, 애니메이션 제외

This commit is contained in:
Yu Sung
2025-11-05 12:20:01 +09:00
parent d8c27ae225
commit 0a59c6f575
6 changed files with 46 additions and 11 deletions

View File

@@ -121,8 +121,15 @@ final class LiveRepository {
return api.requestPublisher(.getAllMenuPreset(creatorId: creatorId)) return api.requestPublisher(.getAllMenuPreset(creatorId: creatorId))
} }
func likeHeart(roomId: Int) -> AnyPublisher<Response, MoyaError> { func likeHeart(roomId: Int, heartCount: Int = 1) -> AnyPublisher<Response, MoyaError> {
return api.requestPublisher(.likeHeart(request: LiveRoomLikeHeartRequest(roomId: roomId))) return api.requestPublisher(
.likeHeart(
request: LiveRoomLikeHeartRequest(
roomId: roomId,
heartCount: heartCount
)
)
)
} }
func getTotalHeartCount(roomId: Int) -> AnyPublisher<Response, MoyaError> { func getTotalHeartCount(roomId: Int) -> AnyPublisher<Response, MoyaError> {

View File

@@ -9,7 +9,8 @@ import Foundation
struct LiveRoomChatRawMessage: Codable { struct LiveRoomChatRawMessage: Codable {
enum LiveRoomChatRawMessageType: String, Codable { enum LiveRoomChatRawMessageType: String, Codable {
case DONATION, SECRET_DONATION, EDIT_ROOM_INFO, SET_MANAGER, TOGGLE_ROULETTE, ROULETTE_DONATION, HEART_DONATION case DONATION, SECRET_DONATION, EDIT_ROOM_INFO, SET_MANAGER, TOGGLE_ROULETTE, ROULETTE_DONATION
case HEART_DONATION, BIG_HEART_DONATION
} }
let type: LiveRoomChatRawMessageType let type: LiveRoomChatRawMessageType

View File

@@ -1897,12 +1897,15 @@ final class LiveRoomViewModel: NSObject, ObservableObject {
} }
} }
func likeHeart() { func likeHeart(
messageType: LiveRoomChatRawMessage.LiveRoomChatRawMessageType = .HEART_DONATION,
heartCount: Int = 1
) {
if isAvailableLikeHeart { if isAvailableLikeHeart {
if !isLoadingLikeHeart { if !isLoadingLikeHeart {
isLoadingLikeHeart = true isLoadingLikeHeart = true
repository.likeHeart(roomId: AppState.shared.roomId) repository.likeHeart(roomId: AppState.shared.roomId, heartCount: heartCount)
.sink { result in .sink { result in
switch result { switch result {
case .finished: case .finished:
@@ -1919,12 +1922,12 @@ final class LiveRoomViewModel: NSObject, ObservableObject {
let decoded = try jsonDecoder.decode(ApiResponseWithoutData.self, from: responseData) let decoded = try jsonDecoder.decode(ApiResponseWithoutData.self, from: responseData)
if decoded.success { if decoded.success {
UserDefaults.set(UserDefaults.int(forKey: .can) - 1, forKey: .can) UserDefaults.set(UserDefaults.int(forKey: .can) - heartCount, forKey: .can)
let donationRawMessage = LiveRoomChatRawMessage( let donationRawMessage = LiveRoomChatRawMessage(
type: .HEART_DONATION, type: messageType,
message: "", message: "",
can: 1, can: heartCount,
donationMessage: nil donationMessage: nil
) )
@@ -1933,7 +1936,7 @@ final class LiveRoomViewModel: NSObject, ObservableObject {
let (nickname, _) = self.getUserNicknameAndProfileUrl(accountId: UserDefaults.int(forKey: .userId)) let (nickname, _) = self.getUserNicknameAndProfileUrl(accountId: UserDefaults.int(forKey: .userId))
self.addHeartMessage(nickname: nickname) self.addHeartMessage(nickname: nickname)
totalHeartCount += 1 totalHeartCount += heartCount
addHeart() addHeart()
self.invalidateChat() self.invalidateChat()
@@ -2255,6 +2258,10 @@ extension LiveRoomViewModel: AgoraRtmClientDelegate {
self.addHeartMessage(nickname: nickname) self.addHeartMessage(nickname: nickname)
self.totalHeartCount += decoded.can self.totalHeartCount += decoded.can
self.addHeart() self.addHeart()
} else if decoded.type == .BIG_HEART_DONATION {
self.addHeartMessage(nickname: nickname)
self.totalHeartCount += decoded.can
self.addHeart()
} }
} catch { } catch {
} }

View File

@@ -11,6 +11,20 @@ struct LiveRoomRightBottomButton: View {
let imageName: String let imageName: String
let onClick: () -> Void let onClick: () -> Void
let onLongPress: (() -> Void)?
let longPressDuration: Double
init(
imageName: String,
onClick: @escaping () -> Void,
onLongPress: (() -> Void)? = nil,
longPressDuration: Double = 2.0
) {
self.imageName = imageName
self.onClick = onClick
self.onLongPress = onLongPress
self.longPressDuration = longPressDuration
}
var body: some View { var body: some View {
Image(imageName) Image(imageName)
@@ -20,6 +34,9 @@ struct LiveRoomRightBottomButton: View {
.background(Color.gray52.opacity(0.6)) .background(Color.gray52.opacity(0.6))
.cornerRadius(10) .cornerRadius(10)
.onTapGesture { onClick() } .onTapGesture { onClick() }
.onLongPressGesture(minimumDuration: longPressDuration) {
onLongPress?()
}
} }
} }
@@ -27,7 +44,8 @@ struct LiveRoomRightBottomButton_Previews: PreviewProvider {
static var previews: some View { static var previews: some View {
LiveRoomRightBottomButton( LiveRoomRightBottomButton(
imageName: "ic_donation", imageName: "ic_donation",
onClick: {} onClick: {},
onLongPress: {}
) )
} }
} }

View File

@@ -7,5 +7,6 @@
struct LiveRoomLikeHeartRequest: Encodable { struct LiveRoomLikeHeartRequest: Encodable {
let roomId: Int let roomId: Int
let heartCount: Int
let container: String = "ios" let container: String = "ios"
} }

View File

@@ -253,7 +253,8 @@ struct LiveRoomViewV2: View {
if liveRoomInfo.creatorId != UserDefaults.int(forKey: .userId) { if liveRoomInfo.creatorId != UserDefaults.int(forKey: .userId) {
LiveRoomRightBottomButton( LiveRoomRightBottomButton(
imageName: "ic_heart_pink", imageName: "ic_heart_pink",
onClick: { viewModel.likeHeart() } onClick: { viewModel.likeHeart() },
onLongPress: { viewModel.likeHeart(messageType: .BIG_HEART_DONATION, heartCount: 100) }
) )
} }
} }