[Embeds] stop adding tracking params to non-bsky.app links (#4167)

* don't add tracking params on non-bsky.app links

* validate facets
zio/stable
Samuel Newman 2024-05-23 03:52:46 +01:00 committed by GitHub
parent 69f4684859
commit 334483ad9a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 37 additions and 19 deletions

View File

@ -15,6 +15,6 @@
"parserOptions": {
"sourceType": "module",
"ecmaVersion": "latest",
"project": "./tsconfig.json"
"project": "./bskyembed/tsconfig.json"
}
}

View File

@ -193,7 +193,7 @@ export function Embed({
function Info({children}: {children: ComponentChildren}) {
return (
<div className="w-full rounded-lg border py-2 px-2.5 flex-row flex gap-2 bg-neutral-50">
<img src={infoIcon as string} className="w-4 h-4 shrink-0 mt-0.5" />
<img src={infoIcon} className="w-4 h-4 shrink-0 mt-0.5" />
<p className="text-sm text-textLight">{children}</p>
</div>
)
@ -293,7 +293,8 @@ function ExternalEmbed({
return (
<Link
href={content.external.uri}
className="w-full rounded-lg overflow-hidden border flex flex-col items-stretch">
className="w-full rounded-lg overflow-hidden border flex flex-col items-stretch"
disableTracking>
{content.external.thumb && (
<img
src={content.external.thumb}

View File

@ -3,10 +3,12 @@ import {h} from 'preact'
export function Link({
href,
className,
disableTracking,
...props
}: {
href: string
className?: string
disableTracking?: boolean
} & h.JSX.HTMLAttributes<HTMLAnchorElement>) {
const searchParam = new URLSearchParams(window.location.search)
const ref_url = searchParam.get('ref_url')
@ -19,9 +21,9 @@ export function Link({
return (
<a
href={`${
href.startsWith('http') ? href : `https://bsky.app${href}`
}?${newSearchParam.toString()}`}
href={`${href.startsWith('http') ? href : `https://bsky.app${href}`}${
disableTracking ? '' : `?${newSearchParam.toString()}`
}`}
target="_blank"
rel="noopener noreferrer nofollow"
onClick={evt => evt.stopPropagation()}

View File

@ -1,4 +1,9 @@
import {AppBskyFeedDefs, AppBskyFeedPost, RichText} from '@atproto/api'
import {
AppBskyFeedDefs,
AppBskyFeedPost,
AppBskyRichtextFacet,
RichText,
} from '@atproto/api'
import {h} from 'preact'
import replyIcon from '../../assets/bubble_filled_stroke2_corner2_rounded.svg'
@ -56,7 +61,7 @@ export function Post({thread}: Props) {
<Link
href={href}
className="transition-transform hover:scale-110 shrink-0 self-start">
<img src={logo as string} className="h-8" />
<img src={logo} className="h-8" />
</Link>
</div>
<PostContent record={record} />
@ -71,7 +76,7 @@ export function Post({thread}: Props) {
<div className="border-t w-full pt-2.5 flex items-center gap-5 text-sm cursor-pointer">
{!!post.likeCount && (
<div className="flex items-center gap-2 cursor-pointer">
<img src={likeIcon as string} className="w-5 h-5" />
<img src={likeIcon} className="w-5 h-5" />
<p className="font-bold text-neutral-500 mb-px">
{post.likeCount}
</p>
@ -79,14 +84,14 @@ export function Post({thread}: Props) {
)}
{!!post.repostCount && (
<div className="flex items-center gap-2 cursor-pointer">
<img src={repostIcon as string} className="w-5 h-5" />
<img src={repostIcon} className="w-5 h-5" />
<p className="font-bold text-neutral-500 mb-px">
{post.repostCount}
</p>
</div>
)}
<div className="flex items-center gap-2 cursor-pointer">
<img src={replyIcon as string} className="w-5 h-5" />
<img src={replyIcon} className="w-5 h-5" />
<p className="font-bold text-neutral-500 mb-px">Reply</p>
</div>
<div className="flex-1" />
@ -118,16 +123,23 @@ function PostContent({record}: {record: AppBskyFeedPost.Record | null}) {
let counter = 0
for (const segment of rt.segments()) {
if (segment.isLink() && segment.link) {
if (
segment.link &&
AppBskyRichtextFacet.validateLink(segment.link).success
) {
richText.push(
<Link
key={counter}
href={segment.link.uri}
className="text-blue-400 hover:underline">
className="text-blue-400 hover:underline"
disableTracking={!segment.link.uri.startsWith('https://bsky.app')}>
{segment.text}
</Link>,
)
} else if (segment.isMention() && segment.mention) {
} else if (
segment.mention &&
AppBskyRichtextFacet.validateMention(segment.mention).success
) {
richText.push(
<Link
key={counter}
@ -136,7 +148,10 @@ function PostContent({record}: {record: AppBskyFeedPost.Record | null}) {
{segment.text}
</Link>,
)
} else if (segment.isTag() && segment.tag) {
} else if (
segment.tag &&
AppBskyRichtextFacet.validateTag(segment.tag).success
) {
richText.push(
<Link
key={counter}

View File

@ -112,7 +112,7 @@ function LandingPage() {
<Link
href="https://bsky.social/about"
className="transition-transform hover:scale-110">
<img src={logo as string} className="h-10" />
<img src={logo} className="h-10" />
</Link>
<h1 className="text-4xl font-bold text-center">Embed a Bluesky Post</h1>
@ -125,7 +125,7 @@ function LandingPage() {
placeholder={DEFAULT_POST}
/>
<img src={arrowBottom as string} className="w-6" />
<img src={arrowBottom} className="w-6" />
{loading ? (
<Skeleton />

View File

@ -52,7 +52,7 @@ function PwiOptOut({thread}: {thread: AppBskyFeedDefs.ThreadViewPost}) {
<Link
href={href}
className="transition-transform hover:scale-110 absolute top-4 right-4">
<img src={logo as string} className="h-6" />
<img src={logo} className="h-6" />
</Link>
<div className="w-full py-12 gap-4 flex flex-col items-center">
<p className="max-w-80 text-center w-full text-textLight">
@ -75,7 +75,7 @@ function ErrorMessage() {
<Link
href="https://bsky.app/"
className="transition-transform hover:scale-110 absolute top-4 right-4">
<img src={logo as string} className="h-6" />
<img src={logo} className="h-6" />
</Link>
<p className="my-16 text-center w-full text-textLight">
Post not found, it may have been deleted.