EMChatViewController.m 139 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289
  1. //
  2. // EMChatViewController.m
  3. // ChatDemo-UI3.0
  4. //
  5. // Created by XieYajie on 2019/1/18.
  6. // Copyright © 2019 XieYajie. All rights reserved.
  7. //
  8. #import <AVKit/AVKit.h>
  9. #import <Photos/Photos.h>
  10. #import <AVFoundation/AVFoundation.h>
  11. #import <AssetsLibrary/AssetsLibrary.h>
  12. #import <MobileCoreServices/MobileCoreServices.h>
  13. #import "EMChatViewController.h"
  14. #import "EMImageBrowser.h"
  15. #import "EMDateHelper.h"
  16. #import "EMAudioPlayerHelper.h"
  17. #import "EMConversationHelper.h"
  18. #import "EMMessageModel.h"
  19. #import "EMReadReceiptMemberModel.h"
  20. #import "EMChatBar.h"
  21. #import "EMMessageCell.h"
  22. #import "EMMessageTimeCell.h"
  23. #import "EMLocationViewController.h"
  24. #import "EMMsgTranspondViewController.h"
  25. #import "EMAtGroupMembersViewController.h"
  26. #import "FavoritesViewController.h"
  27. #import "ChatMsgDetailChatInfoVC.h"
  28. #import "ChatMsgPersonInfoVC.h"
  29. #import "ChatMsgListImModel.h"
  30. #import "MailListDetailVC.h"
  31. #import "FWZFileGetTool.h"
  32. #import "EMChatFileShowVC.h"
  33. #import "DrawerView.h"
  34. #import "TabBarController.h"
  35. #import "FWZGetNoteBookTool.h"
  36. #import "NoteBookVC.h"
  37. #import "OtherNoteBookVC.h"
  38. #import "MyFavoriteVC.h"
  39. #import "OtherFavoriteVC.h"
  40. #import "TDGroupInfoListVC.h"
  41. #import "DownFileViewController.h"
  42. #import "WorkFlowDetailsController.h"
  43. #import "MyTDGroupViewController.h"
  44. #import "HomeDetailController.h"
  45. #import "MyApprovalPageDetail.h"
  46. #import "NoteBookShareVC.h"
  47. #import "MoveViewController.h"
  48. #import "CountDataVC.h"
  49. #import "BookWCDetailVC.h"
  50. #import "BookListenVC.h"
  51. @interface EMChatViewController ()<UIScrollViewDelegate, UINavigationControllerDelegate, UIImagePickerControllerDelegate, EMMultiDevicesDelegate, EMChatManagerDelegate, EMGroupManagerDelegate, EMChatroomManagerDelegate, EMChatBarDelegate, EMMessageCellDelegate, EMChatBarEmoticonViewDelegate, EMChatBarRecordAudioViewDelegate,EMMoreFunctionViewDelegate,EMReadReceiptMsgDelegate,NoteBookShareVCDelegate>
  52. @property (nonatomic,strong) dispatch_queue_t msgQueue;
  53. @property (nonatomic,strong) UIView * titleV;
  54. @property (nonatomic,strong) UIButton * backBtn;
  55. @property (nonatomic,strong) UIButton * tabBtn;
  56. @property (nonatomic,strong) UIButton * mangerBtn;
  57. @property (nonatomic,strong) UILabel * titleL;
  58. @property (strong,nonatomic) DrawerView *drawerView;
  59. @property (nonatomic,assign) BOOL isFirstLoadMsg;
  60. @property (nonatomic,assign) BOOL isViewDidAppear;
  61. @property (nonatomic,strong) EMConversationModel *conversationModel;
  62. @property (nonatomic,strong) NSString *moreMsgId; //第一条消息的消息id
  63. @property (nonatomic,strong) UILabel *titleLabel;
  64. @property (nonatomic,strong) UILabel *titleDetailLabel;
  65. @property (nonatomic,strong) EMChatBar *chatBar;
  66. @property (nonatomic,strong) UIImagePickerController *imagePicker;
  67. @property (nonatomic,strong) EMGroup *group;
  68. //阅读回执
  69. @property (nonatomic,strong) EMReadReceiptMsgViewController *readReceiptControl;
  70. //长按操作栏
  71. @property (strong, nonatomic) NSIndexPath *menuIndexPath;
  72. @property (nonatomic, strong) UIMenuController *menuController;
  73. @property (nonatomic, strong) UIMenuItem *deleteMenuItem;
  74. @property (nonatomic, strong) UIMenuItem *copyMenuItem;
  75. @property (nonatomic, strong) UIMenuItem *recallMenuItem;
  76. @property (nonatomic, strong) UIMenuItem *transpondMenuItem;
  77. @property (nonatomic, strong) UIMenuItem *playAndRecordMenuItem;
  78. //消息格式化
  79. @property (nonatomic, assign) NSTimeInterval msgTimelTag;
  80. //@
  81. @property (nonatomic,assign) BOOL isWillInputAt;
  82. @property (strong, nonatomic) NoteBookShareVC *noteBookShareVC;
  83. @property (strong, nonatomic) UIImage *sendImage;
  84. //Typing
  85. @property (nonatomic,assign) BOOL isTyping;
  86. @property (nonatomic,assign) BOOL enableTyping;
  87. @property (nonatomic,copy) NSMutableArray *userInfoArray;
  88. @property (nonatomic,copy) NSMutableArray *chatDistoryArray;
  89. @property (nonatomic,assign) NSInteger UserId;
  90. @end
  91. @implementation EMChatViewController
  92. - (instancetype)initWithConversationId:(NSString *)aId
  93. type:(EMConversationType)aType
  94. createIfNotExist:(BOOL)aIsCreate
  95. {
  96. self = [super init];
  97. if (self) {
  98. EMConversation *conversation = [[EMClient sharedClient].chatManager getConversation:aId type:aType createIfNotExist:aIsCreate];
  99. _conversationModel = [[EMConversationModel alloc] initWithEMModel:conversation];
  100. }
  101. return self;
  102. }
  103. - (instancetype)initWithCoversationModel:(EMConversationModel *)aConversationModel
  104. {
  105. self = [super init];
  106. if (self) {
  107. _conversationModel = aConversationModel;
  108. }
  109. return self;
  110. }
  111. - (void)viewDidLoad {
  112. [super viewDidLoad];
  113. NSLog(@"conversationId===%@",_conversationModel.emModel.conversationId);
  114. // Do any additional setup after loading the view.
  115. self.msgQueue = dispatch_queue_create("emmessage.com", NULL);
  116. self.msgTimelTag = -1;
  117. [self _setupChatSubviews];
  118. [[EMClient sharedClient] addMultiDevicesDelegate:self delegateQueue:nil];
  119. [[EMClient sharedClient].chatManager addDelegate:self delegateQueue:nil];
  120. [[EMClient sharedClient].groupManager addDelegate:self delegateQueue:nil];
  121. [[EMClient sharedClient].roomManager addDelegate:self delegateQueue:nil];
  122. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleWillPushCallController:) name:CALL_PUSH_VIEWCONTROLLER object:nil];
  123. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleCleanMessages:) name:CHAT_CLEANMESSAGES object:nil];
  124. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleGroupSubjectUpdated:) name:GROUP_SUBJECT_UPDATED object:nil];
  125. self.isTyping = NO;
  126. self.enableTyping = NO;
  127. if ([EMDemoOptions sharedOptions].isChatTyping && self.conversationModel.emModel.type == EMConversationTypeChat) {
  128. self.enableTyping = YES;
  129. }
  130. if (self.conversationModel.emModel.type == EMConversationTypeChatRoom) {
  131. [self _joinChatroom];
  132. } else {
  133. self.isFirstLoadMsg = YES;
  134. [self tableViewDidTriggerHeaderRefresh];
  135. }
  136. [self.view addSubview:self.noteBookShareVC.view];
  137. UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTapTableViewAction:)];
  138. [self.tableView addGestureRecognizer:tap];
  139. }
  140. - (void)viewWillAppear:(BOOL)animated
  141. {
  142. [super viewWillAppear:animated];
  143. self.isViewDidAppear = YES;
  144. [EMConversationHelper markAllAsRead:self.conversationModel];
  145. self.navigationController.navigationBar.hidden = YES;
  146. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(deleteConversationMsg) name:DELETECONVERSATIONMSG object:nil];
  147. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyBoardWillShow:) name:UIKeyboardWillShowNotification object:nil];
  148. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyBoardWillHide:) name:UIKeyboardWillHideNotification object:nil];
  149. }
  150. - (void)viewWillDisappear:(BOOL)animated
  151. {
  152. [super viewWillDisappear:animated];
  153. self.isViewDidAppear = NO;
  154. if (self.enableTyping && self.isTyping) {
  155. [self _sendEndTyping];
  156. }
  157. if (self.chatBar.textView.text.length > 0) {
  158. [self saveUserInfoInDocument:self.chatBar.textView.text];
  159. }else{
  160. [self clearUserInfoInDocument];
  161. }
  162. [self.chatBar mas_updateConstraints:^(MASConstraintMaker *make) {
  163. if (@available(iOS 11.0, *)) {
  164. make.bottom.mas_equalTo(self.view.mas_safeAreaLayoutGuideBottom);
  165. } else {
  166. make.bottom.mas_equalTo(self.view.mas_bottom);
  167. }
  168. }];
  169. [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
  170. [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
  171. }
  172. - (void)dealloc
  173. {
  174. self.isViewDidAppear = NO;
  175. [self.chatBar removeFromSuperview];
  176. [[EMClient sharedClient] removeMultiDevicesDelegate:self];
  177. [[EMClient sharedClient].chatManager removeDelegate:self];
  178. [[EMClient sharedClient].groupManager removeDelegate:self];
  179. [[EMClient sharedClient].roomManager removeDelegate:self];
  180. [[NSNotificationCenter defaultCenter] removeObserver:self];
  181. }
  182. - (BOOL)canBecomeFirstResponder
  183. {
  184. return YES;
  185. }
  186. #pragma mark - Subviews
  187. - (void)_setupChatSubviews
  188. {
  189. NSLog(@"%@",self.conversationModel.emModel.conversationId);
  190. [self _setupNavigationBarTitle];
  191. self.view.backgroundColor = [UIColor whiteColor];
  192. self.showRefreshHeader = YES;
  193. self.chatBar = [[EMChatBar alloc] init];
  194. self.chatBar.delegate = self;
  195. [self.view addSubview:self.chatBar];
  196. [self.chatBar mas_makeConstraints:^(MASConstraintMaker *make) {
  197. make.left.mas_equalTo(self.view);
  198. make.right.mas_equalTo(self.view);
  199. if (@available(iOS 11.0, *)) {
  200. make.bottom.mas_equalTo(self.view.mas_safeAreaLayoutGuideBottom);
  201. } else {
  202. make.bottom.mas_equalTo(self.view.mas_bottom);
  203. }
  204. make.height.offset(56);
  205. }];
  206. if ([self getUserInfoInDocument].length > 0) {
  207. self.chatBar.textView.text = [self getUserInfoInDocument];
  208. }
  209. WS(weakSelf);
  210. self.chatBar.clickMore = ^(NSInteger index, NSString * _Nonnull title) {
  211. [weakSelf selectMoreMenu:index title:title];
  212. };
  213. [self _setupChatBarMoreViews];
  214. self.tableView.backgroundColor = kColor_LightGray;
  215. self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
  216. self.tableView.rowHeight = UITableViewAutomaticDimension;
  217. self.tableView.estimatedRowHeight = 130;
  218. [self.tableView mas_makeConstraints:^(MASConstraintMaker *make) {
  219. make.top.mas_equalTo(self.titleV.mas_bottom);
  220. make.left.mas_equalTo(self.view);
  221. make.right.mas_equalTo(self.view);
  222. make.bottom.mas_equalTo(self.chatBar.mas_top);
  223. }];
  224. }
  225. -(DrawerView *)drawerView{
  226. if(!_drawerView){
  227. _drawerView = [[DrawerView alloc] init];
  228. }
  229. return _drawerView;
  230. }
  231. - (void)_setupNavigationBarTitle
  232. {
  233. [self.view addSubview:self.titleV];
  234. [self.titleV mas_makeConstraints:^(MASConstraintMaker *make) {
  235. make.top.left.right.mas_equalTo(self.view);
  236. make.height.mas_offset(IS_IPHONEX?88:64);
  237. }];
  238. [self.titleV addSubview:self.backBtn];
  239. [self.titleV addSubview:self.tabBtn];
  240. [self.titleV addSubview:self.titleL];
  241. [self.titleV addSubview:self.mangerBtn];
  242. [self.backBtn mas_makeConstraints:^(MASConstraintMaker *make) {
  243. make.left.bottom.mas_equalTo(self.titleV);
  244. make.size.mas_offset(CGSizeMake(50, 44));
  245. }];
  246. [self.tabBtn mas_makeConstraints:^(MASConstraintMaker *make) {
  247. make.bottom.mas_equalTo(self.titleV);
  248. make.left.mas_equalTo(self.backBtn.mas_right);
  249. make.size.mas_offset(CGSizeMake(35, 44));
  250. }];
  251. [self.mangerBtn mas_makeConstraints:^(MASConstraintMaker *make) {
  252. make.right.bottom.mas_equalTo(self.titleV);
  253. make.size.mas_offset(CGSizeMake(50, 44));
  254. }];
  255. [self.titleL mas_makeConstraints:^(MASConstraintMaker *make) {
  256. make.centerX.mas_equalTo(self.titleV);
  257. make.centerY.mas_equalTo(self.backBtn);
  258. make.height.mas_greaterThanOrEqualTo(10);
  259. make.width.mas_lessThanOrEqualTo(SCREEN_WIDTH - 160);
  260. }];
  261. self.titleL.text = self.conversationModel.name;
  262. WS(weakSelf);
  263. [self.backBtn setAction:^{
  264. if (weakSelf.backRoot) {
  265. [weakSelf back1];
  266. }else{
  267. weakSelf.hidesBottomBarWhenPushed = NO;
  268. [weakSelf.navigationController popViewControllerAnimated:YES];
  269. }
  270. }];
  271. [self.tabBtn setAction:^{
  272. [[UtilsTools getWindow] addSubview:weakSelf.drawerView];
  273. weakSelf.drawerView.SelectDrawerBlock = ^(NSIndexPath * _Nonnull indexPath) {
  274. if (![weakSelf.tabBarController isKindOfClass:[TabBarController class]]) {
  275. [TabBarController sharedTabBarController].tabBar.hidden = NO;
  276. [weakSelf.tabBarController.navigationController popViewControllerAnimated:NO];
  277. }
  278. if ([weakSelf.navigationController.viewControllers count] > 1) {
  279. [weakSelf.navigationController popToRootViewControllerAnimated:NO];
  280. }
  281. switch (indexPath.section) {
  282. case 0:
  283. {
  284. [[TabBarController sharedTabBarController] setSelectedIndex:indexPath.row];
  285. }
  286. break;
  287. case 1:
  288. {
  289. switch (indexPath.row) {
  290. case 0:
  291. {
  292. [[TabBarController sharedTabBarController] setSelectedIndex:2];
  293. }
  294. break;
  295. case 1:
  296. {
  297. [[TabBarController sharedTabBarController] setSelectedIndex:2];
  298. }
  299. break;
  300. default:
  301. {
  302. [[TabBarController sharedTabBarController] setSelectedIndex:3];
  303. }
  304. break;
  305. }
  306. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  307. [[NSNotificationCenter defaultCenter] postNotificationName:DRAWERPUSHVC object:nil userInfo:@{VCINDEX:@(indexPath.row)}];
  308. });
  309. }
  310. break;
  311. default:
  312. {
  313. [[TabBarController sharedTabBarController] setSelectedIndex:3];
  314. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  315. [[NSNotificationCenter defaultCenter] postNotificationName:DRAWERPUSHVC object:nil userInfo:@{VCINDEX:@(4 + indexPath.row)}];
  316. });
  317. }
  318. break;
  319. }
  320. };
  321. weakSelf.drawerView.frame = CGRectMake(0,0, SCREEN_WIDTH, SCREEN_HEIGHT);// - kNavigationHeight
  322. }];
  323. [self.mangerBtn setAction:^{
  324. if (weakSelf.chatType == ChatType_SingleChat) {
  325. ChatMsgPersonInfoVC * vc = [ChatMsgPersonInfoVC initChatMsgPersonInfoVC];
  326. vc.refreshStatus = ^(BOOL isTop) {
  327. weakSelf.isTop = isTop;
  328. };
  329. vc.listId = weakSelf.listId;
  330. vc.IsTop = weakSelf.isTop;
  331. vc.model = weakSelf.sModel;
  332. [weakSelf.navigationController pushViewController:vc animated:YES];
  333. }else{
  334. ChatMsgDetailChatInfoVC *vc = [ChatMsgDetailChatInfoVC initChatMsgDetailChatInfoVC];
  335. vc.GroupChatImId = weakSelf.toUserId;
  336. vc.GroupId = weakSelf.GroupId;
  337. vc.GroupName = weakSelf.conversationModel.name;
  338. vc.upDataChatBlock = ^(NSString * _Nonnull name) {
  339. weakSelf.titleL.text = name;
  340. };
  341. [weakSelf.navigationController pushViewController:vc animated:YES];
  342. }
  343. }];
  344. }
  345. - (void)back1
  346. {
  347. for (NSInteger i = (self.navigationController.viewControllers.count - 1); i >= 0 ;i --) {
  348. if ([self.navigationController.viewControllers[i] isKindOfClass:NSClassFromString(@"MyTDTopicDetailVC")]
  349. ||[self.navigationController.viewControllers[i] isKindOfClass:NSClassFromString(@"WorkFlowDetailsController")]
  350. ||[self.navigationController.viewControllers[i] isKindOfClass:NSClassFromString(@"SourceGroupSearchVC")]
  351. ||[self.navigationController.viewControllers[i] isKindOfClass:NSClassFromString(@"MyTDTopicSearchVC")]
  352. ||[self.navigationController.viewControllers[i] isKindOfClass:NSClassFromString(@"TDGroupInfoListVC")]
  353. ||[self.navigationController.viewControllers[i] isKindOfClass:NSClassFromString(@"CommonNoteVC")]
  354. ||[self.navigationController.viewControllers[i] isKindOfClass:NSClassFromString(@"SourceHomeVC")]
  355. ||[self.navigationController.viewControllers[i] isKindOfClass:NSClassFromString(@"MyInfoVC")]
  356. ||[self.navigationController.viewControllers[i] isKindOfClass:NSClassFromString(@"MyFavoriteVC")]
  357. ||[self.navigationController.viewControllers[i] isKindOfClass:NSClassFromString(@"BookWCDetailVC")]
  358. ||[self.navigationController.viewControllers[i] isKindOfClass:NSClassFromString(@"BookListenVC")]
  359. ||[self.navigationController.viewControllers[i] isKindOfClass:NSClassFromString(@"ChatMsgListVC")]
  360. ||[self.navigationController.viewControllers[i] isKindOfClass:NSClassFromString(@"CommonHomeVC")]) {
  361. [self.navigationController popToViewController:self.navigationController.viewControllers[i] animated:YES];
  362. return;
  363. }
  364. }
  365. }
  366. - (void)_setupChatBarMoreViews
  367. {
  368. //语音
  369. NSString *path = [self _getAudioOrVideoPath];
  370. EMChatBarRecordAudioView *recordView = [[EMChatBarRecordAudioView alloc] initWithRecordPath:path];
  371. recordView.delegate = self;
  372. self.chatBar.recordAudioView = recordView;
  373. //表情
  374. EMChatBarEmoticonView *moreEmoticonView = [[EMChatBarEmoticonView alloc] init];
  375. moreEmoticonView.delegate = self;
  376. self.chatBar.moreEmoticonView = moreEmoticonView;
  377. //更多
  378. if (self.conversationModel.emModel.type == EMConversationTypeGroupChat) {
  379. EMMoreFunctionView *moreFunction = [[EMMoreFunctionView alloc]init];
  380. moreFunction.delegate = self;
  381. self.chatBar.moreFunctionView = moreFunction;
  382. }
  383. }
  384. - (NSString *)_getAudioOrVideoPath
  385. {
  386. NSString *path = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];
  387. path = [path stringByAppendingPathComponent:@"EMDemoRecord"];
  388. if (![[NSFileManager defaultManager] fileExistsAtPath:path]) {
  389. [[NSFileManager defaultManager] createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:nil];
  390. }
  391. return path;
  392. }
  393. #pragma mark - Table view data source
  394. - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
  395. return 1;
  396. }
  397. - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
  398. return [self.dataArray count];
  399. }
  400. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
  401. id obj = [self.dataArray objectAtIndex:indexPath.row];
  402. NSString *cellString = nil;
  403. if ([obj isKindOfClass:[NSString class]]) {
  404. cellString = (NSString *)obj;
  405. } else if ([obj isKindOfClass:[EMMessageModel class]]) {
  406. EMMessageModel *model = (EMMessageModel *)obj;
  407. if (model.type == EMMessageTypeExtRecall) {
  408. cellString = @"您撤回一条消息";
  409. }
  410. }
  411. if ([cellString length] > 0) {
  412. EMMessageTimeCell *cell = (EMMessageTimeCell *)[tableView dequeueReusableCellWithIdentifier:@"EMMessageTimeCell"];
  413. // Configure the cell...
  414. if (cell == nil || !cell) {
  415. cell = [[EMMessageTimeCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"EMMessageTimeCell"];
  416. }
  417. cell.timeLabel.text = cellString;
  418. return cell;
  419. } else {
  420. EMMessageModel *model = (EMMessageModel *)obj;
  421. if ([[model.emModel.ext objectForKey:@"app"] boolValue]) {
  422. model.type = EMMessageTypeExtApp;
  423. }
  424. NSString *identifier = [EMMessageCell cellIdentifierWithDirection:model.direction type:model.type];
  425. EMMessageCell *cell = (EMMessageCell *)[tableView dequeueReusableCellWithIdentifier:identifier];
  426. // Configure the cell...
  427. if (cell == nil || !cell) {
  428. cell = [[EMMessageCell alloc] initWithDirection:model.direction type:model.type];
  429. }
  430. cell.delegate = self;
  431. if (self.chatType == ChatType_SingleChat) {
  432. if (model.emModel.direction == EMMessageDirectionSend){
  433. [cell setIconUrl:[AppUserModel sharedAppUserModel].AvatarUrl];
  434. }else{
  435. [cell setIconUrl:self.ReceiveIcon];
  436. }
  437. }else{
  438. [self.groupUserInfoArray enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
  439. if ([obj isKindOfClass:[NSDictionary class]]) {
  440. if ([[obj objectForKey:@"ImId"] integerValue] == [model.emModel.from integerValue]) {
  441. [cell setIconUrl:[obj objectForKey:@"AvatarUrl"]];
  442. }
  443. }
  444. }];
  445. }
  446. cell.model = model;
  447. return cell;
  448. }
  449. }
  450. #pragma mark - UIScrollViewDelegate
  451. - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
  452. {
  453. [self.view endEditing:YES];
  454. [self.chatBar clearMoreViewAndSelectedButton];
  455. }
  456. #pragma mark - UIImagePickerControllerDelegate
  457. - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
  458. {
  459. NSString *mediaType = info[UIImagePickerControllerMediaType];
  460. if ([mediaType isEqualToString:(NSString *)kUTTypeMovie]) {
  461. NSURL *videoURL = info[UIImagePickerControllerMediaURL];
  462. // we will convert it to mp4 format
  463. NSURL *mp4 = [self _videoConvert2Mp4:videoURL];
  464. NSFileManager *fileman = [NSFileManager defaultManager];
  465. if ([fileman fileExistsAtPath:videoURL.path]) {
  466. NSError *error = nil;
  467. [fileman removeItemAtURL:videoURL error:&error];
  468. if (error) {
  469. NSLog(@"failed to remove file, error:%@.", error);
  470. }
  471. }
  472. [self _sendVideoAction:mp4];
  473. } else {
  474. NSURL *url = info[UIImagePickerControllerReferenceURL];
  475. if (url == nil) {
  476. UIImage *orgImage = info[UIImagePickerControllerOriginalImage];
  477. NSData *data = UIImageJPEGRepresentation(orgImage, 1);
  478. [self _sendImageDataAction:data];
  479. } else {
  480. if ([[UIDevice currentDevice].systemVersion doubleValue] >= 9.0f) {
  481. PHFetchResult *result = [PHAsset fetchAssetsWithALAssetURLs:@[url] options:nil];
  482. [result enumerateObjectsUsingBlock:^(PHAsset *asset , NSUInteger idx, BOOL *stop){
  483. if (asset) {
  484. [[PHImageManager defaultManager] requestImageDataForAsset:asset options:nil resultHandler:^(NSData *data, NSString *uti, UIImageOrientation orientation, NSDictionary *dic){
  485. if (data != nil) {
  486. [self _sendImageDataAction:data];
  487. } else {
  488. SHOWERROR(@"图片太大,请选择其他图片");
  489. }
  490. }];
  491. }
  492. }];
  493. } else {
  494. ALAssetsLibrary *alasset = [[ALAssetsLibrary alloc] init];
  495. [alasset assetForURL:url resultBlock:^(ALAsset *asset) {
  496. if (asset) {
  497. ALAssetRepresentation* assetRepresentation = [asset defaultRepresentation];
  498. Byte *buffer = (Byte*)malloc((size_t)[assetRepresentation size]);
  499. NSUInteger bufferSize = [assetRepresentation getBytes:buffer fromOffset:0.0 length:(NSUInteger)[assetRepresentation size] error:nil];
  500. NSData *fileData = [NSData dataWithBytesNoCopy:buffer length:bufferSize freeWhenDone:YES];
  501. [self _sendImageDataAction:fileData];
  502. }
  503. } failureBlock:NULL];
  504. }
  505. }
  506. }
  507. [picker dismissViewControllerAnimated:YES completion:nil];
  508. }
  509. - (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
  510. {
  511. [self.imagePicker dismissViewControllerAnimated:YES completion:nil];
  512. }
  513. #pragma mark - EMChatBarDelegate
  514. - (void)_willInputAt:(EMTextView *)aInputView
  515. {
  516. do {
  517. if (self.conversationModel.emModel.type != EMConversationTypeGroupChat) {
  518. break;
  519. }
  520. NSString *text = aInputView.text;
  521. // if (![text hasSuffix:@"@"]) {
  522. // break;
  523. // }
  524. EMGroup *group = [EMGroup groupWithId:self.conversationModel.emModel.conversationId];
  525. if (!group) {
  526. break;
  527. }
  528. [self.view endEditing:YES];
  529. EMAtGroupMembersViewController *controller = [[EMAtGroupMembersViewController alloc] initWithGroup:group];
  530. [self.navigationController pushViewController:controller animated:YES];
  531. [controller setSelectedCompletion:^(NSString * _Nonnull aName) {
  532. NSString *newStr = [NSString stringWithFormat:@"%@%@ ", text, aName];
  533. aInputView.text = newStr;
  534. aInputView.selectedRange = NSMakeRange(newStr.length, 0);
  535. [aInputView becomeFirstResponder];
  536. }];
  537. } while (0);
  538. }
  539. - (BOOL)inputView:(EMTextView *)aInputView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
  540. {
  541. self.isWillInputAt = NO;
  542. if ([text isEqualToString:@"\n"]) {
  543. [self _sendTextAction:aInputView.text ext:nil];
  544. return NO;
  545. } else if ([text isEqualToString:@"@"]) {
  546. self.isWillInputAt = YES;
  547. } else if ([text length] == 0) {
  548. }
  549. return YES;
  550. }
  551. - (void)inputViewDidChange:(EMTextView *)aInputView
  552. {
  553. if (self.isWillInputAt && self.conversationModel.emModel.type == EMConversationTypeGroupChat) {
  554. NSString *text = aInputView.text;
  555. if ([text hasSuffix:@"@"]) {
  556. self.isWillInputAt = NO;
  557. [self _willInputAt:aInputView];
  558. }
  559. }
  560. if (self.enableTyping) {
  561. if (!self.isTyping) {
  562. self.isTyping = YES;
  563. [self _sendBeginTyping];
  564. }
  565. }
  566. }
  567. - (void)chatBarClickMoreType:(SmartBarType)type
  568. {
  569. WS(weakSelf);
  570. switch (type) {
  571. case SmartBarPhoto:
  572. {
  573. [self chatBarDidPhotoAction];
  574. }
  575. break;
  576. case SmartBarCamera:
  577. {
  578. [self chatBarDidCameraAction];
  579. }
  580. break;
  581. case SmartBarNotes:
  582. {
  583. [[FWZGetNoteBookTool sharedTool] openNoteBookListChooseNoteBookBlock:^(NSMutableArray<MyNoteBookSubModel *> * _Nonnull noteArr) {
  584. NSLog(@"SmartBarNotes %@",noteArr);
  585. for (MyNoteBookSubModel * model in noteArr) {
  586. switch (model.AttributeValue) {
  587. case 1:
  588. {
  589. [weakSelf _sendTextAction:@"笔记" ext:@{@"app":@(YES),
  590. @"app_type":@(CollectModel_NoteBook),
  591. @"app_title":model.Title,
  592. @"app_id":@(model.MiddleId),
  593. @"app_content":@"来自-笔记",
  594. @"app_sourceUserId":@(model.SourceUserId == 0 ? [AppUserModel sharedAppUserModel].Id : model.SourceUserId),
  595. @"app_min_url":@"",
  596. @"app_url":@""
  597. }];
  598. }
  599. break;
  600. default:
  601. {
  602. [weakSelf _sendTextAction:@"笔记" ext:@{@"app":@(YES),
  603. @"app_type":@(CollectModel_NoteFile),
  604. @"app_title":model.FolderName,
  605. @"app_id":@(model.Id),
  606. @"app_sourceUserId":@(model.SourceUserId == 0 ? [AppUserModel sharedAppUserModel].Id : model.SourceUserId),
  607. @"app_content":@"来自-笔记",
  608. @"app_min_url":@"",
  609. @"app_url":@""
  610. }];
  611. }
  612. break;
  613. }
  614. }
  615. }];
  616. }
  617. break;
  618. case SmartBarCollection:
  619. {
  620. [[FWZGetNoteBookTool sharedTool] openCollectListChooseCollectBlock:^(NSMutableArray<MyFavoriteSubModel *> * _Nonnull collectArr) {
  621. NSLog(@"SmartBarCollection %@",collectArr);
  622. for (MyFavoriteSubModel * model in collectArr) {
  623. [weakSelf sendExtWithCollectModel:model];
  624. }
  625. }];
  626. }
  627. break;
  628. case SmartBarFile:
  629. {
  630. [self chatBarDidFileAction];
  631. }
  632. break;
  633. default:
  634. break;
  635. }
  636. }
  637. - (void)sendExtWithCollectModel:(MyFavoriteSubModel *)model
  638. {
  639. NSString * text = @"";
  640. switch (model.CollectionType) {
  641. case CollectModel_NewTopic:
  642. text = @"话题";
  643. break;
  644. case CollectModel_Toipc:
  645. text = @"小组话题";
  646. break;
  647. case CollectModel_Notice:
  648. text = @"通知";
  649. break;
  650. case CollectModel_NoteBook:
  651. text = @"笔记";
  652. break;
  653. case CollectModel_CollectFile:
  654. text = @"文件夹";
  655. break;
  656. case CollectModel_NoteFile:
  657. text = @"文件夹";
  658. break;
  659. case CollectModel_file:
  660. text = @"文件";
  661. break;
  662. case CollectModel_Image:
  663. text = @"图片";
  664. break;
  665. case CollectModel_meetMian:
  666. text = @"会议纪要";
  667. break;
  668. case CollectModel_InterMail:
  669. text = @"站内信";
  670. break;
  671. case CollectModel_NoSignMail:
  672. text = @"站内信";
  673. break;
  674. default:
  675. text = @"话题";
  676. break;
  677. }
  678. switch (model.AttributeValue) {
  679. case 1:
  680. {
  681. [self _sendTextAction:text ext:@{@"app":@(YES),
  682. @"app_type":@(model.CollectionType),
  683. @"app_title":model.Title,
  684. @"app_content":@"来自-收藏",
  685. @"app_sourceUserId":@(model.SourceUserId == 0 ? [AppUserModel sharedAppUserModel].Id : model.SourceUserId),
  686. @"app_id":@(model.CollectionDataId),
  687. @"app_min_url":model.Data.MinFile,
  688. @"app_url":model.Data.File
  689. }];
  690. }
  691. break;
  692. default:
  693. {
  694. [self _sendTextAction:text ext:@{@"app":@(YES),
  695. @"app_type":@(CollectModel_CollectFile),
  696. @"app_title":model.FolderName,
  697. @"app_content":@"来自-收藏",
  698. @"app_sourceUserId":@(model.SourceUserId == 0 ? [AppUserModel sharedAppUserModel].Id : model.SourceUserId),
  699. @"app_id":@(model.Id),
  700. @"app_min_url":model.Data.MinFile,
  701. @"app_url":model.Data.File
  702. }];
  703. }
  704. break;
  705. }
  706. }
  707. - (void)chatBarDidPhotoAction
  708. {
  709. WS(weakSelf);
  710. [self.view endEditing:YES];
  711. TZImagePickerController *imagePickerVc = [[TZImagePickerController alloc] initWithMaxImagesCount:9 delegate:nil];
  712. [imagePickerVc setNavLeftBarButtonSettingBlock:^(UIButton *leftButton){
  713. leftButton.hidden = YES;
  714. }];
  715. imagePickerVc.showSelectBtn = NO;
  716. imagePickerVc.allowCrop = YES;
  717. imagePickerVc.cropRect = CGRectMake(0, (SCREEN_HEIGHT - SCREEN_WIDTH) * 0.5, SCREEN_WIDTH, SCREEN_WIDTH);
  718. imagePickerVc.allowTakePicture = NO;
  719. imagePickerVc.allowTakeVideo = NO;
  720. imagePickerVc.allowPickingOriginalPhoto = NO;
  721. imagePickerVc.allowPickingGif = NO;
  722. [imagePickerVc setIsStatusBarDefault:YES];
  723. [imagePickerVc setNaviTitleColor:[UIColor blackColor]];
  724. [imagePickerVc setBarItemTextColor:[UIColor blackColor]];
  725. [imagePickerVc setDidFinishPickingPhotosHandle:^(NSArray<UIImage *> *photos, NSArray *assets, BOOL isSelectOriginalPhoto) {
  726. // if (assets.count > 0) {
  727. // for (PHAsset *asset in assets) {
  728. // PHVideoRequestOptions *options = [[PHVideoRequestOptions alloc] init];
  729. // options.version = PHImageRequestOptionsVersionCurrent;
  730. // options.deliveryMode = PHVideoRequestOptionsDeliveryModeAutomatic;
  731. // PHImageManager *manager = [PHImageManager defaultManager];
  732. // [manager requestAVAssetForVideo:asset options:options resultHandler:^(AVAsset * _Nullable asset, AVAudioMix * _Nullable audioMix, NSDictionary * _Nullable info) {
  733. // AVURLAsset *urlAsset = (AVURLAsset *)asset;
  734. // NSURL *url = urlAsset.URL;
  735. // [weakSelf _sendVideoAction:url];
  736. // }];
  737. // }
  738. // }
  739. if (photos.count > 0) {
  740. for (UIImage * image in photos) {
  741. NSData *data = UIImageJPEGRepresentation(image, 1);
  742. [weakSelf _sendImageDataAction:data];
  743. }
  744. }
  745. }];
  746. [self presentViewController:imagePickerVc animated:YES completion:nil];
  747. }
  748. - (void)chatBarDidCameraAction
  749. {
  750. [self.view endEditing:YES];
  751. //#if TARGET_IPHONE_SIMULATOR
  752. // [EMAlertController showErrorAlert:@"模拟器不支持照相机"];
  753. //#elif TARGET_OS_IPHONE
  754. self.imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
  755. self.imagePicker.mediaTypes = @[(NSString *)kUTTypeImage, (NSString *)kUTTypeMovie];
  756. [self presentViewController:self.imagePicker animated:YES completion:nil];
  757. //#endif
  758. }
  759. - (void)chatBarDidFileAction
  760. {
  761. WS(weakSelf);
  762. [[FWZFileGetTool sharedTool] openFileWithCrop:YES showImgBlock:^(NSString * _Nonnull fileUrlStr) {
  763. } choosFileBlock:^(NSData * _Nonnull fileData, NSString * _Nonnull fileName) {
  764. // EMFileMessageBody * body = [[EMFileMessageBody alloc] initWithData:fileData displayName:fileName];
  765. // [weakSelf _sendMessageWithBody:body ext:nil isUpload:YES];
  766. SHOWLOADING
  767. [[HttpManager sharedHttpManager] HeaderUploadFileUrl:Host(Modify_UserImages_Post) parameters:@{} fileData:fileData fileKey:@"file" fileName:fileName mimeType:@"multipart/form-data" success:^(id _Nonnull responseObject) {
  768. REMOVESHOW
  769. NSDictionary * dict = responseObject[0];
  770. if ([dict[@"FileType"] isEqualToString:@"image"]) {
  771. [weakSelf _sendImageDataAction:fileData];
  772. }else{
  773. [weakSelf _sendTextAction:@"文件" ext:@{@"app":@(YES),
  774. @"app_type":@(CollectModel_file),
  775. @"app_title":fileName,
  776. @"app_content":@"来自-文件夹",
  777. @"app_sourceUserId":@([AppUserModel sharedAppUserModel].Id),
  778. @"app_id":@([dict[@"FileId"] integerValue]),
  779. @"app_min_url":dict[@"MinAbsolutePath"],
  780. @"app_url":dict[@"AbsolutePath"]
  781. }];
  782. }
  783. } failure:^(NSError * _Nonnull error) {
  784. REMOVESHOW
  785. }];
  786. }];
  787. }
  788. - (void)chatBarDidLocationAction
  789. {
  790. EMLocationViewController *controller = [[EMLocationViewController alloc] init];
  791. [controller setSendCompletion:^(CLLocationCoordinate2D aCoordinate, NSString * _Nonnull aAddress) {
  792. [self _sendLocationAction:aCoordinate address:aAddress];
  793. }];
  794. UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:controller];
  795. [self.navigationController presentViewController:navController animated:YES completion:nil];
  796. }
  797. - (void)chatBarDidCallAction
  798. {
  799. self.alertController = [UIAlertController alertControllerWithTitle:@"实时通话类型" message:nil preferredStyle:UIAlertControllerStyleActionSheet];
  800. __weak typeof(self) weakself = self;
  801. if (self.conversationModel.emModel.type == EMConversationTypeChat) {
  802. [self.alertController addAction:[UIAlertAction actionWithTitle:@"语音通话" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
  803. [weakself.chatBar clearMoreViewAndSelectedButton];
  804. [[NSNotificationCenter defaultCenter] postNotificationName:CALL_MAKE1V1 object:@{CALL_CHATTER:weakself.conversationModel.emModel.conversationId, CALL_TYPE:@(EMCallTypeVoice)}];
  805. }]];
  806. [self.alertController addAction:[UIAlertAction actionWithTitle:@"视频通话" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
  807. [weakself.chatBar clearMoreViewAndSelectedButton];
  808. [[NSNotificationCenter defaultCenter] postNotificationName:CALL_MAKE1V1 object:@{CALL_CHATTER:weakself.conversationModel.emModel.conversationId, CALL_TYPE:@(EMCallTypeVideo)}];
  809. }]];
  810. } else {
  811. [self.alertController addAction:[UIAlertAction actionWithTitle:@"会议模式" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
  812. [weakself.chatBar clearMoreViewAndSelectedButton];
  813. [[NSNotificationCenter defaultCenter] postNotificationName:CALL_MAKECONFERENCE object:@{CALL_TYPE:@(EMConferenceTypeLargeCommunication), CALL_MODEL:weakself.conversationModel, NOTIF_NAVICONTROLLER:self.navigationController}];
  814. }]];
  815. [self.alertController addAction:[UIAlertAction actionWithTitle:@"互动模式" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
  816. [weakself.chatBar clearMoreViewAndSelectedButton];
  817. [[NSNotificationCenter defaultCenter] postNotificationName:CALL_MAKECONFERENCE object:@{CALL_TYPE:@(EMConferenceTypeLive), CALL_MODEL:weakself.conversationModel, NOTIF_NAVICONTROLLER:self.navigationController}];
  818. }]];
  819. }
  820. [self.alertController addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
  821. }]];
  822. [[NSNotificationCenter defaultCenter] postNotificationName:@"didAlert" object:@{@"alert":self.alertController}];
  823. [self presentViewController:self.alertController animated:YES completion:nil];
  824. }
  825. //阅读回执跳转
  826. - (void)chatBarMoreFunctionReadReceipt
  827. {
  828. self.readReceiptControl = [[EMReadReceiptMsgViewController alloc]init];
  829. self.readReceiptControl.delegate = self;
  830. self.readReceiptControl.modalPresentationStyle = 0;
  831. //[self.navigationController pushViewController:readReceipt animated:NO];
  832. [self presentViewController:self.readReceiptControl animated:NO completion:nil];
  833. }
  834. //阅读回执发送信息
  835. - (void)sendReadReceiptMsg:(NSString *)msg
  836. {
  837. NSString *str = msg;
  838. NSLog(@"\n%@",str);
  839. if (self.conversationModel.emModel.type == EMConversationTypeGroupChat) {
  840. [[EMClient sharedClient].groupManager getGroupSpecificationFromServerWithId:self.conversationModel.emModel.conversationId completion:^(EMGroup *aGroup, EMError *aError) {
  841. NSLog(@"\n -------- sendError: %@",aError);
  842. if (!aError) {
  843. self.group = aGroup;
  844. //是群主才可以发送阅读回执信息
  845. [self _sendTextAction:str ext:@{MSG_EXT_READ_RECEIPT:@"receipt"}];
  846. } else {
  847. SHOWERROR(@"获取群组失败");
  848. }
  849. }];
  850. }else {
  851. [self _sendTextAction:str ext:nil];
  852. }
  853. }
  854. - (void)chatBarDidShowMoreViewAction:(BOOL)isKeyBord
  855. {
  856. WS(weakSelf);
  857. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  858. dispatch_async(dispatch_get_main_queue(), ^{
  859. [weakSelf.tableView mas_updateConstraints:^(MASConstraintMaker *make) {
  860. make.bottom.mas_equalTo(weakSelf.chatBar.mas_top);
  861. }];
  862. [weakSelf performSelector:@selector(_scrollToBottomRow) withObject:nil afterDelay:0.1];
  863. });
  864. });
  865. }
  866. #pragma mark - EMChatBarRecordAudioViewDelegate
  867. - (void)chatBarRecordAudioViewStartRecord
  868. {
  869. }
  870. - (void)chatBarRecordAudioViewStopRecord:(NSString *)aPath
  871. timeLength:(NSInteger)aTimeLength
  872. {
  873. EMVoiceMessageBody *body = [[EMVoiceMessageBody alloc] initWithLocalPath:aPath displayName:@"audio"];
  874. body.duration = (int)aTimeLength;
  875. if(body.duration < 1){
  876. [self showHint:@"按键时间太短."];
  877. return;
  878. }
  879. [self _sendMessageWithBody:body ext:nil isUpload:YES];
  880. }
  881. - (void)chatBarRecordAudioViewCancelRecord
  882. {
  883. }
  884. #pragma mark - EMChatBarEmoticonViewDelegate
  885. - (void)didSelectedEmoticonModel:(EMEmoticonModel *)aModel
  886. {
  887. if (aModel.type == EMEmotionTypeEmoji) {
  888. [self.chatBar inputViewAppendText:aModel.name];
  889. } if (aModel.type == EMEmotionTypeGif) {
  890. NSDictionary *ext = @{MSG_EXT_GIF:@(YES), MSG_EXT_GIF_ID:aModel.eId};
  891. [self _sendTextAction:aModel.name ext:ext];
  892. }
  893. }
  894. - (void)didChatBarEmoticonViewSendAction
  895. {
  896. [self _sendTextAction:self.chatBar.textView.text ext:nil];
  897. }
  898. #pragma mark - EMMessageCellDelegate
  899. //阅读回执详情
  900. - (void)messageReadReceiptDetil:(EMMessageCell *)aCell
  901. {
  902. self.readReceiptControl = [[EMReadReceiptMsgViewController alloc] initWithMessageCell:aCell groupId:self.conversationModel.emModel.conversationId];
  903. self.readReceiptControl.modalPresentationStyle = 0;
  904. //[self.navigationController pushViewController:readReceiptControl animated:NO];
  905. [self presentViewController:self.readReceiptControl animated:NO completion:nil];
  906. }
  907. - (void)messageCellDidSelected:(EMMessageCell *)aCell
  908. {
  909. if (aCell.model.type == EMMessageTypeImage) {
  910. [self _imageMessageCellDidSelected:aCell];
  911. } else if (aCell.model.type == EMMessageTypeLocation) {
  912. [self _locationMessageCellDidSelected:aCell];
  913. } else if (aCell.model.type == EMMessageTypeVoice) {
  914. [self _audioMessageCellDidSelected:aCell];
  915. } else if (aCell.model.type == EMMessageTypeVideo) {
  916. [self _videoMessageCellDidSelected:aCell];
  917. } else if (aCell.model.type == EMMessageTypeFile) {
  918. [self _fileMessageCellDidSelected:aCell];
  919. } else if (aCell.model.type == EMMessageTypeExtCall) {
  920. [self _callMessageCellDidSelected:aCell];
  921. } else if (aCell.model.type == EMMessageTypeExtApp) {
  922. [self appPushWithDictionary:aCell.model.emModel.ext];
  923. } else if (aCell.model.type == EMMessageTypeText) {
  924. }
  925. }
  926. - (void)messageClickUserIcon:(EMMessageCell *)aCell
  927. {
  928. WS(weakSelf);
  929. EMMessage * eModel = (EMMessage *)aCell.model.emModel;
  930. if (self.chatType == ChatType_SingleChat) {
  931. if (eModel.direction == EMMessageDirectionSend){
  932. self.UserId = [AppUserModel sharedAppUserModel].Id;
  933. }else{
  934. self.UserId = self.toUserId;
  935. }
  936. }else{
  937. [self.groupUserInfoArray enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
  938. if ([obj isKindOfClass:[NSDictionary class]]) {
  939. if ([[obj objectForKey:@"ImId"] integerValue] == [eModel.from integerValue]) {
  940. weakSelf.UserId = [[obj objectForKey:@"UserId"] integerValue];
  941. }
  942. }
  943. }];
  944. }
  945. MailListDetailVC * vc = [MailListDetailVC initMailListDetailVC];
  946. vc.indexId = self.UserId;
  947. [self.navigationController pushViewController:vc animated:YES];
  948. }
  949. #pragma mark - 点击自定义消息体
  950. - (void)appPushWithDictionary:(NSDictionary *)dict
  951. {
  952. WS(weakSelf);
  953. CollectModelType type = [[dict objectForKey:@"app_type"] intValue];
  954. NSInteger sourceUserId = [[dict objectForKey:@"app_sourceUserId"] integerValue];
  955. NSInteger Id = [[dict objectForKey:@"app_id"] integerValue];
  956. NSString * title = [dict objectForKey:@"app_title"];
  957. NSString * url = [dict objectForKey:@"app_url"];
  958. switch (type) {
  959. case CollectModel_Group:
  960. {
  961. TDGroupInfoListVC * vc = [TDGroupInfoListVC initTDGroupInfoListVC];
  962. vc.GroupId = Id;
  963. vc.titleStr = title;
  964. [self.navigationController pushViewController:vc animated:YES];
  965. }break;
  966. case CollectModel_file:{
  967. DownFileViewController * vc = [[DownFileViewController alloc] init];
  968. FlowAttachmentsModel * model = [[FlowAttachmentsModel alloc] init];
  969. model.Title = title;
  970. model.SoureId = Id;
  971. model.Url = url;
  972. model.MinUrl = dict[@"app_min_url"];
  973. vc.model = model;
  974. [self.navigationController pushViewController:vc animated:YES];
  975. }break;
  976. case CollectModel_Image:{
  977. DownFileViewController * vc = [[DownFileViewController alloc] init];
  978. FlowAttachmentsModel * model = [[FlowAttachmentsModel alloc] init];
  979. model.Title = title;
  980. model.SoureId = Id;
  981. model.Url = url;
  982. model.MinUrl = dict[@"app_min_url"];
  983. vc.model = model;
  984. [self.navigationController pushViewController:vc animated:YES];
  985. }break;
  986. case CollectModel_Aritle:{
  987. SHOWLOADING
  988. [[HttpManager sharedHttpManager] GETWithUrl:[NSString stringWithFormat:@"%@%ld",Article_Detail_Get,(long)Id] parameters:@{} success:^(id _Nonnull responseObject) {
  989. REMOVESHOW;
  990. Item *itemModel = [[Item alloc]initWithDictionary:responseObject error:nil];
  991. MyTDTopicDetailVC * vc = [MyTDTopicDetailVC initMyTDTopicDetailVC];
  992. vc.type = CollectModel_Aritle;
  993. vc.Id = itemModel.Id;
  994. [weakSelf.navigationController pushViewController:vc animated:YES];
  995. } failure:^(NSError * _Nonnull error) {
  996. SHOWERROR([ZYCTool handerResultData:error]);
  997. }];
  998. }break;
  999. case CollectModel_Text:{
  1000. SHOWLOADING
  1001. [[HttpManager sharedHttpManager] GETWithUrl:[NSString stringWithFormat:@"%@%ld",Article_Detail_Get,(long)Id] parameters:@{} success:^(id _Nonnull responseObject) {
  1002. REMOVESHOW;
  1003. Item *itemModel = [[Item alloc]initWithDictionary:responseObject error:nil];
  1004. MyTDTopicDetailVC * vc = [MyTDTopicDetailVC initMyTDTopicDetailVC];
  1005. vc.type = CollectModel_Aritle;
  1006. vc.Id = itemModel.Id;
  1007. [weakSelf.navigationController pushViewController:vc animated:YES];
  1008. } failure:^(NSError * _Nonnull error) {
  1009. SHOWERROR([ZYCTool handerResultData:error]);
  1010. }];
  1011. }break;
  1012. case CollectModel_Notice:{
  1013. MyTDTopicDetailVC * vc = [MyTDTopicDetailVC initMyTDTopicDetailVC];
  1014. vc.type = CollectModel_Notice;
  1015. vc.Id = Id;
  1016. [self.navigationController pushViewController:vc animated:YES];
  1017. }break;
  1018. case CollectModel_Toipc:{
  1019. MyTDTopicDetailVC * vc = [MyTDTopicDetailVC initMyTDTopicDetailVC];
  1020. vc.type = CollectModel_Toipc;
  1021. vc.Id = Id;
  1022. [self.navigationController pushViewController:vc animated:YES];
  1023. }break;
  1024. case CollectModel_NewTopic:{
  1025. MyTDTopicDetailVC * vc = [MyTDTopicDetailVC initMyTDTopicDetailVC];
  1026. vc.type = CollectModel_NewTopic;
  1027. vc.Id = Id;
  1028. [self.navigationController pushViewController:vc animated:YES];
  1029. }break;
  1030. case CollectModel_NoteBook:{
  1031. MyTDTopicDetailVC * vc = [MyTDTopicDetailVC initMyTDTopicDetailVC];
  1032. vc.type = CollectModel_NoteBook;
  1033. vc.Id = Id;
  1034. [self.navigationController pushViewController:vc animated:YES];
  1035. }break;
  1036. case CollectModel_Collect:{
  1037. }break;
  1038. case CollectModel_CollectFile:{
  1039. if (sourceUserId == [AppUserModel sharedAppUserModel].Id || sourceUserId == 0) {
  1040. MyFavoriteVC *vc = [MyFavoriteVC initMyFavoriteVC];
  1041. vc.listType = Id == 0 ? MyFavoriteListLevelTypeA : MyFavoriteListLevelTypeB;
  1042. vc.FolderId = Id;
  1043. vc.myTitle = title;
  1044. [self.navigationController pushViewController:vc animated:YES];
  1045. }else{
  1046. OtherFavoriteVC *vc = [OtherFavoriteVC initOtherFavoriteVC];
  1047. vc.listType = Id == 0 ? MyFavoriteListLevelTypeA : MyFavoriteListLevelTypeB;
  1048. vc.FolderId = Id;
  1049. vc.myTitle = title;
  1050. vc.VisitUserId = sourceUserId;
  1051. [self.navigationController pushViewController:vc animated:YES];
  1052. }
  1053. }break;
  1054. case CollectModel_NoteFile:{
  1055. if (sourceUserId == [AppUserModel sharedAppUserModel].Id || sourceUserId == 0) {
  1056. NoteBookVC *vc = [NoteBookVC initNoteBookVC];
  1057. vc.listType = Id == 0 ? MyFavoriteListLevelTypeA : MyFavoriteListLevelTypeB;
  1058. vc.FolderId = Id;
  1059. vc.myTitle = title;
  1060. vc.VisitUserId = 0;
  1061. [self.navigationController pushViewController:vc animated:YES];
  1062. }else{
  1063. OtherNoteBookVC *vc = [OtherNoteBookVC initOtherNoteBookVC];
  1064. vc.listType = Id == 0 ? MyFavoriteListLevelTypeA : MyFavoriteListLevelTypeB;
  1065. vc.FolderId = Id;
  1066. vc.myTitle = title;
  1067. vc.VisitUserId = sourceUserId;
  1068. [self.navigationController pushViewController:vc animated:YES];
  1069. }
  1070. }break;
  1071. case CollectModel_TopicBooK:{
  1072. if (sourceUserId == [AppUserModel sharedAppUserModel].Id || sourceUserId == 0) {
  1073. NoteBookVC *vc = [NoteBookVC initNoteBookVC];
  1074. vc.listType = MyFavoriteListLevelTypeA;
  1075. vc.FolderId = Id;
  1076. vc.myTitle = title;
  1077. vc.VisitUserId = 0;
  1078. vc.TypeValue = 1;
  1079. [self.navigationController pushViewController:vc animated:YES];
  1080. }else{
  1081. OtherNoteBookVC * vc = [OtherNoteBookVC initOtherNoteBookVC];
  1082. vc.listType = MyFavoriteListLevelTypeA ;
  1083. vc.FolderId = Id;
  1084. vc.CollectionDataId = Id;
  1085. vc.CollectionType = CollectModel_TopicBooK;
  1086. vc.TypeValue = 1;
  1087. vc.myTitle = title;
  1088. vc.VisitUserId = sourceUserId;
  1089. [self.navigationController pushViewController:vc animated:YES];
  1090. }
  1091. }break;
  1092. case CollectModel_TopicSubBooK:{
  1093. if (sourceUserId == [AppUserModel sharedAppUserModel].Id || sourceUserId == 0) {
  1094. NoteBookVC *vc = [NoteBookVC initNoteBookVC];
  1095. vc.listType = MyFavoriteListLevelTypeB;
  1096. vc.FolderId = Id;
  1097. vc.myTitle = title;
  1098. vc.TypeValue = 1;
  1099. [self.navigationController pushViewController:vc animated:YES];
  1100. }else{
  1101. OtherNoteBookVC * vc = [OtherNoteBookVC initOtherNoteBookVC];
  1102. vc.listType = MyFavoriteListLevelTypeB ;
  1103. vc.FolderId = Id;
  1104. vc.CollectionDataId = Id;
  1105. vc.CollectionType = CollectModel_TopicSubBooK;
  1106. vc.TypeValue = 1;
  1107. vc.myTitle = title;
  1108. vc.VisitUserId = sourceUserId;
  1109. [self.navigationController pushViewController:vc animated:YES];
  1110. }
  1111. }break;
  1112. case CollectModel_InterMail:{
  1113. MyTDTopicDetailVC * vc = [MyTDTopicDetailVC initMyTDTopicDetailVC];
  1114. vc.type = CollectModel_InterMail;
  1115. vc.Id = Id;
  1116. [self.navigationController pushViewController:vc animated:YES];
  1117. }break;
  1118. case CollectModel_NoSignMail:{
  1119. MyTDTopicDetailVC * vc = [MyTDTopicDetailVC initMyTDTopicDetailVC];
  1120. vc.type = CollectModel_InterMail;
  1121. vc.Id = Id;
  1122. [self.navigationController pushViewController:vc animated:YES];
  1123. }break;
  1124. case CollectModel_meetDetail:{
  1125. WorkFlowDetailsController *vc = [[WorkFlowDetailsController alloc] initWithId:Id];
  1126. [self.navigationController pushViewController:vc animated:YES];
  1127. }break;
  1128. case CollectModel_work:{
  1129. MyApprovalPageDetail * vc = [[MyApprovalPageDetail alloc]init];
  1130. vc.pageType = Type_ONEC;
  1131. vc.indexId = Id;
  1132. vc.title = title;
  1133. vc.TodoId = Id;
  1134. [self.navigationController pushViewController:vc animated:YES];
  1135. }break;
  1136. case CollectModel_StoreSound:
  1137. {
  1138. BookListenVC * vc = [BookListenVC initBookListenVC];
  1139. vc.Id = Id;
  1140. vc.MediaType = MediaMusicType;
  1141. [self.navigationController pushViewController:vc animated:YES];
  1142. }
  1143. break;
  1144. case CollectModel_StoreVideo:
  1145. {
  1146. BookWCDetailVC * vc = [BookWCDetailVC initBookWCDetailVC];
  1147. vc.Id = Id;
  1148. [self.navigationController pushViewController:vc animated:YES];
  1149. }
  1150. break;
  1151. case CollectModel_meetMian:{
  1152. MyTDTopicDetailVC * vc = [MyTDTopicDetailVC initMyTDTopicDetailVC];
  1153. vc.type = CollectModel_meetMian;
  1154. vc.Id = Id;
  1155. [self.navigationController pushViewController:vc animated:YES];
  1156. }break;
  1157. case CollectModel_financeCount:{
  1158. CountDataVC *vc = [CountDataVC initCountDataVC];
  1159. vc.index = 0;
  1160. vc.titleStr = @"财务统计";
  1161. [self.navigationController pushViewController:vc animated:YES];
  1162. }break;
  1163. case CollectModel_affairsCount:{
  1164. CountDataVC *vc = [CountDataVC initCountDataVC];
  1165. vc.index = 1;
  1166. vc.titleStr = @"人事统计";
  1167. [self.navigationController pushViewController:vc animated:YES];
  1168. }break;
  1169. case CollectModel_publishCount:{
  1170. CountDataVC *vc = [CountDataVC initCountDataVC];
  1171. vc.index = 2;
  1172. vc.titleStr = @"出版统计";
  1173. [self.navigationController pushViewController:vc animated:YES];
  1174. }break;
  1175. default:
  1176. break;
  1177. }
  1178. }
  1179. // OtherNoteBookVC * vc = [OtherNoteBookVC initOtherNoteBookVC];
  1180. // vc.listType = MyFavoriteListLevelTypeA ;
  1181. // vc.FolderId = model.CollectionDataId;
  1182. // vc.CollectionDataId = model.CollectionDataId;
  1183. // vc.CollectionType = model.CollectionType;
  1184. // vc.Author = model.Data.Author;
  1185. // vc.TypeValue = 1;
  1186. // vc.myTitle = model.Title;
  1187. // vc.VisitUserId = model.SourceUserId;
  1188. // [self.navigationController pushViewController:vc animated:YES];
  1189. //}break;
  1190. //case CollectModel_TopicSubBooK:{
  1191. // OtherNoteBookVC * vc = [OtherNoteBookVC initOtherNoteBookVC];
  1192. // vc.listType = MyFavoriteListLevelTypeB ;
  1193. // vc.FolderId = model.CollectionDataId;
  1194. // vc.CollectionDataId = model.CollectionDataId;
  1195. // vc.CollectionType = model.CollectionType;
  1196. // vc.Author = model.Data.Author;
  1197. // vc.TypeValue = 1;
  1198. // vc.myTitle = model.Title;
  1199. // vc.VisitUserId = model.SourceUserId;
  1200. // [self.navigationController pushViewController:vc animated:YES];
  1201. - (void)_imageMessageCellDidSelected:(EMMessageCell *)aCell
  1202. {
  1203. __weak typeof(self) weakself = self;
  1204. void (^downloadThumbBlock)(EMMessageModel *aModel) = ^(EMMessageModel *aModel) {
  1205. [weakself showHint:@"获取缩略图..."];
  1206. [[EMClient sharedClient].chatManager downloadMessageThumbnail:aModel.emModel progress:nil completion:^(EMMessage *message, EMError *error) {
  1207. if (!error) {
  1208. [weakself.tableView reloadData];
  1209. }
  1210. }];
  1211. };
  1212. EMImageMessageBody *body = (EMImageMessageBody*)aCell.model.emModel.body;
  1213. BOOL isCustomDownload = !([EMClient sharedClient].options.isAutoTransferMessageAttachments);
  1214. if (body.thumbnailDownloadStatus == EMDownloadStatusFailed) {
  1215. if (isCustomDownload) {
  1216. [self _showCustomTransferFileAlertView];
  1217. } else {
  1218. downloadThumbBlock(aCell.model);
  1219. }
  1220. return;
  1221. }
  1222. BOOL isAutoDownloadThumbnail = [EMClient sharedClient].options.isAutoDownloadThumbnail;
  1223. if (body.thumbnailDownloadStatus == EMDownloadStatusPending && !isAutoDownloadThumbnail) {
  1224. downloadThumbBlock(aCell.model);
  1225. return;
  1226. }
  1227. if (body.downloadStatus == EMDownloadStatusSucceed) {
  1228. UIImage *image = [UIImage imageWithContentsOfFile:body.localPath];
  1229. if (image) {
  1230. [[EMImageBrowser sharedBrowser] showImages:@[image] fromController:self];
  1231. return;
  1232. }
  1233. }
  1234. if (isCustomDownload) {
  1235. [self _showCustomTransferFileAlertView];
  1236. return;
  1237. }
  1238. [self showHudInView:self.view hint:@"下载原图..."];
  1239. [[EMClient sharedClient].chatManager downloadMessageAttachment:aCell.model.emModel progress:nil completion:^(EMMessage *message, EMError *error) {
  1240. [weakself hideHud];
  1241. if (error) {
  1242. SHOWERROR(@"下载原图失败");
  1243. } else {
  1244. if (message.direction == EMMessageDirectionReceive && !message.isReadAcked) {
  1245. [[EMClient sharedClient].chatManager sendMessageReadAck:message.messageId toUser:message.conversationId completion:nil];
  1246. }
  1247. NSString *localPath = [(EMImageMessageBody *)message.body localPath];
  1248. UIImage *image = [UIImage imageWithContentsOfFile:localPath];
  1249. if (image) {
  1250. [[EMImageBrowser sharedBrowser] showImages:@[image] fromController:self];
  1251. } else {
  1252. SHOWERROR(@"获取原图失败");
  1253. }
  1254. }
  1255. }];
  1256. }
  1257. - (void)_locationMessageCellDidSelected:(EMMessageCell *)aCell
  1258. {
  1259. EMLocationMessageBody *body = (EMLocationMessageBody *)aCell.model.emModel.body;
  1260. EMLocationViewController *controller = [[EMLocationViewController alloc] initWithLocation:CLLocationCoordinate2DMake(body.latitude, body.longitude)];
  1261. UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:controller];
  1262. [self.navigationController presentViewController:navController animated:YES completion:nil];
  1263. }
  1264. - (void)_audioMessageCellDidSelected:(EMMessageCell *)aCell
  1265. {
  1266. if (aCell.model.isPlaying) {
  1267. [[EMAudioPlayerHelper sharedHelper] stopPlayer];
  1268. aCell.model.isPlaying = NO;
  1269. [self.tableView reloadData];
  1270. return;
  1271. }
  1272. EMVoiceMessageBody *body = (EMVoiceMessageBody*)aCell.model.emModel.body;
  1273. if (body.downloadStatus == EMDownloadStatusDownloading) {
  1274. SHOWERROR(@"正在下载语音,稍后点击");
  1275. return;
  1276. }
  1277. __weak typeof(self) weakself = self;
  1278. void (^playBlock)(EMMessageModel *aModel) = ^(EMMessageModel *aModel) {
  1279. id model = [EMAudioPlayerHelper sharedHelper].model;
  1280. if (model && [model isKindOfClass:[EMMessageModel class]]) {
  1281. EMMessageModel *oldModel = (EMMessageModel *)model;
  1282. if (oldModel.isPlaying) {
  1283. oldModel.isPlaying = NO;
  1284. }
  1285. }
  1286. if (!aModel.emModel.isReadAcked) {
  1287. [[EMClient sharedClient].chatManager sendMessageReadAck:aModel.emModel.messageId toUser:aModel.emModel.conversationId completion:nil];
  1288. }
  1289. aModel.isPlaying = YES;
  1290. if (!aModel.emModel.isRead) {
  1291. aModel.emModel.isRead = YES;
  1292. }
  1293. [weakself.tableView reloadData];
  1294. [[EMAudioPlayerHelper sharedHelper] startPlayerWithPath:body.localPath model:aModel AVAudioSessionCategory:AVAudioSessionCategoryPlayback completion:^(NSError * _Nonnull error) {
  1295. aModel.isPlaying = NO;
  1296. [weakself.tableView reloadData];
  1297. }];
  1298. };
  1299. if (body.downloadStatus == EMDownloadStatusSucceed) {
  1300. playBlock(aCell.model);
  1301. return;
  1302. }
  1303. if (![EMClient sharedClient].options.isAutoTransferMessageAttachments) {
  1304. [self _showCustomTransferFileAlertView];
  1305. return;
  1306. }
  1307. [self showHudInView:self.view hint:@"下载语音..."];
  1308. [[EMClient sharedClient].chatManager downloadMessageAttachment:aCell.model.emModel progress:nil completion:^(EMMessage *message, EMError *error) {
  1309. [weakself hideHud];
  1310. if (error) {
  1311. SHOWERROR(@"下载语音失败");
  1312. } else {
  1313. playBlock(aCell.model);
  1314. }
  1315. }];
  1316. }
  1317. - (void)_videoMessageCellDidSelected:(EMMessageCell *)aCell
  1318. {
  1319. EMVideoMessageBody *body = (EMVideoMessageBody*)aCell.model.emModel.body;
  1320. NSFileManager *fileManager = [NSFileManager defaultManager];
  1321. BOOL isCustomDownload = !([EMClient sharedClient].options.isAutoTransferMessageAttachments);
  1322. if (body.thumbnailDownloadStatus == EMDownloadStatusFailed || ![fileManager fileExistsAtPath:body.thumbnailLocalPath]) {
  1323. [self showHint:@"下载缩略图"];
  1324. if (!isCustomDownload) {
  1325. [[EMClient sharedClient].chatManager downloadMessageThumbnail:aCell.model.emModel progress:nil completion:nil];
  1326. }
  1327. }
  1328. if (body.downloadStatus == EMDownloadStatusDownloading) {
  1329. SHOWERROR(@"正在下载视频,稍后点击");
  1330. return;
  1331. }
  1332. void (^playBlock)(NSString *aPath) = ^(NSString *aPathe) {
  1333. NSURL *videoURL = [NSURL fileURLWithPath:aPathe];
  1334. AVPlayerViewController *playerViewController = [[AVPlayerViewController alloc] init];
  1335. playerViewController.player = [AVPlayer playerWithURL:videoURL];
  1336. playerViewController.videoGravity = AVLayerVideoGravityResizeAspect;
  1337. playerViewController.showsPlaybackControls = YES;
  1338. [self presentViewController:playerViewController animated:YES completion:^{
  1339. [playerViewController.player play];
  1340. }];
  1341. };
  1342. if (body.downloadStatus == EMDownloadStatusSuccessed && [fileManager fileExistsAtPath:body.localPath]) {
  1343. playBlock(body.localPath);
  1344. return;
  1345. }
  1346. if (isCustomDownload) {
  1347. [self _showCustomTransferFileAlertView];
  1348. } else {
  1349. [self showHudInView:self.view hint:@"下载视频..."];
  1350. __weak typeof(self) weakself = self;
  1351. [[EMClient sharedClient].chatManager downloadMessageAttachment:aCell.model.emModel progress:nil completion:^(EMMessage *message, EMError *error) {
  1352. [weakself hideHud];
  1353. if (error) {
  1354. SHOWERROR(@"下载视频失败");
  1355. } else {
  1356. if (!message.isReadAcked) {
  1357. [[EMClient sharedClient].chatManager sendMessageReadAck:message.messageId toUser:message.conversationId completion:nil];
  1358. }
  1359. playBlock([(EMVideoMessageBody*)message.body localPath]);
  1360. }
  1361. }];
  1362. }
  1363. }
  1364. - (void)_fileMessageCellDidSelected:(EMMessageCell *)aCell
  1365. {
  1366. WS(weakSelf);
  1367. [[EMClient sharedClient].chatManager downloadMessageAttachment:aCell.model.emModel progress:nil completion:^(EMMessage *message, EMError *error) {
  1368. [weakSelf hideHud];
  1369. if (error) {
  1370. SHOWERROR(@"下载文件失败");
  1371. } else {
  1372. if (message.direction == EMMessageDirectionReceive && !message.isReadAcked) {
  1373. [[EMClient sharedClient].chatManager sendMessageReadAck:message.messageId toUser:message.conversationId completion:nil];
  1374. }
  1375. NSString *remotePath = [(EMImageMessageBody *)message.body remotePath];
  1376. NSString *displayName = [(EMImageMessageBody *)message.body displayName];
  1377. dispatch_async(dispatch_get_main_queue(), ^{
  1378. EMChatFileShowVC * vc = [EMChatFileShowVC initEMChatFileShowVC];
  1379. vc.fileUrl = remotePath;
  1380. vc.titleStr = displayName;
  1381. [weakSelf.navigationController pushViewController:vc animated:YES];
  1382. });
  1383. }
  1384. }];
  1385. }
  1386. - (void)_callMessageCellDidSelected:(EMMessageCell *)aCell
  1387. {
  1388. [[NSNotificationCenter defaultCenter] postNotificationName:CALL_SELECTCONFERENCECELL object:aCell.model.emModel];
  1389. }
  1390. - (void)messageCellDidLongPress:(EMMessageCell *)aCell
  1391. {
  1392. self.menuIndexPath = [self.tableView indexPathForCell:aCell];
  1393. [self _showMenuViewController:aCell model:aCell.model];
  1394. }
  1395. - (void)messageCellDidResend:(EMMessageModel *)aModel
  1396. {
  1397. if (aModel.emModel.status != EMMessageStatusFailed && aModel.emModel.status != EMMessageStatusPending) {
  1398. return;
  1399. }
  1400. __weak typeof(self) weakself = self;
  1401. [[[EMClient sharedClient] chatManager] resendMessage:aModel.emModel progress:nil completion:^(EMMessage *message, EMError *error) {
  1402. [weakself.tableView reloadData];
  1403. }];
  1404. [self.tableView reloadData];
  1405. }
  1406. #pragma mark - EMMultiDevicesDelegate
  1407. - (void)multiDevicesGroupEventDidReceive:(EMMultiDevicesEvent)aEvent
  1408. groupId:(NSString *)aGroupId
  1409. ext:(id)aExt
  1410. {
  1411. if (aEvent == EMMultiDevicesEventGroupDestroy || aEvent == EMMultiDevicesEventGroupLeave) {
  1412. if ([self.conversationModel.emModel.conversationId isEqualToString:aGroupId]) {
  1413. [self.navigationController popToViewController:self animated:YES];
  1414. [self.navigationController popViewControllerAnimated:YES];
  1415. }
  1416. }
  1417. }
  1418. #pragma mark - EMChatManagerDelegate
  1419. - (BOOL)_isNeedSendReadAckForMessage:(EMMessage *)aMessage
  1420. isMarkRead:(BOOL)aIsMarkRead
  1421. {
  1422. if (!self.isViewDidAppear || aMessage.direction == EMMessageDirectionSend || aMessage.isReadAcked || aMessage.chatType != EMChatTypeChat) {
  1423. return NO;
  1424. }
  1425. EMMessageBody *body = aMessage.body;
  1426. if (!aIsMarkRead && (body.type == EMMessageBodyTypeVideo || body.type == EMMessageBodyTypeVoice || body.type == EMMessageBodyTypeImage)) {
  1427. return NO;
  1428. }
  1429. return YES;
  1430. }
  1431. - (void)messagesDidReceive:(NSArray *)aMessages
  1432. {
  1433. __weak typeof(self) weakself = self;
  1434. dispatch_async(self.msgQueue, ^{
  1435. NSString *conId = weakself.conversationModel.emModel.conversationId;
  1436. NSMutableArray *msgArray = [[NSMutableArray alloc] init];
  1437. for (int i = 0; i < [aMessages count]; i++) {
  1438. EMMessage *msg = aMessages[i];
  1439. if (![msg.conversationId isEqualToString:conId]) {
  1440. continue;
  1441. }
  1442. if (msg.isNeedGroupAck && !msg.isReadAcked) {
  1443. [[EMClient sharedClient].chatManager sendGroupMessageReadAck:msg.messageId toGroup:msg.conversationId content:@"123" completion:^(EMError *error) {
  1444. if (error) {
  1445. NSLog(@"\n ------ error %@",error.errorDescription);
  1446. }
  1447. }];
  1448. }
  1449. if ([weakself _isNeedSendReadAckForMessage:msg isMarkRead:NO]) {
  1450. [[EMClient sharedClient].chatManager sendMessageReadAck:msg.messageId toUser:msg.conversationId completion:nil];
  1451. }
  1452. [weakself.conversationModel.emModel markMessageAsReadWithId:msg.messageId error:nil];
  1453. [msgArray addObject:msg];
  1454. }
  1455. NSArray *formated = [weakself _formatMessages:msgArray];
  1456. [weakself.dataArray addObjectsFromArray:formated];
  1457. dispatch_async(dispatch_get_main_queue(), ^{
  1458. [weakself.tableView reloadData];
  1459. [weakself _scrollToBottomRow];
  1460. });
  1461. });
  1462. }
  1463. - (void)messagesDidRecall:(NSArray *)aMessages {
  1464. __block NSMutableArray *sameObject = [NSMutableArray array];
  1465. [aMessages enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
  1466. EMMessage *msg = (EMMessage *)obj;
  1467. [self.dataArray enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
  1468. if ([obj isKindOfClass:[EMMessageModel class]]) {
  1469. EMMessageModel *model = (EMMessageModel *)obj;
  1470. if ([model.emModel.messageId isEqualToString:msg.messageId]) {
  1471. // 如果上一行是时间,且下一行也是时间
  1472. if (idx - 1 >= 0) {
  1473. id nextMessage = nil;
  1474. id prevMessage = [self.dataArray objectAtIndex:(idx - 1)];
  1475. if (idx + 1 < [self.dataArray count]) {
  1476. nextMessage = [self.dataArray objectAtIndex:(idx + 1)];
  1477. }
  1478. if ((!nextMessage
  1479. || [nextMessage isKindOfClass:[NSString class]])
  1480. && [prevMessage isKindOfClass:[NSString class]]) {
  1481. [sameObject addObject:prevMessage];
  1482. }
  1483. }
  1484. [sameObject addObject:model];
  1485. *stop = YES;
  1486. }
  1487. }
  1488. }];
  1489. }];
  1490. if (sameObject.count > 0) {
  1491. for (id obj in sameObject) {
  1492. [self.dataArray removeObject:obj];
  1493. }
  1494. [self.tableView reloadData];
  1495. }
  1496. }
  1497. //为了从home会话列表切进来触发 群组阅读回执 和 消息已读回执
  1498. - (void)sendDidReadReceipt
  1499. {
  1500. __weak typeof(self) weakself = self;
  1501. NSString *conId = weakself.conversationModel.emModel.conversationId;
  1502. void (^block)(NSArray *aMessages, EMError *aError) = ^(NSArray *aMessages, EMError *aError) {
  1503. NSLog(@"\n-------unread: %d messageCount: %lu msgid: %@",self.conversationModel.emModel.unreadMessagesCount,(unsigned long)[aMessages count],self.moreMsgId);
  1504. if (!aError && [aMessages count]) {
  1505. for (int i = 0; i < [aMessages count]; i++) {
  1506. EMMessage *msg = aMessages[i];
  1507. if (![msg.conversationId isEqualToString:conId]) {
  1508. continue;
  1509. }
  1510. if (msg.isNeedGroupAck && !msg.isReadAcked) {
  1511. [[EMClient sharedClient].chatManager sendGroupMessageReadAck:msg.messageId toGroup:msg.conversationId content:@"123" completion:^(EMError *error) {
  1512. if (error) {
  1513. NSLog(@"\n ------ error %@",error.errorDescription);
  1514. }
  1515. }];
  1516. }
  1517. if ([weakself _isNeedSendReadAckForMessage:msg isMarkRead:NO] && (weakself.conversationModel.emModel.type == EMConversationTypeChat)) {
  1518. [[EMClient sharedClient].chatManager sendMessageReadAck:msg.messageId toUser:msg.conversationId completion:nil];
  1519. [weakself.conversationModel.emModel markMessageAsReadWithId:msg.messageId error:nil];
  1520. }
  1521. }
  1522. }
  1523. };
  1524. [self.conversationModel.emModel loadMessagesStartFromId:self.moreMsgId count:self.conversationModel.emModel.unreadMessagesCount searchDirection:EMMessageSearchDirectionUp completion:block];
  1525. }
  1526. //收到群消息已读回执
  1527. - (void)groupMessageDidRead:(EMMessage *)aMessage groupAcks:(NSArray *)aGroupAcks
  1528. {
  1529. EMMessageModel *msgModel;
  1530. EMGroupMessageAck *msgAck = aGroupAcks[0];
  1531. for (int i=0; i<[self.dataArray count]; i++) {
  1532. if([self.dataArray[i] isKindOfClass:[EMMessageModel class]]){
  1533. msgModel = (EMMessageModel *)self.dataArray[i];
  1534. }else{
  1535. continue;
  1536. }
  1537. if([msgModel.emModel.messageId isEqualToString:msgAck.messageId]){
  1538. msgModel.readReceiptCount = [NSString stringWithFormat:@"阅读回执,已读用户(%d)",msgModel.emModel.groupAckCount];
  1539. msgModel.emModel.isReadAcked = YES;
  1540. [[EMClient sharedClient].chatManager sendMessageReadAck:msgModel.emModel.messageId toUser:msgModel.emModel.conversationId completion:nil];
  1541. [self.dataArray setObject:msgModel atIndexedSubscript:i];
  1542. __weak typeof(self) weakself = self;
  1543. dispatch_async(dispatch_get_main_queue(), ^{
  1544. [weakself.tableView reloadData];
  1545. [weakself _scrollToBottomRow];
  1546. });
  1547. break;
  1548. }
  1549. }
  1550. }
  1551. // 收到已读回执
  1552. - (void)messagesDidRead:(NSArray *)aMessages
  1553. {
  1554. __weak typeof(self) weakself = self;
  1555. dispatch_async(self.msgQueue, ^{
  1556. NSString *conId = weakself.conversationModel.emModel.conversationId;
  1557. __block BOOL isReladView = NO;
  1558. for (EMMessage *message in aMessages) {
  1559. if (![conId isEqualToString:message.conversationId]){
  1560. continue;
  1561. }
  1562. [weakself.dataArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
  1563. if ([obj isKindOfClass:[EMMessageModel class]]) {
  1564. EMMessageModel *model = (EMMessageModel *)obj;
  1565. if ([model.emModel.messageId isEqualToString:message.messageId]) {
  1566. model.emModel.isReadAcked = YES;
  1567. isReladView = YES;
  1568. *stop = YES;
  1569. }
  1570. }
  1571. }];
  1572. }
  1573. BOOL changeRead = NO;
  1574. NSInteger msgCount = weakself.dataArray.count - 1;
  1575. for (NSInteger i = msgCount; i >= 0; i --) {
  1576. if ([weakself.dataArray[i] isKindOfClass:[EMMessageModel class]]) {
  1577. EMMessageModel *model = (EMMessageModel *)weakself.dataArray[i];
  1578. if (model.emModel.isReadAcked == YES)
  1579. {
  1580. changeRead = YES;
  1581. }
  1582. if (changeRead) {
  1583. model.emModel.isReadAcked = YES;
  1584. }
  1585. }
  1586. }
  1587. if (isReladView) {
  1588. dispatch_async(dispatch_get_main_queue(), ^{
  1589. [weakself.tableView reloadData];
  1590. });
  1591. }
  1592. });
  1593. }
  1594. - (void)messageStatusDidChange:(EMMessage *)aMessage
  1595. error:(EMError *)aError
  1596. {
  1597. __weak typeof(self) weakself = self;
  1598. dispatch_async(self.msgQueue, ^{
  1599. NSString *conId = weakself.conversationModel.emModel.conversationId;
  1600. if (![conId isEqualToString:aMessage.conversationId]){
  1601. return ;
  1602. }
  1603. __block NSUInteger index = NSNotFound;
  1604. __block EMMessageModel *reloadModel = nil;
  1605. [self.dataArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
  1606. if ([obj isKindOfClass:[EMMessageModel class]]) {
  1607. EMMessageModel *model = (EMMessageModel *)obj;
  1608. if ([model.emModel.messageId isEqualToString:aMessage.messageId]) {
  1609. reloadModel = model;
  1610. index = idx;
  1611. *stop = YES;
  1612. }
  1613. }
  1614. }];
  1615. if (index != NSNotFound) {
  1616. dispatch_async(dispatch_get_main_queue(), ^{
  1617. [weakself.dataArray replaceObjectAtIndex:index withObject:reloadModel];
  1618. [weakself.tableView beginUpdates];
  1619. [weakself.tableView reloadRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:index inSection:0]] withRowAnimation:UITableViewRowAnimationNone];
  1620. [weakself.tableView endUpdates];
  1621. });
  1622. }
  1623. });
  1624. }
  1625. - (void)cmdMessagesDidReceive:(NSArray *)aCmdMessages
  1626. {
  1627. __weak typeof(self) weakself = self;
  1628. dispatch_async(self.msgQueue, ^{
  1629. NSString *conId = weakself.conversationModel.emModel.conversationId;
  1630. for (EMMessage *message in aCmdMessages) {
  1631. if (![conId isEqualToString:message.conversationId]) {
  1632. continue;
  1633. }
  1634. EMCmdMessageBody *body = (EMCmdMessageBody *)message.body;
  1635. NSString *str = @"";
  1636. if ([body.action isEqualToString:MSG_TYPING_BEGIN]) {
  1637. str = @"正在输入...";
  1638. }
  1639. dispatch_async(dispatch_get_main_queue(), ^{
  1640. self.titleDetailLabel.text = str;
  1641. });
  1642. }
  1643. });
  1644. }
  1645. #pragma mark - EMGroupManagerDelegate
  1646. - (void)didLeaveGroup:(EMGroup *)aGroup
  1647. reason:(EMGroupLeaveReason)aReason
  1648. {
  1649. EMConversation *conversation = self.conversationModel.emModel;
  1650. if (conversation.type == EMChatTypeGroupChat && [aGroup.groupId isEqualToString:conversation.conversationId]) {
  1651. [self.navigationController popToViewController:self animated:YES];
  1652. [self.navigationController popViewControllerAnimated:YES];
  1653. }
  1654. }
  1655. #pragma mark - EMChatroomManagerDelegate
  1656. //有用户加入聊天室
  1657. - (void)userDidJoinChatroom:(EMChatroom *)aChatroom
  1658. user:(NSString *)aUsername
  1659. {
  1660. EMConversation *conversation = self.conversationModel.emModel;
  1661. if (conversation.type == EMChatTypeChatRoom && [aChatroom.chatroomId isEqualToString:conversation.conversationId]) {
  1662. NSString *str = [NSString stringWithFormat:@"%@ 进入聊天室", aUsername];
  1663. [self showHint:str];
  1664. }
  1665. }
  1666. - (void)userDidLeaveChatroom:(EMChatroom *)aChatroom
  1667. user:(NSString *)aUsername
  1668. {
  1669. EMConversation *conversation = self.conversationModel.emModel;
  1670. if (conversation.type == EMChatTypeChatRoom && [aChatroom.chatroomId isEqualToString:conversation.conversationId]) {
  1671. NSString *str = [NSString stringWithFormat:@"%@ 离开聊天室", aUsername];
  1672. [self showHint:str];
  1673. }
  1674. }
  1675. - (void)didDismissFromChatroom:(EMChatroom *)aChatroom
  1676. reason:(EMChatroomBeKickedReason)aReason
  1677. {
  1678. EMConversation *conversation = self.conversationModel.emModel;
  1679. if (conversation.type == EMChatTypeChatRoom && [aChatroom.chatroomId isEqualToString:conversation.conversationId]) {
  1680. [self.navigationController popToViewController:self animated:YES];
  1681. [self.navigationController popViewControllerAnimated:YES];
  1682. }
  1683. }
  1684. #pragma mark - KeyBoard
  1685. - (void)keyBoardWillShow:(NSNotification *)note
  1686. {
  1687. // 获取用户信息
  1688. NSDictionary *userInfo = [NSDictionary dictionaryWithDictionary:note.userInfo];
  1689. // 获取键盘高度
  1690. CGRect keyBoardBounds = [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
  1691. CGFloat keyBoardHeight = keyBoardBounds.size.height;
  1692. // 获取键盘动画时间
  1693. CGFloat animationTime = [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] floatValue];
  1694. // 定义好动作
  1695. WS(weakSelf);
  1696. void (^animation)(void) = ^void(void) {
  1697. [weakSelf.chatBar mas_updateConstraints:^(MASConstraintMaker *make) {
  1698. if (@available(iOS 11.0, *)) {
  1699. make.bottom.mas_equalTo(weakSelf.view.mas_safeAreaLayoutGuideBottom).offset(-keyBoardHeight + EMVIEWBOTTOMMARGIN);
  1700. } else {
  1701. make.bottom.mas_equalTo(weakSelf.view.mas_bottom).offset(-keyBoardHeight);
  1702. }
  1703. }];
  1704. };
  1705. if (animationTime > 0) {
  1706. [UIView animateWithDuration:animationTime animations:animation completion:^(BOOL finished) {
  1707. [weakSelf _scrollToBottomRow];
  1708. }];
  1709. }else{
  1710. [UIView animateWithDuration:0.25f animations:animation completion:^(BOOL finished) {
  1711. [weakSelf _scrollToBottomRow];
  1712. }];
  1713. }
  1714. }
  1715. - (void)keyBoardWillHide:(NSNotification *)note
  1716. {
  1717. // 获取用户信息
  1718. NSDictionary *userInfo = [NSDictionary dictionaryWithDictionary:note.userInfo];
  1719. // 获取键盘动画时间
  1720. CGFloat animationTime = [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] floatValue];
  1721. // 定义好动作
  1722. WS(weakSelf);
  1723. void (^animation)(void) = ^void(void) {
  1724. [weakSelf.chatBar mas_updateConstraints:^(MASConstraintMaker *make) {
  1725. if (@available(iOS 11.0, *)) {
  1726. make.bottom.mas_equalTo(weakSelf.view.mas_safeAreaLayoutGuideBottom);
  1727. } else {
  1728. make.bottom.mas_equalTo(weakSelf.view.mas_bottom);
  1729. }
  1730. }];
  1731. };
  1732. if (animationTime > 0) {
  1733. [UIView animateWithDuration:animationTime animations:animation];
  1734. } else {
  1735. [UIView animateWithDuration:0.25f animations:animation];
  1736. }
  1737. if (self.enableTyping) {
  1738. [self _sendEndTyping];
  1739. }
  1740. }
  1741. #pragma mark - NSNotification
  1742. - (UIImagePickerController *)imagePicker
  1743. {
  1744. if (!_imagePicker) {
  1745. _imagePicker = [[UIImagePickerController alloc] init];
  1746. _imagePicker.delegate = self;
  1747. }
  1748. return _imagePicker;
  1749. }
  1750. - (void)handleWillPushCallController:(NSNotification *)aNotif
  1751. {
  1752. [self.imagePicker dismissViewControllerAnimated:YES completion:nil];
  1753. [[EMImageBrowser sharedBrowser] dismissViewController];
  1754. [[EMAudioPlayerHelper sharedHelper] stopPlayer];
  1755. }
  1756. - (void)handleCleanMessages:(NSNotification *)aNotif
  1757. {
  1758. NSString *chatId = aNotif.object;
  1759. if (chatId && [chatId isEqualToString:self.conversationModel.emModel.conversationId]) {
  1760. [self.conversationModel.emModel deleteAllMessages:nil];
  1761. [self.dataArray removeAllObjects];
  1762. [self.tableView reloadData];
  1763. }
  1764. }
  1765. - (void)handleGroupSubjectUpdated:(NSNotification *)aNotif
  1766. {
  1767. EMGroup *group = aNotif.object;
  1768. if (!group) {
  1769. return;
  1770. }
  1771. NSString *groupId = group.groupId;
  1772. if ([groupId isEqualToString:self.conversationModel.emModel.conversationId]) {
  1773. self.conversationModel.name = group.subject;
  1774. self.titleLabel.text = group.subject;
  1775. }
  1776. }
  1777. #pragma mark - Gesture Recognizer
  1778. - (void)handleTapTableViewAction:(UITapGestureRecognizer *)aTap
  1779. {
  1780. if (aTap.state == UIGestureRecognizerStateEnded) {
  1781. [self.view endEditing:YES];
  1782. [self.chatBar clearMoreViewAndSelectedButton];
  1783. [self performSelector:@selector(_scrollToBottomRow) withObject:nil afterDelay:0.1];
  1784. }
  1785. }
  1786. #pragma mark - Private
  1787. - (void)_joinChatroom
  1788. {
  1789. __weak typeof(self) weakself = self;
  1790. [self showHudInView:self.view hint:@"加入聊天室..."];
  1791. [[EMClient sharedClient].roomManager joinChatroom:self.conversationModel.emModel.conversationId completion:^(EMChatroom *aChatroom, EMError *aError) {
  1792. [weakself hideHud];
  1793. if (aError) {
  1794. [EMAlertController showErrorAlert:@"加入聊天室失败"];
  1795. [weakself.navigationController popViewControllerAnimated:YES];
  1796. } else {
  1797. weakself.isFirstLoadMsg = YES;
  1798. [weakself tableViewDidTriggerHeaderRefresh];
  1799. }
  1800. }];
  1801. }
  1802. - (void)_scrollToBottomRow
  1803. {
  1804. if ([self.dataArray count] > 0) {
  1805. NSInteger toRow = self.dataArray.count - 1;
  1806. NSIndexPath *toIndexPath = [NSIndexPath indexPathForRow:toRow inSection:0];
  1807. [self.tableView scrollToRowAtIndexPath:toIndexPath atScrollPosition:UITableViewScrollPositionBottom animated:NO];
  1808. }
  1809. }
  1810. - (void)_showCustomTransferFileAlertView
  1811. {
  1812. UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"(づ。◕‿‿◕。)づ" message:@"需要自定义实现上传附件方法" preferredStyle:UIAlertControllerStyleAlert];
  1813. UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"好的" style:UIAlertActionStyleCancel handler:nil];
  1814. [alertController addAction:okAction];
  1815. [self presentViewController:alertController animated:YES completion:nil];
  1816. }
  1817. - (NSURL *)_videoConvert2Mp4:(NSURL *)movUrl
  1818. {
  1819. NSURL *mp4Url = nil;
  1820. AVURLAsset *avAsset = [AVURLAsset URLAssetWithURL:movUrl options:nil];
  1821. NSArray *compatiblePresets = [AVAssetExportSession exportPresetsCompatibleWithAsset:avAsset];
  1822. if ([compatiblePresets containsObject:AVAssetExportPresetHighestQuality]) {
  1823. AVAssetExportSession *exportSession = [[AVAssetExportSession alloc]initWithAsset:avAsset presetName:AVAssetExportPresetHighestQuality];
  1824. NSString *mp4Path = [NSString stringWithFormat:@"%@/%d%d.mp4", [self _getAudioOrVideoPath], (int)[[NSDate date] timeIntervalSince1970], arc4random() % 100000];
  1825. mp4Url = [NSURL fileURLWithPath:mp4Path];
  1826. exportSession.outputURL = mp4Url;
  1827. exportSession.shouldOptimizeForNetworkUse = YES;
  1828. exportSession.outputFileType = AVFileTypeMPEG4;
  1829. dispatch_semaphore_t wait = dispatch_semaphore_create(0l);
  1830. [exportSession exportAsynchronouslyWithCompletionHandler:^{
  1831. switch ([exportSession status]) {
  1832. case AVAssetExportSessionStatusFailed: {
  1833. NSLog(@"failed, error:%@.", exportSession.error);
  1834. } break;
  1835. case AVAssetExportSessionStatusCancelled: {
  1836. NSLog(@"cancelled.");
  1837. } break;
  1838. case AVAssetExportSessionStatusCompleted: {
  1839. NSLog(@"completed.");
  1840. } break;
  1841. default: {
  1842. NSLog(@"others.");
  1843. } break;
  1844. }
  1845. dispatch_semaphore_signal(wait);
  1846. }];
  1847. long timeout = dispatch_semaphore_wait(wait, DISPATCH_TIME_FOREVER);
  1848. if (timeout) {
  1849. NSLog(@"timeout.");
  1850. }
  1851. if (wait) {
  1852. //dispatch_release(wait);
  1853. wait = nil;
  1854. }
  1855. }
  1856. return mp4Url;
  1857. }
  1858. #pragma mark - Menu Controller
  1859. - (UIMenuController *)menuController
  1860. {
  1861. if (_menuController == nil) {
  1862. _menuController = [UIMenuController sharedMenuController];
  1863. }
  1864. return _menuController;
  1865. }
  1866. - (UIMenuItem *)deleteMenuItem
  1867. {
  1868. if (_deleteMenuItem == nil) {
  1869. _deleteMenuItem = [[UIMenuItem alloc] initWithTitle:@"删除" action:@selector(deleteMenuItemAction:)];
  1870. }
  1871. return _deleteMenuItem;
  1872. }
  1873. - (UIMenuItem *)copyMenuItem
  1874. {
  1875. if (_copyMenuItem == nil) {
  1876. _copyMenuItem = [[UIMenuItem alloc] initWithTitle:@"复制" action:@selector(copyMenuItemAction:)];
  1877. }
  1878. return _copyMenuItem;
  1879. }
  1880. - (UIMenuItem *)transpondMenuItem
  1881. {
  1882. if (_transpondMenuItem == nil) {
  1883. _transpondMenuItem = [[UIMenuItem alloc] initWithTitle:@"转发" action:@selector(transpondMenuItemAction:)];
  1884. }
  1885. return _transpondMenuItem;
  1886. }
  1887. - (UIMenuItem *)recallMenuItem
  1888. {
  1889. if (_recallMenuItem == nil) {
  1890. _recallMenuItem = [[UIMenuItem alloc] initWithTitle:@"撤回" action:@selector(recallMenuItemAction:)];
  1891. }
  1892. return _recallMenuItem;
  1893. }
  1894. - (UIMenuItem *)playAndRecordMenuItem
  1895. {
  1896. if (_playAndRecordMenuItem == nil) {
  1897. _playAndRecordMenuItem = [[UIMenuItem alloc] initWithTitle:@"听筒播放" action:@selector(playAndRecordMenuItemAction:)];
  1898. }
  1899. return _playAndRecordMenuItem;
  1900. }
  1901. //删除消息
  1902. - (void)deleteMenuItemAction:(UIMenuItem *)aItem
  1903. {
  1904. if (self.menuIndexPath == nil) {
  1905. return;
  1906. }
  1907. EMMessageModel *model = [self.dataArray objectAtIndex:self.menuIndexPath.row];
  1908. [self.conversationModel.emModel deleteMessageWithId:model.emModel.messageId error:nil];
  1909. NSMutableIndexSet *indexs = [NSMutableIndexSet indexSetWithIndex:self.menuIndexPath.row];
  1910. NSMutableArray *indexPaths = [NSMutableArray arrayWithObjects:self.menuIndexPath, nil];
  1911. if (self.menuIndexPath.row - 1 >= 0) {
  1912. id nextMessage = nil;
  1913. id prevMessage = [self.dataArray objectAtIndex:(self.menuIndexPath.row - 1)];
  1914. if (self.menuIndexPath.row + 1 < [self.dataArray count]) {
  1915. nextMessage = [self.dataArray objectAtIndex:(self.menuIndexPath.row + 1)];
  1916. }
  1917. if ((!nextMessage || [nextMessage isKindOfClass:[NSString class]]) && [prevMessage isKindOfClass:[NSString class]]) {
  1918. [indexs addIndex:self.menuIndexPath.row - 1];
  1919. [indexPaths addObject:[NSIndexPath indexPathForRow:(self.menuIndexPath.row - 1) inSection:0]];
  1920. }
  1921. }
  1922. [self.dataArray removeObjectsAtIndexes:indexs];
  1923. [self.tableView beginUpdates];
  1924. [self.tableView deleteRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationNone];
  1925. [self.tableView endUpdates];
  1926. if ([self.dataArray count] == 0) {
  1927. self.msgTimelTag = -1;
  1928. }
  1929. self.menuIndexPath = nil;
  1930. }
  1931. - (void)copyMenuItemAction:(UIMenuItem *)aItem
  1932. {
  1933. if (self.menuIndexPath == nil) {
  1934. return;
  1935. }
  1936. EMMessageModel *model = [self.dataArray objectAtIndex:self.menuIndexPath.row];
  1937. if (model.type == EMMessageTypeText) {
  1938. EMTextMessageBody *body = (EMTextMessageBody *)model.emModel.body;
  1939. UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
  1940. pasteboard.string = body.text;
  1941. }
  1942. if (model.type == EMMessageTypeImage) {
  1943. EMMessageCell *cell = [self.tableView cellForRowAtIndexPath:self.menuIndexPath];
  1944. [[UIPasteboard generalPasteboard]setData:UIImagePNGRepresentation(cell.bubbleView.image) forPasteboardType:[UIPasteboardTypeListImage objectAtIndex:0]];
  1945. }
  1946. self.menuIndexPath = nil;
  1947. }
  1948. - (void)transpondMenuItemAction:(UIMenuItem *)aItem
  1949. {
  1950. if (self.menuIndexPath == nil) {
  1951. return;
  1952. }
  1953. EMMessageModel *model = [self.dataArray objectAtIndex:self.menuIndexPath.row];
  1954. // EMMsgTranspondViewController *controller = [[EMMsgTranspondViewController alloc] initWithModel:model];
  1955. // [self.navigationController pushViewController:controller animated:YES];
  1956. //
  1957. // __weak typeof(self) weakself = self;
  1958. // [controller setDoneCompletion:^(EMMessageModel * _Nonnull aModel, NSString * _Nonnull aUsername) {
  1959. // [weakself _transpondMsg:aModel toUser:aUsername];
  1960. // }];
  1961. // if (self.IsShareText) {
  1962. // model.Title = self.shareText;
  1963. // model.SoureTypeId = 1;
  1964. // }else{
  1965. // model.SoureId = self.Id;
  1966. // model.SoureTypeId = self.type;
  1967. // model.Title = self.currentNoteModel.Title;
  1968. // model.Author = self.currentNoteModel.UserName;
  1969. // vc.type = CollectModel_NewTopic;
  1970. // }
  1971. switch (model.type) {
  1972. case EMMessageTypeText:
  1973. {
  1974. FlowAttachmentsModel * sendModel = [[FlowAttachmentsModel alloc] init];
  1975. EMTextMessageBody *body = (EMTextMessageBody *)model.emModel.body;
  1976. sendModel.Title = body.text;
  1977. sendModel.SoureTypeId = 1;
  1978. self.sendModel = sendModel;
  1979. [self shareHander];
  1980. }
  1981. break;
  1982. case EMMessageTypeImage:
  1983. {
  1984. [self shareImage:model];
  1985. // EMTextMessageBody *body = (EMTextMessageBody *)model.emModel.body;
  1986. // self.sendModel.image = body.text;
  1987. // self.sendModel.SoureTypeId = 301;
  1988. }
  1989. break;
  1990. case EMMessageTypeExtApp:
  1991. {
  1992. NSDictionary * dict = model.emModel.ext;
  1993. CollectModelType type = [[dict objectForKey:@"app_type"] intValue];
  1994. NSInteger sourceUserId = [[dict objectForKey:@"app_sourceUserId"] integerValue];
  1995. NSInteger Id = [[dict objectForKey:@"app_id"] integerValue];
  1996. NSString * title = [dict objectForKey:@"app_title"];
  1997. NSString * url = [dict objectForKey:@"app_url"];
  1998. FlowAttachmentsModel * sendModel = [[FlowAttachmentsModel alloc] init];
  1999. sendModel.Title = title;
  2000. sendModel.SoureTypeId = type;
  2001. sendModel.SoureId = Id;
  2002. sendModel.Url = url;
  2003. sendModel.SourceUserId = sourceUserId;
  2004. self.sendModel = sendModel;
  2005. [self shareHander];
  2006. }
  2007. break;
  2008. case EMMessageTypeFile:
  2009. {
  2010. EMFileMessageBody *body = (EMFileMessageBody *)model.emModel.body;
  2011. NSLog(@"%@",body.localPath);
  2012. }
  2013. break;
  2014. default:
  2015. break;
  2016. }
  2017. self.menuIndexPath = nil;
  2018. }
  2019. - (void)shareImage:(EMMessageModel *)model
  2020. {
  2021. __weak typeof(self) weakself = self;
  2022. void (^downloadThumbBlock)(EMMessageModel *aModel) = ^(EMMessageModel *aModel) {
  2023. [weakself showHint:@"获取缩略图..."];
  2024. [[EMClient sharedClient].chatManager downloadMessageThumbnail:aModel.emModel progress:nil completion:^(EMMessage *message, EMError *error) {
  2025. if (!error) {
  2026. [weakself.tableView reloadData];
  2027. }
  2028. }];
  2029. };
  2030. EMImageMessageBody *body = (EMImageMessageBody*)model.emModel.body;
  2031. BOOL isCustomDownload = !([EMClient sharedClient].options.isAutoTransferMessageAttachments);
  2032. if (body.thumbnailDownloadStatus == EMDownloadStatusFailed) {
  2033. if (isCustomDownload) {
  2034. [self _showCustomTransferFileAlertView];
  2035. } else {
  2036. downloadThumbBlock(model);
  2037. }
  2038. return;
  2039. }
  2040. BOOL isAutoDownloadThumbnail = [EMClient sharedClient].options.isAutoDownloadThumbnail;
  2041. if (body.thumbnailDownloadStatus == EMDownloadStatusPending && !isAutoDownloadThumbnail) {
  2042. downloadThumbBlock(model);
  2043. return;
  2044. }
  2045. FlowAttachmentsModel * sendModel = [[FlowAttachmentsModel alloc] init];
  2046. sendModel.SoureTypeId = 301;
  2047. self.sendModel = sendModel;
  2048. if (body.downloadStatus == EMDownloadStatusSucceed) {
  2049. UIImage *image = [UIImage imageWithContentsOfFile:body.localPath];
  2050. if (image) {
  2051. self.sendImage = image;
  2052. [self shareHander];
  2053. // [[EMImageBrowser sharedBrowser] showImages:@[image] fromController:self];
  2054. return;
  2055. }
  2056. }
  2057. if (isCustomDownload) {
  2058. [self _showCustomTransferFileAlertView];
  2059. return;
  2060. }
  2061. [self showHudInView:self.view hint:@"下载原图..."];
  2062. [[EMClient sharedClient].chatManager downloadMessageAttachment:model.emModel progress:nil completion:^(EMMessage *message, EMError *error) {
  2063. [weakself hideHud];
  2064. if (error) {
  2065. SHOWERROR(@"下载原图失败");
  2066. } else {
  2067. if (message.direction == EMMessageDirectionReceive && !message.isReadAcked) {
  2068. [[EMClient sharedClient].chatManager sendMessageReadAck:message.messageId toUser:message.conversationId completion:nil];
  2069. }
  2070. NSString *localPath = [(EMImageMessageBody *)message.body localPath];
  2071. UIImage *image = [UIImage imageWithContentsOfFile:localPath];
  2072. if (image) {
  2073. weakself.sendImage = image;
  2074. [weakself shareHander];
  2075. // [[EMImageBrowser sharedBrowser] showImages:@[image] fromController:self];
  2076. } else {
  2077. SHOWERROR(@"获取原图失败");
  2078. }
  2079. }
  2080. }];
  2081. }
  2082. - (void)recallMenuItemAction:(UIMenuItem *)aItem
  2083. {
  2084. if (self.menuIndexPath == nil) {
  2085. return;
  2086. }
  2087. NSIndexPath *indexPath = self.menuIndexPath;
  2088. __weak typeof(self) weakself = self;
  2089. EMMessageModel *model = [self.dataArray objectAtIndex:self.menuIndexPath.row];
  2090. [[EMClient sharedClient].chatManager recallMessage:model.emModel completion:^(EMMessage *aMessage, EMError *aError) {
  2091. if (aError) {
  2092. if (aError.code == EMErrorMessageRecallTimeLimit) {
  2093. SHOWERROR(@"超过限制撤回时间,无法撤回");
  2094. }
  2095. } else {
  2096. EMTextMessageBody *body = [[EMTextMessageBody alloc] initWithText:@"您撤回一条消息"];
  2097. NSString *from = [[EMClient sharedClient] currentUsername];
  2098. NSString *to = self.conversationModel.emModel.conversationId;
  2099. EMMessage *message = [[EMMessage alloc] initWithConversationID:to from:from to:to body:body ext:@{MSG_EXT_RECALL:@(YES)}];
  2100. message.chatType = (EMChatType)self.conversationModel.emModel.type;
  2101. message.isRead = YES;
  2102. message.timestamp = model.emModel.timestamp;
  2103. message.localTime = model.emModel.localTime;
  2104. [weakself.conversationModel.emModel insertMessage:message error:nil];
  2105. EMMessageModel *model = [[EMMessageModel alloc] initWithEMMessage:message];
  2106. [weakself.dataArray replaceObjectAtIndex:indexPath.row withObject:model];
  2107. [weakself.tableView reloadData];
  2108. }
  2109. }];
  2110. self.menuIndexPath = nil;
  2111. }
  2112. - (void)playAndRecordMenuItemAction:(UIMenuItem *)aItem
  2113. {
  2114. if (self.menuIndexPath == nil) {
  2115. return;
  2116. }
  2117. EMMessageModel *model = [self.dataArray objectAtIndex:self.menuIndexPath.row];
  2118. [self playVoice:model];
  2119. self.menuIndexPath = nil;
  2120. }
  2121. - (void)playVoice:(EMMessageModel *)model
  2122. {
  2123. if (model.isPlaying) {
  2124. [[EMAudioPlayerHelper sharedHelper] stopPlayer];
  2125. model.isPlaying = NO;
  2126. [self.tableView reloadData];
  2127. return;
  2128. }
  2129. EMVoiceMessageBody *body = (EMVoiceMessageBody*)model.emModel.body;
  2130. if (body.downloadStatus == EMDownloadStatusDownloading) {
  2131. [EMAlertController showInfoAlert:@"正在下载语音,稍后点击"];
  2132. return;
  2133. }
  2134. __weak typeof(self) weakself = self;
  2135. void (^playBlock)(EMMessageModel *aModel) = ^(EMMessageModel *aModel) {
  2136. id model = [EMAudioPlayerHelper sharedHelper].model;
  2137. if (model && [model isKindOfClass:[EMMessageModel class]]) {
  2138. EMMessageModel *oldModel = (EMMessageModel *)model;
  2139. if (oldModel.isPlaying) {
  2140. oldModel.isPlaying = NO;
  2141. }
  2142. }
  2143. if (!aModel.emModel.isReadAcked) {
  2144. [[EMClient sharedClient].chatManager sendMessageReadAck:aModel.emModel.messageId toUser:aModel.emModel.conversationId completion:nil];
  2145. }
  2146. aModel.isPlaying = YES;
  2147. if (!aModel.emModel.isRead) {
  2148. aModel.emModel.isRead = YES;
  2149. }
  2150. [weakself.tableView reloadData];
  2151. [[EMAudioPlayerHelper sharedHelper] startPlayerWithPath:body.localPath model:aModel AVAudioSessionCategory:AVAudioSessionCategoryPlayAndRecord completion:^(NSError * _Nonnull error) {
  2152. aModel.isPlaying = NO;
  2153. [weakself.tableView reloadData];
  2154. }];
  2155. };
  2156. if (body.downloadStatus == EMDownloadStatusSucceed) {
  2157. playBlock(model);
  2158. return;
  2159. }
  2160. if (![EMClient sharedClient].options.isAutoTransferMessageAttachments) {
  2161. [self _showCustomTransferFileAlertView];
  2162. return;
  2163. }
  2164. [self showHudInView:self.view hint:@"下载语音..."];
  2165. [[EMClient sharedClient].chatManager downloadMessageAttachment:model.emModel progress:nil completion:^(EMMessage *message, EMError *error) {
  2166. [weakself hideHud];
  2167. if (error) {
  2168. [EMAlertController showErrorAlert:@"下载语音失败"];
  2169. } else {
  2170. playBlock(model);
  2171. }
  2172. }];
  2173. }
  2174. - (void)_showMenuViewController:(EMMessageCell *)aCell
  2175. model:(EMMessageModel *)aModel
  2176. {
  2177. [self becomeFirstResponder];
  2178. NSMutableArray *items = [[NSMutableArray alloc] init];
  2179. if (aModel.type == EMMessageTypeText || aModel.type == EMMessageTypeImage) {
  2180. [items addObject:self.copyMenuItem];
  2181. [items addObject:self.transpondMenuItem];
  2182. // } else if (aModel.type == EMMessageTypeLocation || aModel.type == EMMessageTypeImage || aModel.type == EMMessageTypeVideo) {
  2183. // [items addObject:self.transpondMenuItem];
  2184. }else if(aModel.type == EMMessageTypeExtApp){
  2185. [items addObject:self.transpondMenuItem];
  2186. }else if(aModel.type == EMMessageTypeVoice){
  2187. [items addObject:self.playAndRecordMenuItem];
  2188. }
  2189. if (aModel.emModel.direction == EMMessageDirectionSend) {
  2190. [items addObject:self.recallMenuItem];
  2191. }
  2192. [items addObject:self.deleteMenuItem];
  2193. [self.menuController setMenuItems:items];
  2194. [self.menuController setTargetRect:aCell.bubbleView.frame inView:aCell];
  2195. [self.menuController setMenuVisible:YES animated:NO];
  2196. }
  2197. #pragma mark - Transpond Message
  2198. - (void)_forwardMsgWithBody:(EMMessageBody *)aBody
  2199. to:(NSString *)aTo
  2200. ext:(NSDictionary *)aExt
  2201. completion:(void (^)(EMMessage *message))aCompletionBlock
  2202. {
  2203. NSString *from = [[EMClient sharedClient] currentUsername];
  2204. EMMessage *message = [[EMMessage alloc] initWithConversationID:aTo from:from to:aTo body:aBody ext:aExt];
  2205. message.chatType = EMChatTypeChat;
  2206. __weak typeof(self) weakself = self;
  2207. [[EMClient sharedClient].chatManager sendMessage:message progress:nil completion:^(EMMessage *message, EMError *error) {
  2208. if (error) {
  2209. [weakself.conversationModel.emModel deleteMessageWithId:message.messageId error:nil];
  2210. SHOWERROR(@"转发消息失败");
  2211. } else {
  2212. if (aCompletionBlock) {
  2213. aCompletionBlock(message);
  2214. }
  2215. SHOWSUCCESS(@"转发消息成功");
  2216. }
  2217. }];
  2218. }
  2219. - (void)_forwardImageMsg:(EMMessage *)aMsg
  2220. toUser:(NSString *)aUsername
  2221. {
  2222. NSString *thumbnailLocalPath = [(EMImageMessageBody *)aMsg.body thumbnailLocalPath];
  2223. __weak typeof(self) weakself = self;
  2224. void (^block)(EMMessage *aMessage) = ^(EMMessage *aMessage) {
  2225. EMImageMessageBody *oldBody = (EMImageMessageBody *)aMessage.body;
  2226. EMImageMessageBody *newBody = [[EMImageMessageBody alloc] initWithData:nil thumbnailData:[NSData dataWithContentsOfFile:oldBody.thumbnailLocalPath]];
  2227. newBody.thumbnailRemotePath = oldBody.thumbnailRemotePath;
  2228. newBody.remotePath = oldBody.remotePath;
  2229. [weakself _forwardMsgWithBody:newBody to:aUsername ext:aMsg.ext completion:^(EMMessage *message) {
  2230. [(EMImageMessageBody *)message.body setLocalPath:oldBody.localPath];
  2231. [[EMClient sharedClient].chatManager updateMessage:message completion:nil];
  2232. }];
  2233. };
  2234. if (![[NSFileManager defaultManager] fileExistsAtPath:thumbnailLocalPath]) {
  2235. [[EMClient sharedClient].chatManager downloadMessageThumbnail:aMsg progress:nil completion:^(EMMessage *message, EMError *error) {
  2236. if (error) {
  2237. SHOWERROR(@"转发消息失败");
  2238. } else {
  2239. block(aMsg);
  2240. }
  2241. }];
  2242. } else {
  2243. block(aMsg);
  2244. }
  2245. }
  2246. - (void)_forwardVideoMsg:(EMMessage *)aMsg
  2247. toUser:(NSString *)aUsername
  2248. {
  2249. EMVideoMessageBody *oldBody = (EMVideoMessageBody *)aMsg.body;
  2250. __weak typeof(self) weakself = self;
  2251. void (^block)(EMMessage *aMessage) = ^(EMMessage *aMessage) {
  2252. EMVideoMessageBody *newBody = [[EMVideoMessageBody alloc] initWithLocalPath:oldBody.localPath displayName:oldBody.displayName];
  2253. newBody.thumbnailLocalPath = oldBody.thumbnailLocalPath;
  2254. [weakself _forwardMsgWithBody:newBody to:aUsername ext:aMsg.ext completion:^(EMMessage *message) {
  2255. [(EMVideoMessageBody *)message.body setLocalPath:[(EMVideoMessageBody *)aMessage.body localPath]];
  2256. [[EMClient sharedClient].chatManager updateMessage:message completion:nil];
  2257. }];
  2258. };
  2259. if (![[NSFileManager defaultManager] fileExistsAtPath:oldBody.localPath]) {
  2260. [[EMClient sharedClient].chatManager downloadMessageAttachment:aMsg progress:nil completion:^(EMMessage *message, EMError *error) {
  2261. if (error) {
  2262. SHOWERROR(@"转发消息失败");
  2263. } else {
  2264. block(aMsg);
  2265. }
  2266. }];
  2267. } else {
  2268. block(aMsg);
  2269. }
  2270. }
  2271. - (void)_transpondMsg:(EMMessageModel *)aModel
  2272. toUser:(NSString *)aUsername
  2273. {
  2274. EMMessageBodyType type = aModel.emModel.body.type;
  2275. if (type == EMMessageBodyTypeText || type == EMMessageBodyTypeLocation) {
  2276. [self _forwardMsgWithBody:aModel.emModel.body to:aUsername ext:aModel.emModel.ext completion:nil];
  2277. } else if (type == EMMessageBodyTypeImage) {
  2278. [self _forwardImageMsg:aModel.emModel toUser:aUsername];
  2279. } else if (type == EMMessageBodyTypeVideo) {
  2280. [self _forwardVideoMsg:aModel.emModel toUser:aUsername];
  2281. }
  2282. }
  2283. #pragma mark - Send Message
  2284. - (void)_sendTextAction:(NSString *)aText
  2285. ext:(NSDictionary *)aExt
  2286. {
  2287. [self.chatBar clearInputViewText];
  2288. [self clearUserInfoInDocument];
  2289. if ([aText length] == 0) {
  2290. return;
  2291. }
  2292. //TODO: 处理@
  2293. //messageExt
  2294. //TODO: 处理表情
  2295. // NSString *sendText = [EaseConvertToCommonEmoticonsHelper convertToCommonEmoticons:aText];
  2296. EMTextMessageBody *body = [[EMTextMessageBody alloc] initWithText:aText];
  2297. [self _sendMessageWithBody:body ext:aExt isUpload:NO];
  2298. if (self.enableTyping) {
  2299. [self _sendEndTyping];
  2300. }
  2301. }
  2302. - (void)_sendImageDataAction:(NSData *)aImageData
  2303. {
  2304. EMImageMessageBody *body = [[EMImageMessageBody alloc] initWithData:aImageData displayName:@"image"];
  2305. [self _sendMessageWithBody:body ext:nil isUpload:YES];
  2306. }
  2307. - (void)_sendLocationAction:(CLLocationCoordinate2D)aCoord
  2308. address:(NSString *)aAddress
  2309. {
  2310. EMLocationMessageBody *body = [[EMLocationMessageBody alloc] initWithLatitude:aCoord.latitude longitude:aCoord.longitude address:aAddress];
  2311. [self _sendMessageWithBody:body ext:nil isUpload:NO];
  2312. }
  2313. - (void)_sendVideoAction:(NSURL *)aUrl
  2314. {
  2315. EMVideoMessageBody *body = [[EMVideoMessageBody alloc] initWithLocalPath:[aUrl path] displayName:@"video.mp4"];
  2316. [self _sendMessageWithBody:body ext:nil isUpload:YES];
  2317. }
  2318. - (void)_sendBeginTyping
  2319. {
  2320. NSString *from = [[EMClient sharedClient] currentUsername];
  2321. NSString *to = self.conversationModel.emModel.conversationId;
  2322. EMCmdMessageBody *body = [[EMCmdMessageBody alloc] initWithAction:MSG_TYPING_BEGIN];
  2323. body.isDeliverOnlineOnly = YES;
  2324. EMMessage *message = [[EMMessage alloc] initWithConversationID:to from:from to:to body:body ext:nil];
  2325. message.chatType = (EMChatType)self.conversationModel.emModel.type;
  2326. [[EMClient sharedClient].chatManager sendMessage:message progress:nil completion:nil];
  2327. }
  2328. //正在输入
  2329. - (void)_sendEndTyping
  2330. {
  2331. self.isTyping = NO;
  2332. NSString *from = [[EMClient sharedClient] currentUsername];
  2333. NSString *to = self.conversationModel.emModel.conversationId;
  2334. EMCmdMessageBody *body = [[EMCmdMessageBody alloc] initWithAction:MSG_TYPING_END];
  2335. body.isDeliverOnlineOnly = YES;
  2336. EMMessage *message = [[EMMessage alloc] initWithConversationID:to from:from to:to body:body ext:nil];
  2337. message.chatType = (EMChatType)self.conversationModel.emModel.type;
  2338. [[EMClient sharedClient].chatManager sendMessage:message progress:nil completion:nil];
  2339. }
  2340. #pragma mark - Data
  2341. - (NSArray *)_formatMessages:(NSArray<EMMessage *> *)aMessages
  2342. {
  2343. NSMutableArray *formated = [[NSMutableArray alloc] init];
  2344. for (int i = 0; i < [aMessages count]; i++) {
  2345. EMMessage *msg = aMessages[i];
  2346. // cmd消息不展示
  2347. if(msg.body.type == EMMessageBodyTypeCmd) {
  2348. continue;
  2349. }
  2350. if (msg.chatType == EMChatTypeChat && msg.isReadAcked && (msg.body.type == EMMessageBodyTypeText || msg.body.type == EMMessageBodyTypeLocation)) {
  2351. //
  2352. [[EMClient sharedClient].chatManager sendMessageReadAck:msg.messageId toUser:msg.conversationId completion:nil];
  2353. } else if (msg.chatType == EMChatTypeGroupChat && !msg.isReadAcked && (msg.body.type == EMMessageBodyTypeText || msg.body.type == EMMessageBodyTypeLocation)) {
  2354. }
  2355. CGFloat interval = (self.msgTimelTag - msg.timestamp) / 1000;
  2356. if (self.msgTimelTag < 0 || interval > 60 || interval < -60) {
  2357. NSString *timeStr = [EMDateHelper formattedTimeFromTimeInterval:msg.timestamp];
  2358. [formated addObject:timeStr];
  2359. self.msgTimelTag = msg.timestamp;
  2360. }
  2361. EMMessageModel *model = [[EMMessageModel alloc] initWithEMMessage:msg];
  2362. [formated addObject:model];
  2363. }
  2364. return formated;
  2365. }
  2366. - (void)tableViewDidTriggerHeaderRefresh
  2367. {
  2368. __weak typeof(self) weakself = self;
  2369. void (^block)(NSArray *aMessages, EMError *aError) = ^(NSArray *aMessages, EMError *aError) {
  2370. if (!aError && [aMessages count]) {
  2371. EMMessage *msg = aMessages[0];
  2372. weakself.moreMsgId = msg.messageId;
  2373. dispatch_async(self.msgQueue, ^{
  2374. NSArray *formated = [weakself _formatMessages:aMessages];
  2375. [weakself.dataArray insertObjects:formated atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, [formated count])]];
  2376. if (![weakself.dataArray.firstObject isKindOfClass:[NSString class]]) {
  2377. [weakself.dataArray removeObjectAtIndex:0];
  2378. }
  2379. dispatch_async(dispatch_get_main_queue(), ^{
  2380. [weakself.tableView reloadData];
  2381. [weakself returnMessge];
  2382. if (weakself.isFirstLoadMsg) {
  2383. weakself.isFirstLoadMsg = NO;
  2384. [weakself _scrollToBottomRow];
  2385. }
  2386. });
  2387. });
  2388. }
  2389. if (!aError && [aMessages count] == 0) {
  2390. [weakself returnMessge];
  2391. }
  2392. [weakself tableViewDidFinishTriggerHeader:YES reload:NO];
  2393. };
  2394. if ([EMDemoOptions sharedOptions].isPriorityGetMsgFromServer) {
  2395. EMConversation *conversation = self.conversationModel.emModel;
  2396. [EMClient.sharedClient.chatManager asyncFetchHistoryMessagesFromServer:conversation.conversationId
  2397. conversationType:conversation.type
  2398. startMessageId:self.moreMsgId
  2399. pageSize:50
  2400. completion:^(EMCursorResult *aResult, EMError *aError)
  2401. {
  2402. block(aResult.list, aError);
  2403. }];
  2404. } else {
  2405. [self.conversationModel.emModel loadMessagesStartFromId:self.moreMsgId
  2406. count:50
  2407. searchDirection:EMMessageSearchDirectionUp
  2408. completion:block];
  2409. if(self.conversationModel.emModel.unreadMessagesCount > 0){
  2410. [self sendDidReadReceipt];
  2411. }
  2412. }
  2413. }
  2414. #pragma mark - 转发消息
  2415. - (void)returnMessge
  2416. {
  2417. if (self.isReturn) {
  2418. self.backRoot = YES;
  2419. self.isReturn = NO;
  2420. [[NSNotificationCenter defaultCenter] postNotificationName:MESSAGERETURNSUCCESS object:nil];
  2421. switch (self.sendModel.SoureTypeId) {
  2422. case CollectModel_Text:///文本
  2423. {
  2424. [self _sendTextAction:self.sendModel.Title ext:nil];
  2425. }
  2426. break;
  2427. case CollectModel_Aritle:
  2428. {
  2429. [self _sendTextAction:@"文章" ext:@{@"app":@(YES),
  2430. @"app_type":@(CollectModel_Aritle),
  2431. @"app_title":self.sendModel.Title,
  2432. @"app_id":@(self.sendModel.SoureId),
  2433. @"app_content":@"来自-文章",
  2434. @"app_sourceUserId":@(self.sendModel.SourceUserId),
  2435. @"app_min_url":self.sendModel.MinUrl,
  2436. @"app_url":self.sendModel.Url,
  2437. }];
  2438. }
  2439. break;
  2440. case CollectModel_Notice:
  2441. {
  2442. [self _sendTextAction:@"通知" ext:@{@"app":@(YES),
  2443. @"app_type":@(CollectModel_Notice),
  2444. @"app_title":self.sendModel.Title,
  2445. @"app_id":@(self.sendModel.SoureId),
  2446. @"app_content":@"来自-通知",
  2447. @"app_sourceUserId":@(self.sendModel.SourceUserId),
  2448. @"app_min_url":self.sendModel.MinUrl,
  2449. @"app_url":self.sendModel.Url,
  2450. }];
  2451. }
  2452. break;
  2453. case CollectModel_NoteBook:
  2454. {
  2455. [self _sendTextAction:@"笔记" ext:@{@"app":@(YES),
  2456. @"app_type":@(CollectModel_NoteBook),
  2457. @"app_title":self.sendModel.Title,
  2458. @"app_id":@(self.sendModel.SoureId),
  2459. @"app_content":ISEmpty(self.sendModel.Author) ? @"" : self.sendModel.Author,
  2460. @"app_sourceUserId":@(self.sendModel.SourceUserId),
  2461. @"app_min_url":self.sendModel.MinUrl,
  2462. @"app_url":self.sendModel.Url,
  2463. }];
  2464. }
  2465. break;
  2466. case CollectModel_NewTopic:
  2467. {
  2468. [self _sendTextAction:@"话题" ext:@{@"app":@(YES),
  2469. @"app_type":@(CollectModel_NewTopic),
  2470. @"app_title":self.sendModel.Title,
  2471. @"app_id":@(self.sendModel.SoureId),
  2472. @"app_content":ISEmpty(self.sendModel.Author) ? @"" : self.sendModel.Author,
  2473. @"app_sourceUserId":@(self.sendModel.SourceUserId),
  2474. @"app_min_url":self.sendModel.MinUrl,
  2475. @"app_url":self.sendModel.Url,
  2476. }];
  2477. }
  2478. break;
  2479. case CollectModel_Toipc:
  2480. {
  2481. [self _sendTextAction:@"小组话题" ext:@{@"app":@(YES),
  2482. @"app_type":@(CollectModel_Toipc),
  2483. @"app_title":self.sendModel.Title,
  2484. @"app_id":@(self.sendModel.SoureId),
  2485. @"app_groupname":self.sendModel.GroupName,
  2486. @"app_groupid":@(self.sendModel.GroupId),
  2487. @"app_content":ISEmpty(self.sendModel.Author) ? @"" : self.sendModel.Author,
  2488. @"app_sourceUserId":@(self.sendModel.SourceUserId),
  2489. @"app_min_url":self.sendModel.MinUrl,
  2490. @"app_url":self.sendModel.Url,
  2491. }];
  2492. }
  2493. break;
  2494. case CollectModel_InterMail:
  2495. {
  2496. [self _sendTextAction:@"站内信" ext:@{@"app":@(YES),
  2497. @"app_type":@(CollectModel_InterMail),
  2498. @"app_title":self.sendModel.Title,
  2499. @"app_id":@(self.sendModel.SoureId),
  2500. @"app_content":ISEmpty(self.sendModel.Author) ? @"" : self.sendModel.Author,
  2501. @"app_sourceUserId":@(self.sendModel.SourceUserId),
  2502. @"app_min_url":self.sendModel.MinUrl,
  2503. @"app_url":self.sendModel.Url,
  2504. }];
  2505. }
  2506. break;
  2507. case CollectModel_NoSignMail:
  2508. {
  2509. [self _sendTextAction:@"站内信" ext:@{@"app":@(YES),
  2510. @"app_type":@(CollectModel_InterMail),
  2511. @"app_title":self.sendModel.Title,
  2512. @"app_id":@(self.sendModel.SoureId),
  2513. @"app_content":@"匿名",
  2514. @"app_sourceUserId":@(self.sendModel.SourceUserId),
  2515. @"app_min_url":self.sendModel.MinUrl,
  2516. @"app_url":self.sendModel.Url,
  2517. }];
  2518. }
  2519. break;
  2520. case CollectModel_CollectFile:
  2521. {
  2522. [self _sendTextAction:@"收藏文件夹" ext:@{@"app":@(YES),
  2523. @"app_type":@(CollectModel_CollectFile),
  2524. @"app_title":self.sendModel.Title,
  2525. @"app_id":@(self.sendModel.SoureId),
  2526. @"app_content":@"来自-收藏文件夹",
  2527. @"app_sourceUserId":@(self.sendModel.SourceUserId),
  2528. @"app_min_url":self.sendModel.MinUrl,
  2529. @"app_url":self.sendModel.Url,
  2530. }];
  2531. }
  2532. break;
  2533. case CollectModel_NoteFile:
  2534. {
  2535. [self _sendTextAction:@"笔记文件夹" ext:@{@"app":@(YES),
  2536. @"app_type":@(CollectModel_NoteFile),
  2537. @"app_title":self.sendModel.Title,
  2538. @"app_id":@(self.sendModel.SoureId),
  2539. @"app_content":@"来自-笔记文件夹",
  2540. @"app_sourceUserId":@(self.sendModel.SourceUserId),
  2541. @"app_min_url":self.sendModel.MinUrl,
  2542. @"app_url":self.sendModel.Url,
  2543. }];
  2544. }
  2545. break;
  2546. case CollectModel_meetMian:
  2547. {
  2548. [self _sendTextAction:@"会议纪要" ext:@{@"app":@(YES),
  2549. @"app_type":@(CollectModel_meetMian),
  2550. @"app_title":self.sendModel.Title,
  2551. @"app_id":@(self.sendModel.SoureId),
  2552. @"app_content":@"来自-会议纪要",
  2553. @"app_sourceUserId":@(self.sendModel.SourceUserId),
  2554. @"app_min_url":self.sendModel.MinUrl,
  2555. @"app_url":self.sendModel.Url,
  2556. }];
  2557. }
  2558. break;
  2559. case CollectModel_Image:///图片
  2560. {
  2561. [self _sendImageDataAction:[NSData dataWithContentsOfURL:[NSURL URLWithString:self.sendModel.Url]]];
  2562. }
  2563. break;
  2564. case CollectModel_file:///文件
  2565. {
  2566. [self _sendTextAction:@"文件" ext:@{@"app":@(YES),
  2567. @"app_type":@(CollectModel_file),
  2568. @"app_title":self.sendModel.Title,
  2569. @"app_id":@(self.sendModel.SoureId),
  2570. @"app_content":@"来自-文件",
  2571. @"app_sourceUserId":@(self.sendModel.SourceUserId),
  2572. @"app_min_url":self.sendModel.MinUrl,
  2573. @"app_url":self.sendModel.Url,
  2574. }];
  2575. }
  2576. break;
  2577. case CollectModel_work:///工作
  2578. {
  2579. [self _sendTextAction:@"审批" ext:@{@"app":@(YES),
  2580. @"app_type":@(CollectModel_work),
  2581. @"app_title":self.sendModel.Title,
  2582. @"app_id":@(self.sendModel.SoureId),
  2583. @"app_content":@"来自-审批",
  2584. @"app_sourceUserId":@(self.sendModel.SourceUserId),
  2585. @"app_min_url":@"",
  2586. @"app_url":@""
  2587. }];
  2588. }
  2589. break;
  2590. case CollectModel_meetDetail:///会议
  2591. {
  2592. [self _sendTextAction:@"会议" ext:@{@"app":@(YES),
  2593. @"app_type":@(CollectModel_meetDetail),
  2594. @"app_title":self.sendModel.Title,
  2595. @"app_id":@(self.sendModel.SoureId),
  2596. @"app_content":@"来自-会议",
  2597. @"app_sourceUserId":@(self.sendModel.SourceUserId),
  2598. @"app_min_url":@"",
  2599. @"app_url":@""
  2600. }];
  2601. }
  2602. break;
  2603. case CollectModel_financeCount:///文本
  2604. {
  2605. [self _sendTextAction:@"财务统计" ext:@{@"app":@(YES),
  2606. @"app_type":@(CollectModel_financeCount),
  2607. @"app_title":self.sendModel.Title,
  2608. @"app_id":@(self.sendModel.SoureId),
  2609. @"app_content":@"来自-财务统计",
  2610. @"app_sourceUserId":@(self.sendModel.SourceUserId),
  2611. @"app_min_url":@"",
  2612. @"app_url":@""
  2613. }];
  2614. }
  2615. break;
  2616. case CollectModel_affairsCount:///文本
  2617. {
  2618. [self _sendTextAction:@"人事统计" ext:@{@"app":@(YES),
  2619. @"app_type":@(CollectModel_affairsCount),
  2620. @"app_title":self.sendModel.Title,
  2621. @"app_id":@(self.sendModel.SoureId),
  2622. @"app_content":@"来自-人事统计",
  2623. @"app_sourceUserId":@(self.sendModel.SourceUserId),
  2624. @"app_min_url":@"",
  2625. @"app_url":@""
  2626. }];
  2627. }
  2628. break;
  2629. case CollectModel_publishCount:///文本
  2630. {
  2631. [self _sendTextAction:@"出版统计" ext:@{@"app":@(YES),
  2632. @"app_type":@(CollectModel_publishCount),
  2633. @"app_title":self.sendModel.Title,
  2634. @"app_id":@(self.sendModel.SoureId),
  2635. @"app_content":@"来自-出版统计",
  2636. @"app_sourceUserId":@(self.sendModel.SourceUserId),
  2637. @"app_min_url":@"",
  2638. @"app_url":@""
  2639. }];
  2640. }
  2641. break;
  2642. case CollectModel_TopicBooK:///文本
  2643. {
  2644. [self _sendTextAction:@"话题本" ext:@{@"app":@(YES),
  2645. @"app_type":@(CollectModel_TopicBooK),
  2646. @"app_title":self.sendModel.Title,
  2647. @"app_id":@(self.sendModel.SoureId),
  2648. @"app_content":@"来自-话题本",
  2649. @"app_sourceUserId":@(self.sendModel.SourceUserId),
  2650. @"app_min_url":@"",
  2651. @"app_url":@""
  2652. }];
  2653. }
  2654. break;
  2655. case CollectModel_TopicSubBooK:///文本
  2656. {
  2657. [self _sendTextAction:@"话题本" ext:@{@"app":@(YES),
  2658. @"app_type":@(CollectModel_TopicSubBooK),
  2659. @"app_title":self.sendModel.Title,
  2660. @"app_id":@(self.sendModel.SoureId),
  2661. @"app_content":@"来自-话题本",
  2662. @"app_sourceUserId":@(self.sendModel.SourceUserId),
  2663. @"app_min_url":@"",
  2664. @"app_url":@""
  2665. }];
  2666. }
  2667. break;
  2668. case CollectModel_StoreSound:///文本
  2669. {
  2670. [self _sendTextAction:@"音频" ext:@{@"app":@(YES),
  2671. @"app_type":@(CollectModel_StoreSound),
  2672. @"app_title":self.sendModel.Title,
  2673. @"app_id":@(self.sendModel.SoureId),
  2674. @"app_content":ISEmpty(self.sendModel.Author) ? @"" : self.sendModel.Author,
  2675. @"app_sourceUserId":@(self.sendModel.SourceUserId),
  2676. @"app_min_url":self.sendModel.MinUrl,
  2677. @"app_url":self.sendModel.Url
  2678. }];
  2679. }
  2680. break;
  2681. case CollectModel_StoreVideo:///文本
  2682. {
  2683. [self _sendTextAction:@"视频" ext:@{@"app":@(YES),
  2684. @"app_type":@(CollectModel_StoreVideo),
  2685. @"app_title":self.sendModel.Title,
  2686. @"app_id":@(self.sendModel.SoureId),
  2687. @"app_content":ISEmpty(self.sendModel.Author) ? @"" : self.sendModel.Author,
  2688. @"app_sourceUserId":@(self.sendModel.SourceUserId),
  2689. @"app_min_url":self.sendModel.MinUrl,
  2690. @"app_url":self.sendModel.Url
  2691. }];
  2692. }
  2693. break;
  2694. case CollectModel_StoreBook:///文本
  2695. {
  2696. [self _sendTextAction:@"图书" ext:@{@"app":@(YES),
  2697. @"app_type":@(CollectModel_StoreBook),
  2698. @"app_title":self.sendModel.Title,
  2699. @"app_id":@(self.sendModel.SoureId),
  2700. @"app_content":ISEmpty(self.sendModel.Author) ? @"" : self.sendModel.Author,
  2701. @"app_sourceUserId":@(self.sendModel.SourceUserId),
  2702. @"app_min_url":self.sendModel.MinUrl,
  2703. @"app_url":self.sendModel.Url
  2704. }];
  2705. }
  2706. break;
  2707. case CollectModel_StoreCousre:///文本
  2708. {
  2709. [self _sendTextAction:@"课程" ext:@{@"app":@(YES),
  2710. @"app_type":@(CollectModel_StoreCousre),
  2711. @"app_title":self.sendModel.Title,
  2712. @"app_id":@(self.sendModel.SoureId),
  2713. @"app_content":ISEmpty(self.sendModel.Author) ? @"" : self.sendModel.Author,
  2714. @"app_sourceUserId":@(self.sendModel.SourceUserId),
  2715. @"app_min_url":self.sendModel.MinUrl,
  2716. @"app_url":self.sendModel.Url
  2717. }];
  2718. }
  2719. break;
  2720. case CollectModel_MediaAritle:///文本
  2721. {
  2722. [self _sendTextAction:@"文章" ext:@{@"app":@(YES),
  2723. @"app_type":@(CollectModel_MediaAritle),
  2724. @"app_title":self.sendModel.Title,
  2725. @"app_id":@(self.sendModel.SoureId),
  2726. @"app_content":ISEmpty(self.sendModel.Author) ? @"" : self.sendModel.Author,
  2727. @"app_sourceUserId":@(self.sendModel.SourceUserId),
  2728. @"app_min_url":self.sendModel.MinUrl,
  2729. @"app_url":self.sendModel.Url
  2730. }];
  2731. }
  2732. break;
  2733. default:
  2734. {
  2735. [self _sendTextAction:@"出版统计" ext:@{@"app":@(YES),
  2736. @"app_type":@(CollectModel_publishCount),
  2737. @"app_title":self.sendModel.Title,
  2738. @"app_id":@(self.sendModel.SoureId),
  2739. @"app_content":@"来自-出版统计",
  2740. @"app_sourceUserId":@(self.sendModel.SourceUserId),
  2741. @"app_min_url":@"",
  2742. @"app_url":@""
  2743. }];
  2744. }
  2745. break;
  2746. }
  2747. }
  2748. }
  2749. #pragma mark - Action
  2750. - (void)backAction
  2751. {
  2752. [[EMAudioPlayerHelper sharedHelper] stopPlayer];
  2753. [EMConversationHelper resortConversationsLatestMessage];
  2754. EMConversation *conversation = self.conversationModel.emModel;
  2755. if (conversation.type == EMChatTypeChatRoom) {
  2756. [[EMClient sharedClient].roomManager leaveChatroom:conversation.conversationId completion:nil];
  2757. }
  2758. [self.navigationController popViewControllerAnimated:YES];
  2759. }
  2760. //删除该会话所有消息,同时清除内存和数据库中的消息
  2761. - (void)deleteAllMessageAction
  2762. {
  2763. EMError *error = nil;
  2764. [self.conversationModel.emModel deleteAllMessages:&error];
  2765. if (!error) {
  2766. [self.dataArray removeAllObjects];
  2767. [self.tableView reloadData];
  2768. }
  2769. }
  2770. - (void)groupOrChatroomInfoAction
  2771. {
  2772. if (self.conversationModel.emModel.type == EMConversationTypeGroupChat) {
  2773. [[NSNotificationCenter defaultCenter] postNotificationName:GROUP_INFO_PUSHVIEWCONTROLLER object:@{NOTIF_ID:self.conversationModel.emModel.conversationId, NOTIF_NAVICONTROLLER:self.navigationController}];
  2774. } else if (self.conversationModel.emModel.type == EMConversationTypeChatRoom) {
  2775. [[NSNotificationCenter defaultCenter] postNotificationName:CHATROOM_INFO_PUSHVIEWCONTROLLER object:@{NOTIF_ID:self.conversationModel.emModel.conversationId, NOTIF_NAVICONTROLLER:self.navigationController}];
  2776. }
  2777. }
  2778. //发送消息体
  2779. - (void)_sendMessageWithBody:(EMMessageBody *)aBody
  2780. ext:(NSDictionary *)aExt
  2781. isUpload:(BOOL)aIsUpload
  2782. {
  2783. if (!([EMClient sharedClient].options.isAutoTransferMessageAttachments) && aIsUpload) {
  2784. [self _showCustomTransferFileAlertView];
  2785. return;
  2786. }
  2787. NSString *from = [[EMClient sharedClient] currentUsername];
  2788. NSString *to = self.conversationModel.emModel.conversationId;
  2789. EMMessage *message = [[EMMessage alloc] initWithConversationID:to from:from to:to body:aBody ext:aExt];
  2790. //是否需要发送阅读回执
  2791. if([aExt objectForKey:MSG_EXT_READ_RECEIPT]) {
  2792. message.isNeedGroupAck = YES;
  2793. }
  2794. message.chatType = (EMChatType)self.conversationModel.emModel.type;
  2795. __weak typeof(self) weakself = self;
  2796. [[EMClient sharedClient].chatManager sendMessage:message progress:nil completion:^(EMMessage *message, EMError *error) {
  2797. NSArray *formated = [weakself _formatMessages:@[message]];
  2798. [weakself.dataArray addObjectsFromArray:formated];
  2799. dispatch_async(dispatch_get_main_queue(), ^{
  2800. [weakself.tableView reloadData];
  2801. [weakself _scrollToBottomRow];
  2802. });
  2803. NSString * text = @"";
  2804. switch (message.body.type) {
  2805. case EMMessageBodyTypeText:
  2806. {
  2807. EMTextMessageBody *body = (EMTextMessageBody *)aBody;
  2808. text = body.text;
  2809. }
  2810. break;
  2811. case EMMessageBodyTypeImage:
  2812. text = @"[图片]";
  2813. break;
  2814. case EMMessageBodyTypeVideo:
  2815. text = @"[视频]";
  2816. break;
  2817. case EMMessageBodyTypeVoice:
  2818. text = @"[语音]";
  2819. break;
  2820. case EMMessageBodyTypeFile:
  2821. text = @"[文件]";
  2822. break;
  2823. default:
  2824. break;
  2825. }
  2826. NSLog(@"%@",@{@"ContactUserId":[NSString stringWithFormat:@"%ld",(long)self.toUserId],@"IndividualGroupId":@(self.IndividualGroupId),@"Text":text});
  2827. dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
  2828. [[HttpManager sharedHttpManager] POSTUrl:Host(Often_Contact_Add_Post) parameters:@{@"ContactUserId":[NSString stringWithFormat:@"%ld",(long)self.toUserId],@"IndividualGroupId":@(self.IndividualGroupId),@"ChatType":@(self.chatType),@"Text":text} responseStyle:JOSN success:^(id _Nonnull responseObject) {
  2829. NSLog(@"%@",responseObject);
  2830. if ([responseObject isKindOfClass:[NSDictionary class]]) {
  2831. NSInteger listId = [[responseObject objectForKey:@"Id"] integerValue];
  2832. if (listId > 0) {
  2833. weakself.listId = listId;
  2834. weakself.isTop = [[responseObject objectForKey:@"IsTop"] integerValue];
  2835. }
  2836. }
  2837. } failure:^(NSError * _Nonnull error) {
  2838. }];
  2839. });
  2840. }];
  2841. }
  2842. #pragma mark - CustomView
  2843. - (UIView *)titleV
  2844. {
  2845. if (!_titleV) {
  2846. _titleV = [UIView new];
  2847. _titleV.backgroundColor = [UIColor whiteColor];
  2848. }
  2849. return _titleV;
  2850. }
  2851. - (UIButton *)backBtn
  2852. {
  2853. if (!_backBtn) {
  2854. _backBtn = [UIButton new];
  2855. [_backBtn setImage:[UIImage imageNamed:@"back_black_icon"] forState:UIControlStateNormal];
  2856. }
  2857. return _backBtn;
  2858. }
  2859. - (UIButton *)tabBtn
  2860. {
  2861. if (!_tabBtn) {
  2862. _tabBtn = [UIButton new];
  2863. [_tabBtn setImage:[UIImage imageNamed:@"menu_black_icon"] forState:UIControlStateNormal];
  2864. }
  2865. return _tabBtn;
  2866. }
  2867. - (UILabel *)titleL
  2868. {
  2869. if (!_titleL) {
  2870. _titleL = [UILabel new];
  2871. [_titleL setTextColor: UIColorHex(0A0A0A)];
  2872. _titleL.font = [UIFont systemFontOfSize:18];
  2873. }
  2874. return _titleL;
  2875. }
  2876. - (UIButton *)mangerBtn
  2877. {
  2878. if (!_mangerBtn) {
  2879. _mangerBtn = [UIButton new];
  2880. [_mangerBtn setImage:[UIImage imageNamed:@"chatmsg_detailchat_more_icon"] forState:UIControlStateNormal];
  2881. }
  2882. return _mangerBtn;
  2883. }
  2884. - (NSMutableArray *)userInfoArray
  2885. {
  2886. if (!_userInfoArray) {
  2887. _userInfoArray = [NSMutableArray array];
  2888. }
  2889. return _userInfoArray;
  2890. }
  2891. - (void)selectMoreMenu:(NSInteger)index title:(NSString *)title
  2892. {
  2893. switch (index) {
  2894. case 0:{
  2895. [self chatBarDidCameraAction];
  2896. }break;
  2897. case 1:{
  2898. [self chatBarDidPhotoAction];
  2899. }break;
  2900. case 2:{
  2901. FavoritesViewController *favorites = [[FavoritesViewController alloc] init];
  2902. favorites.title = @"我的笔记";
  2903. [self.navigationController pushViewController:favorites animated:YES];
  2904. }break;
  2905. case 3:{
  2906. FavoritesViewController *favorites = [[FavoritesViewController alloc] init];
  2907. favorites.title = @"我的收藏";
  2908. [self.navigationController pushViewController:favorites animated:YES];
  2909. }break;
  2910. default:
  2911. break;
  2912. }
  2913. }
  2914. - (NSMutableArray *)chatDistoryArray
  2915. {
  2916. if(!_chatDistoryArray)
  2917. {
  2918. _chatDistoryArray = [[NSMutableArray alloc] initWithArray:USERDEFAULTSGET(@"ChatList")];
  2919. }
  2920. return _chatDistoryArray;
  2921. }
  2922. - (NSString *)getUserInfoInDocument{
  2923. for (NSDictionary * dict in self.chatDistoryArray) {
  2924. if ([[dict objectForKey:@"ImId"] isEqualToString:self.conversationModel.emModel.conversationId]) {
  2925. NSString * text = [dict objectForKey:@"text"];
  2926. return text;
  2927. }
  2928. }
  2929. return @"";
  2930. }
  2931. - (void)clearUserInfoInDocument
  2932. {
  2933. for (NSDictionary * dict in self.chatDistoryArray) {
  2934. if ([[dict objectForKey:@"ImId"] isEqualToString:self.conversationModel.emModel.conversationId]) {
  2935. [self.chatDistoryArray removeObject:dict];
  2936. break;
  2937. }
  2938. }
  2939. USERDEFAULTSSET(self.chatDistoryArray,@"ChatList");
  2940. }
  2941. - (void)saveUserInfoInDocument:(NSString *)text{
  2942. for (NSDictionary * dict in self.chatDistoryArray) {
  2943. if ([[dict objectForKey:@"ImId"] isEqualToString:self.conversationModel.emModel.conversationId]) {
  2944. [self.chatDistoryArray removeObject:dict];
  2945. break;
  2946. }
  2947. }
  2948. [self.chatDistoryArray addObject:@{@"ImId":self.conversationModel.emModel.conversationId,@"text":text}];
  2949. USERDEFAULTSSET(self.chatDistoryArray,@"ChatList");
  2950. }
  2951. - (void)deleteConversationMsg
  2952. {
  2953. WS(weakSelf);
  2954. [[EMClient sharedClient].chatManager deleteConversation:self.conversationModel.emModel.conversationId isDeleteMessages:YES completion:^(NSString *aConversationId, EMError *aError) {
  2955. [weakSelf deleteAllMessageAction];
  2956. }];
  2957. }
  2958. #pragma mark - 转发
  2959. - (void)shareHander{
  2960. [self.noteBookShareVC initNoteBookShareData];
  2961. self.noteBookShareVC.view.hidden = !self.noteBookShareVC.view.hidden;
  2962. }
  2963. - (NoteBookShareVC *)noteBookShareVC{
  2964. if (_noteBookShareVC == nil) {
  2965. _noteBookShareVC = [NoteBookShareVC initNoteBookShareVC];
  2966. [_noteBookShareVC.view setFrame:CGRectMake(0,0, SCREEN_WIDTH, SCREEN_HEIGHT)];
  2967. [_noteBookShareVC.view setHidden:YES];
  2968. _noteBookShareVC.delegate = self;
  2969. }
  2970. return _noteBookShareVC;
  2971. }
  2972. -(void)userSelectType:(NSString *)typeName WithIndexPath:(NSIndexPath *)indexPath{
  2973. self.noteBookShareVC.view.hidden = !self.noteBookShareVC.view.hidden;
  2974. if ([typeName isEqualToString:@"发给微信好友"]) {
  2975. }else if ([typeName isEqualToString:@"发到朋友圈"]){
  2976. }else if ([typeName isEqualToString:@"发到微博"]){
  2977. }else if ([typeName isEqualToString:@"发给QQ好友"]){
  2978. }else if ([typeName isEqualToString:@"发到消息"]){
  2979. }else if ([typeName isEqualToString:@"发到小组"]){
  2980. // [self returnToGroup];
  2981. }else if ([typeName isEqualToString:@"发到笔记"]){
  2982. [self returnToNote];
  2983. }else if ([typeName isEqualToString:@"发到话题"]){
  2984. [self returnToTopic];
  2985. }else{
  2986. }
  2987. }
  2988. #pragma mark - 分享功能
  2989. //- (void)returnToGroup
  2990. //{
  2991. // MyTDGroupViewController * vc = [[MyTDGroupViewController alloc] init];
  2992. // vc.type = CollectModel_Group;
  2993. // FlowAttachmentsModel * model = [[FlowAttachmentsModel alloc] init];
  2994. // model.SoureId = self.Id;
  2995. // model.SoureTypeId = self.type;
  2996. // model.Title = self.currentNoteModel.Title;
  2997. // model.Author = self.currentNoteModel.UserName;
  2998. // vc.sendModel = model;
  2999. // vc.isReturn = YES;
  3000. // [self.navigationController pushViewController:vc animated:YES];
  3001. //}
  3002. - (void)returnToNote
  3003. {
  3004. MoveViewController * vc = [MoveViewController initMoveViewController];
  3005. vc.isFromCreateBookVc = YES;
  3006. vc.TypeId = CreateNotesType;
  3007. vc.CollectionType = CollectModel_NoteBook;
  3008. vc.ParentId = 0;
  3009. vc.sendModel = self.sendModel;
  3010. vc.sendImage = self.sendImage;
  3011. vc.isReturn = YES;
  3012. [self.navigationController pushViewController:vc animated:YES];
  3013. }
  3014. - (void)returnToTopic
  3015. {
  3016. MyTDTopicCreateVC * vc = [MyTDTopicCreateVC initMyTDTopicCreateVC];
  3017. vc.type = CollectModel_NewTopic;
  3018. vc.sendModel = self.sendModel;
  3019. vc.sendImage = self.sendImage;
  3020. vc.isReturn = YES;
  3021. [self.navigationController pushViewController:vc animated:YES];
  3022. }
  3023. @end