123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327 |
- //
- // 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>
- @end
- @implementation YMIMMessageCollectionView
- - (void)dealloc
- {
- }
- - (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) {
- 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
- {
- NSString *msg = message.sendText;
- if (msg.length > 0) {
- dispatch_async(dispatch_get_main_queue(), ^{
- __block NSMutableArray<SLMessageDetail *> *msgList = [NSMutableArray array];
- [self.chatDataManager enumerateObjectsUsingBlock:^(MessageModel * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
- SLMessageDetail *detail = [[SLMessageDetail alloc] init];
- detail.role = obj.isReceive ? @"assistant" : @"user";
- detail.content = obj.sendText;
- [msgList addObject:detail];
- }];
-
- // NSString *timestamp = [NSString stringWithFormat:@"%.0f",message.sendTime * 1000];
- // NSString *newStr = [timestamp stringByAppendingString:SLTimeMD5Sign];
- // NSString *newMd5str = [SPEncryption getmd5Str:newStr];
- // SLMessageSendModel *sendModel = [[SLMessageSendModel alloc] init];
- // sendModel.messages = msgList;
- // sendModel.timestamp = timestamp;
- // sendModel.sign = newMd5str;
- // [[SLHttpCenter SharedInstance] postWithUrl:SLChatApiUrl body:[sendModel mj_JSONData] success:^(id responseObject) {
- // NSString *dataStr = [responseObject 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) {
- //
- // }];
- [[SLHttpCenter SharedInstance] getWithUrl:@"/api/Chat/SendMessage" parameter:@{@"chatType" : @"0", @"toId" : message.toId ?: @"", @"message" : message.sendText} success:^(id responseObject) {
- 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];
- model.headImg = self.friendModel.head;
- [self appendRequestMessage:model];
- } failure:^(SPRequestError *error) {
- }];
- });
- }
- }
- - (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.iFlySpeechSynthesizer isSpeaking]) {
- // [self.iFlySpeechSynthesizer stopSpeaking];
- // }
- 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 *model = [self.chatDataManager objectAtIndex:indexPath.item];
- [cell confignBaseMessageContentWith:model];
- [cell setCellLayerCornerRadiusWith:model];
- WS(weakSelf);
- cell.segmentBlock = ^(SLMikeSegmentModel * _Nullable sModel) {
- 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];
- switch (sModel.mikeType) {
- case SLMikeInputDelete:
- {
- [weakSelf removeMessage:model];
- }
- break;
- case SLMikeInputLook:
- {
- models.showText = YES;
- [weakSelf updateMessage:models idx:indexPath.item];
- }
- break;
- case SLMikeInputBroadcast:
- {
- if (weakSelf.broadcastBlock) {
- weakSelf.broadcastBlock(models);
- }
- }
- break;
- case SLMikeInputHidden:
- {
- models.showText = NO;
- [weakSelf updateMessage:models idx:indexPath.item];
- }
- 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开发已经被淘汰了吧
- //
- CGFloat sw = 124;
- NSCharacterSet *set = [NSCharacterSet characterSetWithCharactersInString:@"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"];
- NSRange range = [model.sendText rangeOfCharacterFromSet:set];
- if (range.location != NSNotFound) {
- sw -= 8;
- }
- CGSize contentSize =[model.sendText 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;
- }
- return CGSizeMake(kSCREEN_WIDTH, height);
- }
- - (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
|