forked from Zynh0722/nyazoom
welcome leptos!
parent
33ad2f14a7
commit
107c38d533
File diff suppressed because it is too large
Load Diff
|
@ -8,12 +8,14 @@ edition = "2021"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
async-bincode = { version = "0.7.0", features = ["tokio"] }
|
async-bincode = { version = "0.7.0", features = ["tokio"] }
|
||||||
async_zip = { version = "0.0.13", features = ["deflate", "tokio", "tokio-fs", "async-compression"] }
|
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"
|
bincode = "1.3.3"
|
||||||
chrono = { version = "0.4.24", features = ["serde"] }
|
chrono = { version = "0.4.24", features = ["serde"] }
|
||||||
futures = "0.3.28"
|
futures = "0.3.28"
|
||||||
headers = "0.3.8"
|
headers = "0.3.8"
|
||||||
|
leptos = { version = "0.4.6", features = ["ssr", "nightly", "tracing", "default-tls"] }
|
||||||
rand = { version = "0.8.5", features = ["small_rng"] }
|
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"
|
sanitize-filename-reader-friendly = "2.2.1"
|
||||||
serde = { version = "1.0.160", features = ["serde_derive", "derive"] }
|
serde = { version = "1.0.160", features = ["serde_derive", "derive"] }
|
||||||
serde_derive = "1.0.160"
|
serde_derive = "1.0.160"
|
||||||
|
|
|
@ -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>
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
fetch("https://catfact.ninja/fact")
|
||||||
|
.then(data => data.json())
|
||||||
|
.then(data => {
|
||||||
|
document.getElementById("cat-fact").innerHTML = data.fact;
|
||||||
|
});
|
|
@ -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},
|
extract::{ConnectInfo, DefaultBodyLimit, Multipart, State},
|
||||||
http::{Request, StatusCode},
|
http::{Request, StatusCode},
|
||||||
middleware::{self, Next},
|
middleware::{self, Next},
|
||||||
response::{IntoResponse, Redirect, Response},
|
response::{Html, IntoResponse, Redirect, Response},
|
||||||
routing::{get, post},
|
routing::{get, post},
|
||||||
Router, TypedHeader,
|
Router, TypedHeader,
|
||||||
};
|
};
|
||||||
|
@ -31,9 +31,12 @@ mod cache;
|
||||||
mod nyazoom_headers;
|
mod nyazoom_headers;
|
||||||
mod state;
|
mod state;
|
||||||
mod util;
|
mod util;
|
||||||
|
mod views;
|
||||||
|
|
||||||
use state::{AppState, UploadRecord};
|
use state::{AppState, UploadRecord};
|
||||||
|
|
||||||
|
use crate::views::Welcome;
|
||||||
|
|
||||||
pub mod error {
|
pub mod error {
|
||||||
use std::io::{Error, ErrorKind};
|
use std::io::{Error, ErrorKind};
|
||||||
|
|
||||||
|
@ -53,6 +56,8 @@ async fn main() -> io::Result<()> {
|
||||||
.with(tracing_subscriber::fmt::layer())
|
.with(tracing_subscriber::fmt::layer())
|
||||||
.init();
|
.init();
|
||||||
|
|
||||||
|
// tracing::info!("{}", get_cat_fact().await);
|
||||||
|
|
||||||
// uses create_dir_all to create both .cache and serve inside it in one go
|
// uses create_dir_all to create both .cache and serve inside it in one go
|
||||||
util::make_dir(".cache/serve").await?;
|
util::make_dir(".cache/serve").await?;
|
||||||
|
|
||||||
|
@ -60,6 +65,7 @@ async fn main() -> io::Result<()> {
|
||||||
|
|
||||||
// Router Setup
|
// Router Setup
|
||||||
let app = Router::new()
|
let app = Router::new()
|
||||||
|
.route("/", get(welcome))
|
||||||
.route("/upload", post(upload_to_zip))
|
.route("/upload", post(upload_to_zip))
|
||||||
.route("/download/:id", get(download))
|
.route("/download/:id", get(download))
|
||||||
.layer(DefaultBodyLimit::disable())
|
.layer(DefaultBodyLimit::disable())
|
||||||
|
@ -67,7 +73,7 @@ async fn main() -> io::Result<()> {
|
||||||
10 * 1024 * 1024 * 1024, // 10GiB
|
10 * 1024 * 1024 * 1024, // 10GiB
|
||||||
))
|
))
|
||||||
.with_state(state)
|
.with_state(state)
|
||||||
.nest_service("/", ServeDir::new("dist"))
|
.nest_service("/dist", ServeDir::new("dist"))
|
||||||
.layer(TraceLayer::new_for_http())
|
.layer(TraceLayer::new_for_http())
|
||||||
.layer(middleware::from_fn(log_source));
|
.layer(middleware::from_fn(log_source));
|
||||||
|
|
||||||
|
@ -82,6 +88,13 @@ async fn main() -> io::Result<()> {
|
||||||
Ok(())
|
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>(
|
async fn log_source<B>(
|
||||||
ConnectInfo(addr): ConnectInfo<SocketAddr>,
|
ConnectInfo(addr): ConnectInfo<SocketAddr>,
|
||||||
forwarded_for: Option<TypedHeader<ForwardedFor>>,
|
forwarded_for: Option<TypedHeader<ForwardedFor>>,
|
||||||
|
|
|
@ -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 New Issue