diff --git a/examples/file_upload/Cargo.toml b/examples/file_upload/Cargo.toml index be7408989b2..c01c3d5bc88 100644 --- a/examples/file_upload/Cargo.toml +++ b/examples/file_upload/Cargo.toml @@ -13,4 +13,4 @@ gloo = "0.11" [dependencies.web-sys] version = "0.3" -features = ["File", "DragEvent", "DataTransfer"] +features = ["DataTransfer"] diff --git a/examples/file_upload/src/main.rs b/examples/file_upload/src/main.rs index 1e882fcbda7..49d66bb7906 100644 --- a/examples/file_upload/src/main.rs +++ b/examples/file_upload/src/main.rs @@ -4,20 +4,19 @@ use std::collections::HashMap; use base64::engine::general_purpose::STANDARD; use base64::Engine; use gloo::file::callbacks::FileReader; -use gloo::file::File; -use web_sys::{DragEvent, Event, FileList, HtmlInputElement}; +use web_sys::{DragEvent, Event, HtmlInputElement}; use yew::html::TargetCast; use yew::{html, Callback, Component, Context, Html}; -struct FileDetails { +pub struct FileDetails { name: String, file_type: String, data: Vec, } pub enum Msg { - Loaded(String, String, Vec), - Files(Vec), + Loaded(FileDetails), + Files(Option), } pub struct App { @@ -38,33 +37,27 @@ impl Component for App { fn update(&mut self, ctx: &Context, msg: Self::Message) -> bool { match msg { - Msg::Loaded(file_name, file_type, data) => { - self.files.push(FileDetails { - data, - file_type, - name: file_name.clone(), - }); - self.readers.remove(&file_name); + Msg::Loaded(file) => { + self.readers.remove(&file.name); + self.files.push(file); true } Msg::Files(files) => { - for file in files.into_iter() { - let file_name = file.name(); + for file in gloo::file::FileList::from(files.expect("files")).iter() { + let link = ctx.link().clone(); + let name = file.name().clone(); let file_type = file.raw_mime_type(); let task = { - let link = ctx.link().clone(); - let file_name = file_name.clone(); - - gloo::file::callbacks::read_as_bytes(&file, move |res| { - link.send_message(Msg::Loaded( - file_name, + gloo::file::callbacks::read_as_bytes(file, move |res| { + link.send_message(Msg::Loaded(FileDetails { + data: res.expect("failed to read file"), file_type, - res.expect("failed to read file"), - )) + name, + })) }) }; - self.readers.insert(file_name, task); + self.readers.insert(file.name(), task); } true } @@ -72,6 +65,10 @@ impl Component for App { } fn view(&self, ctx: &Context) -> Html { + let noop_drag = Callback::from(|e: DragEvent| { + e.prevent_default(); + }); + html! {

{ "Upload Your Files To The Cloud" }

@@ -80,15 +77,10 @@ impl Component for App { id="drop-container" ondrop={ctx.link().callback(|event: DragEvent| { event.prevent_default(); - let files = event.data_transfer().unwrap().files(); - Self::upload_files(files) - })} - ondragover={Callback::from(|event: DragEvent| { - event.prevent_default(); - })} - ondragenter={Callback::from(|event: DragEvent| { - event.prevent_default(); + Msg::Files(event.data_transfer().unwrap().files()) })} + ondragover={&noop_drag} + ondragenter={&noop_drag} >

{"Drop your images here or click to select"}

@@ -101,7 +93,7 @@ impl Component for App { multiple={true} onchange={ctx.link().callback(move |e: Event| { let input: HtmlInputElement = e.target_unchecked_into(); - Self::upload_files(input.files()) + Msg::Files(input.files()) })} />
@@ -114,37 +106,24 @@ impl Component for App { impl App { fn view_file(file: &FileDetails) -> Html { + let file_type = file.file_type.to_string(); + let src = format!("data:{};base64,{}", file_type, STANDARD.encode(&file.data)); html! {
-

{ format!("{}", file.name) }

+

{ &file.name }

if file.file_type.contains("image") { - + } else if file.file_type.contains("video") { }
} } - - fn upload_files(files: Option) -> Msg { - let mut result = Vec::new(); - - if let Some(files) = files { - let files = js_sys::try_iter(&files) - .unwrap() - .unwrap() - .map(|v| web_sys::File::from(v.unwrap())) - .map(File::from); - result.extend(files); - } - Msg::Files(result) - } } - fn main() { yew::Renderer::::new().render(); }