file_upload.rs 2.8 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. LaunchBuilder::desktop().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 read_files = move |file_engine: Arc<dyn FileEngine>| async move {
  19. let files = file_engine.files();
  20. for file_name in &files {
  21. if let Some(contents) = file_engine.read_file_to_string(file_name).await {
  22. files_uploaded.write().push(UploadedFile {
  23. name: file_name.clone(),
  24. contents,
  25. });
  26. }
  27. }
  28. };
  29. let upload_files = move |evt: FormEvent| async move {
  30. if let Some(file_engine) = evt.files() {
  31. read_files(file_engine).await;
  32. }
  33. };
  34. let handle_file_drop = move |evt: DragEvent| async move {
  35. if let Some(file_engine) = evt.files() {
  36. read_files(file_engine).await;
  37. }
  38. };
  39. rsx! {
  40. style { {include_str!("./assets/file_upload.css")} }
  41. h1 { "File Upload Example" }
  42. p { "Drop a .txt, .rs, or .js file here to read it" }
  43. div {
  44. label { r#for: "directory-upload", "Enable directory upload" }
  45. input {
  46. r#type: "checkbox",
  47. id: "directory-upload",
  48. checked: enable_directory_upload,
  49. oninput: move |evt| enable_directory_upload.set(evt.checked()),
  50. },
  51. }
  52. div {
  53. label { r#for: "textreader", "Upload text/rust files and read them" }
  54. input {
  55. r#type: "file",
  56. accept: ".txt,.rs,.js",
  57. multiple: true,
  58. name: "textreader",
  59. directory: enable_directory_upload,
  60. onchange: upload_files,
  61. }
  62. }
  63. div {
  64. // cheating with a little bit of JS...
  65. "ondragover": "this.style.backgroundColor='#88FF88';",
  66. "ondragleave": "this.style.backgroundColor='#FFFFFF';",
  67. "ondrop": "this.style.backgroundColor='#FFFFFF';",
  68. id: "drop-zone",
  69. ondrop: handle_file_drop,
  70. "Drop files here"
  71. }
  72. ul {
  73. for file in files_uploaded.read().iter().rev() {
  74. li {
  75. span { "{file.name}" }
  76. pre { "{file.contents}" }
  77. }
  78. }
  79. }
  80. }
  81. }