Compare commits

..

4 Commits

Author SHA1 Message Date
Ernest Hysa 30587cedfa chore: fill LICENSE placeholders (#715)
Fixes #713
2026-05-31 20:03:26 +08:00
Cam F 5df9265de0 refactor: webui add css color variables (#710)
* refactor: webui add css color variables

* refactor: removed redundant css

* fix: correct colors to match original

* fix: update bg-tertiary variable

---------

Co-authored-by: sigoden <sigoden@gmail.com>
2026-05-26 08:47:10 +08:00
sigoden 3ac409ca58 fix: liblzma dynamic linking issues on MacOS (#712) 2026-05-26 08:18:53 +08:00
sigoden f97a47f625 refactor: handle unspecified ip addrs in check_addrs (#708) 2026-05-20 09:28:00 +08:00
6 changed files with 80 additions and 76 deletions
Generated
+1
View File
@@ -654,6 +654,7 @@ dependencies = [
"if-addrs", "if-addrs",
"indexmap", "indexmap",
"lazy_static", "lazy_static",
"liblzma",
"log", "log",
"md5", "md5",
"mime_guess", "mime_guess",
+1
View File
@@ -22,6 +22,7 @@ serde = { version = "1", features = ["derive"] }
serde_json = "1" serde_json = "1"
futures-util = { version = "0.3", default-features = false, features = ["alloc"] } futures-util = { version = "0.3", default-features = false, features = ["alloc"] }
async_zip = { version = "0.0.18", default-features = false, features = ["deflate", "bzip2", "xz", "chrono", "tokio"] } async_zip = { version = "0.0.18", default-features = false, features = ["deflate", "bzip2", "xz", "chrono", "tokio"] }
liblzma = { version = "0.4", features = ["static"] } # avoid dynamic linking issues on MacOS
headers = "0.4" headers = "0.4"
mime_guess = "2.0" mime_guess = "2.0"
if-addrs = "0.15" if-addrs = "0.15"
+1 -1
View File
@@ -186,7 +186,7 @@
same "printed page" as the copyright notice for easier same "printed page" as the copyright notice for easier
identification within third-party archives. identification within third-party archives.
Copyright [yyyy] [name of copyright owner] Copyright 2026 sigoden
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
+58 -59
View File
@@ -1,13 +1,35 @@
:root {
color-scheme: light;
--bg-primary: #fff;
--bg-secondary: #fafafa;
--bg-tertiary: #fff;
--bg-hover: #fafafa;
--text-primary: #24292e;
--text-secondary: #5c5c5c;
--text-tertiary: #586069;
--text-accent: #0366d6;
--svg-primary: #24292e;
--svg-secondary: rgba(3, 47, 98, 0.5);
--svg-tertiary: #24292e;
--border-primary: #ddd;
--border-secondary: #ced4da;
}
html { html {
font-family: -apple-system, BlinkMacSystemFont, Roboto, Helvetica, Arial, sans-serif; font-family: -apple-system, BlinkMacSystemFont, Roboto, Helvetica, Arial, sans-serif;
line-height: 1.5; line-height: 1.5;
color: #24292e; color: var(--text-primary);
} }
body { body {
/* prevent premature breadcrumb wrapping on mobile */ /* prevent premature breadcrumb wrapping on mobile */
min-width: 538px; min-width: 538px;
margin: 0; margin: 0;
background-color: var(--bg-primary);
}
svg {
fill: var(--svg-primary);
} }
.hidden { .hidden {
@@ -21,7 +43,7 @@ body {
padding: 0.6em 1em; padding: 0.6em 1em;
position: sticky; position: sticky;
top: 0; top: 0;
background-color: white; background-color: var(--bg-tertiary);
} }
.breadcrumb { .breadcrumb {
@@ -31,7 +53,7 @@ body {
} }
.breadcrumb>a { .breadcrumb>a {
color: #0366d6; color: var(--text-accent);
text-decoration: none; text-decoration: none;
} }
@@ -41,17 +63,17 @@ body {
/* final breadcrumb */ /* final breadcrumb */
.breadcrumb>b { .breadcrumb>b {
color: #24292e; color: var(--text-primary);
} }
.breadcrumb>.separator { .breadcrumb>.separator {
color: #586069; color: var(--text-tertiary);
padding: 0 0.25em; padding: 0 0.25em;
} }
.breadcrumb svg { .breadcrumb svg {
height: 100%; height: 100%;
fill: rgba(3, 47, 98, 0.5); fill: var(--svg-secondary);
} }
.toolbox { .toolbox {
@@ -83,9 +105,9 @@ body {
flex-wrap: nowrap; flex-wrap: nowrap;
width: 246px; width: 246px;
height: 22px; height: 22px;
background-color: #fafafa; background-color: var(--bg-secondary);
transition: all .15s; transition: all .15s;
border: 1px #ddd solid; border: 1px var(--border-primary) solid;
border-radius: 15px; border-radius: 15px;
margin-bottom: 2px; margin-bottom: 2px;
} }
@@ -97,17 +119,22 @@ body {
font-size: 16px; font-size: 16px;
line-height: 16px; line-height: 16px;
padding: 1px; padding: 1px;
color: var(--text-primary);
background-color: transparent; background-color: transparent;
border: none; border: none;
outline: none; outline: none;
} }
.searchbar .icon { .searchbar .icon {
color: #9a9a9a; color: var(--svg-tertiary);
padding: 3px 3px; padding: 3px 3px;
cursor: pointer; cursor: pointer;
} }
.searchbar svg {
fill: var(--svg-tertiary);
}
.main { .main {
padding: 0 1em; padding: 0 1em;
} }
@@ -120,7 +147,7 @@ body {
.paths-table th { .paths-table th {
text-align: left; text-align: left;
font-weight: unset; font-weight: unset;
color: #5c5c5c; color: var(--text-secondary);
white-space: nowrap; white-space: nowrap;
} }
@@ -148,7 +175,7 @@ body {
} }
.paths-table tbody tr:hover { .paths-table tbody tr:hover {
background-color: #fafafa; background-color: var(--bg-hover);
} }
.paths-table .cell-actions { .paths-table .cell-actions {
@@ -172,7 +199,7 @@ body {
.path svg { .path svg {
height: 16px; height: 16px;
fill: rgba(3, 47, 98, 0.5); fill: var(--svg-secondary);
padding-right: 0.5em; padding-right: 0.5em;
vertical-align: text-top; vertical-align: text-top;
} }
@@ -182,7 +209,7 @@ body {
} }
.path a { .path a {
color: #0366d6; color: var(--text-accent);
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap; white-space: nowrap;
overflow: hidden; overflow: hidden;
@@ -212,7 +239,9 @@ body {
.editor { .editor {
width: 100%; width: 100%;
height: calc(100vh - 5rem); height: calc(100vh - 5rem);
border: 1px solid #ced4da; border: 1px solid var(--border-secondary);
background: var(--bg-primary);
color: var(--text-primary);
outline: none; outline: none;
padding: 5px; padding: 5px;
} }
@@ -258,50 +287,20 @@ body {
/* dark theme */ /* dark theme */
@media (prefers-color-scheme: dark) { @media (prefers-color-scheme: dark) {
body { :root {
background-color: #000; color-scheme: dark;
} --bg-primary: #000;
--bg-secondary: #111;
html, --bg-tertiary: #111;
.breadcrumb>b, --bg-hover: #1a1a1a;
.searchbar #search { --text-primary: #fff;
color: #fff; --text-secondary: #ddd;
} --text-tertiary: #586069; /*Unchanged in both color schemes*/
--text-accent: #3191ff;
.uploaders-table th, --svg-primary: #fff;
.paths-table th { --svg-secondary: #fff;
color: #ddd; --svg-tertiary: #fff6;
} --border-primary: #fff6;
--border-secondary: #ced4da; /*Unchanged in both color schemes*/
svg,
.path svg,
.breadcrumb svg {
fill: #fff;
}
.head {
background-color: #111;
}
.searchbar {
background-color: #111;
border-color: #fff6;
}
.searchbar svg {
fill: #fff6;
}
.path a {
color: #3191ff;
}
.paths-table tbody tr:hover {
background-color: #1a1a1a;
}
.editor {
background: black;
color: white;
} }
} }
+1 -1
View File
@@ -97,7 +97,7 @@
<svg viewBox="0 0 1024 1024" width="24" height="24"> <svg viewBox="0 0 1024 1024" width="24" height="24">
<path <path
d="M426.666667 682.666667v42.666666h170.666666v-42.666666h-170.666666z m-42.666667-85.333334h298.666667v128h42.666666V418.133333L605.866667 298.666667H298.666667v426.666666h42.666666v-128h42.666667z m260.266667-384L810.666667 379.733333V810.666667H213.333333V213.333333h430.933334zM341.333333 341.333333h85.333334v170.666667H341.333333V341.333333z" d="M426.666667 682.666667v42.666666h170.666666v-42.666666h-170.666666z m-42.666667-85.333334h298.666667v128h42.666666V418.133333L605.866667 298.666667H298.666667v426.666666h42.666666v-128h42.666667z m260.266667-384L810.666667 379.733333V810.666667H213.333333V213.333333h430.933334zM341.333333 341.333333h85.333334v170.666667H341.333333V341.333333z"
fill="#444444" p-id="8311"></path> p-id="8311"></path>
</svg> </svg>
</div> </div>
</div> </div>
+18 -15
View File
@@ -211,28 +211,31 @@ fn create_listener(addr: SocketAddr) -> Result<TcpListener> {
fn check_addrs(args: &Args) -> Result<(Vec<BindAddr>, Vec<BindAddr>)> { fn check_addrs(args: &Args) -> Result<(Vec<BindAddr>, Vec<BindAddr>)> {
let mut new_addrs = vec![]; let mut new_addrs = vec![];
let mut print_addrs = vec![]; let mut print_addrs = vec![];
let (ipv4_addrs, ipv6_addrs) = interface_addrs()?; let has_unspecified = args
.addrs
.iter()
.any(|a| matches!(a, BindAddr::IpAddr(ip) if ip.is_unspecified()));
let (ipv4_addrs, ipv6_addrs) = if has_unspecified {
interface_addrs()?
} else {
(vec![], vec![])
};
for bind_addr in args.addrs.iter() { for bind_addr in args.addrs.iter() {
new_addrs.push(bind_addr.clone());
match bind_addr { match bind_addr {
BindAddr::IpAddr(ip) => match &ip { BindAddr::IpAddr(ip) => match &ip {
IpAddr::V4(_) => { IpAddr::V4(_) => {
if !ipv4_addrs.is_empty() { if ip.is_unspecified() {
new_addrs.push(bind_addr.clone()); print_addrs.extend(ipv4_addrs.clone());
if ip.is_unspecified() { } else {
print_addrs.extend(ipv4_addrs.clone()); print_addrs.push(bind_addr.clone());
} else {
print_addrs.push(bind_addr.clone());
}
} }
} }
IpAddr::V6(_) => { IpAddr::V6(_) => {
if !ipv6_addrs.is_empty() { if ip.is_unspecified() {
new_addrs.push(bind_addr.clone()); print_addrs.extend(ipv6_addrs.clone());
if ip.is_unspecified() { } else {
print_addrs.extend(ipv6_addrs.clone()); print_addrs.push(bind_addr.clone());
} else {
print_addrs.push(bind_addr.clone())
}
} }
} }
}, },