diff --git a/go.mod b/go.mod index 52e77d9c6b81b92fa8ca028cf1b90dcfc21f0b39..2b702be5d45e4c52044e4cc94db377431b57d511 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/hack-pad/go-indexeddb v0.2.0 github.com/pkg/errors v0.9.1 github.com/spf13/jwalterweatherman v1.1.0 - gitlab.com/elixxir/client/v4 v4.6.4-0.20230522213235-dc7d3feb05b9 + gitlab.com/elixxir/client/v4 v4.6.4-0.20230523165030-737b5db25f0d gitlab.com/elixxir/crypto v0.0.7-0.20230522190154-5cbcf67f4b39 gitlab.com/elixxir/primitives v0.0.3-0.20230214180039-9a25e2d3969c gitlab.com/xx_network/crypto v0.0.5-0.20230214003943-8a09396e95dd diff --git a/go.sum b/go.sum index 5fd785d49b778e55dc15bc2188a7e527f35073e0..8421df075940eae8587836e91ff57dc64db5053e 100644 --- a/go.sum +++ b/go.sum @@ -533,6 +533,8 @@ gitlab.com/elixxir/client/v4 v4.6.4-0.20230522204511-a198ba2e5749 h1:mFhb9/TDAtm gitlab.com/elixxir/client/v4 v4.6.4-0.20230522204511-a198ba2e5749/go.mod h1:rDC4sLKgj5kuuiJRp8bD1M7r0mlb0ib7q8q1Euct9/k= gitlab.com/elixxir/client/v4 v4.6.4-0.20230522213235-dc7d3feb05b9 h1:/g+OA8nsI0LwY1NgR7WPOAztengA2UqrY7xXZarmwgk= gitlab.com/elixxir/client/v4 v4.6.4-0.20230522213235-dc7d3feb05b9/go.mod h1:trGefpFqH2+kx4/uEV+yyiEWpGq3AhRMnuBQDhDQKMM= +gitlab.com/elixxir/client/v4 v4.6.4-0.20230523165030-737b5db25f0d h1:amrJ1WHTJd9+EArwgoq4XUwHu09hFwxYNtTc3S7W7ew= +gitlab.com/elixxir/client/v4 v4.6.4-0.20230523165030-737b5db25f0d/go.mod h1:trGefpFqH2+kx4/uEV+yyiEWpGq3AhRMnuBQDhDQKMM= gitlab.com/elixxir/comms v0.0.4-0.20230310205528-f06faa0d2f0b h1:8AVK93UEs/aufoqtFgyMVt9gf0oJ8F4pA60ZvEVvG+s= gitlab.com/elixxir/comms v0.0.4-0.20230310205528-f06faa0d2f0b/go.mod h1:z+qW0D9VpY5QKTd7wRlb5SK4kBNqLYsa4DXBcUXue9Q= gitlab.com/elixxir/comms v0.0.4-0.20230519211512-4a998f4b0938 h1:f27+QUFiGWrprKm+fstOg3ABkYLpWcZi3+8Lf5eDnqY= diff --git a/indexedDb/impl/channels/callbacks.go b/indexedDb/impl/channels/callbacks.go index 2550dbb9549ec92c82b8d00028bb5c5bd712c3bc..1d541bf5f23280bfc41d45d6b64f05e2ff4c6684 100644 --- a/indexedDb/impl/channels/callbacks.go +++ b/indexedDb/impl/channels/callbacks.go @@ -15,6 +15,7 @@ import ( "github.com/pkg/errors" jww "github.com/spf13/jwalterweatherman" + "gitlab.com/elixxir/client/v4/bindings" "gitlab.com/elixxir/client/v4/channels" "gitlab.com/elixxir/client/v4/cmix/rounds" cryptoBroadcast "gitlab.com/elixxir/crypto/broadcast" @@ -79,58 +80,27 @@ func (m *manager) newWASMEventModelCB(data []byte) ([]byte, error) { return []byte{}, nil } -// NotificationUpdate implements [bindings.ChannelUICallbacks.NotificationUpdate -func (m *manager) NotificationUpdate(notificationFilterListJSON, - changedNotificationStatesJSON, deletedNotificationStatesJSON []byte, - maxState int) { - jww.FATAL.Panicf("unimplemented") -} - -// MessageReceived implements [bindings.ChannelUICallbacks.MessageReceived]. -func (m *manager) MessageReceived(uuid int64, channelID []byte, update bool) { - // Package parameters for sending - msg := &wChannels.MessageReceivedCallbackMessage{ - UUID: uuid, - ChannelID: channelID, - Update: update, - } - data, err := json.Marshal(msg) - if err != nil { - jww.ERROR.Printf("Could not JSON marshal %T: %+v", msg, err) - return +// EventUpdate implements [bindings.ChannelUICallbacks.EventUpdate]. +func (m *manager) EventUpdate(eventType int64, jsonData []byte) { + var callbackTag worker.Tag + isValid := false + switch eventType { + case bindings.MessageReceived: + callbackTag = wChannels.MessageReceivedCallbackTag + isValid = true + case bindings.MessageDeleted: + callbackTag = wChannels.DeletedMessageCallbackTag + isValid = true + case bindings.UserMuted: + callbackTag = wChannels.MutedUserCallbackTag + isValid = true + default: + jww.ERROR.Printf("invalid indexedDB EventUpdate type %d: %+v)", + eventType, jsonData) + } + if isValid { + m.wtm.SendMessage(callbackTag, jsonData) } - - // Send it to the main thread - m.wtm.SendMessage(wChannels.MessageReceivedCallbackTag, data) -} - -// MessageDeleted implements [bindings.ChannelUICallbacks.MessageDeleted]. -func (m *manager) MessageDeleted(messageID []byte) { - m.wtm.SendMessage(wChannels.DeletedMessageCallbackTag, messageID) -} - -// UserMuted implements [bindings.ChannelUICallbacks.UserMuted]. -func (m *manager) UserMuted(channelID, pubKey []byte, unmute bool) { - // Package parameters for sending - msg := &wChannels.MuteUserMessage{ - ChannelID: channelID, - PubKey: pubKey, - Unmute: unmute, - } - data, err := json.Marshal(msg) - if err != nil { - jww.ERROR.Printf("Could not JSON marshal %T: %+v", msg, err) - return - } - - // Send it to the main thread - m.wtm.SendMessage(wChannels.MutedUserCallbackTag, data) -} - -// NicknameUpdate implements [bindings.ChannelUICallbacks.NicknameUpdate] -func (m *manager) NicknameUpdate(channelIdBytes []byte, nickname string, - exists bool) { - jww.FATAL.Panicf("unimplemented") } // joinChannelCB is the callback for wasmModel.JoinChannel. Always returns nil; diff --git a/indexedDb/impl/channels/implementation.go b/indexedDb/impl/channels/implementation.go index 04d7fb7e17dada785c95666bfc21ffff85eafc42..c017df06881eeef826d08fd54485ad498867aca9 100644 --- a/indexedDb/impl/channels/implementation.go +++ b/indexedDb/impl/channels/implementation.go @@ -172,7 +172,7 @@ func (w *wasmModel) ReceiveMessage(channelID *id.ID, messageID message.ID, return 0 } - go w.cbs.MessageReceived(int64(uuid), channelIDBytes, false) + w.sendReceiveMessageUpdate(uuid, channelID, false) return uuid } @@ -210,7 +210,8 @@ func (w *wasmModel) ReceiveReply(channelID *id.ID, messageID, jww.ERROR.Printf("Failed to receive reply: %+v", err) return 0 } - go w.cbs.MessageReceived(int64(uuid), channelIDBytes, false) + + w.sendReceiveMessageUpdate(uuid, channelID, false) return uuid } @@ -248,7 +249,7 @@ func (w *wasmModel) ReceiveReaction(channelID *id.ID, messageID, jww.ERROR.Printf("Failed to receive reaction: %+v", err) return 0 } - go w.cbs.MessageReceived(int64(uuid), channelIDBytes, false) + w.sendReceiveMessageUpdate(uuid, channelID, false) return uuid } @@ -395,8 +396,7 @@ func (w *wasmModel) updateMessage(currentMsg *Message, messageID *message.ID, if err != nil { return 0, err } - go w.cbs.MessageReceived(int64(uuid), currentMsg.ChannelID, true) - + w.sendReceiveMessageUpdate(uuid, (*id.ID)(currentMsg.ChannelID), true) return uuid, nil } @@ -493,15 +493,48 @@ func (w *wasmModel) DeleteMessage(messageID message.ID) error { return err } - go w.cbs.MessageDeleted(messageID.Bytes()) - + eventData, err := json.Marshal(bindings.MessageDeletedJson{ + MessageID: messageID, + }) + if err != nil { + jww.WARN.Printf("couldn't marshal MessageDeleted: %s, %+v", + messageID, err) + } else { + go w.cbs.EventUpdate(bindings.MessageDeleted, eventData) + } return nil } // MuteUser is called whenever a user is muted or unmuted. func (w *wasmModel) MuteUser( channelID *id.ID, pubKey ed25519.PublicKey, unmute bool) { - go w.cbs.UserMuted(channelID.Marshal(), pubKey, unmute) + eventData, err := json.Marshal(bindings.UserMutedJson{ + ChannelID: channelID, + PubKey: pubKey, + Unmute: unmute, + }) + if err != nil { + jww.WARN.Printf("couldn't marshal UserMuted: %s, %+v", + pubKey, err) + } else { + go w.cbs.EventUpdate(bindings.UserMuted, eventData) + } +} + +func (w *wasmModel) sendReceiveMessageUpdate(uuid uint64, channelID *id.ID, + update bool) { + eventMsg := bindings.MessageReceivedJson{ + Uuid: int64(uuid), + ChannelID: channelID, + Update: update, + } + eventData, err := json.Marshal(eventMsg) + if err != nil { + jww.WARN.Printf("couldn't marshal MessageReceive: %v, %+v", + eventMsg, err) + } else { + go w.cbs.EventUpdate(bindings.MessageReceived, eventData) + } } // valueToMessage is a helper for converting js.Value to Message. diff --git a/indexedDb/impl/channels/implementation_test.go b/indexedDb/impl/channels/implementation_test.go index 7de828ef6235425dcb7b40f4efc5fa47ac717eb4..1a8c87f0792a71ab6274e4e82f7ef075bd17e5f7 100644 --- a/indexedDb/impl/channels/implementation_test.go +++ b/indexedDb/impl/channels/implementation_test.go @@ -44,16 +44,7 @@ func TestMain(m *testing.M) { type dummyCbs struct{} -func (c *dummyCbs) MessageReceived(uuid int64, channelID []byte, update bool) {} -func (c *dummyCbs) UserMuted(channelID []byte, pubKey []byte, unmute bool) {} -func (c *dummyCbs) MessageDeleted(messageId []byte) {} -func (c *dummyCbs) NicknameUpdate(channelIdBytes []byte, nickname string, - exists bool) { -} -func (c *dummyCbs) NotificationUpdate(notificationFilterListJSON, - changedNotificationStatesJSON, deletedNotificationStatesJSON []byte, - maxState int) { -} +func (c *dummyCbs) EventUpdate(eventType int64, dataJson []byte) {} // Happy path test for receiving, updating, getting, and deleting a File. func TestWasmModel_ReceiveFile(t *testing.T) { diff --git a/indexedDb/worker/channels/init.go b/indexedDb/worker/channels/init.go index 34dd3f0d2548042a3778267e9b5e46172c384dd6..cf7b83f5fcb4a72d8e6ea22561f78790c950d727 100644 --- a/indexedDb/worker/channels/init.go +++ b/indexedDb/worker/channels/init.go @@ -20,7 +20,6 @@ import ( "gitlab.com/elixxir/client/v4/channels" cryptoChannel "gitlab.com/elixxir/crypto/channel" - "gitlab.com/elixxir/crypto/message" "gitlab.com/elixxir/xxdk-wasm/storage" "gitlab.com/elixxir/xxdk-wasm/worker" ) @@ -28,17 +27,10 @@ import ( // databaseSuffix is the suffix to be appended to the name of the database. const databaseSuffix = "_speakeasy" -// 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 int64, channelID []byte, update bool) - -// DeletedMessageCallback is called any time a message is deleted. -type DeletedMessageCallback func(messageID []byte) - -// MutedUserCallback is called any time a user is muted or unmuted. unmute is -// true if the user has been unmuted and false if they have been muted. -type MutedUserCallback func(channelID, pubKey []byte, unmute bool) +// eventUpdateCallback is the [bindings.ChannelUICallback] callback function +// it has a type ([bindings.NickNameUpdate] to [bindings.MessageDeleted] +// and json data that is the callback information. +type eventUpdateCallback func(eventType int64, jsonData []byte) // NewWASMEventModelBuilder returns an EventModelBuilder which allows // the channel manager to define the path but the callback is the same @@ -74,15 +66,15 @@ func NewWASMEventModel(path, wasmJsPath string, encryption cryptoChannel.Cipher, // Register handler to manage messages for the MessageReceivedCallback wm.RegisterCallback(MessageReceivedCallbackTag, - messageReceivedCallbackHandler(channelCbs.MessageReceived)) + messageReceivedCallbackHandler(channelCbs.EventUpdate)) // Register handler to manage messages for the DeletedMessageCallback wm.RegisterCallback(DeletedMessageCallbackTag, - deletedMessageCallbackHandler(channelCbs.MessageDeleted)) + deletedMessageCallbackHandler(channelCbs.EventUpdate)) // Register handler to manage messages for the MutedUserCallback wm.RegisterCallback(MutedUserCallbackTag, - mutedUserCallbackHandler(channelCbs.UserMuted)) + mutedUserCallbackHandler(channelCbs.EventUpdate)) // Store the database name err = storage.StoreIndexedDb(databaseName) @@ -139,47 +131,25 @@ type MessageReceivedCallbackMessage struct { // messageReceivedCallbackHandler returns a handler to manage messages for the // MessageReceivedCallback. -func messageReceivedCallbackHandler(cb MessageReceivedCallback) func(data []byte) { +func messageReceivedCallbackHandler(cb eventUpdateCallback) func(data []byte) { return func(data []byte) { - var msg MessageReceivedCallbackMessage - err := json.Unmarshal(data, &msg) - if err != nil { - jww.ERROR.Printf( - "Failed to JSON unmarshal %T from worker: %+v", msg, err) - return - } - - cb(msg.UUID, msg.ChannelID, msg.Update) + cb(bindings.MessageReceived, data) } } // deletedMessageCallbackHandler returns a handler to manage messages for the // DeletedMessageCallback. -func deletedMessageCallbackHandler(cb DeletedMessageCallback) func(data []byte) { +func deletedMessageCallbackHandler(cb eventUpdateCallback) func(data []byte) { return func(data []byte) { - messageID, err := message.UnmarshalID(data) - if err != nil { - jww.ERROR.Printf( - "Failed to JSON unmarshal message ID from worker: %+v", err) - } - - cb(messageID.Bytes()) + cb(bindings.MessageDeleted, data) } } // mutedUserCallbackHandler returns a handler to manage messages for the // MutedUserCallback. -func mutedUserCallbackHandler(cb MutedUserCallback) func(data []byte) { +func mutedUserCallbackHandler(cb eventUpdateCallback) func(data []byte) { return func(data []byte) { - var msg MuteUserMessage - err := json.Unmarshal(data, &msg) - if err != nil { - jww.ERROR.Printf( - "Failed to JSON unmarshal %T from worker: %+v", msg, err) - return - } - - cb(msg.ChannelID, msg.PubKey, msg.Unmute) + cb(bindings.UserMuted, data) } } diff --git a/wasm/channels.go b/wasm/channels.go index e7f3449f712908d26e6e49aaa6f650118f91593c..6795bd0e2f1d6376368d13206109bba6cad20960 100644 --- a/wasm/channels.go +++ b/wasm/channels.go @@ -2342,53 +2342,18 @@ func (c *ChannelDbCipher) UnmarshalJSON(_ js.Value, args []js.Value) any { // channelUI callbacks implementation struct. func newChannelUI(cbImpl js.Value) *channelUI { return &channelUI{ - notificationUpdate: utils.WrapCB(cbImpl, "NotificationUpdate"), - messageReceived: utils.WrapCB(cbImpl, "MessageReceived"), - userMuted: utils.WrapCB(cbImpl, "UserMuted"), - messageDeleted: utils.WrapCB(cbImpl, "MessageDeleted"), - nicknameUpdate: utils.WrapCB(cbImpl, "NicknameUpdate"), + eventUpdate: utils.WrapCB(cbImpl, "eventUpdate"), } } // eventModel wraps Javascript callbacks to adhere to the // [bindings.ChannelUICallbacks] interface. type channelUI struct { - notificationUpdate func(args ...any) js.Value - messageReceived func(args ...any) js.Value - userMuted func(args ...any) js.Value - messageDeleted func(args ...any) js.Value - nicknameUpdate func(args ...any) js.Value + eventUpdate func(args ...any) js.Value } -// NotificationUpdate implements -// [bindings.ChannelUICallbacks.NotificationUpdate]. -func (c *channelUI) NotificationUpdate(notificationFilterListJSON, - changedNotificationStatesJSON, deletedNotificationStatesJSON []byte, - maxState int) { - c.notificationUpdate(notificationFilterListJSON, - changedNotificationStatesJSON, - deletedNotificationStatesJSON, - maxState) -} - -// MessageReceived implements [bindings.ChannelUICallbacks.MessageReceived]. -func (c *channelUI) MessageReceived(uuid int64, channelID []byte, update bool) { - c.messageReceived(uuid, utils.CopyBytesToJS(channelID), update) -} - -// UserMuted implements [bindings.ChannelUICallbacks.UserMuted]. -func (c *channelUI) UserMuted(channelID []byte, pubKey []byte, unmute bool) { - c.userMuted(utils.CopyBytesToJS(channelID), utils.CopyBytesToJS(pubKey), - unmute) -} - -// MessageDeleted implements [bindings.ChannelUICallbacks.MessageDeleted]. -func (c *channelUI) MessageDeleted(messageId []byte) { - c.messageDeleted(utils.CopyBytesToJS(messageId)) -} - -// NicknameUpdate implements [bindings.ChannelUICallbacks.NicknameUpdate] -func (c *channelUI) NicknameUpdate(channelIdBytes []byte, nickname string, - exists bool) { - c.nicknameUpdate(utils.CopyBytesToJS(channelIdBytes), nickname, exists) +// EventUpdate implements +// [bindings.ChannelUICallbacks.EventUpdate]. +func (c *channelUI) EventUpdate(eventType int64, dataJson []byte) { + c.eventUpdate(eventType, utils.CopyBytesToJS(dataJson)) }