perf: implement proper LRU Cache and ETag optimizations
This commit is contained in:
@@ -35,12 +35,12 @@ const PRESET_FONTS: Record<string, { heading: string; body: string; caption: str
|
||||
};
|
||||
|
||||
const PRESET_ACCENTS: Record<string, string> = {
|
||||
studio: '#e60012',
|
||||
minimal: '#000000',
|
||||
editorial: '#8B2500',
|
||||
classic: '#c49a3c',
|
||||
noir: '#ff6b35',
|
||||
monograph: '#333333',
|
||||
studio: 'var(--accent-studio, #e60012)',
|
||||
minimal: 'var(--accent-minimal, #000000)',
|
||||
editorial: 'var(--accent-editorial, #8B2500)',
|
||||
classic: 'var(--accent-classic, #c49a3c)',
|
||||
noir: 'var(--accent-noir, #ff6b35)',
|
||||
monograph: 'var(--accent-monograph, #333333)',
|
||||
};
|
||||
|
||||
function getAttr(attr: string): string {
|
||||
@@ -91,9 +91,12 @@ export function DevToolbar() {
|
||||
setAttr('data-preset', p);
|
||||
setPreset(p);
|
||||
// Update accent + fonts
|
||||
const accent = PRESET_ACCENTS[p] || '#e60012';
|
||||
const accent = PRESET_ACCENTS[p] || 'var(--accent-studio, #e60012)';
|
||||
setVar('--accent', accent);
|
||||
setVar('--accent-dim', `${accent}1f`);
|
||||
// Note: since accent might be a CSS var, appending hex opacity won't work in all browsers if it's a var,
|
||||
// but we provide it for backward compatibility where possible. Or use color-mix if supported.
|
||||
// For now we set it to same var or use a generic dim if needed.
|
||||
setVar('--accent-dim', `color-mix(in srgb, ${accent} 12%, transparent)`);
|
||||
const fonts = PRESET_FONTS[p];
|
||||
if (fonts) {
|
||||
setVar('--font-serif', `'${fonts.heading}', Georgia, 'Times New Roman', serif`);
|
||||
|
||||
@@ -151,7 +151,7 @@ export function MapView() {
|
||||
|
||||
if (error) {
|
||||
return (
|
||||
<div className="map-container__loading">
|
||||
<div className="map-container__loading" style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', height: '100%' }}>
|
||||
<p>{error}</p>
|
||||
</div>
|
||||
);
|
||||
@@ -162,9 +162,39 @@ export function MapView() {
|
||||
{loading && (
|
||||
<div
|
||||
className="map-container__loading"
|
||||
style={{ position: 'absolute', inset: 0, zIndex: 1000 }}
|
||||
style={{
|
||||
position: 'absolute',
|
||||
inset: 0,
|
||||
zIndex: 1000,
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
background: 'rgba(0, 0, 0, 0.5)',
|
||||
color: '#fff'
|
||||
}}
|
||||
>
|
||||
<svg
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
style={{ animation: 'spin 1s linear infinite', marginBottom: '8px' }}
|
||||
>
|
||||
<circle cx="12" cy="12" r="10" strokeOpacity="0.25"></circle>
|
||||
<path d="M12 2a10 10 0 0 1 10 10"></path>
|
||||
</svg>
|
||||
<p>Loading map…</p>
|
||||
<style>{`
|
||||
@keyframes spin {
|
||||
from { transform: rotate(0deg); }
|
||||
to { transform: rotate(360deg); }
|
||||
}
|
||||
`}</style>
|
||||
</div>
|
||||
)}
|
||||
<div ref={containerRef} className="map-container" />
|
||||
|
||||
@@ -33,11 +33,11 @@ export default function PasswordGate({ slug, title }: PasswordGateProps) {
|
||||
if (res.ok) {
|
||||
window.location.reload();
|
||||
} else {
|
||||
setError('Wrong password');
|
||||
setError('Incorrect password. Please try again.');
|
||||
setPassword('');
|
||||
}
|
||||
} catch {
|
||||
setError('Something went wrong');
|
||||
setError('Unable to verify password. Please try again later.');
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user