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