package protocol import ( "encoding/json" "github.com/status-im/status-go/protocol/common" "github.com/status-im/status-go/protocol/communities" "github.com/status-im/status-go/protocol/encryption/multidevice" "github.com/status-im/status-go/protocol/transport" "github.com/status-im/status-go/services/mailservers" ) type MessengerResponse struct { Messages []*common.Message Contacts []*Contact Installations []*multidevice.Installation EmojiReactions []*EmojiReaction Invitations []*GroupChatInvitation CommunityChanges []*communities.CommunityChanges RequestsToJoinCommunity []*communities.RequestToJoin Filters []*transport.Filter RemovedFilters []*transport.Filter Mailservers []mailservers.Mailserver MailserverTopics []mailservers.MailserverTopic MailserverRanges []mailservers.ChatRequestRange // Notifications a list of MessageNotificationBody derived from received messages that are useful to notify the user about Notifications []MessageNotificationBody chats map[string]*Chat removedChats map[string]bool communities map[string]*communities.Community } func (r *MessengerResponse) MarshalJSON() ([]byte, error) { responseItem := struct { Chats []*Chat `json:"chats,omitempty"` RemovedChats []string `json:"removedChats,omitempty"` Messages []*common.Message `json:"messages,omitempty"` Contacts []*Contact `json:"contacts,omitempty"` Installations []*multidevice.Installation `json:"installations,omitempty"` EmojiReactions []*EmojiReaction `json:"emojiReactions,omitempty"` Invitations []*GroupChatInvitation `json:"invitations,omitempty"` CommunityChanges []*communities.CommunityChanges `json:"communityChanges,omitempty"` RequestsToJoinCommunity []*communities.RequestToJoin `json:"requestsToJoinCommunity,omitempty"` Filters []*transport.Filter `json:"filters,omitempty"` RemovedFilters []*transport.Filter `json:"removedFilters,omitempty"` Mailservers []mailservers.Mailserver `json:"mailservers,omitempty"` MailserverTopics []mailservers.MailserverTopic `json:"mailserverTopics,omitempty"` MailserverRanges []mailservers.ChatRequestRange `json:"mailserverRanges,omitempty"` // Notifications a list of MessageNotificationBody derived from received messages that are useful to notify the user about Notifications []MessageNotificationBody `json:"notifications"` Communities []*communities.Community `json:"communities,omitempty"` }{ Messages: r.Messages, Contacts: r.Contacts, Installations: r.Installations, EmojiReactions: r.EmojiReactions, Invitations: r.Invitations, CommunityChanges: r.CommunityChanges, RequestsToJoinCommunity: r.RequestsToJoinCommunity, Filters: r.Filters, RemovedFilters: r.RemovedFilters, Mailservers: r.Mailservers, MailserverTopics: r.MailserverTopics, MailserverRanges: r.MailserverRanges, Notifications: r.Notifications, } responseItem.Chats = r.Chats() responseItem.Communities = r.Communities() responseItem.RemovedChats = r.RemovedChats() return json.Marshal(responseItem) } func (r *MessengerResponse) Chats() []*Chat { var chats []*Chat for _, chat := range r.chats { chats = append(chats, chat) } return chats } func (r *MessengerResponse) RemovedChats() []string { var chats []string for chatID := range r.removedChats { chats = append(chats, chatID) } return chats } func (r *MessengerResponse) Communities() []*communities.Community { var communities []*communities.Community for _, c := range r.communities { communities = append(communities, c) } return communities } func (r *MessengerResponse) IsEmpty() bool { return len(r.chats)+ len(r.Messages)+ len(r.Contacts)+ len(r.Installations)+ len(r.Invitations)+ len(r.EmojiReactions)+ len(r.communities)+ len(r.CommunityChanges)+ len(r.Filters)+ len(r.RemovedFilters)+ len(r.removedChats)+ len(r.MailserverTopics)+ len(r.Mailservers)+ len(r.MailserverRanges)+ len(r.Notifications)+ len(r.RequestsToJoinCommunity) == 0 } // Merge takes another response and appends the new Chats & new Messages and replaces // the existing Messages & Chats if they have the same ID func (r *MessengerResponse) Merge(response *MessengerResponse) error { if len(response.Contacts)+ len(response.Installations)+ len(response.EmojiReactions)+ len(response.Invitations)+ len(response.RequestsToJoinCommunity)+ len(response.Mailservers)+ len(response.MailserverTopics)+ len(response.MailserverRanges)+ len(response.Notifications)+ len(response.EmojiReactions)+ len(response.CommunityChanges) != 0 { return ErrNotImplemented } r.AddChats(response.Chats()) r.AddRemovedChats(response.RemovedChats()) r.overrideMessages(response.Messages) r.overrideFilters(response.Filters) r.overrideRemovedFilters(response.Filters) r.AddCommunities(response.Communities()) return nil } // overrideMessages append new messages and override existing ones in response.Messages func (r *MessengerResponse) overrideMessages(messages []*common.Message) { for _, overrideMessage := range messages { var found = false for idx, chat := range r.Messages { if chat.ID == overrideMessage.ID { r.Messages[idx] = overrideMessage found = true } } if !found { r.Messages = append(r.Messages, overrideMessage) } } } // overrideFilters append new filters and override existing ones in response.Filters func (r *MessengerResponse) overrideFilters(filters []*transport.Filter) { for _, overrideFilter := range filters { var found = false for idx, filter := range r.Filters { if filter.FilterID == overrideFilter.FilterID { r.Filters[idx] = overrideFilter found = true } } if !found { r.Filters = append(r.Filters, overrideFilter) } } } // overrideRemovedFilters append removed filters and override existing ones in response.Filters func (r *MessengerResponse) overrideRemovedFilters(filters []*transport.Filter) { for _, overrideFilter := range filters { var found = false for idx, filter := range r.RemovedFilters { if filter.FilterID == overrideFilter.FilterID { r.RemovedFilters[idx] = overrideFilter found = true } } if !found { r.RemovedFilters = append(r.RemovedFilters, overrideFilter) } } } func (r *MessengerResponse) AddCommunities(communities []*communities.Community) { for _, overrideCommunity := range communities { r.AddCommunity(overrideCommunity) } } func (r *MessengerResponse) AddCommunity(c *communities.Community) { if r.communities == nil { r.communities = make(map[string]*communities.Community) } r.communities[c.IDString()] = c } func (r *MessengerResponse) AddChat(c *Chat) { if r.chats == nil { r.chats = make(map[string]*Chat) } r.chats[c.ID] = c } func (r *MessengerResponse) AddChats(chats []*Chat) { for _, c := range chats { r.AddChat(c) } } func (r *MessengerResponse) AddRemovedChats(chats []string) { for _, c := range chats { r.AddRemovedChat(c) } } func (r *MessengerResponse) AddRemovedChat(chatID string) { if r.removedChats == nil { r.removedChats = make(map[string]bool) } r.removedChats[chatID] = true }