welcome leptos!
This commit is contained in:
parent
33ad2f14a7
commit
107c38d533
7 changed files with 1532 additions and 364 deletions
1752
Cargo.lock
generated
1752
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -8,12 +8,14 @@ edition = "2021"
|
|||
[dependencies]
|
||||
async-bincode = { version = "0.7.0", features = ["tokio"] }
|
||||
async_zip = { version = "0.0.13", features = ["deflate", "tokio", "tokio-fs", "async-compression"] }
|
||||
axum = { version = "0.6.12", features = ["multipart", "http2", "headers"] }
|
||||
axum = { version = "0.6.12", features = ["multipart", "http2", "headers", "macros"] }
|
||||
bincode = "1.3.3"
|
||||
chrono = { version = "0.4.24", features = ["serde"] }
|
||||
futures = "0.3.28"
|
||||
headers = "0.3.8"
|
||||
leptos = { version = "0.4.6", features = ["ssr", "nightly", "tracing", "default-tls"] }
|
||||
rand = { version = "0.8.5", features = ["small_rng"] }
|
||||
reqwest = { version = "0.11.18", features = ["json", "native-tls", "blocking"] }
|
||||
sanitize-filename-reader-friendly = "2.2.1"
|
||||
serde = { version = "1.0.160", features = ["serde_derive", "derive"] }
|
||||
serde_derive = "1.0.160"
|
||||
|
|
54
dist/index.html
vendored
54
dist/index.html
vendored
|
@ -1,54 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<title>NyaZoom</title>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link href="css/main.css" rel="stylesheet">
|
||||
<script>
|
||||
fetch("https://catfact.ninja/fact")
|
||||
.then(data => data.json())
|
||||
.then(data => {
|
||||
document.getElementById("cat-fact").innerHTML = data.fact;
|
||||
});
|
||||
</script>
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
let inputs = document.querySelectorAll('input#file');
|
||||
Array.prototype.forEach.call(inputs, function (input) {
|
||||
let label = input.nextElementSibling;
|
||||
let labelVal = label.innerHTML;
|
||||
input.addEventListener('change', function (e) {
|
||||
let fileName = '';
|
||||
|
||||
if (this.files?.length > 1) {
|
||||
fileName = this.getAttribute('data-multiple-caption')?.replace('{count}', this.files.length);
|
||||
} else {
|
||||
fileName = e.target.value.split('\\').pop();
|
||||
}
|
||||
|
||||
label.innerHTML = fileName || labelVal;
|
||||
});
|
||||
});
|
||||
}, false);
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>NyaZoom<sup>2</sup></h1>
|
||||
<div class="form-wrapper">
|
||||
<form action="/upload" method="post" enctype="multipart/form-data" class="main-form">
|
||||
<div class="cat-img-wrapper">
|
||||
<img class="cat-img" src="https://cataas.com/cat?width=250&height=250" />
|
||||
</div>
|
||||
<input type="file" id="file" name="file" data-multiple-caption="{count} files selected" multiple />
|
||||
<label for="file">Select Files</label>
|
||||
|
||||
<input type="submit" value="Get Link~">
|
||||
<p id="cat-fact" />
|
||||
</form>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
5
dist/scripts/cat_fact_fetcher.js
vendored
Normal file
5
dist/scripts/cat_fact_fetcher.js
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
fetch("https://catfact.ninja/fact")
|
||||
.then(data => data.json())
|
||||
.then(data => {
|
||||
document.getElementById("cat-fact").innerHTML = data.fact;
|
||||
});
|
18
dist/scripts/file_label.js
vendored
Normal file
18
dist/scripts/file_label.js
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
document.addEventListener("DOMContentLoaded", () => {
|
||||
let inputs = document.querySelectorAll('input#file');
|
||||
Array.prototype.forEach.call(inputs, function(input) {
|
||||
let label = input.nextElementSibling;
|
||||
let labelVal = label.innerHTML;
|
||||
input.addEventListener('change', function(e) {
|
||||
let fileName = '';
|
||||
|
||||
if (this.files?.length > 1) {
|
||||
fileName = this.getAttribute('data-multiple-caption')?.replace('{count}', this.files.length);
|
||||
} else {
|
||||
fileName = e.target.value.split('\\').pop();
|
||||
}
|
||||
|
||||
label.innerHTML = fileName || labelVal;
|
||||
});
|
||||
});
|
||||
}, false);
|
17
src/main.rs
17
src/main.rs
|
@ -5,7 +5,7 @@ use axum::{
|
|||
extract::{ConnectInfo, DefaultBodyLimit, Multipart, State},
|
||||
http::{Request, StatusCode},
|
||||
middleware::{self, Next},
|
||||
response::{IntoResponse, Redirect, Response},
|
||||
response::{Html, IntoResponse, Redirect, Response},
|
||||
routing::{get, post},
|
||||
Router, TypedHeader,
|
||||
};
|
||||
|
@ -31,9 +31,12 @@ mod cache;
|
|||
mod nyazoom_headers;
|
||||
mod state;
|
||||
mod util;
|
||||
mod views;
|
||||
|
||||
use state::{AppState, UploadRecord};
|
||||
|
||||
use crate::views::Welcome;
|
||||
|
||||
pub mod error {
|
||||
use std::io::{Error, ErrorKind};
|
||||
|
||||
|
@ -53,6 +56,8 @@ async fn main() -> io::Result<()> {
|
|||
.with(tracing_subscriber::fmt::layer())
|
||||
.init();
|
||||
|
||||
// tracing::info!("{}", get_cat_fact().await);
|
||||
|
||||
// uses create_dir_all to create both .cache and serve inside it in one go
|
||||
util::make_dir(".cache/serve").await?;
|
||||
|
||||
|
@ -60,6 +65,7 @@ async fn main() -> io::Result<()> {
|
|||
|
||||
// Router Setup
|
||||
let app = Router::new()
|
||||
.route("/", get(welcome))
|
||||
.route("/upload", post(upload_to_zip))
|
||||
.route("/download/:id", get(download))
|
||||
.layer(DefaultBodyLimit::disable())
|
||||
|
@ -67,7 +73,7 @@ async fn main() -> io::Result<()> {
|
|||
10 * 1024 * 1024 * 1024, // 10GiB
|
||||
))
|
||||
.with_state(state)
|
||||
.nest_service("/", ServeDir::new("dist"))
|
||||
.nest_service("/dist", ServeDir::new("dist"))
|
||||
.layer(TraceLayer::new_for_http())
|
||||
.layer(middleware::from_fn(log_source));
|
||||
|
||||
|
@ -82,6 +88,13 @@ async fn main() -> io::Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
async fn welcome() -> impl IntoResponse {
|
||||
let cat_fact = views::get_cat_fact().await;
|
||||
Html(leptos::ssr::render_to_string(move |cx| {
|
||||
leptos::view! { cx, <Welcome fact=cat_fact /> }
|
||||
}))
|
||||
}
|
||||
|
||||
async fn log_source<B>(
|
||||
ConnectInfo(addr): ConnectInfo<SocketAddr>,
|
||||
forwarded_for: Option<TypedHeader<ForwardedFor>>,
|
||||
|
|
46
src/views.rs
Normal file
46
src/views.rs
Normal file
|
@ -0,0 +1,46 @@
|
|||
use futures::TryFutureExt;
|
||||
use leptos::IntoView;
|
||||
use serde::Deserialize;
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct CatFact {
|
||||
pub fact: String,
|
||||
}
|
||||
|
||||
pub async fn get_cat_fact() -> String {
|
||||
reqwest::get("https://catfact.ninja/fact")
|
||||
.and_then(|res| res.json())
|
||||
.map_ok(|cf: CatFact| cf.fact)
|
||||
.await
|
||||
.unwrap_or_else(|_| String::from("The cat fact goddess has failed me :<"))
|
||||
}
|
||||
|
||||
#[leptos::component]
|
||||
pub fn Welcome(cx: leptos::Scope, fact: String) -> impl IntoView {
|
||||
leptos::view! { cx,
|
||||
<head>
|
||||
<title>NyaZoom</title>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<link href="dist/css/main.css" rel="stylesheet" />
|
||||
<script src="dist/scripts/file_label.js" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>NyaZoom<sup>2</sup></h1>
|
||||
<div class="form-wrapper">
|
||||
<form action="/upload" method="post" enctype="multipart/form-data" class="main-form">
|
||||
<div class="cat-img-wrapper">
|
||||
<img class="cat-img" src="https://cataas.com/cat?width=250&height=250" />
|
||||
</div>
|
||||
|
||||
<input type="file" id="file" name="file" data-multiple-caption="{{count}} files selected" multiple />
|
||||
<label for="file">Select Files</label>
|
||||
|
||||
<input type="submit" value="Get Link~" />
|
||||
<p id="cat-fact">{fact}</p>
|
||||
</form>
|
||||
</div>
|
||||
</body>
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue