WFCUConversationTableViewController.m 43 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046
  1. //
  2. // ConversationTableViewController.m
  3. // WFChat UIKit
  4. //
  5. // Created by WF Chat on 2017/8/29.
  6. // Copyright © 2017年 WildFireChat. All rights reserved.
  7. //
  8. #import "WFCUConversationTableViewController.h"
  9. #import "WFCUConversationTableViewCell.h"
  10. #import "WFCUContactListViewController.h"
  11. #import "WFCUCreateGroupViewController.h"
  12. #import "WFCUFriendRequestViewController.h"
  13. #import "WFCUSearchGroupTableViewCell.h"
  14. #import "WFCUConversationSearchTableViewController.h"
  15. #import "WFCUSearchChannelViewController.h"
  16. #import "WFCUCreateChannelViewController.h"
  17. #import "WFCUMessageListViewController.h"
  18. #import <WFChatClient/WFCChatClient.h>
  19. #import "WFCUUtilities.h"
  20. #import "UITabBar+badge.h"
  21. #import "KxMenu.h"
  22. #import "UIImage+ERCategory.h"
  23. #import "MBProgressHUD.h"
  24. #import "WFCUContactTableViewCell.h"
  25. #import "QrCodeHelper.h"
  26. #import "WFCUConfigManager.h"
  27. #import "UIImage+ERCategory.h"
  28. #import "UIFont+YH.h"
  29. #import "UIColor+YH.h"
  30. #import "UIView+Toast.h"
  31. #import "WFCUSeletedUserViewController.h"
  32. @interface WFCUConversationTableViewController () <UISearchControllerDelegate, UISearchResultsUpdating, UITableViewDelegate, UITableViewDataSource>
  33. @property (nonatomic, strong)NSMutableArray<WFCCConversationInfo *> *conversations;
  34. @property (nonatomic, strong) UISearchController *searchController;
  35. @property (nonatomic, strong) NSArray<WFCCConversationSearchInfo *> *searchConversationList;
  36. @property (nonatomic, strong) NSArray<WFCCUserInfo *> *searchFriendList;
  37. @property (nonatomic, strong) NSArray<WFCCGroupSearchInfo *> *searchGroupList;
  38. @property (nonatomic ,assign) BOOL isSearchConversationListExpansion;
  39. @property (nonatomic ,assign) BOOL isSearchFriendListExpansion;
  40. @property (nonatomic ,assign) BOOL isSearchGroupListExpansion;
  41. @property (nonatomic, strong) UITableView *tableView;
  42. @property (nonatomic, strong) UIView *searchViewContainer;
  43. @property (nonatomic, assign) BOOL firstAppear;
  44. @property (nonatomic, strong) UIView *pcSessionView;
  45. @end
  46. @implementation WFCUConversationTableViewController
  47. - (void)initSearchUIAndTableView {
  48. _searchConversationList = [NSMutableArray array];
  49. self.searchController = [[UISearchController alloc] initWithSearchResultsController:nil];
  50. self.searchController.searchResultsUpdater = self;
  51. self.searchController.delegate = self;
  52. self.searchController.dimsBackgroundDuringPresentation = NO;
  53. if (@available(iOS 13, *)) {
  54. self.searchController.searchBar.searchBarStyle = UISearchBarStyleDefault;
  55. self.searchController.searchBar.searchTextField.backgroundColor = [WFCUConfigManager globalManager].naviBackgroudColor;
  56. UIImage* searchBarBg = [UIImage imageWithColor:[UIColor whiteColor] size:CGSizeMake(self.view.frame.size.width - 8 * 2, 36) cornerRadius:4];
  57. [self.searchController.searchBar setSearchFieldBackgroundImage:searchBarBg forState:UIControlStateNormal];
  58. } else {
  59. [self.searchController.searchBar setValue:WFCString(@"Cancel") forKey:@"_cancelButtonText"];
  60. }
  61. if (@available(iOS 9.1, *)) {
  62. self.searchController.obscuresBackgroundDuringPresentation = NO;
  63. }
  64. self.searchController.searchBar.placeholder = WFCString(@"Search");
  65. self.tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
  66. [self.view addSubview:self.tableView];
  67. self.tableView.delegate = self;
  68. self.tableView.dataSource = self;
  69. self.tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero];
  70. self.tableView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
  71. [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"expansion"];
  72. if (@available(iOS 11.0, *)) {
  73. self.navigationItem.searchController = _searchController;
  74. } else {
  75. self.tableView.tableHeaderView = _searchController.searchBar;
  76. }
  77. self.definesPresentationContext = YES;
  78. [self updatePcSession];
  79. self.view.backgroundColor = [WFCUConfigManager globalManager].backgroudColor;
  80. }
  81. - (void)onUserInfoUpdated:(NSNotification *)notification {
  82. if (self.searchController.active) {
  83. [self.tableView reloadData];
  84. } else {
  85. WFCCUserInfo *userInfo = notification.userInfo[@"userInfo"];
  86. NSArray *dataSource = self.conversations;
  87. for (int i = 0; i < dataSource.count; i++) {
  88. WFCCConversationInfo *conv = dataSource[i];
  89. if (conv.conversation.type == Single_Type && [conv.conversation.target isEqualToString:userInfo.userId]) {
  90. [self.tableView reloadRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:i inSection:0]] withRowAnimation:UITableViewRowAnimationFade];
  91. } else if ([conv.lastMessage.fromUser isEqualToString:userInfo.userId]) {
  92. [self.tableView reloadRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:i inSection:0]] withRowAnimation:UITableViewRowAnimationFade];
  93. }
  94. }
  95. }
  96. }
  97. - (void)onGroupInfoUpdated:(NSNotification *)notification {
  98. if (self.searchController.active) {
  99. [self.tableView reloadData];
  100. } else {
  101. WFCCGroupInfo *groupInfo = notification.userInfo[@"groupInfo"];
  102. NSArray *dataSource = self.conversations;
  103. for (int i = 0; i < dataSource.count; i++) {
  104. WFCCConversationInfo *conv = dataSource[i];
  105. if (conv.conversation.type == Group_Type && [conv.conversation.target isEqualToString:groupInfo.target]) {
  106. [self.tableView reloadRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:i inSection:0]] withRowAnimation:UITableViewRowAnimationFade];
  107. }
  108. }
  109. }
  110. }
  111. - (void)onChannelInfoUpdated:(NSNotification *)notification {
  112. if (self.searchController.active) {
  113. [self.tableView reloadData];
  114. } else {
  115. WFCCChannelInfo *channelInfo = notification.userInfo[@"groupInfo"];
  116. NSArray *dataSource = self.conversations;
  117. for (int i = 0; i < dataSource.count; i++) {
  118. WFCCConversationInfo *conv = dataSource[i];
  119. if (conv.conversation.type == Channel_Type && [conv.conversation.target isEqualToString:channelInfo.channelId]) {
  120. [self.tableView reloadRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:i inSection:0]] withRowAnimation:UITableViewRowAnimationFade];
  121. }
  122. }
  123. }
  124. }
  125. - (void)onSendingMessageStatusUpdated:(NSNotification *)notification {
  126. if (self.searchController.active) {
  127. [self.tableView reloadData];
  128. } else {
  129. long messageId = [notification.object longValue];
  130. NSArray *dataSource = self.conversations;
  131. if (messageId == 0) {
  132. return;
  133. }
  134. for (int i = 0; i < dataSource.count; i++) {
  135. WFCCConversationInfo *conv = dataSource[i];
  136. if (conv.lastMessage && conv.lastMessage.direction == MessageDirection_Send && conv.lastMessage.messageId == messageId) {
  137. conv.lastMessage = [[WFCCIMService sharedWFCIMService] getMessage:messageId];
  138. [self.tableView reloadRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:i inSection:0]] withRowAnimation:UITableViewRowAnimationFade];
  139. }
  140. }
  141. }
  142. }
  143. - (void)onRightBarBtn:(UIBarButtonItem *)sender {
  144. CGFloat searchExtra = 0;
  145. if ([KxMenu isShowing]) {
  146. [KxMenu dismissMenu];
  147. return;
  148. }
  149. [KxMenu showMenuInView:self.navigationController.view
  150. fromRect:CGRectMake(self.view.bounds.size.width - 56, kStatusBarAndNavigationBarHeight + searchExtra, 48, 5)
  151. menuItems:@[
  152. [KxMenuItem menuItem:WFCString(@"StartChat")
  153. image:[UIImage imageNamed:@"menu_start_chat"]
  154. target:self
  155. action:@selector(startChatAction:)],
  156. [KxMenuItem menuItem:WFCString(@"AddFriend")
  157. image:[UIImage imageNamed:@"menu_add_friends"]
  158. target:self
  159. action:@selector(addFriendsAction:)],
  160. [KxMenuItem menuItem:WFCString(@"SubscribeChannel")
  161. image:[UIImage imageNamed:@"menu_listen_channel"]
  162. target:self
  163. action:@selector(listenChannelAction:)],
  164. [KxMenuItem menuItem:WFCString(@"ScanQRCode")
  165. image:[UIImage imageNamed:@"menu_scan_qr"]
  166. target:self
  167. action:@selector(scanQrCodeAction:)]
  168. ]];
  169. }
  170. - (void)startChatAction:(id)sender {
  171. WFCUSeletedUserViewController *pvc = [[WFCUSeletedUserViewController alloc] init];
  172. pvc.type = Horizontal;
  173. UINavigationController *navi = [[UINavigationController alloc] initWithRootViewController:pvc];
  174. navi.modalPresentationStyle = UIModalPresentationFullScreen;
  175. __weak typeof(self)ws = self;
  176. pvc.selectResult = ^(NSArray<NSString *> *contacts) {
  177. [navi dismissViewControllerAnimated:NO completion:nil];
  178. if (contacts.count == 1) {
  179. WFCUMessageListViewController *mvc = [[WFCUMessageListViewController alloc] init];
  180. mvc.conversation = [WFCCConversation conversationWithType:Single_Type target:contacts[0] line:0];
  181. mvc.hidesBottomBarWhenPushed = YES;
  182. [ws.navigationController pushViewController:mvc animated:YES];
  183. } else {
  184. #if !WFCU_GROUP_GRID_PORTRAIT
  185. WFCUCreateGroupViewController *vc = [[WFCUCreateGroupViewController alloc] init];
  186. vc.memberIds = [contacts mutableCopy];
  187. if (![vc.memberIds containsObject:[WFCCNetworkService sharedInstance].userId]) {
  188. [vc.memberIds insertObject:[WFCCNetworkService sharedInstance].userId atIndex:0];
  189. }
  190. vc.hidesBottomBarWhenPushed = YES;
  191. [ws.navigationController pushViewController:vc animated:YES];
  192. #else
  193. [self createGroup:contacts];
  194. #endif
  195. }
  196. };
  197. [self.navigationController presentViewController:navi animated:YES completion:nil];
  198. }
  199. #if WFCU_GROUP_GRID_PORTRAIT
  200. - (void)createGroup:(NSArray<NSString *> *)contacts {
  201. __weak typeof(self) ws = self;
  202. NSMutableArray<NSString *> *memberIds = [contacts mutableCopy];
  203. if (![memberIds containsObject:[WFCCNetworkService sharedInstance].userId]) {
  204. [memberIds insertObject:[WFCCNetworkService sharedInstance].userId atIndex:0];
  205. }
  206. NSString *name;
  207. WFCCUserInfo *userInfo = [[WFCCIMService sharedWFCIMService] getUserInfo:[memberIds objectAtIndex:0] refresh:NO];
  208. name = userInfo.displayName;
  209. for (int i = 1; i < MIN(8, memberIds.count); i++) {
  210. userInfo = [[WFCCIMService sharedWFCIMService] getUserInfo:[memberIds objectAtIndex:i] refresh:NO];
  211. if (userInfo.displayName.length > 0) {
  212. if (name.length + userInfo.displayName.length + 1 > 16) {
  213. name = [name stringByAppendingString:WFCString(@"Etc")];
  214. break;
  215. }
  216. name = [name stringByAppendingFormat:@",%@", userInfo.displayName];
  217. }
  218. }
  219. if (name.length == 0) {
  220. name = WFCString(@"GroupChat");
  221. }
  222. [[WFCCIMService sharedWFCIMService] createGroup:nil name:name portrait:nil type:GroupType_Restricted members:memberIds notifyLines:@[@(0)] notifyContent:nil success:^(NSString *groupId) {
  223. NSLog(@"create group success");
  224. WFCUMessageListViewController *mvc = [[WFCUMessageListViewController alloc] init];
  225. mvc.conversation = [[WFCCConversation alloc] init];
  226. mvc.conversation.type = Group_Type;
  227. mvc.conversation.target = groupId;
  228. mvc.conversation.line = 0;
  229. mvc.hidesBottomBarWhenPushed = YES;
  230. [ws.navigationController pushViewController:mvc animated:YES];
  231. } error:^(int error_code) {
  232. NSLog(@"create group failure");
  233. [ws.view makeToast:WFCString(@"CreateGroupFailure")
  234. duration:2
  235. position:CSToastPositionCenter];
  236. }];
  237. }
  238. #endif
  239. - (void)addFriendsAction:(id)sender {
  240. UIViewController *addFriendVC = [[WFCUFriendRequestViewController alloc] init];
  241. addFriendVC.hidesBottomBarWhenPushed = YES;
  242. [self.navigationController pushViewController:addFriendVC animated:YES];
  243. }
  244. - (void)listenChannelAction:(id)sender {
  245. UIViewController *searchChannelVC = [[WFCUSearchChannelViewController alloc] init];
  246. searchChannelVC.hidesBottomBarWhenPushed = YES;
  247. [self.navigationController pushViewController:searchChannelVC animated:YES];
  248. }
  249. - (void)scanQrCodeAction:(id)sender {
  250. if (gQrCodeDelegate) {
  251. [gQrCodeDelegate scanQrCode:self.navigationController];
  252. }
  253. }
  254. - (void)viewDidLoad {
  255. [super viewDidLoad];
  256. self.conversations = [[NSMutableArray alloc] init];
  257. [self initSearchUIAndTableView];
  258. self.definesPresentationContext = YES;
  259. self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"bar_plus"] style:UIBarButtonItemStyleDone target:self action:@selector(onRightBarBtn:)];
  260. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onClearAllUnread:) name:@"kTabBarClearBadgeNotification" object:nil];
  261. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onUserInfoUpdated:) name:kUserInfoUpdated object:nil];
  262. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onGroupInfoUpdated:) name:kGroupInfoUpdated object:nil];
  263. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onChannelInfoUpdated:) name:kChannelInfoUpdated object:nil];
  264. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onSendingMessageStatusUpdated:) name:kSendingMessageStatusUpdated object:nil];
  265. self.firstAppear = YES;
  266. }
  267. - (void)updateConnectionStatus:(ConnectionStatus)status {
  268. UIView *title;
  269. if (status != kConnectionStatusConnecting && status != kConnectionStatusReceiving) {
  270. UILabel *navLabel = [[UILabel alloc] initWithFrame:CGRectMake([UIScreen mainScreen].bounds.size.width/2 - 40, 0, 80, 44)];
  271. switch (status) {
  272. case kConnectionStatusLogout:
  273. navLabel.text = WFCString(@"NotLogin");
  274. break;
  275. case kConnectionStatusUnconnected:
  276. navLabel.text = WFCString(@"NotConnect");
  277. break;
  278. case kConnectionStatusConnected:
  279. navLabel.text = WFCString(@"Message");
  280. break;
  281. default:
  282. break;
  283. }
  284. navLabel.textColor = [WFCUConfigManager globalManager].naviTextColor;
  285. navLabel.font = [UIFont fontWithName:@"Arial-BoldMT" size:18];
  286. navLabel.textAlignment = NSTextAlignmentCenter;
  287. title = navLabel;
  288. } else {
  289. UIView *continer = [[UIView alloc] initWithFrame:CGRectMake([UIScreen mainScreen].bounds.size.width/2 - 60, 0, 120, 44)];
  290. UILabel *navLabel = [[UILabel alloc] initWithFrame:CGRectMake(40, 2, 80, 40)];
  291. if (status == kConnectionStatusConnecting) {
  292. navLabel.text = WFCString(@"Connecting");
  293. } else {
  294. navLabel.text = WFCString(@"Synching");
  295. }
  296. navLabel.textColor = [WFCUConfigManager globalManager].naviTextColor;
  297. navLabel.font = [UIFont fontWithName:@"Helvetica-Bold" size:18];
  298. [continer addSubview:navLabel];
  299. UIActivityIndicatorView *indicatorView = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];
  300. indicatorView.center = CGPointMake(20, 21);
  301. [indicatorView startAnimating];
  302. indicatorView.color = [WFCUConfigManager globalManager].naviTextColor;
  303. [continer addSubview:indicatorView];
  304. title = continer;
  305. }
  306. self.navigationItem.titleView = title;
  307. }
  308. - (void)onConnectionStatusChanged:(NSNotification *)notification {
  309. ConnectionStatus status = [notification.object intValue];
  310. [self updateConnectionStatus:status];
  311. }
  312. - (void)onReceiveMessages:(NSNotification *)notification {
  313. NSArray<WFCCMessage *> *messages = notification.object;
  314. if ([messages count]) {
  315. [self refreshList];
  316. [self refreshLeftButton];
  317. }
  318. }
  319. - (void)onSettingUpdated:(NSNotification *)notification {
  320. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  321. [self refreshList];
  322. [self refreshLeftButton];
  323. [self updatePcSession];
  324. });
  325. }
  326. - (void)onRecallMessages:(NSNotification *)notification {
  327. [self refreshList];
  328. [self refreshLeftButton];
  329. }
  330. - (void)onDeleteMessages:(NSNotification *)notification {
  331. [self refreshList];
  332. [self refreshLeftButton];
  333. }
  334. - (void)onClearAllUnread:(NSNotification *)notification {
  335. if ([notification.object intValue] == 0) {
  336. [[WFCCIMService sharedWFCIMService] clearAllUnreadStatus];
  337. [self refreshList];
  338. [self refreshLeftButton];
  339. }
  340. }
  341. - (void)refreshList {
  342. self.conversations = [[[WFCCIMService sharedWFCIMService] getConversationInfos:@[@(Single_Type), @(Group_Type), @(Channel_Type)] lines:@[@(0)]] mutableCopy];
  343. [self updateBadgeNumber];
  344. [self.tableView reloadData];
  345. }
  346. - (void)updateBadgeNumber {
  347. int count = 0;
  348. for (WFCCConversationInfo *info in self.conversations) {
  349. if (!info.isSilent) {
  350. count += info.unreadCount.unread;
  351. }
  352. }
  353. [self.tabBarController.tabBar showBadgeOnItemIndex:0 badgeValue:count];
  354. }
  355. - (void)updatePcSession {
  356. NSArray<WFCCPCOnlineInfo *> *onlines = [[WFCCIMService sharedWFCIMService] getPCOnlineInfos];
  357. if (@available(iOS 11.0, *)) {
  358. if (onlines.count) {
  359. self.tableView.tableHeaderView = self.pcSessionView;
  360. } else {
  361. self.tableView.tableHeaderView = nil;
  362. }
  363. } else {
  364. }
  365. }
  366. - (void)didReceiveMemoryWarning {
  367. [super didReceiveMemoryWarning];
  368. }
  369. -(void)viewDidDisappear:(BOOL)animated {
  370. [super viewDidDisappear:animated];
  371. [self refreshLeftButton];
  372. if ([KxMenu isShowing]) {
  373. [KxMenu dismissMenu];
  374. }
  375. }
  376. - (void)viewWillAppear:(BOOL)animated {
  377. [super viewWillAppear:animated];
  378. if (self.firstAppear) {
  379. self.firstAppear = NO;
  380. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onConnectionStatusChanged:) name:kConnectionStatusChanged object:nil];
  381. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onReceiveMessages:) name:kReceiveMessages object:nil];
  382. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onRecallMessages:) name:kRecallMessages object:nil];
  383. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onDeleteMessages:) name:kDeleteMessages object:nil];
  384. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onSettingUpdated:) name:kSettingUpdated object:nil];
  385. }
  386. [self updateConnectionStatus:[WFCCNetworkService sharedInstance].currentConnectionStatus];
  387. [self refreshList];
  388. [self refreshLeftButton];
  389. }
  390. - (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection {
  391. [super traitCollectionDidChange:previousTraitCollection];
  392. if (@available(iOS 13.0, *)) {
  393. if ([self.traitCollection hasDifferentColorAppearanceComparedToTraitCollection:previousTraitCollection]) {
  394. [self.tableView reloadData];
  395. }
  396. }
  397. }
  398. - (void)viewDidAppear:(BOOL)animated {
  399. [super viewDidAppear:animated];
  400. if (self.searchController.isActive) {
  401. self.tabBarController.tabBar.hidden = YES;
  402. }
  403. }
  404. - (void)refreshLeftButton {
  405. dispatch_async(dispatch_get_main_queue(), ^{
  406. WFCCUnreadCount *unreadCount = [[WFCCIMService sharedWFCIMService] getUnreadCount:@[@(Single_Type), @(Group_Type), @(Channel_Type)] lines:@[@(0)]];
  407. NSUInteger count = unreadCount.unread;
  408. NSString *title = nil;
  409. if (count > 0 && count < 1000) {
  410. title = [NSString stringWithFormat:WFCString(@"BackNumber"), count];
  411. } else if (count >= 1000) {
  412. title = WFCString(@"BackMore");
  413. } else {
  414. title = WFCString(@"Back");
  415. }
  416. UIBarButtonItem *item = [[UIBarButtonItem alloc] init];
  417. item.title = title;
  418. self.navigationItem.backBarButtonItem = item;
  419. });
  420. }
  421. - (UIView *)pcSessionView {
  422. if (!_pcSessionView) {
  423. BOOL darkMode = NO;
  424. if (@available(iOS 13.0, *)) {
  425. if(UITraitCollection.currentTraitCollection.userInterfaceStyle == UIUserInterfaceStyleDark) {
  426. darkMode = YES;
  427. }
  428. }
  429. UIColor *bgColor;
  430. if (darkMode) {
  431. bgColor = [WFCUConfigManager globalManager].backgroudColor;
  432. } else {
  433. bgColor = [UIColor colorWithRed:0.9 green:0.9 blue:0.9 alpha:1.f];
  434. }
  435. _pcSessionView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 40)];
  436. [_pcSessionView setBackgroundColor:bgColor];
  437. UIImageView *iv = [[UIImageView alloc] initWithFrame:CGRectMake(20, 4, 32, 32)];
  438. iv.image = [UIImage imageNamed:@"pc_session"];
  439. [_pcSessionView addSubview:iv];
  440. UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(68, 10, 100, 20)];
  441. label.text = WFCString(@"PCLogined");
  442. [_pcSessionView addSubview:label];
  443. _pcSessionView.userInteractionEnabled = YES;
  444. UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onTapPCBar:)];
  445. [_pcSessionView addGestureRecognizer:tap];
  446. }
  447. return _pcSessionView;
  448. }
  449. - (void)onTapPCBar:(id)sender {
  450. NSArray<WFCCPCOnlineInfo *> *onlines = [[WFCCIMService sharedWFCIMService] getPCOnlineInfos];
  451. if ([[WFCUConfigManager globalManager].appServiceProvider respondsToSelector:@selector(showPCSessionViewController:pcClient:)]) {
  452. [[WFCUConfigManager globalManager].appServiceProvider showPCSessionViewController:self pcClient:[onlines objectAtIndex:0]];
  453. }
  454. }
  455. #pragma mark - Table view data source
  456. - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
  457. int sec = 0;
  458. if (self.searchFriendList.count) {
  459. sec++;
  460. }
  461. if (self.searchGroupList.count) {
  462. sec++;
  463. }
  464. if (self.searchConversationList.count) {
  465. sec++;
  466. }
  467. if (sec == 0) {
  468. sec = 1;
  469. }
  470. return sec;
  471. }
  472. - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
  473. if (self.searchController.active) {
  474. int sec = 0;
  475. if (self.searchFriendList.count) {
  476. sec++;
  477. if (section == sec-1) {
  478. if (self.isSearchFriendListExpansion) {
  479. return self.searchFriendList.count;
  480. } else {
  481. if (self.searchFriendList.count > 2) {
  482. return 3;
  483. } else {
  484. return self.searchFriendList.count;
  485. }
  486. }
  487. }
  488. }
  489. if (self.searchGroupList.count) {
  490. sec++;
  491. if (section == sec-1) {
  492. if (self.isSearchGroupListExpansion) {
  493. return self.searchGroupList.count;
  494. } else {
  495. if (self.searchGroupList.count > 2) {
  496. return 3;
  497. } else {
  498. return self.searchGroupList.count;
  499. }
  500. }
  501. }
  502. }
  503. if (self.searchConversationList.count) {
  504. sec++;
  505. if (sec-1 == section) {
  506. if (self.isSearchConversationListExpansion) {
  507. return self.searchConversationList.count;
  508. } else {
  509. if (self.searchConversationList.count > 2) {
  510. return 3;
  511. } else {
  512. return self.searchConversationList.count;
  513. }
  514. }
  515. }
  516. }
  517. return 0;
  518. } else {
  519. return self.conversations.count;
  520. }
  521. }
  522. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
  523. if (self.searchController.active) {
  524. int sec = 0;
  525. if (self.searchFriendList.count) {
  526. sec++;
  527. if (indexPath.section == sec-1) {
  528. if (self.isSearchFriendListExpansion) {
  529. WFCUContactTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"friendCell"];
  530. if (cell == nil) {
  531. cell = [[WFCUContactTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"friendCell"];
  532. }
  533. cell.big = NO;
  534. cell.separatorInset = UIEdgeInsetsMake(0, 68, 0, 0);
  535. cell.userId = self.searchFriendList[indexPath.row].userId;
  536. return cell;
  537. } else {
  538. if (indexPath.row == 2) {
  539. UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"expansion" forIndexPath:indexPath];
  540. cell.textLabel.textColor = [UIColor colorWithHexString:@"5b6e8e"];
  541. cell.textLabel.text = [NSString stringWithFormat:@"点击展开剩余%lu项", self.searchFriendList.count - 2];
  542. cell.textLabel.font = [UIFont pingFangSCWithWeight:FontWeightStyleRegular size:12];
  543. return cell;
  544. } else {
  545. WFCUContactTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"friendCell"];
  546. if (cell == nil) {
  547. cell = [[WFCUContactTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"friendCell"];
  548. }
  549. cell.big = NO;
  550. if (indexPath.row == 1) {
  551. cell.separatorInset = UIEdgeInsetsMake(0, 0, 0, 0);
  552. } else {
  553. cell.separatorInset = UIEdgeInsetsMake(0, 68, 0, 0);
  554. }
  555. cell.userId = self.searchFriendList[indexPath.row].userId;
  556. return cell;
  557. }
  558. }
  559. }
  560. }
  561. if (self.searchGroupList.count) {
  562. sec++;
  563. if (indexPath.section == sec-1) {
  564. if (self.isSearchGroupListExpansion) {
  565. WFCUSearchGroupTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"groupCell"];
  566. if (cell == nil) {
  567. cell = [[WFCUSearchGroupTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"groupCell"];
  568. }
  569. cell.separatorInset = UIEdgeInsetsMake(0, 68, 0, 0);
  570. cell.groupSearchInfo = self.searchGroupList[indexPath.row];
  571. return cell;
  572. } else {
  573. if (indexPath.row == 2) {
  574. UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"expansion" forIndexPath:indexPath];
  575. cell.textLabel.textColor = [UIColor colorWithHexString:@"5b6e8e"];
  576. cell.textLabel.text = [NSString stringWithFormat:@"点击展开剩余%lu项", self.searchGroupList.count - 2];
  577. cell.textLabel.font = [UIFont pingFangSCWithWeight:FontWeightStyleRegular size:12];
  578. return cell;
  579. } else {
  580. WFCUSearchGroupTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"groupCell"];
  581. if (cell == nil) {
  582. cell = [[WFCUSearchGroupTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"groupCell"];
  583. }
  584. if (indexPath.row == 1) {
  585. cell.separatorInset = UIEdgeInsetsMake(0, 0, 0, 0);
  586. } else {
  587. cell.separatorInset = UIEdgeInsetsMake(0, 68, 0, 0);
  588. }
  589. cell.groupSearchInfo = self.searchGroupList[indexPath.row];
  590. return cell;
  591. }
  592. }
  593. }
  594. }
  595. if (self.searchConversationList.count) {
  596. sec++;
  597. if (sec-1 == indexPath.section) {
  598. if (self.isSearchConversationListExpansion) {
  599. WFCUConversationTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"searchConversationCell"];
  600. if (cell == nil) {
  601. cell = [[WFCUConversationTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"searchConversationCell"];
  602. }
  603. cell.separatorInset = UIEdgeInsetsMake(0, 68, 0, 0);
  604. cell.big = NO;
  605. cell.searchInfo = self.searchConversationList[indexPath.row];
  606. return cell;
  607. } else {
  608. if (indexPath.row == 2) {
  609. UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"expansion" forIndexPath:indexPath];
  610. cell.textLabel.textColor = [UIColor colorWithHexString:@"5b6e8e"];
  611. cell.textLabel.text = [NSString stringWithFormat:@"点击展开剩余%lu项", self.searchConversationList.count - 2];
  612. cell.textLabel.font = [UIFont pingFangSCWithWeight:FontWeightStyleRegular size:12];
  613. return cell;
  614. } else {
  615. WFCUConversationTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"searchConversationCell"];
  616. if (cell == nil) {
  617. cell = [[WFCUConversationTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"searchConversationCell"];
  618. }
  619. if (indexPath.row == 1) {
  620. cell.separatorInset = UIEdgeInsetsMake(0, 0, 0, 0);
  621. } else {
  622. cell.separatorInset = UIEdgeInsetsMake(0, 68, 0, 0);
  623. } cell.big = NO;
  624. cell.searchInfo = self.searchConversationList[indexPath.row];
  625. return cell;
  626. }
  627. }
  628. }
  629. }
  630. return nil;
  631. } else {
  632. WFCUConversationTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"conversationCell"];
  633. if (cell == nil) {
  634. cell = [[WFCUConversationTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"conversationCell"];
  635. }
  636. cell.big = YES;
  637. cell.separatorInset = UIEdgeInsetsMake(0, 76, 0, 0);
  638. cell.info = self.conversations[indexPath.row];
  639. return cell;
  640. }
  641. }
  642. - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
  643. if (self.searchController.active) {
  644. int sec = 0;
  645. if (self.searchFriendList.count) {
  646. sec++;
  647. if (indexPath.section == sec-1) {
  648. if (self.isSearchFriendListExpansion) {
  649. return 60;
  650. } else {
  651. if (indexPath.row == 2) {
  652. return 40;
  653. } else {
  654. return 60;
  655. }
  656. }
  657. }
  658. }
  659. if (self.searchGroupList.count) {
  660. sec++;
  661. if (indexPath.section == sec-1) {
  662. if (self.isSearchGroupListExpansion) {
  663. return 60;
  664. } else {
  665. if (indexPath.row == 2) {
  666. return 40;
  667. } else {
  668. return 60;
  669. }
  670. }
  671. }
  672. }
  673. if (self.searchConversationList.count) {
  674. sec++;
  675. if (sec-1 == indexPath.section ) {
  676. if (self.isSearchConversationListExpansion) {
  677. return 60;
  678. } else {
  679. if (indexPath.row == 2) {
  680. return 40;
  681. } else {
  682. return 60;
  683. }
  684. }
  685. }
  686. }
  687. return 60;
  688. } else {
  689. return 72;
  690. }
  691. }
  692. - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
  693. if (self.searchController.isActive) {
  694. if (self.searchConversationList.count + self.searchGroupList.count + self.searchFriendList.count > 0) {
  695. UIView *header = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.tableView.frame.size.width, 32)];
  696. header.backgroundColor = [WFCUConfigManager globalManager].backgroudColor;
  697. UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(16, 0, self.tableView.frame.size.width, 32)];
  698. label.font = [UIFont pingFangSCWithWeight:FontWeightStyleRegular size:13];
  699. label.textColor = [UIColor colorWithHexString:@"0x828282"];
  700. label.textAlignment = NSTextAlignmentLeft;
  701. int sec = 0;
  702. if (self.searchFriendList.count) {
  703. sec++;
  704. if (section == sec-1) {
  705. label.text = WFCString(@"Contact");
  706. }
  707. }
  708. if (self.searchGroupList.count) {
  709. sec++;
  710. if (section == sec-1) {
  711. label.text = WFCString(@"Group");
  712. }
  713. }
  714. if (self.searchConversationList.count) {
  715. sec++;
  716. if (sec-1 == section) {
  717. label.text = WFCString(@"Message");
  718. }
  719. }
  720. [header addSubview:label];
  721. return header;
  722. } else {
  723. UIView *header = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.tableView.frame.size.width, 50)];
  724. return header;
  725. }
  726. } else {
  727. return nil;
  728. }
  729. }
  730. - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
  731. if (self.searchController.isActive) {
  732. return 32;
  733. }
  734. return 0;
  735. }
  736. // Override to support conditional editing of the table view.
  737. - (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
  738. // Return NO if you do not want the specified item to be editable.
  739. if (self.searchController.active) {
  740. return NO;
  741. }
  742. return YES;
  743. }
  744. - (NSArray<UITableViewRowAction *> *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath {
  745. __weak typeof(self) ws = self;
  746. UITableViewRowAction *delete = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleNormal title:WFCString(@"Delete") handler:^(UITableViewRowAction * _Nonnull action, NSIndexPath * _Nonnull indexPath) {
  747. [[WFCCIMService sharedWFCIMService] clearUnreadStatus:ws.conversations[indexPath.row].conversation];
  748. [[WFCCIMService sharedWFCIMService] removeConversation:ws.conversations[indexPath.row].conversation clearMessage:YES];
  749. [ws.conversations removeObjectAtIndex:indexPath.row];
  750. [ws updateBadgeNumber];
  751. [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
  752. }];
  753. UITableViewRowAction *setTop = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleNormal title:WFCString(@"Pinned") handler:^(UITableViewRowAction * _Nonnull action, NSIndexPath * _Nonnull indexPath) {
  754. [[WFCCIMService sharedWFCIMService] setConversation:ws.conversations[indexPath.row].conversation top:YES success:^{
  755. [ws refreshList];
  756. } error:^(int error_code) {
  757. MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:ws.view animated:NO];
  758. hud.label.text = WFCString(@"UpdateFailure");
  759. hud.mode = MBProgressHUDModeText;
  760. hud.removeFromSuperViewOnHide = YES;
  761. [hud hideAnimated:NO afterDelay:1.5];
  762. }];
  763. }];
  764. UITableViewRowAction *setUntop = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleNormal title:WFCString(@"Unpinned") handler:^(UITableViewRowAction * _Nonnull action, NSIndexPath * _Nonnull indexPath) {
  765. [[WFCCIMService sharedWFCIMService] setConversation:ws.conversations[indexPath.row].conversation top:NO success:^{
  766. [ws refreshList];
  767. } error:^(int error_code) {
  768. MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:ws.view animated:NO];
  769. hud.label.text = WFCString(@"UpdateFailure");
  770. hud.mode = MBProgressHUDModeText;
  771. hud.removeFromSuperViewOnHide = YES;
  772. [hud hideAnimated:NO afterDelay:1.5];
  773. }];
  774. [self refreshList];
  775. }];
  776. setTop.backgroundColor = [UIColor purpleColor];
  777. setUntop.backgroundColor = [UIColor orangeColor];
  778. if (self.conversations[indexPath.row].isTop) {
  779. return @[delete, setUntop ];
  780. } else {
  781. return @[delete, setTop];
  782. }
  783. };
  784. - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
  785. if (self.searchController.active) {
  786. [self.searchController.searchBar resignFirstResponder];
  787. }
  788. }
  789. - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
  790. if (self.searchController.active) {
  791. int sec = 0;
  792. if (self.searchFriendList.count) {
  793. sec++;
  794. if (indexPath.section == sec-1) {
  795. if (!self.isSearchFriendListExpansion && indexPath.row == 2) {
  796. self.isSearchFriendListExpansion = YES;
  797. NSIndexSet *set = [NSIndexSet indexSetWithIndex:indexPath.section];
  798. [self.tableView reloadSections:set withRowAnimation:UITableViewRowAnimationNone];
  799. } else {
  800. WFCUMessageListViewController *mvc = [[WFCUMessageListViewController alloc] init];
  801. WFCCUserInfo *info = self.searchFriendList[indexPath.row];
  802. mvc.conversation = [[WFCCConversation alloc] init];
  803. mvc.conversation.type = Single_Type;
  804. mvc.conversation.target = info.userId;
  805. mvc.conversation.line = 0;
  806. mvc.hidesBottomBarWhenPushed = YES;
  807. [self.navigationController pushViewController:mvc animated:YES];
  808. }
  809. }
  810. }
  811. if (self.searchGroupList.count) {
  812. sec++;
  813. if (indexPath.section == sec-1) {
  814. if (!self.isSearchGroupListExpansion && indexPath.row == 2) {
  815. self.isSearchGroupListExpansion = YES;
  816. NSIndexSet *set = [NSIndexSet indexSetWithIndex:indexPath.section];
  817. [self.tableView reloadSections:set withRowAnimation:UITableViewRowAnimationNone];
  818. } else {
  819. WFCUMessageListViewController *mvc = [[WFCUMessageListViewController alloc] init];
  820. WFCCGroupSearchInfo *info = self.searchGroupList[indexPath.row];
  821. mvc.conversation = [[WFCCConversation alloc] init];
  822. mvc.conversation.type = Group_Type;
  823. mvc.conversation.target = info.groupInfo.target;
  824. mvc.conversation.line = 0;
  825. mvc.hidesBottomBarWhenPushed = YES;
  826. [self.navigationController pushViewController:mvc animated:YES];
  827. }
  828. }
  829. }
  830. if (self.searchConversationList.count) {
  831. sec++;
  832. if (sec-1 == indexPath.section) {
  833. if (!self.isSearchConversationListExpansion && indexPath.row == 2) {
  834. self.isSearchConversationListExpansion = YES;
  835. NSIndexSet *set = [NSIndexSet indexSetWithIndex:indexPath.section];
  836. [self.tableView reloadSections:set withRowAnimation:UITableViewRowAnimationNone];
  837. } else {
  838. WFCCConversationSearchInfo *info = self.searchConversationList[indexPath.row];
  839. if (info.marchedCount == 1) {
  840. WFCUMessageListViewController *mvc = [[WFCUMessageListViewController alloc] init];
  841. mvc.conversation = info.conversation;
  842. mvc.highlightMessageId = info.marchedMessage.messageId;
  843. mvc.highlightText = info.keyword;
  844. mvc.hidesBottomBarWhenPushed = YES;
  845. [self.navigationController pushViewController:mvc animated:YES];
  846. } else {
  847. WFCUConversationSearchTableViewController *mvc = [[WFCUConversationSearchTableViewController alloc] init];
  848. mvc.conversation = info.conversation;
  849. mvc.keyword = info.keyword;
  850. mvc.hidesBottomBarWhenPushed = YES;
  851. [self.navigationController pushViewController:mvc animated:YES];
  852. }
  853. }
  854. }
  855. }
  856. } else {
  857. WFCUMessageListViewController *mvc = [[WFCUMessageListViewController alloc] init];
  858. WFCCConversationInfo *info = self.conversations[indexPath.row];
  859. mvc.conversation = info.conversation;
  860. mvc.hidesBottomBarWhenPushed = YES;
  861. [self.navigationController pushViewController:mvc animated:YES];
  862. }
  863. }
  864. - (void)dealloc {
  865. [[NSNotificationCenter defaultCenter] removeObserver:self];
  866. _searchController = nil;
  867. _searchConversationList = nil;
  868. }
  869. #pragma mark - UISearchControllerDelegate
  870. - (void)didPresentSearchController:(UISearchController *)searchController {
  871. self.searchController.view.frame = self.view.bounds;
  872. self.isSearchFriendListExpansion = NO;
  873. self.isSearchConversationListExpansion = NO;
  874. self.isSearchGroupListExpansion = NO;
  875. self.tabBarController.tabBar.hidden = YES;
  876. self.extendedLayoutIncludesOpaqueBars = YES;
  877. }
  878. - (void)willDismissSearchController:(UISearchController *)searchController {
  879. self.tabBarController.tabBar.hidden = NO;
  880. self.extendedLayoutIncludesOpaqueBars = NO;
  881. }
  882. -(void)updateSearchResultsForSearchController:(UISearchController *)searchController {
  883. NSString *searchString = [self.searchController.searchBar text];
  884. if (searchString.length) {
  885. self.searchConversationList = [[WFCCIMService sharedWFCIMService] searchConversation:searchString inConversation:@[@(Single_Type), @(Group_Type), @(Channel_Type)] lines:@[@(0)]];
  886. self.searchFriendList = [[WFCCIMService sharedWFCIMService] searchFriends:searchString];
  887. self.searchGroupList = [[WFCCIMService sharedWFCIMService] searchGroups:searchString];
  888. } else {
  889. self.searchConversationList = nil;
  890. self.searchFriendList = nil;
  891. self.searchGroupList = nil;
  892. }
  893. [self.tableView reloadData];
  894. }
  895. @end