This repository has no description
0

Configure Feed

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

core / appview / models / notifications.go
6.7 kB 228 lines
1package models 2 3import ( 4 "context" 5 "fmt" 6 "time" 7 8 "github.com/bluesky-social/indigo/atproto/syntax" 9 "tangled.org/core/idresolver" 10) 11 12type NotificationType string 13 14const ( 15 NotificationTypeRepoStarred NotificationType = "repo_starred" 16 NotificationTypeIssueCreated NotificationType = "issue_created" 17 NotificationTypeIssueCommented NotificationType = "issue_commented" 18 NotificationTypePullCreated NotificationType = "pull_created" 19 NotificationTypePullCommented NotificationType = "pull_commented" 20 NotificationTypeFollowed NotificationType = "followed" 21 NotificationTypePullMerged NotificationType = "pull_merged" 22 NotificationTypeIssueClosed NotificationType = "issue_closed" 23 NotificationTypeIssueReopen NotificationType = "issue_reopen" 24 NotificationTypePullClosed NotificationType = "pull_closed" 25 NotificationTypePullReopen NotificationType = "pull_reopen" 26 NotificationTypeUserMentioned NotificationType = "user_mentioned" 27 NotificationTypeIssueAssigned NotificationType = "issue_assigned" 28 NotificationTypeIssueUnassigned NotificationType = "issue_unassigned" 29 NotificationTypePullAssigned NotificationType = "pull_assigned" 30 NotificationTypePullUnassigned NotificationType = "pull_unassigned" 31) 32 33var SocialNotificationTypes = []NotificationType{ 34 NotificationTypeRepoStarred, 35 NotificationTypeFollowed, 36} 37 38var WorkNotificationTypes = []NotificationType{ 39 NotificationTypeIssueCreated, 40 NotificationTypeIssueCommented, 41 NotificationTypeIssueClosed, 42 NotificationTypeIssueReopen, 43 NotificationTypePullCreated, 44 NotificationTypePullCommented, 45 NotificationTypePullMerged, 46 NotificationTypePullClosed, 47 NotificationTypePullReopen, 48 NotificationTypeUserMentioned, 49 NotificationTypeIssueAssigned, 50 NotificationTypeIssueUnassigned, 51 NotificationTypePullAssigned, 52 NotificationTypePullUnassigned, 53} 54 55type Notification struct { 56 ID int64 57 RecipientDid string 58 ActorDid string 59 Type NotificationType 60 EntityType string 61 EntityId string 62 Read bool 63 Emailed bool 64 Created time.Time 65 66 // foreign key references 67 RepoId *int64 68 IssueId *int64 69 PullId *int64 70} 71 72// EmailNotificationTypes are the notification types that are included in email digests. 73// Social types (repo_starred, followed) are intentionally excluded. 74var EmailNotificationTypes = []NotificationType{ 75 NotificationTypeIssueCreated, 76 NotificationTypeIssueCommented, 77 NotificationTypeIssueClosed, 78 NotificationTypeIssueReopen, 79 NotificationTypePullCreated, 80 NotificationTypePullCommented, 81 NotificationTypePullMerged, 82 NotificationTypePullClosed, 83 NotificationTypePullReopen, 84 NotificationTypeUserMentioned, 85 NotificationTypeIssueAssigned, 86 NotificationTypeIssueUnassigned, 87 NotificationTypePullAssigned, 88 NotificationTypePullUnassigned, 89} 90 91// lucide icon that represents this notification 92func (n *Notification) Icon() string { 93 switch n.Type { 94 case NotificationTypeRepoStarred: 95 return "star" 96 case NotificationTypeIssueCreated: 97 return "circle-dot" 98 case NotificationTypeIssueCommented: 99 return "message-square" 100 case NotificationTypeIssueClosed: 101 return "ban" 102 case NotificationTypeIssueReopen: 103 return "circle-dot" 104 case NotificationTypePullCreated: 105 return "git-pull-request-create" 106 case NotificationTypePullCommented: 107 return "message-square" 108 case NotificationTypePullMerged: 109 return "git-merge" 110 case NotificationTypePullClosed: 111 return "git-pull-request-closed" 112 case NotificationTypePullReopen: 113 return "git-pull-request-create" 114 case NotificationTypeFollowed: 115 return "user-plus" 116 case NotificationTypeUserMentioned: 117 return "at-sign" 118 case NotificationTypeIssueAssigned, NotificationTypePullAssigned: 119 return "user-round-arrow-forward" 120 case NotificationTypeIssueUnassigned, NotificationTypePullUnassigned: 121 return "user-round-minus" 122 default: 123 return "" 124 } 125} 126 127type NotificationWithEntity struct { 128 *Notification 129 Repo *Repo 130 Issue *Issue 131 Pull *Pull 132} 133 134// URL returns the navigable path for the notification, resolving DIDs to 135// handles via the provided resolver. 136func (n *NotificationWithEntity) URL(res *idresolver.Resolver) string { 137 resolve := func(did string) string { 138 if id, err := res.ResolveIdent(context.Background(), did); err == nil && !id.Handle.IsInvalidHandle() { 139 return id.Handle.String() 140 } 141 return did 142 } 143 144 switch n.Type { 145 case NotificationTypeFollowed: 146 return "/" + resolve(n.ActorDid) 147 } 148 if n.Repo == nil { 149 return "" 150 } 151 repoHandle := resolve(n.Repo.Did) 152 slug := n.Repo.Slug() 153 switch { 154 case n.Issue != nil: 155 return fmt.Sprintf("/%s/%s/issues/%d", repoHandle, slug, n.Issue.IssueId) 156 case n.Pull != nil: 157 return fmt.Sprintf("/%s/%s/pulls/%d", repoHandle, slug, n.Pull.PullId) 158 default: 159 // repo_starred and other repo-level types 160 return fmt.Sprintf("/%s/%s", repoHandle, slug) 161 } 162} 163 164type NotificationPreferences struct { 165 ID int64 166 UserDid syntax.DID 167 RepoStarred bool 168 IssueCreated bool 169 IssueCommented bool 170 PullCreated bool 171 PullCommented bool 172 Followed bool 173 UserMentioned bool 174 PullMerged bool 175 IssueClosed bool 176 EmailNotifications bool 177} 178 179func (prefs *NotificationPreferences) ShouldNotify(t NotificationType) bool { 180 switch t { 181 case NotificationTypeRepoStarred: 182 return prefs.RepoStarred 183 case NotificationTypeIssueCreated: 184 return prefs.IssueCreated 185 case NotificationTypeIssueCommented: 186 return prefs.IssueCommented 187 case NotificationTypeIssueClosed: 188 return prefs.IssueClosed 189 case NotificationTypeIssueReopen: 190 return prefs.IssueCreated // same pref for now 191 case NotificationTypePullCreated: 192 return prefs.PullCreated 193 case NotificationTypePullCommented: 194 return prefs.PullCommented 195 case NotificationTypePullMerged: 196 return prefs.PullMerged 197 case NotificationTypePullClosed: 198 return prefs.PullMerged // same pref for now 199 case NotificationTypePullReopen: 200 return prefs.PullCreated // same pref for now 201 case NotificationTypeFollowed: 202 return prefs.Followed 203 case NotificationTypeUserMentioned, 204 NotificationTypeIssueAssigned, 205 NotificationTypeIssueUnassigned, 206 NotificationTypePullAssigned, 207 NotificationTypePullUnassigned: 208 return prefs.UserMentioned 209 default: 210 return false 211 } 212} 213 214func DefaultNotificationPreferences(user syntax.DID) *NotificationPreferences { 215 return &NotificationPreferences{ 216 UserDid: user, 217 RepoStarred: true, 218 IssueCreated: true, 219 IssueCommented: true, 220 PullCreated: true, 221 PullCommented: true, 222 Followed: true, 223 UserMentioned: true, 224 PullMerged: true, 225 IssueClosed: true, 226 EmailNotifications: false, 227 } 228}