[Embeds] stop adding tracking params to non-bsky.app links (#4167)
* don't add tracking params on non-bsky.app links * validate facetszio/stable
parent
69f4684859
commit
334483ad9a
|
@ -15,6 +15,6 @@
|
||||||
"parserOptions": {
|
"parserOptions": {
|
||||||
"sourceType": "module",
|
"sourceType": "module",
|
||||||
"ecmaVersion": "latest",
|
"ecmaVersion": "latest",
|
||||||
"project": "./tsconfig.json"
|
"project": "./bskyembed/tsconfig.json"
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -193,7 +193,7 @@ export function Embed({
|
||||||
function Info({children}: {children: ComponentChildren}) {
|
function Info({children}: {children: ComponentChildren}) {
|
||||||
return (
|
return (
|
||||||
<div className="w-full rounded-lg border py-2 px-2.5 flex-row flex gap-2 bg-neutral-50">
|
<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>
|
<p className="text-sm text-textLight">{children}</p>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
@ -293,7 +293,8 @@ function ExternalEmbed({
|
||||||
return (
|
return (
|
||||||
<Link
|
<Link
|
||||||
href={content.external.uri}
|
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 && (
|
{content.external.thumb && (
|
||||||
<img
|
<img
|
||||||
src={content.external.thumb}
|
src={content.external.thumb}
|
||||||
|
|
|
@ -3,10 +3,12 @@ import {h} from 'preact'
|
||||||
export function Link({
|
export function Link({
|
||||||
href,
|
href,
|
||||||
className,
|
className,
|
||||||
|
disableTracking,
|
||||||
...props
|
...props
|
||||||
}: {
|
}: {
|
||||||
href: string
|
href: string
|
||||||
className?: string
|
className?: string
|
||||||
|
disableTracking?: boolean
|
||||||
} & h.JSX.HTMLAttributes<HTMLAnchorElement>) {
|
} & h.JSX.HTMLAttributes<HTMLAnchorElement>) {
|
||||||
const searchParam = new URLSearchParams(window.location.search)
|
const searchParam = new URLSearchParams(window.location.search)
|
||||||
const ref_url = searchParam.get('ref_url')
|
const ref_url = searchParam.get('ref_url')
|
||||||
|
@ -19,9 +21,9 @@ export function Link({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<a
|
<a
|
||||||
href={`${
|
href={`${href.startsWith('http') ? href : `https://bsky.app${href}`}${
|
||||||
href.startsWith('http') ? href : `https://bsky.app${href}`
|
disableTracking ? '' : `?${newSearchParam.toString()}`
|
||||||
}?${newSearchParam.toString()}`}
|
}`}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer nofollow"
|
rel="noopener noreferrer nofollow"
|
||||||
onClick={evt => evt.stopPropagation()}
|
onClick={evt => evt.stopPropagation()}
|
||||||
|
|
|
@ -1,4 +1,9 @@
|
||||||
import {AppBskyFeedDefs, AppBskyFeedPost, RichText} from '@atproto/api'
|
import {
|
||||||
|
AppBskyFeedDefs,
|
||||||
|
AppBskyFeedPost,
|
||||||
|
AppBskyRichtextFacet,
|
||||||
|
RichText,
|
||||||
|
} from '@atproto/api'
|
||||||
import {h} from 'preact'
|
import {h} from 'preact'
|
||||||
|
|
||||||
import replyIcon from '../../assets/bubble_filled_stroke2_corner2_rounded.svg'
|
import replyIcon from '../../assets/bubble_filled_stroke2_corner2_rounded.svg'
|
||||||
|
@ -56,7 +61,7 @@ export function Post({thread}: Props) {
|
||||||
<Link
|
<Link
|
||||||
href={href}
|
href={href}
|
||||||
className="transition-transform hover:scale-110 shrink-0 self-start">
|
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>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
<PostContent record={record} />
|
<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">
|
<div className="border-t w-full pt-2.5 flex items-center gap-5 text-sm cursor-pointer">
|
||||||
{!!post.likeCount && (
|
{!!post.likeCount && (
|
||||||
<div className="flex items-center gap-2 cursor-pointer">
|
<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">
|
<p className="font-bold text-neutral-500 mb-px">
|
||||||
{post.likeCount}
|
{post.likeCount}
|
||||||
</p>
|
</p>
|
||||||
|
@ -79,14 +84,14 @@ export function Post({thread}: Props) {
|
||||||
)}
|
)}
|
||||||
{!!post.repostCount && (
|
{!!post.repostCount && (
|
||||||
<div className="flex items-center gap-2 cursor-pointer">
|
<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">
|
<p className="font-bold text-neutral-500 mb-px">
|
||||||
{post.repostCount}
|
{post.repostCount}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<div className="flex items-center gap-2 cursor-pointer">
|
<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>
|
<p className="font-bold text-neutral-500 mb-px">Reply</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex-1" />
|
<div className="flex-1" />
|
||||||
|
@ -118,16 +123,23 @@ function PostContent({record}: {record: AppBskyFeedPost.Record | null}) {
|
||||||
|
|
||||||
let counter = 0
|
let counter = 0
|
||||||
for (const segment of rt.segments()) {
|
for (const segment of rt.segments()) {
|
||||||
if (segment.isLink() && segment.link) {
|
if (
|
||||||
|
segment.link &&
|
||||||
|
AppBskyRichtextFacet.validateLink(segment.link).success
|
||||||
|
) {
|
||||||
richText.push(
|
richText.push(
|
||||||
<Link
|
<Link
|
||||||
key={counter}
|
key={counter}
|
||||||
href={segment.link.uri}
|
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}
|
{segment.text}
|
||||||
</Link>,
|
</Link>,
|
||||||
)
|
)
|
||||||
} else if (segment.isMention() && segment.mention) {
|
} else if (
|
||||||
|
segment.mention &&
|
||||||
|
AppBskyRichtextFacet.validateMention(segment.mention).success
|
||||||
|
) {
|
||||||
richText.push(
|
richText.push(
|
||||||
<Link
|
<Link
|
||||||
key={counter}
|
key={counter}
|
||||||
|
@ -136,7 +148,10 @@ function PostContent({record}: {record: AppBskyFeedPost.Record | null}) {
|
||||||
{segment.text}
|
{segment.text}
|
||||||
</Link>,
|
</Link>,
|
||||||
)
|
)
|
||||||
} else if (segment.isTag() && segment.tag) {
|
} else if (
|
||||||
|
segment.tag &&
|
||||||
|
AppBskyRichtextFacet.validateTag(segment.tag).success
|
||||||
|
) {
|
||||||
richText.push(
|
richText.push(
|
||||||
<Link
|
<Link
|
||||||
key={counter}
|
key={counter}
|
||||||
|
|
|
@ -112,7 +112,7 @@ function LandingPage() {
|
||||||
<Link
|
<Link
|
||||||
href="https://bsky.social/about"
|
href="https://bsky.social/about"
|
||||||
className="transition-transform hover:scale-110">
|
className="transition-transform hover:scale-110">
|
||||||
<img src={logo as string} className="h-10" />
|
<img src={logo} className="h-10" />
|
||||||
</Link>
|
</Link>
|
||||||
|
|
||||||
<h1 className="text-4xl font-bold text-center">Embed a Bluesky Post</h1>
|
<h1 className="text-4xl font-bold text-center">Embed a Bluesky Post</h1>
|
||||||
|
@ -125,7 +125,7 @@ function LandingPage() {
|
||||||
placeholder={DEFAULT_POST}
|
placeholder={DEFAULT_POST}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<img src={arrowBottom as string} className="w-6" />
|
<img src={arrowBottom} className="w-6" />
|
||||||
|
|
||||||
{loading ? (
|
{loading ? (
|
||||||
<Skeleton />
|
<Skeleton />
|
||||||
|
|
|
@ -52,7 +52,7 @@ function PwiOptOut({thread}: {thread: AppBskyFeedDefs.ThreadViewPost}) {
|
||||||
<Link
|
<Link
|
||||||
href={href}
|
href={href}
|
||||||
className="transition-transform hover:scale-110 absolute top-4 right-4">
|
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>
|
</Link>
|
||||||
<div className="w-full py-12 gap-4 flex flex-col items-center">
|
<div className="w-full py-12 gap-4 flex flex-col items-center">
|
||||||
<p className="max-w-80 text-center w-full text-textLight">
|
<p className="max-w-80 text-center w-full text-textLight">
|
||||||
|
@ -75,7 +75,7 @@ function ErrorMessage() {
|
||||||
<Link
|
<Link
|
||||||
href="https://bsky.app/"
|
href="https://bsky.app/"
|
||||||
className="transition-transform hover:scale-110 absolute top-4 right-4">
|
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>
|
</Link>
|
||||||
<p className="my-16 text-center w-full text-textLight">
|
<p className="my-16 text-center w-full text-textLight">
|
||||||
Post not found, it may have been deleted.
|
Post not found, it may have been deleted.
|
||||||
|
|
Loading…
Reference in New Issue