Files
featherVoice/QXLive/Room(房间)/View/QXRoomChatListView.m

1230 lines
52 KiB
Mathematica
Raw Normal View History

2025-08-08 10:49:36 +08:00
//
// QXRoomChatListView.m
// QXLive
//
// Created by on 2025/6/7.
//
#import "QXRoomChatListView.h"
#import "UIImage+WebP.h"
2025-10-30 18:30:45 +08:00
#import <AVFoundation/AVFoundation.h>
2025-10-25 19:38:29 +08:00
#define messageNoticeColor RGB16(0xCCA882)
2025-10-20 09:43:10 +08:00
#define messageNameColor RGB16(0x00C8FF)
#define messageGiftColor RGB16(0xFFE309)
2025-10-24 10:52:40 +08:00
#define messageBubbleColor RGB16A(0x000000, 0.3)
2025-10-27 17:05:46 +08:00
#define messageBubbleMargin 2
2025-10-20 09:43:10 +08:00
NSArray<NSValue *> *findAllOccurrencesOfString(NSString *fullString, NSString *substring) {
NSMutableArray<NSValue *> *occurrences = [NSMutableArray array];
NSRange searchRange = NSMakeRange(0, fullString.length);
NSRange foundRange;
while (searchRange.location < fullString.length) {
searchRange.length = fullString.length - searchRange.location;
foundRange = [fullString rangeOfString:substring
options:0
range:searchRange];
if (foundRange.location != NSNotFound) {
//
[occurrences addObject:[NSValue valueWithRange:foundRange]];
//
searchRange.location = foundRange.location + foundRange.length;
} else {
// 退
break;
}
}
return [occurrences copy];
}
2025-08-08 10:49:36 +08:00
NSInteger maxMessageCount = 20;
@interface QXRoomChatListView() <UITableViewDelegate,UITableViewDataSource,QXRoomSeatDelegate>
@property (nonatomic,strong)UITableView *tableView;
@property (nonatomic,strong)NSMutableArray *dataArray;
@property (nonatomic,strong)NSMutableArray *giftArray;
@property (nonatomic,strong)NSMutableArray *chatArray;
@property (nonatomic,assign)NSInteger messageCount;
2025-10-21 14:28:18 +08:00
//@property (nonatomic,strong)UIButton *allBtn;
//@property (nonatomic,strong)UIButton *chatBtn;
//@property (nonatomic,strong)UIButton *giftBtn;
//@property (nonatomic,strong)UIButton *selectedBtn;
2025-08-08 10:49:36 +08:00
@property (nonatomic,assign)BOOL isDragging;
@property (nonatomic,strong)UILabel *messageLabel;
@property (nonatomic,strong)UIButton *messageCountBtn;
2025-10-30 18:30:45 +08:00
@property (nonatomic,strong)AVSpeechSynthesizer *synthesizer;
2025-08-08 10:49:36 +08:00
@end
@implementation QXRoomChatListView
- (instancetype)init
{
self = [super init];
if (self) {
[self initSubviews];
}
return self;
}
-(void)initSubviews{
2025-10-30 18:30:45 +08:00
self.synthesizer = [[AVSpeechSynthesizer alloc] init];
2025-08-08 10:49:36 +08:00
[self addSubview:self.tableView];
[self.tableView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.right.equalTo(self);
2025-10-25 19:38:29 +08:00
make.top.equalTo(self).offset(10);
2025-08-08 10:49:36 +08:00
make.bottom.equalTo(self).offset(-10);
}];
2025-10-21 14:28:18 +08:00
// self.allBtn = [[UIButton alloc] init];
// NSAttributedString *allAttrNor = [[NSAttributedString alloc] initWithString:QXText(@"全部") attributes:@{NSFontAttributeName:[UIFont boldSystemFontOfSize:14],NSForegroundColorAttributeName:[UIColor whiteColor]}];
// NSAttributedString *allAttrSel = [[NSAttributedString alloc] initWithString:QXText(@"全部") attributes:@{NSFontAttributeName:[UIFont boldSystemFontOfSize:16],NSForegroundColorAttributeName:[UIColor whiteColor]}];
// [self.allBtn setAttributedTitle:allAttrNor forState:UIControlStateNormal];
// [self.allBtn setAttributedTitle:allAttrSel forState:UIControlStateSelected];
// self.allBtn.selected = YES;
// self.selectedBtn = self.allBtn;
// [self.allBtn addTarget:self action:@selector(typeAction:) forControlEvents:(UIControlEventTouchUpInside)];
// [self addSubview:self.allBtn];
// [self.allBtn mas_makeConstraints:^(MASConstraintMaker *make) {
// make.left.mas_equalTo(16);
// make.top.equalTo(self);
// make.height.mas_equalTo(40);
// make.width.mas_equalTo(50);
// }];
//
// self.chatBtn = [[UIButton alloc] init];
// NSAttributedString *chatAttrNor = [[NSAttributedString alloc] initWithString:QXText(@"聊天") attributes:@{NSFontAttributeName:[UIFont boldSystemFontOfSize:14],NSForegroundColorAttributeName:[UIColor whiteColor]}];
// NSAttributedString *chatAttrSel = [[NSAttributedString alloc] initWithString:QXText(@"聊天") attributes:@{NSFontAttributeName:[UIFont boldSystemFontOfSize:16],NSForegroundColorAttributeName:[UIColor whiteColor]}];
// [self.chatBtn setAttributedTitle:chatAttrNor forState:UIControlStateNormal];
// [self.chatBtn setAttributedTitle:chatAttrSel forState:UIControlStateSelected];
// [self.chatBtn addTarget:self action:@selector(typeAction:) forControlEvents:(UIControlEventTouchUpInside)];
// [self addSubview:self.chatBtn];
// [self.chatBtn mas_makeConstraints:^(MASConstraintMaker *make) {
// make.left.equalTo(self.allBtn.mas_right).offset(5);
// make.top.equalTo(self);
// make.height.mas_equalTo(40);
// make.width.mas_equalTo(50);
// }];
//
// self.giftBtn = [[UIButton alloc] init];
// NSAttributedString *giftAttrNor = [[NSAttributedString alloc] initWithString:QXText(@"礼物") attributes:@{NSFontAttributeName:[UIFont boldSystemFontOfSize:14],NSForegroundColorAttributeName:[UIColor whiteColor]}];
// NSAttributedString *giftAttrSel = [[NSAttributedString alloc] initWithString:QXText(@"礼物") attributes:@{NSFontAttributeName:[UIFont boldSystemFontOfSize:16],NSForegroundColorAttributeName:[UIColor whiteColor]}];
// [self.giftBtn setAttributedTitle:giftAttrNor forState:UIControlStateNormal];
// [self.giftBtn setAttributedTitle:giftAttrSel forState:UIControlStateSelected];
// [self.giftBtn addTarget:self action:@selector(typeAction:) forControlEvents:(UIControlEventTouchUpInside)];
// [self addSubview:self.giftBtn];
// [self.giftBtn mas_makeConstraints:^(MASConstraintMaker *make) {
// make.left.equalTo(self.chatBtn.mas_right).offset(5);
// make.top.equalTo(self);
// make.height.mas_equalTo(40);
// make.width.mas_equalTo(50);
// }];
2025-08-08 10:49:36 +08:00
self.messageCountBtn = [[UIButton alloc] init];;
[self.messageCountBtn setTitleColor:RGB16(0xB265FA) forState:(UIControlStateNormal)];
self.messageCountBtn.backgroundColor = [UIColor whiteColor];
[self.messageCountBtn addRoundedCornersWithRadius:10];
self.messageCountBtn.titleLabel.font = [UIFont systemFontOfSize:12];
[self.messageCountBtn addTarget:self action:@selector(scrollToBottom) forControlEvents:(UIControlEventTouchUpInside)];
[self addSubview:self.messageCountBtn];
self.messageCountBtn.hidden = YES;
[self.messageCountBtn mas_makeConstraints:^(MASConstraintMaker *make) {
make.right.mas_equalTo(-40);
make.bottom.equalTo(self);
make.height.mas_equalTo(20);
make.width.mas_equalTo(75);
}];
2025-10-20 09:43:10 +08:00
// self.messageLabel = [[UILabel alloc] init];
// self.messageLabel.textColor = [UIColor whiteColor];
// self.messageLabel.text = @"张三进入了房间";
// self.messageLabel.font = [UIFont systemFontOfSize:12];
// [self addSubview:self.messageLabel];
// [self.messageLabel mas_makeConstraints:^(MASConstraintMaker *make) {
// make.left.mas_equalTo(16);
// make.bottom.equalTo(self).offset(-5);
// make.height.mas_equalTo(20);
// make.right.equalTo(self);
// }];
2025-08-08 10:49:36 +08:00
}
-(void)typeAction:(UIButton*)sender{
2025-10-21 14:28:18 +08:00
// self.selectedBtn.selected = !self.selectedBtn.selected;
// sender.selected = !sender.selected;
// self.selectedBtn = sender;
// [self.tableView reloadData];
// [self scrollToBottom];
2025-08-08 10:49:36 +08:00
}
-(void)scrollToBottom{
NSArray *arr;
2025-10-21 14:28:18 +08:00
// if (self.selectedBtn == self.chatBtn) {
// arr = self.chatArray;
// }else if (self.selectedBtn == self.giftBtn) {
// arr = self.giftArray;
// }else{
2025-08-08 10:49:36 +08:00
arr = self.dataArray;
2025-10-21 14:28:18 +08:00
// }
2025-08-08 10:49:36 +08:00
if (arr.count > 0) {
[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:arr.count-1 inSection:0] atScrollPosition:(UITableViewScrollPositionBottom) animated:YES];
}
self.isDragging = NO;
self.messageCount = 0;
self.messageCountBtn.hidden = YES;
}
-(void)insertNoitce{
QXRoomChatListModel *model = [QXRoomChatListModel new];
2025-10-25 19:38:29 +08:00
model.messageType = QXRoomChatMessageTypeNotice;
2025-10-21 10:29:06 +08:00
model.text = @"羽声语音严禁未成年人进行直播或打赏官方将24小时在线巡查。我们提倡绿色直播直播间严禁出现涉政、涉恐、涉黄、涉赌等违法违规内容严禁宣传封建迷信、宗教极端思想、出现低俗色情、吸烟酗酒等内容严禁违反社会主义核心价值观、践踏社会道德底线、诱导打赏、低俗 PK 、买卖金币等行为,请大家共同遵守、监督并及时举报。请勿相信各类刷钻、购买礼包、游戏币及电商贩卖等非官方广告信息,谨防网络诈骗。";
2025-08-08 10:49:36 +08:00
[self.dataArray addObject:model];
[self.tableView reloadData];
[self scrollToBottom];
}
-(void)insertMessage:(QXRoomChatListModel *)model{
2025-10-20 09:43:10 +08:00
///
2025-10-21 14:28:18 +08:00
// if (model.messageType != QXRoomChatMessageTypeGift) {
2025-10-20 09:43:10 +08:00
[self.dataArray addObject:model];
2025-10-21 14:28:18 +08:00
// }
2025-10-20 09:43:10 +08:00
2025-10-21 14:28:18 +08:00
// if (model.messageType == QXRoomChatMessageTypeChat) {
// [self.chatArray addObject:model];
// }
// if (model.messageType == QXRoomChatMessageTypeGift) {
// [self.giftArray addObject:model];
// }
2025-10-20 09:43:10 +08:00
// if (self.dataArray.count>maxMessageCount) {
// [self.dataArray removeFirstObject];
// }
// if (self.chatArray.count>maxMessageCount) {
// [self.chatArray removeFirstObject];
// }
// if (self.giftArray.count>maxMessageCount) {
// [self.giftArray removeFirstObject];
// }
2025-10-30 18:30:45 +08:00
#if DEBUG
2025-11-07 10:11:09 +08:00
if (model.messageType == QXRoomChatMessageTypeGift || model.messageType == QXRoomChatMessageTypeSystem || model.messageType == QXRoomChatMessageTypeChat) {
NSString *text = @"";
if (model.messageType == QXRoomChatMessageTypeGift || model.messageType == QXRoomChatMessageTypeSystem) {
text = model.text;
}else{
text = [NSString stringWithFormat:@"%@说,%@",model.FromUserInfo.nickname,model.text];
}
AVSpeechUtterance *utterance = [[AVSpeechUtterance alloc] initWithString:text];
2025-10-30 18:30:45 +08:00
utterance.voice = [AVSpeechSynthesisVoice voiceWithLanguage:@"zh-CN"];
utterance.rate = 0.5 ;
utterance.pitchMultiplier = 1.0 ;
utterance.volume = 1.0 ;
[self.synthesizer speakUtterance:utterance];
}
#endif
2025-10-21 14:28:18 +08:00
NSIndexPath *newIndexPath = [NSIndexPath indexPathForRow:self.dataArray.count - 1 inSection:0];
[self.tableView beginUpdates];
[self.tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationNone];
[self.tableView endUpdates];
2025-08-08 10:49:36 +08:00
if (self.isDragging) {
self.messageCount++;
self.messageCountBtn.hidden = NO;
[self.messageCountBtn setTitle:[NSString localizedStringWithFormat:QXText(@"%@条新消息"),[NSString stringWithFormat:@"%ld",self.messageCount]] forState:(UIControlStateNormal)];
}else{
[self scrollToBottom];
}
}
-(void)clearMessage{
[self.dataArray removeAllObjects];
[self.giftArray removeAllObjects];
[self.chatArray removeAllObjects];
[self.tableView reloadData];
}
-(void)previewUserInfoWithUserId:(NSString *)userId{
if (self.delegate && [self.delegate respondsToSelector:@selector(previewUserInfoWithUserId:)]) {
[self.delegate previewUserInfoWithUserId:userId];
}
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
2025-10-21 14:28:18 +08:00
// if (self.selectedBtn == self.chatBtn) {
// return self.chatArray.count;
// }
// if (self.selectedBtn == self.giftBtn) {
// return self.giftArray.count;
// }
2025-08-08 10:49:36 +08:00
return self.dataArray.count;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
QXRoomChatListModel *model;
2025-10-21 14:28:18 +08:00
// if (self.selectedBtn == self.chatBtn) {
// model = self.chatArray[indexPath.row];
// }else if (self.selectedBtn == self.giftBtn) {
// model = self.giftArray[indexPath.row];
// }else{
2025-08-08 10:49:36 +08:00
model = self.dataArray[indexPath.row];
2025-10-21 14:28:18 +08:00
// }
2025-10-20 09:43:10 +08:00
// model.havBubble = indexPath.row%2;
2025-08-08 10:49:36 +08:00
if (model.messageType == QXRoomChatMessageTypeChat) {
QXRoomChatListCell *cell = [QXRoomChatListCell cellWithTableView:tableView];
cell.delegate = self;
cell.message = model;
return cell;
}else if (model.messageType == QXRoomChatMessageTypeGift) {
QXRoomGiftListCell *cell = [QXRoomGiftListCell cellWithTableView:tableView];
cell.delegate = self;
cell.message = model;
return cell;
2025-10-24 10:52:40 +08:00
}else if(model.messageType == QXRoomChatMessageTypeEmoji){
QXRoomEmojiListCell *cell = [QXRoomEmojiListCell cellWithTableView:tableView];
cell.delegate = self;
cell.message = model;
return cell;
2025-08-08 10:49:36 +08:00
}else{
QXRoomChatListSystemCell *cell = [QXRoomChatListSystemCell cellWithTableView:tableView];
cell.message = model;
return cell;
}
}
-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{
if ([cell isKindOfClass:[QXRoomChatListCell class]]) {
QXRoomChatListCell *Listcell = (QXRoomChatListCell *)cell;
[Listcell loadBubble];
2025-10-24 10:52:40 +08:00
return;
}
if ([cell isKindOfClass:[QXRoomGiftListCell class]]) {
QXRoomGiftListCell *Listcell = (QXRoomGiftListCell *)cell;
[Listcell loadBubble];
return;
}
if ([cell isKindOfClass:[QXRoomEmojiListCell class]]) {
QXRoomEmojiListCell *Listcell = (QXRoomEmojiListCell *)cell;
[Listcell loadBubble];
return;
2025-08-08 10:49:36 +08:00
}
}
-(void)tableView:(UITableView *)tableView didEndDisplayingCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{
if ([cell isKindOfClass:[QXRoomChatListCell class]]) {
QXRoomChatListCell *Listcell = (QXRoomChatListCell *)cell;
[Listcell.bubbleImageView sd_cancelLatestImageLoad];
}
2025-10-24 10:52:40 +08:00
if ([cell isKindOfClass:[QXRoomGiftListCell class]]) {
QXRoomGiftListCell *Listcell = (QXRoomGiftListCell *)cell;
[Listcell.bubbleImageView sd_cancelLatestImageLoad];
return;
}
if ([cell isKindOfClass:[QXRoomEmojiListCell class]]) {
QXRoomEmojiListCell *Listcell = (QXRoomEmojiListCell *)cell;
[Listcell.bubbleImageView sd_cancelLatestImageLoad];
[Listcell.animatedImageView sd_cancelLatestImageLoad];
return;
}
2025-08-08 10:49:36 +08:00
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
QXRoomChatListModel *model;
2025-10-21 14:28:18 +08:00
// if (self.selectedBtn == self.chatBtn) {
// model = self.chatArray[indexPath.row];
// }else if (self.selectedBtn == self.giftBtn) {
// model = self.giftArray[indexPath.row];
// }else{
2025-08-08 10:49:36 +08:00
model = self.dataArray[indexPath.row];
2025-10-21 14:28:18 +08:00
// }
2025-08-08 10:49:36 +08:00
CGFloat height = 0;
if (model.messageType == QXRoomChatMessageTypeChat) {
2025-10-24 10:52:40 +08:00
if ([model.FromUserInfo.chat_bubble isExist]) {
height = [model.text heightForFont:[UIFont systemFontOfSize:14] width:ScaleWidth(280)-60-18];
height = 28+19+13+16 + height;
2025-08-08 10:49:36 +08:00
}else{
2025-10-24 10:52:40 +08:00
height = [model.text heightForFont:[UIFont systemFontOfSize:14] width:ScaleWidth(280)-60-18-16];
height = 28+19+13+8 + height;
2025-08-08 10:49:36 +08:00
}
}else if (model.messageType == QXRoomChatMessageTypeGift) {
2025-10-27 17:05:46 +08:00
height = [model.text heightForFont:[UIFont systemFontOfSize:12] width:ScaleWidth(280)-16-8-8*2] + 12+4+1;
2025-10-24 10:52:40 +08:00
}else if(model.messageType == QXRoomChatMessageTypeEmoji){
if ([model.FromUserInfo.chat_bubble isExist]) {
height = 28+19+13+16 + 40;
}else{
height = 28+19+13+8 + 40;
}
2025-08-08 10:49:36 +08:00
}else{
2025-10-27 17:05:46 +08:00
height = [model.text heightForFont:[UIFont systemFontOfSize:12] width:ScaleWidth(280)-16-8-8*2] + 12+4+1;
2025-08-08 10:49:36 +08:00
}
return height;
}
2025-10-20 09:43:10 +08:00
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
QXRoomChatListModel *model;
2025-10-21 14:28:18 +08:00
// if (self.selectedBtn == self.chatBtn) {
// model = self.chatArray[indexPath.row];
// }else if (self.selectedBtn == self.giftBtn) {
// model = self.giftArray[indexPath.row];
// }else{
2025-10-20 09:43:10 +08:00
model = self.dataArray[indexPath.row];
2025-10-21 14:28:18 +08:00
// }
2025-10-20 09:43:10 +08:00
if (model.FromUserInfo.user_id.longValue > 0 && model.messageType == QXRoomChatMessageTypeSystem) {
if (self.delegate && [self.delegate respondsToSelector:@selector(previewUserInfoWithUserId:)]) {
[self.delegate previewUserInfoWithUserId:model.FromUserInfo.user_id];
}
}
}
2025-08-08 10:49:36 +08:00
-(void)scrollViewDidScroll:(UIScrollView *)scrollView{
CGFloat height = scrollView.frame.size.height;
CGFloat contentYoffset = scrollView.contentOffset.y;
CGFloat distanceFromBottom = scrollView.contentSize.height - contentYoffset;
if (distanceFromBottom < height) {
self.isDragging = NO;
}
2025-10-24 10:52:40 +08:00
CGFloat bottomEdge = scrollView.contentOffset.y + scrollView.frame.size.height;
if (scrollView.contentSize.height-bottomEdge) {
self.messageCountBtn.hidden = YES;
}
2025-08-08 10:49:36 +08:00
}
-(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{
self.isDragging = YES;
}
-(UITableView *)tableView{
if (!_tableView) {
_tableView = [[UITableView alloc] initWithFrame:CGRectZero style:(UITableViewStylePlain)];
_tableView.dataSource = self;
_tableView.delegate = self;
_tableView.backgroundColor = [UIColor clearColor];
_tableView.tableFooterView = [UIView new];
_tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
_tableView.showsHorizontalScrollIndicator = NO;
_tableView.showsVerticalScrollIndicator = NO;
if (@available(iOS 15.0, *)) {
_tableView.sectionHeaderTopPadding = 0;
} else {
// Fallback on earlier versions
}
}
return _tableView;
}
-(NSMutableArray *)dataArray{
if (!_dataArray) {
_dataArray = [NSMutableArray array];
}
return _dataArray;
}
-(NSMutableArray *)giftArray{
if (!_giftArray) {
_giftArray =[ NSMutableArray array];
}
return _giftArray;
}
-(NSMutableArray *)chatArray{
if (!_chatArray) {
_chatArray = [NSMutableArray array];
}
return _chatArray;
}
@end
@implementation QXRoomChatListCell
+(instancetype)cellWithTableView:(UITableView *)tableView{
static NSString* cellId = @"QXRoomChatListCell";
QXRoomChatListCell *cell = [tableView dequeueReusableCellWithIdentifier:cellId];
if (!cell) {
cell = [[QXRoomChatListCell alloc] initWithStyle:(UITableViewCellStyleDefault) reuseIdentifier:cellId];
}
return cell;
}
-(instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{
if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
self.contentView.backgroundColor = [UIColor clearColor];
self.backgroundColor = [UIColor clearColor];
self.selectionStyle = UITableViewCellSelectionStyleNone;
[self initSubviews];
}
return self;
}
-(void)headerAction{
if (self.delegate && [self.delegate respondsToSelector:@selector(previewUserInfoWithUserId:)]) {
[self.delegate previewUserInfoWithUserId:self.message.FromUserInfo.user_id];
}
}
-(void)setMessage:(QXRoomChatListModel *)message{
_message = message;
2025-10-20 09:43:10 +08:00
// self.titleLabel.text = message.text;
NSMutableAttributedString *attr = [[NSMutableAttributedString alloc] initWithString:message.text];
if ([message.FromUserInfo.nickname isExist]) {
[attr yy_setColor:messageNameColor range:[message.text rangeOfString:message.FromUserInfo.nickname]];
}
if ([message.ToUserInfo.nickname isExist]) {
[attr yy_setColor:messageNameColor range:[message.text rangeOfString:message.ToUserInfo.nickname]];
}
if ([message.GiftInfo.gift_name isExist]) {
NSArray *arr = [message.GiftInfo.gift_name componentsSeparatedByString:@","];
for (NSString*gift_name in arr) {
NSArray<NSValue *> *occurrences = findAllOccurrencesOfString(message.text, gift_name);
for (NSValue *rangeValue in occurrences) {
NSRange range = [rangeValue rangeValue];
[attr yy_setColor:messageGiftColor range:range];
}
}
}
if (message.GiftInfos.count > 0) {
for (QXGiftModel*gift in message.GiftInfos) {
if ([gift.gift_name isExist]) {
[attr yy_setColor:messageGiftColor range:[message.text rangeOfString:gift.gift_name]];
}
}
}
if (message.ToUserInfos.count > 0) {
for (int i = 0; i < message.ToUserInfos.count; i++) {
QXUserHomeModel*md = message.ToUserInfos[i];
NSArray<NSValue *> *occurrences = findAllOccurrencesOfString(message.text, md.nickname);
for (NSValue *rangeValue in occurrences) {
NSRange range = [rangeValue rangeValue];
[attr yy_setColor:messageNameColor range:range];
}
}
}
self.titleLabel.attributedText = attr;
2025-08-08 10:49:36 +08:00
self.nameLabel.text = message.FromUserInfo.nickname;
[self.headerImageView sd_setImageWithURL:[NSURL URLWithString:message.FromUserInfo.avatar]];
self.iconBgView.hidden = YES;
for (int i = 0;i < message.FromUserInfo.icon.count;i++) {
if (i < 3) {
self.iconBgView.hidden = NO;
UIImageView *iconImageView = self.iconViewArray[i];
iconImageView.hidden = NO;
[iconImageView sd_setImageWithURL:[NSURL URLWithString:message.FromUserInfo.icon[i]]];
}else{
self.iconBgView.hidden = YES;
}
}
}
-(void)initSubviews{
2025-10-24 10:52:40 +08:00
self.bgView = [[UIView alloc] init];
[self.contentView addSubview:self.bgView];
2025-10-27 17:05:46 +08:00
[self.bgView addRoundedCornersWithRadius:8];
2025-10-24 10:52:40 +08:00
[self.bgView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(16);
make.right.mas_equalTo(0);
make.top.mas_equalTo(messageBubbleMargin);
make.bottom.mas_equalTo(-messageBubbleMargin);
}];
self.bubbleImageView = [[UIImageView alloc] init];
self.bubbleImageView.contentMode = UIViewContentModeScaleToFill;
[self.bubbleImageView addRoundedCornersWithRadius:6];
self.bubbleImageView.backgroundColor = messageBubbleColor;
[self.bgView addSubview:self.bubbleImageView];
[self.bubbleImageView mas_makeConstraints:^(MASConstraintMaker *make) {
2025-10-27 17:05:46 +08:00
make.left.right.equalTo(self.bgView);
make.top.mas_equalTo(-4);
make.bottom.mas_equalTo(4);
2025-10-24 10:52:40 +08:00
}];
2025-08-08 10:49:36 +08:00
self.headerImageView = [[UIImageView alloc] init];
self.headerImageView.contentMode = UIViewContentModeScaleAspectFill;
self.headerImageView.backgroundColor = [UIColor whiteColor];
[self.headerImageView addRoundedCornersWithRadius:14];
2025-10-24 10:52:40 +08:00
[self.bgView addSubview:self.headerImageView];
2025-08-08 10:49:36 +08:00
[self.headerImageView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(16);
2025-10-24 10:52:40 +08:00
make.top.mas_equalTo(19);
2025-08-08 10:49:36 +08:00
make.size.mas_equalTo(CGSizeMake(28, 28));
}];
UIButton *headerBtn = [[UIButton alloc] init];
[headerBtn addTarget:self action:@selector(headerAction) forControlEvents:(UIControlEventTouchUpInside)];
2025-10-24 10:52:40 +08:00
[self.bgView addSubview:headerBtn];
2025-08-08 10:49:36 +08:00
[headerBtn mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.top.equalTo(self.headerImageView).offset(-2);
make.bottom.right.equalTo(self.headerImageView).offset(2);
}];
self.nameLabel = [[UILabel alloc] init];
2025-10-24 10:52:40 +08:00
self.nameLabel.textColor = RGB16(0xDED6ED);
self.nameLabel.font = [UIFont systemFontOfSize:14];
[self.bgView addSubview:self.nameLabel];
2025-08-08 10:49:36 +08:00
[self.nameLabel mas_makeConstraints:^(MASConstraintMaker *make) {
2025-10-24 10:52:40 +08:00
make.top.equalTo(self.headerImageView).offset(-3);
2025-08-08 10:49:36 +08:00
make.left.equalTo(self.headerImageView.mas_right).offset(6);
2025-10-24 10:52:40 +08:00
make.height.mas_equalTo(18);
2025-08-08 10:49:36 +08:00
}];
self.titleLabel = [[UILabel alloc] init];
self.titleLabel.textColor = [UIColor whiteColor];
self.titleLabel.font = [UIFont systemFontOfSize:14];
self.titleLabel.numberOfLines = 0;
2025-10-24 10:52:40 +08:00
[self.bgView addSubview:self.titleLabel];
2025-08-08 10:49:36 +08:00
[self.titleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
2025-10-24 10:52:40 +08:00
make.left.equalTo(self.nameLabel).offset(0);
make.top.equalTo(self.headerImageView.mas_bottom).offset(13);
make.right.mas_lessThanOrEqualTo(-18);
2025-08-08 10:49:36 +08:00
}];
self.nameLabel.text = @"张三站撒旦撒大萨达撒";
[self.contentView bringSubviewToFront:self.titleLabel];
self.iconBgView = [[UIView alloc] init];
2025-10-24 10:52:40 +08:00
[self.bgView addSubview:self.iconBgView];
2025-08-08 10:49:36 +08:00
[self.iconBgView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.nameLabel);
2025-10-24 10:52:40 +08:00
make.width.mas_equalTo(UserIconWidth*2+6);
2025-08-08 10:49:36 +08:00
make.height.mas_equalTo(16);
make.top.equalTo(self.nameLabel.mas_bottom).offset(2);
}];
2025-10-20 09:43:10 +08:00
CGFloat iconWidth = UserIconWidth;
CGFloat iconHeight = UserIconHeight;
2025-08-08 10:49:36 +08:00
CGFloat margin = 6;
for (int i = 0; i < 3; i++) {
UIImageView *iconImageView = [[UIImageView alloc] init];
iconImageView.hidden = YES;
2025-10-24 10:52:40 +08:00
iconImageView.contentMode = UIViewContentModeScaleAspectFit;
2025-08-08 10:49:36 +08:00
[self.iconBgView addSubview:iconImageView];
[iconImageView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(i*(iconWidth+margin));
make.width.mas_equalTo(iconWidth);
make.height.mas_equalTo(iconHeight);
make.centerY.equalTo(self.iconBgView);
}];
[self.iconViewArray addObject:iconImageView];
}
2025-10-24 10:52:40 +08:00
2025-08-08 10:49:36 +08:00
}
-(void)loadBubble{
2025-10-24 10:52:40 +08:00
if ([self.message.FromUserInfo.chat_bubble isExist]) {
self.bubbleImageView.backgroundColor = UIColor.clearColor;
self.bgView.backgroundColor = UIColor.clearColor;
// self.bubbleImageView.image = [[UIImage imageNamed:@"chat_bubble2"] resizableImageWithCapInsets:UIEdgeInsetsMake(30, 40, 40, 40) resizingMode:(UIImageResizingModeStretch)];;
[self.bubbleImageView sd_setImageWithURL:[NSURL URLWithString:self.message.FromUserInfo.chat_bubble] placeholderImage:nil options:SDWebImageRetryFailed completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) {
image = [image resizableImageWithCapInsets:UIEdgeInsetsMake(40, 40, 40, 40) resizingMode:(UIImageResizingModeStretch)];
self.bubbleImageView.image = image;
}];
[self.bgView mas_updateConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(8);
make.right.mas_equalTo(0);
make.top.mas_equalTo(0);
make.bottom.mas_equalTo(0);
}];
[self.headerImageView mas_updateConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(16);
make.top.mas_equalTo(19);
2025-08-08 10:49:36 +08:00
}];
}else{
2025-10-27 17:05:46 +08:00
self.bgView.backgroundColor = messageBubbleColor;
2025-10-24 10:52:40 +08:00
[self.bgView mas_updateConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(16);
make.right.mas_equalTo(-8);
make.top.mas_equalTo(messageBubbleMargin);
make.bottom.mas_equalTo(-messageBubbleMargin);
2025-08-08 10:49:36 +08:00
}];
2025-10-24 10:52:40 +08:00
[self.headerImageView mas_updateConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(9);
make.top.mas_equalTo(11);
2025-08-08 10:49:36 +08:00
}];
2025-10-24 10:52:40 +08:00
self.bubbleImageView.image = nil;
2025-10-27 17:05:46 +08:00
self.bubbleImageView.backgroundColor = UIColor.clearColor;
2025-08-08 10:49:36 +08:00
}
}
-(NSMutableArray *)iconViewArray{
if (!_iconViewArray) {
_iconViewArray = [NSMutableArray array];
}
return _iconViewArray;
}
@end
@implementation QXRoomGiftListCell
+(instancetype)cellWithTableView:(UITableView *)tableView{
static NSString* cellId = @"QXRoomGiftListCell";
QXRoomGiftListCell *cell = [tableView dequeueReusableCellWithIdentifier:cellId];
if (!cell) {
cell = [[QXRoomGiftListCell alloc] initWithStyle:(UITableViewCellStyleDefault) reuseIdentifier:cellId];
}
return cell;
}
-(instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{
if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
self.contentView.backgroundColor = [UIColor clearColor];
self.backgroundColor = [UIColor clearColor];
self.selectionStyle = UITableViewCellSelectionStyleNone;
[self initSubviews];
}
return self;
}
-(void)headerAction{
if (self.delegate && [self.delegate respondsToSelector:@selector(previewUserInfoWithUserId:)]) {
[self.delegate previewUserInfoWithUserId:self.message.FromUserInfo.user_id];
}
}
-(void)setMessage:(QXRoomChatListModel *)message{
_message = message;
2025-10-20 09:43:10 +08:00
// self.titleLabel.text = message.text;
NSMutableAttributedString *attr = [[NSMutableAttributedString alloc] initWithString:message.text];
if ([message.FromUserInfo.nickname isExist]) {
[attr yy_setColor:messageNameColor range:[message.text rangeOfString:message.FromUserInfo.nickname]];
}
if ([message.ToUserInfo.nickname isExist]) {
[attr yy_setColor:messageNameColor range:[message.text rangeOfString:message.ToUserInfo.nickname]];
}
if ([message.GiftInfo.gift_name isExist]) {
NSArray *arr = [message.GiftInfo.gift_name componentsSeparatedByString:@","];
for (NSString*gift_name in arr) {
NSArray<NSValue *> *occurrences = findAllOccurrencesOfString(message.text, gift_name);
for (NSValue *rangeValue in occurrences) {
NSRange range = [rangeValue rangeValue];
[attr yy_setColor:messageGiftColor range:range];
}
}
}
if (message.GiftInfos.count > 0) {
for (QXGiftModel*gift in message.GiftInfos) {
if ([gift.gift_name isExist]) {
[attr yy_setColor:messageGiftColor range:[message.text rangeOfString:gift.gift_name]];
}
}
}
if (message.ToUserInfos.count > 0) {
for (int i = 0; i < message.ToUserInfos.count; i++) {
QXUserHomeModel*md = message.ToUserInfos[i];
NSArray<NSValue *> *occurrences = findAllOccurrencesOfString(message.text, md.nickname);
for (NSValue *rangeValue in occurrences) {
NSRange range = [rangeValue rangeValue];
[attr yy_setColor:messageNameColor range:range];
}
}
}
self.titleLabel.attributedText = attr;
2025-10-25 19:38:29 +08:00
// self.nameLabel.text = message.FromUserInfo.nickname;
// [self.headerImageView sd_setImageWithURL:[NSURL URLWithString:message.FromUserInfo.avatar]];
// self.iconBgView.hidden = YES;
// for (int i = 0;i < message.FromUserInfo.icon.count;i++) {
// if (i < 3) {
// self.iconBgView.hidden = NO;
// UIImageView *iconImageView = self.iconViewArray[i];
// iconImageView.hidden = NO;
// [iconImageView sd_setImageWithURL:[NSURL URLWithString:message.FromUserInfo.icon[i]]];
// }else{
// self.iconBgView.hidden = YES;
// }
// }
2025-08-08 10:49:36 +08:00
}
-(void)initSubviews{
2025-10-24 10:52:40 +08:00
self.bgView = [[UIView alloc] init];
[self.contentView addSubview:self.bgView];
[self.bgView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(16);
2025-10-25 19:38:29 +08:00
make.right.mas_lessThanOrEqualTo(-8);
2025-10-24 10:52:40 +08:00
make.top.mas_equalTo(messageBubbleMargin);
make.bottom.mas_equalTo(-messageBubbleMargin);
}];
self.bubbleImageView = [[UIImageView alloc] init];
self.bubbleImageView.contentMode = UIViewContentModeScaleToFill;
[self.bubbleImageView addRoundedCornersWithRadius:6];
self.bubbleImageView.backgroundColor = messageBubbleColor;
[self.bgView addSubview:self.bubbleImageView];
[self.bubbleImageView mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(self.bgView);
}];
2025-10-25 19:38:29 +08:00
// self.headerImageView = [[UIImageView alloc] init];
// self.headerImageView.contentMode = UIViewContentModeScaleAspectFill;
// self.headerImageView.backgroundColor = [UIColor whiteColor];
// [self.headerImageView addRoundedCornersWithRadius:14];
// [self.bgView addSubview:self.headerImageView];
//
// [self.headerImageView mas_makeConstraints:^(MASConstraintMaker *make) {
// make.left.mas_equalTo(16);
// make.top.mas_equalTo(19);
// make.size.mas_equalTo(CGSizeMake(28, 28));
// }];
//
// UIButton *headerBtn = [[UIButton alloc] init];
// [headerBtn addTarget:self action:@selector(headerAction) forControlEvents:(UIControlEventTouchUpInside)];
// [self.bgView addSubview:headerBtn];
// [headerBtn mas_makeConstraints:^(MASConstraintMaker *make) {
// make.left.top.equalTo(self.headerImageView).offset(-2);
// make.bottom.right.equalTo(self.headerImageView).offset(2);
// }];
//
// self.nameLabel = [[UILabel alloc] init];
// self.nameLabel.textColor = RGB16(0xDED6ED);
// self.nameLabel.font = [UIFont systemFontOfSize:14];
// [self.bgView addSubview:self.nameLabel];
// [self.nameLabel mas_makeConstraints:^(MASConstraintMaker *make) {
// make.top.equalTo(self.headerImageView).offset(-3);
// make.left.equalTo(self.headerImageView.mas_right).offset(8);
// make.height.mas_equalTo(18);
// }];
//
2025-08-08 10:49:36 +08:00
self.titleLabel = [[UILabel alloc] init];
self.titleLabel.textColor = [UIColor whiteColor];
2025-10-27 17:05:46 +08:00
self.titleLabel.font = [UIFont systemFontOfSize:12];
2025-08-08 10:49:36 +08:00
self.titleLabel.numberOfLines = 0;
2025-10-24 10:52:40 +08:00
[self.bgView addSubview:self.titleLabel];
2025-10-25 19:38:29 +08:00
// [self.titleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
// make.left.equalTo(self.nameLabel).offset(0);
// make.top.equalTo(self.headerImageView.mas_bottom).offset(13);
// make.right.mas_lessThanOrEqualTo(-18);
// }];
2025-08-08 10:49:36 +08:00
[self.titleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
2025-10-25 19:38:29 +08:00
make.left.equalTo(self.bgView).offset(8);
2025-10-27 17:05:46 +08:00
make.top.mas_equalTo(2);
make.bottom.mas_equalTo(-2);
2025-10-25 19:38:29 +08:00
make.right.mas_equalTo(-8);
2025-08-08 10:49:36 +08:00
}];
2025-10-25 19:38:29 +08:00
2025-08-08 10:49:36 +08:00
2025-10-25 19:38:29 +08:00
// self.nameLabel.text = @"张三站撒旦撒大萨达撒";
2025-08-08 10:49:36 +08:00
2025-10-24 10:52:40 +08:00
[self.contentView bringSubviewToFront:self.titleLabel];
2025-10-25 19:38:29 +08:00
// self.iconBgView = [[UIView alloc] init];
// [self.bgView addSubview:self.iconBgView];
// [self.iconBgView mas_makeConstraints:^(MASConstraintMaker *make) {
// make.left.equalTo(self.nameLabel);
// make.width.mas_equalTo(UserIconWidth*2+6);
// make.height.mas_equalTo(16);
// make.top.equalTo(self.nameLabel.mas_bottom).offset(2);
// }];
//
// CGFloat iconWidth = UserIconWidth;
// CGFloat iconHeight = UserIconHeight;
// CGFloat margin = 6;
// for (int i = 0; i < 3; i++) {
// UIImageView *iconImageView = [[UIImageView alloc] init];
// iconImageView.hidden = YES;
// iconImageView.contentMode = UIViewContentModeScaleAspectFit;
// [self.iconBgView addSubview:iconImageView];
// [iconImageView mas_makeConstraints:^(MASConstraintMaker *make) {
// make.left.mas_equalTo(i*(iconWidth+margin));
// make.width.mas_equalTo(iconWidth);
// make.height.mas_equalTo(iconHeight);
// make.centerY.equalTo(self.iconBgView);
// }];
// [self.iconViewArray addObject:iconImageView];
// }
2025-10-24 10:52:40 +08:00
2025-10-27 17:05:46 +08:00
}
-(void)layoutSubviews{
[super layoutSubviews];
[self.bgView addRoundedCornersWithRadius:self.bgView.height/2];
2025-10-24 10:52:40 +08:00
}
-(void)loadBubble{
2025-10-25 19:38:29 +08:00
// if ([self.message.FromUserInfo.chat_bubble isExist]) {
// self.bubbleImageView.backgroundColor = UIColor.clearColor;
//// self.bubbleImageView.image = [[UIImage imageNamed:@"chat_bubble2"] resizableImageWithCapInsets:UIEdgeInsetsMake(30, 40, 40, 40) resizingMode:(UIImageResizingModeStretch)];;
// [self.bubbleImageView sd_setImageWithURL:[NSURL URLWithString:self.message.FromUserInfo.chat_bubble] placeholderImage:nil options:SDWebImageRetryFailed completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) {
// image = [image resizableImageWithCapInsets:UIEdgeInsetsMake(40, 40, 40, 40) resizingMode:(UIImageResizingModeStretch)];
// self.bubbleImageView.image = image;
// }];
// [self.bgView mas_updateConstraints:^(MASConstraintMaker *make) {
// make.left.mas_equalTo(8);
// make.right.mas_equalTo(0);
// make.top.mas_equalTo(0);
// make.bottom.mas_equalTo(0);
// }];
// [self.titleLabel mas_updateConstraints:^(MASConstraintMaker *make) {
// make.left.mas_equalTo(16);
// make.top.mas_equalTo(16);
// make.bottom.mas_equalTo(-16);
// make.right.mas_equalTo(-16);
// }];
// }else{
// [self.bgView mas_updateConstraints:^(MASConstraintMaker *make) {
// make.left.mas_equalTo(16);
// make.right.mas_equalTo(-8);
// make.top.mas_equalTo(messageBubbleMargin);
// make.bottom.mas_equalTo(-messageBubbleMargin);
// }];
// [self.titleLabel mas_updateConstraints:^(MASConstraintMaker *make) {
// make.left.mas_equalTo(8);
// make.top.mas_equalTo(8);
// make.bottom.mas_equalTo(-8);
// make.right.mas_equalTo(-8);
// }];
// self.bubbleImageView.image = nil;
// self.bubbleImageView.backgroundColor = messageBubbleColor;
// }
2025-10-24 10:52:40 +08:00
}
2025-10-25 19:38:29 +08:00
//-(NSMutableArray *)iconViewArray{
// if (!_iconViewArray) {
// _iconViewArray = [NSMutableArray array];
// }
// return _iconViewArray;
//}
2025-10-24 10:52:40 +08:00
@end
@implementation QXRoomEmojiListCell
+(instancetype)cellWithTableView:(UITableView *)tableView{
static NSString* cellId = @"QXRoomEmojiListCell";
QXRoomEmojiListCell *cell = [tableView dequeueReusableCellWithIdentifier:cellId];
if (!cell) {
cell = [[QXRoomEmojiListCell alloc] initWithStyle:(UITableViewCellStyleDefault) reuseIdentifier:cellId];
}
return cell;
}
-(instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{
if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
self.contentView.backgroundColor = [UIColor clearColor];
self.backgroundColor = [UIColor clearColor];
self.selectionStyle = UITableViewCellSelectionStyleNone;
[self initSubviews];
}
return self;
}
-(void)setMessage:(QXRoomChatListModel *)message{
_message = message;
self.nameLabel.text = message.FromUserInfo.nickname;
[self.headerImageView sd_setImageWithURL:[NSURL URLWithString:message.FromUserInfo.avatar]];
self.iconBgView.hidden = YES;
for (int i = 0;i < message.FromUserInfo.icon.count;i++) {
if (i < 3) {
self.iconBgView.hidden = NO;
UIImageView *iconImageView = self.iconViewArray[i];
iconImageView.hidden = NO;
[iconImageView sd_setImageWithURL:[NSURL URLWithString:message.FromUserInfo.icon[i]]];
}else{
self.iconBgView.hidden = YES;
}
}
if (![message.emoji.animate_image isExist]) {
[self.animatedImageView sd_cancelCurrentImageLoad];
[self.animatedImageView sd_setImageWithURL:[NSURL URLWithString:message.emoji.image]];
return;
}
if (message.emoji.isAnimated) {
[self.animatedImageView sd_cancelCurrentImageLoad];
[self.animatedImageView sd_setImageWithURL:[NSURL URLWithString:message.emoji.image]];
}else{
message.emoji.isAnimated = YES;
NSURL *animiteUrl = [NSURL URLWithString:message.emoji.animate_image];
[self.animatedImageView sd_setImageWithURL:animiteUrl
placeholderImage:nil
options:SDWebImageHighPriority
completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) {
//
if (image) {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (double)(1.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
//
[self.animatedImageView.player stopPlaying];
[self.animatedImageView.player clearFrameBuffer];
[self.animatedImageView sd_cancelCurrentImageLoad];
[self.animatedImageView sd_setImageWithURL:[NSURL URLWithString:message.emoji.image]];
});
}else{
[self.animatedImageView sd_cancelCurrentImageLoad];
[self.animatedImageView sd_setImageWithURL:[NSURL URLWithString:message.emoji.image]];
}
}];
}
}
-(void)initSubviews{
self.bgView = [[UIView alloc] init];
2025-10-28 09:18:28 +08:00
self.bgView.backgroundColor = UIColor.clearColor;
2025-10-24 10:52:40 +08:00
[self.contentView addSubview:self.bgView];
[self.bgView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(16);
make.right.mas_equalTo(0);
make.top.mas_equalTo(messageBubbleMargin);
make.bottom.mas_equalTo(-messageBubbleMargin);
}];
2025-08-08 10:49:36 +08:00
self.bubbleImageView = [[UIImageView alloc] init];
2025-10-24 10:52:40 +08:00
self.bubbleImageView.contentMode = UIViewContentModeScaleToFill;
2025-08-08 10:49:36 +08:00
[self.bubbleImageView addRoundedCornersWithRadius:6];
2025-10-24 10:52:40 +08:00
self.bubbleImageView.backgroundColor = messageBubbleColor;
[self.bgView addSubview:self.bubbleImageView];
[self.bubbleImageView mas_makeConstraints:^(MASConstraintMaker *make) {
2025-10-27 17:05:46 +08:00
make.left.right.equalTo(self.bgView);
make.top.mas_equalTo(-4);
make.bottom.mas_equalTo(4);
2025-10-24 10:52:40 +08:00
}];
2025-10-20 09:43:10 +08:00
2025-10-24 10:52:40 +08:00
self.headerImageView = [[UIImageView alloc] init];
self.headerImageView.contentMode = UIViewContentModeScaleAspectFill;
self.headerImageView.backgroundColor = [UIColor whiteColor];
[self.headerImageView addRoundedCornersWithRadius:14];
[self.bgView addSubview:self.headerImageView];
[self.headerImageView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(16);
make.top.mas_equalTo(19);
make.size.mas_equalTo(CGSizeMake(28, 28));
}];
2025-10-20 09:43:10 +08:00
2025-10-24 10:52:40 +08:00
UIButton *headerBtn = [[UIButton alloc] init];
[headerBtn addTarget:self action:@selector(headerAction) forControlEvents:(UIControlEventTouchUpInside)];
[self.bgView addSubview:headerBtn];
[headerBtn mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.top.equalTo(self.headerImageView).offset(-2);
make.bottom.right.equalTo(self.headerImageView).offset(2);
}];
2025-10-20 09:43:10 +08:00
2025-10-24 10:52:40 +08:00
self.nameLabel = [[UILabel alloc] init];
self.nameLabel.textColor = RGB16(0xDED6ED);
self.nameLabel.font = [UIFont systemFontOfSize:14];
[self.bgView addSubview:self.nameLabel];
[self.nameLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.headerImageView).offset(-3);
make.left.equalTo(self.headerImageView.mas_right).offset(6);
make.height.mas_equalTo(18);
}];
2025-08-08 10:49:36 +08:00
2025-10-24 10:52:40 +08:00
self.animatedImageView = [[SDAnimatedImageView alloc] init];
self.animatedImageView.shouldCustomLoopCount = YES;
self.animatedImageView.animationRepeatCount = 5;
self.animatedImageView.clearBufferWhenStopped = YES;
self.animatedImageView.contentMode = UIViewContentModeScaleAspectFit;
[self.bgView addSubview:self.animatedImageView];
[self.animatedImageView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.nameLabel).offset(0);
make.top.equalTo(self.headerImageView.mas_bottom).offset(13);
make.height.width.mas_equalTo(40);
2025-08-08 10:49:36 +08:00
}];
2025-10-24 10:52:40 +08:00
self.nameLabel.text = @"张三站撒旦撒大萨达撒";
2025-08-08 10:49:36 +08:00
self.iconBgView = [[UIView alloc] init];
2025-10-24 10:52:40 +08:00
[self.bgView addSubview:self.iconBgView];
2025-08-08 10:49:36 +08:00
[self.iconBgView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.nameLabel);
2025-10-24 10:52:40 +08:00
make.width.mas_equalTo(UserIconWidth*2+6);
2025-08-08 10:49:36 +08:00
make.height.mas_equalTo(16);
make.top.equalTo(self.nameLabel.mas_bottom).offset(2);
}];
2025-10-20 09:43:10 +08:00
CGFloat iconWidth = UserIconWidth;
CGFloat iconHeight = UserIconHeight;
2025-08-08 10:49:36 +08:00
CGFloat margin = 6;
for (int i = 0; i < 3; i++) {
UIImageView *iconImageView = [[UIImageView alloc] init];
iconImageView.hidden = YES;
2025-10-24 10:52:40 +08:00
iconImageView.contentMode = UIViewContentModeScaleAspectFit;
2025-08-08 10:49:36 +08:00
[self.iconBgView addSubview:iconImageView];
[iconImageView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(i*(iconWidth+margin));
make.width.mas_equalTo(iconWidth);
make.height.mas_equalTo(iconHeight);
make.centerY.equalTo(self.iconBgView);
}];
[self.iconViewArray addObject:iconImageView];
}
2025-10-24 10:52:40 +08:00
2025-08-08 10:49:36 +08:00
}
2025-10-28 09:18:28 +08:00
-(void)layoutSubviews{
[super layoutSubviews];
[self.bgView addRoundedCornersWithRadius:8];
}
2025-08-08 10:49:36 +08:00
-(void)loadBubble{
2025-10-24 10:52:40 +08:00
if ([self.message.FromUserInfo.chat_bubble isExist]) {
self.bubbleImageView.backgroundColor = UIColor.clearColor;
2025-10-28 09:18:28 +08:00
self.bgView.backgroundColor = UIColor.clearColor;
2025-10-24 10:52:40 +08:00
// self.bubbleImageView.image = [[UIImage imageNamed:@"chat_bubble2"] resizableImageWithCapInsets:UIEdgeInsetsMake(30, 40, 40, 40) resizingMode:(UIImageResizingModeStretch)];;
[self.bubbleImageView sd_setImageWithURL:[NSURL URLWithString:self.message.FromUserInfo.chat_bubble] placeholderImage:nil options:SDWebImageRetryFailed completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) {
image = [image resizableImageWithCapInsets:UIEdgeInsetsMake(40, 40, 40, 40) resizingMode:(UIImageResizingModeStretch)];
self.bubbleImageView.image = image;
}];
[self.bgView mas_updateConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(8);
make.right.mas_equalTo(0);
make.top.mas_equalTo(0);
make.bottom.mas_equalTo(0);
}];
[self.headerImageView mas_updateConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(16);
make.top.mas_equalTo(19);
2025-08-08 10:49:36 +08:00
}];
}else{
2025-10-24 10:52:40 +08:00
[self.bgView mas_updateConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(16);
make.right.mas_equalTo(-8);
make.top.mas_equalTo(messageBubbleMargin);
make.bottom.mas_equalTo(-messageBubbleMargin);
2025-08-08 10:49:36 +08:00
}];
2025-10-24 10:52:40 +08:00
[self.headerImageView mas_updateConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(9);
make.top.mas_equalTo(11);
2025-08-08 10:49:36 +08:00
}];
2025-10-24 10:52:40 +08:00
self.bubbleImageView.image = nil;
2025-10-28 09:18:28 +08:00
self.bubbleImageView.backgroundColor = UIColor.clearColor;
self.bgView.backgroundColor = messageBubbleColor;
2025-08-08 10:49:36 +08:00
}
}
-(NSMutableArray *)iconViewArray{
if (!_iconViewArray) {
_iconViewArray = [NSMutableArray array];
}
return _iconViewArray;
}
@end
@implementation QXRoomChatListSystemCell
+(instancetype)cellWithTableView:(UITableView *)tableView{
static NSString* cellId = @"QXRoomChatListSystemCell";
QXRoomChatListSystemCell *cell = [tableView dequeueReusableCellWithIdentifier:cellId];
if (!cell) {
cell = [[QXRoomChatListSystemCell alloc] initWithStyle:(UITableViewCellStyleDefault) reuseIdentifier:cellId];
}
return cell;
}
-(instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{
if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
self.contentView.backgroundColor = [UIColor clearColor];
self.backgroundColor = [UIColor clearColor];
self.selectionStyle = UITableViewCellSelectionStyleNone;
[self initSubviews];
}
return self;
}
2025-10-27 17:05:46 +08:00
-(void)layoutSubviews{
[super layoutSubviews];
if (self.message.messageType == QXRoomChatMessageTypeNotice) {
[self.bgView addRoundedCornersWithRadius:8];
}else{
[self.bgView addRoundedCornersWithRadius:self.bgView.height/2];
}
}
2025-08-08 10:49:36 +08:00
-(void)setMessage:(QXRoomChatListModel *)message{
_message = message;
2025-10-20 09:43:10 +08:00
NSMutableAttributedString *attr = [[NSMutableAttributedString alloc] initWithString:message.text];
if ([message.FromUserInfo.nickname isExist]) {
[attr yy_setColor:messageNameColor range:[message.text rangeOfString:message.FromUserInfo.nickname]];
}
if ([message.ToUserInfo.nickname isExist]) {
[attr yy_setColor:messageNameColor range:[message.text rangeOfString:message.ToUserInfo.nickname]];
}
if ([message.GiftInfo.gift_name isExist]) {
NSArray *arr = [message.GiftInfo.gift_name componentsSeparatedByString:@","];
for (NSString*gift_name in arr) {
NSArray<NSValue *> *occurrences = findAllOccurrencesOfString(message.text, gift_name);
for (NSValue *rangeValue in occurrences) {
NSRange range = [rangeValue rangeValue];
[attr yy_setColor:messageGiftColor range:range];
}
}
}
if (message.GiftInfos.count > 0) {
for (QXGiftModel*gift in message.GiftInfos) {
if ([gift.gift_name isExist]) {
[attr yy_setColor:messageGiftColor range:[message.text rangeOfString:gift.gift_name]];
}
}
}
if (message.ToUserInfos.count > 0) {
for (int i = 0; i < message.ToUserInfos.count; i++) {
QXUserHomeModel*md = message.ToUserInfos[i];
NSArray<NSValue *> *occurrences = findAllOccurrencesOfString(message.text, md.nickname);
for (NSValue *rangeValue in occurrences) {
NSRange range = [rangeValue rangeValue];
[attr yy_setColor:messageNameColor range:range];
}
}
}
2025-10-25 19:38:29 +08:00
if (message.messageType == QXRoomChatMessageTypeNotice) {
2025-10-27 17:05:46 +08:00
[attr yy_setColor:messageNoticeColor range:NSMakeRange(0, attr.length)];
2025-10-25 19:38:29 +08:00
}
2025-10-20 09:43:10 +08:00
self.titleLabel.attributedText = attr;
2025-08-08 10:49:36 +08:00
}
-(void)initSubviews{
self.bgView = [[UIView alloc] init];
2025-10-24 10:52:40 +08:00
self.bgView.backgroundColor = messageBubbleColor;
2025-08-08 10:49:36 +08:00
[self.bgView addRoundedCornersWithRadius:6];
[self.contentView addSubview:self.bgView];
[self.bgView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(16);
make.right.mas_lessThanOrEqualTo(-8);
2025-10-24 10:52:40 +08:00
make.top.mas_equalTo(messageBubbleMargin);
make.bottom.mas_equalTo(-messageBubbleMargin);
2025-08-08 10:49:36 +08:00
}];
2025-10-21 14:28:18 +08:00
2025-08-08 10:49:36 +08:00
self.titleLabel = [[UILabel alloc] init];
2025-10-20 09:43:10 +08:00
// self.titleLabel.textColor = RGB16(0XD1A9FE);
self.titleLabel.textColor = UIColor.whiteColor;
2025-10-27 17:05:46 +08:00
self.titleLabel.font = [UIFont systemFontOfSize:12];
2025-08-08 10:49:36 +08:00
self.titleLabel.numberOfLines = 0;
[self.bgView addSubview:self.titleLabel];
[self.titleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.bgView).offset(8);
2025-10-27 17:05:46 +08:00
make.top.mas_equalTo(2);
make.bottom.mas_equalTo(-2);
2025-08-08 10:49:36 +08:00
make.right.mas_equalTo(-8);
}];
}
@end
@implementation QXRoomChatListModel
+(NSDictionary<NSString *,id> *)modelContainerPropertyGenericClass{
2025-10-20 09:43:10 +08:00
return @{
@"GiftInfo" : @"QXGiftModel",
@"GiftInfos" : @"QXGiftModel",
2025-08-08 10:49:36 +08:00
@"FromUserInfo":@"QXUserHomeModel",
@"nextInfo":@"QXSongListModel",
2025-10-20 09:43:10 +08:00
@"songInfo":@"QXSongListModel",
@"ToUserInfo":@"QXUserHomeModel",
@"ToUserInfos":@"QXUserHomeModel",
@"friend_user":@"QXRoomFriendRelationModel"
2025-08-08 10:49:36 +08:00
};
}
2025-10-20 20:05:55 +08:00
- (BOOL)isSameGiftFromSameSender:(QXRoomChatListModel *)otherGift {
if (!otherGift) return NO;
return [self.GiftInfo.gift_id isEqualToString:otherGift.GiftInfo.gift_id] &&
[self.FromUserInfo.nickname isEqualToString:otherGift.FromUserInfo.nickname] &&
[self.ToUserInfo.nickname isEqualToString:otherGift.ToUserInfo.nickname];
}
- (instancetype)copy {
QXRoomChatListModel *copy = [[QXRoomChatListModel alloc] init];
QXGiftModel *gift = [[QXGiftModel alloc] init];
gift.gift_id = self.GiftInfo.gift_id;
gift.base_image = self.GiftInfo.base_image;
gift.gift_name = self.GiftInfo.gift_name;
copy.GiftInfo = gift;
QXUserHomeModel *fromUser = [[QXUserHomeModel alloc] init];
fromUser.nickname = self.FromUserInfo.nickname;
fromUser.avatar = self.FromUserInfo.avatar;
copy.FromUserInfo = fromUser;
QXUserHomeModel *toUser = [[QXUserHomeModel alloc] init];
toUser.nickname = self.FromUserInfo.nickname;
toUser.avatar = self.FromUserInfo.avatar;
copy.ToUserInfo = toUser;
copy.gift_num = self.gift_num;
return copy;
}
2025-08-08 10:49:36 +08:00
@end