This commit is contained in:
Andrea Maria Piana 2021-06-03 16:09:30 +02:00
parent 5d856adc0c
commit dbdf2565ae
3 changed files with 102 additions and 6 deletions

View file

@ -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 {

View file

@ -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
}

View file

@ -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]
}