feat: add clickable hyperlinks in transaction memos#2024
feat: add clickable hyperlinks in transaction memos#2024kanishka0411 wants to merge 1 commit intogetAlby:masterfrom
Conversation
📝 WalkthroughWalkthroughAdds URL linkification to transaction text fields in the frontend by integrating Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~8 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@frontend/src/lib/linkify.tsx`:
- Line 21: The protocol check is case-sensitive (url.startsWith("http")) while
the validation regex is case-insensitive, so URLs like "HTTP://example.com"
become "https://HTTP://example.com"; update the logic that computes href (use
the same case-insensitive test as the regex) by either normalizing the input
(e.g., url.toLowerCase().startsWith("http")) or replacing the check with a
case-insensitive regex test (e.g., /^https?:/i.test(url)); apply this change
where href is assigned (the code referencing url and href in linkify.tsx) so
uppercase protocols are detected correctly.
🧹 Nitpick comments (1)
frontend/src/lib/linkify.tsx (1)
3-4: URL regex may produce false positives and has limited validation.The regex matches any word containing a dot followed by 2+ letters (e.g.,
test.co,file.txt), which could linkify unintended text. Consider:
- Requiring
www.prefix for non-http URLs, or- Validating against a known TLD list, or
- At minimum, requiring a longer TLD or path component
5910ebb to
c3634e9
Compare
There was a problem hiding this comment.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
frontend/src/components/TransactionItem.tsx (1)
167-188: Avoid nested interactive elements insideDialogTrigger.
DialogTriggerrenders a<button>by default, and linkified<a>tags inside it create invalid nested interactive elements (can break keyboard/mouse behavior). ConsiderasChildwith a non‑interactive wrapper and explicit keyboard handling, or move the linkified text outside the trigger.🛠️ Suggested structure
- <DialogTrigger className="p-3 mb-4 hover:bg-muted/50 data-[state=selected]:bg-muted cursor-pointer rounded-md slashed-zero transaction sensitive"> - <div - className={cn( - "flex gap-3", - tx.state === "pending" && "animate-pulse" - )} - > + <DialogTrigger asChild> + <div + className="p-3 mb-4 hover:bg-muted/50 data-[state=selected]:bg-muted cursor-pointer rounded-md slashed-zero transaction sensitive" + role="button" + tabIndex={0} + onKeyDown={(e) => { + if (e.key === "Enter" || e.key === " ") { + e.preventDefault(); + e.currentTarget.click(); + } + }} + > + <div + className={cn( + "flex gap-3", + tx.state === "pending" && "animate-pulse" + )} + > {typeStateIcon} ... - </div> - </DialogTrigger> + </div> + </div> + </DialogTrigger>
|
Hi, thanks for the PR. Is there a more standard way to do it then adding this custom linkify code? |
c3634e9 to
fc4e125
Compare
|
Thanks for the feedback! I've updated the PR to use react-linkify-it instead of custom code |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@frontend/src/components/TransactionItem.tsx`:
- Around line 186-188: The LinkItUrl inside TransactionItem's paragraph is
causing link clicks to propagate and open the surrounding DialogTrigger; stop
that by preventing event propagation on the container: add an onClick={(e) =>
e.stopPropagation()} to the <p> (or wrap LinkItUrl in a wrapper element that
calls e.stopPropagation()) so anchor clicks do not bubble to the dialog, and
ensure LinkItUrl anchors render with target="_blank" and rel="noopener
noreferrer" (or switch to LinkIt with a custom renderer) to open external links
safely.
🧹 Nitpick comments (2)
frontend/src/components/TransactionItem.tsx (2)
285-291: Apply the same custom link component for security and consistency.While this usage isn't inside a
DialogTrigger, it should still use a custom component to ensure links open in new tabs with properrel="noopener noreferrer"attributes to prevent tabnabbing. Using the same component across allLinkItUrlusages maintains consistency.♻️ Suggested change
<p className="text-muted-foreground break-all"> - <LinkItUrl>{tx.description}</LinkItUrl> + <LinkItUrl component={ExternalMemoLink}>{tx.description}</LinkItUrl> </p>
293-308: Apply consistent link handling for Comment and Payer Note fields.Same recommendation applies here: use the custom link component for security attributes (
target="_blank"andrel="noopener noreferrer") across all linkified text fields.♻️ Suggested changes
<p className="text-muted-foreground break-all"> - <LinkItUrl>{tx.metadata.comment}</LinkItUrl> + <LinkItUrl component={ExternalMemoLink}>{tx.metadata.comment}</LinkItUrl> </p><p className="text-muted-foreground break-all"> - <LinkItUrl>{bolt12Offer.payer_note}</LinkItUrl> + <LinkItUrl component={ExternalMemoLink}>{bolt12Offer.payer_note}</LinkItUrl> </p>
fc4e125 to
26f702f
Compare
Fixes: #1515
Makes URLs in transaction memos clickable. Links open in a new tab.
Summary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings.