Attachment upload with file dialog#674
Attachment upload with file dialog#674alanpoon wants to merge 32 commits intoproject-robius:mainfrom
Conversation
|
awesome! I know this isn't yet complete, but I wanted to quickly drop in and suggest using Plus, with |
Kindly refer to this implementation of the rfd. https://github.com/Vjze/YY_DPS/blob/edb15ffc85b646c27547081b30a0e6f0d8ba688b/src/export/export_view.rs#L158 This requires the tokio runtime in a field in export screen |
Ok, what's the issue with that? Is that problematic? Apologies, but I'm not quite sure what point you're trying to make. Moly has used |
Thanks for referring me to Moly. File Dialog does not work well in asynchronously in macOS as file dialog is only allowing in main thread. |
eae0bfa to
f922cf2
Compare
kevinaboos
left a comment
There was a problem hiding this comment.
Thanks Alan, looks very good — impressive work here!
I left comments about a few major structural decisions, but it's mostly just about refactoring things into more modular widgets. I also left some questions about using higher-level Timeline APIs vs Room APIs for sending attachments.
Also, now that you're using |
e78c41b to
81f4718
Compare
Co-authored-by: Kevin Boos <1139460+kevinaboos@users.noreply.github.com>
Co-authored-by: Kevin Boos <1139460+kevinaboos@users.noreply.github.com>
kevinaboos
left a comment
There was a problem hiding this comment.
Looks pretty good, just a few minor comments.
src/room/room_input_bar.rs
Outdated
| /// Counter for generating unique IDs for file load tasks. | ||
| #[rust] file_load_task_id_counter: u32, | ||
| /// The pending file load operation, if any. Contains the task ID and receiver | ||
| /// channel for receiving the loaded file data from a background thread. | ||
| #[rust] pending_file_load: Option<(u32, FileLoadReceiver)>, |
There was a problem hiding this comment.
it looks like neither of these u32 values are used any more, correct? If so, please remove them.
Seems like they wouldn't be needed anyway now that you're using proper TimelineUpdate channels for this stuff.
There was a problem hiding this comment.
Remove file_load_task_id_counter
| draw_icon: { | ||
| svg_file: (ICON_ADD_ATTACHMENT) | ||
| color: (COLOR_ACTIVE_PRIMARY_DARKER) | ||
| }, | ||
| draw_bg: { | ||
| color: (COLOR_PRIMARY), | ||
| } |
There was a problem hiding this comment.
I think you've flipped these. The background color should be COLOR_ACTIVE_PRIMARY (blue), and the foreground color (both text and icon) should be COLOR_PRIMARY (white)
There was a problem hiding this comment.
Change to follow "location_button"
src/room/room_input_bar.rs
Outdated
| } | ||
| if remove_receiver { | ||
| self.pending_file_load = None; | ||
| cx.set_cursor(MouseCursor::Default); |
There was a problem hiding this comment.
nit: why is this needed? I suppose it doesn't hurt, but I don't see how it's beneficial. The cursor should be based on what the mouse is hovering over, right?
There was a problem hiding this comment.
Remove "cx.set_cursor(MouseCursor::Default);"
src/shared/file_upload_modal.rs
Outdated
| } | ||
| } | ||
|
|
||
| /// Actions emitted by the `FileUploadModal` widget. |
There was a problem hiding this comment.
nit: are these actions actually emitted by the FileUploadModal widget? seems like they aren't necessarily; please update the doc comments to be clear for each variant.
There was a problem hiding this comment.
Updated the doc comments.
src/sliding_sync.rs
Outdated
| let mime_type = file_meta.mime.clone(); | ||
| let attachment_config = matrix_sdk_ui::timeline::AttachmentConfig { | ||
| txn_id: None, | ||
| info: None, |
There was a problem hiding this comment.
shouldn't you fill in this info here, especially since most of it is already available as part of the file_data?
note that we do rely on this basic image info when showing images in the RoomScreen timeline, so it's only fair to expect that we should provide it to Robrix and other clients as well when uploading an image/file.
| let mut subscriber = send_attachment.subscribe_to_send_progress(); | ||
| let timeline_update_sender = sender.clone(); | ||
| Handle::current().spawn(async move { | ||
| while let Some(progress) = subscriber.next().await { | ||
| sender.send(TimelineUpdate::FileUploadUpdate { current: progress.current as u64, total: file_meta.file_size }).unwrap_or_else(|e| { | ||
| error!("Failed to send progress update to UI: {e:?}"); | ||
| }); | ||
| SignalToUI::set_ui_signal(); | ||
| } | ||
| }); | ||
| timeline_update_sender.send(TimelineUpdate::FileUploadUpdate { current: 0, total: file_meta.file_size }).unwrap_or_else(|e| { | ||
| error!("Failed to send initial progress update to UI: {e:?}"); | ||
| }); | ||
| match send_attachment.await { | ||
| Ok(_) => { | ||
| log!("Successfully uploaded and sent file to {timeline_kind}"); | ||
| timeline_update_sender.send(TimelineUpdate::FileUploadUpdate { current: file_meta.file_size, total: file_meta.file_size }).unwrap_or_else(|e| { | ||
| error!("Failed to send progress update to UI: {e:?}"); | ||
| }); | ||
| SignalToUI::set_ui_signal(); | ||
| } | ||
| Err(e) => { | ||
| error!("Failed to upload file to {timeline_kind}: {e:?}"); | ||
| // Set progress to completion state (0/0) to hide the progress bar | ||
| timeline_update_sender.send(TimelineUpdate::FileUploadUpdate { current: 0, total: 0 }).unwrap_or_else(|e| { | ||
| error!("Failed to send progress update to UI: {e:?}"); | ||
| }); | ||
| SignalToUI::set_ui_signal(); | ||
| enqueue_popup_notification(format!("Failed to upload file: {e}"), PopupKind::Error, None); | ||
| } | ||
| } | ||
| }); |
There was a problem hiding this comment.
can you improve the formatting of this? it's hard to read. Needs more whitespace newlines for separation, and better wrapping to avoid very long lines (ideally not much longer than 100 chars)
src/sliding_sync.rs
Outdated
| timeline_update_sender.send(TimelineUpdate::FileUploadUpdate { current: 0, total: 0 }).unwrap_or_else(|e| { | ||
| error!("Failed to send progress update to UI: {e:?}"); | ||
| }); | ||
| SignalToUI::set_ui_signal(); | ||
| enqueue_popup_notification(format!("Failed to upload file: {e}"), PopupKind::Error, None); |
There was a problem hiding this comment.
While this technically works, it's not a great user experience.
Don't just hide the progress bar and show a popup notification error from the background task here. That doesn't allow the user to retry if anything went wrong (e.g., a temporary network disconnection).
Instead, send a variant of the FileUploadUpdate action with the explicit error to the UI, such that we can then show a retry button in the UI to allow the user to (1) see the error, and (2) attempt to re-send it.
There was a problem hiding this comment.
Added Retry button.
Co-authored-by: Kevin Boos <1139460+kevinaboos@users.noreply.github.com>
Co-authored-by: Kevin Boos <1139460+kevinaboos@users.noreply.github.com>
Co-authored-by: Kevin Boos <1139460+kevinaboos@users.noreply.github.com>
Screen.Recording.2026-01-26.at.4.09.11.PM.mov