aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.thicket/tickets.jsonl5
-rw-r--r--frontend/src/App.css2
-rw-r--r--frontend/src/components/FeedItem.css12
-rw-r--r--frontend/src/components/FeedItems.css2
-rw-r--r--frontend/src/components/FeedList.css33
-rw-r--r--frontend/src/components/FeedList.tsx19
-rw-r--r--frontend/src/components/Settings.css17
-rw-r--r--frontend/src/index.css23
8 files changed, 62 insertions, 51 deletions
diff --git a/.thicket/tickets.jsonl b/.thicket/tickets.jsonl
index 3c2a8fc..db0ad3d 100644
--- a/.thicket/tickets.jsonl
+++ b/.thicket/tickets.jsonl
@@ -18,7 +18,8 @@
{"id":"NK-6o87rr","title":"Vanilla JS: Implement Pagination","description":"Implement 'Load More' or infinite scroll for item list in vanilla JS prototype.","type":"feature","status":"closed","priority":2,"labels":null,"assignee":"","created":"2026-02-14T04:47:40.618957267Z","updated":"2026-02-14T04:47:40.618957267Z"}
{"id":"NK-6q9nyg","title":"Refactor HTTP-dependent functions for testability","description":"Several functions use http.Get or external libraries directly (GetFullContent uses goose, ResolveFeedURL uses http.Get + goquery, imageProxyHandler uses http.Client). Refactor these to accept interfaces for HTTP fetching so they can be unit tested with mocks. This is the primary blocker for reaching 90% coverage.","type":"cleanup","status":"closed","priority":3,"labels":null,"assignee":"","created":"2026-02-13T03:54:37.630148644Z","updated":"2026-02-14T02:44:05.328784994Z"}
{"id":"NK-7tzbql","title":"Fix TUI Content View Navigation and Interaction","description":"The TUI content view (reading a single item) is currently non-functional or severely limited. Users cannot easily navigate back, scroll, or interact with the content. This task involves improving the 'viewContent' state in the TUI.","type":"bug","status":"closed","priority":1,"labels":null,"assignee":"","created":"2026-02-13T05:02:57.382793121Z","updated":"2026-02-13T05:06:15.144485446Z"}
-{"id":"NK-7xuajb","title":"[security] Add HTTP Security Headers","description":"Add middleware to set standard security headers: Content-Security-Policy (restrict sources), X-Content-Type-Options: nosniff, X-Frame-Options: DENY, Referrer-Policy: strict-origin-when-cross-origin.","type":"","status":"open","priority":2,"labels":null,"assignee":"","created":"2026-02-14T16:35:59.320775688Z","updated":"2026-02-14T16:36:49.446994841Z"}
+{"id":"NK-7xuajb","title":"[security] Add HTTP Security Headers","description":"Add middleware to set standard security headers: Content-Security-Policy (restrict sources), X-Content-Type-Options: nosniff, X-Frame-Options: DENY, Referrer-Policy: strict-origin-when-cross-origin.","type":"","status":"closed","priority":2,"labels":null,"assignee":"","created":"2026-02-14T16:35:59.320775688Z","updated":"2026-02-14T17:20:46.397582923Z"}
+{"id":"NK-8hu7z1","title":"scrape full text button","description":"add this feature back in to the v2 ui and verify it is still working (not sure if we have any tests)","type":"feature","status":"open","priority":1,"labels":null,"assignee":"","created":"2026-02-14T17:27:49.815938946Z","updated":"2026-02-14T17:27:49.815938946Z"}
{"id":"NK-8rhpp3","title":"v2 frontend: when selected, don't change style of feed items","description":"Just leave them the same when j/k \"selects\" an item. No blue side thing, no change in background, it's distracting. Just scroll it to the right place.","type":"bug","status":"closed","priority":0,"labels":null,"assignee":"","created":"2026-02-14T00:39:50.01934312Z","updated":"2026-02-14T01:02:54.204739756Z"}
{"id":"NK-8s75ec","title":"page size and performance","description":"Do some analysis of page size (css/html/javascript) on the legacy version vs. new version and give me a report. We want it to be small and fast! If the new version is much worse file some tickets to investigate further.","type":"task","status":"closed","priority":0,"labels":null,"assignee":"","created":"2026-02-13T20:16:13.898081788Z","updated":"2026-02-13T21:50:12.004391671Z"}
{"id":"NK-9hx0y7","title":"Implement Frontend Login","description":"Create login page and auth logic in the new React frontend. Port functionality from legacy login.html.","type":"","status":"closed","priority":1,"labels":null,"assignee":"","created":"2026-02-13T05:44:01.546395342Z","updated":"2026-02-13T05:50:33.877452063Z"}
@@ -31,7 +32,7 @@
{"id":"NK-chns2b","title":"reach parity between vanilla js and react v2 ui","description":"Continue implementing the vanilla js one with minimal overhad/depdnencies to be fast and lean. Make sure there are tests and rely on the v2 ui and legacy version as references.","type":"epic","status":"closed","priority":1,"labels":null,"assignee":"","created":"2026-02-14T04:45:06.813453353Z","updated":"2026-02-14T04:45:06.813453353Z"}
{"id":"NK-d4c8jv","title":"Vanilla JS Parity: Read/Star/Filter","description":"Implement read/unread toggle, star/unstar, and special filters (All, Unread, Starred) in vanilla JS prototype.","type":"feature","status":"closed","priority":1,"labels":null,"assignee":"","created":"2026-02-14T04:46:32.113504545Z","updated":"2026-02-14T04:47:46.412290355Z"}
{"id":"NK-doss0v","title":"v2 ui: change title fonts to Helvetica Neue","description":"to match style in legacy change font to match Helventic Neue where applicable","type":"bug","status":"closed","priority":0,"labels":null,"assignee":"","created":"2026-02-14T06:27:57.270935467Z","updated":"2026-02-14T06:31:42.798620609Z"}
-{"id":"NK-dp5efo","title":"v2 ui: themes","description":"simplify the themes selector by getting of the giant THEMES title\n\nloook at the logic for the theme colors, it doesn't look like the feed item text is changing right. look at the legacy one for behavior.\n\nLet's also simplify down to just light and dark themes (white bg, black bg) and use an emoji or something to distinguish.","type":"bug","status":"open","priority":0,"labels":null,"assignee":"","created":"2026-02-14T06:30:23.170098963Z","updated":"2026-02-14T06:30:23.170098963Z"}
+{"id":"NK-dp5efo","title":"v2 ui: themes","description":"simplify the themes selector by getting of the giant THEMES title\n\nloook at the logic for the theme colors, it doesn't look like the feed item text is changing right. look at the legacy one for behavior.\n\nLet's also simplify down to just light and dark themes (white bg, black bg) and use an emoji or something to distinguish.","type":"bug","status":"closed","priority":0,"labels":null,"assignee":"","created":"2026-02-14T06:30:23.170098963Z","updated":"2026-02-14T17:30:10.097878555Z"}
{"id":"NK-e07i2w","title":"v2 ui: sidebar design","description":"I don't like the new sidebar design in v2 compared to v1. although I realize the v1 is kind of dated. can you take another pass at it -- more like v1, but you can spice it up a little bit maybe. but remember, this is a minimalist, simple, fast rss reader.","type":"feature","status":"open","priority":1,"labels":null,"assignee":"","created":"2026-02-14T17:07:54.877100059Z","updated":"2026-02-14T17:07:54.877100059Z"}
{"id":"NK-ed1iah","title":"Make feed crawling async in API","description":"Currently, POST /api/feed triggers an immediate crawl which blocks the response (or at least keeps the goroutine alive). Refactor the crawling architecture to be truly async with a job queue or status updates, improving API responsiveness and reliability.","type":"cleanup","status":"icebox","priority":4,"labels":null,"assignee":"","created":"2026-02-13T04:26:55.908243985Z","updated":"2026-02-13T04:26:55.908243985Z"}
{"id":"NK-ek0cox","title":"Implement Item Interactions","description":"Add ability to toggle read/unread and star/unstar status for items. Use PUT /item/:id","type":"","status":"closed","priority":1,"labels":null,"assignee":"","created":"2026-02-13T14:55:14.825454967Z","updated":"2026-02-13T14:58:18.307521003Z"}
diff --git a/frontend/src/App.css b/frontend/src/App.css
index ff3ea60..97b7d65 100644
--- a/frontend/src/App.css
+++ b/frontend/src/App.css
@@ -66,7 +66,7 @@ body {
.dashboard-sidebar {
width: 15rem;
background: var(--sidebar-bg);
- border-right: 1px solid #999;
+ border-right: 1px solid var(--border-color);
display: flex;
flex-direction: column;
overflow-y: auto;
diff --git a/frontend/src/components/FeedItem.css b/frontend/src/components/FeedItem.css
index 1736032..fc2c850 100644
--- a/frontend/src/components/FeedItem.css
+++ b/frontend/src/components/FeedItem.css
@@ -52,7 +52,8 @@
}
.star-btn.is-unstarred {
- color: black;
+ color: var(--text-color);
+ opacity: 0.3;
}
.star-btn:hover {
@@ -60,8 +61,8 @@
}
.action-btn {
- background: whitesmoke;
- border: none;
+ background: var(--sidebar-bg);
+ border: 1px solid var(--border-color, #ccc);
cursor: pointer;
padding: 2px 6px;
font-size: 1rem;
@@ -102,7 +103,8 @@
.item-description blockquote {
padding: 1rem 1rem 0 1rem;
- border-left: 4px solid #ddd;
- color: #666;
+ border-left: 4px solid var(--sidebar-bg);
+ color: var(--text-color);
+ opacity: 0.8;
margin-left: 0;
} \ No newline at end of file
diff --git a/frontend/src/components/FeedItems.css b/frontend/src/components/FeedItems.css
index 02323a9..7154ac2 100644
--- a/frontend/src/components/FeedItems.css
+++ b/frontend/src/components/FeedItems.css
@@ -5,7 +5,7 @@
.feed-items h2 {
margin-top: 0;
- border-bottom: 2px solid #eee;
+ border-bottom: 2px solid var(--border-color);
padding-bottom: 0.5rem;
}
diff --git a/frontend/src/components/FeedList.css b/frontend/src/components/FeedList.css
index ff0f41b..fa0278a 100644
--- a/frontend/src/components/FeedList.css
+++ b/frontend/src/components/FeedList.css
@@ -15,23 +15,24 @@
.search-input {
width: 100%;
padding: 0.5rem;
- border: 1px solid #999;
- background: #eee;
+ border: 1px solid var(--border-color, #999);
+ background: var(--bg-color);
+ color: var(--text-color);
font-size: 1rem;
font-family: inherit;
}
.search-input:focus {
outline: none;
- background: white;
- border-color: #000;
+ background: var(--bg-color);
+ border-color: var(--link-color);
}
.feed-list h2,
.feed-section-header {
font-size: 1.2rem;
margin-bottom: 0.5rem;
- border-bottom: 1px solid #999;
+ border-bottom: 1px solid var(--border-color, #999);
padding-bottom: 0.25rem;
text-transform: uppercase;
letter-spacing: 1px;
@@ -149,22 +150,20 @@
}
.theme-selector button {
- font-size: 0.8rem;
- padding: 0.2rem 0.5rem;
- width: 30%;
- background: whitesmoke;
- color: blue;
- border: 1px solid #ccc;
+ font-size: 1.2rem;
+ padding: 0.5rem;
+ width: 48%;
+ background: var(--sidebar-bg);
+ border: 1px solid var(--border-color, #ccc);
border-radius: 4px;
- font-variant: small-caps;
- text-transform: lowercase;
}
.theme-selector button:hover {
- background: #eee;
+ background: var(--bg-color);
}
.theme-selector button.active {
- color: black;
- border-color: #000;
-}
+ background: var(--bg-color);
+ border-color: var(--link-color);
+ box-shadow: 0 0 5px var(--link-color);
+} \ No newline at end of file
diff --git a/frontend/src/components/FeedList.tsx b/frontend/src/components/FeedList.tsx
index d2dc8e1..1cd1bfd 100644
--- a/frontend/src/components/FeedList.tsx
+++ b/frontend/src/components/FeedList.tsx
@@ -138,14 +138,19 @@ export default function FeedList({
<div className="theme-section">
<div className="theme-selector">
- <button onClick={() => setTheme('light')} className={theme === 'light' ? 'active' : ''}>
- light
+ <button
+ onClick={() => setTheme('light')}
+ className={theme === 'light' ? 'active' : ''}
+ title="Light Theme"
+ >
+ ☀️
</button>
- <button onClick={() => setTheme('dark')} className={theme === 'dark' ? 'active' : ''}>
- dark
- </button>
- <button onClick={() => setTheme('black')} className={theme === 'black' ? 'active' : ''}>
- black
+ <button
+ onClick={() => setTheme('dark')}
+ className={theme === 'dark' ? 'active' : ''}
+ title="Dark Theme"
+ >
+ 🌙
</button>
</div>
</div>
diff --git a/frontend/src/components/Settings.css b/frontend/src/components/Settings.css
index 6e74475..171dcad 100644
--- a/frontend/src/components/Settings.css
+++ b/frontend/src/components/Settings.css
@@ -5,11 +5,11 @@
}
.add-feed-section {
- background: #f9f9f9;
+ background: var(--sidebar-bg);
padding: 1.5rem;
border-radius: 8px;
margin-bottom: 2rem;
- border: 1px solid #eee;
+ border: 1px solid var(--border-color);
}
.add-feed-form {
@@ -20,7 +20,9 @@
.feed-input {
flex: 1;
padding: 0.5rem;
- border: 1px solid #ccc;
+ border: 1px solid var(--border-color);
+ background: var(--bg-color);
+ color: var(--text-color);
border-radius: 4px;
font-size: 1rem;
}
@@ -33,7 +35,7 @@
.settings-feed-list {
list-style: none;
padding: 0;
- border: 1px solid #eee;
+ border: 1px solid var(--border-color);
border-radius: 8px;
}
@@ -42,7 +44,7 @@
justify-content: space-between;
align-items: center;
padding: 1rem;
- border-bottom: 1px solid #eee;
+ border-bottom: 1px solid var(--border-color);
}
.settings-feed-item:last-child {
@@ -61,7 +63,8 @@
}
.feed-url {
- color: #666;
+ color: var(--text-color);
+ opacity: 0.6;
font-size: 0.9rem;
}
@@ -81,4 +84,4 @@
.delete-btn:disabled {
background: #ffcdd2;
cursor: not-allowed;
-}
+} \ No newline at end of file
diff --git a/frontend/src/index.css b/frontend/src/index.css
index 209a30a..3365d34 100644
--- a/frontend/src/index.css
+++ b/frontend/src/index.css
@@ -30,6 +30,16 @@ h5,
background-color: var(--bg-color);
}
+.theme-light {
+ --bg-color: #ffffff;
+ --text-color: rgba(0, 0, 0, 0.87);
+ --sidebar-bg: #ccc;
+ --link-color: #0000ee;
+ --border-color: #999;
+ background-color: var(--bg-color);
+ color: var(--text-color);
+}
+
@media (prefers-color-scheme: dark) {
:root {
--bg-color: #24292e;
@@ -43,25 +53,16 @@ h5,
}
.theme-dark {
- --bg-color: #24292e;
- --text-color: #ffffff;
- --sidebar-bg: #1b1f23;
- --link-color: rgb(90, 200, 250);
- background-color: var(--bg-color);
- color: var(--text-color);
-}
-
-.theme-black {
--bg-color: #000000;
--text-color: #ffffff;
--sidebar-bg: #111111;
--link-color: rgb(90, 200, 250);
+ --border-color: #333;
background-color: var(--bg-color);
color: var(--text-color);
}
-.theme-dark button,
-.theme-black button {
+.theme-dark button {
background-color: #333;
color: #fff;
}