llm-proxy(ui): 修 placeholder token 泄漏 + UI 重做 + λ favicon
deploy llm-proxy / build-and-deploy (push) Successful in 1m46s

- 修:token 输入框 placeholder 之前硬编码了真实 token (`e.g.
  famzheng-llm-2026`),等于明文泄露。改成 `your auth token`
- UI 重做 — 100dvh 锁 viewport(处理移动软键盘)+ grid 布局
  让 thread 永远占中间、footer 永远贴底
- textarea autogrow(最高 200px,超出内部滚)
- 复制按钮 / smooth scroll-to-bottom (double rAF) /
  iOS momentum scroll / safe-area padding
- 错误状态独立 row,monospace + 红底
- λ favicon(紫蓝渐变 + 绿色在线点 + glow)— SVG include_str!
  进 binary,`/favicon.svg` + `/favicon.ico` 同源响应
This commit is contained in:
Fam Zheng
2026-05-18 00:34:49 +01:00
parent a5e97adf85
commit a8e5100380
3 changed files with 32 additions and 0 deletions
+13
View File
@@ -37,6 +37,8 @@ async fn main() -> std::io::Result<()> {
.route("/healthz", get(|| async { "ok" }))
.route("/", get(|| async { Redirect::permanent("/chat") }))
.route("/chat", get(chat_ui))
.route("/favicon.svg", get(favicon))
.route("/favicon.ico", get(favicon)) // 浏览器默认会请求 .ico,让它共享同一 SVG
.merge(chat_api)
.layer(TraceLayer::new_for_http());
@@ -47,11 +49,22 @@ async fn main() -> std::io::Result<()> {
}
const CHAT_HTML: &str = include_str!("../web/chat.html");
const FAVICON_SVG: &str = include_str!("../web/favicon.svg");
async fn chat_ui() -> Html<&'static str> {
Html(CHAT_HTML)
}
async fn favicon() -> impl IntoResponse {
(
[
(axum::http::header::CONTENT_TYPE, "image/svg+xml"),
(axum::http::header::CACHE_CONTROL, "public, max-age=604800"),
],
FAVICON_SVG,
)
}
/// 验 `Authorization: token <PROXY_AUTH_TOKEN>`,错的直接 401。
async fn require_token(
State(cfg): State<Arc<proxy::Config>>,