123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433 |
- //
- // YMIMMessageCollectionView.m
- // PCDBank
- //
- // Created by Gusont on 2021/8/25.
- // Copyright © 2021 SLAiELTS. All rights reserved.
- //
- #import "YMIMMessageCollectionView.h"
- #import "YMIMBaseMessageCell.h"
- #import "UICollectionView+YMHelper.h"
- @interface YMIMMessageCollectionView()<UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout, UIScrollViewDelegate>
- @property (nonatomic, assign) BOOL scrollViewDidEnd;
- @property (nonatomic, assign) CGFloat scrollViewOfsetY;
- @end
- @implementation YMIMMessageCollectionView
- - (void)dealloc
- {
- [self saveChatData];
- }
- - (void)saveChatData {
- NSString *key = [NSString stringWithFormat:@"%@--to--%@",[SLGlobalInfo SharedInstance].loginInfo.user.userId, self.friendModel.userId];
- NSArray *dictArr = [NSObject mj_keyValuesArrayWithObjectArray:self.chatDataManager];
- [[NSUserDefaults standardUserDefaults] setObject:dictArr forKey:key];
- [[NSUserDefaults standardUserDefaults] synchronize];
- }
- - (instancetype)initWithFrame:(CGRect)frame
- {
- self = [super initWithFrame:frame];
- if (self) {
- [self setupMessageCollectionView];
- }
- return self;
- }
- - (void)setupMessageCollectionView
- {
- [self.messageCollectionView mas_makeConstraints:^(MASConstraintMaker *make) {
- make.edges.equalTo(self);
- }];
- [self.messageCollectionView registerCellWithReuseIdentifierClass:YMIMBaseMessageCell.class];
- }
- - (void)applicationEnterBackground:(id)noti
- {
- // if ([_iFlySpeechSynthesizer isSpeaking]) {
- // [_iFlySpeechSynthesizer pauseSpeaking];
- // }
- }
- - (CGFloat)getBotttomCellMaxY
- {
- if (self.chatDataManager.count > 0) {
- NSIndexPath *idxPath = [NSIndexPath indexPathForItem:self.chatDataManager.count - 1 inSection:0];
- UICollectionViewCell *cell = [self.messageCollectionView cellForItemAtIndexPath:idxPath];
- CGRect rect = [self.messageCollectionView convertRect:cell.frame toView:self.messageCollectionView];
- return CGRectGetMaxY(rect);
- }
- return 0;
- }
- - (void)scrollToBottom:(BOOL)animated
- {
- dispatch_async(dispatch_get_main_queue(), ^{
- if (self.chatDataManager.count > 0) {
- // UIScrollView * scrollView= self.messageCollectionView;
- // CGPoint bottomOffset = CGPointMake(0, scrollView.contentSize.height - scrollView.bounds.size.height);
- // self.scrollViewDidEnd = NO;
- // [scrollView setContentOffset:bottomOffset animated:YES];
-
- NSIndexPath *endIndex = [NSIndexPath indexPathForItem:self.chatDataManager.count - 1 inSection:0];
- [self.messageCollectionView scrollToItemAtIndexPath:endIndex atScrollPosition:UICollectionViewScrollPositionBottom animated:animated];
- }
- });
- }
- ///Q
- - (void)appendMessage:(MessageModel *)message
- {
- MessageModel *lastModel = self.chatDataManager.lastObject;
- if ((lastModel && message.sendTime - lastModel.sendTime > 120) || !lastModel) {
- message.showTime = YES;
- }
- [self appendRequestMessage:message];
- [self resultsRequestWith:message];
- }
- ///A
- - (void)appendRequestMessage:(MessageModel *)message
- {
- [self.chatDataManager addObject:message];
- dispatch_async(dispatch_get_main_queue(), ^{
- [self.messageCollectionView reloadData];
- [self scrollToBottom:YES];
- });
- }
- /// 结果请求数据
- /// @param message <#message description#>
- - (void)resultsRequestWith:(MessageModel *)message
- {
- __block MessageModel *msgModel = message;
- NSString *msg = message.sendText;
- if (msg.length > 0) {
- dispatch_async(dispatch_get_main_queue(), ^{
- SLMessageSendModel *sendModel = [[SLMessageSendModel alloc] init];
- sendModel.chatType = 0;
- sendModel.toId = message.toId;
- sendModel.message = message.sendText;
- [[SLHttpCenter SharedInstance] postWithUrl:@"/api/Chat/SendMessage_WebSocket" body:[sendModel mj_JSONData] success:^(id responseObject) {
- if (msgModel.sendFailure) {
- msgModel.sendFailure = NO;
- }
- // NSDictionary *dataDict = [responseObject objectForKey:@"data"];
- // NSString *dataStr = [dataDict objectForKey:@"data"];
- // NSString *str = [self replaceHasPrefix:@"\n" str:dataStr];
- // MessageModel *model = [MessageModel initWithSendText:str isReceive:YES showMike:message.isMike showText:!message.isMike isMike:message.isMike];
- // [self appendRequestMessage:model];
- } failure:^(SPRequestError *error) {
- NSInteger i = [self.chatDataManager indexOfObject:msgModel];
- if (i < self.chatDataManager.count && i > -1) {
- msgModel.sendFailure = YES;
- dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
- [self updateMessage:msgModel idx:i];
- });
- }
- }];
- });
- }
- }
- - (NSString *)replaceHasPrefix:(NSString *)fixStr str:(NSString *)str {
- if ([str hasPrefix:fixStr]) {
- NSString *newStr = [str substringFromIndex:fixStr.length];
- return [self replaceHasPrefix:fixStr str:newStr];
- }
- return str;
- }
- - (void)setVoiceStatus:(BOOL)voiceStatus
- {
- _voiceStatus = voiceStatus;
- }
- #pragma mark - 语音合成
- - (void)startSpeakingMessage:(NSString *)responseString
- {
- }
- - (void)insertMessage:(NSArray *)message
- {
- [self.chatDataManager addObjectsFromArray:message];
- [self.messageCollectionView reloadDataNoScroll];
- }
- - (void)updateMessage:(MessageModel *)message idx:(NSInteger)idx
- {
- if (self.chatDataManager.count > 1) {
- [self.chatDataManager replaceObjectAtIndex:idx withObject:message];
- [self.messageCollectionView reloadData];
- }
- }
- - (void)removeMessage:(MessageModel *)message
- {
- NSInteger idx = [self.chatDataManager indexOfObject:message];
- if (message.showTime && self.chatDataManager.count > idx + 1) {
- MessageModel *nextModel = [self.chatDataManager objectAtIndex:idx + 1];
- nextModel.showTime = YES;
- }
- [self.chatDataManager removeObject:message];
- [self.messageCollectionView reloadDataNoScroll];
- }
- - (void)removeAllMessages
- {
- [self.chatDataManager removeAllObjects];
- [self.messageCollectionView reloadData];
- }
- #pragma mark - UICollectionViewDataSource
- - (nonnull __kindof UICollectionViewCell *)collectionView:(nonnull UICollectionView *)collectionView cellForItemAtIndexPath:(nonnull NSIndexPath *)indexPath
- {
- YMIMBaseMessageCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:NSStringFromClass(YMIMBaseMessageCell.class) forIndexPath:indexPath];
- MessageModel *rowModel = [self.chatDataManager objectAtIndex:indexPath.item];
- [cell confignBaseMessageContentWith:rowModel receiveHeardImg:self.friendModel.userHead];
- [cell setCellLayerCornerRadiusWith:rowModel];
- WS(weakSelf);
- cell.segmentBlock = ^(SLMikeSegmentModel * _Nullable sModel, MessageModel * _Nullable mModel) {
- // MessageModel *models = [MessageModel initWithSendText:model.sendText isReceive:model.isReceive showMike:model.showMike showText:model.showText isMike:model.isMike showTime:model.showTime sendTime:model.sendTime voicePath:model.voicePath sendFailure:model.sendFailure sendTextTrans:model.sendTextTrans];
- MessageModel *newModel = [MessageModel mj_objectWithKeyValues:[mModel mj_JSONObject]];
- switch (sModel.mikeType) {
- case SLMikeInputDelete:
- {//删除
- [weakSelf removeMessage:mModel];
- }
- break;
- case SLMikeInputLook:
- {
- newModel.showText = YES;
- newModel.showTrans = NO;
- [weakSelf updateMessage:newModel idx:indexPath.row];
- }
- break;
- case SLMikeInputBroadcast:
- {
- [weakSelf.chatDataManager enumerateObjectsUsingBlock:^(MessageModel * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
- if (obj.onBroadcast) {
- obj.onBroadcast = NO;
- [weakSelf.messageCollectionView reloadItemsAtIndexPaths:@[[NSIndexPath indexPathForRow:idx inSection:0]]];
- }
- if ([obj isEqual:mModel]) {
- obj.onBroadcast = YES;
- [weakSelf.messageCollectionView reloadItemsAtIndexPaths:@[[NSIndexPath indexPathForRow:idx inSection:0]]];
- }
- }];
- if (weakSelf.broadcastBlock) {
- weakSelf.broadcastBlock(mModel);
- }
- }
- break;
- case SLMikeInputHidden:
- {
- newModel.showText = NO;
- newModel.showTrans = NO;
- [weakSelf updateMessage:newModel idx:indexPath.row];
- }
- break;
- case SLMikeInputTransHidden:
- {
- newModel.showTrans = NO;
- [weakSelf updateMessage:newModel idx:indexPath.row];
- }
- break;
- case SLMikeInputTrans:
- {
- newModel.showText = YES;
- newModel.showTrans = !newModel.showTrans;
- if (!newModel.sendTextTrans) {
- //百度智能云
- [[SLHttpCenter SharedInstance] getWithUrl:@"https://aip.baidubce.com/oauth/2.0/token" parameter:@{@"grant_type":@"client_credentials", @"client_id":@"0VhDeLqdcbLamGENfw4c24aq", @"client_secret": @"92qphFKyc0uXGktqFLtfdmqlojt9MsgG"} success:^(id responseObject) {
- NSString *accessToken = [responseObject objectForKey:@"access_token"];
- if (accessToken) {
- NSString *bdUrl = [NSString stringWithFormat:@"https://aip.baidubce.com/rpc/2.0/mt/texttrans/v1?access_token=%@",accessToken];
- NSDictionary *dict = @{@"q":newModel.sendText,
- @"from":@"auto",
- @"to":@"zh"};
- [[SLHttpCenter SharedInstance] postWithUrl:bdUrl parameter:dict success:^(id responseObject) {
- NSDictionary *reslut = [responseObject objectForKey:@"result"];
- NSArray *arr = [reslut objectForKey:@"trans_result"];
- if (arr && arr.count) {
- NSDictionary *resultDict = arr.firstObject;
- NSString *dst = [resultDict objectForKey:@"dst"];
- newModel.sendTextTrans = dst;
- [weakSelf updateMessage:newModel idx:indexPath.row];
- }else {
- [ZFToast ShowWithMessage:@"翻译失败"];
- }
- } failure:^(SPRequestError *error) {
- [ZFToast ShowWithMessage:@"翻译失败"];
- }];
- }else {
- [ZFToast ShowWithMessage:@"翻译失败"];
- }
- } failure:^(SPRequestError *error) {
- [ZFToast ShowWithMessage:@"翻译失败"];
- }];
- }else {
- [weakSelf updateMessage:newModel idx:indexPath.row];
- }
- }
- break;
- case SLMsgRepeat:
- {
- [weakSelf resultsRequestWith:newModel];
- }
- break;
- case SLMsgCopy:
- {
- [[UIPasteboard generalPasteboard] setString:newModel.sendText];
- }
- break;
- default:
- break;
- }
- };
- return cell;
- }
- - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
- {
- [collectionView.collectionViewLayout invalidateLayout];
- return 1;
- }
- - (NSInteger)collectionView:(nonnull UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
- {
- return self.chatDataManager.count;
- }
- - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
- {
-
- }
- - (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section
- {
- return UIEdgeInsetsMake(0, 0, 0, 0);
- }
- - (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section
- {
- return 0;
- }
- /**
- */
- - (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section
- {
- return 0;
- }
- - (void)collectionView:(UICollectionView *)collectionView didEndDisplayingCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath
- {
- if (indexPath.item >= self.chatDataManager.count) {
- return;
- }
- }
- #pragma mark - UICollectionViewDelegateFlowLayout
- - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
- {
- MessageModel *model = [self.chatDataManager objectAtIndex:indexPath.item];
- //实际send宽度16 + 52 + 10 + 16 英文和中文宽度不一致、ios string包含字符串iOS开发已经被淘汰了吧
- //8 + 48 + 8 + 56
- CGFloat sw = 150;
- NSCharacterSet *set = [NSCharacterSet characterSetWithCharactersInString:@"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"];
- NSRange range = [model.sendText rangeOfCharacterFromSet:set];
- if (range.location != NSNotFound) {
- sw -= 8;
- }
- // if (model.sendFailure) {
- // sw += 8;
- // }
- NSString *text = model.sendText;
- if (model.showMike && model.showTrans) {
- text = model.sendTextTrans;
- }
- CGSize contentSize = [text boundingRectWithSize:CGSizeMake(kSCREEN_WIDTH - sw, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:17]} context:nil].size;
- // NSLog(@"%f---%f",contentSize.width, contentSize.height);
- CGFloat height = 0;
- if (model.showMike) {
- height += 65;
- }
- if (model.showText) {
- height += contentSize.height + (model.showMike ? 25 : 42);
- }
- if (model.showTime) {
- height += 23;
- }
- if (!model.showMike && model.showTrans) {
- CGSize transContentSize = [model.sendTextTrans boundingRectWithSize:CGSizeMake(kSCREEN_WIDTH - 124, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:17]} context:nil].size;
- height += transContentSize.height + 40;
- }
- return CGSizeMake(kSCREEN_WIDTH, height);
- }
- //
- //- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
- //{
- // return [[UICollectionReusableView alloc] initWithFrame:CGRectZero];
- //}
- //
- //
- //- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout referenceSizeForFooterInSection:(NSInteger)section {
- // return CGSizeZero;
- //}
- - (void)scrollViewDidScroll:(UIScrollView *)scrollView {
- if (self.scrollViewDidEnd && self.scrollViewOfsetY - scrollView.contentOffset.y > 10) {
- self.scrollViewDidEnd = NO;
- self.scrollViewOfsetY = 0.0f;
- [self.viewController.view endEditing:YES];
- }
- }
- - (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView {
- CGFloat ty = self.superview.transform.ty;
- if (ty < 0) {
- self.scrollViewDidEnd = YES;
- self.scrollViewOfsetY = scrollView.contentOffset.y;
- }
- }
- - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
-
- }
- - (UICollectionView *)messageCollectionView
- {
- if (!_messageCollectionView) {
- UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
- layout.minimumLineSpacing = 0.0;
- layout.minimumInteritemSpacing = 0.0;
- _messageCollectionView = [[UICollectionView alloc] initWithFrame:self.frame collectionViewLayout:layout];
- _messageCollectionView.delegate = self;
- _messageCollectionView.dataSource = self;
- _messageCollectionView.backgroundColor = [UIColor clearColor];
- _messageCollectionView.showsVerticalScrollIndicator = NO;
- _messageCollectionView.showsHorizontalScrollIndicator = NO;
- _messageCollectionView.bounces = NO;
- [self addSubview:_messageCollectionView];
- }
- return _messageCollectionView;
- }
- - (NSMutableArray<MessageModel *> *)chatDataManager
- {
- if (!_chatDataManager) {
- _chatDataManager = [NSMutableArray array];
- }
- return _chatDataManager;
- }
- @end
|