use crate::*;
pub(crate) fn use_file_upload() -> UseFileUpload {
UseFileUpload::new(
use_signal(Vec::new),
use_signal(Vec::new),
use_signal(Vec::new),
use_signal(|| false),
use_signal(String::new),
use_signal(|| false),
use_signal(|| "No files selected".to_string()),
)
}
pub(crate) fn file_upload_on_change(state: UseFileUpload) -> Option<Rc<dyn Fn(Event)>> {
Some(Rc::new(move |event: Event| {
if let Some(target) = event.target()
&& let Ok(input) = target.clone().dyn_into::<HtmlInputElement>()
{
let file_list: Option<FileList> = input.files();
let names: Vec<String>;
let sizes: Vec<f64>;
let types: Vec<String>;
match file_list {
Some(files) => {
let count: u32 = files.length();
names = (0..count)
.filter_map(|index: u32| files.get(index).map(|file: File| file.name()))
.collect();
sizes = (0..count)
.filter_map(|index: u32| files.get(index).map(|file: File| file.size()))
.collect();
types = (0..count)
.filter_map(|index: u32| files.get(index).map(|file: File| file.type_()))
.collect();
}
None => {
names = Vec::new();
sizes = Vec::new();
types = Vec::new();
}
}
state.get_file_names().set(names.clone());
state.get_file_sizes().set(sizes);
state.get_file_types().set(types);
if names.is_empty() {
state.get_status().set("No files selected".to_string());
} else {
let count: usize = names.len();
state
.get_status()
.set(format!("{} file(s) selected", count));
Console::log(&format!("Files selected: {:?}", names));
}
}
}))
}
pub(crate) fn file_upload_on_clear(state: UseFileUpload) -> Option<Rc<dyn Fn(Event)>> {
Some(Rc::new(move |_event: Event| {
state.get_file_names().set(Vec::new());
state.get_file_sizes().set(Vec::new());
state.get_file_types().set(Vec::new());
state.get_drag_over().set(false);
state.get_status().set("No files selected".to_string());
}))
}
pub(crate) fn file_upload_on_drag_enter(state: UseFileUpload) -> Option<Rc<dyn Fn(Event)>> {
Some(Rc::new(move |_event: Event| {
state.get_drag_over().set(true);
}))
}
pub(crate) fn file_upload_on_drag_leave(state: UseFileUpload) -> Option<Rc<dyn Fn(Event)>> {
Some(Rc::new(move |_event: Event| {
state.get_drag_over().set(false);
}))
}
pub(crate) fn file_upload_on_drag_over(state: UseFileUpload) -> Option<Rc<dyn Fn(Event)>> {
Some(Rc::new(move |_event: Event| {
state.get_drag_over().set(true);
}))
}
pub(crate) fn file_upload_on_drop(state: UseFileUpload) -> Option<Rc<dyn Fn(Event)>> {
Some(Rc::new(move |event: Event| {
state.get_drag_over().set(false);
if let Some(drag_event) = event.dyn_ref::<DragEvent>() {
let has_files: bool = drag_event
.data_transfer()
.map(|data_transfer: DataTransfer| {
let type_count: u32 = data_transfer.types().length();
(0..type_count).any(|index: u32| {
data_transfer.types().get(index).as_string() == Some("Files".to_string())
})
})
.unwrap_or(false);
if has_files {
state
.get_status()
.set("File(s) dropped - reading file names requires JS interop".to_string());
Console::log("Drop: files detected in data transfer");
} else {
state.get_status().set("No files in drop data".to_string());
}
}
}))
}