Files
yinmeng-ios/xplan-ios/Main/Message/View/Session/MessageCell.m
2022-08-26 21:47:28 +08:00

462 lines
18 KiB
Objective-C

//
// MessageCell.m
// xplan-ios
//
// Created by zu on 2021/11/28.
//
#import "MessageCell.h"
#import "MessageContentProtocol.h"
#import "MessageContentText.h"
#import "MessageContentImage.h"
#import "MessageContentTextClickable.h"
#import "MessageContentCustomView.h"
#import "MessageContentGiftView.h"
#import "MessageContentGuildView.h"
#import "MessageContentUnSupportView.h"
#import "MessageContentOpenLiveView.h"
#import "MessageContentApplicationShareView.h"
#import "MessageContentLevelUpgradeView.h"
#import "MessageConentAudioView.h"
#import "MessageContentTweetView.h"
#import "MessageContentSkillCardView.h"
#import "MessageContentFindNewGreetView.h"
#import "MessageContentRiskAlertView.h"
#import "MessageContentMonentsView.h"
#import "AttachmentModel.h"
#import "NetImageView.h"
#import "ThemeColor.h"
#import "XPMacro.h"
#import <Masonry/Masonry.h>
@interface MessageCell()<MessageContentCustomViewDelegate>
@property (nonatomic, assign) NIMMessageType messageType;
/**
左侧头像(私聊对象)
*/
@property (nonatomic, strong) NetImageView * leftAvatar;
/**
右侧头像(自己)
*/
@property (nonatomic, strong) NetImageView * rightAvatar;
///处理失败的
@property (nonatomic,strong) UIButton *failButton;
/**
消息背景
*/
@property (nonatomic, strong) UIView * messageBackground;
@property (nonatomic, strong) MASConstraint * messageBackgroundLeft;
@property (nonatomic, strong) MASConstraint * messageBackgroundRight;
/**
消息内容实体
*/
@property (nonatomic, strong) UIView<MessageContentProtocol> * messageContent;
///当前的消息
@property (nonatomic,strong) NIMMessage *currentMessage;
@end
@implementation MessageCell
+ (CGFloat)measureHeight:(NIMMessage *)message {
CGFloat minHeight = AVATAR_SIZE + AVATAR_MARGIN_H * 2;
if (!message) {
return minHeight;
}
CGFloat mesuredHeight = 0;
switch (message.messageType) {
case NIMMessageTypeText:
case NIMMessageTypeTip:
mesuredHeight = [MessageContentText measureHeight:message];
break;
case NIMMessageTypeImage:
mesuredHeight = [MessageContentImage measureHeight:message];
break;
case NIMMessageTypeAudio:
mesuredHeight = [MessageConentAudioView measureHeight:message];
break;
case NIMMessageTypeCustom:
mesuredHeight = [self customMessageMeasureHeight:message];
break;
default:
break;
}
return MAX(minHeight, mesuredHeight);
}
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
self.selectionStyle = UITableViewCellSelectionStyleNone;
[self initViews];
[self initLayout];
}
return self;
}
- (void)initViews {
self.backgroundColor = UIColor.clearColor;
[self.contentView addSubview:self.leftAvatar];
[self.contentView addSubview:self.rightAvatar];
[self.contentView addSubview:self.messageBackground];
[self.contentView addSubview:self.failButton];
}
- (void)initLayout {
[self.leftAvatar mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.top.mas_equalTo(self).offset(15);
make.width.height.mas_equalTo(45);
}];
[self.rightAvatar mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.mas_equalTo(self).offset(15);
make.right.mas_equalTo(self).offset(-15);
make.width.height.mas_equalTo(45);
}];
[self.messageBackground mas_makeConstraints:^(MASConstraintMaker *make) {
self.messageBackgroundLeft = make.left.mas_equalTo(self.leftAvatar.mas_right).offset(15);
self.messageBackgroundRight = make.right.mas_equalTo(self.rightAvatar.mas_left).offset(-15);
make.top.mas_equalTo(self).offset(20);
}];
[self.failButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.size.mas_equalTo(CGSizeMake(20, 20));
make.centerY.mas_equalTo(self.messageBackground);
make.left.mas_equalTo(self.messageBackground.mas_right).offset(10);
}];
}
- (void)renderWithMessage:(NIMMessage *)message {
self.currentMessage = message;
NSString * avatarUrl = [[NIMSDK sharedSDK].userManager userInfo:message.from].userInfo.avatarUrl;
avatarUrl = [avatarUrl stringByReplacingOccurrencesOfString:@"https" withString:@"http"];
BOOL isSelf = [[NIMSDK sharedSDK].loginManager.currentAccount isEqualToString:message.from];
if (isSelf) {
self.leftAvatar.hidden = YES;
self.rightAvatar.hidden = NO;
[self.messageBackgroundLeft uninstall];
[self.messageBackgroundRight install];
self.rightAvatar.imageUrl = avatarUrl;
} else {
self.leftAvatar.hidden = NO;
self.rightAvatar.hidden = YES;
[self.messageBackgroundLeft install];
[self.messageBackgroundRight uninstall];
self.leftAvatar.imageUrl = avatarUrl;
}
[self handleMessageFail:message];
if ([self messageShowAvatar:message]) {
self.leftAvatar.hidden= [self messageShowAvatar:message];
self.rightAvatar.hidden = [self messageShowAvatar:message];
}
if (self.messageContent) {
[self.messageContent removeFromSuperview];
}
switch (message.messageType) {
case NIMMessageTypeText:
case NIMMessageTypeTip:
if (![self.messageContent isKindOfClass:[MessageContentText class]]) {
self.messageContent = [[MessageContentText alloc] init];
}
break;
case NIMMessageTypeImage:
if (![self.messageContent isKindOfClass:[MessageContentImage class]]) {
self.messageContent = [[MessageContentImage alloc] init];
}
break;
case NIMMessageTypeAudio:
if (![self.messageContent isKindOfClass:[MessageConentAudioView class]]) {
self.messageContent = [[MessageConentAudioView alloc] init];
}
break;
case NIMMessageTypeCustom:
self.messageContent = [self getCustomMessageContentView:message];
break;
default:
if (![self.messageContent isKindOfClass:[MessageContentUnSupportView class]]) {
self.messageContent = [[MessageContentUnSupportView alloc] init];
}
break;
}
[self.messageBackground addSubview:self.messageContent];
[self.messageContent mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.top.right.bottom.mas_equalTo(self.messageBackground);
}];
[self.messageContent render:message];
}
- (void)handleMessageFail:(NIMMessage *)message {
BOOL isHiddenFail = YES;
if (!message.isReceivedMsg) {
isHiddenFail = message.deliveryState != NIMMessageDeliveryStateFailed;
if (message.localExt) {
NSDictionary * dic = message.localExt;
if (((NSString *)dic[@"suggestion"]).integerValue == 2) {
isHiddenFail = NO;
}
}
} else {
isHiddenFail = message.attachmentDownloadState != NIMMessageAttachmentDownloadStateFailed;
}
self.failButton.hidden = isHiddenFail;
if (!isHiddenFail) {
if (message.isReceivedMsg) {
[self.failButton mas_remakeConstraints:^(MASConstraintMaker *make) {
make.size.mas_equalTo(CGSizeMake(20, 20));
make.centerY.mas_equalTo(self.messageBackground);
make.left.mas_equalTo(self.messageBackground.mas_right).offset(10);
}];
} else {
[self.failButton mas_remakeConstraints:^(MASConstraintMaker *make) {
make.size.mas_equalTo(CGSizeMake(20, 20));
make.centerY.mas_equalTo(self.messageBackground);
make.right.mas_equalTo(self.messageBackground.mas_left).offset(-10);
}];
}
}
}
+ (NSString *)cellContent:(NIMMessage *)message {
if (message.messageType == NIMMessageTypeText || message.messageType == NIMMessageTypeTip) {
return @"MessageContentText";
} else if(message.messageType == NIMMessageTypeImage) {
return @"MessageContentImage";
}else if(message.messageType == NIMMessageTypeAudio) {
return @"MessageConentAudioView";
} else if(message.messageType == NIMMessageTypeCustom) {
NIMCustomObject *obj = (NIMCustomObject *)message.messageObject;
AttachmentModel *attachment = (AttachmentModel *)obj.attachment;
if (attachment.first == CustomMessageType_Gift && attachment.second == Custom_Message_Sub_Gift_Send) {
return @"MessageContentGiftView";
} else if(attachment.first == CustomMessageType_Secretary) {
return @"MessageContentTextClickable";
} else if(attachment.first == CustomMessageType_Hall) {
return @"MessageContentGuildView";
} else if(attachment.first == CustomMessageType_Member_Online && attachment.second == Custom_Message_Type_Attention_Member_Online) {
return @"MessageContentOpenLiveView";
} else if(attachment.first == CustomMessageType_Application_Share && attachment.second == Custom_Message_Sub_Application_Share_Room) {
return @"MessageContentOpenLiveView";
} else if(attachment.first == CustomMessageType_User_UpGrade && (attachment.second == Custom_Message_Sub_User_UpGrade_Charm || attachment.second == Custom_Message_Sub_User_UpGrade_Exper)) {
return @"MessageContentLevelUpgradeView";
} else if(attachment.first == CustomMessageType_Tweet && attachment.second == Custom_Message_Sub_Tweet_News) {
return @"MessageContentTweetView";
} else if(attachment.first == CustomMessageType_Skill_Card) {
return @"MessageContentSkillCardView";
} else if(attachment.first == CustomMessageType_FindNew){
return @"MessageContentFindNewGreetView";
} else if(attachment.first == CustomMessageType_Chat_Risk_Alert) {
return @"MessageContentRiskAlertView";
}else if(attachment.first == CustomMessageType_Monents && attachment.second == Custom_Message_Sub_Monents_Share) {
return @"MessageContentMonentsView";
} else {
return @"MessageContentOpenLiveView";
}
} else {
return @"MessageContentUnSupportView";
}
}
- (BOOL)messageShowAvatar:(NIMMessage *)message {
NIMCustomObject *obj = (NIMCustomObject *)message.messageObject;
AttachmentModel *attachment = (AttachmentModel *)obj.attachment;
if (attachment.first == CustomMessageType_Chat_Risk_Alert) {
return YES;
}
return NO;
}
+ (CGFloat)customMessageMeasureHeight:(NIMMessage *)message {
NIMCustomObject *obj = (NIMCustomObject *)message.messageObject;
AttachmentModel *attachment = (AttachmentModel *)obj.attachment;
if (attachment.first == CustomMessageType_Gift && attachment.second == Custom_Message_Sub_Gift_Send) {
return [MessageContentGiftView measureHeight:message];
} else if(attachment.first == CustomMessageType_Secretary && attachment.second == Custom_Message_Sub_Secretary_Router) {
return [MessageContentTextClickable measureHeight:message];
} else if(attachment.first == CustomMessageType_Hall) {
return [MessageContentGuildView measureHeight:message];
} else if(attachment.first == CustomMessageType_Member_Online && attachment.second == Custom_Message_Type_Attention_Member_Online) {
return [MessageContentOpenLiveView measureHeight:message];
} else if(attachment.first == CustomMessageType_Application_Share && attachment.second == Custom_Message_Sub_Application_Share_Room) {
return [MessageContentApplicationShareView measureHeight:message];
} else if(attachment.first == CustomMessageType_User_UpGrade && (attachment.second == Custom_Message_Sub_User_UpGrade_Charm || attachment.second == Custom_Message_Sub_User_UpGrade_Exper)) {
return [MessageContentLevelUpgradeView measureHeight:message];
} else if(attachment.first == CustomMessageType_Tweet && attachment.second == Custom_Message_Sub_Tweet_News) {
return [MessageContentTweetView measureHeight:message];
} else if(attachment.first == CustomMessageType_Skill_Card) {
return [MessageContentSkillCardView measureHeight:message];
} else if(attachment.first == CustomMessageType_FindNew) {
return [MessageContentFindNewGreetView measureHeight:message];
} else if(attachment.first == CustomMessageType_Chat_Risk_Alert) {
return [MessageContentRiskAlertView measureHeight:message];
} else if(attachment.first == CustomMessageType_Monents && attachment.second == Custom_Message_Sub_Monents_Share) {
return [MessageContentMonentsView measureHeight:message];
} else {
return [MessageContentUnSupportView measureHeight:message];
}
}
- (UIView<MessageContentProtocol> *)getCustomMessageContentView:(NIMMessage *)message {
NIMCustomObject *obj = (NIMCustomObject *)message.messageObject;
AttachmentModel *attachment = (AttachmentModel *)obj.attachment;
if (attachment.first == CustomMessageType_Gift && attachment.second == Custom_Message_Sub_Gift_Send) {
if ([self.messageContent isKindOfClass:[MessageContentGiftView class]]) {
return self.messageContent;
}
return [[MessageContentGiftView alloc] init];
} else if(attachment.first == CustomMessageType_Secretary && attachment.second == Custom_Message_Sub_Secretary_Router) {
if ([self.messageContent isKindOfClass:[MessageContentTextClickable class]]) {
return self.messageContent;
}
return [[MessageContentTextClickable alloc] init];
} else if(attachment.first == CustomMessageType_Hall) {
if ([self.messageContent isKindOfClass:[MessageContentTextClickable class]]) {
return self.messageContent;
}
MessageContentGuildView * hallView =[[MessageContentGuildView alloc] init];
hallView.delegate = self;
return hallView;
} else if(attachment.first == CustomMessageType_Member_Online && attachment.second == Custom_Message_Type_Attention_Member_Online) {
if ([self.messageContent isKindOfClass:[MessageContentOpenLiveView class]]) {
return self.messageContent;
}
return [[MessageContentOpenLiveView alloc] init];
} else if(attachment.first == CustomMessageType_Application_Share && attachment.second == Custom_Message_Sub_Application_Share_Room) {
if ([self.messageContent isKindOfClass:[MessageContentApplicationShareView class]]) {
return self.messageContent;
}
return [[MessageContentApplicationShareView alloc] init];
}else if(attachment.first == CustomMessageType_User_UpGrade && (attachment.second == Custom_Message_Sub_User_UpGrade_Charm || attachment.second == Custom_Message_Sub_User_UpGrade_Exper)) {
if ([self.messageContent isKindOfClass:[MessageContentLevelUpgradeView class]]) {
return self.messageContent;
}
return [[MessageContentLevelUpgradeView alloc] init];
}else if(attachment.first == CustomMessageType_Tweet && attachment.second == Custom_Message_Sub_Tweet_News) {
if ([self.messageContent isKindOfClass:[MessageContentTweetView class]]) {
return self.messageContent;
}
return [[MessageContentTweetView alloc] init];
} else if(attachment.first == CustomMessageType_Skill_Card) {
if ([self.messageContent isKindOfClass:[MessageContentSkillCardView class]]) {
return self.messageContent;
}
return [[MessageContentSkillCardView alloc] init];
}else if(attachment.first == CustomMessageType_FindNew) {
if ([self.messageContent isKindOfClass:[MessageContentFindNewGreetView class]]) {
return self.messageContent;
}
return [[MessageContentFindNewGreetView alloc] init];
} else if(attachment.first == CustomMessageType_Chat_Risk_Alert) {
if ([self.messageContent isKindOfClass:[MessageContentRiskAlertView class]]) {
return self.messageContent;
}
return [[MessageContentRiskAlertView alloc] init];
}else if(attachment.first == CustomMessageType_Monents && attachment.second == Custom_Message_Sub_Monents_Share) {
if ([self.messageContent isKindOfClass:[MessageContentMonentsView class]]) {
return self.messageContent;
}
return [[MessageContentMonentsView alloc] init];
}else {
if ([self.messageContent isKindOfClass:[MessageContentUnSupportView class]]) {
return self.messageContent;
}
return [[MessageContentUnSupportView alloc] init];
}
}
#pragma mark - MessageContentCustomViewDelegate
- (void)updateMessageSuccess:(NIMMessage *)message {
if (self.delegate && [self.delegate respondsToSelector:@selector(updateMessageSuccess:)]) {
[self.delegate updateMessageSuccess:message];
}
}
#pragma mark - Event Response
- (void)rightAvatarTapRecognizer {
if (self.delegate && [self.delegate respondsToSelector:@selector(didTapAvatar:)]) {
[self.delegate didTapAvatar:self.currentMessage.from];
}
}
- (void)leftAvatarTapRecognizer {
if (self.delegate && [self.delegate respondsToSelector:@selector(didTapAvatar:)]) {
[self.delegate didTapAvatar:self.currentMessage.from];
}
}
- (void)failButtonAction:(UIButton *)sender {
if (self.delegate && [self.delegate respondsToSelector:@selector(didFailRetry:)]) {
[self.delegate didFailRetry:self.currentMessage];
}
}
#pragma mark - Getters And Setters
- (NetImageView *)leftAvatar {
if (!_leftAvatar) {
NetImageConfig * config = [[NetImageConfig alloc] init];
config.placeHolder = [UIImageConstant defaultAvatarPlaceholder];
config.radius = MAXFLOAT;
config.imageType = ImageTypeUserIcon;
_leftAvatar = [[NetImageView alloc] initWithConfig:config];
_leftAvatar.layer.masksToBounds = YES;
_leftAvatar.layer.cornerRadius = 45.f / 2;
_leftAvatar.hidden = YES;
_leftAvatar.userInteractionEnabled = YES;
UITapGestureRecognizer * tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(leftAvatarTapRecognizer)];
[_leftAvatar addGestureRecognizer:tap];
}
return _leftAvatar;
}
- (NetImageView *)rightAvatar {
if (!_rightAvatar) {
NetImageConfig * config = [[NetImageConfig alloc] init];
config.placeHolder = [UIImageConstant defaultAvatarPlaceholder];
config.radius = MAXFLOAT;
config.imageType = ImageTypeUserIcon;
_rightAvatar = [[NetImageView alloc] initWithConfig:config];
_rightAvatar.layer.masksToBounds = YES;
_rightAvatar.layer.cornerRadius = 45.f / 2;
_rightAvatar.hidden = YES;
_rightAvatar.userInteractionEnabled = YES;
UITapGestureRecognizer * tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(rightAvatarTapRecognizer)];
[_rightAvatar addGestureRecognizer:tap];
}
return _rightAvatar;
}
- (UIView *)messageBackground {
if (!_messageBackground) {
_messageBackground = [[UIView alloc]init];
_messageBackground.backgroundColor = [ThemeColor appCellBackgroundColor];
_messageBackground.layer.masksToBounds = YES;
_messageBackground.layer.cornerRadius = 8.f;
}
return _messageBackground;
}
- (UIButton *)failButton {
if (!_failButton) {
_failButton = [UIButton buttonWithType:UIButtonTypeCustom];
[_failButton setImage:[UIImage imageNamed:@"message_session_download_fail"] forState:UIControlStateNormal];
[_failButton setImage:[UIImage imageNamed:@"message_session_download_fail"] forState:UIControlStateSelected];
[_failButton addTarget:self action:@selector(failButtonAction:) forControlEvents:UIControlEventTouchUpInside];
_failButton.hidden = YES;
}
return _failButton;
}
@end