diff --git a/bskyembed/.eslintrc b/bskyembed/.eslintrc
index e6e575a1..2b290d58 100644
--- a/bskyembed/.eslintrc
+++ b/bskyembed/.eslintrc
@@ -10,11 +10,12 @@
],
"rules": {
"simple-import-sort/imports": "warn",
- "simple-import-sort/exports": "warn"
+ "simple-import-sort/exports": "warn",
+ 'no-else-return': 'off'
},
"parserOptions": {
"sourceType": "module",
"ecmaVersion": "latest",
"project": "./bskyembed/tsconfig.json"
}
-}
\ No newline at end of file
+}
diff --git a/bskyembed/assets/starterPack.svg b/bskyembed/assets/starterPack.svg
new file mode 100644
index 00000000..eb8dd710
--- /dev/null
+++ b/bskyembed/assets/starterPack.svg
@@ -0,0 +1 @@
+
diff --git a/bskyembed/package.json b/bskyembed/package.json
index f610e8c0..cb9a4621 100644
--- a/bskyembed/package.json
+++ b/bskyembed/package.json
@@ -9,7 +9,7 @@
"lint": "eslint --cache --ext .js,.jsx,.ts,.tsx src"
},
"dependencies": {
- "@atproto/api": "^0.12.2",
+ "@atproto/api": "0.13.1",
"@preact/preset-vite": "^2.8.2",
"@vitejs/plugin-legacy": "^5.3.2",
"preact": "^10.4.8",
diff --git a/bskyembed/src/components/embed.tsx b/bskyembed/src/components/embed.tsx
index 1dadfee3..600c7c2c 100644
--- a/bskyembed/src/components/embed.tsx
+++ b/bskyembed/src/components/embed.tsx
@@ -6,12 +6,15 @@ import {
AppBskyFeedDefs,
AppBskyFeedPost,
AppBskyGraphDefs,
+ AppBskyGraphStarterpack,
AppBskyLabelerDefs,
+ AtUri,
} from '@atproto/api'
import {ComponentChildren, h} from 'preact'
import {useMemo} from 'preact/hooks'
import infoIcon from '../../assets/circleInfo_stroke2_corner0_rounded.svg'
+import starterPackIcon from '../../assets/starterPack.svg'
import {CONTENT_LABELS, labelsToInfo} from '../labels'
import {getRkey} from '../utils'
import {Link} from './link'
@@ -105,7 +108,7 @@ export function Embed({
// Case 3.2: List
if (AppBskyGraphDefs.isListView(record)) {
return (
-
- )
+ // Embed type does not exist in the app, so show nothing
+ return null
}
- // Case 3.5: Post not found
+ // Case 3.5: Starter pack
+ if (AppBskyGraphDefs.isStarterPackViewBasic(record)) {
+ return
+ }
+
+ // Case 3.6: Post not found
if (AppBskyEmbedRecord.isViewNotFound(record)) {
return Quoted post not found, it may have been deleted.
}
- // Case 3.6: Post blocked
+ // Case 3.7: Post blocked
if (AppBskyEmbedRecord.isViewBlocked(record)) {
return The quoted post is blocked.
}
- throw new Error('Unknown embed type')
+ // Unknown embed type
+ return null
}
// Case 4: Record with media
@@ -182,7 +184,8 @@ export function Embed({
)
}
- throw new Error('Unsupported embed type')
+ // Unknown embed type
+ return null
} catch (err) {
return (
{err instanceof Error ? err.message : 'An error occurred'}
@@ -314,7 +317,7 @@ function ExternalEmbed({
)
}
-function GenericWithImage({
+function GenericWithImageEmbed({
title,
subtitle,
href,
@@ -350,3 +353,60 @@ function GenericWithImage({
)
}
+
+function StarterPackEmbed({
+ content,
+}: {
+ content: AppBskyGraphDefs.StarterPackViewBasic
+}) {
+ if (!AppBskyGraphStarterpack.isRecord(content.record)) {
+ return null
+ }
+
+ const starterPackHref = getStarterPackHref(content)
+ const imageUri = getStarterPackImage(content)
+
+ return (
+
+
+
+
+
+
+
+ {content.record.name}
+
+
+ Starter pack by{' '}
+ {content.creator.displayName || `@${content.creator.handle}`}
+
+
+
+ {content.record.description && (
+
{content.record.description}
+ )}
+ {!!content.joinedAllTimeCount && content.joinedAllTimeCount > 50 && (
+
+ {content.joinedAllTimeCount} users have joined!
+
+ )}
+
+
+ )
+}
+
+// from #/lib/strings/starter-pack.ts
+function getStarterPackImage(starterPack: AppBskyGraphDefs.StarterPackView) {
+ const rkey = new AtUri(starterPack.uri).rkey
+ return `https://ogcard.cdn.bsky.app/start/${starterPack.creator.did}/${rkey}`
+}
+
+function getStarterPackHref(
+ starterPack: AppBskyGraphDefs.StarterPackViewBasic,
+) {
+ const rkey = new AtUri(starterPack.uri).rkey
+ const handleOrDid = starterPack.creator.handle || starterPack.creator.did
+ return `/starter-pack/${handleOrDid}/${rkey}`
+}
diff --git a/bskyembed/src/components/post.tsx b/bskyembed/src/components/post.tsx
index d23c84cb..1d1e8f4d 100644
--- a/bskyembed/src/components/post.tsx
+++ b/bskyembed/src/components/post.tsx
@@ -132,7 +132,10 @@ function PostContent({record}: {record: AppBskyFeedPost.Record | null}) {
key={counter}
href={segment.link.uri}
className="text-blue-400 hover:underline"
- disableTracking={!segment.link.uri.startsWith('https://bsky.app')}>
+ disableTracking={
+ !segment.link.uri.startsWith('https://bsky.app') &&
+ !segment.link.uri.startsWith('https://go.bsky.app')
+ }>
{segment.text}
,
)
diff --git a/bskyembed/src/screens/post.tsx b/bskyembed/src/screens/post.tsx
index 337bf010..6ccf10a7 100644
--- a/bskyembed/src/screens/post.tsx
+++ b/bskyembed/src/screens/post.tsx
@@ -1,6 +1,6 @@
import '../index.css'
-import {AppBskyFeedDefs, BskyAgent} from '@atproto/api'
+import {AppBskyFeedDefs, AtpAgent} from '@atproto/api'
import {h, render} from 'preact'
import logo from '../../assets/logo.svg'
@@ -12,7 +12,7 @@ import {getRkey} from '../utils'
const root = document.getElementById('app')
if (!root) throw new Error('No root element')
-const agent = new BskyAgent({
+const agent = new AtpAgent({
service: 'https://public.api.bsky.app',
})
diff --git a/bskyembed/yarn.lock b/bskyembed/yarn.lock
index 60efe368..ca52dc07 100644
--- a/bskyembed/yarn.lock
+++ b/bskyembed/yarn.lock
@@ -20,15 +20,16 @@
"@jridgewell/gen-mapping" "^0.3.5"
"@jridgewell/trace-mapping" "^0.3.24"
-"@atproto/api@^0.12.2":
- version "0.12.2"
- resolved "https://registry.yarnpkg.com/@atproto/api/-/api-0.12.2.tgz#5df6d4f60dea0395c84fdebd9e81a7e853edf130"
- integrity sha512-UVzCiDZH2j0wrr/O8nb1edD5cYLVqB5iujueXUCbHS3rAwIxgmyLtA3Hzm2QYsGPo/+xsIg1fNvpq9rNT6KWUA==
+"@atproto/api@0.13.1":
+ version "0.13.1"
+ resolved "https://registry.yarnpkg.com/@atproto/api/-/api-0.13.1.tgz#fbf4306e4465d5467aaf031308c1b47dcc8039d0"
+ integrity sha512-DL3iBfavn8Nnl48FmnAreQB0k0cIkW531DJ5JAHUCQZo10Nq0ZLk2/WFxcs0KuBG5wuLnGUdo+Y6/GQPVq8dYw==
dependencies:
"@atproto/common-web" "^0.3.0"
- "@atproto/lexicon" "^0.4.0"
+ "@atproto/lexicon" "^0.4.1"
"@atproto/syntax" "^0.3.0"
- "@atproto/xrpc" "^0.5.0"
+ "@atproto/xrpc" "^0.6.0"
+ await-lock "^2.2.2"
multiformats "^9.9.0"
tlds "^1.234.0"
@@ -42,29 +43,29 @@
uint8arrays "3.0.0"
zod "^3.21.4"
-"@atproto/lexicon@^0.4.0":
- version "0.4.0"
- resolved "https://registry.yarnpkg.com/@atproto/lexicon/-/lexicon-0.4.0.tgz#63e8829945d80c25524882caa8ed27b1151cc576"
- integrity sha512-RvCBKdSI4M8qWm5uTNz1z3R2yIvIhmOsMuleOj8YR6BwRD+QbtUBy3l+xQ7iXf4M5fdfJFxaUNa6Ty0iRwdKqQ==
+"@atproto/lexicon@^0.4.1":
+ version "0.4.1"
+ resolved "https://registry.yarnpkg.com/@atproto/lexicon/-/lexicon-0.4.1.tgz#19155210570a2fafbcc7d4f655d9b813948e72a0"
+ integrity sha512-bzyr+/VHXLQWbumViX5L7h1NKQObfs8Z+XZJl43OUK8nYFUI4e/sW1IZKRNfw7Wvi5YVNK+J+yP3DWIBZhkCYA==
dependencies:
"@atproto/common-web" "^0.3.0"
"@atproto/syntax" "^0.3.0"
iso-datestring-validator "^2.2.2"
multiformats "^9.9.0"
- zod "^3.21.4"
+ zod "^3.23.8"
"@atproto/syntax@^0.3.0":
version "0.3.0"
resolved "https://registry.yarnpkg.com/@atproto/syntax/-/syntax-0.3.0.tgz#fafa2dbea9add37253005cb663e7373e05e618b3"
integrity sha512-Weq0ZBxffGHDXHl9U7BQc2BFJi/e23AL+k+i5+D9hUq/bzT4yjGsrCejkjq0xt82xXDjmhhvQSZ0LqxyZ5woxA==
-"@atproto/xrpc@^0.5.0":
- version "0.5.0"
- resolved "https://registry.yarnpkg.com/@atproto/xrpc/-/xrpc-0.5.0.tgz#dacbfd8f7b13f0ab5bd56f8fdd4b460e132a6032"
- integrity sha512-swu+wyOLvYW4l3n+VAuJbHcPcES+tin2Lsrp8Bw5aIXIICiuFn1YMFlwK9JwVUzTH21Py1s1nHEjr4CJeElJog==
+"@atproto/xrpc@^0.6.0":
+ version "0.6.0"
+ resolved "https://registry.yarnpkg.com/@atproto/xrpc/-/xrpc-0.6.0.tgz#668c3262e67e2afa65951ea79a03bfe3720ddf5c"
+ integrity sha512-5BbhBTv5j6MC3iIQ4+vYxQE7nLy2dDGQ+LYJrH8PptOCUdq0Pwg6aRccQ3y52kUZlhE/mzOTZ8Ngiy9pSAyfVQ==
dependencies:
- "@atproto/lexicon" "^0.4.0"
- zod "^3.21.4"
+ "@atproto/lexicon" "^0.4.1"
+ zod "^3.23.8"
"@babel/code-frame@^7.23.5", "@babel/code-frame@^7.24.1", "@babel/code-frame@^7.24.2":
version "7.24.2"
@@ -1710,6 +1711,11 @@ available-typed-arrays@^1.0.7:
dependencies:
possible-typed-array-names "^1.0.0"
+await-lock@^2.2.2:
+ version "2.2.2"
+ resolved "https://registry.yarnpkg.com/await-lock/-/await-lock-2.2.2.tgz#a95a9b269bfd2f69d22b17a321686f551152bcef"
+ integrity sha512-aDczADvlvTGajTDjcjpJMqRkOF6Qdz3YbPZm/PyW6tKPkx2hlYBzxMhEywM/tU72HrVZjgl5VCdRuMlA7pZ8Gw==
+
babel-plugin-polyfill-corejs2@^0.4.10:
version "0.4.10"
resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.10.tgz#276f41710b03a64f6467433cab72cbc2653c38b1"
@@ -3730,8 +3736,16 @@ stack-trace@^1.0.0-pre2:
resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-1.0.0-pre2.tgz#46a83a79f1b287807e9aaafc6a5dd8bcde626f9c"
integrity sha512-2ztBJRek8IVofG9DBJqdy2N5kulaacX30Nz7xmkYF6ale9WBVmIy6mFBchvGX7Vx/MyjBhx+Rcxqrj+dbOnQ6A==
-"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0:
- name string-width-cjs
+"string-width-cjs@npm:string-width@^4.2.0":
+ version "4.2.3"
+ resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
+ integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
+ dependencies:
+ emoji-regex "^8.0.0"
+ is-fullwidth-code-point "^3.0.0"
+ strip-ansi "^6.0.1"
+
+string-width@^4.1.0:
version "4.2.3"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
@@ -3795,7 +3809,14 @@ string.prototype.trimstart@^1.0.8:
define-properties "^1.2.1"
es-object-atoms "^1.0.0"
-"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1:
+"strip-ansi-cjs@npm:strip-ansi@^6.0.1":
+ version "6.0.1"
+ resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
+ integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
+ dependencies:
+ ansi-regex "^5.0.1"
+
+strip-ansi@^6.0.0, strip-ansi@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
@@ -4192,3 +4213,8 @@ zod@^3.21.4:
version "3.22.4"
resolved "https://registry.yarnpkg.com/zod/-/zod-3.22.4.tgz#f31c3a9386f61b1f228af56faa9255e845cf3fff"
integrity sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==
+
+zod@^3.23.8:
+ version "3.23.8"
+ resolved "https://registry.yarnpkg.com/zod/-/zod-3.23.8.tgz#e37b957b5d52079769fb8097099b592f0ef4067d"
+ integrity sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==
diff --git a/src/components/StarterPack/StarterPackCard.tsx b/src/components/StarterPack/StarterPackCard.tsx
index dc9e4b70..4c4bf246 100644
--- a/src/components/StarterPack/StarterPackCard.tsx
+++ b/src/components/StarterPack/StarterPackCard.tsx
@@ -1,8 +1,7 @@
import React from 'react'
import {View} from 'react-native'
import {Image} from 'expo-image'
-import {AppBskyGraphStarterpack, AtUri} from '@atproto/api'
-import {StarterPackViewBasic} from '@atproto/api/dist/client/types/app/bsky/graph/defs'
+import {AppBskyGraphDefs, AppBskyGraphStarterpack, AtUri} from '@atproto/api'
import {msg, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import {useQueryClient} from '@tanstack/react-query'
@@ -17,7 +16,11 @@ import {StarterPack} from '#/components/icons/StarterPack'
import {BaseLink} from '#/components/Link'
import {Text} from '#/components/Typography'
-export function Default({starterPack}: {starterPack?: StarterPackViewBasic}) {
+export function Default({
+ starterPack,
+}: {
+ starterPack?: AppBskyGraphDefs.StarterPackViewBasic
+}) {
if (!starterPack) return null
return (
@@ -29,7 +32,7 @@ export function Default({starterPack}: {starterPack?: StarterPackViewBasic}) {
export function Notification({
starterPack,
}: {
- starterPack?: StarterPackViewBasic
+ starterPack?: AppBskyGraphDefs.StarterPackViewBasic
}) {
if (!starterPack) return null
return (
@@ -44,7 +47,7 @@ export function Card({
noIcon,
noDescription,
}: {
- starterPack: StarterPackViewBasic
+ starterPack: AppBskyGraphDefs.StarterPackViewBasic
noIcon?: boolean
noDescription?: boolean
}) {
@@ -94,7 +97,7 @@ export function Link({
starterPack,
children,
}: {
- starterPack: StarterPackViewBasic
+ starterPack: AppBskyGraphDefs.StarterPackViewBasic
onPress?: () => void
children: React.ReactNode
}) {
@@ -129,7 +132,11 @@ export function Link({
)
}
-export function Embed({starterPack}: {starterPack: StarterPackViewBasic}) {
+export function Embed({
+ starterPack,
+}: {
+ starterPack: AppBskyGraphDefs.StarterPackViewBasic
+}) {
const t = useTheme()
const imageUri = getStarterPackOgCard(starterPack)