Skip to content

Who-to-follow: 5 on home + dedicated paginated page (frontend)#303

Merged
filinvadim merged 7 commits into
developfrom
claude/nice-brown-yf3c6z
Jun 22, 2026
Merged

Who-to-follow: 5 on home + dedicated paginated page (frontend)#303
filinvadim merged 7 commits into
developfrom
claude/nice-brown-yf3c6z

Conversation

@filinvadim

@filinvadim filinvadim commented Jun 21, 2026

Copy link
Copy Markdown
Member

Summary

Frontend-only changes to the Who-To-Follow experience. (An earlier backend
recommendation rework was reverted at the author's request — this PR ships UI
changes that work against the existing, unchanged handler.)

Changes

  • Home sidebar (components/WhoToFollow.vue): shows 5 recommendations;
    "Show More" now navigates to a dedicated page instead of appending inline.
  • Dedicated page (views/WhoToFollow.vue + /who-to-follow route): full
    paginated recommendations list modeled on the followers list, with a guarded
    "Show More" (no concurrent fetches, error-handled).
  • Service (service/service.js): getWhoToFollow is strictly scoped to the
    signed-in owner (always sends the owner's id), takes a configurable limit,
    guards a missing owner / invalid response, and only ends the cursor on a
    successful empty page.
  • Added tests/views/WhoToFollow.spec.js (initial fetch, empty/end state,
    pagination append, back navigation).

All recommendations are scoped to the signed-in owner.

🤖 Generated with Claude Code

https://claude.ai/code/session_01K32zQa9jDnomaYXiSGKRVw

Backend:
- Rank recommendations owner-centrically: an RTT-nearest baseline is served
  synchronously, while followings-of-followings is computed in the background
  and cached for the next open (hybrid). New accounts (empty follow graph)
  stay RTT-only.
- Always pin the Mastodon entry account on top until it is followed, bypassing
  the avatar/tweets quality filters that previously hid the seeded entry.
- Fetch the full following set (drop the hardcoded 80 cap) for already-followed
  exclusion and FoF seeding.
- Offset-cursor pagination over the ranked snapshot.

Frontend:
- Home sidebar shows 5 recommendations; "Show More" now opens a dedicated
  /who-to-follow page (owner-scoped, 20 per page) modeled on the followers
  list, instead of appending inline.
- getWhoToFollow takes a limit and terminates pagination on the end cursor.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K32zQa9jDnomaYXiSGKRVw
@codecov-commenter

codecov-commenter commented Jun 21, 2026

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

claude added 3 commits June 21, 2026 21:17
- Bound the page limit to whoToFollowMaxLimit before the uint64->int
  conversion (prevents offset+size overflow) and annotate the conversion.
- Use the min builtin for the page-end clamp.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K32zQa9jDnomaYXiSGKRVw
- Replace the limit clamp if-statement with min() (modernize).
- Rename the followings-count locals from cnt to followCount for clarity.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K32zQa9jDnomaYXiSGKRVw
…hot)

Per review: the cursor must stay an opaque BadgerDB key like every other
list handler. Reverted the in-memory snapshot + offset cursor + background
FoF fan-out; page natively via userRepo.WhoToFollow(limit, cursor):

- candidates come back in RTT-key order, so a new account (empty graph)
  gets nearest-by-RTT peers and pagination stays cursor-based.
- keep the original exclusions (self, already-followed, offline, per-node
  dedup) and the cross-network filter.
- pin the Mastodon entry account on the owner's first page until followed
  (it is seeded without avatar/tweets, so it never survives the candidate
  filters and must be surfaced explicitly).

Frontend (5 on home, paginated /who-to-follow page) is unchanged and works
with the native cursor.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K32zQa9jDnomaYXiSGKRVw
@filinvadim filinvadim closed this Jun 21, 2026
@filinvadim filinvadim reopened this Jun 21, 2026
Per request, revert the recommendation handler, its test, and the node
registration back to develop. The branch now ships frontend-only changes
that work against the unchanged backend handler:

- home sidebar shows 5 recommendations with a "Show More" link
- new paginated /who-to-follow page + route
- getWhoToFollow gains a limit arg and stops on the end cursor

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K32zQa9jDnomaYXiSGKRVw

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Refactors the Who-To-Follow experience to support a dedicated, paginated recommendations page and extends the frontend service API to request variable-sized pages.

Changes:

  • Added a new /who-to-follow route and a dedicated WhoToFollow view with “Show More” pagination.
  • Updated the right-rail WhoToFollow component to link to the dedicated view and request a smaller initial batch.
  • Extended warpnetService.getWhoToFollow() to accept a configurable limit and adjusted cursor handling.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
version Bumps app version to 0.7.343.
frontend/src/views/WhoToFollow.vue New full-page recommendations view with pagination button and basic layout.
frontend/src/service/service.js Adds limit parameter to getWhoToFollow and tweaks cursor end handling.
frontend/src/router/index.js Registers the new /who-to-follow protected route.
frontend/src/components/WhoToFollow.vue Changes “Show More” to navigate to the new route and limits initial fetch to 5 users.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread frontend/src/service/service.js
Comment thread frontend/src/components/WhoToFollow.vue Outdated
Comment on lines +112 to +115
this.ownerProfile = warpnetService.getOwnerProfile();
const effectiveProfile = this.profile || this.ownerProfile;
const profileId = effectiveProfile?.id || effectiveProfile?.user_id;
this.profiles = await warpnetService.getWhoToFollow(profileId, true)
this.profiles = await warpnetService.getWhoToFollow(profileId, true, 5)
Addresses Copilot review on PR #303:
- Enforce owner scope at the single choke point: getWhoToFollow now always
  sends the signed-in owner's user_id and no longer accepts a per-call
  profile id, so recommendations can never be scoped to a viewed profile.
- Guard against a node response without a `users` field (avoid throwing on
  {code,message}/partial payloads).
- Drop the now-unused profile-id plumbing in the sidebar component and the
  dedicated /who-to-follow view.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K32zQa9jDnomaYXiSGKRVw

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.

Comment on lines 347 to 351
const followResp = await this.sendToNode(request);
if (!followResp || followResp.users.length === 0) {
if (!followResp || !followResp.users || followResp.users.length === 0) {
this.setCursor('whotofollow', endCursor)
return []
}
Comment on lines +89 to +99
async loadMore() {
if (!this.hasMore) {
return;
}
const users = await warpnetService.getWhoToFollow(false);
if (!users || users.length === 0) {
this.hasMore = false;
return;
}
this.profiles.push(...users);
},
Comment on lines +101 to +105
async created() {
console.log("loading component:", this.$options.name);
try {
const users = await warpnetService.getWhoToFollow(true);
this.profiles = users || [];
Comment thread version Outdated
@@ -1 +1 @@
0.7.339
0.7.344
- service.getWhoToFollow: return early if there is no signed-in owner, and
  only mark the cursor as ended on a successful empty response (don't end
  on a falsy/invalid response, so transient failures stay retryable).
- views/WhoToFollow.vue loadMore: guard against concurrent clicks via a
  loadingMore flag (also disables the button) and wrap the fetch in
  try/catch to avoid unhandled rejections / duplicate appends.
- add frontend/tests/views/WhoToFollow.spec.js covering initial fetch,
  empty/end state, pagination append, and back navigation.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K32zQa9jDnomaYXiSGKRVw
@filinvadim filinvadim changed the title Implement intelligent who-to-follow recommendations with FoF ranking Who-to-follow: 5 on home + dedicated paginated page (frontend) Jun 22, 2026
@filinvadim filinvadim merged commit 58ba99d into develop Jun 22, 2026
6 checks passed
@filinvadim filinvadim deleted the claude/nice-brown-yf3c6z branch June 22, 2026 09:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants