Add basic file reading functionality

This commit is contained in:
Rob Watson 2020-09-04 13:42:16 +02:00
parent 083ff74b0c
commit ef1159c139
6 changed files with 85 additions and 10 deletions

View File

@ -10,3 +10,15 @@ crate-type = ["cdylib", "rlib"]
[dependencies] [dependencies]
yew = "0.17" yew = "0.17"
wasm-bindgen = "0.2" wasm-bindgen = "0.2"
gloo-events = "0.1.0"
js-sys = "0.3.44"
futures = "0.3.5"
wasm-bindgen-futures = "0.4"
console_error_panic_hook = "0.1.6"
[dependencies.web-sys]
version = "0.3.44"
features = [
"console",
"AudioContext",
]

View File

@ -1,4 +1,3 @@
use wasm_bindgen::prelude::*;
use yew::prelude::*; use yew::prelude::*;
use crate::home::Home; use crate::home::Home;

View File

@ -1,10 +1,14 @@
use wasm_bindgen::prelude::*;
use yew::prelude::*; use yew::prelude::*;
pub struct Canvas {} pub struct Canvas {}
pub enum Msg {
Reset,
SamplesLoaded,
}
impl Component for Canvas { impl Component for Canvas {
type Message = (); type Message = Msg;
type Properties = (); type Properties = ();
fn create(_: Self::Properties, _: ComponentLink<Self>) -> Self { fn create(_: Self::Properties, _: ComponentLink<Self>) -> Self {

View File

@ -1,13 +1,18 @@
use wasm_bindgen::prelude::*; use web_sys::HtmlInputElement;
use yew::prelude::*; use yew::prelude::*;
use yew::web_sys::console; use yew::services::reader::{FileChunk, ReaderTask};
use yew::services::{ConsoleService, ReaderService};
pub struct Controls { pub struct Controls {
link: ComponentLink<Self>, link: ComponentLink<Self>,
file_input: NodeRef,
reader_service: ReaderService,
reader_task: Option<ReaderTask>,
} }
pub enum Msg { pub enum Msg {
SubmitForm, SubmitForm,
FileProgress(Option<FileChunk>),
} }
impl Component for Controls { impl Component for Controls {
@ -15,13 +20,27 @@ impl Component for Controls {
type Properties = (); type Properties = ();
fn create(_: Self::Properties, link: ComponentLink<Self>) -> Self { fn create(_: Self::Properties, link: ComponentLink<Self>) -> Self {
Self { link } Self {
link,
file_input: NodeRef::default(),
reader_service: ReaderService::new(),
reader_task: None,
}
} }
fn update(&mut self, msg: Self::Message) -> ShouldRender { fn update(&mut self, msg: Self::Message) -> ShouldRender {
match msg { match msg {
Msg::SubmitForm => console::log_1(&"Handle submit form".into()), Msg::SubmitForm => {
if let Err(e) = self.handle_submit_form() {
ConsoleService::error(&e);
};
} }
Msg::FileProgress(c) => {
if let Err(e) = self.handle_file_progress(c) {
ConsoleService::error(&e);
};
}
};
true true
} }
@ -29,15 +48,52 @@ impl Component for Controls {
false false
} }
fn rendered(&mut self, _: bool) {}
fn view(&self) -> Html { fn view(&self) -> Html {
html! { html! {
<section id="controls" style="width: 800px; height: 100px; border: 1px solid grey"> <section id="controls" style="width: 800px; height: 100px; border: 1px solid grey">
<label> <label>
{"Select an audio file"} {"Select an audio file"}
<input type="file"/> <input ref=self.file_input.clone() type="file"/>
</label> </label>
<button onclick=self.link.callback(move |_| Msg::SubmitForm)>{"Open file"}</button> <button onclick=self.link.callback(move |_| Msg::SubmitForm)>{"Open file"}</button>
</section> </section>
} }
} }
} }
impl Controls {
fn handle_submit_form(&mut self) -> Result<(), String> {
let file_input = self
.file_input
.cast::<HtmlInputElement>()
.ok_or("could not cast file_input")?;
let file_list = file_input.files().ok_or("could not get file list")?;
let file = file_list.get(0).ok_or("could not get file")?;
let cb = self.link.callback(Msg::FileProgress);
let task = self
.reader_service
.read_file_by_chunks(file, cb, 256)
.map_err(|e| e.to_string())?;
self.reader_task = Some(task);
Ok(())
}
fn handle_file_progress(&self, chunk: Option<FileChunk>) -> Result<(), String> {
match chunk {
Some(FileChunk::Started { name, .. }) => {
ConsoleService::log(&format!("Started: {}", name))
}
Some(FileChunk::DataChunk { progress, .. }) => {
ConsoleService::log(&format!("Got chunk, progress: {}", progress))
}
Some(FileChunk::Finished) => ConsoleService::log("Finished"),
_ => (),
}
Ok(())
}
}

View File

@ -1,6 +1,5 @@
use crate::canvas::Canvas; use crate::canvas::Canvas;
use crate::controls::Controls; use crate::controls::Controls;
use wasm_bindgen::prelude::*;
use yew::prelude::*; use yew::prelude::*;
pub struct Home {} pub struct Home {}

View File

@ -1,3 +1,7 @@
extern crate console_error_panic_hook;
extern crate js_sys;
use std::panic;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
use yew::prelude::*; use yew::prelude::*;
@ -8,5 +12,6 @@ mod home;
#[wasm_bindgen(start)] #[wasm_bindgen(start)]
pub fn run_app() { pub fn run_app() {
panic::set_hook(Box::new(console_error_panic_hook::hook));
App::<app::App>::new().mount_to_body(); App::<app::App>::new().mount_to_body();
} }