From 76b6745666b945f8d6336e2a5fc6e5705985273d Mon Sep 17 00:00:00 2001 From: Mohsen Date: Mon, 4 Dec 2023 14:48:28 +0300 Subject: [PATCH] fix: 'Join Community' notification is not getting dismissed (#4267) --- protocol/activity_center_persistence.go | 31 +++++++++++++++++++ protocol/messenger_activity_center.go | 15 +++++++++ protocol/messenger_activity_center_test.go | 25 +++++++++++++++ .../dismiss_community_notifications.go | 23 ++++++++++++++ services/ext/api.go | 4 +++ 5 files changed, 98 insertions(+) create mode 100644 protocol/requests/dismiss_community_notifications.go diff --git a/protocol/activity_center_persistence.go b/protocol/activity_center_persistence.go index 20752b750..3c14a4d8a 100644 --- a/protocol/activity_center_persistence.go +++ b/protocol/activity_center_persistence.go @@ -859,6 +859,37 @@ func (db sqlitePersistence) DismissActivityCenterNotifications(ids []types.HexBy return updateActivityCenterState(tx, updatedAt) } +func (db sqlitePersistence) DismissActivityCenterNotificationsByCommunity(communityID string, updatedAt uint64) ([]*ActivityCenterNotification, error) { + var tx *sql.Tx + var err error + + tx, err = db.db.BeginTx(context.Background(), &sql.TxOptions{}) + if err != nil { + return nil, err + } + defer func() { + if err == nil { + err = tx.Commit() + return + } + // don't shadow original error + _ = tx.Rollback() + }() + + query := "UPDATE activity_center_notifications SET read = 1, dismissed = 1, updated_at = ? WHERE community_id = ? AND notification_type IN (?, ?) AND NOT deleted" // nolint: gosec + _, err = tx.Exec(query, updatedAt, communityID, ActivityCenterNotificationTypeCommunityRequest, ActivityCenterNotificationTypeCommunityKicked) + if err != nil { + return nil, err + } + + _, notifications, err := db.buildActivityCenterQuery(tx, activityCenterQueryParams{}) + if err != nil { + return nil, err + } + + return notifications, updateActivityCenterState(tx, updatedAt) +} + func (db sqlitePersistence) DismissAllActivityCenterNotificationsFromCommunity(communityID string, updatedAt uint64) ([]*ActivityCenterNotification, error) { var tx *sql.Tx var err error diff --git a/protocol/messenger_activity_center.go b/protocol/messenger_activity_center.go index 0cdfab11a..ffbfd704d 100644 --- a/protocol/messenger_activity_center.go +++ b/protocol/messenger_activity_center.go @@ -12,6 +12,7 @@ import ( "github.com/status-im/status-go/eth-node/types" "github.com/status-im/status-go/protocol/common" "github.com/status-im/status-go/protocol/protobuf" + "github.com/status-im/status-go/protocol/requests" ) var errOnlyOneNotificationID = errors.New("only one notification id is supported") @@ -452,6 +453,20 @@ func (m *Messenger) DismissAllActivityCenterNotificationsFromUser(ctx context.Co return notifications, m.syncActivityCenterDismissed(ctx, notifications, updatedAt) } +func (m *Messenger) DismissActivityCenterNotificationsByCommunity(ctx context.Context, request *requests.DismissCommunityNotifications) error { + err := request.Validate() + if err != nil { + return err + } + + updatedAt := m.GetCurrentTimeInMillis() + notifications, err := m.persistence.DismissActivityCenterNotificationsByCommunity(request.CommunityID.String(), updatedAt) + if err != nil { + return err + } + return m.syncActivityCenterDismissed(ctx, notifications, updatedAt) +} + func (m *Messenger) DismissAllActivityCenterNotificationsFromCommunity(ctx context.Context, communityID string, updatedAt uint64) ([]*ActivityCenterNotification, error) { notifications, err := m.persistence.DismissAllActivityCenterNotificationsFromCommunity(communityID, updatedAt) if err != nil { diff --git a/protocol/messenger_activity_center_test.go b/protocol/messenger_activity_center_test.go index 3a514b0a6..156f534fb 100644 --- a/protocol/messenger_activity_center_test.go +++ b/protocol/messenger_activity_center_test.go @@ -267,6 +267,31 @@ func (s *MessengerActivityCenterMessageSuite) TestMuteCommunityActivityCenterNot s.Require().Len(response.ActivityCenterNotifications(), 0) } +func (s *MessengerActivityCenterMessageSuite) TestReadCommunityOverviewNotifications() { + alice := s.m + bob := s.newMessenger() + _, err := bob.Start() + s.Require().NoError(err) + defer bob.Shutdown() // nolint: errcheck + + // Create a community + community, chat := s.createCommunity(bob) + s.Require().NotNil(community) + s.Require().NotNil(chat) + + // Alice joins the community + s.advertiseCommunityTo(community, bob, alice) + s.joinCommunity(community, bob, alice) + + // Mark community overview notification read + err = alice.DismissActivityCenterNotificationsByCommunity(context.Background(), &requests.DismissCommunityNotifications{CommunityID: community.ID()}) + s.Require().NoError(err) + + response, err := alice.GetActivityCenterState() + s.Require().NoError(err) + s.Require().Equal(response.HasSeen, true) +} + func (s *MessengerActivityCenterMessageSuite) prepareCommunityChannelWithMentionAndReply() (*Messenger, *Messenger, *common.Message, *common.Message, *communities.Community) { alice := s.m bob := s.newMessenger() diff --git a/protocol/requests/dismiss_community_notifications.go b/protocol/requests/dismiss_community_notifications.go new file mode 100644 index 000000000..9ad2e2fc2 --- /dev/null +++ b/protocol/requests/dismiss_community_notifications.go @@ -0,0 +1,23 @@ +package requests + +import ( + "errors" + + "github.com/status-im/status-go/eth-node/types" +) + +var ( + ErrDismissCommunityNotificationsInvalidID = errors.New("dismiss-community-notifications: invalid id") +) + +type DismissCommunityNotifications struct { + CommunityID types.HexBytes `json:"communityId"` +} + +func (r *DismissCommunityNotifications) Validate() error { + if len(r.CommunityID) == 0 { + return ErrDismissCommunityNotificationsInvalidID + } + + return nil +} diff --git a/services/ext/api.go b/services/ext/api.go index b5226c47f..6ad7bea1d 100644 --- a/services/ext/api.go +++ b/services/ext/api.go @@ -820,6 +820,10 @@ func (api *PublicAPI) MarkAllRead(ctx context.Context, chatID string) (*protocol return api.service.messenger.MarkAllRead(ctx, chatID) } +func (api *PublicAPI) DismissActivityCenterNotificationsByCommunity(ctx context.Context, request *requests.DismissCommunityNotifications) error { + return api.service.messenger.DismissActivityCenterNotificationsByCommunity(ctx, request) +} + func (api *PublicAPI) MarkAllReadInCommunity(ctx context.Context, communityID string) (*protocol.MessengerResponse, error) { return api.service.messenger.MarkAllReadInCommunity(ctx, communityID) }