EMChatViewController.m 133 KB

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