fork
Configure Feed
Select the types of activity you want to include in your feed.
mirror of https://git.lenooby09.tech/LeNooby09/social-app.git
fork
Configure Feed
Select the types of activity you want to include in your feed.
1import {useEffect, useMemo, useState} from 'react'
2import {AppBskyActorDefs} from '@atproto/api'
3import {QueryClient} from '@tanstack/react-query'
4import EventEmitter from 'eventemitter3'
5
6import {batchedUpdates} from '#/lib/batchedUpdates'
7import {findAllProfilesInQueryData as findAllProfilesInActorSearchQueryData} from '../queries/actor-search'
8import {findAllProfilesInQueryData as findAllProfilesInListMembersQueryData} from '../queries/list-members'
9import {findAllProfilesInQueryData as findAllProfilesInListConvosQueryData} from '../queries/messages/list-converations'
10import {findAllProfilesInQueryData as findAllProfilesInMyBlockedAccountsQueryData} from '../queries/my-blocked-accounts'
11import {findAllProfilesInQueryData as findAllProfilesInMyMutedAccountsQueryData} from '../queries/my-muted-accounts'
12import {findAllProfilesInQueryData as findAllProfilesInFeedsQueryData} from '../queries/post-feed'
13import {findAllProfilesInQueryData as findAllProfilesInPostLikedByQueryData} from '../queries/post-liked-by'
14import {findAllProfilesInQueryData as findAllProfilesInPostRepostedByQueryData} from '../queries/post-reposted-by'
15import {findAllProfilesInQueryData as findAllProfilesInPostThreadQueryData} from '../queries/post-thread'
16import {findAllProfilesInQueryData as findAllProfilesInProfileQueryData} from '../queries/profile'
17import {findAllProfilesInQueryData as findAllProfilesInProfileFollowersQueryData} from '../queries/profile-followers'
18import {findAllProfilesInQueryData as findAllProfilesInProfileFollowsQueryData} from '../queries/profile-follows'
19import {findAllProfilesInQueryData as findAllProfilesInSuggestedFollowsQueryData} from '../queries/suggested-follows'
20import {castAsShadow, Shadow} from './types'
21export type {Shadow} from './types'
22
23export interface ProfileShadow {
24 followingUri: string | undefined
25 muted: boolean | undefined
26 blockingUri: string | undefined
27}
28
29const shadows: WeakMap<
30 AppBskyActorDefs.ProfileView,
31 Partial<ProfileShadow>
32> = new WeakMap()
33const emitter = new EventEmitter()
34
35export function useProfileShadow<
36 TProfileView extends AppBskyActorDefs.ProfileView,
37>(profile: TProfileView): Shadow<TProfileView> {
38 const [shadow, setShadow] = useState(() => shadows.get(profile))
39 const [prevPost, setPrevPost] = useState(profile)
40 if (profile !== prevPost) {
41 setPrevPost(profile)
42 setShadow(shadows.get(profile))
43 }
44
45 useEffect(() => {
46 function onUpdate() {
47 setShadow(shadows.get(profile))
48 }
49 emitter.addListener(profile.did, onUpdate)
50 return () => {
51 emitter.removeListener(profile.did, onUpdate)
52 }
53 }, [profile])
54
55 return useMemo(() => {
56 if (shadow) {
57 return mergeShadow(profile, shadow)
58 } else {
59 return castAsShadow(profile)
60 }
61 }, [profile, shadow])
62}
63
64export function updateProfileShadow(
65 queryClient: QueryClient,
66 did: string,
67 value: Partial<ProfileShadow>,
68) {
69 const cachedProfiles = findProfilesInCache(queryClient, did)
70 for (let post of cachedProfiles) {
71 shadows.set(post, {...shadows.get(post), ...value})
72 }
73 batchedUpdates(() => {
74 emitter.emit(did, value)
75 })
76}
77
78function mergeShadow<TProfileView extends AppBskyActorDefs.ProfileView>(
79 profile: TProfileView,
80 shadow: Partial<ProfileShadow>,
81): Shadow<TProfileView> {
82 return castAsShadow({
83 ...profile,
84 viewer: {
85 ...(profile.viewer || {}),
86 following:
87 'followingUri' in shadow
88 ? shadow.followingUri
89 : profile.viewer?.following,
90 muted: 'muted' in shadow ? shadow.muted : profile.viewer?.muted,
91 blocking:
92 'blockingUri' in shadow ? shadow.blockingUri : profile.viewer?.blocking,
93 },
94 })
95}
96
97function* findProfilesInCache(
98 queryClient: QueryClient,
99 did: string,
100): Generator<AppBskyActorDefs.ProfileView, void> {
101 yield* findAllProfilesInListMembersQueryData(queryClient, did)
102 yield* findAllProfilesInMyBlockedAccountsQueryData(queryClient, did)
103 yield* findAllProfilesInMyMutedAccountsQueryData(queryClient, did)
104 yield* findAllProfilesInPostLikedByQueryData(queryClient, did)
105 yield* findAllProfilesInPostRepostedByQueryData(queryClient, did)
106 yield* findAllProfilesInProfileQueryData(queryClient, did)
107 yield* findAllProfilesInProfileFollowersQueryData(queryClient, did)
108 yield* findAllProfilesInProfileFollowsQueryData(queryClient, did)
109 yield* findAllProfilesInSuggestedFollowsQueryData(queryClient, did)
110 yield* findAllProfilesInActorSearchQueryData(queryClient, did)
111 yield* findAllProfilesInListConvosQueryData(queryClient, did)
112 yield* findAllProfilesInFeedsQueryData(queryClient, did)
113 yield* findAllProfilesInPostThreadQueryData(queryClient, did)
114}