From dbdf2565ae474c5d6ee97e60c67bedfd73334ac1 Mon Sep 17 00:00:00 2001 From: Andrea Maria Piana Date: Thu, 3 Jun 2021 16:09:30 +0200 Subject: [PATCH] WIP --- protocol/message_handler.go | 64 +++++++++++++++++++++++++++++---- protocol/message_persistence.go | 37 +++++++++++++++++++ protocol/messenger_response.go | 7 ++++ 3 files changed, 102 insertions(+), 6 deletions(-) diff --git a/protocol/message_handler.go b/protocol/message_handler.go index 147261198..23343899e 100644 --- a/protocol/message_handler.go +++ b/protocol/message_handler.go @@ -585,6 +585,20 @@ func (m *MessageHandler) HandleChatMessage(state *ReceivedMessageState) error { return err } + if len(receivedMessage.OriginalMessageId) != 0 { + if receivedMessage.ContentType != protobuf.ChatMessage_EDIT { + return errors.New("replace can only be used with an edit content type") + } + shouldContinue, err := m.handleEditedMessage(state, receivedMessage) + if err != nil { + return err + } + + if !shouldContinue { + return nil + } + } + // If the chat is not active, create a notification in the center if chat.OneToOne() && !chat.Active { m.createMessageNotification(chat, state) @@ -623,12 +637,6 @@ func (m *MessageHandler) HandleChatMessage(state *ReceivedMessageState) error { state.Response.CommunityChanges = append(state.Response.CommunityChanges, communityResponse.Changes) } - if len(receivedMessage.OriginalMessageId) != 0 { - if receivedMessage.ContentType != protobuf.ChatMessage_EDIT { - return errors.New("replace can only be used with an edit content type") - } - } - state.Response.AddMessage(receivedMessage) return nil @@ -1116,6 +1124,50 @@ func (m *MessageHandler) HandleChatIdentity(state *ReceivedMessageState, ci prot return nil } +func (m *MessageHandler) handleEditedMessage(state *ReceivedMessageState, message *common.Message) (bool, error) { + originalMessageID := message.OriginalMessageId + // Check if it's already in the response + originalMessage := state.Response.GetMessage(originalMessageID) + // and pull all the edits + original message + messageHistory, err := m.persistence.MessagesByOriginalMessageID(originalMessageID) + if err != nil { + return false, err + } + + // Check if we have the original message + + if originalMessage == nil { + for _, m := range messageHistory { + if m.ID == originalMessageID { + originalMessage = m + } + } + } + + // We don't have the original message, save the edited message hidden and continue + if originalMessage == nil { + // This could be a single query + err := m.persistence.SaveMessages([]*common.Message{message}) + if err != nil { + return false, nil + } + err = m.persistence.HideMessage(message.ID) + if err != nil { + return false, nil + } + // We tell them to ignore this message + return false, nil + } + + // We have an original message and potentially some edits + + // check that the edit is valid + + // find the most up to date edit + + return true, nil +} + func (m *MessageHandler) isMessageAllowedFrom(allContacts *contactMap, publicKey string, chat *Chat) (bool, error) { onlyFromContacts, err := m.settings.GetMessagesFromContactsOnly() if err != nil { diff --git a/protocol/message_persistence.go b/protocol/message_persistence.go index cf65388e2..b3bf42aba 100644 --- a/protocol/message_persistence.go +++ b/protocol/message_persistence.go @@ -1454,3 +1454,40 @@ func (db sqlitePersistence) clearHistory(chat *Chat, currentClockValue uint64, t err = db.saveChat(tx, *chat) return err } + +func (db sqlitePersistence) MessagesByOriginalMessageID(id string) ([]*common.Message, error) { + allFields := db.tableUserMessagesAllFieldsJoin() + + // nolint: gosec + rows, err := db.db.Query(fmt.Sprintf(` + SELECT + %s + FROM + user_messages m1 + LEFT JOIN + user_messages m2 + ON + m1.response_to = m2.id + + LEFT JOIN + contacts c + ON + + m1.source = c.id + WHERE m1.id = ? OR m1.original_message_id = ?`, allFields), id, id) + if err != nil { + return nil, err + } + defer rows.Close() + + var result []*common.Message + for rows.Next() { + var message common.Message + if err := db.tableUserMessagesScanAllFields(rows, &message); err != nil { + return nil, err + } + result = append(result, &message) + } + + return result, nil +} diff --git a/protocol/messenger_response.go b/protocol/messenger_response.go index 5edcb8f47..d6fa4f42f 100644 --- a/protocol/messenger_response.go +++ b/protocol/messenger_response.go @@ -272,3 +272,10 @@ func (r *MessengerResponse) SetMessages(messages []*common.Message) { r.messages = make(map[string]*common.Message) r.AddMessages(messages) } + +func (r *MessengerResponse) GetMessage(messageID string) *common.Message { + if r.messages == nil { + return nil + } + return r.messages[messageID] +}