2021-04-07 12:57:14 +00:00
|
|
|
package protocol
|
|
|
|
|
|
|
|
import (
|
2021-12-02 14:23:02 +00:00
|
|
|
"context"
|
|
|
|
|
|
|
|
"github.com/golang/protobuf/proto"
|
2022-02-09 13:15:57 +00:00
|
|
|
"github.com/pkg/errors"
|
2022-05-30 15:34:48 +00:00
|
|
|
"go.uber.org/zap"
|
2022-02-09 13:15:57 +00:00
|
|
|
|
2023-10-22 09:41:20 +00:00
|
|
|
v1protocol "github.com/status-im/status-go/protocol/v1"
|
|
|
|
|
2021-04-07 12:57:14 +00:00
|
|
|
"github.com/status-im/status-go/eth-node/types"
|
2021-12-02 14:23:02 +00:00
|
|
|
"github.com/status-im/status-go/protocol/common"
|
|
|
|
"github.com/status-im/status-go/protocol/protobuf"
|
2023-12-04 11:48:28 +00:00
|
|
|
"github.com/status-im/status-go/protocol/requests"
|
2021-04-07 12:57:14 +00:00
|
|
|
)
|
|
|
|
|
2023-10-26 04:17:18 +00:00
|
|
|
var errOnlyOneNotificationID = errors.New("only one notification id is supported")
|
|
|
|
|
2021-12-02 14:23:02 +00:00
|
|
|
func toHexBytes(b [][]byte) []types.HexBytes {
|
|
|
|
hb := make([]types.HexBytes, len(b))
|
|
|
|
|
|
|
|
for i, v := range b {
|
|
|
|
hb[i] = types.HexBytes(v)
|
|
|
|
}
|
|
|
|
|
|
|
|
return hb
|
|
|
|
}
|
|
|
|
|
|
|
|
func fromHexBytes(hb []types.HexBytes) [][]byte {
|
|
|
|
b := make([][]byte, len(hb))
|
|
|
|
|
|
|
|
for i, v := range hb {
|
|
|
|
b[i] = v
|
|
|
|
}
|
|
|
|
|
|
|
|
return b
|
|
|
|
}
|
|
|
|
|
2023-03-03 14:31:48 +00:00
|
|
|
func (m *Messenger) ActivityCenterNotifications(request ActivityCenterNotificationsRequest) (*ActivityCenterPaginationResponse, error) {
|
|
|
|
cursor, notifications, err := m.persistence.ActivityCenterNotifications(request.Cursor, request.Limit, request.ActivityTypes, request.ReadType, true)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2023-08-10 15:12:23 +00:00
|
|
|
if m.httpServer != nil {
|
|
|
|
for _, notification := range notifications {
|
|
|
|
if notification.Message != nil {
|
2024-01-08 18:18:57 +00:00
|
|
|
err = m.prepareMessage(notification.Message, m.httpServer)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2023-09-19 17:17:11 +00:00
|
|
|
|
|
|
|
image := notification.Message.GetImage()
|
|
|
|
if image != nil && image.AlbumId != "" {
|
|
|
|
album, err := m.persistence.albumMessages(notification.Message.LocalChatID, image.AlbumId)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
notification.AlbumMessages = album
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if notification.AlbumMessages != nil {
|
|
|
|
for _, message := range notification.AlbumMessages {
|
2024-01-08 18:18:57 +00:00
|
|
|
err = m.prepareMessage(message, m.httpServer)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2023-09-19 17:17:11 +00:00
|
|
|
}
|
2023-08-10 15:12:23 +00:00
|
|
|
}
|
2024-02-19 13:55:38 +00:00
|
|
|
if notification.TokenData != nil {
|
|
|
|
if notification.Type == ActivityCenterNotificationTypeCommunityTokenReceived || notification.Type == ActivityCenterNotificationTypeFirstCommunityTokenReceived {
|
|
|
|
err = m.prepareTokenData(notification.TokenData, m.httpServer)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-08-10 15:12:23 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-03-03 14:31:48 +00:00
|
|
|
return &ActivityCenterPaginationResponse{
|
|
|
|
Cursor: cursor,
|
|
|
|
Notifications: notifications,
|
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m *Messenger) ActivityCenterNotificationsCount(request ActivityCenterCountRequest) (*ActivityCenterCountResponse, error) {
|
|
|
|
response := make(ActivityCenterCountResponse)
|
|
|
|
|
|
|
|
for _, activityType := range request.ActivityTypes {
|
|
|
|
count, err := m.persistence.ActivityCenterNotificationsCount([]ActivityCenterType{activityType}, request.ReadType, true)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
response[activityType] = count
|
|
|
|
}
|
|
|
|
|
|
|
|
return &response, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m *Messenger) HasUnseenActivityCenterNotifications() (bool, error) {
|
2023-06-10 02:00:17 +00:00
|
|
|
seen, _, err := m.persistence.HasUnseenActivityCenterNotifications()
|
|
|
|
return seen, err
|
2023-03-03 14:31:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (m *Messenger) GetActivityCenterState() (*ActivityCenterState, error) {
|
|
|
|
return m.persistence.GetActivityCenterState()
|
|
|
|
}
|
|
|
|
|
2023-02-17 10:08:08 +00:00
|
|
|
func (m *Messenger) MarkAsSeenActivityCenterNotifications() (*MessengerResponse, error) {
|
|
|
|
response := &MessengerResponse{}
|
2023-06-10 02:00:17 +00:00
|
|
|
s := &ActivityCenterState{
|
2023-10-22 09:41:20 +00:00
|
|
|
UpdatedAt: m.GetCurrentTimeInMillis(),
|
2023-06-10 02:00:17 +00:00
|
|
|
HasSeen: true,
|
|
|
|
}
|
2023-10-22 09:41:20 +00:00
|
|
|
_, err := m.persistence.UpdateActivityCenterNotificationState(s)
|
2023-02-17 10:08:08 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
state, err := m.persistence.GetActivityCenterState()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
response.SetActivityCenterState(state)
|
2023-11-02 15:07:03 +00:00
|
|
|
return response, nil
|
2023-02-17 10:08:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (m *Messenger) MarkAllActivityCenterNotificationsRead(ctx context.Context) (*MessengerResponse, error) {
|
2023-11-27 11:22:24 +00:00
|
|
|
ids, err := m.persistence.GetNotReadActivityCenterNotificationIds()
|
2023-02-17 10:08:08 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
2021-12-02 14:23:02 +00:00
|
|
|
}
|
|
|
|
|
2023-11-27 11:22:24 +00:00
|
|
|
updateAt := m.GetCurrentTimeInMillis()
|
|
|
|
return m.MarkActivityCenterNotificationsRead(ctx, toHexBytes(ids), updateAt, true)
|
2021-04-07 12:57:14 +00:00
|
|
|
}
|
|
|
|
|
2023-06-10 02:00:17 +00:00
|
|
|
func (m *Messenger) MarkActivityCenterNotificationsRead(ctx context.Context, ids []types.HexBytes, updatedAt uint64, sync bool) (*MessengerResponse, error) {
|
2023-11-27 11:22:24 +00:00
|
|
|
// Mark notifications as read in the database
|
2023-06-10 02:00:17 +00:00
|
|
|
if updatedAt == 0 {
|
2023-10-22 09:41:20 +00:00
|
|
|
updatedAt = m.GetCurrentTimeInMillis()
|
2023-06-10 02:00:17 +00:00
|
|
|
}
|
|
|
|
err := m.persistence.MarkActivityCenterNotificationsRead(ids, updatedAt)
|
2021-12-02 14:23:02 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2023-11-27 11:22:24 +00:00
|
|
|
notifications, err := m.persistence.GetActivityCenterNotificationsByID(ids)
|
2023-10-22 09:41:20 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2023-11-27 11:22:24 +00:00
|
|
|
response := &MessengerResponse{}
|
|
|
|
repliesAndMentions := make(map[string][]string)
|
2023-10-22 09:41:20 +00:00
|
|
|
|
2023-12-25 06:25:22 +00:00
|
|
|
// When marking as read Mention or Reply notification, the corresponding chat message should also be seen.
|
2023-11-27 11:22:24 +00:00
|
|
|
for _, notification := range notifications {
|
|
|
|
response.AddActivityCenterNotification(notification)
|
|
|
|
|
|
|
|
if notification.Message != nil &&
|
|
|
|
(notification.Type == ActivityCenterNotificationTypeMention || notification.Type == ActivityCenterNotificationTypeReply) {
|
|
|
|
repliesAndMentions[notification.ChatID] = append(repliesAndMentions[notification.ChatID], notification.Message.ID)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Mark messages as seen
|
|
|
|
for chatID, messageIDs := range repliesAndMentions {
|
2024-01-10 01:36:33 +00:00
|
|
|
count, countWithMentions, chat, err := m.markMessagesSeenImpl(chatID, messageIDs)
|
2021-12-02 14:23:02 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2024-01-10 01:36:33 +00:00
|
|
|
response.AddChat(chat)
|
2023-12-25 06:25:22 +00:00
|
|
|
response.AddSeenAndUnseenMessages(&SeenUnseenMessages{
|
|
|
|
ChatID: chatID,
|
|
|
|
Count: count,
|
|
|
|
CountWithMentions: countWithMentions,
|
|
|
|
Seen: true,
|
|
|
|
})
|
2023-11-27 11:22:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
state, err := m.persistence.GetActivityCenterState()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
response.SetActivityCenterState(state)
|
|
|
|
|
|
|
|
if !sync {
|
2023-10-22 09:41:20 +00:00
|
|
|
response2, err := m.processActivityCenterNotifications(notifications, true)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
if err = response2.Merge(response); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return response2, nil
|
2021-12-02 14:23:02 +00:00
|
|
|
}
|
2023-11-02 15:07:03 +00:00
|
|
|
return response, m.syncActivityCenterReadByIDs(ctx, ids, updatedAt)
|
2023-10-22 09:41:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (m *Messenger) MarkActivityCenterNotificationsUnread(ctx context.Context, ids []types.HexBytes, updatedAt uint64, sync bool) (*MessengerResponse, error) {
|
|
|
|
notifications, err := m.persistence.MarkActivityCenterNotificationsUnread(ids, updatedAt)
|
2023-02-17 10:08:08 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2023-12-25 06:25:22 +00:00
|
|
|
response := &MessengerResponse{}
|
|
|
|
response.AddActivityCenterNotifications(notifications)
|
|
|
|
|
|
|
|
// Don't mark messages unseen in chat, that looks weird
|
|
|
|
|
2023-02-17 10:08:08 +00:00
|
|
|
state, err := m.persistence.GetActivityCenterState()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
response.SetActivityCenterState(state)
|
2023-10-22 09:41:20 +00:00
|
|
|
|
|
|
|
if sync && len(notifications) > 0 {
|
|
|
|
err = m.syncActivityCenterUnreadByIDs(ctx, ids, updatedAt)
|
|
|
|
}
|
2023-11-02 15:07:03 +00:00
|
|
|
return response, err
|
2021-06-11 16:47:53 +00:00
|
|
|
}
|
|
|
|
|
2023-10-22 09:41:20 +00:00
|
|
|
func (m *Messenger) MarkActivityCenterNotificationsDeleted(ctx context.Context, ids []types.HexBytes, updatedAt uint64, sync bool) (*MessengerResponse, error) {
|
2023-02-17 10:08:08 +00:00
|
|
|
response := &MessengerResponse{}
|
2023-10-22 09:41:20 +00:00
|
|
|
notifications, err := m.persistence.MarkActivityCenterNotificationsDeleted(ids, updatedAt)
|
2023-02-17 10:08:08 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2023-10-22 09:41:20 +00:00
|
|
|
response.AddActivityCenterNotifications(notifications)
|
|
|
|
state, err := m.persistence.GetActivityCenterState()
|
2023-06-10 02:00:17 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2023-10-22 09:41:20 +00:00
|
|
|
response.SetActivityCenterState(state)
|
|
|
|
if sync {
|
|
|
|
err = m.syncActivityCenterDeletedByIDs(ctx, ids, updatedAt)
|
|
|
|
if err != nil {
|
|
|
|
m.logger.Error("MarkActivityCenterNotificationsDeleted, failed to sync activity center notifications as deleted", zap.Error(err))
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return response, nil
|
|
|
|
}
|
2023-02-17 10:08:08 +00:00
|
|
|
|
2023-10-22 09:41:20 +00:00
|
|
|
func (m *Messenger) addActivityCenterNotification(response *MessengerResponse, notification *ActivityCenterNotification, syncAction func(context.Context, []types.HexBytes, uint64) error) error {
|
|
|
|
_, err := m.persistence.SaveActivityCenterNotification(notification, true)
|
2023-02-17 10:08:08 +00:00
|
|
|
if err != nil {
|
2023-10-22 09:41:20 +00:00
|
|
|
m.logger.Error("failed to save notification", zap.Error(err))
|
|
|
|
return err
|
2023-02-17 10:08:08 +00:00
|
|
|
}
|
|
|
|
|
2023-10-22 09:41:20 +00:00
|
|
|
state, err := m.persistence.GetActivityCenterState()
|
|
|
|
if err != nil {
|
|
|
|
m.logger.Error("failed to obtain activity center state", zap.Error(err))
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
response.AddActivityCenterNotification(notification)
|
2023-02-17 10:08:08 +00:00
|
|
|
response.SetActivityCenterState(state)
|
2023-10-22 09:41:20 +00:00
|
|
|
|
|
|
|
if syncAction != nil {
|
|
|
|
//TODO a way to pass context
|
|
|
|
err = syncAction(context.TODO(), []types.HexBytes{notification.ID}, notification.UpdatedAt)
|
|
|
|
if err != nil {
|
|
|
|
m.logger.Error("[addActivityCenterNotification] failed to sync activity center notification", zap.Error(err))
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
2023-10-26 04:17:18 +00:00
|
|
|
return nil
|
2023-10-22 09:41:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (m *Messenger) syncActivityCenterReadByIDs(ctx context.Context, ids []types.HexBytes, clock uint64) error {
|
|
|
|
syncMessage := &protobuf.SyncActivityCenterRead{
|
|
|
|
Clock: clock,
|
|
|
|
Ids: fromHexBytes(ids),
|
|
|
|
}
|
|
|
|
|
|
|
|
encodedMessage, err := proto.Marshal(syncMessage)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return m.sendToPairedDevices(ctx, common.RawMessage{
|
2024-03-22 10:55:09 +00:00
|
|
|
Payload: encodedMessage,
|
|
|
|
MessageType: protobuf.ApplicationMetadataMessage_SYNC_ACTIVITY_CENTER_READ,
|
|
|
|
ResendType: common.ResendTypeDataSync,
|
2023-10-22 09:41:20 +00:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m *Messenger) syncActivityCenterUnreadByIDs(ctx context.Context, ids []types.HexBytes, clock uint64) error {
|
|
|
|
syncMessage := &protobuf.SyncActivityCenterUnread{
|
|
|
|
Clock: clock,
|
|
|
|
Ids: fromHexBytes(ids),
|
|
|
|
}
|
|
|
|
|
|
|
|
encodedMessage, err := proto.Marshal(syncMessage)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return m.sendToPairedDevices(ctx, common.RawMessage{
|
2024-03-22 10:55:09 +00:00
|
|
|
Payload: encodedMessage,
|
|
|
|
MessageType: protobuf.ApplicationMetadataMessage_SYNC_ACTIVITY_CENTER_UNREAD,
|
|
|
|
ResendType: common.ResendTypeDataSync,
|
2023-10-22 09:41:20 +00:00
|
|
|
})
|
2021-09-24 10:57:15 +00:00
|
|
|
}
|
|
|
|
|
2021-12-02 14:23:02 +00:00
|
|
|
func (m *Messenger) processActivityCenterNotifications(notifications []*ActivityCenterNotification, addNotifications bool) (*MessengerResponse, error) {
|
2021-04-07 12:57:14 +00:00
|
|
|
response := &MessengerResponse{}
|
|
|
|
var chats []*Chat
|
|
|
|
for _, notification := range notifications {
|
|
|
|
if notification.ChatID != "" {
|
|
|
|
chat, ok := m.allChats.Load(notification.ChatID)
|
|
|
|
if !ok {
|
|
|
|
// This should not really happen, but ignore just in case it was deleted in the meantime
|
|
|
|
m.logger.Warn("chat not found")
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
chat.Active = true
|
|
|
|
|
2022-05-30 15:34:48 +00:00
|
|
|
if chat.PrivateGroupChat() {
|
|
|
|
// Send Joined message for backward compatibility
|
|
|
|
_, err := m.ConfirmJoiningGroup(context.Background(), chat.ID)
|
|
|
|
if err != nil {
|
|
|
|
m.logger.Error("failed to join group", zap.Error(err))
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-04-07 12:57:14 +00:00
|
|
|
chats = append(chats, chat)
|
|
|
|
response.AddChat(chat)
|
|
|
|
}
|
2021-12-02 14:23:02 +00:00
|
|
|
|
|
|
|
if addNotifications {
|
|
|
|
response.AddActivityCenterNotification(notification)
|
|
|
|
}
|
2021-04-07 12:57:14 +00:00
|
|
|
}
|
|
|
|
if len(chats) != 0 {
|
|
|
|
err := m.saveChats(chats)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return response, nil
|
|
|
|
}
|
|
|
|
|
2021-12-02 14:23:02 +00:00
|
|
|
func (m *Messenger) processAcceptedActivityCenterNotifications(ctx context.Context, notifications []*ActivityCenterNotification, sync bool) (*MessengerResponse, error) {
|
2023-10-22 09:41:20 +00:00
|
|
|
ids := make([]types.HexBytes, len(notifications))
|
2021-12-02 14:23:02 +00:00
|
|
|
|
|
|
|
for i := range notifications {
|
|
|
|
ids[i] = notifications[i].ID
|
|
|
|
}
|
|
|
|
|
2023-10-22 09:41:20 +00:00
|
|
|
state, err := m.persistence.GetActivityCenterState()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2021-12-02 14:23:02 +00:00
|
|
|
if sync {
|
2023-10-22 09:41:20 +00:00
|
|
|
err = m.syncActivityCenterAcceptedByIDs(ctx, ids, m.GetCurrentTimeInMillis())
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
2021-12-02 14:23:02 +00:00
|
|
|
}
|
2023-10-22 09:41:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
response, err := m.processActivityCenterNotifications(notifications, !sync)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
response.SetActivityCenterState(state)
|
|
|
|
return response, nil
|
|
|
|
}
|
2021-12-02 14:23:02 +00:00
|
|
|
|
2023-10-22 09:41:20 +00:00
|
|
|
func (m *Messenger) AcceptActivityCenterNotificationsForInvitesFromUser(ctx context.Context, userPublicKey string, updatedAt uint64) ([]*ActivityCenterNotification, error) {
|
|
|
|
notifications, err := m.persistence.AcceptActivityCenterNotificationsForInvitesFromUser(userPublicKey, updatedAt)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
if len(notifications) > 0 {
|
|
|
|
err = m.syncActivityCenterAccepted(ctx, notifications, updatedAt)
|
|
|
|
}
|
2023-11-02 15:07:03 +00:00
|
|
|
return notifications, err
|
2023-10-22 09:41:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (m *Messenger) syncActivityCenterAccepted(ctx context.Context, notifications []*ActivityCenterNotification, updatedAt uint64) error {
|
|
|
|
ids := make([]types.HexBytes, len(notifications))
|
|
|
|
for _, notification := range notifications {
|
|
|
|
ids = append(ids, notification.ID)
|
|
|
|
}
|
|
|
|
return m.syncActivityCenterAcceptedByIDs(ctx, ids, updatedAt)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m *Messenger) syncActivityCenterAcceptedByIDs(ctx context.Context, ids []types.HexBytes, clock uint64) error {
|
|
|
|
syncMessage := &protobuf.SyncActivityCenterAccepted{
|
|
|
|
Clock: clock,
|
|
|
|
Ids: fromHexBytes(ids),
|
2021-12-02 14:23:02 +00:00
|
|
|
}
|
|
|
|
|
2023-10-22 09:41:20 +00:00
|
|
|
encodedMessage, err := proto.Marshal(syncMessage)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return m.sendToPairedDevices(ctx, common.RawMessage{
|
2024-03-22 10:55:09 +00:00
|
|
|
Payload: encodedMessage,
|
|
|
|
MessageType: protobuf.ApplicationMetadataMessage_SYNC_ACTIVITY_CENTER_ACCEPTED,
|
|
|
|
ResendType: common.ResendTypeDataSync,
|
2023-10-22 09:41:20 +00:00
|
|
|
})
|
2021-12-02 14:23:02 +00:00
|
|
|
}
|
|
|
|
|
2023-10-26 04:17:18 +00:00
|
|
|
func (m *Messenger) syncActivityCenterCommunityRequestDecisionAdapter(ctx context.Context, ids []types.HexBytes, _ uint64) error {
|
|
|
|
if len(ids) != 1 {
|
|
|
|
return errOnlyOneNotificationID
|
|
|
|
}
|
|
|
|
id := ids[0]
|
|
|
|
notification, err := m.persistence.GetActivityCenterNotificationByID(id)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return m.syncActivityCenterCommunityRequestDecision(ctx, notification)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m *Messenger) syncActivityCenterCommunityRequestDecision(ctx context.Context, notification *ActivityCenterNotification) error {
|
|
|
|
var decision protobuf.SyncActivityCenterCommunityRequestDecisionCommunityRequestDecision
|
|
|
|
if notification.Accepted {
|
|
|
|
decision = protobuf.SyncActivityCenterCommunityRequestDecision_ACCEPTED
|
|
|
|
} else if notification.Dismissed {
|
|
|
|
decision = protobuf.SyncActivityCenterCommunityRequestDecision_DECLINED
|
|
|
|
} else {
|
|
|
|
return errors.New("[syncActivityCenterCommunityRequestDecision] notification is not accepted or dismissed")
|
|
|
|
}
|
|
|
|
|
|
|
|
syncMessage := &protobuf.SyncActivityCenterCommunityRequestDecision{
|
|
|
|
Clock: notification.UpdatedAt,
|
|
|
|
Id: notification.ID,
|
|
|
|
MembershipStatus: uint32(notification.MembershipStatus),
|
|
|
|
Decision: decision,
|
|
|
|
}
|
|
|
|
|
|
|
|
encodedMessage, err := proto.Marshal(syncMessage)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return m.sendToPairedDevices(ctx, common.RawMessage{
|
2024-03-22 10:55:09 +00:00
|
|
|
Payload: encodedMessage,
|
|
|
|
MessageType: protobuf.ApplicationMetadataMessage_SYNC_ACTIVITY_CENTER_COMMUNITY_REQUEST_DECISION,
|
|
|
|
ResendType: common.ResendTypeDataSync,
|
2023-10-26 04:17:18 +00:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2023-06-10 02:00:17 +00:00
|
|
|
func (m *Messenger) AcceptActivityCenterNotifications(ctx context.Context, ids []types.HexBytes, updatedAt uint64, sync bool) (*MessengerResponse, error) {
|
2022-02-09 13:15:57 +00:00
|
|
|
if len(ids) == 0 {
|
|
|
|
return nil, errors.New("notifications ids are not provided")
|
|
|
|
}
|
|
|
|
|
2023-06-10 02:00:17 +00:00
|
|
|
notifications, err := m.persistence.AcceptActivityCenterNotifications(ids, updatedAt)
|
2021-04-07 12:57:14 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2021-12-02 14:23:02 +00:00
|
|
|
|
|
|
|
return m.processAcceptedActivityCenterNotifications(ctx, notifications, sync)
|
2021-04-07 12:57:14 +00:00
|
|
|
}
|
|
|
|
|
2023-10-22 09:41:20 +00:00
|
|
|
func (m *Messenger) DismissAllActivityCenterNotificationsFromUser(ctx context.Context, userPublicKey string, updatedAt uint64) ([]*ActivityCenterNotification, error) {
|
|
|
|
notifications, err := m.persistence.DismissAllActivityCenterNotificationsFromUser(userPublicKey, updatedAt)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
2023-06-10 02:00:17 +00:00
|
|
|
}
|
2023-10-22 09:41:20 +00:00
|
|
|
if notifications == nil {
|
|
|
|
return nil, nil
|
|
|
|
}
|
2023-11-02 15:07:03 +00:00
|
|
|
return notifications, m.syncActivityCenterDismissed(ctx, notifications, updatedAt)
|
2023-10-22 09:41:20 +00:00
|
|
|
}
|
|
|
|
|
2023-12-04 11:48:28 +00:00
|
|
|
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)
|
|
|
|
}
|
|
|
|
|
2023-10-22 09:41:20 +00:00
|
|
|
func (m *Messenger) DismissAllActivityCenterNotificationsFromCommunity(ctx context.Context, communityID string, updatedAt uint64) ([]*ActivityCenterNotification, error) {
|
|
|
|
notifications, err := m.persistence.DismissAllActivityCenterNotificationsFromCommunity(communityID, updatedAt)
|
2021-12-02 14:23:02 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2023-11-02 15:07:03 +00:00
|
|
|
return notifications, m.syncActivityCenterDismissed(ctx, notifications, updatedAt)
|
2023-10-22 09:41:20 +00:00
|
|
|
}
|
2021-12-02 14:23:02 +00:00
|
|
|
|
2023-10-22 09:41:20 +00:00
|
|
|
func (m *Messenger) DismissAllActivityCenterNotificationsFromChatID(ctx context.Context, chatID string, updatedAt uint64) ([]*ActivityCenterNotification, error) {
|
|
|
|
notifications, err := m.persistence.DismissAllActivityCenterNotificationsFromChatID(chatID, updatedAt)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2023-11-02 15:07:03 +00:00
|
|
|
return notifications, m.syncActivityCenterDismissed(ctx, notifications, updatedAt)
|
2023-10-22 09:41:20 +00:00
|
|
|
}
|
2021-12-02 14:23:02 +00:00
|
|
|
|
2023-10-22 09:41:20 +00:00
|
|
|
func (m *Messenger) syncActivityCenterDeleted(ctx context.Context, notifications []*ActivityCenterNotification, updatedAt uint64) error {
|
|
|
|
ids := make([]types.HexBytes, len(notifications))
|
|
|
|
for _, notification := range notifications {
|
|
|
|
ids = append(ids, notification.ID)
|
2021-12-02 14:23:02 +00:00
|
|
|
}
|
2023-10-22 09:41:20 +00:00
|
|
|
return m.syncActivityCenterDeletedByIDs(ctx, ids, updatedAt)
|
|
|
|
}
|
2021-12-02 14:23:02 +00:00
|
|
|
|
2023-10-22 09:41:20 +00:00
|
|
|
func (m *Messenger) syncActivityCenterDeletedByIDs(ctx context.Context, ids []types.HexBytes, clock uint64) error {
|
|
|
|
syncMessage := &protobuf.SyncActivityCenterDeleted{
|
|
|
|
Clock: clock,
|
2021-12-02 14:23:02 +00:00
|
|
|
Ids: fromHexBytes(ids),
|
|
|
|
}
|
|
|
|
|
|
|
|
encodedMessage, err := proto.Marshal(syncMessage)
|
|
|
|
if err != nil {
|
2023-10-22 09:41:20 +00:00
|
|
|
return err
|
2021-12-02 14:23:02 +00:00
|
|
|
}
|
|
|
|
|
2023-10-22 09:41:20 +00:00
|
|
|
return m.sendToPairedDevices(ctx, common.RawMessage{
|
2024-03-22 10:55:09 +00:00
|
|
|
Payload: encodedMessage,
|
|
|
|
MessageType: protobuf.ApplicationMetadataMessage_SYNC_ACTIVITY_CENTER_DELETED,
|
|
|
|
ResendType: common.ResendTypeDataSync,
|
2021-12-02 14:23:02 +00:00
|
|
|
})
|
2023-10-22 09:41:20 +00:00
|
|
|
}
|
2021-12-02 14:23:02 +00:00
|
|
|
|
2023-10-22 09:41:20 +00:00
|
|
|
func (m *Messenger) syncActivityCenterDismissed(ctx context.Context, notifications []*ActivityCenterNotification, updatedAt uint64) error {
|
|
|
|
ids := make([]types.HexBytes, len(notifications))
|
|
|
|
for _, notification := range notifications {
|
|
|
|
ids = append(ids, notification.ID)
|
|
|
|
}
|
|
|
|
return m.syncActivityCenterDismissedByIDs(ctx, ids, updatedAt)
|
2021-04-07 12:57:14 +00:00
|
|
|
}
|
|
|
|
|
2023-10-22 09:41:20 +00:00
|
|
|
func (m *Messenger) syncActivityCenterDismissedByIDs(ctx context.Context, ids []types.HexBytes, clock uint64) error {
|
|
|
|
syncMessage := &protobuf.SyncActivityCenterDismissed{
|
|
|
|
Clock: clock,
|
|
|
|
Ids: fromHexBytes(ids),
|
|
|
|
}
|
|
|
|
|
|
|
|
encodedMessage, err := proto.Marshal(syncMessage)
|
2023-06-10 02:00:17 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2023-10-22 09:41:20 +00:00
|
|
|
|
|
|
|
return m.sendToPairedDevices(ctx, common.RawMessage{
|
2024-03-22 10:55:09 +00:00
|
|
|
Payload: encodedMessage,
|
|
|
|
MessageType: protobuf.ApplicationMetadataMessage_SYNC_ACTIVITY_CENTER_DISMISSED,
|
|
|
|
ResendType: common.ResendTypeDataSync,
|
2023-10-22 09:41:20 +00:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m *Messenger) DismissActivityCenterNotifications(ctx context.Context, ids []types.HexBytes, updatedAt uint64, sync bool) (*MessengerResponse, error) {
|
|
|
|
if updatedAt == 0 {
|
|
|
|
updatedAt = m.GetCurrentTimeInMillis()
|
|
|
|
}
|
|
|
|
err := m.persistence.DismissActivityCenterNotifications(ids, updatedAt)
|
2023-06-10 02:00:17 +00:00
|
|
|
if err != nil {
|
2023-10-22 09:41:20 +00:00
|
|
|
return nil, err
|
2023-06-10 02:00:17 +00:00
|
|
|
}
|
2023-10-22 09:41:20 +00:00
|
|
|
|
|
|
|
state, err := m.persistence.GetActivityCenterState()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
response := &MessengerResponse{}
|
|
|
|
response.SetActivityCenterState(state)
|
|
|
|
if !sync {
|
|
|
|
notifications, err := m.persistence.GetActivityCenterNotificationsByID(ids)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
response2, err := m.processActivityCenterNotifications(notifications, true)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
err = response2.Merge(response)
|
|
|
|
return response, err
|
|
|
|
}
|
2023-11-02 15:07:03 +00:00
|
|
|
return response, m.syncActivityCenterDismissedByIDs(ctx, ids, updatedAt)
|
2023-02-24 23:47:04 +00:00
|
|
|
}
|
|
|
|
|
2023-01-28 09:52:53 +00:00
|
|
|
func (m *Messenger) ActivityCenterNotification(id types.HexBytes) (*ActivityCenterNotification, error) {
|
2023-09-19 17:17:11 +00:00
|
|
|
notification, err := m.persistence.GetActivityCenterNotificationByID(id)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
if notification.Message != nil {
|
|
|
|
image := notification.Message.GetImage()
|
|
|
|
if image != nil && image.AlbumId != "" {
|
|
|
|
album, err := m.persistence.albumMessages(notification.Message.LocalChatID, image.AlbumId)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
notification.AlbumMessages = album
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return notification, nil
|
2023-01-28 09:52:53 +00:00
|
|
|
}
|
|
|
|
|
2023-08-18 11:39:59 +00:00
|
|
|
func (m *Messenger) HandleSyncActivityCenterRead(state *ReceivedMessageState, message *protobuf.SyncActivityCenterRead, statusMessage *v1protocol.StatusMessage) error {
|
2023-06-10 02:00:17 +00:00
|
|
|
resp, err := m.MarkActivityCenterNotificationsRead(context.TODO(), toHexBytes(message.Ids), message.Clock, false)
|
2021-12-02 14:23:02 +00:00
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return state.Response.Merge(resp)
|
|
|
|
}
|
|
|
|
|
2023-10-22 09:41:20 +00:00
|
|
|
func (m *Messenger) HandleSyncActivityCenterUnread(state *ReceivedMessageState, message *protobuf.SyncActivityCenterUnread, statusMessage *v1protocol.StatusMessage) error {
|
|
|
|
resp, err := m.MarkActivityCenterNotificationsUnread(context.TODO(), toHexBytes(message.Ids), message.Clock, false)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return state.Response.Merge(resp)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m *Messenger) HandleSyncActivityCenterDeleted(state *ReceivedMessageState, message *protobuf.SyncActivityCenterDeleted, statusMessage *v1protocol.StatusMessage) error {
|
|
|
|
response, err := m.MarkActivityCenterNotificationsDeleted(context.TODO(), toHexBytes(message.Ids), message.Clock, false)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return state.Response.Merge(response)
|
|
|
|
}
|
|
|
|
|
2023-08-18 11:39:59 +00:00
|
|
|
func (m *Messenger) HandleSyncActivityCenterAccepted(state *ReceivedMessageState, message *protobuf.SyncActivityCenterAccepted, statusMessage *v1protocol.StatusMessage) error {
|
2023-06-10 02:00:17 +00:00
|
|
|
resp, err := m.AcceptActivityCenterNotifications(context.TODO(), toHexBytes(message.Ids), message.Clock, false)
|
2021-12-02 14:23:02 +00:00
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return state.Response.Merge(resp)
|
|
|
|
}
|
|
|
|
|
2023-08-18 11:39:59 +00:00
|
|
|
func (m *Messenger) HandleSyncActivityCenterDismissed(state *ReceivedMessageState, message *protobuf.SyncActivityCenterDismissed, statusMessage *v1protocol.StatusMessage) error {
|
2023-06-10 02:00:17 +00:00
|
|
|
resp, err := m.DismissActivityCenterNotifications(context.TODO(), toHexBytes(message.Ids), message.Clock, false)
|
2021-12-02 14:23:02 +00:00
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return state.Response.Merge(resp)
|
|
|
|
}
|
2023-06-10 02:00:17 +00:00
|
|
|
|
2023-10-26 04:17:18 +00:00
|
|
|
func (m *Messenger) HandleSyncActivityCenterCommunityRequestDecision(state *ReceivedMessageState, a *protobuf.SyncActivityCenterCommunityRequestDecision, statusMessage *v1protocol.StatusMessage) error {
|
|
|
|
notification, err := m.persistence.GetActivityCenterNotificationByID(a.Id)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if notification == nil {
|
|
|
|
return errors.New("[HandleSyncActivityCenterCommunityRequestDecision] notification not found")
|
|
|
|
}
|
|
|
|
|
|
|
|
notification.MembershipStatus = ActivityCenterMembershipStatus(a.MembershipStatus)
|
|
|
|
notification.UpdatedAt = a.Clock
|
|
|
|
if a.Decision == protobuf.SyncActivityCenterCommunityRequestDecision_DECLINED {
|
|
|
|
notification.Dismissed = true
|
|
|
|
} else if a.Decision == protobuf.SyncActivityCenterCommunityRequestDecision_ACCEPTED {
|
|
|
|
notification.Accepted = true
|
|
|
|
} else {
|
|
|
|
return errors.New("[HandleSyncActivityCenterCommunityRequestDecision] invalid decision")
|
|
|
|
}
|
|
|
|
_, err = m.persistence.SaveActivityCenterNotification(notification, false)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
resp := state.Response
|
|
|
|
resp.AddActivityCenterNotification(notification)
|
|
|
|
|
|
|
|
s, err := m.persistence.UpdateActivityCenterState(notification.UpdatedAt)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
resp.SetActivityCenterState(s)
|
|
|
|
return nil
|
|
|
|
}
|