10 Commits
Author SHA1 Message Date
Laan Tungir 1a17bef1ac Implement Phase 1 remaining tasks: notifications append-only, listener leak fix, memory caps
Task 1.2: Append-only rendering for notifications page
- Extracted buildNotificationRow(item) helper from renderNotifications()
- Added prependNotificationRow(item) with sorted insertion by created_at
- addNotificationFromEvent uses prepend when DOM has children

Task 1.3: Fix notification document.click listener leak
- Removed per-row document.addEventListener('click') that leaked on every render
- Added single delegated click listener in main() using .notif-menu-panel class
- Menu panels still close when clicking outside .notif-right

Task 1.4: Cap posts[] and postIds with rolling eviction
- Added MAX_STORED_POSTS=500 constant to feed.html and post.html
- Added prunePostsArray() that sorts, slices, rebuilds postIds/renderedPostIds
- Called in upsertFeedPost/upsertPost with +50 batch threshold
- post.html skips pruning in event mode

Task 1.5: Cap notificationsById/unreadNotificationsById with periodic pruning
- Added MAX_STORED_NOTIFICATIONS=500, MAX_POST_IMAGE_CACHE=200
- Added pruneNotificationMaps() that prunes both Maps and LRU-caps postImageCache
- Called in addNotificationFromEvent, hydrateNotificationsFromCache/Relays

Updated plan checklist marking all Phase 1 tasks complete.
2026-07-01 09:33:29 -04:00
Laan Tungir 04405da933 Fix feed page dropped posts: out-of-order events and race condition
prependPostCard() now inserts posts in the correct sorted position within
the existing DOM instead of falling back to a full renderFeed() rebuild
when a post is older than the first visible post. This handles relays
that deliver events out of order without wiping the feed.

Also fixed a race condition in fetchFeedWindow: the fire-and-forget
ndkFetchEvents callback was calling renderFeed() after bootstrap
completed, which wiped prepended live posts and caused concurrent
rebuild races. Now it only calls renderFeed() if the feed hasn't been
rendered yet (renderedPostIds.size === 0).

Same prependPostCard sorted-insert fix applied to post.html.
2026-07-01 09:22:33 -04:00
Laan Tungir ee0077063d Implement append-only rendering for feed and post pages (task 1.1)
Split renderFeed() into full rebuild + prependPostCard() on both feed.html
and post.html. New live events now prepend a single card at the top of the
feed without rebuilding existing cards, eliminating O(n) DOM rebuilds on
every incoming event. DOM is trimmed to displayCount on overflow with
renderedPostIds kept in sync. Full rebuild path preserved for See More,
mute removal, bootstrap completion, and event mode.

Also added implementation checklist to plans/long-running-memory-bloat-fix.md.
2026-07-01 07:59:39 -04:00
Laan Tungir bff0bca411 Remove redundant warmOutbox calls from ensureLiveFeedSubscription and newAuthors path — NDK.subscribe already calls trackUsers internally, so only the pre-bootstrap warmOutbox is needed. This reduces the outbox event burst that was starving the worker message queue. 2026-06-26 10:17:56 -04:00
Laan Tungir c758333269 Implement feed outbox model pre-warming (Phases 1-3) and relays.html connection history toggle with performance fixes (Phase 4)
Phase 1 (ndk-worker.js): Add warmOutbox, setRelayEventLogging, and getDiscoveredRelays RPC handlers. Gate broadcastRelayEvent and logRelayEvent IndexedDB writes behind relayEventLoggingEnabled flag (default off). trackRelayRead/trackRelayWrite left ungated to preserve footer activity carrots.

Phase 2 (init-ndk.mjs): Add warmOutbox, setRelayEventLogging, and getDiscoveredRelays page API exports with proper request/response wiring and timeouts.

Phase 3 (feed.html): Pre-warm outbox tracker via warmOutbox() before bootstrapFeedPosts and fetchFeedWindow calls so NDK routes author-based subscriptions to follows' write relays before short-lived fetchEvents EOSE.

Phase 4 (relays.html): Add 'Show connection history' sidenav toggle (sidenavRowToggle pattern from feed.html), gate ndkRelayEvent listener and DB loading behind connectionHistoryEnabled flag, switch live event stream to incremental DOM appending, sync state on init/beforeunload.
2026-06-26 09:38:31 -04:00
Laan Tungir 543ae6a1b3 Fix feed.html: disable inline comment rendering that caused flash of replies
Two fixes:
1. post-interactions2.mjs: only call addCommentToPost when getCommentsVisible() is true
2. feed.html: call cards.setCommentsVisible(false) after initPostCards to disable
   inline comment rendering for the new simplified feed

The old feed (feed-old.html) still has the Comments toggle and can re-enable them.
2026-06-25 21:02:21 -04:00
Laan Tungir 508952a1ea Rename feed.html -> feed-old.html, feed2.html -> feed.html
The new simplified feed (formerly feed2.html) is now the primary feed page.
Updated post-feed.html back button to point to feed.html instead of feed2.html.
2026-06-25 20:57:34 -04:00
Laan Tungir e943870d77 Port projects page functionality into template with public/no-login mode and project-native styling 2026-05-28 14:44:00 -04:00
Laan Tungir 9c85c8ec5e Vendor CDN scripts locally for FIPS HTTP compatibility 2026-04-19 13:37:32 -04:00
Laan Tungir a8bbbbafb9 rename to client 2026-04-17 16:52:51 -04:00