You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
199 lines
9.1 KiB
199 lines
9.1 KiB
// Copyright 2021 OpenIM Corporation
|
|
//
|
|
// 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.
|
|
|
|
package friend
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/openimsdk/openim-sdk-core/v3/internal/user"
|
|
"github.com/openimsdk/openim-sdk-core/v3/open_im_sdk_callback"
|
|
"github.com/openimsdk/openim-sdk-core/v3/pkg/common"
|
|
"github.com/openimsdk/openim-sdk-core/v3/pkg/constant"
|
|
"github.com/openimsdk/openim-sdk-core/v3/pkg/db/db_interface"
|
|
"github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct"
|
|
"github.com/openimsdk/openim-sdk-core/v3/pkg/page"
|
|
"github.com/openimsdk/openim-sdk-core/v3/pkg/syncer"
|
|
friend "github.com/openimsdk/protocol/relation"
|
|
"github.com/openimsdk/tools/utils/datautil"
|
|
|
|
"github.com/openimsdk/protocol/sdkws"
|
|
"github.com/openimsdk/tools/log"
|
|
)
|
|
|
|
func NewFriend(loginUserID string, db db_interface.DataBase, user *user.User, conversationCh chan common.Cmd2Value) *Friend {
|
|
f := &Friend{loginUserID: loginUserID, db: db, user: user, conversationCh: conversationCh}
|
|
f.initSyncer()
|
|
return f
|
|
}
|
|
|
|
type Friend struct {
|
|
friendListener open_im_sdk_callback.OnFriendshipListenerSdk
|
|
loginUserID string
|
|
db db_interface.DataBase
|
|
user *user.User
|
|
friendSyncer *syncer.Syncer[*model_struct.LocalFriend, friend.GetPaginationFriendsResp, [2]string]
|
|
blockSyncer *syncer.Syncer[*model_struct.LocalBlack, syncer.NoResp, [2]string]
|
|
requestRecvSyncer *syncer.Syncer[*model_struct.LocalFriendRequest, syncer.NoResp, [2]string]
|
|
requestSendSyncer *syncer.Syncer[*model_struct.LocalFriendRequest, syncer.NoResp, [2]string]
|
|
conversationCh chan common.Cmd2Value
|
|
listenerForService open_im_sdk_callback.OnListenerForService
|
|
}
|
|
|
|
func (f *Friend) initSyncer() {
|
|
f.friendSyncer = syncer.New2[*model_struct.LocalFriend, friend.GetPaginationFriendsResp, [2]string](
|
|
syncer.WithInsert[*model_struct.LocalFriend, friend.GetPaginationFriendsResp, [2]string](func(ctx context.Context, value *model_struct.LocalFriend) error {
|
|
return f.db.InsertFriend(ctx, value)
|
|
}),
|
|
syncer.WithDelete[*model_struct.LocalFriend, friend.GetPaginationFriendsResp, [2]string](func(ctx context.Context, value *model_struct.LocalFriend) error {
|
|
return f.db.DeleteFriendDB(ctx, value.FriendUserID)
|
|
}),
|
|
syncer.WithUpdate[*model_struct.LocalFriend, friend.GetPaginationFriendsResp, [2]string](func(ctx context.Context, server, local *model_struct.LocalFriend) error {
|
|
return f.db.UpdateFriend(ctx, server)
|
|
}),
|
|
syncer.WithUUID[*model_struct.LocalFriend, friend.GetPaginationFriendsResp, [2]string](func(value *model_struct.LocalFriend) [2]string {
|
|
return [...]string{value.OwnerUserID, value.FriendUserID}
|
|
}),
|
|
syncer.WithNotice[*model_struct.LocalFriend, friend.GetPaginationFriendsResp, [2]string](func(ctx context.Context, state int, server, local *model_struct.LocalFriend) error {
|
|
switch state {
|
|
case syncer.Insert:
|
|
f.friendListener.OnFriendAdded(*server)
|
|
case syncer.Delete:
|
|
log.ZDebug(ctx, "syncer OnFriendDeleted", "local", local)
|
|
f.friendListener.OnFriendDeleted(*local)
|
|
case syncer.Update:
|
|
f.friendListener.OnFriendInfoChanged(*server)
|
|
if local.Nickname != server.Nickname || local.FaceURL != server.FaceURL || local.Remark != server.Remark {
|
|
if server.Remark != "" {
|
|
server.Nickname = server.Remark
|
|
}
|
|
_ = common.TriggerCmdUpdateConversation(ctx, common.UpdateConNode{
|
|
Action: constant.UpdateConFaceUrlAndNickName,
|
|
Args: common.SourceIDAndSessionType{
|
|
SourceID: server.FriendUserID,
|
|
SessionType: constant.SingleChatType,
|
|
FaceURL: server.FaceURL,
|
|
Nickname: server.Nickname,
|
|
},
|
|
}, f.conversationCh)
|
|
_ = common.TriggerCmdUpdateMessage(ctx, common.UpdateMessageNode{
|
|
Action: constant.UpdateMsgFaceUrlAndNickName,
|
|
Args: common.UpdateMessageInfo{
|
|
SessionType: constant.SingleChatType,
|
|
UserID: server.FriendUserID,
|
|
FaceURL: server.FaceURL,
|
|
Nickname: server.Nickname,
|
|
},
|
|
}, f.conversationCh)
|
|
}
|
|
}
|
|
return nil
|
|
}),
|
|
syncer.WithBatchInsert[*model_struct.LocalFriend, friend.GetPaginationFriendsResp, [2]string](func(ctx context.Context, values []*model_struct.LocalFriend) error {
|
|
log.ZDebug(ctx, "BatchInsertFriend", "length", len(values))
|
|
return f.db.BatchInsertFriend(ctx, values)
|
|
}),
|
|
syncer.WithDeleteAll[*model_struct.LocalFriend, friend.GetPaginationFriendsResp, [2]string](func(ctx context.Context, _ string) error {
|
|
return f.db.DeleteAllFriend(ctx)
|
|
}),
|
|
syncer.WithBatchPageReq[*model_struct.LocalFriend, friend.GetPaginationFriendsResp, [2]string](func(entityID string) page.PageReq {
|
|
return &friend.GetPaginationFriendsReq{UserID: entityID,
|
|
Pagination: &sdkws.RequestPagination{ShowNumber: 100}}
|
|
}),
|
|
syncer.WithBatchPageRespConvertFunc[*model_struct.LocalFriend, friend.GetPaginationFriendsResp, [2]string](func(resp *friend.GetPaginationFriendsResp) []*model_struct.LocalFriend {
|
|
return datautil.Batch(ServerFriendToLocalFriend, resp.FriendsInfo)
|
|
}),
|
|
syncer.WithReqApiRouter[*model_struct.LocalFriend, friend.GetPaginationFriendsResp, [2]string](constant.GetFriendListRouter),
|
|
)
|
|
|
|
f.blockSyncer = syncer.New[*model_struct.LocalBlack, syncer.NoResp, [2]string](func(ctx context.Context, value *model_struct.LocalBlack) error {
|
|
return f.db.InsertBlack(ctx, value)
|
|
}, func(ctx context.Context, value *model_struct.LocalBlack) error {
|
|
return f.db.DeleteBlack(ctx, value.BlockUserID)
|
|
}, func(ctx context.Context, server *model_struct.LocalBlack, local *model_struct.LocalBlack) error {
|
|
return f.db.UpdateBlack(ctx, server)
|
|
}, func(value *model_struct.LocalBlack) [2]string {
|
|
return [...]string{value.OwnerUserID, value.BlockUserID}
|
|
}, nil, func(ctx context.Context, state int, server, local *model_struct.LocalBlack) error {
|
|
switch state {
|
|
case syncer.Insert:
|
|
f.friendListener.OnBlackAdded(*server)
|
|
case syncer.Delete:
|
|
f.friendListener.OnBlackDeleted(*local)
|
|
}
|
|
return nil
|
|
})
|
|
f.requestRecvSyncer = syncer.New[*model_struct.LocalFriendRequest, syncer.NoResp, [2]string](func(ctx context.Context, value *model_struct.LocalFriendRequest) error {
|
|
return f.db.InsertFriendRequest(ctx, value)
|
|
}, func(ctx context.Context, value *model_struct.LocalFriendRequest) error {
|
|
return f.db.DeleteFriendRequestBothUserID(ctx, value.FromUserID, value.ToUserID)
|
|
}, func(ctx context.Context, server *model_struct.LocalFriendRequest, local *model_struct.LocalFriendRequest) error {
|
|
return f.db.UpdateFriendRequest(ctx, server)
|
|
}, func(value *model_struct.LocalFriendRequest) [2]string {
|
|
return [...]string{value.FromUserID, value.ToUserID}
|
|
}, nil, func(ctx context.Context, state int, server, local *model_struct.LocalFriendRequest) error {
|
|
switch state {
|
|
case syncer.Insert:
|
|
f.friendListener.OnFriendApplicationAdded(*server)
|
|
case syncer.Delete:
|
|
f.friendListener.OnFriendApplicationDeleted(*local)
|
|
case syncer.Update:
|
|
switch server.HandleResult {
|
|
case constant.FriendResponseAgree:
|
|
f.friendListener.OnFriendApplicationAccepted(*server)
|
|
case constant.FriendResponseRefuse:
|
|
f.friendListener.OnFriendApplicationRejected(*server)
|
|
case constant.FriendResponseDefault:
|
|
f.friendListener.OnFriendApplicationAdded(*server)
|
|
}
|
|
}
|
|
return nil
|
|
})
|
|
f.requestSendSyncer = syncer.New[*model_struct.LocalFriendRequest, syncer.NoResp, [2]string](func(ctx context.Context, value *model_struct.LocalFriendRequest) error {
|
|
return f.db.InsertFriendRequest(ctx, value)
|
|
}, func(ctx context.Context, value *model_struct.LocalFriendRequest) error {
|
|
return f.db.DeleteFriendRequestBothUserID(ctx, value.FromUserID, value.ToUserID)
|
|
}, func(ctx context.Context, server *model_struct.LocalFriendRequest, local *model_struct.LocalFriendRequest) error {
|
|
return f.db.UpdateFriendRequest(ctx, server)
|
|
}, func(value *model_struct.LocalFriendRequest) [2]string {
|
|
return [...]string{value.FromUserID, value.ToUserID}
|
|
}, nil, func(ctx context.Context, state int, server, local *model_struct.LocalFriendRequest) error {
|
|
switch state {
|
|
case syncer.Insert:
|
|
f.friendListener.OnFriendApplicationAdded(*server)
|
|
case syncer.Delete:
|
|
f.friendListener.OnFriendApplicationDeleted(*local)
|
|
case syncer.Update:
|
|
switch server.HandleResult {
|
|
case constant.FriendResponseAgree:
|
|
f.friendListener.OnFriendApplicationAccepted(*server)
|
|
case constant.FriendResponseRefuse:
|
|
f.friendListener.OnFriendApplicationRejected(*server)
|
|
}
|
|
}
|
|
return nil
|
|
})
|
|
}
|
|
|
|
func (f *Friend) Db() db_interface.DataBase {
|
|
return f.db
|
|
}
|
|
|
|
func (f *Friend) SetListener(listener func() open_im_sdk_callback.OnFriendshipListener) {
|
|
f.friendListener = open_im_sdk_callback.NewOnFriendshipListenerSdk(listener)
|
|
}
|
|
|
|
func (f *Friend) SetListenerForService(listener open_im_sdk_callback.OnListenerForService) {
|
|
f.listenerForService = listener
|
|
}
|
|
|