This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

core / appview / state / timeline.go
3.8 kB 136 lines
1package state 2 3import ( 4 "net/http" 5 6 "github.com/bluesky-social/indigo/atproto/syntax" 7 "tangled.org/core/appview/db" 8 "tangled.org/core/appview/models" 9 "tangled.org/core/appview/oauth" 10 "tangled.org/core/appview/pages" 11 "tangled.org/core/appview/pagination" 12 "tangled.org/core/orm" 13) 14 15func (s *State) Home(w http.ResponseWriter, r *http.Request) { 16 // TODO: set this flag based on the UI 17 filtered := false 18 19 user := s.oauth.GetMultiAccountUser(r) 20 21 timeline, err := db.MakeTimeline(s.db, 50, "", filtered) 22 if err != nil { 23 s.logger.Error("failed to make timeline", "err", err) 24 s.pages.Notice(w, "timeline", "Uh oh! Failed to load timeline.") 25 return 26 } 27 28 blueskyPosts, err := db.GetBlueskyPosts(s.db, 8) 29 if err != nil { 30 s.logger.Error("failed to get bluesky posts", "err", err) 31 } 32 33 s.pages.Home(w, pages.TimelineParams{ 34 LoggedInUser: user, 35 Timeline: timeline, 36 BlueskyPosts: blueskyPosts, 37 ShowNewsletter: s.showNewsletter(user), 38 }) 39} 40func (s *State) HomeOrTimeline(w http.ResponseWriter, r *http.Request) { 41 if s.oauth.GetMultiAccountUser(r) != nil { 42 s.Timeline(w, r) 43 return 44 } 45 s.Home(w, r) 46} 47 48func (s *State) Timeline(w http.ResponseWriter, r *http.Request) { 49 user := s.oauth.GetMultiAccountUser(r) 50 51 // TODO: set this flag based on the UI 52 filtered := false 53 54 var userDid string 55 if user != nil { 56 userDid = user.Did 57 } 58 timeline, err := db.MakeTimeline(s.db, 50, userDid, filtered) 59 if err != nil { 60 s.logger.Error("failed to make timeline", "err", err) 61 s.pages.Notice(w, "timeline", "Uh oh! Failed to load timeline.") 62 } 63 64 repos, err := db.GetTopStarredReposLastWeek(s.db) 65 if err != nil { 66 s.logger.Error("failed to get top starred repos", "err", err) 67 s.pages.Notice(w, "topstarredrepos", "Unable to load.") 68 return 69 } 70 71 gfiLabel, err := db.GetLabelDefinition(s.db, orm.FilterEq("at_uri", s.config.Label.GoodFirstIssue)) 72 if err != nil { 73 // non-fatal 74 } 75 76 var notifications []*models.NotificationWithEntity 77 if user != nil { 78 notifications, err = db.GetNotificationsWithEntities( 79 s.db, 80 pagination.Page{Limit: 5, Offset: 0}, 81 orm.FilterEq("recipient_did", user.Did), 82 orm.FilterEq("read", 0), 83 ) 84 if err != nil { 85 s.logger.Error("failed to get notifications for timeline", "err", err) 86 } 87 } 88 89 var vouchSuggestions []models.VouchSuggestion 90 if user != nil { 91 vouchSuggestions, err = db.GetVouchSuggestions(s.db, user.Did, 3) 92 if err != nil { 93 s.logger.Error("failed to get vouch suggestions", "err", err) 94 } 95 if len(vouchSuggestions) > 0 { 96 suggestionDids := make([]syntax.DID, len(vouchSuggestions)) 97 for i, sv := range vouchSuggestions { 98 suggestionDids[i] = syntax.DID(sv.Did) 99 } 100 relationships, err := db.GetVouchRelationshipsBatch(s.db, syntax.DID(user.Did), suggestionDids) 101 if err != nil { 102 s.logger.Error("failed to get vouch relationships for suggestions", "err", err) 103 } else { 104 for i := range vouchSuggestions { 105 vouchSuggestions[i].VouchRelationship = relationships[vouchSuggestions[i].Did] 106 } 107 } 108 } 109 } 110 111 s.pages.Timeline(w, pages.TimelineParams{ 112 LoggedInUser: user, 113 Timeline: timeline, 114 Repos: repos, 115 GfiLabel: gfiLabel, 116 VouchSuggestions: vouchSuggestions, 117 Notifications: notifications, 118 ShowNewsletter: s.showNewsletter(user), 119 }) 120} 121 122// showNewsletter decides whether the newsletter widget/CTA should render. 123// Anonymous visitors always see it (they can dismiss via localStorage); 124// logged-in users whose newsletter_preferences row exists (either 125// subscribed or dismissed) do not. 126func (s *State) showNewsletter(user *oauth.MultiAccountUser) bool { 127 if user == nil { 128 return true 129 } 130 pref, err := db.GetNewsletterPref(s.db, user.Did) 131 if err != nil { 132 s.logger.Error("failed to read newsletter preference", "did", user.Did, "err", err) 133 return true 134 } 135 return pref == nil 136}