Skip to content

Commit

Permalink
feat: Development of pinned function
Browse files Browse the repository at this point in the history
  • Loading branch information
tangtaoit committed May 23, 2024
1 parent 58f14ff commit fbf7437
Show file tree
Hide file tree
Showing 19 changed files with 517 additions and 9 deletions.
4 changes: 2 additions & 2 deletions WuKongIMSDK.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ Pod::Spec.new do |s|
s.pod_target_xcconfig = {
'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'arm64',
'DEFINES_MODULE' => 'YES'
}
s.user_target_xcconfig = { 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'arm64' }
}
s.user_target_xcconfig = { 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'arm64' }

s.dependency 'CocoaAsyncSocket', '~> 7.6.4'
s.dependency 'FMDB/SQLCipher', '~>2.7.5'
Expand Down
17 changes: 17 additions & 0 deletions WuKongIMSDK/Assets/Migrations/202405221231.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@

alter table `message_extra` add column is_pinned smallint not null default 0; -- 是否置顶


-- 消息扩展表
create table pinned_message
(
id INTEGER PRIMARY KEY AUTOINCREMENT,
message_id UNSIGNED BIG INT not null default 0, -- 消息ID
message_seq UNSIGNED BIG INT not null default 0, -- 消息seq
channel_id VARCHAR(100) not null default '', -- 频道ID
channel_type smallint not null default 0, -- 频道类型
version bigint not null default 0, -- 数据版本
is_deleted smallint not null default 0 -- 是否已删除
);
CREATE UNIQUE INDEX IF NOT EXISTS idx_pinned_message_id ON pinned_message(message_id);
CREATE INDEX IF NOT EXISTS idx_pinned_message_channel ON pinned_message (channel_id, channel_type);
5 changes: 5 additions & 0 deletions WuKongIMSDK/Classes/WKSDK.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@ NS_ASSUME_NONNULL_BEGIN
// 机器人管理者
@property(nonatomic,strong) WKRobotManager *robotManager;

// 置顶消息管理者
@property(nonatomic,strong) WKPinnedMessageManager *pinnedMessageManager;

// 提醒管理者
// 负责最近会话的提醒项,比如 有人@我,入群申请等等 还可以自定义一些提醒,比如类似微信的 [红包] [转账] 列表都会有提醒
@property(nonatomic,strong) WKReminderManager *reminderManager;
Expand All @@ -93,6 +96,8 @@ NS_ASSUME_NONNULL_BEGIN
// sdk版本号,每次升级记得修改此处
@property(nonatomic,copy,readonly) NSString *sdkVersion;



/**
是否是debug模式
Expand Down
4 changes: 4 additions & 0 deletions WuKongIMSDK/Classes/WKSDK.m
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,10 @@ - (WKFlameManager *)flameManager {
return [WKFlameManager shared];
}

- (WKPinnedMessageManager *)pinnedMessageManager {
return WKPinnedMessageManager.shared;
}


-(WKCoder*) coder{
if(!_coder){
Expand Down
2 changes: 2 additions & 0 deletions WuKongIMSDK/Classes/WuKongIMSDK.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,5 @@





1 change: 1 addition & 0 deletions WuKongIMSDK/Classes/WuKongIMSDKHeader.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#import "WKCoder.h"
#import "WKPakcetBodyCoderManager.h"
#import "WKChatManager.h"
#import "WKPinnedMessageManager.h"
#import "WKMessageContent.h"
#import "WKConversationManager.h"
#import "WKChannelManager.h"
Expand Down
6 changes: 5 additions & 1 deletion WuKongIMSDK/Classes/db/WKMessageDB.m
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
//#define SQL_MESSAGE_QUERY_OLDESTID [NSString stringWithFormat:@"select * from %@ where channel_id=? and channel_type=? and is_deleted=0 and content_type<>0 and content_type<>99 and order_seq < ? order by order_seq desc limit 0,?",TB_MESSAGE]

// 扩展表的字段
#define SQL_EXTRA_COLS [NSString stringWithFormat:@"%@,%@,%@,%@,%@,%@,%@,%@,%@,%@",@"IFNULL(message_extra.readed,0) readed",@"IFNULL(message_extra.readed_at,0) readed_at",@"IFNULL(message_extra.readed_count,0) readed_count",@"IFNULL(message_extra.unread_count,0) unread_count",@"IFNULL(message_extra.revoke,'') revoke",@"IFNULL(message_extra.revoker,0) revoker",@"IFNULL(message_extra.content_edit,'') content_edit",@"IFNULL(message_extra.edited_at,0) edited_at",@"IFNULL(message_extra.upload_status,0) upload_status",@"IFNULL(message_extra.extra_version,0) extra_version"]
#define SQL_EXTRA_COLS [NSString stringWithFormat:@"%@,%@,%@,%@,%@,%@,%@,%@,%@,%@,%@",@"IFNULL(message_extra.readed,0) readed",@"IFNULL(message_extra.readed_at,0) readed_at",@"IFNULL(message_extra.readed_count,0) readed_count",@"IFNULL(message_extra.unread_count,0) unread_count",@"IFNULL(message_extra.revoke,'') revoke",@"IFNULL(message_extra.revoker,0) revoker",@"IFNULL(message_extra.is_pinned,0) is_pinned",@"IFNULL(message_extra.content_edit,'') content_edit",@"IFNULL(message_extra.edited_at,0) edited_at",@"IFNULL(message_extra.upload_status,0) upload_status",@"IFNULL(message_extra.extra_version,0) extra_version"]

#define SQL_MESSAGE_QUERY_OLDESTID_DESC(symbol,symbol2) [NSString stringWithFormat:@"select message.*,%@ from %@ left join message_extra on message.message_id=message_extra.message_id where message.channel_id=? and message.channel_type=? and message.is_deleted=0 and message.content_type<>99 and message.order_seq %@ ? %@ order by message.order_seq desc,message.timestamp desc limit 0,?",SQL_EXTRA_COLS,TB_MESSAGE,symbol,symbol2?[NSString stringWithFormat:@" and message.order_seq %@ ?",symbol2]:@""]

Expand Down Expand Up @@ -1096,6 +1096,10 @@ -(WKMessage*) toMessage:(NSDictionary*)dict db:(FMDatabase*)db{
message.remoteExtra.revoker = dict[@"revoker"];
}

if(dict[@"is_pinned"]) {
message.remoteExtra.isPinned = [dict[@"is_pinned"] boolValue];
}

if(dict[@"readed_count"]) {
message.remoteExtra.readedCount = [dict[@"readed_count"] integerValue];
}
Expand Down
7 changes: 4 additions & 3 deletions WuKongIMSDK/Classes/db/WKMessageExtraDB.m
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
#import "WKMessageExtraDB.h"
#import "WKMessageDB.h"
#import "WKDB.h"
#define SQL_MESSAGE_EXTRA_INSERT_OR_UPDATE [NSString stringWithFormat:@"insert into message_extra( message_id,message_seq,channel_id,channel_type,readed,readed_at,readed_count,unread_count,revoke,revoker,content_edit,edited_at,extra,extra_version) values(?,?,?,?,?,?,?,?,?,?,?,?,?,?) ON CONFLICT(message_id) DO UPDATE SET readed=excluded.readed,readed_at=excluded.readed_at,readed_count=excluded.readed_count,unread_count=excluded.unread_count,revoke=excluded.revoke,revoker=excluded.revoker,content_edit=excluded.content_edit,edited_at=excluded.edited_at,extra=excluded.extra,extra_version=excluded.extra_version"]
#define SQL_MESSAGE_EXTRA_INSERT_OR_UPDATE [NSString stringWithFormat:@"insert into message_extra( message_id,message_seq,channel_id,channel_type,readed,readed_at,readed_count,unread_count,revoke,revoker,is_pinned,content_edit,edited_at,extra,extra_version) values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) ON CONFLICT(message_id) DO UPDATE SET readed=excluded.readed,readed_at=excluded.readed_at,readed_count=excluded.readed_count,unread_count=excluded.unread_count,revoke=excluded.revoke,revoker=excluded.revoker,is_pinned=excluded.is_pinned,content_edit=excluded.content_edit,edited_at=excluded.edited_at,extra=excluded.extra,extra_version=excluded.extra_version"]

// 获取指定频道的最大扩展版本号
#define SQL_MESSAGE_EXTRA_MAX_VERSION [NSString stringWithFormat:@"select max(extra_version) max_version from %@ where channel_id=? and channel_type=?",@"message_extra"]
Expand Down Expand Up @@ -65,7 +65,7 @@ -(void) addOrUpdateMessageExtras:(NSArray<WKMessageExtra*>*)messageExtras {
if(messageExtra.readedAt) {
readedAt = [messageExtra.readedAt timeIntervalSince1970];
}
[db executeUpdate:SQL_MESSAGE_EXTRA_INSERT_OR_UPDATE,@(messageExtra.messageID),@(messageExtra.messageSeq),messageExtra.channelID?:@"",@(messageExtra.channelType),@(messageExtra.readed),@(readedAt),@(messageExtra.readedCount),@(messageExtra.unreadCount),@(messageExtra.revoke),messageExtra.revoker?:@"",messageExtra.contentEditData?:@"",@(messageExtra.editedAt),extraStr,@(messageExtra.extraVersion)];
[db executeUpdate:SQL_MESSAGE_EXTRA_INSERT_OR_UPDATE,@(messageExtra.messageID),@(messageExtra.messageSeq),messageExtra.channelID?:@"",@(messageExtra.channelType),@(messageExtra.readed),@(readedAt),@(messageExtra.readedCount),@(messageExtra.unreadCount),@(messageExtra.revoke),messageExtra.revoker?:@"",@(messageExtra.isPinned),messageExtra.contentEditData?:@"",@(messageExtra.editedAt),extraStr,@(messageExtra.extraVersion)];

}
}];
Expand All @@ -92,7 +92,7 @@ -(void) addOrUpdateMessageExtra:(WKMessageExtra*)messageExtra db:(FMDatabase*)db
if(messageExtra.readedAt) {
readedAt = [messageExtra.readedAt timeIntervalSince1970];
}
[db executeUpdate:SQL_MESSAGE_EXTRA_INSERT_OR_UPDATE,@(messageExtra.messageID),@(messageExtra.messageSeq),messageExtra.channelID?:@"",@(messageExtra.channelType),@(messageExtra.readed),@(readedAt),@(messageExtra.readedCount),@(messageExtra.unreadCount),@(messageExtra.revoke),messageExtra.revoker?:@"",messageExtra.contentEditData?:@"",@(messageExtra.editedAt),extraStr,@(messageExtra.extraVersion)];
[db executeUpdate:SQL_MESSAGE_EXTRA_INSERT_OR_UPDATE,@(messageExtra.messageID),@(messageExtra.messageSeq),messageExtra.channelID?:@"",@(messageExtra.channelType),@(messageExtra.readed),@(readedAt),@(messageExtra.readedCount),@(messageExtra.unreadCount),@(messageExtra.revoke),messageExtra.revoker?:@"",@(messageExtra.isPinned),messageExtra.contentEditData?:@"",@(messageExtra.editedAt),extraStr,@(messageExtra.extraVersion)];
}

-(void) addOrUpdateContentEdit:(WKMessageExtra*)messageExtra {
Expand Down Expand Up @@ -153,6 +153,7 @@ -(WKMessageExtra*) toMessageExtra:(FMResultSet*)resultSet db:(FMDatabase*)db{
messageExtra.channelID = [resultSet stringForColumn:@"channel_id"];
messageExtra.channelType = [resultSet intForColumn:@"channel_type"];
messageExtra.readed = [resultSet boolForColumn:@"readed"];
messageExtra.isPinned = [resultSet boolForColumn:@"is_pinned"];
NSInteger readedAt = [resultSet intForColumn:@"readed_at"];
if(readedAt>0) {
messageExtra.readedAt = [NSDate dateWithTimeIntervalSince1970:readedAt];
Expand Down
40 changes: 40 additions & 0 deletions WuKongIMSDK/Classes/db/WKPinnedMessageDB.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
//
// WKPinnedMessageDB.h
// WuKongIMSDK
//
// Created by tt on 2024/5/22.
//

#import <Foundation/Foundation.h>
#import "WKPinnedMessage.h"
NS_ASSUME_NONNULL_BEGIN

@interface WKPinnedMessageDB : NSObject

+ (WKPinnedMessageDB *)shared;


// 通过频道获取置顶的消息集合
-(NSArray<WKPinnedMessage*>*) getPinnedMessagesByChannel:(WKChannel*)channel;

// 获取某个频道的最大version
-(uint64_t) getMaxVersion:(WKChannel*)channel;

// 删除某个频道的所有置顶
-(void) deletePinnedByChannel:(WKChannel*)channel;

// 删除某条消息的置顶
-(void) deletePinnedByMessageId:(uint64_t)messageId;

// 获取某条置顶消息
-(WKPinnedMessage*) getPinnedMessageByMessageId:(uint64_t)messageId;

// 添加或更新置顶消息
-(void) addOrUpdatePinnedMessages:(NSArray<WKPinnedMessage*>*)messages;

// 根据消息id查询是否置顶
-(BOOL) hasPinned:(uint64_t)messageId;

@end

NS_ASSUME_NONNULL_END
141 changes: 141 additions & 0 deletions WuKongIMSDK/Classes/db/WKPinnedMessageDB.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
//
// WKPinnedMessageDB.m
// WuKongIMSDK
//
// Created by tt on 2024/5/22.
//

#import "WKPinnedMessageDB.h"
#import "WKDB.h"

// 根据频道查询
#define SQL_PINNED_MESSAGE_GET_WITH_CHANNEL [NSString stringWithFormat:@"select * from %@ where channel_id=? and channel_type=? and is_deleted=0",@"pinned_message"]

// 获取频道最大版本号
#define SQL_PINNED_MESSAGE_MAX_VERSION_WITH_CHANNEL [NSString stringWithFormat:@"select max(version) version from %@ where channel_id=? and channel_type=?",@"pinned_message"]

// 通过消息id获取置顶消息
#define SQL_PINNED_MESSAGE_GET_WITH_MESSAGEID [NSString stringWithFormat:@"select * from %@ where message_id=? and is_deleted=0",@"pinned_message"]

// 通过消息id获取置顶消息
#define SQL_PINNED_MESSAGE_HAS_WITH_MESSAGEID [NSString stringWithFormat:@"select count(*) cn from %@ where message_id=? and is_deleted=0",@"pinned_message"]

// 根据频道删除置顶消息
#define SQL_PINNED_MESSAGE_DELETE_WITH_CHANNEL [NSString stringWithFormat:@"update %@ set is_deleted=1 where channel_id=? and channel_type=?",@"pinned_message"]

// 根据消息id删除置顶消息
#define SQL_PINNED_MESSAGE_DELETE_WITH_MESSAGE_ID [NSString stringWithFormat:@"update %@ set is_deleted=1 where message_id=?",@"pinned_message"]

// 添加或更新置顶消息
#define SQL_PINNED_MESSAGE_ADD_OR_UPDATE [NSString stringWithFormat:@"insert into pinned_message( message_id,message_seq,channel_id,channel_type,version,is_deleted) values(?,?,?,?,?,?) ON CONFLICT(message_id) DO UPDATE SET version=excluded.version,is_deleted=excluded.is_deleted"]

@implementation WKPinnedMessageDB


static WKPinnedMessageDB *_instance;
+ (id)allocWithZone:(NSZone *)zone
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance = [super allocWithZone:zone];
});
return _instance;
}
+ (WKPinnedMessageDB *)shared
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance = [[self alloc] init];
});
return _instance;
}

-(NSArray<WKPinnedMessage*>*) getPinnedMessagesByChannel:(WKChannel*)channel {

__block NSMutableArray *pinnedMessages = [NSMutableArray array];
[WKDB.sharedDB.dbQueue inDatabase:^(FMDatabase * _Nonnull db) {
FMResultSet *resultSet = [db executeQuery:SQL_PINNED_MESSAGE_GET_WITH_CHANNEL,channel.channelId?:@"",@(channel.channelType)];
while (resultSet.next) {
[pinnedMessages addObject:[self toPinnedMessage:resultSet]];
}
[resultSet close];
}];

return pinnedMessages;
}

-(uint64_t) getMaxVersion:(WKChannel*)channel {
__block uint64_t version = 0;
[WKDB.sharedDB.dbQueue inDatabase:^(FMDatabase * _Nonnull db) {
FMResultSet *resultSet = [db executeQuery:SQL_PINNED_MESSAGE_MAX_VERSION_WITH_CHANNEL,channel.channelId?:@"",@(channel.channelType)];
if (resultSet.next) {
version = [resultSet unsignedLongLongIntForColumn:@"version"];
}
[resultSet close];
}];
return version;
}

-(void) deletePinnedByChannel:(WKChannel*)channel {
[WKDB.sharedDB.dbQueue inDatabase:^(FMDatabase * _Nonnull db) {
[db executeUpdate:SQL_PINNED_MESSAGE_DELETE_WITH_CHANNEL,channel.channelId?:@"",@(channel.channelType)];
}];
}

-(void) deletePinnedByMessageId:(uint64_t)messageId {
[WKDB.sharedDB.dbQueue inDatabase:^(FMDatabase * _Nonnull db) {
[db executeUpdate:SQL_PINNED_MESSAGE_DELETE_WITH_MESSAGE_ID,@(messageId)];
}];
}

-(void) addOrUpdatePinnedMessages:(NSArray<WKPinnedMessage*>*)messages {
if(!messages || messages.count==0) {
return;
}
[WKDB.sharedDB.dbQueue inTransaction:^(FMDatabase * _Nonnull db, BOOL * _Nonnull rollback) {
for (WKPinnedMessage *message in messages) {
[db executeUpdate:SQL_PINNED_MESSAGE_ADD_OR_UPDATE,@(message.messageId),@(message.messageSeq),message.channel.channelId?:@"",@(message.channel.channelType),@(message.version),@(message.isDeleted)];
}
}];
}

-(WKPinnedMessage*) getPinnedMessageByMessageId:(uint64_t)messageId {
__block WKPinnedMessage *message;
[WKDB.sharedDB.dbQueue inDatabase:^(FMDatabase * _Nonnull db) {
FMResultSet *resultSet = [db executeQuery:SQL_PINNED_MESSAGE_GET_WITH_MESSAGEID,@(messageId)];
if (resultSet.next) {
message = [self toPinnedMessage:resultSet];
}
[resultSet close];
}];
return message;
}

-(BOOL) hasPinned:(uint64_t)messageId {
__block BOOL has = false;
[WKDB.sharedDB.dbQueue inDatabase:^(FMDatabase * _Nonnull db) {
FMResultSet *resultSet = [db executeQuery:SQL_PINNED_MESSAGE_HAS_WITH_MESSAGEID,@(messageId)];
if (resultSet.next) {
has = [resultSet intForColumn:@"cn"]>0;
}
[resultSet close];
}];
return has;
}

-(WKPinnedMessage*) toPinnedMessage:(FMResultSet*)resultSet{
WKPinnedMessage *msg = [WKPinnedMessage new];
msg.messageId = [resultSet unsignedLongLongIntForColumn:@"message_id"];
msg.messageSeq = (uint32_t)[resultSet longLongIntForColumn:@"message_seq"];

NSString *channelId = [resultSet stringForColumn:@"channel_id"];
int channelType = [resultSet intForColumn:@"channel_type"];

WKChannel *channel = [WKChannel channelID:channelId channelType:channelType];
msg.channel = channel;
msg.isDeleted = [resultSet boolForColumn:@"is_deleted"];
msg.version = [resultSet unsignedLongLongIntForColumn:@"version"];

return msg;
}
@end
4 changes: 2 additions & 2 deletions WuKongIMSDK/Classes/manager/WKCMDManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,15 @@ NS_ASSUME_NONNULL_BEGIN


/**
添加媒体委托
添加cmd委托
@param delegate <#delegate description#>
*/
-(void) addDelegate:(id<WKCMDManagerDelegate>) delegate;


/**
移除媒体委托
移除cmd委托
@param delegate <#delegate description#>
*/
Expand Down
7 changes: 7 additions & 0 deletions WuKongIMSDK/Classes/manager/WKChatManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,13 @@ typedef BOOL(^MessageStoreBeforeIntercept)(WKMessage*message);
/// 保存消息
-(void) saveMessages:(NSArray<WKMessage*>*)messages;


// 添加或更新消息(如果存在则更新,不存在添加)
- (void) addOrUpdateMessages:(NSArray<WKMessage*>*)messages;

// 添加或更新消息(如果存在则更新,不存在添加)
// notify 是否通知ui
-(void) addOrUpdateMessages:(NSArray<WKMessage*>*)messages notify:(BOOL)notify;
/**
转发消息
Expand Down
27 changes: 27 additions & 0 deletions WuKongIMSDK/Classes/manager/WKChatManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,34 @@ -(void) saveMessages:(NSArray<WKMessage*>*)messages {
[self addOrUpdateConversationWithMessages:messages];
}

-(void) addOrUpdateMessages:(NSArray<WKMessage*>*)messages {
if(!messages || messages.count<=0) {
return;
}
for (WKMessage *message in messages) {
message.isDeleted = ![self needStoreOfIntercept:message];
}
[WKMessageDB.shared replaceMessages:messages];
// 更新最近会话
[self addOrUpdateConversationWithMessages:messages];
}

-(void) addOrUpdateMessages:(NSArray<WKMessage*>*)messages notify:(BOOL)notify {
if(!messages || messages.count<=0) {
return;
}
for (WKMessage *message in messages) {
message.isDeleted = ![self needStoreOfIntercept:message];
}
[WKMessageDB.shared replaceMessages:messages];

if(notify) {
for(WKMessage *message in messages) {
[self callMessageUpdateDelegate:message];
}
}

}

-(WKConversation*) toConversationWtihMessage:(WKMessage*)message {
WKConversation *conversation = [WKConversation new];
Expand Down
Loading

0 comments on commit fbf7437

Please sign in to comment.