mirror of
https://github.com/wu736139669/Ash_AWord.git
synced 2026-08-05 05:55:19 +00:00
1239 lines
49 KiB
Objective-C
1239 lines
49 KiB
Objective-C
//
|
|
// ChatMainViewController.m
|
|
// Ash_AWord
|
|
//
|
|
// Created by xmfish on 15/6/18.
|
|
// Copyright (c) 2015年 ash. All rights reserved.
|
|
//
|
|
|
|
#import "ChatMainViewController.h"
|
|
#import "DXMessageToolBar.h"
|
|
#import "DXChatBarMoreView.h"
|
|
#import <AVFoundation/AVFoundation.h>
|
|
#import <MediaPlayer/MediaPlayer.h>
|
|
#import "EMCDDeviceManager.h"
|
|
#import "EMChatVoice.h"
|
|
#import "EMChatVideo.h"
|
|
#import "LocationViewController.h"
|
|
#import "CallViewController.h"
|
|
#import "EaseMob.h"
|
|
#import "ChatSendHelper.h"
|
|
#import "EMChatTimeCell.h"
|
|
#import "MessageViewModel.h"
|
|
#import "MessageModel.h"
|
|
#import "EMChatViewCell.h"
|
|
#import "NSDate+Category.h"
|
|
#import "MessageModelManager.h"
|
|
#import "NSDateFormatter+Category.h"
|
|
#import "MessageReadManager.h"
|
|
#import "SRRefreshView.h"
|
|
#import "PersonalInfoViewController.h"
|
|
#import "AppDelegate.h"
|
|
#define KPageCount 20
|
|
|
|
@interface ChatMainViewController ()<UITableViewDelegate,UITableViewDataSource,DXMessageToolBarDelegate,LocationViewDelegate,UINavigationControllerDelegate, UIImagePickerControllerDelegate,DXChatBarMoreViewDelegate,EMCallManagerDelegate,EMCDDeviceManagerDelegate,EMChatManagerDelegate,SRRefreshDelegate>
|
|
{
|
|
DXMessageToolBar *_chatToolBar;
|
|
NSMutableArray* _dataSource;
|
|
NSMutableArray *_messages;
|
|
dispatch_queue_t _messageQueue;
|
|
NSDate *_chatTagDate;
|
|
|
|
}
|
|
@property (strong, nonatomic) EMConversation *conversation;//会话管理者
|
|
@property (strong, nonatomic) MessageReadManager *messageReadManager;//message阅读的管理者
|
|
@property (strong, nonatomic) SRRefreshView *slimeView;
|
|
|
|
@property (nonatomic) BOOL isPlayingAudio;
|
|
|
|
@end
|
|
|
|
@implementation ChatMainViewController
|
|
- (MessageReadManager *)messageReadManager
|
|
{
|
|
if (_messageReadManager == nil) {
|
|
_messageReadManager = [MessageReadManager defaultManager];
|
|
}
|
|
|
|
return _messageReadManager;
|
|
}
|
|
- (SRRefreshView *)slimeView
|
|
{
|
|
if (_slimeView == nil) {
|
|
_slimeView = [[SRRefreshView alloc] init];
|
|
_slimeView.delegate = self;
|
|
_slimeView.upInset = 0;
|
|
_slimeView.slimeMissWhenGoingBack = YES;
|
|
_slimeView.slime.bodyColor = [UIColor grayColor];
|
|
_slimeView.slime.skinColor = [UIColor grayColor];
|
|
_slimeView.slime.lineWith = 1;
|
|
_slimeView.slime.shadowBlur = 4;
|
|
_slimeView.slime.shadowColor = [UIColor grayColor];
|
|
}
|
|
|
|
return _slimeView;
|
|
}
|
|
|
|
|
|
- (void)viewDidLoad {
|
|
[super viewDidLoad];
|
|
// Do any additional setup after loading the view from its nib.
|
|
[self customViewDidLoad];
|
|
_tableView.dataSource = self;
|
|
_tableView.delegate = self;
|
|
_dataSource = [NSMutableArray array];
|
|
_messages = [NSMutableArray array];
|
|
_messageQueue = dispatch_queue_create("easemob.com", NULL);
|
|
_isPlayingAudio = NO;
|
|
|
|
self.navigationItem.title = _otherUserName;
|
|
|
|
if (!_otherUserName) {
|
|
_otherUserName = @"";
|
|
}
|
|
if (!_otherUserAvatar) {
|
|
_otherUserAvatar = @"";
|
|
}
|
|
//根据接收者的username获取当前会话的管理者
|
|
_conversation = [[EaseMob sharedInstance].chatManager conversationForChatter:_otherUserId conversationType:eConversationTypeChat];
|
|
[_conversation markAllMessagesAsRead:YES];
|
|
|
|
_chatToolBar = [[DXMessageToolBar alloc] initWithFrame:CGRectMake(0, self.view.frame.size.height-[DXMessageToolBar defaultHeight], kScreenWidth, [DXMessageToolBar defaultHeight])];
|
|
_chatToolBar.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleRightMargin;
|
|
_chatToolBar.delegate = self;
|
|
|
|
ChatMoreType type = ChatMoreTypeChat;
|
|
DXChatBarMoreView* dxChatBarMoreView = [[DXChatBarMoreView alloc] initWithFrame:CGRectMake(0, (kVerticalPadding * 2 + kInputTextViewMinHeight), _chatToolBar.frame.size.width, 80) typw:type];
|
|
dxChatBarMoreView.delegate = self;
|
|
_chatToolBar.moreView = dxChatBarMoreView;
|
|
_chatToolBar.moreView.backgroundColor = [UIColor colorWithRed:240.0/255.0 green:242.0/255.0 blue:247.0/255.0 alpha:1.0];
|
|
_chatToolBar.moreView.autoresizingMask = UIViewAutoresizingFlexibleTopMargin;
|
|
[self.view addSubview:_chatToolBar];
|
|
|
|
|
|
#warning 以下三行代码必须写,注册为SDK的ChatManager的delegate
|
|
[EMCDDeviceManager sharedInstance].delegate = self;
|
|
[[EaseMob sharedInstance].chatManager removeDelegate:self];
|
|
//注册为SDK的ChatManager的delegate
|
|
[[EaseMob sharedInstance].chatManager addDelegate:self delegateQueue:nil];
|
|
|
|
[[EaseMob sharedInstance].callManager removeDelegate:self];
|
|
// 注册为Call的Delegate
|
|
[[EaseMob sharedInstance].callManager addDelegate:self delegateQueue:nil];
|
|
|
|
|
|
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(keyBoardHidden)];
|
|
[self.view addGestureRecognizer:tap];
|
|
|
|
|
|
|
|
[self.tableView addSubview:self.slimeView];
|
|
|
|
|
|
//通过会话管理者获取已收发消息
|
|
[self loadMoreMessages];
|
|
}
|
|
|
|
#pragma mark - DXMessageToolBarDelegate
|
|
- (void)inputTextViewWillBeginEditing:(XHMessageTextView *)messageInputTextView{
|
|
}
|
|
|
|
- (void)didChangeFrameToHeight:(CGFloat)toHeight
|
|
{
|
|
[UIView animateWithDuration:0.3 animations:^{
|
|
CGRect rect = self.tableView.frame;
|
|
rect.origin.y = 0;
|
|
rect.size.height = self.view.frame.size.height - toHeight;
|
|
self.tableView.frame = rect;
|
|
}];
|
|
[self scrollViewToBottom:NO];
|
|
}
|
|
- (void)scrollViewToBottom:(BOOL)animated
|
|
{
|
|
if (self.tableView.contentSize.height > self.tableView.frame.size.height)
|
|
{
|
|
CGPoint offset = CGPointMake(0, self.tableView.contentSize.height - self.tableView.frame.size.height);
|
|
[self.tableView setContentOffset:offset animated:animated];
|
|
}
|
|
}
|
|
|
|
- (void)didSendText:(NSString *)text
|
|
{
|
|
if (text && text.length > 0) {
|
|
[self sendTextMessage:text];
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 按下录音按钮开始录音
|
|
*/
|
|
#pragma mark - private
|
|
|
|
- (BOOL)canRecord
|
|
{
|
|
__block BOOL bCanRecord = YES;
|
|
if ([[[UIDevice currentDevice] systemVersion] compare:@"7.0"] != NSOrderedAscending)
|
|
{
|
|
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
|
|
if ([audioSession respondsToSelector:@selector(requestRecordPermission:)]) {
|
|
[audioSession performSelector:@selector(requestRecordPermission:) withObject:^(BOOL granted) {
|
|
bCanRecord = granted;
|
|
}];
|
|
}
|
|
}
|
|
|
|
return bCanRecord;
|
|
}
|
|
- (void)didStartRecordingVoiceAction:(UIView *)recordView
|
|
{
|
|
if ([self canRecord]) {
|
|
DXRecordView *tmpView = (DXRecordView *)recordView;
|
|
tmpView.center = self.view.center;
|
|
[self.view addSubview:tmpView];
|
|
[self.view bringSubviewToFront:recordView];
|
|
int x = arc4random() % 100000;
|
|
NSTimeInterval time = [[NSDate date] timeIntervalSince1970];
|
|
NSString *fileName = [NSString stringWithFormat:@"%d%d",(int)time,x];
|
|
|
|
[[EMCDDeviceManager sharedInstance] asyncStartRecordingWithFileName:fileName
|
|
completion:^(NSError *error)
|
|
{
|
|
if (error) {
|
|
NSLog(NSLocalizedString(@"message.startRecordFail", @"failure to start recording"));
|
|
}
|
|
}];
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 手指向上滑动取消录音
|
|
*/
|
|
- (void)didCancelRecordingVoiceAction:(UIView *)recordView
|
|
{
|
|
[[EMCDDeviceManager sharedInstance] cancelCurrentRecording];
|
|
}
|
|
|
|
/**
|
|
* 松开手指完成录音
|
|
*/
|
|
- (void)didFinishRecoingVoiceAction:(UIView *)recordView
|
|
{
|
|
[[EMCDDeviceManager sharedInstance] asyncStopRecordingWithCompletion:^(NSString *recordPath, NSInteger aDuration, NSError *error) {
|
|
if (!error) {
|
|
EMChatVoice *voice = [[EMChatVoice alloc] initWithFile:recordPath
|
|
displayName:@"audio"];
|
|
voice.duration = aDuration;
|
|
[self sendAudioMessage:voice];
|
|
}else {
|
|
// [weakSelf showHudInView:self.view hint:@"录音时间太短了"];
|
|
[MBProgressHUD errorHudWithView:self.view label:@"录音时间太短了" hidesAfter:1.0];
|
|
_chatToolBar.recordButton.enabled = NO;
|
|
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
|
// [weakSelf hideHud];
|
|
_chatToolBar.recordButton.enabled = YES;
|
|
});
|
|
}
|
|
}];
|
|
}
|
|
|
|
|
|
#pragma mark - UIImagePickerControllerDelegate
|
|
|
|
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
|
|
{
|
|
NSString *mediaType = info[UIImagePickerControllerMediaType];
|
|
if ([mediaType isEqualToString:(NSString *)kUTTypeMovie]) {
|
|
NSURL *videoURL = info[UIImagePickerControllerMediaURL];
|
|
[picker dismissViewControllerAnimated:YES completion:^{
|
|
[[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithBool:NO] forKey:@"isShowPicker"];
|
|
}];
|
|
// video url:
|
|
// file:///private/var/mobile/Applications/B3CDD0B2-2F19-432B-9CFA-158700F4DE8F/tmp/capture-T0x16e39100.tmp.9R8weF/capturedvideo.mp4
|
|
// we will convert it to mp4 format
|
|
NSURL *mp4 = [self convert2Mp4:videoURL];
|
|
NSFileManager *fileman = [NSFileManager defaultManager];
|
|
if ([fileman fileExistsAtPath:videoURL.path]) {
|
|
NSError *error = nil;
|
|
[fileman removeItemAtURL:videoURL error:&error];
|
|
if (error) {
|
|
NSLog(@"failed to remove file, error:%@.", error);
|
|
}
|
|
}
|
|
EMChatVideo *chatVideo = [[EMChatVideo alloc] initWithFile:[mp4 relativePath] displayName:@"video.mp4"];
|
|
[self sendVideoMessage:chatVideo];
|
|
|
|
}else{
|
|
UIImage *orgImage = info[UIImagePickerControllerOriginalImage];
|
|
[picker dismissViewControllerAnimated:YES completion:^{
|
|
[[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithBool:NO] forKey:@"isShowPicker"];
|
|
}];
|
|
[self sendImageMessage:orgImage];
|
|
}
|
|
// self.isInvisible = NO;
|
|
}
|
|
|
|
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
|
|
{
|
|
[[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithBool:NO] forKey:@"isShowPicker"];
|
|
[picker dismissViewControllerAnimated:YES completion:nil];
|
|
// self.isInvisible = NO;
|
|
}
|
|
|
|
#pragma mark - EMChatBarMoreViewDelegate
|
|
|
|
- (void)moreViewPhotoAction:(DXChatBarMoreView *)moreView
|
|
{
|
|
[[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithBool:YES] forKey:@"isShowPicker"];
|
|
// 隐藏键盘
|
|
[self keyBoardHidden];
|
|
|
|
// 弹出照片选择
|
|
|
|
UIImagePickerController* picker = [[UIImagePickerController alloc] init];
|
|
// picker.allowsEditing = YES;
|
|
picker.delegate = self;
|
|
picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
|
|
[self presentViewController:picker animated:YES completion:nil];
|
|
|
|
}
|
|
|
|
#pragma mark - slimeRefresh delegate
|
|
//加载更多
|
|
- (void)slimeRefreshStartRefresh:(SRRefreshView *)refreshView
|
|
{
|
|
_chatTagDate = nil;
|
|
[self loadMoreMessages];
|
|
[_slimeView endRefresh];
|
|
}
|
|
|
|
// 点击背景隐藏
|
|
-(void)keyBoardHidden
|
|
{
|
|
[_chatToolBar endEditing:YES];
|
|
}
|
|
|
|
- (void)moreViewTakePicAction:(DXChatBarMoreView *)moreView
|
|
{
|
|
[[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithBool:YES] forKey:@"isShowPicker"];
|
|
[self keyBoardHidden];
|
|
|
|
#if TARGET_IPHONE_SIMULATOR
|
|
// [self showHint:NSLocalizedString(@"message.simulatorNotSupportCamera", @"simulator does not support taking picture")];
|
|
#elif TARGET_OS_IPHONE
|
|
UIImagePickerController* picker = [[UIImagePickerController alloc] init];
|
|
// picker.allowsEditing = YES;
|
|
picker.delegate = self;
|
|
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
|
|
[self presentViewController:picker animated:YES completion:nil];
|
|
#endif
|
|
}
|
|
|
|
- (void)moreViewLocationAction:(DXChatBarMoreView *)moreView
|
|
{
|
|
// 隐藏键盘
|
|
[self keyBoardHidden];
|
|
|
|
LocationViewController *locationController = [[LocationViewController alloc] initWithNibName:nil bundle:nil];
|
|
locationController.delegate = self;
|
|
[self.navigationController pushViewController:locationController animated:YES];
|
|
}
|
|
|
|
- (void)moreViewAudioCallAction:(DXChatBarMoreView *)moreView
|
|
{
|
|
// 隐藏键盘
|
|
[self keyBoardHidden];
|
|
[[NSNotificationCenter defaultCenter] postNotificationName:@"callOutWithChatter" object:@{@"chatter":_otherUserId, @"type":[NSNumber numberWithInt:eCallSessionTypeAudio],@"username":_otherUserName,@"useravatar":_otherUserAvatar}];
|
|
|
|
// EMCallSession *callSession = nil;
|
|
// EMError *error = nil;
|
|
|
|
// callSession = [[EaseMob sharedInstance].callManager asyncMakeVoiceCall:_conversation.chatter timeout:50 error:&error];
|
|
//
|
|
//
|
|
// CallViewController *callController = [[CallViewController alloc] initWithSession:callSession isIncoming:NO withName:_otherUserName withAvatar:_otherUserAvatar];
|
|
// callController.modalPresentationStyle = UIModalPresentationOverFullScreen;
|
|
// [self presentViewController:callController animated:NO completion:nil];
|
|
}
|
|
|
|
- (void)moreViewVideoCallAction:(DXChatBarMoreView *)moreView
|
|
{
|
|
// 隐藏键盘
|
|
[self keyBoardHidden];
|
|
[[NSNotificationCenter defaultCenter] postNotificationName:@"callOutWithChatter" object:@{@"chatter":_otherUserId, @"type":[NSNumber numberWithInt:eCallSessionTypeVideo],@"username":_otherUserName,@"useravatar":_otherUserAvatar}];
|
|
// EMCallSession *callSession = nil;
|
|
// EMError *error = nil;
|
|
//
|
|
// if (![CallViewController canVideo]) {
|
|
// return;
|
|
// }
|
|
// callSession = [[EaseMob sharedInstance].callManager asyncMakeVideoCall:_conversation.chatter timeout:50 error:&error];
|
|
//
|
|
//
|
|
// CallViewController *callController = [[CallViewController alloc] initWithSession:callSession isIncoming:NO withName:_otherUserName withAvatar:_otherUserAvatar];
|
|
// callController.modalPresentationStyle = UIModalPresentationOverFullScreen;
|
|
// [self presentViewController:callController animated:NO completion:nil];
|
|
}
|
|
|
|
#pragma mark - helper
|
|
- (NSURL *)convert2Mp4:(NSURL *)movUrl {
|
|
NSURL *mp4Url = nil;
|
|
AVURLAsset *avAsset = [AVURLAsset URLAssetWithURL:movUrl options:nil];
|
|
NSArray *compatiblePresets = [AVAssetExportSession exportPresetsCompatibleWithAsset:avAsset];
|
|
|
|
if ([compatiblePresets containsObject:AVAssetExportPresetHighestQuality]) {
|
|
AVAssetExportSession *exportSession = [[AVAssetExportSession alloc]initWithAsset:avAsset
|
|
presetName:AVAssetExportPresetHighestQuality];
|
|
mp4Url = [movUrl copy];
|
|
mp4Url = [mp4Url URLByDeletingPathExtension];
|
|
mp4Url = [mp4Url URLByAppendingPathExtension:@"mp4"];
|
|
exportSession.outputURL = mp4Url;
|
|
exportSession.shouldOptimizeForNetworkUse = YES;
|
|
exportSession.outputFileType = AVFileTypeMPEG4;
|
|
dispatch_semaphore_t wait = dispatch_semaphore_create(0l);
|
|
[exportSession exportAsynchronouslyWithCompletionHandler:^{
|
|
switch ([exportSession status]) {
|
|
case AVAssetExportSessionStatusFailed: {
|
|
NSLog(@"failed, error:%@.", exportSession.error);
|
|
} break;
|
|
case AVAssetExportSessionStatusCancelled: {
|
|
NSLog(@"cancelled.");
|
|
} break;
|
|
case AVAssetExportSessionStatusCompleted: {
|
|
NSLog(@"completed.");
|
|
} break;
|
|
default: {
|
|
NSLog(@"others.");
|
|
} break;
|
|
}
|
|
dispatch_semaphore_signal(wait);
|
|
}];
|
|
long timeout = dispatch_semaphore_wait(wait, DISPATCH_TIME_FOREVER);
|
|
if (timeout) {
|
|
NSLog(@"timeout.");
|
|
}
|
|
if (wait) {
|
|
//dispatch_release(wait);
|
|
wait = nil;
|
|
}
|
|
}
|
|
|
|
return mp4Url;
|
|
}
|
|
|
|
#pragma mark UITableViewDelegate
|
|
#pragma mark - Table view data source
|
|
|
|
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
|
|
{
|
|
// Return the number of sections.
|
|
return 1;
|
|
}
|
|
|
|
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
|
|
{
|
|
return _dataSource.count;
|
|
}
|
|
|
|
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
|
|
{
|
|
if (indexPath.row < [_dataSource count]) {
|
|
id obj = [_dataSource objectAtIndex:indexPath.row];
|
|
if ([obj isKindOfClass:[NSString class]]) {
|
|
EMChatTimeCell *timeCell = (EMChatTimeCell *)[tableView dequeueReusableCellWithIdentifier:@"MessageCellTime"];
|
|
if (timeCell == nil) {
|
|
timeCell = [[EMChatTimeCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"MessageCellTime"];
|
|
timeCell.backgroundColor = [UIColor clearColor];
|
|
timeCell.selectionStyle = UITableViewCellSelectionStyleNone;
|
|
}
|
|
|
|
timeCell.textLabel.text = (NSString *)obj;
|
|
|
|
return timeCell;
|
|
}
|
|
else{
|
|
MessageModel *model = (MessageModel *)obj;
|
|
NSString *cellIdentifier = [EMChatViewCell cellIdentifierForMessageModel:model];
|
|
EMChatViewCell *cell = (EMChatViewCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
|
|
if (cell == nil) {
|
|
cell = [[EMChatViewCell alloc] initWithMessageModel:model reuseIdentifier:cellIdentifier];
|
|
cell.backgroundColor = [UIColor clearColor];
|
|
cell.selectionStyle = UITableViewCellSelectionStyleNone;
|
|
}
|
|
cell.messageModel = model;
|
|
[cell setDelMessage:^(NSInteger index){
|
|
[self deleteMsgWithIndex:index];
|
|
}];
|
|
cell.tag = indexPath.row;
|
|
return cell;
|
|
}
|
|
}
|
|
|
|
return nil;
|
|
}
|
|
|
|
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
|
|
{
|
|
NSObject *obj = [_dataSource objectAtIndex:indexPath.row];
|
|
if ([obj isKindOfClass:[NSString class]]) {
|
|
return 40;
|
|
}
|
|
else{
|
|
return [EMChatViewCell tableView:tableView heightForRowAtIndexPath:indexPath withObject:(MessageModel *)obj];
|
|
}
|
|
}
|
|
|
|
#pragma mark - scrollView delegate
|
|
|
|
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
|
|
{
|
|
if (_slimeView) {
|
|
[_slimeView scrollViewDidScroll];
|
|
}
|
|
}
|
|
|
|
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
|
|
{
|
|
if (_slimeView) {
|
|
[_slimeView scrollViewDidEndDraging];
|
|
}
|
|
}
|
|
|
|
#pragma mark - send message
|
|
|
|
-(void)sendTextMessage:(NSString *)textMessage
|
|
{
|
|
EMMessage *tempMessage = [ChatSendHelper sendTextMessageWithString:textMessage
|
|
toUsername:_conversation.chatter
|
|
messageType:eMessageTypeChat
|
|
requireEncryption:NO
|
|
ext:[NSDictionary dictionaryWithObject:[AWordUser sharedInstance].userName forKey:@"username"]];
|
|
|
|
[self addMessage:tempMessage];
|
|
}
|
|
-(void)sendImageMessage:(UIImage *)image
|
|
{
|
|
EMMessage *tempMessage = [ChatSendHelper sendImageMessageWithImage:image
|
|
toUsername:_conversation.chatter
|
|
messageType:eMessageTypeChat
|
|
requireEncryption:NO
|
|
ext:[NSDictionary dictionaryWithObject:[AWordUser sharedInstance].userName forKey:@"username"]];
|
|
[self addMessage:tempMessage];
|
|
}
|
|
|
|
-(void)sendAudioMessage:(EMChatVoice *)voice
|
|
{
|
|
EMMessage *tempMessage = [ChatSendHelper sendVoice:voice
|
|
toUsername:_conversation.chatter
|
|
messageType:eMessageTypeChat
|
|
requireEncryption:NO ext:[NSDictionary dictionaryWithObject:[AWordUser sharedInstance].userName forKey:@"username"]];
|
|
[self addMessage:tempMessage];
|
|
}
|
|
|
|
-(void)sendVideoMessage:(EMChatVideo *)video
|
|
{
|
|
EMMessage *tempMessage = [ChatSendHelper sendVideo:video
|
|
toUsername:_conversation.chatter
|
|
messageType:eMessageTypeChat
|
|
requireEncryption:NO ext:[NSDictionary dictionaryWithObject:[AWordUser sharedInstance].userName forKey:@"username"]];
|
|
[self addMessage:tempMessage];
|
|
}
|
|
|
|
-(void)addMessage:(EMMessage *)message
|
|
{
|
|
[_messages addObject:message];
|
|
__weak ChatMainViewController *weakSelf = self;
|
|
dispatch_async(_messageQueue, ^{
|
|
NSArray *messages = [weakSelf formatMessage:message];
|
|
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
[_dataSource addObjectsFromArray:messages];
|
|
[weakSelf.tableView reloadData];
|
|
[weakSelf.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:[_dataSource count] - 1 inSection:0] atScrollPosition:UITableViewScrollPositionBottom animated:YES];
|
|
});
|
|
});
|
|
}
|
|
-(NSMutableArray *)formatMessage:(EMMessage *)message
|
|
{
|
|
NSMutableArray *ret = [[NSMutableArray alloc] init];
|
|
NSDate *createDate = [NSDate dateWithTimeIntervalInMilliSecondSince1970:(NSTimeInterval)message.timestamp];
|
|
NSTimeInterval tempDate = [createDate timeIntervalSinceDate:_chatTagDate];
|
|
if (tempDate > 60 || tempDate < -60 || (_chatTagDate == nil)) {
|
|
[ret addObject:[createDate formattedTime]];
|
|
_chatTagDate = createDate;
|
|
}
|
|
|
|
MessageModel *model = [MessageModelManager modelWithMessage:message];
|
|
|
|
if (model.isSender){
|
|
model.nickName = [AWordUser sharedInstance].userName;
|
|
|
|
model.headImageURL = [NSURL URLWithString:[AWordUser sharedInstance].userAvatar];
|
|
}else{
|
|
model.nickName = _otherUserName;
|
|
|
|
model.headImageURL = [NSURL URLWithString:_otherUserAvatar];
|
|
}
|
|
|
|
if (model) {
|
|
[ret addObject:model];
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
#pragma mark - LocationViewDelegate
|
|
|
|
-(void)sendLocationLatitude:(double)latitude longitude:(double)longitude andAddress:(NSString *)address
|
|
{
|
|
EMMessage *locationMessage = [ChatSendHelper sendLocationLatitude:latitude longitude:longitude address:address toUsername:_conversation.chatter messageType:eMessageTypeChat requireEncryption:NO ext:nil];
|
|
[self addMessage:locationMessage];
|
|
}
|
|
#pragma mark - ICallManagerDelegate
|
|
|
|
- (void)callSessionStatusChanged:(EMCallSession *)callSession changeReason:(EMCallStatusChangedReason)reason error:(EMError *)error{
|
|
if (reason == eCallReason_Null) {
|
|
if ([[EMCDDeviceManager sharedInstance] isPlaying]) {
|
|
[self stopAudioPlayingWithChangeCategory:NO];
|
|
}
|
|
}
|
|
}
|
|
|
|
-(void)didSendMessage:(EMMessage *)message error:(EMError *)error
|
|
{
|
|
[_dataSource enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop)
|
|
{
|
|
if ([obj isKindOfClass:[MessageModel class]])
|
|
{
|
|
MessageModel *model = (MessageModel*)obj;
|
|
if ([model.messageId isEqualToString:message.messageId])
|
|
{
|
|
model.message.deliveryState = message.deliveryState;
|
|
*stop = YES;
|
|
}
|
|
}
|
|
}];
|
|
[self.tableView reloadData];
|
|
}
|
|
|
|
- (void)reloadTableViewDataWithMessage:(EMMessage *)message{
|
|
__weak ChatMainViewController *weakSelf = self;
|
|
dispatch_async(_messageQueue, ^{
|
|
if ([_conversation.chatter isEqualToString:message.conversationChatter])
|
|
{
|
|
for (int i = 0; i < _dataSource.count; i ++) {
|
|
id object = [_dataSource objectAtIndex:i];
|
|
if ([object isKindOfClass:[MessageModel class]]) {
|
|
MessageModel *model = (MessageModel *)object;
|
|
if ([message.messageId isEqualToString:model.messageId]) {
|
|
MessageModel *cellModel = [MessageModelManager modelWithMessage:message];
|
|
cellModel.nickName = cellModel.username;
|
|
|
|
if (cellModel.isSender){
|
|
cellModel.headImageURL = [NSURL URLWithString:[AWordUser sharedInstance].userAvatar];
|
|
}else{
|
|
cellModel.headImageURL = [NSURL URLWithString:_otherUserAvatar];
|
|
}
|
|
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
[weakSelf.tableView beginUpdates];
|
|
[_dataSource replaceObjectAtIndex:i withObject:cellModel];
|
|
[weakSelf.tableView reloadRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:i inSection:0]] withRowAnimation:UITableViewRowAnimationNone];
|
|
[weakSelf.tableView endUpdates];
|
|
});
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
-(void)didReceiveMessage:(EMMessage *)message
|
|
{
|
|
if ([_conversation.chatter isEqualToString:message.conversationChatter]) {
|
|
[self addMessage:message];
|
|
if ([self shouldAckMessage:message read:NO])
|
|
{
|
|
[self sendHasReadResponseForMessages:@[message]];
|
|
}
|
|
if ([self shouldMarkMessageAsRead])
|
|
{
|
|
[self markMessagesAsRead:@[message]];
|
|
}
|
|
}
|
|
}
|
|
- (void)didReceiveMessageId:(NSString *)messageId
|
|
chatter:(NSString *)conversationChatter
|
|
error:(EMError *)error
|
|
{
|
|
if (error && [_conversation.chatter isEqualToString:conversationChatter]) {
|
|
|
|
__weak ChatMainViewController *weakSelf = self;
|
|
for (int i = 0; i <_dataSource.count; i ++) {
|
|
id object = [_dataSource objectAtIndex:i];
|
|
if ([object isKindOfClass:[MessageModel class]]) {
|
|
MessageModel *currentModel = [_dataSource objectAtIndex:i];
|
|
EMMessage *currMsg = [currentModel message];
|
|
if ([messageId isEqualToString:currMsg.messageId]) {
|
|
currMsg.deliveryState = eMessageDeliveryState_Failure;
|
|
MessageModel *cellModel = [MessageModelManager modelWithMessage:currMsg];
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
[weakSelf.tableView beginUpdates];
|
|
[_dataSource replaceObjectAtIndex:i withObject:cellModel];
|
|
[weakSelf.tableView reloadRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:i inSection:0]] withRowAnimation:UITableViewRowAnimationNone];
|
|
[weakSelf.tableView endUpdates];
|
|
|
|
});
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
- (NSArray *)formatMessages:(NSArray *)messagesArray
|
|
{
|
|
NSMutableArray *formatArray = [[NSMutableArray alloc] init];
|
|
if ([messagesArray count] > 0) {
|
|
for (EMMessage *message in messagesArray) {
|
|
NSDate *createDate = [NSDate dateWithTimeIntervalInMilliSecondSince1970:(NSTimeInterval)message.timestamp];
|
|
NSTimeInterval tempDate = [createDate timeIntervalSinceDate:_chatTagDate];
|
|
if (tempDate > 60 || tempDate < -60 || (_chatTagDate == nil)) {
|
|
[formatArray addObject:[createDate formattedTime]];
|
|
_chatTagDate = createDate;
|
|
}
|
|
|
|
MessageModel *model = [MessageModelManager modelWithMessage:message];
|
|
|
|
if (model.isSender) {
|
|
model.nickName = [AWordUser sharedInstance].userName;
|
|
}else{
|
|
model.nickName = _otherUserName;
|
|
}
|
|
if (model.isSender){
|
|
model.headImageURL = [NSURL URLWithString:[AWordUser sharedInstance].userAvatar];
|
|
}else{
|
|
model.headImageURL = [NSURL URLWithString:_otherUserAvatar];
|
|
}
|
|
|
|
if (model) {
|
|
[formatArray addObject:model];
|
|
}
|
|
}
|
|
}
|
|
|
|
return formatArray;
|
|
}
|
|
|
|
- (void)downloadMessageAttachments:(MessageModel *)model
|
|
{
|
|
void (^completion)(EMMessage *aMessage, EMError *error) = ^(EMMessage *aMessage, EMError *error) {
|
|
if (!error)
|
|
{
|
|
[self reloadTableViewDataWithMessage:model.message];
|
|
}
|
|
else
|
|
{
|
|
// [self showHint:NSLocalizedString(@"message.thumImageFail", @"thumbnail for failure!")];
|
|
}
|
|
};
|
|
|
|
if ([model.messageBody messageBodyType] == eMessageBodyType_Image) {
|
|
EMImageMessageBody *imageBody = (EMImageMessageBody *)model.messageBody;
|
|
if (imageBody.thumbnailDownloadStatus != EMAttachmentDownloadSuccessed)
|
|
{
|
|
//下载缩略图
|
|
[[[EaseMob sharedInstance] chatManager] asyncFetchMessageThumbnail:model.message progress:nil completion:completion onQueue:nil];
|
|
}
|
|
}
|
|
else if ([model.messageBody messageBodyType] == eMessageBodyType_Video)
|
|
{
|
|
EMVideoMessageBody *videoBody = (EMVideoMessageBody *)model.messageBody;
|
|
if (videoBody.thumbnailDownloadStatus != EMAttachmentDownloadSuccessed)
|
|
{
|
|
//下载缩略图
|
|
[[[EaseMob sharedInstance] chatManager] asyncFetchMessageThumbnail:model.message progress:nil completion:completion onQueue:nil];
|
|
}
|
|
}
|
|
else if ([model.messageBody messageBodyType] == eMessageBodyType_Voice)
|
|
{
|
|
EMVoiceMessageBody *voiceBody = (EMVoiceMessageBody*)model.messageBody;
|
|
if (voiceBody.attachmentDownloadStatus != EMAttachmentDownloadSuccessed)
|
|
{
|
|
//下载语言
|
|
[[EaseMob sharedInstance].chatManager asyncFetchMessage:model.message progress:nil];
|
|
}
|
|
}
|
|
}
|
|
- (void)didMessageAttachmentsStatusChanged:(EMMessage *)message error:(EMError *)error{
|
|
if (!error) {
|
|
id<IEMFileMessageBody>fileBody = (id<IEMFileMessageBody>)[message.messageBodies firstObject];
|
|
if ([fileBody messageBodyType] == eMessageBodyType_Image) {
|
|
EMImageMessageBody *imageBody = (EMImageMessageBody *)fileBody;
|
|
if ([imageBody thumbnailDownloadStatus] == EMAttachmentDownloadSuccessed)
|
|
{
|
|
[self reloadTableViewDataWithMessage:message];
|
|
}
|
|
}else if([fileBody messageBodyType] == eMessageBodyType_Video){
|
|
EMVideoMessageBody *videoBody = (EMVideoMessageBody *)fileBody;
|
|
if ([videoBody thumbnailDownloadStatus] == EMAttachmentDownloadSuccessed)
|
|
{
|
|
[self reloadTableViewDataWithMessage:message];
|
|
}
|
|
}else if([fileBody messageBodyType] == eMessageBodyType_Voice){
|
|
if ([fileBody attachmentDownloadStatus] == EMAttachmentDownloadSuccessed)
|
|
{
|
|
[self reloadTableViewDataWithMessage:message];
|
|
}
|
|
}
|
|
|
|
}else{
|
|
|
|
}
|
|
}
|
|
|
|
- (void)didFetchingMessageAttachments:(EMMessage *)message progress:(float)progress{
|
|
DLog(@"didFetchingMessageAttachment: %f", progress);
|
|
}
|
|
- (void)loadMoreMessages
|
|
{
|
|
__weak typeof(self) weakSelf = self;
|
|
dispatch_async(_messageQueue, ^{
|
|
long long timestamp = [[NSDate date] timeIntervalSince1970] * 1000 + 1;
|
|
|
|
NSArray *messages = [weakSelf.conversation loadNumbersOfMessages:([_messages count] + KPageCount) before:timestamp];
|
|
if ([messages count] > 0) {
|
|
_messages = [messages mutableCopy];
|
|
|
|
NSInteger currentCount = [_dataSource count];
|
|
_dataSource = [[weakSelf formatMessages:messages] mutableCopy];
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
[weakSelf.tableView reloadData];
|
|
|
|
[weakSelf.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:[_dataSource count] - currentCount - 1 inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:NO];
|
|
});
|
|
|
|
//从数据库导入时重新下载没有下载成功的附件
|
|
for (NSInteger i = 0; i < [_dataSource count]; i++)
|
|
{
|
|
id obj = _dataSource[i];
|
|
if ([obj isKindOfClass:[MessageModel class]])
|
|
{
|
|
[weakSelf downloadMessageAttachments:obj];
|
|
}
|
|
}
|
|
|
|
NSMutableArray *unreadMessages = [NSMutableArray array];
|
|
for (NSInteger i = 0; i < [messages count]; i++)
|
|
{
|
|
EMMessage *message = messages[i];
|
|
if ([self shouldAckMessage:message read:NO])
|
|
{
|
|
[unreadMessages addObject:message];
|
|
}
|
|
}
|
|
if ([unreadMessages count])
|
|
{
|
|
[self sendHasReadResponseForMessages:unreadMessages];
|
|
}
|
|
}
|
|
});
|
|
}
|
|
- (BOOL)shouldAckMessage:(EMMessage *)message read:(BOOL)read
|
|
{
|
|
NSString *account = [[EaseMob sharedInstance].chatManager loginInfo][kSDKUsername];
|
|
if (message.messageType != eMessageTypeChat || message.isReadAcked || [account isEqualToString:message.from] || ([UIApplication sharedApplication].applicationState == UIApplicationStateBackground) )
|
|
{
|
|
return NO;
|
|
}
|
|
|
|
id<IEMMessageBody> body = [message.messageBodies firstObject];
|
|
if (((body.messageBodyType == eMessageBodyType_Video) ||
|
|
(body.messageBodyType == eMessageBodyType_Voice) ||
|
|
(body.messageBodyType == eMessageBodyType_Image)) &&
|
|
!read)
|
|
{
|
|
return NO;
|
|
}
|
|
else
|
|
{
|
|
return YES;
|
|
}
|
|
}
|
|
|
|
- (BOOL)shouldMarkMessageAsRead
|
|
{
|
|
if (([UIApplication sharedApplication].applicationState == UIApplicationStateBackground))
|
|
{
|
|
return NO;
|
|
}
|
|
|
|
return YES;
|
|
}
|
|
- (void)sendHasReadResponseForMessages:(NSArray*)messages
|
|
{
|
|
dispatch_async(_messageQueue, ^{
|
|
for (EMMessage *message in messages)
|
|
{
|
|
[[EaseMob sharedInstance].chatManager sendReadAckForMessage:message];
|
|
}
|
|
});
|
|
}
|
|
|
|
- (void)didReceiveHasReadResponse:(EMReceipt *)resp;
|
|
{
|
|
|
|
for (int i=0; i<_dataSource.count; i++) {
|
|
|
|
MessageModel* message = [_dataSource objectAtIndex:i];
|
|
if ([message isKindOfClass:[NSString class]]) {
|
|
continue;
|
|
}
|
|
if ([message.messageId isEqualToString:resp.chatId]) {
|
|
|
|
[self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:i inSection:0]] withRowAnimation:UITableViewRowAnimationFade];
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
- (void)stopAudioPlayingWithChangeCategory:(BOOL)isChange
|
|
{
|
|
//停止音频播放及播放动画
|
|
[[EMCDDeviceManager sharedInstance] stopPlaying];
|
|
[[EMCDDeviceManager sharedInstance] disableProximitySensor];
|
|
[EMCDDeviceManager sharedInstance].delegate = nil;
|
|
MessageModel *playingModel = [self.messageReadManager stopMessageAudioModel];
|
|
NSIndexPath *indexPath = nil;
|
|
if (playingModel) {
|
|
indexPath = [NSIndexPath indexPathForRow:[_dataSource indexOfObject:playingModel] inSection:0];
|
|
}
|
|
|
|
if (indexPath) {
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
[self.tableView beginUpdates];
|
|
[self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
|
|
[self.tableView endUpdates];
|
|
});
|
|
}
|
|
}
|
|
#pragma mark - EMCDDeviceManagerDelegate
|
|
- (void)proximitySensorChanged:(BOOL)isCloseToUser{
|
|
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
|
|
if (isCloseToUser)
|
|
{
|
|
[audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
|
|
} else {
|
|
[audioSession setCategory:AVAudioSessionCategoryPlayback error:nil];
|
|
if (!_isPlayingAudio) {
|
|
[[EMCDDeviceManager sharedInstance] disableProximitySensor];
|
|
}
|
|
}
|
|
[audioSession setActive:YES error:nil];
|
|
}
|
|
- (void)markMessagesAsRead:(NSArray*)messages
|
|
{
|
|
EMConversation *conversation = _conversation;
|
|
dispatch_async(_messageQueue, ^{
|
|
for (EMMessage *message in messages)
|
|
{
|
|
[conversation markMessageWithId:message.messageId asRead:YES];
|
|
}
|
|
});
|
|
}
|
|
|
|
#pragma mark - UIResponder actions
|
|
|
|
- (void)routerEventWithName:(NSString *)eventName userInfo:(NSDictionary *)userInfo
|
|
{
|
|
MessageModel *model = [userInfo objectForKey:KMESSAGEKEY];
|
|
if ([eventName isEqualToString:kRouterEventTextURLTapEventName]) {
|
|
[self chatTextCellUrlPressed:[userInfo objectForKey:@"url"]];
|
|
}
|
|
else if ([eventName isEqualToString:kRouterEventAudioBubbleTapEventName]) {
|
|
[self chatAudioCellBubblePressed:model];
|
|
}
|
|
else if ([eventName isEqualToString:kRouterEventImageBubbleTapEventName]){
|
|
[self chatImageCellBubblePressed:model];
|
|
}
|
|
else if ([eventName isEqualToString:kRouterEventLocationBubbleTapEventName]){
|
|
[self chatLocationCellBubblePressed:model];
|
|
}
|
|
else if([eventName isEqualToString:kResendButtonTapEventName]){
|
|
EMChatViewCell *resendCell = [userInfo objectForKey:kShouldResendCell];
|
|
MessageModel *messageModel = resendCell.messageModel;
|
|
if ((messageModel.status != eMessageDeliveryState_Failure) && (messageModel.status != eMessageDeliveryState_Pending))
|
|
{
|
|
return;
|
|
}
|
|
id <IChatManager> chatManager = [[EaseMob sharedInstance] chatManager];
|
|
[chatManager asyncResendMessage:messageModel.message progress:nil];
|
|
NSIndexPath *indexPath = [self.tableView indexPathForCell:resendCell];
|
|
[self.tableView beginUpdates];
|
|
[self.tableView reloadRowsAtIndexPaths:@[indexPath]
|
|
withRowAnimation:UITableViewRowAnimationNone];
|
|
[self.tableView endUpdates];
|
|
}else if([eventName isEqualToString:kRouterEventChatCellVideoTapEventName]){
|
|
[self chatVideoCellPressed:model];
|
|
}else if([eventName isEqualToString:kRouterEventChatHeadImageTapEventName]){
|
|
if ([_otherUserId isEqualToString:@"admin"]) {
|
|
return;
|
|
}
|
|
PersonalInfoViewController* personalInfoViewController = [[PersonalInfoViewController alloc] init];
|
|
personalInfoViewController.hidesBottomBarWhenPushed = YES;
|
|
personalInfoViewController.otherUserId = _otherUserId;
|
|
[[AppDelegate visibleViewController].navigationController pushViewController:personalInfoViewController animated:YES];
|
|
}
|
|
}
|
|
|
|
//链接被点击
|
|
- (void)chatTextCellUrlPressed:(NSURL *)url
|
|
{
|
|
if (url) {
|
|
[[UIApplication sharedApplication] openURL:url];
|
|
}
|
|
}
|
|
|
|
// 语音的bubble被点击
|
|
-(void)chatAudioCellBubblePressed:(MessageModel *)model
|
|
{
|
|
id <IEMFileMessageBody> body = [model.message.messageBodies firstObject];
|
|
EMAttachmentDownloadStatus downloadStatus = [body attachmentDownloadStatus];
|
|
if (downloadStatus == EMAttachmentDownloading) {
|
|
// [self showHint:NSLocalizedString(@"message.downloadingAudio", @"downloading voice, click later")];
|
|
[MBProgressHUD checkHudWithView:self.view label:NSLocalizedString(@"message.downloadingAudio", @"downloading voice, click later") hidesAfter:1.0];
|
|
return;
|
|
}
|
|
else if (downloadStatus == EMAttachmentDownloadFailure)
|
|
{
|
|
[MBProgressHUD checkHudWithView:self.view label:NSLocalizedString(@"message.downloadingAudio", @"downloading voice, click later") hidesAfter:1.0];
|
|
|
|
[[EaseMob sharedInstance].chatManager asyncFetchMessage:model.message progress:nil];
|
|
|
|
return;
|
|
}
|
|
|
|
// 播放音频
|
|
if (model.type == eMessageBodyType_Voice) {
|
|
//发送已读回执
|
|
if ([self shouldAckMessage:model.message read:YES])
|
|
{
|
|
[self sendHasReadResponseForMessages:@[model.message]];
|
|
}
|
|
__weak ChatMainViewController *weakSelf = self;
|
|
BOOL isPrepare = [self.messageReadManager prepareMessageAudioModel:model updateViewCompletion:^(MessageModel *prevAudioModel, MessageModel *currentAudioModel) {
|
|
if (prevAudioModel || currentAudioModel) {
|
|
[weakSelf.tableView reloadData];
|
|
}
|
|
}];
|
|
|
|
if (isPrepare) {
|
|
_isPlayingAudio = YES;
|
|
__weak ChatMainViewController *weakSelf = self;
|
|
[[EMCDDeviceManager sharedInstance] enableProximitySensor];
|
|
[[EMCDDeviceManager sharedInstance] asyncPlayingWithPath:model.chatVoice.localPath completion:^(NSError *error) {
|
|
[weakSelf.messageReadManager stopMessageAudioModel];
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
[weakSelf.tableView reloadData];
|
|
weakSelf.isPlayingAudio = NO;
|
|
[[EMCDDeviceManager sharedInstance] disableProximitySensor];
|
|
});
|
|
}];
|
|
}
|
|
else{
|
|
_isPlayingAudio = NO;
|
|
}
|
|
}
|
|
}
|
|
|
|
// 位置的bubble被点击
|
|
-(void)chatLocationCellBubblePressed:(MessageModel *)model
|
|
{
|
|
// _isScrollToBottom = NO;
|
|
LocationViewController *locationController = [[LocationViewController alloc] initWithLocation:CLLocationCoordinate2DMake(model.latitude, model.longitude)];
|
|
[self.navigationController pushViewController:locationController animated:YES];
|
|
}
|
|
|
|
- (void)chatVideoCellPressed:(MessageModel *)model{
|
|
EMVideoMessageBody *videoBody = (EMVideoMessageBody*)model.messageBody;
|
|
if (videoBody.attachmentDownloadStatus == EMAttachmentDownloadSuccessed)
|
|
{
|
|
NSString *localPath = model.message == nil ? model.localPath : [[model.message.messageBodies firstObject] localPath];
|
|
if (localPath && localPath.length > 0)
|
|
{
|
|
//发送已读回执
|
|
if ([self shouldAckMessage:model.message read:YES])
|
|
{
|
|
[self sendHasReadResponseForMessages:@[model.message]];
|
|
}
|
|
[self playVideoWithVideoPath:localPath];
|
|
return;
|
|
}
|
|
}
|
|
|
|
__weak ChatMainViewController *weakSelf = self;
|
|
id <IChatManager> chatManager = [[EaseMob sharedInstance] chatManager];
|
|
[MBProgressHUD hudWithView:self.view label:NSLocalizedString(@"message.downloadingVideo", @"downloading video...")];
|
|
[chatManager asyncFetchMessage:model.message progress:nil completion:^(EMMessage *aMessage, EMError *error) {
|
|
[MBProgressHUD hideAllHUDsForView:self.view animated:YES];
|
|
if (!error) {
|
|
//发送已读回执
|
|
if ([weakSelf shouldAckMessage:model.message read:YES])
|
|
{
|
|
[weakSelf sendHasReadResponseForMessages:@[model.message]];
|
|
}
|
|
NSString *localPath = aMessage == nil ? model.localPath : [[aMessage.messageBodies firstObject] localPath];
|
|
if (localPath && localPath.length > 0) {
|
|
[weakSelf playVideoWithVideoPath:localPath];
|
|
}
|
|
}else{
|
|
[MBProgressHUD checkHudWithView:self.view label:NSLocalizedString(@"message.videoFail", @"video for failure!") hidesAfter:1.0];
|
|
}
|
|
} onQueue:nil];
|
|
}
|
|
|
|
- (void)playVideoWithVideoPath:(NSString *)videoPath
|
|
{
|
|
// _isScrollToBottom = NO;
|
|
NSURL *videoURL = [NSURL fileURLWithPath:videoPath];
|
|
MPMoviePlayerViewController *moviePlayerController = [[MPMoviePlayerViewController alloc] initWithContentURL:videoURL];
|
|
[moviePlayerController.moviePlayer prepareToPlay];
|
|
moviePlayerController.moviePlayer.movieSourceType = MPMovieSourceTypeFile;
|
|
[self presentMoviePlayerViewControllerAnimated:moviePlayerController];
|
|
}
|
|
|
|
// 图片的bubble被点击
|
|
-(void)chatImageCellBubblePressed:(MessageModel *)model
|
|
{
|
|
__weak ChatMainViewController *weakSelf = self;
|
|
id <IChatManager> chatManager = [[EaseMob sharedInstance] chatManager];
|
|
if ([model.messageBody messageBodyType] == eMessageBodyType_Image) {
|
|
EMImageMessageBody *imageBody = (EMImageMessageBody *)model.messageBody;
|
|
if (imageBody.thumbnailDownloadStatus == EMAttachmentDownloadSuccessed) {
|
|
if (imageBody.attachmentDownloadStatus == EMAttachmentDownloadSuccessed)
|
|
{
|
|
//发送已读回执
|
|
if ([self shouldAckMessage:model.message read:YES])
|
|
{
|
|
[self sendHasReadResponseForMessages:@[model.message]];
|
|
}
|
|
NSString *localPath = model.message == nil ? model.localPath : [[model.message.messageBodies firstObject] localPath];
|
|
if (localPath && localPath.length > 0) {
|
|
UIImage *image = [UIImage imageWithContentsOfFile:localPath];
|
|
// self.isScrollToBottom = NO;
|
|
if (image)
|
|
{
|
|
[self.messageReadManager showBrowserWithImages:@[image]];
|
|
}
|
|
else
|
|
{
|
|
NSLog(@"Read %@ failed!", localPath);
|
|
}
|
|
return ;
|
|
}
|
|
}
|
|
[MBProgressHUD hudWithView:self.view label:NSLocalizedString(@"message.downloadingImage", @"downloading a image...")];
|
|
|
|
[chatManager asyncFetchMessage:model.message progress:nil completion:^(EMMessage *aMessage, EMError *error) {
|
|
[MBProgressHUD hideAllHUDsForView:self.view animated:YES];
|
|
if (!error) {
|
|
//发送已读回执
|
|
if ([weakSelf shouldAckMessage:model.message read:YES])
|
|
{
|
|
[weakSelf sendHasReadResponseForMessages:@[model.message]];
|
|
}
|
|
NSString *localPath = aMessage == nil ? model.localPath : [[aMessage.messageBodies firstObject] localPath];
|
|
if (localPath && localPath.length > 0) {
|
|
UIImage *image = [UIImage imageWithContentsOfFile:localPath];
|
|
// weakSelf.isScrollToBottom = NO;
|
|
if (image)
|
|
{
|
|
[weakSelf.messageReadManager showBrowserWithImages:@[image]];
|
|
}
|
|
else
|
|
{
|
|
NSLog(@"Read %@ failed!", localPath);
|
|
}
|
|
return ;
|
|
}
|
|
}
|
|
[MBProgressHUD errorHudWithView:self.view label:NSLocalizedString(@"message.imageFail", @"image for failure!") hidesAfter:1.0];
|
|
} onQueue:nil];
|
|
}else{
|
|
//获取缩略图
|
|
[chatManager asyncFetchMessageThumbnail:model.message progress:nil completion:^(EMMessage *aMessage, EMError *error) {
|
|
if (!error) {
|
|
[weakSelf reloadTableViewDataWithMessage:model.message];
|
|
}else{
|
|
// [weakSelf showHint:NSLocalizedString(@"message.thumImageFail", @"thumbnail for failure!")];
|
|
[MBProgressHUD errorHudWithView:self.view label:NSLocalizedString(@"message.thumImageFail", @"thumbnail for failure!") hidesAfter:1.0];
|
|
|
|
}
|
|
|
|
} onQueue:nil];
|
|
}
|
|
}else if ([model.messageBody messageBodyType] == eMessageBodyType_Video) {
|
|
//获取缩略图
|
|
EMVideoMessageBody *videoBody = (EMVideoMessageBody *)model.messageBody;
|
|
if (videoBody.thumbnailDownloadStatus != EMAttachmentDownloadSuccessed) {
|
|
[chatManager asyncFetchMessageThumbnail:model.message progress:nil completion:^(EMMessage *aMessage, EMError *error) {
|
|
if (!error) {
|
|
[weakSelf reloadTableViewDataWithMessage:model.message];
|
|
}else{
|
|
[MBProgressHUD errorHudWithView:self.view label:NSLocalizedString(@"message.thumImageFail", @"thumbnail for failure!") hidesAfter:1.0];
|
|
|
|
}
|
|
} onQueue:nil];
|
|
}
|
|
}
|
|
}
|
|
|
|
- (void)deleteMsgWithIndex:(NSInteger)index;
|
|
{
|
|
if (index > 0) {
|
|
MessageModel *model = [_dataSource objectAtIndex:index];
|
|
NSMutableIndexSet *indexs = [NSMutableIndexSet indexSetWithIndex:index];
|
|
[_conversation removeMessage:model.message];
|
|
[_messages removeObject:model.message];
|
|
NSMutableArray *indexPaths = [NSMutableArray arrayWithObjects:[NSIndexPath indexPathForRow:index inSection:0], nil];;
|
|
if (index - 1 >= 0) {
|
|
id nextMessage = nil;
|
|
id prevMessage = [_dataSource objectAtIndex:(index- 1)];
|
|
if (index + 1 < [_dataSource count]) {
|
|
nextMessage = [_dataSource objectAtIndex:(index + 1)];
|
|
}
|
|
if ((!nextMessage || [nextMessage isKindOfClass:[NSString class]]) && [prevMessage isKindOfClass:[NSString class]]) {
|
|
[indexs addIndex:index - 1];
|
|
[indexPaths addObject:[NSIndexPath indexPathForRow:(index - 1) inSection:0]];
|
|
}
|
|
}
|
|
|
|
[_dataSource removeObjectsAtIndexes:indexs];
|
|
[self.tableView beginUpdates];
|
|
[self.tableView deleteRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationFade];
|
|
[self.tableView endUpdates];
|
|
}
|
|
}
|
|
|
|
- (void)didReceiveMemoryWarning {
|
|
[super didReceiveMemoryWarning];
|
|
// Dispose of any resources that can be recreated.
|
|
}
|
|
-(void)dealloc
|
|
{
|
|
_slimeView.delegate = nil;
|
|
_slimeView = nil;
|
|
}
|
|
/*
|
|
#pragma mark - Navigation
|
|
|
|
// In a storyboard-based application, you will often want to do a little preparation before navigation
|
|
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
|
|
// Get the new view controller using [segue destinationViewController].
|
|
// Pass the selected object to the new view controller.
|
|
}
|
|
*/
|
|
|
|
@end
|