github.com/status-im/status-go@v1.1.0/protocol/messenger_activity_center.go (about) 1 package protocol 2 3 import ( 4 "context" 5 6 "github.com/golang/protobuf/proto" 7 "github.com/pkg/errors" 8 "go.uber.org/zap" 9 10 v1protocol "github.com/status-im/status-go/protocol/v1" 11 12 "github.com/status-im/status-go/eth-node/types" 13 "github.com/status-im/status-go/protocol/common" 14 "github.com/status-im/status-go/protocol/protobuf" 15 "github.com/status-im/status-go/protocol/requests" 16 ) 17 18 var errOnlyOneNotificationID = errors.New("only one notification id is supported") 19 20 func toHexBytes(b [][]byte) []types.HexBytes { 21 hb := make([]types.HexBytes, len(b)) 22 23 for i, v := range b { 24 hb[i] = types.HexBytes(v) 25 } 26 27 return hb 28 } 29 30 func fromHexBytes(hb []types.HexBytes) [][]byte { 31 b := make([][]byte, len(hb)) 32 33 for i, v := range hb { 34 b[i] = v 35 } 36 37 return b 38 } 39 40 func (m *Messenger) ActivityCenterNotifications(request ActivityCenterNotificationsRequest) (*ActivityCenterPaginationResponse, error) { 41 cursor, notifications, err := m.persistence.ActivityCenterNotifications(request.Cursor, request.Limit, request.ActivityTypes, request.ReadType, true) 42 if err != nil { 43 return nil, err 44 } 45 46 if m.httpServer != nil { 47 for _, notification := range notifications { 48 if notification.Message != nil { 49 err = m.prepareMessage(notification.Message, m.httpServer) 50 51 if err != nil { 52 return nil, err 53 } 54 55 image := notification.Message.GetImage() 56 if image != nil && image.AlbumId != "" { 57 album, err := m.persistence.albumMessages(notification.Message.LocalChatID, image.AlbumId) 58 if err != nil { 59 return nil, err 60 } 61 notification.AlbumMessages = album 62 } 63 } 64 if notification.AlbumMessages != nil { 65 for _, message := range notification.AlbumMessages { 66 err = m.prepareMessage(message, m.httpServer) 67 68 if err != nil { 69 return nil, err 70 } 71 } 72 } 73 if notification.TokenData != nil { 74 if notification.Type == ActivityCenterNotificationTypeCommunityTokenReceived || notification.Type == ActivityCenterNotificationTypeFirstCommunityTokenReceived { 75 err = m.prepareTokenData(notification.TokenData, m.httpServer) 76 if err != nil { 77 return nil, err 78 } 79 } 80 } 81 } 82 } 83 84 return &ActivityCenterPaginationResponse{ 85 Cursor: cursor, 86 Notifications: notifications, 87 }, nil 88 } 89 90 func (m *Messenger) ActivityCenterNotificationsCount(request ActivityCenterCountRequest) (*ActivityCenterCountResponse, error) { 91 response := make(ActivityCenterCountResponse) 92 93 for _, activityType := range request.ActivityTypes { 94 count, err := m.persistence.ActivityCenterNotificationsCount([]ActivityCenterType{activityType}, request.ReadType, true) 95 if err != nil { 96 return nil, err 97 } 98 99 response[activityType] = count 100 } 101 102 return &response, nil 103 } 104 105 func (m *Messenger) HasUnseenActivityCenterNotifications() (bool, error) { 106 seen, _, err := m.persistence.HasUnseenActivityCenterNotifications() 107 return seen, err 108 } 109 110 func (m *Messenger) GetActivityCenterState() (*ActivityCenterState, error) { 111 return m.persistence.GetActivityCenterState() 112 } 113 114 func (m *Messenger) MarkAsSeenActivityCenterNotifications() (*MessengerResponse, error) { 115 response := &MessengerResponse{} 116 s := &ActivityCenterState{ 117 UpdatedAt: m.GetCurrentTimeInMillis(), 118 HasSeen: true, 119 } 120 _, err := m.persistence.UpdateActivityCenterNotificationState(s) 121 if err != nil { 122 return nil, err 123 } 124 125 state, err := m.persistence.GetActivityCenterState() 126 if err != nil { 127 return nil, err 128 } 129 130 response.SetActivityCenterState(state) 131 return response, nil 132 } 133 134 func (m *Messenger) MarkAllActivityCenterNotificationsRead(ctx context.Context) (*MessengerResponse, error) { 135 ids, err := m.persistence.GetNotReadActivityCenterNotificationIds() 136 if err != nil { 137 return nil, err 138 } 139 140 updateAt := m.GetCurrentTimeInMillis() 141 return m.MarkActivityCenterNotificationsRead(ctx, toHexBytes(ids), updateAt, true) 142 } 143 144 func (m *Messenger) MarkActivityCenterNotificationsRead(ctx context.Context, ids []types.HexBytes, updatedAt uint64, sync bool) (*MessengerResponse, error) { 145 // Mark notifications as read in the database 146 if updatedAt == 0 { 147 updatedAt = m.GetCurrentTimeInMillis() 148 } 149 err := m.persistence.MarkActivityCenterNotificationsRead(ids, updatedAt) 150 if err != nil { 151 return nil, err 152 } 153 154 notifications, err := m.persistence.GetActivityCenterNotificationsByID(ids) 155 if err != nil { 156 return nil, err 157 } 158 159 response := &MessengerResponse{} 160 repliesAndMentions := make(map[string][]string) 161 162 // When marking as read Mention or Reply notification, the corresponding chat message should also be seen. 163 for _, notification := range notifications { 164 response.AddActivityCenterNotification(notification) 165 166 if notification.Message != nil && 167 (notification.Type == ActivityCenterNotificationTypeMention || notification.Type == ActivityCenterNotificationTypeReply) { 168 repliesAndMentions[notification.ChatID] = append(repliesAndMentions[notification.ChatID], notification.Message.ID) 169 } 170 } 171 172 // Mark messages as seen 173 for chatID, messageIDs := range repliesAndMentions { 174 count, countWithMentions, chat, err := m.markMessagesSeenImpl(chatID, messageIDs) 175 if err != nil { 176 return nil, err 177 } 178 response.AddChat(chat) 179 response.AddSeenAndUnseenMessages(&SeenUnseenMessages{ 180 ChatID: chatID, 181 Count: count, 182 CountWithMentions: countWithMentions, 183 Seen: true, 184 }) 185 } 186 187 state, err := m.persistence.GetActivityCenterState() 188 if err != nil { 189 return nil, err 190 } 191 192 response.SetActivityCenterState(state) 193 194 if !sync { 195 response2, err := m.processActivityCenterNotifications(notifications, true) 196 if err != nil { 197 return nil, err 198 } 199 if err = response2.Merge(response); err != nil { 200 return nil, err 201 } 202 return response2, nil 203 } 204 return response, m.syncActivityCenterReadByIDs(ctx, ids, updatedAt) 205 } 206 207 func (m *Messenger) MarkActivityCenterNotificationsUnread(ctx context.Context, ids []types.HexBytes, updatedAt uint64, sync bool) (*MessengerResponse, error) { 208 notifications, err := m.persistence.MarkActivityCenterNotificationsUnread(ids, updatedAt) 209 if err != nil { 210 return nil, err 211 } 212 213 response := &MessengerResponse{} 214 response.AddActivityCenterNotifications(notifications) 215 216 // Don't mark messages unseen in chat, that looks weird 217 218 state, err := m.persistence.GetActivityCenterState() 219 if err != nil { 220 return nil, err 221 } 222 response.SetActivityCenterState(state) 223 224 if sync && len(notifications) > 0 { 225 err = m.syncActivityCenterUnreadByIDs(ctx, ids, updatedAt) 226 } 227 return response, err 228 } 229 230 func (m *Messenger) MarkActivityCenterNotificationsDeleted(ctx context.Context, ids []types.HexBytes, updatedAt uint64, sync bool) (*MessengerResponse, error) { 231 response := &MessengerResponse{} 232 notifications, err := m.persistence.MarkActivityCenterNotificationsDeleted(ids, updatedAt) 233 if err != nil { 234 return nil, err 235 } 236 response.AddActivityCenterNotifications(notifications) 237 state, err := m.persistence.GetActivityCenterState() 238 if err != nil { 239 return nil, err 240 } 241 response.SetActivityCenterState(state) 242 if sync { 243 err = m.syncActivityCenterDeletedByIDs(ctx, ids, updatedAt) 244 if err != nil { 245 m.logger.Error("MarkActivityCenterNotificationsDeleted, failed to sync activity center notifications as deleted", zap.Error(err)) 246 return nil, err 247 } 248 } 249 return response, nil 250 } 251 252 func (m *Messenger) addActivityCenterNotification(response *MessengerResponse, notification *ActivityCenterNotification, syncAction func(context.Context, []types.HexBytes, uint64) error) error { 253 _, err := m.persistence.SaveActivityCenterNotification(notification, true) 254 if err != nil { 255 m.logger.Error("failed to save notification", zap.Error(err)) 256 return err 257 } 258 259 state, err := m.persistence.GetActivityCenterState() 260 if err != nil { 261 m.logger.Error("failed to obtain activity center state", zap.Error(err)) 262 return err 263 } 264 response.AddActivityCenterNotification(notification) 265 response.SetActivityCenterState(state) 266 267 if syncAction != nil { 268 //TODO a way to pass context 269 err = syncAction(context.TODO(), []types.HexBytes{notification.ID}, notification.UpdatedAt) 270 if err != nil { 271 m.logger.Error("[addActivityCenterNotification] failed to sync activity center notification", zap.Error(err)) 272 return err 273 } 274 } 275 return nil 276 } 277 278 func (m *Messenger) syncActivityCenterReadByIDs(ctx context.Context, ids []types.HexBytes, clock uint64) error { 279 syncMessage := &protobuf.SyncActivityCenterRead{ 280 Clock: clock, 281 Ids: fromHexBytes(ids), 282 } 283 284 encodedMessage, err := proto.Marshal(syncMessage) 285 if err != nil { 286 return err 287 } 288 289 return m.sendToPairedDevices(ctx, common.RawMessage{ 290 Payload: encodedMessage, 291 MessageType: protobuf.ApplicationMetadataMessage_SYNC_ACTIVITY_CENTER_READ, 292 ResendType: common.ResendTypeDataSync, 293 }) 294 } 295 296 func (m *Messenger) syncActivityCenterUnreadByIDs(ctx context.Context, ids []types.HexBytes, clock uint64) error { 297 syncMessage := &protobuf.SyncActivityCenterUnread{ 298 Clock: clock, 299 Ids: fromHexBytes(ids), 300 } 301 302 encodedMessage, err := proto.Marshal(syncMessage) 303 if err != nil { 304 return err 305 } 306 307 return m.sendToPairedDevices(ctx, common.RawMessage{ 308 Payload: encodedMessage, 309 MessageType: protobuf.ApplicationMetadataMessage_SYNC_ACTIVITY_CENTER_UNREAD, 310 ResendType: common.ResendTypeDataSync, 311 }) 312 } 313 314 func (m *Messenger) processActivityCenterNotifications(notifications []*ActivityCenterNotification, addNotifications bool) (*MessengerResponse, error) { 315 response := &MessengerResponse{} 316 var chats []*Chat 317 for _, notification := range notifications { 318 if notification.ChatID != "" { 319 chat, ok := m.allChats.Load(notification.ChatID) 320 if !ok { 321 // This should not really happen, but ignore just in case it was deleted in the meantime 322 m.logger.Warn("chat not found") 323 continue 324 } 325 chat.Active = true 326 327 if chat.PrivateGroupChat() { 328 // Send Joined message for backward compatibility 329 _, err := m.ConfirmJoiningGroup(context.Background(), chat.ID) 330 if err != nil { 331 m.logger.Error("failed to join group", zap.Error(err)) 332 return nil, err 333 } 334 } 335 336 chats = append(chats, chat) 337 response.AddChat(chat) 338 } 339 340 if addNotifications { 341 response.AddActivityCenterNotification(notification) 342 } 343 } 344 if len(chats) != 0 { 345 err := m.saveChats(chats) 346 if err != nil { 347 return nil, err 348 } 349 } 350 return response, nil 351 } 352 353 func (m *Messenger) processAcceptedActivityCenterNotifications(ctx context.Context, notifications []*ActivityCenterNotification, sync bool) (*MessengerResponse, error) { 354 ids := make([]types.HexBytes, len(notifications)) 355 356 for i := range notifications { 357 ids[i] = notifications[i].ID 358 } 359 360 state, err := m.persistence.GetActivityCenterState() 361 if err != nil { 362 return nil, err 363 } 364 365 if sync { 366 err = m.syncActivityCenterAcceptedByIDs(ctx, ids, m.GetCurrentTimeInMillis()) 367 if err != nil { 368 return nil, err 369 } 370 } 371 372 response, err := m.processActivityCenterNotifications(notifications, !sync) 373 if err != nil { 374 return nil, err 375 } 376 response.SetActivityCenterState(state) 377 return response, nil 378 } 379 380 func (m *Messenger) AcceptActivityCenterNotificationsForInvitesFromUser(ctx context.Context, userPublicKey string, updatedAt uint64) ([]*ActivityCenterNotification, error) { 381 notifications, err := m.persistence.AcceptActivityCenterNotificationsForInvitesFromUser(userPublicKey, updatedAt) 382 if err != nil { 383 return nil, err 384 } 385 if len(notifications) > 0 { 386 err = m.syncActivityCenterAccepted(ctx, notifications, updatedAt) 387 } 388 return notifications, err 389 } 390 391 func (m *Messenger) syncActivityCenterAccepted(ctx context.Context, notifications []*ActivityCenterNotification, updatedAt uint64) error { 392 ids := make([]types.HexBytes, len(notifications)) 393 for _, notification := range notifications { 394 ids = append(ids, notification.ID) 395 } 396 return m.syncActivityCenterAcceptedByIDs(ctx, ids, updatedAt) 397 } 398 399 func (m *Messenger) syncActivityCenterAcceptedByIDs(ctx context.Context, ids []types.HexBytes, clock uint64) error { 400 syncMessage := &protobuf.SyncActivityCenterAccepted{ 401 Clock: clock, 402 Ids: fromHexBytes(ids), 403 } 404 405 encodedMessage, err := proto.Marshal(syncMessage) 406 if err != nil { 407 return err 408 } 409 410 return m.sendToPairedDevices(ctx, common.RawMessage{ 411 Payload: encodedMessage, 412 MessageType: protobuf.ApplicationMetadataMessage_SYNC_ACTIVITY_CENTER_ACCEPTED, 413 ResendType: common.ResendTypeDataSync, 414 }) 415 } 416 417 func (m *Messenger) syncActivityCenterCommunityRequestDecisionAdapter(ctx context.Context, ids []types.HexBytes, _ uint64) error { 418 if len(ids) != 1 { 419 return errOnlyOneNotificationID 420 } 421 id := ids[0] 422 notification, err := m.persistence.GetActivityCenterNotificationByID(id) 423 if err != nil { 424 return err 425 } 426 427 return m.syncActivityCenterCommunityRequestDecision(ctx, notification) 428 } 429 430 func (m *Messenger) syncActivityCenterCommunityRequestDecision(ctx context.Context, notification *ActivityCenterNotification) error { 431 var decision protobuf.SyncActivityCenterCommunityRequestDecisionCommunityRequestDecision 432 if notification.Accepted { 433 decision = protobuf.SyncActivityCenterCommunityRequestDecision_ACCEPTED 434 } else if notification.Dismissed { 435 decision = protobuf.SyncActivityCenterCommunityRequestDecision_DECLINED 436 } else { 437 return errors.New("[syncActivityCenterCommunityRequestDecision] notification is not accepted or dismissed") 438 } 439 440 syncMessage := &protobuf.SyncActivityCenterCommunityRequestDecision{ 441 Clock: notification.UpdatedAt, 442 Id: notification.ID, 443 MembershipStatus: uint32(notification.MembershipStatus), 444 Decision: decision, 445 } 446 447 encodedMessage, err := proto.Marshal(syncMessage) 448 if err != nil { 449 return err 450 } 451 452 return m.sendToPairedDevices(ctx, common.RawMessage{ 453 Payload: encodedMessage, 454 MessageType: protobuf.ApplicationMetadataMessage_SYNC_ACTIVITY_CENTER_COMMUNITY_REQUEST_DECISION, 455 ResendType: common.ResendTypeDataSync, 456 }) 457 } 458 459 func (m *Messenger) AcceptActivityCenterNotifications(ctx context.Context, ids []types.HexBytes, updatedAt uint64, sync bool) (*MessengerResponse, error) { 460 if len(ids) == 0 { 461 return nil, errors.New("notifications ids are not provided") 462 } 463 464 notifications, err := m.persistence.AcceptActivityCenterNotifications(ids, updatedAt) 465 if err != nil { 466 return nil, err 467 } 468 469 return m.processAcceptedActivityCenterNotifications(ctx, notifications, sync) 470 } 471 472 func (m *Messenger) DismissAllActivityCenterNotificationsFromUser(ctx context.Context, userPublicKey string, updatedAt uint64) ([]*ActivityCenterNotification, error) { 473 notifications, err := m.persistence.DismissAllActivityCenterNotificationsFromUser(userPublicKey, updatedAt) 474 if err != nil { 475 return nil, err 476 } 477 if notifications == nil { 478 return nil, nil 479 } 480 return notifications, m.syncActivityCenterDismissed(ctx, notifications, updatedAt) 481 } 482 483 func (m *Messenger) DismissActivityCenterNotificationsByCommunity(ctx context.Context, request *requests.DismissCommunityNotifications) error { 484 err := request.Validate() 485 if err != nil { 486 return err 487 } 488 489 updatedAt := m.GetCurrentTimeInMillis() 490 notifications, err := m.persistence.DismissActivityCenterNotificationsByCommunity(request.CommunityID.String(), updatedAt) 491 if err != nil { 492 return err 493 } 494 return m.syncActivityCenterDismissed(ctx, notifications, updatedAt) 495 } 496 497 func (m *Messenger) DismissAllActivityCenterNotificationsFromCommunity(ctx context.Context, communityID string, updatedAt uint64) ([]*ActivityCenterNotification, error) { 498 notifications, err := m.persistence.DismissAllActivityCenterNotificationsFromCommunity(communityID, updatedAt) 499 if err != nil { 500 return nil, err 501 } 502 return notifications, m.syncActivityCenterDismissed(ctx, notifications, updatedAt) 503 } 504 505 func (m *Messenger) DismissAllActivityCenterNotificationsFromChatID(ctx context.Context, chatID string, updatedAt uint64) ([]*ActivityCenterNotification, error) { 506 notifications, err := m.persistence.DismissAllActivityCenterNotificationsFromChatID(chatID, updatedAt) 507 if err != nil { 508 return nil, err 509 } 510 return notifications, m.syncActivityCenterDismissed(ctx, notifications, updatedAt) 511 } 512 513 func (m *Messenger) syncActivityCenterDeleted(ctx context.Context, notifications []*ActivityCenterNotification, updatedAt uint64) error { 514 ids := make([]types.HexBytes, len(notifications)) 515 for _, notification := range notifications { 516 ids = append(ids, notification.ID) 517 } 518 return m.syncActivityCenterDeletedByIDs(ctx, ids, updatedAt) 519 } 520 521 func (m *Messenger) syncActivityCenterDeletedByIDs(ctx context.Context, ids []types.HexBytes, clock uint64) error { 522 syncMessage := &protobuf.SyncActivityCenterDeleted{ 523 Clock: clock, 524 Ids: fromHexBytes(ids), 525 } 526 527 encodedMessage, err := proto.Marshal(syncMessage) 528 if err != nil { 529 return err 530 } 531 532 return m.sendToPairedDevices(ctx, common.RawMessage{ 533 Payload: encodedMessage, 534 MessageType: protobuf.ApplicationMetadataMessage_SYNC_ACTIVITY_CENTER_DELETED, 535 ResendType: common.ResendTypeDataSync, 536 }) 537 } 538 539 func (m *Messenger) syncActivityCenterDismissed(ctx context.Context, notifications []*ActivityCenterNotification, updatedAt uint64) error { 540 ids := make([]types.HexBytes, len(notifications)) 541 for _, notification := range notifications { 542 ids = append(ids, notification.ID) 543 } 544 return m.syncActivityCenterDismissedByIDs(ctx, ids, updatedAt) 545 } 546 547 func (m *Messenger) syncActivityCenterDismissedByIDs(ctx context.Context, ids []types.HexBytes, clock uint64) error { 548 syncMessage := &protobuf.SyncActivityCenterDismissed{ 549 Clock: clock, 550 Ids: fromHexBytes(ids), 551 } 552 553 encodedMessage, err := proto.Marshal(syncMessage) 554 if err != nil { 555 return err 556 } 557 558 return m.sendToPairedDevices(ctx, common.RawMessage{ 559 Payload: encodedMessage, 560 MessageType: protobuf.ApplicationMetadataMessage_SYNC_ACTIVITY_CENTER_DISMISSED, 561 ResendType: common.ResendTypeDataSync, 562 }) 563 } 564 565 func (m *Messenger) DismissActivityCenterNotifications(ctx context.Context, ids []types.HexBytes, updatedAt uint64, sync bool) (*MessengerResponse, error) { 566 if updatedAt == 0 { 567 updatedAt = m.GetCurrentTimeInMillis() 568 } 569 err := m.persistence.DismissActivityCenterNotifications(ids, updatedAt) 570 if err != nil { 571 return nil, err 572 } 573 574 state, err := m.persistence.GetActivityCenterState() 575 if err != nil { 576 return nil, err 577 } 578 579 response := &MessengerResponse{} 580 response.SetActivityCenterState(state) 581 if !sync { 582 notifications, err := m.persistence.GetActivityCenterNotificationsByID(ids) 583 if err != nil { 584 return nil, err 585 } 586 response2, err := m.processActivityCenterNotifications(notifications, true) 587 if err != nil { 588 return nil, err 589 } 590 err = response2.Merge(response) 591 return response, err 592 } 593 return response, m.syncActivityCenterDismissedByIDs(ctx, ids, updatedAt) 594 } 595 596 func (m *Messenger) ActivityCenterNotification(id types.HexBytes) (*ActivityCenterNotification, error) { 597 notification, err := m.persistence.GetActivityCenterNotificationByID(id) 598 if err != nil { 599 return nil, err 600 } 601 602 if notification.Message != nil { 603 image := notification.Message.GetImage() 604 if image != nil && image.AlbumId != "" { 605 album, err := m.persistence.albumMessages(notification.Message.LocalChatID, image.AlbumId) 606 if err != nil { 607 return nil, err 608 } 609 notification.AlbumMessages = album 610 } 611 } 612 613 return notification, nil 614 } 615 616 func (m *Messenger) HandleSyncActivityCenterRead(state *ReceivedMessageState, message *protobuf.SyncActivityCenterRead, statusMessage *v1protocol.StatusMessage) error { 617 resp, err := m.MarkActivityCenterNotificationsRead(context.TODO(), toHexBytes(message.Ids), message.Clock, false) 618 619 if err != nil { 620 return err 621 } 622 623 return state.Response.Merge(resp) 624 } 625 626 func (m *Messenger) HandleSyncActivityCenterUnread(state *ReceivedMessageState, message *protobuf.SyncActivityCenterUnread, statusMessage *v1protocol.StatusMessage) error { 627 resp, err := m.MarkActivityCenterNotificationsUnread(context.TODO(), toHexBytes(message.Ids), message.Clock, false) 628 629 if err != nil { 630 return err 631 } 632 633 return state.Response.Merge(resp) 634 } 635 636 func (m *Messenger) HandleSyncActivityCenterDeleted(state *ReceivedMessageState, message *protobuf.SyncActivityCenterDeleted, statusMessage *v1protocol.StatusMessage) error { 637 response, err := m.MarkActivityCenterNotificationsDeleted(context.TODO(), toHexBytes(message.Ids), message.Clock, false) 638 if err != nil { 639 return err 640 } 641 return state.Response.Merge(response) 642 } 643 644 func (m *Messenger) HandleSyncActivityCenterAccepted(state *ReceivedMessageState, message *protobuf.SyncActivityCenterAccepted, statusMessage *v1protocol.StatusMessage) error { 645 resp, err := m.AcceptActivityCenterNotifications(context.TODO(), toHexBytes(message.Ids), message.Clock, false) 646 647 if err != nil { 648 return err 649 } 650 651 return state.Response.Merge(resp) 652 } 653 654 func (m *Messenger) HandleSyncActivityCenterDismissed(state *ReceivedMessageState, message *protobuf.SyncActivityCenterDismissed, statusMessage *v1protocol.StatusMessage) error { 655 resp, err := m.DismissActivityCenterNotifications(context.TODO(), toHexBytes(message.Ids), message.Clock, false) 656 657 if err != nil { 658 return err 659 } 660 661 return state.Response.Merge(resp) 662 } 663 664 func (m *Messenger) HandleSyncActivityCenterCommunityRequestDecision(state *ReceivedMessageState, a *protobuf.SyncActivityCenterCommunityRequestDecision, statusMessage *v1protocol.StatusMessage) error { 665 notification, err := m.persistence.GetActivityCenterNotificationByID(a.Id) 666 if err != nil { 667 return err 668 } 669 if notification == nil { 670 return errors.New("[HandleSyncActivityCenterCommunityRequestDecision] notification not found") 671 } 672 673 notification.MembershipStatus = ActivityCenterMembershipStatus(a.MembershipStatus) 674 notification.UpdatedAt = a.Clock 675 if a.Decision == protobuf.SyncActivityCenterCommunityRequestDecision_DECLINED { 676 notification.Dismissed = true 677 } else if a.Decision == protobuf.SyncActivityCenterCommunityRequestDecision_ACCEPTED { 678 notification.Accepted = true 679 } else { 680 return errors.New("[HandleSyncActivityCenterCommunityRequestDecision] invalid decision") 681 } 682 _, err = m.persistence.SaveActivityCenterNotification(notification, false) 683 if err != nil { 684 return err 685 } 686 687 resp := state.Response 688 resp.AddActivityCenterNotification(notification) 689 690 s, err := m.persistence.UpdateActivityCenterState(notification.UpdatedAt) 691 if err != nil { 692 return err 693 } 694 resp.SetActivityCenterState(s) 695 return nil 696 }