perf+ui: gzip (api/static precompressed), immutable attachment cache, responsive dialogs/header, safe-area + dynamic theme-color, mobile tuning

This commit is contained in:
root
2026-10-16 23:34:36 +08:00
parent 3ba44aa2de
commit 275a0313e1
21 changed files with 145 additions and 95 deletions
+4 -3
View File
@@ -15,9 +15,10 @@
"title": "足迹 Footprints",
"width": 1280,
"height": 800,
"minWidth": 960,
"minHeight": 640,
"center": true
"minWidth": 420,
"minHeight": 560,
"center": true,
"backgroundColor": "#f3f4f6"
}
],
"security": {
+4 -4
View File
@@ -29,7 +29,7 @@ export function Header({ onMenu }: { onMenu?: () => void }) {
};
return (
<header className="flex h-14 shrink-0 items-center gap-4 border-b border-line bg-surface px-5">
<header className="flex h-14 shrink-0 items-center gap-2 border-b border-line bg-surface px-3 sm:gap-4 sm:px-5">
<Button variant="ghost" size="icon" className="lg:hidden" onClick={onMenu} aria-label="打开导航">
<Menu size={17} />
</Button>
@@ -39,7 +39,7 @@ export function Header({ onMenu }: { onMenu?: () => void }) {
{meta.sub && <p className="truncate text-[11px] leading-tight text-ink-3">{meta.sub}</p>}
</div>
<div className="relative ml-auto w-[280px]">
<div className="relative ml-auto hidden w-[240px] md:block lg:w-[280px]">
<Search size={14} className="pointer-events-none absolute left-2.5 top-1/2 -translate-y-1/2 text-ink-3" />
<Input
className="pl-8"
@@ -58,9 +58,9 @@ export function Header({ onMenu }: { onMenu?: () => void }) {
{dark ? <Sun size={15} /> : <Moon size={15} />}
</Button>
<Button variant="primary" onClick={() => navigate('/records?new=1')}>
<Button variant="primary" onClick={() => navigate('/records?new=1')} aria-label="新建记录">
<Plus size={14} />
新建记录
<span className="hidden sm:inline">新建记录</span>
</Button>
</header>
);
+4 -4
View File
@@ -21,10 +21,10 @@ export function Dialog({ open, onClose, title, width = 560, children, footer }:
if (!open) return null;
return createPortal(
<div className="fixed inset-0 z-50 flex items-start justify-center overflow-y-auto p-6 pt-[8vh]">
<div className="fixed inset-0 z-50 flex items-start justify-center overflow-y-auto p-3 pt-[6vh] sm:p-6 sm:pt-[8vh]">
<div className="fixed inset-0 bg-black/45" onClick={onClose} />
<div
className="relative w-full rounded-lg border border-line bg-surface shadow-pop"
className="animate-in relative w-full rounded-lg border border-line bg-surface shadow-pop"
style={{ maxWidth: width }}
role="dialog"
>
@@ -34,9 +34,9 @@ export function Dialog({ open, onClose, title, width = 560, children, footer }:
<X size={15} />
</Button>
</div>
<div className="px-4 py-4 max-h-[64vh] overflow-y-auto">{children}</div>
<div className="max-h-[70vh] overflow-y-auto px-3 py-3 sm:px-4 sm:py-4">{children}</div>
{footer && (
<div className="flex items-center justify-end gap-2 border-t border-line px-4 h-14">
<div className="flex flex-wrap items-center justify-end gap-2 border-t border-line px-3 py-2.5 sm:h-14 sm:flex-nowrap sm:px-4 sm:py-0">
{footer}
</div>
)}
+8
View File
@@ -17,6 +17,14 @@ if (saved === 'dark' || (!saved && window.matchMedia('(prefers-color-scheme: dar
document.documentElement.classList.add('dark');
}
// 状态栏/标题栏颜色跟随主题(亮暗切换实时同步)
function syncThemeColor() {
const bg = getComputedStyle(document.documentElement).getPropertyValue('--bg').trim();
if (bg) document.querySelector('meta[name="theme-color"]')?.setAttribute('content', bg);
}
syncThemeColor();
window.addEventListener('fp-theme-change', syncThemeColor);
// PWA:仅生产构建且非桌面壳时注册(桌面端走 Tauri,无需 SW)
if ('serviceWorker' in navigator && import.meta.env.PROD && !('__TAURI_INTERNALS__' in window)) {
window.addEventListener('load', () => {
+16
View File
@@ -80,6 +80,17 @@
html, body, #root { height: 100%; }
/* 移动端适配:禁止横向溢出 / 去点按高亮 / 双击不缩放 / 刘海安全区 */
html, body { overflow-x: clip; }
body {
-webkit-tap-highlight-color: transparent;
touch-action: manipulation;
padding: env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left);
}
@media (pointer: coarse) {
button, [role='button'], a { min-height: 36px; }
}
body {
background: var(--bg);
color: var(--text-1);
@@ -95,6 +106,11 @@ body {
h1, h2, h3 { letter-spacing: -0.022em; text-wrap: balance; }
/* 小屏:分区标题与卡片间距收紧 */
@media (max-width: 640px) {
.hover-lift:hover { transform: none; }
}
.num { font-variant-numeric: tabular-nums lining-nums; font-feature-settings: 'tnum' 1, 'lnum' 1; }
::selection { background: color-mix(in srgb, var(--brand) 18%, transparent); }