| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
|
|
|
|
| |
Service worker now only caches Supabase REST responses when the user's
tier allows offline reading. Client syncs tier status to SW via
postMessage after profile loads. Free users see a descriptive offline
banner instead of stale cached data.
|
| |
|
|
|
|
|
|
|
| |
Disable no-img-element (RSS reader needs <img> for arbitrary external
URLs). Remove unused variables/imports and redundant getUser() calls
guarded by middleware. Fix exhaustive-deps by adding stable deps,
wrapping handlers in useCallback, and suppressing intentional omissions.
Fix ref cleanup in use-realtime-entries. Allow triple-slash TS reference
directives in no-comments rule.
|
| |
|
|
|
|
|
|
|
|
|
| |
P0: add missing 'developer' case to check_custom_feed_limit trigger,
scope user_entry_states join to authenticated user in API v1 entries,
replace in-memory rate limiting with Supabase-backed check_rate_limit RPC.
P1: fix all 9 ESLint errors — useSyncExternalStore for useIsMobile,
restructure WebhookSection to avoid set-state-in-effect, move ref
mutations into useEffect, replace <a> with <Link> on shared page,
ignore generated public/sw.js in eslint config.
|
| |
|
|
|
|
| |
Persist React Query cache to IndexedDB via idb-keyval so timeline,
entry details, subscriptions, and other read data survive page reloads
and brief offline periods. Add network status banner in reader layout.
|
| |
|
|
|
|
|
|
|
|
|
|
| |
clamping
Use imperative groupRef API to resize panels instantly instead of
writing to localStorage and calling window.location.reload(). Register
reset callbacks in Zustand store from layout components.
Change sidebarMaxWidth early return from && to || so the generous 35%
fallback is used until both subscriptions and custom feeds have loaded,
preventing intermittent clamping to minimum size.
|
| |
|
|
|
|
| |
Return 35% max until subscriptions/feeds data loads. Previously the
useMemo computed a small max from just nav items on first render,
causing the library to clamp and overwrite the stored sidebar width.
|
| |
|
|
|
|
| |
When sidebar is collapsed, the Group fires onLayoutChanged with only
main-content, overwriting the stored sidebar size. Pass undefined for
onLayoutChanged when collapsed so the stored layout is preserved.
|
| |
|
|
|
|
| |
Measures all sidebar items (nav links, feeds, folders, custom feeds,
footer) using Canvas measureText to determine the narrowest width
that avoids truncation, then passes it as the Panel maxSize.
|
| |
|
|
|
|
|
|
| |
The dynamic measurement approach failed because the library caches
Panel constraints at mount and ignores state-driven prop updates.
Now uses fixed rem values (12rem min, 16rem default) which scale
with font size, plus whitespace-nowrap on all sidebar items to
prevent text wrapping at any width.
|
| |
|
|
|
|
| |
querySelectorAll(':scope > *') misses bare text nodes like
'notifications' in the footer button. Now walks childNodes to
handle mixed text node + element children correctly.
|
| |
|
|
|
|
| |
Notifications button text is wider than all entries. Now measures
all nav items AND footer links/buttons, taking the widest row plus
badge reserve as the sidebar minimum width.
|
| |
|
|
|
|
| |
getBoundingClientRect on wrapped text returns the narrow wrapped
width, not the single-line width. Canvas measureText is layout-
independent and gives the true single-line intrinsic text width.
|
| |
|
|
|
|
| |
scrollWidth on a block flex element returns parent width, not content
width. Now sums getBoundingClientRect().width of each child element
(text span + unread badge) for a screen-independent measurement.
|
| |
|
|
|
|
| |
Measures the first sidebar nav item (all entries + unread badge)
after mount and uses its scrollWidth + padding as minSize. Default
is 1.4x the minimum for comfortable reading of feed titles.
|
| |
|
|
|
| |
Wire useDefaultLayout to sidebar Group with localStorage storage.
Update reset command to clear both sidebar and detail layout keys.
|
| |
|
|
|
| |
v4 treats numeric size props as pixels, not percentages.
defaultSize={20} was rendering as 20px (~1.9% of viewport).
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
settings
- Rename "muted keywords" to "muted phrases" throughout settings UI
- Add header with navigation to auth pages (sign-in, sign-up, etc.)
- Merge security tab (TOTP setup) into account settings tab
- Fix TOTP name input truncation on Safari (w-64 → flex-1 min-w-0)
- Add appearance settings: font size, time display format, entry images toggle, reading time toggle
- Add keyboard shortcuts dialog (? key) with all keybindings documented
- Add extended vim shortcuts: gg, G, n/N (next/prev unread), Ctrl+h/l (panel focus)
- Add command palette shortcut (⌘K) to shortcuts dialog
- Add icon URL fields for folders and custom feeds (DB + queries + settings UI)
- Add data-has-unreads attribute for sidebar keyboard navigation
- Fix SSR prerendering crash from Zustand persist and react-resizable-panels localStorage access
- Add detail panel layout persistence via useDefaultLayout
- Update marketing copy to advertise vim-like keyboard navigation
|
|
|
Full-stack RSS reader SaaS: Supabase + Next.js + Go worker.
Includes three subscription tiers (free/pro/developer), API key auth,
read-only REST API, webhook push notifications, Stripe billing with
proration, and PWA support.
|