Starter Packs (#4332)

Co-authored-by: Dan Abramov <dan.abramov@gmail.com>
Co-authored-by: Paul Frazee <pfrazee@gmail.com>
Co-authored-by: Eric Bailey <git@esb.lol>
Co-authored-by: Samuel Newman <mozzius@protonmail.com>
This commit is contained in:
Hailey
2024-06-21 21:38:04 -07:00
committed by GitHub
parent 35f64535cb
commit f089f45781
115 changed files with 6336 additions and 237 deletions
+8 -3
View File
@@ -155,8 +155,10 @@ export function* findAllPostsInQueryData(
for (const page of queryData?.pages) {
for (const item of page.items) {
if (item.subject && didOrHandleUriMatches(atUri, item.subject)) {
yield item.subject
if (item.type !== 'starterpack-joined') {
if (item.subject && didOrHandleUriMatches(atUri, item.subject)) {
yield item.subject
}
}
const quotedPost = getEmbeddedPost(item.subject?.embed)
@@ -181,7 +183,10 @@ export function* findAllProfilesInQueryData(
}
for (const page of queryData?.pages) {
for (const item of page.items) {
if (item.subject?.author.did === did) {
if (
item.type !== 'starterpack-joined' &&
item.subject?.author.did === did
) {
yield item.subject.author
}
const quotedPost = getEmbeddedPost(item.subject?.embed)
+32 -17
View File
@@ -1,26 +1,22 @@
import {
AppBskyNotificationListNotifications,
AppBskyFeedDefs,
AppBskyGraphDefs,
AppBskyNotificationListNotifications,
} from '@atproto/api'
export type NotificationType =
| 'post-like'
| 'feedgen-like'
| 'repost'
| 'mention'
| 'reply'
| 'quote'
| 'follow'
| 'unknown'
| StarterPackNotificationType
| OtherNotificationType
export interface FeedNotification {
_reactKey: string
type: NotificationType
notification: AppBskyNotificationListNotifications.Notification
additional?: AppBskyNotificationListNotifications.Notification[]
subjectUri?: string
subject?: AppBskyFeedDefs.PostView
}
export type FeedNotification =
| (FeedNotificationBase & {
type: StarterPackNotificationType
subject?: AppBskyGraphDefs.StarterPackViewBasic
})
| (FeedNotificationBase & {
type: OtherNotificationType
subject?: AppBskyFeedDefs.PostView
})
export interface FeedPage {
cursor: string | undefined
@@ -37,3 +33,22 @@ export interface CachedFeedPage {
data: FeedPage | undefined
unreadCount: number
}
type StarterPackNotificationType = 'starterpack-joined'
type OtherNotificationType =
| 'post-like'
| 'repost'
| 'mention'
| 'reply'
| 'quote'
| 'follow'
| 'feedgen-like'
| 'unknown'
type FeedNotificationBase = {
_reactKey: string
notification: AppBskyNotificationListNotifications.Notification
additional?: AppBskyNotificationListNotifications.Notification[]
subjectUri?: string
subject?: AppBskyFeedDefs.PostView | AppBskyGraphDefs.StarterPackViewBasic
}
+65 -18
View File
@@ -3,6 +3,8 @@ import {
AppBskyFeedLike,
AppBskyFeedPost,
AppBskyFeedRepost,
AppBskyGraphDefs,
AppBskyGraphStarterpack,
AppBskyNotificationListNotifications,
BskyAgent,
moderateNotification,
@@ -40,6 +42,7 @@ export async function fetchPage({
limit,
cursor,
})
const indexedAt = res.data.notifications[0]?.indexedAt
// filter out notifs by mod rules
@@ -56,9 +59,18 @@ export async function fetchPage({
const subjects = await fetchSubjects(agent, notifsGrouped)
for (const notif of notifsGrouped) {
if (notif.subjectUri) {
notif.subject = subjects.get(notif.subjectUri)
if (notif.subject) {
precacheProfile(queryClient, notif.subject.author)
if (
notif.type === 'starterpack-joined' &&
notif.notification.reasonSubject
) {
notif.subject = subjects.starterPacks.get(
notif.notification.reasonSubject,
)
} else {
notif.subject = subjects.posts.get(notif.subjectUri)
if (notif.subject) {
precacheProfile(queryClient, notif.subject.author)
}
}
}
}
@@ -120,12 +132,21 @@ export function groupNotifications(
}
if (!grouped) {
const type = toKnownType(notif)
groupedNotifs.push({
_reactKey: `notif-${notif.uri}`,
type,
notification: notif,
subjectUri: getSubjectUri(type, notif),
})
if (type !== 'starterpack-joined') {
groupedNotifs.push({
_reactKey: `notif-${notif.uri}`,
type,
notification: notif,
subjectUri: getSubjectUri(type, notif),
})
} else {
groupedNotifs.push({
_reactKey: `notif-${notif.uri}`,
type: 'starterpack-joined',
notification: notif,
subjectUri: notif.uri,
})
}
}
}
return groupedNotifs
@@ -134,29 +155,54 @@ export function groupNotifications(
async function fetchSubjects(
agent: BskyAgent,
groupedNotifs: FeedNotification[],
): Promise<Map<string, AppBskyFeedDefs.PostView>> {
const uris = new Set<string>()
): Promise<{
posts: Map<string, AppBskyFeedDefs.PostView>
starterPacks: Map<string, AppBskyGraphDefs.StarterPackViewBasic>
}> {
const postUris = new Set<string>()
const packUris = new Set<string>()
for (const notif of groupedNotifs) {
if (notif.subjectUri?.includes('app.bsky.feed.post')) {
uris.add(notif.subjectUri)
postUris.add(notif.subjectUri)
} else if (
notif.notification.reasonSubject?.includes('app.bsky.graph.starterpack')
) {
packUris.add(notif.notification.reasonSubject)
}
}
const uriChunks = chunk(Array.from(uris), 25)
const postUriChunks = chunk(Array.from(postUris), 25)
const packUriChunks = chunk(Array.from(packUris), 25)
const postsChunks = await Promise.all(
uriChunks.map(uris =>
postUriChunks.map(uris =>
agent.app.bsky.feed.getPosts({uris}).then(res => res.data.posts),
),
)
const map = new Map<string, AppBskyFeedDefs.PostView>()
const packsChunks = await Promise.all(
packUriChunks.map(uris =>
agent.app.bsky.graph
.getStarterPacks({uris})
.then(res => res.data.starterPacks),
),
)
const postsMap = new Map<string, AppBskyFeedDefs.PostView>()
const packsMap = new Map<string, AppBskyGraphDefs.StarterPackView>()
for (const post of postsChunks.flat()) {
if (
AppBskyFeedPost.isRecord(post.record) &&
AppBskyFeedPost.validateRecord(post.record).success
) {
map.set(post.uri, post)
postsMap.set(post.uri, post)
}
}
return map
for (const pack of packsChunks.flat()) {
if (AppBskyGraphStarterpack.isRecord(pack.record)) {
packsMap.set(pack.uri, pack)
}
}
return {
posts: postsMap,
starterPacks: packsMap,
}
}
function toKnownType(
@@ -173,7 +219,8 @@ function toKnownType(
notif.reason === 'mention' ||
notif.reason === 'reply' ||
notif.reason === 'quote' ||
notif.reason === 'follow'
notif.reason === 'follow' ||
notif.reason === 'starterpack-joined'
) {
return notif.reason as NotificationType
}