diff --git a/crates/chat_ui/src/lib.rs b/crates/chat_ui/src/lib.rs index 0ad30ce3..221b1e8c 100644 --- a/crates/chat_ui/src/lib.rs +++ b/crates/chat_ui/src/lib.rs @@ -714,17 +714,34 @@ impl ChatPanel { return Ok(()); }; - this.update(cx, |this, cx| { - this.set_uploading(true, cx); + this.update_in(cx, |this, window, cx| { + this.upload_file(server, path, encrypted, window, cx); })?; - // Upload the file, encrypted when it is the whole message + Ok(()) + })); + } + + /// Upload a file, encrypted when the attachment is the whole message + fn upload_file( + &mut self, + server: Url, + path: PathBuf, + encrypted: bool, + window: &mut Window, + cx: &mut Context, + ) { + self.set_uploading(true, cx); + + self.tasks.push(cx.spawn_in(window, async move |this, cx| { let result = if encrypted { - upload_encrypted(server, path.clone(), cx) + upload_encrypted(server.clone(), path.clone(), cx) .await - .map(|file| Uploaded::File(file, path)) + .map(|file| Uploaded::File(file, path.clone())) } else { - upload(server, path, cx).await.map(Uploaded::Url) + upload(server.clone(), path.clone(), cx) + .await + .map(Uploaded::Url) }; this.update_in(cx, |this, window, cx| { @@ -733,6 +750,9 @@ impl ChatPanel { match result { Ok(Uploaded::Url(url)) => this.add_attachment(url, cx), Ok(Uploaded::File(file, path)) => this.add_pending_file(file, path, cx), + Err(e) if encrypted => { + this.report_encrypted_upload_error(server, path, e, window, cx) + } Err(e) => { window.push_notification( Notification::error(e.to_string()).autohide(false), @@ -746,6 +766,38 @@ impl ChatPanel { })); } + /// Report a failed encrypted upload, offering to retry it without encryption + fn report_encrypted_upload_error( + &mut self, + server: Url, + path: PathBuf, + error: Error, + window: &mut Window, + cx: &mut Context, + ) { + let view = cx.entity().downgrade(); + + window.push_notification( + Notification::error(error.to_string()) + .title("Encrypted upload failed") + .action(move |_this, _window, _cx| { + let view = view.clone(); + let server = server.clone(); + let path = path.clone(); + + Button::new("retry-without-encryption") + .label("Upload without encryption") + .on_click(move |_ev, window, cx| { + view.update(cx, |this, cx| { + this.upload_file(server.clone(), path.clone(), false, window, cx); + }) + .ok(); + }) + }), + cx, + ); + } + fn set_uploading(&mut self, uploading: bool, cx: &mut Context) { self.uploading = uploading; cx.notify();