feat: add configurable reading font using Bunny Fonts

- Add readingFont setting to UserSettings interface
- Create fontLoader utility to load fonts from Bunny Fonts
- Add font selector dropdown in settings with popular reading fonts
- Use CSS variable --reading-font to apply font to reader content
- Support fonts: Inter, Lora, Merriweather, Open Sans, Roboto, Source Serif 4, Crimson Text, Libre Baskerville, PT Serif
- Fonts loaded from https://fonts.bunny.net/ (GDPR-friendly)
This commit is contained in:
Gigi
2025-10-05 02:52:21 +01:00
parent 20e9ba1675
commit 0ccad88dfd
5 changed files with 76 additions and 0 deletions

View File

@@ -13,6 +13,7 @@ import { HighlightsPanel } from './HighlightsPanel'
import { fetchReadableContent, ReadableContent } from '../services/readerService'
import Settings from './Settings'
import { UserSettings, loadSettings, saveSettings } from '../services/settingsService'
import { loadFont, getFontFamily } from '../utils/fontLoader'
export type ViewMode = 'compact' | 'cards' | 'large'
@@ -65,6 +66,12 @@ const Bookmarks: React.FC<BookmarksProps> = ({ relayPool, onLogout }) => {
if (settings.showUnderlines !== undefined) setShowUnderlines(settings.showUnderlines)
if (settings.sidebarCollapsed !== undefined) setIsCollapsed(settings.sidebarCollapsed)
if (settings.highlightsCollapsed !== undefined) setIsHighlightsCollapsed(settings.highlightsCollapsed)
if (settings.readingFont) {
loadFont(settings.readingFont)
// Apply font to content panel
const fontFamily = getFontFamily(settings.readingFont)
document.documentElement.style.setProperty('--reading-font', fontFamily)
}
}, [settings])
const handleFetchBookmarks = async () => {

View File

@@ -76,6 +76,27 @@ const Settings: React.FC<SettingsProps> = ({ settings, onSave, onClose, isSaving
</div>
</div>
<div className="setting-group">
<label htmlFor="readingFont">Reading Font</label>
<select
id="readingFont"
value={localSettings.readingFont || 'system'}
onChange={(e) => setLocalSettings({ ...localSettings, readingFont: e.target.value })}
className="setting-select"
>
<option value="system">System Default</option>
<option value="inter">Inter</option>
<option value="lora">Lora</option>
<option value="merriweather">Merriweather</option>
<option value="open-sans">Open Sans</option>
<option value="roboto">Roboto</option>
<option value="source-serif-4">Source Serif 4</option>
<option value="crimson-text">Crimson Text</option>
<option value="libre-baskerville">Libre Baskerville</option>
<option value="pt-serif">PT Serif</option>
</select>
</div>
<div className="setting-group">
<label htmlFor="showUnderlines" className="checkbox-label">
<input

View File

@@ -12,6 +12,8 @@
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
-webkit-text-size-adjust: 100%;
--reading-font: system-ui, -apple-system, sans-serif;
}
body {
@@ -524,11 +526,13 @@ body {
word-wrap: break-word;
overflow-wrap: break-word;
word-break: break-word;
font-family: var(--reading-font);
}
.reader-markdown {
color: #ddd;
line-height: 1.7;
font-family: var(--reading-font);
}
/* Ensure content is left-aligned even if source markup uses center */

View File

@@ -14,6 +14,7 @@ export interface UserSettings {
showUnderlines?: boolean
sidebarCollapsed?: boolean
highlightsCollapsed?: boolean
readingFont?: string
}
export async function loadSettings(

43
src/utils/fontLoader.ts Normal file
View File

@@ -0,0 +1,43 @@
// Map of font names to their Bunny Fonts family names
const FONT_FAMILIES: Record<string, string> = {
'inter': 'Inter',
'lora': 'Lora',
'merriweather': 'Merriweather',
'open-sans': 'Open Sans',
'roboto': 'Roboto',
'source-serif-4': 'Source Serif 4',
'crimson-text': 'Crimson Text',
'libre-baskerville': 'Libre Baskerville',
'pt-serif': 'PT Serif'
}
const loadedFonts = new Set<string>()
export function loadFont(fontKey: string) {
if (fontKey === 'system' || loadedFonts.has(fontKey)) {
return
}
const fontFamily = FONT_FAMILIES[fontKey]
if (!fontFamily) {
console.warn(`Unknown font: ${fontKey}`)
return
}
// Create a link element to load the font from Bunny Fonts
const link = document.createElement('link')
link.rel = 'stylesheet'
link.href = `https://fonts.bunny.net/css?family=${encodeURIComponent(fontFamily.toLowerCase().replace(/ /g, '-'))}:400,400i,700,700i`
document.head.appendChild(link)
loadedFonts.add(fontKey)
}
export function getFontFamily(fontKey: string | undefined): string {
if (!fontKey || fontKey === 'system') {
return 'system-ui, -apple-system, sans-serif'
}
const fontFamily = FONT_FAMILIES[fontKey]
return fontFamily ? `'${fontFamily}', serif` : 'system-ui, -apple-system, sans-serif'
}