From 50052fc88d4a400b5815ece1856dc507dddb83af Mon Sep 17 00:00:00 2001 From: Emilia Date: Tue, 25 Nov 2025 21:17:40 -0500 Subject: [PATCH] Small fixes for wasm version Also, the vibe coded wasm versions of file picking seem to work? big if true --- Cargo.lock | 23 +++++++++++++- plate-tool-eframe/Cargo.toml | 15 ++++++++- plate-tool-eframe/src/file_handling.rs | 43 ++++++++++++++++++++++++-- 3 files changed, 77 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 586b7e1..36aaa7b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1473,6 +1473,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97563d71863fb2824b2e974e754a81d19c4a7ec47b09ced8a0e6656b6d54bd1f" dependencies = [ + "futures-channel", "gloo-events 0.2.0", "js-sys", "wasm-bindgen", @@ -1620,6 +1621,8 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbb143cf96099802033e0d4f4963b19fd2e0b728bcf076cd9cf7f6634f092994" dependencies = [ + "futures-channel", + "futures-core", "js-sys", "wasm-bindgen", ] @@ -2372,7 +2375,7 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" dependencies = [ - "proc-macro-crate 1.3.1", + "proc-macro-crate 3.4.0", "proc-macro2", "quote", "syn 2.0.87", @@ -2794,10 +2797,16 @@ version = "0.1.0" dependencies = [ "eframe", "env_logger", + "gloo-file 0.3.0", + "gloo-timers 0.3.0", + "js-sys", "log", "plate-tool-lib", + "poll-promise", "rfd", "serde", + "serde_json", + "wasm-bindgen", "wasm-bindgen-futures", "web-sys", ] @@ -2854,6 +2863,18 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "poll-promise" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f6a58fecbf9da8965bcdb20ce4fd29788d1acee68ddbb64f0ba1b81bccdb7df" +dependencies = [ + "document-features", + "static_assertions", + "wasm-bindgen", + "wasm-bindgen-futures", +] + [[package]] name = "polling" version = "3.7.4" diff --git a/plate-tool-eframe/Cargo.toml b/plate-tool-eframe/Cargo.toml index e71cc9a..43b206e 100644 --- a/plate-tool-eframe/Cargo.toml +++ b/plate-tool-eframe/Cargo.toml @@ -23,7 +23,20 @@ rfd = "0.15" [target.'cfg(target_arch = "wasm32")'.dependencies] wasm-bindgen-futures = "0.4" -web-sys = "0.3" +web-sys = { version = "0.3", features = [ + "Window", + "Document", + "HtmlInputElement", + "HtmlAnchorElement", + "FileList", + "Blob", + "Url" +] } +wasm-bindgen = "0.2" +js-sys = "0.3" +gloo-file = { version = "0.3", features = ["futures"] } +gloo-timers = { version = "0.3", features = ["futures"] } +poll-promise = { version = "0.3", features = ["web"] } #[profile.release] #opt-level = 2 diff --git a/plate-tool-eframe/src/file_handling.rs b/plate-tool-eframe/src/file_handling.rs index 47d90d7..50f3b0b 100644 --- a/plate-tool-eframe/src/file_handling.rs +++ b/plate-tool-eframe/src/file_handling.rs @@ -1,4 +1,3 @@ -#[cfg(not(target_arch = "wasm32"))] use crate::app; // Native case, use rfd @@ -49,7 +48,7 @@ pub fn upload_file(filetype: &str, extension: &str) -> app::FileUploadPromise { // Web case, use web_sys // Not tested yet!! #[cfg(target_arch = "wasm32")] -pub fn save_file(default_filename: Option<&str>, data: &[u8]) { +pub fn save_file(data: &[u8], default_filename: Option<&str>) { use wasm_bindgen::JsCast; use web_sys::{Blob, HtmlAnchorElement, Url}; @@ -71,3 +70,43 @@ pub fn save_file(default_filename: Option<&str>, data: &[u8]) { Url::revoke_object_url(&url).unwrap(); } + +#[cfg(target_arch = "wasm32")] +pub fn upload_file(filetype: &str, extension: &str) -> app::FileUploadPromise { + use poll_promise; + use wasm_bindgen::JsCast; + use web_sys::{window, HtmlInputElement}; + use gloo_file::futures::read_as_bytes; + + let extension = extension.to_owned(); + + app::FileUploadPromise(poll_promise::Promise::spawn_local(async move { + let document = window()?.document()?; + + let input: HtmlInputElement = document + .create_element("input") + .ok()? + .dyn_into() + .ok()?; + + input.set_type("file"); + input.set_accept(&format!(".{}", extension)); + input.click(); + + // Wait for file to be selected + let file_list = loop { + if let Some(files) = input.files() { + if files.length() > 0 { + break files; + } + } + gloo_timers::future::TimeoutFuture::new(100).await; + }; + + let file = file_list.get(0)?; + let data = read_as_bytes(&file.into()).await.ok()?; + + log::info!("Read {} bytes", data.len()); + Some(data) + })) +}