97 lines
3.0 KiB
Rust
97 lines
3.0 KiB
Rust
use super::canvas::Canvas;
|
|
use crate::agents::audio_agent::{self, AudioAgent};
|
|
use crate::components::Player;
|
|
use web_sys::HtmlInputElement;
|
|
use yew::agent::Dispatcher;
|
|
use yew::prelude::*;
|
|
use yew::services::ConsoleService;
|
|
|
|
pub struct Container {
|
|
link: ComponentLink<Self>,
|
|
file_input: NodeRef,
|
|
audio_agent: Dispatcher<AudioAgent>,
|
|
zoom_factor: i32,
|
|
}
|
|
|
|
pub enum Msg {
|
|
SubmitForm,
|
|
ZoomButtonClicked(i32),
|
|
}
|
|
|
|
impl Component for Container {
|
|
type Message = Msg;
|
|
type Properties = ();
|
|
|
|
fn create(_: Self::Properties, link: ComponentLink<Self>) -> Self {
|
|
Self {
|
|
link,
|
|
file_input: NodeRef::default(),
|
|
audio_agent: AudioAgent::dispatcher(),
|
|
zoom_factor: 1,
|
|
}
|
|
}
|
|
|
|
fn update(&mut self, msg: Self::Message) -> ShouldRender {
|
|
match msg {
|
|
Msg::SubmitForm => {
|
|
if let Err(e) = self.handle_upload() {
|
|
ConsoleService::error(&e);
|
|
};
|
|
}
|
|
Msg::ZoomButtonClicked(factor) => {
|
|
self.zoom_factor = factor;
|
|
}
|
|
};
|
|
true
|
|
}
|
|
|
|
fn change(&mut self, _: Self::Properties) -> ShouldRender {
|
|
true
|
|
}
|
|
|
|
fn view(&self) -> Html {
|
|
html! {
|
|
<div id="waveform">
|
|
<Canvas zoom_factor=self.zoom_factor/>
|
|
|
|
<section id="controls" style="width: 800px; height: 100px; border: 1px solid grey">
|
|
<label>
|
|
{"Select an audio file"}
|
|
<input ref=self.file_input.clone() type="file"/>
|
|
</label>
|
|
<button onclick=self.link.callback(move |_| Msg::SubmitForm)>{"Open file"}</button>
|
|
|
|
<Player/>
|
|
</section>
|
|
|
|
<section>
|
|
<h3>{ "Zoom" }</h3>
|
|
<button onclick=self.link.callback(move |_| Msg::ZoomButtonClicked(1))>{ "1x" }</button>
|
|
<button onclick=self.link.callback(move |_| Msg::ZoomButtonClicked(2))>{ "2x" }</button>
|
|
<button onclick=self.link.callback(move |_| Msg::ZoomButtonClicked(4))>{ "4x" }</button>
|
|
<button onclick=self.link.callback(move |_| Msg::ZoomButtonClicked(8))>{ "8x" }</button>
|
|
<button onclick=self.link.callback(move |_| Msg::ZoomButtonClicked(16))>{ "16x" }</button>
|
|
<button onclick=self.link.callback(move |_| Msg::ZoomButtonClicked(32))>{ "32x" }</button>
|
|
</section>
|
|
</div>
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Container {
|
|
fn handle_upload(&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")?;
|
|
|
|
self.audio_agent
|
|
.send(audio_agent::Request::LoadSamplesFromFile(file));
|
|
|
|
Ok(())
|
|
}
|
|
}
|