From b1021ef382373664c107f67361bda25c7740c047 Mon Sep 17 00:00:00 2001 From: Godefroy Ponsinet Date: Thu, 13 Dec 2018 18:02:25 +0100 Subject: [PATCH] feat(rn): create conversation when add contact Signed-off-by: Godefroy Ponsinet --- core/node/event_handlers.go | 9 +++-- core/node/nodeapi.go | 28 ++++++++++----- core/sql/helpers.go | 69 +++++++++++++++++++++++++++++++++++++ 3 files changed, 93 insertions(+), 13 deletions(-) diff --git a/core/node/event_handlers.go b/core/node/event_handlers.go index 929ec0728f..cb362822c8 100644 --- a/core/node/event_handlers.go +++ b/core/node/event_handlers.go @@ -5,10 +5,9 @@ import ( "fmt" "time" - "berty.tech/core/pkg/errorcodes" - "berty.tech/core/api/p2p" "berty.tech/core/entity" + "berty.tech/core/pkg/errorcodes" bsql "berty.tech/core/sql" "github.com/gofrs/uuid" "github.com/pkg/errors" @@ -73,6 +72,7 @@ func (n *Node) handleContactRequestAccepted(ctx context.Context, input *p2p.Even if err := n.networkDriver.Join(ctx, input.SenderID); err != nil { return err } + return nil } @@ -121,9 +121,8 @@ func (n *Node) handleConversationInvite(ctx context.Context, input *p2p.Event) e Topic: attrs.Conversation.Topic, } - // save c donversation - if err := n.sql(ctx).Set("gorm:association_autoupdate", true).Save(conversation).Error; err != nil { - return errorcodes.ErrDbUpdate.Wrap(err) + if _, err := bsql.CreateConversation(n.sql(ctx), conversation); err != nil { + return err } if err := n.networkDriver.Join(ctx, attrs.Conversation.ID); err != nil { diff --git a/core/node/nodeapi.go b/core/node/nodeapi.go index f761f4c94f..ac425557c4 100644 --- a/core/node/nodeapi.go +++ b/core/node/nodeapi.go @@ -242,6 +242,24 @@ func (n *Node) ContactRequest(ctx context.Context, req *node.ContactRequestInput return nil, errorcodes.ErrContactReqExisting.New() } + // check if already have contact request from/to this contact + // if not, create a conversation + count := 0 + sql.Model(&p2p.Event{}). + Where(&p2p.Event{ + SenderID: contact.ID, + Kind: p2p.Kind_ContactRequest, + }). + Or(&p2p.Event{ + ReceiverID: contact.ID, + Kind: p2p.Kind_ContactRequest, + }). + Count(&count). + First(&p2p.Event{}) + if count == 0 { + n.ConversationCreate(ctx, &node.ConversationCreateInput{Contacts: []*entity.Contact{contact}}) + } + // send request to peer event := n.NewContactEvent(ctx, contact, p2p.Kind_ContactRequest) if err := event.SetAttrs(&p2p.ContactRequestAttrs{ @@ -406,16 +424,10 @@ func (n *Node) conversationCreate(ctx context.Context, input *node.ConversationC Title: input.Title, Topic: input.Topic, } - sql := n.sql(ctx) - if err := sql.Set("gorm:association_autoupdate", true).Save(&createConversation).Error; err != nil { - return nil, errorcodes.ErrDbCreate.Wrap(err) - } - - // load new conversation again, to preload associations - conversation, err := bsql.ConversationByID(sql, createConversation.ID) + conversation, err := bsql.CreateConversation(n.sql(ctx), createConversation) if err != nil { - return nil, errorcodes.ErrDb.Wrap(err) + return nil, err } // Async subscribe to conversation diff --git a/core/sql/helpers.go b/core/sql/helpers.go index c5d9cf978c..12ed539a67 100644 --- a/core/sql/helpers.go +++ b/core/sql/helpers.go @@ -2,8 +2,11 @@ package sql import ( "errors" + "strings" + "berty.tech/core/api/p2p" "berty.tech/core/entity" + "berty.tech/core/pkg/errorcodes" "github.com/jinzhu/gorm" ) @@ -32,3 +35,69 @@ func MembersByConversationID(db *gorm.DB, conversationID string) ([]*entity.Conv Find(&members). Error } + +func MergeConversations(db *gorm.DB, conversations []entity.Conversation) (*entity.Conversation, error) { + logger().Debug("MERGE_CONVERSATION") + // chosse the conversation to save + merge := conversations[0] + for i := range conversations { + if strings.Compare(merge.ID, conversations[i].ID) > 0 { + merge = conversations[i] + } + } + + // move all messages to that conversation + for i := range conversations { + if err := db.Model(&p2p.Event{}).Where(&p2p.Event{ + ConversationID: conversations[i].ID, + Kind: p2p.Kind_ConversationNewMessage, + }).Update(&p2p.Event{ + ConversationID: merge.ID, + }).Error; err != nil { + return nil, err + } + } + + // remove other conversations + for i := range conversations { + if conversations[i].ID != merge.ID { + db.Where(&entity.ConversationMember{ + ConversationID: conversations[i].ID, + }).Delete(&entity.ConversationMember{}) + db.Delete(conversations[i]) + } + } + + return &merge, nil +} + +func CreateConversation(db *gorm.DB, conversation *entity.Conversation) (*entity.Conversation, error) { + // save conversation + if err := db.Set("gorm:association_autoupdate", true).Save(conversation).Error; err != nil { + return nil, errorcodes.ErrDbCreate.Wrap(err) + } + + // load new conversation again, to preload associations + conversation, err := ConversationByID(db, conversation.ID) + if err != nil { + return nil, errorcodes.ErrDb.Wrap(err) + } + + // check if that is 1-1 conversation + // if len(conversation.Members) <= 2 { + // logger().Debug("CREATE_CONVERSATION") + // // check if there already a 1-1 conversation + // conversations := []entity.Conversation{} + + // logger().Debug(fmt.Sprintf("GET_MEMBERS %+v", conversation.Members)) + // db.Model(&entity.Conversation{}).Find(conversations).Error; err != nil { + // logger().Error(err.Error()) + // } + // logger().Debug(fmt.Sprintf("CONVERSATIONS %+v", conversations)) + // if len(conversations) >= 1 { + // return MergeConversations(db, conversations) + // } + // } + + return conversation, nil +}