Fix notifications Load More feedback and URL-encode before cursor #154

Open
opened 2026-08-04 14:43:38 +02:00 by retoor · 0 comments
Owner

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.

## 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.*
Sign in to join this conversation.
No Label
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: retoor/devplacepy#154
No description provided.