Bladeren bron

添加群成员禁言,添加用户回执开关

heavyrain2012 4 jaren geleden
bovenliggende
commit
207dbae588

+ 40 - 17
wfchat/WildFireChat/Me/WFCPrivacyTableViewController.m

@@ -44,7 +44,7 @@
     if (indexPath.section == 0) {
         WFCUBlackListViewController *vc = [[WFCUBlackListViewController alloc] init];
         [self.navigationController pushViewController:vc animated:YES];
-    } else if(indexPath.section == 1) {
+    } else if(indexPath.section == 2) {
         UIViewController *vc = [[NSClassFromString(@"MomentSettingsTableViewController") alloc] init];
         [self.navigationController pushViewController:vc animated:YES];
     }
@@ -57,9 +57,9 @@
 //#pragma mark - Table view data source
 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
     if (NSClassFromString(@"MomentSettingsTableViewController")) {
-        return 2;
+        return 3;
     }
-    return 1;
+    return 2;
 }
 
 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
@@ -67,28 +67,51 @@
         return 1;
     } else if(section == 1) {
         return 1;
+    } else if(section == 2) {
+       return 1;
     }
+    
     return 0;
 }
 
 
 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
-    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"style1Cell"];
-    if (cell == nil) {
-        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:@"style1Cell"];
-    }
-    
-    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
-    cell.accessoryView = nil;
-    cell.selectionStyle = UITableViewCellSelectionStyleNone;
-    
-    if (indexPath.section == 0) {
-        cell.textLabel.text = LocalizedString(@"Blacklist");
+    if (indexPath.section == 0 || indexPath.section == 2) {
+        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"style1Cell"];
+        if (cell == nil) {
+            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:@"style1Cell"];
+        }
+        
+        cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
+        cell.accessoryView = nil;
+        cell.selectionStyle = UITableViewCellSelectionStyleNone;
+        if(indexPath.section == 2) {
+            cell.textLabel.text = LocalizedString(@"Moments");
+        } else {
+            cell.textLabel.text = LocalizedString(@"Blacklist");
+        }
+        return cell;;
     } else if(indexPath.section == 1) {
-        cell.textLabel.text = LocalizedString(@"Moments");
+        WFCUGeneralSwitchTableViewCell *switchCell = [[WFCUGeneralSwitchTableViewCell alloc] init];
+        switchCell.textLabel.text = LocalizedString(@"MsgReceipt");
+        if ([[WFCCIMService sharedWFCIMService] isUserEnableReceipt]) {
+            switchCell.on = YES;
+        } else {
+            switchCell.on = NO;
+        }
+        __weak typeof(self)ws = self;
+        [switchCell setOnSwitch:^(BOOL value, void (^result)(BOOL success)) {
+            [[WFCCIMService sharedWFCIMService] setUserEnableReceipt:value success:^{
+                result(YES);
+            } error:^(int error_code) {
+                [ws.view makeToast:@"网络错误"];
+                result(NO);
+            }];
+        }];
+        
+        return switchCell;
     }
-    
-    return cell;
+    return nil;
 }
 
 @end

+ 7 - 1
wfclient/WFChatClient/Client/Common.h

@@ -72,12 +72,18 @@
 #define MESSAGE_CONTENT_TYPE_MODIFY_GROUP_ALIAS 111
 //修改群头像的通知消息
 #define MESSAGE_CONTENT_TYPE_CHANGE_GROUP_PORTRAIT 112
-
+//修改群全局禁言的通知消息
 #define MESSAGE_CONTENT_TYPE_CHANGE_MUTE 113
+//修改群加入权限的通知消息
 #define MESSAGE_CONTENT_TYPE_CHANGE_JOINTYPE 114
+//修改群群成员私聊的通知消息
 #define MESSAGE_CONTENT_TYPE_CHANGE_PRIVATECHAT 115
+//修改群是否可搜索的通知消息
 #define MESSAGE_CONTENT_TYPE_CHANGE_SEARCHABLE 116
+//修改群管理的通知消息
 #define MESSAGE_CONTENT_TYPE_SET_MANAGER 117
+//禁言/取消禁言群成员的通知消息
+#define MESSAGE_CONTENT_TYPE_MUTE_MEMBER 118
 
 //VoIP开始消息
 #define VOIP_CONTENT_TYPE_START 400

+ 85 - 2
wfclient/WFChatClient/Client/WFCCIMService.h

@@ -106,6 +106,12 @@ typedef NS_ENUM(NSInteger, UserSettingScope) {
     
     //不能直接使用,协议栈内会使用此值
     UserSettingScope_PC_Online = 10,
+    //不能直接使用,协议栈内会使用此值
+    UserSetting_Conversation_Readed = 11,
+    //不能直接使用,协议栈内会使用此值
+    UserSetting_WebOnline = 12,
+    //不能直接使用,协议栈内会使用此值
+    UserSetting_DisableRecipt = 13,
     
     
     //自定义用户设置,请使用1000以上的key
@@ -1005,7 +1011,7 @@ typedef NS_ENUM(NSInteger, WFCCPlatformType) {
  
  @param groupId 群ID
  @param isSet    设置或取消
- @param memberId    成员ID
+ @param memberIds    成员ID
  @param notifyLines 默认传 @[@(0)]
  @param notifyContent 通知消息
  @param successBlock 成功的回调
@@ -1013,11 +1019,30 @@ typedef NS_ENUM(NSInteger, WFCCPlatformType) {
  */
 - (void)setGroupManager:(NSString *)groupId
                   isSet:(BOOL)isSet
-              memberIds:(NSArray<NSString *> *)memberId
+              memberIds:(NSArray<NSString *> *)memberIds
             notifyLines:(NSArray<NSNumber *> *)notifyLines
           notifyContent:(WFCCMessageContent *)notifyContent
                 success:(void(^)(void))successBlock
                   error:(void(^)(int error_code))errorBlock;
+
+/**
+ 设置群成员禁言,仅专业版支持
+ 
+ @param groupId 群ID
+ @param isSet    设置或取消
+ @param memberIds    成员ID
+ @param notifyLines 默认传 @[@(0)]
+ @param notifyContent 通知消息
+ @param successBlock 成功的回调
+ @param errorBlock 失败的回调
+ */
+- (void)muteGroupMember:(NSString *)groupId
+                     isSet:(BOOL)isSet
+                 memberIds:(NSArray<NSString *> *)memberIds
+               notifyLines:(NSArray<NSNumber *> *)notifyLines
+             notifyContent:(WFCCMessageContent *)notifyContent
+                   success:(void(^)(void))successBlock
+                     error:(void(^)(int error_code))errorBlock;
 /**
  获取当前用户收藏的群组
  
@@ -1089,20 +1114,78 @@ typedef NS_ENUM(NSInteger, WFCCPlatformType) {
 
 
 
+/**
+是否全局静音
 
+@return YES,当前用户全局静音;NO,没有全局静音
+*/
 - (BOOL)isGlobalSlient;
+
+/**
+修改全局静音状态
+
+@param slient 是否静音
+@param successBlock 成功的回调
+@param errorBlock 失败的回调
+*/
 - (void)setGlobalSlient:(BOOL)slient
                 success:(void(^)(void))successBlock
                   error:(void(^)(int error_code))errorBlock;
+
+/**
+是否隐藏推送详情
+
+@return YES,隐藏推送详情,提示“您收到一条消息”;NO,推送显示消息摘要
+*/
 - (BOOL)isHiddenNotificationDetail;
+
+/**
+修改全局静音状态
+
+@param hidden 是否静音
+@param successBlock 成功的回调
+@param errorBlock 失败的回调
+*/
 - (void)setHiddenNotificationDetail:(BOOL)hidden
                             success:(void(^)(void))successBlock
                               error:(void(^)(int error_code))errorBlock;
+
+/**
+是否隐藏群组会话中群成员昵称显示
+
+@return YES,群组会话中不显示群成员昵称;NO,显示
+*/
 - (BOOL)isHiddenGroupMemberName:(NSString *)groupId;
+
+/**
+修改隐藏群组会话中群成员昵称显示状态
+
+@param hidden 是否隐藏
+@param successBlock 成功的回调
+@param errorBlock 失败的回调
+*/
 - (void)setHiddenGroupMemberName:(BOOL)hidden
                            group:(NSString *)groupId
                          success:(void(^)(void))successBlock
                            error:(void(^)(int error_code))errorBlock;
+/**
+当前用户是否启用消息回执功能,仅专业版有效
+
+@return YES,开启消息回执功能;NO,关闭个人的消息回执功能。
+@disscussion 仅当服务器开启这个功能才有效
+*/
+- (BOOL)isUserEnableReceipt;
+/**
+修改当前用户是否启用消息回执功能,仅专业版有效
+
+@param enable 是否开启
+@param successBlock 成功的回调
+@param errorBlock 失败的回调
+ @disscussion 仅当服务器开启这个功能才有效
+*/
+- (void)setUserEnableReceipt:(BOOL)enable
+                success:(void(^)(void))successBlock
+                       error:(void(^)(int error_code))errorBlock;
 
 #pragma mark - 聊天室相关
 - (void)joinChatroom:(NSString *)chatroomId

+ 42 - 3
wfclient/WFChatClient/Client/WFCCIMService.mm

@@ -1277,8 +1277,26 @@ WFCCGroupInfo *convertProtoGroupInfo(mars::stn::TGroupInfo tgi) {
         }
     }];
 }
-//UserSettingScope_Global_Silent = 2,
-//
+
+- (BOOL)isUserEnableReceipt {
+    NSString *strValue = [[WFCCIMService sharedWFCIMService] getUserSetting:UserSetting_DisableRecipt key:@""];
+    return ![strValue isEqualToString:@"1"];
+}
+
+- (void)setUserEnableReceipt:(BOOL)enable
+                success:(void(^)(void))successBlock
+                  error:(void(^)(int error_code))errorBlock {
+    [[WFCCIMService sharedWFCIMService] setUserSetting:UserSetting_DisableRecipt key:@"" value:enable?@"0":@"1" success:^{
+        if (successBlock) {
+            successBlock();
+        }
+    } error:^(int error_code) {
+        if (errorBlock) {
+            errorBlock(error_code);
+        }
+    }];
+}
+
 - (BOOL)isHiddenNotificationDetail {
     NSString *strValue = [[WFCCIMService sharedWFCIMService] getUserSetting:UserSettingScope_Hidden_Notification_Detail key:@""];
     return [strValue isEqualToString:@"1"];
@@ -1578,7 +1596,28 @@ WFCCGroupInfo *convertProtoGroupInfo(mars::stn::TGroupInfo tgi) {
     
     mars::stn::SetGroupManager([groupId UTF8String], memberList, isSet, lines, tcontent, new IMGeneralOperationCallback(successBlock, errorBlock));
 }
-
+- (void)muteGroupMember:(NSString *)groupId
+                     isSet:(BOOL)isSet
+                 memberIds:(NSArray<NSString *> *)memberIds
+               notifyLines:(NSArray<NSNumber *> *)notifyLines
+             notifyContent:(WFCCMessageContent *)notifyContent
+                   success:(void(^)(void))successBlock
+                     error:(void(^)(int error_code))errorBlock {
+    mars::stn::TMessageContent tcontent;
+    fillTMessageContent(tcontent, notifyContent);
+    
+    std::list<int> lines;
+    for (NSNumber *number in notifyLines) {
+        lines.push_back([number intValue]);
+    }
+    
+    std::list<std::string> memberList;
+    for (NSString *member in memberIds) {
+        memberList.push_back([member UTF8String]);
+    }
+    
+    mars::stn::MuteGroupMember([groupId UTF8String], memberList, isSet, lines, tcontent, new IMGeneralOperationCallback(successBlock, errorBlock));
+}
 - (NSArray<NSString *> *)getFavGroups {
     NSDictionary *favGroupDict = [[WFCCIMService sharedWFCIMService] getUserSettings:UserSettingScope_Favourite_Group];
     NSMutableArray *ids = [[NSMutableArray alloc] init];

+ 35 - 0
wfclient/WFChatClient/Messages/WFCCGroupMemberMutedNotificationContent.h

@@ -0,0 +1,35 @@
+//
+//  WFCCCreateGroupNotificationContent.h
+//  WFChatClient
+//
+//  Created by heavyrain on 2017/9/19.
+//  Copyright © 2017年 WildFireChat. All rights reserved.
+//
+
+#import "WFCCNotificationMessageContent.h"
+
+/**
+ 建群的通知消息
+ */
+@interface WFCCGroupMemberMutedNotificationContent : WFCCNotificationMessageContent
+
+/**
+ 群组ID
+ */
+@property (nonatomic, strong)NSString *groupId;
+
+/**
+ 操作者ID
+ */
+@property (nonatomic, strong)NSString *operatorId;
+
+/**
+ 操作类型,1禁言,0取消禁言
+ */
+@property (nonatomic, strong)NSString *type;
+
+/**
+ Member ID
+ */
+@property (nonatomic, strong)NSArray<NSString *> *memberIds;
+@end

+ 121 - 0
wfclient/WFChatClient/Messages/WFCCGroupMemberMutedNotificationContent.m

@@ -0,0 +1,121 @@
+//
+//  WFCCCreateGroupNotificationContent.m
+//  WFChatClient
+//
+//  Created by heavyrain on 2017/9/19.
+//  Copyright © 2017年 WildFireChat. All rights reserved.
+//
+
+#import "WFCCGroupMemberMutedNotificationContent.h"
+#import "WFCCIMService.h"
+#import "WFCCNetworkService.h"
+#import "Common.h"
+
+@implementation WFCCGroupMemberMutedNotificationContent
+- (WFCCMessagePayload *)encode {
+    WFCCMessagePayload *payload = [super encode];
+    payload.contentType = [self.class getContentType];
+    
+    NSMutableDictionary *dataDict = [NSMutableDictionary dictionary];
+    if (self.operatorId) {
+        [dataDict setObject:self.operatorId forKey:@"o"];
+    }
+    if (self.type) {
+        [dataDict setObject:self.type forKey:@"n"];
+    }
+    
+    if (self.groupId) {
+        [dataDict setObject:self.groupId forKey:@"g"];
+    }
+    
+    
+    if (self.memberIds) {
+        [dataDict setObject:self.memberIds forKey:@"ms"];
+    }
+    payload.binaryContent = [NSJSONSerialization dataWithJSONObject:dataDict
+                                                                           options:kNilOptions
+                                                                             error:nil];
+    
+    return payload;
+}
+
+- (void)decode:(WFCCMessagePayload *)payload {
+    [super decode:payload];
+    NSError *__error = nil;
+    NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:payload.binaryContent
+                                                               options:kNilOptions
+                                                                 error:&__error];
+    if (!__error) {
+        self.operatorId = dictionary[@"o"];
+        self.type = dictionary[@"n"];
+        self.groupId = dictionary[@"g"];
+        self.memberIds = dictionary[@"ms"];
+    }
+}
+
++ (int)getContentType {
+    return MESSAGE_CONTENT_TYPE_MUTE_MEMBER;
+}
+
++ (int)getContentFlags {
+    return WFCCPersistFlag_PERSIST;
+}
+
+
+
++ (void)load {
+    [[WFCCIMService sharedWFCIMService] registerMessageContent:self];
+}
+
+- (NSString *)digest:(WFCCMessage *)message {
+    return [self formatNotification:message];
+}
+
+- (NSString *)formatNotification:(WFCCMessage *)message {
+    NSString *from;
+    NSString *targets;
+    if ([[WFCCNetworkService sharedInstance].userId isEqualToString:self.operatorId]) {
+        from = @"你";
+    } else {
+        WFCCUserInfo *fromUserInfo = [[WFCCIMService sharedWFCIMService] getUserInfo:self.operatorId inGroup:self.groupId refresh:NO];
+        if (fromUserInfo.friendAlias.length > 0) {
+            from = fromUserInfo.friendAlias;
+        } else if(fromUserInfo.groupAlias.length > 0) {
+            from = fromUserInfo.groupAlias;
+        } else if (fromUserInfo.displayName.length > 0) {
+            from = fromUserInfo.displayName;
+        } else {
+            from = [NSString stringWithFormat:@"用户<%@>", self.operatorId];
+        }
+    }
+    
+    for (NSString *memberId in self.memberIds) {
+        NSString *target;
+        if ([[WFCCNetworkService sharedInstance].userId isEqualToString:memberId]) {
+            target = @"你";
+        } else {
+            WFCCUserInfo *memberUserInfo = [[WFCCIMService sharedWFCIMService] getUserInfo:memberId inGroup:self.groupId refresh:NO];
+            if (memberUserInfo.friendAlias.length > 0) {
+                target = memberUserInfo.friendAlias;
+            } else if(memberUserInfo.groupAlias.length > 0) {
+                target = memberUserInfo.groupAlias;
+            } else if (memberUserInfo.displayName.length > 0) {
+                target = memberUserInfo.displayName;
+            } else {
+                target = [NSString stringWithFormat:@"用户<%@>", memberId];
+            }
+        }
+        if (!targets) {
+            targets = target;
+        } else {
+            targets = [NSString stringWithFormat:@"%@,%@", targets, target];
+        }
+    }
+    
+    if ([self.type isEqualToString:@"1"]) {
+        return [NSString stringWithFormat:@"%@ 禁言了 %@", from, targets];
+    } else {
+        return [NSString stringWithFormat:@"%@ 取消禁言了 %@", from, targets];
+    }
+}
+@end

+ 2 - 0
wfclient/WFChatClient/Model/WFCCGroupMember.h

@@ -14,11 +14,13 @@
  - Member_Type_Normal: 普通成员
  - Member_Type_Manager: 管理员
  - Member_Type_Owner: 群主
+ - Member_Type_Muted: 被禁言
  */
 typedef NS_ENUM(NSInteger, WFCCGroupMemberType) {
     Member_Type_Normal = 0,
     Member_Type_Manager,
     Member_Type_Owner,
+    Member_Type_Muted
 } ;
 
 /**

+ 2 - 2
wfclient/WFChatClient/Proto/mars.framework/Headers/comm/verinfo.h

@@ -2,10 +2,10 @@
 #ifndef Mars_verinfo_h
 #define Mars_verinfo_h
 
-#define MARS_REVISION "7e89125b"
+#define MARS_REVISION "62e6df5d"
 #define MARS_PATH "firechat"
 #define MARS_URL ""
-#define MARS_BUILD_TIME "2020-05-22 22:02:45"
+#define MARS_BUILD_TIME "2020-05-24 19:07:24"
 #define MARS_TAG ""
 
 #endif

+ 1 - 0
wfclient/WFChatClient/Proto/mars.framework/Headers/proto/MessageDB.h

@@ -104,6 +104,7 @@ namespace mars {
             void RemoveGroupMembers(const std::string &groupId, const std::list<std::string> &members);
             void AddGroupMembers(const std::string &groupId, const std::list<std::string> &members);
             int UpdateGroupManager(const std::string &groupId, const std::list<std::string> &members, int setOrDelete);
+            int UpdateGroupMemberMute(const std::string &groupId, const std::list<std::string> &members, int setOrDelete);
             
             TUserInfo getUserInfo(const std::string &userId, const std::string &groupId, bool refresh);
             std::list<TUserInfo> getUserInfos(const std::list<std::string> &userIds, const std::string &groupId);

+ 4 - 0
wfclient/WFChatClient/Proto/mars.framework/Headers/proto/proto.h

@@ -40,6 +40,7 @@
 #define MESSAGE_CONTENT_TYPE_CHANGE_PRIVATECHAT 115
 #define MESSAGE_CONTENT_TYPE_CHANGE_SEARCHABLE 116
 #define MESSAGE_CONTENT_TYPE_SET_MANAGER 117
+#define MESSAGE_CONTENT_TYPE_MUTE_MEMBER 118
 
 
 
@@ -429,6 +430,7 @@ namespace mars{
             kUserSettingPCOnline = 10,
             kUserSettingConversationReaded = 11,
             kUserSettingWebOnline = 12,
+            kUserSettingDisableRecipt = 13,
 
             kUserSettingCustomBegin = 1000
         };
@@ -719,6 +721,8 @@ namespace mars{
         extern void (*transferGroup)(const std::string &groupId, const std::string &newOwner, const std::list<int> &notifyLines, TMessageContent &content, GeneralOperationCallback *callback);
 
         extern void SetGroupManager(const std::string &groupId, const std::list<std::string> userIds, int setOrDelete, const std::list<int> &notifyLines, TMessageContent &content, GeneralOperationCallback *callback);
+    
+        extern void MuteGroupMember(const std::string &groupId, const std::list<std::string> userIds, int setOrDelete, const std::list<int> &notifyLines, TMessageContent &content, GeneralOperationCallback *callback);
 
         extern void (*getUserInfo)(const std::list<std::pair<std::string, int64_t>> &userReqList, GetUserInfoCallback *callback);
 

BIN
wfclient/WFChatClient/Proto/mars.framework/mars


+ 1 - 1
wfuikit/WFChatUIKit/ConversationSetting/ViewController/GroupMuteTableViewController.h

@@ -1,5 +1,5 @@
 //
-//  ManagerTableViewController.h
+//  GroupMuteTableViewController.h
 //  WFChatUIKit
 //
 //  Created by heavyrain lee on 2019/6/26.

+ 158 - 24
wfuikit/WFChatUIKit/ConversationSetting/ViewController/GroupMuteTableViewController.m

@@ -1,5 +1,5 @@
 //
-//  ManagerTableViewController.m
+//  GroupMuteTableViewController.m
 //  WFChatUIKit
 //
 //  Created by heavyrain lee on 2019/6/26.
@@ -10,19 +10,21 @@
 #import "SDWebImage.h"
 #import "WFCUContactListViewController.h"
 #import "WFCUGeneralSwitchTableViewCell.h"
+#import "WFCUContactListViewController.h"
 
 @interface GroupMuteTableViewController () <UITableViewDelegate, UITableViewDataSource>
 @property(nonatomic, strong)UITableView *tableView;
-@property(nonatomic, strong)NSMutableArray<WFCCGroupMember *> *managerList;
+@property(nonatomic, strong)NSMutableArray<WFCCGroupMember *> *mutedMemberList;
 @end
 
 @implementation GroupMuteTableViewController
 
 - (void)viewDidLoad {
     [super viewDidLoad];
-
+    
     self.title = WFCString(@"GroupMuteSetting");
     
+    [self loadMutedMemberList];
     self.tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height) style:UITableViewStyleGrouped];
     
     self.tableView.delegate = self;
@@ -32,38 +34,170 @@
     [self.tableView reloadData];
     
     [self.view addSubview:self.tableView];
+    
+    __weak typeof(self)ws = self;
+    [[NSNotificationCenter defaultCenter] addObserverForName:kGroupMemberUpdated object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification * _Nonnull note) {
+        if ([ws.groupInfo.target isEqualToString:note.object]) {
+            [ws loadMutedMemberList];
+            [ws.tableView reloadData];
+        }
+    }];
 }
 
+- (void)loadMutedMemberList {
+    NSArray *memberList = [[WFCCIMService sharedWFCIMService] getGroupMembers:self.groupInfo.target forceUpdate:YES];
+    self.mutedMemberList = [[NSMutableArray alloc] init];
+    for (WFCCGroupMember *member in memberList) {
+        if (member.type == Member_Type_Muted) {
+            [self.mutedMemberList addObject:member];
+        }
+    }
+}
+- (void)selectMemberToAdd {
+    WFCUContactListViewController *pvc = [[WFCUContactListViewController alloc] init];
+    pvc.selectContact = YES;
+    pvc.multiSelect = YES;
+    __weak typeof(self)ws = self;
+    pvc.selectResult = ^(NSArray<NSString *> *contacts) {
+        [[WFCCIMService sharedWFCIMService] muteGroupMember:self.groupInfo.target isSet:YES memberIds:contacts notifyLines:@[@(0)] notifyContent:nil success:^{
+            for (NSString *memberId in contacts) {
+                WFCCGroupMember *member = [[WFCCIMService sharedWFCIMService] getGroupMember:ws.groupInfo.target memberId:memberId];
+                if (member) {
+                    member.type = Member_Type_Muted;
+                    [ws.mutedMemberList addObject:member];
+                }
+            }
+            if (contacts.count) {
+                [ws.tableView reloadData];
+            }
+        } error:^(int error_code) {
+            
+        }];
+    };
+    NSMutableArray *candidateUsers = [[NSMutableArray alloc] init];
+    NSArray *memberList = [[WFCCIMService sharedWFCIMService] getGroupMembers:self.groupInfo.target forceUpdate:NO];
+    for (WFCCGroupMember *member in memberList) {
+        if (member.type == Member_Type_Normal && ![member.memberId isEqualToString:self.groupInfo.owner]) {
+            [candidateUsers addObject:member.memberId];
+        }
+    }
+    pvc.candidateUsers = candidateUsers;
+    UINavigationController *navi = [[UINavigationController alloc] initWithRootViewController:pvc];
+    [self.navigationController presentViewController:navi animated:YES completion:nil];
+}
 - (nonnull UITableViewCell *)tableView:(nonnull UITableView *)tableView cellForRowAtIndexPath:(nonnull NSIndexPath *)indexPath {
-    WFCUGeneralSwitchTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
-    if (cell == nil) {
-        cell = [[WFCUGeneralSwitchTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"];
-        cell.textLabel.text = WFCString(@"MuteAll");
-        cell.onSwitch = ^(BOOL value, void (^onDone)(BOOL success)) {
-            [[WFCCIMService sharedWFCIMService] modifyGroupInfo:self.groupInfo.target type:Modify_Group_Mute newValue:value?@"1":@"0" notifyLines:@[@(0)] notifyContent:nil success:^{
-                onDone(YES);
-            } error:^(int error_code) {
-                onDone(NO);
-            }];
-        };
+
+    if (indexPath.section == 0) {
+        WFCUGeneralSwitchTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
+        if (cell == nil) {
+            cell = [[WFCUGeneralSwitchTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"];
+            cell.textLabel.text = WFCString(@"MuteAll");
+            cell.onSwitch = ^(BOOL value, void (^onDone)(BOOL success)) {
+                [[WFCCIMService sharedWFCIMService] modifyGroupInfo:self.groupInfo.target type:Modify_Group_Mute newValue:value?@"1":@"0" notifyLines:@[@(0)] notifyContent:nil success:^{
+                    onDone(YES);
+                } error:^(int error_code) {
+                    onDone(NO);
+                }];
+            };
+        }
+        
+        cell.on = self.groupInfo.mute;
+        return cell;
+    } else {
+        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
+        if (cell == nil) {
+            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"];
+        }
+        
+        cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
+        cell.accessoryView = nil;
+        cell.selectionStyle = UITableViewCellSelectionStyleNone;
+        
+        if(indexPath.section == 1) {
+            if (indexPath.row == 0) {
+                cell.imageView.image = [UIImage imageNamed:@"plus"];
+                cell.textLabel.text = WFCString(@"MuteMember");
+            } else {
+                WFCCUserInfo *member = [[WFCCIMService sharedWFCIMService] getUserInfo:[self.mutedMemberList objectAtIndex:indexPath.row-1].memberId  refresh:NO];
+                [cell.imageView sd_setImageWithURL:[NSURL URLWithString:[member.portrait stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]] placeholderImage: [UIImage imageNamed:@"PersonalChat"]];
+                cell.textLabel.text = member.displayName;
+            }
+        }
+        
+        return cell;
     }
-    
-    cell.on = self.groupInfo.mute;
-    
-   
-    
-    return cell;
 }
 
+- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
+    if (indexPath.section == 0 || (indexPath.section == 1 && indexPath.row == 0)) {
+        return NO;
+    }
+    return YES;
+}
+- (NSArray<UITableViewRowAction *> *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath {
+    UITableViewRowAction *deleteAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDestructive title:WFCString(@"Unmute") handler:^(UITableViewRowAction * _Nonnull action, NSIndexPath * _Nonnull indexPath) {
+
+        __weak typeof(self)ws = self;
+        [[WFCCIMService sharedWFCIMService] muteGroupMember:self.groupInfo.target isSet:NO memberIds:@[[self.mutedMemberList objectAtIndex:indexPath.row-1].memberId] notifyLines:@[@(0)] notifyContent:nil success:^{
+            for (WFCCGroupMember *member in ws.mutedMemberList) {
+                if ([member.memberId isEqualToString:[ws.mutedMemberList objectAtIndex:indexPath.row-1].memberId]) {
+                    [ws.mutedMemberList removeObject:member];
+                    [ws.tableView reloadData];
+                    break;
+                }
+            }
+        } error:^(int error_code) {
+            
+        }];
+    }];
+    UITableViewRowAction *editAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleNormal title:WFCString(@"Cancel") handler:^(UITableViewRowAction * _Nonnull action, NSIndexPath * _Nonnull indexPath) {
+        NSLog(@"点击了编辑");
+    }];
+    editAction.backgroundColor = [UIColor grayColor];
+    return @[deleteAction, editAction];
+}
+
+
 - (NSInteger)tableView:(nonnull UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
-    return 1;
+    if (section == 0) {
+        return 1;
+    } else if(section == 1) {
+        return self.mutedMemberList.count+1;
+    }
+    return 0;
 }
 
+-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
+    if (section == 0) {
+        return WFCString(@"MuteAll");
+    } else if(section == 1) {
+        return WFCString(@"MutedMemberList");
+    }
+    return nil;
+}
+-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
+    return 30.f;
+}
+-(CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
+    return 0.f;
+}
 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
-    return 1;
+    return 2; //成员管理,加群设置
 }
-
 -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
-    
+    if (indexPath.section == 0) {
+        
+    } else if(indexPath.section == 1) {
+        if (indexPath.row == 0) {
+            [self selectMemberToAdd];
+        } else {
+            
+        }
+    }
+}
+
+- (void)dealloc {
+    [[NSNotificationCenter defaultCenter] removeObserver:self];
 }
 @end
+

+ 6 - 6
wfuikit/WFChatUIKit/ConversationSetting/ViewController/ManagerTableViewController.m

@@ -98,11 +98,11 @@
         [cell.imageView sd_setImageWithURL:[NSURL URLWithString:[owner.portrait stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]];
         cell.textLabel.text = owner.displayName;
     } else if(indexPath.section == 1) {
-        if (indexPath.row == self.managerList.count) {
+        if (indexPath.row == 0) {
             cell.imageView.image = [UIImage imageNamed:@"plus"];
             cell.textLabel.text = WFCString(@"AddManager");
         } else {
-            WFCCUserInfo *manager = [[WFCCIMService sharedWFCIMService] getUserInfo:[self.managerList objectAtIndex:indexPath.row].memberId  refresh:NO];
+            WFCCUserInfo *manager = [[WFCCIMService sharedWFCIMService] getUserInfo:[self.managerList objectAtIndex:indexPath.row-1].memberId  refresh:NO];
             [cell.imageView sd_setImageWithURL:[NSURL URLWithString:[manager.portrait stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]] placeholderImage: [UIImage imageNamed:@"PersonalChat"]];
             cell.textLabel.text = manager.displayName;
         }
@@ -113,7 +113,7 @@
 }
 
 - (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
-    if (indexPath.section == 0 || (indexPath.section == 1 && indexPath.row == self.managerList.count)) {
+    if (indexPath.section == 0 || (indexPath.section == 1 && indexPath.row == 0)) {
         return NO;
     }
     return YES;
@@ -122,9 +122,9 @@
     UITableViewRowAction *deleteAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDestructive title:WFCString(@"RemoveManager") handler:^(UITableViewRowAction * _Nonnull action, NSIndexPath * _Nonnull indexPath) {
 
         __weak typeof(self)ws = self;
-        [[WFCCIMService sharedWFCIMService] setGroupManager:self.groupInfo.target isSet:NO memberIds:@[[self.managerList objectAtIndex:indexPath.row].memberId] notifyLines:@[@(0)] notifyContent:nil success:^{
+        [[WFCCIMService sharedWFCIMService] setGroupManager:self.groupInfo.target isSet:NO memberIds:@[[self.managerList objectAtIndex:indexPath.row-1].memberId] notifyLines:@[@(0)] notifyContent:nil success:^{
             for (WFCCGroupMember *member in ws.managerList) {
-                if ([member.memberId isEqualToString:[ws.managerList objectAtIndex:indexPath.row].memberId]) {
+                if ([member.memberId isEqualToString:[ws.managerList objectAtIndex:indexPath.row-1].memberId]) {
                     [ws.managerList removeObject:member];
                     [ws.tableView reloadData];
                     break;
@@ -172,7 +172,7 @@
     if (indexPath.section == 0) {
         
     } else if(indexPath.section == 1) {
-        if (indexPath.row == self.managerList.count) {
+        if (indexPath.row == 0) {
             [self selectMemberToAdd];
         } else {
             

+ 1 - 1
wfuikit/WFChatUIKit/MessageList/Cell/WFCUMessageCell.m

@@ -176,7 +176,7 @@
       UIImage *image = self.bubbleView.image;
       self.bubbleView.image = [self.bubbleView.image
                                          resizableImageWithCapInsets:UIEdgeInsetsMake(image.size.height * 0.95, image.size.width * 0.2,image.size.height * 0.1, image.size.width * 0.05)];
-      if((model.message.status == Message_Status_Sent || model.message.status == Message_Status_Readed) && [[WFCCIMService sharedWFCIMService] isReceiptEnabled]) {
+      if((model.message.status == Message_Status_Sent || model.message.status == Message_Status_Readed) && [[WFCCIMService sharedWFCIMService] isReceiptEnabled] && [[WFCCIMService sharedWFCIMService] isUserEnableReceipt]) {
           if (model.message.conversation.type == Single_Type) {
               if (model.message.serverTime <= [[model.readDict objectForKey:model.message.conversation.target] longLongValue]) {
                   [self.receiptView setProgress:1 subProgress:1];

+ 9 - 1
wfuikit/WFChatUIKit/MessageList/ViewController/WFCUMessageListViewController.m

@@ -158,6 +158,13 @@
             }
         }];
         
+        [[NSNotificationCenter defaultCenter] addObserverForName:kGroupMemberUpdated object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification * _Nonnull note) {
+            if ([ws.conversation.target isEqualToString:note.object]) {
+                ws.targetGroup = ws.targetGroup;
+            }
+            
+        }];
+        
         self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"nav_chat_group"] style:UIBarButtonItemStyleDone target:self action:@selector(onRightBarBtn:)];
     } else if(self.conversation.type == Channel_Type) {
         [[NSNotificationCenter defaultCenter] addObserverForName:kChannelInfoUpdated object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification * _Nonnull note) {
@@ -407,7 +414,8 @@
         self.navigationItem.backBarButtonItem.title = targetGroup.name;
     }
     ChatInputBarStatus defaultStatus = ChatInputBarDefaultStatus;
-    if (targetGroup.mute) {
+    WFCCGroupMember *member = [[WFCCIMService sharedWFCIMService] getGroupMember:targetGroup.target memberId:[WFCCNetworkService sharedInstance].userId];
+    if (targetGroup.mute || member.type == Member_Type_Muted) {
         if ([targetGroup.owner isEqualToString:[WFCCNetworkService sharedInstance].userId]) {
             self.chatInputBar.inputBarStatus =  defaultStatus;
         } else {

+ 1 - 0
wfuikit/WFChatUIKit/Resources/en.lproj/wfc.strings

@@ -67,6 +67,7 @@
 "VoiceCall"="Voice call";
 "VideoCall"="Video call";
 "Blacklist"="Black list";
+"MsgReceipt"="Message receipt";
 "Delete"="Delete";
 "SearchContact"="Search contact";
 "NumberOfContacts"="%d contact(s)";

+ 1 - 0
wfuikit/WFChatUIKit/Resources/zh-Hans.lproj/wfc.strings

@@ -67,6 +67,7 @@
 "VoiceCall"="语音通话";
 "VideoCall"="视频通话";
 "Blacklist"="黑名单";
+"MsgReceipt"="消息回执";
 "Delete"="删除";
 "SearchContact"="搜索联系人";
 "NumberOfContacts"="%d 位联系人";