forked from 1b-agent/opencadstudio-upstream
fix(web): STEP export no longer panics; STEP/STL exports download in the browser
The STEP header timestamp used SystemTime, which panics on wasm, and the exports wrote through std::fs, which the browser does not have. Fixes #761 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
5ccaaad48e
commit
d70cc46712
2 files changed
+28
-7
No files matched your search
+17
-2
@@ -19,6 +19,21 @@ use codec::{EntityType as AcadEntityType, Handle};
|
|||||||
use iced::time::Instant;
|
use iced::time::Instant;
|
||||||
use iced::{mouse, Point, Task};
|
use iced::{mouse, Point, Task};
|
||||||
|
|
||||||
|
/// Write an exported file: to disk on the desktop, as a browser download on
|
||||||
|
/// the web, where there is no filesystem behind the dialog's path. (#761)
|
||||||
|
fn write_export(path: &std::path::Path, bytes: &[u8]) -> Result<(), String> {
|
||||||
|
#[cfg(target_arch = "wasm32")]
|
||||||
|
{
|
||||||
|
let name = path.file_name().map_or_else(|| "export".into(), |n| n.to_string_lossy());
|
||||||
|
crate::sys::download_bytes(&name, bytes);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
|
{
|
||||||
|
std::fs::write(path, bytes).map_err(|e| e.to_string())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub(super) fn background_task<T, F, M>(work: F, map: M) -> Task<Message>
|
pub(super) fn background_task<T, F, M>(work: F, map: M) -> Task<Message>
|
||||||
where
|
where
|
||||||
T: Send + 'static,
|
T: Send + 'static,
|
||||||
@@ -2006,7 +2021,7 @@ impl OpenCADStudio {
|
|||||||
let mesh_refs: Vec<_> = meshes.iter().collect();
|
let mesh_refs: Vec<_> = meshes.iter().collect();
|
||||||
let bytes = crate::io::stl::build_stl(&mesh_refs)
|
let bytes = crate::io::stl::build_stl(&mesh_refs)
|
||||||
.ok_or_else(|| "no mesh data to export".to_string())?;
|
.ok_or_else(|| "no mesh data to export".to_string())?;
|
||||||
std::fs::write(&worker_path, bytes).map_err(|e| e.to_string())
|
write_export(&worker_path, &bytes)
|
||||||
},
|
},
|
||||||
move |result| Message::StlExportFinished(path, result),
|
move |result| Message::StlExportFinished(path, result),
|
||||||
)
|
)
|
||||||
@@ -2027,7 +2042,7 @@ impl OpenCADStudio {
|
|||||||
let mesh_refs: Vec<_> = meshes.iter().collect();
|
let mesh_refs: Vec<_> = meshes.iter().collect();
|
||||||
let text = crate::io::step::build_step(&mesh_refs)
|
let text = crate::io::step::build_step(&mesh_refs)
|
||||||
.ok_or_else(|| "no mesh data to export".to_string())?;
|
.ok_or_else(|| "no mesh data to export".to_string())?;
|
||||||
std::fs::write(&worker_path, text.as_bytes()).map_err(|e| e.to_string())
|
write_export(&worker_path, text.as_bytes())
|
||||||
},
|
},
|
||||||
move |result| Message::StepExportFinished(path, result),
|
move |result| Message::StepExportFinished(path, result),
|
||||||
)
|
)
|
||||||
|
|||||||
+11
-5
@@ -255,11 +255,17 @@ pub fn build_step(meshes: &[&MeshModel]) -> Option<String> {
|
|||||||
/// Returns an ISO 8601-like timestamp string for the STEP file header.
|
/// Returns an ISO 8601-like timestamp string for the STEP file header.
|
||||||
fn chrono_timestamp() -> String {
|
fn chrono_timestamp() -> String {
|
||||||
// Use seconds since Unix epoch for a simple timestamp without chrono dep.
|
// Use seconds since Unix epoch for a simple timestamp without chrono dep.
|
||||||
use std::time::{SystemTime, UNIX_EPOCH};
|
// `SystemTime::now` panics in the browser; ask the page's clock there. (#761)
|
||||||
let secs = SystemTime::now()
|
#[cfg(target_arch = "wasm32")]
|
||||||
.duration_since(UNIX_EPOCH)
|
let secs = (js_sys::Date::now() / 1000.0) as u64;
|
||||||
.map(|d| d.as_secs())
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
.unwrap_or(0);
|
let secs = {
|
||||||
|
use std::time::{SystemTime, UNIX_EPOCH};
|
||||||
|
SystemTime::now()
|
||||||
|
.duration_since(UNIX_EPOCH)
|
||||||
|
.map(|d| d.as_secs())
|
||||||
|
.unwrap_or(0)
|
||||||
|
};
|
||||||
// Format: YYYY-MM-DDTHH:MM:SS (approximate UTC from epoch seconds).
|
// Format: YYYY-MM-DDTHH:MM:SS (approximate UTC from epoch seconds).
|
||||||
let s = secs;
|
let s = secs;
|
||||||
let mins = s / 60;
|
let mins = s / 60;
|
||||||
|
|||||||
Reference in new issue
Block a user