diff options
| author | Adam Mathes <adam@adammathes.com> | 2026-02-14 10:12:22 -0800 |
|---|---|---|
| committer | Adam Mathes <adam@adammathes.com> | 2026-02-14 10:12:22 -0800 |
| commit | 9d3b2a90316a1a5f735845f61abbd8a875529060 (patch) | |
| tree | b51c86306a75c4ea57a0e733eeda67a099f15d58 /frontend | |
| parent | 90fa99359fafea4b0e10a88716675de9de4593ed (diff) | |
| download | neko-9d3b2a90316a1a5f735845f61abbd8a875529060.tar.gz neko-9d3b2a90316a1a5f735845f61abbd8a875529060.tar.bz2 neko-9d3b2a90316a1a5f735845f61abbd8a875529060.zip | |
feat: add font theme support (fixing NK-rn4nzp)
Diffstat (limited to 'frontend')
| -rw-r--r-- | frontend/src/App.tsx | 26 | ||||
| -rw-r--r-- | frontend/src/components/FeedItem.css | 4 | ||||
| -rw-r--r-- | frontend/src/components/FeedList.css | 7 | ||||
| -rw-r--r-- | frontend/src/components/Settings.css | 21 | ||||
| -rw-r--r-- | frontend/src/components/Settings.tsx | 29 | ||||
| -rw-r--r-- | frontend/src/index.css | 31 |
6 files changed, 102 insertions, 16 deletions
diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 74ae89e..1812451 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -36,12 +36,19 @@ import FeedList from './components/FeedList'; import FeedItems from './components/FeedItems'; import Settings from './components/Settings'; -function Dashboard({ theme, setTheme }: { theme: string; setTheme: (t: string) => void }) { +interface DashboardProps { + theme: string; + setTheme: (t: string) => void; + fontTheme: string; + setFontTheme: (t: string) => void; +} + +function Dashboard({ theme, setTheme, fontTheme, setFontTheme }: DashboardProps) { const [sidebarVisible, setSidebarVisible] = useState(true); return ( <div - className={`dashboard ${sidebarVisible ? 'sidebar-visible' : 'sidebar-hidden'} theme-${theme}`} + className={`dashboard ${sidebarVisible ? 'sidebar-visible' : 'sidebar-hidden'} theme-${theme} font-${fontTheme}`} > <div className="dashboard-content"> {!sidebarVisible && ( @@ -60,7 +67,7 @@ function Dashboard({ theme, setTheme }: { theme: string; setTheme: (t: string) = <Routes> <Route path="/feed/:feedId" element={<FeedItems />} /> <Route path="/tag/:tagName" element={<FeedItems />} /> - <Route path="/settings" element={<Settings />} /> + <Route path="/settings" element={<Settings fontTheme={fontTheme} setFontTheme={setFontTheme} />} /> <Route path="/" element={<FeedItems />} /> </Routes> </main> @@ -71,12 +78,18 @@ function Dashboard({ theme, setTheme }: { theme: string; setTheme: (t: string) = function App() { const [theme, setTheme] = useState(localStorage.getItem('neko-theme') || 'light'); + const [fontTheme, setFontTheme] = useState(localStorage.getItem('neko-font-theme') || 'default'); const handleSetTheme = (newTheme: string) => { setTheme(newTheme); localStorage.setItem('neko-theme', newTheme); }; + const handleSetFontTheme = (newFontTheme: string) => { + setFontTheme(newFontTheme); + localStorage.setItem('neko-font-theme', newFontTheme); + }; + const basename = window.location.pathname.startsWith('/v2') ? '/v2' : '/'; return ( @@ -87,7 +100,12 @@ function App() { path="/*" element={ <RequireAuth> - <Dashboard theme={theme} setTheme={handleSetTheme} /> + <Dashboard + theme={theme} + setTheme={handleSetTheme} + fontTheme={fontTheme} + setFontTheme={handleSetFontTheme} + /> </RequireAuth> } /> diff --git a/frontend/src/components/FeedItem.css b/frontend/src/components/FeedItem.css index 3becb20..4eca2b1 100644 --- a/frontend/src/components/FeedItem.css +++ b/frontend/src/components/FeedItem.css @@ -15,7 +15,7 @@ } .item-title { - font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; + font-family: var(--font-heading); font-size: 1.8rem; font-weight: bold; text-decoration: none; @@ -114,7 +114,7 @@ border: 1px solid var(--border-color, #ccc); color: blue; cursor: pointer; - font-family: 'Helvetica Neue'; + font-family: var(--font-heading); font-weight: bold; font-size: 0.8rem; padding: 2px 6px; diff --git a/frontend/src/components/FeedList.css b/frontend/src/components/FeedList.css index 7bb0f4c..7c39901 100644 --- a/frontend/src/components/FeedList.css +++ b/frontend/src/components/FeedList.css @@ -1,6 +1,6 @@ .feed-list { padding: 1rem; - font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; + font-family: var(--font-heading); color: #777; /* specific v1 color */ font-size: 0.8rem; @@ -18,9 +18,6 @@ z-index: 10; padding-bottom: 0.5rem; color: var(--text-color); - /* Usually dark/white depending on theme, v1 was white on blue? No, white on fixed header? No, v1 logo class says color: white. But sidebar is #ccc. */ - /* In v1 logo was fixed top left (blue header bar?). In v2 sidebar is #ccc. - Let's use theme text color but maybe bolder? */ } /* Override logo color if necessary for themes */ @@ -55,7 +52,7 @@ margin: 1rem 0 0.25rem 0; cursor: pointer; user-select: none; - font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; + font-family: var(--font-heading); color: #333; /* Darker than list items */ text-transform: lowercase; diff --git a/frontend/src/components/Settings.css b/frontend/src/components/Settings.css index ec6fc83..c8784a0 100644 --- a/frontend/src/components/Settings.css +++ b/frontend/src/components/Settings.css @@ -4,7 +4,8 @@ margin: 0 auto; } -.add-feed-section { +.add-feed-section, +.appearance-section { background: var(--sidebar-bg); padding: 1.5rem; border-radius: 8px; @@ -12,6 +13,22 @@ border: 1px solid var(--border-color); } +.font-selector { + display: flex; + align-items: center; + gap: 1rem; +} + +.font-select { + padding: 0.5rem; + border: 1px solid var(--border-color); + background: var(--bg-color); + color: var(--text-color); + border-radius: 4px; + font-size: 1rem; + min-width: 200px; +} + .add-feed-form { display: flex; gap: 1rem; @@ -57,7 +74,7 @@ } .feed-title { - font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; + font-family: var(--font-heading); font-weight: bold; font-size: 1.1rem; } diff --git a/frontend/src/components/Settings.tsx b/frontend/src/components/Settings.tsx index 16cf6a3..80e3068 100644 --- a/frontend/src/components/Settings.tsx +++ b/frontend/src/components/Settings.tsx @@ -3,14 +3,21 @@ import type { Feed } from '../types'; import './Settings.css'; import { apiFetch } from '../utils'; -export default function Settings() { +interface SettingsProps { + fontTheme?: string; + setFontTheme?: (t: string) => void; +} + +export default function Settings({ fontTheme, setFontTheme }: SettingsProps) { const [feeds, setFeeds] = useState<Feed[]>([]); + /* ... existing state ... */ const [newFeedUrl, setNewFeedUrl] = useState(''); const [loading, setLoading] = useState(false); const [error, setError] = useState<string | null>(null); const [importFile, setImportFile] = useState<File | null>(null); + /* ... existing fetchFeeds ... */ const fetchFeeds = () => { setLoading(true); apiFetch('/api/feed/') @@ -32,6 +39,7 @@ export default function Settings() { fetchFeeds(); }, []); + /* ... existing handlers ... */ const handleAddFeed = (e: React.FormEvent) => { e.preventDefault(); if (!newFeedUrl) return; @@ -106,6 +114,25 @@ export default function Settings() { <div className="settings-page"> <h2>Settings</h2> + {setFontTheme && ( + <div className="appearance-section"> + <h3>Appearance</h3> + <div className="font-selector"> + <label>Font Theme:</label> + <select + value={fontTheme || 'default'} + onChange={(e) => setFontTheme(e.target.value)} + className="font-select" + > + <option value="default">Default</option> + <option value="serif">Serif</option> + <option value="sans">Sans-Serif</option> + <option value="mono">Monospace</option> + </select> + </div> + </div> + )} + <div className="add-feed-section"> <h3>Add New Feed</h3> <form onSubmit={handleAddFeed} className="add-feed-form"> diff --git a/frontend/src/index.css b/frontend/src/index.css index 3365d34..6396633 100644 --- a/frontend/src/index.css +++ b/frontend/src/index.css @@ -1,5 +1,11 @@ +:root { + /* Font Variables */ + --font-body: Palatino, 'Palatino Linotype', 'Palatino LT STD', 'Book Antiqua', Georgia, serif; + --font-heading: 'Helvetica Neue', Helvetica, Arial, sans-serif; +} + body { - font-family: Palatino, 'Palatino Linotype', 'Palatino LT STD', 'Book Antiqua', Georgia, serif; + font-family: var(--font-body); } h1, @@ -10,10 +16,31 @@ h5, .logo, .nav-link, .logout-btn { - font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; + font-family: var(--font-heading); font-weight: bold; } +/* Font Themes */ +.font-default { + --font-body: Palatino, 'Palatino Linotype', 'Palatino LT STD', 'Book Antiqua', Georgia, serif; + --font-heading: 'Helvetica Neue', Helvetica, Arial, sans-serif; +} + +.font-serif { + --font-body: Georgia, 'Times New Roman', Times, serif; + --font-heading: Georgia, 'Times New Roman', Times, serif; +} + +.font-sans { + --font-body: Inter, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; + --font-heading: Inter, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; +} + +.font-mono { + --font-body: Menlo, Monaco, Consolas, 'Courier New', monospace; + --font-heading: Menlo, Monaco, Consolas, 'Courier New', monospace; +} + :root { line-height: 1.5; font-size: 18px; |
