working(ish) upload

This commit is contained in:
2026-03-26 15:59:54 +01:00
parent 2d19e3b5d7
commit cd030a6c44
21 changed files with 651 additions and 126 deletions

2
.gitignore vendored
View File

@ -5,3 +5,5 @@
# These are backup files generated by rustfmt # These are backup files generated by rustfmt
**/*.rs.bk **/*.rs.bk
serveurhttp
test

273
Cargo.lock generated
View File

@ -128,6 +128,28 @@ version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
[[package]]
name = "aws-lc-rs"
version = "1.16.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a054912289d18629dc78375ba2c3726a3afe3ff71b4edba9dedfca0e3446d1fc"
dependencies = [
"aws-lc-sys",
"zeroize",
]
[[package]]
name = "aws-lc-sys"
version = "0.39.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fa7e52a4c5c547c741610a2c6f123f3881e409b714cd27e6798ef020c514f0a"
dependencies = [
"cc",
"cmake",
"dunce",
"fs_extra",
]
[[package]] [[package]]
name = "axum" name = "axum"
version = "0.8.8" version = "0.8.8"
@ -323,6 +345,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aebf35691d1bfb0ac386a69bac2fde4dd276fb618cf8bf4f5318fe285e821bb2" checksum = "aebf35691d1bfb0ac386a69bac2fde4dd276fb618cf8bf4f5318fe285e821bb2"
dependencies = [ dependencies = [
"find-msvc-tools", "find-msvc-tools",
"jobserver",
"libc",
"shlex", "shlex",
] ]
@ -415,6 +439,15 @@ dependencies = [
"half", "half",
] ]
[[package]]
name = "cmake"
version = "0.1.57"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75443c44cd6b379beb8c5b45d85d0773baf31cce901fe7bb252f4eff3008ef7d"
dependencies = [
"cc",
]
[[package]] [[package]]
name = "cocoa" name = "cocoa"
version = "0.26.1" version = "0.26.1"
@ -887,6 +920,17 @@ dependencies = [
"web-sys", "web-sys",
] ]
[[package]]
name = "dioxus-attributes"
version = "0.1.0"
source = "git+https://github.com/DioxusLabs/components#6ed7699b85fa4f4f50381138fc9d16e988768933"
dependencies = [
"dioxus-rsx",
"proc-macro2",
"quote",
"syn 2.0.117",
]
[[package]] [[package]]
name = "dioxus-cli-config" name = "dioxus-cli-config"
version = "0.7.3" version = "0.7.3"
@ -981,7 +1025,7 @@ dependencies = [
"global-hotkey", "global-hotkey",
"infer", "infer",
"jni 0.21.1", "jni 0.21.1",
"lazy-js-bundle", "lazy-js-bundle 0.7.3",
"libc", "libc",
"muda", "muda",
"ndk", "ndk",
@ -1052,7 +1096,7 @@ dependencies = [
"futures-channel", "futures-channel",
"futures-util", "futures-util",
"generational-box", "generational-box",
"lazy-js-bundle", "lazy-js-bundle 0.7.3",
"serde", "serde",
"serde_json", "serde_json",
"tracing", "tracing",
@ -1098,7 +1142,7 @@ dependencies = [
"js-sys", "js-sys",
"mime", "mime",
"pin-project", "pin-project",
"reqwest", "reqwest 0.12.28",
"rustversion", "rustversion",
"send_wrapper", "send_wrapper",
"serde", "serde",
@ -1118,7 +1162,7 @@ dependencies = [
"url", "url",
"wasm-bindgen", "wasm-bindgen",
"wasm-bindgen-futures", "wasm-bindgen-futures",
"wasm-streams", "wasm-streams 0.4.2",
"web-sys", "web-sys",
"xxhash-rust", "xxhash-rust",
] ]
@ -1210,7 +1254,7 @@ dependencies = [
"futures-util", "futures-util",
"generational-box", "generational-box",
"keyboard-types", "keyboard-types",
"lazy-js-bundle", "lazy-js-bundle 0.7.3",
"rustversion", "rustversion",
"serde", "serde",
"serde_json", "serde_json",
@ -1240,7 +1284,7 @@ dependencies = [
"dioxus-core-types", "dioxus-core-types",
"dioxus-html", "dioxus-html",
"js-sys", "js-sys",
"lazy-js-bundle", "lazy-js-bundle 0.7.3",
"rustc-hash 2.1.1", "rustc-hash 2.1.1",
"serde", "serde",
"sledgehammer_bindgen", "sledgehammer_bindgen",
@ -1290,6 +1334,21 @@ dependencies = [
"tracing-wasm", "tracing-wasm",
] ]
[[package]]
name = "dioxus-primitives"
version = "0.0.1"
source = "git+https://github.com/DioxusLabs/components#6ed7699b85fa4f4f50381138fc9d16e988768933"
dependencies = [
"dioxus",
"dioxus-attributes",
"dioxus-sdk-time",
"lazy-js-bundle 0.6.2",
"num-integer",
"serde",
"time",
"tracing",
]
[[package]] [[package]]
name = "dioxus-router" name = "dioxus-router"
version = "0.7.3" version = "0.7.3"
@ -1339,6 +1398,18 @@ dependencies = [
"syn 2.0.117", "syn 2.0.117",
] ]
[[package]]
name = "dioxus-sdk-time"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "80c25ae93a3f72e734873b97fbd09d9b1b6adff97205fb0ffd8543e3564fb78e"
dependencies = [
"dioxus",
"futures",
"gloo-timers",
"tokio",
]
[[package]] [[package]]
name = "dioxus-server" name = "dioxus-server"
version = "0.7.3" version = "0.7.3"
@ -1470,7 +1541,7 @@ dependencies = [
"generational-box", "generational-box",
"gloo-timers", "gloo-timers",
"js-sys", "js-sys",
"lazy-js-bundle", "lazy-js-bundle 0.7.3",
"rustc-hash 2.1.1", "rustc-hash 2.1.1",
"send_wrapper", "send_wrapper",
"serde", "serde",
@ -1479,7 +1550,7 @@ dependencies = [
"tracing", "tracing",
"wasm-bindgen", "wasm-bindgen",
"wasm-bindgen-futures", "wasm-bindgen-futures",
"wasm-streams", "wasm-streams 0.4.2",
"web-sys", "web-sys",
] ]
@ -1642,6 +1713,15 @@ dependencies = [
"serde", "serde",
] ]
[[package]]
name = "fastrand"
version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be"
dependencies = [
"instant",
]
[[package]] [[package]]
name = "fastrand" name = "fastrand"
version = "2.3.0" version = "2.3.0"
@ -1752,6 +1832,12 @@ dependencies = [
"percent-encoding", "percent-encoding",
] ]
[[package]]
name = "fs_extra"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c"
[[package]] [[package]]
name = "futf" name = "futf"
version = "0.1.5" version = "0.1.5"
@ -2390,6 +2476,14 @@ name = "httpserver"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"dioxus", "dioxus",
"dioxus-html",
"dioxus-primitives",
"futures",
"random-string",
"reqwest 0.13.2",
"tracing",
"wasm-bindgen",
"web-sys",
] ]
[[package]] [[package]]
@ -2617,6 +2711,15 @@ dependencies = [
"cfb", "cfb",
] ]
[[package]]
name = "instant"
version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222"
dependencies = [
"cfg-if",
]
[[package]] [[package]]
name = "inventory" name = "inventory"
version = "0.3.22" version = "0.3.22"
@ -2742,6 +2845,16 @@ dependencies = [
"syn 2.0.117", "syn 2.0.117",
] ]
[[package]]
name = "jobserver"
version = "0.1.34"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33"
dependencies = [
"getrandom 0.3.4",
"libc",
]
[[package]] [[package]]
name = "js-sys" name = "js-sys"
version = "0.3.91" version = "0.3.91"
@ -2775,6 +2888,12 @@ dependencies = [
"selectors", "selectors",
] ]
[[package]]
name = "lazy-js-bundle"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e49596223b9d9d4947a14a25c142a6e7d8ab3f27eb3ade269d238bb8b5c267e2"
[[package]] [[package]]
name = "lazy-js-bundle" name = "lazy-js-bundle"
version = "0.7.3" version = "0.7.3"
@ -3210,6 +3329,15 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf97ec579c3c42f953ef76dbf8d55ac91fb219dde70e49aa4a6b7d74e9919050" checksum = "cf97ec579c3c42f953ef76dbf8d55ac91fb219dde70e49aa4a6b7d74e9919050"
[[package]]
name = "num-integer"
version = "0.1.46"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f"
dependencies = [
"num-traits",
]
[[package]] [[package]]
name = "num-traits" name = "num-traits"
version = "0.2.19" version = "0.2.19"
@ -3241,6 +3369,15 @@ dependencies = [
"syn 2.0.117", "syn 2.0.117",
] ]
[[package]]
name = "num_threads"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9"
dependencies = [
"libc",
]
[[package]] [[package]]
name = "objc" name = "objc"
version = "0.2.7" version = "0.2.7"
@ -3805,6 +3942,7 @@ version = "0.11.14"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "434b42fec591c96ef50e21e886936e66d3cc3f737104fdb9b737c40ffb94c098" checksum = "434b42fec591c96ef50e21e886936e66d3cc3f737104fdb9b737c40ffb94c098"
dependencies = [ dependencies = [
"aws-lc-rs",
"bytes", "bytes",
"getrandom 0.3.4", "getrandom 0.3.4",
"lru-slab", "lru-slab",
@ -3965,6 +4103,15 @@ dependencies = [
"rand_core 0.5.1", "rand_core 0.5.1",
] ]
[[package]]
name = "random-string"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f70fd13c3024ae3f17381bb5c4d409c6dc9ea6895c08fa2147aba305bea3c4af"
dependencies = [
"fastrand 1.9.0",
]
[[package]] [[package]]
name = "raw-window-handle" name = "raw-window-handle"
version = "0.5.2" version = "0.5.2"
@ -4053,11 +4200,52 @@ dependencies = [
"url", "url",
"wasm-bindgen", "wasm-bindgen",
"wasm-bindgen-futures", "wasm-bindgen-futures",
"wasm-streams", "wasm-streams 0.4.2",
"web-sys", "web-sys",
"webpki-roots", "webpki-roots",
] ]
[[package]]
name = "reqwest"
version = "0.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab3f43e3283ab1488b624b44b0e988d0acea0b3214e694730a055cb6b2efa801"
dependencies = [
"base64",
"bytes",
"encoding_rs",
"futures-core",
"futures-util",
"h2",
"http",
"http-body",
"http-body-util",
"hyper",
"hyper-rustls",
"hyper-util",
"js-sys",
"log",
"mime",
"percent-encoding",
"pin-project-lite",
"quinn",
"rustls",
"rustls-pki-types",
"rustls-platform-verifier",
"sync_wrapper",
"tokio",
"tokio-rustls",
"tokio-util",
"tower",
"tower-http",
"tower-service",
"url",
"wasm-bindgen",
"wasm-bindgen-futures",
"wasm-streams 0.5.0",
"web-sys",
]
[[package]] [[package]]
name = "rfd" name = "rfd"
version = "0.17.2" version = "0.17.2"
@ -4136,6 +4324,7 @@ version = "0.23.37"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "758025cb5fccfd3bc2fd74708fd4682be41d99e5dff73c377c0646c6012c73a4" checksum = "758025cb5fccfd3bc2fd74708fd4682be41d99e5dff73c377c0646c6012c73a4"
dependencies = [ dependencies = [
"aws-lc-rs",
"once_cell", "once_cell",
"ring", "ring",
"rustls-pki-types", "rustls-pki-types",
@ -4144,6 +4333,18 @@ dependencies = [
"zeroize", "zeroize",
] ]
[[package]]
name = "rustls-native-certs"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "612460d5f7bea540c490b2b6395d8e34a953e52b491accd6c86c8164c5932a63"
dependencies = [
"openssl-probe",
"rustls-pki-types",
"schannel",
"security-framework",
]
[[package]] [[package]]
name = "rustls-pki-types" name = "rustls-pki-types"
version = "1.14.0" version = "1.14.0"
@ -4154,12 +4355,40 @@ dependencies = [
"zeroize", "zeroize",
] ]
[[package]]
name = "rustls-platform-verifier"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d99feebc72bae7ab76ba994bb5e121b8d83d910ca40b36e0921f53becc41784"
dependencies = [
"core-foundation 0.10.1",
"core-foundation-sys",
"jni 0.21.1",
"log",
"once_cell",
"rustls",
"rustls-native-certs",
"rustls-platform-verifier-android",
"rustls-webpki",
"security-framework",
"security-framework-sys",
"webpki-root-certs",
"windows-sys 0.61.2",
]
[[package]]
name = "rustls-platform-verifier-android"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f"
[[package]] [[package]]
name = "rustls-webpki" name = "rustls-webpki"
version = "0.103.9" version = "0.103.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7df23109aa6c1567d1c575b9952556388da57401e4ace1d15f79eedad0d8f53" checksum = "d7df23109aa6c1567d1c575b9952556388da57401e4ace1d15f79eedad0d8f53"
dependencies = [ dependencies = [
"aws-lc-rs",
"ring", "ring",
"rustls-pki-types", "rustls-pki-types",
"untrusted", "untrusted",
@ -4762,7 +4991,7 @@ version = "3.26.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "82a72c767771b47409d2345987fda8628641887d5466101319899796367354a0" checksum = "82a72c767771b47409d2345987fda8628641887d5466101319899796367354a0"
dependencies = [ dependencies = [
"fastrand", "fastrand 2.3.0",
"getrandom 0.4.2", "getrandom 0.4.2",
"once_cell", "once_cell",
"rustix", "rustix",
@ -4837,7 +5066,9 @@ checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c"
dependencies = [ dependencies = [
"deranged", "deranged",
"itoa", "itoa",
"libc",
"num-conv", "num-conv",
"num_threads",
"powerfmt", "powerfmt",
"serde_core", "serde_core",
"time-core", "time-core",
@ -5487,6 +5718,19 @@ dependencies = [
"web-sys", "web-sys",
] ]
[[package]]
name = "wasm-streams"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d1ec4f6517c9e11ae630e200b2b65d193279042e28edd4a2cda233e46670bbb"
dependencies = [
"futures-util",
"js-sys",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
]
[[package]] [[package]]
name = "wasmparser" name = "wasmparser"
version = "0.244.0" version = "0.244.0"
@ -5579,6 +5823,15 @@ dependencies = [
"system-deps", "system-deps",
] ]
[[package]]
name = "webpki-root-certs"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "804f18a4ac2676ffb4e8b5b5fa9ae38af06df08162314f96a68d2a363e21a8ca"
dependencies = [
"rustls-pki-types",
]
[[package]] [[package]]
name = "webpki-roots" name = "webpki-roots"
version = "1.0.6" version = "1.0.6"

View File

@ -8,6 +8,14 @@ edition = "2021"
[dependencies] [dependencies]
dioxus = { version = "0.7.1", features = ["router", "fullstack"] } dioxus = { version = "0.7.1", features = ["router", "fullstack"] }
dioxus-html = "0.7.3"
dioxus-primitives = { git = "https://github.com/DioxusLabs/components", version = "0.0.1", default-features = false }
futures = "0.3.32"
random-string = "1.1.0"
reqwest = { version = "0.13.2", features = ["stream"] }
tracing = "0.1.44"
wasm-bindgen = "0.2.114"
web-sys = { version = "0.3.91", features = ["XmlHttpRequest", "XmlHttpRequestUpload", "ProgressEvent" ] }
[features] [features]
default = ["web"] default = ["web"]
@ -19,3 +27,11 @@ desktop = ["dioxus/desktop"]
mobile = ["dioxus/mobile"] mobile = ["dioxus/mobile"]
# The feature that are only required for the server = ["dioxus/server"] build target should be optional and only enabled in the server = ["dioxus/server"] feature # The feature that are only required for the server = ["dioxus/server"] build target should be optional and only enabled in the server = ["dioxus/server"] feature
server = ["dioxus/server"] server = ["dioxus/server"]
[profile.release]
opt-level = "z"
debug = false
lto = true
codegen-units = 1
panic = "abort"
incremental = false

View File

@ -0,0 +1,87 @@
/* This file contains the global styles for the styled dioxus components. You only
* need to import this file once in your project root.
*/
@import url("https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap");
body {
color: var(--secondary-color-4);
font-family: Inter, sans-serif;
font-optical-sizing: auto;
font-style: normal;
font-weight: 400;
}
html[data-theme="dark"] {
--dark: initial;
--light: ;
}
html[data-theme="light"] {
--dark: ;
--light: initial;
}
@media (prefers-color-scheme: dark) {
:root {
--dark: initial;
--light: ;
}
}
@media (prefers-color-scheme: light) {
:root {
--dark: ;
--light: initial;
}
}
:root {
/* Primary colors */
--primary-color: var(--dark, #000) var(--light, #fff);
--primary-color-1: var(--dark, #0e0e0e) var(--light, #fbfbfb);
--primary-color-2: var(--dark, #0a0a0a) var(--light, #fff);
--primary-color-3: var(--dark, #141313) var(--light, #f8f8f8);
--primary-color-4: var(--dark, #1a1a1a) var(--light, #f8f8f8);
--primary-color-5: var(--dark, #262626) var(--light, #f5f5f5);
--primary-color-6: var(--dark, #232323) var(--light, #e5e5e5);
--primary-color-7: var(--dark, #3e3e3e) var(--light, #b0b0b0);
/* Secondary colors */
--secondary-color: var(--dark, #fff) var(--light, #000);
--secondary-color-1: var(--dark, #fafafa) var(--light, #000);
--secondary-color-2: var(--dark, #e6e6e6) var(--light, #0d0d0d);
--secondary-color-3: var(--dark, #dcdcdc) var(--light, #2b2b2b);
--secondary-color-4: var(--dark, #d4d4d4) var(--light, #111);
--secondary-color-5: var(--dark, #a1a1a1) var(--light, #848484);
--secondary-color-6: var(--dark, #5d5d5d) var(--light, #d0d0d0);
/* Highlight colors */
--focused-border-color: var(--dark, #2b7fff) var(--light, #2b7fff);
--primary-success-color: var(--dark, #02271c) var(--light, #ecfdf5);
--secondary-success-color: var(--dark, #b6fae3) var(--light, #10b981);
--primary-warning-color: var(--dark, #342203) var(--light, #fffbeb);
--secondary-warning-color: var(--dark, #feeac7) var(--light, #f59e0b);
--primary-error-color: var(--dark, #a22e2e) var(--light, #dc2626);
--secondary-error-color: var(--dark, #9b1c1c) var(--light, #ef4444);
--contrast-error-color: var(--dark, var(--secondary-color-3)) var(--light, var(--primary-color));
--primary-info-color: var(--dark, var(--primary-color-5)) var(--light, var(--primary-color));
--secondary-info-color: var(--dark, var(--primary-color-7)) var(--light, var(--secondary-color-3));
}
/* Modern browsers with `scrollbar-*` support */
@supports (scrollbar-width: auto) {
:not(:hover) {
scrollbar-color: rgb(0 0 0 / 0%) rgb(0 0 0 / 0%);
}
:hover {
scrollbar-color: var(--secondary-color-2) rgb(0 0 0 / 0%);
}
}
/* Legacy browsers with `::-webkit-scrollbar-*` support */
@supports selector(::-webkit-scrollbar) {
:root::-webkit-scrollbar-track {
background: transparent;
}
}

View File

@ -1,8 +0,0 @@
#blog {
margin-top: 50px;
}
#blog a {
color: #ffffff;
margin-top: 50px;
}

View File

@ -1,34 +0,0 @@
#echo {
width: 360px;
margin-left: auto;
margin-right: auto;
margin-top: 50px;
background-color: #1e222d;
padding: 20px;
border-radius: 10px;
}
#echo>h4 {
margin: 0px 0px 15px 0px;
}
#echo>input {
border: none;
border-bottom: 1px white solid;
background-color: transparent;
color: #ffffff;
transition: border-bottom-color 0.2s ease;
outline: none;
display: block;
padding: 0px 0px 5px 0px;
width: 100%;
}
#echo>input:focus {
border-bottom-color: #6d85c6;
}
#echo>p {
margin: 20px 0px 0px auto;
}

View File

@ -1,42 +0,0 @@
body {
background-color: #0f1116;
color: #ffffff;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
margin: 20px;
}
#hero {
margin: 0;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
#links {
width: 400px;
text-align: left;
font-size: x-large;
color: white;
display: flex;
flex-direction: column;
}
#links a {
color: white;
text-decoration: none;
margin-top: 20px;
margin: 10px 0px;
border: white 1px solid;
border-radius: 5px;
padding: 10px;
}
#links a:hover {
background-color: #1f1f1f;
cursor: pointer;
}
#header {
max-width: 1200px;
}

View File

@ -1,16 +0,0 @@
#navbar {
display: flex;
flex-direction: row;
}
#navbar a {
color: #ffffff;
margin-right: 20px;
text-decoration: none;
transition: color 0.2s ease;
}
#navbar a:hover {
cursor: pointer;
color: #91a4d2;
}

View File

@ -7,6 +7,10 @@
'Noto Color Emoji'; 'Noto Color Emoji';
--font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', --font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New',
monospace; monospace;
--spacing: 0.25rem;
--text-4xl: 2.25rem;
--text-4xl--line-height: calc(2.5 / 2.25);
--font-weight-bold: 700;
--default-font-family: var(--font-sans); --default-font-family: var(--font-sans);
--default-mono-font-family: var(--font-mono); --default-mono-font-family: var(--font-mono);
} }
@ -160,18 +164,41 @@
.visible { .visible {
visibility: visible; visibility: visible;
} }
.relative { .m-0 {
position: relative; margin: calc(var(--spacing) * 0);
} }
.block { .hidden {
display: block; display: none;
} }
.contents { .table {
display: contents; display: table;
}
.w-1 {
width: calc(var(--spacing) * 1);
} }
.transform { .transform {
transform: var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,); transform: var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,);
} }
.p-1 {
padding: calc(var(--spacing) * 1);
}
.p-2 {
padding: calc(var(--spacing) * 2);
}
.px-2 {
padding-inline: calc(var(--spacing) * 2);
}
.ps-6 {
padding-inline-start: calc(var(--spacing) * 6);
}
.text-4xl {
font-size: var(--text-4xl);
line-height: var(--tw-leading, var(--text-4xl--line-height));
}
.font-bold {
--tw-font-weight: var(--font-weight-bold);
font-weight: var(--font-weight-bold);
}
} }
@property --tw-rotate-x { @property --tw-rotate-x {
syntax: "*"; syntax: "*";
@ -193,6 +220,10 @@
syntax: "*"; syntax: "*";
inherits: false; inherits: false;
} }
@property --tw-font-weight {
syntax: "*";
inherits: false;
}
@layer properties { @layer properties {
@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))) { @supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))) {
*, ::before, ::after, ::backdrop { *, ::before, ::after, ::backdrop {
@ -201,6 +232,7 @@
--tw-rotate-z: initial; --tw-rotate-z: initial;
--tw-skew-x: initial; --tw-skew-x: initial;
--tw-skew-y: initial; --tw-skew-y: initial;
--tw-font-weight: initial;
} }
} }
} }

View File

@ -5,6 +5,12 @@ pkgs.mkShell {
]; ];
nativeBuildInputs = with pkgs;[ nativeBuildInputs = with pkgs;[
openssl openssl
glib
gdk-pixbuf
pango
atk
xdo
lld
]; ];
PKG_CONFIG_PATH = "${pkgs.openssl.dev}/lib/pkgconfig"; PKG_CONFIG_PATH = "${pkgs.openssl.dev}/lib/pkgconfig";
} }

View File

@ -1,13 +1,13 @@
use dioxus::prelude::*; use dioxus::prelude::*;
const ECHO_CSS: Asset = asset!("/assets/styling/echo.css"); //const ECHO_CSS: Asset = asset!("/assets/styling/echo.css");
#[component] #[component]
pub fn Echo() -> Element { pub fn Echo() -> Element {
let mut response = use_signal(|| String::new()); let mut response = use_signal(|| String::new());
rsx! { rsx! {
document::Link { rel: "stylesheet", href: ECHO_CSS } // document::Link { rel: "stylesheet", href: ECHO_CSS }
div { div {
id: "echo", id: "echo",

View File

@ -4,3 +4,4 @@ pub use hero::Hero;
mod echo; mod echo;
pub use echo::Echo; pub use echo::Echo;
pub mod progress;

View File

@ -0,0 +1,23 @@
use dioxus::prelude::*;
use dioxus_primitives::progress::{self, ProgressIndicatorProps, ProgressProps};
#[component]
pub fn Progress(props: ProgressProps) -> Element {
rsx! {
document::Link { rel: "stylesheet", href: asset!("./style.css") }
progress::Progress {
class: "progress",
value: props.value,
max: props.max,
attributes: props.attributes,
{props.children}
}
}
}
#[component]
pub fn ProgressIndicator(props: ProgressIndicatorProps) -> Element {
rsx! {
progress::ProgressIndicator { class: "progress-indicator", attributes: props.attributes, {props.children} }
}
}

View File

@ -0,0 +1,2 @@
mod component;
pub use component::*;

View File

@ -0,0 +1,31 @@
.progress {
position: relative;
overflow: hidden;
width: 200px;
height: .5rem;
box-sizing: border-box;
border-radius: 9999px;
background: var(--primary-color-5);
}
.progress[data-state='indeterminate'] .progress-indicator {
width: 50%;
animation: indeterminate 1s infinite linear;
}
.progress-indicator {
width: var(--progress-value, 0%);
height: 100%;
background-color: var(--secondary-color-1);
transition: width 250ms ease;
}
@keyframes indeterminate {
0% {
transform: translateX(-100%);
}
100% {
transform: translateX(200%);
}
}

View File

@ -1,7 +1,7 @@
use dioxus::prelude::*; use dioxus::prelude::*;
use views::{Blog, Home, Navbar, Upload};
use views::{Blog, Home, Navbar}; use tracing::Level;
mod components; mod components;
mod views; mod views;
@ -9,6 +9,8 @@ mod views;
#[derive(Debug, Clone, Routable, PartialEq)] #[derive(Debug, Clone, Routable, PartialEq)]
#[rustfmt::skip] #[rustfmt::skip]
enum Route { enum Route {
#[route("/upload")]
Upload {},
#[layout(Navbar)] #[layout(Navbar)]
#[route("/")] #[route("/")]
Home {}, Home {},
@ -17,10 +19,11 @@ enum Route {
} }
const FAVICON: Asset = asset!("/assets/favicon.ico"); const FAVICON: Asset = asset!("/assets/favicon.ico");
const MAIN_CSS: Asset = asset!("/assets/styling/main.css"); //const MAIN_CSS: Asset = asset!("/assets/styling/main.css");
const TAILWIND_CSS: Asset = asset!("/assets/tailwind.css"); const TAILWIND_CSS: Asset = asset!("/assets/tailwind.css");
fn main() { fn main() {
dioxus::logger::init(Level::INFO).expect("failed to init logger");
dioxus::launch(App); dioxus::launch(App);
} }
@ -28,7 +31,7 @@ fn main() {
fn App() -> Element { fn App() -> Element {
rsx! { rsx! {
document::Link { rel: "icon", href: FAVICON } document::Link { rel: "icon", href: FAVICON }
document::Link { rel: "stylesheet", href: MAIN_CSS } // document::Link { rel: "stylesheet", href: MAIN_CSS }
document::Link { rel: "stylesheet", href: TAILWIND_CSS } document::Link { rel: "stylesheet", href: TAILWIND_CSS }
Router::<Route> {} Router::<Route> {}

View File

@ -2,12 +2,12 @@ use crate::Route;
use dioxus::prelude::*; use dioxus::prelude::*;
use crate::components::{Hero}; use crate::components::{Hero};
const BLOG_CSS: Asset = asset!("/assets/styling/blog.css"); //const BLOG_CSS: Asset = asset!("/assets/styling/blog.css");
#[component] #[component]
pub fn Blog(id: i32) -> Element { pub fn Blog(id: i32) -> Element {
rsx! { rsx! {
document::Link { rel: "stylesheet", href: BLOG_CSS } // document::Link { rel: "stylesheet", href: BLOG_CSS }
div { div {
id: "blog", id: "blog",

View File

@ -6,3 +6,6 @@ pub use blog::Blog;
mod navbar; mod navbar;
pub use navbar::Navbar; pub use navbar::Navbar;
mod upload;
pub use upload::Upload;

View File

@ -1,12 +1,12 @@
use crate::Route; use crate::Route;
use dioxus::prelude::*; use dioxus::prelude::*;
const NAVBAR_CSS: Asset = asset!("/assets/styling/navbar.css"); //const NAVBAR_CSS: Asset = asset!("/assets/styling/navbar.css");
#[component] #[component]
pub fn Navbar() -> Element { pub fn Navbar() -> Element {
rsx! { rsx! {
document::Link { rel: "stylesheet", href: NAVBAR_CSS } // document::Link { rel: "stylesheet", href: NAVBAR_CSS }
div { div {
id: "navbar", id: "navbar",

154
src/views/upload.rs Normal file
View File

@ -0,0 +1,154 @@
use dioxus::{
fullstack::{ByteStream, FileStream},
prelude::*,
};
use dioxus_html::{FileData, HasFileData};
use futures::StreamExt;
use std::{ env, fs, io::Write };
use random_string;
pub fn byte_to_human_size(size: u64) -> String {
let sizes = vec!["B", "KB", "MB", "GB", "TB", "WTFAREYOUDOINGB"];
let mut current = 0;
let mut res_size: f64 = size as f64;
let mut res: String;
while (res_size >= 1000.0 && current < sizes.len()) {
res_size /= 1000.0;
current += 1;
}
res = ((res_size * 100.0).round() / 100.0).to_string() + " " + sizes[current];
res
}
#[post("/api/upload")]
async fn upload_file(mut upload: FileStream) -> Result<String, HttpError> {
let UPLOAD_SIZE_LIMIT: u64 = 1024 * 1024 * 1024 * 1;
let UPLOAD_FOLDER: String = match env::var("UPLOAD_FOLDER") {
Ok(value) => { value },
Err(_) => { return HttpError::internal_server_error("UPLOAD_FOLDER not set"); }
};
let mut total_len: u64 = 0;
let mut error: Option<&str> = None;
let filename: String = loop {
let cur = random_string::generate(20, "ABCDEFGHIJKLMNOPQRTSTUVWXYZ0123456789");
if (!fs::exists(UPLOAD_FOLDER.clone() + &cur).expect("can't check if file exists")) {
break cur;
}
};
if upload.size().unwrap() > UPLOAD_SIZE_LIMIT {
return HttpError::payload_too_large("this file is too large");
}
let mut file = match fs::File::create(UPLOAD_FOLDER.clone() + &filename) {
Ok(val) => { val },
Err(_) => { return HttpError::internal_server_error("failed to open the output file") }
};
while let Some(chunk) = upload.next().await {
match chunk {
Ok(bytes) => {
total_len += bytes.len() as u64;
if total_len > UPLOAD_SIZE_LIMIT {
error = Some("Uploaded file to large");
break;
}
if file.write(&bytes).is_err() { error == Some("failed write"); break; };
},
Err(_) => { error = Some("unknown"); break; }
}
}
match error {
Some(err)=> {
file.sync_data();
fs::remove_file(UPLOAD_FOLDER.clone() + &filename);
HttpError::internal_server_error(err)?
}
None => { Ok(filename) }
}
}
pub fn build_table(files: Vec<(String, String, Option<Result<String, HttpError>>)>) -> Element {
rsx! {
table {
tr {
th { "filename" }
th { "size" }
th { "url" }
}
{ files.iter().map(|file| rsx! {
tr {
td { class: "px-2", "{file.0}" }
td { class: "px-2", "{file.1}" }
td { class: "px-2",
match &file.2 {
Some(res) => { match res {
Ok(file_id) => { rsx! { input { type:"button" , "/upload/dl/{file_id}"} } },
Err(e) => {
let msg = e.message.clone().unwrap();
rsx! { p { "Upload failed, reason : {msg}" } }
}
} }
None => { rsx! { p { "Waiting for file to be uploaded" } } }
}
}
}
}) }
}
}
}
#[component]
pub fn Upload() -> Element {
//TODO: global config struct
let UPLOAD_SIZE_LIMIT: u64 = 1024 * 1024 * 1024 * 1;
let mut selected : Signal<Vec<(String, String, Option<Result<String, HttpError>>)>> = use_signal(|| vec![]);
rsx! {
div { class : "p-2",
p { class: "text-4xl font-bold p-1", "Upload a file" }
form {
label { for :"file", {
if selected.len() == 0 {
rsx! { "No file selected" }
} else {
build_table(selected())
}
} }
input { id: "file", r#type : "file" ,multiple: true, class : "hidden", oninput: move |e| async move {
for file in e.files() {
selected.with_mut(|files| {files.push((file.name(), byte_to_human_size(file.size()), None)); } );
let idx = selected().len() - 1;
if (file.size() > UPLOAD_SIZE_LIMIT) {
//messy but firefox can't handle when server returns early
selected.with_mut(|files| { files[idx].2 = Some(HttpError::payload_too_large("This file is too large")) });
continue;
}
let res = upload_file(file.clone().into()).await;
selected.with_mut(|files| { files[idx].2 = Some(res) });
}
}}
}
}
}
}

12
todo Normal file
View File

@ -0,0 +1,12 @@
/upload
- can upload up to 100GB
- if video, set mime
- deletion rules:
- older than 1 month
- more than 300GB used and more than 7 days old
- show file deletion info
/status (check status of dependent devices, maybe useless)
/boot (later, previous program is bad)