From 11f312762afde7bfff6c4fc7d9ae48f8b93b6307 Mon Sep 17 00:00:00 2001 From: Foysal Ahamed Date: Tue, 25 Jun 2024 19:03:55 +0200 Subject: [PATCH] :sparkles: Add starterpack support (#137) * :sparkles: Add starterpack support * :sparkles: Add og card image for starter packs and cleanup --- components/common/PreviewCard.tsx | 1 + components/common/RecordCard.tsx | 4 + components/common/starterpacks/RecordCard.tsx | 176 ++++++++++++++++++ components/reports/SubjectOverview.tsx | 22 +++ components/reports/helpers/subject.ts | 4 + components/repositories/RecordView.tsx | 15 ++ lib/constants.ts | 2 + package.json | 2 +- yarn.lock | 8 +- 9 files changed, 229 insertions(+), 5 deletions(-) create mode 100644 components/common/starterpacks/RecordCard.tsx diff --git a/components/common/PreviewCard.tsx b/components/common/PreviewCard.tsx index 6ac21143..2e304160 100644 --- a/components/common/PreviewCard.tsx +++ b/components/common/PreviewCard.tsx @@ -8,6 +8,7 @@ const PreviewTitleMap = { [CollectionId.FeedGenerator]: 'Reported feed', [CollectionId.List]: 'Reported list', [CollectionId.Profile]: 'Reported profile', + [CollectionId.StarterPack]: 'Reported starter pack', } const getPreviewTitleForAtUri = (uri: string): string => { diff --git a/components/common/RecordCard.tsx b/components/common/RecordCard.tsx index eebc23d3..deb09359 100644 --- a/components/common/RecordCard.tsx +++ b/components/common/RecordCard.tsx @@ -12,6 +12,7 @@ import { ProfileAvatar } from '@/repositories/ProfileAvatar' import { ShieldCheckIcon } from '@heroicons/react/24/solid' import { ProfileViewDetailed } from '@atproto/api/dist/client/types/app/bsky/actor/defs' import { isSelfLabels } from '@atproto/api/dist/client/types/com/atproto/label/defs' +import { StarterPackRecordCard } from './starterpacks/RecordCard' export function RecordCard(props: { uri: string; showLabels?: boolean }) { const { uri, showLabels = false } = props @@ -28,6 +29,9 @@ export function RecordCard(props: { uri: string; showLabels?: boolean }) { if (parsed.collection === CollectionId.List) { return } + if (parsed.collection === CollectionId.StarterPack) { + return + } if (parsed?.collection === CollectionId.Profile) { return ( { + const { error, data, isFetching } = useQuery({ + retry: false, + queryKey: ['starterpack', uri], + queryFn: async () => { + const { data } = await client.api.app.bsky.graph.getStarterPack( + { + starterPack: uri, + }, + { headers: client.proxyHeaders() }, + ) + return data + }, + }) + + if (isFetching) { + return + } + + if (error) { + return + } + + if (!data) { + return + } + + const { + starterPack: { + creator, + list, + feeds, + joinedWeekCount, + joinedAllTimeCount, + indexedAt, + record, + }, + } = data + const displayName = record['name'] || 'Untitled' + const rkey = uri.split('/').pop() + + const meta: string[] = [ + `${joinedWeekCount} Joined last week`, + `${joinedAllTimeCount} Joined all time`, + `${feeds?.length || 'No'} feed(s) included`, + ] + + if (indexedAt) { + meta.push(new Date(indexedAt as string).toLocaleString()) + } + + return ( +
+
+
+ {`Avatar +
+
+

+ <> + + {displayName} + + by + + + @{creator.handle} + + + {' '} +  ·  + + Peek + +

+
+
+
+ + Starter pack OG card + + {!!feeds?.length && ( +
+
Feeds
+
    + {feeds.map((feed) => ( +
  • + + {feed.displayName} + +  ·  + + Peek + +
  • + ))} +
+
+ )} + {!!list && } + {!!meta.length && ( +

{meta.join(' - ')}

+ )} +
+
+ ) +} + +const ListSummary = ({ list }: { list: AppBskyGraphDefs.ListViewBasic }) => { + const listUri = parseAtUri(list.uri) + if (!listUri) { + return null + } + const { did, rkey } = listUri + + return ( +
+
List
+
+ + {list.name} + +  ·  + {list.listItemCount} members  ·  + + Peek + +
+
+ ) +} diff --git a/components/reports/SubjectOverview.tsx b/components/reports/SubjectOverview.tsx index de32fb7d..f64a7304 100644 --- a/components/reports/SubjectOverview.tsx +++ b/components/reports/SubjectOverview.tsx @@ -131,6 +131,28 @@ export function SubjectOverview(props: { ) } + if (summary.collection === CollectionId.StarterPack) { + return ( +
+ + {!hideActor && ( + <> + by + + + )} +
+ ) + } + if (summary.collection === CollectionId.Profile) { return (
diff --git a/components/reports/helpers/subject.ts b/components/reports/helpers/subject.ts index bbf67536..78d3e094 100644 --- a/components/reports/helpers/subject.ts +++ b/components/reports/helpers/subject.ts @@ -69,6 +69,7 @@ export enum CollectionId { List = 'app.bsky.graph.list', Post = 'app.bsky.feed.post', LabelerService = 'app.bsky.labeler.service', + StarterPack = 'app.bsky.graph.starterpack', } export const getProfileUriForDid = (did: string) => `at://${did}/${CollectionId.Profile}/self` @@ -89,6 +90,9 @@ export const getCollectionName = (collection: string) => { if (collection === CollectionId.LabelerService) { return 'Labeler' } + if (collection === CollectionId.StarterPack) { + return 'Starter Pack' + } // If the collection is a string with ., use the last two segments as the title // so app.bsky.graph.list -> graph list if (collection.includes('.')) { diff --git a/components/repositories/RecordView.tsx b/components/repositories/RecordView.tsx index b981a050..381dd31c 100644 --- a/components/repositories/RecordView.tsx +++ b/components/repositories/RecordView.tsx @@ -206,6 +206,21 @@ function Details({ record }: { record: GetRecord.OutputSchema }) { return (
+ {record.value?.['displayName'] && ( + + )} + {record.value?.['name'] && ( + + )} + {record.value?.['description'] && ( + + )} {record.repo.handle} diff --git a/lib/constants.ts b/lib/constants.ts index 648eb291..886f4d7e 100644 --- a/lib/constants.ts +++ b/lib/constants.ts @@ -10,3 +10,5 @@ export const SOCIAL_APP_DOMAIN = 'bsky.app' export const SOCIAL_APP_URL = `https://${SOCIAL_APP_DOMAIN}` export const DM_DISABLE_TAG = 'chat-disabled' + +export const STARTER_PACK_OG_CARD_URL = `https://ogcard.cdn.bsky.app/start` diff --git a/package.json b/package.json index f4a561d6..acadb8b3 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "e2e:run": "$(yarn bin)/cypress run" }, "dependencies": { - "@atproto/api": "^0.12.17", + "@atproto/api": "0.12.22", "@headlessui/react": "^1.7.7", "@heroicons/react": "^2.0.13", "@tanstack/react-query": "^4.22.0", diff --git a/yarn.lock b/yarn.lock index bb267fe6..77c027ca 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,10 +2,10 @@ # yarn lockfile v1 -"@atproto/api@^0.12.17": - version "0.12.17" - resolved "https://registry.yarnpkg.com/@atproto/api/-/api-0.12.17.tgz#6fc98f9e4a831d5d0bb792a4dd2388713a587ed9" - integrity sha512-hj2LnEJGM27xPB1cugZHMnsvPDzjcIc0JtrGS11LO8+XJ/QYL192/HVdPQR82rN8XMlSPHXhNoeI2NJna8MUGQ== +"@atproto/api@0.12.22": + version "0.12.22" + resolved "https://registry.yarnpkg.com/@atproto/api/-/api-0.12.22.tgz#1880a93a0caa4485cd8463bd1e10bf2424b9826c" + integrity sha512-TIXSnf3qqyX40Ei/FkK4H24w+7s5rOc63TPwrGakRBOqIgSNBKOggei8I600fJ/AXB7HO6Vp9tBmDVOt2+021A== dependencies: "@atproto/common-web" "^0.3.0" "@atproto/lexicon" "^0.4.0"