diff --git a/cmd/gordon_main.go b/cmd/gordon_main.go index 57f5ed962..fae68f87d 100644 --- a/cmd/gordon_main.go +++ b/cmd/gordon_main.go @@ -89,7 +89,7 @@ func gRunGetToken(strMyUid string) string { return token } func main() { - uid := "7789" + uid := "7788" //Gordon //uid:="1554321956297519104" //Gordon2 diff --git a/go.mod b/go.mod index d4a560f8f..ff635b1d4 100644 --- a/go.mod +++ b/go.mod @@ -23,7 +23,10 @@ require ( require golang.org/x/net v0.11.0 -require github.com/OpenIMSDK/Open-IM-Server v0.0.0-20230712062720-2e6ea7b193c3 +require ( + github.com/OpenIMSDK/Open-IM-Server v0.0.0-20230712062720-2e6ea7b193c3 + github.com/google/go-cmp v0.5.9 +) require ( github.com/bwmarrin/snowflake v0.3.0 // indirect diff --git a/go.sum b/go.sum index 7804a1dc8..582918769 100644 --- a/go.sum +++ b/go.sum @@ -44,6 +44,7 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= diff --git a/internal/conversation_msg/conversation.go b/internal/conversation_msg/conversation.go index ffdd5b7fc..6120b3a63 100644 --- a/internal/conversation_msg/conversation.go +++ b/internal/conversation_msg/conversation.go @@ -286,16 +286,16 @@ func (c *Conversation) getAdvancedHistoryMessageList2(ctx context.Context, req s rawMessageLength := len(list) t = time.Now() if rawMessageLength < req.Count { - maxSeq, minSeq, lostSeqListLength := c.messageBlocksInternalContinuityCheck(ctx, conversationID, notStartTime, isReverse, req.Count, sessionType, startTime, &list, &messageListCallback) - _ = c.messageBlocksBetweenContinuityCheck(ctx, req.LastMinSeq, maxSeq, conversationID, notStartTime, isReverse, req.Count, sessionType, startTime, &list, &messageListCallback) + maxSeq, minSeq, lostSeqListLength := c.messageBlocksInternalContinuityCheck(ctx, conversationID, notStartTime, isReverse, req.Count, startTime, &list, &messageListCallback) + _ = c.messageBlocksBetweenContinuityCheck(ctx, req.LastMinSeq, maxSeq, conversationID, notStartTime, isReverse, req.Count, startTime, &list, &messageListCallback) if minSeq == 1 && lostSeqListLength == 0 { messageListCallback.IsEnd = true } else { - c.messageBlocksEndContinuityCheck(ctx, minSeq, conversationID, notStartTime, isReverse, req.Count, sessionType, startTime, &list, &messageListCallback) + c.messageBlocksEndContinuityCheck(ctx, minSeq, conversationID, notStartTime, isReverse, req.Count, startTime, &list, &messageListCallback) } } else { - maxSeq, _, _ := c.messageBlocksInternalContinuityCheck(ctx, conversationID, notStartTime, isReverse, req.Count, sessionType, startTime, &list, &messageListCallback) - c.messageBlocksBetweenContinuityCheck(ctx, req.LastMinSeq, maxSeq, conversationID, notStartTime, isReverse, req.Count, sessionType, startTime, &list, &messageListCallback) + maxSeq, _, _ := c.messageBlocksInternalContinuityCheck(ctx, conversationID, notStartTime, isReverse, req.Count, startTime, &list, &messageListCallback) + c.messageBlocksBetweenContinuityCheck(ctx, req.LastMinSeq, maxSeq, conversationID, notStartTime, isReverse, req.Count, startTime, &list, &messageListCallback) } log.ZDebug(ctx, "pull message", "pull cost time", time.Since(t)) diff --git a/internal/conversation_msg/conversation_notification.go b/internal/conversation_msg/conversation_notification.go index 7797c0e35..62a98d9bc 100644 --- a/internal/conversation_msg/conversation_notification.go +++ b/internal/conversation_msg/conversation_notification.go @@ -621,7 +621,7 @@ func (c *Conversation) doNotificationNew(c2v common.Cmd2Value) { } for _, syncFunc := range []func(c context.Context) error{ - c.user.SyncLoginUserInfo, c.SyncConversations, + c.user.SyncLoginUserInfo, c.friend.SyncBlackList, c.friend.SyncFriendList, c.friend.SyncFriendApplication, c.friend.SyncSelfFriendApplication, c.group.SyncJoinedGroup, c.group.SyncAdminGroupApplication, c.group.SyncSelfGroupApplication, c.group.SyncJoinedGroupMember, } { @@ -633,9 +633,11 @@ func (c *Conversation) doNotificationNew(c2v common.Cmd2Value) { c.ConversationListener.OnSyncServerFailed() case constant.MsgSyncEnd: defer c.ConversationListener.OnSyncServerFinish() + go c.SyncConversations(ctx) } for conversationID, msgs := range allMsg { + log.ZDebug(ctx, "notification handling", "conversationID", conversationID, "msgs", msgs) if len(msgs.Msgs) != 0 { lastMsg := msgs.Msgs[len(msgs.Msgs)-1] log.ZDebug(ctx, "SetNotificationSeq", "conversationID", conversationID, "seq", lastMsg.Seq) diff --git a/internal/conversation_msg/create_message.go b/internal/conversation_msg/create_message.go index 0b4d13649..6552bf90a 100644 --- a/internal/conversation_msg/create_message.go +++ b/internal/conversation_msg/create_message.go @@ -23,6 +23,8 @@ import ( "open_im_sdk/pkg/utils" "open_im_sdk/sdk_struct" "os" + "path/filepath" + "strings" ) func (c *Conversation) CreateTextMessage(ctx context.Context, text string) (*sdk_struct.MsgStruct, error) { @@ -274,6 +276,7 @@ func (c *Conversation) CreateSoundMessageFromFullPath(ctx context.Context, sound SoundPath: soundPath, Duration: duration, DataSize: fi.Size(), + SoundType: strings.Replace(filepath.Ext(fi.Name()), ".", "", 1), } return &s, nil } @@ -347,6 +350,9 @@ func (c *Conversation) CreateSoundMessage(ctx context.Context, soundPath string, Duration: duration, DataSize: fi.Size(), } + if typ := strings.Replace(filepath.Ext(fi.Name()), ".", "", 1); typ != "" { + s.SoundElem.SoundType = "audio/" + strings.ToLower(typ) + } return &s, nil } func (c *Conversation) CreateVideoMessageByURL(ctx context.Context, videoElem sdk_struct.VideoBaseInfo) (*sdk_struct.MsgStruct, error) { @@ -460,8 +466,8 @@ func (c *Conversation) CreateFaceMessage(ctx context.Context, index int, data st s.FaceElem.Index = index s.Content = utils.StructToJsonString(s.FaceElem) return &s, nil - } + func (c *Conversation) CreateForwardMessage(ctx context.Context, s *sdk_struct.MsgStruct) (*sdk_struct.MsgStruct, error) { if s.Status != constant.MsgStatusSendSuccess { log.Error("internal", "only send success message can be Forward") diff --git a/internal/conversation_msg/file_js.go b/internal/conversation_msg/file_js.go deleted file mode 100644 index 8627910d7..000000000 --- a/internal/conversation_msg/file_js.go +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright © 2023 OpenIM SDK. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build js && wasm -// +build js,wasm - -package conversation_msg - -import ( - "open_im_sdk/wasm/exec" - "syscall/js" -) - -type JSFile struct { -} - -func NewFile() *JSFile { - return &JSFile{} -} -func (j *JSFile) Open(uuid string) (int64, error) { - return WasmOpen(uuid) -} - -func (j *JSFile) Read(uuid string, offset int64, length int64) ([]byte, error) { - return WasmRead(uuid, offset, length) -} - -func (j *JSFile) Close(uuid string) error { - return WasmClose(uuid) -} - -func WasmOpen(uuid string) (int64, error) { - result, err := exec.Exec(uuid) - if err != nil { - return 0, err - } - if v, ok := result.(float64); ok { - return int64(v), nil - } - return 0, exec.ErrType -} -func WasmRead(uuid string, offset int64, length int64) ([]byte, error) { - result, err := exec.Exec(uuid, offset, length) - if err != nil { - return nil, err - } else { - if v, ok := result.(js.Value); ok { - return exec.ExtractArrayBuffer(v), nil - } else { - return nil, exec.ErrType - } - } -} -func WasmClose(uuid string) error { - _, err := exec.Exec(uuid) - return err -} diff --git a/internal/conversation_msg/message_check.go b/internal/conversation_msg/message_check.go index 65f1d4c10..72f848658 100644 --- a/internal/conversation_msg/message_check.go +++ b/internal/conversation_msg/message_check.go @@ -27,8 +27,8 @@ import ( ) // 检测其内部连续性,如果不连续,则向前补齐,获取这一组消息的最大最小seq,以及需要补齐的seq列表长度 -func (c *Conversation) messageBlocksInternalContinuityCheck(ctx context.Context, conversationID string, notStartTime, isReverse bool, count, - sessionType int, startTime int64, list *[]*model_struct.LocalChatLog, messageListCallback *sdk.GetAdvancedHistoryMessageListCallback) (max, min int64, length int) { +func (c *Conversation) messageBlocksInternalContinuityCheck(ctx context.Context, conversationID string, notStartTime, isReverse bool, count int, + startTime int64, list *[]*model_struct.LocalChatLog, messageListCallback *sdk.GetAdvancedHistoryMessageListCallback) (max, min int64, length int) { var lostSeqListLength int maxSeq, minSeq, haveSeqList := c.getMaxAndMinHaveSeqList(*list) log.ZDebug(ctx, "getMaxAndMinHaveSeqList is:", "maxSeq", maxSeq, "minSeq", minSeq, "haveSeqList", haveSeqList) @@ -49,7 +49,7 @@ func (c *Conversation) messageBlocksInternalContinuityCheck(ctx context.Context, } else { pullSeqList = lostSeqList[lostSeqListLength-constant.PullMsgNumForReadDiffusion : lostSeqListLength] } - c.pullMessageAndReGetHistoryMessages(ctx, conversationID, pullSeqList, notStartTime, isReverse, count, sessionType, startTime, list, messageListCallback) + c.pullMessageAndReGetHistoryMessages(ctx, conversationID, pullSeqList, notStartTime, isReverse, count, startTime, list, messageListCallback) } } @@ -58,13 +58,13 @@ func (c *Conversation) messageBlocksInternalContinuityCheck(ctx context.Context, // 检测消息块之间的连续性,如果不连续,则向前补齐,返回块之间是否连续,bool func (c *Conversation) messageBlocksBetweenContinuityCheck(ctx context.Context, lastMinSeq, maxSeq int64, conversationID string, - notStartTime, isReverse bool, count, sessionType int, startTime int64, list *[]*model_struct.LocalChatLog, messageListCallback *sdk.GetAdvancedHistoryMessageListCallback) bool { + notStartTime, isReverse bool, count int, startTime int64, list *[]*model_struct.LocalChatLog, messageListCallback *sdk.GetAdvancedHistoryMessageListCallback) bool { if lastMinSeq != 0 { log.ZDebug(ctx, "get lost LastMinSeq is :", "lastMinSeq", lastMinSeq, "thisMaxSeq", maxSeq) if maxSeq != 0 { if maxSeq+1 != lastMinSeq { startSeq := int64(lastMinSeq) - constant.PullMsgNumForReadDiffusion - if startSeq <= int64(maxSeq) { + if startSeq <= maxSeq { startSeq = int64(maxSeq) + 1 } successiveSeqList := func(max, min int64) (seqList []int64) { @@ -75,7 +75,7 @@ func (c *Conversation) messageBlocksBetweenContinuityCheck(ctx context.Context, }(lastMinSeq-1, startSeq) log.ZDebug(ctx, "get lost successiveSeqList is :", "successiveSeqList", successiveSeqList, "length:", len(successiveSeqList)) if len(successiveSeqList) > 0 { - c.pullMessageAndReGetHistoryMessages(ctx, conversationID, successiveSeqList, notStartTime, isReverse, count, sessionType, startTime, list, messageListCallback) + c.pullMessageAndReGetHistoryMessages(ctx, conversationID, successiveSeqList, notStartTime, isReverse, count, startTime, list, messageListCallback) } } else { return true @@ -94,7 +94,7 @@ func (c *Conversation) messageBlocksBetweenContinuityCheck(ctx context.Context, // 根据最小seq向前补齐消息,由服务器告诉拉取消息结果是否到底,如果网络,则向前补齐,获取这一组消息的最大最小seq,以及需要补齐的seq列表长度 func (c *Conversation) messageBlocksEndContinuityCheck(ctx context.Context, minSeq int64, conversationID string, notStartTime, - isReverse bool, count, sessionType int, startTime int64, list *[]*model_struct.LocalChatLog, messageListCallback *sdk.GetAdvancedHistoryMessageListCallback) { + isReverse bool, count int, startTime int64, list *[]*model_struct.LocalChatLog, messageListCallback *sdk.GetAdvancedHistoryMessageListCallback) { if minSeq != 0 { seqList := func(seq int64) (seqList []int64) { startSeq := seq - constant.PullMsgNumForReadDiffusion @@ -110,13 +110,13 @@ func (c *Conversation) messageBlocksEndContinuityCheck(ctx context.Context, minS log.ZDebug(ctx, "pull seqList is ", "seqList", seqList, "len", len(seqList)) if len(seqList) > 0 { - c.pullMessageAndReGetHistoryMessages(ctx, conversationID, seqList, notStartTime, isReverse, count, sessionType, startTime, list, messageListCallback) + c.pullMessageAndReGetHistoryMessages(ctx, conversationID, seqList, notStartTime, isReverse, count, startTime, list, messageListCallback) } } else { //local don't have messages,本地无消息,但是服务器最大消息不为0 seqList := []int64{0, 0} - c.pullMessageAndReGetHistoryMessages(ctx, conversationID, seqList, notStartTime, isReverse, count, sessionType, startTime, list, messageListCallback) + c.pullMessageAndReGetHistoryMessages(ctx, conversationID, seqList, notStartTime, isReverse, count, startTime, list, messageListCallback) } @@ -145,19 +145,19 @@ func (c *Conversation) getMaxAndMinHaveSeqList(messages []*model_struct.LocalCha // 2、块中连续性检测 // 3、块之间连续性检测 func (c *Conversation) pullMessageAndReGetHistoryMessages(ctx context.Context, conversationID string, seqList []int64, notStartTime, - isReverse bool, count, sessionType int, startTime int64, list *[]*model_struct.LocalChatLog, messageListCallback *sdk.GetAdvancedHistoryMessageListCallback) { + isReverse bool, count int, startTime int64, list *[]*model_struct.LocalChatLog, messageListCallback *sdk.GetAdvancedHistoryMessageListCallback) { existedSeqList, err := c.db.GetAlreadyExistSeqList(ctx, conversationID, seqList) if err != nil { - // log.Error(operationID, "SuperGroupGetAlreadyExistSeqList err", err.Error(), sourceID, seqList) + log.ZError(ctx, "GetAlreadyExistSeqList err", err, "conversationID", conversationID, "seqList", seqList) return } if len(existedSeqList) == len(seqList) { - // log.Debug(operationID, "do not pull message") + log.ZDebug(ctx, "do not pull message", "seqList", seqList, "existedSeqList", existedSeqList) return } newSeqList := utils.DifferenceSubset(seqList, existedSeqList) if len(newSeqList) == 0 { - // log.Debug(operationID, "do not pull message") + log.ZDebug(ctx, "do not pull message", "seqList", seqList, "existedSeqList", existedSeqList, "newSeqList", newSeqList) return } var pullMsgResp sdkws.PullMessageBySeqsResp diff --git a/internal/conversation_msg/progress.go b/internal/conversation_msg/progress.go index db7275d82..b7f7373d3 100644 --- a/internal/conversation_msg/progress.go +++ b/internal/conversation_msg/progress.go @@ -32,10 +32,10 @@ type msgUploadFileCallback struct { func (c *msgUploadFileCallback) Open(size int64) { } -func (c *msgUploadFileCallback) PartSize(partSize int64, num int32) { +func (c *msgUploadFileCallback) PartSize(partSize int64, num int) { } -func (c *msgUploadFileCallback) HashPartProgress(index int32, size int64, partHash string) { +func (c *msgUploadFileCallback) HashPartProgress(index int, size int64, partHash string) { } func (c *msgUploadFileCallback) HashPartComplete(partsHash string, fileHash string) { @@ -52,7 +52,7 @@ func (c *msgUploadFileCallback) UploadID(uploadID string) { } } -func (c *msgUploadFileCallback) UploadPartComplete(index int32, partSize int64, partHash string) { +func (c *msgUploadFileCallback) UploadPartComplete(index int, partSize int64, partHash string) { } @@ -74,7 +74,7 @@ func (c *msgUploadFileCallback) UploadComplete(fileSize int64, streamSize int64, } } -func (c *msgUploadFileCallback) Complete(size int64, url string, typ int32) { +func (c *msgUploadFileCallback) Complete(size int64, url string, typ int) { c.msg.AttachedInfoElem.Progress = nil data, err := json.Marshal(c.msg.AttachedInfoElem) if err != nil { diff --git a/internal/conversation_msg/sdk.go b/internal/conversation_msg/sdk.go index ba1ef726f..f611980d7 100644 --- a/internal/conversation_msg/sdk.go +++ b/internal/conversation_msg/sdk.go @@ -424,9 +424,11 @@ func (c *Conversation) SendMessage(ctx context.Context, s *sdk_struct.MsgStruct, res, err := c.file.UploadFile(ctx, &file.UploadFileReq{ //PutID: s.ClientMsgID, - Filepath: sourcePath, - Name: c.fileName("picture", s.ClientMsgID) + filepath.Ext(sourcePath), - Cause: "msg-picture", + ContentType: s.PictureElem.SourcePicture.Type, + Filepath: sourcePath, + Uuid: s.PictureElem.SourcePicture.UUID, + Name: c.fileName("picture", s.ClientMsgID) + filepath.Ext(sourcePath), + Cause: "msg-picture", }, NewUploadFileCallback(ctx, callback.OnProgress, s, lc.ConversationID, c.db)) if err != nil { c.updateMsgStatusAndTriggerConversation(ctx, s.ClientMsgID, "", s.CreateTime, constant.MsgStatusSendFailed, s, lc) @@ -461,9 +463,11 @@ func (c *Conversation) SendMessage(ctx context.Context, s *sdk_struct.MsgStruct, // log.Info("", "file", sourcePath, delFile) res, err := c.file.UploadFile(ctx, &file.UploadFileReq{ - Filepath: sourcePath, - Name: c.fileName("voice", s.ClientMsgID) + filepath.Ext(sourcePath), - Cause: "msg-voice", + ContentType: s.SoundElem.SoundType, + Filepath: sourcePath, + Uuid: s.SoundElem.UUID, + Name: c.fileName("voice", s.ClientMsgID) + filepath.Ext(sourcePath), + Cause: "msg-voice", }, NewUploadFileCallback(ctx, callback.OnProgress, s, lc.ConversationID, c.db)) if err != nil { c.updateMsgStatusAndTriggerConversation(ctx, s.ClientMsgID, "", s.CreateTime, constant.MsgStatusSendFailed, s, lc) @@ -494,27 +498,33 @@ func (c *Conversation) SendMessage(ctx context.Context, s *sdk_struct.MsgStruct, var wg sync.WaitGroup wg.Add(2) var putErrs [2]error - go func() { - defer wg.Done() - snapRes, err := c.file.UploadFile(ctx, &file.UploadFileReq{ - Filepath: snapPath, - Name: c.fileName("videoSnapshot", s.ClientMsgID) + filepath.Ext(snapPath), - Cause: "msg-video-snapshot", - }, nil) - if err != nil { - c.updateMsgStatusAndTriggerConversation(ctx, s.ClientMsgID, "", s.CreateTime, constant.MsgStatusSendFailed, s, lc) - putErrs[0] = err - return - } - s.VideoElem.SnapshotURL = snapRes.URL - }() + if s.VideoElem.SnapshotUUID != "" { + go func() { + defer wg.Done() + snapRes, err := c.file.UploadFile(ctx, &file.UploadFileReq{ + ContentType: s.VideoElem.SnapshotType, + Filepath: snapPath, + Uuid: s.VideoElem.SnapshotUUID, + Name: c.fileName("videoSnapshot", s.ClientMsgID) + filepath.Ext(snapPath), + Cause: "msg-video-snapshot", + }, nil) + if err != nil { + c.updateMsgStatusAndTriggerConversation(ctx, s.ClientMsgID, "", s.CreateTime, constant.MsgStatusSendFailed, s, lc) + putErrs[0] = err + return + } + s.VideoElem.SnapshotURL = snapRes.URL + }() + } go func() { defer wg.Done() res, err := c.file.UploadFile(ctx, &file.UploadFileReq{ - Filepath: videoPath, - Name: c.fileName("video", s.ClientMsgID) + filepath.Ext(videoPath), - Cause: "msg-video", + ContentType: s.VideoElem.VideoType, + Filepath: videoPath, + Uuid: s.VideoElem.VideoUUID, + Name: c.fileName("video", s.ClientMsgID) + filepath.Ext(videoPath), + Cause: "msg-video", }, NewUploadFileCallback(ctx, callback.OnProgress, s, lc.ConversationID, c.db)) if err != nil { c.updateMsgStatusAndTriggerConversation(ctx, s.ClientMsgID, "", s.CreateTime, constant.MsgStatusSendFailed, s, lc) @@ -537,6 +547,7 @@ func (c *Conversation) SendMessage(ctx context.Context, s *sdk_struct.MsgStruct, } res, err := c.file.UploadFile(ctx, &file.UploadFileReq{ Filepath: s.FileElem.FilePath, + Uuid: s.FileElem.UUID, Name: c.fileName("file", s.ClientMsgID) + filepath.Ext(s.FileElem.FilePath), Cause: "msg-file", }, NewUploadFileCallback(ctx, callback.OnProgress, s, lc.ConversationID, c.db)) diff --git a/internal/conversation_msg/sync.go b/internal/conversation_msg/sync.go index 5e8949edd..944cab237 100644 --- a/internal/conversation_msg/sync.go +++ b/internal/conversation_msg/sync.go @@ -84,13 +84,15 @@ func (c *Conversation) SyncConversationHashReadSeqs(ctx context.Context) error { unreadCount = int32(v.MaxSeq - v.HasReadSeq) } if err := c.db.UpdateColumnsConversation(ctx, conversationID, map[string]interface{}{"unread_count": unreadCount, "has_read_seq": v.HasReadSeq}); err != nil { - log.ZError(ctx, "UpdateColumnsConversation err", err, "conversationID", conversationID) + log.ZWarn(ctx, "UpdateColumnsConversation err", err, "conversationID", conversationID) + continue } conversationIDs = append(conversationIDs, conversationID) } log.ZDebug(ctx, "update conversations", "conversations", conversations) - - common.TriggerCmdUpdateConversation(ctx, common.UpdateConNode{Action: constant.ConChange, Args: conversationIDs}, c.GetCh()) - common.TriggerCmdUpdateConversation(ctx, common.UpdateConNode{Action: constant.TotalUnreadMessageChanged, Args: conversationIDs}, c.GetCh()) + if len(conversationIDs) > 0 { + common.TriggerCmdUpdateConversation(ctx, common.UpdateConNode{Action: constant.ConChange, Args: conversationIDs}, c.GetCh()) + common.TriggerCmdUpdateConversation(ctx, common.UpdateConNode{Action: constant.TotalUnreadMessageChanged, Args: conversationIDs}, c.GetCh()) + } return nil } diff --git a/internal/file/file_default.go b/internal/file/file_default.go index 80b152df8..dc38f5e72 100644 --- a/internal/file/file_default.go +++ b/internal/file/file_default.go @@ -7,8 +7,8 @@ import ( "os" ) -func Open(path string) (ReadFile, error) { - file, err := os.Open(path) +func Open(req *UploadFileReq) (ReadFile, error) { + file, err := os.Open(req.Filepath) if err != nil { return nil, err } diff --git a/internal/file/file_js.go b/internal/file/file_js.go index 0e7b754d1..5720cee07 100644 --- a/internal/file/file_js.go +++ b/internal/file/file_js.go @@ -7,10 +7,11 @@ import ( "errors" "io" "open_im_sdk/wasm/exec" + "syscall/js" ) -func Open(uuid string) (ReadFile, error) { - file := &jsCallFile{uuid: uuid} +func Open(req *UploadFileReq) (ReadFile, error) { + file := newJsCallFile(req.Uuid) size, err := file.Open() if err != nil { return nil, err @@ -18,7 +19,7 @@ func Open(uuid string) (ReadFile, error) { return &jsFile{ size: size, file: file, - } + }, nil } type jsFile struct { @@ -32,13 +33,13 @@ func (j *jsFile) Read(p []byte) (n int, err error) { if length == 0 { return 0, errors.New("read buffer is empty") } - if j.whence >= j.size { + if j.whence >= int(j.size) { return 0, io.EOF } - if j.whence+length > j.size { - length = int(j.size - j.whence) + if j.whence+length > int(j.size) { + length = int(j.size) - j.whence } - data, err := j.file.Read(j.whence, length) + data, err := j.file.Read(int64(j.whence), int64(length)) if err != nil { return 0, err } @@ -59,7 +60,7 @@ func (j *jsFile) Size() int64 { } func (j *jsFile) StartSeek(whence int) error { - if whence < 0 || whence > j.size { + if whence < 0 || whence > int(j.size) { return errors.New("seek whence is out of range") } j.whence = whence @@ -70,6 +71,10 @@ type jsCallFile struct { uuid string } +func newJsCallFile(uuid string) *jsCallFile { + return &jsCallFile{uuid: uuid} +} + func (j *jsCallFile) Open() (int64, error) { return WasmOpen(j.uuid) } diff --git a/internal/file/upload.go b/internal/file/upload.go index 0bfc6208b..b6cd78684 100644 --- a/internal/file/upload.go +++ b/internal/file/upload.go @@ -26,6 +26,7 @@ type UploadFileReq struct { Name string `json:"name"` ContentType string `json:"contentType"` Cause string `json:"cause"` + Uuid string `json:"uuid"` } type UploadFileResp struct { @@ -67,7 +68,7 @@ func (f *File) UploadFile(ctx context.Context, req *UploadFileReq, cb UploadFile if prefix := f.loginUserID + "/"; !strings.HasPrefix(req.Name, prefix) { req.Name = prefix + req.Name } - file, err := Open(req.Filepath) + file, err := Open(req) if err != nil { return nil, err } @@ -78,6 +79,9 @@ func (f *File) UploadFile(ctx context.Context, req *UploadFileReq, cb UploadFile if err != nil { return nil, err } + if req.ContentType == "" { + req.ContentType = info.ContentType + } partSize := info.PartSize partSizes := info.PartSizes partMd5s := info.PartMd5s @@ -385,7 +389,7 @@ func (f *File) getPartInfo(ctx context.Context, r io.Reader, fileSize int64, cb } partSizes[partNum-1] = fileSize - partSize*(int64(partNum)-1) partMd5s := make([]string, partNum) - buf := make([]byte, 1024) + buf := make([]byte, 1024*8) fileMd5 := md5.New() var contentType string for i := 0; i < partNum; i++ { diff --git a/internal/user/convert.go b/internal/user/convert.go index 329765ebd..73ffcb056 100644 --- a/internal/user/convert.go +++ b/internal/user/convert.go @@ -22,12 +22,12 @@ import ( func ServerUserToLocalUser(user *sdkws.UserInfo) *model_struct.LocalUser { return &model_struct.LocalUser{ - UserID: user.UserID, - Nickname: user.Nickname, - FaceURL: user.FaceURL, - CreateTime: user.CreateTime, - Ex: user.Ex, - AppMangerLevel: user.AppMangerLevel, + UserID: user.UserID, + Nickname: user.Nickname, + FaceURL: user.FaceURL, + CreateTime: user.CreateTime, + Ex: user.Ex, + //AppMangerLevel: user.AppMangerLevel, GlobalRecvMsgOpt: user.GlobalRecvMsgOpt, //AttachedInfo: user.AttachedInfo, } diff --git a/internal/user/user.go b/internal/user/user.go index ff21ff647..2c8c3fd37 100644 --- a/internal/user/user.go +++ b/internal/user/user.go @@ -98,6 +98,37 @@ func (u *User) initSyncer() { ) } +//func (u *User) equal(a, b *model_struct.LocalUser) bool { +// if a.CreateTime != b.CreateTime { +// log.ZDebug(context.Background(), "user equal", "a", a.CreateTime, "b", b.CreateTime) +// } +// if a.UserID != b.UserID { +// log.ZDebug(context.Background(), "user equal", "a", a.UserID, "b", b.UserID) +// } +// if a.Ex != b.Ex { +// log.ZDebug(context.Background(), "user equal", "a", a.Ex, "b", b.Ex) +// } +// +// if a.Nickname != b.Nickname { +// log.ZDebug(context.Background(), "user equal", "a", a.Nickname, "b", b.Nickname) +// } +// if a.FaceURL != b.FaceURL { +// log.ZDebug(context.Background(), "user equal", "a", a.FaceURL, "b", b.FaceURL) +// } +// if a.AttachedInfo != b.AttachedInfo { +// log.ZDebug(context.Background(), "user equal", "a", a.AttachedInfo, "b", b.AttachedInfo) +// } +// if a.GlobalRecvMsgOpt != b.GlobalRecvMsgOpt { +// log.ZDebug(context.Background(), "user equal", "a", a.GlobalRecvMsgOpt, "b", b.GlobalRecvMsgOpt) +// } +// if a.AppMangerLevel != b.AppMangerLevel { +// log.ZDebug(context.Background(), "user equal", "a", a.AppMangerLevel, "b", b.AppMangerLevel) +// } +// return a.UserID == b.UserID && a.Nickname == b.Nickname && a.FaceURL == b.FaceURL && +// a.CreateTime == b.CreateTime && a.AttachedInfo == b.AttachedInfo && +// a.Ex == b.Ex && a.GlobalRecvMsgOpt == b.GlobalRecvMsgOpt && a.AppMangerLevel == b.AppMangerLevel +//} + // DoNotification handles incoming notifications for the user. func (u *User) DoNotification(ctx context.Context, msg *sdkws.MsgData) { log.ZDebug(ctx, "user notification", "msg", *msg) diff --git a/open_im_sdk/file.go b/open_im_sdk/file.go index b31782b75..0bbf87f5a 100644 --- a/open_im_sdk/file.go +++ b/open_im_sdk/file.go @@ -1,5 +1,11 @@ package open_im_sdk -// func UploadFile(callback open_im_sdk_callback.Base, operationID string, req string, progress open_im_sdk_callback.UploadFileCallback) { -// call(callback, operationID, UserForSDK.File().UploadFile, req, file.UploadFileCallback(progress)) -// } +import ( + "open_im_sdk/internal/file" + "open_im_sdk/open_im_sdk_callback" +) + +func UploadFile(callback open_im_sdk_callback.Base, operationID string, req string, progress open_im_sdk_callback.UploadFileCallback) { + call(callback, operationID, UserForSDK.File().UploadFile, req, file.UploadFileCallback(progress)) +} + diff --git a/open_im_sdk_callback/callback_client.go b/open_im_sdk_callback/callback_client.go index 87465da43..a6e1aa134 100644 --- a/open_im_sdk_callback/callback_client.go +++ b/open_im_sdk_callback/callback_client.go @@ -130,11 +130,11 @@ type OnSignalingListener interface { type UploadFileCallback interface { Open(size int64) // 文件打开的大小 - PartSize(partSize int64, num int32) // 分片大小,数量 - HashPartProgress(index int32, size int64, partHash string) // 每块分片的hash值 + PartSize(partSize int64, num int) // 分片大小,数量 + HashPartProgress(index int, size int64, partHash string) // 每块分片的hash值 HashPartComplete(partsHash string, fileHash string) // 分块完成,服务端标记hash和文件最终hash UploadID(uploadID string) // 上传ID - UploadPartComplete(index int32, partSize int64, partHash string) // 上传分片进度 + UploadPartComplete(index int, partSize int64, partHash string) // 上传分片进度 UploadComplete(fileSize int64, streamSize int64, storageSize int64) // 整体进度 - Complete(size int64, url string, typ int32) // 上传完成 + Complete(size int64, url string, typ int) // 上传完成 } diff --git a/pkg/db/db_js.go b/pkg/db/db_js.go index fa2ac9d85..2a42e165a 100644 --- a/pkg/db/db_js.go +++ b/pkg/db/db_js.go @@ -39,6 +39,7 @@ type IndexDB struct { *indexdb.LocalGroupRequest *indexdb.LocalChatLogReactionExtensions *indexdb.NotificationSeqs + *indexdb.LocalUpload loginUserID string } @@ -68,6 +69,7 @@ func NewDataBase(ctx context.Context, loginUserID string, dbDir string) (*IndexD LocalGroupRequest: indexdb.NewLocalGroupRequest(), LocalChatLogReactionExtensions: indexdb.NewLocalChatLogReactionExtensions(), NotificationSeqs: indexdb.NewNotificationSeqs(), + LocalUpload: indexdb.NewLocalUpload(), loginUserID: loginUserID, } err := i.InitDB(ctx, loginUserID, dbDir) diff --git a/pkg/db/model_struct/data_model_struct.go b/pkg/db/model_struct/data_model_struct.go index 27db633e9..81f6a514c 100644 --- a/pkg/db/model_struct/data_model_struct.go +++ b/pkg/db/model_struct/data_model_struct.go @@ -488,7 +488,7 @@ func (NotificationSeqs) TableName() string { type LocalUpload struct { PartHash string `gorm:"column:part_hash;primary_key" json:"partHash"` UploadID string `gorm:"column:upload_id;type:varchar(1000)" json:"uploadID"` - UploadInfo string `gorm:"column:info;type:varchar(2000)" json:"info"` + UploadInfo string `gorm:"column:upload_info;type:varchar(2000)" json:"uploadInfo"` ExpireTime int64 `gorm:"column:expire_time" json:"expireTime"` CreateTime int64 `gorm:"column:create_time" json:"createTime"` } diff --git a/pkg/db/upload_model.go b/pkg/db/upload_model.go index f3790da1b..de1bd104c 100644 --- a/pkg/db/upload_model.go +++ b/pkg/db/upload_model.go @@ -1,3 +1,20 @@ +// Copyright © 2023 OpenIM SDK. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:build !js +// +build !js + package db import ( diff --git a/pkg/syncer/syncer.go b/pkg/syncer/syncer.go index 68af34182..79479e353 100644 --- a/pkg/syncer/syncer.go +++ b/pkg/syncer/syncer.go @@ -16,6 +16,7 @@ package syncer import ( "context" + "github.com/google/go-cmp/cmp" "reflect" "github.com/OpenIMSDK/Open-IM-Server/pkg/common/log" @@ -62,7 +63,7 @@ func (s *Syncer[T, V]) eq(server T, local T) bool { if s.equal != nil { return s.equal(server, local) } - return reflect.DeepEqual(server, local) + return cmp.Equal(server, local) } func (s *Syncer[T, V]) onNotice(ctx context.Context, state int, server, local T, fn func(ctx context.Context, state int, server, local T) error) error { @@ -111,6 +112,8 @@ func (s *Syncer[T, V]) Sync(ctx context.Context, serverData []T, localData []T, continue } delete(localMap, id) + log.ZDebug(ctx, "syncer come", "type", s.ts, "server", server, "local", local, "isEq", s.eq(server, local)) + if s.eq(server, local) { if err := s.onNotice(ctx, Unchanged, local, server, notice); err != nil { log.ZError(ctx, "sync notice unchanged failed", err, "type", s.ts, "server", server, "local", local) @@ -122,9 +125,6 @@ func (s *Syncer[T, V]) Sync(ctx context.Context, serverData []T, localData []T, log.ZError(ctx, "sync update failed", err, "type", s.ts, "server", server, "local", local) return err } - if s.ts == "model_struct.LocalUser" { - log.ZDebug(ctx, "model_struct.LocalUser", "type", s.ts, "server", server, "local", local, "isEq", s.eq(server, local)) - } if err := s.onNotice(ctx, Update, server, local, notice); err != nil { log.ZError(ctx, "sync notice update failed", err, "type", s.ts, "server", server, "local", local) return err diff --git a/test/login.go b/test/login.go index 06119a3df..fa76855f9 100644 --- a/test/login.go +++ b/test/login.go @@ -48,7 +48,7 @@ func (b *BaseSuccessFailed) OnSuccess(data string) { func InOutDoTest(uid, tk, ws, api string) { var cf sdk_struct.IMConfig cf.ApiAddr = api - cf.PlatformID = 3 + cf.PlatformID = 1 cf.WsAddr = ws cf.DataDir = "./" cf.LogLevel = LogLevel diff --git a/testv2/config.go b/testv2/config.go index 3cf6838dc..28ad957bc 100644 --- a/testv2/config.go +++ b/testv2/config.go @@ -22,17 +22,17 @@ const ( //UserID = "kernaltestuid2" //APIADDR = "http://59.36.173.89:10002" - APIADDR = "http://203.56.175.233:10002" + APIADDR = "http://43.154.157.177:10002" //WSADDR = "ws://59.36.173.89:10001" - WSADDR = "ws://203.56.175.233:10001" + WSADDR = "ws://43.154.157.177:10001" //UserID = "2688118337" //UserID = "7204255074" - UserID = "5226390099" + UserID = "6896076866" friendUserID = "3281432310" // APIADDR = "http://192.168.44.128:10002" // WSADDR = "ws://192.168.44.128:10001" // UserID = "100" - + //APIADDR = "http://59.36.173.89:10002" //WSADDR = "ws://59.36.173.89:10001" //UserID = "kernaltestuid9" diff --git a/testv2/init.go b/testv2/init.go index 00731aa67..cb494c599 100644 --- a/testv2/init.go +++ b/testv2/init.go @@ -38,6 +38,7 @@ func init() { rand.Seed(time.Now().UnixNano()) listner := &OnConnListener{} config := getConf(APIADDR, WSADDR) + config.DataDir = "" configData, err := json.Marshal(config) if err != nil { panic(err) @@ -67,7 +68,7 @@ func GetUserToken(ctx context.Context, userID string) (string, error) { jsonReqData, err := json.Marshal(map[string]any{ "userID": userID, "platformID": 1, - "secret": "openIM123", + "secret": "tuoyun", //"secret": "111111", }) if err != nil { diff --git a/testv3/msg_test.go b/testv3/msg_test.go index 18c05c654..4d1f4fd99 100644 --- a/testv3/msg_test.go +++ b/testv3/msg_test.go @@ -296,18 +296,15 @@ func Test_SendMsgByGroup_One(t *testing.T) { // 管理员邀请大量群成员进行群聊测试 func Test_SendMsgByGroup_Batch(t *testing.T) { - count := 10 + count := 1000 // groupID := "780048154" - groupID := "3159824577" + // groupID := "3159824577" + groupID := "4269768429" var uidList []string - var ctxList []context.Context for i := 0; i <= count; i++ { uid := fmt.Sprintf("register_test_%v", i+1) - funcation.LoginOne(uid) uidList = append(uidList, uid) - ctx := getCtx(uid) - ctxList = append(ctxList, ctx) } // 管理员批量邀请进群 adminUID := "openIM123456" @@ -321,7 +318,8 @@ func Test_SendMsgByGroup_Batch(t *testing.T) { for i := 0; i <= count; i++ { uid := uidList[i] - ctx := ctxList[i] + funcation.LoginOne(uid) + ctx := getCtx(uid) // time.Sleep(time.Duration(200) * time.Millisecond) msg := fmt.Sprintf("%v send to %v message", uid, groupID) diff --git a/wasm/cmd/main.go b/wasm/cmd/main.go index 6a330f978..de49c12d5 100644 --- a/wasm/cmd/main.go +++ b/wasm/cmd/main.go @@ -39,10 +39,10 @@ func main() { } func registerFunc() { - //register global listener funcation + //register global listener function globalFuc := wasm_wrapper.NewWrapperCommon() js.Global().Set(wasm_wrapper.COMMONEVENTFUNC, js.FuncOf(globalFuc.CommonEventFunc)) - //register init login funcation + //register init login function wrapperInitLogin := wasm_wrapper.NewWrapperInitLogin(globalFuc) js.Global().Set("initSDK", js.FuncOf(wrapperInitLogin.InitSDK)) js.Global().Set("login", js.FuncOf(wrapperInitLogin.Login)) @@ -50,7 +50,7 @@ func registerFunc() { js.Global().Set("getLoginStatus", js.FuncOf(wrapperInitLogin.GetLoginStatus)) js.Global().Set("setAppBackgroundStatus", js.FuncOf(wrapperInitLogin.SetAppBackgroundStatus)) js.Global().Set("networkStatusChanged", js.FuncOf(wrapperInitLogin.NetworkStatusChanged)) - //register conversation and message funcation + //register conversation and message function wrapperConMsg := wasm_wrapper.NewWrapperConMsg(globalFuc) js.Global().Set("createTextMessage", js.FuncOf(wrapperConMsg.CreateTextMessage)) js.Global().Set("createImageMessage", js.FuncOf(wrapperConMsg.CreateImageMessage)) @@ -184,4 +184,6 @@ func registerFunc() { wrapperThird := wasm_wrapper.NewWrapperThird(globalFuc) js.Global().Set("updateFcmToken", js.FuncOf(wrapperThird.UpdateFcmToken)) + js.Global().Set("uploadFile", js.FuncOf(wrapperThird.UploadFile)) + } diff --git a/wasm/event_listener/listener.go b/wasm/event_listener/listener.go index 5125f1830..826ec62cd 100644 --- a/wasm/event_listener/listener.go +++ b/wasm/event_listener/listener.go @@ -18,6 +18,8 @@ package event_listener import ( + "open_im_sdk/internal/file" + "open_im_sdk/open_im_sdk_callback" "open_im_sdk/pkg/utils" "open_im_sdk/sdk_struct" "syscall/js" @@ -188,6 +190,94 @@ func (s *SendMessageCallback) OnProgress(progress int) { mReply["clientMsgID"] = s.clientMsgID s.globalEvent.SetEvent(utils.GetSelfFuncName()).SetData(utils.StructToJsonString(mReply)).SendMessage() } +type UploadInterface interface { + open_im_sdk_callback.Base + open_im_sdk_callback.UploadFileCallback +} +var _ UploadInterface = (*UploadFileCallback)(nil) +type UploadFileCallback struct { + BaseCallback + globalEvent CallbackWriter + Uuid string +} + +func NewUploadFileCallback(funcName string, callback *js.Value) *UploadFileCallback { + return &UploadFileCallback{BaseCallback: BaseCallback{CallbackWriter: NewPromiseHandler().SetEvent(funcName)}, globalEvent: NewEventData(callback).SetEvent(funcName)} +} +func (u *UploadFileCallback) SetUuid(args *[]js.Value)*UploadFileCallback{ + f := file.UploadFileReq{} + utils.JsonStringToStruct((*args)[1].String(), &f) + u.Uuid = f.Uuid + return u +} +func (u *UploadFileCallback) Open(size int64) { + mReply := make(map[string]interface{}) + mReply["size"] = size + mReply["uuid"] = u.Uuid + u.globalEvent.SetEvent(utils.GetSelfFuncName()).SetData(utils.StructToJsonString(mReply)).SendMessage() +} + +func (u *UploadFileCallback) PartSize(partSize int64, num int) { + mReply := make(map[string]interface{}) + mReply["partSize"] = partSize + mReply["num"] = num + mReply["uuid"] = u.Uuid + u.globalEvent.SetEvent(utils.GetSelfFuncName()).SetData(utils.StructToJsonString(mReply)).SendMessage() +} + +func (u *UploadFileCallback) HashPartProgress(index int, size int64, partHash string) { + mReply := make(map[string]interface{}) + mReply["index"] = index + mReply["size"] = size + mReply["partHash"] = partHash + mReply["uuid"] = u.Uuid + u.globalEvent.SetEvent(utils.GetSelfFuncName()).SetData(utils.StructToJsonString(mReply)).SendMessage() +} + +func (u *UploadFileCallback) HashPartComplete(partsHash string, fileHash string) { + mReply := make(map[string]interface{}) + mReply["partsHash"] = partsHash + mReply["fileHash"] = fileHash + mReply["uuid"] = u.Uuid + u.globalEvent.SetEvent(utils.GetSelfFuncName()).SetData(utils.StructToJsonString(mReply)).SendMessage() +} + +func (u *UploadFileCallback) UploadID(uploadID string) { + mReply := make(map[string]interface{}) + mReply["uploadID"] = uploadID + mReply["uuid"] = u.Uuid + u.globalEvent.SetEvent(utils.GetSelfFuncName()).SetData(utils.StructToJsonString(mReply)).SendMessage() +} + +func (u *UploadFileCallback) UploadPartComplete(index int, partSize int64, partHash string) { + mReply := make(map[string]interface{}) + mReply["index"] = index + mReply["partSize"] = partSize + mReply["partHash"] = partHash + mReply["uuid"] = u.Uuid + u.globalEvent.SetEvent(utils.GetSelfFuncName()).SetData(utils.StructToJsonString(mReply)).SendMessage() +} + +func (u *UploadFileCallback) UploadComplete(fileSize int64, streamSize int64, storageSize int64) { + mReply := make(map[string]interface{}) + mReply["fileSize"] = fileSize + mReply["streamSize"] = streamSize + mReply["storageSize"] = storageSize + mReply["uuid"] = u.Uuid + u.globalEvent.SetEvent(utils.GetSelfFuncName()).SetData(utils.StructToJsonString(mReply)).SendMessage() +} + +func (u *UploadFileCallback) Complete(size int64, url string, typ int) { + mReply := make(map[string]interface{}) + mReply["size"] = size + mReply["url"] = url + mReply["typ"] = typ + mReply["uuid"] = u.Uuid + u.globalEvent.SetEvent(utils.GetSelfFuncName()).SetData(utils.StructToJsonString(mReply)).SendMessage() +} + + + type BatchMessageCallback struct { CallbackWriter diff --git a/wasm/exec/executor.go b/wasm/exec/executor.go index a5f624abc..24d04bcac 100644 --- a/wasm/exec/executor.go +++ b/wasm/exec/executor.go @@ -73,7 +73,7 @@ func Exec(args ...interface{}) (output interface{}, err error) { } } }() - log.Debug("js then funcation", "=> (main go context) "+funcName+" with respone ", args[0].String()) + log.Debug("js then function", "=> (main go context) "+funcName+" with response ", args[0].String()) thenChannel <- args return nil }) @@ -91,7 +91,7 @@ func Exec(args ...interface{}) (output interface{}, err error) { } } }() - log.Debug("js catch funcation", "=> (main go context) "+funcName+" with respone ", args[0].String()) + log.Debug("js catch function", "=> (main go context) "+funcName+" with respone ", args[0].String()) catchChannel <- args return nil }) @@ -110,7 +110,7 @@ func Exec(args ...interface{}) (output interface{}, err error) { return result[0], nil default: - err = errors.New("unkown return type from javascript") + err = errors.New("unknown return type from javascript") } } else { diff --git a/wasm/indexdb/upload_model.go b/wasm/indexdb/upload_model.go new file mode 100644 index 000000000..ec2f386c5 --- /dev/null +++ b/wasm/indexdb/upload_model.go @@ -0,0 +1,68 @@ +// Copyright © 2023 OpenIM SDK. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:build js && wasm +// +build js,wasm + +package indexdb + +import ( + "context" + "open_im_sdk/pkg/db/model_struct" + "open_im_sdk/pkg/utils" + "open_im_sdk/wasm/exec" +) + +type LocalUpload struct{} + +func NewLocalUpload() *LocalUpload { + return &LocalUpload{} +} + +func (i *LocalUpload) GetUpload(ctx context.Context, partHash string) (*model_struct.LocalUpload, error) { + c, err := exec.Exec(partHash) + if err != nil { + return nil, err + } else { + if v, ok := c.(string); ok { + result := model_struct.LocalUpload{} + err := utils.JsonStringToStruct(v, &result) + if err != nil { + return nil, err + } + return &result, err + } else { + return nil, exec.ErrType + } + } +} + +func (i *LocalUpload) InsertUpload(ctx context.Context, upload *model_struct.LocalUpload) error { + _, err := exec.Exec(utils.StructToJsonString(upload)) + return err +} + +func (i *LocalUpload) DeleteUpload(ctx context.Context, partHash string) error { + _, err := exec.Exec(partHash) + return err +} +func (i *LocalUpload) UpdateUpload(ctx context.Context, upload *model_struct.LocalUpload) error { + _, err := exec.Exec(utils.StructToJsonString(upload)) + return err +} + +func (i *LocalUpload) DeleteExpireUpload(ctx context.Context) error { + //TODO implement me + panic("implement me") +} diff --git a/wasm/wasm_wrapper/wasm_third.go b/wasm/wasm_wrapper/wasm_third.go index 97ca96c3d..b32d48af2 100644 --- a/wasm/wasm_wrapper/wasm_third.go +++ b/wasm/wasm_wrapper/wasm_third.go @@ -19,12 +19,13 @@ package wasm_wrapper import ( "open_im_sdk/open_im_sdk" + "open_im_sdk/open_im_sdk_callback" "open_im_sdk/pkg/utils" "open_im_sdk/wasm/event_listener" "syscall/js" ) -// ------------------------------------group--------------------------- +// ------------------------------------third--------------------------- type WrapperThird struct { *WrapperCommon } @@ -36,3 +37,73 @@ func (w *WrapperThird) UpdateFcmToken(_ js.Value, args []js.Value) interface{} { callback := event_listener.NewBaseCallback(utils.FirstLower(utils.GetSelfFuncName()), w.commonFunc) return event_listener.NewCaller(open_im_sdk.UpdateFcmToken, callback, &args).AsyncCallWithCallback() } +func (w *WrapperThird) UploadFile(_ js.Value, args []js.Value) interface{} { + callback := event_listener.NewUploadFileCallback(utils.FirstLower(utils.GetSelfFuncName()), w.commonFunc).SetUuid(&args) + return event_listener.NewCaller(UploadFile, callback, &args).AsyncCallWithCallback() +} + +var _ open_im_sdk_callback.Base = (*TempBase)(nil) + +type TempBase struct { + u event_listener.UploadInterface +} + +func NewTempBase(u event_listener.UploadInterface) *TempBase { + return &TempBase{u: u} +} + +func (t TempBase) OnError(errCode int32, errMsg string) { + t.u.OnError(errCode, errMsg) +} + +func (t TempBase) OnSuccess(data string) { + t.u.OnSuccess(data) +} + +var _ open_im_sdk_callback.UploadFileCallback = (*TempUploadFile)(nil) + +type TempUploadFile struct { + u event_listener.UploadInterface +} + +func NewTempUploadFile(u event_listener.UploadInterface) *TempUploadFile { + return &TempUploadFile{u: u} +} + +func (t TempUploadFile) Open(size int64) { + t.u.Open(size) +} + +func (t TempUploadFile) PartSize(partSize int64, num int) { + t.u.PartSize(partSize, num) +} + +func (t TempUploadFile) HashPartProgress(index int, size int64, partHash string) { + t.u.HashPartProgress(index, size, partHash) +} + +func (t TempUploadFile) HashPartComplete(partsHash string, fileHash string) { + t.u.HashPartComplete(partsHash, fileHash) +} + +func (t TempUploadFile) UploadID(uploadID string) { + t.u.UploadID(uploadID) +} + +func (t TempUploadFile) UploadPartComplete(index int, partSize int64, partHash string) { + t.u.UploadPartComplete(index, partSize, partHash) +} + +func (t TempUploadFile) UploadComplete(fileSize int64, streamSize int64, storageSize int64) { + t.u.UploadComplete(fileSize, streamSize, storageSize) +} + +func (t TempUploadFile) Complete(size int64, url string, typ int) { + t.u.Complete(size, url, typ) +} + +func UploadFile(callback event_listener.UploadInterface, operationID string, req string) { + b := NewTempBase(callback) + t := NewTempUploadFile(callback) + open_im_sdk.UploadFile(b, operationID, req, t) +}