Skip to content

Fixed social web handle not being constructed from API in Notes/Reader#28477

Merged
sagzy merged 1 commit into
mainfrom
ap-display-correct-handle
Jun 10, 2026
Merged

Fixed social web handle not being constructed from API in Notes/Reader#28477
sagzy merged 1 commit into
mainfrom
ap-display-correct-handle

Conversation

@sagzy

@sagzy sagzy commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

ref TryGhost/ActivityPub#1821

In TryGhost/ActivityPub#1821, we're introducing support for changing the displayed domain on a social web handle to a different subdomain or another domain they own. For example, a site hosted on jamie.larson.com can choose to expose their handle as @jamie@larson.com (instead of @index@jamie.larson.com).

In Notes/Reader, we were re-constructing the displayed handle from the ap_id, which meant we did not correctly displayed the new handle returned by the API.

Two additional tidy-ings:

  • renamed getUsername to getHandle
  • simplified calls such as actor.handle || getHandle(actor) to getHandle(actor)

@coderabbitai

coderabbitai Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

This pull request replaces the getUsername utility with a new getHandle function that prioritizes an explicit handle field from actor objects, falling back to a derived @username@domain format. The new utility is deployed across all ActivityPub components and views including feed items, avatars, modal dialogs, and profile views. The ActivityPub package version is incremented to 3.1.36.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: fixing handle display in Notes/Reader to use API-provided values instead of reconstructing from ap_id.
Description check ✅ Passed The description is directly related to the changeset, explaining the motivation (API support for custom handle domains), the problem (handle reconstruction from ap_id), and the solution (using API-provided handle).
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ap-display-correct-handle

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

ref TryGhost/ActivityPub#1821

In TryGhost/ActivityPub#1821, we're introducing support for changing the displayed domain
on a social web handle to a different subdomain or another domain they own. For example, a site hosted on jamie.larson.com
can choose to expose their handle as @jamie@larson.com (instead of @index@jamie.larson.com).

In Notes/Reader, we were re-constructing the displayed handle from the ap_id,
which meant we did not correctly displayed the new handle returned by the API.

Two additional tidy-ings:
- renamed getUsername to getHandle
- simplified calls such as `actor.handle || getHandle(actor)` to `getHandle(actor)`
@sagzy sagzy force-pushed the ap-display-correct-handle branch from 8f34531 to 2cd9eca Compare June 10, 2026 08:30

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8f34531745

ℹ️ 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".

Comment thread apps/activitypub/src/components/feed/feed-item.tsx

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

🧹 Nitpick comments (2)
apps/activitypub/src/utils/get-handle.ts (1)

1-1: 💤 Low value

Consider adding spaces around the union type operator.

The type annotation id: string|null is more commonly written as id: string | null in TypeScript for better readability.

♻️ Suggested formatting improvement
-function getHandle(actor: {handle?: string; preferredUsername: string; id: string|null;}) {
+function getHandle(actor: {handle?: string; preferredUsername: string; id: string | null;}) {
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/activitypub/src/utils/get-handle.ts` at line 1, The type annotation in
the getHandle function uses `string|null`; update it to the more readable
`string | null` by adding spaces around the union operator in the parameter type
(actor: { handle?: string; preferredUsername: string; id: string | null; }) so
it follows TypeScript style conventions; ensure any other occurrences in the
same file follow the same spacing for consistency.
apps/activitypub/test/unit/utils/get-handle.test.tsx (1)

4-4: 💤 Low value

Remove unnecessary async declarations from test functions.

These test functions don't contain any await statements or async operations. The async keyword can be removed for clarity.

♻️ Suggested simplification
-    it('returns the API-provided handle when present', async function () {
+    it('returns the API-provided handle when present', function () {

Apply the same change to all four test functions (lines 4, 16, 27, 38).

Also applies to: 16-16, 27-27, 38-38

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/activitypub/test/unit/utils/get-handle.test.tsx` at line 4, Remove the
unnecessary async keyword from the four test functions in get-handle.test.tsx;
locate the four it(...) blocks with descriptions "returns the API-provided
handle when present", "returns the API-provided handle when not present" (if
present), and the other two test descriptions on lines noted in the review and
simply delete the async modifier from their function declarations so they are
plain synchronous functions (e.g., change "it('returns the API-provided handle
when present', async function () {" to "it('returns the API-provided handle when
present', function () {"). Ensure you update all four it(...) blocks referenced
in the comment.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/activitypub/src/utils/posts.ts`:
- Around line 26-27: The preferredUsername assignments derived from
post.author.handle and post.repostedBy.handle assume an `@user`@domain shape and
can produce undefined; update both occurrences (the preferredUsername lines
using post.author.handle.split('@')[1] and post.repostedBy.handle.split('@')[1])
to provide a safe fallback (e.g. use nullish coalescing to default to 'unknown'
or a sensible fallback) so an unexpected handle format never propagates
undefined into the ActivityPub actor.

---

Nitpick comments:
In `@apps/activitypub/src/utils/get-handle.ts`:
- Line 1: The type annotation in the getHandle function uses `string|null`;
update it to the more readable `string | null` by adding spaces around the union
operator in the parameter type (actor: { handle?: string; preferredUsername:
string; id: string | null; }) so it follows TypeScript style conventions; ensure
any other occurrences in the same file follow the same spacing for consistency.

In `@apps/activitypub/test/unit/utils/get-handle.test.tsx`:
- Line 4: Remove the unnecessary async keyword from the four test functions in
get-handle.test.tsx; locate the four it(...) blocks with descriptions "returns
the API-provided handle when present", "returns the API-provided handle when not
present" (if present), and the other two test descriptions on lines noted in the
review and simply delete the async modifier from their function declarations so
they are plain synchronous functions (e.g., change "it('returns the API-provided
handle when present', async function () {" to "it('returns the API-provided
handle when present', function () {"). Ensure you update all four it(...) blocks
referenced in the comment.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 214d4eb7-61fa-4d48-86a7-899a6980185e

📥 Commits

Reviewing files that changed from the base of the PR and between b0b78b2 and 8f34531.

📒 Files selected for processing (16)
  • apps/activitypub/src/components/feed/feed-item.tsx
  • apps/activitypub/src/components/global/ap-avatar.tsx
  • apps/activitypub/src/components/global/ap-reply-box.tsx
  • apps/activitypub/src/components/global/profile-preview-hover-card.tsx
  • apps/activitypub/src/components/modals/new-note-modal.tsx
  • apps/activitypub/src/utils/get-handle.ts
  • apps/activitypub/src/utils/handle-profile-click.ts
  • apps/activitypub/src/utils/posts.ts
  • apps/activitypub/src/views/feed/note.tsx
  • apps/activitypub/src/views/inbox/components/reader.tsx
  • apps/activitypub/src/views/profile/components/actor-list.tsx
  • apps/activitypub/test/unit/utils/get-handle.test.tsx
  • apps/activitypub/test/unit/utils/get-username.test.tsx
  • apps/activitypub/test/unit/utils/posts.test.ts
  • ghost/core/content/themes/casper
  • ghost/core/content/themes/source
💤 Files with no reviewable changes (1)
  • apps/activitypub/test/unit/utils/get-username.test.tsx

Comment thread apps/activitypub/src/utils/posts.ts

@coderabbitai coderabbitai Bot 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.

🧹 Nitpick comments (1)
apps/activitypub/test/unit/utils/get-handle.test.tsx (1)

4-4: ⚡ Quick win

Remove unnecessary async keywords from test functions.

All four test functions are declared as async but none use await or perform asynchronous operations. The getHandle utility appears to be synchronous. Removing the async keywords improves clarity and avoids misleading future maintainers.

♻️ Proposed fix
-    it('returns the API-provided handle when present', async function () {
+    it('returns the API-provided handle when present', function () {
         const user = {
             handle: '`@index`@activitypub.example',
             preferredUsername: 'index',
             id: 'https://www.platformer.news/'
         };

         const result = getHandle(user);

         expect(result).toBe('`@index`@activitypub.example');
     });

-    it('returns the formatted handle', async function () {
+    it('returns the formatted handle', function () {
         const user = {
             preferredUsername: 'index',
             id: 'https://www.platformer.news/'
         };

         const result = getHandle(user);

         expect(result).toBe('`@index`@platformer.news');
     });

-    it('returns a default handle if the user object is missing data', async function () {
+    it('returns a default handle if the user object is missing data', function () {
         const user = {
             preferredUsername: '',
             id: ''
         };

         const result = getHandle(user);

         expect(result).toBe('`@unknown`@unknown');
     });

-    it('returns a default handle if url parsing fails', async function () {
+    it('returns a default handle if url parsing fails', function () {
         const user = {
             preferredUsername: 'index',
             id: 'not-a-url'
         };

         const result = getHandle(user);

         expect(result).toBe('`@unknown`@unknown');
     });

Also applies to: 16-16, 27-27, 38-38

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/activitypub/test/unit/utils/get-handle.test.tsx` at line 4, Remove the
unnecessary async keywords from the four test declarations in
apps/activitypub/test/unit/utils/get-handle.test.tsx (the it blocks named
"returns the API-provided handle when present" and the other three tests)
because getHandle is synchronous and none of these tests use await; update each
it(...) declaration to be a plain synchronous function (remove async from the
function signature) so the tests accurately reflect their synchronous behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@apps/activitypub/test/unit/utils/get-handle.test.tsx`:
- Line 4: Remove the unnecessary async keywords from the four test declarations
in apps/activitypub/test/unit/utils/get-handle.test.tsx (the it blocks named
"returns the API-provided handle when present" and the other three tests)
because getHandle is synchronous and none of these tests use await; update each
it(...) declaration to be a plain synchronous function (remove async from the
function signature) so the tests accurately reflect their synchronous behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: e76d2848-db1a-4fe2-b2a0-d0fd1cd463d4

📥 Commits

Reviewing files that changed from the base of the PR and between 8f34531 and 2cd9eca.

📒 Files selected for processing (15)
  • apps/activitypub/package.json
  • apps/activitypub/src/components/feed/feed-item.tsx
  • apps/activitypub/src/components/global/ap-avatar.tsx
  • apps/activitypub/src/components/global/ap-reply-box.tsx
  • apps/activitypub/src/components/global/profile-preview-hover-card.tsx
  • apps/activitypub/src/components/modals/new-note-modal.tsx
  • apps/activitypub/src/utils/get-handle.ts
  • apps/activitypub/src/utils/handle-profile-click.ts
  • apps/activitypub/src/utils/posts.ts
  • apps/activitypub/src/views/feed/note.tsx
  • apps/activitypub/src/views/inbox/components/reader.tsx
  • apps/activitypub/src/views/profile/components/actor-list.tsx
  • apps/activitypub/test/unit/utils/get-handle.test.tsx
  • apps/activitypub/test/unit/utils/get-username.test.tsx
  • apps/activitypub/test/unit/utils/posts.test.ts
💤 Files with no reviewable changes (1)
  • apps/activitypub/test/unit/utils/get-username.test.tsx
✅ Files skipped from review due to trivial changes (2)
  • apps/activitypub/package.json
  • apps/activitypub/src/components/modals/new-note-modal.tsx
🚧 Files skipped from review as they are similar to previous changes (11)
  • apps/activitypub/src/utils/posts.ts
  • apps/activitypub/src/components/global/ap-reply-box.tsx
  • apps/activitypub/src/views/profile/components/actor-list.tsx
  • apps/activitypub/src/views/feed/note.tsx
  • apps/activitypub/src/utils/get-handle.ts
  • apps/activitypub/src/components/global/profile-preview-hover-card.tsx
  • apps/activitypub/src/views/inbox/components/reader.tsx
  • apps/activitypub/src/utils/handle-profile-click.ts
  • apps/activitypub/src/components/global/ap-avatar.tsx
  • apps/activitypub/src/components/feed/feed-item.tsx
  • apps/activitypub/test/unit/utils/posts.test.ts

@sagzy sagzy merged commit 3ae1986 into main Jun 10, 2026
47 checks passed
@sagzy sagzy deleted the ap-display-correct-handle branch June 10, 2026 09:33
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.

1 participant