Files
photos/frontend/src/components/home.rs

154 lines
4.7 KiB
Rust

use super::BasePage;
use crate::gallery::Grid;
use crate::hooks::use_user_context;
use gloo_net::http::Request;
use js_sys::Array;
use serde::{Deserialize, Serialize};
use wasm_bindgen::{prelude::wasm_bindgen, JsCast, JsValue};
use web_sys::{DataTransferItemList, File, FileSystemDirectoryEntry, FileSystemEntry};
use weblog::console_log;
use yew::prelude::*;
use yew_hooks::prelude::*;
use common::OutputPicture;
#[derive(Debug, Deserialize, Serialize)]
pub struct PhotosWrapper {
photos: Vec<String>,
}
#[derive(Debug, Deserialize, Serialize)]
pub struct PhotosUrlsWrapper {
photos: Vec<(String, String)>,
}
#[function_component(Home)]
pub fn home() -> Html {
let user_ctx = use_user_context();
let node = use_node_ref();
let size = use_size(node.clone());
let pictures = use_state(std::vec::Vec::new);
{
let pictures = pictures.clone();
use_effect_with_deps(
move |_| {
wasm_bindgen_futures::spawn_local(async move {
let url = "/api/pictures/";
let fetched_pictures: Vec<OutputPicture> = Request::get(url)
.send()
.await
.unwrap()
.json()
.await
.unwrap();
pictures.set(fetched_pictures);
});
|| ()
},
(),
);
}
let ondrop = Callback::from(move |e: DragEvent| {
e.prevent_default();
let items = e.data_transfer().unwrap().items();
wasm_bindgen_futures::spawn_local(async move {
let promise = get_files_data_transfer_items(items);
let result = wasm_bindgen_futures::JsFuture::from(promise).await.unwrap();
console_log!(&result);
let traverse = |d: JsValue| {
let mut new_files: Vec<JsValue> = Vec::new();
let mut files: Vec<File> = Vec::new();
if let Ok(fse) = d.clone().dyn_into::<File>() {
console_log!(&fse);
// fse.filepath = path;
files.push(fse);
} else if let Ok(a) = d.clone().dyn_into::<js_sys::Array>() {
for i in 0..a.length() {
let f = a.get(i);
new_files.push(f);
}
} else if let Ok(o) = d.clone().dyn_into::<js_sys::Object>() {
if let Ok(subfolder) = js_sys::Reflect::get(&o, &JsValue::from_str("subfolder"))
{
new_files.push(subfolder);
}
}
(new_files, files)
};
let mut files: Vec<File> = Vec::new();
let mut new_files = vec![result];
loop {
console_log!(files.len());
let Some(current) = new_files.pop() else {
console_log!("break");
break;
};
let (news, fs) = traverse(current);
news.iter().for_each(|x| new_files.push(x.clone()));
fs.iter().for_each(|x| files.push(x.clone()));
}
let uiae: Vec<String> = files
.iter()
.map(|x| {
if let Ok(filepath) = js_sys::Reflect::get(x, &JsValue::from_str("filepath")) {
filepath.as_string().unwrap_or("".to_string())
} else {
"".to_string()
}
})
.collect();
console_log!("end", uiae.join("\n"));
let url = "/api/photos/upload";
let photos: PhotosUrlsWrapper = Request::post(url)
.json(&PhotosWrapper { photos: uiae })
.unwrap()
.send()
.await
.unwrap()
.json()
.await
.unwrap();
console_log!("{}", serde_json::to_string(&photos).unwrap());
});
});
let ondragover = Callback::from(move |e: DragEvent| {
e.prevent_default();
});
let body = if user_ctx.is_authenticated() {
html! {
<Grid
pictures={(*pictures).clone()}
width={size.0}
/>
}
} else {
html! {}
};
html! {
<BasePage>
<div ref={node} {ondrop} {ondragover}>
{body}
</div>
</BasePage>
}
}
#[wasm_bindgen(module = "/src/components/home.js")]
extern "C" {
fn get_files_data_transfer_items(data_transfer_items: DataTransferItemList) -> js_sys::Promise;
}