From 2174feed441459448668934015810fe0eb876dde Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 8 Aug 2024 15:49:34 +0100 Subject: [PATCH] Include follow-based suggestions in interstitial (#4889) --- src/components/FeedInterstitials.tsx | 14 ++++++++++++-- src/state/queries/profile.ts | 15 +++++++++++++++ src/state/userActionHistory.ts | 13 +++++++++++++ 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/src/components/FeedInterstitials.tsx b/src/components/FeedInterstitials.tsx index eca1c86f..e37d2c3e 100644 --- a/src/components/FeedInterstitials.tsx +++ b/src/components/FeedInterstitials.tsx @@ -133,16 +133,26 @@ function useExperimentalSuggestedUsersQuery() { const {currentAccount} = useSession() const userActionSnapshot = userActionHistory.useActionHistorySnapshot() const dids = React.useMemo(() => { - const {likes, follows, seen} = userActionSnapshot + const {likes, follows, followSuggestions, seen} = userActionSnapshot const likeDids = likes .map(l => new AtUri(l)) .map(uri => uri.host) .filter(did => !follows.includes(did)) + let suggestedDids: string[] = [] + if (followSuggestions.length > 0) { + suggestedDids = [ + // It's ok if these will pick the same item (weighed by its frequency) + followSuggestions[Math.floor(Math.random() * followSuggestions.length)], + followSuggestions[Math.floor(Math.random() * followSuggestions.length)], + followSuggestions[Math.floor(Math.random() * followSuggestions.length)], + followSuggestions[Math.floor(Math.random() * followSuggestions.length)], + ] + } const seenDids = seen .sort(sortSeenPosts) .map(l => new AtUri(l.uri)) .map(uri => uri.host) - return [...new Set([...likeDids, ...seenDids])].filter( + return [...new Set([...suggestedDids, ...likeDids, ...seenDids])].filter( did => did !== currentAccount?.did, ) }, [userActionSnapshot, currentAccount]) diff --git a/src/state/queries/profile.ts b/src/state/queries/profile.ts index 1f866d26..6682cf3c 100644 --- a/src/state/queries/profile.ts +++ b/src/state/queries/profile.ts @@ -222,6 +222,7 @@ export function useProfileFollowMutationQueue( logContext: LogEvents['profile:follow']['logContext'] & LogEvents['profile:unfollow']['logContext'], ) { + const agent = useAgent() const queryClient = useQueryClient() const did = profile.did const initialFollowingUri = profile.viewer?.following @@ -253,6 +254,20 @@ export function useProfileFollowMutationQueue( updateProfileShadow(queryClient, did, { followingUri: finalFollowingUri, }) + + if (finalFollowingUri) { + agent.app.bsky.graph + .getSuggestedFollowsByActor({ + actor: did, + }) + .then(res => { + const dids = res.data.suggestions + .filter(a => !a.viewer?.following) + .map(a => a.did) + .slice(0, 8) + userActionHistory.followSuggestion(dids) + }) + } }, }) diff --git a/src/state/userActionHistory.ts b/src/state/userActionHistory.ts index d82b3723..8ffe7241 100644 --- a/src/state/userActionHistory.ts +++ b/src/state/userActionHistory.ts @@ -2,6 +2,7 @@ import React from 'react' const LIKE_WINDOW = 100 const FOLLOW_WINDOW = 100 +const FOLLOW_SUGGESTION_WINDOW = 100 const SEEN_WINDOW = 100 export type SeenPost = { @@ -22,6 +23,10 @@ export type UserActionHistory = { * The last 100 DIDs the user has followed */ follows: string[] + /* + * The last 100 DIDs of suggested follows based on last follows + */ + followSuggestions: string[] /** * The last 100 post URIs the user has seen from the Discover feed only */ @@ -31,6 +36,7 @@ export type UserActionHistory = { const userActionHistory: UserActionHistory = { likes: [], follows: [], + followSuggestions: [], seen: [], } @@ -58,6 +64,13 @@ export function follow(dids: string[]) { .concat(dids) .slice(-FOLLOW_WINDOW) } + +export function followSuggestion(dids: string[]) { + userActionHistory.followSuggestions = userActionHistory.followSuggestions + .concat(dids) + .slice(-FOLLOW_SUGGESTION_WINDOW) +} + export function unfollow(dids: string[]) { userActionHistory.follows = userActionHistory.follows.filter( uri => !dids.includes(uri),