summaryrefslogtreecommitdiff
path: root/src/viewmodel/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/viewmodel/mod.rs')
-rw-r--r--src/viewmodel/mod.rs95
1 files changed, 94 insertions, 1 deletions
diff --git a/src/viewmodel/mod.rs b/src/viewmodel/mod.rs
index 75ed1d2..044dbad 100644
--- a/src/viewmodel/mod.rs
+++ b/src/viewmodel/mod.rs
@@ -1,3 +1,8 @@
+use wasm_bindgen::closure::Closure;
+use web_sys::FileReader;
+use wasm_bindgen::JsCast;
+use yew::services::ConsoleService;
+use crate::viewmodel::utility::File;
use yew::prelude::*;
use crate::view::VCardPropertyInputComponent;
@@ -50,7 +55,13 @@ pub enum VCardPropertyInputField {
placeholder: Option<String>,
oninput: Callback<InputData>,
value: String,
- typ: String
+ typ: String,
+ },
+ File {
+ label: String,
+ name: String,
+ callback: Callback<Option<File>>,
+ value: Option<File>,
},
CheckBox {
label: String,
@@ -72,6 +83,12 @@ impl VCardPropertyInputField {
value: _,
typ,
} => Self::text_field_input(label, id, placeholder, oninput, typ),
+ Self::File {
+ label,
+ name,
+ callback,
+ value,
+ } => Self::file_field_input(label, name, callback, value),
Self::CheckBox {
label,
id,
@@ -99,6 +116,82 @@ impl VCardPropertyInputField {
</div>
}
}
+ /// Returns an `Html` representation of a file input field with the given parameters.
+ fn file_field_input(label: &str, name: &str, callback: &Callback<Option<File>>, file: &Option<File>) -> Html {
+ let callback = callback.clone();
+ let onchange = Callback::<()>::default();
+ let onchange = onchange.reform(move |c: ChangeData|
+ if let ChangeData::Files(files) = c {
+ match files.item(0) {
+ Some(file) => {
+ let file_reader = FileReader::new().unwrap();
+ match file_reader.read_as_data_url(&file) {
+ Ok(_) => (),
+ Err(_) => ConsoleService::warn("Error: Couldn't get file as data url."),
+ };
+
+ let callback = callback.clone();
+ let onload = Closure::wrap(Box::new(move |event: Event|{
+ let file_reader: FileReader = event.target().unwrap().dyn_into().unwrap();
+ let data_url: Option<String> = file_reader.result().unwrap().as_string();
+ match data_url {
+ Some(content) => callback.emit(
+ Some(File {
+ name: file.name(),
+ content,
+ })
+ ),
+ None => {
+ ConsoleService::warn("Couldn't get data url as string.");
+ callback.emit(None);
+ },
+ };
+ }) as Box<dyn FnMut(_)>);
+
+ file_reader.set_onload(Some(onload.as_ref().unchecked_ref()));
+ onload.forget();
+ },
+ None => callback.emit(None),
+ }
+ } else {
+ callback.emit(None);
+ }
+ );
+ html!{
+ <div class="field column
+ is-one-fifth-widescreen
+ is-one-quarter-desktop
+ is-one-third-tablet
+ is-half-mobile" >
+ <label class="label">{ label }</label>
+ <div class="file has-name control">
+ <label class="file-label">
+ <input class="file-input"
+ type="file"
+ name=name
+ onchange=onchange
+ />
+ <span class="file-cta">
+ <span class="file-icon">
+ <i class="fas fa-upload"></i>
+ </span>
+ <span class="file-label">
+ { "Choose file..." }
+ </span>
+ </span>
+ <span class="file-name">
+ {
+ match file {
+ Some(file) => file.name.clone(),
+ None => String::from("No file selected"),
+ }
+ }
+ </span>
+ </label>
+ </div>
+ </div>
+ }
+ }
/// Returns an `Html` representation of a checkbox input field with the given parameters.
fn checkbox_field_input(label: &str, id: &Option<String>, checked: &bool, onclick: &Callback<MouseEvent>) -> Html {
html!{