Mirror of @tangled.org/core. Running on a Raspberry Pi Zero 2 (Please be gentle).
0
fork

Configure Feed

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

appview/notify: use sets to manage participant list

Signed-off-by: oppiliappan <me@oppi.li>

authored by

oppiliappan and committed by
Tangled
d2ecb7c2 b729a533

+67 -57
+67 -57
appview/notify/db/db.go
··· 3 3 import ( 4 4 "context" 5 5 "log" 6 - "maps" 7 6 "slices" 8 7 9 8 "github.com/bluesky-social/indigo/atproto/syntax" ··· 12 13 "tangled.org/core/appview/notify" 13 14 "tangled.org/core/idresolver" 14 15 "tangled.org/core/orm" 16 + "tangled.org/oppi.li/sets" 15 17 ) 16 18 17 19 const ( 18 - maxMentions = 5 20 + maxMentions = 8 19 21 ) 20 22 21 23 type databaseNotifier struct { ··· 50 50 } 51 51 52 52 actorDid := syntax.DID(star.Did) 53 - recipients := []syntax.DID{syntax.DID(repo.Did)} 53 + recipients := sets.Singleton(syntax.DID(repo.Did)) 54 54 eventType := models.NotificationTypeRepoStarred 55 55 entityType := "repo" 56 56 entityId := star.RepoAt.String() ··· 75 75 } 76 76 77 77 func (n *databaseNotifier) NewIssue(ctx context.Context, issue *models.Issue, mentions []syntax.DID) { 78 - 79 - // build the recipients list 80 - // - owner of the repo 81 - // - collaborators in the repo 82 - var recipients []syntax.DID 83 - recipients = append(recipients, syntax.DID(issue.Repo.Did)) 84 78 collaborators, err := db.GetCollaborators(n.db, orm.FilterEq("repo_at", issue.Repo.RepoAt())) 85 79 if err != nil { 86 80 log.Printf("failed to fetch collaborators: %v", err) 87 81 return 88 82 } 83 + 84 + // build the recipients list 85 + // - owner of the repo 86 + // - collaborators in the repo 87 + // - remove users already mentioned 88 + recipients := sets.Singleton(syntax.DID(issue.Repo.Did)) 89 89 for _, c := range collaborators { 90 - recipients = append(recipients, c.SubjectDid) 90 + recipients.Insert(c.SubjectDid) 91 + } 92 + for _, m := range mentions { 93 + recipients.Remove(m) 91 94 } 92 95 93 96 actorDid := syntax.DID(issue.Did) ··· 112 109 ) 113 110 n.notifyEvent( 114 111 actorDid, 115 - mentions, 112 + sets.Collect(slices.Values(mentions)), 116 113 models.NotificationTypeUserMentioned, 117 114 entityType, 118 115 entityId, ··· 134 131 } 135 132 issue := issues[0] 136 133 137 - var recipients []syntax.DID 138 - recipients = append(recipients, syntax.DID(issue.Repo.Did)) 134 + // built the recipients list: 135 + // - the owner of the repo 136 + // - | if the comment is a reply -> everybody on that thread 137 + // | if the comment is a top level -> just the issue owner 138 + // - remove mentioned users from the recipients list 139 + recipients := sets.Singleton(syntax.DID(issue.Repo.Did)) 139 140 140 141 if comment.IsReply() { 141 142 // if this comment is a reply, then notify everybody in that thread 142 143 parentAtUri := *comment.ReplyTo 143 - allThreads := issue.CommentList() 144 144 145 145 // find the parent thread, and add all DIDs from here to the recipient list 146 - for _, t := range allThreads { 146 + for _, t := range issue.CommentList() { 147 147 if t.Self.AtUri().String() == parentAtUri { 148 - recipients = append(recipients, t.Participants()...) 148 + for _, p := range t.Participants() { 149 + recipients.Insert(p) 150 + } 149 151 } 150 152 } 151 153 } else { 152 154 // not a reply, notify just the issue author 153 - recipients = append(recipients, syntax.DID(issue.Did)) 155 + recipients.Insert(syntax.DID(issue.Did)) 156 + } 157 + 158 + for _, m := range mentions { 159 + recipients.Remove(m) 154 160 } 155 161 156 162 actorDid := syntax.DID(comment.Did) ··· 181 169 ) 182 170 n.notifyEvent( 183 171 actorDid, 184 - mentions, 172 + sets.Collect(slices.Values(mentions)), 185 173 models.NotificationTypeUserMentioned, 186 174 entityType, 187 175 entityId, ··· 197 185 198 186 func (n *databaseNotifier) NewFollow(ctx context.Context, follow *models.Follow) { 199 187 actorDid := syntax.DID(follow.UserDid) 200 - recipients := []syntax.DID{syntax.DID(follow.SubjectDid)} 188 + recipients := sets.Singleton(syntax.DID(follow.SubjectDid)) 201 189 eventType := models.NotificationTypeFollowed 202 190 entityType := "follow" 203 191 entityId := follow.UserDid ··· 225 213 log.Printf("NewPull: failed to get repos: %v", err) 226 214 return 227 215 } 228 - 229 - // build the recipients list 230 - // - owner of the repo 231 - // - collaborators in the repo 232 - var recipients []syntax.DID 233 - recipients = append(recipients, syntax.DID(repo.Did)) 234 216 collaborators, err := db.GetCollaborators(n.db, orm.FilterEq("repo_at", repo.RepoAt())) 235 217 if err != nil { 236 218 log.Printf("failed to fetch collaborators: %v", err) 237 219 return 238 220 } 221 + 222 + // build the recipients list 223 + // - owner of the repo 224 + // - collaborators in the repo 225 + recipients := sets.Singleton(syntax.DID(repo.Did)) 239 226 for _, c := range collaborators { 240 - recipients = append(recipients, c.SubjectDid) 227 + recipients.Insert(c.SubjectDid) 241 228 } 242 229 243 230 actorDid := syntax.DID(pull.OwnerDid) ··· 279 268 // build up the recipients list: 280 269 // - repo owner 281 270 // - all pull participants 282 - var recipients []syntax.DID 283 - recipients = append(recipients, syntax.DID(repo.Did)) 271 + // - remove those already mentioned 272 + recipients := sets.Singleton(syntax.DID(repo.Did)) 284 273 for _, p := range pull.Participants() { 285 - recipients = append(recipients, syntax.DID(p)) 274 + recipients.Insert(syntax.DID(p)) 275 + } 276 + for _, m := range mentions { 277 + recipients.Remove(m) 286 278 } 287 279 288 280 actorDid := syntax.DID(comment.OwnerDid) ··· 309 295 ) 310 296 n.notifyEvent( 311 297 actorDid, 312 - mentions, 298 + sets.Collect(slices.Values(mentions)), 313 299 models.NotificationTypeUserMentioned, 314 300 entityType, 315 301 entityId, ··· 336 322 } 337 323 338 324 func (n *databaseNotifier) NewIssueState(ctx context.Context, actor syntax.DID, issue *models.Issue) { 339 - // build up the recipients list: 340 - // - repo owner 341 - // - repo collaborators 342 - // - all issue participants 343 - var recipients []syntax.DID 344 - recipients = append(recipients, syntax.DID(issue.Repo.Did)) 345 325 collaborators, err := db.GetCollaborators(n.db, orm.FilterEq("repo_at", issue.Repo.RepoAt())) 346 326 if err != nil { 347 327 log.Printf("failed to fetch collaborators: %v", err) 348 328 return 349 329 } 330 + 331 + // build up the recipients list: 332 + // - repo owner 333 + // - repo collaborators 334 + // - all issue participants 335 + recipients := sets.Singleton(syntax.DID(issue.Repo.Did)) 350 336 for _, c := range collaborators { 351 - recipients = append(recipients, c.SubjectDid) 337 + recipients.Insert(c.SubjectDid) 352 338 } 353 339 for _, p := range issue.Participants() { 354 - recipients = append(recipients, syntax.DID(p)) 340 + recipients.Insert(syntax.DID(p)) 355 341 } 356 342 357 343 entityType := "pull" ··· 387 373 return 388 374 } 389 375 390 - // build up the recipients list: 391 - // - repo owner 392 - // - all pull participants 393 - var recipients []syntax.DID 394 - recipients = append(recipients, syntax.DID(repo.Did)) 395 376 collaborators, err := db.GetCollaborators(n.db, orm.FilterEq("repo_at", repo.RepoAt())) 396 377 if err != nil { 397 378 log.Printf("failed to fetch collaborators: %v", err) 398 379 return 399 380 } 381 + 382 + // build up the recipients list: 383 + // - repo owner 384 + // - all pull participants 385 + recipients := sets.Singleton(syntax.DID(repo.Did)) 400 386 for _, c := range collaborators { 401 - recipients = append(recipients, c.SubjectDid) 387 + recipients.Insert(c.SubjectDid) 402 388 } 403 389 for _, p := range pull.Participants() { 404 - recipients = append(recipients, syntax.DID(p)) 390 + recipients.Insert(syntax.DID(p)) 405 391 } 406 392 407 393 entityType := "pull" ··· 437 423 438 424 func (n *databaseNotifier) notifyEvent( 439 425 actorDid syntax.DID, 440 - recipients []syntax.DID, 426 + recipients sets.Set[syntax.DID], 441 427 eventType models.NotificationType, 442 428 entityType string, 443 429 entityId string, ··· 445 431 issueId *int64, 446 432 pullId *int64, 447 433 ) { 448 - if eventType == models.NotificationTypeUserMentioned && len(recipients) > maxMentions { 449 - recipients = recipients[:maxMentions] 434 + // if the user is attempting to mention >maxMentions users, this is probably spam, do not mention anybody 435 + if eventType == models.NotificationTypeUserMentioned && recipients.Len() > maxMentions { 436 + return 450 437 } 451 - recipientSet := make(map[syntax.DID]struct{}) 452 - for _, did := range recipients { 453 - // everybody except actor themselves 454 - if did != actorDid { 455 - recipientSet[did] = struct{}{} 456 - } 457 - } 438 + 439 + recipients.Remove(actorDid) 458 440 459 441 prefMap, err := db.GetNotificationPreferences( 460 442 n.db, 461 - orm.FilterIn("user_did", slices.Collect(maps.Keys(recipientSet))), 443 + orm.FilterIn("user_did", slices.Collect(recipients.All())), 462 444 ) 463 445 if err != nil { 464 446 // failed to get prefs for users ··· 470 460 defer tx.Rollback() 471 461 472 462 // filter based on preferences 473 - for recipientDid := range recipientSet { 463 + for recipientDid := range recipients.All() { 474 464 prefs, ok := prefMap[recipientDid] 475 465 if !ok { 476 466 prefs = models.DefaultNotificationPreferences(recipientDid)