Skip to content

feat(ui): adds social likes to compare page#940

Merged
danielroe merged 11 commits intonpmx-dev:mainfrom
Sukiiu:feat/like-comparaison
Feb 7, 2026
Merged

feat(ui): adds social likes to compare page#940
danielroe merged 11 commits intonpmx-dev:mainfrom
Sukiiu:feat/like-comparaison

Conversation

@Sukiiu
Copy link
Contributor

@Sukiiu Sukiiu commented Feb 4, 2026

Following this msg on discord :
image

This PR add like as a metric (I don't really know if it's a relevant metric)

image

@vercel
Copy link

vercel bot commented Feb 4, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
npmx.dev Ready Ready Preview, Comment Feb 7, 2026 10:19am
2 Skipped Deployments
Project Deployment Actions Updated (UTC)
docs.npmx.dev Ignored Ignored Preview Feb 7, 2026 10:19am
npmx-lunaria Ignored Ignored Feb 7, 2026 10:19am

Request Review

@github-actions
Copy link

github-actions bot commented Feb 4, 2026

Lunaria Status Overview

🌕 This pull request will trigger status changes.

Learn more

By default, every PR changing files present in the Lunaria configuration's files property will be considered and trigger status changes accordingly.

You can change this by adding one of the keywords present in the ignoreKeywords property in your Lunaria configuration file in the PR's title (ignoring all files) or by including a tracker directive in the merged commit's description.

Tracked Files

File Note
lunaria/files/en-GB.json Localization changed, will be marked as complete. 🔄️
lunaria/files/en-US.json Source changed, localizations will be marked as outdated.
lunaria/files/fr-FR.json Localization changed, will be marked as complete. 🔄️
Warnings reference
Icon Description
🔄️ The source for this localization has been updated since the creation of this pull request, make sure all changes in the source have been applied.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 4, 2026

📝 Walkthrough

Walkthrough

Adds a new numeric facet totalLikes to package comparison. The composable app/composables/usePackageComparison.ts now imports PackageLikes, fetches likes from /api/social/likes/{name}, exposes totalLikes?: number on PackageComparisonData, and threads likes through data assembly and computeFacetValue. shared/types/comparison.ts adds totalLikes to the ComparisonFacet union and FACET_INFO. Translation entries for totalLikes were added for English (en.json, en-GB.json, en-US.json) and French (fr-FR.json), useFacetSelection.ts was updated to include the new label mapping, and a test mapping was updated.

Possibly related PRs

  • fix: show correct dependencies count #787 — Modifies app/composables/usePackageComparison.ts to extend PackageComparisonData and adjust per-package data/facet computation, showing a strong code-level overlap.

Suggested reviewers

  • danielroe
  • ghostdevv
🚥 Pre-merge checks | ✅ 1
✅ Passed checks (1 passed)
Check name Status Explanation
Description check ✅ Passed The pull request description references Discord discussion and includes visual mockups showing the new 'Likes' metric being added to the package comparison page, which aligns with the changeset.

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

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

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 (1)
app/composables/usePackageComparison.ts (1)

109-120: Consider surfacing likes fetch failures as “unknown” rather than “0”.

A failed likes request currently renders as 0 likes, which can be misleading. Aligning with downloads (null/undefined on failure) keeps comparisons honest.

♻️ Suggested adjustment
 export interface PackageComparisonData {
   package: ComparisonPackage
   downloads?: number
   /** Total likes from atproto */
-  totalLikes: number
+  totalLikes?: number
   /** Package's own unpacked size (from dist.unpackedSize) */
   packageSize?: number
@@
-              $fetch<PackageLikes>(`/api/social/likes/${name}`).catch(() => ({
-                totalLikes: 0,
-                userHasLiked: false,
-              })),
+              $fetch<PackageLikes>(`/api/social/likes/${name}`).catch(() => null),
@@
-              totalLikes: likes.totalLikes,
+              totalLikes: likes?.totalLikes,

Also applies to: 168-168

@codecov
Copy link

codecov bot commented Feb 4, 2026

Codecov Report

❌ Patch coverage is 42.85714% with 4 lines in your changes missing coverage. Please review.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
app/composables/usePackageComparison.ts 20.00% 3 Missing and 1 partial ⚠️

📢 Thoughts on this report? Let us know!

@graphieros graphieros requested a review from serhalp February 4, 2026 14:42
@serhalp
Copy link
Contributor

serhalp commented Feb 5, 2026

The verdict is in, sorry Daniel

Screenshot 2026-02-05 at 09 37 56

@serhalp
Copy link
Contributor

serhalp commented Feb 5, 2026

ok ok never mind, you do win this round:

Screenshot 2026-02-05 at 09 38 54

Copy link
Contributor

@serhalp serhalp left a comment

Choose a reason for hiding this comment

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

Awesome, thanks! 🚀

When you merge main in, please test this feature with the new "no dep" column from #801. I think you'll just need to add a field to this 'fake' column.

@serhalp serhalp changed the title feat: like comparaison feat(ui): adds social likes to compare page Feb 5, 2026
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

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 (1)
app/composables/usePackageComparison.ts (1)

361-368: Consider handling the isNoDependency case for consistency with downloads.

The downloads facet (lines 351-354) has special handling for the "no dependency" column, returning { raw: 0, display: '–', status: 'neutral' }. The totalLikes case doesn't have this handling, so the no-dependency column will show nothing for Likes whilst showing "–" for Downloads.

If the intent is to show "–" for likes in the no-dependency column as well, consider adding the same pattern:

♻️ Proposed change for consistency
     case 'totalLikes': {
-      if (data.totalLikes === undefined) return null
+      if (data.totalLikes === undefined) {
+        if (isNoDependency) return { raw: 0, display: '–', status: 'neutral' }
+        return null
+      }
       return {
         raw: data.totalLikes,
         display: formatCompactNumber(data.totalLikes),
         status: 'neutral',
       }
     }

$fetch<VulnerabilityTreeResult>(
`/api/registry/vulnerabilities/${encodePackageName(name)}`,
).catch(() => null),
$fetch<PackageLikes>(`/api/social/likes/${name}`).catch(() => null),
Copy link
Contributor

@coderabbitai coderabbitai bot Feb 5, 2026

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

cat -n app/composables/usePackageComparison.ts | sed -n '130,150p'

Repository: npmx-dev/npmx.dev

Length of output: 1254


🏁 Script executed:

# Search for the API route definition for /api/social/likes
rg -n "social/likes" --type ts --type js -B 2 -A 5

Repository: npmx-dev/npmx.dev

Length of output: 1906


🏁 Script executed:

# Find where encodePackageName is defined and used
rg -n "encodePackageName" --type ts --type js | head -20

Repository: npmx-dev/npmx.dev

Length of output: 2075


🏁 Script executed:

# Check the broader context of lines around 143 to see other API calls
cat -n app/composables/usePackageComparison.ts | sed -n '125,160p'

Repository: npmx-dev/npmx.dev

Length of output: 1890


🏁 Script executed:

# Find the API route definition for social/likes
fd -type f -name "*.ts" -o -name "*.js" | xargs rg -l "social/likes" | head -10

Repository: npmx-dev/npmx.dev

Length of output: 358


🏁 Script executed:

# Search for the server-side route handler
rg -n "api/social/likes" --type ts --type js -B 3 -A 10

Repository: npmx-dev/npmx.dev

Length of output: 3146


🏁 Script executed:

# Look for likes route in server/api
fd -path "*/server/api/*" -name "*likes*" -o -path "*/server/api/*" -name "*social*"

Repository: npmx-dev/npmx.dev

Length of output: 229


🏁 Script executed:

# Find server API routes for social/likes
find server -name "*.ts" -o -name "*.js" | xargs grep -l "social" 2>/dev/null | head -10

Repository: npmx-dev/npmx.dev

Length of output: 124


🏁 Script executed:

# Search more broadly for likes route handler
rg "likes" server/api --type-list | head -5

Repository: npmx-dev/npmx.dev

Length of output: 450


🏁 Script executed:

# List the server/api directory structure
find server/api -type f -name "*.ts" | sort

Repository: npmx-dev/npmx.dev

Length of output: 1035


🏁 Script executed:

cat -n server/api/social/likes/[...pkg].get.ts

Repository: npmx-dev/npmx.dev

Length of output: 520


Package name should be encoded for consistency and scoped package support.

The likes API call uses the raw name without encodePackageName(), unlike the other API calls in this block. This causes issues with scoped packages (e.g., @vue/core) because the forward slash in the scope becomes a path separator. The same issue exists in two other locations: app/pages/package/[...package].vue line 402 and app/components/OgImage/Package.vue line 49.

🐛 Proposed fix
-              $fetch<PackageLikes>(`/api/social/likes/${name}`).catch(() => null),
+              $fetch<PackageLikes>(`/api/social/likes/${encodePackageName(name)}`).catch(() => null),

Apply the same fix to app/pages/package/[...package].vue line 402 and app/components/OgImage/Package.vue line 49.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
$fetch<PackageLikes>(`/api/social/likes/${name}`).catch(() => null),
$fetch<PackageLikes>(`/api/social/likes/${encodePackageName(name)}`).catch(() => null),

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Whoops thought i did it my bad coderabbit

Copy link
Contributor

Choose a reason for hiding this comment

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

@Sukiiu No worries at all! It's an easy thing to miss, especially since the API route uses [...pkg] which handles it server-side. Thanks for taking a look! 🐰

🐰✨
( •_•)
/>🔧

@Sukiiu
Copy link
Contributor Author

Sukiiu commented Feb 5, 2026

Oh a small issue here, CodeRabbit is right about the consistency of encodePackageName but the current like endpoint doesn't parse the package like the 2 others. (#940 (review))

So for now the proposed solution is to remove encodePackage for the like endpoint and open an issue to refactor api/social/like to behave like the other endpoints.

@serhalp what do you think ?

@Sukiiu Sukiiu force-pushed the feat/like-comparaison branch from e891e26 to 3526acf Compare February 5, 2026 23:20
@Sukiiu Sukiiu marked this pull request as ready for review February 6, 2026 08:59
@ghostdevv
Copy link
Contributor

ghostdevv commented Feb 6, 2026

Is encoding it even necessary because the like endpoint seems to capture the entire path greedily @Sukiiu? Regardless, go for it! Consistency is good. Will mark this as draft until you're ready 🙏

@ghostdevv ghostdevv marked this pull request as draft February 6, 2026 22:26
@Sukiiu
Copy link
Contributor Author

Sukiiu commented Feb 6, 2026

Is encoding it even necessary because the like endpoint seems to capture the entire path greedily @Sukiiu? Regardless, go for it! Consistency is good. Will mark this as draft until you're ready 🙏

No not needed, it works without the encoding, but it was more to keep consistency. Will keep it like that for now, so it's ready to go then

@Sukiiu Sukiiu marked this pull request as ready for review February 6, 2026 23:42
@danielroe danielroe added this pull request to the merge queue Feb 7, 2026
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Feb 7, 2026
@Sukiiu Sukiiu marked this pull request as draft February 7, 2026 09:47
@Sukiiu Sukiiu marked this pull request as ready for review February 7, 2026 10:22
@danielroe danielroe added this pull request to the merge queue Feb 7, 2026
Merged via the queue into npmx-dev:main with commit 4aceb9c Feb 7, 2026
17 checks passed
@github-actions
Copy link

github-actions bot commented Feb 7, 2026

Thanks for your first contribution, @Sukiiu! 💫

We'd love to welcome you to the npmx community. Come and say hi on Discord! And once you've joined, visit npmx.wamellow.com to claim the contributor role.

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