PageRenderTime 57ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/TeamTalk/IOSDuoduo/VC/Chatting/ChattingMainViewController.m

https://gitlab.com/lisit1003/TTiOSClient
Objective C | 1268 lines | 1072 code | 152 blank | 44 comment | 98 complexity | ad5e86cfa6f83aec27e87a33bff9804e MD5 | raw file
  1. //
  2. // DDChattingMainViewController.m
  3. // IOSDuoduo
  4. //
  5. // Created by 东邪 on 14-5-26.
  6. // Copyright (c) 2014年 dujia. All rights reserved.
  7. //
  8. #import "ChattingMainViewController.h"
  9. #import "ChatUtilityViewController.h"
  10. #import "std.h"
  11. #import "PhotosCache.h"
  12. #import "DDGroupModule.h"
  13. #import "DDMessageSendManager.h"
  14. #import "DDGroupMsgReadACKAPI.h"
  15. #import "DDDatabaseUtil.h"
  16. #import "DDChatTextCell.h"
  17. #import "DDChatVoiceCell.h"
  18. #import "DDChatImageCell.h"
  19. #import "DDChattingEditViewController.h"
  20. #import "DDPromptCell.h"
  21. #import "UIView+DDAddition.h"
  22. #import "DDMessageModule.h"
  23. #import "RecordingView.h"
  24. #import "AnalysisImage.h"
  25. #import "TouchDownGestureRecognizer.h"
  26. #import "DDSendMessageReadACKAPI.h"
  27. #import "DDSendPhotoMessageAPI.h"
  28. #import "NSDictionary+JSON.h"
  29. #import "EmotionsModule.h"
  30. #import "RuntimeStatus.h"
  31. #import "RecentUsersViewController.h"
  32. #import "PublicProfileViewControll.h"
  33. #import "UnAckMessageManager.h"
  34. typedef NS_ENUM(NSUInteger, DDBottomShowComponent)
  35. {
  36. DDInputViewUp = 1,
  37. DDShowKeyboard = 1 << 1,
  38. DDShowEmotion = 1 << 2,
  39. DDShowUtility = 1 << 3
  40. };
  41. typedef NS_ENUM(NSUInteger, DDBottomHiddComponent)
  42. {
  43. DDInputViewDown = 14,
  44. DDHideKeyboard = 13,
  45. DDHideEmotion = 11,
  46. DDHideUtility = 7
  47. };
  48. //
  49. typedef NS_ENUM(NSUInteger, DDInputType)
  50. {
  51. DDVoiceInput,
  52. DDTextInput
  53. };
  54. typedef NS_ENUM(NSUInteger, PanelStatus)
  55. {
  56. VoiceStatus,
  57. TextInputStatus,
  58. EmotionStatus,
  59. ImageStatus
  60. };
  61. #define DDINPUT_MIN_HEIGHT 44.0f
  62. #define DDINPUT_HEIGHT self.chatInputView.size.height
  63. #define DDINPUT_BOTTOM_FRAME CGRectMake(0, CONTENT_HEIGHT - self.chatInputView.height + NAVBAR_HEIGHT,FULL_WIDTH,self.chatInputView.height)
  64. #define DDINPUT_TOP_FRAME CGRectMake(0, CONTENT_HEIGHT - self.chatInputView.height + NAVBAR_HEIGHT - 216, 320, self.chatInputView.height)
  65. #define DDUTILITY_FRAME CGRectMake(0, CONTENT_HEIGHT + NAVBAR_HEIGHT -216, 320, 216)
  66. #define DDEMOTION_FRAME CGRectMake(0, CONTENT_HEIGHT + NAVBAR_HEIGHT-216, 320, 216)
  67. #define DDCOMPONENT_BOTTOM CGRectMake(0, CONTENT_HEIGHT + NAVBAR_HEIGHT, 320, 216)
  68. @interface ChattingMainViewController ()<UIGestureRecognizerDelegate>
  69. @property(nonatomic,assign)CGPoint inputViewCenter;
  70. @property(nonatomic,strong)UIActivityIndicatorView *activity;
  71. @property(assign)PanelStatus panelStatus;
  72. @property(strong)NSString *chatObjectID;
  73. @property(strong) UIButton *titleBtn ;
  74. - (void)recentViewController;
  75. - (UITableViewCell*)p_textCell_tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath message:(DDMessageEntity*)message;
  76. - (UITableViewCell*)p_voiceCell_tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath message:(DDMessageEntity*)message;
  77. - (UITableViewCell*)p_promptCell_tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath message:(DDPromptEntity*)prompt;
  78. - (UITableViewCell*)p_commodityCell_tableView:(UITableView* )tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath message:(DDMessageEntity*)commodity;
  79. - (void)n_receiveMessage:(NSNotification*)notification;
  80. - (void)n_receiveStartLoginNotification:(NSNotification*)notification;
  81. - (void)n_receiveLoginSuccessNotification:(NSNotification*)notification;
  82. - (void)n_receiveLoginFailureNotification:(NSNotification*)notification;
  83. - (void)n_receiveUserKickoffNotification:(NSNotification*)notification;
  84. - (void)p_clickThRecordButton:(UIButton*)button;
  85. - (void)p_record:(UIButton*)button;
  86. - (void)p_willCancelRecord:(UIButton*)button;
  87. - (void)p_cancelRecord:(UIButton*)button;
  88. - (void)p_sendRecord:(UIButton*)button;
  89. - (void)p_endCancelRecord:(UIButton*)button;
  90. - (void)p_tapOnTableView:(UIGestureRecognizer*)sender;
  91. - (void)p_hideBottomComponent;
  92. - (void)p_enableChatFunction;
  93. - (void)p_unableChatFunction;
  94. @end
  95. @implementation ChattingMainViewController
  96. {
  97. TouchDownGestureRecognizer* _touchDownGestureRecognizer;
  98. NSString* _currentInputContent;
  99. UIButton *_recordButton;
  100. DDBottomShowComponent _bottomShowComponent;
  101. float _inputViewY;
  102. int _type;
  103. }
  104. +(instancetype )shareInstance
  105. {
  106. static dispatch_once_t onceToken;
  107. static ChattingMainViewController *_sharedManager = nil;
  108. dispatch_once(&onceToken, ^{
  109. _sharedManager = [ChattingMainViewController new];
  110. });
  111. return _sharedManager;
  112. }
  113. - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
  114. {
  115. CGPoint location = [gestureRecognizer locationInView:self.view];
  116. if (CGRectContainsPoint(DDINPUT_BOTTOM_FRAME, location))
  117. {
  118. return NO;
  119. }
  120. return YES;
  121. }
  122. -(void)sendImageMessage:(Photo *)photo Image:(UIImage *)image
  123. {
  124. NSDictionary* messageContentDic = @{DD_IMAGE_LOCAL_KEY:photo.localPath};
  125. NSString* messageContent = [messageContentDic jsonString];
  126. DDMessageEntity *message = [DDMessageEntity makeMessage:messageContent Module:self.module MsgType:DDMessageTypeImage];
  127. [self scrollToBottomAnimated:YES];
  128. NSData *photoData = UIImagePNGRepresentation(image);
  129. [[PhotosCache sharedPhotoCache] storePhoto:photoData forKey:photo.localPath toDisk:YES];
  130. //[self.chatInputView.textView setText:@""];
  131. [[DDDatabaseUtil instance] insertMessages:@[message] success:^{
  132. DDLog(@"消息插入DB成功");
  133. } failure:^(NSString *errorDescripe) {
  134. DDLog(@"消息插入DB失败");
  135. }];
  136. photo=nil;
  137. [[DDSendPhotoMessageAPI sharedPhotoCache] uploadImage:messageContentDic[DD_IMAGE_LOCAL_KEY] success:^(NSString *imageURL) {
  138. [self scrollToBottomAnimated:YES];
  139. NSDictionary* tempMessageContent = [NSDictionary initWithJsonString:message.msgContent];
  140. NSMutableDictionary* mutalMessageContent = [[NSMutableDictionary alloc] initWithDictionary:tempMessageContent];
  141. [mutalMessageContent setValue:imageURL forKey:DD_IMAGE_URL_KEY];
  142. NSString* messageContent = [mutalMessageContent jsonString];
  143. message.msgContent = messageContent;
  144. [self sendMessage:imageURL messageEntity:message];
  145. [[DDDatabaseUtil instance] updateMessageForMessage:message completion:^(BOOL result) {
  146. }];
  147. } failure:^(id error) {
  148. message.state = DDMessageSendFailure;
  149. //刷新DB
  150. [[DDDatabaseUtil instance] updateMessageForMessage:message completion:^(BOOL result) {
  151. if (result)
  152. {
  153. dispatch_async(dispatch_get_main_queue(), ^{
  154. [_tableView reloadData];
  155. });
  156. }
  157. }];
  158. }];
  159. }
  160. - (void)textViewEnterSend
  161. {
  162. //发送消息
  163. NSString* text = [self.chatInputView.textView text];
  164. NSString* parten = @"\\s";
  165. NSRegularExpression* reg = [NSRegularExpression regularExpressionWithPattern:parten options:NSRegularExpressionCaseInsensitive error:nil];
  166. NSString* checkoutText = [reg stringByReplacingMatchesInString:text options:NSMatchingReportProgress range:NSMakeRange(0, [text length]) withTemplate:@""];
  167. if ([checkoutText length] == 0)
  168. {
  169. return;
  170. }
  171. DDMessageContentType msgContentType = DDMessageTypeText;
  172. DDMessageEntity *message = [DDMessageEntity makeMessage:text Module:self.module MsgType:msgContentType];
  173. [self.chatInputView.textView setText:nil];
  174. [[DDDatabaseUtil instance] insertMessages:@[message] success:^{
  175. DDLog(@"消息插入DB成功");
  176. } failure:^(NSString *errorDescripe) {
  177. DDLog(@"消息插入DB失败");
  178. }];
  179. [self sendMessage:text messageEntity:message];
  180. [self scrollToBottomAnimated:YES];
  181. }
  182. -(void)sendMessage:(NSString *)msg messageEntity:(DDMessageEntity *)message
  183. {
  184. if (message) {
  185. BOOL isGroup = self.module.sessionEntity.sessionType == SESSIONTYPE_SINGLE?NO:YES;
  186. [[DDMessageSendManager instance] sendMessage:message isGroup:isGroup forSessionID:self.module.sessionEntity.sessionID completion:^(DDMessageEntity* theMessage,NSError *error) {
  187. if (error)
  188. {
  189. [[DDDatabaseUtil instance] updateMessageForMessage:theMessage completion:^(BOOL result) {
  190. if (result)
  191. {
  192. dispatch_async(dispatch_get_main_queue(), ^{
  193. [self.tableView reloadData];
  194. [self scrollToBottomAnimated:YES];
  195. });
  196. }
  197. }];
  198. }
  199. else
  200. {
  201. theMessage.state = DDmessageSendSuccess;
  202. [[DDDatabaseUtil instance] updateMessageForMessage:theMessage completion:^(BOOL result) {
  203. if (result)
  204. {
  205. dispatch_async(dispatch_get_main_queue(), ^{
  206. [self.tableView reloadData];
  207. [self scrollToBottomAnimated:YES];
  208. });
  209. }
  210. }];
  211. }
  212. }];
  213. }
  214. }
  215. //--------------------------------------------------------------------------------------------
  216. #pragma mark -
  217. #pragma mark RecordingDelegate
  218. - (void)recordingFinishedWithFileName:(NSString *)filePath time:(NSTimeInterval)interval
  219. {
  220. NSMutableData* muData = [[NSMutableData alloc] init];
  221. NSData* data = [NSData dataWithContentsOfFile:filePath];
  222. int length = [RecorderManager sharedManager].recordedTimeInterval;
  223. if (length < 1 )
  224. {
  225. DDLog(@"录音时间太短");
  226. dispatch_async(dispatch_get_main_queue(), ^{
  227. [_recordingView setHidden:NO];
  228. [_recordingView setRecordingState:DDShowRecordTimeTooShort];
  229. });
  230. return;
  231. }
  232. else
  233. {
  234. dispatch_async(dispatch_get_main_queue(), ^{
  235. [_recordingView setHidden:YES];
  236. });
  237. }
  238. int8_t ch[4];
  239. for(int32_t i = 0;i<4;i++){
  240. ch[i] = ((length >> ((3 - i)*8)) & 0x0ff);
  241. }
  242. [muData appendBytes:ch length:4];
  243. [muData appendData:data];
  244. DDMessageContentType msgContentType = DDMessageTypeVoice;
  245. DDMessageEntity* message = [DDMessageEntity makeMessage:filePath Module:self.module MsgType:msgContentType];
  246. BOOL isGroup = self.module.sessionEntity.sessionType == SESSIONTYPE_SINGLE?NO:YES;
  247. // if (isGroup) {
  248. // message.msgType=MSG_TYPE_GROUP_AUDIO;
  249. // }else
  250. // {
  251. // message.msgType = MSG_TYPE_AUDIO;
  252. // }
  253. [message.info setObject:@(length) forKey:VOICE_LENGTH];
  254. [message.info setObject:@(1) forKey:DDVOICE_PLAYED];
  255. dispatch_async(dispatch_get_main_queue(), ^{
  256. [self.tableView reloadData];
  257. [self scrollToBottomAnimated:YES];
  258. [[DDDatabaseUtil instance] insertMessages:@[message] success:^{
  259. NSLog(@"消息插入DB成功");
  260. } failure:^(NSString *errorDescripe) {
  261. NSLog(@"消息插入DB失败");
  262. }];
  263. });
  264. [[DDMessageSendManager instance] sendVoiceMessage:muData filePath:filePath forSessionID:self.module.sessionEntity.sessionID isGroup:isGroup completion:^(DDMessageEntity *theMessage, NSError *error) {
  265. if (!error)
  266. {
  267. DDLog(@"发送语音消息成功");
  268. [[PlayerManager sharedManager] playAudioWithFileName:@"msg.caf" playerType:DDSpeaker delegate:self];
  269. message.state = DDmessageSendSuccess;
  270. [[DDDatabaseUtil instance] updateMessageForMessage:message completion:^(BOOL result) {
  271. if (result)
  272. {
  273. dispatch_async(dispatch_get_main_queue(), ^{
  274. [self.tableView reloadData];
  275. });
  276. }
  277. }];
  278. }
  279. else
  280. {
  281. DDLog(@"发送语音消息失败");
  282. message.state = DDMessageSendFailure;
  283. [[DDDatabaseUtil instance] updateMessageForMessage:message completion:^(BOOL result) {
  284. if (result)
  285. {
  286. dispatch_async(dispatch_get_main_queue(), ^{
  287. [self.tableView reloadData];
  288. });
  289. }
  290. }];
  291. }
  292. }];
  293. }
  294. - (void)playingStoped
  295. {
  296. }
  297. - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
  298. {
  299. self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
  300. if (self) {
  301. // Custom initialization
  302. self.titleBtn = [UIButton buttonWithType:UIButtonTypeCustom];
  303. self.titleBtn.frame=CGRectMake(0, 0, 150, 40);
  304. [self.titleBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
  305. [self.titleBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateHighlighted];
  306. [self.titleBtn addTarget:self action:@selector(titleTap:) forControlEvents:UIControlEventTouchUpInside];
  307. [self.titleBtn.titleLabel setTextAlignment:NSTextAlignmentLeft];
  308. }
  309. return self;
  310. }
  311. -(void)notificationCenter
  312. {
  313. [[NSNotificationCenter defaultCenter] addObserver:self
  314. selector:@selector(n_receiveMessage:)
  315. name:DDNotificationReceiveMessage
  316. object:nil];
  317. [[NSNotificationCenter defaultCenter] addObserver:self
  318. selector:@selector(n_receiveStartLoginNotification:) name:DDNotificationStartLogin object:nil];
  319. [[NSNotificationCenter defaultCenter] addObserver:self
  320. selector:@selector(n_receiveLoginSuccessNotification:)
  321. name:DDNotificationUserLoginSuccess
  322. object:nil];
  323. [[NSNotificationCenter defaultCenter] addObserver:self
  324. selector:@selector(n_receiveLoginFailureNotification:)
  325. name:DDNotificationUserLoginFailure
  326. object:nil];
  327. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(n_receiveUserKickoffNotification:) name:DDNotificationUserKickouted object:nil];
  328. [[NSNotificationCenter defaultCenter] addObserver:self
  329. selector:@selector(handleWillShowKeyboard:)
  330. name:UIKeyboardWillShowNotification
  331. object:nil];
  332. [[NSNotificationCenter defaultCenter] addObserver:self
  333. selector:@selector(handleWillHideKeyboard:)
  334. name:UIKeyboardWillHideNotification
  335. object:nil];
  336. }
  337. - (void)viewDidLoad
  338. {
  339. [super viewDidLoad];
  340. UIImage* image = [UIImage imageNamed:@"navigationbar_back"];
  341. self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithImage:image style:UIBarButtonItemStylePlain target:self action:@selector(p_popViewController)];
  342. [self notificationCenter];
  343. [self initialInput];
  344. UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self
  345. action:@selector(p_tapOnTableView:)];
  346. [self.tableView addGestureRecognizer:tap];
  347. UIPanGestureRecognizer* pan = [[UIPanGestureRecognizer alloc] initWithTarget:self
  348. action:@selector(p_tapOnTableView:)];
  349. pan.delegate = self;
  350. [self.tableView addGestureRecognizer:pan];
  351. self.tableView.delegate=self;
  352. self.tableView.dataSource=self;
  353. [self.tableView setContentInset:UIEdgeInsetsMake(0, 0, 0, 0)];
  354. [self scrollToBottomAnimated:NO];
  355. _originalTableViewContentInset = self.tableView.contentInset;
  356. self.activity = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
  357. self.activity.frame=CGRectMake(self.view.frame.size.width/2, 70, 20, 20);
  358. [self.view addSubview:self.activity];
  359. UIBarButtonItem* item = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"contacts"] style:UIBarButtonItemStyleBordered target:self action:@selector(Edit:)];
  360. self.navigationItem.rightBarButtonItem=item;
  361. [self.module addObserver:self forKeyPath:@"showingMessages" options:NSKeyValueObservingOptionOld|NSKeyValueObservingOptionNew context:NULL];
  362. [self.module addObserver:self forKeyPath:@"sessionEntity.sessionID" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:NULL];
  363. [self.navigationItem.titleView setUserInteractionEnabled:YES];
  364. self.navigationItem.titleView=self.titleBtn;
  365. self.view.backgroundColor=[UIColor whiteColor];
  366. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(n_receiveUnreadMessageUpdateNotification:) name:DDNotificationUpdateUnReadMessage object:nil];
  367. }
  368. -(void)setThisViewTitle:(NSString *)title
  369. {
  370. [self.titleBtn setTitle:title forState:UIControlStateNormal];
  371. }
  372. -(IBAction)Edit:(id)sender
  373. {
  374. DDChattingEditViewController *chattingedit = [DDChattingEditViewController new];
  375. chattingedit.session=self.module.sessionEntity;
  376. [self.navigationController pushViewController:chattingedit animated:YES];
  377. }
  378. - (void)back
  379. {
  380. [self.chatInputView.textView resignFirstResponder];
  381. }
  382. - (void)didReceiveMemoryWarning
  383. {
  384. [super didReceiveMemoryWarning];
  385. // Dispose of any resources that can be recreated.
  386. }
  387. - (void)scrollToBottomAnimated:(BOOL)animated
  388. {
  389. NSInteger rows = [self.tableView numberOfRowsInSection:0];
  390. if(rows > 0) {
  391. [self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:rows - 1 inSection:0]
  392. atScrollPosition:UITableViewScrollPositionBottom
  393. animated:animated];
  394. }
  395. }
  396. - (ChattingModule*)module
  397. {
  398. if (!_module)
  399. {
  400. _module = [[ChattingModule alloc] init];
  401. }
  402. return _module;
  403. }
  404. #pragma mark -
  405. #pragma mark ActionMethods 发送sendAction 音频 voiceChange 显示表情 disFaceKeyboard
  406. -(IBAction)sendAction:(id)sender{
  407. if (self.chatInputView.textView.text.length>0) {
  408. NSLog(@"点击发送");
  409. [self.chatInputView.textView setText:@""];
  410. }
  411. }
  412. -(void)viewWillAppear:(BOOL)animated
  413. {
  414. [super viewWillAppear:animated];
  415. [self.tableView reloadData];
  416. [self.chatInputView.textView setText:nil];
  417. [self.tabBarController.tabBar setHidden:YES];
  418. [self p_hideBottomComponent];
  419. }
  420. - (void)viewDidAppear:(BOOL)animated
  421. {
  422. [super viewDidAppear:animated];
  423. [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent animated:animated];
  424. }
  425. - (void)viewWillDisappear:(BOOL)animated
  426. {
  427. [super viewWillDisappear:animated];
  428. [self.tabBarController.tabBar setHidden:NO];
  429. [self p_hideBottomComponent];
  430. }
  431. - (void)viewDidDisappear:(BOOL)animated
  432. {
  433. [super viewDidDisappear:animated];
  434. }
  435. #pragma mark -
  436. #pragma mark UIGesture Delegate
  437. - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
  438. if ([gestureRecognizer.view isEqual:_tableView])
  439. {
  440. return YES;
  441. }
  442. return NO;
  443. }
  444. #pragma mark - EmojiFace Funcation
  445. -(void)insertEmojiFace:(NSString *)string
  446. {
  447. NSMutableString* content = [NSMutableString stringWithString:self.chatInputView.textView.text];
  448. [content appendString:string];
  449. [self.chatInputView.textView setText:content];
  450. }
  451. -(void)deleteEmojiFace
  452. {
  453. EmotionsModule* emotionModule = [EmotionsModule shareInstance];
  454. NSString* toDeleteString = nil;
  455. if (self.chatInputView.textView.text.length == 0)
  456. {
  457. return;
  458. }
  459. if (self.chatInputView.textView.text.length == 1)
  460. {
  461. self.chatInputView.textView.text = @"";
  462. }
  463. else
  464. {
  465. toDeleteString = [self.chatInputView.textView.text substringFromIndex:self.chatInputView.textView.text.length - 1];
  466. int length = [emotionModule.emotionLength[toDeleteString] intValue];
  467. if (length == 0)
  468. {
  469. toDeleteString = [self.chatInputView.textView.text substringFromIndex:self.chatInputView.textView.text.length - 2];
  470. length = [emotionModule.emotionLength[toDeleteString] intValue];
  471. }
  472. length = length == 0 ? 1 : length;
  473. self.chatInputView.textView.text = [self.chatInputView.textView.text substringToIndex:self.chatInputView.textView.text.length - length];
  474. }
  475. }
  476. #pragma mark - UITableView DataSource
  477. - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
  478. {
  479. return 1;
  480. }
  481. - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
  482. {
  483. return [self.module.showingMessages count];
  484. }
  485. - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
  486. {
  487. float height = 0;
  488. id object = self.module.showingMessages[indexPath.row];
  489. if ([object isKindOfClass:[DDMessageEntity class]])
  490. {
  491. DDMessageEntity* message = object;
  492. height = [self.module messageHeight:message];
  493. }
  494. else if([object isKindOfClass:[DDPromptEntity class]])
  495. {
  496. height = 30;
  497. }
  498. return height+10;
  499. }
  500. - (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
  501. {
  502. id object = self.module.showingMessages[indexPath.row];
  503. UITableViewCell* cell = nil;
  504. if ([object isKindOfClass:[DDMessageEntity class]])
  505. {
  506. DDMessageEntity* message = (DDMessageEntity*)object;
  507. if (message.msgContentType == DDMessageTypeText ) {
  508. cell = [self p_textCell_tableView:tableView cellForRowAtIndexPath:indexPath message:message];
  509. }else if (message.msgContentType == DDMessageTypeVoice || message.msgContentType==DDGroup_MessageTypeVoice)
  510. {
  511. cell = [self p_voiceCell_tableView:tableView cellForRowAtIndexPath:indexPath message:message];
  512. }
  513. else if(message.msgContentType == DDMessageTypeImage)
  514. {
  515. cell = [self p_imageCell_tableView:tableView cellForRowAtIndexPath:indexPath message:message];
  516. }
  517. else
  518. {
  519. cell = [self p_textCell_tableView:tableView cellForRowAtIndexPath:indexPath message:message];
  520. }
  521. }
  522. else if ([object isKindOfClass:[DDPromptEntity class]])
  523. {
  524. DDPromptEntity* prompt = (DDPromptEntity*)object;
  525. cell = [self p_promptCell_tableView:tableView cellForRowAtIndexPath:indexPath message:prompt];
  526. }
  527. return cell;
  528. }
  529. - (void)scrollViewDidScroll:(UIScrollView *)scrollView
  530. {
  531. static BOOL loadingHistory = NO;
  532. if (scrollView.contentOffset.y < -100 && [self.module.showingMessages count] > 0 && !loadingHistory)
  533. {
  534. loadingHistory = YES;
  535. [self.activity startAnimating];
  536. NSString* sessionID = self.module.sessionEntity.sessionID;
  537. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  538. [self.module loadMoreHistoryCompletion:^(NSUInteger addCount,NSError *error) {
  539. loadingHistory = NO;
  540. if ([sessionID isEqualToString:self.module.sessionEntity.sessionID])
  541. {
  542. dispatch_async(dispatch_get_main_queue(), ^{
  543. [_tableView reloadData];
  544. });
  545. [self.activity stopAnimating];
  546. if ([self.module.showingMessages count] > addCount)
  547. {
  548. dispatch_async(dispatch_get_main_queue(), ^{
  549. [_tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:addCount inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:NO];
  550. });
  551. }
  552. }
  553. }];
  554. });
  555. }
  556. }
  557. #pragma mark PublicAPI
  558. - (void)showChattingContentForSession:(DDSessionEntity*)session
  559. {
  560. [self.module.showingMessages removeAllObjects];
  561. self.module.sessionEntity = nil;
  562. [self p_unableChatFunction];
  563. [self p_enableChatFunction];
  564. [self.module.showingMessages removeAllObjects];
  565. self.module.sessionEntity = session;
  566. [self setThisViewTitle:session.name];
  567. NSArray* unreadMessages = [[DDMessageModule shareInstance]popAllUnreadMessagesForSessionID:session.sessionID];
  568. [self.module.showingMessages addObjectsFromArray:unreadMessages];
  569. [self.module loadMoreHistoryCompletion:^(NSUInteger addCount,NSError *error) {
  570. [_tableView reloadData];
  571. if (addCount < DD_PAGE_ITEM_COUNT)
  572. {
  573. [self.activity stopAnimating];
  574. }
  575. [self scrollToBottomAnimated:NO];
  576. }];
  577. }
  578. #pragma mark - Text view delegatef
  579. - (void)viewheightChanged:(float)height
  580. {
  581. [self setValue:@(self.chatInputView.origin.y) forKeyPath:@"_inputViewY"];
  582. }
  583. #pragma mark PrivateAPI
  584. - (UITableViewCell*)p_textCell_tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath message:(DDMessageEntity*)message
  585. {
  586. static NSString* identifier = @"DDChatTextCellIdentifier";
  587. DDChatBaseCell* cell = (DDChatBaseCell*)[tableView dequeueReusableCellWithIdentifier:identifier];
  588. if (!cell)
  589. {
  590. cell = [[DDChatTextCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
  591. }
  592. NSString* myUserID = [RuntimeStatus instance].user.objID;
  593. if ([message.senderId isEqualToString:myUserID])
  594. {
  595. [cell setLocation:DDBubbleRight];
  596. }
  597. else
  598. {
  599. [cell setLocation:DDBubbleLeft];
  600. }
  601. if (![[UnAckMessageManager instance] isInUnAckQueue:message] && message.state == DDMessageSending && [message isSendBySelf]) {
  602. message.state=DDMessageSendFailure;
  603. }
  604. [[DDDatabaseUtil instance] updateMessageForMessage:message completion:^(BOOL result) {
  605. }];
  606. [cell setContent:message];
  607. __weak DDChatTextCell* weakCell = (DDChatTextCell*)cell;
  608. cell.sendAgain = ^{
  609. [weakCell showSending];
  610. [weakCell sendTextAgain:message];
  611. };
  612. return cell;
  613. }
  614. - (UITableViewCell*)p_voiceCell_tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath message:(DDMessageEntity*)message
  615. {
  616. static NSString* identifier = @"DDVoiceCellIdentifier";
  617. DDChatBaseCell* cell = (DDChatBaseCell*)[tableView dequeueReusableCellWithIdentifier:identifier];
  618. if (!cell)
  619. {
  620. cell = [[DDChatVoiceCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
  621. }
  622. NSString* myUserID = [RuntimeStatus instance].user.objID;
  623. if ([message.senderId isEqualToString:myUserID])
  624. {
  625. [cell setLocation:DDBubbleRight];
  626. }
  627. else
  628. {
  629. [cell setLocation:DDBubbleLeft];
  630. }
  631. [cell setContent:message];
  632. __weak DDChatVoiceCell* weakCell = (DDChatVoiceCell*)cell;
  633. [(DDChatVoiceCell*)cell setTapInBubble:^{
  634. //播放语音
  635. NSString* fileName = message.msgContent;
  636. [[PlayerManager sharedManager] playAudioWithFileName:fileName delegate:self];
  637. [message.info setObject:@(1) forKey:DDVOICE_PLAYED];
  638. [weakCell showVoicePlayed];
  639. [[DDDatabaseUtil instance] updateMessageForMessage:message completion:^(BOOL result) {
  640. }];
  641. }];
  642. [(DDChatVoiceCell*)cell setEarphonePlay:^{
  643. //听筒播放
  644. NSString* fileName = message.msgContent;
  645. [[PlayerManager sharedManager] playAudioWithFileName:fileName playerType:DDEarPhone delegate:self];
  646. [message.info setObject:@(1) forKey:DDVOICE_PLAYED];
  647. [weakCell showVoicePlayed];
  648. [[DDDatabaseUtil instance] updateMessageForMessage:message completion:^(BOOL result) {
  649. }];
  650. }];
  651. [(DDChatVoiceCell*)cell setSpeakerPlay:^{
  652. //扬声器播放
  653. NSString* fileName = message.msgContent;
  654. [[PlayerManager sharedManager] playAudioWithFileName:fileName playerType:DDSpeaker delegate:self];
  655. [message.info setObject:@(1) forKey:DDVOICE_PLAYED];
  656. [weakCell showVoicePlayed];
  657. [[DDDatabaseUtil instance] updateMessageForMessage:message completion:^(BOOL result) {
  658. }];
  659. }];
  660. [(DDChatVoiceCell *)cell setSendAgain:^{
  661. //重发
  662. [weakCell showSending];
  663. [weakCell sendVoiceAgain:message];
  664. }];
  665. return cell;
  666. }
  667. - (UITableViewCell*)p_promptCell_tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath message:(DDPromptEntity*)prompt
  668. {
  669. static NSString* identifier = @"DDPromptCellIdentifier";
  670. DDPromptCell* cell = (DDPromptCell*)[tableView dequeueReusableCellWithIdentifier:identifier];
  671. if (!cell)
  672. {
  673. cell = [[DDPromptCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
  674. }
  675. NSString* promptMessage = prompt.message;
  676. [cell setprompt:promptMessage];
  677. return cell;
  678. }
  679. - (UITableViewCell*)p_imageCell_tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath message:(DDMessageEntity*)message
  680. {
  681. static NSString* identifier = @"DDImageCellIdentifier";
  682. DDChatImageCell* cell = (DDChatImageCell*)[tableView dequeueReusableCellWithIdentifier:identifier];
  683. if (!cell)
  684. {
  685. cell = [[DDChatImageCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
  686. }
  687. NSString* myUserID =[RuntimeStatus instance].user.objID;
  688. if ([message.senderId isEqualToString:myUserID])
  689. {
  690. [cell setLocation:DDBubbleRight];
  691. }
  692. else
  693. {
  694. [cell setLocation:DDBubbleLeft];
  695. }
  696. [cell setContent:message];
  697. __weak DDChatImageCell* weakCell = cell;
  698. [cell setSendAgain:^{
  699. [weakCell sendImageAgain:message];
  700. }];
  701. [cell setTapInBubble:^{
  702. [weakCell showPreview];
  703. }];
  704. [cell setPreview:cell.tapInBubble];
  705. return cell;
  706. }
  707. - (void)n_receiveStartLoginNotification:(NSNotification*)notification
  708. {
  709. [self setThisViewTitle:@"正在连接..."];
  710. }
  711. - (void)n_receiveLoginSuccessNotification:(NSNotification*)notification
  712. {
  713. if (self.module.sessionEntity)
  714. [self setThisViewTitle:self.module.sessionEntity.name];
  715. }
  716. - (void)n_receiveLoginFailureNotification:(NSNotification*)notification
  717. {
  718. [self setThisViewTitle:@"未连接"];
  719. }
  720. - (void)n_receiveUserKickoffNotification:(NSNotification*)notification
  721. {
  722. if ([self.navigationController.topViewController isEqual:self])
  723. {
  724. UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:@"您的帐号在别处登录" delegate:self cancelButtonTitle:nil otherButtonTitles:@"重连", nil];
  725. [alert show];
  726. }
  727. }
  728. - (void)p_clickThRecordButton:(UIButton*)button
  729. {
  730. switch (button.tag) {
  731. case DDVoiceInput:
  732. //开始录音
  733. [self p_hideBottomComponent];
  734. [button setImage:[UIImage imageNamed:@"dd_input_normal"] forState:UIControlStateNormal];
  735. button.tag = DDTextInput;
  736. [self.chatInputView willBeginRecord];
  737. [self.chatInputView.textView resignFirstResponder];
  738. _currentInputContent = self.chatInputView.textView.text;
  739. if ([_currentInputContent length] > 0)
  740. {
  741. [self.chatInputView.textView setText:nil];
  742. }
  743. break;
  744. case DDTextInput:
  745. //开始输入文字
  746. [button setImage:[UIImage imageNamed:@"dd_record_normal"] forState:UIControlStateNormal];
  747. button.tag = DDVoiceInput;
  748. [self.chatInputView willBeginInput];
  749. if ([_currentInputContent length] > 0)
  750. {
  751. [self.chatInputView.textView setText:_currentInputContent];
  752. }
  753. [self.chatInputView.textView becomeFirstResponder];
  754. break;
  755. }
  756. }
  757. - (void)p_record:(UIButton*)button
  758. {
  759. [self.chatInputView.recordButton setHighlighted:YES];
  760. if (![[self.view subviews] containsObject:_recordingView])
  761. {
  762. [self.view addSubview:_recordingView];
  763. }
  764. [_recordingView setHidden:NO];
  765. [_recordingView setRecordingState:DDShowVolumnState];
  766. [[RecorderManager sharedManager] setDelegate:self];
  767. [[RecorderManager sharedManager] startRecording];
  768. DDLog(@"record");
  769. }
  770. - (void)p_willCancelRecord:(UIButton*)button
  771. {
  772. [_recordingView setHidden:NO];
  773. [_recordingView setRecordingState:DDShowCancelSendState];
  774. DDLog(@"will cancel record");
  775. }
  776. - (void)p_cancelRecord:(UIButton*)button
  777. {
  778. [self.chatInputView.recordButton setHighlighted:NO];
  779. [_recordingView setHidden:YES];
  780. [[RecorderManager sharedManager] cancelRecording];
  781. DDLog(@"cancel record");
  782. }
  783. - (void)p_sendRecord:(UIButton*)button
  784. {
  785. [self.chatInputView.recordButton setHighlighted:NO];
  786. [[RecorderManager sharedManager] stopRecording];
  787. DDLog(@"send record");
  788. }
  789. - (void)p_endCancelRecord:(UIButton*)button
  790. {
  791. [_recordingView setHidden:NO];
  792. [_recordingView setRecordingState:DDShowVolumnState];
  793. }
  794. - (void)p_tapOnTableView:(UIGestureRecognizer*)sender
  795. {
  796. if (_bottomShowComponent)
  797. {
  798. [self p_hideBottomComponent];
  799. }
  800. }
  801. - (void)p_hideBottomComponent
  802. {
  803. _bottomShowComponent = _bottomShowComponent & 0;
  804. //隐藏所有
  805. [self.chatInputView.textView resignFirstResponder];
  806. [UIView animateWithDuration:0.25 animations:^{
  807. [self.ddUtility.view setFrame:DDCOMPONENT_BOTTOM];
  808. [self.emotions.view setFrame:DDCOMPONENT_BOTTOM];
  809. [self.chatInputView setFrame:DDINPUT_BOTTOM_FRAME];
  810. }];
  811. [self setValue:@(self.chatInputView.origin.y) forKeyPath:@"_inputViewY"];
  812. }
  813. - (void)p_enableChatFunction
  814. {
  815. [self.chatInputView setUserInteractionEnabled:YES];
  816. }
  817. - (void)p_unableChatFunction
  818. {
  819. [self.chatInputView setUserInteractionEnabled:NO];
  820. }
  821. - (void)p_popViewController
  822. {
  823. [self.navigationController popViewControllerAnimated:YES];
  824. }
  825. #pragma mark -
  826. #pragma mark DDEmotionViewCOntroller Delegate
  827. - (void)emotionViewClickSendButton
  828. {
  829. [self textViewEnterSend];
  830. }
  831. - (void)recordingTimeout
  832. {
  833. }
  834. - (void)recordingStopped //录音机停止采集声音
  835. {
  836. }
  837. - (void)recordingFailed:(NSString *)failureInfoString
  838. {
  839. }
  840. - (void)levelMeterChanged:(float)levelMeter
  841. {
  842. [_recordingView setVolume:levelMeter];
  843. }
  844. #pragma mark -
  845. #pragma mark - KVO
  846. - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
  847. {
  848. if ([keyPath isEqualToString:@"sessionEntity.sessionID"]) {
  849. if ([change objectForKey:@"new"] !=nil) {
  850. [self setThisViewTitle:self.module.sessionEntity.name];
  851. }
  852. }
  853. if ([keyPath isEqualToString:@"showingMessages"]) {
  854. dispatch_async(dispatch_get_main_queue(), ^{
  855. [self.tableView reloadData];
  856. });
  857. }
  858. if ([keyPath isEqualToString:@"_inputViewY"])
  859. {
  860. float maxY = FULL_HEIGHT - DDINPUT_MIN_HEIGHT;
  861. float gap = maxY - _inputViewY;
  862. // [self p_unableLoadFunction];
  863. [UIView animateWithDuration:0.25 animations:^{
  864. _tableView.contentInset = UIEdgeInsetsMake(_tableView.contentInset.top, 0, gap, 0);
  865. _tableView.scrollIndicatorInsets = UIEdgeInsetsMake(0, 0, gap, 0);
  866. if (_bottomShowComponent & DDShowEmotion)
  867. {
  868. [self.emotions.view setTop:self.chatInputView.bottom];
  869. }
  870. if (_bottomShowComponent & DDShowUtility)
  871. {
  872. [self.ddUtility.view setTop:self.chatInputView.bottom];
  873. }
  874. } completion:^(BOOL finished) {
  875. // [self p_enableLoadFunction];
  876. }];
  877. if (gap != 0)
  878. {
  879. [self scrollToBottomAnimated:YES];
  880. }
  881. }
  882. }
  883. @end
  884. @implementation ChattingMainViewController(ChattingInput)
  885. - (void)initialInput
  886. {
  887. CGRect inputFrame = CGRectMake(0, CONTENT_HEIGHT - DDINPUT_MIN_HEIGHT + NAVBAR_HEIGHT,FULL_WIDTH,DDINPUT_MIN_HEIGHT);
  888. self.chatInputView = [[JSMessageInputView alloc] initWithFrame:inputFrame delegate:self];
  889. [self.chatInputView setBackgroundColor:RGB(249, 249, 249)];
  890. [self.view addSubview:self.chatInputView];
  891. [self.chatInputView.emotionbutton addTarget:self
  892. action:@selector(showEmotions:)
  893. forControlEvents:UIControlEventTouchUpInside];
  894. [self.chatInputView.showUtilitysbutton addTarget:self
  895. action:@selector(showUtilitys:)
  896. forControlEvents:UIControlEventTouchDown];
  897. [self.chatInputView.voiceButton addTarget:self
  898. action:@selector(p_clickThRecordButton:)
  899. forControlEvents:UIControlEventTouchUpInside];
  900. _touchDownGestureRecognizer = [[TouchDownGestureRecognizer alloc] initWithTarget:self action:nil];
  901. __weak ChattingMainViewController* weakSelf = self;
  902. _touchDownGestureRecognizer.touchDown = ^{
  903. [weakSelf p_record:nil];
  904. };
  905. _touchDownGestureRecognizer.moveInside = ^{
  906. [weakSelf p_endCancelRecord:nil];
  907. };
  908. _touchDownGestureRecognizer.moveOutside = ^{
  909. [weakSelf p_willCancelRecord:nil];
  910. };
  911. _touchDownGestureRecognizer.touchEnd = ^(BOOL inside){
  912. if (inside)
  913. {
  914. [weakSelf p_sendRecord:nil];
  915. }
  916. else
  917. {
  918. [weakSelf p_cancelRecord:nil];
  919. }
  920. };
  921. [self.chatInputView.recordButton addGestureRecognizer:_touchDownGestureRecognizer];
  922. _recordingView = [[RecordingView alloc] initWithState:DDShowVolumnState];
  923. [_recordingView setHidden:YES];
  924. [_recordingView setCenter:CGPointMake(self.view.centerX, self.view.centerY)];
  925. [self addObserver:self forKeyPath:@"_inputViewY" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:nil];
  926. }
  927. -(IBAction)showUtilitys:(id)sender
  928. {
  929. [_recordButton setImage:[UIImage imageNamed:@"dd_record_normal"] forState:UIControlStateNormal];
  930. _recordButton.tag = DDVoiceInput;
  931. [self.chatInputView willBeginInput];
  932. if ([_currentInputContent length] > 0)
  933. {
  934. [self.chatInputView.textView setText:_currentInputContent];
  935. }
  936. if (self.ddUtility == nil)
  937. {
  938. self.ddUtility = [ChatUtilityViewController new];
  939. [self addChildViewController:self.ddUtility];
  940. self.ddUtility.view.frame=CGRectMake(0, self.view.size.height,320 , 280);
  941. [self.view addSubview:self.ddUtility.view];
  942. }
  943. if (_bottomShowComponent & DDShowKeyboard)
  944. {
  945. //显示的是键盘,这是需要隐藏键盘,显示插件,不需要动画
  946. _bottomShowComponent = (_bottomShowComponent & 0) | DDShowUtility;
  947. [self.chatInputView.textView resignFirstResponder];
  948. [self.ddUtility.view setFrame:DDUTILITY_FRAME];
  949. [self.emotions.view setFrame:DDCOMPONENT_BOTTOM];
  950. }
  951. else if (_bottomShowComponent & DDShowUtility)
  952. {
  953. //插件面板本来就是显示的,这时需要隐藏所有底部界面
  954. // [self p_hideBottomComponent];
  955. [self.chatInputView.textView becomeFirstResponder];
  956. _bottomShowComponent = _bottomShowComponent & DDHideUtility;
  957. }
  958. else if (_bottomShowComponent & DDShowEmotion)
  959. {
  960. //显示的是表情,这时需要隐藏表情,显示插件
  961. [self.emotions.view setFrame:DDCOMPONENT_BOTTOM];
  962. [self.ddUtility.view setFrame:DDUTILITY_FRAME];
  963. _bottomShowComponent = (_bottomShowComponent & DDHideEmotion) | DDShowUtility;
  964. }
  965. else
  966. {
  967. //这是什么都没有显示,需用动画显示插件
  968. _bottomShowComponent = _bottomShowComponent | DDShowUtility;
  969. [UIView animateWithDuration:0.25 animations:^{
  970. [self.ddUtility.view setFrame:DDUTILITY_FRAME];
  971. [self.chatInputView setFrame:DDINPUT_TOP_FRAME];
  972. }];
  973. [self setValue:@(DDINPUT_TOP_FRAME.origin.y) forKeyPath:@"_inputViewY"];
  974. }
  975. }
  976. -(IBAction)showEmotions:(id)sender
  977. {
  978. [_recordButton setImage:[UIImage imageNamed:@"dd_record_normal"] forState:UIControlStateNormal];
  979. _recordButton.tag = DDVoiceInput;
  980. [self.chatInputView willBeginInput];
  981. if ([_currentInputContent length] > 0)
  982. {
  983. [self.chatInputView.textView setText:_currentInputContent];
  984. }
  985. if (self.emotions == nil) {
  986. self.emotions = [EmotionsViewController new];
  987. [self.emotions.view setBackgroundColor:[UIColor darkGrayColor]];
  988. self.emotions.view.frame=DDCOMPONENT_BOTTOM;
  989. self.emotions.delegate = self;
  990. [self.view addSubview:self.emotions.view];
  991. }
  992. if (_bottomShowComponent & DDShowKeyboard)
  993. {
  994. //显示的是键盘,这是需要隐藏键盘,显示表情,不需要动画
  995. _bottomShowComponent = (_bottomShowComponent & 0) | DDShowEmotion;
  996. [self.chatInputView.textView resignFirstResponder];
  997. [self.emotions.view setFrame:DDEMOTION_FRAME];
  998. [self.ddUtility.view setFrame:DDCOMPONENT_BOTTOM];
  999. }
  1000. else if (_bottomShowComponent & DDShowEmotion)
  1001. {
  1002. //表情面板本来就是显示的,这时需要隐藏所有底部界面
  1003. [self.chatInputView.textView resignFirstResponder];
  1004. _bottomShowComponent = _bottomShowComponent & DDHideEmotion;
  1005. }
  1006. else if (_bottomShowComponent & DDShowUtility)
  1007. {
  1008. //显示的是插件,这时需要隐藏插件,显示表情
  1009. [self.ddUtility.view setFrame:DDCOMPONENT_BOTTOM];
  1010. [self.emotions.view setFrame:DDEMOTION_FRAME];
  1011. _bottomShowComponent = (_bottomShowComponent & DDHideUtility) | DDShowEmotion;
  1012. }
  1013. else
  1014. {
  1015. //这是什么都没有显示,需用动画显示表情
  1016. _bottomShowComponent = _bottomShowComponent | DDShowEmotion;
  1017. [UIView animateWithDuration:0.25 animations:^{
  1018. [self.emotions.view setFrame:DDEMOTION_FRAME];
  1019. [self.chatInputView setFrame:DDINPUT_TOP_FRAME];
  1020. }];
  1021. [self setValue:@(DDINPUT_TOP_FRAME.origin.y) forKeyPath:@"_inputViewY"];
  1022. }
  1023. }
  1024. #pragma mark - KeyBoardNotification
  1025. - (void)handleWillShowKeyboard:(NSNotification *)notification
  1026. {
  1027. CGRect keyboardRect;
  1028. keyboardRect = [(notification.userInfo)[UIKeyboardFrameEndUserInfoKey] CGRectValue];
  1029. keyboardRect = [self.view convertRect:keyboardRect fromView:nil];
  1030. _bottomShowComponent = _bottomShowComponent | DDShowKeyboard;
  1031. //什么都没有显示
  1032. [UIView animateWithDuration:0.25 animations:^{
  1033. [self.chatInputView setFrame:CGRectMake(0, keyboardRect.origin.y - DDINPUT_HEIGHT, self.view.size.width, DDINPUT_HEIGHT)];
  1034. }];
  1035. [self setValue:@(keyboardRect.origin.y - DDINPUT_HEIGHT) forKeyPath:@"_inputViewY"];
  1036. }
  1037. - (void)handleWillHideKeyboard:(NSNotification *)notification
  1038. {
  1039. CGRect keyboardRect;
  1040. keyboardRect = [notification.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
  1041. keyboardRect = [self.view convertRect:keyboardRect fromView:nil];
  1042. _bottomShowComponent = _bottomShowComponent & DDHideKeyboard;
  1043. if (_bottomShowComponent & DDShowUtility)
  1044. {
  1045. //显示的是插件
  1046. [UIView animateWithDuration:0.25 animations:^{
  1047. [self.chatInputView setFrame:DDINPUT_TOP_FRAME];
  1048. }];
  1049. [self setValue:@(self.chatInputView.origin.y) forKeyPath:@"_inputViewY"];
  1050. }
  1051. else if (_bottomShowComponent & DDShowEmotion)
  1052. {
  1053. //显示的是表情
  1054. [UIView animateWithDuration:0.25 animations:^{
  1055. [self.chatInputView setFrame:DDINPUT_TOP_FRAME];
  1056. }];
  1057. [self setValue:@(self.chatInputView.origin.y) forKeyPath:@"_inputViewY"];
  1058. }
  1059. else
  1060. {
  1061. [self p_hideBottomComponent];
  1062. }
  1063. }
  1064. -(IBAction)titleTap:(id)sender
  1065. {
  1066. if ([self.module.sessionEntity isGroup]) {
  1067. return;
  1068. }
  1069. [self.module getCurrentUser:^(DDUserEntity *user) {
  1070. PublicProfileViewControll *profile = [PublicProfileViewControll new];
  1071. profile.title=user.nick;
  1072. profile.user=user;
  1073. [self.navigationController pushViewController:profile animated:YES];
  1074. }];
  1075. }
  1076. - (void)n_receiveUnreadMessageUpdateNotification:(NSNotification*)notification
  1077. {
  1078. DDLog(@"read message from chattmainview");
  1079. if (![self.navigationController.topViewController isEqual:self])
  1080. {
  1081. //当前不是聊天界面直接返回
  1082. return;
  1083. }
  1084. NSString *senderID = [notification object];
  1085. NSString *newID = [senderID componentsSeparatedByString:@"_"][1];
  1086. if (![newID isEqualToString:self.module.sessionEntity.sessionID]) {
  1087. return;
  1088. }
  1089. NSArray* unreadMessages = [[DDMessageModule shareInstance]popAllUnreadMessagesForSessionID:newID];
  1090. [self.module addShowMessages:unreadMessages];
  1091. [_tableView reloadData];
  1092. [self scrollToBottomAnimated:NO];
  1093. }
  1094. - (void)n_receiveMessage:(NSNotification*)notification
  1095. {
  1096. if (![self.navigationController.topViewController isEqual:self])
  1097. {
  1098. //当前不是聊天界面直接返回
  1099. return;
  1100. }
  1101. DDMessageEntity* message = [notification object];
  1102. //显示消息
  1103. [[DDSundriesCenter instance] pushTaskToParallelQueue:^{
  1104. if([message.sessionId isEqualToString:self.module.sessionEntity.sessionID])
  1105. {
  1106. [self.module addShowMessage:message];
  1107. [self.module updateSessionUpdateTime:message.msgTime];
  1108. [[DDMessageModule shareInstance] clearUnreadMessagesForSessionID:self.module.sessionEntity.sessionID];
  1109. dispatch_async(dispatch_get_main_queue(), ^{
  1110. [self scrollToBottomAnimated:YES];
  1111. [self.tableView reloadData];
  1112. });
  1113. }
  1114. }];
  1115. }
  1116. @end