Wire iOS media downloads through session bridge
This commit is contained in:
@@ -18,6 +18,8 @@ public protocol SessionBridge: Sendable {
|
|||||||
func react(chatId: Int64, messageId: Int64, reaction: String) async throws -> [Reaction]
|
func react(chatId: Int64, messageId: Int64, reaction: String) async throws -> [Reaction]
|
||||||
func pinnedMessages(chatId: Int64) async throws -> [Message]
|
func pinnedMessages(chatId: Int64) async throws -> [Message]
|
||||||
func copyPayload(chatId: Int64, messageId: Int64) async throws -> String
|
func copyPayload(chatId: Int64, messageId: Int64) async throws -> String
|
||||||
|
func downloadPhoto(fileId: Int32) async throws -> DownloadedFile
|
||||||
|
func downloadVoice(fileId: Int32) async throws -> DownloadedFile
|
||||||
}
|
}
|
||||||
|
|
||||||
public actor FakeSessionBridge: SessionBridge {
|
public actor FakeSessionBridge: SessionBridge {
|
||||||
@@ -201,6 +203,14 @@ public actor FakeSessionBridge: SessionBridge {
|
|||||||
}
|
}
|
||||||
return message.text
|
return message.text
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func downloadPhoto(fileId: Int32) async throws -> DownloadedFile {
|
||||||
|
DownloadedFile(fileId: fileId, path: "/tmp/fake-photo-\(fileId).jpg")
|
||||||
|
}
|
||||||
|
|
||||||
|
public func downloadVoice(fileId: Int32) async throws -> DownloadedFile {
|
||||||
|
DownloadedFile(fileId: fileId, path: "/tmp/fake-voice-\(fileId).ogg")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum FakeBridgeError: LocalizedError {
|
public enum FakeBridgeError: LocalizedError {
|
||||||
|
|||||||
@@ -153,6 +153,16 @@ public struct Profile: Equatable, Sendable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public struct DownloadedFile: Equatable, Sendable {
|
||||||
|
public var fileId: Int32
|
||||||
|
public var path: String
|
||||||
|
|
||||||
|
public init(fileId: Int32, path: String) {
|
||||||
|
self.fileId = fileId
|
||||||
|
self.path = path
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public enum SessionEvent: Equatable, Sendable {
|
public enum SessionEvent: Equatable, Sendable {
|
||||||
case authChanged(AuthState)
|
case authChanged(AuthState)
|
||||||
case chatListChanged([ChatSummary])
|
case chatListChanged([ChatSummary])
|
||||||
|
|||||||
@@ -105,6 +105,14 @@ public actor UniFfiSessionBridge: SessionBridge {
|
|||||||
try handle.copyPayload(chatId: chatId, messageId: messageId)
|
try handle.copyPayload(chatId: chatId, messageId: messageId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func downloadPhoto(fileId: Int32) async throws -> DownloadedFile {
|
||||||
|
try Self.mapDownloadedFile(handle.downloadPhoto(fileId: fileId))
|
||||||
|
}
|
||||||
|
|
||||||
|
public func downloadVoice(fileId: Int32) async throws -> DownloadedFile {
|
||||||
|
try Self.mapDownloadedFile(handle.downloadVoice(fileId: fileId))
|
||||||
|
}
|
||||||
|
|
||||||
private static func mapAuthState(_ state: IosAuthState) -> AuthState {
|
private static func mapAuthState(_ state: IosAuthState) -> AuthState {
|
||||||
switch state {
|
switch state {
|
||||||
case .waitTdlibParameters:
|
case .waitTdlibParameters:
|
||||||
@@ -192,6 +200,10 @@ public actor UniFfiSessionBridge: SessionBridge {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static func mapDownloadedFile(_ file: IosDownloadedFile) -> DownloadedFile {
|
||||||
|
DownloadedFile(fileId: file.fileId, path: file.path)
|
||||||
|
}
|
||||||
|
|
||||||
private static func mapEvent(_ event: IosEvent) -> SessionEvent {
|
private static func mapEvent(_ event: IosEvent) -> SessionEvent {
|
||||||
switch event {
|
switch event {
|
||||||
case let .authChanged(state):
|
case let .authChanged(state):
|
||||||
|
|||||||
@@ -100,6 +100,11 @@ struct TeleTuiIOSSmokeTests {
|
|||||||
await viewModel.copyPayload(for: viewModel.messages[0])
|
await viewModel.copyPayload(for: viewModel.messages[0])
|
||||||
precondition(viewModel.copiedPayload == "Edited text")
|
precondition(viewModel.copiedPayload == "Edited text")
|
||||||
|
|
||||||
|
let photo = try await bridge.downloadPhoto(fileId: 100)
|
||||||
|
let voice = try await bridge.downloadVoice(fileId: 200)
|
||||||
|
precondition(photo.path == "/tmp/fake-photo-100.jpg")
|
||||||
|
precondition(voice.path == "/tmp/fake-voice-200.ogg")
|
||||||
|
|
||||||
await viewModel.forward(message: viewModel.messages[0], to: 2)
|
await viewModel.forward(message: viewModel.messages[0], to: 2)
|
||||||
let forwarded = try await bridge.loadHistory(chatId: 2)
|
let forwarded = try await bridge.loadHistory(chatId: 2)
|
||||||
precondition(forwarded.contains { $0.forwardSenderName == "Alice" && $0.text == "Edited text" })
|
precondition(forwarded.contains { $0.forwardSenderName == "Alice" && $0.text == "Edited text" })
|
||||||
|
|||||||
@@ -942,7 +942,8 @@ mod tests {
|
|||||||
.build();
|
.build();
|
||||||
let client = FakeTdClient::new()
|
let client = FakeTdClient::new()
|
||||||
.with_message(chat_id.as_i64(), message)
|
.with_message(chat_id.as_i64(), message)
|
||||||
.with_downloaded_file(77, "/tmp/photo.jpg");
|
.with_downloaded_file(77, "/tmp/photo.jpg")
|
||||||
|
.with_downloaded_file(88, "/tmp/voice.ogg");
|
||||||
let mut session = CoreSession::new(client);
|
let mut session = CoreSession::new(client);
|
||||||
|
|
||||||
session
|
session
|
||||||
@@ -960,8 +961,10 @@ mod tests {
|
|||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let downloaded = session.download_photo(77).await.unwrap();
|
let downloaded = session.download_photo(77).await.unwrap();
|
||||||
|
let downloaded_voice = session.download_voice(88).await.unwrap();
|
||||||
|
|
||||||
assert_eq!(downloaded.path, "/tmp/photo.jpg");
|
assert_eq!(downloaded.path, "/tmp/photo.jpg");
|
||||||
|
assert_eq!(downloaded_voice.path, "/tmp/voice.ogg");
|
||||||
assert_eq!(session.client().get_forwarded_messages().len(), 1);
|
assert_eq!(session.client().get_forwarded_messages().len(), 1);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
reactions,
|
reactions,
|
||||||
|
|||||||
@@ -308,7 +308,7 @@ impl FileClient for FakeTdClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn download_voice_note(&self, file_id: i32) -> Result<String, String> {
|
async fn download_voice_note(&self, file_id: i32) -> Result<String, String> {
|
||||||
Ok(format!("/tmp/fake_voice_{}.ogg", file_id))
|
FakeTdClient::download_file(self, file_id).await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1301,6 +1301,8 @@ mod tests {
|
|||||||
assert_eq!(history[0].text, "Hello from fake TDLib");
|
assert_eq!(history[0].text, "Hello from fake TDLib");
|
||||||
let pinned = session.pinned_messages(chats[0].id).unwrap();
|
let pinned = session.pinned_messages(chats[0].id).unwrap();
|
||||||
assert_eq!(pinned[0].text, "Hello from fake TDLib");
|
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");
|
||||||
|
|
||||||
let sent = session
|
let sent = session
|
||||||
.send_message(chats[0].id, "Hi from Swift".to_string(), None)
|
.send_message(chats[0].id, "Hi from Swift".to_string(), None)
|
||||||
|
|||||||
@@ -63,6 +63,12 @@ struct Smoke {
|
|||||||
let pinned = try session.pinnedMessages(chatId: chat.id)
|
let pinned = try session.pinnedMessages(chatId: chat.id)
|
||||||
require(pinned.first?.text == "Hello from fake TDLib", "expected pinned message")
|
require(pinned.first?.text == "Hello from fake TDLib", "expected pinned message")
|
||||||
|
|
||||||
|
let photo = try session.downloadPhoto(fileId: 100)
|
||||||
|
require(photo.path == "/tmp/fake-photo.jpg", "expected downloaded photo path")
|
||||||
|
|
||||||
|
let voice = try session.downloadVoice(fileId: 200)
|
||||||
|
require(voice.path == "/tmp/fake-voice.ogg", "expected downloaded voice path")
|
||||||
|
|
||||||
let sent = try session.sendMessage(chatId: chat.id, text: "Hi from Swift FFI", replyToMessageId: nil)
|
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")
|
require(sent.text == "Hi from Swift FFI", "expected sent message text")
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user