feat(chat-room): 채팅방 이미지 메시지

- 구매한 이미지 터치시 구매한 이미지만 모아볼 수 있는 뷰어 추가
This commit is contained in:
Yu Sung
2025-09-04 07:27:24 +09:00
parent f98f625200
commit b06ffcc97c
3 changed files with 37 additions and 10 deletions

View File

@@ -123,9 +123,13 @@ struct ChatRoomView: View {
message: message, message: message,
characterName: viewModel.characterName characterName: viewModel.characterName
) { ) {
if message.hasAccess {
viewModel.showImageViewer(message.imageUrl)
} else {
viewModel.selectedMessage = message viewModel.selectedMessage = message
viewModel.selectedMessageIndex = index viewModel.selectedMessageIndex = index
} }
}
.id(index) .id(index)
} }
} }
@@ -229,6 +233,12 @@ struct ChatRoomView: View {
} }
} }
} }
.sheet(isPresented: $viewModel.isShowImageViewer) {
ImageViewerView(
images: viewModel.ownedImageUrls,
selectedIndex: $viewModel.selectedImageIndex
)
}
.onAppear { .onAppear {
viewModel.getMemberInfo() viewModel.getMemberInfo()
viewModel.enterRoom(roomId: roomId) viewModel.enterRoom(roomId: roomId)

View File

@@ -33,6 +33,16 @@ final class ChatRoomViewModel: ObservableObject {
@Published var selectedMessage: ServerChatMessage? = nil @Published var selectedMessage: ServerChatMessage? = nil
@Published var selectedMessageIndex: Int = -1 @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 // MARK: - Private
private let userRepository = UserRepository() private let userRepository = UserRepository()
private let repository = ChatRoomRepository() private let repository = ChatRoomRepository()
@@ -281,6 +291,13 @@ final class ChatRoomViewModel: ObservableObject {
.store(in: &subscription) .store(in: &subscription)
} }
func showImageViewer(_ imageUrl: String?) {
if let imageUrl = imageUrl {
selectedImageIndex = ownedImageUrls.firstIndex(of: imageUrl) ?? 0
isShowImageViewer = true
}
}
private func checkQuotaStatus() { private func checkQuotaStatus() {
isLoading = true isLoading = true

View File

@@ -103,11 +103,11 @@ struct AiMessageItemView: View {
.resizable() .resizable()
.scaledToFill() // .scaledToFill() //
if let price = message.price, price > 0, !message.hasAccess {
Color.black.opacity(0.2) Color.black.opacity(0.2)
.frame(width: maxWidth, height: imageHeight) .frame(width: maxWidth, height: imageHeight)
.cornerRadius(30) .cornerRadius(10)
if let price = message.price, price > 0, !message.hasAccess {
VStack(spacing: 18) { VStack(spacing: 18) {
HStack(spacing: 4) { HStack(spacing: 4) {
Image("ic_can") Image("ic_can")
@@ -123,7 +123,7 @@ struct AiMessageItemView: View {
.background(Color(hex: "B5E7FA")) .background(Color(hex: "B5E7FA"))
.cornerRadius(30) .cornerRadius(30)
.overlay { .overlay {
RoundedRectangle(cornerRadius: 30) RoundedRectangle(cornerRadius: 10)
.stroke(lineWidth: 1) .stroke(lineWidth: 1)
.foregroundColor(.button) .foregroundColor(.button)
} }
@@ -133,13 +133,13 @@ struct AiMessageItemView: View {
.foregroundColor(.white) .foregroundColor(.white)
} }
.frame(width: maxWidth, height: imageHeight) .frame(width: maxWidth, height: imageHeight)
.onTapGesture {
purchaseMessage()
}
} }
} }
.frame(width: maxWidth, height: imageHeight) .frame(width: maxWidth, height: imageHeight)
.clipShape(RoundedRectangle(cornerRadius: 10, style: .continuous)) .clipShape(RoundedRectangle(cornerRadius: 10, style: .continuous))
.onTapGesture {
purchaseMessage()
}
} else { } else {
// //
HStack(spacing: 10) { HStack(spacing: 10) {