增加换肤功能

This commit is contained in:
启星
2025-08-14 10:07:49 +08:00
parent f6964c1e89
commit 4f9318d98e
8789 changed files with 978530 additions and 2 deletions

View File

@@ -0,0 +1,16 @@
//
// TUICustomerServicePluginAccountController.h
// TUICustomerServicePlugin
//
// Created by xia on 2023/6/21.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface TUICustomerServicePluginAccountController : UITableViewController
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,115 @@
//
// TUICustomerServicePluginAccountController.m
// TUICustomerServicePlugin
//
// Created by xia on 2023/6/21.
//
#import "TUICustomerServicePluginAccountController.h"
#import <TIMCommon/TIMDefine.h>
#import <TUICore/TUIThemeManager.h>
#import "ReactiveObjC.h"
#import <TUIContact/TUICommonContactCell.h>
#import "TUICustomerServicePluginPrivateConfig.h"
#import <TUIChat/TUIChatConversationModel.h>
#import <TUIChat/TUIC2CChatViewController.h>
@interface TUICustomerServicePluginAccountController()
@property (nonatomic, strong) NSMutableArray *cellDatas;
@end
@implementation TUICustomerServicePluginAccountController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = TIMCommonDynamicColor(@"controller_bg_color", @"#F2F3F5");
UILabel *titleLabel = [[UILabel alloc] init];
titleLabel.text = TIMCommonLocalizableString(TUICustomerServiceAccounts);
titleLabel.font = [UIFont boldSystemFontOfSize:17.0];
titleLabel.textColor = TIMCommonDynamicColor(@"nav_title_text_color", @"#000000");
[titleLabel sizeToFit];
self.navigationItem.titleView = titleLabel;
[self.tableView registerClass:[TUICommonContactCell class] forCellReuseIdentifier:@"CustomerServiceCell"];
self.tableView.tableFooterView = [UIView new];
self.tableView.backgroundColor = self.view.backgroundColor;
self.tableView.rowHeight = 56;
[self getUserInfo];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.cellDatas.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
TUICommonContactCell *cell = [tableView dequeueReusableCellWithIdentifier:@"CustomerServiceCell"
forIndexPath:indexPath];
if (self.cellDatas.count == 0) {
return nil;
}
TUICommonContactCellData *data = self.cellDatas[indexPath.row];
data.cselector = @selector(didSelectCustomerServiceAccount:);
[cell fillWithData:data];
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 56;
}
#pragma mark - Event response
- (void)didSelectCustomerServiceAccount:(TUICommonContactCell *)cell {
NSString *userID = cell.contactData.identifier;
if (userID.length == 0) {
return;
}
TUIChatConversationModel *conversationModel = [[TUIChatConversationModel alloc] init];
conversationModel.userID = userID;
conversationModel.conversationID = [NSString stringWithFormat:@"c2c_%@", userID];
TUIC2CChatViewController *chatVC = [[TUIC2CChatViewController alloc] init];
chatVC.conversationData = conversationModel;
chatVC.title = conversationModel.title;
[self.navigationController pushViewController:chatVC animated:YES];
}
- (void)getUserInfo {
NSArray *accounts = TUICustomerServicePluginPrivateConfig.sharedInstance.customerServiceAccounts;
[[V2TIMManager sharedInstance] getUsersInfo:accounts
succ:^(NSArray<V2TIMUserFullInfo *> *infoList) {
for (NSString *account in accounts) {
for (V2TIMUserFullInfo *info in infoList) {
if ([account isEqualToString:info.userID]) {
TUICommonContactCellData *data = [TUICommonContactCellData new];
data.identifier = info.userID;
data.avatarUrl = [NSURL URLWithString:info.faceURL];
data.title = (info.nickName.length > 0 ? info.nickName : info.userID);
[self.cellDatas addObject:data];
break;
}
}
}
[self.tableView reloadData];
} fail:^(int code, NSString *desc) {
}];
}
#pragma mark - Getter
- (NSMutableArray *)cellDatas {
if (!_cellDatas) {
_cellDatas = [[NSMutableArray alloc] init];
}
return _cellDatas;
}
@end

View File

@@ -0,0 +1,30 @@
//
// TUICustomerServicePluginCardInputView.h
// Masonry
//
// Created by xia on 2023/6/13.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface TUICustomerServicePluginCardInputItemCell : UITableViewCell
@property (nonatomic, strong) UILabel *descLabel;
@property (nonatomic, strong) UITextField *inputTextField;
@end
@interface TUICustomerServicePluginCardInputView : UIView
@property (nonatomic, strong) UIView *backView;
@property (nonatomic, strong) UILabel *headerLabel;
@property (nonatomic, strong) UITableView *itemsTableView;
@property (nonatomic, strong) UIButton *submitButton;
@property (nonatomic, strong) UIButton *closeButton;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,361 @@
//
// TUICustomerServicePluginCardInputView.m
// Masonry
//
// Created by xia on 2023/6/13.
//
#import "TUICustomerServicePluginCardInputView.h"
#import "TUICustomerServicePluginDataProvider.h"
#import <TUICore/TUIDefine.h>
#import <TIMCommon/TIMDefine.h>
@interface TUICustomerServicePluginCardInputItemCell()
@end
@implementation TUICustomerServicePluginCardInputItemCell
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
self.backgroundColor = [UIColor clearColor];
self.contentView.backgroundColor = [UIColor clearColor];
_descLabel = [[UILabel alloc] init];
_descLabel.font = [UIFont systemFontOfSize:14];
_descLabel.numberOfLines = 1;
_descLabel.lineBreakMode = NSLineBreakByTruncatingTail;
_descLabel.textColor = TUICustomerServicePluginDynamicColor(@"customer_service_card_item_desc_text_color", @"#999999");
[self.contentView addSubview:_descLabel];
_inputTextField = [[UITextField alloc] init];
_inputTextField.backgroundColor = TUICustomerServicePluginDynamicColor(@"customer_service_card_input_bg_color", @"#F9F9F9");
_inputTextField.layer.cornerRadius = 8;
_inputTextField.layer.masksToBounds = YES;
_inputTextField.textColor = TUICustomerServicePluginDynamicColor(@"customer_service_card_input_text_color", @"#000000");
_inputTextField.font = [UIFont systemFontOfSize:14];
_inputTextField.clearButtonMode = UITextFieldViewModeWhileEditing;
[self.contentView addSubview:_inputTextField];
UIView *blankView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 16, 20)];
blankView.backgroundColor = [UIColor clearColor];
_inputTextField.leftViewMode = UITextFieldViewModeAlways;
_inputTextField.leftView = blankView;
}
return self;
}
- (void)updateConstraints {
[super updateConstraints];
[self.descLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.leading.mas_equalTo(20);
make.top.mas_equalTo(12);
make.width.mas_equalTo(40);
make.height.mas_equalTo(21);
}];
[self.inputTextField mas_makeConstraints:^(MASConstraintMaker *make) {
make.leading.mas_equalTo(self.descLabel.mas_trailing).offset(8);
make.top.mas_equalTo(0);
make.width.mas_equalTo(self.mm_w - self.descLabel.mm_maxX - 20);
make.height.mas_equalTo(46);
}];
}
@end
@interface TUICustomerServicePluginCardInputView()<UITableViewDelegate, UITableViewDataSource>
@property (nonatomic, strong) NSArray *defaultInfo;
@property(nonatomic, assign) BOOL isKeyboardVisible;
@property(nonatomic, assign) CGRect oldFrame;
@end
@implementation TUICustomerServicePluginCardInputView
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
[self setupViews];
[self addNotification];
}
return self;
}
- (void)setupViews {
UIColor *color = TUICustomerServicePluginDynamicColor(@"customer_service_card_bg_color", @"#000000");
self.backgroundColor = [color colorWithAlphaComponent:0.5];
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onTapped:)];
[self addGestureRecognizer:tap];
[self addSubview:self.backView];
[self.backView addSubview:self.headerLabel];
[self.backView addSubview:self.itemsTableView];
[self.backView addSubview:self.submitButton];
[self.backView addSubview:self.closeButton];
// tell constraints they need updating
[self setNeedsUpdateConstraints];
// update constraints now so we can animate the change
[self updateConstraintsIfNeeded];
[self layoutIfNeeded];
}
- (void)addNotification {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidHide:) name:UIKeyboardDidHideNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidShow:) name:UIKeyboardDidShowNotification object:nil];
}
- (void)onTapped:(UITapGestureRecognizer *)recognizer {
[self endEditing:YES];
}
- (void)updateConstraints {
[super updateConstraints];
[self.backView mas_makeConstraints:^(MASConstraintMaker *make) {
make.leading.mas_equalTo(0);
make.top.mas_equalTo(Screen_Height - 378);
make.width.mas_equalTo(Screen_Width);
make.height.mas_equalTo(378);
}];
[self.headerLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.leading.mas_equalTo(20);
make.top.mas_equalTo(20);
make.width.mas_equalTo(300);
make.height.mas_equalTo(25);
}];
[self.closeButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.trailing.mas_equalTo(20);
make.top.mas_equalTo(22);
make.width.mas_equalTo(50);
make.height.mas_equalTo(24);
}];
float tableViewHeight = self.defaultInfo.count * self.itemsTableView.rowHeight;
[self.itemsTableView mas_makeConstraints:^(MASConstraintMaker *make) {
make.leading.mas_equalTo(0);
make.top.mas_equalTo(self.headerLabel.mas_bottom).offset(20);
make.width.mas_equalTo(self.backView.mas_width);
make.height.mas_equalTo(tableViewHeight);
}];
[self.submitButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.leading.mas_equalTo(20);
make.top.mas_equalTo(self.itemsTableView.mas_bottom).offset(20);
make.width.mas_equalTo(self.backView.mas_width).offset(-20 * 2);
make.height.mas_equalTo(46);
}];
}
#pragma mark - UITableViewDelegate & UITableViewDataSource
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.defaultInfo.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if (self.defaultInfo.count <= indexPath.row) {
return nil;
}
NSDictionary *info = self.defaultInfo[indexPath.row];
TUICustomerServicePluginCardInputItemCell *cell = [tableView dequeueReusableCellWithIdentifier:@"item_cell" forIndexPath:indexPath];
cell.descLabel.text = info[@"desc"];
cell.inputTextField.placeholder = info[@"placeHolder"];
// TODO: debug
if (info[@"content"]) {
cell.inputTextField.text = info[@"content"];
}
// tell constraints they need updating
[self setNeedsUpdateConstraints];
// update constraints now so we can animate the change
[self updateConstraintsIfNeeded];
[self layoutIfNeeded];
return cell;
}
#pragma mark - Keyboard
- (void)keyboardWillShow:(NSNotification *)notification {
if (self.isKeyboardVisible) {
return;
}
self.oldFrame = self.backView.frame;
NSValue *keyBoardEndFrame = [[notification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey];
CGRect endFrame = [keyBoardEndFrame CGRectValue];
[UIView animateWithDuration:0.25
delay:0
options:UIViewAnimationOptionCurveEaseOut
animations:^{
[self setFrame:CGRectMake(self.frame.origin.x,
self.frame.origin.y - endFrame.size.height,
self.frame.size.width,
self.frame.size.height)];
}
completion:nil];
}
- (void)keyboardDidShow:(NSNotification *)notification {
self.isKeyboardVisible = YES;
}
- (void)keyboardWillHide:(NSNotification *)notification {
if (!self.isKeyboardVisible) {
return;
}
[UIView animateWithDuration:0.25
delay:0
options:UIViewAnimationOptionCurveEaseOut
animations:^{
[self setFrame:CGRectMake(0, 0, self.oldFrame.size.width, self.oldFrame.size.height)];
}
completion:nil];
}
- (void)keyboardDidHide:(NSNotification *)notification {
self.isKeyboardVisible = NO;
}
#pragma mark - Getter
- (UIView *)backView {
if (!_backView) {
_backView = [[UIView alloc] init];
_backView.backgroundColor = TUICustomerServicePluginDynamicColor(@"customer_service_card_backview_bg_color", @"#FFFFFF");
}
return _backView;
}
- (UILabel *)headerLabel {
if (!_headerLabel) {
_headerLabel = [[UILabel alloc] init];
_headerLabel.font = [UIFont systemFontOfSize:18];
_headerLabel.numberOfLines = 0;
_headerLabel.lineBreakMode = NSLineBreakByTruncatingTail;
_headerLabel.text = TIMCommonLocalizableString(TUICustomerServiceFillProductInfo);
_headerLabel.textColor = TUICustomerServicePluginDynamicColor(@"customer_service_card_header_text_color", @"#000000");
}
return _headerLabel;
}
- (UITableView *)itemsTableView {
if (!_itemsTableView) {
_itemsTableView = [[UITableView alloc] init];
_itemsTableView.tableFooterView = [[UIView alloc] init];
// _itemsTableView.backgroundColor = TUICoreDynamicColor(@"customer_service_brance_bg_color", @"#FFFFFF");
_itemsTableView.backgroundColor = [UIColor clearColor];
_itemsTableView.delegate = self;
_itemsTableView.dataSource = self;
_itemsTableView.separatorStyle = UITableViewCellSeparatorStyleNone;
_itemsTableView.rowHeight = 56;
[_itemsTableView registerClass:[TUICustomerServicePluginCardInputItemCell class] forCellReuseIdentifier:@"item_cell"];
}
return _itemsTableView;
}
- (UIButton *)submitButton {
if (!_submitButton) {
_submitButton = [UIButton new];
[_submitButton setTitle:TIMCommonLocalizableString(TUICustomerServiceSubmitProductInfo) forState:UIControlStateNormal];
_submitButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;
_submitButton.titleLabel.font = [UIFont systemFontOfSize:16];
[_submitButton setTitleColor:TUICustomerServicePluginDynamicColor(@"customer_service_card_submit_text_color", @"#FFFFFF")
forState:UIControlStateNormal];
_submitButton.layer.cornerRadius = 4;
_submitButton.layer.masksToBounds = YES;
[_submitButton setBackgroundColor:TUICustomerServicePluginDynamicColor(@"customer_service_card_submit_bg_color", @"#006EFF")];
[_submitButton addTarget:self
action:@selector(onSubmitButtonClicked:)
forControlEvents:UIControlEventTouchUpInside];
}
return _submitButton;
}
- (void)onSubmitButtonClicked:(UIButton *)sender {
NSString *header = [self getCellOfRow:0].inputTextField.text;
NSString *desc = [self getCellOfRow:1].inputTextField.text;
NSString *pic = [self getCellOfRow:2].inputTextField.text;
NSString *url = [self getCellOfRow:3].inputTextField.text;
// TODO:
if (header.length == 0 || desc.length == 0 || pic.length == 0) {
return;
}
NSDictionary *dict = @{@"src": BussinessID_Src_CustomerService_Card,
@"content": @{@"header": header,
@"desc": desc,
@"pic": pic,
@"url": url}
};
NSData *data = [TUITool dictionary2JsonData:dict];
[TUICustomerServicePluginDataProvider sendCustomMessage:data];
[self removeFromSuperview];
}
- (TUICustomerServicePluginCardInputItemCell *)getCellOfRow:(int)row {
if (row >= self.defaultInfo.count) {
return nil;
}
NSIndexPath *index = [NSIndexPath indexPathForRow:row inSection:0];
return (TUICustomerServicePluginCardInputItemCell *)[self.itemsTableView cellForRowAtIndexPath:index];
}
- (UIButton *)closeButton {
if (!_closeButton) {
_closeButton = [UIButton new];
[_closeButton setTitle:TIMCommonLocalizableString(TUICustomerServiceClose) forState:UIControlStateNormal];
_closeButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;
_closeButton.titleLabel.font = [UIFont systemFontOfSize:16];
[_closeButton setTitleColor:TUICustomerServicePluginDynamicColor(@"customer_service_card_close_text_color", @"#3370FF")
forState:UIControlStateNormal];
[_closeButton addTarget:self
action:@selector(onCloseButtonClicked:)
forControlEvents:UIControlEventTouchUpInside];
}
return _closeButton;
}
- (void)onCloseButtonClicked:(UIButton *)sender {
[self removeFromSuperview];
}
- (NSArray *)defaultInfo {
return @[
@{@"desc": TIMCommonLocalizableString(TUICustomerServiceName),
@"placeHolder": TIMCommonLocalizableString(TUICustomerServiceFillProductName),
@"content": @"手工编织皮革提包2023新品女士迷你简约大方高端有档次"
},
@{@"desc": TIMCommonLocalizableString(TUICustomerServiceDesc),
@"placeHolder": TIMCommonLocalizableString(TUICustomerServiceFillProductDesc),
@"content": @"¥788"
},
@{@"desc": TIMCommonLocalizableString(TUICustomerServicePic),
@"placeHolder": TIMCommonLocalizableString(TUICustomerServiceFillPicLink),
@"content": @"https://qcloudimg.tencent-cloud.cn/raw/a811f634eab5023f973c9b224bc07a51.png"
},
@{@"desc": TIMCommonLocalizableString(TUICustomerServiceJumpLink),
@"placeHolder": TIMCommonLocalizableString(TUICustomerServiceFillJumpLink),
@"content": @"https://cloud.tencent.com/document/product/269"
}
];
}
@end

View File

@@ -0,0 +1,38 @@
//
// TUICustomerServicePluginMenuView.h
// TUICustomerServicePlugin
//
// Created by xia on 2023/6/29.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface TUICustomerServicePluginMenuCellData : NSObject
@property (nonatomic, strong) NSString *title;
@property (nonatomic, assign) SEL cselector;
@property (nonatomic, strong) id target;
- (CGSize)calcSize;
@end
@interface TUICustomerServicePluginMenuCell : UICollectionViewCell
@property (nonatomic, strong) UIButton *button;
@property (nonatomic, strong) TUICustomerServicePluginMenuCellData *cellData;
@end
@interface TUICustomerServicePluginMenuView : UIView
- (instancetype)initWithDataSource:(NSArray *)source;
- (void)updateFrame;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,159 @@
//
// TUICustomerServicePluginMenuView.m
// TUICustomerServicePlugin
//
// Created by xia on 2023/6/29.
//
#import "TUICustomerServicePluginMenuView.h"
#import <TUICore/TUICore.h>
#import <TUICore/TUIDefine.h>
#import <TIMCommon/TIMDefine.h>
#import "TUICustomerServicePluginDataProvider+CalculateSize.h"
@interface TUICustomerServicePluginMenuCellData()
@end
@implementation TUICustomerServicePluginMenuCellData
- (CGSize)calcSize {
return [TUICustomerServicePluginDataProvider calcMenuCellSize:self.title];
}
@end
@interface TUICustomerServicePluginMenuCell()
@end
@implementation TUICustomerServicePluginMenuCell
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
self.button = [UIButton new];
self.button.layer.borderWidth = 1.0;
self.button.layer.borderColor = TUICustomerServicePluginDynamicColor(@"customer_service_menu_button_border_color", @"#C5CBD4").CGColor;
self.button.layer.cornerRadius = 16;
self.button.titleLabel.font = [UIFont systemFontOfSize:14];
[self.button setTitleColor:TUICustomerServicePluginDynamicColor(@"customer_service_menu_button_text_color", @"#8F959E") forState:UIControlStateNormal];
self.button.backgroundColor = TUICustomerServicePluginDynamicColor(@"customer_service_menu_button_bg_color", @"#F6F7F9");
[self addSubview:self.button];
}
return self;
}
- (void)fillWithData:(TUICustomerServicePluginMenuCellData *)cellData {
self.cellData = cellData;
[self.button setTitle:cellData.title forState:UIControlStateNormal];
[self.button addTarget:cellData.target action:cellData.cselector forControlEvents:UIControlEventTouchUpInside];
// tell constraints they need updating
[self setNeedsUpdateConstraints];
// update constraints now so we can animate the change
[self updateConstraintsIfNeeded];
[self layoutIfNeeded];
}
- (void)updateConstraints {
[super updateConstraints];
CGSize size = [TUICustomerServicePluginDataProvider calcMenuCellButtonSize:self.cellData.title];
[self.button mas_makeConstraints:^(MASConstraintMaker *make) {
make.leading.mas_equalTo(12);
make.top.mas_equalTo(8);
make.width.mas_equalTo(size.width);
make.height.mas_equalTo(size.height);
}];
}
@end
@interface TUICustomerServicePluginMenuView() <UICollectionViewDelegate, UICollectionViewDataSource>
@property (nonatomic, strong) UICollectionView *backView;
@property (nonatomic, strong) NSMutableArray *dataSource;
@end
@implementation TUICustomerServicePluginMenuView
- (instancetype)initWithDataSource:(NSArray *)source {
self = [super init];
if (self) {
self.dataSource = [source mutableCopy];
[self setupViews];
}
return self;
}
- (void)setupViews {
self.backgroundColor = TUIChatDynamicColor(@"chat_input_controller_bg_color", @"#EBF0F6");
[self addSubview:self.backView];
}
#pragma mark - Public
- (void)updateFrame {
self.mm_left(0).mm_top(0).mm_width(Screen_Width).mm_height(46);
self.backView.mm_fill();
}
#pragma mark - Getter
- (UICollectionView *)backView {
if (!_backView) {
UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
[layout setScrollDirection:UICollectionViewScrollDirectionHorizontal];
_backView = [[UICollectionView alloc] initWithFrame:self.bounds collectionViewLayout:layout];
_backView.delegate = self;
_backView.dataSource = self;
_backView.scrollEnabled = YES;
_backView.backgroundColor = [UIColor clearColor];
_backView.showsHorizontalScrollIndicator = NO;
[_backView registerClass:[TUICustomerServicePluginMenuCell class] forCellWithReuseIdentifier:@"menuCell"];
}
return _backView;
}
#pragma mark - UICollectionViewDataSource & Delegate
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
return 1;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return self.dataSource.count;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
TUICustomerServicePluginMenuCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"menuCell" forIndexPath:indexPath];
TUICustomerServicePluginMenuCellData *cellData = self.dataSource[indexPath.row];
[cell fillWithData:cellData];
return cell;
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
TUICustomerServicePluginMenuCellData *cellData = self.dataSource[indexPath.row];
return [cellData calcSize];
}
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
return UIEdgeInsetsMake(0, 0, 0, 0);
}
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section {
return 0;
}
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section {
return 0;
}
- (BOOL)collectionView:(UICollectionView *)collectionView shouldSelectItemAtIndexPath:(NSIndexPath *)indexPath {
return YES;
}
@end

View File

@@ -0,0 +1,19 @@
//
// TUICustomerServicePluginPhraseView.h
// TUICustomerServicePlugin
//
// Created by xia on 2023/7/4.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface TUICustomerServicePluginPhraseView : UIView
@property (nonatomic, strong) UIView *backView;
@property (nonatomic, strong) UITableView *itemsTableView;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,145 @@
//
// TUICustomerServicePluginPhraseView.m
// TUICustomerServicePlugin
//
// Created by xia on 2023/7/4.
//
#import "TUICustomerServicePluginPhraseView.h"
#import "TUICustomerServicePluginDataProvider.h"
#import <TUICore/TUIDefine.h>
#import <TIMCommon/TIMDefine.h>
@interface TUICustomerServicePluginPhraseView() <UITableViewDelegate, UITableViewDataSource, UIGestureRecognizerDelegate>
@end
@implementation TUICustomerServicePluginPhraseView
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
[self setupViews];
}
return self;
}
- (void)setupViews {
UIColor *color = TUICustomerServicePluginDynamicColor(@"customer_service_phrase_bg_color", @"#000000");
self.backgroundColor = [color colorWithAlphaComponent:0.5];
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onTapped:)];
tap.delegate = self;
[self addGestureRecognizer:tap];
[self addSubview:self.backView];
[self.backView addSubview:self.itemsTableView];
// tell constraints they need updating
[self setNeedsUpdateConstraints];
// update constraints now so we can animate the change
[self updateConstraintsIfNeeded];
[self layoutIfNeeded];
}
- (void)setupCorners {
UIRectCorner corners = UIRectCornerTopLeft | UIRectCornerTopRight;
UIBezierPath *bezierPath = [UIBezierPath bezierPathWithRoundedRect:self.backView.bounds byRoundingCorners:corners cornerRadii:CGSizeMake(8, 8)];
CAShapeLayer *layer = [[CAShapeLayer alloc] init];
layer.path = bezierPath.CGPath;
self.backView.layer.mask = layer;
}
- (void)updateConstraints {
[super updateConstraints];
float tableViewHeight = 5 * self.itemsTableView.rowHeight;
[self.backView mas_remakeConstraints:^(MASConstraintMaker *make) {
make.leading.mas_equalTo(0);
make.top.mas_equalTo(self.mas_bottom).offset(-tableViewHeight);
make.width.mas_equalTo(self.mas_width);
make.height.mas_equalTo(223);
}];
self.itemsTableView.mm_fill();
[self setupCorners];
}
- (void)onTapped:(UITapGestureRecognizer *)recognizer {
[self removeFromSuperview];
}
#pragma mark - UIGestureRecognizerDelegate
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
if ([touch.view isDescendantOfView:self.itemsTableView]) {
return NO;
}
return YES;
}
#pragma mark - UITableViewDelegate & UITableViewDataSource
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.defaultInfo.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if (self.defaultInfo.count <= indexPath.row) {
return nil;
}
NSString *phrase = self.defaultInfo[indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"item_cell" forIndexPath:indexPath];
cell.textLabel.text = phrase;
cell.textLabel.font = [UIFont systemFontOfSize:14];
cell.textLabel.textColor = TUICustomerServicePluginDynamicColor(@"customer_service_phrase_text_color", @"#000000");
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (self.defaultInfo.count <= indexPath.row) {
return;
}
NSString *phase = self.defaultInfo[indexPath.row];
[TUICustomerServicePluginDataProvider sendTextMessage:phase];
[self removeFromSuperview];
}
#pragma mark - Getter
- (UIView *)backView {
if (!_backView) {
_backView = [[UIView alloc] init];
_backView.backgroundColor = TUICustomerServicePluginDynamicColor(@"customer_service_phrase_backview_bg_color", @"#FFFFFF");
}
return _backView;
}
- (UITableView *)itemsTableView {
if (!_itemsTableView) {
_itemsTableView = [[UITableView alloc] init];
_itemsTableView.tableFooterView = [[UIView alloc] init];
_itemsTableView.backgroundColor = [UIColor clearColor];
_itemsTableView.delegate = self;
_itemsTableView.dataSource = self;
_itemsTableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
_itemsTableView.rowHeight = 44;
_itemsTableView.bounces = NO;
[_itemsTableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"item_cell"];
}
return _itemsTableView;
}
- (NSArray *)defaultInfo {
return @[
TIMCommonLocalizableString(TUICustomerServiceCommonPhraseStock),
TIMCommonLocalizableString(TUICustomerServiceCommonPhraseCheaper),
TIMCommonLocalizableString(TUICustomerServiceCommonPhraseGift),
TIMCommonLocalizableString(TUICustomerServiceCommonPhraseShipping),
TIMCommonLocalizableString(TUICustomerServiceCommonPhraseDelivery),
TIMCommonLocalizableString(TUICustomerServiceCommonPhraseArrive),
];
}
@end

View File

@@ -0,0 +1,20 @@
//
// TUICustomerServicePluginUserController.h
// TUICustomerServicePlugin
//
// Created by xia on 2023/7/6.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@class V2TIMUserInfo;
@interface TUICustomerServicePluginUserController : UITableViewController
- (instancetype)initWithUserInfo:(V2TIMUserInfo *)userInfo;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,238 @@
//
// TUICustomerServicePluginUserController.m
// TUICustomerServicePlugin
//
// Created by xia on 2023/7/6.
//
#import "TUICustomerServicePluginUserController.h"
#import <TIMCommon/TIMCommonModel.h>
#import <TUIContact/TUICommonContactTextCell.h>
#import <TUIContact/TUICommonContactSwitchCell.h>
#import <TUIContact/TUICommonContactProfileCardCell.h>
#import <TUICore/TUICore.h>
@interface TUICustomerServicePluginUserController ()
@property (nonatomic, copy) NSArray<NSArray *> *dataList;
@property (nonatomic, strong) TUINaviBarIndicatorView *titleView;
@property (nonatomic, strong) V2TIMUserInfo *userInfo;
@end
@implementation TUICustomerServicePluginUserController
- (instancetype)initWithUserInfo:(V2TIMUserInfo *)userInfo {
self = [super init];
if (self) {
self.userInfo = userInfo;
}
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
[self addLongPressGesture];
if (@available(iOS 15.0, *)) {
self.tableView.sectionHeaderTopPadding = 0;
}
self.tableView.backgroundColor = TIMCommonDynamicColor(@"controller_bg_color", @"#F2F3F5");
[self.tableView registerClass:[TUICommonContactTextCell class] forCellReuseIdentifier:@"TextCell"];
[self.tableView registerClass:[TUICommonContactSwitchCell class] forCellReuseIdentifier:@"SwitchCell"];
[self.tableView registerClass:[TUICommonContactProfileCardCell class] forCellReuseIdentifier:@"CardCell"];
self.tableView.delaysContentTouches = NO;
_titleView = [[TUINaviBarIndicatorView alloc] init];
[_titleView setTitle:TIMCommonLocalizableString(ProfileDetails)];
self.navigationItem.titleView = _titleView;
self.navigationItem.title = @"";
[self loadData];
}
- (void)loadData {
NSMutableArray *list = @[].mutableCopy;
[list addObject:({
NSMutableArray *inlist = @[].mutableCopy;
[inlist addObject:({
TUICommonContactProfileCardCellData *personal = [[TUICommonContactProfileCardCellData alloc] init];
personal.identifier = self.userInfo.userID;
personal.avatarImage = DefaultAvatarImage;
personal.avatarUrl = [NSURL URLWithString:self.userInfo.faceURL];
personal.name = self.userInfo.nickName;
personal.signature = TIMCommonLocalizableString(no_personal_signature);
personal.reuseId = @"CardCell";
personal.showSignature = YES;
personal;
})];
inlist;
})];
[list addObject:({
NSMutableArray *inlist = @[].mutableCopy;
[inlist addObject:({
TUICommonContactSwitchCellData *data = TUICommonContactSwitchCellData.new;
data.title = TIMCommonLocalizableString(ProfileMessageDoNotDisturb);
data.cswitchSelector = @selector(onMessageDoNotDisturb:);
data.reuseId = @"SwitchCell";
__weak typeof(self) weakSelf = self;
[[V2TIMManager sharedInstance] getC2CReceiveMessageOpt:@[ self.userInfo.userID ]
succ:^(NSArray<V2TIMUserReceiveMessageOptInfo *> *optList) {
for (V2TIMReceiveMessageOptInfo *info in optList) {
if ([info.userID isEqual:self.userInfo.userID]) {
data.on = (info.receiveOpt == V2TIM_RECEIVE_NOT_NOTIFY_MESSAGE);
[weakSelf.tableView reloadData];
break;
}
}
}
fail:nil];
data;
})];
inlist;
})];
[list addObject:({
NSMutableArray *inlist = @[].mutableCopy;
[inlist addObject:({
TUICommonContactTextCellData *data = TUICommonContactTextCellData.new;
data.key = TIMCommonLocalizableString(TUIKitClearAllChatHistory);
data.showAccessory = YES;
data.cselector = @selector(onClearHistoryChatMessage:);
data.reuseId = @"TextCell";
data;
})];
inlist;
})];
self.dataList = list;
[self.tableView reloadData];
}
- (void)onClearHistoryChatMessage:(TUICommonContactTextCell *)cell {
if (IS_NOT_EMPTY_NSSTRING(self.userInfo.userID)) {
NSString *userID = self.userInfo.userID;
@weakify(self);
UIAlertController *ac = [UIAlertController alertControllerWithTitle:nil
message:TIMCommonLocalizableString(TUIKitClearAllChatHistoryTips)
preferredStyle:UIAlertControllerStyleAlert];
[ac tuitheme_addAction:[UIAlertAction actionWithTitle:TIMCommonLocalizableString(Confirm)
style:UIAlertActionStyleDestructive
handler:^(UIAlertAction *_Nonnull action) {
@strongify(self);
[V2TIMManager.sharedInstance clearC2CHistoryMessage:userID
succ:^{
[TUICore notifyEvent:TUICore_TUIConversationNotify
subKey:TUICore_TUIConversationNotify_ClearConversationUIHistorySubKey
object:self
param:nil];
[TUITool makeToast:@"success"];
}
fail:^(int code, NSString *desc) {
[TUITool makeToastError:code msg:desc];
}];
}]];
[ac tuitheme_addAction:[UIAlertAction actionWithTitle:TIMCommonLocalizableString(Cancel) style:UIAlertActionStyleCancel handler:nil]];
[self presentViewController:ac animated:YES completion:nil];
}
}
#pragma mark - TableView data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return self.dataList.count;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.dataList[section].count;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
UIView *view = [[UIView alloc] init];
view.backgroundColor = TIMCommonDynamicColor(@"controller_bg_color", @"#F2F3F5");
return view;
}
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {
UIView *view = [[UIView alloc] init];
view.backgroundColor = TIMCommonDynamicColor(@"controller_bg_color", @"#F2F3F5");
return view;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return section == 0 ? 0 : 10;
}
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
return 0;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSObject *data = self.dataList[indexPath.section][indexPath.row];
if ([data isKindOfClass:[TUICommonContactProfileCardCellData class]]) {
TUICommonContactProfileCardCell *cell = [tableView dequeueReusableCellWithIdentifier:@"CardCell" forIndexPath:indexPath];
cell.delegate = self;
[cell fillWithData:(TUICommonContactProfileCardCellData *)data];
return cell;
} else if ([data isKindOfClass:[TUICommonContactTextCellData class]]) {
TUICommonContactTextCell *cell = [tableView dequeueReusableCellWithIdentifier:@"TextCell" forIndexPath:indexPath];
[cell fillWithData:(TUICommonContactTextCellData *)data];
return cell;
} else if ([data isKindOfClass:[TUICommonContactSwitchCellData class]]) {
TUICommonContactSwitchCell *cell = [tableView dequeueReusableCellWithIdentifier:@"SwitchCell" forIndexPath:indexPath];
[cell fillWithData:(TUICommonContactSwitchCellData *)data];
return cell;
}
return nil;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(nonnull NSIndexPath *)indexPath {
TUICommonCellData *data = self.dataList[indexPath.section][indexPath.row];
return [data heightOfWidth:Screen_Width];
}
- (void)onMessageDoNotDisturb:(TUICommonContactSwitchCell *)cell {
V2TIMReceiveMessageOpt opt;
if (cell.switcher.on) {
opt = V2TIM_RECEIVE_NOT_NOTIFY_MESSAGE;
} else {
opt = V2TIM_RECEIVE_MESSAGE;
}
[[V2TIMManager sharedInstance] setC2CReceiveMessageOpt:@[ self.userInfo.userID ] opt:opt succ:nil fail:nil];
}
- (void)addLongPressGesture {
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(didLongPressAtCell:)];
[self.tableView addGestureRecognizer:longPress];
}
- (void)didLongPressAtCell:(UILongPressGestureRecognizer *)longPress {
if (longPress.state == UIGestureRecognizerStateBegan) {
CGPoint point = [longPress locationInView:self.tableView];
NSIndexPath *pathAtView = [self.tableView indexPathForRowAtPoint:point];
NSObject *data = [self.tableView cellForRowAtIndexPath:pathAtView];
if ([data isKindOfClass:[TUICommonContactTextCell class]]) {
TUICommonContactTextCell *textCell = (TUICommonContactTextCell *)data;
if (textCell.textData.value && ![textCell.textData.value isEqualToString:@"未设置"]) {
UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
pasteboard.string = textCell.textData.value;
NSString *toastString = [NSString stringWithFormat:@"已将 %@ 复制到粘贴板", textCell.textData.key];
[TUITool makeToast:toastString];
}
} else if ([data isKindOfClass:[TUICommonContactProfileCardCell class]]) {
TUICommonContactProfileCardCell *profileCard = (TUICommonContactProfileCardCell *)data;
if (profileCard.cardData.identifier) {
UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
pasteboard.string = profileCard.cardData.identifier;
NSString *toastString = [NSString stringWithFormat:@"已将该用户账号复制到粘贴板"];
[TUITool makeToast:toastString];
}
}
}
}
@end