feat(chat-room): 채팅방 이미지 메시지
- 구매한 이미지 터치시 구매한 이미지만 모아볼 수 있는 뷰어 추가
This commit is contained in:
		@@ -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)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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) {
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user