1use std::sync::mpsc::Receiver;
14
15use blockworx_doc::block_model::Asset;
16
17#[cfg(not(target_arch = "wasm32"))]
20pub use blockworx_editor::import::file_stem;
21
22#[cfg(not(target_arch = "wasm32"))]
26pub fn spawn_import_dialog(ctx: &egui::Context) -> Receiver<Option<(String, Vec<u8>)>> {
27 let (tx, rx) = std::sync::mpsc::channel();
28 let thread_ctx = ctx.clone();
29 std::thread::spawn(move || {
30 let picked = rfd::FileDialog::new()
31 .add_filter("Image", &["png", "svg"])
32 .pick_file()
33 .and_then(|path| {
34 let name = path.file_name()?.to_string_lossy().into_owned();
35 Some((name, std::fs::read(&path).ok()?))
36 });
37 let _ = tx.send(picked);
38 thread_ctx.request_repaint();
39 });
40 ctx.request_repaint();
41 rx
42}
43#[cfg(target_arch = "wasm32")]
46pub fn spawn_import_dialog(ctx: &egui::Context) -> Receiver<Option<(String, Vec<u8>)>> {
47 let (tx, rx) = std::sync::mpsc::channel();
48 let task_ctx = ctx.clone();
49 wasm_bindgen_futures::spawn_local(async move {
50 let picked = if let Some(file) = rfd::AsyncFileDialog::new()
51 .add_filter("Image", &["png", "svg"])
52 .pick_file()
53 .await
54 {
55 Some((file.file_name(), file.read().await))
56 } else {
57 None
58 };
59 let _ = tx.send(picked);
60 task_ctx.request_repaint();
61 });
62 ctx.request_repaint();
63 rx
64}
65
66#[cfg(not(target_arch = "wasm32"))]
71pub fn spawn_image_dialog(ctx: &egui::Context) -> Receiver<Option<Asset>> {
72 let (tx, rx) = std::sync::mpsc::channel();
73 let thread_ctx = ctx.clone();
74 std::thread::spawn(move || {
75 let image = rfd::FileDialog::new()
76 .add_filter("Image", &["svg", "png"])
77 .pick_file()
78 .and_then(|path| read_image(&path));
79 let _ = tx.send(image);
80 thread_ctx.request_repaint();
81 });
82 ctx.request_repaint();
83 rx
84}
85
86#[cfg(target_arch = "wasm32")]
90pub fn spawn_image_dialog(ctx: &egui::Context) -> Receiver<Option<Asset>> {
91 let (tx, rx) = std::sync::mpsc::channel();
92 let task_ctx = ctx.clone();
93 wasm_bindgen_futures::spawn_local(async move {
94 let image = if let Some(file) = rfd::AsyncFileDialog::new()
95 .add_filter("Image", &["svg", "png"])
96 .pick_file()
97 .await
98 {
99 let is_png = file.file_name().to_ascii_lowercase().ends_with(".png");
100 let bytes = file.read().await;
101 if is_png {
102 Some(Asset::Png(bytes.into()))
103 } else {
104 String::from_utf8(bytes)
105 .ok()
106 .map(|text| Asset::Svg(text.into_bytes().into()))
107 }
108 } else {
109 None
110 };
111 let _ = tx.send(image);
112 task_ctx.request_repaint();
113 });
114 ctx.request_repaint();
115 rx
116}
117
118#[cfg(not(target_arch = "wasm32"))]
122fn read_image(path: &std::path::Path) -> Option<Asset> {
123 let is_png = path
124 .extension()
125 .is_some_and(|ext| ext.eq_ignore_ascii_case("png"));
126 if is_png {
127 std::fs::read(path)
128 .ok()
129 .map(|bytes| Asset::Png(bytes.into()))
130 } else {
131 std::fs::read_to_string(path)
132 .ok()
133 .map(|text| Asset::Svg(text.into_bytes().into()))
134 }
135}