matrix_sdk_ui/timeline/
futures.rs1use std::future::IntoFuture;
2
3use eyeball::SharedObservable;
4use matrix_sdk::{attachment::AttachmentConfig, TransmissionProgress};
5use matrix_sdk_base::boxed_into_future;
6use mime::Mime;
7use tracing::{Instrument as _, Span};
8
9use super::{AttachmentSource, Error, Timeline};
10
11pub struct SendAttachment<'a> {
12 timeline: &'a Timeline,
13 source: AttachmentSource,
14 mime_type: Mime,
15 config: AttachmentConfig,
16 tracing_span: Span,
17 pub(crate) send_progress: SharedObservable<TransmissionProgress>,
18 use_send_queue: bool,
19}
20
21impl<'a> SendAttachment<'a> {
22 pub(crate) fn new(
23 timeline: &'a Timeline,
24 source: AttachmentSource,
25 mime_type: Mime,
26 config: AttachmentConfig,
27 ) -> Self {
28 Self {
29 timeline,
30 source,
31 mime_type,
32 config,
33 tracing_span: Span::current(),
34 send_progress: Default::default(),
35 use_send_queue: false,
36 }
37 }
38
39 pub fn use_send_queue(self) -> Self {
48 Self { use_send_queue: true, ..self }
49 }
50
51 #[cfg(not(target_arch = "wasm32"))]
53 pub fn subscribe_to_send_progress(&self) -> eyeball::Subscriber<TransmissionProgress> {
54 self.send_progress.subscribe()
55 }
56}
57
58impl<'a> IntoFuture for SendAttachment<'a> {
59 type Output = Result<(), Error>;
60 boxed_into_future!(extra_bounds: 'a);
61
62 fn into_future(self) -> Self::IntoFuture {
63 let Self {
64 timeline,
65 source,
66 mime_type,
67 config,
68 tracing_span,
69 use_send_queue,
70 send_progress,
71 } = self;
72
73 let fut = async move {
74 let (data, filename) = source.try_into_bytes_and_filename()?;
75
76 if use_send_queue {
77 let send_queue = timeline.room().send_queue();
78 let fut = send_queue.send_attachment(filename, mime_type, data, config);
79 fut.await.map_err(|_| Error::FailedSendingAttachment)?;
80 } else {
81 let fut = timeline
82 .room()
83 .send_attachment(filename, &mime_type, data, config)
84 .with_send_progress_observable(send_progress)
85 .store_in_cache();
86 fut.await.map_err(|_| Error::FailedSendingAttachment)?;
87 }
88
89 Ok(())
90 };
91
92 Box::pin(fut.instrument(tracing_span))
93 }
94}