forked from 1b-agent/opencadstudio-upstream
feat(wasm): web Save/Save As go through the dialog with a direct download
On the web, Save and Save As now open the in-app Save dialog (filename + format) like the desktop, and the unsaved-changes prompt's Save routes through it too — instead of an immediate rfd download. Confirm serializes to bytes and downloads directly via a Blob + hidden `<a download>` click (a user gesture), so there is no intermediate "click to download" link. Replaces the rfd-based download_web / WebSaveResult round-trip with a synchronous sys::download_bytes. Native save is unchanged. Native + web build; 75 tests pass. Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
1 parent
93d136c5db
commit
fefae274d4
6 files changed
+99
-107
No files matched your search
+27
@@ -32,3 +32,30 @@ pub fn handle_path(h: &rfd::FileHandle) -> std::path::PathBuf {
|
||||
pub fn handle_path(h: &rfd::FileHandle) -> std::path::PathBuf {
|
||||
std::path::PathBuf::from(h.file_name())
|
||||
}
|
||||
|
||||
/// Trigger a browser download of `bytes` as `name`. Builds a Blob, points a
|
||||
/// hidden `<a download>` at it and clicks it programmatically — because this
|
||||
/// runs inside the Save button's click (a user gesture), the file downloads
|
||||
/// immediately with no extra "click to download" link. Web only.
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
pub fn download_bytes(name: &str, bytes: &[u8]) {
|
||||
use wasm_bindgen::JsCast;
|
||||
let Some(window) = web_sys::window() else { return };
|
||||
let Some(document) = window.document() else { return };
|
||||
let array = js_sys::Uint8Array::from(bytes);
|
||||
let parts = js_sys::Array::new();
|
||||
parts.push(&array.buffer());
|
||||
let Ok(blob) = web_sys::Blob::new_with_u8_array_sequence(&parts) else {
|
||||
return;
|
||||
};
|
||||
let Ok(url) = web_sys::Url::create_object_url_with_blob(&blob) else {
|
||||
return;
|
||||
};
|
||||
if let Ok(el) = document.create_element("a") {
|
||||
let a: web_sys::HtmlAnchorElement = el.unchecked_into();
|
||||
a.set_href(&url);
|
||||
a.set_download(name);
|
||||
a.click();
|
||||
}
|
||||
let _ = web_sys::Url::revoke_object_url(&url);
|
||||
}
|
||||
Reference in new issue
Block a user