A community based topic aggregation platform built on atproto
at main 2.0 kB view raw
1package common 2 3import ( 4 "Coves/internal/api/middleware" 5 "Coves/internal/core/posts" 6 "Coves/internal/core/votes" 7 "context" 8 "log" 9 "net/http" 10) 11 12// FeedPostProvider is implemented by any feed post wrapper that contains a PostView. 13// This allows the helper to work with different feed post types (discover, timeline, communityFeed). 14type FeedPostProvider interface { 15 GetPost() *posts.PostView 16} 17 18// PopulateViewerVoteState enriches feed posts with the authenticated user's vote state. 19// This is a no-op if voteService is nil or the request is unauthenticated. 20// 21// Parameters: 22// - ctx: Request context for PDS calls 23// - r: HTTP request (used to extract OAuth session) 24// - voteService: Vote service for cache lookup (may be nil) 25// - feedPosts: Posts to enrich with viewer state (must implement FeedPostProvider) 26// 27// The function logs but does not fail on errors - viewer state is optional enrichment. 28func PopulateViewerVoteState[T FeedPostProvider]( 29 ctx context.Context, 30 r *http.Request, 31 voteService votes.Service, 32 feedPosts []T, 33) { 34 if voteService == nil { 35 return 36 } 37 38 session := middleware.GetOAuthSession(r) 39 if session == nil { 40 return 41 } 42 43 userDID := middleware.GetUserDID(r) 44 45 // Ensure vote cache is populated from PDS 46 if err := voteService.EnsureCachePopulated(ctx, session); err != nil { 47 log.Printf("Warning: failed to populate vote cache: %v", err) 48 return 49 } 50 51 // Collect post URIs to batch lookup 52 postURIs := make([]string, 0, len(feedPosts)) 53 for _, feedPost := range feedPosts { 54 if post := feedPost.GetPost(); post != nil { 55 postURIs = append(postURIs, post.URI) 56 } 57 } 58 59 // Get viewer votes for all posts 60 viewerVotes := voteService.GetViewerVotesForSubjects(userDID, postURIs) 61 62 // Populate viewer state on each post 63 for _, feedPost := range feedPosts { 64 if post := feedPost.GetPost(); post != nil { 65 if vote, exists := viewerVotes[post.URI]; exists { 66 post.Viewer = &posts.ViewerState{ 67 Vote: &vote.Direction, 68 VoteURI: &vote.URI, 69 } 70 } 71 } 72 } 73}