Expose draft updates to iOS bridge

This commit is contained in:
Mikhail Kilin
2026-05-21 00:33:05 +03:00
parent 892582df67
commit 3e67e0d1b8
6 changed files with 48 additions and 0 deletions

View File

@@ -18,6 +18,7 @@ public protocol SessionBridge: Sendable {
func react(chatId: Int64, messageId: Int64, reaction: String) async throws -> [Reaction]
func pinnedMessages(chatId: Int64) async throws -> [Message]
func copyPayload(chatId: Int64, messageId: Int64) async throws -> String
func setDraft(chatId: Int64, text: String) async throws
func downloadPhoto(fileId: Int32) async throws -> DownloadedFile
func downloadVoice(fileId: Int32) async throws -> DownloadedFile
}
@@ -204,6 +205,14 @@ public actor FakeSessionBridge: SessionBridge {
return message.text
}
public func setDraft(chatId: Int64, text: String) async throws {
let draft = Draft(chatId: chatId, text: text)
if let index = chats.firstIndex(where: { $0.id == chatId }) {
chats[index].draft = text.isEmpty ? nil : draft
}
events.append(.draftChanged(draft))
}
public func downloadPhoto(fileId: Int32) async throws -> DownloadedFile {
DownloadedFile(fileId: fileId, path: "/tmp/fake-photo-\(fileId).jpg")
}

View File

@@ -105,6 +105,10 @@ public actor UniFfiSessionBridge: SessionBridge {
try handle.copyPayload(chatId: chatId, messageId: messageId)
}
public func setDraft(chatId: Int64, text: String) async throws {
try handle.setDraft(chatId: chatId, text: text)
}
public func downloadPhoto(fileId: Int32) async throws -> DownloadedFile {
try Self.mapDownloadedFile(handle.downloadPhoto(fileId: fileId))
}

View File

@@ -228,6 +228,15 @@ public final class ChatViewModel: ObservableObject {
}
}
public func saveDraft() async {
do {
try await bridge.setDraft(chatId: chat.id, text: composeText)
errorMessage = nil
} catch {
errorMessage = error.localizedDescription
}
}
private func replaceMessage(_ message: Message) {
if let index = messages.firstIndex(where: { $0.id == message.id }) {
messages[index] = message

View File

@@ -100,6 +100,16 @@ struct TeleTuiIOSSmokeTests {
await viewModel.copyPayload(for: viewModel.messages[0])
precondition(viewModel.copiedPayload == "Edited text")
viewModel.composeText = "Draft text"
await viewModel.saveDraft()
let draftEvents = try await bridge.pollEvents()
precondition(draftEvents.contains { event in
if case let .draftChanged(draft) = event {
return draft.chatId == chat.id && draft.text == "Draft text"
}
return false
})
let photo = try await bridge.downloadPhoto(fileId: 100)
let voice = try await bridge.downloadVoice(fileId: 200)
precondition(photo.path == "/tmp/fake-photo-100.jpg")

View File

@@ -1303,6 +1303,13 @@ mod tests {
assert_eq!(pinned[0].text, "Hello from fake TDLib");
assert_eq!(session.download_photo(100).unwrap().path, "/tmp/fake-photo.jpg");
assert_eq!(session.download_voice(200).unwrap().path, "/tmp/fake-voice.ogg");
session
.set_draft(chats[0].id, "Draft from Rust test".to_string())
.unwrap();
assert!(session.poll_events().iter().any(|event| matches!(
event,
IosEvent::DraftChanged { draft } if draft.text == "Draft from Rust test"
)));
let sent = session
.send_message(chats[0].id, "Hi from Swift".to_string(), None)

View File

@@ -69,6 +69,15 @@ struct Smoke {
let voice = try session.downloadVoice(fileId: 200)
require(voice.path == "/tmp/fake-voice.ogg", "expected downloaded voice path")
try session.setDraft(chatId: chat.id, text: "Draft from Swift FFI")
let draftEvents = session.pollEvents()
require(draftEvents.contains {
if case let .draftChanged(draft) = $0 {
return draft.text == "Draft from Swift FFI"
}
return false
}, "expected draftChanged event")
let sent = try session.sendMessage(chatId: chat.id, text: "Hi from Swift FFI", replyToMessageId: nil)
require(sent.text == "Hi from Swift FFI", "expected sent message text")