diff --git a/VERSION b/VERSION index da011ce41..1afbfdb8a 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.92.1 +0.92.2 diff --git a/protocol/activity_center_persistence.go b/protocol/activity_center_persistence.go index b7ffabbdd..379254bc9 100644 --- a/protocol/activity_center_persistence.go +++ b/protocol/activity_center_persistence.go @@ -55,7 +55,7 @@ func (db sqlitePersistence) DeleteActivityCenterNotificationForMessage(chatID st } inVector := strings.Repeat("?, ", len(ids)-1) + "?" - query := "UPDATE activity_center_notifications SET dismissed = 1 WHERE id IN (" + inVector + ")" // nolint: gosec + query := "UPDATE activity_center_notifications SET read = 1, dismissed = 1 WHERE id IN (" + inVector + ")" // nolint: gosec _, err = tx.Exec(query, idsArgs...) return err } @@ -297,6 +297,15 @@ func (db sqlitePersistence) GetToProcessActivityCenterNotificationIds() ([][]byt return db.runActivityCenterIDQuery("SELECT a.id FROM activity_center_notifications a WHERE NOT a.dismissed AND NOT a.accepted") } +func (db sqlitePersistence) HasPendingNotificationsForChat(chatID string) (bool, error) { + rows, err := db.db.Query("SELECT 1 FROM activity_center_notifications a WHERE a.chat_id = ? NOT a.dismissed AND NOT a.accepted", chatID) + if err != nil { + return false, err + } + + return rows.Next(), nil +} + func (db sqlitePersistence) GetActivityCenterNotificationsByID(ids []types.HexBytes) ([]*ActivityCenterNotification, error) { idsArgs := make([]interface{}, 0, len(ids)) for _, id := range ids { @@ -362,12 +371,12 @@ func (db sqlitePersistence) ActivityCenterNotifications(currCursor string, limit } func (db sqlitePersistence) DismissAllActivityCenterNotifications() error { - _, err := db.db.Exec(`UPDATE activity_center_notifications SET dismissed = 1 WHERE NOT dismissed AND NOT accepted`) + _, err := db.db.Exec(`UPDATE activity_center_notifications SET read = 1, dismissed = 1 WHERE NOT dismissed AND NOT accepted`) return err } func (db sqlitePersistence) DismissAllActivityCenterNotificationsFromUser(userPublicKey string) error { - _, err := db.db.Exec(`UPDATE activity_center_notifications SET dismissed = 1 WHERE NOT dismissed AND NOT accepted AND author = ?`, userPublicKey) + _, err := db.db.Exec(`UPDATE activity_center_notifications SET read = 1, dismissed = 1 WHERE NOT dismissed AND NOT accepted AND author = ?`, userPublicKey) return err } @@ -379,7 +388,7 @@ func (db sqlitePersistence) DismissActivityCenterNotifications(ids []types.HexBy } inVector := strings.Repeat("?, ", len(ids)-1) + "?" - query := "UPDATE activity_center_notifications SET dismissed = 1 WHERE id IN (" + inVector + ")" // nolint: gosec + query := "UPDATE activity_center_notifications SET read = 1, dismissed = 1 WHERE id IN (" + inVector + ")" // nolint: gosec _, err := db.db.Exec(query, idsArgs...) return err @@ -404,7 +413,7 @@ func (db sqlitePersistence) AcceptAllActivityCenterNotifications() ([]*ActivityC _, notifications, err := db.buildActivityCenterQuery(tx, "", 0, nil, "", "", ActivityCenterNotificationNoType) - _, err = tx.Exec(`UPDATE activity_center_notifications SET 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 { return nil, err } @@ -441,7 +450,7 @@ func (db sqlitePersistence) AcceptActivityCenterNotifications(ids []types.HexByt } inVector := strings.Repeat("?, ", len(ids)-1) + "?" - query := "UPDATE activity_center_notifications SET accepted = 1 WHERE id IN (" + inVector + ")" // nolint: gosec + query := "UPDATE activity_center_notifications SET read = 1, accepted = 1 WHERE id IN (" + inVector + ")" // nolint: gosec _, err = tx.Exec(query, idsArgs...) return notifications, err } @@ -469,7 +478,7 @@ func (db sqlitePersistence) AcceptActivityCenterNotificationsForInvitesFromUser( return nil, err } - _, err = tx.Exec(`UPDATE activity_center_notifications SET accepted = 1 WHERE NOT accepted AND NOT dismissed AND author = ? AND notification_type = ?`, userPublicKey, ActivityCenterNotificationTypeNewPrivateGroupChat) + _, err = tx.Exec(`UPDATE activity_center_notifications SET read = 1, accepted = 1 WHERE NOT accepted AND NOT dismissed AND author = ? AND notification_type = ?`, userPublicKey, ActivityCenterNotificationTypeNewPrivateGroupChat) if err != nil { return nil, err diff --git a/protocol/messenger.go b/protocol/messenger.go index ed202a59d..566084490 100644 --- a/protocol/messenger.go +++ b/protocol/messenger.go @@ -1894,14 +1894,19 @@ func (m *Messenger) leaveGroupChat(ctx context.Context, response *MessengerRespo if err != nil { return nil, err } - _, err = m.dispatchMessage(ctx, common.RawMessage{ - LocalChatID: chat.ID, - Payload: encodedMessage, - MessageType: protobuf.ApplicationMetadataMessage_MEMBERSHIP_UPDATE_MESSAGE, - Recipients: recipients, - }) - if err != nil { - return nil, err + + // shouldBeSynced is false if we got here because a synced client has already + // sent the leave group message. In that case we don't need to send it again. + if shouldBeSynced { + _, err = m.dispatchMessage(ctx, common.RawMessage{ + LocalChatID: chat.ID, + Payload: encodedMessage, + MessageType: protobuf.ApplicationMetadataMessage_MEMBERSHIP_UPDATE_MESSAGE, + Recipients: recipients, + }) + if err != nil { + return nil, err + } } chat.updateChatFromGroupMembershipChanges(group) @@ -2346,10 +2351,17 @@ func (m *Messenger) SyncDevices(ctx context.Context, ensName, photoPath string) } if (isPublicChat || chat.OneToOne() || chat.PrivateGroupChat()) && !chat.Active { - err := m.syncChatRemoving(ctx, chatID) + pending, err := m.persistence.HasPendingNotificationsForChat(chat.ID) if err != nil { return false } + + if !pending { + err = m.syncChatRemoving(ctx, chatID) + if err != nil { + return false + } + } } if (isPublicChat || chat.OneToOne() || chat.PrivateGroupChat() || chat.CommunityChat()) && chat.Active { diff --git a/protocol/messenger_activity_center.go b/protocol/messenger_activity_center.go index cc46fc2f9..672e19e82 100644 --- a/protocol/messenger_activity_center.go +++ b/protocol/messenger_activity_center.go @@ -121,6 +121,7 @@ func (m *Messenger) processAcceptedActivityCenterNotifications(ctx context.Conte for i := range notifications { ids[i] = notifications[i].ID notifications[i].Accepted = true + notifications[i].Read = true } if sync { diff --git a/protocol/messenger_handler.go b/protocol/messenger_handler.go index 90333bcc5..320ecb58a 100644 --- a/protocol/messenger_handler.go +++ b/protocol/messenger_handler.go @@ -1209,6 +1209,8 @@ func (m *Messenger) matchChatEntity(chatEntity common.ChatEntity) (*Chat, error) chat = CreateOneToOneChat(chatID[:8], pubKey, m.getTimesource()) } + // if we are the sender, the chat must be active + chat.Active = true return chat, nil case chatEntity.GetMessageType() == protobuf.MessageType_ONE_TO_ONE: // It's an incoming private chatEntity. ChatID is calculated from the signature.