Able to send message on watchOS

This commit is contained in:
2025-10-31 00:39:06 +08:00
parent dc6af6d9e5
commit ab90d244b5

View File

@@ -261,6 +261,8 @@ struct ChatRoomView: View {
@State private var error: Error? @State private var error: Error?
@State private var wsState: WebSocketState = .disconnected // New state for WebSocket status @State private var wsState: WebSocketState = .disconnected // New state for WebSocket status
@State private var hasLoadedMessages = false // Track if messages have been loaded @State private var hasLoadedMessages = false // Track if messages have been loaded
@State private var messageText = "" // Text input for sending messages
@State private var isSending = false // Track sending state
@State private var cancellables = Set<AnyCancellable>() // For managing subscriptions @State private var cancellables = Set<AnyCancellable>() // For managing subscriptions
@@ -316,7 +318,7 @@ struct ChatRoomView: View {
scrollView.scrollTo(lastMessage.id, anchor: .bottom) scrollView.scrollTo(lastMessage.id, anchor: .bottom)
} }
} }
.onChange(of: messages.count) { _ in .onChange(of: messages.count) { _, _ in
// Scroll to bottom when new messages arrive // Scroll to bottom when new messages arrive
if let lastMessage = messages.last { if let lastMessage = messages.last {
withAnimation { withAnimation {
@@ -326,6 +328,35 @@ struct ChatRoomView: View {
} }
} }
} }
// Message input area
HStack(spacing: 8) {
TextField("Send message...", text: $messageText)
.font(.system(size: 14))
.disabled(isSending)
.frame(height: 40)
Button {
Task {
await sendMessage()
}
} label: {
if isSending {
ProgressView()
.frame(width: 20, height: 20)
} else {
Image(systemName: "arrow.up.circle.fill")
.resizable()
.frame(width: 20, height: 20)
}
}
.labelStyle(.iconOnly)
.buttonStyle(.glass)
.disabled(messageText.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty || isSending)
.frame(width: 40, height: 40)
}
.padding(.horizontal)
.padding(.top, 8)
} }
.navigationTitle(room.name ?? "Chat") .navigationTitle(room.name ?? "Chat")
.task { .task {
@@ -380,6 +411,66 @@ struct ChatRoomView: View {
isLoading = false isLoading = false
} }
private func sendMessage() async {
let content = messageText.trimmingCharacters(in: .whitespacesAndNewlines)
guard !content.isEmpty,
let token = appState.token,
let serverUrl = appState.serverUrl else { return }
isSending = true
do {
// Generate a nonce for the message
let nonce = UUID().uuidString
// Prepare the request data
let messageData: [String: Any] = [
"content": content,
"attachments_id": [], // Empty for now, can be extended for attachments
"meta": [:],
"nonce": nonce
]
// Create the URL
guard let url = URL(string: "\(serverUrl)/sphere/chat/\(room.id)/messages") else {
throw URLError(.badURL)
}
// Create the request
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization")
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpBody = try JSONSerialization.data(withJSONObject: messageData, options: [])
// Send the request
let (data, response) = try await URLSession.shared.data(for: request)
guard let httpResponse = response as? HTTPURLResponse,
(200...299).contains(httpResponse.statusCode) else {
throw URLError(.badServerResponse)
}
// Parse the response to get the sent message
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .iso8601
decoder.keyDecodingStrategy = .convertFromSnakeCase
let sentMessage = try decoder.decode(SnChatMessage.self, from: data)
// Add the message to the local list
messages.append(sentMessage)
// Clear the input
messageText = ""
} catch {
print("[watchOS] Error sending message: \(error.localizedDescription)")
// Could show an error alert here
}
isSending = false
}
private func sendReadReceipt() { private func sendReadReceipt() {
let data: [String: Any] = ["chat_room_id": room.id] let data: [String: Any] = ["chat_room_id": room.id]
let packet: [String: Any] = ["type": "messages.read", "data": data, "endpoint": "sphere"] let packet: [String: Any] = ["type": "messages.read", "data": data, "endpoint": "sphere"]