#154

Fix notifications Load More feedback and URL-encode before cursor

Status: open
Lensflare Lensflare ·

Summary

The "Load More" button on the notifications page (/notifications) appears broken: clicking it seems to just reload the same page. The backend is not broken - API pagination via the before cursor works correctly (verified over JSON and HTML, and a third-party client using the API paginates fine).

The button is a plain full-page link (<a href="/notifications?before=..."> styled as btn btn-secondary btn-sm), so clicking it causes a hard navigation: scroll position resets to top and the whole page re-renders. Because the feed is dominated by dozens of near-identical rows (e.g. "retoor sent you a message") with coarse relative timestamps ("1d ago" covers a whole day), and every page starts with the same "Notifications" heading and section labels ("Today", "Yesterday", "This week"), the new page looks exactly like the old one.

Secondary hygiene issue: the Load More href ships the cursor with a raw, unencoded + (the UTC offset): /notifications?before=2026-08-03T15:58:20.244013+00:00. In a query string + decodes to a space; the server happens to parse this correctly today, but the cursor should be percent-encoded (%2B) to be safe.

Steps to Reproduce

  1. Open /notifications in the web app.
  2. Scroll down and click the "๐Ÿ“„Load More" button (a plain <a href="/notifications?before=...">).
  3. Observe that the page navigates, scroll position resets to top, and the visible rows look identical to the previous page - indistinguishable from a full page reload. There is no loading state, no indication that older entries were loaded, and no indication of which time range is now shown.

Expected Behaviour

  • Load More should give clear feedback that older notifications were loaded, ideally by appending them to the existing list (AJAX/fetch) instead of a full navigation, keeping the scroll position.
  • At minimum: show a loading state, keep scroll position, and display the loaded time range so the page cannot be mistaken for a reload.
  • The before cursor in the href should be URL-encoded.

Actual Behaviour

  • Clicking Load More causes a full page navigation with no loading state; scroll position resets to top and the visible content is indistinguishable from a reload.
  • The before cursor is present unencoded with a raw + in the query string: /notifications?before=2026-08-03T15:58:20.244013+00:00.

Environment

  • Web app on https://devplace.net, Chrome (1920x955), signed in.
  • API GET /notifications?before=<cursor> verified working over both Accept: text/html and Accept: application/json; also confirmed working from an external API client (iOS app).

Reported by Lensflare via DevPlace.

Updates & comments

No updates yet.

Log in to comment.