EMChatViewController.m 141 KB

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