dioxus/examples/file_upload.rs

97 lines
2.9 KiB
Rust
Raw Normal View History

2024-02-14 20:33:07 +00:00
//! This example shows how to use the `file` methods on FormEvent and DragEvent to handle file uploads and drops.
//!
//! Dioxus intercepts these events and provides a Rusty interface to the file data. Since we want this interface to
//! be crossplatform,
use std::sync::Arc;
2023-04-25 13:16:11 +00:00
use dioxus::prelude::*;
use dioxus::{html::HasFileData, prelude::dioxus_elements::FileEngine};
2023-04-25 13:16:11 +00:00
fn main() {
2024-03-06 10:00:24 +00:00
launch(app);
2023-04-25 13:16:11 +00:00
}
struct UploadedFile {
name: String,
contents: String,
}
2024-02-14 20:33:07 +00:00
fn app() -> Element {
let mut enable_directory_upload = use_signal(|| false);
let mut files_uploaded = use_signal(|| Vec::new() as Vec<UploadedFile>);
2024-03-07 00:42:45 +00:00
let mut hovered = use_signal(|| false);
2024-01-15 21:06:05 +00:00
let read_files = move |file_engine: Arc<dyn FileEngine>| async move {
let files = file_engine.files();
for file_name in &files {
if let Some(contents) = file_engine.read_file_to_string(file_name).await {
files_uploaded.write().push(UploadedFile {
name: file_name.clone(),
contents,
});
}
}
};
2024-01-15 21:06:05 +00:00
let upload_files = move |evt: FormEvent| async move {
if let Some(file_engine) = evt.files() {
read_files(file_engine).await;
2024-01-15 21:06:05 +00:00
}
};
2024-01-16 19:18:46 +00:00
rsx! {
2024-02-14 20:33:07 +00:00
style { {include_str!("./assets/file_upload.css")} }
h1 { "File Upload Example" }
p { "Drop a .txt, .rs, or .js file here to read it" }
2024-03-07 00:42:45 +00:00
button { onclick: move |_| files_uploaded.write().clear(), "Clear files" }
div {
label { r#for: "directory-upload", "Enable directory upload" }
input {
r#type: "checkbox",
id: "directory-upload",
checked: enable_directory_upload,
oninput: move |evt| enable_directory_upload.set(evt.checked()),
},
2023-04-25 13:16:11 +00:00
}
2024-02-14 20:33:07 +00:00
div {
label { r#for: "textreader", "Upload text/rust files and read them" }
input {
r#type: "file",
accept: ".txt,.rs,.js",
multiple: true,
name: "textreader",
directory: enable_directory_upload,
onchange: upload_files,
}
}
2023-04-27 15:21:05 +00:00
div {
2024-02-14 20:33:07 +00:00
id: "drop-zone",
2024-03-07 00:42:45 +00:00
prevent_default: "ondragover ondrop",
background_color: if hovered() { "lightblue" } else { "lightgray" },
ondragover: move |_| hovered.set(true),
ondragleave: move |_| hovered.set(false),
ondrop: move |evt| async move {
hovered.set(false);
if let Some(file_engine) = evt.files() {
read_files(file_engine).await;
}
},
2023-04-27 15:21:05 +00:00
"Drop files here"
}
2023-04-25 13:16:11 +00:00
ul {
for file in files_uploaded.read().iter().rev() {
li {
span { "{file.name}" }
pre { "{file.contents}" }
}
2023-04-25 13:16:11 +00:00
}
}
2024-01-14 05:12:21 +00:00
}
2023-04-25 13:16:11 +00:00
}