消息模块

This commit is contained in:
liyuhua
2023-11-21 17:44:17 +08:00
parent e17c7fd160
commit 6140577b01
83 changed files with 2070 additions and 64 deletions

View File

@@ -1,5 +1,6 @@
# Uncomment the next line to define a global platform for your project # Uncomment the next line to define a global platform for your project
# platform :ios, '9.0' # platform :ios, '9.0'
source 'https://mirrors.tuna.tsinghua.edu.cn/git/CocoaPods/Specs.git'
target 'yinmeng-ios' do target 'yinmeng-ios' do
# Comment the next line if you don't want to use dynamic frameworks # Comment the next line if you don't want to use dynamic frameworks
@@ -13,6 +14,7 @@ target 'yinmeng-ios' do
pod 'MBProgressHUD' pod 'MBProgressHUD'
pod 'ReactiveObjC' pod 'ReactiveObjC'
pod 'FFPopup' pod 'FFPopup'
pod 'TZImagePickerController'
#易盾 本机一键登录 #易盾 本机一键登录
pod 'NTESQuickPass' pod 'NTESQuickPass'
#模型转化 #模型转化

View File

@@ -26,7 +26,7 @@ PODS:
- Masonry (1.1.0) - Masonry (1.1.0)
- MBProgressHUD (1.2.0) - MBProgressHUD (1.2.0)
- MJExtension (3.4.1) - MJExtension (3.4.1)
- MJRefresh (3.7.6) - MJRefresh (3.7.5)
- NIMSDK_LITE (8.9.119) - NIMSDK_LITE (8.9.119)
- NTESBaseComponent (1.8) - NTESBaseComponent (1.8)
- NTESQuickPass (3.4.5): - NTESQuickPass (3.4.5):
@@ -46,6 +46,11 @@ PODS:
- TXLiteAVSDK_TRTC (10.3.12363): - TXLiteAVSDK_TRTC (10.3.12363):
- TXLiteAVSDK_TRTC/TRTC (= 10.3.12363) - TXLiteAVSDK_TRTC/TRTC (= 10.3.12363)
- TXLiteAVSDK_TRTC/TRTC (10.3.12363) - TXLiteAVSDK_TRTC/TRTC (10.3.12363)
- TZImagePickerController (3.8.3):
- TZImagePickerController/Basic (= 3.8.3)
- TZImagePickerController/Location (= 3.8.3)
- TZImagePickerController/Basic (3.8.3)
- TZImagePickerController/Location (3.8.3)
- YYText (1.0.7) - YYText (1.0.7)
DEPENDENCIES: DEPENDENCIES:
@@ -70,10 +75,11 @@ DEPENDENCIES:
- SDWebImageFLPlugin - SDWebImageFLPlugin
- SSKeychain - SSKeychain
- TXLiteAVSDK_TRTC (~> 10.3.12271) - TXLiteAVSDK_TRTC (~> 10.3.12271)
- TZImagePickerController
- YYText - YYText
SPEC REPOS: SPEC REPOS:
trunk: https://mirrors.tuna.tsinghua.edu.cn/git/CocoaPods/Specs.git:
- AFNetworking - AFNetworking
- Base64 - Base64
- FFPopup - FFPopup
@@ -97,6 +103,7 @@ SPEC REPOS:
- SDWebImageFLPlugin - SDWebImageFLPlugin
- SSKeychain - SSKeychain
- TXLiteAVSDK_TRTC - TXLiteAVSDK_TRTC
- TZImagePickerController
- YYText - YYText
SPEC CHECKSUMS: SPEC CHECKSUMS:
@@ -111,7 +118,7 @@ SPEC CHECKSUMS:
Masonry: 678fab65091a9290e40e2832a55e7ab731aad201 Masonry: 678fab65091a9290e40e2832a55e7ab731aad201
MBProgressHUD: 3ee5efcc380f6a79a7cc9b363dd669c5e1ae7406 MBProgressHUD: 3ee5efcc380f6a79a7cc9b363dd669c5e1ae7406
MJExtension: 21c5f6f8c4d5d8844b7ae8fbae08fed0b501f961 MJExtension: 21c5f6f8c4d5d8844b7ae8fbae08fed0b501f961
MJRefresh: 2fe7fb43a5167ceda20bb7e63f130c04fd1814a5 MJRefresh: fdf5e979eb406a0341468932d1dfc8b7f9fce961
NIMSDK_LITE: c4895574b3e519c34e2c70ae013f0863efc87661 NIMSDK_LITE: c4895574b3e519c34e2c70ae013f0863efc87661
NTESBaseComponent: 7b310e7e80bb6c27183176188b98356d200dbbc5 NTESBaseComponent: 7b310e7e80bb6c27183176188b98356d200dbbc5
NTESQuickPass: 7baf2a68a091fd69dbf70b84ecdc4eb6aa7dd7ad NTESQuickPass: 7baf2a68a091fd69dbf70b84ecdc4eb6aa7dd7ad
@@ -123,8 +130,9 @@ SPEC CHECKSUMS:
SDWebImageFLPlugin: 72efd2cfbf565bc438421abb426f4bcf7b670754 SDWebImageFLPlugin: 72efd2cfbf565bc438421abb426f4bcf7b670754
SSKeychain: 55cc80f66f5c73da827e3077f02e43528897db41 SSKeychain: 55cc80f66f5c73da827e3077f02e43528897db41
TXLiteAVSDK_TRTC: c4e42ef113788558b7c5f4250bad5f81925bcfb4 TXLiteAVSDK_TRTC: c4e42ef113788558b7c5f4250bad5f81925bcfb4
TZImagePickerController: e9909edbadf7381140efc5b5c9f5bdbfd630f7d4
YYText: 5c461d709e24d55a182d1441c41dc639a18a4849 YYText: 5c461d709e24d55a182d1441c41dc639a18a4849
PODFILE CHECKSUM: 184de66867fbe584c7a06fef08bcddd83dbb0322 PODFILE CHECKSUM: 2a4277ff265cc4f2794e24536deeb780e0a31077
COCOAPODS: 1.14.2 COCOAPODS: 1.12.1

View File

@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,22 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "Session_Message_Game_InfoView_arrow@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "Session_Message_Game_InfoView_arrow@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,22 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "message_content_audio_playing_first@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "message_content_audio_playing_first@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,22 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "message_content_audio_playing_second@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "message_content_audio_playing_second@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,22 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "message_content_audio_playing_third@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "message_content_audio_playing_third@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,22 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "message_content_upgrade_charm@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "message_content_upgrade_charm@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

View File

@@ -0,0 +1,22 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "message_content_upgrade_expre@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "message_content_upgrade_expre@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

View File

@@ -0,0 +1,22 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "message_session_download_fail@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "message_session_download_fail@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,22 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "message_session_find_new_filtrate@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "message_session_find_new_filtrate@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,22 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "message_session_game_Invite_bg@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "message_session_game_Invite_bg@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,22 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "message_session_menu_gift@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "message_session_menu_gift@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

View File

@@ -0,0 +1,22 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "message_session_menu_photo@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "message_session_menu_photo@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

View File

@@ -0,0 +1,22 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "message_session_nav_report@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "message_session_nav_report@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 193 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 263 B

View File

@@ -0,0 +1,22 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "message_session_tool_audio@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "message_session_tool_audio@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 823 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -0,0 +1,22 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "message_session_tool_more_normal@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "message_session_tool_more_normal@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,22 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "message_session_tool_text@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "message_session_tool_text@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 807 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -0,0 +1,22 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "message_tool_audio_record_cancel@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "message_tool_audio_record_cancel@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,22 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "message_tool_audio_record_first@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "message_tool_audio_record_first@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,22 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "message_tool_audio_record_second@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "message_tool_audio_record_second@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,22 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "message_tool_audio_record_third@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "message_tool_audio_record_third@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,22 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "session_list_clean@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "session_list_clean@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 498 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 734 B

View File

@@ -0,0 +1,20 @@
//
// UIView+FilletCorner.h
// yinmeng-ios
//
// Created by duoban on 2023/11/21.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface UIView (FilletCorner)
- (void)setCornerWithLeftTopCorner:(CGFloat)leftTop
rightTopCorner:(CGFloat)rigtTop
bottomLeftCorner:(CGFloat)bottemLeft
bottomRightCorner:(CGFloat)bottemRight
size:(CGSize)size;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,41 @@
//
// UIView+FilletCorner.m
// yinmeng-ios
//
// Created by duoban on 2023/11/21.
//
#import "UIView+FilletCorner.h"
@implementation UIView (FilletCorner)
- (void)setCornerWithLeftTopCorner:(CGFloat)leftTop
rightTopCorner:(CGFloat)rigtTop
bottomLeftCorner:(CGFloat)bottemLeft
bottomRightCorner:(CGFloat)bottemRight
size:(CGSize)size {
CGFloat width = size.width;
CGFloat height = size.height;
UIBezierPath *maskPath = [UIBezierPath bezierPath];
maskPath.lineWidth = 1.0;
maskPath.lineCapStyle = kCGLineCapRound;
maskPath.lineJoinStyle = kCGLineJoinRound;
[maskPath moveToPoint:CGPointMake(bottemRight, height)]; //
[maskPath addLineToPoint:CGPointMake(width - bottemRight, height)];
[maskPath addQuadCurveToPoint:CGPointMake(width, height- bottemRight) controlPoint:CGPointMake(width, height)]; //
[maskPath addLineToPoint:CGPointMake(width, rigtTop)]; //线
[maskPath addQuadCurveToPoint:CGPointMake(width - rigtTop, 0) controlPoint:CGPointMake(width, 0)]; //
[maskPath addLineToPoint:CGPointMake(leftTop, 0)]; //线
[maskPath addQuadCurveToPoint:CGPointMake(0, leftTop) controlPoint:CGPointMake(0, 0)]; //
[maskPath addLineToPoint:CGPointMake(0, height - bottemLeft)]; //线
[maskPath addQuadCurveToPoint:CGPointMake(bottemLeft, height) controlPoint:CGPointMake(0, height)]; //
CAShapeLayer *maskLayer = [CAShapeLayer layer];
maskLayer.frame = CGRectMake(0, 0, size.width, size.height);
maskLayer.path = maskPath.CGPath;
self.layer.mask = maskLayer;
}
@end

View File

@@ -2,6 +2,12 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0"> <plist version="1.0">
<dict> <dict>
<key>NSCameraUsageDescription</key>
<string>“Mew”需要您的同意,才能访问进行拍照并上传您的图片,便于他人查看</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>“Mew”需要您的同意,才可以访问相册并选择您需要上传的图片,便于他人查看</string>
<key>NSPhotoLibraryAddUsageDescription</key>
<string>“Mew”需要您的同意,才可以存储相片到相册</string>
<key>NSMicrophoneUsageDescription</key> <key>NSMicrophoneUsageDescription</key>
<string>&quot;Mew&quot;需要您的同意,才可以进行语音聊天</string> <string>&quot;Mew&quot;需要您的同意,才可以进行语音聊天</string>
<key>NSAppTransportSecurity</key> <key>NSAppTransportSecurity</key>

View File

@@ -5,7 +5,7 @@
// Created by on 2023/11/9. // Created by on 2023/11/9.
// //
#import "MewSessionListTableViewCell.h" #import "SessionListTableViewCell.h"
/// Third /// Third
#import <Masonry/Masonry.h> #import <Masonry/Masonry.h>
#import <NIMSDK/NIMSDK.h> #import <NIMSDK/NIMSDK.h>
@@ -18,8 +18,9 @@
#import "NIMMessageUtils.h" #import "NIMMessageUtils.h"
#import "TimeIntervalUtils.h" #import "TimeIntervalUtils.h"
#import "UIView+NIM.h" #import "UIView+NIM.h"
#import "UIView+FilletCorner.h"
@interface MewSessionListTableViewCell() #import "YMMacro.h"
@interface SessionListTableViewCell()
/// ///
@property (nonatomic, strong) UIView *containerView; @property (nonatomic, strong) UIView *containerView;
@@ -37,7 +38,7 @@
//@property (nonatomic,strong) UIView *divider; //@property (nonatomic,strong) UIView *divider;
@end @end
@implementation MewSessionListTableViewCell @implementation SessionListTableViewCell
#pragma mark - Public Method #pragma mark - Public Method
- (void)renderWithSession:(NIMRecentSession *)recent { - (void)renderWithSession:(NIMRecentSession *)recent {
@@ -86,13 +87,15 @@
#pragma mark - LayoutSubviews #pragma mark - LayoutSubviews
- (void)layoutSubviews { - (void)layoutSubviews {
[super layoutSubviews]; [super layoutSubviews];
self.badgeView.nim_right = self.nim_width - 24 - 15; self.badgeView.nim_right = self.nim_width - 28;
self.badgeView.nim_top = 8.0; self.badgeView.nim_top = 50.0;
} }
#pragma mark - Init View #pragma mark - Init View
- (void)initView { - (void)initView {
self.backgroundColor = [UIColor clearColor];
self.contentView.backgroundColor = [UIColor clearColor];
[self.contentView addSubview:self.containerView]; [self.contentView addSubview:self.containerView];
[self.containerView addSubview:self.avatarImageView]; [self.containerView addSubview:self.avatarImageView];
[self.containerView addSubview:self.nameLabel]; [self.containerView addSubview:self.nameLabel];
@@ -103,37 +106,42 @@
} }
- (void)initLayout { - (void)initLayout {
[self.containerView mas_makeConstraints:^(MASConstraintMaker *make) { [self.containerView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.mas_equalTo(10); make.top.mas_equalTo(10);
make.bottom.equalTo(self.contentView); make.height.mas_equalTo(72);
// make.top.mas_equalTo(10); // make.top.mas_equalTo(10);
make.left.mas_offset(24); make.left.mas_offset(16);
make.right.mas_offset(-24); make.width.mas_equalTo(KScreenWidth - 32);
}]; }];
[self.avatarImageView mas_makeConstraints:^(MASConstraintMaker *make) { [self.avatarImageView mas_makeConstraints:^(MASConstraintMaker *make) {
// make.top.offset(10); // make.top.offset(10);
make.centerY.equalTo(self.containerView); make.centerY.equalTo(self.containerView);
make.left.mas_equalTo(10); make.left.mas_equalTo(8);
make.height.width.mas_equalTo(54); make.height.width.mas_equalTo(60);
}];
[self.timeLabel mas_makeConstraints:^(MASConstraintMaker *make) {
// make.bottom.mas_equalTo(self).offset(-15);
make.top.mas_equalTo(9);
make.right.mas_equalTo(self.containerView).offset(-8);
make.height.mas_equalTo(17);
}]; }];
[self.nameLabel mas_makeConstraints:^(MASConstraintMaker *make) { [self.nameLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.bottom.mas_equalTo(self.avatarImageView.mas_centerY).offset(-2); make.top.mas_equalTo(9);
make.left.mas_equalTo(self.avatarImageView.mas_right).offset(15); make.height.mas_equalTo(22);
make.left.mas_equalTo(self.avatarImageView.mas_right).offset(12);
make.right.equalTo(self.timeLabel.mas_left).mas_offset(-5);
}]; }];
[self.messageLabel mas_makeConstraints:^(MASConstraintMaker *make) { [self.messageLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(self.nameLabel); make.left.mas_equalTo(self.nameLabel);
make.top.mas_equalTo(self.avatarImageView.mas_centerY).offset(2); make.top.mas_equalTo(39);
make.height.mas_equalTo(20);
make.right.mas_equalTo(self.timeLabel.mas_left).offset(-15); make.right.mas_equalTo(self.timeLabel.mas_left).offset(-15);
}]; }];
[self.timeLabel mas_makeConstraints:^(MASConstraintMaker *make) {
// make.bottom.mas_equalTo(self).offset(-15);
make.centerY.equalTo(self.avatarImageView);
make.right.mas_equalTo(self.containerView).offset(-10);
}];
// [self.divider mas_makeConstraints:^(MASConstraintMaker *make) { // [self.divider mas_makeConstraints:^(MASConstraintMaker *make) {
// make.right.offset(-15); // make.right.offset(-15);
@@ -148,9 +156,8 @@
- (UIView *)containerView { - (UIView *)containerView {
if (!_containerView) { if (!_containerView) {
_containerView = [[UIView alloc] init]; _containerView = [[UIView alloc] init];
_containerView.backgroundColor = UIColor.grayColor; [_containerView setCornerWithLeftTopCorner:36 rightTopCorner:10 bottomLeftCorner:36 bottomRightCorner:10 size:CGSizeMake(KScreenWidth - 32, 72)];
_containerView.layer.cornerRadius = 20; _containerView.backgroundColor = UIColorFromRGB(0x525566);
_containerView.layer.masksToBounds = YES;
} }
return _containerView; return _containerView;
@@ -165,7 +172,7 @@
_avatarImageView = [[NetImageView alloc] initWithConfig:config]; _avatarImageView = [[NetImageView alloc] initWithConfig:config];
_avatarImageView.contentMode = UIViewContentModeScaleAspectFill; _avatarImageView.contentMode = UIViewContentModeScaleAspectFill;
_avatarImageView.layer.masksToBounds = YES; _avatarImageView.layer.masksToBounds = YES;
_avatarImageView.layer.cornerRadius = 54.f / 2; _avatarImageView.layer.cornerRadius = 60 / 2;
_avatarImageView.backgroundColor = UIColor.blueColor; _avatarImageView.backgroundColor = UIColor.blueColor;
} }
return _avatarImageView; return _avatarImageView;
@@ -176,7 +183,7 @@
_nameLabel = [[UILabel alloc] initWithFrame:CGRectZero]; _nameLabel = [[UILabel alloc] initWithFrame:CGRectZero];
_nameLabel.backgroundColor = [UIColor clearColor]; _nameLabel.backgroundColor = [UIColor clearColor];
_nameLabel.font = [UIFont systemFontOfSize:15.f weight:UIFontWeightMedium]; _nameLabel.font = [UIFont systemFontOfSize:15.f weight:UIFontWeightMedium];
_nameLabel.textColor = ThemeColor.mainTextColor; _nameLabel.textColor = [UIColor whiteColor];
_nameLabel.text = @"用户昵称"; _nameLabel.text = @"用户昵称";
} }
return _nameLabel; return _nameLabel;
@@ -186,8 +193,8 @@
if (!_messageLabel) { if (!_messageLabel) {
_messageLabel = [[UILabel alloc] initWithFrame:CGRectZero]; _messageLabel = [[UILabel alloc] initWithFrame:CGRectZero];
_messageLabel.backgroundColor = [UIColor clearColor]; _messageLabel.backgroundColor = [UIColor clearColor];
_messageLabel.font = [UIFont systemFontOfSize:13.f]; _messageLabel.font = [UIFont systemFontOfSize:14.f];
_messageLabel.textColor = ThemeColor.secondTextColor; _messageLabel.textColor = UIColorRGBAlpha(0xFFFFFF, 0.8);
_messageLabel.text = @"用户回复信息内容"; _messageLabel.text = @"用户回复信息内容";
} }
return _messageLabel; return _messageLabel;
@@ -196,12 +203,12 @@
- (UILabel *)timeLabel { - (UILabel *)timeLabel {
if (!_timeLabel) { if (!_timeLabel) {
_timeLabel = [[UILabel alloc] initWithFrame:CGRectZero]; _timeLabel = [[UILabel alloc] initWithFrame:CGRectZero];
_timeLabel.backgroundColor = [UIColor clearColor];
_timeLabel.font = [UIFont systemFontOfSize:12.f weight:UIFontWeightLight]; _timeLabel.font = [UIFont systemFontOfSize:12.f weight:UIFontWeightLight];
_timeLabel.textColor = UIColor.whiteColor; _timeLabel.textColor = UIColor.whiteColor;
[_timeLabel setContentHuggingPriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal]; [_timeLabel setContentHuggingPriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal];
[_timeLabel setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal]; [_timeLabel setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal];
_timeLabel.text = @"2023-10-30";
} }
return _timeLabel; return _timeLabel;
} }
@@ -209,9 +216,19 @@
- (NIMBadgeView *)badgeView { - (NIMBadgeView *)badgeView {
if (!_badgeView) { if (!_badgeView) {
_badgeView = [NIMBadgeView viewWithBadgeTip:@"1"]; _badgeView = [NIMBadgeView viewWithBadgeTip:@"1"];
_badgeView.layer.cornerRadius = 9;
_badgeView.layer.masksToBounds = YES;
} }
return _badgeView; return _badgeView;
} }
//- (UIView *)divider {
// if (!_divider) {
// _divider = [[UIView alloc]init];
// _divider.backgroundColor = UIColor.blackColor;
// _divider.hidden = YES;
// }
// return _divider;
//}
@end @end

View File

@@ -5,22 +5,24 @@
// Created by on 2023/11/9. // Created by on 2023/11/9.
// //
#import "MewSessionListViewController.h" #import "SessionListViewController.h"
/// Third /// Third
#import <NIMSDK/NIMSDK.h> #import <NIMSDK/NIMSDK.h>
/// View /// View
#import "MewSessionListTableViewCell.h" #import "SessionListTableViewCell.h"
/// Tool /// Tool
#import "YMMacro.h" #import "YMMacro.h"
#import "ClientConfig.h" #import "ClientConfig.h"
#import <Masonry/Masonry.h>
@interface MewSessionListViewController ()<UITableViewDelegate, UITableViewDataSource, #import "SessionViewController.h"
@interface SessionListViewController ()<UITableViewDelegate, UITableViewDataSource,
NIMConversationManagerDelegate,NIMLoginManagerDelegate> NIMConversationManagerDelegate,NIMLoginManagerDelegate>
/// HeaderView /// HeaderView
@property (nonatomic, strong) UIView *headerView; @property (nonatomic, strong) UIView *headerView;
@property (nonatomic, strong) UILabel *titleLabel; @property (nonatomic, strong) UILabel *titleLabel;
@property (nonatomic, strong) UIButton *cleanMessageButton; @property (nonatomic, strong) UIButton *cleanMessageButton;
@property(nonatomic,strong) UIImageView *sessionBgView;
/** /**
* *
*/ */
@@ -33,7 +35,7 @@
@end @end
@implementation MewSessionListViewController @implementation SessionListViewController
- (void)dealloc { - (void)dealloc {
@@ -174,17 +176,24 @@
#pragma mark - UITableViewDelegate, UITableViewDataSource #pragma mark - UITableViewDelegate, UITableViewDataSource
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return 10;
// return self.recentSessions.count; return self.recentSessions.count;
} }
- (nonnull UITableViewCell *)tableView:(nonnull UITableView *)tableView cellForRowAtIndexPath:(nonnull NSIndexPath *)indexPath { - (nonnull UITableViewCell *)tableView:(nonnull UITableView *)tableView cellForRowAtIndexPath:(nonnull NSIndexPath *)indexPath {
MewSessionListTableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([MewSessionListTableViewCell class])]; SessionListTableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([SessionListTableViewCell class])];
[cell renderWithSession:self.recentSessions[indexPath.row]];
return cell; return cell;
} }
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
NIMRecentSession *recentSession = self.recentSessions[indexPath.row];
SessionViewController *vc = [[SessionViewController alloc] initWithSession:recentSession.session];
[self.navigationController pushViewController:vc animated:YES];
}
#pragma mark - Action Event #pragma mark - Action Event
/// ///
@@ -246,6 +255,7 @@
#pragma mark - Init #pragma mark - Init
- (void)initViews { - (void)initViews {
[self.view addSubview:self.sessionBgView];
[self.view addSubview:self.headerView]; [self.view addSubview:self.headerView];
[self.headerView addSubview:self.titleLabel]; [self.headerView addSubview:self.titleLabel];
[self.headerView addSubview:self.cleanMessageButton]; [self.headerView addSubview:self.cleanMessageButton];
@@ -254,10 +264,18 @@
} }
- (void)initLayout { - (void)initLayout {
[self.sessionBgView mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(self.view);
}];
self.headerView.frame = CGRectMake(0, 0, KScreenWidth, 100); self.headerView.frame = CGRectMake(0, 0, KScreenWidth, 100);
self.titleLabel.frame = CGRectMake(30, kStatusBarHeight, 200, 30); self.titleLabel.frame = CGRectMake(20, kStatusBarHeight+10, 200, 30);
self.cleanMessageButton.frame = CGRectMake(KScreenWidth - 40 - 24, CGRectGetMinX(self.titleLabel.frame) + 10.0, 24, 24);
self.sessionListView.frame = CGRectMake(0, CGRectGetMaxY(self.headerView.frame), KScreenWidth, KScreenHeight - CGRectGetMaxY(self.headerView.frame)); self.sessionListView.frame = CGRectMake(0, CGRectGetMaxY(self.headerView.frame), KScreenWidth, KScreenHeight - CGRectGetMaxY(self.headerView.frame));
[self.cleanMessageButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.width.height.mas_equalTo(28);
make.right.mas_equalTo(-16);
make.centerY.equalTo(self.titleLabel);
}];
} }
#pragma mark - Get #pragma mark - Get
@@ -271,7 +289,7 @@
- (UIView *)headerView { - (UIView *)headerView {
if (!_headerView) { if (!_headerView) {
_headerView = [[UIView alloc] init]; _headerView = [[UIView alloc] init];
_headerView.backgroundColor = UIColor.whiteColor; _headerView.backgroundColor = UIColor.clearColor;
} }
return _headerView; return _headerView;
} }
@@ -280,8 +298,8 @@
if (!_titleLabel) { if (!_titleLabel) {
_titleLabel = [[UILabel alloc] init]; _titleLabel = [[UILabel alloc] init];
_titleLabel.text = @"消息中心"; _titleLabel.text = @"消息中心";
_titleLabel.textColor = UIColor.blackColor; _titleLabel.textColor = [UIColor whiteColor];
_titleLabel.font = kFontBold(20); _titleLabel.font = kFontMedium(18);
} }
return _titleLabel; return _titleLabel;
} }
@@ -289,7 +307,7 @@
- (UIButton *)cleanMessageButton { - (UIButton *)cleanMessageButton {
if (!_cleanMessageButton) { if (!_cleanMessageButton) {
_cleanMessageButton = [[UIButton alloc] init]; _cleanMessageButton = [[UIButton alloc] init];
_cleanMessageButton.backgroundColor = UIColor.blueColor; [_cleanMessageButton setBackgroundImage:kImage(@"session_list_clean") forState:UIControlStateNormal];
[_cleanMessageButton addTarget:self action:@selector(cleanMessageButtonAction) forControlEvents:UIControlEventTouchUpInside]; [_cleanMessageButton addTarget:self action:@selector(cleanMessageButtonAction) forControlEvents:UIControlEventTouchUpInside];
} }
return _cleanMessageButton; return _cleanMessageButton;
@@ -304,11 +322,17 @@
_sessionListView.delegate = self; _sessionListView.delegate = self;
_sessionListView.dataSource = self; _sessionListView.dataSource = self;
_sessionListView.showsVerticalScrollIndicator = NO; _sessionListView.showsVerticalScrollIndicator = NO;
_sessionListView.rowHeight = 80; _sessionListView.rowHeight = 82;
[_sessionListView registerClass:[MewSessionListTableViewCell class] forCellReuseIdentifier:NSStringFromClass([MewSessionListTableViewCell class])]; [_sessionListView registerClass:[SessionListTableViewCell class] forCellReuseIdentifier:NSStringFromClass([SessionListTableViewCell class])];
} }
return _sessionListView; return _sessionListView;
} }
- (UIImageView *)sessionBgView{
if(!_sessionBgView){
_sessionBgView = [UIImageView new];
_sessionBgView.image = kImage(@"mew_home_bg");
}
return _sessionBgView;
}
@end @end

View File

@@ -0,0 +1,27 @@
//
// MessageMenuModel.h
// xplan-ios
//
// Created by 冯硕 on 2022/4/21.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
typedef NS_ENUM(NSInteger, MessageMenuType) {
///发送图片
MessageMenuType_Photo = 1,
///送礼物
MessageMenuType_Gift
};
@interface MessageMenuModel : NSObject
///图片
@property (nonatomic,strong) NSString *imageName;
///类型
@property (nonatomic,assign) MessageMenuType type;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,12 @@
//
// MessageMenuModel.m
// xplan-ios
//
// Created by on 2022/4/21.
//
#import "MessageMenuModel.h"
@implementation MessageMenuModel
@end

View File

@@ -0,0 +1,16 @@
//
// MessageToolMenuCollectionViewCell.h
// xplan-ios
//
// Created by 冯硕 on 2022/4/20.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface MessageToolMenuCollectionViewCell : UICollectionViewCell
@property (nonatomic,copy) NSString *imageName;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,56 @@
//
// MessageToolMenuCollectionViewCell.m
// xplan-ios
//
// Created by on 2022/4/20.
//
#import "MessageToolMenuCollectionViewCell.h"
///Third
#import <Masonry/Masonry.h>
@interface MessageToolMenuCollectionViewCell ()
@property (nonatomic,strong) UIImageView *logoImageView;
@end
@implementation MessageToolMenuCollectionViewCell
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
[self initSubViews];
[self initSubViewConstraints];
}
return self;
}
#pragma mark - Private Method
- (void)initSubViews {
[self.contentView addSubview:self.logoImageView];
}
- (void)initSubViewConstraints {
[self.logoImageView mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.mas_equalTo(self.contentView);
}];
}
#pragma mark - Getters And Setters
- (void)setImageName:(NSString *)imageName {
_imageName = imageName;
if (_imageName) {
self.logoImageView.image = [UIImage imageNamed:_imageName];
}
}
- (UIImageView *)logoImageView {
if (!_logoImageView) {
_logoImageView = [[UIImageView alloc] init];
_logoImageView.userInteractionEnabled = YES;
}
return _logoImageView;
}
@end

View File

@@ -0,0 +1,34 @@
//
// NIMMessageMaker.h
// xplan-ios
//
// Created by zu on 2021/11/28.
//
#import <Foundation/Foundation.h>
#import <NIMSDK/NIMSDK.h>
@interface NIMMessageMaker : NSObject
+ (NIMMessage*)msgWithText:(NSString *)text;
+ (NIMMessage *)msgWithAudio:(NSString *)filePath;
+ (NIMMessage *)msgWithImage:(UIImage *)image;
+ (NIMMessage *)msgWithImagePath:(NSString *)path;
+ (NIMMessage *)msgWithImageData:(NSData *)data extension:(NSString *)extension;
+ (NIMMessage *)msgWithVideo:(NSString *)filePath;
@end
@interface NIMCommentMaker : NSObject
+ (NIMQuickComment *)commentWithType:(int64_t)type
content:(NSString *)content
ext:(NSString *)ext;
@end

View File

@@ -0,0 +1,121 @@
//
// NIMMessageMaker.m
// xplan-ios
//
// Created by zu on 2021/11/28.
//
#import "NIMMessageMaker.h"
#import "YMConstant.h"
@implementation NIMMessageMaker
+ (NIMMessage*)msgWithText:(NSString*)text
{
NIMMessage *textMessage = [[NIMMessage alloc] init];
textMessage.text = text;
[self setupMessage:textMessage];
return textMessage;
}
+ (NIMMessage*)msgWithAudio:(NSString*)filePath
{
NIMAudioObject *audioObject = [[NIMAudioObject alloc] initWithSourcePath:filePath scene:NIMNOSSceneTypeMessage];
NIMMessage *message = [[NIMMessage alloc] init];
message.messageObject = audioObject;
message.text = @"发来了一段语音";
[self setupMessage:message];
return message;
}
+ (NIMMessage*)msgWithVideo:(NSString*)filePath
{
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm"];
NSString *dateString = [dateFormatter stringFromDate:[NSDate date]];
NIMVideoObject *videoObject = [[NIMVideoObject alloc] initWithSourcePath:filePath scene:NIMNOSSceneTypeMessage];
videoObject.displayName = [NSString stringWithFormat:@"视频发送于%@", dateString];
NIMMessage *message = [[NIMMessage alloc] init];
message.messageObject = videoObject;
message.apnsContent = @"发来了一段视频";
[self setupMessage:message];
return message;
}
+ (NIMMessage*)msgWithImage:(UIImage*)image
{
NIMImageObject *imageObject = [[NIMImageObject alloc] initWithImage:image scene:NIMNOSSceneTypeMessage];
NIMImageOption *option = [[NIMImageOption alloc] init];
option.compressQuality = 0.7;
imageObject.option = option;
return [NIMMessageMaker generateImageMessage:imageObject];
}
+ (NIMMessage *)msgWithImagePath:(NSString*)path
{
NIMImageObject * imageObject = [[NIMImageObject alloc] initWithFilepath:path scene:NIMNOSSceneTypeMessage];
return [NIMMessageMaker generateImageMessage:imageObject];
}
+ (NIMMessage *)msgWithImageData:(NSData *)data extension:(NSString *)extension
{
NIMImageObject *imageObject = [[NIMImageObject alloc] initWithData:data extension:extension];
return [NIMMessageMaker generateImageMessage:imageObject];
}
+ (NIMMessage *)generateImageMessage:(NIMImageObject *)imageObject
{
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm"];
NSString *dateString = [dateFormatter stringFromDate:[NSDate date]];
imageObject.displayName = [NSString stringWithFormat:@"图片发送于%@", dateString];
NIMMessage *message = [[NIMMessage alloc] init];
message.messageObject = imageObject;
message.apnsContent = @"发来了一张图片";
[self setupMessage:message];
return message;
}
+ (void)setupMessage:(NIMMessage *)message
{
message.apnsPayload = @{
@"apns-collapse-id": message.messageId,
};
NIMMessageSetting *setting = [[NIMMessageSetting alloc] init];
setting.scene = NIMNOSSceneTypeMessage;
setting.apnsEnabled = YES;
message.setting = setting;
NIMAntiSpamOption *option = [NIMAntiSpamOption new];
option.yidunEnabled = YES;
option.businessId = KeyWithType(keyType_YiDunBussinessId);
message.antiSpamOption = option;
}
@end
@implementation NIMCommentMaker
+ (NIMQuickComment *)commentWithType:(int64_t)type
content:(NSString *)content
ext:(NSString *)ext
{
NIMQuickComment *comment = [[NIMQuickComment alloc] init];
comment.ext = ext;
NIMQuickCommentSetting *setting = [[NIMQuickCommentSetting alloc] init];
setting.needPush = YES;
setting.needBadge = YES;
setting.pushTitle = @"你收到了一条快捷评论";
setting.pushContent = content;
setting.pushPayload = @{
@"key" : @"value"
};
comment.setting = setting;
comment.replyType = type;
return comment;
}
@end

View File

@@ -0,0 +1,26 @@
//
// SessionAudioRecordView.h
// xplan-ios
//
// Created by 冯硕 on 2022/4/21.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface SessionAudioRecordView : UIView
- (void)configAudioRecord:(NSString *)imageName title:(NSString *)title isAnimation:(BOOL)isAnimation;
///开始录音
- (void)beginAudioRecord;
///取消录音
- (void)cancelAudioRecord;
///完成录音
- (void)finishAudioRecord;
///更新进度
- (void)updateAudioRecordProgress:(NSTimeInterval)recordTime;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,148 @@
//
// SessionAudioRecordView.m
// xplan-ios
//
// Created by on 2022/4/21.
//
#import "SessionAudioRecordView.h"
///Third
#import <Masonry/Masonry.h>
#import <NIMSDK/NIMSDK.h>
@interface SessionAudioRecordView ()
///
@property (nonatomic,strong) UIView * backView;
///
@property (nonatomic,strong) UIImageView *logoImageView;
///
@property (nonatomic,strong) UILabel *titleLabel;
///
@property (nonatomic,strong) UILabel *timeLabel;
@end
@implementation SessionAudioRecordView
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
[self initSubViews];
[self initSubViewConstraints];
}
return self;
}
#pragma mark - Public Method
- (void)configAudioRecord:(NSString *)imageName title:(NSString *)title isAnimation:(BOOL)isAnimation {
self.logoImageView.image = [UIImage imageNamed:imageName];
if (isAnimation) {
[self.logoImageView startAnimating];
} else {
[self.logoImageView stopAnimating];
}
self.titleLabel.text = title;
}
///
- (void)beginAudioRecord {
self.timeLabel.text = @"00:00";
[[NIMSDK sharedSDK].mediaManager recordForDuration:60];
}
///
- (void)cancelAudioRecord {
self.timeLabel.text = @"00:00";
[[NIMSDK sharedSDK].mediaManager cancelRecord];
}
///
- (void)finishAudioRecord {
self.timeLabel.text = @"00:00";
[[NIMSDK sharedSDK].mediaManager stopRecord];
}
- (void)updateAudioRecordProgress:(NSTimeInterval)recordTime {
NSInteger minutes = (NSInteger)recordTime / 60;
NSInteger seconds = (NSInteger)recordTime % 60;
self.timeLabel.text = [NSString stringWithFormat:@"%02zd:%02zd", minutes, seconds];
}
#pragma mark - Private Method
- (void)initSubViews {
[self addSubview:self.backView];
[self.backView addSubview:self.logoImageView];
[self.backView addSubview:self.titleLabel];
[self.backView addSubview:self.timeLabel];
}
- (void)initSubViewConstraints {
[self mas_makeConstraints:^(MASConstraintMaker *make) {
make.size.mas_equalTo(CGSizeMake(250, 200));
}];
[self.timeLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.right.mas_equalTo(self.backView);
make.top.mas_equalTo(self.backView).offset(15);
}];
[self.backView mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.mas_equalTo(self);
}];
[self.logoImageView mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.mas_equalTo(self.backView);
make.top.mas_equalTo(self.backView).offset(50);
make.size.mas_equalTo(CGSizeMake(90, 72));
}];
[self.titleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.right.mas_equalTo(self.backView);
make.top.mas_equalTo(self.logoImageView.mas_bottom).offset(25);
}];
}
#pragma mark - Getters And Setters
- (UIView *)backView {
if (!_backView) {
_backView = [[UIView alloc] init];
_backView.backgroundColor = [UIColor blackColor];
_backView.layer.masksToBounds = YES;
_backView.layer.cornerRadius = 10;
}
return _backView;
}
- (UIImageView *)logoImageView {
if (!_logoImageView) {
_logoImageView = [[UIImageView alloc] init];
_logoImageView.userInteractionEnabled = YES;
UIImage *firstImage = [UIImage imageNamed:@"message_tool_audio_record_first"];
UIImage *secondImage = [UIImage imageNamed:@"message_tool_audio_record_second"];
UIImage *thirdImage = [UIImage imageNamed:@"message_tool_audio_record_third"];
_logoImageView.animationImages = @[firstImage, secondImage, thirdImage];
_logoImageView.animationDuration = 1;
_logoImageView.animationRepeatCount = HUGE;
}
return _logoImageView;
}
- (UILabel *)titleLabel {
if (!_titleLabel) {
_titleLabel = [[UILabel alloc] init];
_titleLabel.font = [UIFont systemFontOfSize:15];
_titleLabel.textColor = [UIColor whiteColor];
_titleLabel.textAlignment = NSTextAlignmentCenter;
}
return _titleLabel;
}
- (UILabel *)timeLabel {
if (!_timeLabel) {
_timeLabel = [[UILabel alloc] init];
_timeLabel.font = [UIFont systemFontOfSize:17 weight:UIFontWeightMedium];
_timeLabel.textColor = [UIColor whiteColor];
_timeLabel.textAlignment = NSTextAlignmentCenter;
}
return _timeLabel;
}
@end

View File

@@ -0,0 +1,17 @@
//
// SessionInfoViewController.h
// xplan-ios
//
// Created by 冯硕 on 2022/4/25.
//
#import "BaseViewController.h"
NS_ASSUME_NONNULL_BEGIN
@interface SessionInfoViewController : BaseViewController
///用户的id
@property (nonatomic,copy) NSString *userId;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,295 @@
//
// SessionInfoViewController.m
// xplan-ios
//
// Created by on 2022/4/25.
//
#import "SessionInfoViewController.h"
///Third
#import <Masonry/Masonry.h>
#import <NIMSDK/NIMSDK.h>
///Tool
#import "ThemeColor.h"
#import "NetImageView.h"
#import "TTPopup.h"
///View
#import "YMWebViewController.h"
@interface SessionInfoViewController ()
///
@property (nonatomic,strong) UIStackView *stackView;
///view
@property (nonatomic,strong) UIView * infoView;
///
@property (nonatomic,strong) NetImageView *avatarImageView;
///
@property (nonatomic,strong) UILabel *nickLabel;
///
@property (nonatomic,strong) UILabel *titleLabel;
///
@property (nonatomic,strong) UIImageView *arrowImageView;
///
@property (nonatomic,strong) UIStackView *contentStackView;
///
@property (nonatomic,strong) UIButton *reportButton;
///线
@property (nonatomic,strong) UIView * lineView;
///
@property (nonatomic,strong) UIButton *blackButton;
@end
@implementation SessionInfoViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self initData];
[self initSubViews];
[self initSubViewConstraints];
}
#pragma mark - Private Method
- (void)initData {
[[NIMSDK sharedSDK].userManager fetchUserInfos:@[self.userId] completion:^(NSArray<NIMUser *> * _Nullable users, NSError * _Nullable error) {
if (!error) {
NIMUser * user = users.firstObject;
self.avatarImageView.imageUrl = user.userInfo.avatarUrl;
self.nickLabel.text = user.userInfo.nickName;
} else {
[self showErrorToast:@"用户信息请求失败,请重试"];
[self.navigationController popViewControllerAnimated:YES];
}
}];
self.blackButton.selected = [[NIMSDK sharedSDK].userManager isUserInBlackList:self.userId];
}
- (void)initSubViews {
self.title = @"加入黑名单";
[self.view addSubview:self.stackView];
[self.stackView addArrangedSubview:self.infoView];
[self.stackView addArrangedSubview:self.contentStackView];
[self.infoView addSubview:self.avatarImageView];
[self.infoView addSubview:self.nickLabel];
[self.infoView addSubview:self.titleLabel];
[self.infoView addSubview:self.arrowImageView];
[self.contentStackView addArrangedSubview:self.reportButton];
[self.contentStackView addArrangedSubview:self.lineView];
[self.contentStackView addArrangedSubview:self.blackButton];
}
- (void)initSubViewConstraints {
[self.stackView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.right.mas_equalTo(self.view);
make.top.mas_equalTo(self.view).offset(10);
}];
[self.infoView mas_makeConstraints:^(MASConstraintMaker *make) {
make.height.mas_equalTo(60);
}];
[self.avatarImageView mas_makeConstraints:^(MASConstraintMaker *make) {
make.size.mas_equalTo(CGSizeMake(40, 40));
make.left.mas_equalTo(self.infoView).offset(15);
make.centerY.mas_equalTo(self.infoView);
}];
[self.nickLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.mas_equalTo(self.infoView);
make.left.mas_equalTo(self.avatarImageView.mas_right).offset(5);
make.right.mas_lessThanOrEqualTo(self.titleLabel.mas_left).offset(-5);
}];
[self.titleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.right.mas_equalTo(self.arrowImageView.mas_left).offset(-5);
make.centerY.mas_equalTo(self.infoView);
}];
[self.arrowImageView mas_makeConstraints:^(MASConstraintMaker *make) {
make.size.mas_equalTo(CGSizeMake(6.5, 11));
make.centerY.mas_equalTo(self.infoView);
make.right.mas_equalTo(self.infoView).offset(-10);
}];
[self.reportButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.height.mas_equalTo(44);
}];
[self.lineView mas_makeConstraints:^(MASConstraintMaker *make) {
make.height.mas_equalTo(0.5);
}];
[self.blackButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.height.mas_equalTo(44);
}];
}
#pragma mark - Event Response
- (void)blackButtonAction:(UIButton *)sender {
NSString *title = nil;
NSString *message = nil;
BOOL isInBlack = [[NIMSDK sharedSDK].userManager isUserInBlackList:self.userId];
if (!isInBlack) {
title = @"加入黑名单";
message = @"加入黑名单,你将不再收到对方的消息";
} else {
title = @"移除黑名单";
message = @"移除黑名单,你将正常收到对方的消息";
}
TTAlertConfig *config = [[TTAlertConfig alloc] init];
config.title = title;
config.message = message;
[TTPopup alertWithConfig:config confirmHandler:^{
if (isInBlack) {
[[NIMSDK sharedSDK].userManager removeFromBlackBlackList:self.userId completion:^(NSError * _Nullable error) {
if (error == nil) {
[self showErrorToast:@"已经成功将对方移除黑名单"];
self.blackButton.selected = NO;
} else {
[self showErrorToast:error.description];
}
}];
} else {
[[NIMSDK sharedSDK].userManager addToBlackList:self.userId completion:^(NSError * _Nullable error) {
if (error == nil) {
[self showErrorToast:@"已经成功将对方加入黑名单"];
self.blackButton.selected = YES;
} else {
[self showErrorToast:error.description];
}
}];
}
} cancelHandler:^{
}];
}
- (void)reportButtonAction:(UIButton *)sender {
[self showSuccessToast:@"举报成功"];
}
- (void)didTapUserRecognizer {
// XPMineUserInfoViewController * mineVC = [[XPMineUserInfoViewController alloc] init];
// mineVC.uid = self.userId.integerValue;
// [self.navigationController pushViewController:mineVC animated:YES];
}
#pragma mark - Getters And Setters
- (UIStackView *)stackView {
if (!_stackView) {
_stackView = [[UIStackView alloc] init];
_stackView.axis = UILayoutConstraintAxisVertical;
_stackView.distribution = UIStackViewDistributionFill;
_stackView.alignment = UIStackViewAlignmentFill;
_stackView.spacing = 20;
}
return _stackView;
}
- (UIView *)infoView {
if (!_infoView) {
_infoView = [[UIView alloc] init];
_infoView.backgroundColor = [ThemeColor appCellBackgroundColor];
UITapGestureRecognizer * tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(didTapUserRecognizer)];
[_infoView addGestureRecognizer:tap];
_infoView.hidden = YES;
}
return _infoView;
}
- (NetImageView *)avatarImageView {
if (!_avatarImageView) {
NetImageConfig * config = [[NetImageConfig alloc]init];
config.imageType = ImageTypeUserIcon;
config.placeHolder = [UIImageConstant defaultAvatarPlaceholder];
_avatarImageView = [[NetImageView alloc] initWithConfig:config];
_avatarImageView.layer.masksToBounds = YES;
_avatarImageView.layer.cornerRadius = 20;
}
return _avatarImageView;
}
- (UILabel *)nickLabel {
if (!_nickLabel) {
_nickLabel = [[UILabel alloc] init];
_nickLabel.font = [UIFont systemFontOfSize:15];
_nickLabel.textColor = [ThemeColor mainTextColor];
}
return _nickLabel;
}
- (UILabel *)titleLabel {
if (!_titleLabel) {
_titleLabel = [[UILabel alloc] init];
_titleLabel.font = [UIFont systemFontOfSize:14];
_titleLabel.text = @"个人主页";
_titleLabel.textColor = [ThemeColor secondTextColor];
}
return _titleLabel;
}
- (UIImageView *)arrowImageView {
if (!_arrowImageView) {
_arrowImageView = [[UIImageView alloc] init];
_arrowImageView.userInteractionEnabled = YES;
_arrowImageView.image = [UIImage imageNamed:@"room_setting_arrow"];
}
return _arrowImageView;
}
- (UIStackView *)contentStackView {
if (!_contentStackView) {
_contentStackView = [[UIStackView alloc] init];
_contentStackView.axis = UILayoutConstraintAxisVertical;
_contentStackView.distribution = UIStackViewDistributionFill;
_contentStackView.alignment = UIStackViewAlignmentFill;
_contentStackView.spacing = 0;
}
return _contentStackView;
}
- (UIButton *)reportButton {
if (!_reportButton) {
_reportButton = [UIButton buttonWithType:UIButtonTypeCustom];
[_reportButton setTitle:@"举报" forState:UIControlStateNormal];
[_reportButton setTitleColor:[ThemeColor mainTextColor] forState:UIControlStateNormal];
_reportButton.titleLabel.font = [UIFont systemFontOfSize:16 weight:UIFontWeightMedium];
[_reportButton setBackgroundColor:[ThemeColor appCellBackgroundColor]];
[_reportButton addTarget:self action:@selector(reportButtonAction:) forControlEvents:UIControlEventTouchUpInside];
}
return _reportButton;
}
- (UIView *)lineView {
if (!_lineView) {
_lineView = [[UIView alloc] init];
_lineView.backgroundColor = [ThemeColor dividerColor];
}
return _lineView;
}
- (UIButton *)blackButton {
if (!_blackButton) {
_blackButton = [UIButton buttonWithType:UIButtonTypeCustom];
[_blackButton setTitle:@"加入黑名单" forState:UIControlStateNormal];
[_blackButton setTitle:@"移除黑名单" forState:UIControlStateSelected];
[_blackButton setTitleColor:[ThemeColor mainTextColor] forState:UIControlStateNormal];
[_blackButton setTitleColor:[ThemeColor mainTextColor] forState:UIControlStateSelected];
_blackButton.titleLabel.font = [UIFont systemFontOfSize:16 weight:UIFontWeightMedium];
[_blackButton setBackgroundColor:[ThemeColor appCellBackgroundColor]];
[_blackButton addTarget:self action:@selector(blackButtonAction:) forControlEvents:UIControlEventTouchUpInside];
}
return _blackButton;
}
@end

View File

@@ -237,12 +237,44 @@
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) { if (self) {
[self initViews];
[self initLayout];
} }
return self; 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);
}];
}
#pragma mark - Get #pragma mark - Get
- (NetImageView *)leftAvatar { - (NetImageView *)leftAvatar {
if (!_leftAvatar) { if (!_leftAvatar) {

View File

@@ -8,6 +8,7 @@
#import "SessionNavView.h" #import "SessionNavView.h"
/// Tool /// Tool
#import "ThemeColor.h" #import "ThemeColor.h"
#import <NIMSDK/NIMSDK.h>
#import "YMMacro.h" #import "YMMacro.h"
/// Third /// Third
#import <Masonry/Masonry.h> #import <Masonry/Masonry.h>
@@ -90,6 +91,32 @@
make.right.equalTo(self.reportButton.mas_left).mas_offset(-14); make.right.equalTo(self.reportButton.mas_left).mas_offset(-14);
}]; }];
} }
- (void)setUserId:(NSString *)userId {
_userId = userId;
if (_userId.length > 0) {
[[NIMSDK sharedSDK].userManager fetchUserInfos:@[self.userId] completion:^(NSArray<NIMUser *> * _Nullable users, NSError * _Nullable error) {
if (!error) {
self.title = users[0].userInfo.nickName;
}
}];
}
}
- (void)setTitle:(NSString *)title {
_title = title;
if (_title) {
NSString * nick = title;
if (nick.length > 10 ) {
nick = [nick substringToIndex:10];
}
self.nickLabel.text = nick;
}
}
- (void)setIsLike:(BOOL)isLike {
_isLike = isLike;
self.likeButton.hidden = _isLike;
}
#pragma mark - Get #pragma mark - Get
- (UIButton *)backButton { - (UIButton *)backButton {

View File

@@ -0,0 +1,29 @@
//
// MessageToolbarView.h
// xplan-ios
//
// Created by 冯硕 on 2022/4/20.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@class MessageMenuModel;
@protocol SessionToolbarViewDelegate <NSObject>
- (void)keyboardWillChangeFrame:(CGRect)rect;
- (void)sendTextMessage:(NSString *)text;
- (void)audioRecordCompletion:(NSString *)recordPath;
- (void)didSelectMenuItem:(MessageMenuModel *)info;
@end
@interface SessionToolbarView : UIView
///代理
@property (nonatomic,weak) id<SessionToolbarViewDelegate> delegate;
@property(nonatomic,assign) int model;
@property (nonatomic, assign, getter=isSendDisabled) BOOL sendDisabled;
///折叠 菜单view
- (void)foldMenuView;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,485 @@
//
// MessageToolbarView.m
// xplan-ios
//
// Created by on 2022/4/20.
//
#import "SessionToolbarView.h"
///Third
#import <Masonry/Masonry.h>
#import <NIMSDK/NIMSDK.h>
///Tool
#import "ThemeColor.h"
#import "YMMacro.h"
#import "NSArray+Safe.h"
///Model
#import "MessageMenuModel.h"
///View
#import "MessageToolMenuCollectionViewCell.h"
#import "SessionAudioRecordView.h"
#define TOOL_HEIGHT 60
#define MENU_HEIGHT 130
@interface SessionToolbarView ()<UICollectionViewDelegate, UICollectionViewDataSource, UITextFieldDelegate, NIMMediaManagerDelegate>
///
@property (nonatomic,strong) UIStackView *stackView;
///
@property (nonatomic,strong) UIStackView *toolStackView;
///
@property (nonatomic,strong) UIButton *changeButton;
///
@property (nonatomic,strong) UIButton *moreButton;
///
@property (nonatomic,strong) UIStackView *audioStackView;
///
@property (nonatomic,strong) UIView * inputBackView;
///
@property (nonatomic,strong) UITextField *inputView;
///
@property (nonatomic,strong) UIButton *audioButton;
///
@property (nonatomic,strong) UICollectionView *collectionView;
///view
@property (nonatomic,strong) UIView * placeView;
///
@property (nonatomic,strong) NSArray<MessageMenuModel *> *menuList;
///view
@property (nonatomic,strong) SessionAudioRecordView *audioRecordView;
@end
@implementation SessionToolbarView
- (void)dealloc {
[[NIMSDK sharedSDK].mediaManager removeDelegate:self];
}
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
[[NIMSDK sharedSDK].mediaManager addDelegate:self];
[self addNotification];
[self addAudioButtonAction];
[self initSubViews];
[self initSubViewConstraints];
}
return self;
}
#pragma mark - Public Method
- (void)foldMenuView {
[self.inputView resignFirstResponder];
if (self.collectionView.hidden == NO) {
self.collectionView.hidden = YES;
self.moreButton.selected = NO;
}
}
#pragma mark - Private Method
- (void)addAudioButtonAction {
///button 70px out in enter exit
[self.audioButton addTarget:self action:@selector(audioTouchDownAction) forControlEvents:UIControlEventTouchDown];
[self.audioButton addTarget:self action:@selector(audioTouchUpOutsideAction) forControlEvents:UIControlEventTouchUpOutside];
[self.audioButton addTarget:self action:@selector(audioTouchUpInsideAction) forControlEvents:UIControlEventTouchUpInside];
[self.audioButton addTarget:self action:@selector(audioTouchDragEnterAction) forControlEvents:UIControlEventTouchDragEnter];
[self.audioButton addTarget:self action:@selector(audioTouchDragExitAction) forControlEvents:UIControlEventTouchDragExit];
}
- (void)addNotification {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHidden:) name:UIKeyboardWillHideNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
}
- (void)initSubViews {
self.backgroundColor = [ThemeColor appCellBackgroundColor];
[self addSubview:self.stackView];
[self.stackView addArrangedSubview:self.toolStackView];
[self.stackView addArrangedSubview:self.collectionView];
[self.stackView addArrangedSubview:self.placeView];
[self.toolStackView addArrangedSubview:self.changeButton];
[self.toolStackView addArrangedSubview:self.audioStackView];
[self.toolStackView addArrangedSubview:self.moreButton];
[self.audioStackView addArrangedSubview:self.inputBackView];
[self.audioStackView addArrangedSubview:self.audioButton];
[self.inputBackView addSubview:self.inputView];
}
- (void)initSubViewConstraints {
[self mas_makeConstraints:^(MASConstraintMaker *make) {
make.bottom.mas_equalTo(self.stackView);
}];
[self.stackView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.right.mas_equalTo(self).inset(15);
make.top.mas_equalTo(self);
}];
[self.toolStackView mas_makeConstraints:^(MASConstraintMaker *make) {
make.height.mas_equalTo(TOOL_HEIGHT);
}];
[self.collectionView mas_makeConstraints:^(MASConstraintMaker *make) {
make.height.mas_equalTo(MENU_HEIGHT);
}];
[self.placeView mas_makeConstraints:^(MASConstraintMaker *make) {
make.height.mas_equalTo(kSafeAreaBottomHeight);
}];
[self.changeButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.size.mas_equalTo(CGSizeMake(40, 40));
}];
[self.moreButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.size.mas_equalTo(CGSizeMake(40, 40));
}];
[self.audioStackView mas_makeConstraints:^(MASConstraintMaker *make) {
make.height.mas_equalTo(40);
}];
[self.inputView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(self.inputBackView.mas_left).offset(16);
make.top.bottom.mas_equalTo(self.inputBackView);
make.right.mas_equalTo(self.inputBackView).offset(-5);
}];
}
#pragma mark - UICollectionViewDelegate And UICollectionViewDatasource
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return self.menuList.count;
}
- (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
MessageToolMenuCollectionViewCell * cell = [collectionView dequeueReusableCellWithReuseIdentifier:NSStringFromClass([MessageToolMenuCollectionViewCell class]) forIndexPath:indexPath];
MessageMenuModel * model = [self.menuList safeObjectAtIndex1:indexPath.row];
cell.imageName = model.imageName;
return cell;
}
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
[collectionView deselectItemAtIndexPath:indexPath animated:YES];
if (self.menuList.count > 0) {
MessageMenuModel * model = [self.menuList safeObjectAtIndex1:indexPath.row];
if (self.delegate && [self.delegate respondsToSelector:@selector(didSelectMenuItem:)]) {
[self.delegate didSelectMenuItem:model];
}
}
}
#pragma mark - UITextFieldDelegate
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
if (textField.text.length >0) {
if (self.delegate && [self.delegate respondsToSelector:@selector(sendTextMessage:)]) {
[self.delegate sendTextMessage:textField.text];
textField.text = nil;
}
}
return YES;
}
#pragma mark - NIMMediaManagerDelegate
/**
*
*
* @param filePath
* @param error
* @discussion filePath nil
*/
- (void)recordAudio:(nullable NSString *)filePath didBeganWithError:(nullable NSError *)error {
NSLog(@"开始录制语音");
}
/**
*
*
* @param filePath
* @param error
*/
- (void)recordAudio:(nullable NSString *)filePath didCompletedWithError:(nullable NSError *)error {
if (filePath.length > 0 && error == nil) {
if (self.delegate && [self.delegate respondsToSelector:@selector(audioRecordCompletion:)]) {
[self.delegate audioRecordCompletion:filePath];
}
}
NSLog(@"录制音频完成后的回调 %@", filePath);
}
/**
*
*/
- (void)recordAudioDidCancelled {
NSLog(@"录音被取消的回调");
}
/**
*
*
* @param currentTime
*/
- (void)recordAudioProgress:(NSTimeInterval)currentTime {
[self.audioRecordView updateAudioRecordProgress:currentTime];
}
/**
*
*/
- (void)recordAudioInterruptionBegin {
[self.audioRecordView cancelAudioRecord];
}
#pragma mark - Event Response
- (void)keyboardWillShow:(NSNotification *)notification {
if (self.collectionView.hidden == NO) {
self.collectionView.hidden = YES;
self.moreButton.selected = NO;
}
NSDictionary *userInfo = [notification userInfo];
CGRect keyboardEndFrame = [userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
if (CGRectIsNull(keyboardEndFrame)) {
return;
}
UIViewAnimationCurve animationCurve = [userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue];
NSInteger animationCurveOption = (animationCurve << 16);
double animationDuration = [userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
[UIView animateWithDuration:animationDuration delay:0.0 options:animationCurveOption animations:^{
if (self.delegate && [self.delegate respondsToSelector:@selector(keyboardWillChangeFrame:)]) {
[self.delegate keyboardWillChangeFrame:keyboardEndFrame];
}
} completion:^(BOOL finished) {
}];
}
- (void)keyboardWillHidden:(NSNotification*)notification {
CGRect keyboardEndFrame = CGRectMake(0, 0, 0, 0);
[UIView animateWithDuration:0.25 animations:^{
if (self.delegate && [self.delegate respondsToSelector:@selector(keyboardWillChangeFrame:)]) {
[self.delegate keyboardWillChangeFrame:keyboardEndFrame];
}
}];
}
- (void)changeButtonAction:(UIButton *)sender {
sender.selected = !sender.selected;
self.inputBackView.hidden = sender.selected;
self.audioButton.hidden = !sender.selected;
self.collectionView.hidden = YES;
self.moreButton.selected = NO;
if (sender.selected) {
[self.inputView resignFirstResponder];
} else {
[self.inputView becomeFirstResponder];
}
}
- (void)moreButtonAction:(UIButton *)sender {
sender.selected = !sender.selected;
self.collectionView.hidden = !sender.selected;
[self.inputView resignFirstResponder];
CGRect keyboardEndFrame = CGRectMake(0, 0, 0, 0);
[UIView animateWithDuration:0.25 animations:^{
if (self.delegate && [self.delegate respondsToSelector:@selector(keyboardWillChangeFrame:)]) {
[self.delegate keyboardWillChangeFrame:keyboardEndFrame];
}
}];
}
- (void)audioTouchDownAction {
self.audioButton.selected = YES;
///
if (!self.audioRecordView.superview) {
[[UIApplication sharedApplication].keyWindow addSubview:self.audioRecordView];
[self.audioRecordView mas_makeConstraints:^(MASConstraintMaker *make) {
make.center.mas_equalTo(self.audioRecordView.superview);
}];
[self.audioRecordView configAudioRecord:@"message_tool_audio_record_first" title:@"手指上滑,取消发送" isAnimation:YES];
[self.audioRecordView beginAudioRecord];
}
}
- (void)audioTouchUpOutsideAction {
self.audioButton.selected = NO;
///
[self.audioRecordView cancelAudioRecord];
[self.audioRecordView removeFromSuperview];
}
- (void)audioTouchUpInsideAction {
self.audioButton.selected = NO;
///
[self.audioRecordView finishAudioRecord];
[self.audioRecordView removeFromSuperview];
}
- (void)audioTouchDragEnterAction {
///
[self.audioRecordView configAudioRecord:@"message_tool_audio_record_first" title:@"手指上滑,取消发送" isAnimation:YES];
}
- (void)audioTouchDragExitAction {
///
[self.audioRecordView configAudioRecord:@"message_tool_audio_record_cancel" title:@"松开手指 取消发送" isAnimation:NO];
}
#pragma mark - Getters And Setters
- (void)setSendDisabled:(BOOL)sendDisabled {
self.userInteractionEnabled = !sendDisabled;
if (sendDisabled) {
self.inputView.text = @"";
NSAttributedString * attribute = [[NSAttributedString alloc] initWithString:_model == 2 ? @"互相关注成为好友可发起聊天" : @"暂时无法私聊" attributes:@{NSFontAttributeName : [UIFont systemFontOfSize:15], NSForegroundColorAttributeName : [ThemeColor secondTextColor]}];
self.inputView.attributedPlaceholder = attribute;
} else {
NSAttributedString * attribute = [[NSAttributedString alloc] initWithString:@"请输入消息" attributes:@{NSFontAttributeName : [UIFont systemFontOfSize:15], NSForegroundColorAttributeName : [ThemeColor secondTextColor]}];
self.inputView.attributedPlaceholder = attribute;
}
}
- (UIStackView *)stackView {
if (!_stackView) {
_stackView = [[UIStackView alloc] init];
_stackView.axis = UILayoutConstraintAxisVertical;
_stackView.distribution = UIStackViewDistributionFill;
_stackView.alignment = UIStackViewAlignmentFill;
_stackView.spacing = 0;
}
return _stackView;
}
- (UIStackView *)toolStackView {
if (!_toolStackView) {
_toolStackView = [[UIStackView alloc] init];
_toolStackView.axis = UILayoutConstraintAxisHorizontal;
_toolStackView.distribution = UIStackViewDistributionFill;
_toolStackView.alignment = UIStackViewAlignmentCenter;
_toolStackView.spacing = 8;
}
return _toolStackView;
}
- (UIButton *)changeButton {
if (!_changeButton) {
_changeButton = [UIButton buttonWithType:UIButtonTypeCustom];
[_changeButton setImage:[UIImage imageNamed:@"message_session_tool_text"] forState:UIControlStateNormal];
[_changeButton setImage:[UIImage imageNamed:@"message_session_tool_audio"] forState:UIControlStateSelected];
[_changeButton addTarget:self action:@selector(changeButtonAction:) forControlEvents:UIControlEventTouchUpInside];
}
return _changeButton;
}
- (UIStackView *)audioStackView {
if (!_audioStackView) {
_audioStackView = [[UIStackView alloc] init];
_audioStackView.axis = UILayoutConstraintAxisHorizontal;
_audioStackView.distribution = UIStackViewDistributionFill;
_audioStackView.alignment = UIStackViewAlignmentFill;
_audioStackView.spacing = 0;
}
return _audioStackView;
}
- (UIView *)inputBackView {
if (!_inputBackView) {
_inputBackView = [[UIView alloc] init];
_inputBackView.backgroundColor = UIColorFromRGB(0xF1F1FA);
_inputBackView.layer.masksToBounds = YES;
_inputBackView.layer.cornerRadius = 4;
}
return _inputBackView;
}
- (UITextField *)inputView{
if (!_inputView) {
_inputView = [[UITextField alloc] init];
NSAttributedString * attribute = [[NSAttributedString alloc] initWithString:@"请输入消息" attributes:@{NSFontAttributeName : [UIFont systemFontOfSize:15], NSForegroundColorAttributeName : [ThemeColor secondTextColor]}];
_inputView.attributedPlaceholder = attribute;
_inputView.borderStyle = UITextBorderStyleNone;
_inputView.tintColor = UIColorFromRGB(0xFFE710);
_inputView.textColor = [ThemeColor mainTextColor];
_inputView.font = [UIFont systemFontOfSize:12.f];
_inputView.delegate = self;
_inputView.autocorrectionType = UITextAutocorrectionTypeNo;
_inputView.returnKeyType = UIReturnKeySend;
}
return _inputView;
}
- (UIButton *)audioButton {
if (!_audioButton) {
_audioButton = [UIButton buttonWithType:UIButtonTypeCustom];
[_audioButton setTitle:@"按住说话" forState:UIControlStateNormal];
[_audioButton setTitle:@"松开结束" forState:UIControlStateSelected];
[_audioButton setTitleColor:[ThemeColor mainTextColor] forState:UIControlStateNormal];
_audioButton.titleLabel.font = [UIFont systemFontOfSize:14 weight:UIFontWeightMedium];
_audioButton.layer.masksToBounds = YES;
_audioButton.layer.cornerRadius = 4;
_audioButton.backgroundColor = UIColorFromRGB(0xF1F1FA);
_audioButton.hidden = YES;
}
return _audioButton;
}
- (UIButton *)moreButton {
if (!_moreButton) {
_moreButton = [UIButton buttonWithType:UIButtonTypeCustom];
[_moreButton setImage:[UIImage imageNamed:@"message_session_tool_more_normal"] forState:UIControlStateNormal];
[_moreButton setImage:[UIImage imageNamed:@"message_session_tool_more_select"] forState:UIControlStateSelected];
[_moreButton addTarget:self action:@selector(moreButtonAction:) forControlEvents:UIControlEventTouchUpInside];
}
return _moreButton;
}
- (UICollectionView *)collectionView{
if (!_collectionView) {
UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
layout.sectionInset = UIEdgeInsetsMake(0, 0, 0, 0);
layout.itemSize = CGSizeMake(48, 48);
layout.minimumLineSpacing = 24;
layout.minimumInteritemSpacing = 10;
_collectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:layout];
_collectionView.dataSource = self;
_collectionView.delegate = self;
_collectionView.backgroundColor = [UIColor clearColor];
_collectionView.hidden = YES;
[_collectionView registerClass:[MessageToolMenuCollectionViewCell class] forCellWithReuseIdentifier:NSStringFromClass([MessageToolMenuCollectionViewCell class])];
}
return _collectionView;
}
- (UIView *)placeView {
if (!_placeView) {
_placeView = [[UIView alloc] init];
_placeView.backgroundColor = [UIColor clearColor];
}
return _placeView;
}
- (NSArray<MessageMenuModel *> *)menuList {
if (!_menuList) {
MessageMenuModel * phototModel = [[MessageMenuModel alloc] init];
phototModel.imageName = @"message_session_menu_photo";
phototModel.type= MessageMenuType_Photo;
MessageMenuModel * giftModel = [[MessageMenuModel alloc] init];
giftModel.imageName = @"message_session_menu_gift";
giftModel.type= MessageMenuType_Gift;
_menuList = @[phototModel];
}
return _menuList;
}
- (SessionAudioRecordView *)audioRecordView {
if (!_audioRecordView) {
_audioRecordView = [[SessionAudioRecordView alloc] init];
}
return _audioRecordView;
}
@end

View File

@@ -23,20 +23,24 @@
/// Presenter /// Presenter
#import "MessagePresenter.h" #import "MessagePresenter.h"
#import "MessageProtocol.h" #import "MessageProtocol.h"
#import <TZImagePickerController/TZImagePickerController.h>
/// Model /// Model
#import "ChatLimitModel.h" #import "ChatLimitModel.h"
#import "UserInfoModel.h" #import "UserInfoModel.h"
#import "SessionInfoViewController.h"
#import "SessionToolbarView.h"
#import "NIMMessageMaker.h"
#import "MessageMenuModel.h"
@interface SessionViewController ()<SessionToolbarViewDelegate,SessionNavViewDelegate,SessionMessageCellDelegate,MessageProtocol,
@interface SessionViewController ()<SessionNavViewDelegate,SessionMessageCellDelegate,MessageProtocol,
UITableViewDelegate, UITableViewDataSource, UITableViewDelegate, UITableViewDataSource,
NIMChatManagerDelegate, NIMConversationManagerDelegate, NIMMediaManagerDelegate> NIMChatManagerDelegate, NIMConversationManagerDelegate, NIMMediaManagerDelegate,TZImagePickerControllerDelegate>
/// ///
@property (nonatomic,strong) SessionNavView *sessionNavView; @property (nonatomic,strong) SessionNavView *sessionNavView;
/// ///
@property (nonatomic, strong) UITableView * sessionTableView; @property (nonatomic, strong) UITableView * sessionTableView;
/// ///
//@property (nonatomic,strong) SessionToolbarView *toolbarView; @property (nonatomic,strong) SessionToolbarView *toolbarView;
// //
@property (nonatomic, strong) NIMSession * session; @property (nonatomic, strong) NIMSession * session;
@@ -50,14 +54,21 @@
@end @end
@implementation SessionViewController @implementation SessionViewController
- (BOOL)isHiddenNavBar {
return YES;
}
- (MessagePresenter *)createPresenter {
return [[MessagePresenter alloc] init];
}
#pragma mark - Life Cycle #pragma mark - Life Cycle
- (void)viewDidLoad { - (void)viewDidLoad {
[super viewDidLoad]; [super viewDidLoad];
[self initViews]; [self initViews];
self.view.backgroundColor = [UIColor whiteColor];
[[NIMSDK sharedSDK].chatManager addDelegate:self]; [[NIMSDK sharedSDK].chatManager addDelegate:self];
[[NIMSDK sharedSDK].conversationManager addDelegate:self]; [[NIMSDK sharedSDK].conversationManager addDelegate:self];
[self initHeaderAndFooterRefresh];
} }
- (void)viewWillAppear:(BOOL)animated { - (void)viewWillAppear:(BOOL)animated {
@@ -96,7 +107,9 @@
// //
- (void)sessionNavView:(SessionNavView *)view didClickReport:(UIButton *)sender { - (void)sessionNavView:(SessionNavView *)view didClickReport:(UIButton *)sender {
SessionInfoViewController * reportVC = [[SessionInfoViewController alloc] init];
reportVC.userId = self.session.sessionId;
[self.navigationController pushViewController:reportVC animated:YES];
} }
#pragma mark - SessionMessageCellDelegate(cell) #pragma mark - SessionMessageCellDelegate(cell)
@@ -237,17 +250,36 @@
#pragma mark - UITableViewDelegate, UITableViewDataSource #pragma mark - UITableViewDelegate, UITableViewDataSource
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.messages.count; return self.messages.count;
} }
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { - (nonnull UITableViewCell *)tableView:(nonnull UITableView *)tableView cellForRowAtIndexPath:(nonnull NSIndexPath *)indexPath {
SessionMessageCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([SessionMessageCell class])]; NIMMessage * message = [self.messages safeObjectAtIndex1:indexPath.row];
NSString * identifier = [SessionMessageCell cellContent:message];
///cell
SessionMessageCell * cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (!cell) {
/// identifier
[tableView registerClass:[SessionMessageCell class] forCellReuseIdentifier:identifier];
/// cell
cell = [tableView dequeueReusableCellWithIdentifier:identifier];
}
cell.delegate = self; cell.delegate = self;
cell.selectionStyle = 0;
[cell renderWithMessage:[self.messages safeObjectAtIndex1:indexPath.row]];
return cell; return cell;
} }
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
NIMMessage *msg = [self.messages safeObjectAtIndex1:indexPath.row];
return [SessionMessageCell measureHeight:msg];
}
#pragma mark - Private Method () #pragma mark - Private Method ()
/// ///
@@ -323,6 +355,8 @@
#pragma mark - Init View #pragma mark - Init View
- (void)initViews { - (void)initViews {
[self.view addSubview:self.sessionNavView]; [self.view addSubview:self.sessionNavView];
[self.view addSubview:self.sessionTableView];
[self.view addSubview:self.toolbarView];
[self initLayout]; [self initLayout];
@@ -332,8 +366,84 @@
make.height.mas_equalTo(kNavigationHeight); make.height.mas_equalTo(kNavigationHeight);
make.left.top.right.mas_equalTo(self.view); make.left.top.right.mas_equalTo(self.view);
}]; }];
[self.toolbarView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.right.mas_equalTo(self.view);
make.bottom.mas_equalTo(self.view);
}];
[self.sessionTableView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.right.mas_equalTo(self.view);
make.top.mas_equalTo(self.sessionNavView.mas_bottom).mas_offset(10);
make.bottom.mas_equalTo(self.toolbarView.mas_top);
}];
}
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
[self.toolbarView foldMenuView];
}
#pragma mark - MessageToolbarViewDelegate
- (void)keyboardWillChangeFrame:(CGRect)rect {
CGFloat heightFromBottom = rect.size.height;
heightFromBottom = MAX(0.0, heightFromBottom);
[self.toolbarView mas_updateConstraints:^(MASConstraintMaker *make) {
make.bottom.mas_equalTo(self.view).offset(-heightFromBottom);
}];
[self.sessionTableView nim_scrollToBottom:NO];
} }
- (void)sendTextMessage:(NSString *)text {
NIMMessage *message = [NIMMessageMaker msgWithText:text];
[[[NIMSDK sharedSDK] chatManager] sendMessage:message toSession:self.session error:nil];
}
- (void)didSelectMenuItem:(MessageMenuModel *)info {
UIWindow * currentWindow;
for (int i = 0; i < [UIApplication sharedApplication].windows.count; i++) {
UIWindow * window = [[UIApplication sharedApplication].windows safeObjectAtIndex1:i];
if(window.tag == 1000) {
currentWindow = window;
break;
}
}
if (currentWindow) {
currentWindow.windowLevel = -1;
}
switch (info.type) {
case MessageMenuType_Photo:
{
TZImagePickerController *imagePickerVc = [[TZImagePickerController alloc] initWithMaxImagesCount:1 delegate:self];
imagePickerVc.modalPresentationStyle = UIModalPresentationOverFullScreen;
imagePickerVc.allowPickingVideo = NO;
imagePickerVc.allowTakeVideo = NO;
imagePickerVc.naviBgColor = [ThemeColor appCellBackgroundColor];
imagePickerVc.naviTitleColor = [ThemeColor mainTextColor];
imagePickerVc.barItemTextColor = [ThemeColor mainTextColor];
[self presentViewController:imagePickerVc animated:YES completion:nil];
}
break;
default:
break;
}
}
- (void)audioRecordCompletion:(NSString *)recordPath {
NIMMessage *message = [NIMMessageMaker msgWithAudio:recordPath];
[[[NIMSDK sharedSDK] chatManager] sendMessage:message toSession:self.session error:nil];
}
#pragma mark - TZImagePickerControllerDelegate
- (void)imagePickerController:(TZImagePickerController *)picker didFinishPickingPhotos:(NSArray<UIImage *> *)photos sourceAssets:(NSArray *)assets isSelectOriginalPhoto:(BOOL)isSelectOriginalPhoto infos:(NSArray<NSDictionary *> *)infos {
[photos enumerateObjectsUsingBlock:^(UIImage * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
if (obj) {
//
NIMMessage * message = [NIMMessageMaker msgWithImage:obj];
//
[[NIMSDK sharedSDK].chatManager sendMessage:message toSession:self.session error:nil];
}
}];
}
#pragma mark - Get #pragma mark - Get
- (SessionNavView *)sessionNavView { - (SessionNavView *)sessionNavView {
if (!_sessionNavView) { if (!_sessionNavView) {
@@ -348,7 +458,7 @@
_sessionTableView = [[UITableView alloc] init]; _sessionTableView = [[UITableView alloc] init];
_sessionTableView.delegate = self; _sessionTableView.delegate = self;
_sessionTableView.dataSource = self; _sessionTableView.dataSource = self;
_sessionTableView.backgroundColor = UIColor.clearColor; _sessionTableView.backgroundColor = UIColorFromRGB(0xF8F8FB);
_sessionTableView.separatorStyle = UITableViewCellSeparatorStyleNone; _sessionTableView.separatorStyle = UITableViewCellSeparatorStyleNone;
_sessionTableView.showsVerticalScrollIndicator = NO; _sessionTableView.showsVerticalScrollIndicator = NO;
[_sessionTableView registerClass:[SessionMessageCell class] forCellReuseIdentifier:NSStringFromClass([SessionMessageCell class])]; [_sessionTableView registerClass:[SessionMessageCell class] forCellReuseIdentifier:NSStringFromClass([SessionMessageCell class])];
@@ -364,5 +474,12 @@
} }
return _messages; return _messages;
} }
- (SessionToolbarView *)toolbarView {
if (!_toolbarView) {
_toolbarView = [[SessionToolbarView alloc] init];
_toolbarView.delegate = self;
_toolbarView.sendDisabled = NO;
}
return _toolbarView;
}
@end @end