diff --git a/xplan-ios.xcodeproj/project.pbxproj b/xplan-ios.xcodeproj/project.pbxproj index e4ee4157..c34e2c6a 100644 --- a/xplan-ios.xcodeproj/project.pbxproj +++ b/xplan-ios.xcodeproj/project.pbxproj @@ -138,8 +138,7 @@ E82EE0F8272FDDFA00D15DC1 /* UserPrivacyView.m in Sources */ = {isa = PBXBuildFile; fileRef = E82EE0F7272FDDFA00D15DC1 /* UserPrivacyView.m */; }; E84B0E3F2727EDF6008818C6 /* XPRoomMessageTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = E84B0E3E2727EDF6008818C6 /* XPRoomMessageTableViewCell.m */; }; E84B0E422727EE0A008818C6 /* XPRoomMessageHeaderView.m in Sources */ = {isa = PBXBuildFile; fileRef = E84B0E412727EE0A008818C6 /* XPRoomMessageHeaderView.m */; }; - E84B0E462727EF9D008818C6 /* XPRoomMessageDisplayModel.m in Sources */ = {isa = PBXBuildFile; fileRef = E84B0E452727EF9D008818C6 /* XPRoomMessageDisplayModel.m */; }; - E84B0E4C27281530008818C6 /* XPRoomMessageAttributeHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = E84B0E4B27281530008818C6 /* XPRoomMessageAttributeHelper.m */; }; + E84B0E462727EF9D008818C6 /* XPRoomMessageParser.m in Sources */ = {isa = PBXBuildFile; fileRef = E84B0E452727EF9D008818C6 /* XPRoomMessageParser.m */; }; E865963F27015A9C00846EBD /* XPMineUserTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = E865963E27015A9C00846EBD /* XPMineUserTableView.m */; }; E86596432701611A00846EBD /* UIImage+ImageEffects.m in Sources */ = {isa = PBXBuildFile; fileRef = E86596412701611A00846EBD /* UIImage+ImageEffects.m */; }; E86596512701A1C000846EBD /* StatisticsService.m in Sources */ = {isa = PBXBuildFile; fileRef = E86596502701A1C000846EBD /* StatisticsService.m */; }; @@ -494,11 +493,9 @@ E84B0E3E2727EDF6008818C6 /* XPRoomMessageTableViewCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XPRoomMessageTableViewCell.m; sourceTree = ""; }; E84B0E402727EE0A008818C6 /* XPRoomMessageHeaderView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XPRoomMessageHeaderView.h; sourceTree = ""; }; E84B0E412727EE0A008818C6 /* XPRoomMessageHeaderView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XPRoomMessageHeaderView.m; sourceTree = ""; }; - E84B0E442727EF9D008818C6 /* XPRoomMessageDisplayModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XPRoomMessageDisplayModel.h; sourceTree = ""; }; - E84B0E452727EF9D008818C6 /* XPRoomMessageDisplayModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XPRoomMessageDisplayModel.m; sourceTree = ""; }; + E84B0E442727EF9D008818C6 /* XPRoomMessageParser.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XPRoomMessageParser.h; sourceTree = ""; }; + E84B0E452727EF9D008818C6 /* XPRoomMessageParser.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XPRoomMessageParser.m; sourceTree = ""; }; E84B0E4927280289008818C6 /* XPRoomMessageConstant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XPRoomMessageConstant.h; sourceTree = ""; }; - E84B0E4A27281530008818C6 /* XPRoomMessageAttributeHelper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XPRoomMessageAttributeHelper.h; sourceTree = ""; }; - E84B0E4B27281530008818C6 /* XPRoomMessageAttributeHelper.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XPRoomMessageAttributeHelper.m; sourceTree = ""; }; E865963D27015A9C00846EBD /* XPMineUserTableView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XPMineUserTableView.h; sourceTree = ""; }; E865963E27015A9C00846EBD /* XPMineUserTableView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XPMineUserTableView.m; sourceTree = ""; }; E86596412701611A00846EBD /* UIImage+ImageEffects.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImage+ImageEffects.m"; sourceTree = ""; }; @@ -1363,8 +1360,6 @@ E84B0E432727EF2C008818C6 /* Model */ = { isa = PBXGroup; children = ( - E84B0E442727EF9D008818C6 /* XPRoomMessageDisplayModel.h */, - E84B0E452727EF9D008818C6 /* XPRoomMessageDisplayModel.m */, E87A24EF272935920086A794 /* XPMessageRemoteExtModel.h */, E87A24F0272935920086A794 /* XPMessageRemoteExtModel.m */, ); @@ -1375,8 +1370,8 @@ isa = PBXGroup; children = ( E84B0E4927280289008818C6 /* XPRoomMessageConstant.h */, - E84B0E4A27281530008818C6 /* XPRoomMessageAttributeHelper.h */, - E84B0E4B27281530008818C6 /* XPRoomMessageAttributeHelper.m */, + E84B0E442727EF9D008818C6 /* XPRoomMessageParser.h */, + E84B0E452727EF9D008818C6 /* XPRoomMessageParser.m */, ); path = Tool; sourceTree = ""; @@ -2037,7 +2032,6 @@ E81C279826EB3AC40031E639 /* LoginForgetPasswordProtocol.h in Sources */, E82109B026F1D83500FC3319 /* LoginBindPhonePresent.m in Sources */, E865963F27015A9C00846EBD /* XPMineUserTableView.m in Sources */, - E84B0E4C27281530008818C6 /* XPRoomMessageAttributeHelper.m in Sources */, E8B825C726EA0D9A009E8E9F /* LoginVerifCodeProtocol.h in Sources */, E824544E26F5BC1A00BE8163 /* XPMineModifPayPwdView.m in Sources */, E8B825CA26EA1231009E8E9F /* LoginVerifCodeViewController.m in Sources */, @@ -2195,7 +2189,7 @@ E8B846DC26FDE24300A777FE /* RechargeListModel.m in Sources */, 189DD75926E6003C00AB55B1 /* Api.m in Sources */, E88B5CB826FB325200DA9178 /* XPMineTeenagerPwdPresenter.m in Sources */, - E84B0E462727EF9D008818C6 /* XPRoomMessageDisplayModel.m in Sources */, + E84B0E462727EF9D008818C6 /* XPRoomMessageParser.m in Sources */, E874B88827215D39003954B9 /* MicroStateModel.m in Sources */, E89D60C1271D64B9001F8895 /* RoomInfoModel.m in Sources */, E89DA66727006443008483C1 /* RechargeStorage.m in Sources */, diff --git a/xplan-ios/Main/Room/View/MessageContainerView/Model/XPRoomMessageDisplayModel.h b/xplan-ios/Main/Room/View/MessageContainerView/Model/XPRoomMessageDisplayModel.h deleted file mode 100644 index bb05b94a..00000000 --- a/xplan-ios/Main/Room/View/MessageContainerView/Model/XPRoomMessageDisplayModel.h +++ /dev/null @@ -1,28 +0,0 @@ -// -// XPRoomMessageDisplayModel.h -// xplan-ios -// -// Created by 冯硕 on 2021/10/26. -// - -#import -#import -NS_ASSUME_NONNULL_BEGIN - -@class XPRoomMessageDisplayModel; - -@interface XPRoomMessageDisplayModel : NSObject -///消息实体 -@property (nonatomic,strong, readonly) NIMMessage *message; -///索要展示的cell的高度 -@property (nonatomic,assign, readonly) CGFloat cellHeight; -///所要展示的富文本 -@property (nonatomic,strong, readonly) NSMutableAttributedString *contentAttribute; -///选择了某个item -@property (nonatomic,copy) void(^didSelectItem)(NSString * uid); - -- (instancetype)initDisplayModel:(NIMMessage *)message; - -@end - -NS_ASSUME_NONNULL_END diff --git a/xplan-ios/Main/Room/View/MessageContainerView/Model/XPRoomMessageDisplayModel.m b/xplan-ios/Main/Room/View/MessageContainerView/Model/XPRoomMessageDisplayModel.m deleted file mode 100644 index 40a2ea18..00000000 --- a/xplan-ios/Main/Room/View/MessageContainerView/Model/XPRoomMessageDisplayModel.m +++ /dev/null @@ -1,126 +0,0 @@ -// -// XPRoomMessageDisplayModel.m -// xplan-ios -// -// Created by 冯硕 on 2021/10/26. -// - -#import "XPRoomMessageDisplayModel.h" -#import -///Tool -#import "ThemeColor+Room.h" -#import "XPRoomMessageConstant.h" -#import "AccountInfoStorage.h" -#import "XPRoomMessageAttributeHelper.h" -#import "XPMacro.h" -///Model -#import "XPMessageRemoteExtModel.h" - -@interface XPRoomMessageDisplayModel () -/// -@property (nonatomic,strong) NIMMessage *message; -///索要展示的cell的高度 -@property (nonatomic,assign) CGFloat cellHeight; -/// -@property (nonatomic,strong) NSMutableAttributedString *contentAttribute; -@end - -@implementation XPRoomMessageDisplayModel - -- (instancetype)initDisplayModel:(NIMMessage *)message { - if (self = [super init]) { - self.message = message; - [self makeMessageAttribute:message]; - } - return self; -} - -- (void)makeMessageAttribute:(NIMMessage *)message { - NIMMessageType messageType = message.messageType; - switch (messageType) { - case NIMMessageTypeText: - [self makeTextAttribute:message]; - break; - case NIMMessageTypeTip: - [self makeTipsAttribute:message]; - break; - case NIMMessageTypeNotification: - [self makeNotificationAttribute:message]; - break; - default: - break; - } -} - - -/// 房间文本类消息 -/// @param message 消息的实体 -- (void)makeTextAttribute:(NIMMessage *)message{ - NSString * uid = [AccountInfoStorage instance].getUid; - XPMessageRemoteExtModel * model = [XPMessageRemoteExtModel modelWithJSON:message.remoteExt[message.from]]; - NSString * nick = [NSString stringWithFormat:@"%@:", ((NIMMessageChatroomExtension *)message.messageExt).roomNickname]; - if ([message.from isEqualToString:uid]) { - nick = @"我:"; - } - @kWeakify(self); - self.contentAttribute = [XPRoomMessageAttributeHelper createLevelTextAttribute:model nick:nick text:message.text]; - - [self.contentAttribute yy_setTextHighlightRange:NSMakeRange(0, self.contentAttribute.length) color:nil backgroundColor:nil tapAction:^(UIView * _Nonnull containerView, NSAttributedString * _Nonnull text, NSRange range, CGRect rect) { - @kStrongify(self); - if (self.didSelectItem) { - self.didSelectItem(message.from); - } - - }]; -} - -/// 房间tips消息 -/// @param message 消息的实体 -- (void)makeTipsAttribute:(NIMMessage *)message { - self.contentAttribute = [XPRoomMessageAttributeHelper createTextAttribute:message.text titleColor:[ThemeColor messageDefaultTextColor] font:kRoomMessageDefalutFont]; -} - -/// 房间通知类消息 -/// @param message 消息的实体 -- (void)makeNotificationAttribute:(NIMMessage *)message { - NIMNotificationObject *notiMsg = (NIMNotificationObject *)message.messageObject; - NIMChatroomNotificationContent *content = (NIMChatroomNotificationContent *)notiMsg.content; - NIMChatroomNotificationMember *member = content.targets[0]; - switch (content.eventType) { - case NIMChatroomEventTypeEnter:///进入房间 - { - self.contentAttribute = [XPRoomMessageAttributeHelper createUserEnterRoomAttribute:member.nick]; - @kWeakify(self); - [self.contentAttribute yy_setTextHighlightRange:NSMakeRange(0, self.contentAttribute.length) color:nil backgroundColor:nil tapAction:^(UIView * _Nonnull containerView, NSAttributedString * _Nonnull text, NSRange range, CGRect rect) { - @kStrongify(self); - if (self.didSelectItem) { - self.didSelectItem(message.from); - } - }]; - } - break; - case NIMChatroomEventTypeInfoUpdated:///房间信息更新 - [self createRoomInfoUpdateAttribute:content.notifyExt]; - break; - default: - break; - } -} - -///房间信息更新 -- (void)createRoomInfoUpdateAttribute:(NSString *)notifyExt { - -} - -#pragma mark - Getters And Setters -- (void)setContentAttribute:(NSMutableAttributedString *)contentAttributed { - _contentAttribute = contentAttributed; - if (_contentAttribute.length > 0) { - CGSize maxSize = CGSizeMake(kRoomMessageMaxWidth, MAXFLOAT); - YYTextLayout *layout = [YYTextLayout layoutWithContainerSize:maxSize text:_contentAttribute]; - self.cellHeight = layout.textBoundingSize.height + kRoomMessageTextSpaceHeight * 2 + 10; - } -} - -#pragma mark - Tool -@end diff --git a/xplan-ios/Main/Room/View/MessageContainerView/Tool/XPRoomMessageAttributeHelper.h b/xplan-ios/Main/Room/View/MessageContainerView/Tool/XPRoomMessageAttributeHelper.h deleted file mode 100644 index 0d27905f..00000000 --- a/xplan-ios/Main/Room/View/MessageContainerView/Tool/XPRoomMessageAttributeHelper.h +++ /dev/null @@ -1,41 +0,0 @@ -// -// XPRoomMessageHelper.h -// xplan-ios -// -// Created by 冯硕 on 2021/10/26. -// - -#import - -NS_ASSUME_NONNULL_BEGIN - -@class XPMessageRemoteExtModel; -@interface XPRoomMessageAttributeHelper : NSObject -#pragma mark - 生成某个消息类型的富文本 -/// 文本类的消息的富文本 NIMMessageTypeText -/// @param remoteModel 扩展字段中的内容 -/// @param nick 名字 -+ (NSMutableAttributedString *)createLevelTextAttribute:(XPMessageRemoteExtModel *)remoteModel nick:(NSString *)nick text:(NSString *)text; - -/// 进入房间的富文本 NIMChatroomEventTypeEnter -/// @param nick 进入房间的名称 -+ (NSMutableAttributedString *)createUserEnterRoomAttribute:(NSString *)nick; -#pragma mark - 工具类 富文本 -/// 生成一个图片的富文本 -/// @param imageUrl 网络图片的地址 -/// @param size 网络图片的大小 -+ (NSMutableAttributedString *)createUrlImageAttribute:(NSString *)imageUrl size:(CGSize)size; - -/// 生成本地一个图片的富文本 -/// @param imageName 网络图片的地址 -/// @param size 网络图片的大小 -+ (NSMutableAttributedString *)createLocalImageAttribute:(NSString *)imageName size:(CGSize)size; - -/// 生成一个富文本 -/// @param text 富文本的文字 -/// @param titleColor 文字的颜色 -/// @param font 文字的大小 -+ (NSMutableAttributedString *)createTextAttribute:(NSString *)text titleColor:(UIColor *)titleColor font:(CGFloat)font; -@end - -NS_ASSUME_NONNULL_END diff --git a/xplan-ios/Main/Room/View/MessageContainerView/Tool/XPRoomMessageAttributeHelper.m b/xplan-ios/Main/Room/View/MessageContainerView/Tool/XPRoomMessageAttributeHelper.m deleted file mode 100644 index 69a2dea7..00000000 --- a/xplan-ios/Main/Room/View/MessageContainerView/Tool/XPRoomMessageAttributeHelper.m +++ /dev/null @@ -1,147 +0,0 @@ -// -// XPRoomMessageHelper.m -// xplan-ios -// -// Created by 冯硕 on 1621/10/26. -// - -#import "XPRoomMessageAttributeHelper.h" -///Third -#import -#import -///Model -#import "XPMessageRemoteExtModel.h" -#import "ThemeColor+Room.h" -#import "XPRoomMessageConstant.h" - -#import "NetImageView.h" - -@implementation XPRoomMessageAttributeHelper - -/// 文本类的消息的富文本 -/// @param remoteModel 扩展字段中的内容 -/// @param nick 名字 -+ (NSMutableAttributedString *)createLevelTextAttribute:(XPMessageRemoteExtModel *)remoteModel nick:(NSString *)nick text:(NSString *)text { - NSMutableAttributedString * attribute = [[NSMutableAttributedString alloc] init]; - if (remoteModel.defUser == UserLevelType_Offical) { - NSMutableAttributedString * offcialAttribute = [self createLocalImageAttribute:@"common_offical" size:CGSizeMake(13, 13)]; - [attribute appendAttributedString:offcialAttribute]; - [attribute appendAttributedString:[self createSapceAttribute:2]]; - } - - if (remoteModel.newUser) { - NSMutableAttributedString * newUserAttribute = [self createLocalImageAttribute:@"common_new_user" size:CGSizeMake(13, 13)]; - [attribute appendAttributedString:newUserAttribute]; - [attribute appendAttributedString:[self createSapceAttribute:2]]; - } - - if (remoteModel.experUrl) { - NSMutableAttributedString * experAttribute = [self createUrlImageAttribute:remoteModel.experUrl size:CGSizeMake(25, 16)]; - [attribute appendAttributedString:experAttribute]; - [attribute appendAttributedString:[self createSapceAttribute:2]]; - } - - NSMutableAttributedString * nickAttribute = [self createTextAttribute:nick titleColor:[ThemeColor messageDefaultTextColor] font:kRoomMessageDefalutFont]; - [attribute appendAttributedString:nickAttribute]; - [attribute appendAttributedString:[self createSapceAttribute:2]]; - - NSMutableAttributedString * textAttribute = [self createTextAttribute:text titleColor:[ThemeColor messageTextColor] font:kRoomMessageDefalutFont]; - [attribute appendAttributedString:textAttribute]; - return attribute; -} - - -/// 进入房间的富文本 NIMChatroomEventTypeEnter -/// @param nick 进入房间的名称 -+ (NSMutableAttributedString *)createUserEnterRoomAttribute:(NSString *)nick { - nick = nick.length > 0 ? nick : @""; - NSMutableAttributedString * attribute = [[NSMutableAttributedString alloc] init]; - NSMutableAttributedString * nickAttribute = [self createTextAttribute:nick titleColor:[ThemeColor messageNickColor] font:kRoomMessageDefalutFont]; - NSMutableAttributedString * enterRoomAttribute = [self createTextAttribute:@"进入了房间" titleColor:[ThemeColor messageDefaultTextColor] font:kRoomMessageDefalutFont]; - [attribute appendAttributedString:nickAttribute]; - [attribute appendAttributedString:enterRoomAttribute]; - - return attribute; -} - - -#pragma mark - 富文本的基础工具方法 - -/// 生成一个图片的富文本 -/// @param imageUrl 网络图片的地址 -/// @param size 网络图片的大小 -+ (NSMutableAttributedString *)createUrlImageAttribute:(NSString *)imageUrl size:(CGSize)size { - NetImageView *imageView = [[NetImageView alloc]init]; - imageView.imageUrl = imageUrl; - - UIImage* image = imageView.image; - if (image) { - CGFloat scale = image.size.width / image.size.height; - imageView.bounds = CGRectMake(0, 0, 16 * scale, 16); - } else { - imageView.bounds = CGRectMake(0, 0, 16, 16); - } - imageView.layer.masksToBounds = YES; - imageView.contentMode = UIViewContentModeScaleAspectFill; - NSMutableAttributedString * genderString = [NSMutableAttributedString yy_attachmentStringWithContent:imageView contentMode:UIViewContentModeScaleAspectFit attachmentSize:CGSizeMake(imageView.frame.size.width, imageView.frame.size.height) alignToFont:[UIFont systemFontOfSize:15.0] alignment:YYTextVerticalAlignmentCenter]; - return genderString; -} - -/// 生成本地一个图片的富文本 -/// @param imageName 网络图片的地址 -/// @param size 网络图片的大小 -+ (NSMutableAttributedString *)createLocalImageAttribute:(NSString *)imageName size:(CGSize)size { - UIImageView *genderImageView = [[UIImageView alloc]init]; - genderImageView.image = [UIImage imageNamed:imageName]; - CGFloat kscale = (CGFloat)genderImageView.image.size.width / (CGFloat)genderImageView.image.size.height; - genderImageView.bounds = CGRectMake(0, 0, 16 * kscale, 16); - NSMutableAttributedString * genderString = [NSMutableAttributedString yy_attachmentStringWithContent:genderImageView contentMode:UIViewContentModeScaleAspectFit attachmentSize:CGSizeMake(genderImageView.frame.size.width, genderImageView.frame.size.height) alignToFont:[UIFont systemFontOfSize:15.0] alignment:YYTextVerticalAlignmentCenter]; - return genderString; -} - -/// 生成本地一个图片的富文本 -/// @param image 本地的图片 -/// @param size 本地图片的大小 -+ (NSMutableAttributedString *)createImageAttribute:(UIImage *)image size:(CGSize)size { - UIImageView *genderImageView = [[UIImageView alloc]init]; - genderImageView.image = image; - CGFloat kscale = (CGFloat)genderImageView.image.size.width / (CGFloat)genderImageView.image.size.height; - genderImageView.bounds = CGRectMake(0, 0, 16 * kscale,16); - NSMutableAttributedString * genderString = [NSMutableAttributedString yy_attachmentStringWithContent:genderImageView contentMode:UIViewContentModeScaleAspectFit attachmentSize:CGSizeMake(genderImageView.frame.size.width, genderImageView.frame.size.height) alignToFont:[UIFont systemFontOfSize:15.0] alignment:YYTextVerticalAlignmentCenter]; - return genderString; -} - -/// 生成一个富文本 -/// @param text 富文本的文字 -/// @param titleColor 文字的颜色 -/// @param font 文字的大小 -+ (NSMutableAttributedString *)createTextAttribute:(NSString *)text titleColor:(UIColor *)titleColor font:(CGFloat)font { - NSMutableAttributedString *attribute = [[NSMutableAttributedString alloc] initWithString:text attributes:nil]; - attribute.yy_font = [UIFont systemFontOfSize:font]; - attribute.yy_color = titleColor; - attribute.yy_paragraphStyle = [self paragraphStyle]; - return attribute; -} - -/// 设置文本的样式 间隙 缩进 ... -+ (NSMutableParagraphStyle *)paragraphStyle { - NSMutableParagraphStyle *paraStyle = [[NSMutableParagraphStyle alloc] init]; - paraStyle.lineSpacing = 4.0f;//行间距 - // 强制排版(从左到右) - paraStyle.alignment = NSTextAlignmentLeft; - paraStyle.baseWritingDirection = NSWritingDirectionLeftToRight; - - return paraStyle; -} - -/// 占位的富文本 -/// @param width 需要的间隙 -+ (NSMutableAttributedString *)createSapceAttribute:(CGFloat)width { - UIView *spaceView = [[UIView alloc]init]; - spaceView.backgroundColor = [UIColor clearColor]; - spaceView.bounds = CGRectMake(0, 0, width,10); - NSMutableAttributedString * genderString = [NSMutableAttributedString yy_attachmentStringWithContent:spaceView contentMode:UIViewContentModeScaleAspectFit attachmentSize:CGSizeMake(spaceView.frame.size.width, spaceView.frame.size.height) alignToFont:[UIFont systemFontOfSize:15.0] alignment:YYTextVerticalAlignmentCenter]; - return genderString; -} - -@end diff --git a/xplan-ios/Main/Room/View/MessageContainerView/Tool/XPRoomMessageConstant.h b/xplan-ios/Main/Room/View/MessageContainerView/Tool/XPRoomMessageConstant.h index 5f02e8b3..a9c16d15 100644 --- a/xplan-ios/Main/Room/View/MessageContainerView/Tool/XPRoomMessageConstant.h +++ b/xplan-ios/Main/Room/View/MessageContainerView/Tool/XPRoomMessageConstant.h @@ -19,7 +19,7 @@ static CGFloat kRoomMessageTextSpaceHeight = 10; static CGFloat kRoomMessageBubbleCornerRadius = 7; ///公屏保存的最大数 -static CGFloat kRoomMessageMaxLength = 1000; +static NSInteger kRoomMessageMaxLength = 1000; #endif /* XPRoomMessageConstant_h */ diff --git a/xplan-ios/Main/Room/View/MessageContainerView/Tool/XPRoomMessageParser.h b/xplan-ios/Main/Room/View/MessageContainerView/Tool/XPRoomMessageParser.h new file mode 100644 index 00000000..3f3cba80 --- /dev/null +++ b/xplan-ios/Main/Room/View/MessageContainerView/Tool/XPRoomMessageParser.h @@ -0,0 +1,20 @@ +// +// XPRoomMessageParser.h +// xplan-ios +// +// Created by 冯硕 on 2021/10/26. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@class NIMMessage; + +@interface XPRoomMessageParser : NSObject + ++ (NSAttributedString*)parseMessageAttribute:(NIMMessage *)message; + +@end + +NS_ASSUME_NONNULL_END diff --git a/xplan-ios/Main/Room/View/MessageContainerView/Tool/XPRoomMessageParser.m b/xplan-ios/Main/Room/View/MessageContainerView/Tool/XPRoomMessageParser.m new file mode 100644 index 00000000..b6ba0f63 --- /dev/null +++ b/xplan-ios/Main/Room/View/MessageContainerView/Tool/XPRoomMessageParser.m @@ -0,0 +1,185 @@ +// +// XPRoomMessageParser.m +// xplan-ios +// +// Created by 冯硕 on 2021/10/26. +// + +#import "XPRoomMessageParser.h" +#import +#import +///Tool +#import "ThemeColor+Room.h" +#import "XPRoomMessageConstant.h" +#import "AccountInfoStorage.h" +#import "XPMacro.h" +///Model +#import "XPMessageRemoteExtModel.h" + +#import "NetImageView.h" + +@implementation XPRoomMessageParser + ++ (NSAttributedString*)parseMessageAttribute:(NIMMessage *)message { + NIMMessageType messageType = message.messageType; + switch (messageType) { + case NIMMessageTypeText: + return [self makeChatAttribute:message]; + + case NIMMessageTypeTip: + return [self makeTipsAttribute:message]; + + case NIMMessageTypeNotification: + return [self makeNotificationAttribute:message]; + default: + return nil; + } +} + +/// 用户公屏聊天 +/// @param message 消息的实体 ++ (NSAttributedString*)makeChatAttribute:(NIMMessage *)message{ + NSString * uid = [AccountInfoStorage instance].getUid; + XPMessageRemoteExtModel * model = [XPMessageRemoteExtModel modelWithJSON:message.remoteExt[message.from]]; + NSString * nick = [NSString stringWithFormat:@"%@:", ((NIMMessageChatroomExtension *)message.messageExt).roomNickname]; + if ([message.from isEqualToString:uid]) { + nick = @"我:"; + } + + NSMutableAttributedString * attribute = [[NSMutableAttributedString alloc] init]; + if (model.defUser == UserLevelType_Offical) { + NSMutableAttributedString * offcialAttribute = [self createLocalImageAttribute:@"common_offical"]; + [attribute appendAttributedString:offcialAttribute]; + [attribute appendAttributedString:[self createSapceAttribute:2]]; + } + + if (model.newUser) { + NSMutableAttributedString * newUserAttribute = [self createLocalImageAttribute:@"common_new_user"]; + [attribute appendAttributedString:newUserAttribute]; + [attribute appendAttributedString:[self createSapceAttribute:2]]; + } + + if (model.experUrl) { + NSMutableAttributedString * experAttribute = [self createUrlImageAttribute:model.experUrl]; + [attribute appendAttributedString:experAttribute]; + [attribute appendAttributedString:[self createSapceAttribute:2]]; + } + + NSMutableAttributedString * nickAttribute = [self createTextAttribute:nick color:[ThemeColor messageDefaultTextColor] font:kRoomMessageDefalutFont]; + [attribute appendAttributedString:nickAttribute]; + [attribute appendAttributedString:[self createSapceAttribute:2]]; + + NSMutableAttributedString * textAttribute = [self createTextAttribute:message.text color:[ThemeColor messageTextColor] font:kRoomMessageDefalutFont]; + [attribute appendAttributedString:textAttribute]; + + return attribute; +} + +/// 房间tips消息 +/// @param message 消息的实体 ++ (NSAttributedString*)makeTipsAttribute:(NIMMessage *)message { + return [self createTextAttribute:message.text color:[ThemeColor messageDefaultTextColor] font:kRoomMessageDefalutFont]; +} + +/// 房间通知类消息 +/// @param message 消息的实体 ++ (NSAttributedString*)makeNotificationAttribute:(NIMMessage *)message { + NIMNotificationObject *notiMsg = (NIMNotificationObject *)message.messageObject; + NIMChatroomNotificationContent *content = (NIMChatroomNotificationContent *)notiMsg.content; + NIMChatroomNotificationMember *member = content.targets[0]; + switch (content.eventType) { + case NIMChatroomEventTypeEnter:///进入房间 + { + NSString* nick = member.nick.length > 0 ? member.nick : @""; + NSMutableAttributedString * attribute = [[NSMutableAttributedString alloc] init]; + NSMutableAttributedString * nickAttribute = [self createTextAttribute:nick color:[ThemeColor messageNickColor] font:kRoomMessageDefalutFont]; + NSMutableAttributedString * enterRoomAttribute = [self createTextAttribute:@"进入了房间" color:[ThemeColor messageDefaultTextColor] font:kRoomMessageDefalutFont]; + [attribute appendAttributedString:nickAttribute]; + [attribute appendAttributedString:enterRoomAttribute]; + return attribute; + } + + case NIMChatroomEventTypeInfoUpdated:///房间信息更新 + return [self createRoomInfoUpdateAttribute:content.notifyExt]; + + default: + return nil; + } +} + +///房间信息更新 ++ (NSAttributedString*)createRoomInfoUpdateAttribute:(NSString *)notifyExt { + return nil; +} + +/// 生成一个图片的富文本 +/// @param imageUrl 网络图片的地址 ++ (NSMutableAttributedString *)createUrlImageAttribute:(NSString *)imageUrl { + NetImageView *imageView = [[NetImageView alloc]init]; + imageView.imageUrl = imageUrl; + + UIImage* image = imageView.image; + if (image) { + CGFloat scale = image.size.width / image.size.height; + imageView.bounds = CGRectMake(0, 0, 16 * scale, 16); + } else { + imageView.bounds = CGRectMake(0, 0, 16, 16); + } + imageView.layer.masksToBounds = YES; + imageView.contentMode = UIViewContentModeScaleAspectFill; + NSMutableAttributedString * attrString = [NSMutableAttributedString yy_attachmentStringWithContent:imageView contentMode:UIViewContentModeScaleAspectFit attachmentSize:CGSizeMake(imageView.bounds.size.width, imageView.bounds.size.height) alignToFont:[UIFont systemFontOfSize:15.0] alignment:YYTextVerticalAlignmentCenter]; + return attrString; +} + +#pragma mark - private base methods +/// 生成本地一个图片的富文本 +/// @param imageName 网络图片的地址 ++ (NSMutableAttributedString *)createLocalImageAttribute:(NSString *)imageName { + return [self createImageAttribute:[UIImage imageNamed:imageName]]; +} + +/// 生成本地一个图片的富文本 +/// @param image 本地的图片 ++ (NSMutableAttributedString *)createImageAttribute:(UIImage *)image { + UIImageView *imaveView = [[UIImageView alloc]init]; + imaveView.image = image; + CGFloat scale = (CGFloat)imaveView.image.size.width / (CGFloat)imaveView.image.size.height; + imaveView.bounds = CGRectMake(0, 0, 16 * scale, 16); + NSMutableAttributedString * attrString = [NSMutableAttributedString yy_attachmentStringWithContent:imaveView contentMode:UIViewContentModeScaleAspectFit attachmentSize:CGSizeMake(imaveView.frame.size.width, imaveView.frame.size.height) alignToFont:[UIFont systemFontOfSize:15.0] alignment:YYTextVerticalAlignmentCenter]; + return attrString; +} + +/// 生成一个富文本 +/// @param text 富文本的文字 +/// @param color 文字的颜色 +/// @param font 文字的大小 ++ (NSMutableAttributedString *)createTextAttribute:(NSString *)text color:(UIColor *)color font:(CGFloat)font { + NSMutableAttributedString *attribute = [[NSMutableAttributedString alloc] initWithString:text attributes:nil]; + attribute.yy_font = [UIFont systemFontOfSize:font]; + attribute.yy_color = color; + attribute.yy_paragraphStyle = [self paragraphStyle]; + return attribute; +} + +/// 设置文本的样式 间隙 缩进 ... ++ (NSMutableParagraphStyle *)paragraphStyle { + NSMutableParagraphStyle *paraStyle = [[NSMutableParagraphStyle alloc] init]; + paraStyle.lineSpacing = 4.0f;//行间距 + // 强制排版(从左到右) + paraStyle.alignment = NSTextAlignmentLeft; + paraStyle.baseWritingDirection = NSWritingDirectionLeftToRight; + + return paraStyle; +} + +/// 占位的富文本 +/// @param width 需要的间隙 ++ (NSMutableAttributedString *)createSapceAttribute:(CGFloat)width { + UIView *spaceView = [[UIView alloc]init]; + spaceView.backgroundColor = [UIColor clearColor]; + spaceView.bounds = CGRectMake(0, 0, width, 10); + NSMutableAttributedString * attribute = [NSMutableAttributedString yy_attachmentStringWithContent:spaceView contentMode:UIViewContentModeScaleAspectFit attachmentSize:CGSizeMake(spaceView.frame.size.width, spaceView.frame.size.height) alignToFont:[UIFont systemFontOfSize:15.0] alignment:YYTextVerticalAlignmentCenter]; + return attribute; +} + +@end diff --git a/xplan-ios/Main/Room/View/MessageContainerView/View/XPRoomMessageTableViewCell.h b/xplan-ios/Main/Room/View/MessageContainerView/View/XPRoomMessageTableViewCell.h index 0c60ad32..82e6cd92 100644 --- a/xplan-ios/Main/Room/View/MessageContainerView/View/XPRoomMessageTableViewCell.h +++ b/xplan-ios/Main/Room/View/MessageContainerView/View/XPRoomMessageTableViewCell.h @@ -11,11 +11,11 @@ NS_ASSUME_NONNULL_BEGIN -@class XPRoomMessageDisplayModel, YYLabel; +@class XPRoomMessageParser, YYLabel; @interface XPRoomMessageTableViewCell : UITableViewCell -@property (nonatomic,strong) XPRoomMessageDisplayModel *displayModel; +@property (nonatomic,strong) NSAttributedString *attributedString; @end diff --git a/xplan-ios/Main/Room/View/MessageContainerView/View/XPRoomMessageTableViewCell.m b/xplan-ios/Main/Room/View/MessageContainerView/View/XPRoomMessageTableViewCell.m index c5b6fead..8d6f0fbe 100644 --- a/xplan-ios/Main/Room/View/MessageContainerView/View/XPRoomMessageTableViewCell.m +++ b/xplan-ios/Main/Room/View/MessageContainerView/View/XPRoomMessageTableViewCell.m @@ -12,10 +12,9 @@ ///Tool #import "XPMacro.h" #import "ThemeColor+Room.h" -#import "XPRoomMessageConstant.h" #import "UIImage+Utils.h" -///Model -#import "XPRoomMessageDisplayModel.h" + +#import "XPRoomMessageConstant.h" @interface XPRoomMessageTableViewCell () ///气泡 @@ -56,13 +55,9 @@ } #pragma mark - Getters And Setters -- (void)setDisplayModel:(XPRoomMessageDisplayModel *)displayModel { - _displayModel = displayModel; - self.contentLabel.attributedText = displayModel.contentAttribute; - displayModel.didSelectItem = ^(NSString * _Nonnull uid) { - /// TODO : 展示用户卡片 - NSLog(@"%@", uid); - }; +- (void)setAttributedString:(NSAttributedString *)attribute { + _attributedString = attribute; + self.contentLabel.attributedText = attribute; } - (UIImageView *)bubbleImageView { @@ -79,7 +74,7 @@ - (XPNetImageYYLabel *)contentLabel { if (!_contentLabel) { _contentLabel = [[XPNetImageYYLabel alloc] init]; - _contentLabel.preferredMaxLayoutWidth = kRoomMessageMaxWidth - 10; + _contentLabel.preferredMaxLayoutWidth = kRoomMessageMaxWidth - 10; _contentLabel.numberOfLines = 0; } return _contentLabel; diff --git a/xplan-ios/Main/Room/View/MessageContainerView/XPRoomMessageContainerView.h b/xplan-ios/Main/Room/View/MessageContainerView/XPRoomMessageContainerView.h index e2cadcf8..7cf79411 100644 --- a/xplan-ios/Main/Room/View/MessageContainerView/XPRoomMessageContainerView.h +++ b/xplan-ios/Main/Room/View/MessageContainerView/XPRoomMessageContainerView.h @@ -9,7 +9,7 @@ #import "RoomHostDelegate.h" NS_ASSUME_NONNULL_BEGIN -@interface XPRoomMessageContainerView : UIView +@interface XPRoomMessageContainerView : UIView - (instancetype)initWithDelegate:(id)delegate; diff --git a/xplan-ios/Main/Room/View/MessageContainerView/XPRoomMessageContainerView.m b/xplan-ios/Main/Room/View/MessageContainerView/XPRoomMessageContainerView.m index c1b81f3b..96399ad7 100644 --- a/xplan-ios/Main/Room/View/MessageContainerView/XPRoomMessageContainerView.m +++ b/xplan-ios/Main/Room/View/MessageContainerView/XPRoomMessageContainerView.m @@ -14,8 +14,8 @@ #import "ThemeColor.h" #import "XPMacro.h" #import "XPRoomMessageConstant.h" +#import "XPRoomMessageParser.h" ///Model -#import "XPRoomMessageDisplayModel.h" #import "RoomInfoModel.h" ///View #import "XPRoomMessageTableViewCell.h" @@ -23,21 +23,23 @@ #import "View/XPRoomMessageHeaderView.h" -@interface XPRoomMessageContainerView () +@interface XPRoomMessageContainerView () +///房间的代理 +@property (nonatomic,weak) id hostDelegate; + ///列表 @property (nonatomic,strong) UITableView *messageTableView; -///数据源 -@property (nonatomic,strong) NSMutableArray *datasource; -///临时存放消息的数组 -@property (nonatomic,strong) NSMutableArray *tempArray; ///头部 @property (nonatomic,strong) XPRoomMessageHeaderView *headerView; ///底部有新的消息 @property (nonatomic,strong) UIButton *messageTipsBtn; ///是否处于正在爬楼 @property (nonatomic,assign) BOOL isPending; -///房间的代理 -@property (nonatomic,weak) id hostDelegate; + +///数据源 +@property (nonatomic,strong) NSMutableArray *datasource; +///临时存放消息的数组 +@property (nonatomic,strong) NSMutableArray *incomingMessages; @end @@ -56,7 +58,7 @@ #pragma mark - Response - (void)messagTipsBtnAction:(UIButton *)sender { - [self tryToappendAndScrollToBottom]; + [self tryToAppendAndScrollToBottom]; self.isPending = NO; } @@ -92,34 +94,29 @@ #pragma mark - 添加数据并且做自动滚动 ///添加信息 - (void)addRoomMessage:(NIMMessage *)message { - XPRoomMessageDisplayModel * model = [[XPRoomMessageDisplayModel alloc] initDisplayModel:message]; - [self.tempArray addObject:model]; + [self.incomingMessages addObject:message]; ///开始加入数据 - [self tryToappendAndScrollToBottom]; + [self tryToAppendAndScrollToBottom]; } /// 添加数据并滚动到底部 -- (void)tryToappendAndScrollToBottom { +- (void)tryToAppendAndScrollToBottom { // 处于爬楼状态更新更多按钮 - [self updateMessageTipsBtnHidden]; + if (self.isPending && self.incomingMessages.count > 0) { + self.messageTipsBtn.hidden = NO; + } else { + self.messageTipsBtn.hidden = YES; + } + if (!self.isPending) { // 如果不处在爬楼状态,追加数据源并滚动到底部 [self appendAndScrollToBottom]; } } -///更新底部有新的消息按钮的状态 -- (void)updateMessageTipsBtnHidden { - if (self.isPending && self.tempArray.count > 0) { - self.messageTipsBtn.hidden = NO; - } else { - self.messageTipsBtn.hidden = YES; - } -} - ///追加数据源 - (void)appendAndScrollToBottom { - if (self.tempArray.count < 1) { + if (self.incomingMessages.count < 1) { return; } @@ -131,13 +128,13 @@ // 执行插入 NSMutableArray *indexPaths = [NSMutableArray array]; - for (XPRoomMessageDisplayModel *item in self.tempArray) { - [self.datasource addObject:item]; + for (NIMMessage *item in self.incomingMessages) { + [self.datasource addObject:[XPRoomMessageParser parseMessageAttribute:item]]; [indexPaths addObject:[NSIndexPath indexPathForRow:self.datasource.count - 1 inSection:0]]; } NSLog(@"消息的总数%ld", self.datasource.count); [self.messageTableView reloadData]; - [self.tempArray removeAllObjects]; + [self.incomingMessages removeAllObjects]; //执行插入动画并滚动 [self scrollToBottom:YES]; @@ -208,7 +205,7 @@ CGFloat sizeH = scrollView.frame.size.height; self.isPending = contentSizeH - contentOffsetY - sizeH > 20.0; // 如果不处在爬楼状态,追加数据源并滚动到底部 - [self tryToappendAndScrollToBottom]; + [self tryToAppendAndScrollToBottom]; } @@ -218,8 +215,10 @@ } - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { - XPRoomMessageDisplayModel * model = [self.datasource objectAtIndex:indexPath.row]; - return model.cellHeight; + NSAttributedString* attr = [self.datasource objectAtIndex:indexPath.row]; + CGSize maxSize = CGSizeMake(kRoomMessageMaxWidth, MAXFLOAT); + YYTextLayout *layout = [YYTextLayout layoutWithContainerSize:maxSize text:attr]; + return layout.textBoundingSize.height + kRoomMessageTextSpaceHeight * 2 + 10; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { @@ -227,8 +226,8 @@ if (cell == nil) { cell = [[XPRoomMessageTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:NSStringFromClass([XPRoomMessageTableViewCell class])]; } - XPRoomMessageDisplayModel * model = [self.datasource objectAtIndex:indexPath.row]; - cell.displayModel = model; + NSAttributedString* attr = [self.datasource objectAtIndex:indexPath.row]; + cell.attributedString = attr; return cell; } #pragma mark - Getters And Setters @@ -271,18 +270,18 @@ return _messageTipsBtn; } -- (NSMutableArray *)datasource { +- (NSMutableArray *)datasource { if (!_datasource) { _datasource = [NSMutableArray array]; } return _datasource; } -- (NSMutableArray *)tempArray { - if (!_tempArray) { - _tempArray = [NSMutableArray array]; +- (NSMutableArray *)incomingMessages { + if (!_incomingMessages) { + _incomingMessages = [NSMutableArray array]; } - return _tempArray; + return _incomingMessages; } @end