audioview/frontend/core/src/components/waveform/container.rs

106 lines
3.1 KiB
Rust

use super::canvas::Canvas;
use crate::agents::audio_agent::{self, AudioAgent};
use crate::components::Player;
use web_sys::{File, HtmlInputElement};
use yew::agent::Dispatcher;
use yew::prelude::*;
use yew::services::ConsoleService;
use wasm_bindgen::prelude::*;
use weblog::*;
#[wasm_bindgen(module = "/static/player.js")]
extern "C" {
fn get_val() -> i32;
fn load_file(file: &str) -> i32;
}
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")?;
load_file("oh!");
console_log!("Done.");
Ok(())
}
}