Bluesky app fork with some witchin' additions 💫

Shadows (#4265)

authored by

Eric Bailey and committed by
GitHub
d614f6cb 89c9fd3b

+149 -11
+4
src/state/cache/profile-shadow.ts
··· 9 9 import {findAllProfilesInQueryData as findAllProfilesInListConvosQueryData} from '../queries/messages/list-converations' 10 10 import {findAllProfilesInQueryData as findAllProfilesInMyBlockedAccountsQueryData} from '../queries/my-blocked-accounts' 11 11 import {findAllProfilesInQueryData as findAllProfilesInMyMutedAccountsQueryData} from '../queries/my-muted-accounts' 12 + import {findAllProfilesInQueryData as findAllProfilesInFeedsQueryData} from '../queries/post-feed' 12 13 import {findAllProfilesInQueryData as findAllProfilesInPostLikedByQueryData} from '../queries/post-liked-by' 13 14 import {findAllProfilesInQueryData as findAllProfilesInPostRepostedByQueryData} from '../queries/post-reposted-by' 15 + import {findAllProfilesInQueryData as findAllProfilesInPostThreadQueryData} from '../queries/post-thread' 14 16 import {findAllProfilesInQueryData as findAllProfilesInProfileQueryData} from '../queries/profile' 15 17 import {findAllProfilesInQueryData as findAllProfilesInProfileFollowersQueryData} from '../queries/profile-followers' 16 18 import {findAllProfilesInQueryData as findAllProfilesInProfileFollowsQueryData} from '../queries/profile-follows' ··· 107 109 yield* findAllProfilesInSuggestedFollowsQueryData(queryClient, did) 108 110 yield* findAllProfilesInActorSearchQueryData(queryClient, did) 109 111 yield* findAllProfilesInListConvosQueryData(queryClient, did) 112 + yield* findAllProfilesInFeedsQueryData(queryClient, did) 113 + yield* findAllProfilesInPostThreadQueryData(queryClient, did) 110 114 }
+26 -1
src/state/queries/notifications/feed.ts
··· 17 17 */ 18 18 19 19 import {useEffect, useRef} from 'react' 20 - import {AppBskyFeedDefs} from '@atproto/api' 20 + import {AppBskyActorDefs, AppBskyFeedDefs} from '@atproto/api' 21 21 import { 22 22 InfiniteData, 23 23 QueryClient, ··· 162 162 } 163 163 } 164 164 } 165 + 166 + export function* findAllProfilesInQueryData( 167 + queryClient: QueryClient, 168 + did: string, 169 + ): Generator<AppBskyActorDefs.ProfileView, void> { 170 + const queryDatas = queryClient.getQueriesData<InfiniteData<FeedPage>>({ 171 + queryKey: [RQKEY_ROOT], 172 + }) 173 + for (const [_queryKey, queryData] of queryDatas) { 174 + if (!queryData?.pages) { 175 + continue 176 + } 177 + for (const page of queryData?.pages) { 178 + for (const item of page.items) { 179 + if (item.subject?.author.did === did) { 180 + yield item.subject.author 181 + } 182 + const quotedPost = getEmbeddedPost(item.subject?.embed) 183 + if (quotedPost?.author.did === did) { 184 + yield quotedPost.author 185 + } 186 + } 187 + } 188 + } 189 + }
+39
src/state/queries/post-feed.ts
··· 483 483 } 484 484 } 485 485 486 + export function* findAllProfilesInQueryData( 487 + queryClient: QueryClient, 488 + did: string, 489 + ): Generator<AppBskyActorDefs.ProfileView, undefined> { 490 + const queryDatas = queryClient.getQueriesData< 491 + InfiniteData<FeedPageUnselected> 492 + >({ 493 + queryKey: [RQKEY_ROOT], 494 + }) 495 + for (const [_queryKey, queryData] of queryDatas) { 496 + if (!queryData?.pages) { 497 + continue 498 + } 499 + for (const page of queryData?.pages) { 500 + for (const item of page.feed) { 501 + if (item.post.author.did === did) { 502 + yield item.post.author 503 + } 504 + const quotedPost = getEmbeddedPost(item.post.embed) 505 + if (quotedPost?.author.did === did) { 506 + yield quotedPost.author 507 + } 508 + if ( 509 + AppBskyFeedDefs.isPostView(item.reply?.parent) && 510 + item.reply?.parent?.author.did === did 511 + ) { 512 + yield item.reply.parent.author 513 + } 514 + if ( 515 + AppBskyFeedDefs.isPostView(item.reply?.root) && 516 + item.reply?.root?.author.did === did 517 + ) { 518 + yield item.reply.root.author 519 + } 520 + } 521 + } 522 + } 523 + } 524 + 486 525 function assertSomePostsPassModeration(feed: AppBskyFeedDefs.FeedViewPost[]) { 487 526 // no posts in this feed 488 527 if (feed.length === 0) return true
+46 -3
src/state/queries/post-thread.ts
··· 1 1 import { 2 + AppBskyActorDefs, 2 3 AppBskyEmbedRecord, 3 4 AppBskyFeedDefs, 4 5 AppBskyFeedGetPostThread, ··· 11 12 import {moderatePost_wrapped as moderatePost} from '#/lib/moderatePost_wrapped' 12 13 import {UsePreferencesQueryResponse} from '#/state/queries/preferences/types' 13 14 import {useAgent} from '#/state/session' 14 - import {findAllPostsInQueryData as findAllPostsInSearchQueryData} from 'state/queries/search-posts' 15 - import {findAllPostsInQueryData as findAllPostsInNotifsQueryData} from './notifications/feed' 16 - import {findAllPostsInQueryData as findAllPostsInFeedQueryData} from './post-feed' 15 + import { 16 + findAllPostsInQueryData as findAllPostsInSearchQueryData, 17 + findAllProfilesInQueryData as findAllProfilesInSearchQueryData, 18 + } from 'state/queries/search-posts' 19 + import { 20 + findAllPostsInQueryData as findAllPostsInNotifsQueryData, 21 + findAllProfilesInQueryData as findAllProfilesInNotifsQueryData, 22 + } from './notifications/feed' 23 + import { 24 + findAllPostsInQueryData as findAllPostsInFeedQueryData, 25 + findAllProfilesInQueryData as findAllProfilesInFeedQueryData, 26 + } from './post-feed' 17 27 import {embedViewRecordToPostView, getEmbeddedPost} from './util' 18 28 19 29 const RQKEY_ROOT = 'post-thread' ··· 290 300 } 291 301 for (let post of findAllPostsInSearchQueryData(queryClient, uri)) { 292 302 yield postViewToPlaceholderThread(post) 303 + } 304 + } 305 + 306 + export function* findAllProfilesInQueryData( 307 + queryClient: QueryClient, 308 + did: string, 309 + ): Generator<AppBskyActorDefs.ProfileView, void> { 310 + const queryDatas = queryClient.getQueriesData<ThreadNode>({ 311 + queryKey: [RQKEY_ROOT], 312 + }) 313 + for (const [_queryKey, queryData] of queryDatas) { 314 + if (!queryData) { 315 + continue 316 + } 317 + for (const item of traverseThread(queryData)) { 318 + if (item.type === 'post' && item.post.author.did === did) { 319 + yield item.post.author 320 + } 321 + const quotedPost = 322 + item.type === 'post' ? getEmbeddedPost(item.post.embed) : undefined 323 + if (quotedPost?.author.did === did) { 324 + yield quotedPost?.author 325 + } 326 + } 327 + } 328 + for (let profile of findAllProfilesInFeedQueryData(queryClient, did)) { 329 + yield profile 330 + } 331 + for (let profile of findAllProfilesInNotifsQueryData(queryClient, did)) { 332 + yield profile 333 + } 334 + for (let profile of findAllProfilesInSearchQueryData(queryClient, did)) { 335 + yield profile 293 336 } 294 337 } 295 338
+32 -1
src/state/queries/search-posts.ts
··· 1 - import {AppBskyFeedDefs, AppBskyFeedSearchPosts} from '@atproto/api' 1 + import { 2 + AppBskyActorDefs, 3 + AppBskyFeedDefs, 4 + AppBskyFeedSearchPosts, 5 + } from '@atproto/api' 2 6 import { 3 7 InfiniteData, 4 8 QueryClient, ··· 75 79 } 76 80 } 77 81 } 82 + 83 + export function* findAllProfilesInQueryData( 84 + queryClient: QueryClient, 85 + did: string, 86 + ): Generator<AppBskyActorDefs.ProfileView, undefined> { 87 + const queryDatas = queryClient.getQueriesData< 88 + InfiniteData<AppBskyFeedSearchPosts.OutputSchema> 89 + >({ 90 + queryKey: [searchPostsQueryKeyRoot], 91 + }) 92 + for (const [_queryKey, queryData] of queryDatas) { 93 + if (!queryData?.pages) { 94 + continue 95 + } 96 + for (const page of queryData?.pages) { 97 + for (const post of page.posts) { 98 + if (post.author.did === did) { 99 + yield post.author 100 + } 101 + const quotedPost = getEmbeddedPost(post.embed) 102 + if (quotedPost?.author.did === did) { 103 + yield quotedPost.author 104 + } 105 + } 106 + } 107 + } 108 + }
+2 -6
src/view/com/posts/AviFollowButton.tsx
··· 1 - import React, {useState} from 'react' 1 + import React from 'react' 2 2 import {View} from 'react-native' 3 3 import {AppBskyActorDefs, ModerationDecision} from '@atproto/api' 4 4 import {msg} from '@lingui/macro' ··· 39 39 }) 40 40 const gate = useGate() 41 41 const {currentAccount, hasSession} = useSession() 42 - const [followed, setFollowed] = useState<string | null>(null) 43 42 const navigation = useNavigation<NavigationProp>() 44 43 45 44 const name = sanitizeDisplayName( ··· 47 46 moderation.ui('displayName'), 48 47 ) 49 48 const isFollowing = 50 - profile.viewer?.following || 51 - profile.did === followed || 52 - profile.did === currentAccount?.did 49 + profile.viewer?.following || profile.did === currentAccount?.did 53 50 54 51 function onPress() { 55 52 follow() 56 - setFollowed(profile.did) 57 53 Toast.show(_(msg`Following ${name}`)) 58 54 } 59 55