Bluesky app fork with some witchin' additions 💫 witchsky.app
bluesky fork client

Include follow-based suggestions in interstitial (#4889)

authored by danabra.mov and committed by

GitHub 2174feed f1031d10

+40 -2
+12 -2
src/components/FeedInterstitials.tsx
··· 133 const {currentAccount} = useSession() 134 const userActionSnapshot = userActionHistory.useActionHistorySnapshot() 135 const dids = React.useMemo(() => { 136 - const {likes, follows, seen} = userActionSnapshot 137 const likeDids = likes 138 .map(l => new AtUri(l)) 139 .map(uri => uri.host) 140 .filter(did => !follows.includes(did)) 141 const seenDids = seen 142 .sort(sortSeenPosts) 143 .map(l => new AtUri(l.uri)) 144 .map(uri => uri.host) 145 - return [...new Set([...likeDids, ...seenDids])].filter( 146 did => did !== currentAccount?.did, 147 ) 148 }, [userActionSnapshot, currentAccount])
··· 133 const {currentAccount} = useSession() 134 const userActionSnapshot = userActionHistory.useActionHistorySnapshot() 135 const dids = React.useMemo(() => { 136 + const {likes, follows, followSuggestions, seen} = userActionSnapshot 137 const likeDids = likes 138 .map(l => new AtUri(l)) 139 .map(uri => uri.host) 140 .filter(did => !follows.includes(did)) 141 + let suggestedDids: string[] = [] 142 + if (followSuggestions.length > 0) { 143 + suggestedDids = [ 144 + // It's ok if these will pick the same item (weighed by its frequency) 145 + followSuggestions[Math.floor(Math.random() * followSuggestions.length)], 146 + followSuggestions[Math.floor(Math.random() * followSuggestions.length)], 147 + followSuggestions[Math.floor(Math.random() * followSuggestions.length)], 148 + followSuggestions[Math.floor(Math.random() * followSuggestions.length)], 149 + ] 150 + } 151 const seenDids = seen 152 .sort(sortSeenPosts) 153 .map(l => new AtUri(l.uri)) 154 .map(uri => uri.host) 155 + return [...new Set([...suggestedDids, ...likeDids, ...seenDids])].filter( 156 did => did !== currentAccount?.did, 157 ) 158 }, [userActionSnapshot, currentAccount])
+15
src/state/queries/profile.ts
··· 222 logContext: LogEvents['profile:follow']['logContext'] & 223 LogEvents['profile:unfollow']['logContext'], 224 ) { 225 const queryClient = useQueryClient() 226 const did = profile.did 227 const initialFollowingUri = profile.viewer?.following ··· 253 updateProfileShadow(queryClient, did, { 254 followingUri: finalFollowingUri, 255 }) 256 }, 257 }) 258
··· 222 logContext: LogEvents['profile:follow']['logContext'] & 223 LogEvents['profile:unfollow']['logContext'], 224 ) { 225 + const agent = useAgent() 226 const queryClient = useQueryClient() 227 const did = profile.did 228 const initialFollowingUri = profile.viewer?.following ··· 254 updateProfileShadow(queryClient, did, { 255 followingUri: finalFollowingUri, 256 }) 257 + 258 + if (finalFollowingUri) { 259 + agent.app.bsky.graph 260 + .getSuggestedFollowsByActor({ 261 + actor: did, 262 + }) 263 + .then(res => { 264 + const dids = res.data.suggestions 265 + .filter(a => !a.viewer?.following) 266 + .map(a => a.did) 267 + .slice(0, 8) 268 + userActionHistory.followSuggestion(dids) 269 + }) 270 + } 271 }, 272 }) 273
+13
src/state/userActionHistory.ts
··· 2 3 const LIKE_WINDOW = 100 4 const FOLLOW_WINDOW = 100 5 const SEEN_WINDOW = 100 6 7 export type SeenPost = { ··· 22 * The last 100 DIDs the user has followed 23 */ 24 follows: string[] 25 /** 26 * The last 100 post URIs the user has seen from the Discover feed only 27 */ ··· 31 const userActionHistory: UserActionHistory = { 32 likes: [], 33 follows: [], 34 seen: [], 35 } 36 ··· 58 .concat(dids) 59 .slice(-FOLLOW_WINDOW) 60 } 61 export function unfollow(dids: string[]) { 62 userActionHistory.follows = userActionHistory.follows.filter( 63 uri => !dids.includes(uri),
··· 2 3 const LIKE_WINDOW = 100 4 const FOLLOW_WINDOW = 100 5 + const FOLLOW_SUGGESTION_WINDOW = 100 6 const SEEN_WINDOW = 100 7 8 export type SeenPost = { ··· 23 * The last 100 DIDs the user has followed 24 */ 25 follows: string[] 26 + /* 27 + * The last 100 DIDs of suggested follows based on last follows 28 + */ 29 + followSuggestions: string[] 30 /** 31 * The last 100 post URIs the user has seen from the Discover feed only 32 */ ··· 36 const userActionHistory: UserActionHistory = { 37 likes: [], 38 follows: [], 39 + followSuggestions: [], 40 seen: [], 41 } 42 ··· 64 .concat(dids) 65 .slice(-FOLLOW_WINDOW) 66 } 67 + 68 + export function followSuggestion(dids: string[]) { 69 + userActionHistory.followSuggestions = userActionHistory.followSuggestions 70 + .concat(dids) 71 + .slice(-FOLLOW_SUGGESTION_WINDOW) 72 + } 73 + 74 export function unfollow(dids: string[]) { 75 userActionHistory.follows = userActionHistory.follows.filter( 76 uri => !dids.includes(uri),