|
@@ -6,16 +6,545 @@
|
|
|
//
|
|
|
|
|
|
#import "KSTXGroupChatViewController.h"
|
|
|
+#import <TIMCommon/NSString+TUIEmoji.h>
|
|
|
+#import <TIMCommon/TIMCommonModel.h>
|
|
|
+#import <TIMCommon/TIMDefine.h>
|
|
|
+#import <TUICore/NSDictionary+TUISafe.h>
|
|
|
+#import <TUICore/TUICore.h>
|
|
|
+#import <TUICore/TUILogin.h>
|
|
|
+#import "TUIBaseChatViewController+ProtectedAPI.h"
|
|
|
+#import "TUIGroupChatViewController.h"
|
|
|
+#import "TUIGroupPendencyController.h"
|
|
|
+#import "TUIGroupPendencyDataProvider.h"
|
|
|
+#import "TUILinkCellData.h"
|
|
|
+#import "TUIMessageDataProvider.h"
|
|
|
+#import "TUITextMessageCellData.h"
|
|
|
+#import "KSMuteTipsView.h"
|
|
|
+#import "CustomNavViewController.h"
|
|
|
|
|
|
-@interface KSTXGroupChatViewController ()
|
|
|
+@interface KSTXGroupChatViewController ()<V2TIMGroupListener>
|
|
|
+
|
|
|
+@property(nonatomic, strong) UIView *tipsView;
|
|
|
+@property(nonatomic, strong) UILabel *pendencyLabel;
|
|
|
+@property(nonatomic, strong) UIButton *pendencyBtn;
|
|
|
+
|
|
|
+@property(nonatomic, strong) TUIGroupPendencyDataProvider *pendencyViewModel;
|
|
|
+@property(nonatomic, strong) NSMutableArray<TUIUserModel *> *atUserList;
|
|
|
+@property(nonatomic, assign) BOOL responseKeyboard;
|
|
|
+
|
|
|
+@property (nonatomic, strong) UIView *muteView;
|
|
|
+
|
|
|
+@property (nonatomic, strong) dispatch_group_t requestGroup;
|
|
|
+
|
|
|
+@property (nonatomic, assign) BOOL isGroupMute; // 是否群禁言
|
|
|
+
|
|
|
+@property (nonatomic, assign) BOOL isUserMute; // 是否个人禁言
|
|
|
+
|
|
|
+@property (nonatomic, assign) BOOL isGroupManager; // 是否管理员
|
|
|
+
|
|
|
+@property (nonatomic, assign) BOOL isMute;
|
|
|
|
|
|
@end
|
|
|
|
|
|
@implementation KSTXGroupChatViewController
|
|
|
|
|
|
+- (void)setIsMute:(BOOL)isMute {
|
|
|
+ _isMute = isMute;
|
|
|
+ UIView *viewContainer = self.inputController.inputBar;
|
|
|
+ if (isMute) {
|
|
|
+ if ([viewContainer.subviews containsObject:self.muteView]) {
|
|
|
+ [viewContainer bringSubviewToFront:self.muteView];
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ [viewContainer addSubview:self.muteView];
|
|
|
+ [self.muteView mas_makeConstraints:^(MASConstraintMaker *make) {
|
|
|
+ make.left.right.top.bottom.mas_equalTo(viewContainer);
|
|
|
+ }];
|
|
|
+ }
|
|
|
+ @weakObj(self);
|
|
|
+ dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
|
|
+ @strongObj(self);
|
|
|
+ [self resetStatus];
|
|
|
+ });
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ if ([viewContainer.subviews containsObject:self.muteView]) {
|
|
|
+ [self.muteView removeFromSuperview];
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+- (void)resetStatus {
|
|
|
+ UIViewController *ctrl = [self theTopviewControler];
|
|
|
+ if ([ctrl isKindOfClass:NSClassFromString(@"KSGroupConversationController")] || [ctrl isKindOfClass:NSClassFromString(@"UIDocumentPickerViewController")]) {
|
|
|
+ // 重置键盘状态
|
|
|
+ [self.inputController reset];
|
|
|
+ [self.inputController exitReplyAndReference:nil];
|
|
|
+ [self.inputController.inputBar clearInput];
|
|
|
+ [self.inputController.inputBar.inputTextView resignFirstResponder];
|
|
|
+ [self removePopMemuView];
|
|
|
+ [self.messageController enableMultiSelectedMode:NO]; // 关闭选择
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+- (UIViewController *)theTopviewControler {
|
|
|
+ UIViewController *rootVC = [[UIApplication sharedApplication].delegate window].rootViewController;
|
|
|
+ UIViewController *parent = rootVC;
|
|
|
+ while ((parent = rootVC.presentedViewController) != nil) {
|
|
|
+ rootVC = parent;
|
|
|
+ }
|
|
|
+ while ([rootVC isKindOfClass:[UINavigationController class]]) {
|
|
|
+ rootVC = [(UINavigationController *)rootVC topViewController];
|
|
|
+ }
|
|
|
+ while ([rootVC isKindOfClass:[UITabBarController class]]) {
|
|
|
+ UITabBarController *tab = (UITabBarController *)rootVC;
|
|
|
+ CustomNavViewController *ctrl = (CustomNavViewController *)tab.selectedViewController;
|
|
|
+ if (ctrl.presentedViewController) {
|
|
|
+ rootVC = ctrl.presentedViewController;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ rootVC = [ctrl topViewController];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return rootVC;
|
|
|
+}
|
|
|
+- (void)removePopMemuView {
|
|
|
+ for (UIView *view in self.messageController.tableView.subviews) {
|
|
|
+ if ([view isKindOfClass:NSClassFromString(@"TUIChatPopMenu")]) {
|
|
|
+ [view removeFromSuperview];
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+- (dispatch_group_t)requestGroup {
|
|
|
+ if (!_requestGroup) {
|
|
|
+ _requestGroup = dispatch_group_create();
|
|
|
+ }
|
|
|
+ return _requestGroup;
|
|
|
+}
|
|
|
+
|
|
|
+- (UIView *)muteView {
|
|
|
+ if (!_muteView) {
|
|
|
+ _muteView = [[UIView alloc] initWithFrame:CGRectZero];
|
|
|
+ _muteView.backgroundColor = HexRGB(0xEBF0F6);
|
|
|
+ KSMuteTipsView *tipsView = [KSMuteTipsView shareInstance];
|
|
|
+ [_muteView addSubview:tipsView];
|
|
|
+ [tipsView mas_makeConstraints:^(MASConstraintMaker *make) {
|
|
|
+ make.top.mas_equalTo(_muteView.mas_top).offset(10);
|
|
|
+ make.left.mas_equalTo(_muteView.mas_left).offset(12);
|
|
|
+ make.right.mas_equalTo(_muteView.mas_right).offset(-12);
|
|
|
+ make.height.mas_equalTo(36);
|
|
|
+ }];
|
|
|
+ }
|
|
|
+ return _muteView;
|
|
|
+}
|
|
|
+
|
|
|
- (void)viewDidLoad {
|
|
|
[super viewDidLoad];
|
|
|
// Do any additional setup after loading the view.
|
|
|
+ [self setupTipsView];
|
|
|
+
|
|
|
+ [[V2TIMManager sharedInstance] addGroupListener:self];
|
|
|
+}
|
|
|
+
|
|
|
+- (void)viewWillAppear:(BOOL)animated {
|
|
|
+ [super viewWillAppear:animated];
|
|
|
+ [self getGroupAndMemberInfo];
|
|
|
+}
|
|
|
+
|
|
|
+- (void)getGroupAndMemberInfo {
|
|
|
+ [self getGroupInfo];
|
|
|
+ [self getMineInfo];
|
|
|
+ dispatch_group_notify(self.requestGroup, dispatch_get_main_queue(), ^{
|
|
|
+ [self modifyMuteViewDisplay];
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
+- (void)getMineInfo {
|
|
|
+ dispatch_group_enter(self.requestGroup);
|
|
|
+
|
|
|
+ [[V2TIMManager sharedInstance] getGroupMembersInfo:self.conversationData.groupID memberList:@[UserDefault(IM_USERID)] succ:^(NSArray<V2TIMGroupMemberFullInfo *> *memberList) {
|
|
|
+ for (V2TIMGroupMemberFullInfo *memberInfo in memberList) {
|
|
|
+ uint64_t currentTime = [self getCurrentTime];
|
|
|
+
|
|
|
+ if (memberInfo.muteUntil > currentTime) { // 存在禁言时间
|
|
|
+ self.isUserMute = YES;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ self.isUserMute = NO;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ dispatch_group_leave(self.requestGroup);
|
|
|
+ } fail:^(int code, NSString *desc) {
|
|
|
+ dispatch_group_leave(self.requestGroup);
|
|
|
+ }];
|
|
|
+}
|
|
|
+
|
|
|
+- (uint64_t)getCurrentTime {
|
|
|
+ return [[V2TIMManager sharedInstance] getServerTime];
|
|
|
+}
|
|
|
+
|
|
|
+- (void)getGroupInfo {
|
|
|
+ dispatch_group_enter(self.requestGroup);
|
|
|
+ [[V2TIMManager sharedInstance] getGroupsInfo:@[self.conversationData.groupID] succ:^(NSArray<V2TIMGroupInfoResult *> *groupResultList) {
|
|
|
+ for (V2TIMGroupInfoResult *result in groupResultList) {
|
|
|
+ V2TIMGroupInfo *groupInfo = result.info;
|
|
|
+ if (groupInfo.role == 300 || groupInfo.role == 400) {
|
|
|
+ self.isGroupManager = YES;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ self.isGroupManager = NO;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (groupInfo.allMuted) { // 全员禁言
|
|
|
+ self.isGroupMute = YES;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ self.isGroupMute = NO;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ dispatch_group_leave(self.requestGroup);
|
|
|
+ } fail:^(int code, NSString *desc) {
|
|
|
+ dispatch_group_leave(self.requestGroup);
|
|
|
+ }];
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+- (void)modifyMuteViewDisplay {
|
|
|
+
|
|
|
+ if ((self.isGroupMute && self.isGroupManager == NO) || self.isUserMute) {
|
|
|
+ self.isMute = YES;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ self.isMute = NO;
|
|
|
+ }
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+- (void)dealloc {
|
|
|
+ [TUICore unRegisterEventByObject:self];
|
|
|
+}
|
|
|
+
|
|
|
+- (void)setupTipsView {
|
|
|
+ self.tipsView = [[UIView alloc] initWithFrame:CGRectZero];
|
|
|
+ self.tipsView.backgroundColor = RGB(246, 234, 190);
|
|
|
+ [self.view addSubview:self.tipsView];
|
|
|
+ self.tipsView.mm_height(24).mm_width(self.view.mm_w);
|
|
|
+
|
|
|
+ self.pendencyLabel = [[UILabel alloc] initWithFrame:CGRectZero];
|
|
|
+ [self.tipsView addSubview:self.pendencyLabel];
|
|
|
+ self.pendencyLabel.font = [UIFont systemFontOfSize:12];
|
|
|
+
|
|
|
+ self.pendencyBtn = [UIButton buttonWithType:UIButtonTypeSystem];
|
|
|
+ [self.tipsView addSubview:self.pendencyBtn];
|
|
|
+ [self.pendencyBtn setTitle:TIMCommonLocalizableString(TUIKitChatPendencyTitle) forState:UIControlStateNormal];
|
|
|
+ [self.pendencyBtn.titleLabel setFont:[UIFont systemFontOfSize:12]];
|
|
|
+ [self.pendencyBtn addTarget:self action:@selector(openPendency:) forControlEvents:UIControlEventTouchUpInside];
|
|
|
+ [self.pendencyBtn sizeToFit];
|
|
|
+ self.tipsView.alpha = 0;
|
|
|
+
|
|
|
+ @weakify(self);
|
|
|
+ [RACObserve(self.pendencyViewModel, unReadCnt) subscribeNext:^(NSNumber *unReadCnt) {
|
|
|
+ @strongify(self);
|
|
|
+ if ([unReadCnt intValue]) {
|
|
|
+ self.pendencyLabel.text = [NSString stringWithFormat:TIMCommonLocalizableString(TUIKitChatPendencyRequestToJoinGroupFormat), unReadCnt];
|
|
|
+ [self.pendencyLabel sizeToFit];
|
|
|
+ CGFloat gap = (self.tipsView.mm_w - self.pendencyLabel.mm_w - self.pendencyBtn.mm_w - 8) / 2;
|
|
|
+ self.pendencyLabel.mm_left(gap).mm__centerY(self.tipsView.mm_h / 2);
|
|
|
+ self.pendencyBtn.mm_hstack(8);
|
|
|
+
|
|
|
+ self.tipsView.alpha = 1;
|
|
|
+ UIView *topView = [TUIGroupChatViewController customTopView];
|
|
|
+ self.tipsView.mm_top(topView ? topView.mm_h : 0);
|
|
|
+ } else {
|
|
|
+ self.tipsView.alpha = 0;
|
|
|
+ }
|
|
|
+ }];
|
|
|
+
|
|
|
+ [self getPendencyList];
|
|
|
+}
|
|
|
+
|
|
|
+- (void)getPendencyList {
|
|
|
+ if (self.conversationData.groupID.length > 0) [self.pendencyViewModel loadData];
|
|
|
+}
|
|
|
+
|
|
|
+- (void)openPendency:(id)sender {
|
|
|
+ TUIGroupPendencyController *vc = [[TUIGroupPendencyController alloc] init];
|
|
|
+ @weakify(self);
|
|
|
+ vc.cellClickBlock = ^(TUIGroupPendencyCell *_Nonnull cell) {
|
|
|
+ if (cell.pendencyData.isRejectd || cell.pendencyData.isAccepted) {
|
|
|
+ // 选择后不再进详情页了
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ @strongify(self);
|
|
|
+ [[V2TIMManager sharedInstance] getUsersInfo:@[ cell.pendencyData.fromUser ]
|
|
|
+ succ:^(NSArray<V2TIMUserFullInfo *> *profiles) {
|
|
|
+ // 显示用户资料 VC
|
|
|
+ NSDictionary *param = @{
|
|
|
+ TUICore_TUIContactObjectFactory_UserProfileController_UserProfile : profiles.firstObject,
|
|
|
+ TUICore_TUIContactObjectFactory_UserProfileController_PendencyData : cell.pendencyData,
|
|
|
+ TUICore_TUIContactObjectFactory_UserProfileController_ActionType : @(3)
|
|
|
+ };
|
|
|
+ [self.navigationController pushViewController:TUICore_TUIContactObjectFactory_UserProfileController_Classic
|
|
|
+ param:param
|
|
|
+ forResult:nil];
|
|
|
+ }
|
|
|
+ fail:nil];
|
|
|
+ };
|
|
|
+ vc.viewModel = self.pendencyViewModel;
|
|
|
+ [self.navigationController pushViewController:vc animated:YES];
|
|
|
+}
|
|
|
+
|
|
|
+- (void)setConversationData:(TUIChatConversationModel *)conversationData {
|
|
|
+ [super setConversationData:conversationData];
|
|
|
+
|
|
|
+ if (self.conversationData.groupID.length > 0) {
|
|
|
+ _pendencyViewModel = [TUIGroupPendencyDataProvider new];
|
|
|
+ _pendencyViewModel.groupId = conversationData.groupID;
|
|
|
+ }
|
|
|
+
|
|
|
+ self.atUserList = [NSMutableArray array];
|
|
|
+}
|
|
|
+
|
|
|
+#pragma mark - V2TIMGroupListener
|
|
|
+- (void)onReceiveJoinApplication:(NSString *)groupID member:(V2TIMGroupMemberInfo *)member opReason:(NSString *)opReason {
|
|
|
+ [self getPendencyList];
|
|
|
+}
|
|
|
+
|
|
|
+- (void)onGroupInfoChanged:(NSString *)groupID changeInfoList:(NSArray<V2TIMGroupChangeInfo *> *)changeInfoList {
|
|
|
+ if (![groupID isEqualToString:self.conversationData.groupID]) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ for (V2TIMGroupChangeInfo *changeInfo in changeInfoList) {
|
|
|
+ if (changeInfo.type == V2TIM_GROUP_INFO_CHANGE_TYPE_NAME) {
|
|
|
+ self.conversationData.title = changeInfo.value;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ else if (changeInfo.type == V2TIM_GROUP_INFO_CHANGE_TYPE_SHUT_UP_ALL) { // 群禁言
|
|
|
+ // 提示
|
|
|
+ BOOL mute = changeInfo.boolValue;
|
|
|
+ if (mute) {
|
|
|
+ self.isGroupMute = YES;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ self.isGroupMute = NO;
|
|
|
+ }
|
|
|
+ // 刷新状态
|
|
|
+ [self modifyMuteViewDisplay];
|
|
|
+ }
|
|
|
+ else if (changeInfo.type == V2TIM_GROUP_INFO_CHANGE_TYPE_OWNER) { // 群主变更
|
|
|
+ NSString *userID = changeInfo.value;
|
|
|
+ if ([userID isEqualToString:UserDefault(IM_USERID)]) {
|
|
|
+ self.isGroupManager = YES;
|
|
|
+ // 刷新状态
|
|
|
+ [self modifyMuteViewDisplay];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+//searchGroupMembers
|
|
|
+- (void)onMemberInfoChanged:(NSString *)groupID changeInfoList:(NSArray<V2TIMGroupMemberChangeInfo *> *)changeInfoList {
|
|
|
+ for (V2TIMGroupMemberChangeInfo *memberChangeInfo in changeInfoList) {
|
|
|
+ if ([memberChangeInfo.userID isEqualToString:UserDefault(IM_USERID)]) {
|
|
|
+ if (memberChangeInfo.muteTime > 0) {
|
|
|
+ self.isUserMute = YES;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ self.isUserMute = NO;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 刷新状态
|
|
|
+ [self modifyMuteViewDisplay];
|
|
|
+}
|
|
|
+
|
|
|
+/// 指定管理员身份
|
|
|
+- (void)onGrantAdministrator:(NSString *)groupID opUser:(V2TIMGroupMemberInfo *)opUser memberList:(NSArray <V2TIMGroupMemberInfo *> *)memberList {
|
|
|
+ for (V2TIMGroupMemberInfo *memberInfo in memberList) {
|
|
|
+ if ([memberInfo.userID isEqualToString:UserDefault(IM_USERID)]) {
|
|
|
+ self.isGroupManager = YES;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 刷新状态
|
|
|
+ [self modifyMuteViewDisplay];
|
|
|
+}
|
|
|
+
|
|
|
+/// 取消管理员身份
|
|
|
+- (void)onRevokeAdministrator:(NSString *)groupID opUser:(V2TIMGroupMemberInfo *)opUser memberList:(NSArray <V2TIMGroupMemberInfo *> *)memberList {
|
|
|
+ for (V2TIMGroupMemberInfo *memberInfo in memberList) {
|
|
|
+ if ([memberInfo.userID isEqualToString:UserDefault(IM_USERID)]) {
|
|
|
+ self.isGroupManager = NO;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 刷新状态
|
|
|
+ [self modifyMuteViewDisplay];
|
|
|
+}
|
|
|
+
|
|
|
+#pragma mark - TUIInputControllerDelegate
|
|
|
+- (void)inputController:(TUIInputController *)inputController didSendMessage:(V2TIMMessage *)msg {
|
|
|
+ /**
|
|
|
+ * 文本消息如果有 @ 用户,需要 createTextAtMessage
|
|
|
+ * If the text message has @ user, createTextAtMessage is required
|
|
|
+ */
|
|
|
+ if (msg.elemType == V2TIM_ELEM_TYPE_TEXT) {
|
|
|
+ NSMutableArray *atUserList = [NSMutableArray array];
|
|
|
+ for (TUIUserModel *model in self.atUserList) {
|
|
|
+ if (model.userId) {
|
|
|
+ [atUserList addObject:model.userId];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (atUserList.count > 0) {
|
|
|
+ NSData *cloudCustomData = msg.cloudCustomData;
|
|
|
+ msg = [[V2TIMManager sharedInstance] createTextAtMessage:msg.textElem.text atUserList:atUserList];
|
|
|
+ msg.cloudCustomData = cloudCustomData;
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * 消息发送完后 atUserList 要重置
|
|
|
+ * After the message is sent, the atUserList need to be reset
|
|
|
+ */
|
|
|
+ [self.atUserList removeAllObjects];
|
|
|
+ }
|
|
|
+ [super inputController:inputController didSendMessage:msg];
|
|
|
+}
|
|
|
+
|
|
|
+- (void)inputControllerDidInputAt:(TUIInputController *)inputController {
|
|
|
+ [super inputControllerDidInputAt:inputController];
|
|
|
+ /**
|
|
|
+ * 检测到 @ 字符的输入
|
|
|
+ * Input of @ character detected
|
|
|
+ */
|
|
|
+ if (self.conversationData.groupID.length > 0) {
|
|
|
+ if ([self.navigationController.topViewController isKindOfClass:NSClassFromString(@"TUISelectGroupMemberViewController")]) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ __weak typeof(self) weakSelf = self;
|
|
|
+ NSMutableDictionary *param = [NSMutableDictionary dictionary];
|
|
|
+ param[TUICore_TUIGroupObjectFactory_SelectGroupMemberVC_GroupID] = self.conversationData.groupID;
|
|
|
+ param[TUICore_TUIGroupObjectFactory_SelectGroupMemberVC_Name] = TIMCommonLocalizableString(TUIKitAtSelectMemberTitle);
|
|
|
+ param[TUICore_TUIGroupObjectFactory_SelectGroupMemberVC_OptionalStyle] = @(1);
|
|
|
+ [self.navigationController
|
|
|
+ pushViewController:TUICore_TUIGroupObjectFactory_SelectGroupMemberVC_Classic
|
|
|
+ param:param
|
|
|
+ forResult:^(NSDictionary *_Nonnull param) {
|
|
|
+ NSArray<TUIUserModel *> *modelList = [param tui_objectForKey:TUICore_TUIGroupObjectFactory_SelectGroupMemberVC_ResultUserList
|
|
|
+ asClass:NSArray.class];
|
|
|
+ NSMutableString *atText = [[NSMutableString alloc] init];
|
|
|
+ for (int i = 0; i < modelList.count; i++) {
|
|
|
+ TUIUserModel *model = modelList[i];
|
|
|
+ if (![model isKindOfClass:TUIUserModel.class]) {
|
|
|
+ NSAssert(NO, @"Error data-type in modelList");
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ [weakSelf.atUserList addObject:model];
|
|
|
+ if (i == 0) {
|
|
|
+ [atText appendString:[NSString stringWithFormat:@"%@ ", model.name]];
|
|
|
+ } else {
|
|
|
+ [atText appendString:[NSString stringWithFormat:@"@%@ ", model.name]];
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ NSAttributedString *spaceString = [[NSAttributedString alloc]
|
|
|
+ initWithString:atText
|
|
|
+ attributes:@{NSFontAttributeName : kTUIInputNoramlFont, NSForegroundColorAttributeName : kTUIInputNormalTextColor}];
|
|
|
+ NSRange range = weakSelf.inputController.inputBar.inputTextView.selectedRange;
|
|
|
+ [weakSelf.inputController.inputBar.inputTextView.textStorage insertAttributedString:spaceString atIndex:range.location + range.length];
|
|
|
+ [weakSelf.inputController.inputBar updateTextViewFrame];
|
|
|
+ }];
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+- (void)inputController:(TUIInputController *)inputController didDeleteAt:(NSString *)atText {
|
|
|
+ [super inputController:inputController didDeleteAt:atText];
|
|
|
+
|
|
|
+ for (TUIUserModel *user in self.atUserList) {
|
|
|
+ if ([atText rangeOfString:user.name].location != NSNotFound) {
|
|
|
+ [self.atUserList removeObject:user];
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+- (void)inputController:(TUIInputController *)inputController didSelectMoreCell:(TUIInputMoreCell *)cell {
|
|
|
+ [super inputController:inputController didSelectMoreCell:cell];
|
|
|
+}
|
|
|
+
|
|
|
+#pragma mark - TUIBaseMessageControllerDelegate
|
|
|
+- (void)messageController:(TUIBaseMessageController *)controller onLongSelectMessageAvatar:(TUIMessageCell *)cell {
|
|
|
+ if (self.isMute) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (!cell || !cell.messageData || !cell.messageData.identifier) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if ([cell.messageData.identifier isEqualToString:[TUILogin getUserID]]) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ BOOL atUserExist = NO;
|
|
|
+ for (TUIUserModel *model in self.atUserList) {
|
|
|
+ if ([model.userId isEqualToString:cell.messageData.identifier]) {
|
|
|
+ atUserExist = YES;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (!atUserExist) {
|
|
|
+ TUIUserModel *user = [[TUIUserModel alloc] init];
|
|
|
+ user.userId = cell.messageData.identifier;
|
|
|
+ user.name = cell.messageData.name;
|
|
|
+ [self.atUserList addObject:user];
|
|
|
+
|
|
|
+ NSString *nameString = [NSString stringWithFormat:@"@%@ ", user.name];
|
|
|
+ UIFont *textFont = kTUIInputNoramlFont;
|
|
|
+ NSAttributedString *spaceString = [[NSAttributedString alloc] initWithString:nameString attributes:@{NSFontAttributeName : textFont}];
|
|
|
+ [self.inputController.inputBar.inputTextView.textStorage insertAttributedString:spaceString
|
|
|
+ atIndex:self.inputController.inputBar.inputTextView.textStorage.length];
|
|
|
+ [self.inputController.inputBar.inputTextView becomeFirstResponder];
|
|
|
+ self.inputController.inputBar.inputTextView.selectedRange =
|
|
|
+ NSMakeRange(spaceString.length + self.inputController.inputBar.inputTextView.textStorage.length, 0);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+- (void)messageController:(TUIBaseMessageController *)controller onSelectMessageMenu:(NSInteger)menuType withData:(TUIMessageCellData *)data {
|
|
|
+ if (self.isMute) {
|
|
|
+ [self.messageController enableMultiSelectedMode:NO]; // 关闭选择
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ [self onSelectMessageMenu:menuType withData:data];
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+- (void)messageController:(TUIBaseMessageController *)controller onRelyMessage:(TUIMessageCellData *)data {
|
|
|
+ if (self.isMute) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ [super messageController:controller onRelyMessage:data];
|
|
|
+}
|
|
|
+
|
|
|
+- (void)messageController:(TUIBaseMessageController *)controller onReferenceMessage:(TUIMessageCellData *)data {
|
|
|
+ if (self.isMute) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ [super messageController:controller onReferenceMessage:data];
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+- (void)messageController:(TUIBaseMessageController *)controller modifyMessage:(nonnull TUIMessageCellData *)cellData reactEmoji:(NSString *)emojiName {
|
|
|
+ if (self.isMute) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ [super messageController:controller modifyMessage:cellData reactEmoji:emojiName];
|
|
|
+}
|
|
|
+
|
|
|
+- (void)messageController:(TUIBaseMessageController *)controller onReEditMessage:(TUIMessageCellData *)data {
|
|
|
+ if (self.isMute) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ [super messageController:controller onReEditMessage:data];
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+#pragma mark - Override Methods
|
|
|
+- (NSString *)forwardTitleWithMyName:(NSString *)nameStr {
|
|
|
+ return TIMCommonLocalizableString(TUIKitRelayGroupChatHistory);
|
|
|
}
|
|
|
|
|
|
|