MessageViewController.m 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488
  1. //
  2. // MessageViewController.m
  3. // 千模
  4. //
  5. // Created by MUMEI on 2018/6/28.
  6. // Copyright © 2018年 MUMEI. All rights reserved.
  7. //
  8. #import "MessageViewController.h"
  9. #import "NTESSessionConfig.h"
  10. #import "NTESVideoChatViewController.h"
  11. #import "NTESVideoViewController.h"
  12. #import "NTESNetChatViewController.h"
  13. #import "NTESGalleryViewController.h"
  14. #import "NIMMessageMaker.h"
  15. #import "NIMKitLocationPoint.h"
  16. #import "NIMLocationViewController.h"
  17. NSString *const NIMDemoEventNameOpenSnapPicture = @"NIMDemoEventNameOpenSnapPicture";
  18. NSString *const NIMDemoEventNameCloseSnapPicture = @"NIMDemoEventNameCloseSnapPicture";
  19. @interface MessageViewController ()<NIMMessageObject>
  20. @property (nonatomic,strong) NTESSessionConfig *sessionConfig;
  21. @property (nonatomic,strong) UIView * bgblackView;//黑色背景
  22. @property (nonatomic,strong) UIView * bgwhiteView;//下拉选项背景
  23. @end
  24. @implementation MessageViewController
  25. - (void)viewDidLoad {
  26. [super viewDidLoad];
  27. self.extendedLayoutIncludesOpaqueBars = YES;
  28. // [self setupNav];
  29. }
  30. - (void)setupNav{
  31. [super setUpTitleView];
  32. if ([UIScreen spt_currentScreenMode]== LESScreenModeIPhoneX){
  33. self.view.frame = CGRectMake(0, 0, ScreenWidth, ScreenHeight+34);
  34. }
  35. UIButton * btn = [UIButton buttonWithType:UIButtonTypeCustom];
  36. btn.frame = CGRectMake(0, 0, 40, 40);
  37. [btn setImage:[UIImage imageNamed:@"fanhui2"] forState:UIControlStateNormal];
  38. btn.imageEdgeInsets = UIEdgeInsetsMake(0, -20, 0, 0);
  39. [btn addTarget:self action:@selector(backClick) forControlEvents:UIControlEventTouchUpInside];
  40. UIBarButtonItem *leftItem = [[UIBarButtonItem alloc] initWithCustomView:btn];
  41. UIBarButtonItem *nagetiveSpacer = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
  42. nagetiveSpacer.width = -12;//这个值可以根据自己需要自己调整
  43. self.navigationItem.leftBarButtonItems = @[nagetiveSpacer, leftItem];
  44. UIButton *rightBtn = [UIButton buttonWithType:UIButtonTypeCustom];
  45. rightBtn.frame = CGRectMake(0, 0, 40, 40);
  46. [rightBtn setImage:[UIImage imageNamed:@"more"] forState:UIControlStateNormal];
  47. rightBtn.imageEdgeInsets = UIEdgeInsetsMake(0, 0, 0, -20);
  48. [rightBtn addTarget:self action:@selector(rightBtnClick) forControlEvents:UIControlEventTouchUpInside];
  49. UIBarButtonItem *rightItem = [[UIBarButtonItem alloc] initWithCustomView:rightBtn];
  50. UIBarButtonItem *nagetiveRightSpacer = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
  51. // nagetiveSpacer.width = -12;//这个值可以根据自己需要自己调整
  52. self.navigationItem.rightBarButtonItems = @[rightItem, nagetiveRightSpacer];
  53. }
  54. - (void)viewWillAppear:(BOOL)animated{
  55. self.tabBarController.tabBar.hidden = YES;
  56. }
  57. - (void)viewWillDisappear:(BOOL)animated{
  58. self.tabBarController.tabBar.hidden = NO;
  59. }
  60. - (void)viewDidLayoutSubviews {
  61. [super viewDidLayoutSubviews];
  62. if ([@"system" isEqualToString:self.session.sessionId]) {
  63. self.sessionInputView.hidden = YES;
  64. [self.tableView setFrame: CGRectMake(0, self.navigationController.navigationBar.frame.size.height, ScreenWidth, self.view.frame.size.height - self.navigationController.navigationBar.frame.size.height)];
  65. }
  66. }
  67. -(void)rightBtnClick{
  68. if (!_bgblackView) {
  69. _bgblackView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, ScreenWidth, ScreenHeight)];
  70. _bgblackView.backgroundColor = RGBA(0, 0, 0, 0.6);
  71. _bgblackView.hidden = YES;
  72. UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(clickHiddenSiftView)];
  73. [_bgblackView addGestureRecognizer:tap];
  74. [self.view addSubview:_bgblackView];
  75. self.bgwhiteView = [[UIView alloc]initWithFrame:CGRectMake(ScreenWidth-100, -100, 100, 100)];
  76. self.bgwhiteView.backgroundColor = [UIColor whiteColor];
  77. self.bgwhiteView.layer.shadowColor = RGB(200, 200, 200).CGColor;
  78. self.bgwhiteView.layer.shadowOffset = CGSizeMake(0, 1);
  79. self.bgwhiteView.layer.shadowOpacity = 0.5;
  80. [_bgblackView addSubview:self.bgwhiteView];
  81. UIButton *reportButton = [[UIButton alloc]initWithFrame:CGRectMake(0, 0, 100, 50)];
  82. reportButton.backgroundColor = [UIColor whiteColor];
  83. [reportButton setImage:[UIImage imageNamed:@"report"] forState:UIControlStateNormal];
  84. [reportButton setTitle:@"举报" forState:UIControlStateNormal];
  85. [reportButton setTitleColor:RGB(51, 51, 51) forState:UIControlStateNormal];
  86. reportButton.titleLabel.font = [UIFont systemFontOfSize:14];
  87. reportButton.titleLabel.textAlignment = NSTextAlignmentLeft;
  88. [reportButton setImageEdgeInsets:UIEdgeInsetsMake(10, 10, 10, 60)];
  89. [reportButton setTitleEdgeInsets:UIEdgeInsetsMake(10, 10, 10, 10)];
  90. [reportButton addTarget:self action:@selector(clickReport) forControlEvents:UIControlEventTouchUpInside];
  91. [self.bgwhiteView addSubview:reportButton];
  92. UIButton *screenButton = [[UIButton alloc]initWithFrame:CGRectMake(0, 50, 100, 50)];
  93. screenButton.backgroundColor = [UIColor whiteColor];
  94. [screenButton setImage:[UIImage imageNamed:@"screen"] forState:UIControlStateNormal];
  95. [screenButton setTitle:@"屏蔽" forState:UIControlStateNormal];
  96. [screenButton setTitleColor:RGB(51, 51, 51) forState:UIControlStateNormal];
  97. screenButton.titleLabel.font = [UIFont systemFontOfSize:14];
  98. screenButton.titleLabel.textAlignment = NSTextAlignmentLeft;
  99. [screenButton setImageEdgeInsets:UIEdgeInsetsMake(10, 10, 10, 60)];
  100. [screenButton setTitleEdgeInsets:UIEdgeInsetsMake(10, 10, 10, 10)];
  101. [screenButton addTarget:self action:@selector(clickScreen) forControlEvents:UIControlEventTouchUpInside];
  102. [self.bgwhiteView addSubview:screenButton];
  103. UIView *line = [[UIView alloc]initWithFrame:CGRectMake(0, 50, 100, 0.5)];
  104. line.backgroundColor = RGB(151, 151, 151);
  105. [self.bgwhiteView addSubview:line];
  106. }
  107. _bgblackView.hidden = NO;
  108. [UIView animateWithDuration:0.25 animations:^{
  109. self.bgwhiteView.frame = CGRectMake(ScreenWidth-100, 64, 100, 100);
  110. } completion:^(BOOL finished) {
  111. }];
  112. }
  113. //点击隐藏
  114. -(void)clickHiddenSiftView{
  115. [UIView animateWithDuration:0.25 animations:^{
  116. self.bgwhiteView.frame = CGRectMake(ScreenWidth-100, -100, 100, 100);
  117. } completion:^(BOOL finished) {
  118. _bgblackView.hidden = YES;
  119. }];
  120. }
  121. //举报
  122. -(void)clickReport{
  123. UIAlertController *alertVc = [UIAlertController alertControllerWithTitle:nil message:@"是否确定举报该用户" preferredStyle:UIAlertControllerStyleAlert];
  124. UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil];
  125. UIAlertAction *sureAction = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
  126. [self postReport];
  127. }];
  128. [alertVc addAction:cancelAction];
  129. [alertVc addAction:sureAction];
  130. [self presentViewController:alertVc animated:YES completion:nil];
  131. [self clickHiddenSiftView];
  132. }
  133. - (void)postReport{
  134. NSString *str = [NSString stringWithFormat:@"%@/memberInfo?action=report&accuserpk=%@&appelleepk=%@&reason=%@",PublicUrl,[ModelUser user].pk,self.session.sessionId,@""];
  135. [[AHHttpManager sharedManager]POST:[str stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding] parameters:nil success:^(id responseObject) {
  136. if ([[responseObject objectForKey:@"msg"]isEqualToString:@"success"]) {
  137. UIAlertController *alertVc = [UIAlertController alertControllerWithTitle:nil message:@"举报成功,我们将会在24小时之内给出回复" preferredStyle:UIAlertControllerStyleAlert];
  138. UIAlertAction *sureAction = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
  139. }];
  140. [alertVc addAction:sureAction];
  141. [self presentViewController:alertVc animated:YES completion:nil];
  142. }else{
  143. [MBProgressHUD showTextHUD:@"超时" inView:self.view hideAfterDelay:1];
  144. }
  145. } failure:^(NSError *error) {
  146. NSLog(@"error = %@",error);
  147. [MBProgressHUD showTextHUD:@"超时" inView:self.view hideAfterDelay:1];
  148. }];
  149. }
  150. //屏蔽
  151. -(void)clickScreen{
  152. UIAlertController *alertVc = [UIAlertController alertControllerWithTitle:nil message:@"是否确定屏蔽该用户" preferredStyle:UIAlertControllerStyleAlert];
  153. UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil];
  154. UIAlertAction *sureAction = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
  155. [[NIMSDK sharedSDK].userManager addToBlackList:self.session.sessionId completion:^(NSError * _Nullable error) {
  156. if (!error) {
  157. [MBProgressHUD showTextHUD:@"已屏蔽该用户" inView:self.view hideAfterDelay:1];
  158. }
  159. }];
  160. }];
  161. [alertVc addAction:cancelAction];
  162. [alertVc addAction:sureAction];
  163. [self presentViewController:alertVc animated:YES completion:nil];
  164. [self clickHiddenSiftView];
  165. }
  166. //- (void)onSendText:(NSString *)text atUsers:(NSArray *)atUsers
  167. //{
  168. // NSMutableArray *users = [NSMutableArray arrayWithArray:atUsers];
  169. // if (self.session.sessionType == NIMSessionTypeP2P)
  170. // {
  171. // [users addObject:self.session.sessionId];
  172. // }
  173. //// NSString *robotsToSend = [self robotsToSend:users];
  174. ////
  175. // NIMMessage *message = nil;
  176. //// if (robotsToSend.length)
  177. //// {
  178. //// message = [NIMMessageMaker msgWithRobotQuery:text toRobot:robotsToSend];
  179. //// }
  180. //// else
  181. //// {
  182. //// message = [NIMMessageMaker msgWithText:text];
  183. //// }
  184. // message = [NIMMessageMaker msgWithText:text];
  185. //
  186. // if (atUsers.count)
  187. // {
  188. // NIMMessageApnsMemberOption *apnsOption = [[NIMMessageApnsMemberOption alloc] init];
  189. // apnsOption.userIds = atUsers;
  190. // apnsOption.forcePush = YES;
  191. //
  192. // NIMKitInfoFetchOption *option = [[NIMKitInfoFetchOption alloc] init];
  193. // option.session = self.session;
  194. //
  195. // NSString *me = [[NIMKit sharedKit].provider infoByUser:[NIMSDK sharedSDK].loginManager.currentAccount option:option].showName;
  196. // apnsOption.apnsContent = [NSString stringWithFormat:@"%@在群里@了你",me];
  197. // message.apnsMemberOption = apnsOption;
  198. // }
  199. //// message.apnsPayload = @{@"session":self.session.sessionId};
  200. // [self sendMessage:message];
  201. //}
  202. #pragma mark - Cell事件
  203. - (BOOL)onTapCell:(NIMKitEvent *)event
  204. {
  205. BOOL handled = [super onTapCell:event];
  206. NSString *eventName = event.eventName;
  207. if ([eventName isEqualToString:NIMKitEventNameTapContent])
  208. {
  209. NIMMessage *message = event.messageModel.message;
  210. NSDictionary *actions = [self cellActions];
  211. NSString *value = actions[@(message.messageType)];
  212. if (value) {
  213. SEL selector = NSSelectorFromString(value);
  214. if (selector && [self respondsToSelector:selector]) {
  215. SuppressPerformSelectorLeakWarning([self performSelector:selector withObject:message]);
  216. handled = YES;
  217. }
  218. }
  219. }
  220. else if([eventName isEqualToString:NIMKitEventNameTapLabelLink])
  221. {
  222. NSString *link = event.data;
  223. [self openSafari:link];
  224. handled = YES;
  225. }
  226. else if([eventName isEqualToString:NIMDemoEventNameOpenSnapPicture])
  227. {
  228. // NIMCustomObject *object = event.messageModel.message.messageObject;
  229. // NTESSnapchatAttachment *attachment = (NTESSnapchatAttachment *)object.attachment;
  230. // if(attachment.isFired){
  231. // return handled;
  232. // }
  233. // UIView *sender = event.data;
  234. // self.currentSingleSnapView = [NTESGalleryViewController alertSingleSnapViewWithMessage:object.message baseView:sender];
  235. // handled = YES;
  236. }
  237. else if([eventName isEqualToString:NIMDemoEventNameCloseSnapPicture])
  238. {
  239. // //点击很快的时候可能会触发两次查看,所以这里不管有没有查看过 先强直销毁掉
  240. // NIMCustomObject *object = event.messageModel.message.messageObject;
  241. // UIView *senderView = event.data;
  242. // [senderView dismissPresentedView:YES complete:nil];
  243. //
  244. // NTESSnapchatAttachment *attachment = (NTESSnapchatAttachment *)object.attachment;
  245. // if(attachment.isFired){
  246. // return handled;
  247. // }
  248. // attachment.isFired = YES;
  249. // NIMMessage *message = object.message;
  250. // if ([NTESBundleSetting sharedConfig].autoRemoveSnapMessage) {
  251. // [[NIMSDK sharedSDK].conversationManager deleteMessage:message];
  252. // [self uiDeleteMessage:message];
  253. // }else{
  254. // [[NIMSDK sharedSDK].conversationManager updateMessage:message forSession:message.session completion:nil];
  255. // [self uiUpdateMessage:message];
  256. // }
  257. // [[NSFileManager defaultManager] removeItemAtPath:attachment.filepath error:nil];
  258. // self.currentSingleSnapView = nil;
  259. // handled = YES;
  260. }
  261. else if([eventName isEqualToString:NIMKitEventNameTapRobotLink])
  262. {
  263. NSString *link = event.data;
  264. [self openSafari:link];
  265. handled = YES;
  266. }
  267. if (!handled) {
  268. NSAssert(0, @"invalid event");
  269. }
  270. return handled;
  271. }
  272. #pragma mark - Cell Actions
  273. - (void)showImage:(NIMMessage *)message
  274. {
  275. NIMImageObject *object = message.messageObject;
  276. NTESGalleryItem *item = [[NTESGalleryItem alloc] init];
  277. item.thumbPath = [object thumbPath];
  278. item.imageURL = [object url];
  279. item.name = [object displayName];
  280. item.itemId = [message messageId];
  281. item.size = [object size];
  282. NIMSession *session = [self isMemberOfClass:[MessageViewController class]]? self.session : nil;
  283. NTESGalleryViewController *vc = [[NTESGalleryViewController alloc] initWithItem:item session:session];
  284. [self.navigationController pushViewController:vc animated:YES];
  285. if(![[NSFileManager defaultManager] fileExistsAtPath:object.thumbPath]){
  286. //如果缩略图下跪了,点进看大图的时候再去下一把缩略图
  287. __weak typeof(self) wself = self;
  288. [[NIMSDK sharedSDK].resourceManager download:object.thumbUrl filepath:object.thumbPath progress:nil completion:^(NSError *error) {
  289. if (!error) {
  290. [wself uiUpdateMessage:message];
  291. }
  292. }];
  293. }
  294. }
  295. - (void)showVideo:(NIMMessage *)message
  296. {
  297. NIMVideoObject *object = message.messageObject;
  298. NIMSession *session = [self isMemberOfClass:[MessageViewController class]]? self.session : nil;
  299. NTESVideoViewItem *item = [[NTESVideoViewItem alloc] init];
  300. item.path = object.path;
  301. item.url = object.url;
  302. item.session = session;
  303. item.itemId = object.message.messageId;
  304. NTESVideoViewController *playerViewController = [[NTESVideoViewController alloc] initWithVideoViewItem:item];
  305. [self.navigationController pushViewController:playerViewController animated:YES];
  306. if(![[NSFileManager defaultManager] fileExistsAtPath:object.coverPath]){
  307. //如果封面图下跪了,点进视频的时候再去下一把封面图
  308. __weak typeof(self) wself = self;
  309. [[NIMSDK sharedSDK].resourceManager download:object.coverUrl filepath:object.coverPath progress:nil completion:^(NSError *error) {
  310. if (!error) {
  311. [wself uiUpdateMessage:message];
  312. }
  313. }];
  314. }
  315. }
  316. - (void)showLocation:(NIMMessage *)message
  317. {
  318. NIMLocationObject *object = message.messageObject;
  319. NIMKitLocationPoint *locationPoint = [[NIMKitLocationPoint alloc] initWithLocationObject:object];
  320. NIMLocationViewController *vc = [[NIMLocationViewController alloc] initWithLocationPoint:locationPoint];
  321. [self.navigationController pushViewController:vc animated:YES];
  322. }
  323. //- (void)showFile:(NIMMessage *)message
  324. //{
  325. // NIMFileObject *object = message.messageObject;
  326. // NTESFilePreViewController *vc = [[NTESFilePreViewController alloc] initWithFileObject:object];
  327. // [self.navigationController pushViewController:vc animated:YES];
  328. //}
  329. - (void)showCustom:(NIMMessage *)message
  330. {
  331. //普通的自定义消息点击事件可以在这里做哦~
  332. }
  333. - (void)openSafari:(NSString *)link
  334. {
  335. NSURLComponents *components = [[NSURLComponents alloc] initWithString:link];
  336. if (components)
  337. {
  338. if (!components.scheme)
  339. {
  340. //默认添加 http
  341. components.scheme = @"http";
  342. }
  343. [[UIApplication sharedApplication] openURL:[components URL]];
  344. }
  345. }
  346. - (NSDictionary *)cellActions
  347. {
  348. static NSDictionary *actions = nil;
  349. static dispatch_once_t onceToken;
  350. dispatch_once(&onceToken, ^{
  351. actions = @{@(NIMMessageTypeImage) : @"showImage:",
  352. @(NIMMessageTypeVideo) : @"showVideo:",
  353. @(NIMMessageTypeLocation) : @"showLocation:",
  354. @(NIMMessageTypeFile) : @"showFile:",
  355. @(NIMMessageTypeCustom): @"showCustom:"};
  356. });
  357. return actions;
  358. }
  359. -(void)backClick{
  360. [self.navigationController popViewControllerAnimated:YES];
  361. }
  362. - (id<NIMSessionConfig>)sessionConfig
  363. {
  364. if (_sessionConfig == nil) {
  365. _sessionConfig = [[NTESSessionConfig alloc] init];
  366. _sessionConfig.session = self.session;
  367. }
  368. return _sessionConfig;
  369. }
  370. - (BOOL)checkRTSCondition
  371. {
  372. BOOL result = YES;
  373. if (![[Reachability reachabilityForInternetConnection] isReachable])
  374. {
  375. [self.view makeToast:@"请检查网络" duration:2.0 position:CSToastPositionCenter];
  376. result = NO;
  377. }
  378. NSString *currentAccount = [[NIMSDK sharedSDK].loginManager currentAccount];
  379. if (self.session.sessionType == NIMSessionTypeP2P && [currentAccount isEqualToString:self.session.sessionId])
  380. {
  381. [self.view makeToast:@"不能和自己通话哦" duration:2.0 position:CSToastPositionCenter];
  382. result = NO;
  383. }
  384. if (self.session.sessionType == NIMSessionTypeTeam)
  385. {
  386. NIMTeam *team = [[NIMSDK sharedSDK].teamManager teamById:self.session.sessionId];
  387. NSInteger memberNumber = team.memberNumber;
  388. if (memberNumber < 2)
  389. {
  390. [self.view makeToast:@"无法发起,群人数少于2人" duration:2.0 position:CSToastPositionCenter];
  391. result = NO;
  392. }
  393. }
  394. return result;
  395. }
  396. #pragma mark - 视频聊天
  397. - (void)onTapMediaItemVideoChat:(NIMMediaItem *)item
  398. {
  399. if ([self checkRTSCondition]) {
  400. //由于音视频聊天里头有音频和视频聊天界面的切换,直接用present的话页面过渡会不太自然,这里还是用push,然后做出present的效果
  401. NTESVideoChatViewController *vc = [[NTESVideoChatViewController alloc] initWithCallee:self.session.sessionId];
  402. vc.hidesBottomBarWhenPushed = YES;
  403. CATransition *transition = [CATransition animation];
  404. transition.duration = 0.25;
  405. transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionDefault];
  406. transition.type = kCATransitionPush;
  407. transition.subtype = kCATransitionFromTop;
  408. [self.navigationController.view.layer addAnimation:transition forKey:nil];
  409. self.navigationController.navigationBarHidden = YES;
  410. [self.navigationController pushViewController:vc animated:NO];
  411. }
  412. }
  413. //- (void)viewWillAppear:(BOOL)animated{
  414. // self.tabBarController.tabBar.hidden = YES;
  415. //}
  416. //
  417. //- (void)viewWillDisappear:(BOOL)animated{
  418. // self.tabBarController.tabBar.hidden = NO;
  419. //}
  420. - (void)didReceiveMemoryWarning {
  421. [super didReceiveMemoryWarning];
  422. // Dispose of any resources that can be recreated.
  423. }
  424. @end