diff --git a/indexedDb/impl/dm/callbacks.go b/indexedDb/impl/dm/callbacks.go index c6f257f67c064094263dffd69db2fc89e6c71ce5..b477df50c01c0c9dda3195be7f9706d8070cd930 100644 --- a/indexedDb/impl/dm/callbacks.go +++ b/indexedDb/impl/dm/callbacks.go @@ -80,13 +80,14 @@ func (m *manager) newWASMEventModelCB(data []byte) ([]byte, error) { // main thread. // // messageReceivedCallback adhere to the MessageReceivedCallback type. -func (m *manager) messageReceivedCallback( - uuid uint64, pubKey ed25519.PublicKey, update bool) { +func (m *manager) messageReceivedCallback(uuid uint64, pubKey ed25519.PublicKey, + messageUpdate, conversationUpdate bool) { // Package parameters for sending msg := &wDm.MessageReceivedCallbackMessage{ - UUID: uuid, - PubKey: pubKey, - Update: update, + UUID: uuid, + PubKey: pubKey, + MessageUpdate: messageUpdate, + ConversationUpdate: conversationUpdate, } data, err := json.Marshal(msg) if err != nil { diff --git a/indexedDb/impl/dm/implementation.go b/indexedDb/impl/dm/implementation.go index a28bd5b4f9f2f4626116b16bb7f6111088a309a4..e0149736ce487d81e0530996fb5d8d2171d77ea4 100644 --- a/indexedDb/impl/dm/implementation.go +++ b/indexedDb/impl/dm/implementation.go @@ -39,10 +39,10 @@ type wasmModel struct { updateMux sync.Mutex } -// joinConversation is used for joining new conversations. -func (w *wasmModel) joinConversation(nickname string, - pubKey ed25519.PublicKey, dmToken uint32, codeset uint8) error { - parentErr := errors.New("failed to joinConversation") +// upsertConversation is used for joining or updating a Conversation. +func (w *wasmModel) upsertConversation(nickname string, + pubKey ed25519.PublicKey, dmToken uint32, codeset uint8, blocked bool) error { + parentErr := errors.New("failed to upsertConversation") // Build object newConvo := Conversation{ @@ -50,7 +50,7 @@ func (w *wasmModel) joinConversation(nickname string, Nickname: nickname, Token: dmToken, CodesetVersion: codeset, - Blocked: false, + Blocked: blocked, } // Convert to jsObject @@ -212,9 +212,10 @@ func (w *wasmModel) UpdateSentStatus(uuid uint64, messageID message.ID, return } - jww.TRACE.Printf("[DM indexedDB] Calling ReceiveMessageCB(%v, %v, t)", + jww.TRACE.Printf("[DM indexedDB] Calling ReceiveMessageCB(%v, %v, t, f)", uuid, newMessage.ConversationPubKey) - go w.receivedMessageCB(uuid, newMessage.ConversationPubKey, true) + go w.receivedMessageCB(uuid, newMessage.ConversationPubKey, + true, false) } // receiveWrapper is a higher-level wrapper of receiveHelper. @@ -222,21 +223,34 @@ func (w *wasmModel) receiveWrapper(messageID message.ID, parentID *message.ID, n data string, partnerKey, senderKey ed25519.PublicKey, dmToken uint32, codeset uint8, timestamp time.Time, round rounds.Round, mType dm.MessageType, status dm.Status) (uint64, error) { - // If there is no extant Conversation, create one. - _, err := impl.Get(w.db, conversationStoreName, impl.EncodeBytes(partnerKey)) + // Keep track of whether Conversation was altered + conversationUpdated := false + result, err := w.getConversation(partnerKey) if err != nil { - if strings.Contains(err.Error(), impl.ErrDoesNotExist) { - err = w.joinConversation(nickname, partnerKey, dmToken, - codeset) + if !strings.Contains(err.Error(), impl.ErrDoesNotExist) { + return 0, err + } else { + // If there is no extant Conversation, create one. + err = w.upsertConversation(nickname, partnerKey, dmToken, + codeset, false) if err != nil { return 0, err } - } else { - return 0, err + conversationUpdated = true } } else { jww.DEBUG.Printf( "[DM indexedDB] Conversation with %s already joined", nickname) + + // Update Conversation if nickname was altered + if result.Nickname != nickname { + err = w.upsertConversation(nickname, result.Pubkey, result.Token, + result.CodesetVersion, result.Blocked) + if err != nil { + return 0, err + } + conversationUpdated = true + } } // Handle encryption, if it is present @@ -261,9 +275,9 @@ func (w *wasmModel) receiveWrapper(messageID message.ID, parentID *message.ID, n return 0, err } - jww.TRACE.Printf("[DM indexedDB] Calling ReceiveMessageCB(%v, %v, f)", - uuid, partnerKey) - go w.receivedMessageCB(uuid, partnerKey, false) + jww.TRACE.Printf("[DM indexedDB] Calling ReceiveMessageCB(%v, %v, f, %t)", + uuid, partnerKey, conversationUpdated) + go w.receivedMessageCB(uuid, partnerKey, false, conversationUpdated) return uuid, nil } @@ -280,7 +294,7 @@ func (w *wasmModel) receiveHelper( return 0, errors.Errorf("Unable to marshal Message: %+v", err) } - // Unset the primaryKey for inserts so that it can be auto-populated and + // Unset the primaryKey for inserts so that it can be autopopulated and // incremented if !isUpdate { messageObj.Delete("id") @@ -357,21 +371,9 @@ func (w *wasmModel) setBlocked(senderPubKey ed25519.PublicKey, isBlocked bool) e if err != nil { return err } - resultConvo.Blocked = isBlocked - // Convert back to js.Value - newMessageJson, err := json.Marshal(resultConvo) - if err != nil { - return err - } - convoObj, err := utils.JsonToJS(newMessageJson) - if err != nil { - return err - } - - // Insert into storage - _, err = impl.Put(w.db, conversationStoreName, convoObj) - return err + return w.upsertConversation(resultConvo.Nickname, resultConvo.Pubkey, + resultConvo.Token, resultConvo.CodesetVersion, isBlocked) } // GetConversation returns the conversation held by the model (receiver). diff --git a/indexedDb/impl/dm/init.go b/indexedDb/impl/dm/init.go index 69dd7ec56e48a9d0ce5a0fe2b88afafbae83f5a8..98c9e85a8278e9ed67bce4a960df99431819648d 100644 --- a/indexedDb/impl/dm/init.go +++ b/indexedDb/impl/dm/init.go @@ -33,9 +33,10 @@ const ( // MessageReceivedCallback is called any time a message is received or updated. // -// update is true if the row is old and was edited. +// messageUpdate is true if the Message already exists and was edited. +// conversationUpdate is true if the Conversation was created or modified. type MessageReceivedCallback func( - uuid uint64, pubKey ed25519.PublicKey, update bool) + uuid uint64, pubKey ed25519.PublicKey, messageUpdate, conversationUpdate bool) // storeDatabaseNameFn matches storage.StoreIndexedDb so that the data can be // sent between the worker and main thread. diff --git a/indexedDb/worker/dm/init.go b/indexedDb/worker/dm/init.go index 145edf935ba9804dd315c2196d301bb60581ecfb..14b72acf0bc443be3b763b2249fdbab3b48b4499 100644 --- a/indexedDb/worker/dm/init.go +++ b/indexedDb/worker/dm/init.go @@ -26,8 +26,8 @@ import ( // MessageReceivedCallback is called any time a message is received or updated. // // update is true if the row is old and was edited. -type MessageReceivedCallback func( - uuid uint64, pubKey ed25519.PublicKey, update bool) +type MessageReceivedCallback func(uuid uint64, pubKey ed25519.PublicKey, + messageUpdate, conversationUpdate bool) // NewWASMEventModelMessage is JSON marshalled and sent to the worker for // [NewWASMEventModel]. @@ -91,9 +91,10 @@ func NewWASMEventModel(path, wasmJsPath string, encryption cryptoChannel.Cipher, // MessageReceivedCallbackMessage is JSON marshalled and received from the // worker for the [MessageReceivedCallback] callback. type MessageReceivedCallbackMessage struct { - UUID uint64 `json:"uuid"` - PubKey ed25519.PublicKey `json:"pubKey"` - Update bool `json:"update"` + UUID uint64 `json:"uuid"` + PubKey ed25519.PublicKey `json:"pubKey"` + MessageUpdate bool `json:"message_update"` + ConversationUpdate bool `json:"conversation_update"` } // messageReceivedCallbackHandler returns a handler to manage messages for the @@ -107,7 +108,7 @@ func messageReceivedCallbackHandler(cb MessageReceivedCallback) func(data []byte "MessageReceivedCallback message from worker: %+v", err) return } - cb(msg.UUID, msg.PubKey, msg.Update) + cb(msg.UUID, msg.PubKey, msg.MessageUpdate, msg.ConversationUpdate) } } diff --git a/wasm/dm.go b/wasm/dm.go index 84d70eb45573bdeea8559cc693715842d51261d0..70b51c00e872c6ba299df5054a4ec84fdef4e31f 100644 --- a/wasm/dm.go +++ b/wasm/dm.go @@ -210,8 +210,9 @@ func newDMClientWithIndexedDb(cmixID int, wasmJsPath string, privateIdentity []byte, cb js.Value, cipher *bindings.DMDbCipher) any { messageReceivedCB := func(uuid uint64, pubKey ed25519.PublicKey, - update bool) { - cb.Invoke(uuid, utils.CopyBytesToJS(pubKey[:]), update) + messageUpdate, conversationUpdate bool) { + cb.Invoke(uuid, utils.CopyBytesToJS(pubKey[:]), + messageUpdate, conversationUpdate) } promiseFn := func(resolve, reject func(args ...any) js.Value) {