From b06ffcc97c6312d7609977933cd027903ad005ff Mon Sep 17 00:00:00 2001 From: Yu Sung Date: Thu, 4 Sep 2025 07:27:24 +0900 Subject: [PATCH] =?UTF-8?q?feat(chat-room):=20=EC=B1=84=ED=8C=85=EB=B0=A9?= =?UTF-8?q?=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20=EB=A9=94=EC=8B=9C=EC=A7=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 구매한 이미지 터치시 구매한 이미지만 모아볼 수 있는 뷰어 추가 --- .../Sources/Chat/Talk/Room/ChatRoomView.swift | 14 ++++++++++++-- .../Chat/Talk/Room/ChatRoomViewModel.swift | 17 +++++++++++++++++ .../Talk/Room/Message/AiMessageItemView.swift | 16 ++++++++-------- 3 files changed, 37 insertions(+), 10 deletions(-) diff --git a/SodaLive/Sources/Chat/Talk/Room/ChatRoomView.swift b/SodaLive/Sources/Chat/Talk/Room/ChatRoomView.swift index e3a1f5f..3d57f34 100644 --- a/SodaLive/Sources/Chat/Talk/Room/ChatRoomView.swift +++ b/SodaLive/Sources/Chat/Talk/Room/ChatRoomView.swift @@ -123,8 +123,12 @@ struct ChatRoomView: View { message: message, characterName: viewModel.characterName ) { - viewModel.selectedMessage = message - viewModel.selectedMessageIndex = index + if message.hasAccess { + viewModel.showImageViewer(message.imageUrl) + } else { + viewModel.selectedMessage = message + viewModel.selectedMessageIndex = index + } } .id(index) } @@ -229,6 +233,12 @@ struct ChatRoomView: View { } } } + .sheet(isPresented: $viewModel.isShowImageViewer) { + ImageViewerView( + images: viewModel.ownedImageUrls, + selectedIndex: $viewModel.selectedImageIndex + ) + } .onAppear { viewModel.getMemberInfo() viewModel.enterRoom(roomId: roomId) diff --git a/SodaLive/Sources/Chat/Talk/Room/ChatRoomViewModel.swift b/SodaLive/Sources/Chat/Talk/Room/ChatRoomViewModel.swift index 63cfce0..acc0ce7 100644 --- a/SodaLive/Sources/Chat/Talk/Room/ChatRoomViewModel.swift +++ b/SodaLive/Sources/Chat/Talk/Room/ChatRoomViewModel.swift @@ -33,6 +33,16 @@ final class ChatRoomViewModel: ObservableObject { @Published var selectedMessage: ServerChatMessage? = nil @Published var selectedMessageIndex: Int = -1 + @Published var isShowImageViewer = false + @Published var selectedImageIndex: Int = 0 + + var ownedImageUrls: [String] { + return messages + .filter { $0.hasAccess } + .filter { $0.messageType.lowercased() == "image" && $0.imageUrl != nil && !$0.imageUrl.isNullOrBlank() } + .map { $0.imageUrl! } + } + // MARK: - Private private let userRepository = UserRepository() private let repository = ChatRoomRepository() @@ -281,6 +291,13 @@ final class ChatRoomViewModel: ObservableObject { .store(in: &subscription) } + func showImageViewer(_ imageUrl: String?) { + if let imageUrl = imageUrl { + selectedImageIndex = ownedImageUrls.firstIndex(of: imageUrl) ?? 0 + isShowImageViewer = true + } + } + private func checkQuotaStatus() { isLoading = true diff --git a/SodaLive/Sources/Chat/Talk/Room/Message/AiMessageItemView.swift b/SodaLive/Sources/Chat/Talk/Room/Message/AiMessageItemView.swift index cee4b52..91fee7c 100644 --- a/SodaLive/Sources/Chat/Talk/Room/Message/AiMessageItemView.swift +++ b/SodaLive/Sources/Chat/Talk/Room/Message/AiMessageItemView.swift @@ -103,11 +103,11 @@ struct AiMessageItemView: View { .resizable() .scaledToFill() // 비율 유지하며 프레임을 채움 - Color.black.opacity(0.2) - .frame(width: maxWidth, height: imageHeight) - .cornerRadius(30) - if let price = message.price, price > 0, !message.hasAccess { + Color.black.opacity(0.2) + .frame(width: maxWidth, height: imageHeight) + .cornerRadius(10) + VStack(spacing: 18) { HStack(spacing: 4) { Image("ic_can") @@ -123,7 +123,7 @@ struct AiMessageItemView: View { .background(Color(hex: "B5E7FA")) .cornerRadius(30) .overlay { - RoundedRectangle(cornerRadius: 30) + RoundedRectangle(cornerRadius: 10) .stroke(lineWidth: 1) .foregroundColor(.button) } @@ -133,13 +133,13 @@ struct AiMessageItemView: View { .foregroundColor(.white) } .frame(width: maxWidth, height: imageHeight) - .onTapGesture { - purchaseMessage() - } } } .frame(width: maxWidth, height: imageHeight) .clipShape(RoundedRectangle(cornerRadius: 10, style: .continuous)) + .onTapGesture { + purchaseMessage() + } } else { // 텍스트 메시지 버블 HStack(spacing: 10) {