Skip to content

feat(client): personalize empty-feed follow suggestions - #14562

Merged
dylanjeffers merged 1 commit into
mainfrom
feat/suggested-follows
Aug 18, 2026
Merged

feat(client): personalize empty-feed follow suggestions#14562
dylanjeffers merged 1 commit into
mainfrom
feat/suggested-follows

Conversation

@dylanjeffers

Copy link
Copy Markdown
Contributor

Wires GET /users/:id/suggested-follows (AudiusProject/api#1020) into the two surfaces that currently show a hardcoded list: web's empty feed and mobile's SuggestedFollows.

Depends on AudiusProject/api#1020 being merged and deployed. Until then sdk.users.getSuggestedFollows 404s. It degrades to the current behavior rather than breaking — an errored query leaves data undefined, which takes the fallback path — but it'll be noisy in the meantime, so please don't merge this first.

Shape

useFollowSuggestions is the shared entry point: personalized suggestions when the user has favorites or reposts to draw on, the existing SUGGESTED_FOLLOW_HANDLES list when they don't. Both surfaces go through it so the fallback rule lives in one place instead of being duplicated per platform.

Sign-up artist selection deliberately keeps the static list — personalization has nothing to work with for an account that's seconds old.

The fallback is fetched unconditionally rather than gated on the personalized query returning empty. Empty is the new-account case these surfaces exist for, so gating would put a serial round-trip in front of exactly the users who need them most, and the fallback is a small static file. Web also swaps its copy when the suggestions are personalized.

The hand-written SDK method

sdk.users.getSuggestedFollows is hand-written in the UsersApi wrapper rather than generated, because npm run gen pulls the spec from a running node — the generated method can't exist until the API side deploys. It mirrors what the generator emits, so swapping to the generated one later is a no-op for callers. Both it and GetSuggestedFollowsRequest carry a comment saying to delete them after the next regen.

Testing

sdk, common, web, and mobile all typecheck clean; eslint clean on the changed files.

Not verified: this hasn't been run against a live API with real data, so the render and the fallback switch are unproven at runtime — worth exercising once the API PR is deployed to staging.

🤖 Generated with Claude Code

Wires the new GET /users/:id/suggested-follows endpoint into the two
surfaces that currently show a hardcoded list: web's empty feed and
mobile's SuggestedFollows.
useFollowSuggestions is the shared entry point -- personalized
suggestions when the user has favorites or reposts to draw on, and the
existing SUGGESTED_FOLLOW_HANDLES list when they don't. Both surfaces go
through it so the fallback rule lives in one place rather than being
duplicated per platform. Sign-up artist selection deliberately keeps the
static list; personalization has nothing to work with there.
The fallback is fetched unconditionally rather than gated on the
personalized query coming back empty. Empty is exactly the new-account
case these surfaces exist for, so gating would put a serial round-trip in
front of the users who need them most, and the fallback is a small static
file.
sdk.users.getSuggestedFollows is hand-written rather than generated: `npm
run gen` pulls the spec from a running node, so the generated method
can't exist until the API side deploys. It mirrors what the generator
emits, and both it and its request type carry a comment to delete them
after the next regen.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@changeset-bot

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 22163a7

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@dylanjeffers
dylanjeffers merged commit 0736770 into mainAug 18, 2026
22 checks passed
@dylanjeffers
dylanjeffers deleted the feat/suggested-follows branch August 18, 2026 22:04
dylanjeffers added a commit that referenced this pull request Aug 24, 2026
Wires `GET /users/:id/discover-weekly` into the Explore page on web and
native, rendered as a collection card so the mix reads like a playlist.
Depends on [api#1025](AudiusProject/api#1025)
and [api#1026](AudiusProject/api#1026) — both
merged and live in production.
## What's here
- `useDiscoverWeekly` — a plain `useQuery`, not infinite. The mix is a
fixed-size artifact, not a lineup you scroll; there is no page 2.
- `sdk.users.getDiscoverWeekly` — hand-written pending the next SDK
regen, same as `getSuggestedFollows` in #14562, since `npm run gen`
pulls the spec from a running node.
- Web section (desktop + mobile web) and a parallel native section,
since `packages/mobile` composes its own Explore screen.
## Three decisions worth reviewing
**The artwork is a checked-in asset.** The mix has no `playlist_id` to
hang cover art on — Audius playlists are on-chain entities and the mix
is computed per request. Styled to sit alongside the Hot & New playlist
art.
**Clicking plays instead of navigating.** No permalink to navigate to,
so the card queues all 30 starting at the top. Closest thing to playlist
behavior without a route.
**No section heading or Carousel.** One card, so the scroll affordance
is dead weight and a heading would repeat the card's own title.
## Known gaps
- **The card has playlist affordances without playlist substance** —
can't be favorited, reposted, shared, or linked to. Closing that needs
the stored track-list per `(user, year, week)`, which would also fix the
mid-week drift noted in api#1025.
- **Not visually verified in the running app** at time of opening — the
section is signed-in-only.
## Verification
`tsc` and eslint clean across web, mobile, and sdk. The one `common`
error (`getDiscoverWeekly` not on `UsersApi`) is the known SDK-dist
parity issue — the built `dist/index.d.ts` types `sdk.users` as the
generated class, so the already-merged `useSuggestedFollows` produces an
identical error. Resolves on the next regen.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@dylanjeffers