status-im/status-go

View on GitHub
services/chat/api_group_chats.go

Summary

Maintainability
A
0 mins
Test Coverage
F
0%
package chat

import (
    "context"

    "github.com/status-im/status-go/eth-node/crypto"
    "github.com/status-im/status-go/eth-node/types"
    "github.com/status-im/status-go/protocol"
    "github.com/status-im/status-go/protocol/common"
    "github.com/status-im/status-go/protocol/requests"
)

type GroupChatResponse struct {
    Chat     *protocol.Chat    `json:"chat"`
    Messages []*common.Message `json:"messages"`
}

type GroupChatResponseWithInvitations struct {
    Chat        *protocol.Chat                  `json:"chat"`
    Messages    []*common.Message               `json:"messages"`
    Invitations []*protocol.GroupChatInvitation `json:"invitations"`
}

type CreateOneToOneChatResponse struct {
    Chat    *protocol.Chat    `json:"chat,omitempty"`
    Contact *protocol.Contact `json:"contact,omitempty"`
}

type StartGroupChatResponse struct {
    Chat     *protocol.Chat      `json:"chat,omitempty"`
    Contacts []*protocol.Contact `json:"contacts"`
    Messages []*common.Message   `json:"messages,omitempty"`
}

func (api *API) CreateOneToOneChat(ctx context.Context, communityID types.HexBytes, ID types.HexBytes, ensName string) (*CreateOneToOneChatResponse, error) {
    if len(communityID) != 0 {
        return nil, ErrCommunitiesNotSupported
    }

    response, err := api.s.messenger.CreateOneToOneChat(&requests.CreateOneToOneChat{ID: ID, ENSName: ensName})
    if err != nil {
        return nil, err
    }

    chat := response.Chats()[0]

    var contact *protocol.Contact
    if ensName != "" {
        contact = response.Contacts[0]
    }

    return &CreateOneToOneChatResponse{
        Chat:    chat,
        Contact: contact,
    }, nil
}

func (api *API) CreateGroupChat(ctx context.Context, communityID types.HexBytes, name string, members []string) (*GroupChatResponse, error) {
    if len(communityID) != 0 {
        return nil, ErrCommunitiesNotSupported
    }

    return api.execAndGetGroupChatResponse(func() (*protocol.MessengerResponse, error) {
        return api.s.messenger.CreateGroupChatWithMembers(ctx, name, members)
    })
}

func (api *API) CreateGroupChatFromInvitation(communityID types.HexBytes, name string, chatID string, adminPK string) (*GroupChatResponse, error) {
    if len(communityID) != 0 {
        return nil, ErrCommunitiesNotSupported
    }

    return api.execAndGetGroupChatResponse(func() (*protocol.MessengerResponse, error) {
        return api.s.messenger.CreateGroupChatFromInvitation(name, chatID, adminPK)
    })
}

func (api *API) LeaveChat(ctx context.Context, communityID types.HexBytes, chatID string, remove bool) (*GroupChatResponse, error) {
    if len(communityID) != 0 {
        return nil, ErrCommunitiesNotSupported
    }

    return api.execAndGetGroupChatResponse(func() (*protocol.MessengerResponse, error) {
        return api.s.messenger.LeaveGroupChat(ctx, chatID, remove)
    })
}

func (api *API) AddMembers(ctx context.Context, communityID types.HexBytes, chatID string, members []string) (*GroupChatResponseWithInvitations, error) {
    if len(communityID) != 0 {
        return nil, ErrCommunitiesNotSupported
    }

    return api.execAndGetGroupChatResponseWithInvitations(func() (*protocol.MessengerResponse, error) {
        return api.s.messenger.AddMembersToGroupChat(ctx, chatID, members)
    })
}

func (api *API) RemoveMember(ctx context.Context, communityID types.HexBytes, chatID string, member string) (*GroupChatResponse, error) {
    if len(communityID) != 0 {
        return nil, ErrCommunitiesNotSupported
    }

    return api.execAndGetGroupChatResponse(func() (*protocol.MessengerResponse, error) {
        return api.s.messenger.RemoveMembersFromGroupChat(ctx, chatID, []string{member})
    })
}

func (api *API) MakeAdmin(ctx context.Context, communityID types.HexBytes, chatID string, member string) (*GroupChatResponse, error) {
    if len(communityID) != 0 {
        return nil, ErrCommunitiesNotSupported
    }

    return api.execAndGetGroupChatResponse(func() (*protocol.MessengerResponse, error) {
        return api.s.messenger.AddAdminsToGroupChat(ctx, chatID, []string{member})
    })
}

func (api *API) RenameChat(ctx context.Context, communityID types.HexBytes, chatID string, name string) (*GroupChatResponse, error) {
    if len(communityID) != 0 {
        return nil, ErrCommunitiesNotSupported
    }

    return api.execAndGetGroupChatResponse(func() (*protocol.MessengerResponse, error) {
        return api.s.messenger.ChangeGroupChatName(ctx, chatID, name)
    })
}

func (api *API) SendGroupChatInvitationRequest(ctx context.Context, communityID types.HexBytes, chatID string, adminPK string, message string) (*GroupChatResponseWithInvitations, error) {
    if len(communityID) != 0 {
        return nil, ErrCommunitiesNotSupported
    }

    return api.execAndGetGroupChatResponseWithInvitations(func() (*protocol.MessengerResponse, error) {
        return api.s.messenger.SendGroupChatInvitationRequest(ctx, chatID, adminPK, message)
    })
}

func (api *API) GetGroupChatInvitations() ([]*protocol.GroupChatInvitation, error) {
    return api.s.messenger.GetGroupChatInvitations()
}

func (api *API) SendGroupChatInvitationRejection(ctx context.Context, invitationRequestID string) ([]*protocol.GroupChatInvitation, error) {
    response, err := api.s.messenger.SendGroupChatInvitationRejection(ctx, invitationRequestID)
    if err != nil {
        return nil, err
    }
    return response.Invitations, nil
}

func (api *API) StartGroupChat(ctx context.Context, communityID types.HexBytes, name string, members []string) (*StartGroupChatResponse, error) {
    if len(communityID) != 0 {
        return nil, ErrCommunitiesNotSupported
    }

    var response *protocol.MessengerResponse
    var err error
    if len(members) == 1 {
        memberPk, err := common.HexToPubkey(members[0])
        if err != nil {
            return nil, err
        }
        response, err = api.s.messenger.CreateOneToOneChat(&requests.CreateOneToOneChat{
            ID: types.HexBytes(crypto.FromECDSAPub(memberPk)),
        })
        if err != nil {
            return nil, err
        }
    } else {
        response, err = api.s.messenger.CreateGroupChatWithMembers(ctx, name, members)
        if err != nil {
            return nil, err
        }
    }

    chat := response.Chats()[0]

    return &StartGroupChatResponse{
        Chat:     chat,
        Contacts: response.Contacts,
        Messages: response.Messages(),
    }, nil
}

func (api *API) toGroupChatResponse(pubKey string, response *protocol.MessengerResponse) (*GroupChatResponse, error) {
    chat := response.Chats()[0]

    return &GroupChatResponse{
        Chat:     chat,
        Messages: response.Messages(),
    }, nil
}

func (api *API) toGroupChatResponseWithInvitations(pubKey string, response *protocol.MessengerResponse) (*GroupChatResponseWithInvitations, error) {
    g, err := api.toGroupChatResponse(pubKey, response)
    if err != nil {
        return nil, err
    }

    return &GroupChatResponseWithInvitations{
        Chat:        g.Chat,
        Messages:    g.Messages,
        Invitations: response.Invitations,
    }, nil
}

func (api *API) execAndGetGroupChatResponse(fn func() (*protocol.MessengerResponse, error)) (*GroupChatResponse, error) {
    pubKey := types.EncodeHex(crypto.FromECDSAPub(api.s.messenger.IdentityPublicKey()))
    response, err := fn()
    if err != nil {
        return nil, err
    }
    return api.toGroupChatResponse(pubKey, response)
}

func (api *API) execAndGetGroupChatResponseWithInvitations(fn func() (*protocol.MessengerResponse, error)) (*GroupChatResponseWithInvitations, error) {
    pubKey := types.EncodeHex(crypto.FromECDSAPub(api.s.messenger.IdentityPublicKey()))

    response, err := fn()
    if err != nil {
        return nil, err
    }

    return api.toGroupChatResponseWithInvitations(pubKey, response)
}