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) {