refactor(chat)_: remove concept of ChannelGroup and remove api functions (#4997)
For status-im/status-desktop#12595
This commit is contained in:
parent
eb6ebade8e
commit
8f50b578d1
|
@ -108,6 +108,7 @@ type CommunityChat struct {
|
||||||
Permissions *protobuf.CommunityPermissions `json:"permissions"`
|
Permissions *protobuf.CommunityPermissions `json:"permissions"`
|
||||||
CanPost bool `json:"canPost"`
|
CanPost bool `json:"canPost"`
|
||||||
CanView bool `json:"canView"`
|
CanView bool `json:"canView"`
|
||||||
|
CanPostReactions bool `json:"canPostReactions"`
|
||||||
ViewersCanPostReactions bool `json:"viewersCanPostReactions"`
|
ViewersCanPostReactions bool `json:"viewersCanPostReactions"`
|
||||||
Position int `json:"position"`
|
Position int `json:"position"`
|
||||||
CategoryID string `json:"categoryID"`
|
CategoryID string `json:"categoryID"`
|
||||||
|
@ -185,12 +186,16 @@ func (o *Community) MarshalPublicAPIJSON() ([]byte, error) {
|
||||||
communityItem.Encrypted = o.Encrypted()
|
communityItem.Encrypted = o.Encrypted()
|
||||||
}
|
}
|
||||||
for id, c := range o.config.CommunityDescription.Chats {
|
for id, c := range o.config.CommunityDescription.Chats {
|
||||||
// NOTE: Here `CanPost` is only set for ChatMessage. But it can be different for reactions/pin/etc.
|
// NOTE: Here `CanPost` is only set for ChatMessage and Emoji reactions. But it can be different for pin/etc.
|
||||||
// Consider adding more properties to `CommunityChat` to reflect that.
|
// Consider adding more properties to `CommunityChat` to reflect that.
|
||||||
canPost, err := o.CanPost(o.config.MemberIdentity, id, protobuf.ApplicationMetadataMessage_CHAT_MESSAGE)
|
canPost, err := o.CanPost(o.config.MemberIdentity, id, protobuf.ApplicationMetadataMessage_CHAT_MESSAGE)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
canPostReactions, err := o.CanPost(o.config.MemberIdentity, id, protobuf.ApplicationMetadataMessage_EMOJI_REACTION)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
canView := o.CanView(o.config.MemberIdentity, id)
|
canView := o.CanView(o.config.MemberIdentity, id)
|
||||||
|
|
||||||
chat := CommunityChat{
|
chat := CommunityChat{
|
||||||
|
@ -203,6 +208,7 @@ func (o *Community) MarshalPublicAPIJSON() ([]byte, error) {
|
||||||
Members: c.Members,
|
Members: c.Members,
|
||||||
CanPost: canPost,
|
CanPost: canPost,
|
||||||
CanView: canView,
|
CanView: canView,
|
||||||
|
CanPostReactions: canPostReactions,
|
||||||
ViewersCanPostReactions: c.ViewersCanPostReactions,
|
ViewersCanPostReactions: c.ViewersCanPostReactions,
|
||||||
TokenGated: o.channelEncrypted(id),
|
TokenGated: o.channelEncrypted(id),
|
||||||
CategoryID: c.CategoryId,
|
CategoryID: c.CategoryId,
|
||||||
|
@ -335,6 +341,10 @@ func (o *Community) MarshalJSON() ([]byte, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
canPostReactions, err := o.CanPost(o.config.MemberIdentity, id, protobuf.ApplicationMetadataMessage_EMOJI_REACTION)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
canView := o.CanView(o.config.MemberIdentity, id)
|
canView := o.CanView(o.config.MemberIdentity, id)
|
||||||
|
|
||||||
chat := CommunityChat{
|
chat := CommunityChat{
|
||||||
|
@ -347,6 +357,7 @@ func (o *Community) MarshalJSON() ([]byte, error) {
|
||||||
Members: c.Members,
|
Members: c.Members,
|
||||||
CanPost: canPost,
|
CanPost: canPost,
|
||||||
CanView: canView,
|
CanView: canView,
|
||||||
|
CanPostReactions: canPostReactions,
|
||||||
ViewersCanPostReactions: c.ViewersCanPostReactions,
|
ViewersCanPostReactions: c.ViewersCanPostReactions,
|
||||||
TokenGated: o.channelEncrypted(id),
|
TokenGated: o.channelEncrypted(id),
|
||||||
CategoryID: c.CategoryId,
|
CategoryID: c.CategoryId,
|
||||||
|
|
|
@ -3,119 +3,20 @@ package chat
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
|
||||||
"github.com/status-im/status-go/eth-node/crypto"
|
|
||||||
"github.com/status-im/status-go/eth-node/types"
|
"github.com/status-im/status-go/eth-node/types"
|
||||||
"github.com/status-im/status-go/images"
|
"github.com/status-im/status-go/images"
|
||||||
"github.com/status-im/status-go/protocol"
|
"github.com/status-im/status-go/protocol"
|
||||||
"github.com/status-im/status-go/protocol/common"
|
|
||||||
"github.com/status-im/status-go/protocol/common/shard"
|
|
||||||
"github.com/status-im/status-go/protocol/communities"
|
|
||||||
"github.com/status-im/status-go/protocol/protobuf"
|
|
||||||
"github.com/status-im/status-go/protocol/requests"
|
|
||||||
v1protocol "github.com/status-im/status-go/protocol/v1"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ErrChatNotFound = errors.New("can't find chat")
|
ErrChatNotFound = errors.New("can't find chat")
|
||||||
ErrCommunityNotFound = errors.New("can't find community")
|
|
||||||
ErrCommunitiesNotSupported = errors.New("communities are not supported")
|
ErrCommunitiesNotSupported = errors.New("communities are not supported")
|
||||||
ErrChatTypeNotSupported = errors.New("chat type not supported")
|
ErrChatTypeNotSupported = errors.New("chat type not supported")
|
||||||
)
|
)
|
||||||
|
|
||||||
type ChannelGroupType string
|
|
||||||
|
|
||||||
const Personal ChannelGroupType = "personal"
|
|
||||||
const Community ChannelGroupType = "community"
|
|
||||||
|
|
||||||
type PinnedMessages struct {
|
|
||||||
Cursor string
|
|
||||||
PinnedMessages []*common.PinnedMessage
|
|
||||||
}
|
|
||||||
|
|
||||||
type Member struct {
|
|
||||||
// Community Role
|
|
||||||
Role protobuf.CommunityMember_Roles `json:"role,omitempty"`
|
|
||||||
// Joined indicates if the member has joined the group chat
|
|
||||||
Joined bool `json:"joined"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type Chat struct {
|
|
||||||
ID string `json:"id"`
|
|
||||||
Name string `json:"name"`
|
|
||||||
Description string `json:"description"`
|
|
||||||
Color string `json:"color"`
|
|
||||||
Emoji string `json:"emoji"`
|
|
||||||
Active bool `json:"active"`
|
|
||||||
ChatType protocol.ChatType `json:"chatType"`
|
|
||||||
Timestamp int64 `json:"timestamp"`
|
|
||||||
LastClockValue uint64 `json:"lastClockValue"`
|
|
||||||
DeletedAtClockValue uint64 `json:"deletedAtClockValue"`
|
|
||||||
ReadMessagesAtClockValue uint64 `json:"readMessagesAtClockValue"`
|
|
||||||
UnviewedMessagesCount uint `json:"unviewedMessagesCount"`
|
|
||||||
UnviewedMentionsCount uint `json:"unviewedMentionsCount"`
|
|
||||||
LastMessage *common.Message `json:"lastMessage"`
|
|
||||||
Members map[string]Member `json:"members,omitempty"`
|
|
||||||
MembershipUpdates []v1protocol.MembershipUpdateEvent `json:"membershipUpdateEvents"`
|
|
||||||
Alias string `json:"alias,omitempty"`
|
|
||||||
Identicon string `json:"identicon"`
|
|
||||||
Muted bool `json:"muted"`
|
|
||||||
InvitationAdmin string `json:"invitationAdmin,omitempty"`
|
|
||||||
ReceivedInvitationAdmin string `json:"receivedInvitationAdmin,omitempty"`
|
|
||||||
Profile string `json:"profile,omitempty"`
|
|
||||||
CommunityID string `json:"communityId"`
|
|
||||||
CategoryID string `json:"categoryId"`
|
|
||||||
Position int32 `json:"position,omitempty"`
|
|
||||||
Permissions *protobuf.CommunityPermissions `json:"permissions,omitempty"`
|
|
||||||
Joined int64 `json:"joined,omitempty"`
|
|
||||||
SyncedTo uint32 `json:"syncedTo,omitempty"`
|
|
||||||
SyncedFrom uint32 `json:"syncedFrom,omitempty"`
|
|
||||||
FirstMessageTimestamp uint32 `json:"firstMessageTimestamp,omitempty"`
|
|
||||||
Highlight bool `json:"highlight,omitempty"`
|
|
||||||
PinnedMessages *PinnedMessages `json:"pinnedMessages,omitempty"`
|
|
||||||
// Deprecated: CanPost is deprecated in favor of CanPostMessages/CanPostReactions/etc.
|
|
||||||
// For now CanPost will equal to CanPostMessages.
|
|
||||||
CanPost bool `json:"canPost"`
|
|
||||||
CanPostMessages bool `json:"canPostMessages"`
|
|
||||||
CanPostReactions bool `json:"canPostReactions"`
|
|
||||||
ViewersCanPostReactions bool `json:"viewersCanPostReactions"`
|
|
||||||
Base64Image string `json:"image,omitempty"`
|
|
||||||
HideIfPermissionsNotMet bool `json:"hideIfPermissionsNotMet,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type ChannelGroup struct {
|
|
||||||
Type ChannelGroupType `json:"channelGroupType"`
|
|
||||||
Name string `json:"name"`
|
|
||||||
Images map[string]images.IdentityImage `json:"images"`
|
|
||||||
Color string `json:"color"`
|
|
||||||
Chats map[string]*Chat `json:"chats"`
|
|
||||||
Categories map[string]communities.CommunityCategory `json:"categories"`
|
|
||||||
EnsName string `json:"ensName"`
|
|
||||||
MemberRole protobuf.CommunityMember_Roles `json:"memberRole"`
|
|
||||||
Verified bool `json:"verified"`
|
|
||||||
Description string `json:"description"`
|
|
||||||
IntroMessage string `json:"introMessage"`
|
|
||||||
OutroMessage string `json:"outroMessage"`
|
|
||||||
Tags []communities.CommunityTag `json:"tags"`
|
|
||||||
Permissions *protobuf.CommunityPermissions `json:"permissions"`
|
|
||||||
Members map[string]*protobuf.CommunityMember `json:"members"`
|
|
||||||
CanManageUsers bool `json:"canManageUsers"`
|
|
||||||
Muted bool `json:"muted"`
|
|
||||||
BanList []string `json:"banList"`
|
|
||||||
Encrypted bool `json:"encrypted"`
|
|
||||||
CommunityTokensMetadata []*protobuf.CommunityTokenMetadata `json:"communityTokensMetadata"`
|
|
||||||
UnviewedMessagesCount int `json:"unviewedMessagesCount"`
|
|
||||||
UnviewedMentionsCount int `json:"unviewedMentionsCount"`
|
|
||||||
CheckChannelPermissionResponses map[string]*communities.CheckChannelPermissionsResponse `json:"checkChannelPermissionResponses"`
|
|
||||||
PubsubTopic string `json:"pubsubTopic"`
|
|
||||||
PubsubTopicKey string `json:"pubsubTopicKey"`
|
|
||||||
Shard *shard.Shard `json:"shard"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewAPI(service *Service) *API {
|
func NewAPI(service *Service) *API {
|
||||||
return &API{
|
return &API{
|
||||||
s: service,
|
s: service,
|
||||||
|
@ -128,431 +29,7 @@ type API struct {
|
||||||
log log.Logger
|
log log.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
func unique(communities []*communities.Community) (result []*communities.Community) {
|
func (api *API) EditChat(ctx context.Context, communityID types.HexBytes, chatID string, name string, color string, image images.CroppedImage) (*protocol.MessengerResponse, error) {
|
||||||
inResult := make(map[string]bool)
|
|
||||||
for _, community := range communities {
|
|
||||||
if _, ok := inResult[community.IDString()]; !ok {
|
|
||||||
inResult[community.IDString()] = true
|
|
||||||
result = append(result, community)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
func (api *API) getChannelGroups(ctx context.Context, channelGroupID string) (map[string]ChannelGroup, error) {
|
|
||||||
joinedCommunities, err := api.s.messenger.JoinedCommunities()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
spectatedCommunities, err := api.s.messenger.SpectatedCommunities()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
pubKey := types.EncodeHex(crypto.FromECDSAPub(api.s.messenger.IdentityPublicKey()))
|
|
||||||
|
|
||||||
result := make(map[string]ChannelGroup)
|
|
||||||
|
|
||||||
// Get chats from cache to get unviewed messages counts
|
|
||||||
channels := api.s.messenger.Chats()
|
|
||||||
totalUnviewedMessageCount := 0
|
|
||||||
totalUnviewedMentionsCount := 0
|
|
||||||
|
|
||||||
if channelGroupID == "" || channelGroupID == pubKey {
|
|
||||||
chats := make(map[string]*Chat)
|
|
||||||
for _, chat := range channels {
|
|
||||||
if !chat.IsActivePersonalChat() {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if !chat.Muted || chat.UnviewedMentionsCount > 0 {
|
|
||||||
totalUnviewedMessageCount += int(chat.UnviewedMessagesCount)
|
|
||||||
}
|
|
||||||
totalUnviewedMentionsCount += int(chat.UnviewedMentionsCount)
|
|
||||||
|
|
||||||
c, err := api.toAPIChat(chat, nil, pubKey, true)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
chats[chat.ID] = c
|
|
||||||
}
|
|
||||||
|
|
||||||
result[pubKey] = ChannelGroup{
|
|
||||||
Type: Personal,
|
|
||||||
Name: "",
|
|
||||||
Images: make(map[string]images.IdentityImage),
|
|
||||||
Color: "",
|
|
||||||
Chats: chats,
|
|
||||||
Categories: make(map[string]communities.CommunityCategory),
|
|
||||||
EnsName: "", // Not implemented yet in communities
|
|
||||||
MemberRole: protobuf.CommunityMember_ROLE_OWNER,
|
|
||||||
Verified: true,
|
|
||||||
Description: "",
|
|
||||||
IntroMessage: "",
|
|
||||||
OutroMessage: "",
|
|
||||||
Tags: []communities.CommunityTag{},
|
|
||||||
Permissions: &protobuf.CommunityPermissions{},
|
|
||||||
Muted: false,
|
|
||||||
CommunityTokensMetadata: []*protobuf.CommunityTokenMetadata{},
|
|
||||||
UnviewedMessagesCount: totalUnviewedMessageCount,
|
|
||||||
UnviewedMentionsCount: totalUnviewedMentionsCount,
|
|
||||||
CheckChannelPermissionResponses: make(map[string]*communities.CheckChannelPermissionsResponse),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if channelGroupID == pubKey {
|
|
||||||
// They asked for the personal channel group only, so we return now
|
|
||||||
return result, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, community := range unique(append(joinedCommunities, spectatedCommunities...)) {
|
|
||||||
if channelGroupID != "" && channelGroupID != community.IDString() {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
totalUnviewedMessageCount = 0
|
|
||||||
totalUnviewedMentionsCount = 0
|
|
||||||
|
|
||||||
for _, chat := range channels {
|
|
||||||
if chat.CommunityID != community.IDString() || !chat.Active {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if !chat.Muted || chat.UnviewedMentionsCount > 0 {
|
|
||||||
totalUnviewedMessageCount += int(chat.UnviewedMessagesCount)
|
|
||||||
}
|
|
||||||
totalUnviewedMentionsCount += int(chat.UnviewedMentionsCount)
|
|
||||||
}
|
|
||||||
|
|
||||||
chGrp := ChannelGroup{
|
|
||||||
Type: Community,
|
|
||||||
Name: community.Name(),
|
|
||||||
Color: community.Color(),
|
|
||||||
Images: make(map[string]images.IdentityImage),
|
|
||||||
Chats: make(map[string]*Chat),
|
|
||||||
Categories: make(map[string]communities.CommunityCategory),
|
|
||||||
MemberRole: community.MemberRole(community.MemberIdentity()),
|
|
||||||
Verified: community.Verified(),
|
|
||||||
Description: community.DescriptionText(),
|
|
||||||
IntroMessage: community.IntroMessage(),
|
|
||||||
OutroMessage: community.OutroMessage(),
|
|
||||||
Tags: community.Tags(),
|
|
||||||
Permissions: community.Description().Permissions,
|
|
||||||
Members: community.Description().Members,
|
|
||||||
CanManageUsers: community.CanManageUsers(community.MemberIdentity()),
|
|
||||||
Muted: community.Muted(),
|
|
||||||
BanList: community.Description().BanList,
|
|
||||||
Encrypted: community.Encrypted(),
|
|
||||||
CommunityTokensMetadata: community.Description().CommunityTokensMetadata,
|
|
||||||
UnviewedMessagesCount: totalUnviewedMessageCount,
|
|
||||||
UnviewedMentionsCount: totalUnviewedMentionsCount,
|
|
||||||
CheckChannelPermissionResponses: make(map[string]*communities.CheckChannelPermissionsResponse),
|
|
||||||
PubsubTopic: community.PubsubTopic(),
|
|
||||||
PubsubTopicKey: community.PubsubTopicKey(),
|
|
||||||
Shard: community.Shard(),
|
|
||||||
}
|
|
||||||
|
|
||||||
for t, i := range community.Images() {
|
|
||||||
chGrp.Images[t] = images.IdentityImage{Name: t, Payload: i.Payload}
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, cat := range community.Categories() {
|
|
||||||
chGrp.Categories[cat.CategoryId] = communities.CommunityCategory{
|
|
||||||
ID: cat.CategoryId,
|
|
||||||
Name: cat.Name,
|
|
||||||
Position: int(cat.Position),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, chat := range channels {
|
|
||||||
if chat.CommunityID == community.IDString() && chat.Active {
|
|
||||||
_, exists := community.Chats()[chat.CommunityChatID()]
|
|
||||||
if !exists {
|
|
||||||
api.log.Warn("Chat not found in the community", "chat.ID", chat.ID)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
c, err := api.toAPIChat(chat, community, pubKey, true)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
chGrp.Chats[c.ID] = c
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
response, err := api.s.messenger.GetCommunityCheckChannelPermissionResponses(community.ID())
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
chGrp.CheckChannelPermissionResponses = response.Channels
|
|
||||||
|
|
||||||
result[community.IDString()] = chGrp
|
|
||||||
|
|
||||||
if channelGroupID == community.IDString() {
|
|
||||||
// We asked for this particular community, so we return now
|
|
||||||
return result, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (api *API) GetChannelGroups(ctx context.Context) (map[string]ChannelGroup, error) {
|
|
||||||
return api.getChannelGroups(ctx, "")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (api *API) GetChannelGroupByID(ctx context.Context, channelGroupID string) (map[string]ChannelGroup, error) {
|
|
||||||
return api.getChannelGroups(ctx, channelGroupID)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (api *API) GetChat(ctx context.Context, communityID types.HexBytes, chatID string) (*Chat, error) {
|
|
||||||
pubKey := types.EncodeHex(crypto.FromECDSAPub(api.s.messenger.IdentityPublicKey()))
|
|
||||||
messengerChat, community, err := api.getChatAndCommunity(pubKey, communityID, chatID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if messengerChat == nil {
|
|
||||||
return nil, ErrChatNotFound
|
|
||||||
}
|
|
||||||
|
|
||||||
result, err := api.toAPIChat(messengerChat, community, pubKey, false)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return result, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (api *API) GetMembers(ctx context.Context, communityID types.HexBytes, chatID string) (map[string]Member, error) {
|
|
||||||
pubKey := types.EncodeHex(crypto.FromECDSAPub(api.s.messenger.IdentityPublicKey()))
|
|
||||||
messengerChat, community, err := api.getChatAndCommunity(pubKey, communityID, chatID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return getChatMembers(messengerChat, community, pubKey)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (api *API) JoinChat(ctx context.Context, communityID types.HexBytes, chatID string) (*Chat, error) {
|
|
||||||
if len(communityID) != 0 {
|
|
||||||
return nil, ErrCommunitiesNotSupported
|
|
||||||
}
|
|
||||||
|
|
||||||
response, err := api.s.messenger.CreatePublicChat(&requests.CreatePublicChat{ID: chatID})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
pubKey := types.EncodeHex(crypto.FromECDSAPub(api.s.messenger.IdentityPublicKey()))
|
|
||||||
|
|
||||||
return api.toAPIChat(response.Chats()[0], nil, pubKey, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (api *API) toAPIChat(protocolChat *protocol.Chat, community *communities.Community, pubKey string, skipPinnedMessages bool) (*Chat, error) {
|
|
||||||
chat := &Chat{
|
|
||||||
ID: strings.TrimPrefix(protocolChat.ID, protocolChat.CommunityID),
|
|
||||||
Name: protocolChat.Name,
|
|
||||||
Description: protocolChat.Description,
|
|
||||||
Color: protocolChat.Color,
|
|
||||||
Emoji: protocolChat.Emoji,
|
|
||||||
Active: protocolChat.Active,
|
|
||||||
ChatType: protocolChat.ChatType,
|
|
||||||
Timestamp: protocolChat.Timestamp,
|
|
||||||
LastClockValue: protocolChat.LastClockValue,
|
|
||||||
DeletedAtClockValue: protocolChat.DeletedAtClockValue,
|
|
||||||
ReadMessagesAtClockValue: protocolChat.ReadMessagesAtClockValue,
|
|
||||||
UnviewedMessagesCount: protocolChat.UnviewedMessagesCount,
|
|
||||||
UnviewedMentionsCount: protocolChat.UnviewedMentionsCount,
|
|
||||||
LastMessage: protocolChat.LastMessage,
|
|
||||||
MembershipUpdates: protocolChat.MembershipUpdates,
|
|
||||||
Alias: protocolChat.Alias,
|
|
||||||
Identicon: protocolChat.Identicon,
|
|
||||||
Muted: protocolChat.Muted,
|
|
||||||
InvitationAdmin: protocolChat.InvitationAdmin,
|
|
||||||
ReceivedInvitationAdmin: protocolChat.ReceivedInvitationAdmin,
|
|
||||||
Profile: protocolChat.Profile,
|
|
||||||
CommunityID: protocolChat.CommunityID,
|
|
||||||
CategoryID: protocolChat.CategoryID,
|
|
||||||
Joined: protocolChat.Joined,
|
|
||||||
SyncedTo: protocolChat.SyncedTo,
|
|
||||||
SyncedFrom: protocolChat.SyncedFrom,
|
|
||||||
FirstMessageTimestamp: protocolChat.FirstMessageTimestamp,
|
|
||||||
Highlight: protocolChat.Highlight,
|
|
||||||
Base64Image: protocolChat.Base64Image,
|
|
||||||
}
|
|
||||||
|
|
||||||
if protocolChat.OneToOne() {
|
|
||||||
chat.Name = "" // Emptying since it contains non useful data
|
|
||||||
}
|
|
||||||
|
|
||||||
if !skipPinnedMessages {
|
|
||||||
pinnedMessages, cursor, err := api.s.messenger.PinnedMessageByChatID(protocolChat.ID, "", -1)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(pinnedMessages) != 0 {
|
|
||||||
chat.PinnedMessages = &PinnedMessages{
|
|
||||||
Cursor: cursor,
|
|
||||||
PinnedMessages: pinnedMessages,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
err := chat.populateCommunityFields(community)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
chatMembers, err := getChatMembers(protocolChat, community, pubKey)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
chat.Members = chatMembers
|
|
||||||
|
|
||||||
return chat, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func getChatMembers(sourceChat *protocol.Chat, community *communities.Community, userPubKey string) (map[string]Member, error) {
|
|
||||||
result := make(map[string]Member)
|
|
||||||
if sourceChat != nil {
|
|
||||||
if sourceChat.ChatType == protocol.ChatTypePrivateGroupChat && len(sourceChat.Members) > 0 {
|
|
||||||
for _, m := range sourceChat.Members {
|
|
||||||
result[m.ID] = Member{
|
|
||||||
Role: func() protobuf.CommunityMember_Roles {
|
|
||||||
if m.Admin {
|
|
||||||
return protobuf.CommunityMember_ROLE_OWNER
|
|
||||||
}
|
|
||||||
return protobuf.CommunityMember_ROLE_NONE
|
|
||||||
}(),
|
|
||||||
Joined: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if sourceChat.ChatType == protocol.ChatTypeOneToOne {
|
|
||||||
result[sourceChat.ID] = Member{
|
|
||||||
Joined: true,
|
|
||||||
}
|
|
||||||
result[userPubKey] = Member{
|
|
||||||
Joined: true,
|
|
||||||
}
|
|
||||||
return result, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if community != nil {
|
|
||||||
channel, exists := community.Chats()[sourceChat.CommunityChatID()]
|
|
||||||
if !exists {
|
|
||||||
// Skip unknown community chats. They might be channels that were deleted. We shouldn't get here
|
|
||||||
return result, nil
|
|
||||||
}
|
|
||||||
for member := range channel.Members {
|
|
||||||
pubKey, err := common.HexToPubkey(member)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
result[member] = Member{
|
|
||||||
Role: community.MemberRole(pubKey),
|
|
||||||
Joined: community.Joined(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (api *API) getCommunityByID(id string) (*communities.Community, error) {
|
|
||||||
communityID, err := hexutil.Decode(id)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
community, err := api.s.messenger.GetCommunityByID(communityID)
|
|
||||||
if community == nil && err == nil {
|
|
||||||
return nil, ErrCommunityNotFound
|
|
||||||
}
|
|
||||||
|
|
||||||
return community, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (chat *Chat) populateCommunityFields(community *communities.Community) error {
|
|
||||||
chat.CanPost = true
|
|
||||||
chat.CanPostMessages = true
|
|
||||||
chat.CanPostReactions = true
|
|
||||||
if community == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
commChat, exists := community.Chats()[chat.ID]
|
|
||||||
if !exists {
|
|
||||||
// Skip unknown community chats. They might be channels that were deleted
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
canPostMessages, err := community.CanMemberIdentityPost(chat.ID, protobuf.ApplicationMetadataMessage_CHAT_MESSAGE)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
canPostReactions, err := community.CanMemberIdentityPost(chat.ID, protobuf.ApplicationMetadataMessage_EMOJI_REACTION)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
chat.CategoryID = commChat.CategoryId
|
|
||||||
chat.HideIfPermissionsNotMet = commChat.HideIfPermissionsNotMet
|
|
||||||
chat.Position = commChat.Position
|
|
||||||
chat.Permissions = commChat.Permissions
|
|
||||||
chat.Emoji = commChat.Identity.Emoji
|
|
||||||
chat.Name = commChat.Identity.DisplayName
|
|
||||||
chat.Description = commChat.Identity.Description
|
|
||||||
chat.CanPost = canPostMessages
|
|
||||||
chat.CanPostMessages = canPostMessages
|
|
||||||
chat.CanPostReactions = canPostReactions
|
|
||||||
chat.ViewersCanPostReactions = commChat.ViewersCanPostReactions
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (api *API) getChatAndCommunity(pubKey string, communityID types.HexBytes, chatID string) (*protocol.Chat, *communities.Community, error) {
|
|
||||||
fullChatID := chatID
|
|
||||||
|
|
||||||
if string(communityID.Bytes()) == pubKey { // Obtaining chats from personal
|
|
||||||
communityID = []byte{}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(communityID) != 0 {
|
|
||||||
id := string(communityID.Bytes())
|
|
||||||
|
|
||||||
if chatID == "" {
|
|
||||||
community, err := api.getCommunityByID(id)
|
|
||||||
return nil, community, err
|
|
||||||
}
|
|
||||||
|
|
||||||
fullChatID = id + chatID
|
|
||||||
}
|
|
||||||
|
|
||||||
messengerChat := api.s.messenger.Chat(fullChatID)
|
|
||||||
if messengerChat == nil {
|
|
||||||
return nil, nil, ErrChatNotFound
|
|
||||||
}
|
|
||||||
|
|
||||||
var community *communities.Community
|
|
||||||
if messengerChat.CommunityID != "" {
|
|
||||||
var err error
|
|
||||||
community, err = api.getCommunityByID(messengerChat.CommunityID)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return messengerChat, community, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (api *API) EditChat(ctx context.Context, communityID types.HexBytes, chatID string, name string, color string, image images.CroppedImage) (*Chat, error) {
|
|
||||||
if len(communityID) != 0 {
|
if len(communityID) != 0 {
|
||||||
return nil, ErrCommunitiesNotSupported
|
return nil, ErrCommunitiesNotSupported
|
||||||
}
|
}
|
||||||
|
@ -571,6 +48,5 @@ func (api *API) EditChat(ctx context.Context, communityID types.HexBytes, chatID
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
pubKey := types.EncodeHex(crypto.FromECDSAPub(api.s.messenger.IdentityPublicKey()))
|
return response, nil
|
||||||
return api.toAPIChat(response.Chats()[0], nil, pubKey, false)
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,23 +11,23 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type GroupChatResponse struct {
|
type GroupChatResponse struct {
|
||||||
Chat *Chat `json:"chat"`
|
Chat *protocol.Chat `json:"chat"`
|
||||||
Messages []*common.Message `json:"messages"`
|
Messages []*common.Message `json:"messages"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type GroupChatResponseWithInvitations struct {
|
type GroupChatResponseWithInvitations struct {
|
||||||
Chat *Chat `json:"chat"`
|
Chat *protocol.Chat `json:"chat"`
|
||||||
Messages []*common.Message `json:"messages"`
|
Messages []*common.Message `json:"messages"`
|
||||||
Invitations []*protocol.GroupChatInvitation `json:"invitations"`
|
Invitations []*protocol.GroupChatInvitation `json:"invitations"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type CreateOneToOneChatResponse struct {
|
type CreateOneToOneChatResponse struct {
|
||||||
Chat *Chat `json:"chat,omitempty"`
|
Chat *protocol.Chat `json:"chat,omitempty"`
|
||||||
Contact *protocol.Contact `json:"contact,omitempty"`
|
Contact *protocol.Contact `json:"contact,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type StartGroupChatResponse struct {
|
type StartGroupChatResponse struct {
|
||||||
Chat *Chat `json:"chat,omitempty"`
|
Chat *protocol.Chat `json:"chat,omitempty"`
|
||||||
Contacts []*protocol.Contact `json:"contacts"`
|
Contacts []*protocol.Contact `json:"contacts"`
|
||||||
Messages []*common.Message `json:"messages,omitempty"`
|
Messages []*common.Message `json:"messages,omitempty"`
|
||||||
}
|
}
|
||||||
|
@ -37,16 +37,12 @@ func (api *API) CreateOneToOneChat(ctx context.Context, communityID types.HexByt
|
||||||
return nil, ErrCommunitiesNotSupported
|
return nil, ErrCommunitiesNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
pubKey := types.EncodeHex(crypto.FromECDSAPub(api.s.messenger.IdentityPublicKey()))
|
|
||||||
response, err := api.s.messenger.CreateOneToOneChat(&requests.CreateOneToOneChat{ID: ID, ENSName: ensName})
|
response, err := api.s.messenger.CreateOneToOneChat(&requests.CreateOneToOneChat{ID: ID, ENSName: ensName})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
chat, err := api.toAPIChat(response.Chats()[0], nil, pubKey, false)
|
chat := response.Chats()[0]
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var contact *protocol.Contact
|
var contact *protocol.Contact
|
||||||
if ensName != "" {
|
if ensName != "" {
|
||||||
|
@ -156,8 +152,6 @@ func (api *API) StartGroupChat(ctx context.Context, communityID types.HexBytes,
|
||||||
return nil, ErrCommunitiesNotSupported
|
return nil, ErrCommunitiesNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
pubKey := types.EncodeHex(crypto.FromECDSAPub(api.s.messenger.IdentityPublicKey()))
|
|
||||||
|
|
||||||
var response *protocol.MessengerResponse
|
var response *protocol.MessengerResponse
|
||||||
var err error
|
var err error
|
||||||
if len(members) == 1 {
|
if len(members) == 1 {
|
||||||
|
@ -178,10 +172,7 @@ func (api *API) StartGroupChat(ctx context.Context, communityID types.HexBytes,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
chat, err := api.toAPIChat(response.Chats()[0], nil, pubKey, false)
|
chat := response.Chats()[0]
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &StartGroupChatResponse{
|
return &StartGroupChatResponse{
|
||||||
Chat: chat,
|
Chat: chat,
|
||||||
|
@ -191,10 +182,7 @@ func (api *API) StartGroupChat(ctx context.Context, communityID types.HexBytes,
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *API) toGroupChatResponse(pubKey string, response *protocol.MessengerResponse) (*GroupChatResponse, error) {
|
func (api *API) toGroupChatResponse(pubKey string, response *protocol.MessengerResponse) (*GroupChatResponse, error) {
|
||||||
chat, err := api.toAPIChat(response.Chats()[0], nil, pubKey, false)
|
chat := response.Chats()[0]
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &GroupChatResponse{
|
return &GroupChatResponse{
|
||||||
Chat: chat,
|
Chat: chat,
|
||||||
|
|
|
@ -5,7 +5,6 @@ import (
|
||||||
|
|
||||||
"github.com/forPelevin/gomoji"
|
"github.com/forPelevin/gomoji"
|
||||||
|
|
||||||
"github.com/status-im/status-go/eth-node/crypto"
|
|
||||||
"github.com/status-im/status-go/eth-node/types"
|
"github.com/status-im/status-go/eth-node/types"
|
||||||
"github.com/status-im/status-go/protocol"
|
"github.com/status-im/status-go/protocol"
|
||||||
"github.com/status-im/status-go/protocol/common"
|
"github.com/status-im/status-go/protocol/common"
|
||||||
|
@ -13,7 +12,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type SendMessageResponse struct {
|
type SendMessageResponse struct {
|
||||||
Chat *Chat `json:"chat"`
|
Chat *protocol.Chat `json:"chat"`
|
||||||
Messages []*common.Message `json:"messages"`
|
Messages []*common.Message `json:"messages"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,18 +48,8 @@ func (api *API) SendSticker(ctx context.Context, communityID types.HexBytes, cha
|
||||||
func (api *API) toSendMessageResponse(response *protocol.MessengerResponse) (*SendMessageResponse, error) {
|
func (api *API) toSendMessageResponse(response *protocol.MessengerResponse) (*SendMessageResponse, error) {
|
||||||
protocolChat := response.Chats()[0]
|
protocolChat := response.Chats()[0]
|
||||||
|
|
||||||
community, err := api.s.messenger.GetCommunityByID(types.HexBytes(protocolChat.CommunityID))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
pubKey := types.EncodeHex(crypto.FromECDSAPub(api.s.messenger.IdentityPublicKey()))
|
|
||||||
chat, err := api.toAPIChat(protocolChat, community, pubKey, false)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &SendMessageResponse{
|
return &SendMessageResponse{
|
||||||
Chat: chat,
|
Chat: protocolChat,
|
||||||
Messages: response.Messages(),
|
Messages: response.Messages(),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue