1
0

file_upload.rs 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. //! This example shows how to use the `file` methods on FormEvent and DragEvent to handle file uploads and drops.
  2. //!
  3. //! Dioxus intercepts these events and provides a Rusty interface to the file data. Since we want this interface to
  4. //! be crossplatform,
  5. use std::sync::Arc;
  6. use dioxus::prelude::*;
  7. use dioxus::{html::HasFileData, prelude::dioxus_elements::FileEngine};
  8. fn main() {
  9. launch(app);
  10. }
  11. struct UploadedFile {
  12. name: String,
  13. contents: String,
  14. }
  15. fn app() -> Element {
  16. let mut enable_directory_upload = use_signal(|| false);
  17. let mut files_uploaded = use_signal(|| Vec::new() as Vec<UploadedFile>);
  18. let mut hovered = use_signal(|| false);
  19. let read_files = move |file_engine: Arc<dyn FileEngine>| async move {
  20. let files = file_engine.files();
  21. for file_name in &files {
  22. if let Some(contents) = file_engine.read_file_to_string(file_name).await {
  23. files_uploaded.write().push(UploadedFile {
  24. name: file_name.clone(),
  25. contents,
  26. });
  27. }
  28. }
  29. };
  30. let upload_files = move |evt: FormEvent| async move {
  31. if let Some(file_engine) = evt.files() {
  32. read_files(file_engine).await;
  33. }
  34. };
  35. rsx! {
  36. style { {include_str!("./assets/file_upload.css")} }
  37. h1 { "File Upload Example" }
  38. p { "Drop a .txt, .rs, or .js file here to read it" }
  39. button { onclick: move |_| files_uploaded.write().clear(), "Clear files" }
  40. div {
  41. label { r#for: "directory-upload", "Enable directory upload" }
  42. input {
  43. r#type: "checkbox",
  44. id: "directory-upload",
  45. checked: enable_directory_upload,
  46. oninput: move |evt| enable_directory_upload.set(evt.checked()),
  47. },
  48. }
  49. div {
  50. label { r#for: "textreader", "Upload text/rust files and read them" }
  51. input {
  52. r#type: "file",
  53. accept: ".txt,.rs,.js",
  54. multiple: true,
  55. name: "textreader",
  56. directory: enable_directory_upload,
  57. onchange: upload_files,
  58. }
  59. }
  60. div {
  61. id: "drop-zone",
  62. prevent_default: "ondragover ondrop",
  63. background_color: if hovered() { "lightblue" } else { "lightgray" },
  64. ondragover: move |_| hovered.set(true),
  65. ondragleave: move |_| hovered.set(false),
  66. ondrop: move |evt| async move {
  67. hovered.set(false);
  68. if let Some(file_engine) = evt.files() {
  69. read_files(file_engine).await;
  70. }
  71. },
  72. "Drop files here"
  73. }
  74. ul {
  75. for file in files_uploaded.read().iter().rev() {
  76. li {
  77. span { "{file.name}" }
  78. pre { "{file.contents}" }
  79. }
  80. }
  81. }
  82. }
  83. }