From e7396de1a4cd9e179a64be0769e274496b291928 Mon Sep 17 00:00:00 2001 From: Zichao Lin Date: Sat, 18 Jul 2026 09:21:07 +0800 Subject: [PATCH] feat(ui): add favicon.ico route and link tag in base template --- app/main.py | 9 ++++++++- app/static/favicon.ico | Bin 0 -> 135 bytes app/templates/base.html | 1 + favicon.ico | Bin 0 -> 14510 bytes 4 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 app/static/favicon.ico create mode 100644 favicon.ico diff --git a/app/main.py b/app/main.py index 50a48de..d2e48a1 100644 --- a/app/main.py +++ b/app/main.py @@ -1,6 +1,7 @@ from pathlib import Path from fastapi import FastAPI +from fastapi.responses import FileResponse from fastapi.staticfiles import StaticFiles from app.config import UPLOAD_DIR @@ -10,6 +11,7 @@ from app.routers import web, api app = FastAPI(title="Mailova 星笺") UPLOAD_DIR.mkdir(exist_ok=True) +STATIC_DIR = Path(__file__).resolve().parent / "static" # Cache-Control for uploaded images (30 days, immutable — filenames contain UUID) @@ -21,7 +23,12 @@ async def cache_control_middleware(request, call_next): return response -app.mount("/static", StaticFiles(directory=str(Path(__file__).resolve().parent / "static")), name="static") +@app.get("/favicon.ico") +async def favicon(): + return FileResponse(STATIC_DIR / "favicon.ico", media_type="image/x-icon") + + +app.mount("/static", StaticFiles(directory=str(STATIC_DIR)), name="static") app.mount("/uploads", StaticFiles(directory=str(UPLOAD_DIR)), name="uploads") app.include_router(web.router) diff --git a/app/static/favicon.ico b/app/static/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..9c66e66854d8a297327144fd9ae71e17ef39b925 GIT binary patch literal 135 zcmZQzU<5(|0R|wcz);A*z#s<1odJICyj)UTKqjxJhf5HU2C85X;9vrh6DDSu0VxYl z7srr_Imti#l@b;-vAtfFU*O`vyeTN=mITKtx697!*#4}V_?0J)cMHF2krLl(GoQ#T d6}vwS47RUw_SXkxy#|`W;OXk;vd$@?2>|F@BSQcH literal 0 HcmV?d00001 diff --git a/app/templates/base.html b/app/templates/base.html index 2ce08fc..af1e2d9 100644 --- a/app/templates/base.html +++ b/app/templates/base.html @@ -2,6 +2,7 @@ + {% block title %}星笺{% endblock %} diff --git a/favicon.ico b/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..71daceb886f42170ff6d2843ae9cc9780f39c3b1 GIT binary patch literal 14510 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