Skip to content

Public followers and following pages#491

Merged
dahlia merged 8 commits into
fedify-dev:mainfrom
dahlia:feat/following-followers
May 17, 2026
Merged

Public followers and following pages#491
dahlia merged 8 commits into
fedify-dev:mainfrom
dahlia:feat/following-followers

Conversation

@dahlia
Copy link
Copy Markdown
Member

@dahlia dahlia commented May 17, 2026

Adds public Followers and Following pages to every profile, with pagination (100 per page) and a substring search filter over display name and handle.

The followers list is always public. The following list is gated by a new per-account setting, Make following list public, off by default. When the toggle is off the page returns 404 Not Found, the ActivityPub following collection reports totalItems: 0 with no items, and the Mastodon-compatible GET /api/v1/accounts/:id/following returns an empty array. The toggle also round-trips through PATCH /api/v1/accounts/update_credentials as the standard hide_collections field, so existing Mastodon clients can read and write it.

The search filter uses ILIKE over accounts.name and accounts.handle, with \, %, and _ escaped in user input so wildcard characters can't slip through. Queries reuse the existing pg_trgm GIN indexes on those columns, so no new indexes were needed.

The schema change is one new boolean column on account_owners, following_list_public, default false. The generated migration lives at drizzle/20260517021029_account_owners_following_list_public/migration.sql.

Commits

  • Gate the following list on a per-account public/private flag (schema, migration, ActivityPub dispatcher, Mastodon API gating).
  • Expose the following-list visibility toggle in account settings (new Privacy section checkbox).
  • Add public followers and following pages (new src/pages/profile/follows.tsx).
  • Link follower / following counts on the profile card (src/components/Profile.tsx) and update CHANGES.md.

Test plan

  • mise run check (typecheck + Oxlint + Oxfmt) is green.
  • pnpm migrate:test && pnpm test:ci, 512 passed.
  • /@hongminhee/followers renders the profile card, the list, and paginates with ?page=N.
  • /@hongminhee/following returns 404 Not Found while the flag is off; toggling it on in account settings makes the page render and the AP collection report totalItems matching the row count.
  • Search for inputs containing % and _ finds no spurious matches.
  • Malformed ?page= values (0, -1, abc, 1.5, 999) all 404 Not Found.

dahlia added 4 commits May 17, 2026 11:16
Add `account_owners.following_list_public` (default false) and respect
it in three places that expose the list:

 -  the ActivityPub `setFollowingDispatcher` returns empty items and a
    zero counter when the flag is off, so remote servers can't enumerate
    the list either;
 -  the Mastodon-compatible `GET /api/v1/accounts/:id/following` returns
    an empty array when the target is a local account with the flag off;
 -  `PATCH /api/v1/accounts/update_credentials` now persists
    `hide_collections` to the flag (inverse), and `serializeAccountOwner`
    exposes `hide_collections` so clients can round-trip the value.

The followers list stays public unconditionally.

Assisted-by: Codex:gpt-5.5
Add a "Make following list public" checkbox to the dashboard's account
settings form, alongside the other Privacy toggles, and thread the value
through the create and edit handlers so it persists on `account_owners`.

Assisted-by: Codex:gpt-5.5
For each profile, expose `/@{handle}/followers` and (when the new
visibility flag is on) `/@{handle}/following` as plain HTML pages with
the same profile card on top and a paginated list of accounts below.
Pages are 100 entries each, ordered by follow-approval time, with a
substring filter over display name and handle backed by the existing
pg_trgm GIN indexes on `accounts.name` / `accounts.handle`.  The
filter input uses `ILIKE` with `\\%_` escaped to prevent unintended
wildcard matches.  The following page returns 404 when the account's
`following_list_public` flag is off, matching the behaviour already
applied to the ActivityPub collection and the Mastodon API.

Assisted-by: Codex:gpt-5.5
The followers count is now a link to the new `/@{handle}/followers`
page.  The following count becomes a link to `/@{handle}/following`
only when the new *Make following list public* flag is on; otherwise
it remains plain text so the URL is never offered when the page would
404 anyway.  Both links use a subtle theme-color hover transition,
consistent with the rest of the profile chrome.

Assisted-by: Codex:gpt-5.5
@dahlia dahlia added this to the Hollo 0.9 milestone May 17, 2026
@dahlia dahlia self-assigned this May 17, 2026
@dahlia dahlia added the enhancement New feature or request label May 17, 2026
@dahlia
Copy link
Copy Markdown
Member Author

dahlia commented May 17, 2026

@codex review

@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 🎉

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces public 'Followers' and 'Following' pages to user profiles, including pagination and a search filter. It also adds a per-account setting to toggle the visibility of the following list, which defaults to private. When the following list is private, the web page returns a 404, the ActivityPub collection is hidden, and the Mastodon-compatible API returns an empty array. One piece of feedback was provided regarding a variable name in the Mastodon API implementation to improve clarity and consistency with other endpoints.

Comment thread src/api/v1/accounts.ts Outdated
The Mastodon `/:id/following` handler reused `followers` as the local
variable name for the list of accounts being followed, mirroring the
adjacent `/:id/followers` handler. Renaming it to `following` lines
the variable up with the endpoint and removes the confusion at a
glance.

fedify-dev#491 (comment)

Assisted-by: Claude Code:claude-opus-4-7
@dahlia
Copy link
Copy Markdown
Member Author

dahlia commented May 17, 2026

/gemini review

@dahlia
Copy link
Copy Markdown
Member Author

dahlia commented May 17, 2026

@codex review

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request adds public Followers and Following pages to user profiles, including pagination and search capabilities. It also introduces a privacy setting to control the visibility of the following list across the web interface, Mastodon-compatible APIs, and ActivityPub federation. Feedback from the review suggests adding a secondary sort key to ensure deterministic pagination and refining the search logic to handle canonicalized handles more effectively.

Comment thread src/pages/profile/follows.tsx Outdated
Comment thread src/pages/profile/follows.tsx
@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Hooray!

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

The followers and following pages sorted by `follows.approved`
alone, so ties (rows approved at the same instant) could shift
between pages under offset pagination and items could be skipped
or repeated. Break ties by the other side's account id, which is
unique within an owner's follow set.

fedify-dev#491 (comment)

Assisted-by: Claude Code:claude-opus-4-7
@dahlia
Copy link
Copy Markdown
Member Author

dahlia commented May 17, 2026

/gemini review

@dahlia
Copy link
Copy Markdown
Member Author

dahlia commented May 17, 2026

@codex review

@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Already looking forward to the next diff.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces public 'Followers' and 'Following' pages for user profiles, including pagination and search functionality. It also adds a per-account setting to control the visibility of the following list, which defaults to private. The feedback provided identifies an inconsistency in the import pattern for the database connection in the newly added follows page, recommending a named import to align with the rest of the codebase.

Comment thread src/pages/profile/follows.tsx Outdated
Match the convention used by every other non-test file in src/ that
pulls in the database handle, including the neighbouring profile
route.

fedify-dev#491 (comment)

Assisted-by: Claude Code:claude-opus-4-7
@dahlia
Copy link
Copy Markdown
Member Author

dahlia commented May 17, 2026

/gemini review

@dahlia
Copy link
Copy Markdown
Member Author

dahlia commented May 17, 2026

@codex review

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request implements public 'Followers' and 'Following' pages for user profiles, featuring pagination and a substring search filter. It introduces a 'Make following list public' setting (defaulting to off) that gates the visibility of the following list in the web UI, ActivityPub collections, and Mastodon-compatible API endpoints. Feedback was provided regarding the optimization of the database query used for counting entries; specifically, removing a redundant join when no search query is active and capping the total count to prevent performance degradation on large datasets.

Comment thread src/pages/profile/follows.tsx Outdated
@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Another round soon, please!

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

When the followers / following page has no search query, the count
query no longer joins against `accounts`. The `where` clause already
filters on `follows` alone, and the join was only there to support
the `ILIKE` filter, so the unfiltered count now goes straight against
the partial index on `(follower|following_id, approved)`.

fedify-dev#491 (comment)

Assisted-by: Claude Code:claude-opus-4-7
@dahlia
Copy link
Copy Markdown
Member Author

dahlia commented May 17, 2026

/gemini review

@dahlia
Copy link
Copy Markdown
Member Author

dahlia commented May 17, 2026

@codex review

@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Nice work!

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request implements public "Followers" and "Following" pages for user profiles, featuring pagination and a search filter. It introduces a "Make following list public" setting that gates visibility across the web UI, ActivityPub collections, and Mastodon-compatible APIs. Feedback suggests documenting the current limitation where these pages only resolve local accounts, as well as improving handle normalization and search query logic for better federation compatibility.

Comment thread src/pages/profile/follows.tsx
@dahlia dahlia merged commit c775864 into fedify-dev:main May 17, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant