376 lines
12 KiB
Rust
376 lines
12 KiB
Rust
use crate::error_template::{AppError, ErrorTemplate};
|
|
use cfg_if::*;
|
|
use leptos::*;
|
|
use leptos_meta::*;
|
|
use leptos_router::*;
|
|
|
|
cfg_if! {
|
|
if #[cfg(feature="ssr")]{
|
|
use surrealdb::sql::Thing;
|
|
use surrealdb::Surreal;
|
|
use surrealdb::engine::remote::ws::Ws;
|
|
use surrealdb::opt::auth::Root;
|
|
}
|
|
}
|
|
|
|
#[component]
|
|
pub fn App() -> impl IntoView {
|
|
// Provides context that manages stylesheets, titles, meta tags, etc.
|
|
provide_meta_context();
|
|
|
|
view! {
|
|
<Link
|
|
rel="stylesheet"
|
|
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css"
|
|
/>
|
|
|
|
<Stylesheet id="leptos" href="/pkg/wallpaper-gen-front-back.css"/>
|
|
|
|
// sets the document title
|
|
<Title text="Welcome to Leptos"/>
|
|
|
|
// content for this welcome page
|
|
<Router fallback=|| {
|
|
let mut outside_errors = Errors::default();
|
|
outside_errors.insert_with_default_key(AppError::NotFound);
|
|
view! { <ErrorTemplate outside_errors/> }.into_view()
|
|
}>
|
|
<main>
|
|
<Routes>
|
|
<Route path="/" view=Home/>
|
|
</Routes>
|
|
</main>
|
|
</Router>
|
|
}
|
|
}
|
|
|
|
#[component]
|
|
fn Home() -> impl IntoView {
|
|
use leptos::html::Div;
|
|
use leptos_use::*;
|
|
let (size, set_size) = create_signal(1.);
|
|
let (page, set_page) = create_signal(0);
|
|
//let res = create_local_resource(page, get_pics2);
|
|
let (all, set_all) = create_signal(Vec::<PicStruct>::new());
|
|
let res = create_local_resource(
|
|
move || (page.get(), size.get()),
|
|
move |d| get_pics2(d.0, d.1),
|
|
);
|
|
let el = create_node_ref::<Div>();
|
|
|
|
let _ = use_infinite_scroll_with_options(
|
|
el,
|
|
move |_| async move {
|
|
if !res.loading().get() && res().is_some() {
|
|
set_page.update(|page| *page += 1);
|
|
}
|
|
res.and_then(move |_| {
|
|
set_all.update(|dat| dat.extend(res().unwrap().unwrap()));
|
|
});
|
|
/*if !res.loading().get() {
|
|
set_page.update(|page| *page += 1);
|
|
} else if res().is_some() {
|
|
set_all.update(|dat| dat.extend(res().unwrap().unwrap()));
|
|
// println!("{:?}", all().len())
|
|
}*/
|
|
},
|
|
UseInfiniteScrollOptions::default().distance(10.0),
|
|
);
|
|
|
|
view! {
|
|
<h1>"Home"</h1>
|
|
<div>
|
|
<input
|
|
on:input=move |ev| {
|
|
set_size(event_target_value(&ev).parse::<f64>().unwrap());
|
|
}
|
|
|
|
prop:value=size
|
|
type="range"
|
|
min="0.5"
|
|
max="2"
|
|
step="0.5"
|
|
value="1"
|
|
/>
|
|
</div>
|
|
<div class="main overflow-y-auto max-h-300" node_ref=el>
|
|
<For each=move || all.get() key=|state| state.key.clone() let:child>
|
|
<Pic width=child.width height=child.height scale=size url=child.url/>
|
|
</For>
|
|
</div>
|
|
<div class="w-full">
|
|
<p class="text-center">{move || page()}</p>
|
|
</div>
|
|
}
|
|
}
|
|
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
|
pub struct PicStruct {
|
|
key: String,
|
|
width: i32,
|
|
height: i32,
|
|
url: String,
|
|
}
|
|
|
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
|
struct Wallpaper {
|
|
file_name: String,
|
|
info: String,
|
|
date_added: String,
|
|
height: u64,
|
|
width: u64,
|
|
path: String,
|
|
thumbs: Vec<String>,
|
|
}
|
|
|
|
#[derive(Debug, Serialize)]
|
|
struct Name<'a> {
|
|
first: &'a str,
|
|
last: &'a str,
|
|
}
|
|
|
|
#[derive(Debug, Serialize)]
|
|
struct Person<'a> {
|
|
title: &'a str,
|
|
name: Name<'a>,
|
|
marketing: bool,
|
|
}
|
|
|
|
#[derive(Debug, Serialize)]
|
|
struct Responsibility {
|
|
marketing: bool,
|
|
}
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
struct Record {
|
|
#[allow(dead_code)]
|
|
id: i32,
|
|
}
|
|
|
|
use std::env;
|
|
|
|
#[server(GetPics, "/api")]
|
|
pub async fn get_pics2(page: i32, size: f64) -> Result<Vec<PicStruct>, ServerFnError> {
|
|
use image::GenericImageView;
|
|
use imageinfo::ImageInfo;
|
|
use std::fs;
|
|
use std::path::PathBuf;
|
|
|
|
let query = "
|
|
SELECT * FROM wallpapers LIMIT 10;
|
|
";
|
|
|
|
let db = Surreal::new::<Ws>("127.0.0.1:8000")
|
|
.await
|
|
.expect("Couldnt connect to db server");
|
|
// Select a specific namespace / database
|
|
db.use_ns("test")
|
|
.use_db("test")
|
|
.await
|
|
.expect("Couldnt find db");
|
|
//let papers: Vec<Wallpaper> = db.select("wallpapers").await.expect("Err");
|
|
//println!("{papers:#?}");
|
|
|
|
let mut res = db.query(query).await?;
|
|
let pap: Vec<Wallpaper> = res.take(0)?;
|
|
println!("{pap:#?}");
|
|
|
|
let mut pics = Vec::new();
|
|
|
|
let folder_path = "./public";
|
|
|
|
// Define the number of pictures per page
|
|
let pics_per_page = 10;
|
|
|
|
// Calculate the index to start from based on the page number
|
|
let start_index = (page) * pics_per_page;
|
|
let end_index = start_index + pics_per_page;
|
|
|
|
// manage a vector with all the image paths
|
|
let mut image_file_paths = Vec::<PathBuf>::new();
|
|
for entry in fs::read_dir(folder_path)? {
|
|
let entry = entry?;
|
|
let file_path = entry.path();
|
|
let file_name_str = file_path.file_name().unwrap_or_default().to_str().unwrap();
|
|
if size == 0.5 {
|
|
//skip 1024 and 512
|
|
if file_name_str.contains("512x512") || file_name_str.contains("1024x1024") {
|
|
continue;
|
|
}
|
|
} else if size == 1.0 {
|
|
if file_name_str.contains("256x256") || file_name_str.contains("1024x1024") {
|
|
println!("sdfasdf");
|
|
continue;
|
|
}
|
|
} else if size == 1.5 {
|
|
if file_name_str.contains("256x256") || file_name_str.contains("512x512") {
|
|
continue;
|
|
}
|
|
}
|
|
image_file_paths.push(file_path.clone());
|
|
}
|
|
|
|
for (i, file_path) in image_file_paths.iter().enumerate() {
|
|
if file_path.is_file() {
|
|
if i < start_index as usize {
|
|
continue;
|
|
}
|
|
let file = std::fs::File::open(file_path)?;
|
|
let mut bufreader = std::io::BufReader::new(&file);
|
|
let exifreader = exif::Reader::new();
|
|
let exif = exifreader.read_from_container(&mut bufreader)?;
|
|
for f in exif.fields() {
|
|
println!(
|
|
"{} {} {}",
|
|
f.tag,
|
|
f.ifd_num,
|
|
f.display_value().with_unit(&exif)
|
|
);
|
|
}
|
|
let file_name = file_path.file_name().unwrap_or_default();
|
|
let file_name_str = file_name.to_str().unwrap();
|
|
// Check if the file has a supported image extension
|
|
if let Some(extension) = file_path.extension() {
|
|
if let Some(extension_str) = extension.to_str() {
|
|
if image::ImageFormat::from_extension(extension_str).is_some() {
|
|
// Process the image
|
|
let img = image::open(&file_path).expect("Failed to open image");
|
|
let (x, y) = img.dimensions();
|
|
|
|
pics.push(PicStruct {
|
|
key: file_name_str.to_string(), // Could not be unique if two images were created at exactly
|
|
// the same time
|
|
width: x as i32,
|
|
height: y as i32,
|
|
url: file_name.to_string_lossy().into(),
|
|
});
|
|
if i + 1 >= end_index as usize {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Send different picture resolutions depending on selected size
|
|
// sizes 256 512 1024
|
|
|
|
// Iterate over the entries in the folder
|
|
/*for (index, entry) in fs::read_dir(folder_path)
|
|
.expect("Failed to read directory")
|
|
.enumerate()
|
|
{
|
|
if let Ok(entry) = entry {
|
|
if index < start_index as usize {
|
|
// Skip pictures before the start index
|
|
continue;
|
|
}
|
|
|
|
let file_path = entry.path();
|
|
let file_name = file_path.file_name().unwrap_or_default();
|
|
let file_name_str = file_name.to_str().unwrap();
|
|
// Skip the wrong sizes
|
|
if size == 0.5 {
|
|
//skip 1024 and 512
|
|
if file_name_str.contains("512x512") || file_name_str.contains("1024x1024") {
|
|
continue;
|
|
}
|
|
} else if size == 1.0 {
|
|
if file_name_str.contains("256x256") || file_name_str.contains("1024x1024") {
|
|
continue;
|
|
}
|
|
} else if size == 1.5 {
|
|
if file_name_str.contains("256x256") || file_name_str.contains("512x512") {
|
|
continue;
|
|
}
|
|
}
|
|
|
|
// Check if the entry is a file
|
|
if file_path.is_file() {
|
|
// Check if the file has a supported image extension
|
|
if let Some(extension) = file_path.extension() {
|
|
if let Some(extension_str) = extension.to_str() {
|
|
if image::ImageFormat::from_extension(extension_str).is_some() {
|
|
// Process the image
|
|
let img = image::open(&file_path).expect("Failed to open image");
|
|
let (x, y) = img.dimensions();
|
|
|
|
pics.push(PicStruct {
|
|
key: file_name_str.to_string(), // Could not be unique if two images were created at exactly
|
|
// the same time
|
|
width: x as i32,
|
|
height: y as i32,
|
|
url: file_name.to_string_lossy().into(),
|
|
});
|
|
|
|
// Break if we have reached the end index
|
|
if index + 1 >= end_index as usize {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}*/
|
|
println!("{:#?}", pics);
|
|
|
|
Ok(pics)
|
|
}
|
|
|
|
#[component]
|
|
fn Info(show: ReadSignal<bool>, set_show: WriteSignal<bool>) -> impl IntoView {
|
|
view! {
|
|
<Show when=move || show()>
|
|
<div id="info-main" class="rounded">
|
|
<button type="button" on:click=move |_| set_show(false)>
|
|
"Close"
|
|
</button>
|
|
<input type="text" id="country" name="country" value="Norway" readonly/>
|
|
<br/>
|
|
<br/>
|
|
</div>
|
|
</Show>
|
|
}
|
|
}
|
|
|
|
#[component]
|
|
fn Pic(width: i32, height: i32, url: String, scale: ReadSignal<f64>) -> impl IntoView {
|
|
let (showInfo, set_showInfo) = create_signal(false);
|
|
|
|
view! {
|
|
<div
|
|
class="pic-outer"
|
|
// style="border:1px solid black;"
|
|
style:width=move || format!("{}px", f64::from(width + 10))
|
|
style:height=move || format!("{}px", f64::from(height + 10))
|
|
>
|
|
<div
|
|
class="pic-inner"
|
|
style=format!("background-image: url('{}'); background-size: cover;", url)
|
|
style:width=move || format!("{}px", f64::from(width))
|
|
style:height=move || format!("{}px", f64::from(height))
|
|
>
|
|
<div class="dropdown">
|
|
<button class="dropbtn">
|
|
<i class="fa-solid fa-download"></i>
|
|
</button>
|
|
<div class="dropdown-content">
|
|
<a href="https://google.com">16:9</a>
|
|
<a href="#">16:10</a>
|
|
<a href="#">4:3</a>
|
|
</div>
|
|
</div>
|
|
<button id="info-button" on:click=move |_| set_showInfo(true)>
|
|
<i class="fa-regular fa-circle-question"></i>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<Info show=showInfo set_show=set_showInfo/>
|
|
}
|
|
}
|
|
|