UI cleanup: plain language, fix relay status display, remove jargon
This commit is contained in:
+21
-17
@@ -24,11 +24,11 @@ async fn render(state: &AppState) -> anyhow::Result<Html<String>> {
|
||||
|
||||
let stats_html = format!(
|
||||
r#"<div class="stats">
|
||||
<div class="stat"><div class="val">{}</div><div class="lbl">Indexed</div></div>
|
||||
<div class="stat"><div class="val">{}</div><div class="lbl">Torrents</div></div>
|
||||
<div class="stat"><div class="val">{}</div><div class="lbl">Publishers</div></div>
|
||||
<div class="stat"><div class="val">{}</div><div class="lbl">Queued</div></div>
|
||||
<div class="stat"><div class="val">{}</div><div class="lbl">In queue</div></div>
|
||||
<div class="stat"><div class="val">{}</div><div class="lbl">Published</div></div>
|
||||
<div class="stat"><div class="val" style="font-size:1rem;padding-top:.2rem">{last_seen}</div><div class="lbl">Last ingest</div></div>
|
||||
<div class="stat"><div class="val" style="font-size:1rem;padding-top:.2rem">{last_seen}</div><div class="lbl">Last activity</div></div>
|
||||
</div>"#,
|
||||
stats.torrent_count,
|
||||
stats.publisher_count,
|
||||
@@ -47,15 +47,13 @@ async fn render(state: &AppState) -> anyhow::Result<Html<String>> {
|
||||
relays
|
||||
.iter()
|
||||
.map(|r| {
|
||||
let (dot, ts_str) = match r.last_event {
|
||||
Some(ts) => ("dot-ok", format!("last event {}", fmt_ts_ago(ts))),
|
||||
// "no events yet" is normal on a fresh start — the relay is connected
|
||||
// but kindexr hasn't received any NIP-35 events from it this session.
|
||||
None => ("dot-dim", "connected — no events received yet".into()),
|
||||
let ts_str = match r.last_event {
|
||||
Some(ts) => format!("last event {}", fmt_ts_ago(ts)),
|
||||
None => "no events yet".into(),
|
||||
};
|
||||
format!(
|
||||
r#"<div class="relay-row">
|
||||
<span><span class="dot {dot}"></span><span class="relay-url">{url}</span></span>
|
||||
<span class="relay-url">{url}</span>
|
||||
<span class="relay-ts">{ts_str}</span>
|
||||
</div>"#,
|
||||
url = esc(&r.url),
|
||||
@@ -64,12 +62,18 @@ async fn render(state: &AppState) -> anyhow::Result<Html<String>> {
|
||||
.collect()
|
||||
};
|
||||
|
||||
let all = relays.len();
|
||||
let conn_label = if relay_count as usize == all {
|
||||
format!("{relay_count} relays connected")
|
||||
} else {
|
||||
format!("{relay_count} of {all} relays connected")
|
||||
};
|
||||
|
||||
let relays_html = format!(
|
||||
r#"<div class="section">
|
||||
<div class="section-title">Relays — {relay_count} connected / {} configured</div>
|
||||
<div class="section-title">{conn_label}</div>
|
||||
<div class="relay-list">{relay_rows}</div>
|
||||
</div>"#,
|
||||
relays.len(),
|
||||
);
|
||||
|
||||
// Recent ingest table
|
||||
@@ -101,7 +105,7 @@ async fn render(state: &AppState) -> anyhow::Result<Html<String>> {
|
||||
|
||||
let recent_html = format!(
|
||||
r#"<div class="section">
|
||||
<div class="section-title">Recent ingest</div>
|
||||
<div class="section-title">Recently indexed</div>
|
||||
<div class="table-wrap">
|
||||
<table>
|
||||
<thead><tr><th>Title</th><th>Category</th><th>Publisher</th><th>When</th></tr></thead>
|
||||
@@ -124,25 +128,25 @@ fn build_network_html(state: &AppState) -> String {
|
||||
"tor" => (
|
||||
"badge-warn",
|
||||
"Tor",
|
||||
"SOCKS5 → 127.0.0.1:9050 — all outbound traffic routed through Tor".to_string(),
|
||||
"All connections go through Tor (127.0.0.1:9050)".to_string(),
|
||||
),
|
||||
"i2p" => (
|
||||
"badge-accent",
|
||||
"I2P",
|
||||
"SOCKS5 → 127.0.0.1:4446 — all outbound traffic routed through I2P".to_string(),
|
||||
"All connections go through I2P (127.0.0.1:4446)".to_string(),
|
||||
),
|
||||
"socks5" => {
|
||||
let addr = proxy.url.trim_start_matches("socks5://").trim_start_matches("socks5h://");
|
||||
(
|
||||
"badge-accent",
|
||||
"SOCKS5",
|
||||
format!("SOCKS5 → {addr} — all outbound traffic proxied"),
|
||||
format!("All connections go through {addr}"),
|
||||
)
|
||||
}
|
||||
_ => (
|
||||
"badge-dim",
|
||||
"Direct",
|
||||
format!("No proxy — outbound connections use your host's network stack directly"),
|
||||
"No proxy, using your server's network directly".to_string(),
|
||||
),
|
||||
};
|
||||
|
||||
@@ -161,7 +165,7 @@ fn build_network_html(state: &AppState) -> String {
|
||||
<div class="card" style="margin-bottom:.75rem">
|
||||
<div style="display:flex;gap:1rem;align-items:flex-start;flex-wrap:wrap">
|
||||
<div style="min-width:160px">
|
||||
<div style="font-size:.65rem;text-transform:uppercase;letter-spacing:.07em;color:var(--muted);margin-bottom:.3rem">Proxy / anonymity</div>
|
||||
<div style="font-size:.65rem;text-transform:uppercase;letter-spacing:.07em;color:var(--muted);margin-bottom:.3rem">Network</div>
|
||||
<span class="badge {proxy_badge_class}" style="font-size:12px;padding:.2rem .6rem">{proxy_label}</span>
|
||||
<div style="font-size:11px;color:var(--muted);margin-top:.4rem;max-width:440px">{proxy_detail}</div>
|
||||
</div>
|
||||
|
||||
+1
-1
@@ -83,7 +83,7 @@ async fn render(state: &AppState, params: &Params) -> anyhow::Result<Html<String
|
||||
let pager = pagination(&base_url, page_num, total_pages);
|
||||
|
||||
let body = format!(
|
||||
r#"<h1>Indexed <span style="font-weight:400;color:var(--muted);font-size:.9rem">({total} total)</span></h1>
|
||||
r#"<h1>Content <span style="font-weight:400;color:var(--muted);font-size:.9rem">({total} total)</span></h1>
|
||||
{search}
|
||||
<div class="table-wrap">
|
||||
<table>
|
||||
|
||||
+1
-1
@@ -66,7 +66,7 @@ async fn torrent_blob_handler(
|
||||
pub fn page(active: &str, title: &str, body: &str) -> axum::response::Html<String> {
|
||||
let nav = [
|
||||
("dashboard", "/ui", "Dashboard"),
|
||||
("indexed", "/ui/indexed", "Indexed"),
|
||||
("indexed", "/ui/indexed", "Content"),
|
||||
("publishers", "/ui/publishers", "Publishers"),
|
||||
("published", "/ui/published", "Published"),
|
||||
("settings", "/ui/settings", "Settings"),
|
||||
|
||||
+2
-2
@@ -39,7 +39,7 @@ async fn render(state: &AppState, params: &Params) -> anyhow::Result<Html<String
|
||||
let tabs = format!(
|
||||
r#"<div class="tabs">
|
||||
<a href="/ui/published?tab=done" class="{c_done}">Published</a>
|
||||
<a href="/ui/published?tab=pending" class="{c_pend}">Pending queue</a>
|
||||
<a href="/ui/published?tab=pending" class="{c_pend}">Pending</a>
|
||||
</div>"#,
|
||||
c_done = if tab == "done" { "cur" } else { "" },
|
||||
c_pend = if tab == "pending" { "cur" } else { "" },
|
||||
@@ -64,7 +64,7 @@ async fn render(state: &AppState, params: &Params) -> anyhow::Result<Html<String
|
||||
Some(e) => format!(r#"<span class="mono" style="color:var(--danger)" title="{}">[error]</span>"#, esc(e)),
|
||||
None => {
|
||||
let sched = fmt_ts_ago(r.scheduled_at);
|
||||
format!(r#"<span class="mono" style="color:var(--muted)">in {sched}</span>"#)
|
||||
format!(r#"<span class="mono" style="color:var(--muted)">scheduled {sched}</span>"#)
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
+10
-11
@@ -47,24 +47,23 @@ async fn render(state: &AppState, params: &ListParams) -> anyhow::Result<Html<St
|
||||
|
||||
// Vouch form
|
||||
let vouch_form = r#"<div class="card">
|
||||
<div class="card-title">Override publisher trust</div>
|
||||
<div class="card-title">Set trust level</div>
|
||||
<form method="POST" action="/ui/publishers/vouch">
|
||||
<div class="form-row">
|
||||
<input class="wide mono-in" type="text" name="pubkey"
|
||||
placeholder="npub1… or 64-char hex pubkey" required>
|
||||
placeholder="npub1… or hex pubkey" required>
|
||||
<select name="action">
|
||||
<option value="trusted">Trusted (score 1.0)</option>
|
||||
<option value="neutral">Neutral (score 0.5)</option>
|
||||
<option value="untrusted">Untrusted (score 0.0)</option>
|
||||
<option value="trusted">Trusted</option>
|
||||
<option value="neutral">Neutral</option>
|
||||
<option value="untrusted">Untrusted</option>
|
||||
<option value="block">Block</option>
|
||||
</select>
|
||||
<button type="submit" class="btn-accent">Apply</button>
|
||||
</div>
|
||||
<div style="margin-top:.6rem;font-size:11px;color:var(--muted);line-height:1.6">
|
||||
<strong style="color:var(--text)">Local override only — nothing is broadcast to Nostr.</strong>
|
||||
The <em>Follow depth</em> column is read from your operator pubkey's real Nostr follow list.
|
||||
This form lets you override trust for anyone regardless of whether you follow them.
|
||||
Blocking silently drops all future events from that pubkey at ingest.
|
||||
This is local only, nothing gets posted to Nostr.
|
||||
Click any publisher row to copy their npub into the box above.
|
||||
Blocking drops all future posts from that person.
|
||||
</div>
|
||||
</form>
|
||||
</div>"#;
|
||||
@@ -173,8 +172,8 @@ function fillVouch(el) {{
|
||||
<div class="table-wrap">
|
||||
<table>
|
||||
<thead><tr>
|
||||
<th>Identity</th><th>Trust</th><th title="How many hops from your operator pubkey's follow list: 0=you, 1=you follow them, 2=someone you follow follows them, —=outside your network">Follow depth</th>
|
||||
<th>Events</th><th>Reports</th><th>Last seen</th><th>Actions</th>
|
||||
<th>Publisher</th><th>Trust</th><th title="0=you, 1=you follow them, 2=a follow of yours follows them">Follows</th>
|
||||
<th>Posts</th><th>Reports</th><th>Last seen</th><th></th>
|
||||
</tr></thead>
|
||||
<tbody>{table_rows}</tbody>
|
||||
</table>
|
||||
|
||||
Reference in New Issue
Block a user