feat: Support fetching accepted Activity Center notifications by multiple types (#3088)

Summary
=======

- [x] Changes endpoint ActivityCenterNotificationsBy to support fetching
  multiple types of notification in a single query.
- [x] Adds endpoint UnreadAndAcceptedActivityCenterNotificationsCount to
  allow the mobile client to fetch the count of unread & accepted
  notifications.
- [x] Add `golangci-lint` to Nix shell. This was possible since PR
  https://github.com/status-im/status-go/pull/3087 was merged.

Notes
=====

- If you'd like to understand why these changes are needed, please see
  the mobile PR https://github.com/status-im/status-mobile/pull/14785,
  or issue https://github.com/status-im/status-mobile/issues/14712
- All changes should be completely backwards compatible, and there
  should be no impact for the desktop app.
- The mobile client has been already tested using this branch.
This commit is contained in:
Icaro Motta 2023-01-20 09:45:32 -03:00 committed by GitHub
parent f9faac4293
commit e40cbfc28f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 252 additions and 145 deletions

View File

@ -1 +1 @@
0.124.0 0.125.0

View File

@ -36,8 +36,7 @@ func (db sqlitePersistence) DeleteActivityCenterNotificationForMessage(chatID st
}() }()
params := activityCenterQueryParams{ params := activityCenterQueryParams{
chatID: chatID, chatID: chatID,
activityCenterType: ActivityCenterNotificationNoType,
} }
_, notifications, err := db.buildActivityCenterQuery(tx, params) _, notifications, err := db.buildActivityCenterQuery(tx, params)
@ -294,27 +293,29 @@ const (
) )
type activityCenterQueryParams struct { type activityCenterQueryParams struct {
cursor string cursor string
limit uint64 limit uint64
ids []types.HexBytes ids []types.HexBytes
chatID string chatID string
author string author string
read ActivityCenterQueryParamsRead read ActivityCenterQueryParamsRead
activityCenterType ActivityCenterType accepted bool
activityCenterTypes []ActivityCenterType
} }
func (db sqlitePersistence) buildActivityCenterQuery(tx *sql.Tx, params activityCenterQueryParams) (string, []*ActivityCenterNotification, error) { func (db sqlitePersistence) buildActivityCenterQuery(tx *sql.Tx, params activityCenterQueryParams) (string, []*ActivityCenterNotification, error) {
var args []interface{} var args []interface{}
var cursorWhere, inQueryWhere, inChatWhere, fromAuthorWhere, ofTypeWhere, readWhere string var cursorWhere, inQueryWhere, inChatWhere, fromAuthorWhere, inTypeWhere, readWhere, acceptedWhere string
cursor := params.cursor cursor := params.cursor
ids := params.ids ids := params.ids
author := params.author author := params.author
activityCenterType := params.activityCenterType activityCenterTypes := params.activityCenterTypes
limit := params.limit limit := params.limit
chatID := params.chatID chatID := params.chatID
read := params.read read := params.read
accepted := params.accepted
if cursor != "" { if cursor != "" {
cursorWhere = "AND cursor <= ?" //nolint: goconst cursorWhere = "AND cursor <= ?" //nolint: goconst
@ -322,13 +323,11 @@ func (db sqlitePersistence) buildActivityCenterQuery(tx *sql.Tx, params activity
} }
if len(ids) != 0 { if len(ids) != 0 {
inVector := strings.Repeat("?, ", len(ids)-1) + "?" inVector := strings.Repeat("?, ", len(ids)-1) + "?"
inQueryWhere = fmt.Sprintf(" AND a.id IN (%s)", inVector) inQueryWhere = fmt.Sprintf(" AND a.id IN (%s)", inVector)
for _, id := range ids { for _, id := range ids {
args = append(args, id) args = append(args, id)
} }
} }
switch read { switch read {
@ -338,52 +337,60 @@ func (db sqlitePersistence) buildActivityCenterQuery(tx *sql.Tx, params activity
readWhere = "AND NOT(a.read)" readWhere = "AND NOT(a.read)"
} }
if !accepted {
acceptedWhere = "AND NOT a.accepted"
}
if chatID != "" { if chatID != "" {
inChatWhere = "AND a.chat_id = ?" //nolint: goconst inChatWhere = "AND a.chat_id = ?" //nolint: goconst
args = append(args, chatID) args = append(args, chatID)
} }
if author != "" { if author != "" {
fromAuthorWhere = " AND author = ?" fromAuthorWhere = " AND a.author = ?"
args = append(args, author) args = append(args, author)
} }
if activityCenterType != ActivityCenterNotificationNoType { if len(activityCenterTypes) != 0 {
ofTypeWhere = " AND notification_type = ?" inVector := strings.Repeat("?, ", len(activityCenterTypes)-1) + "?"
args = append(args, activityCenterType) inTypeWhere = fmt.Sprintf(" AND a.notification_type IN (%s)", inVector)
for _, activityCenterType := range activityCenterTypes {
args = append(args, activityCenterType)
}
} }
query := fmt.Sprintf( // nolint: gosec query := fmt.Sprintf( // nolint: gosec
` `
SELECT SELECT
a.id, a.id,
a.timestamp, a.timestamp,
a.notification_type, a.notification_type,
a.chat_id, a.chat_id,
a.community_id, a.community_id,
a.membership_status, a.membership_status,
a.read, a.read,
a.accepted, a.accepted,
a.dismissed, a.dismissed,
a.message, a.message,
c.last_message, c.last_message,
a.reply_message, a.reply_message,
a.contact_verification_status, a.contact_verification_status,
c.name, c.name,
a.author, a.author,
substr('0000000000000000000000000000000000000000000000000000000000000000' || a.timestamp, -64, 64) || a.id as cursor substr('0000000000000000000000000000000000000000000000000000000000000000' || a.timestamp, -64, 64) || a.id as cursor
FROM activity_center_notifications a FROM activity_center_notifications a
LEFT JOIN chats c LEFT JOIN chats c
ON ON
c.id = a.chat_id c.id = a.chat_id
WHERE NOT a.dismissed AND NOT a.accepted WHERE NOT a.dismissed
%s %s
%s %s
%s %s
%s %s
%s %s
%s %s
ORDER BY cursor DESC`, cursorWhere, inQueryWhere, inChatWhere, fromAuthorWhere, ofTypeWhere, readWhere) %s
ORDER BY cursor DESC`, cursorWhere, inQueryWhere, inChatWhere, fromAuthorWhere, inTypeWhere, readWhere, acceptedWhere)
if limit != 0 { if limit != 0 {
args = append(args, limit) args = append(args, limit)
@ -475,27 +482,27 @@ func (db sqlitePersistence) GetActivityCenterNotificationsByID(ids []types.HexBy
func (db sqlitePersistence) GetActivityCenterNotificationByID(id types.HexBytes) (*ActivityCenterNotification, error) { func (db sqlitePersistence) GetActivityCenterNotificationByID(id types.HexBytes) (*ActivityCenterNotification, error) {
row := db.db.QueryRow(` row := db.db.QueryRow(`
SELECT SELECT
a.id, a.id,
a.timestamp, a.timestamp,
a.notification_type, a.notification_type,
a.chat_id, a.chat_id,
a.community_id, a.community_id,
a.membership_status, a.membership_status,
a.read, a.read,
a.accepted, a.accepted,
a.dismissed, a.dismissed,
a.message, a.message,
c.last_message, c.last_message,
a.reply_message, a.reply_message,
a.contact_verification_status, a.contact_verification_status,
c.name, c.name,
a.author a.author
FROM activity_center_notifications a FROM activity_center_notifications a
LEFT JOIN chats c LEFT JOIN chats c
ON ON
c.id = a.chat_id c.id = a.chat_id
WHERE a.id = ?`, id) WHERE a.id = ?`, id)
notification, err := db.unmarshalActivityCenterNotificationRow(row) notification, err := db.unmarshalActivityCenterNotificationRow(row)
if err == sql.ErrNoRows { if err == sql.ErrNoRows {
@ -504,34 +511,35 @@ func (db sqlitePersistence) GetActivityCenterNotificationByID(id types.HexBytes)
return notification, err return notification, err
} }
func (db sqlitePersistence) UnreadActivityCenterNotifications(cursor string, limit uint64, activityType ActivityCenterType) (string, []*ActivityCenterNotification, error) { func (db sqlitePersistence) UnreadActivityCenterNotifications(cursor string, limit uint64, activityTypes []ActivityCenterType) (string, []*ActivityCenterNotification, error) {
params := activityCenterQueryParams{ params := activityCenterQueryParams{
activityCenterType: activityType, activityCenterTypes: activityTypes,
cursor: cursor, cursor: cursor,
limit: limit, limit: limit,
read: ActivityCenterQueryParamsReadUnread, read: ActivityCenterQueryParamsReadUnread,
} }
return db.activityCenterNotifications(params) return db.activityCenterNotifications(params)
} }
func (db sqlitePersistence) ReadActivityCenterNotifications(cursor string, limit uint64, activityType ActivityCenterType) (string, []*ActivityCenterNotification, error) { func (db sqlitePersistence) ReadActivityCenterNotifications(cursor string, limit uint64, activityTypes []ActivityCenterType) (string, []*ActivityCenterNotification, error) {
params := activityCenterQueryParams{ params := activityCenterQueryParams{
activityCenterType: activityType, activityCenterTypes: activityTypes,
cursor: cursor, cursor: cursor,
limit: limit, limit: limit,
read: ActivityCenterQueryParamsReadRead, read: ActivityCenterQueryParamsReadRead,
} }
return db.activityCenterNotifications(params) return db.activityCenterNotifications(params)
} }
func (db sqlitePersistence) ActivityCenterNotificationsBy(cursor string, limit uint64, activityType ActivityCenterType, readType ActivityCenterQueryParamsRead) (string, []*ActivityCenterNotification, error) { func (db sqlitePersistence) ActivityCenterNotificationsBy(cursor string, limit uint64, activityTypes []ActivityCenterType, readType ActivityCenterQueryParamsRead, accepted bool) (string, []*ActivityCenterNotification, error) {
params := activityCenterQueryParams{ params := activityCenterQueryParams{
activityCenterType: activityType, activityCenterTypes: activityTypes,
cursor: cursor, cursor: cursor,
limit: limit, limit: limit,
read: readType, read: readType,
accepted: accepted,
} }
return db.activityCenterNotifications(params) return db.activityCenterNotifications(params)
@ -657,11 +665,7 @@ func (db sqlitePersistence) AcceptAllActivityCenterNotifications() ([]*ActivityC
_ = tx.Rollback() _ = tx.Rollback()
}() }()
params := activityCenterQueryParams{ _, notifications, err := db.buildActivityCenterQuery(tx, activityCenterQueryParams{})
activityCenterType: ActivityCenterNotificationNoType,
}
_, notifications, err := db.buildActivityCenterQuery(tx, params)
_, err = tx.Exec(`UPDATE activity_center_notifications SET read = 1, accepted = 1 WHERE NOT accepted AND NOT dismissed`) _, err = tx.Exec(`UPDATE activity_center_notifications SET read = 1, accepted = 1 WHERE NOT accepted AND NOT dismissed`)
if err != nil { if err != nil {
@ -689,8 +693,7 @@ func (db sqlitePersistence) AcceptActivityCenterNotifications(ids []types.HexByt
}() }()
params := activityCenterQueryParams{ params := activityCenterQueryParams{
ids: ids, ids: ids,
activityCenterType: ActivityCenterNotificationNoType,
} }
_, notifications, err := db.buildActivityCenterQuery(tx, params) _, notifications, err := db.buildActivityCenterQuery(tx, params)
@ -761,8 +764,8 @@ func (db sqlitePersistence) AcceptActivityCenterNotificationsForInvitesFromUser(
}() }()
params := activityCenterQueryParams{ params := activityCenterQueryParams{
author: userPublicKey, author: userPublicKey,
activityCenterType: ActivityCenterNotificationTypeNewPrivateGroupChat, activityCenterTypes: []ActivityCenterType{ActivityCenterNotificationTypeNewPrivateGroupChat},
} }
_, notifications, err := db.buildActivityCenterQuery(tx, params) _, notifications, err := db.buildActivityCenterQuery(tx, params)
@ -813,35 +816,53 @@ func (db sqlitePersistence) MarkActivityCenterNotificationsUnread(ids []types.He
} }
func buildActivityCenterNotificationsCountQuery(isAccepted bool) string {
var acceptedWhere string
if !isAccepted {
acceptedWhere = `AND NOT accepted`
}
return fmt.Sprintf(`SELECT COUNT(1) FROM activity_center_notifications WHERE NOT read AND NOT dismissed %s`, acceptedWhere)
}
func (db sqlitePersistence) UnreadActivityCenterNotificationsCount() (uint64, error) { func (db sqlitePersistence) UnreadActivityCenterNotificationsCount() (uint64, error) {
var count uint64 var count uint64
err := db.db.QueryRow(`SELECT COUNT(1) FROM activity_center_notifications WHERE NOT read AND NOT dismissed AND NOT accepted`).Scan(&count) query := buildActivityCenterNotificationsCountQuery(false)
err := db.db.QueryRow(query).Scan(&count)
return count, err
}
func (db sqlitePersistence) UnreadAndAcceptedActivityCenterNotificationsCount() (uint64, error) {
var count uint64
query := buildActivityCenterNotificationsCountQuery(true)
err := db.db.QueryRow(query).Scan(&count)
return count, err return count, err
} }
func (db sqlitePersistence) ActiveContactRequestNotification(contactID string) (*ActivityCenterNotification, error) { func (db sqlitePersistence) ActiveContactRequestNotification(contactID string) (*ActivityCenterNotification, error) {
row := db.db.QueryRow(` row := db.db.QueryRow(`
SELECT SELECT
a.id, a.id,
a.timestamp, a.timestamp,
a.notification_type, a.notification_type,
a.chat_id, a.chat_id,
a.community_id, a.community_id,
a.membership_status, a.membership_status,
a.read, a.read,
a.accepted, a.accepted,
a.dismissed, a.dismissed,
a.message, a.message,
c.last_message, c.last_message,
a.reply_message, a.reply_message,
a.contact_verification_status, a.contact_verification_status,
c.name, c.name,
a.author a.author
FROM activity_center_notifications a FROM activity_center_notifications a
LEFT JOIN chats c LEFT JOIN chats c
ON ON
c.id = a.chat_id c.id = a.chat_id
WHERE NOT dismissed AND NOT a.accepted AND notification_type = ? AND author = ?`, ActivityCenterNotificationTypeContactRequest, contactID) WHERE NOT dismissed AND NOT a.accepted AND notification_type = ? AND author = ?`, ActivityCenterNotificationTypeContactRequest, contactID)
notification, err := db.unmarshalActivityCenterNotificationRow(row) notification, err := db.unmarshalActivityCenterNotificationRow(row)
if err == sql.ErrNoRows { if err == sql.ErrNoRows {
return nil, nil return nil, nil

View File

@ -16,6 +16,10 @@ func (m *Messenger) UnreadActivityCenterNotificationsCount() (uint64, error) {
return m.persistence.UnreadActivityCenterNotificationsCount() return m.persistence.UnreadActivityCenterNotificationsCount()
} }
func (m *Messenger) UnreadAndAcceptedActivityCenterNotificationsCount() (uint64, error) {
return m.persistence.UnreadAndAcceptedActivityCenterNotificationsCount()
}
func toHexBytes(b [][]byte) []types.HexBytes { func toHexBytes(b [][]byte) []types.HexBytes {
hb := make([]types.HexBytes, len(b)) hb := make([]types.HexBytes, len(b))
@ -243,8 +247,8 @@ func (m *Messenger) ActivityCenterNotifications(cursor string, limit uint64) (*A
}, nil }, nil
} }
func (m *Messenger) ReadActivityCenterNotifications(cursor string, limit uint64, activityType ActivityCenterType) (*ActivityCenterPaginationResponse, error) { func (m *Messenger) ReadActivityCenterNotifications(cursor string, limit uint64, activityTypes []ActivityCenterType) (*ActivityCenterPaginationResponse, error) {
cursor, notifications, err := m.persistence.ReadActivityCenterNotifications(cursor, limit, activityType) cursor, notifications, err := m.persistence.ReadActivityCenterNotifications(cursor, limit, activityTypes)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -255,8 +259,8 @@ func (m *Messenger) ReadActivityCenterNotifications(cursor string, limit uint64,
}, nil }, nil
} }
func (m *Messenger) UnreadActivityCenterNotifications(cursor string, limit uint64, activityType ActivityCenterType) (*ActivityCenterPaginationResponse, error) { func (m *Messenger) UnreadActivityCenterNotifications(cursor string, limit uint64, activityTypes []ActivityCenterType) (*ActivityCenterPaginationResponse, error) {
cursor, notifications, err := m.persistence.UnreadActivityCenterNotifications(cursor, limit, activityType) cursor, notifications, err := m.persistence.UnreadActivityCenterNotifications(cursor, limit, activityTypes)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -267,8 +271,8 @@ func (m *Messenger) UnreadActivityCenterNotifications(cursor string, limit uint6
}, nil }, nil
} }
func (m *Messenger) ActivityCenterNotificationsBy(cursor string, limit uint64, activityType ActivityCenterType, readType ActivityCenterQueryParamsRead) (*ActivityCenterPaginationResponse, error) { func (m *Messenger) ActivityCenterNotificationsBy(cursor string, limit uint64, activityTypes []ActivityCenterType, readType ActivityCenterQueryParamsRead, accepted bool) (*ActivityCenterPaginationResponse, error) {
cursor, notifications, err := m.persistence.ActivityCenterNotificationsBy(cursor, limit, activityType, readType) cursor, notifications, err := m.persistence.ActivityCenterNotificationsBy(cursor, limit, activityTypes, readType, accepted)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -2005,9 +2005,10 @@ func (m *Messenger) resumeHistoryArchivesImport(communityID types.HexBytes) erro
m.communitiesManager.AddHistoryArchiveDownloadTask(communityID.String(), task) m.communitiesManager.AddHistoryArchiveDownloadTask(communityID.String(), task)
// this wait groups tracks the ongoing task for a particular community
task.Waiter.Add(1)
go func() { go func() {
// this wait groups tracks the ongoing task for a particular community
task.Waiter.Add(1)
defer func() { defer func() {
task.Waiter.Done() task.Waiter.Done()
m.communitiesManager.DeleteHistoryArchiveDownloadTask(communityID.String()) m.communitiesManager.DeleteHistoryArchiveDownloadTask(communityID.String())

View File

@ -535,7 +535,11 @@ func (s *MessengerVerificationRequests) TestDeclineVerificationRequests() {
s.Require().Equal(resp.Messages()[0].ContactVerificationState, common.ContactVerificationStatePending) s.Require().Equal(resp.Messages()[0].ContactVerificationState, common.ContactVerificationStatePending)
// Make sure it's stored and retrieved correctly // Make sure it's stored and retrieved correctly
notifications, err := theirMessenger.UnreadActivityCenterNotifications("", 4, ActivityCenterNotificationTypeContactVerification) notifications, err := theirMessenger.UnreadActivityCenterNotifications(
"",
4,
[]ActivityCenterType{ActivityCenterNotificationTypeContactVerification},
)
s.Require().NoError(err) s.Require().NoError(err)
s.Require().Len(notifications.Notifications, 1) s.Require().Len(notifications.Notifications, 1)
s.Require().Equal(notifications.Notifications[0].ContactVerificationStatus, verification.RequestStatusPENDING) s.Require().Equal(notifications.Notifications[0].ContactVerificationStatus, verification.RequestStatusPENDING)
@ -561,7 +565,11 @@ func (s *MessengerVerificationRequests) TestDeclineVerificationRequests() {
s.Require().Equal(resp.Messages()[0].ContactVerificationState, common.ContactVerificationStateDeclined) s.Require().Equal(resp.Messages()[0].ContactVerificationState, common.ContactVerificationStateDeclined)
// Make sure it's stored and retrieved correctly // Make sure it's stored and retrieved correctly
notifications, err = theirMessenger.UnreadActivityCenterNotifications("", 4, ActivityCenterNotificationTypeContactVerification) notifications, err = theirMessenger.UnreadActivityCenterNotifications(
"",
4,
[]ActivityCenterType{ActivityCenterNotificationTypeContactVerification},
)
s.Require().NoError(err) s.Require().NoError(err)
s.Require().Len(notifications.Notifications, 1) s.Require().Len(notifications.Notifications, 1)
s.Require().Equal(notifications.Notifications[0].ContactVerificationStatus, verification.RequestStatusDECLINED) s.Require().Equal(notifications.Notifications[0].ContactVerificationStatus, verification.RequestStatusDECLINED)
@ -629,7 +637,11 @@ func (s *MessengerVerificationRequests) TestCancelVerificationRequest() {
s.Require().Equal(common.ContactVerificationStatePending, resp.Messages()[0].ContactVerificationState) s.Require().Equal(common.ContactVerificationStatePending, resp.Messages()[0].ContactVerificationState)
// Make sure it's stored and retrieved correctly // Make sure it's stored and retrieved correctly
notifications, err := theirMessenger.UnreadActivityCenterNotifications("", 4, ActivityCenterNotificationTypeContactVerification) notifications, err := theirMessenger.UnreadActivityCenterNotifications(
"",
4,
[]ActivityCenterType{ActivityCenterNotificationTypeContactVerification},
)
s.Require().NoError(err) s.Require().NoError(err)
s.Require().Len(notifications.Notifications, 1) s.Require().Len(notifications.Notifications, 1)
s.Require().Equal(notifications.Notifications[0].ContactVerificationStatus, verification.RequestStatusPENDING) s.Require().Equal(notifications.Notifications[0].ContactVerificationStatus, verification.RequestStatusPENDING)

View File

@ -1486,20 +1486,28 @@ func TestActivityCenterReadUnread(t *testing.T) {
err = p.MarkActivityCenterNotificationsRead([]types.HexBytes{nID2}) err = p.MarkActivityCenterNotificationsRead([]types.HexBytes{nID2})
require.NoError(t, err) require.NoError(t, err)
cursor, notifications, err := p.UnreadActivityCenterNotifications("", 2, ActivityCenterNotificationTypeNewOneToOne) cursor, notifications, err := p.UnreadActivityCenterNotifications(
"",
2,
[]ActivityCenterType{ActivityCenterNotificationTypeNewOneToOne},
)
require.NoError(t, err) require.NoError(t, err)
require.Empty(t, cursor) require.Empty(t, cursor)
require.Len(t, notifications, 1) require.Len(t, notifications, 1)
require.Equal(t, nID1, notifications[0].ID) require.Equal(t, nID1, notifications[0].ID)
cursor, notifications, err = p.ReadActivityCenterNotifications("", 2, ActivityCenterNotificationTypeNewOneToOne) cursor, notifications, err = p.ReadActivityCenterNotifications(
"",
2,
[]ActivityCenterType{ActivityCenterNotificationTypeNewOneToOne},
)
require.NoError(t, err) require.NoError(t, err)
require.Empty(t, cursor) require.Empty(t, cursor)
require.Len(t, notifications, 1) require.Len(t, notifications, 1)
require.Equal(t, nID2, notifications[0].ID) require.Equal(t, nID2, notifications[0].ID)
} }
func TestActivityCenterReadUnreadFilterByType(t *testing.T) { func TestActivityCenterReadUnreadFilterByTypes(t *testing.T) {
db, err := openTestDB() db, err := openTestDB()
require.NoError(t, err) require.NoError(t, err)
p := newSQLitePersistence(db) p := newSQLitePersistence(db)
@ -1544,29 +1552,68 @@ func TestActivityCenterReadUnreadFilterByType(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
} }
_, notifications, err := p.UnreadActivityCenterNotifications(initialCursor, limit, ActivityCenterNotificationTypeNewOneToOne) // Don't filter by type if the array of types is empty.
_, notifications, err := p.UnreadActivityCenterNotifications(
initialCursor,
limit,
[]ActivityCenterType{},
)
require.NoError(t, err)
require.Len(t, notifications, 3)
require.Equal(t, nID3, notifications[0].ID)
require.Equal(t, nID2, notifications[1].ID)
require.Equal(t, nID1, notifications[2].ID)
_, notifications, err = p.UnreadActivityCenterNotifications(
initialCursor,
limit,
[]ActivityCenterType{ActivityCenterNotificationTypeNewOneToOne},
)
require.NoError(t, err) require.NoError(t, err)
require.Len(t, notifications, 1) require.Len(t, notifications, 1)
require.Equal(t, nID2, notifications[0].ID) require.Equal(t, nID2, notifications[0].ID)
_, notifications, err = p.UnreadActivityCenterNotifications(initialCursor, limit, ActivityCenterNotificationTypeMention) _, notifications, err = p.UnreadActivityCenterNotifications(
initialCursor,
limit,
[]ActivityCenterType{ActivityCenterNotificationTypeMention},
)
require.NoError(t, err) require.NoError(t, err)
require.Len(t, notifications, 2) require.Len(t, notifications, 2)
require.Equal(t, nID3, notifications[0].ID) require.Equal(t, nID3, notifications[0].ID)
require.Equal(t, nID1, notifications[1].ID) require.Equal(t, nID1, notifications[1].ID)
_, notifications, err = p.UnreadActivityCenterNotifications(
initialCursor,
limit,
[]ActivityCenterType{ActivityCenterNotificationTypeMention, ActivityCenterNotificationTypeNewOneToOne},
)
require.NoError(t, err)
require.Len(t, notifications, 3)
require.Equal(t, nID3, notifications[0].ID)
require.Equal(t, nID2, notifications[1].ID)
require.Equal(t, nID1, notifications[2].ID)
// Mark all notifications as read. // Mark all notifications as read.
for _, notification := range allNotifications { for _, notification := range allNotifications {
err = p.MarkActivityCenterNotificationsRead([]types.HexBytes{notification.ID}) err = p.MarkActivityCenterNotificationsRead([]types.HexBytes{notification.ID})
require.NoError(t, err) require.NoError(t, err)
} }
_, notifications, err = p.ReadActivityCenterNotifications(initialCursor, limit, ActivityCenterNotificationTypeNewOneToOne) _, notifications, err = p.ReadActivityCenterNotifications(
initialCursor,
limit,
[]ActivityCenterType{ActivityCenterNotificationTypeNewOneToOne},
)
require.NoError(t, err) require.NoError(t, err)
require.Len(t, notifications, 1) require.Len(t, notifications, 1)
require.Equal(t, nID2, notifications[0].ID) require.Equal(t, nID2, notifications[0].ID)
_, notifications, err = p.ReadActivityCenterNotifications(initialCursor, limit, ActivityCenterNotificationTypeMention) _, notifications, err = p.ReadActivityCenterNotifications(
initialCursor,
limit,
[]ActivityCenterType{ActivityCenterNotificationTypeMention},
)
require.NoError(t, err) require.NoError(t, err)
require.Len(t, notifications, 2) require.Len(t, notifications, 2)
require.Equal(t, nID3, notifications[0].ID) require.Equal(t, nID3, notifications[0].ID)
@ -1638,34 +1685,54 @@ func TestActivityCenterReadUnreadPagination(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
// Fetch UNREAD notifications, first page. // Fetch UNREAD notifications, first page.
cursor, notifications, err := p.UnreadActivityCenterNotifications(initialOrFinalCursor, 1, ActivityCenterNotificationTypeNewOneToOne) cursor, notifications, err := p.UnreadActivityCenterNotifications(
initialOrFinalCursor,
1,
[]ActivityCenterType{ActivityCenterNotificationTypeNewOneToOne},
)
require.NoError(t, err) require.NoError(t, err)
require.Len(t, notifications, 1) require.Len(t, notifications, 1)
require.Equal(t, nID5, notifications[0].ID) require.Equal(t, nID5, notifications[0].ID)
require.NotEmpty(t, cursor) require.NotEmpty(t, cursor)
// Fetch next pages. // Fetch next pages.
cursor, notifications, err = p.UnreadActivityCenterNotifications(cursor, 1, ActivityCenterNotificationTypeNewOneToOne) cursor, notifications, err = p.UnreadActivityCenterNotifications(
cursor,
1,
[]ActivityCenterType{ActivityCenterNotificationTypeNewOneToOne},
)
require.NoError(t, err) require.NoError(t, err)
require.Len(t, notifications, 1) require.Len(t, notifications, 1)
require.Equal(t, nID3, notifications[0].ID) require.Equal(t, nID3, notifications[0].ID)
require.NotEmpty(t, cursor) require.NotEmpty(t, cursor)
cursor, notifications, err = p.UnreadActivityCenterNotifications(cursor, 1, ActivityCenterNotificationTypeNewOneToOne) cursor, notifications, err = p.UnreadActivityCenterNotifications(
cursor,
1,
[]ActivityCenterType{ActivityCenterNotificationTypeNewOneToOne},
)
require.NoError(t, err) require.NoError(t, err)
require.Len(t, notifications, 1) require.Len(t, notifications, 1)
require.Equal(t, nID1, notifications[0].ID) require.Equal(t, nID1, notifications[0].ID)
require.Empty(t, cursor) require.Empty(t, cursor)
// Fetch READ notifications, first page. // Fetch READ notifications, first page.
cursor, notifications, err = p.ReadActivityCenterNotifications(initialOrFinalCursor, 1, ActivityCenterNotificationTypeNewOneToOne) cursor, notifications, err = p.ReadActivityCenterNotifications(
initialOrFinalCursor,
1,
[]ActivityCenterType{ActivityCenterNotificationTypeNewOneToOne},
)
require.NoError(t, err) require.NoError(t, err)
require.Len(t, notifications, 1) require.Len(t, notifications, 1)
require.Equal(t, nID4, notifications[0].ID) require.Equal(t, nID4, notifications[0].ID)
require.NotEmpty(t, cursor) require.NotEmpty(t, cursor)
// Fetch next page. // Fetch next page.
cursor, notifications, err = p.ReadActivityCenterNotifications(cursor, 1, ActivityCenterNotificationTypeNewOneToOne) cursor, notifications, err = p.ReadActivityCenterNotifications(
cursor,
1,
[]ActivityCenterType{ActivityCenterNotificationTypeNewOneToOne},
)
require.NoError(t, err) require.NoError(t, err)
require.Len(t, notifications, 1) require.Len(t, notifications, 1)
require.Equal(t, nID2, notifications[0].ID) require.Equal(t, nID2, notifications[0].ID)

View File

@ -31,7 +31,6 @@ import (
"github.com/status-im/status-go/contracts/resolver" "github.com/status-im/status-go/contracts/resolver"
"github.com/status-im/status-go/contracts/snt" "github.com/status-im/status-go/contracts/snt"
"github.com/status-im/status-go/eth-node/types" "github.com/status-im/status-go/eth-node/types"
"github.com/status-im/status-go/multiaccounts/accounts"
"github.com/status-im/status-go/params" "github.com/status-im/status-go/params"
"github.com/status-im/status-go/rpc" "github.com/status-im/status-go/rpc"
"github.com/status-im/status-go/services/rpcfilters" "github.com/status-im/status-go/services/rpcfilters"
@ -73,8 +72,7 @@ type API struct {
quitOnce sync.Once quitOnce sync.Once
quit chan struct{} quit chan struct{}
db *Database db *Database
settings *accounts.Database // NOTE: Accounts db is here for compatibility. Remove when settings.usernames is dropped.
} }
func (api *API) Stop() { func (api *API) Stop() {

View File

@ -1082,6 +1082,10 @@ func (api *PublicAPI) UnreadActivityCenterNotificationsCount() (uint64, error) {
return api.service.messenger.UnreadActivityCenterNotificationsCount() return api.service.messenger.UnreadActivityCenterNotificationsCount()
} }
func (api *PublicAPI) UnreadAndAcceptedActivityCenterNotificationsCount() (uint64, error) {
return api.service.messenger.UnreadAndAcceptedActivityCenterNotificationsCount()
}
func (api *PublicAPI) MarkAllActivityCenterNotificationsRead(ctx context.Context) error { func (api *PublicAPI) MarkAllActivityCenterNotificationsRead(ctx context.Context) error {
return api.service.messenger.MarkAllActivityCenterNotificationsRead(ctx) return api.service.messenger.MarkAllActivityCenterNotificationsRead(ctx)
} }
@ -1117,15 +1121,15 @@ func (api *PublicAPI) ActivityCenterNotifications(cursor string, limit uint64) (
} }
func (api *PublicAPI) ReadActivityCenterNotifications(cursor string, limit uint64, activityType protocol.ActivityCenterType) (*protocol.ActivityCenterPaginationResponse, error) { func (api *PublicAPI) ReadActivityCenterNotifications(cursor string, limit uint64, activityType protocol.ActivityCenterType) (*protocol.ActivityCenterPaginationResponse, error) {
return api.service.messenger.ReadActivityCenterNotifications(cursor, limit, activityType) return api.service.messenger.ReadActivityCenterNotifications(cursor, limit, []protocol.ActivityCenterType{activityType})
} }
func (api *PublicAPI) UnreadActivityCenterNotifications(cursor string, limit uint64, activityType protocol.ActivityCenterType) (*protocol.ActivityCenterPaginationResponse, error) { func (api *PublicAPI) UnreadActivityCenterNotifications(cursor string, limit uint64, activityType protocol.ActivityCenterType) (*protocol.ActivityCenterPaginationResponse, error) {
return api.service.messenger.UnreadActivityCenterNotifications(cursor, limit, activityType) return api.service.messenger.UnreadActivityCenterNotifications(cursor, limit, []protocol.ActivityCenterType{activityType})
} }
func (api *PublicAPI) ActivityCenterNotificationsBy(cursor string, limit uint64, activityType protocol.ActivityCenterType, readType protocol.ActivityCenterQueryParamsRead) (*protocol.ActivityCenterPaginationResponse, error) { func (api *PublicAPI) ActivityCenterNotificationsBy(cursor string, limit uint64, activityTypes []protocol.ActivityCenterType, readType protocol.ActivityCenterQueryParamsRead, accepted bool) (*protocol.ActivityCenterPaginationResponse, error) {
return api.service.messenger.ActivityCenterNotificationsBy(cursor, limit, activityType, readType) return api.service.messenger.ActivityCenterNotificationsBy(cursor, limit, activityTypes, readType, accepted)
} }
func (api *PublicAPI) RequestAllHistoricMessages() (*protocol.MessengerResponse, error) { func (api *PublicAPI) RequestAllHistoricMessages() (*protocol.MessengerResponse, error) {

View File

@ -34,7 +34,7 @@ pkgs.mkShell {
buildInputs = with pkgs; [ buildInputs = with pkgs; [
git jq which git jq which
go_1_18 gopls go-bindata go_1_18 golangci-lint gopls go-bindata
mockgen protobuf3_17 protoc-gen-go mockgen protobuf3_17 protoc-gen-go
(gomobile.override { xcodeWrapperArgs = { version = "13.4.1"; }; }) (gomobile.override { xcodeWrapperArgs = { version = "13.4.1"; }; })
] ++ pkgs.lib.optionals pkgs.stdenv.isDarwin [ ] ++ pkgs.lib.optionals pkgs.stdenv.isDarwin [