增加换肤功能

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,22 @@
// Created by Tencent on 2023/06/09.
// Copyright © 2023 Tencent. All rights reserved.
#import <UIKit/UIKit.h>
#import "TUIBlackListViewDataProvider.h"
NS_ASSUME_NONNULL_BEGIN
/**
* 【Module name】Block list interferface (TUIBlackListController)
* 【Function description】It is responsible for pulling the user's blocklist information and displaying it on the page.
* - ViewController provides the display function of the blocklist, and also realizes the response to user interaction.
* - Users can also click on a user in the blocklist to remove them from the blocklist or send them a message.
*/
@interface TUIBlackListController : UITableViewController
@property TUIBlackListViewDataProvider *viewModel;
@property(nonatomic, copy) void (^didSelectCellBlock)(TUICommonContactCell *cell);
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,111 @@
//
// TUIBlackListController.m
// TXIMSDK_TUIKit_iOS
//
// Created by annidyfeng on 2019/5/5.
// Copyright © 2023 Tencent. All rights reserved.
//
#import "TUIBlackListController.h"
#import <TIMCommon/TIMDefine.h>
#import <TUICore/TUIThemeManager.h>
@interface TUIBlackListController () <V2TIMFriendshipListener>
@property(nonatomic, strong) UILabel *noDataTipsLabel;
@end
@implementation TUIBlackListController
- (void)viewDidLoad {
[super viewDidLoad];
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
self.view.backgroundColor = TIMCommonDynamicColor(@"controller_bg_color", @"#F2F3F5");
UILabel *titleLabel = [[UILabel alloc] init];
titleLabel.text = TIMCommonLocalizableString(TUIKitContactsBlackList);
titleLabel.font = [UIFont boldSystemFontOfSize:17.0];
titleLabel.textColor = TIMCommonDynamicColor(@"nav_title_text_color", @"#000000");
[titleLabel sizeToFit];
self.navigationItem.titleView = titleLabel;
self.tableView.delaysContentTouches = NO;
if (!self.viewModel) {
self.viewModel = TUIBlackListViewDataProvider.new;
@weakify(self);
[RACObserve(self.viewModel, isLoadFinished) subscribeNext:^(id finished) {
@strongify(self);
if ([(NSNumber *)finished boolValue]) [self.tableView reloadData];
}];
[self.viewModel loadBlackList];
}
[self.tableView registerClass:[TUICommonContactCell class] forCellReuseIdentifier:@"FriendCell"];
self.tableView.tableFooterView = [UIView new];
self.tableView.backgroundColor = self.view.backgroundColor;
[[V2TIMManager sharedInstance] addFriendListener:self];
[self.tableView addSubview:self.noDataTipsLabel];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
self.noDataTipsLabel.frame = CGRectMake(10, 60, self.view.bounds.size.width - 20, 40);
}
#pragma mark - V2TIMFriendshipListener
- (void)onBlackListAdded:(NSArray<V2TIMFriendInfo *> *)infoList {
[self.viewModel loadBlackList];
}
- (void)onBlackListDeleted:(NSArray *)userIDList {
[self.viewModel loadBlackList];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
self.noDataTipsLabel.hidden = (self.viewModel.blackListData.count != 0);
return self.viewModel.blackListData.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
TUICommonContactCell *cell = [tableView dequeueReusableCellWithIdentifier:@"FriendCell" forIndexPath:indexPath];
TUICommonContactCellData *data = self.viewModel.blackListData[indexPath.row];
data.cselector = @selector(didSelectBlackList:);
[cell fillWithData:data];
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 56;
}
- (void)didSelectBlackList:(TUICommonContactCell *)cell {
if (self.didSelectCellBlock) {
self.didSelectCellBlock(cell);
}
}
- (UILabel *)noDataTipsLabel {
if (_noDataTipsLabel == nil) {
_noDataTipsLabel = [[UILabel alloc] init];
_noDataTipsLabel.textColor = TIMCommonDynamicColor(@"nodata_tips_color", @"#999999");
_noDataTipsLabel.font = [UIFont systemFontOfSize:14.0];
_noDataTipsLabel.textAlignment = NSTextAlignmentCenter;
_noDataTipsLabel.text = TIMCommonLocalizableString(TUIKitContactNoBlockList);
}
return _noDataTipsLabel;
}
@end

View File

@@ -0,0 +1,15 @@
// Created by Tencent on 2023/06/09.
// Copyright © 2023 Tencent. All rights reserved.
#import <UIKit/UIKit.h>
#import "TUICommonContactProfileCardCell.h"
NS_ASSUME_NONNULL_BEGIN
@interface TUIContactAvatarViewController : UIViewController
@property(nonatomic, strong) TUICommonContactProfileCardCellData *avatarData;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,85 @@
// Created by Tencent on 2023/06/09.
// Copyright © 2023 Tencent. All rights reserved.
#import "TUIContactAvatarViewController.h"
#import <TIMCommon/TIMCommonModel.h>
#import <TIMCommon/TIMDefine.h>
#import <TUICore/UIView+TUILayout.h>
#import "ReactiveObjC/ReactiveObjC.h"
#import "SDWebImage/UIImageView+WebCache.h"
@interface TUIContactAvatarViewController () <UIScrollViewDelegate>
@property UIImageView *avatarView;
@property TUIScrollView *avatarScrollView;
@property UIImage *saveBackgroundImage;
@property UIImage *saveShadowImage;
@end
@implementation TUIContactAvatarViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.saveBackgroundImage = [self.navigationController.navigationBar backgroundImageForBarMetrics:UIBarMetricsDefault];
self.saveShadowImage = self.navigationController.navigationBar.shadowImage;
[self.navigationController.navigationBar setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault];
self.navigationController.navigationBar.shadowImage = [UIImage new];
CGRect rect = self.view.bounds;
self.avatarScrollView = [[TUIScrollView alloc] initWithFrame:CGRectZero];
[self.view addSubview:self.avatarScrollView];
self.avatarScrollView.backgroundColor = [UIColor blackColor];
self.avatarScrollView.frame = rect;
self.avatarView = [[UIImageView alloc] initWithImage:self.avatarData.avatarImage];
self.avatarScrollView.imageView = self.avatarView;
self.avatarScrollView.maximumZoomScale = 4.0;
self.avatarScrollView.delegate = self;
self.avatarView.image = self.avatarData.avatarImage;
TUICommonContactProfileCardCellData *data = self.avatarData;
/*
@weakify(self);
[RACObserve(data, avatarUrl) subscribeNext:^(NSURL *x) {
@strongify(self);
[self.avatarView sd_setImageWithURL:x placeholderImage:self.avatarData.avatarImage];
}];
*/
@weakify(self);
[RACObserve(data, avatarUrl) subscribeNext:^(NSURL *x) {
@strongify(self);
[self.avatarView sd_setImageWithURL:x placeholderImage:self.avatarData.avatarImage];
[self.avatarScrollView setNeedsLayout];
}];
}
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
return self.avatarView;
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationNone];
[self.navigationController.navigationBar setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault];
self.navigationController.navigationBar.shadowImage = [UIImage new];
self.navigationController.navigationBar.backgroundColor = [UIColor clearColor];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationNone];
}
- (void)willMoveToParentViewController:(UIViewController *)parent {
if (parent == nil) {
[self.navigationController.navigationBar setBackgroundImage:self.saveBackgroundImage forBarMetrics:UIBarMetricsDefault];
self.navigationController.navigationBar.shadowImage = self.saveShadowImage;
}
}
@end

View File

@@ -0,0 +1,27 @@
// Created by Tencent on 2023/06/09.
// Copyright © 2023 Tencent. All rights reserved.
#import <UIKit/UIKit.h>
#import "TUIContactViewDataProvider.h"
#import "TUIFindContactCellModel.h"
NS_ASSUME_NONNULL_BEGIN
@protocol TUIContactControllerListener <NSObject>
@optional
- (void)onSelectFriend:(TUICommonContactCell *)cell;
- (void)onAddNewFriend:(TUICommonTableViewCell *)cell;
- (void)onGroupConversation:(TUICommonTableViewCell *)cell;
@end
@interface TUIContactController : UIViewController
@property(nonatomic, strong) TUIContactViewDataProvider *viewModel;
@property(nonatomic, weak) id<TUIContactControllerListener> delegate;
@property UITableView *tableView;
- (void)addToContactsOrGroups:(TUIFindContactType)type;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,394 @@
//
// TContactsController.m
// TUIKit
//
// Created by annidyfeng on 2019/3/25.
// Copyright © 2019 Tencent. All rights reserved.
//
#import "TUIContactController.h"
#import <TIMCommon/TIMDefine.h>
#import <TUICore/TUICore.h>
#import <TUICore/TUILogin.h>
#import <TUICore/TUIThemeManager.h>
#import "TUIBlackListController.h"
#import "TUIContactActionCell.h"
#import "TUIFindContactViewController.h"
#import "TUIFriendProfileController.h"
#import "TUIFriendRequestViewController.h"
#import "TUIGroupConversationListController.h"
#import "TUINewFriendViewController.h"
#import "TUIUserProfileController.h"
#define kContactCellReuseId @"ContactCellReuseId"
#define kContactActionCellReuseId @"ContactActionCellReuseId"
@interface TUIContactController () <UITableViewDelegate, UITableViewDataSource, V2TIMFriendshipListener, TUIPopViewDelegate>
@property NSArray<TUIContactActionCellData *> *firstGroupData;
@end
@implementation TUIContactController
#pragma mark - Life Cycle
- (void)viewDidLoad {
[super viewDidLoad];
NSMutableArray *list = @[].mutableCopy;
[list addObject:({
TUIContactActionCellData *data = [[TUIContactActionCellData alloc] init];
data.icon = TUIContactDynamicImage(@"contact_new_friend_img", [UIImage imageNamed:TUIContactImagePath(@"new_friend")]);
data.title = TIMCommonLocalizableString(TUIKitContactsNewFriends);
data.cselector = @selector(onAddNewFriend:);
data;
})];
[list addObject:({
TUIContactActionCellData *data = [[TUIContactActionCellData alloc] init];
data.icon = TUIContactDynamicImage(@"contact_public_group_img", [UIImage imageNamed:TUIContactImagePath(@"public_group")]);
data.title = TIMCommonLocalizableString(TUIKitContactsGroupChats);
data.cselector = @selector(onGroupConversation:);
data;
})];
[list addObject:({
TUIContactActionCellData *data = [[TUIContactActionCellData alloc] init];
data.icon = TUIContactDynamicImage(@"contact_blacklist_img", [UIImage imageNamed:TUIContactImagePath(@"blacklist")]);
data.title = TIMCommonLocalizableString(TUIKitContactsBlackList);
data.cselector = @selector(onBlackList:);
data;
})];
[self addExtensionsToList:list];
self.firstGroupData = [NSArray arrayWithArray:list];
[self setupNavigator];
[self setupViews];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onLoginSucceeded) name:TUILoginSuccessNotification object:nil];
[NSNotificationCenter.defaultCenter addObserver:self selector:@selector(onFriendInfoChanged) name:@"FriendInfoChangedNotification" object:nil];
}
- (void)addExtensionsToList:(NSMutableArray *)list {
NSDictionary *param = @{TUICore_TUIContactExtension_ContactMenu_Nav: self.navigationController};
NSArray<TUIExtensionInfo *> *extensionList = [TUICore getExtensionList:TUICore_TUIContactExtension_ContactMenu_ClassicExtensionID param:param];
NSArray *sortedExtensionList = [extensionList sortedArrayUsingComparator:^NSComparisonResult(TUIExtensionInfo *obj1, TUIExtensionInfo *obj2) {
if (obj1.weight <= obj2.weight) {
return NSOrderedDescending;
} else {
return NSOrderedAscending;
}
}];
for (TUIExtensionInfo *info in sortedExtensionList) {
[list addObject:({
TUIContactActionCellData *data = [[TUIContactActionCellData alloc] init];
data.icon = info.icon;
data.title = info.text;
data.cselector = @selector(onExtensionClicked:);
data.onClicked = info.onClicked;
data;
})];
}
}
- (void)dealloc {
[NSNotificationCenter.defaultCenter removeObserver:self];
}
- (void)onLoginSucceeded {
[self.viewModel loadContacts];
}
- (void)onFriendInfoChanged {
[self.viewModel loadContacts];
}
- (void)setupNavigator {
UIButton *moreButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 30, 30)];
[moreButton setImage:TIMCommonDynamicImage(@"nav_more_img", [UIImage imageNamed:TIMCommonImagePath(@"more")]) forState:UIControlStateNormal];
[moreButton addTarget:self action:@selector(onRightItem:) forControlEvents:UIControlEventTouchUpInside];
[moreButton.widthAnchor constraintEqualToConstant:24].active = YES;
[moreButton.heightAnchor constraintEqualToConstant:24].active = YES;
UIBarButtonItem *moreItem = [[UIBarButtonItem alloc] initWithCustomView:moreButton];
self.navigationItem.rightBarButtonItem = moreItem;
self.navigationController.interactivePopGestureRecognizer.enabled = YES;
}
- (void)setupViews {
self.view.backgroundColor = TIMCommonDynamicColor(@"controller_bg_color", @"#F2F3F5");
CGRect rect = self.view.bounds;
_tableView = [[UITableView alloc] initWithFrame:rect style:UITableViewStylePlain];
_tableView.delegate = self;
_tableView.dataSource = self;
[_tableView setSectionIndexBackgroundColor:[UIColor clearColor]];
_tableView.contentInset = UIEdgeInsetsMake(0, 0, 8, 0);
[_tableView setSectionIndexColor:[UIColor darkGrayColor]];
[_tableView setBackgroundColor:self.view.backgroundColor];
_tableView.delaysContentTouches = NO;
if (@available(iOS 15.0, *)) {
_tableView.sectionHeaderTopPadding = 0;
}
[self.view addSubview:_tableView];
UIView *v = [[UIView alloc] initWithFrame:CGRectZero];
[_tableView setTableFooterView:v];
_tableView.separatorInset = UIEdgeInsetsMake(0, 58, 0, 0);
[_tableView registerClass:[TUICommonContactCell class] forCellReuseIdentifier:kContactCellReuseId];
[_tableView registerClass:[TUIContactActionCell class] forCellReuseIdentifier:kContactActionCellReuseId];
@weakify(self);
[RACObserve(self.viewModel, isLoadFinished) subscribeNext:^(id finished) {
@strongify(self);
if ([(NSNumber *)finished boolValue]) {
[self.tableView reloadData];
}
}];
[RACObserve(self.viewModel, pendencyCnt) subscribeNext:^(NSNumber *x) {
@strongify(self);
self.firstGroupData[0].readNum = [x integerValue];
}];
}
- (void)onRightItem:(UIButton *)rightBarButton;
{
NSMutableArray *menus = [NSMutableArray array];
TUIPopCellData *friend = [[TUIPopCellData alloc] init];
friend.image = TUIDemoDynamicImage(@"pop_icon_add_friend_img", [UIImage imageNamed:TUIDemoImagePath(@"add_friend")]);
friend.title = TIMCommonLocalizableString(ContactsAddFriends); //@"";
[menus addObject:friend];
TUIPopCellData *group = [[TUIPopCellData alloc] init];
group.image = TUIDemoDynamicImage(@"pop_icon_add_group_img", [UIImage imageNamed:TUIDemoImagePath(@"add_group")]);
group.title = TIMCommonLocalizableString(ContactsJoinGroup); //@"";
[menus addObject:group];
CGFloat height = [TUIPopCell getHeight] * menus.count + TUIPopView_Arrow_Size.height;
CGFloat orginY = StatusBar_Height + NavBar_Height;
CGFloat orginX = Screen_Width - 140;
if(isRTL()){
orginX = 10;
}
TUIPopView *popView = [[TUIPopView alloc] initWithFrame:CGRectMake(orginX, orginY, 130, height)];
CGRect frameInNaviView = [self.navigationController.view convertRect:rightBarButton.frame fromView:rightBarButton.superview];
popView.arrowPoint = CGPointMake(frameInNaviView.origin.x + frameInNaviView.size.width * 0.5, orginY);
popView.delegate = self;
[popView setData:menus];
[popView showInWindow:self.view.window];
}
- (void)popView:(TUIPopView *)popView didSelectRowAtIndex:(NSInteger)index {
[self addToContactsOrGroups:(index == 0 ? TUIFindContactTypeC2C : TUIFindContactTypeGroup)];
}
- (void)addToContactsOrGroups:(TUIFindContactType)type {
TUIFindContactViewController *add = [[TUIFindContactViewController alloc] init];
add.type = type;
@weakify(self);
add.onSelect = ^(TUIFindContactCellModel *cellModel) {
@strongify(self);
if (cellModel.type == TUIFindContactTypeC2C) {
NSString *userID = cellModel.userInfo.userID.length >0
?cellModel.userInfo.userID : @"";
TUICommonContactCellData *friendContactData = self.viewModel.contactMap[userID];
if (friendContactData) {
TUIFriendProfileController *vc = [[TUIFriendProfileController alloc] init];
vc.friendProfile = friendContactData.friendProfile;
[self.navigationController pushViewController:(UIViewController *)vc animated:YES];
}
else {
TUIFriendRequestViewController *frc = [[TUIFriendRequestViewController alloc] init];
frc.profile = cellModel.userInfo;
[self.navigationController popViewControllerAnimated:NO];
[self.navigationController pushViewController:frc animated:YES];
}
} else {
NSDictionary *param = @{TUICore_TUIContactObjectFactory_GetGroupRequestViewControllerMethod_GroupInfoKey : cellModel.groupInfo};
UIViewController *vc = [TUICore createObject:TUICore_TUIContactObjectFactory
key:TUICore_TUIContactObjectFactory_GetGroupRequestViewControllerMethod
param:param];
[self.navigationController pushViewController:vc animated:YES];
}
};
[self.navigationController pushViewController:add animated:YES];
}
- (TUIContactViewDataProvider *)viewModel {
if (_viewModel == nil) {
_viewModel = [TUIContactViewDataProvider new];
[_viewModel loadContacts];
}
return _viewModel;
}
- (void)onFriendListChanged {
[_viewModel loadContacts];
}
- (void)onFriendApplicationListChanged {
[_viewModel loadFriendApplication];
}
#pragma mark - UITableView
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView;
{ return self.viewModel.groupList.count + 1; }
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (section == 0) {
return self.firstGroupData.count;
} else {
NSString *group = self.viewModel.groupList[section - 1];
NSArray *list = self.viewModel.dataDict[group];
return list.count;
}
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
if (section == 0) return nil;
#define TEXT_TAG 1
static NSString *headerViewId = @"ContactDrawerView";
UITableViewHeaderFooterView *headerView = [tableView dequeueReusableHeaderFooterViewWithIdentifier:headerViewId];
if (!headerView) {
headerView = [[UITableViewHeaderFooterView alloc] initWithReuseIdentifier:headerViewId];
UILabel *textLabel = [[UILabel alloc] initWithFrame:CGRectZero];
textLabel.tag = TEXT_TAG;
textLabel.font = [UIFont systemFontOfSize:16];
textLabel.textColor = RGB(0x80, 0x80, 0x80);
[textLabel setRtlAlignment:TUITextRTLAlignmentLeading];
[headerView addSubview:textLabel];
[textLabel mas_remakeConstraints:^(MASConstraintMaker *make) {
make.leading.mas_equalTo(headerView.mas_leading).mas_offset(12);
make.top.bottom.trailing.mas_equalTo(headerView);
}];
}
UILabel *label = [headerView viewWithTag:TEXT_TAG];
label.text = self.viewModel.groupList[section - 1];
headerView.contentView.backgroundColor = TIMCommonDynamicColor(@"controller_bg_color", @"#F2F3F5");
return headerView;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 56;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
if (section == 0) return 0;
return 33;
}
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
NSMutableArray *array = [NSMutableArray arrayWithObject:@""];
[array addObjectsFromArray:self.viewModel.groupList];
return array;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.section == 0) {
TUIContactActionCell *cell = [tableView dequeueReusableCellWithIdentifier:kContactActionCellReuseId forIndexPath:indexPath];
[cell fillWithData:self.firstGroupData[indexPath.row]];
cell.changeColorWhenTouched = YES;
return cell;
} else {
TUICommonContactCell *cell = [tableView dequeueReusableCellWithIdentifier:kContactCellReuseId forIndexPath:indexPath];
NSString *group = self.viewModel.groupList[indexPath.section - 1];
NSArray *list = self.viewModel.dataDict[group];
TUICommonContactCellData *data = list[indexPath.row];
data.cselector = @selector(onSelectFriend:);
[cell fillWithData:data];
cell.changeColorWhenTouched = YES;
return cell;
}
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
}
#pragma mark -
- (void)onSelectFriend:(TUICommonContactCell *)cell {
if (self.delegate && [self.delegate respondsToSelector:@selector(onSelectFriend:)]) {
[self.delegate onSelectFriend:cell];
return;
}
TUICommonContactCellData *data = cell.contactData;
TUIFriendProfileController *vc = [[TUIFriendProfileController alloc] init];
vc.friendProfile = data.friendProfile;
[self.navigationController pushViewController:(UIViewController *)vc animated:YES];
}
- (void)onAddNewFriend:(TUICommonTableViewCell *)cell {
if (self.delegate && [self.delegate respondsToSelector:@selector(onAddNewFriend:)]) {
[self.delegate onAddNewFriend:cell];
return;
}
TUINewFriendViewController *vc = TUINewFriendViewController.new;
vc.cellClickBlock = ^(TUICommonPendencyCell *_Nonnull cell) {
TUIUserProfileController *controller = [[TUIUserProfileController alloc] init];
[[V2TIMManager sharedInstance] getUsersInfo:@[ cell.pendencyData.identifier ]
succ:^(NSArray<V2TIMUserFullInfo *> *profiles) {
controller.userFullInfo = profiles.firstObject;
controller.pendency = cell.pendencyData;
controller.actionType = PCA_PENDENDY_CONFIRM;
[self.navigationController pushViewController:(UIViewController *)controller animated:YES];
}
fail:nil];
};
[self.navigationController pushViewController:vc animated:YES];
[self.viewModel clearApplicationCnt];
}
- (void)onGroupConversation:(TUICommonTableViewCell *)cell {
if (self.delegate && [self.delegate respondsToSelector:@selector(onGroupConversation:)]) {
[self.delegate onGroupConversation:cell];
return;
}
TUIGroupConversationListController *vc = TUIGroupConversationListController.new;
@weakify(self);
vc.onSelect = ^(TUICommonContactCellData *_Nonnull cellData) {
@strongify(self);
NSDictionary *param = @{TUICore_TUIChatObjectFactory_ChatViewController_GroupID : cellData.identifier ?: @""};
[self.navigationController pushViewController:TUICore_TUIChatObjectFactory_ChatViewController_Classic param:param forResult:nil];
};
[self.navigationController pushViewController:vc animated:YES];
}
- (void)onBlackList:(TUICommonContactCell *)cell {
TUIBlackListController *vc = TUIBlackListController.new;
@weakify(self);
vc.didSelectCellBlock = ^(TUICommonContactCell *_Nonnull cell) {
@strongify(self);
[self onSelectFriend:cell];
};
[self.navigationController pushViewController:vc animated:YES];
}
- (void)onExtensionClicked:(TUIContactActionCell *)cell {
if (cell.actionData.onClicked) {
cell.actionData.onClicked(nil);
}
}
- (void)runSelector:(SEL)selector withObject:(id)object {
if ([self respondsToSelector:selector]) {
IMP imp = [self methodForSelector:selector];
void (*func)(id, SEL, id) = (void *)imp;
func(self, selector, object);
}
}
@end
@interface IUContactView : UIView
@property(nonatomic, strong) UIView *view;
@end
@implementation IUContactView
- (instancetype)init {
self = [super init];
if (self) {
self.view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
[self addSubview:self.view];
}
return self;
}
@end

View File

@@ -0,0 +1,49 @@
// Created by Tencent on 2023/06/09.
// Copyright © 2023 Tencent. All rights reserved.
#import <TIMCommon/TIMCommonModel.h>
#import <TIMCommon/TIMDefine.h>
#import <UIKit/UIKit.h>
#import "TUIContactSelectViewDataProvider.h"
NS_ASSUME_NONNULL_BEGIN
typedef void (^ContactSelectFinishBlock)(NSArray<TUICommonContactSelectCellData *> *_Nonnull selectArray);
@interface TUIContactSelectController : UIViewController
@property(nonatomic, strong, nullable) TUIContactSelectViewDataProvider *viewModel;
/**
* Callback for contact selection end
*/
@property(nonatomic, copy, nullable) ContactSelectFinishBlock finishBlock;
/**
* Maximum number of selected contactsdefalut value is 0 which means no limit
*/
@property(nonatomic, assign) NSInteger maxSelectCount;
/**
* List of pre-selected users
*/
@property(nonatomic, strong, nullable) NSArray *sourceIds;
/**
* List of pre-banned users
*/
@property(nonatomic, strong, nullable) NSArray *disableIds;
/**
* Display name for sourceIds or disableIds
*/
@property(nonatomic, strong, nullable) NSDictionary *displayNames;
/**
* Navigation title for view controller
*/
@property(nonatomic, copy, nullable) NSString *title;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,216 @@
//
// TUIContactSelectController.m
// TXIMSDK_TUIKit_iOS
//
// Created by annidyfeng on 2019/5/8.
// Copyright © 2023 Tencent. All rights reserved.
//
#import "TUIContactSelectController.h"
#import <TIMCommon/TIMDefine.h>
#import <TUICore/TUICore.h>
#import <TUICore/TUIThemeManager.h>
#import "TUICommonContactSelectCell.h"
#import "TUIContactSelectViewDataProvider.h"
static NSString *gReuseIdentifier = @"ContactSelectCell";
@interface TUIContactSelectController () <UITableViewDelegate, UITableViewDataSource>
@property UITableView *tableView;
@property UIView *emptyView;
@property TUIContactListPicker *pickerView;
@property NSMutableArray<TUICommonContactSelectCellData *> *selectArray;
@end
@implementation TUIContactSelectController
@synthesize finishBlock;
@synthesize maxSelectCount;
@synthesize sourceIds;
@synthesize viewModel;
- (instancetype)init {
self = [super init];
if (self) {
[self initData];
}
return self;
}
- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
[self initData];
}
return self;
}
- (void)initData {
self.maxSelectCount = 0;
self.selectArray = @[].mutableCopy;
self.viewModel = [TUIContactSelectViewDataProvider new];
}
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = TIMCommonDynamicColor(@"controller_bg_color", @"#F3F5F9");
self.navigationController.interactivePopGestureRecognizer.enabled = YES;
_tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
[self.view addSubview:_tableView];
_tableView.delegate = self;
_tableView.dataSource = self;
[_tableView setSectionIndexBackgroundColor:[UIColor clearColor]];
[_tableView setSectionIndexColor:[UIColor darkGrayColor]];
[_tableView setBackgroundColor:self.view.backgroundColor];
UIView *v = [[UIView alloc] initWithFrame:CGRectZero];
[_tableView setTableFooterView:v];
_tableView.separatorInset = UIEdgeInsetsMake(0, 58, 0, 0);
[_tableView registerClass:[TUICommonContactSelectCell class] forCellReuseIdentifier:gReuseIdentifier];
if (@available(iOS 15.0, *)) {
_tableView.sectionHeaderTopPadding = 0;
}
_emptyView = [[UIView alloc] initWithFrame:CGRectZero];
[self.view addSubview:_emptyView];
_emptyView.mm_fill();
_emptyView.hidden = YES;
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(contactListNilLabelTapped:)];
[_emptyView addGestureRecognizer:tapGesture];
UILabel *tipsLabel = [[UILabel alloc] initWithFrame:CGRectZero];
[_emptyView addSubview:tipsLabel];
tipsLabel.text = TIMCommonLocalizableString(TUIKitTipsContactListNil);
tipsLabel.mm_sizeToFit().tui_mm_center();
_pickerView = [[TUIContactListPicker alloc] initWithFrame:CGRectZero];
[_pickerView setBackgroundColor:[UIColor groupTableViewBackgroundColor]];
[self.view addSubview:_pickerView];
[_pickerView.accessoryBtn addTarget:self action:@selector(finishTask) forControlEvents:UIControlEventTouchUpInside];
[self setupBinds];
if (self.sourceIds) {
[self.viewModel setSourceIds:self.sourceIds displayNames:self.displayNames];
} else {
[self.viewModel loadContacts];
}
self.view.backgroundColor = RGB(42, 42, 40);
self.navigationItem.title = self.title;
}
- (void)setupBinds {
@weakify(self);
[RACObserve(self.viewModel, isLoadFinished) subscribeNext:^(NSNumber *finished) {
@strongify(self);
if ([finished boolValue]) {
[self.tableView reloadData];
}
}];
[RACObserve(self.viewModel, groupList) subscribeNext:^(NSArray *group) {
@strongify(self);
self.emptyView.hidden = (group.count > 0);
}];
}
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
_pickerView.mm_width(self.view.mm_w).mm_height(60 + _pickerView.mm_safeAreaBottomGap).mm_bottom(0);
_tableView.mm_width(self.view.mm_w).mm_flexToBottom(_pickerView.mm_h);
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView;
{ return self.viewModel.groupList.count; }
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSString *group = self.viewModel.groupList[section];
NSArray *list = self.viewModel.dataDict[group];
return list.count;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
#define TEXT_TAG 1
static NSString *headerViewId = @"ContactDrawerView";
UITableViewHeaderFooterView *headerView = [tableView dequeueReusableHeaderFooterViewWithIdentifier:headerViewId];
if (!headerView) {
headerView = [[UITableViewHeaderFooterView alloc] initWithReuseIdentifier:headerViewId];
UILabel *textLabel = [[UILabel alloc] initWithFrame:CGRectZero];
textLabel.tag = TEXT_TAG;
textLabel.font = [UIFont systemFontOfSize:16];
textLabel.textColor = RGB(0x80, 0x80, 0x80);
[textLabel setRtlAlignment:TUITextRTLAlignmentLeading];
[headerView addSubview:textLabel];
[textLabel mas_remakeConstraints:^(MASConstraintMaker *make) {
make.leading.mas_equalTo(headerView.mas_leading).mas_offset(12);
make.top.bottom.trailing.mas_equalTo(headerView);
}];
textLabel.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
}
UILabel *label = [headerView viewWithTag:TEXT_TAG];
label.text = self.viewModel.groupList[section];
return headerView;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 56;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return 33;
}
//- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
//{
// return CGFLOAT_MIN;
//}
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
return self.viewModel.groupList;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
TUICommonContactSelectCell *cell = [tableView dequeueReusableCellWithIdentifier:gReuseIdentifier forIndexPath:indexPath];
NSString *group = self.viewModel.groupList[indexPath.section];
NSArray *list = self.viewModel.dataDict[group];
TUICommonContactSelectCellData *data = list[indexPath.row];
if (data.enabled) {
data.cselector = @selector(didSelectContactCell:);
} else {
data.cselector = NULL;
}
[cell fillWithData:data];
return cell;
}
- (void)didSelectContactCell:(TUICommonContactSelectCell *)cell {
TUICommonContactSelectCellData *data = cell.selectData;
if (!data.isSelected) {
if (maxSelectCount > 0 && self.selectArray.count + 1 > self.maxSelectCount) {
[TUITool makeToast:[NSString stringWithFormat:TIMCommonLocalizableString(TUIKitTipsMostSelectTextFormat), (long)self.maxSelectCount]];
return;
}
}
data.selected = !data.isSelected;
[cell fillWithData:data];
if (data.isSelected) {
[self.selectArray addObject:data];
} else {
[self.selectArray removeObject:data];
}
self.pickerView.selectArray = [self.selectArray copy];
}
- (void)contactListNilLabelTapped:(id)label {
[TUITool makeToast:TIMCommonLocalizableString(TUIKitTipsContactListNil)];
}
- (void)finishTask {
if (self.finishBlock) {
self.finishBlock(self.selectArray);
}
}
@end

View File

@@ -0,0 +1,24 @@
//
// TUIFindContactViewController.h
// TUIContact
//
// Created by harvy on 2021/12/13.
// Copyright © 2023 Tencent. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "TUIFindContactCellModel.h"
NS_ASSUME_NONNULL_BEGIN
typedef void (^TUIFindContactViewControllerCallback)(TUIFindContactCellModel *);
@interface TUIFindContactViewController : UIViewController
@property(nonatomic, assign) TUIFindContactType type;
@property(nonatomic, copy) TUIFindContactViewControllerCallback onSelect;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,200 @@
//
// TUIFindContactViewController.m
// TUIContact
//
// Created by harvy on 2021/12/13.
// Copyright © 2023 Tencent. All rights reserved.
//
#import "TUIFindContactViewController.h"
#import <TUICore/TUICore.h>
#import <TUICore/TUIGlobalization.h>
#import <TUICore/TUIThemeManager.h>
#import "TUIFindContactCell.h"
#import "TUIFindContactViewDataProvider.h"
@interface TUIFindContactViewController () <UISearchBarDelegate, UITableViewDelegate, UITableViewDataSource>
@property(nonatomic, strong) UISearchBar *searchBar;
@property(nonatomic, strong) UITableView *tableView;
@property(nonatomic, strong) UILabel *tipsLabel;
@property(nonatomic, strong) UILabel *noDataTipsLabel;
@property(nonatomic, strong) TUIFindContactViewDataProvider *provider;
@end
@implementation TUIFindContactViewController
- (void)dealloc {
[[UIBarButtonItem appearanceWhenContainedInInstancesOfClasses:@[ [UISearchBar class] ]] setTitle:TIMCommonLocalizableString(Cancel)];
}
- (void)viewDidLoad {
[super viewDidLoad];
[self setupView];
NSString *tipsLabelText = [self.provider getMyUserIDDescription];
if (self.type == TUIFindContactTypeGroup) {
tipsLabelText = @"";
}
self.tipsLabel.text = tipsLabelText;
}
- (void)setupView {
self.edgesForExtendedLayout = UIRectEdgeNone;
self.automaticallyAdjustsScrollViewInsets = NO;
self.definesPresentationContext = YES; // Not setting it will cause some problems such as position confusion and no animation.
UILabel *titleLabel = [[UILabel alloc] init];
titleLabel.text = self.type == TUIFindContactTypeC2C ? TIMCommonLocalizableString(TUIKitAddFriend) : TIMCommonLocalizableString(TUIKitAddGroup);
titleLabel.font = [UIFont boldSystemFontOfSize:17.0];
titleLabel.textColor = TIMCommonDynamicColor(@"nav_title_text_color", @"#000000");
[titleLabel sizeToFit];
self.navigationItem.titleView = titleLabel;
self.view.backgroundColor = self.searchBar.backgroundColor;
self.searchBar.frame = CGRectMake(10, 0, self.view.bounds.size.width - 20, 60);
[self.view addSubview:self.searchBar];
self.tableView.frame = CGRectMake(0, 60, self.view.bounds.size.width, self.view.bounds.size.height - 60);
[self.view addSubview:self.tableView];
self.tipsLabel.frame = CGRectMake(10, 10, self.view.bounds.size.width - 20, 40);
[self.tableView addSubview:self.tipsLabel];
self.noDataTipsLabel.frame = CGRectMake(10, 60, self.view.bounds.size.width - 20, 40);
[self.tableView addSubview:self.noDataTipsLabel];
}
#pragma mark - UITableViewDelegate/UITableViewDataSource
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSInteger count = self.type == TUIFindContactTypeC2C ? self.provider.users.count : self.provider.groups.count;
self.noDataTipsLabel.hidden = !self.tipsLabel.hidden || count || self.searchBar.text.length == 0;
self.noDataTipsLabel.text =
self.type == TUIFindContactTypeC2C ? TIMCommonLocalizableString(TUIKitAddUserNoDataTips) : TIMCommonLocalizableString(TUIKitAddGroupNoDataTips);
return count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
TUIFindContactCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
NSArray *result = self.type == TUIFindContactTypeC2C ? self.provider.users : self.provider.groups;
TUIFindContactCellModel *cellModel = result[indexPath.row];
cell.data = cellModel;
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:NO];
NSArray *result = self.type == TUIFindContactTypeC2C ? self.provider.users : self.provider.groups;
TUIFindContactCellModel *cellModel = result[indexPath.row];
[self onSelectCellModel:cellModel];
}
- (void)onSelectCellModel:(TUIFindContactCellModel *)cellModel {
if (self.onSelect) {
self.onSelect(cellModel);
}
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
[self.view endEditing:YES];
}
#pragma mark - UISearchBarDelegate
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
[self doSearchWithKeyword:searchBar.text];
}
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {
if (searchText.length == 0) {
[self.provider clear];
[self.tableView reloadData];
}
}
- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar {
[searchBar setShowsCancelButton:YES animated:YES];
self.tipsLabel.hidden = YES;
return YES;
}
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar {
[self doSearchWithKeyword:searchBar.text];
}
- (void)doSearchWithKeyword:(NSString *)keyword {
__weak typeof(self) weakSelf = self;
if (self.type == TUIFindContactTypeC2C) {
[self.provider findUser:keyword
completion:^{
[weakSelf.tableView reloadData];
}];
} else {
[self.provider findGroup:keyword
completion:^{
[weakSelf.tableView reloadData];
}];
}
}
- (UISearchBar *)searchBar {
if (_searchBar == nil) {
_searchBar = [[UISearchBar alloc] init];
_searchBar.backgroundColor = TIMCommonDynamicColor(@"controller_bg_color", @"F3F4F5");
_searchBar.placeholder =
self.type == TUIFindContactTypeC2C ? TIMCommonLocalizableString(TUIKitSearchUserID) : TIMCommonLocalizableString(TUIKitSearchGroupID);
_searchBar.backgroundImage = [[UIImage alloc] init];
_searchBar.delegate = self;
_searchBar.searchTextField.textAlignment = isRTL()?NSTextAlignmentRight:NSTextAlignmentLeft;
UITextField *searchField = [_searchBar valueForKey:@"searchField"];
if (searchField) {
searchField.backgroundColor = TIMCommonDynamicColor(@"search_textfield_bg_color", @"#FEFEFE");
}
[[UIBarButtonItem appearanceWhenContainedInInstancesOfClasses:@[ [UISearchBar class] ]] setTitle:TIMCommonLocalizableString(Search)];
}
return _searchBar;
}
- (UITableView *)tableView {
if (_tableView == nil) {
_tableView = [[UITableView alloc] init];
_tableView.backgroundColor = TIMCommonDynamicColor(@"controller_bg_color", @"F3F4F5");
_tableView.delegate = self;
_tableView.dataSource = self;
[_tableView registerClass:TUIFindContactCell.class forCellReuseIdentifier:@"cell"];
_tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
_tableView.rowHeight = self.type == TUIFindContactTypeC2C ? 72 : 94;
}
return _tableView;
}
- (UILabel *)tipsLabel {
if (_tipsLabel == nil) {
_tipsLabel = [[UILabel alloc] init];
_tipsLabel.textColor = TUIContactDynamicColor(@"contact_add_contact_tips_text_color", @"#444444");
_tipsLabel.font = [UIFont systemFontOfSize:12.0];
_tipsLabel.textAlignment = NSTextAlignmentCenter;
}
return _tipsLabel;
}
- (UILabel *)noDataTipsLabel {
if (_noDataTipsLabel == nil) {
_noDataTipsLabel = [[UILabel alloc] init];
_noDataTipsLabel.textColor = TUIContactDynamicColor(@"contact_add_contact_nodata_tips_text_color", @"#999999");
_noDataTipsLabel.font = [UIFont systemFontOfSize:14.0];
_noDataTipsLabel.textAlignment = NSTextAlignmentCenter;
}
return _noDataTipsLabel;
}
- (TUIFindContactViewDataProvider *)provider {
if (_provider == nil) {
_provider = [[TUIFindContactViewDataProvider alloc] init];
}
return _provider;
}
@end

View File

@@ -0,0 +1,21 @@
// Created by Tencent on 2023/06/09.
// Copyright © 2023 Tencent. All rights reserved.
/**
* Tencent Cloud Communication Service Interface Components TUIKIT - Friends Information Interface
* This file implements the friend profile view controller, which is only used when displaying friends.
* To display user information for non-friends, see TUIUserProfileController.h
*/
#import <UIKit/UIKit.h>
@import ImSDK_Plus;
NS_ASSUME_NONNULL_BEGIN
@interface TUIFriendProfileController : UITableViewController
@property(nonatomic, strong) V2TIMFriendInfo *friendProfile;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,594 @@
//
// TUIFriendController.m
// TUIKit
//
// Created by annidyfeng on 2019/4/29.
// Copyright © 2019 kennethmiao. All rights reserved.
//
#import "TUIFriendProfileController.h"
#import <TIMCommon/TIMCommonModel.h>
#import <TUICore/TUICore.h>
#import <TUICore/TUILogin.h>
#import <TUICore/TUIThemeManager.h>
#import <TUICore/UIView+TUILayout.h>
#import "ReactiveObjC/ReactiveObjC.h"
#import "SDWebImage/UIImageView+WebCache.h"
#import "TUICommonContactSwitchCell.h"
#import "TUICommonContactTextCell.h"
#import "TUIContactAvatarViewController.h"
#import "TUIContactConversationCellData.h"
#import "TUITextEditController.h"
#import "TUIContactConfig.h"
@interface TUIFriendProfileController ()
@property NSArray<NSArray *> *dataList;
@property BOOL modified;
@property V2TIMUserFullInfo *userFullInfo;
@property TUINaviBarIndicatorView *titleView;
@end
@implementation TUIFriendProfileController
@synthesize friendProfile;
- (instancetype)init {
self = [super initWithStyle:UITableViewStyleGrouped];
return self;
}
- (void)willMoveToParentViewController:(nullable UIViewController *)parent {
[super willMoveToParentViewController:parent];
if (parent == nil) {
if (self.modified) {
}
}
}
- (void)viewDidLoad {
[super viewDidLoad];
[self addLongPressGesture];
self.userFullInfo = self.friendProfile.userFullInfo;
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 registerClass:[TUIButtonCell class] forCellReuseIdentifier:@"ButtonCell"];
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.userFullInfo.userID;
personal.avatarImage = DefaultAvatarImage;
personal.avatarUrl = [NSURL URLWithString:self.userFullInfo.faceURL];
personal.name = [self.userFullInfo showName];
personal.genderString = [self.userFullInfo showGender];
personal.signature = self.userFullInfo.selfSignature.length
? [NSString stringWithFormat:TIMCommonLocalizableString(SignatureFormat), self.userFullInfo.selfSignature]
: TIMCommonLocalizableString(no_personal_signature);
personal.reuseId = @"CardCell";
personal.showSignature = YES;
personal;
})];
inlist;
})];
if ([self isItemShown:TUIContactConfigItem_Alias]) {
[list addObject:({
NSMutableArray *inlist = @[].mutableCopy;
[inlist addObject:({
TUICommonContactTextCellData *data = TUICommonContactTextCellData.new;
data.key = TIMCommonLocalizableString(ProfileAlia);
data.value = self.friendProfile.friendRemark;
if (data.value.length == 0) {
data.value = TIMCommonLocalizableString(None);
}
data.showAccessory = YES;
data.cselector = @selector(onChangeRemark:);
data.reuseId = @"TextCell";
data;
})];
inlist;
})];
}
if ([self isItemShown:TUIContactConfigItem_MuteAndPin]) {
[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.friendProfile.userID ]
succ:^(NSArray<V2TIMUserReceiveMessageOptInfo *> *optList) {
for (V2TIMReceiveMessageOptInfo *info in optList) {
if ([info.userID isEqual:self.friendProfile.userID]) {
data.on = (info.receiveOpt == V2TIM_RECEIVE_NOT_NOTIFY_MESSAGE);
[weakSelf.tableView reloadData];
break;
}
}
}
fail:nil];
data;
})];
[inlist addObject:({
TUICommonContactSwitchCellData *data = TUICommonContactSwitchCellData.new;
data.title = TIMCommonLocalizableString(ProfileStickyonTop);
data.on = NO;
#ifndef SDKPlaceTop
#define SDKPlaceTop
#endif
#ifdef SDKPlaceTop
__weak typeof(self) weakSelf = self;
[V2TIMManager.sharedInstance getConversation:[NSString stringWithFormat:@"c2c_%@", self.friendProfile.userID]
succ:^(V2TIMConversation *conv) {
data.on = conv.isPinned;
[weakSelf.tableView reloadData];
}
fail:^(int code, NSString *desc){
}];
#else
if ([[[TUIConversationPin sharedInstance] topConversationList]
containsObject:[NSString stringWithFormat:@"c2c_%@", self.friendProfile.userID]]) {
data.on = YES;
}
#endif
data.cswitchSelector = @selector(onTopMostChat:);
data.reuseId = @"SwitchCell";
data;
})];
inlist;
})];
}
[list addObject:({
NSMutableArray *inlist = @[].mutableCopy;
if ([self isItemShown:TUIContactConfigItem_ClearChatHistory]) {
[inlist addObject:({
TUICommonContactTextCellData *data = TUICommonContactTextCellData.new;
data.key = TIMCommonLocalizableString(TUIKitClearAllChatHistory);
data.showAccessory = YES;
data.cselector = @selector(onClearHistoryChatMessage:);
data.reuseId = @"TextCell";
data;
})];
}
if ([self isItemShown:TUIContactConfigItem_Background]) {
[inlist addObject:({
TUICommonContactTextCellData *data = TUICommonContactTextCellData.new;
data.key = TIMCommonLocalizableString(ProfileSetBackgroundImage);
data.showAccessory = YES;
data.cselector = @selector(onChangeBackgroundImage:);
data.reuseId = @"TextCell";
data;
})];
}
inlist;
})];
if ([self isItemShown:TUIContactConfigItem_Block]) {
[list addObject:({
NSMutableArray *inlist = @[].mutableCopy;
[inlist addObject:({
TUICommonContactSwitchCellData *data = TUICommonContactSwitchCellData.new;
data.title = TIMCommonLocalizableString(ProfileBlocked);
data.cswitchSelector = @selector(onChangeBlackList:);
data.reuseId = @"SwitchCell";
__weak typeof(self) weakSelf = self;
[[V2TIMManager sharedInstance]
getBlackList:^(NSArray<V2TIMFriendInfo *> *infoList) {
for (V2TIMFriendInfo *friend in infoList) {
if ([friend.userID isEqualToString:self.friendProfile.userID]) {
data.on = true;
[weakSelf.tableView reloadData];
break;
}
}
}
fail:nil];
data;
})];
inlist;
})];
}
// Action menu
[list addObject:({
NSMutableArray *inlist = @[].mutableCopy;
// Extension menus
NSMutableDictionary *extensionParam = [NSMutableDictionary dictionary];
if (self.friendProfile.userID.length > 0) {
extensionParam[TUICore_TUIContactExtension_FriendProfileActionMenu_UserID] = self.friendProfile.userID;
}
extensionParam[TUICore_TUIContactExtension_FriendProfileActionMenu_FilterVideoCall] = @(NO);
extensionParam[TUICore_TUIContactExtension_FriendProfileActionMenu_FilterAudioCall] = @(NO);
NSArray *extensionList = [TUICore getExtensionList:TUICore_TUIContactExtension_FriendProfileActionMenu_ClassicExtensionID param:extensionParam];
for (TUIExtensionInfo *info in extensionList) {
if (info.text && info.onClicked) {
TUIButtonCellData *data = [[TUIButtonCellData alloc] init];
data.title = info.text;
data.style = ButtonWhite;
data.textColor = TIMCommonDynamicColor(@"primary_theme_color", @"147AFF");
data.reuseId = @"ButtonCell";
data.cbuttonSelector = @selector(onActionMenuExtensionClicked:);
data.tui_extValueObj = info;
[inlist addObject:data];
}
}
// Built-in "Delete Friend" menu
if ([self isItemShown:TUIContactConfigItem_Block]) {
[inlist addObject:({
TUIButtonCellData *data = TUIButtonCellData.new;
data.title = TIMCommonLocalizableString(ProfileDeleteFirend);
data.style = ButtonRedText;
data.cbuttonSelector = @selector(onDeleteFriend:);
data.reuseId = @"ButtonCell";
data;
})];
}
TUIButtonCellData *lastdata = [inlist lastObject];
lastdata.hideSeparatorLine = YES;
inlist;
})];
self.dataList = list;
[self.tableView reloadData];
}
- (BOOL)isItemShown:(TUIContactConfigItem)item {
return ![TUIContactConfig.sharedConfig isItemHiddenInContactConfig:item];
}
#pragma mark - Table view data source
- (void)onChangeBlackList:(TUICommonContactSwitchCell *)cell {
if (cell.switcher.on) {
[[V2TIMManager sharedInstance] addToBlackList:@[ self.friendProfile.userID ] succ:nil fail:nil];
} else {
[[V2TIMManager sharedInstance] deleteFromBlackList:@[ self.friendProfile.userID ] succ:nil fail:nil];
}
}
- (void)onChangeRemark:(TUICommonContactTextCell *)cell {
TUITextEditController *vc = [[TUITextEditController alloc] initWithText:self.friendProfile.friendRemark];
vc.title = TIMCommonLocalizableString(ProfileEditAlia); // @"";
vc.textValue = self.friendProfile.friendRemark;
[self.navigationController pushViewController:vc animated:YES];
@weakify(self);
[[RACObserve(vc, textValue) skip:1] subscribeNext:^(NSString *value) {
@strongify(self);
self.modified = YES;
self.friendProfile.friendRemark = value;
[[V2TIMManager sharedInstance] setFriendInfo:self.friendProfile
succ:^{
[self loadData];
[NSNotificationCenter.defaultCenter postNotificationName:@"FriendInfoChangedNotification"
object:self.friendProfile];
}
fail:nil];
}];
}
- (void)onClearHistoryChatMessage:(TUICommonContactTextCell *)cell {
if (IS_NOT_EMPTY_NSSTRING(self.friendProfile.userID)) {
NSString *userID = self.friendProfile.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];
}
}
- (void)onChangeBackgroundImage:(TUICommonContactTextCell *)cell {
@weakify(self);
NSString *conversationID = [NSString stringWithFormat:@"c2c_%@", self.friendProfile.userID];
TUISelectAvatarController *vc = [[TUISelectAvatarController alloc] init];
vc.selectAvatarType = TUISelectAvatarTypeConversationBackGroundCover;
vc.profilFaceURL = [self getBackgroundImageUrlByConversationID:conversationID];
[self.navigationController pushViewController:vc animated:YES];
vc.selectCallBack = ^(NSString *_Nonnull urlStr) {
@strongify(self);
[self appendBackgroundImage:urlStr conversationID:conversationID];
if (IS_NOT_EMPTY_NSSTRING(conversationID)) {
[TUICore notifyEvent:TUICore_TUIContactNotify
subKey:TUICore_TUIContactNotify_UpdateConversationBackgroundImageSubKey
object:self
param:@{TUICore_TUIContactNotify_UpdateConversationBackgroundImageSubKey_ConversationID : conversationID}];
}
};
}
- (NSString *)getBackgroundImageUrlByConversationID:(NSString *)targerConversationID {
if (targerConversationID.length == 0) {
return nil;
}
NSDictionary *dict = [NSUserDefaults.standardUserDefaults objectForKey:@"conversation_backgroundImage_map"];
if (dict == nil) {
dict = @{};
}
NSString *conversationID_UserID = [NSString stringWithFormat:@"%@_%@", targerConversationID, [TUILogin getUserID]];
if (![dict isKindOfClass:NSDictionary.class] || ![dict.allKeys containsObject:conversationID_UserID]) {
return nil;
}
return [dict objectForKey:conversationID_UserID];
}
- (void)appendBackgroundImage:(NSString *)imgUrl conversationID:(NSString *)conversationID {
if (conversationID.length == 0) {
return;
}
NSDictionary *dict = [NSUserDefaults.standardUserDefaults objectForKey:@"conversation_backgroundImage_map"];
if (dict == nil) {
dict = @{};
}
if (![dict isKindOfClass:NSDictionary.class]) {
return;
}
NSString *conversationID_UserID = [NSString stringWithFormat:@"%@_%@", conversationID, [TUILogin getUserID]];
NSMutableDictionary *originDataDict = [NSMutableDictionary dictionaryWithDictionary:dict];
if (imgUrl.length == 0) {
[originDataDict removeObjectForKey:conversationID_UserID];
} else {
[originDataDict setObject:imgUrl forKey:conversationID_UserID];
}
[NSUserDefaults.standardUserDefaults setObject:originDataDict forKey:@"conversation_backgroundImage_map"];
[NSUserDefaults.standardUserDefaults synchronize];
}
- (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:[TUIButtonCellData class]]) {
TUIButtonCell *cell = [tableView dequeueReusableCellWithIdentifier:@"ButtonCell"];
if (!cell) {
cell = [[TUIButtonCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"ButtonCell"];
}
[cell fillWithData:(TUIButtonCellData *)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)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
}
- (void)onActionMenuExtensionClicked:(id)sender {
if (![sender isKindOfClass:TUIButtonCell.class]) {
return;
}
TUIButtonCell *cell = (TUIButtonCell *)sender;
TUIButtonCellData *data = cell.buttonData;
TUIExtensionInfo *info = data.tui_extValueObj;
if (info && [info isKindOfClass:TUIExtensionInfo.class] && info.onClicked) {
NSMutableDictionary *param = [NSMutableDictionary dictionary];
if (self.friendProfile.userID.length > 0) {
param[TUICore_TUIContactExtension_FriendProfileActionMenu_UserID] = self.friendProfile.userID;
}
if (self.navigationController) {
param[TUICore_TUIContactExtension_FriendProfileActionMenu_PushVC] = self.navigationController;
}
info.onClicked(param);
}
}
- (void)onVoiceCall:(id)sender {
NSDictionary *param = @{
TUICore_TUICallingService_ShowCallingViewMethod_UserIDsKey : @[ self.userFullInfo.userID ?: @"" ],
TUICore_TUICallingService_ShowCallingViewMethod_CallTypeKey : @"0"
};
[TUICore callService:TUICore_TUICallingService method:TUICore_TUICallingService_ShowCallingViewMethod param:param];
}
- (void)onVideoCall:(id)sender {
NSDictionary *param = @{
TUICore_TUICallingService_ShowCallingViewMethod_UserIDsKey : @[ self.userFullInfo.userID ?: @"" ],
TUICore_TUICallingService_ShowCallingViewMethod_CallTypeKey : @"1"
};
[TUICore callService:TUICore_TUICallingService method:TUICore_TUICallingService_ShowCallingViewMethod param:param];
}
- (void)onDeleteFriend:(id)sender {
__weak typeof(self) weakSelf = self;
[[V2TIMManager sharedInstance]
deleteFromFriendList:@[ self.friendProfile.userID ]
deleteType:V2TIM_FRIEND_TYPE_BOTH
succ:^(NSArray<V2TIMFriendOperationResult *> *resultList) {
weakSelf.modified = YES;
[[TUIConversationPin sharedInstance] removeTopConversation:[NSString stringWithFormat:@"c2c_%@", weakSelf.friendProfile.userID]
callback:nil];
NSString *conversationID = [NSString stringWithFormat:@"c2c_%@", weakSelf.friendProfile.userID];
if (IS_NOT_EMPTY_NSSTRING(conversationID)) {
[TUICore notifyEvent:TUICore_TUIConversationNotify
subKey:TUICore_TUIConversationNotify_RemoveConversationSubKey
object:self
param:@{TUICore_TUIConversationNotify_RemoveConversationSubKey_ConversationID : conversationID}];
}
[weakSelf.navigationController popToRootViewControllerAnimated:YES];
}
fail:nil];
}
- (void)onSendMessage:(id)sender {
NSString *title = [self.friendProfile.userFullInfo showName];
if (IS_NOT_EMPTY_NSSTRING(self.friendProfile.friendRemark)) {
title = self.friendProfile.friendRemark;
}
NSDictionary *param = @{
TUICore_TUIChatObjectFactory_ChatViewController_Title : title,
TUICore_TUIChatObjectFactory_ChatViewController_UserID : self.friendProfile.userID,
TUICore_TUIChatObjectFactory_ChatViewController_ConversationID : [NSString stringWithFormat:@"c2c_%@", self.userFullInfo.userID]
};
[self.navigationController pushViewController:TUICore_TUIChatObjectFactory_ChatViewController_Classic param:param forResult:nil];
}
- (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.friendProfile.userID ] opt:opt succ:nil fail:nil];
}
- (void)onTopMostChat:(TUICommonContactSwitchCell *)cell {
if (cell.switcher.on) {
[[TUIConversationPin sharedInstance] addTopConversation:[NSString stringWithFormat:@"c2c_%@", self.friendProfile.userID]
callback:^(BOOL success, NSString *_Nonnull errorMessage) {
if (success) {
return;
}
cell.switcher.on = !cell.switcher.isOn;
[TUITool makeToast:errorMessage];
}];
} else {
[[TUIConversationPin sharedInstance] removeTopConversation:[NSString stringWithFormat:@"c2c_%@", self.friendProfile.userID]
callback:^(BOOL success, NSString *_Nonnull errorMessage) {
if (success) {
return;
}
cell.switcher.on = !cell.switcher.isOn;
[TUITool makeToast:errorMessage];
}];
}
}
- (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];
}
}
}
}
- (void)didTapOnAvatar:(TUICommonContactProfileCardCell *)cell {
TUIContactAvatarViewController *image = [[TUIContactAvatarViewController alloc] init];
image.avatarData = cell.cardData;
[self.navigationController pushViewController:image animated:YES];
}
+ (BOOL)isMarkedByHideType:(NSArray *)markList {
for (NSNumber *num in markList) {
if (num.unsignedLongValue == V2TIM_CONVERSATION_MARK_TYPE_HIDE) {
return YES;
}
}
return NO;
}
@end

View File

@@ -0,0 +1,18 @@
//
// TUIFriendRequestViewController.h
// TUIKitDemo
//
// Created by annidyfeng on 2019/4/18.
// Copyright © 2019 kennethmiao. All rights reserved.
//
#import <TIMCommon/TIMCommonModel.h>
#import <TIMCommon/TIMDefine.h>
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface TUIFriendRequestViewController : UIViewController
@property V2TIMUserFullInfo *profile;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,264 @@
//
// TUIFriendRequestViewController.m
// TUIKitDemo
//
// Created by annidyfeng on 2019/4/18.
// Copyright © 2019 kennethmiao. All rights reserved.
//
#import "TUIFriendRequestViewController.h"
#import <TIMCommon/TIMCommonModel.h>
#import <TIMCommon/TIMDefine.h>
#import <TUICore/TUIThemeManager.h>
#import <TUICore/UIView+TUILayout.h>
#import "TUICommonContactProfileCardCell.h"
#import "TUICommonContactSwitchCell.h"
#import "TUIContactAvatarViewController.h"
@interface TUIFriendRequestViewController () <UITableViewDataSource, UITableViewDelegate>
@property UITableView *tableView;
@property UITextView *addWordTextView;
@property UITextField *nickTextField;
@property BOOL keyboardShown;
@property TUICommonContactProfileCardCellData *cardCellData;
@property TUICommonContactSwitchCellData *singleSwitchData;
@property(nonatomic, strong) TUINaviBarIndicatorView *titleView;
@end
@implementation TUIFriendRequestViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.tableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];
[self.view addSubview:self.tableView];
self.tableView.frame = self.view.frame;
self.tableView.delegate = self;
self.tableView.dataSource = self;
[self.tableView setSeparatorInset:UIEdgeInsetsMake(0, 0, 0, 0)];
self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
self.tableView.backgroundColor = [UIColor groupTableViewBackgroundColor];
if (@available(iOS 15.0, *)) {
self.tableView.sectionHeaderTopPadding = 0;
}
self.addWordTextView = [[UITextView alloc] initWithFrame:CGRectZero];
self.addWordTextView.font = [UIFont systemFontOfSize:14];
self.addWordTextView.textAlignment = isRTL()?NSTextAlignmentRight:NSTextAlignmentLeft;
NSString *selfUserID = [[V2TIMManager sharedInstance] getLoginUser];
[[V2TIMManager sharedInstance] getUsersInfo:@[ selfUserID ]
succ:^(NSArray<V2TIMUserFullInfo *> *infoList) {
if (infoList && infoList.count > 0) {
V2TIMUserFullInfo *userInfo = [infoList firstObject];
if (userInfo) {
self.addWordTextView.text =
[NSString stringWithFormat:TIMCommonLocalizableString(FriendRequestFormat),
userInfo.nickName ? userInfo.nickName : userInfo.userID];
}
}
}
fail:^(int code, NSString *desc){
}];
self.nickTextField = [[UITextField alloc] initWithFrame:CGRectZero];
if (isRTL()) {
self.nickTextField.textAlignment = NSTextAlignmentLeft;
}
else {
self.nickTextField.textAlignment = NSTextAlignmentRight;
}
_titleView = [[TUINaviBarIndicatorView alloc] init];
[_titleView setTitle:TIMCommonLocalizableString(FriendRequestFillInfo)];
self.navigationItem.titleView = _titleView;
self.navigationItem.title = @"";
TUICommonContactProfileCardCellData *data = [TUICommonContactProfileCardCellData new];
data.name = [self.profile showName];
data.genderString = [self.profile showGender];
data.identifier = self.profile.userID;
data.signature = [self.profile showSignature];
data.avatarImage = DefaultAvatarImage;
data.avatarUrl = [NSURL URLWithString:self.profile.faceURL];
data.showSignature = YES;
self.cardCellData = data;
self.singleSwitchData = [TUICommonContactSwitchCellData new];
self.singleSwitchData.title = TIMCommonLocalizableString(FriendOneWay);
@weakify(self);
[[[[NSNotificationCenter defaultCenter] rac_addObserverForName:UIKeyboardWillShowNotification object:nil] filter:^BOOL(NSNotification *value) {
@strongify(self);
return !self.keyboardShown;
}] subscribeNext:^(NSNotification *x) {
@strongify(self);
self.keyboardShown = YES;
[self adjustContentOffsetDuringKeyboardAppear:YES withNotification:x];
}];
[[[[NSNotificationCenter defaultCenter] rac_addObserverForName:UIKeyboardWillHideNotification object:nil] filter:^BOOL(NSNotification *value) {
@strongify(self);
return self.keyboardShown;
}] subscribeNext:^(NSNotification *x) {
@strongify(self);
self.keyboardShown = NO;
[self adjustContentOffsetDuringKeyboardAppear:NO withNotification:x];
}];
}
#pragma mark - Keyboard
- (void)adjustContentOffsetDuringKeyboardAppear:(BOOL)appear withNotification:(NSNotification *)notification {
NSTimeInterval duration = [notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
UIViewAnimationCurve curve = [notification.userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue];
CGRect keyboardEndFrame = [notification.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
CGFloat keyboardHeight = CGRectGetHeight(keyboardEndFrame);
CGSize contentSize = self.tableView.contentSize;
contentSize.height += appear ? -keyboardHeight : keyboardHeight;
[UIView animateWithDuration:duration
delay:0
options:UIViewAnimationOptionBeginFromCurrentState | curve
animations:^{
self.tableView.contentSize = contentSize;
[self.view layoutIfNeeded];
}
completion:nil];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
{
if (indexPath.section == 0) {
return [self.cardCellData heightOfWidth:Screen_Width];
}
if (indexPath.section == 1) {
return 120;
}
return 44;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 4;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
UILabel *label = [[UILabel alloc] init];
label.textColor = [UIColor colorWithRed:136 / 255.0 green:136 / 255.0 blue:136 / 255.0 alpha:1 / 1.0];
label.font = [UIFont systemFontOfSize:14.0];
if (section == 1) {
label.text = [NSString stringWithFormat:@" %@", TIMCommonLocalizableString(please_fill_in_verification_information)];
} else if (section == 2) {
label.text = [NSString stringWithFormat:@" %@", TIMCommonLocalizableString(please_fill_in_remarks_group_info)];
}
return label;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return section == 0 ? 0 : 38;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.section == 0) {
TUICommonContactProfileCardCell *cell = [[TUICommonContactProfileCardCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:@"TPersonalCommonCell_ReuseId"];
cell.delegate = self;
[cell fillWithData:self.cardCellData];
return cell;
} else if (indexPath.section == 1) {
UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"AddWord"];
[cell.contentView addSubview:self.addWordTextView];
self.addWordTextView.mm_width(Screen_Width).mm_height(120);
return cell;
} else if (indexPath.section == 2) {
UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:@"NickName"];
cell.textLabel.text = TIMCommonLocalizableString(Alia);
[cell.contentView addSubview:self.nickTextField];
UIView *separtor = [[UIView alloc] init];
separtor.backgroundColor = [UIColor groupTableViewBackgroundColor];
[cell.contentView addSubview:separtor];
separtor.mm_width(tableView.mm_w).mm_bottom(0).mm_left(0).mm_height(1);
self.nickTextField.mm_width(cell.contentView.mm_w / 2).mm_height(cell.contentView.mm_h).mm_right(20);
self.nickTextField.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
return cell;
} else if (indexPath.section == 3) {
TUIButtonCell *cell = [[TUIButtonCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"send"];
TUIButtonCellData *data = [[TUIButtonCellData alloc] init];
data.style = ButtonWhite;
data.title = TIMCommonLocalizableString(Send);
data.cselector = @selector(onSend);
data.textColor =
TIMCommonDynamicColor(@"primary_theme_color", @"147AFF"); //[UIColor colorWithRed:20/255.0 green:122/255.0 blue:255/255.0 alpha:1/1.0];
[cell fillWithData:data];
return cell;
}
return nil;
}
- (BOOL)tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath {
return NO;
}
- (void)onSend {
[self.view endEditing:YES];
// display toast with an activity spinner
[TUITool makeToastActivity];
V2TIMFriendAddApplication *application = [[V2TIMFriendAddApplication alloc] init];
application.addWording = self.addWordTextView.text;
application.friendRemark = self.nickTextField.text;
application.userID = self.profile.userID;
application.addSource = @"iOS";
if (self.singleSwitchData.on) {
application.addType = V2TIM_FRIEND_TYPE_SINGLE;
} else {
application.addType = V2TIM_FRIEND_TYPE_BOTH;
}
[[V2TIMManager sharedInstance] addFriend:application
succ:^(V2TIMFriendOperationResult *result) {
NSString *msg = nil;
if (ERR_SUCC == result.resultCode) {
msg = TIMCommonLocalizableString(FriendAddResultSuccess);
} else if (ERR_SVR_FRIENDSHIP_INVALID_PARAMETERS == result.resultCode) {
if ([result.resultInfo isEqualToString:@"Err_SNS_FriendAdd_Friend_Exist"]) {
msg = TIMCommonLocalizableString(FriendAddResultExists);
}
} else {
msg = [TUITool convertIMError:result.resultCode msg:result.resultInfo];
}
if (msg.length == 0) {
msg = [NSString stringWithFormat:@"%ld", (long)result.resultCode];
}
[TUITool hideToastActivity];
[TUITool makeToast:msg duration:3.0 idposition:TUICSToastPositionBottom];
}
fail:^(int code, NSString *desc) {
[TUITool hideToastActivity];
[TUITool makeToastError:code msg:desc];
}];
}
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
[self.view endEditing:YES];
}
- (void)didTapOnAvatar:(TUICommonContactProfileCardCell *)cell {
TUIContactAvatarViewController *image = [[TUIContactAvatarViewController alloc] init];
image.avatarData = cell.cardData;
[self.navigationController pushViewController:image animated:YES];
}
@end

View File

@@ -0,0 +1,30 @@
// Created by Tencent on 2023/06/09.
// Copyright © 2023 Tencent. All rights reserved.
#import <UIKit/UIKit.h>
#import "TUIGroupConversationListViewDataProvider.h"
NS_ASSUME_NONNULL_BEGIN
typedef void (^TUIGroupConversationListSelectCallback)(TUICommonContactCellData *cellData);
/**
* 【Module name】Group list interface (TUIGroupConversationListController)
* 【Function description】Responsible for pulling the group information of the user and displaying it in the interface.
* Users can view all the groups they hava joined through the group list interface. The groups are displayed in the order of the first latter of the group
* names, and the group names with special symbols are displayed at the end.
*/
@interface TUIGroupConversationListController : UIViewController
@property(nonatomic, strong) UITableView *tableView;
@property(nonatomic, strong) TUIGroupConversationListViewDataProvider *viewModel;
/**
* The selected callback, if it is empty, TUIKit will jump by itself
*/
@property(nonatomic, copy) TUIGroupConversationListSelectCallback __nullable onSelect;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,191 @@
//
// TUIGroupConversationListController.m
// TXIMSDK_TUIKit_iOS
//
// Created by annidyfeng on 2019/6/10.
// Copyright © 2023 Tencent. All rights reserved.
//
#import "TUIGroupConversationListController.h"
#import <TIMCommon/TIMCommonModel.h>
#import <TIMCommon/TIMDefine.h>
#import <TUICore/TUICore.h>
#import <TUICore/TUIThemeManager.h>
static NSString *gConversationCell_ReuseId = @"TConversationCell";
@interface TUIGroupConversationListController () <UIGestureRecognizerDelegate,
UITableViewDelegate,
UITableViewDataSource,
UIPopoverPresentationControllerDelegate>
@property(nonatomic, strong) UILabel *noDataTipsLabel;
@end
@implementation TUIGroupConversationListController
- (void)viewDidLoad {
[super viewDidLoad];
UILabel *titleLabel = [[UILabel alloc] init];
titleLabel.text = TIMCommonLocalizableString(TUIKitContactsGroupChats);
titleLabel.font = [UIFont boldSystemFontOfSize:17.0];
titleLabel.textColor = TIMCommonDynamicColor(@"nav_title_text_color", @"#000000");
[titleLabel sizeToFit];
self.navigationItem.titleView = titleLabel;
self.view.backgroundColor = TIMCommonDynamicColor(@"controller_bg_color", @"#F2F3F5");
CGRect rect = self.view.bounds;
_tableView = [[UITableView alloc] initWithFrame:rect style:UITableViewStylePlain];
[self.view addSubview:_tableView];
_tableView.delegate = self;
_tableView.dataSource = self;
[_tableView setSectionIndexBackgroundColor:[UIColor clearColor]];
[_tableView setSectionIndexColor:[UIColor darkGrayColor]];
[_tableView setBackgroundColor:self.view.backgroundColor];
if (@available(iOS 15.0, *)) {
_tableView.sectionHeaderTopPadding = 0;
}
UIView *v = [[UIView alloc] initWithFrame:CGRectZero];
[_tableView setTableFooterView:v];
_tableView.separatorInset = UIEdgeInsetsMake(0, 58, 0, 0);
[_tableView registerClass:[TUICommonContactCell class] forCellReuseIdentifier:gConversationCell_ReuseId];
self.viewModel = [TUIGroupConversationListViewDataProvider new];
[self updateConversations];
@weakify(self);
[RACObserve(self.viewModel, isLoadFinished) subscribeNext:^(id _Nullable x) {
@strongify(self);
[self.tableView reloadData];
}];
self.noDataTipsLabel.frame = CGRectMake(10, 60, self.view.bounds.size.width - 20, 40);
[self.tableView addSubview:self.noDataTipsLabel];
}
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)updateConversations {
[self.viewModel loadConversation];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView;
{
self.noDataTipsLabel.hidden = (self.viewModel.groupList.count != 0);
return self.viewModel.groupList.count;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.viewModel.dataDict[self.viewModel.groupList[section]].count;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
TUICommonContactCellData *data = self.viewModel.dataDict[self.viewModel.groupList[indexPath.section]][indexPath.row];
return [data heightOfWidth:Screen_Width];
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
return YES;
}
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
return UITableViewCellEditingStyleDelete;
}
- (NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath {
return TIMCommonLocalizableString(Delete);
}
- (BOOL)tableView:(UITableView *)tableView shouldIndentWhileEditingRowAtIndexPath:(NSIndexPath *)indexPath {
return NO;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
[tableView beginUpdates];
TUICommonContactCellData *data = self.viewModel.dataDict[self.viewModel.groupList[indexPath.section]][indexPath.row];
[self.viewModel removeData:data];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObjects:indexPath, nil] withRowAnimation:UITableViewRowAnimationNone];
[tableView endUpdates];
}
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
#define TEXT_TAG 1
static NSString *headerViewId = @"ContactDrawerView";
UITableViewHeaderFooterView *headerView = [tableView dequeueReusableHeaderFooterViewWithIdentifier:headerViewId];
if (!headerView) {
headerView = [[UITableViewHeaderFooterView alloc] initWithReuseIdentifier:headerViewId];
UILabel *textLabel = [[UILabel alloc] initWithFrame:CGRectZero];
textLabel.tag = TEXT_TAG;
textLabel.textColor = RGB(0x80, 0x80, 0x80);
[textLabel setRtlAlignment:TUITextRTLAlignmentLeading];
[headerView addSubview:textLabel];
[textLabel mas_remakeConstraints:^(MASConstraintMaker *make) {
make.leading.mas_equalTo(headerView.mas_leading).mas_offset(12);
make.top.bottom.trailing.mas_equalTo(headerView);
}];
textLabel.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
}
UILabel *label = [headerView viewWithTag:TEXT_TAG];
label.text = self.viewModel.groupList[section];
headerView.backgroundColor = TIMCommonDynamicColor(@"controller_bg_color", @"#F2F3F5");
headerView.contentView.backgroundColor = TIMCommonDynamicColor(@"controller_bg_color", @"#F2F3F5");
return headerView;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return 33;
}
- (void)didSelectConversation:(TUICommonContactCell *)cell {
if (self.onSelect) {
self.onSelect(cell.contactData);
return;
}
NSDictionary *param = @{
TUICore_TUIChatObjectFactory_ChatViewController_Title : cell.contactData.title ?: @"",
TUICore_TUIChatObjectFactory_ChatViewController_GroupID : cell.contactData.identifier ?: @"",
};
[self.navigationController pushViewController:TUICore_TUIChatObjectFactory_ChatViewController_Classic param:param forResult:nil];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
TUICommonContactCell *cell = [tableView dequeueReusableCellWithIdentifier:gConversationCell_ReuseId forIndexPath:indexPath];
TUICommonContactCellData *data = self.viewModel.dataDict[self.viewModel.groupList[indexPath.section]][indexPath.row];
if (!data.cselector) {
data.cselector = @selector(didSelectConversation:);
}
[cell fillWithData:data];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
}
- (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller {
return UIModalPresentationNone;
}
- (UILabel *)noDataTipsLabel {
if (_noDataTipsLabel == nil) {
_noDataTipsLabel = [[UILabel alloc] init];
_noDataTipsLabel.textColor = TIMCommonDynamicColor(@"nodata_tips_color", @"#999999");
_noDataTipsLabel.font = [UIFont systemFontOfSize:14.0];
_noDataTipsLabel.textAlignment = NSTextAlignmentCenter;
_noDataTipsLabel.text = TIMCommonLocalizableString(TUIKitContactNoGroupChats);
}
return _noDataTipsLabel;
}
@end

View File

@@ -0,0 +1,21 @@
//
// TUIGroupCreateController.h
// TUIContact
//
// Created by wyl on 2022/8/22.
// Copyright © 2023 Tencent. All rights reserved.
//
#import <TIMCommon/TIMCommonModel.h>
#import <TIMCommon/TIMDefine.h>
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface TUIGroupCreateController : UIViewController
@property(nonatomic, strong) V2TIMGroupInfo *createGroupInfo;
@property(nonatomic, strong) NSArray<TUICommonContactSelectCellData *> *createContactArray;
@property(nonatomic, copy) void (^submitCallback)(BOOL isSuccess, V2TIMGroupInfo *info);
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,432 @@
//
// TUIGroupCreateController.m
// TUIContact
//
// Created by wyl on 2022/8/22.
// Copyright © 2023 Tencent. All rights reserved.
//
#import "TUIGroupCreateController.h"
#import <TIMCommon/TIMCommonModel.h>
#import <TIMCommon/TIMDefine.h>
#import <TUICore/TUILogin.h>
#import <TUICore/TUIThemeManager.h>
#import <TUICore/UIView+TUILayout.h>
#import "TUIGroupTypeListController.h"
@interface TUIGroupCreateController () <UITableViewDataSource, UITableViewDelegate, UITextFieldDelegate>
@property(nonatomic, strong) UITableView *tableView;
@property(nonatomic, strong) UITextField *groupNameTextField;
@property(nonatomic, strong) UITextField *groupIDTextField;
@property(nonatomic, assign) BOOL keyboardShown;
@property(nonatomic, strong) TUINaviBarIndicatorView *titleView;
@property(nonatomic, strong) UITextView *describeTextView;
@property(nonatomic, assign) CGRect describeTextViewRect;
@property(nonatomic, strong) TUIContactListPicker *pickerView;
@property(nonatomic, strong) UIImage *cacheGroupGridAvatarImage;
@end
@implementation TUIGroupCreateController
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
_pickerView.mm_width(self.view.mm_w).mm_height(60 + _pickerView.mm_safeAreaBottomGap).mm_bottom(0);
_tableView.mm_width(self.view.mm_w).mm_flexToBottom(_pickerView.mm_h);
}
- (void)viewDidLoad {
[super viewDidLoad];
self.tableView = [[UITableView alloc] initWithFrame:self.view.frame style:UITableViewStylePlain];
[self.view addSubview:self.tableView];
self.tableView.frame = self.view.frame;
self.tableView.delegate = self;
self.tableView.dataSource = self;
[self.tableView setSeparatorInset:UIEdgeInsetsMake(0, 0, 0, 0)];
self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
self.tableView.backgroundColor = [UIColor groupTableViewBackgroundColor];
if (@available(iOS 15.0, *)) {
self.tableView.sectionHeaderTopPadding = 0;
}
self.groupNameTextField = [[UITextField alloc] initWithFrame:CGRectZero];
self.groupNameTextField.textAlignment = isRTL()?NSTextAlignmentLeft: NSTextAlignmentRight;
self.groupNameTextField.placeholder = TIMCommonLocalizableString(TUIKitCreatGroupNamed_Placeholder);
self.groupNameTextField.delegate = self;
if (IS_NOT_EMPTY_NSSTRING(self.createGroupInfo.groupName)) {
self.groupNameTextField.text = self.createGroupInfo.groupName;
}
self.groupIDTextField = [[UITextField alloc] initWithFrame:CGRectZero];
self.groupIDTextField.textAlignment = isRTL()?NSTextAlignmentLeft: NSTextAlignmentRight;
self.groupIDTextField.keyboardType = UIKeyboardTypeDefault;
self.groupIDTextField.placeholder = TIMCommonLocalizableString(TUIKitCreatGroupID_Placeholder);
self.groupIDTextField.delegate = self;
[self updateRectAndTextForDescribeTextView:self.describeTextView];
_titleView = [[TUINaviBarIndicatorView alloc] init];
[_titleView setTitle:TIMCommonLocalizableString(ChatsNewGroupText)];
self.navigationItem.titleView = _titleView;
self.navigationItem.title = @"";
_pickerView = [[TUIContactListPicker alloc] initWithFrame:CGRectZero];
[_pickerView setBackgroundColor:[UIColor groupTableViewBackgroundColor]];
[self.view addSubview:_pickerView];
_pickerView.accessoryBtn.enabled = YES;
[_pickerView.accessoryBtn addTarget:self action:@selector(finishTask) forControlEvents:UIControlEventTouchUpInside];
[self creatGroupAvatarImage];
}
- (UITextView *)describeTextView {
if (!_describeTextView) {
_describeTextView = [[UITextView alloc] init];
_describeTextView.backgroundColor = [UIColor clearColor];
_describeTextView.textAlignment = isRTL()?NSTextAlignmentRight:NSTextAlignmentLeft;
_describeTextView.editable = NO;
_describeTextView.scrollEnabled = NO;
_describeTextView.textContainerInset = UIEdgeInsetsMake(0.f, 0.f, 0.f, 0.f);
}
return _describeTextView;
}
- (void)creatGroupAvatarImage {
if (!TUIConfig.defaultConfig.enableGroupGridAvatar) {
return;
}
if (_cacheGroupGridAvatarImage) {
return;
}
NSMutableArray *muArray = [NSMutableArray array];
for (TUICommonContactSelectCellData *cellData in self.createContactArray) {
if (cellData.avatarUrl.absoluteString.length > 0) {
[muArray addObject:cellData.avatarUrl.absoluteString];
} else {
[muArray addObject:@"about:blank"];
}
}
// currentUser
[muArray addObject:[TUILogin getFaceUrl] ?: @""];
@weakify(self);
[TUIGroupAvatar createGroupAvatar:muArray
finished:^(UIImage *groupAvatar) {
@strongify(self);
self.cacheGroupGridAvatarImage = groupAvatar;
[self.tableView reloadData];
}];
}
- (void)updateRectAndTextForDescribeTextView:(UITextView *)describeTextView {
__block NSString *descStr = @"";
[self.class getfomatDescribeType:self.createGroupInfo.groupType
completion:^(NSString *groupTypeStr, NSString *groupTypeDescribeStr) {
descStr = groupTypeDescribeStr;
}];
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.minimumLineHeight = 18;
[paragraphStyle setLineBreakMode:NSLineBreakByWordWrapping];
[paragraphStyle setAlignment:isRTL()?NSTextAlignmentRight: NSTextAlignmentLeft];
NSDictionary *dictionary = @{
NSFontAttributeName : [UIFont systemFontOfSize:12],
NSForegroundColorAttributeName : [UIColor tui_colorWithHex:@"#888888"],
NSParagraphStyleAttributeName : paragraphStyle
};
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:descStr attributes:dictionary];
[attributedString addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0, [descStr length])];
NSString *inviteTipstring = TIMCommonLocalizableString(TUIKitCreatGroupType_Desc_Highlight);
[attributedString addAttribute:NSLinkAttributeName value:@"https://cloud.tencent.com/product/im" range:[descStr rangeOfString:inviteTipstring]];
self.describeTextView.attributedText = attributedString;
CGRect rect =
[self.describeTextView.text boundingRectWithSize:CGSizeMake(self.view.mm_w - 32, MAXFLOAT)
options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading
attributes:@{NSFontAttributeName : [UIFont systemFontOfSize:12], NSParagraphStyleAttributeName : paragraphStyle}
context:nil];
self.describeTextViewRect = rect;
}
#pragma mark - tableView
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
{
if (indexPath.section == 2) {
return 88;
}
return 44;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 3;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
UIView *view = [[UIView alloc] init];
view.backgroundColor = [UIColor clearColor];
if (section == 2) {
[view addSubview:self.describeTextView];
_describeTextView.mm_width(_describeTextViewRect.size.width).mm_height(_describeTextViewRect.size.height).mm_top(10).mm_left(15);
}
return view;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return section == 2 ? _describeTextViewRect.size.height + 20 : 10;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (section == 0) {
return 2;
}
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.section == 0) {
if (indexPath.row == 0) {
UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:@"groupName"];
cell.textLabel.text = TIMCommonLocalizableString(TUIKitCreatGroupNamed);
[cell.contentView addSubview:self.groupNameTextField];
cell.backgroundColor = TIMCommonDynamicColor(@"form_bg_color", @"#FFFFFF");
[self.groupNameTextField mas_remakeConstraints:^(MASConstraintMaker *make) {
make.trailing.mas_equalTo(cell.contentView.mas_trailing).mas_offset(- 16);
make.height.mas_equalTo(cell.contentView);
make.width.mas_equalTo(cell.contentView).multipliedBy(0.5);
make.centerY.mas_equalTo(cell.contentView);
}];
return cell;
} else {
UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:@"groupID"];
cell.backgroundColor = TIMCommonDynamicColor(@"form_bg_color", @"#FFFFFF");
cell.textLabel.text = TIMCommonLocalizableString(TUIKitCreatGroupID);
[cell.contentView addSubview:self.groupIDTextField];
[self.groupIDTextField mas_remakeConstraints:^(MASConstraintMaker *make) {
make.trailing.mas_equalTo(cell.contentView.mas_trailing).mas_offset(- 16);
make.height.mas_equalTo(cell.contentView);
make.width.mas_equalTo(cell.contentView).multipliedBy(0.5);
make.centerY.mas_equalTo(cell.contentView);
}];
return cell;
}
} else if (indexPath.section == 1) {
UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:@"GroupType"];
cell.backgroundColor = TIMCommonDynamicColor(@"form_bg_color", @"#FFFFFF");
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
cell.textLabel.text = TIMCommonLocalizableString(TUIKitCreatGroupType);
[self.class getfomatDescribeType:self.createGroupInfo.groupType
completion:^(NSString *groupTypeStr, NSString *groupTypeDescribeStr) {
cell.detailTextLabel.text = groupTypeStr;
}];
return cell;
} else if (indexPath.section == 2) {
UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:@"GroupType"];
cell.backgroundColor = TIMCommonDynamicColor(@"form_bg_color", @"#FFFFFF");
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
cell.textLabel.text = TIMCommonLocalizableString(TUIKitCreatGroupAvatar);
UIImageView *headImage = [[UIImageView alloc] initWithImage:DefaultGroupAvatarImageByGroupType(self.createGroupInfo.groupType)];
[cell.contentView addSubview:headImage];
if (TUIConfig.defaultConfig.enableGroupGridAvatar && self.cacheGroupGridAvatarImage) {
[headImage sd_setImageWithURL:[NSURL URLWithString:self.createGroupInfo.faceURL] placeholderImage:self.cacheGroupGridAvatarImage];
}
CGFloat margin = 5;
[headImage mas_remakeConstraints:^(MASConstraintMaker *make) {
make.trailing.mas_equalTo(cell.contentView.mas_trailing).mas_offset(- margin);
make.height.width.mas_equalTo(48);
make.centerY.mas_equalTo(cell.contentView);
}];
return cell;
}
return nil;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:NO];
if (indexPath.section == 1) {
TUIGroupTypeListController *vc = [[TUIGroupTypeListController alloc] init];
vc.title = @"";
[self.navigationController pushViewController:vc animated:YES];
@weakify(self);
vc.selectCallBack = ^(NSString *_Nonnull groupType) {
@strongify(self);
self.createGroupInfo.groupType = groupType;
[self updateRectAndTextForDescribeTextView:self.describeTextView];
[self.tableView reloadData];
};
} else if (indexPath.section == 2) {
[self didTapToChooseAvatar];
}
}
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
[self.view endEditing:YES];
}
#pragma mark - textField
- (void)textFieldDidEndEditing:(UITextField *)textField {
if (textField == self.groupNameTextField) {
if (textField.text.length > 10) {
textField.text = [textField.text substringToIndex:10];
}
}
}
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
// Check for total length
if (textField == self.groupIDTextField) {
NSUInteger lengthOfString = string.length;
// Check for total length
NSUInteger proposedNewLength = textField.text.length - range.length + string.length;
if (proposedNewLength > 16) {
return NO;
}
return YES;
}
return YES;
}
#pragma mark - format
+ (void)getfomatDescribeType:(NSString *)groupType completion:(void (^)(NSString *groupTypeStr, NSString *groupTypeDescribeStr))completion {
if (!completion) {
return;
}
NSString *desc = @"";
if ([groupType isEqualToString:@"Work"]) {
desc = [NSString
stringWithFormat:@"%@\n%@", TIMCommonLocalizableString(TUIKitCreatGroupType_Work_Desc), TIMCommonLocalizableString(TUIKitCreatGroupType_See_Doc)];
completion(TIMCommonLocalizableString(TUIKitCreatGroupType_Work), desc);
} else if ([groupType isEqualToString:@"Public"]) {
desc = [NSString
stringWithFormat:@"%@\n%@", TIMCommonLocalizableString(TUIKitCreatGroupType_Public_Desc), TIMCommonLocalizableString(TUIKitCreatGroupType_See_Doc)];
completion(TIMCommonLocalizableString(TUIKitCreatGroupType_Public), desc);
} else if ([groupType isEqualToString:@"Meeting"]) {
desc = [NSString stringWithFormat:@"%@\n%@", TIMCommonLocalizableString(TUIKitCreatGroupType_Meeting_Desc),
TIMCommonLocalizableString(TUIKitCreatGroupType_See_Doc)];
completion(TIMCommonLocalizableString(TUIKitCreatGroupType_Meeting), desc);
} else if ([groupType isEqualToString:@"Community"]) {
desc = [NSString stringWithFormat:@"%@\n%@", TIMCommonLocalizableString(TUIKitCreatGroupType_Community_Desc),
TIMCommonLocalizableString(TUIKitCreatGroupType_See_Doc)];
completion(TIMCommonLocalizableString(TUIKitCreatGroupType_Community), desc);
} else {
completion(groupType, groupType);
}
}
#pragma mark - action
- (void)didTapToChooseAvatar {
TUISelectAvatarController *vc = [[TUISelectAvatarController alloc] init];
vc.selectAvatarType = TUISelectAvatarTypeGroupAvatar;
vc.createGroupType = self.createGroupInfo.groupType;
vc.cacheGroupGridAvatarImage = self.cacheGroupGridAvatarImage;
vc.profilFaceURL = self.createGroupInfo.faceURL;
[self.navigationController pushViewController:vc animated:YES];
@weakify(self);
vc.selectCallBack = ^(NSString *_Nonnull urlStr) {
if (urlStr.length > 0) {
@strongify(self);
self.createGroupInfo.faceURL = urlStr;
} else {
self.createGroupInfo.faceURL = nil;
}
[self.tableView reloadData];
};
}
- (void)finishTask {
self.createGroupInfo.groupName = self.groupNameTextField.text;
self.createGroupInfo.groupID = self.groupIDTextField.text;
V2TIMGroupInfo *info = self.createGroupInfo;
if (!info) {
return;
}
if (!self.createContactArray) {
return;
}
BOOL isCommunity = [info.groupType isEqualToString:@"Community"];
BOOL hasTGSPrefix = [info.groupID hasPrefix:@"@TGS#_"];
if (self.groupIDTextField.text.length > 0 ) {
if (isCommunity && !hasTGSPrefix) {
NSString *toastMsg = TIMCommonLocalizableString(TUICommunityCreateTipsMessageRuleError);
[TUITool makeToast:toastMsg duration:3.0 idposition:TUICSToastPositionBottom];
return;
}
if (!isCommunity && hasTGSPrefix) {
NSString *toastMsg = TIMCommonLocalizableString(TUIGroupCreateTipsMessageRuleError);
[TUITool makeToast:toastMsg duration:3.0 idposition:TUICSToastPositionBottom];
return;
}
}
NSMutableArray *members = [NSMutableArray array];
for (TUICommonContactSelectCellData *item in self.createContactArray) {
V2TIMCreateGroupMemberInfo *member = [[V2TIMCreateGroupMemberInfo alloc] init];
member.userID = item.identifier;
member.role = V2TIM_GROUP_MEMBER_ROLE_MEMBER;
[members addObject:member];
}
NSString *showName = [TUILogin getNickName] ?: [TUILogin getUserID];
@weakify(self);
[[V2TIMManager sharedInstance] createGroup:info
memberList:members
succ:^(NSString *groupID) {
@strongify(self);
NSString *content = TIMCommonLocalizableString(TUIGroupCreateTipsMessage);
if ([info.groupType isEqualToString:GroupType_Community]) {
content = TIMCommonLocalizableString(TUICommunityCreateTipsMessage);
}
NSDictionary *dic = @{
@"version" : @(GroupCreate_Version),
BussinessID : BussinessID_GroupCreate,
@"opUser" : showName,
@"content" : content,
@"cmd" : [info.groupType isEqualToString:GroupType_Community] ? @1 : @0
};
NSData *data = [NSJSONSerialization dataWithJSONObject:dic options:NSJSONWritingPrettyPrinted error:nil];
V2TIMMessage *msg = [[V2TIMManager sharedInstance] createCustomMessage:data];
[[V2TIMManager sharedInstance] sendMessage:msg
receiver:nil
groupID:groupID
priority:V2TIM_PRIORITY_DEFAULT
onlineUserOnly:NO
offlinePushInfo:nil
progress:nil
succ:nil
fail:nil];
self.createGroupInfo.groupID = groupID;
// wait for a second to ensure the group created message arrives first
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.15 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
if (self.submitCallback) {
self.submitCallback(YES, self.createGroupInfo);
}
});
}
fail:^(int code, NSString *msg) {
@strongify(self);
if (code == ERR_SDK_INTERFACE_NOT_SUPPORT) {
[TUITool postUnsupportNotificationOfService:TIMCommonLocalizableString(TUIKitErrorUnsupportIntefaceCommunity)
serviceDesc:TIMCommonLocalizableString(TUIKitErrorUnsupportIntefaceCommunityDesc)
debugOnly:YES];
} else {
NSString *toastMsg = nil;
toastMsg = [TUITool convertIMError:code msg:msg];
if (toastMsg.length == 0) {
toastMsg = [NSString stringWithFormat:@"%ld", (long)code];
}
[TUITool hideToastActivity];
[TUITool makeToast:toastMsg duration:3.0 idposition:TUICSToastPositionBottom];
}
if (self.submitCallback) {
self.submitCallback(NO, self.createGroupInfo);
}
}];
}
@end

View File

@@ -0,0 +1,19 @@
//
// TUIGroupManageController.h
// TUIGroup
//
// Created by harvy on 2021/12/24.
// Copyright © 2023 Tencent. All rights reserved.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface TUIGroupManageController : UIViewController
@property(nonatomic, copy) NSString *groupID;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,260 @@
//
// TUIGroupManageController.m
// TUIGroup
//
// Created by harvy on 2021/12/24.
// Copyright © 2023 Tencent. All rights reserved.
//
#import "TUIGroupManageController.h"
#import <TUICore/TUIGlobalization.h>
#import <TUICore/TUIThemeManager.h>
#import "TUIGroupManageDataProvider.h"
#import "TUIMemberInfoCell.h"
#import "TUIMemberInfoCellData.h"
#import "TUISelectGroupMemberViewController.h"
#import "TUISettingAdminController.h"
@interface TUIGroupManageController () <UITableViewDelegate, UITableViewDataSource, TUIGroupManageDataProviderDelegate>
@property(nonatomic, strong) UITableView *tableView;
@property(nonatomic, strong) TUIGroupManageDataProvider *dataProvider;
@property(nonatomic, strong) UIView *coverView;
@end
@implementation TUIGroupManageController
- (void)viewDidLoad {
[super viewDidLoad];
[self setupViews];
self.dataProvider.groupID = self.groupID;
[self showCoverViewWhenMuteAll:YES];
[self.dataProvider loadData];
}
- (void)setupViews {
UILabel *titleLabel = [[UILabel alloc] init];
titleLabel.text = TIMCommonLocalizableString(TUIKitGroupProfileManage);
titleLabel.font = [UIFont boldSystemFontOfSize:17.0];
titleLabel.textColor = TIMCommonDynamicColor(@"nav_title_text_color", @"#000000");
[titleLabel sizeToFit];
self.navigationItem.titleView = titleLabel;
[self.view addSubview:self.tableView];
}
- (void)viewWillLayoutSubviews {
[super viewWillLayoutSubviews];
self.tableView.frame = self.view.bounds;
}
- (void)onSettingAdmin:(TUICommonTextCellData *)textData {
if (!self.dataProvider.currentGroupTypeSupportSettingAdmin) {
[TUITool makeToast:TIMCommonLocalizableString(TUIKitGroupSetAdminsForbidden)];
return;
}
TUISettingAdminController *vc = [[TUISettingAdminController alloc] init];
vc.groupID = self.groupID;
__weak typeof(self) weakSelf = self;
vc.settingAdminDissmissCallBack = ^{
[weakSelf.dataProvider updateMuteMembersFilterAdmins];
[weakSelf.tableView reloadData];
};
[self.navigationController pushViewController:vc animated:YES];
}
- (void)onMutedAll:(TUICommonSwitchCell *)switchCell {
__weak typeof(self) weakSelf = self;
[self.dataProvider mutedAll:switchCell.switcher.isOn
completion:^(int code, NSString *error) {
if (code != 0) {
switchCell.switcher.on = !switchCell.switcher.isOn;
[weakSelf.view makeToast:error];
return;
}
[weakSelf showCoverViewWhenMuteAll:switchCell.switcher.isOn];
}];
}
#pragma mark - TUIGroupManageDataProviderDelegate
- (void)onError:(int)code desc:(NSString *)desc operate:(NSString *)operate {
if (code != 0) {
[TUITool makeToast:[NSString stringWithFormat:@"%d, %@", code, desc]];
}
}
- (void)showCoverViewWhenMuteAll:(BOOL)show {
[self.coverView removeFromSuperview];
if (show) {
CGFloat y = 0;
if (self.dataProvider.datas.count == 0) {
y = 100;
} else {
CGRect rect = [self.tableView rectForSection:0];
y = CGRectGetMaxY(rect);
}
self.coverView.frame = CGRectMake(0, y, self.tableView.mm_w, self.tableView.mm_h);
[self.tableView addSubview:self.coverView];
}
}
- (void)reloadData {
[self.tableView reloadData];
__weak typeof(self) weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
[weakSelf showCoverViewWhenMuteAll:weakSelf.dataProvider.muteAll];
});
}
- (void)insertSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation {
[self.tableView insertSections:sections withRowAnimation:animation];
}
- (void)reloadRowsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation {
[self.tableView reloadRowsAtIndexPaths:indexPaths withRowAnimation:animation];
}
- (void)insertRowsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation {
[self.tableView insertRowsAtIndexPaths:indexPaths withRowAnimation:animation];
}
#pragma mark - UITableViewDelegate, UITableViewDataSource
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return self.dataProvider.datas.count;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSArray *subArray = self.dataProvider.datas[section];
return subArray.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = nil;
NSArray *subArray = self.dataProvider.datas[indexPath.section];
TUICommonCellData *data = subArray[indexPath.row];
if ([data isKindOfClass:TUICommonTextCellData.class]) {
cell = [[TUICommonTextCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:NSStringFromClass(TUICommonTextCell.class)];
[(TUICommonTextCell *)cell fillWithData:(TUICommonTextCellData *)data];
} else if ([data isKindOfClass:TUICommonSwitchCellData.class]) {
cell = [[TUICommonSwitchCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:NSStringFromClass(TUICommonSwitchCell.class)];
[(TUICommonSwitchCell *)cell fillWithData:(TUICommonSwitchCellData *)data];
} else if ([data isKindOfClass:TUIMemberInfoCellData.class]) {
cell = [[TUIMemberInfoCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:NSStringFromClass(TUIMemberInfoCell.class)];
[(TUIMemberInfoCell *)cell setData:(TUIMemberInfoCellData *)data];
} else {
cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
cell.textLabel.text = @"";
}
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 48.0;
}
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
return section == 0 ? 30 : 0;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return 0;
}
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {
UIView *view = [[UIView alloc] init];
view.backgroundColor = [UIColor groupTableViewBackgroundColor];
UILabel *label = [[UILabel alloc] init];
label.text = TIMCommonLocalizableString(TUIKitGroupManageShutupAllTips);
label.textColor = [UIColor colorWithRed:136 / 255.0 green:136 / 255.0 blue:136 / 255.0 alpha:1 / 1.0];
label.font = [UIFont systemFontOfSize:14.0];
[view addSubview:label];
[label sizeToFit];
label.mm_x = 20;
label.mm_y = 10;
return view;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:NO];
if (indexPath.section == 1 && indexPath.row == 0) {
if (!self.dataProvider.currentGroupTypeSupportAddMemberOfBlocked) {
[TUITool makeToast:TIMCommonLocalizableString(TUIKitGroupAddMemberOfBlockedForbidden)];
return;
}
TUISelectGroupMemberViewController *vc = [[TUISelectGroupMemberViewController alloc] init];
vc.optionalStyle = TUISelectMemberOptionalStylePublicMan;
vc.groupId = self.groupID;
vc.name = TIMCommonLocalizableString(TUIKitGroupProfileMember);
__weak typeof(self) weakSelf = self;
vc.selectedFinished = ^(NSMutableArray<TUIUserModel *> *_Nonnull modelList) {
for (TUIUserModel *userModel in modelList) {
[weakSelf.dataProvider mute:YES user:userModel];
}
};
[self.navigationController pushViewController:vc animated:YES];
}
}
- (NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath {
return TIMCommonLocalizableString(Delete);
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.section == 1 && indexPath.row > 0) {
return YES;
}
return NO;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
TUIMemberInfoCellData *cellData = self.dataProvider.datas[indexPath.section][indexPath.row];
if (![cellData isKindOfClass:TUIMemberInfoCellData.class]) {
return;
}
TUIUserModel *userModel = [[TUIUserModel alloc] init];
userModel.userId = cellData.identifier;
[self.dataProvider mute:NO user:userModel];
}
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
return [[UIView alloc] init];
}
- (UITableView *)tableView {
if (_tableView == nil) {
_tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStyleGrouped];
_tableView.backgroundColor = TIMCommonDynamicColor(@"controller_bg_color", @"#F2F3F5");
_tableView.delaysContentTouches = NO;
_tableView.delegate = self;
_tableView.dataSource = self;
}
return _tableView;
}
- (TUIGroupManageDataProvider *)dataProvider {
if (_dataProvider == nil) {
_dataProvider = [[TUIGroupManageDataProvider alloc] init];
_dataProvider.delegate = self;
}
return _dataProvider;
}
- (UIView *)coverView {
if (_coverView == nil) {
_coverView = [[UIView alloc] init];
_coverView.backgroundColor = self.tableView.backgroundColor;
}
return _coverView;
}
@end

View File

@@ -0,0 +1,27 @@
// Created by Tencent on 2023/06/09.
// Copyright © 2023 Tencent. All rights reserved.
#import <UIKit/UIKit.h>
#import "TUIGroupMembersView.h"
@class TUIGroupMemberController;
@class V2TIMGroupInfo;
/////////////////////////////////////////////////////////////////////////////////
//
// TUIGroupMemberController
//
/////////////////////////////////////////////////////////////////////////////////
@interface TUIGroupMemberController : UIViewController
@property(nonatomic, strong) UITableView *tableView;
@property(nonatomic, strong) NSString *groupId;
@property(nonatomic, strong) V2TIMGroupInfo *groupInfo;
- (void)refreshData;
@end

View File

@@ -0,0 +1,311 @@
//
// GroupMemberController.m
// UIKit
//
// Created by kennethmiao on 2018/9/27.
// Copyright © 2018 Tencent. All rights reserved.
//
#import "TUIGroupMemberController.h"
#import <TIMCommon/TIMDefine.h>
#import <TUICore/TUICore.h>
#import <TIMCommon/TIMGroupInfo+TUIDataProvider.h>
#import "TUIGroupMemberCell.h"
#import "TUIGroupMemberDataProvider.h"
#import <TUICore/TUILogin.h>
#import <TUICore/TUIThemeManager.h>
#import "TUIMemberInfoCell.h"
#import "TUIMemberInfoCellData.h"
@interface TUIGroupMemberController () <UITableViewDelegate, UITableViewDataSource>
@property(nonatomic, strong) UIActivityIndicatorView *indicatorView;
@property(nonatomic, strong) TUINaviBarIndicatorView *titleView;
@property(nonatomic, strong) UIViewController *showContactSelectVC;
@property(nonatomic, strong) TUIGroupMemberDataProvider *dataProvider;
@property(nonatomic, strong) NSMutableArray<TUIMemberInfoCellData *> *members;
@property NSInteger tag;
@end
@implementation TUIGroupMemberController
- (void)viewDidLoad {
[super viewDidLoad];
[self setupViews];
self.dataProvider = [[TUIGroupMemberDataProvider alloc] initWithGroupID:self.groupId];
self.dataProvider.groupInfo = self.groupInfo;
[self refreshData];
}
- (void)refreshData {
@weakify(self);
[self.dataProvider loadDatas:^(BOOL success, NSString *_Nonnull err, NSArray *_Nonnull datas) {
@strongify(self);
NSString *title = [NSString stringWithFormat:TIMCommonLocalizableString(TUIKitGroupProfileGroupCountFormat), (long)datas.count];
self.title = title;
self.members = [NSMutableArray arrayWithArray:datas];
[self.tableView reloadData];
}];
}
- (void)setupViews {
self.view.backgroundColor = TIMCommonDynamicColor(@"controller_bg_color", @"#F2F3F5");
// left
UIImage *image = TUIContactDynamicImage(@"group_nav_back_img", [UIImage imageNamed:TUIContactImagePath(@"back")]);
image = [image rtl_imageFlippedForRightToLeftLayoutDirection];
UIButton *leftButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 30, 30)];
[leftButton addTarget:self action:@selector(leftBarButtonClick) forControlEvents:UIControlEventTouchUpInside];
[leftButton setImage:image forState:UIControlStateNormal];
UIBarButtonItem *leftItem = [[UIBarButtonItem alloc] initWithCustomView:leftButton];
UIBarButtonItem *spaceItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
spaceItem.width = -10.0f;
if (([[TUITool deviceVersion] floatValue] >= 11.0)) {
leftButton.contentEdgeInsets = UIEdgeInsetsMake(0, -15, 0, 0);
leftButton.imageEdgeInsets = UIEdgeInsetsMake(0, -15, 0, 0);
}
self.navigationItem.leftBarButtonItems = @[ spaceItem, leftItem ];
self.parentViewController.navigationItem.leftBarButtonItems = @[ spaceItem, leftItem ];
// right
UIButton *rightButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 30, 30)];
[rightButton addTarget:self action:@selector(rightBarButtonClick) forControlEvents:UIControlEventTouchUpInside];
[rightButton setTitle:TIMCommonLocalizableString(TUIKitGroupProfileManage) forState:UIControlStateNormal];
[rightButton setTitleColor:TIMCommonDynamicColor(@"nav_title_text_color", @"#000000") forState:UIControlStateNormal];
rightButton.titleLabel.font = [UIFont systemFontOfSize:16];
UIBarButtonItem *rightItem = [[UIBarButtonItem alloc] initWithCustomView:rightButton];
self.navigationItem.rightBarButtonItem = rightItem;
self.parentViewController.navigationItem.rightBarButtonItem = rightItem;
self.indicatorView.frame = CGRectMake(0, 0, self.view.bounds.size.width, TMessageController_Header_Height);
self.tableView.frame = self.view.bounds;
self.tableView.tableFooterView = self.indicatorView;
[self.view addSubview:self.tableView];
_titleView = [[TUINaviBarIndicatorView alloc] init];
self.navigationItem.titleView = _titleView;
self.navigationItem.title = @"";
[_titleView setTitle:TIMCommonLocalizableString(GroupMember)];
}
- (void)leftBarButtonClick {
[self.navigationController popViewControllerAnimated:YES];
}
- (void)rightBarButtonClick {
UIAlertController *ac = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet];
NSMutableArray *ids = [NSMutableArray array];
NSMutableDictionary *displayNames = [NSMutableDictionary dictionary];
for (TUIGroupMemberCellData *cd in self.members) {
if (![cd.identifier isEqualToString:[[V2TIMManager sharedInstance] getLoginUser]]) {
[ids addObject:cd.identifier];
[displayNames setObject:cd.name ?: @"" forKey:cd.identifier ?: @""];
}
}
@weakify(self);
void (^selectContactCompletion)(NSArray<TUICommonContactSelectCellData *> *) = ^(NSArray<TUICommonContactSelectCellData *> *array) {
@strongify(self);
if (self.tag == 1) {
// add
NSMutableArray *list = @[].mutableCopy;
for (TUICommonContactSelectCellData *data in array) {
[list addObject:data.identifier];
}
[self.navigationController popToViewController:self animated:YES];
[self addGroupId:self.groupId memebers:list];
} else if (self.tag == 2) {
// delete
NSMutableArray *list = @[].mutableCopy;
for (TUICommonContactSelectCellData *data in array) {
[list addObject:data.identifier];
}
[self.navigationController popToViewController:self animated:YES];
[self deleteGroupId:self.groupId memebers:list];
}
};
if ([self.dataProvider.groupInfo canInviteMember]) {
[ac tuitheme_addAction:[UIAlertAction
actionWithTitle:TIMCommonLocalizableString(TUIKitGroupProfileManageAdd)
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *_Nonnull action) {
// add
self.tag = 1;
NSMutableDictionary *param = [NSMutableDictionary dictionary];
param[TUICore_TUIContactObjectFactory_GetContactSelectControllerMethod_TitleKey] =
TIMCommonLocalizableString(GroupAddFirend);
param[TUICore_TUIContactObjectFactory_GetContactSelectControllerMethod_DisableIdsKey] = ids;
param[TUICore_TUIContactObjectFactory_GetContactSelectControllerMethod_DisplayNamesKey] = displayNames;
param[TUICore_TUIContactObjectFactory_GetContactSelectControllerMethod_CompletionKey] = selectContactCompletion;
self.showContactSelectVC = [TUICore createObject:TUICore_TUIContactObjectFactory
key:TUICore_TUIContactObjectFactory_GetContactSelectControllerMethod
param:param];
[self.navigationController pushViewController:self.showContactSelectVC animated:YES];
}]];
}
if ([self.dataProvider.groupInfo canRemoveMember]) {
[ac tuitheme_addAction:[UIAlertAction
actionWithTitle:TIMCommonLocalizableString(TUIKitGroupProfileManageDelete)
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *_Nonnull action) {
// delete
self.tag = 2;
NSMutableDictionary *param = [NSMutableDictionary dictionary];
param[TUICore_TUIContactObjectFactory_GetContactSelectControllerMethod_TitleKey] =
TIMCommonLocalizableString(GroupDeleteFriend);
param[TUICore_TUIContactObjectFactory_GetContactSelectControllerMethod_SourceIdsKey] = ids;
param[TUICore_TUIContactObjectFactory_GetContactSelectControllerMethod_DisplayNamesKey] = displayNames;
param[TUICore_TUIContactObjectFactory_GetContactSelectControllerMethod_CompletionKey] = selectContactCompletion;
self.showContactSelectVC = [TUICore createObject:TUICore_TUIContactObjectFactory
key:TUICore_TUIContactObjectFactory_GetContactSelectControllerMethod
param:param];
[self.navigationController pushViewController:self.showContactSelectVC animated:YES];
}]];
}
[ac tuitheme_addAction:[UIAlertAction actionWithTitle:TIMCommonLocalizableString(Cancel) style:UIAlertActionStyleCancel handler:nil]];
[self presentViewController:ac animated:YES completion:nil];
}
- (void)addGroupId:(NSString *)groupId memebers:(NSArray *)members {
@weakify(self);
[[V2TIMManager sharedInstance] inviteUserToGroup:_groupId
userList:members
succ:^(NSArray<V2TIMGroupMemberOperationResult *> *resultList) {
@strongify(self);
[self refreshData];
[TUITool makeToast:TIMCommonLocalizableString(add_success)];
}
fail:^(int code, NSString *desc) {
[TUITool makeToastError:code msg:desc];
}];
}
- (void)deleteGroupId:(NSString *)groupId memebers:(NSArray *)members {
@weakify(self);
[[V2TIMManager sharedInstance] kickGroupMember:groupId
memberList:members
reason:@""
succ:^(NSArray<V2TIMGroupMemberOperationResult *> *resultList) {
@strongify(self);
[self refreshData];
[TUITool makeToast:TIMCommonLocalizableString(delete_success)];
}
fail:^(int code, NSString *desc) {
[TUITool makeToastError:code msg:desc];
}];
}
#pragma mark - UITableViewDelegate, UITableViewDataSource
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.members.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
TUIMemberInfoCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
TUIMemberInfoCellData *data = self.members[indexPath.row];
cell.data = data;
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:NO];
TUIMemberInfoCellData *data = self.members[indexPath.row];
if (data) {
[self didCurrentMemberAtCellData:data];
}
}
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
return 0;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return 0;
}
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {
return [UIView new];
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
return [UIView new];
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
if (scrollView.contentOffset.y > 0 && (scrollView.contentOffset.y >= scrollView.bounds.origin.y)) {
if (self.indicatorView.isAnimating) {
return;
}
[self.indicatorView startAnimating];
// There's no more data, stop loading.
if (self.dataProvider.isNoMoreData) {
[self.indicatorView stopAnimating];
[TUITool makeToast:TIMCommonLocalizableString(TUIKitMessageReadNoMoreData)];
return;
}
@weakify(self);
[self.dataProvider loadDatas:^(BOOL success, NSString *_Nonnull err, NSArray *_Nonnull datas) {
@strongify(self);
[self.indicatorView stopAnimating];
if (!success) {
return;
}
[self.members addObjectsFromArray:datas];
[self.tableView reloadData];
[self.tableView layoutIfNeeded];
if (datas.count == 0) {
[self.tableView setContentOffset:CGPointMake(0, scrollView.contentOffset.y - TMessageController_Header_Height) animated:YES];
}
}];
}
}
- (void)didCurrentMemberAtCellData:(TUIMemberInfoCellData *)mem {
NSString *userID = mem.identifier;
@weakify(self);
[self getUserOrFriendProfileVCWithUserID:userID
succBlock:^(UIViewController *vc) {
@strongify(self);
[self.navigationController pushViewController:vc animated:YES];
}
failBlock:^(int code, NSString *desc){
}];
}
- (void)getUserOrFriendProfileVCWithUserID:(NSString *)userID succBlock:(void (^)(UIViewController *vc))succ failBlock:(nullable V2TIMFail)fail {
NSDictionary *param = @{
TUICore_TUIContactObjectFactory_GetUserOrFriendProfileVCMethod_UserIDKey: userID ? : @"",
TUICore_TUIContactObjectFactory_GetUserOrFriendProfileVCMethod_SuccKey: succ ? : ^(UIViewController *vc){},
TUICore_TUIContactObjectFactory_GetUserOrFriendProfileVCMethod_FailKey: fail ? : ^(int code, NSString * desc){}
};
[TUICore createObject:TUICore_TUIContactObjectFactory key:TUICore_TUIContactObjectFactory_GetUserOrFriendProfileVCMethod param:param];
}
- (UIActivityIndicatorView *)indicatorView {
if (_indicatorView == nil) {
_indicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
_indicatorView.hidesWhenStopped = YES;
}
return _indicatorView;
}
- (UITableView *)tableView {
if (_tableView == nil) {
_tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStyleGrouped];
_tableView.backgroundColor = TIMCommonDynamicColor(@"controller_bg_color", @"#F2F3F5");
_tableView.delegate = self;
_tableView.dataSource = self;
[_tableView registerClass:TUIMemberInfoCell.class forCellReuseIdentifier:@"cell"];
_tableView.rowHeight = 48.0;
}
return _tableView;
}
@end

View File

@@ -0,0 +1,17 @@
//
// TUIGroupRequestViewController.h
// TUIKitDemo
//
// Created by annidyfeng on 2019/5/20.
// Copyright © 2019 Tencent. All rights reserved.
//
#import <TIMCommon/TIMDefine.h>
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface TUIGroupRequestViewController : UIViewController
@property V2TIMGroupInfo *groupInfo;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,168 @@
//
// TUIGroupRequestViewController.m
// TUIKitDemo
//
// Created by annidyfeng on 2019/5/20.
// Copyright © 2019 Tencent. All rights reserved.
//
#import "TUIGroupRequestViewController.h"
#import <TIMCommon/TIMCommonModel.h>
#import <TIMCommon/TIMDefine.h>
@interface TUIGroupRequestViewController () <UITableViewDataSource, UITableViewDelegate, TUIProfileCardDelegate>
@property UITableView *tableView;
@property UITextView *addMsgTextView;
@property TUIProfileCardCellData *cardCellData;
@end
@implementation TUIGroupRequestViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.tableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStyleGrouped];
[self.view addSubview:self.tableView];
self.tableView.mm_fill();
self.tableView.delegate = self;
self.tableView.dataSource = self;
self.addMsgTextView = [[UITextView alloc] initWithFrame:CGRectZero];
self.addMsgTextView.font = [UIFont systemFontOfSize:14];
self.addMsgTextView.textAlignment = isRTL()?NSTextAlignmentRight:NSTextAlignmentLeft;
NSString *loginUser = [[V2TIMManager sharedInstance] getLoginUser];
[[V2TIMManager sharedInstance] getUsersInfo:@[ loginUser ]
succ:^(NSArray<V2TIMUserFullInfo *> *infoList) {
self.addMsgTextView.text = [NSString
stringWithFormat:TIMCommonLocalizableString(GroupRequestJoinGroupFormat), [[infoList firstObject] showName]];
}
fail:^(int code, NSString *msg){
}];
TUIProfileCardCellData *data = [TUIProfileCardCellData new];
data.name = self.groupInfo.groupName;
data.identifier = self.groupInfo.groupID;
data.avatarImage = DefaultGroupAvatarImageByGroupType(self.groupInfo.groupType);
data.avatarUrl = [NSURL URLWithString:self.groupInfo.faceURL];
self.cardCellData = data;
self.title = TIMCommonLocalizableString(GroupJoin);
[TUITool addUnsupportNotificationInVC:self];
}
- (void)dealloc {
NSLog(@"%s dealloc", __FUNCTION__);
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
{
if (indexPath.section == 0) {
return [self.cardCellData heightOfWidth:Screen_Width];
}
if (indexPath.section == 1) {
return 120;
}
if (indexPath.section == 2) {
return 54;
}
return 0.;
}
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {
UIView *view = [[UIView alloc] init];
return view;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
UIView *view = [[UIView alloc] init];
view.backgroundColor = [UIColor clearColor];
UILabel *label = [[UILabel alloc] init];
label.text = TIMCommonLocalizableString(please_fill_in_verification_information);
label.textColor = [UIColor colorWithRed:136 / 255.0 green:136 / 255.0 blue:136 / 255.0 alpha:1 / 1.0];
label.font = [UIFont systemFontOfSize:14.0];
label.frame = CGRectMake(10, 0, self.tableView.bounds.size.width - 20, 40);
[view addSubview:label];
return section == 1 ? view : nil;
}
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
return 0;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
if (section == 1) {
return 40;
}
if (section == 2) {
return 10;
}
return 0;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView;
{ return 3; }
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.section == 0) {
TUIProfileCardCell *cell = [[TUIProfileCardCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"TPersonalCommonCell_ReuseId"];
cell.delegate = self;
[cell fillWithData:self.cardCellData];
return cell;
}
if (indexPath.section == 1) {
UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"AddWord"];
[cell.contentView addSubview:self.addMsgTextView];
self.addMsgTextView.mm_width(Screen_Width).mm_height(120);
return cell;
}
if (indexPath.section == 2) {
TUIButtonCell *cell = [[TUIButtonCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"send"];
TUIButtonCellData *cellData = [[TUIButtonCellData alloc] init];
cellData.title = TIMCommonLocalizableString(Send);
cellData.style = ButtonWhite;
cellData.cselector = @selector(onSend);
cellData.textColor = [UIColor colorWithRed:20 / 255.0 green:122 / 255.0 blue:255 / 255.0 alpha:1 / 1.0];
[cell fillWithData:cellData];
return cell;
}
return nil;
}
- (BOOL)tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath {
return NO;
}
- (void)onSend {
// display toast with an activity spinner
[TUITool makeToastActivity];
[[V2TIMManager sharedInstance] joinGroup:self.groupInfo.groupID
msg:self.addMsgTextView.text
succ:^{
[TUITool hideToastActivity];
[TUITool makeToast:TIMCommonLocalizableString(send_success) duration:3.0 idposition:TUICSToastPositionBottom];
}
fail:^(int code, NSString *desc) {
[TUITool hideToastActivity];
[TUITool makeToastError:code msg:desc];
if (code == ERR_SDK_INTERFACE_NOT_SUPPORT) {
[TUITool postUnsupportNotificationOfService:TIMCommonLocalizableString(TUIKitErrorUnsupportIntefaceCommunity)
serviceDesc:TIMCommonLocalizableString(TUIKitErrorUnsupportIntefaceCommunityDesc)
debugOnly:YES];
}
}];
}
- (void)didTapOnAvatar:(TUIProfileCardCell *)cell {
TUIAvatarViewController *image = [[TUIAvatarViewController alloc] init];
image.avatarData = cell.cardData;
[self.navigationController pushViewController:image animated:YES];
}
@end

View File

@@ -0,0 +1,19 @@
//
// TUIGroupTypeListController.h
// TUIContact
//
// Created by wyl on 2022/8/23.
// Copyright © 2023 Tencent. All rights reserved.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface TUIGroupTypeListController : UIViewController
@property(nonatomic, copy) void (^selectCallBack)(NSString *groupType);
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,317 @@
//
// TUIGroupTypeListController.m
// TUIContact
//
// Created by wyl on 2022/8/23.
// Copyright © 2023 Tencent. All rights reserved.
//
#import "TUIGroupTypeListController.h"
#import <TIMCommon/TIMCommonModel.h>
#import <TIMCommon/TIMDefine.h>
#import <TUICore/UIView+TUILayout.h>
@interface TUIGroupTypeData : NSObject
@property(nonatomic, strong) UIImage *image;
@property(nonatomic, copy) NSString *title;
@property(nonatomic, copy) NSString *describeText;
@property(nonatomic, copy) NSString *groupType;
@property(nonatomic, assign) CGFloat cellHeight;
- (void)caculateCellHeight;
@end
@interface TUIGroupTypeCell : UITableViewCell
@property(nonatomic, strong) UIImageView *image;
@property(nonatomic, strong) UILabel *title;
@property(nonatomic, strong) UITextView *describeTextView;
@property(nonatomic, assign) CGRect describeTextViewRect;
@property(nonatomic, strong) TUIGroupTypeData *cellData;
- (void)setData:(TUIGroupTypeData *)data;
@end
@implementation TUIGroupTypeData
- (void)caculateCellHeight {
__block NSString *descStr = self.describeText;
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.minimumLineHeight = 18;
if (@available(iOS 9.0, *)) {
paragraphStyle.allowsDefaultTighteningForTruncation = YES;
}
paragraphStyle.alignment = NSTextAlignmentJustified;
CGRect rect = [descStr boundingRectWithSize:CGSizeMake(Screen_Width - 32, MAXFLOAT)
options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading
attributes:@{NSFontAttributeName : [UIFont systemFontOfSize:12], NSParagraphStyleAttributeName : paragraphStyle}
context:nil];
rect.size.width = ceil(rect.size.width) + 1;
rect.size.height = ceil(rect.size.height) + 1;
CGFloat height = 0;
// Image Height
height += 12;
height += 40;
// Image Describe Height
height += 8;
height += rect.size.height;
height += 16;
self.cellHeight = height;
}
@end
@implementation TUIGroupTypeCell
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
[self setupViews];
}
return self;
}
- (void)setupViews {
self.backgroundColor = TIMCommonDynamicColor(@"form_bg_color", @"#FFFFFF");
_image = [[UIImageView alloc] init];
_image.contentMode = UIViewContentModeScaleAspectFit;
[self addSubview:_image];
_title = [[UILabel alloc] init];
_title.font = [UIFont systemFontOfSize:16];
_title.textColor = TIMCommonDynamicColor(@"form_title_color", @"#000000");
_title.textAlignment = isRTL()?NSTextAlignmentRight:NSTextAlignmentLeft;
_title.numberOfLines = 0;
[self addSubview:_title];
[self addSubview:self.describeTextView];
}
+ (BOOL)requiresConstraintBasedLayout {
return YES;
}
// this is Apple's recommended place for adding/updating constraints
- (void)updateConstraints {
[super updateConstraints];
[self.image mas_remakeConstraints:^(MASConstraintMaker *make) {
make.leading.mas_equalTo(self.contentView).mas_offset(16);
make.top.mas_equalTo(self.contentView).mas_offset(16);
make.width.height.mas_equalTo(40);
}];
[self.title sizeToFit];
[self.title mas_remakeConstraints:^(MASConstraintMaker *make) {
make.leading.mas_equalTo(self.image.mas_trailing).mas_offset(10);
make.centerY.mas_equalTo(self.image);
make.trailing.mas_equalTo(self.contentView).mas_offset(- 4);
}];
[self.describeTextView mas_remakeConstraints:^(MASConstraintMaker *make) {
make.leading.mas_equalTo(16);
make.trailing.mas_equalTo(self.contentView).mas_offset(-16);
make.top.mas_equalTo(self.image.mas_bottom).mas_offset(8);
make.height.mas_equalTo(_describeTextViewRect.size.height);
}];
}
- (void)setData:(TUIGroupTypeData *)data {
_cellData = data;
_image.image = data.image;
_title.text = data.title;
[self updateRectAndTextForDescribeTextView:self.describeTextView groupType:data.groupType];
}
- (UITextView *)describeTextView {
if (!_describeTextView) {
_describeTextView = [[UITextView alloc] init];
_describeTextView.backgroundColor = [UIColor clearColor];
_describeTextView.editable = NO;
_describeTextView.scrollEnabled = NO;
_describeTextView.textContainerInset = UIEdgeInsetsMake(0.f, 0.f, 0.f, 0.f);
_describeTextView.textAlignment = isRTL()?NSTextAlignmentRight:NSTextAlignmentLeft;
}
return _describeTextView;
}
- (void)updateRectAndTextForDescribeTextView:(UITextView *)describeTextView groupType:(NSString *)groupType {
__block NSString *descStr = self.cellData.describeText;
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.minimumLineHeight = 18;
if (@available(iOS 9.0, *)) {
paragraphStyle.allowsDefaultTighteningForTruncation = YES;
}
paragraphStyle.alignment = isRTL()?NSTextAlignmentRight: NSTextAlignmentLeft;
NSDictionary *dictionary = @{
NSFontAttributeName : [UIFont systemFontOfSize:12],
NSForegroundColorAttributeName : [UIColor tui_colorWithHex:@"#888888"],
NSParagraphStyleAttributeName : paragraphStyle
};
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:descStr attributes:dictionary];
[attributedString addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0, [descStr length])];
self.describeTextView.attributedText = attributedString;
CGRect rect = [descStr boundingRectWithSize:CGSizeMake(Screen_Width - 32, MAXFLOAT)
options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading
attributes:@{NSFontAttributeName : [UIFont systemFontOfSize:12], NSParagraphStyleAttributeName : paragraphStyle}
context:nil];
rect.size.width = ceil(rect.size.width) + 1;
rect.size.height = ceil(rect.size.height) + 1;
self.describeTextViewRect = rect;
}
@end
@interface TUIGroupTypeListController () <UITableViewDataSource, UITableViewDelegate>
@property(nonatomic, strong) UITableView *tableView;
@property(nonatomic, strong) TUINaviBarIndicatorView *titleView;
@property(nonatomic, strong) NSMutableArray *data;
@property(nonatomic, strong) UIButton *bottomButton;
@end
@implementation TUIGroupTypeListController
- (void)viewDidLoad {
[super viewDidLoad];
[self setupData];
[self setupView];
}
- (void)setupData {
self.data = [NSMutableArray array];
{
// work
TUIGroupTypeData *dataWork = [[TUIGroupTypeData alloc] init];
dataWork.groupType = GroupType_Work;
dataWork.image = DefaultGroupAvatarImageByGroupType(GroupType_Work);
dataWork.title = TIMCommonLocalizableString(TUIKitCreatGroupType_Work);
dataWork.describeText = [NSString
stringWithFormat:@"%@%@", TIMCommonLocalizableString(TUIKitCreatGroupType_Work_Desc), TIMCommonLocalizableString(TUIKitCreatGroupType_See_Doc)];
[dataWork caculateCellHeight];
[self.data addObject:dataWork];
}
{
// Public
TUIGroupTypeData *dataPublic = [[TUIGroupTypeData alloc] init];
dataPublic.groupType = GroupType_Public;
dataPublic.image = DefaultGroupAvatarImageByGroupType(GroupType_Public);
dataPublic.title = TIMCommonLocalizableString(TUIKitCreatGroupType_Public);
dataPublic.describeText = [NSString
stringWithFormat:@"%@%@", TIMCommonLocalizableString(TUIKitCreatGroupType_Public_Desc), TIMCommonLocalizableString(TUIKitCreatGroupType_See_Doc)];
[dataPublic caculateCellHeight];
[self.data addObject:dataPublic];
}
{
// Meeting
TUIGroupTypeData *dataMeeting = [[TUIGroupTypeData alloc] init];
dataMeeting.groupType = GroupType_Meeting;
dataMeeting.image = DefaultGroupAvatarImageByGroupType(GroupType_Meeting);
dataMeeting.title = TIMCommonLocalizableString(TUIKitCreatGroupType_Meeting);
dataMeeting.describeText = [NSString
stringWithFormat:@"%@%@", TIMCommonLocalizableString(TUIKitCreatGroupType_Meeting_Desc), TIMCommonLocalizableString(TUIKitCreatGroupType_See_Doc)];
[dataMeeting caculateCellHeight];
[self.data addObject:dataMeeting];
}
{
// Community
TUIGroupTypeData *dataCommunity = [[TUIGroupTypeData alloc] init];
dataCommunity.groupType = GroupType_Community;
dataCommunity.image = DefaultGroupAvatarImageByGroupType(GroupType_Community);
dataCommunity.title = TIMCommonLocalizableString(TUIKitCreatGroupType_Community);
dataCommunity.describeText = [NSString stringWithFormat:@"%@%@", TIMCommonLocalizableString(TUIKitCreatGroupType_Community_Desc),
TIMCommonLocalizableString(TUIKitCreatGroupType_See_Doc)];
[dataCommunity caculateCellHeight];
[self.data addObject:dataCommunity];
}
}
- (void)setupView {
self.tableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];
[self.view addSubview:self.tableView];
self.tableView.frame = self.view.frame;
self.tableView.delegate = self;
self.tableView.dataSource = self;
[self.tableView setSeparatorInset:UIEdgeInsetsMake(0, 0, 0, 0)];
self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
self.tableView.backgroundColor = [UIColor groupTableViewBackgroundColor];
if (@available(iOS 15.0, *)) {
self.tableView.sectionHeaderTopPadding = 0;
}
_titleView = [[TUINaviBarIndicatorView alloc] init];
[_titleView setTitle:TIMCommonLocalizableString(ChatsNewGroupText)];
self.navigationItem.titleView = _titleView;
self.navigationItem.title = @"";
UIView *bottomView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.mm_w, 140)];
self.tableView.tableFooterView = bottomView;
self.bottomButton = [UIButton buttonWithType:UIButtonTypeCustom];
[bottomView addSubview:self.bottomButton];
self.bottomButton.titleLabel.font = [UIFont systemFontOfSize:13];
[self.bottomButton setTitle:TIMCommonLocalizableString(TUIKitCreatGroupType_See_Doc_Simple) forState:UIControlStateNormal];
[self.bottomButton setTitleColor:[UIColor systemBlueColor] forState:UIControlStateNormal];
self.bottomButton.mm_width(self.view.mm_w - 30).mm_bottom(40).mm__centerX(self.view.mm_w / 2.0).mm_height(18);
[self.bottomButton addTarget:self action:@selector(bottomButtonClick) forControlEvents:UIControlEventTouchUpInside];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
{
TUIGroupTypeData *data = self.data[indexPath.section];
return data.cellHeight;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView;
{ return 4; }
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 1;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
UIView *view = [[UIView alloc] init];
view.backgroundColor = [UIColor clearColor];
return view;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return 10;
}
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
return 140;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
TUIGroupTypeCell *cell = [tableView dequeueReusableCellWithIdentifier:@"TUIGroupTypeCell"];
if (cell == nil) {
cell = [[TUIGroupTypeCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"TUIGroupTypeCell"];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
[cell setData:self.data[indexPath.section]];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
TUIGroupTypeData *data = self.data[indexPath.section];
if (self.selectCallBack) {
self.selectCallBack(data.groupType);
}
[self.navigationController popViewControllerAnimated:YES];
}
- (void)bottomButtonClick {
NSURL *url = [NSURL URLWithString:@"https://cloud.tencent.com/product/im"];
[TUITool openLinkWithURL:url];
}
@end

View File

@@ -0,0 +1,21 @@
// Created by Tencent on 2023/06/09.
// Copyright © 2023 Tencent. All rights reserved.
#import <UIKit/UIKit.h>
#import "TUICommonPendencyCell.h"
NS_ASSUME_NONNULL_BEGIN
/**
* 【Module name】The interface that displays the received friend request (TUINewFriendViewController)
* 【Function description】Responsible for pulling friend application information and displaying it in the interface.
* Through this interface, you can view the friend requests you have received, and perform the operations of agreeing/rejecting the application.
*/
@interface TUINewFriendViewController : UIViewController
@property(nonatomic) void (^cellClickBlock)(TUICommonPendencyCell *cell);
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,145 @@
//
// TUINewFriendViewController.m
// TUIKit
//
// Created by annidyfeng on 2019/4/19.
// Copyright © 2019 Tencent. All rights reserved.
//
#import "TUINewFriendViewController.h"
#import <TIMCommon/TIMDefine.h>
#import <TUICore/TUIThemeManager.h>
#import "TUINewFriendViewDataProvider.h"
@interface TUINewFriendViewController () <UITableViewDelegate, UITableViewDataSource>
@property UITableView *tableView;
@property UIButton *moreBtn;
@property TUINewFriendViewDataProvider *viewModel;
@property(nonatomic, strong) UILabel *noDataTipsLabel;
@end
@implementation TUINewFriendViewController
- (void)viewDidLoad {
[super viewDidLoad];
UILabel *titleLabel = [[UILabel alloc] init];
titleLabel.text = TIMCommonLocalizableString(TUIKitContactsNewFriends);
titleLabel.font = [UIFont boldSystemFontOfSize:17.0];
titleLabel.textColor = TIMCommonDynamicColor(@"nav_title_text_color", @"#000000");
[titleLabel sizeToFit];
self.navigationItem.titleView = titleLabel;
self.view.backgroundColor = TIMCommonDynamicColor(@"controller_bg_color", @"#F2F3F5");
CGRect rect = self.view.bounds;
_tableView = [[UITableView alloc] initWithFrame:rect style:UITableViewStylePlain];
if (@available(iOS 15.0, *)) {
_tableView.sectionHeaderTopPadding = 0;
}
[self.view addSubview:_tableView];
_tableView.delegate = self;
_tableView.dataSource = self;
[_tableView registerClass:[TUICommonPendencyCell class] forCellReuseIdentifier:@"PendencyCell"];
self.tableView.allowsMultipleSelectionDuringEditing = NO;
_tableView.separatorInset = UIEdgeInsetsMake(0, 94, 0, 0);
_tableView.backgroundColor = self.view.backgroundColor;
_viewModel = TUINewFriendViewDataProvider.new;
_moreBtn = [UIButton buttonWithType:UIButtonTypeSystem];
_moreBtn.mm_h = 20;
_tableView.tableFooterView = _moreBtn;
_moreBtn.hidden = YES;
@weakify(self);
[RACObserve(_viewModel, dataList) subscribeNext:^(id _Nullable x) {
@strongify(self);
[self.tableView reloadData];
}];
self.noDataTipsLabel.frame = CGRectMake(10, 60, self.view.bounds.size.width - 20, 40);
[self.tableView addSubview:self.noDataTipsLabel];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self loadData];
}
- (void)loadData {
[_viewModel loadData];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
self.noDataTipsLabel.hidden = (self.viewModel.dataList.count != 0);
return self.viewModel.dataList.count;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 86;
}
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
return 20;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
TUICommonPendencyCell *cell = [self.tableView dequeueReusableCellWithIdentifier:@"PendencyCell" forIndexPath:indexPath];
TUICommonPendencyCellData *data = self.viewModel.dataList[indexPath.row];
data.cselector = @selector(cellClick:);
data.cbuttonSelector = @selector(btnClick:);
data.cRejectButtonSelector = @selector(rejectBtnClick:);
cell.selectionStyle = UITableViewCellSelectionStyleNone;
[cell fillWithData:data];
return cell;
}
- (BOOL)tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath {
return NO;
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
return YES;
}
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
// add code here for when you hit delete
[self.tableView beginUpdates];
TUICommonPendencyCellData *data = self.viewModel.dataList[indexPath.row];
[self.viewModel removeData:data];
[self.tableView deleteRowsAtIndexPaths:@[ indexPath ] withRowAnimation:UITableViewRowAnimationFade];
[self.tableView endUpdates];
}
}
- (void)btnClick:(TUICommonPendencyCell *)cell {
[self.viewModel agreeData:cell.pendencyData];
[self.tableView reloadData];
}
- (void)rejectBtnClick:(TUICommonPendencyCell *)cell {
[self.viewModel rejectData:cell.pendencyData];
[self.tableView reloadData];
}
- (void)cellClick:(TUICommonPendencyCell *)cell {
if (self.cellClickBlock) {
self.cellClickBlock(cell);
}
}
- (UILabel *)noDataTipsLabel {
if (_noDataTipsLabel == nil) {
_noDataTipsLabel = [[UILabel alloc] init];
_noDataTipsLabel.textColor = TIMCommonDynamicColor(@"nodata_tips_color", @"#999999");
_noDataTipsLabel.font = [UIFont systemFontOfSize:14.0];
_noDataTipsLabel.textAlignment = NSTextAlignmentCenter;
_noDataTipsLabel.text = TIMCommonLocalizableString(TUIKitContactNoNewApplicationRequest);
}
return _noDataTipsLabel;
}
@end

View File

@@ -0,0 +1,9 @@
// Created by Tencent on 2023/06/09.
// Copyright © 2023 Tencent. All rights reserved.
#import <UIKit/UIKit.h>
@interface TUIProfileController : UITableViewController
@end

View File

@@ -0,0 +1,386 @@
//
// SettingController.m
// TUIKitDemo
//
// Created by lynxzhang on 2018/10/19.
// Copyright © 2018 Tencent. All rights reserved.
//
#import "TUIProfileController.h"
#import <TIMCommon/TIMCommonModel.h>
#import <TUICore/TUIThemeManager.h>
#import "TUITextEditController.h"
#define SHEET_COMMON 1
#define SHEET_AGREE 2
#define SHEET_SEX 3
@interface TUIProfileController () <UIActionSheetDelegate, V2TIMSDKListener, TUIModifyViewDelegate>
@property(nonatomic, strong) TUINaviBarIndicatorView *titleView;
@property(nonatomic, strong) NSMutableArray *data;
@property V2TIMUserFullInfo *profile;
@property(nonatomic, weak) UIDatePicker *picker;
@property(nonatomic, strong) UIView *datePicker;
@end
@implementation TUIProfileController {
NSDateFormatter *_dateFormatter;
}
- (void)viewDidLoad {
[super viewDidLoad];
self.tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero];
[self addLongPressGesture];
[self setupViews];
self.tableView.delaysContentTouches = NO;
_dateFormatter = [[NSDateFormatter alloc] init];
_dateFormatter.dateFormat = @"yyyy-MM-dd";
}
- (void)setupViews {
_titleView = [[TUINaviBarIndicatorView alloc] init];
[_titleView setTitle:TIMCommonLocalizableString(ProfileDetails)];
self.navigationItem.titleView = _titleView;
self.navigationItem.title = @"";
if (@available(iOS 15.0, *)) {
self.tableView.sectionHeaderTopPadding = 0;
}
self.tableView.backgroundColor = TIMCommonDynamicColor(@"controller_bg_color", @"#F2F3F5");
[self.tableView registerClass:[TUICommonTextCell class] forCellReuseIdentifier:@"textCell"];
[self.tableView registerClass:[TUICommonAvatarCell class] forCellReuseIdentifier:@"avatarCell"];
[[V2TIMManager sharedInstance] addIMSDKListener:self];
NSString *loginUser = [[V2TIMManager sharedInstance] getLoginUser];
[[V2TIMManager sharedInstance] getUsersInfo:@[ loginUser?:@"" ]
succ:^(NSArray<V2TIMUserFullInfo *> *infoList) {
self.profile = infoList.firstObject;
[self setupData];
}
fail:nil];
}
- (void)setupData {
_data = [NSMutableArray array];
TUICommonAvatarCellData *avatarData = [TUICommonAvatarCellData new];
avatarData.key = TIMCommonLocalizableString(ProfilePhoto);
avatarData.showAccessory = YES;
avatarData.cselector = @selector(didSelectAvatar);
avatarData.avatarUrl = [NSURL URLWithString:self.profile.faceURL];
[_data addObject:@[ avatarData ]];
TUICommonTextCellData *nicknameData = [TUICommonTextCellData new];
nicknameData.key = TIMCommonLocalizableString(ProfileName);
nicknameData.value = self.profile.showName;
nicknameData.showAccessory = YES;
nicknameData.cselector = @selector(didSelectChangeNick);
TUICommonTextCellData *IDData = [TUICommonTextCellData new];
IDData.key = TIMCommonLocalizableString(ProfileAccount);
IDData.value = [NSString stringWithFormat:@"%@ ", self.profile.userID];
IDData.showAccessory = NO;
[_data addObject:@[ nicknameData, IDData ]];
TUICommonTextCellData *signatureData = [TUICommonTextCellData new];
signatureData.key = TIMCommonLocalizableString(ProfileSignature);
signatureData.value = self.profile.selfSignature.length ? self.profile.selfSignature : @"";
signatureData.showAccessory = YES;
signatureData.cselector = @selector(didSelectChangeSignature);
TUICommonTextCellData *sexData = [TUICommonTextCellData new];
sexData.key = TIMCommonLocalizableString(ProfileGender);
sexData.value = [self.profile showGender];
sexData.showAccessory = YES;
sexData.cselector = @selector(didSelectSex);
TUICommonTextCellData *birthdayData = [TUICommonTextCellData new];
birthdayData.key = TIMCommonLocalizableString(ProfileBirthday);
birthdayData.value = [_dateFormatter stringFromDate:NSDate.new];
if (self.profile.birthday) {
NSInteger year = self.profile.birthday / 10000;
NSInteger month = (self.profile.birthday - year * 10000) / 100;
NSInteger day = (self.profile.birthday - year * 10000 - month * 100);
birthdayData.value = [NSString stringWithFormat:@"%04zd-%02zd-%02zd", year, month, day];
}
birthdayData.showAccessory = YES;
birthdayData.cselector = @selector(didSelectBirthday);
[_data addObject:@[ signatureData, sexData, birthdayData ]];
[self.tableView reloadData];
}
#pragma mark - V2TIMSDKListener
- (void)onSelfInfoUpdated:(V2TIMUserFullInfo *)Info {
self.profile = Info;
[self setupData];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return _data.count;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
UIView *view = [[UIView alloc] init];
view.backgroundColor = [UIColor clearColor];
return view;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return section == 0 ? 0 : 10;
}
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
return 0;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSMutableArray *array = _data[section];
return array.count;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
NSMutableArray *array = _data[indexPath.section];
TUICommonCellData *data = array[indexPath.row];
return [data heightOfWidth:Screen_Width];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSMutableArray *array = _data[indexPath.section];
NSObject *data = array[indexPath.row];
if ([data isKindOfClass:[TUICommonTextCellData class]]) {
TUICommonTextCell *cell = [tableView dequeueReusableCellWithIdentifier:@"textCell" forIndexPath:indexPath];
[cell fillWithData:(TUICommonTextCellData *)data];
return cell;
} else if ([data isKindOfClass:[TUICommonAvatarCellData class]]) {
TUICommonAvatarCell *cell = [tableView dequeueReusableCellWithIdentifier:@"avatarCell" forIndexPath:indexPath];
[cell fillWithData:(TUICommonAvatarCellData *)data];
return cell;
}
return nil;
}
- (void)modifyView:(TUIModifyView *)modifyView didModiyContent:(NSString *)content {
if (modifyView.tag == 0) {
if (![self validForSignatureAndNick:content]) {
[TUITool makeToast:TIMCommonLocalizableString(ProfileEditNameDesc)];
return;
}
V2TIMUserFullInfo *info = [[V2TIMUserFullInfo alloc] init];
info.nickName = content;
[[V2TIMManager sharedInstance] setSelfInfo:info
succ:^{
self.profile.nickName = content;
[self setupData];
}
fail:nil];
} else if (modifyView.tag == 1) {
if (![self validForSignatureAndNick:content]) {
[TUITool makeToast:TIMCommonLocalizableString(ProfileEditNameDesc)];
return;
}
V2TIMUserFullInfo *info = [[V2TIMUserFullInfo alloc] init];
info.selfSignature = content;
[[V2TIMManager sharedInstance] setSelfInfo:info
succ:^{
self.profile.selfSignature = content;
[self setupData];
}
fail:nil];
}
}
- (BOOL)validForSignatureAndNick:(NSString *)content {
NSString *reg = @"^[a-zA-Z0-9_\u4e00-\u9fa5]*$";
NSPredicate *regex = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", reg];
return [regex evaluateWithObject:content];
}
- (void)didSelectChangeNick {
TUIModifyViewData *data = [[TUIModifyViewData alloc] init];
data.title = TIMCommonLocalizableString(ProfileEditName);
data.desc = TIMCommonLocalizableString(ProfileEditNameDesc);
data.content = self.profile.showName;
TUIModifyView *modify = [[TUIModifyView alloc] init];
modify.tag = 0;
modify.delegate = self;
[modify setData:data];
[modify showInWindow:self.view.window];
}
- (void)didSelectChangeSignature {
TUIModifyViewData *data = [[TUIModifyViewData alloc] init];
data.title = TIMCommonLocalizableString(ProfileEditSignture);
data.desc = TIMCommonLocalizableString(ProfileEditNameDesc);
data.content = self.profile.selfSignature;
TUIModifyView *modify = [[TUIModifyView alloc] init];
modify.tag = 1;
modify.delegate = self;
[modify setData:data];
[modify showInWindow:self.view.window];
}
- (void)didSelectSex {
UIActionSheet *sheet = [[UIActionSheet alloc] init];
sheet.tag = SHEET_SEX;
sheet.title = TIMCommonLocalizableString(ProfileEditGender);
[sheet addButtonWithTitle:TIMCommonLocalizableString(Male)];
[sheet addButtonWithTitle:TIMCommonLocalizableString(Female)];
[sheet setCancelButtonIndex:[sheet addButtonWithTitle:TIMCommonLocalizableString(Canel)]];
[sheet setDelegate:self];
[sheet showInView:self.view];
}
- (void)didSelectAvatar {
TUISelectAvatarController *vc = [[TUISelectAvatarController alloc] init];
vc.selectAvatarType = TUISelectAvatarTypeUserAvatar;
vc.profilFaceURL = self.profile.faceURL;
[self.navigationController pushViewController:vc animated:YES];
__weak typeof(self) weakSelf = self;
vc.selectCallBack = ^(NSString *_Nonnull urlStr) {
__strong typeof(weakSelf) strongSelf = weakSelf;
if (urlStr.length > 0) {
V2TIMUserFullInfo *info = [[V2TIMUserFullInfo alloc] init];
info.faceURL = urlStr;
[[V2TIMManager sharedInstance] setSelfInfo:info
succ:^{
[strongSelf.profile setFaceURL:urlStr];
[strongSelf setupData];
}
fail:^(int code, NSString *desc){
}];
}
};
}
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
if (actionSheet.tag == SHEET_SEX) {
V2TIMGender gender = V2TIM_GENDER_UNKNOWN;
if (buttonIndex == 0) {
gender = V2TIM_GENDER_MALE;
}
if (buttonIndex == 1) {
gender = V2TIM_GENDER_FEMALE;
}
V2TIMUserFullInfo *info = [[V2TIMUserFullInfo alloc] init];
info.gender = gender;
[[V2TIMManager sharedInstance] setSelfInfo:info
succ:^{
self.profile.gender = gender;
[self setupData];
}
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:[TUICommonTextCell class]]) {
TUICommonTextCell *textCell = (TUICommonTextCell *)data;
if (textCell.textData.value && ![textCell.textData.value isEqualToString:TIMCommonLocalizableString(no_set)]) {
UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
pasteboard.string = textCell.textData.value;
NSString *toastString = [NSString stringWithFormat:@"copy %@", textCell.textData.key];
[TUITool makeToast:toastString];
}
} else if ([data isKindOfClass:[TUIProfileCardCell class]]) {
TUIProfileCardCell *profileCard = (TUIProfileCardCell *)data;
if (profileCard.cardData.identifier) {
UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
pasteboard.string = profileCard.cardData.identifier;
NSString *toastString = [NSString stringWithFormat:@"copy"];
[TUITool makeToast:toastString];
}
}
}
}
- (void)didSelectBirthday {
[self hideDatePicker];
[UIApplication.sharedApplication.keyWindow addSubview:self.datePicker];
}
- (UIView *)datePicker {
if (_datePicker == nil) {
UIView *cover = [[UIView alloc] initWithFrame:CGRectMake(0, 0, UIScreen.mainScreen.bounds.size.width, UIScreen.mainScreen.bounds.size.height)];
cover.backgroundColor = TUIContactDynamicColor(@"group_modify_view_bg_color", @"#0000007F");
[cover addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(hideDatePicker)]];
UIView *menuView = [[UIView alloc] init];
menuView.backgroundColor = TUIContactDynamicColor(@"group_modify_container_view_bg_color", @"#FFFFFF");
menuView.frame = CGRectMake(0, UIScreen.mainScreen.bounds.size.height - 340, UIScreen.mainScreen.bounds.size.width, 40);
[cover addSubview:menuView];
UIButton *cancelButton = [UIButton buttonWithType:UIButtonTypeCustom];
[cancelButton setTitle:TIMCommonLocalizableString(Cancel) forState:UIControlStateNormal];
[cancelButton setTitleColor:UIColor.darkGrayColor forState:UIControlStateNormal];
cancelButton.frame = CGRectMake(10, 0, 60, 35);
[cancelButton addTarget:self action:@selector(hideDatePicker) forControlEvents:UIControlEventTouchUpInside];
[menuView addSubview:cancelButton];
UIButton *okButton = [UIButton buttonWithType:UIButtonTypeCustom];
[okButton setTitle:TIMCommonLocalizableString(Confirm) forState:UIControlStateNormal];
[okButton setTitleColor:UIColor.darkGrayColor forState:UIControlStateNormal];
okButton.frame = CGRectMake(cover.bounds.size.width - 10 - 60, 0, 60, 35);
[okButton addTarget:self action:@selector(onOKDatePicker) forControlEvents:UIControlEventTouchUpInside];
[menuView addSubview:okButton];
UIDatePicker *picker = [[UIDatePicker alloc] init];
NSString *language = [TUIGlobalization tk_localizableLanguageKey];
picker.locale = [[NSLocale alloc] initWithLocaleIdentifier:language];
if (@available(iOS 13.0, *)) {
picker.overrideUserInterfaceStyle = UIUserInterfaceStyleLight;
} else {
// Fallback on earlier versions
}
if (@available(iOS 13.4, *)) {
picker.preferredDatePickerStyle = UIDatePickerStyleWheels;
}
picker.backgroundColor = TUIContactDynamicColor(@"group_modify_container_view_bg_color", @"#FFFFFF");
picker.datePickerMode = UIDatePickerModeDate;
picker.frame = CGRectMake(0, CGRectGetMaxY(menuView.frame), cover.bounds.size.width, 300);
[cover addSubview:picker];
self.picker = picker;
_datePicker = cover;
}
return _datePicker;
}
- (void)hideDatePicker {
[self.datePicker removeFromSuperview];
}
- (void)onOKDatePicker {
[self hideDatePicker];
NSDate *date = self.picker.date;
NSString *dateStr = [_dateFormatter stringFromDate:date];
dateStr = [dateStr stringByReplacingOccurrencesOfString:@"-" withString:@""];
int birthday = [dateStr intValue];
V2TIMUserFullInfo *info = [[V2TIMUserFullInfo alloc] init];
info.birthday = birthday;
[[V2TIMManager sharedInstance] setSelfInfo:info
succ:^{
self.profile.birthday = birthday;
[self setupData];
}
fail:nil];
}
@end

View File

@@ -0,0 +1,16 @@
//
// TUISearchFriendViewController.h
// TIMChat
//
// Created by AlexiChen on 16/2/29.
// Copyright © 2016 AlexiChen. All rights reserved.
//
#import <TIMCommon/TIMCommonModel.h>
#import <TIMCommon/TIMDefine.h>
#import <UIKit/UIKit.h>
@interface TUISearchFriendViewController : UIViewController
@property(nonatomic, retain) UISearchController *searchController;
@end

View File

@@ -0,0 +1,164 @@
//
// TUISearchFriendViewController.m
// TIMChat
//
// Created by AlexiChen on 16/2/29.
// Copyright © 2016 AlexiChen. All rights reserved.
//
#import "TUISearchFriendViewController.h"
#import <TUICore/TUIThemeManager.h>
#import "TUIDefine.h"
#import "TUIFriendRequestViewController.h"
@interface AddFriendUserView : UIView
@property(nonatomic) V2TIMUserFullInfo *profile;
@end
@implementation AddFriendUserView {
UILabel *_idLabel;
UIView *_line;
}
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
_idLabel = [[UILabel alloc] initWithFrame:CGRectZero];
[self addSubview:_idLabel];
_line = [[UIView alloc] initWithFrame:CGRectZero];
_line.backgroundColor = [UIColor grayColor];
[self addSubview:_line];
return self;
}
- (void)setProfile:(V2TIMUserFullInfo *)profile {
_profile = profile;
if (_profile) {
_idLabel.text = profile.userID;
_idLabel.mm_sizeToFit().tui_mm_center().mm_left(8);
_line.mm_height(1).mm_width(self.mm_w).mm_bottom(0);
_line.hidden = NO;
} else {
_idLabel.text = @"";
_line.hidden = YES;
}
}
@end
@interface TUISearchFriendViewController () <UISearchResultsUpdating>
@property(nonatomic, strong) AddFriendUserView *userView;
;
@end
@interface TUISearchFriendViewController () <UISearchControllerDelegate, UISearchResultsUpdating, UISearchResultsUpdating>
@end
@implementation TUISearchFriendViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.title = TIMCommonLocalizableString(ContactsAddFriends);
self.view.backgroundColor = TIMCommonDynamicColor(@"controller_bg_color", @"#F2F3F5");
self.edgesForExtendedLayout = UIRectEdgeNone;
self.automaticallyAdjustsScrollViewInsets = NO;
self.definesPresentationContext = YES;
self.searchController = [[UISearchController alloc] initWithSearchResultsController:nil];
self.searchController.delegate = self;
self.searchController.searchResultsUpdater = self;
self.searchController.dimsBackgroundDuringPresentation = NO;
_searchController.searchBar.placeholder = TIMCommonLocalizableString(SearchGroupPlaceholder);
[self.view addSubview:_searchController.searchBar];
self.searchController.searchBar.mm_sizeToFit();
[self setSearchIconCenter:YES];
self.userView = [[AddFriendUserView alloc] initWithFrame:CGRectZero];
[self.view addSubview:self.userView];
UITapGestureRecognizer *singleFingerTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleUserTap:)];
[self.userView addGestureRecognizer:singleFingerTap];
}
- (void)setSearchIconCenter:(BOOL)center {
if (center) {
CGSize size = [self.searchController.searchBar.placeholder sizeWithAttributes:@{NSFontAttributeName : [UIFont systemFontOfSize:14.0]}];
CGFloat width = size.width + 60;
[self.searchController.searchBar setPositionAdjustment:UIOffsetMake(0.5 * (self.searchController.searchBar.bounds.size.width - width), 0)
forSearchBarIcon:UISearchBarIconSearch];
} else {
[self.searchController.searchBar setPositionAdjustment:UIOffsetZero forSearchBarIcon:UISearchBarIconSearch];
}
}
#pragma mark - UISearchControllerDelegate
- (void)willPresentSearchController:(UISearchController *)searchController {
[self setSearchIconCenter:NO];
}
- (void)didPresentSearchController:(UISearchController *)searchController {
NSLog(@"didPresentSearchController");
[self.view addSubview:self.searchController.searchBar];
self.searchController.searchBar.mm_top([self safeAreaTopGap]);
self.userView.mm_top(self.searchController.searchBar.mm_maxY).mm_height(44).mm_width(Screen_Width);
}
- (void)willDismissSearchController:(UISearchController *)searchController {
[self setSearchIconCenter:YES];
}
- (CGFloat)safeAreaTopGap {
NSNumber *gap;
if (gap == nil) {
if (@available(iOS 11, *)) {
gap = @(self.view.safeAreaLayoutGuide.layoutFrame.origin.y);
} else {
gap = @(0);
}
}
return gap.floatValue;
}
- (void)didDismissSearchController:(UISearchController *)searchController {
NSLog(@"didDismissSearchController");
self.searchController.searchBar.mm_top(0);
self.userView.profile = nil;
}
- (void)updateSearchResultsForSearchController:(UISearchController *)searchController {
NSString *inputStr = searchController.searchBar.text;
NSLog(@"serach %@", inputStr);
[[V2TIMManager sharedInstance] getUsersInfo:@[ inputStr ]
succ:^(NSArray<V2TIMUserFullInfo *> *infoList) {
self.userView.profile = infoList.firstObject;
}
fail:^(int code, NSString *msg) {
self.userView.profile = nil;
}];
}
- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar {
self.searchController.active = YES;
return YES;
}
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
self.searchController.active = NO;
}
- (void)handleUserTap:(id)sender {
if (self.userView.profile.userID.length > 0) {
TUIFriendRequestViewController *frc = [[TUIFriendRequestViewController alloc] init];
frc.profile = self.userView.profile;
[self.navigationController pushViewController:frc animated:YES];
}
}
@end

View File

@@ -0,0 +1,22 @@
//
// TUISearchGroupViewController.h
// TUIKitDemo
//
// Created by annidyfeng on 2019/5/20.
// Copyright © 2019 Tencent. All rights reserved.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface SearchGroupSearchResultViewController : UIViewController
@end
@interface TUISearchGroupViewController : UIViewController
@property(nonatomic, retain) UISearchController *searchController;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,186 @@
//
// TUISearchGroupViewController.m
// TUIKitDemo
//
// Created by annidyfeng on 2019/5/20.
// Copyright © 2019 Tencent. All rights reserved.
//
#import "TUISearchGroupViewController.h"
#import <TIMCommon/TIMDefine.h>
#import <TUICore/TUIThemeManager.h>
#import "TUIGroupRequestViewController.h"
@implementation UISearchController (Leak)
- (BOOL)willDealloc {
return NO;
}
@end
@interface AddGroupItemView : UIView
@property(nonatomic) V2TIMGroupInfo *groupInfo;
@end
@implementation AddGroupItemView {
UILabel *_idLabel;
UIView *_line;
}
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
_idLabel = [[UILabel alloc] initWithFrame:CGRectZero];
[self addSubview:_idLabel];
_line = [[UIView alloc] initWithFrame:CGRectZero];
_line.backgroundColor = [UIColor grayColor];
[self addSubview:_line];
return self;
}
- (void)setGroupInfo:(V2TIMGroupInfo *)groupInfo {
if (groupInfo) {
if (groupInfo.groupName.length > 0) {
_idLabel.text = [NSString stringWithFormat:@"%@ (group id: %@)", groupInfo.groupName, groupInfo.groupID];
} else {
_idLabel.text = groupInfo.groupID;
}
_idLabel.mm_sizeToFit().tui_mm_center().mm_left(8);
_line.mm_height(1).mm_width(self.mm_w).mm_bottom(0);
_line.hidden = NO;
} else {
_idLabel.text = @"";
_line.hidden = YES;
}
_groupInfo = groupInfo;
}
@end
@interface TUISearchGroupViewController () <UISearchBarDelegate>
@property(nonatomic, strong) AddGroupItemView *userView;
;
@end
@interface TUISearchGroupViewController () <UISearchControllerDelegate, UISearchBarDelegate>
@end
@implementation TUISearchGroupViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.title = TIMCommonLocalizableString(ContactsJoinGroup);
self.view.backgroundColor = TIMCommonDynamicColor(@"controller_bg_color", @"#F2F3F5");
self.edgesForExtendedLayout = UIRectEdgeNone;
self.automaticallyAdjustsScrollViewInsets = NO;
self.definesPresentationContext = YES;
self.searchController = [[UISearchController alloc] initWithSearchResultsController:nil];
self.searchController.delegate = self;
self.searchController.dimsBackgroundDuringPresentation = NO;
_searchController.searchBar.placeholder = @"group ID";
_searchController.searchBar.delegate = self;
[self.view addSubview:_searchController.searchBar];
[self setSearchIconCenter:YES];
self.userView = [[AddGroupItemView alloc] initWithFrame:CGRectZero];
[self.view addSubview:self.userView];
UITapGestureRecognizer *singleFingerTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleUserTap:)];
[self.userView addGestureRecognizer:singleFingerTap];
}
- (void)setSearchIconCenter:(BOOL)center {
if (center) {
CGSize size = [self.searchController.searchBar.placeholder sizeWithAttributes:@{NSFontAttributeName : [UIFont systemFontOfSize:14.0]}];
CGFloat width = size.width + 60;
[self.searchController.searchBar setPositionAdjustment:UIOffsetMake(0.5 * (self.searchController.searchBar.bounds.size.width - width), 0)
forSearchBarIcon:UISearchBarIconSearch];
} else {
[self.searchController.searchBar setPositionAdjustment:UIOffsetZero forSearchBarIcon:UISearchBarIconSearch];
}
}
#pragma mark - UISearchControllerDelegate
- (void)didPresentSearchController:(UISearchController *)searchController {
NSLog(@"didPresentSearchController");
[self.view addSubview:self.searchController.searchBar];
self.searchController.searchBar.mm_top([self safeAreaTopGap]);
self.userView.mm_top(self.searchController.searchBar.mm_maxY).mm_height(44).mm_width(Screen_Width);
}
- (void)willPresentSearchController:(UISearchController *)searchController {
[self setSearchIconCenter:NO];
}
- (void)willDismissSearchController:(UISearchController *)searchController {
[self setSearchIconCenter:YES];
}
- (CGFloat)safeAreaTopGap {
NSNumber *gap;
if (gap == nil) {
if (@available(iOS 11, *)) {
gap = @(self.view.safeAreaLayoutGuide.layoutFrame.origin.y);
} else {
gap = @(0);
}
}
return gap.floatValue;
}
- (void)didDismissSearchController:(UISearchController *)searchController {
NSLog(@"didDismissSearchController");
self.searchController.searchBar.mm_top(0);
self.userView.groupInfo = nil;
}
- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar {
self.searchController.active = YES;
return YES;
}
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
self.searchController.active = NO;
}
- (void)handleUserTap:(id)sender {
if (self.userView.groupInfo) {
TUIGroupRequestViewController *frc = [[TUIGroupRequestViewController alloc] init];
frc.groupInfo = self.userView.groupInfo;
[self.navigationController pushViewController:frc animated:YES];
}
}
#pragma mark - UISearchBarDelegate
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar {
NSString *inputStr = searchBar.text;
[[V2TIMManager sharedInstance] getGroupsInfo:@[ inputStr ]
succ:^(NSArray<V2TIMGroupInfoResult *> *groupResultList) {
if (groupResultList.count > 0) {
V2TIMGroupInfoResult *result = groupResultList.firstObject;
if (0 == result.resultCode) {
self.userView.groupInfo = result.info;
} else {
self.userView.groupInfo = nil;
}
} else {
self.userView.groupInfo = nil;
}
}
fail:^(int code, NSString *desc) {
self.userView.groupInfo = nil;
}];
}
@end

View File

@@ -0,0 +1,25 @@
//
// TUISelectGroupMemberViewController.h
// TXIMSDK_TUIKit_iOS
//
// Created by xiangzhang on 2020/7/6.
// Copyright © 2023 Tencent. All rights reserved.
//
#import <TIMCommon/TIMDefine.h>
#import <UIKit/UIKit.h>
#import "TUIContactDefine.h"
#import "TUISelectGroupMemberCell.h"
NS_ASSUME_NONNULL_BEGIN
@interface TUISelectGroupMemberViewController : UIViewController
@property(nonatomic, copy) NSString *groupId;
@property(nonatomic, copy) NSString *name;
@property(nonatomic, strong) SelectedFinished selectedFinished;
@property(nonatomic, assign) TUISelectMemberOptionalStyle optionalStyle;
@property(nonatomic, strong) NSArray *selectedUserIDList;
@property(nonatomic, copy) NSString *userData;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,481 @@
//
// TUISelectGroupMemberViewController.m
// TXIMSDK_TUIKit_iOS
//
// Created by xiangzhang on 2020/7/6.
// Copyright © 2023 Tencent. All rights reserved.
//
#import "TUISelectGroupMemberViewController.h"
#import <TUICore/TUICore.h>
#import <TUICore/TUIDarkModel.h>
#import <TUICore/TUIGlobalization.h>
#import <TUICore/TUIThemeManager.h>
#import "ReactiveObjC/ReactiveObjC.h"
#import "TUIMemberPanelCell.h"
#import "TUISelectGroupMemberCell.h"
#define kUserBorder 44.0
#define kUserSpacing 2
#define kUserPanelLeftSpacing 15
@interface TUISelectGroupMemberViewController () <UICollectionViewDelegate,
UICollectionViewDataSource,
UICollectionViewDelegateFlowLayout,
UITableViewDelegate,
UITableViewDataSource>
@property(nonatomic, strong) UIButton *cancelBtn;
@property(nonatomic, strong) UIButton *doneBtn;
@property(nonatomic, strong) UICollectionView *userPanel;
@property(nonatomic, strong) UITableView *selectTable;
@property(nonatomic, strong) UIActivityIndicatorView *indicatorView;
@property(nonatomic, strong) NSMutableArray<TUIUserModel *> *selectedUsers;
@property(nonatomic, assign) CGFloat topStartPosition;
@property(nonatomic, assign) CGFloat userPanelWidth;
@property(nonatomic, assign) CGFloat userPanelHeight;
@property(nonatomic, assign) CGFloat realSpacing;
@property(nonatomic, assign) NSInteger userPanelColumnCount;
@property(nonatomic, assign) NSInteger userPanelRowCount;
@property(nonatomic, strong) NSMutableArray *memberList;
@property(nonatomic, assign) NSInteger pageIndex;
@property(nonatomic, assign) BOOL isNoData;
@end
@implementation TUISelectGroupMemberViewController {
UICollectionView *_userPanel;
UITableView *_selectTable;
UIButton *_cancelBtn;
UIButton *_doneBtn;
}
- (void)viewDidLoad {
[super viewDidLoad];
UILabel *titleLabel = [[UILabel alloc] init];
titleLabel.text = self.name ?: TIMCommonLocalizableString(Make_a_call);
titleLabel.font = [UIFont boldSystemFontOfSize:17.0];
titleLabel.textColor = TIMCommonDynamicColor(@"nav_title_text_color", @"#000000");
[titleLabel sizeToFit];
self.navigationItem.titleView = titleLabel;
self.view.backgroundColor = TIMCommonDynamicColor(@"controller_bg_color", @"#F2F3F5");
UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithCustomView:self.cancelBtn];
self.navigationItem.leftBarButtonItem = item;
UIBarButtonItem *item2 = [[UIBarButtonItem alloc] initWithCustomView:self.doneBtn];
self.navigationItem.rightBarButtonItem = item2;
CGFloat topPadding = 44.f;
if (@available(iOS 11.0, *)) {
UIWindow *window = [UIApplication sharedApplication].keyWindow;
topPadding = window.safeAreaInsets.top;
}
topPadding = MAX(26, topPadding);
CGFloat navBarHeight = self.navigationController.navigationBar.bounds.size.height;
self.topStartPosition = topPadding + (navBarHeight > 0 ? navBarHeight : 44);
CGRect rect = self.view.bounds;
self.memberList = [NSMutableArray array];
self.selectedUsers = [NSMutableArray array];
self.indicatorView.frame = CGRectMake(0, 0, self.view.bounds.size.width, TMessageController_Header_Height);
self.selectTable.tableFooterView = self.indicatorView;
[self getMembers];
}
#pragma mark UI
- (UIButton *)cancelBtn {
if (!_cancelBtn.superview) {
_cancelBtn = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 30, 30)];
[_cancelBtn setTitle:TIMCommonLocalizableString(Cancel) forState:UIControlStateNormal];
[_cancelBtn setTitleColor:TIMCommonDynamicColor(@"nav_title_text_color", @"#000000") forState:UIControlStateNormal];
[_cancelBtn addTarget:self action:@selector(cancel) forControlEvents:UIControlEventTouchUpInside];
}
return _cancelBtn;
}
- (UIButton *)doneBtn {
if (!_doneBtn.superview) {
_doneBtn = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 30, 30)];
[_doneBtn setTitle:TIMCommonLocalizableString(Done) forState:UIControlStateNormal];
[_doneBtn setAlpha:0.5];
[_doneBtn setTitleColor:TIMCommonDynamicColor(@"nav_title_text_color", @"#000000") forState:UIControlStateNormal];
[_doneBtn addTarget:self action:@selector(onNext) forControlEvents:UIControlEventTouchUpInside];
}
return _doneBtn;
}
- (UICollectionView *)userPanel {
if (!_userPanel.superview) {
UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
layout.scrollDirection = UICollectionViewScrollDirectionVertical;
_userPanel = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:layout];
_userPanel.backgroundColor = [UIColor clearColor];
[_userPanel registerClass:[TUIMemberPanelCell class] forCellWithReuseIdentifier:@"TUIMemberPanelCell"];
if (@available(iOS 10.0, *)) {
_userPanel.prefetchingEnabled = YES;
} else {
// Fallback on earlier versions
}
_userPanel.showsVerticalScrollIndicator = NO;
_userPanel.showsHorizontalScrollIndicator = NO;
_userPanel.contentMode = UIViewContentModeScaleAspectFit;
_userPanel.scrollEnabled = NO;
_userPanel.delegate = self;
_userPanel.dataSource = self;
[self.view addSubview:_userPanel];
}
return _userPanel;
}
- (UITableView *)selectTable {
if (!_selectTable.superview) {
_selectTable = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];
_selectTable.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero];
[_selectTable registerClass:[TUISelectGroupMemberCell class] forCellReuseIdentifier:@"TUISelectGroupMemberCell"];
if (@available(iOS 15.0, *)) {
_selectTable.sectionHeaderTopPadding = 0;
}
_selectTable.delegate = self;
_selectTable.dataSource = self;
[self.view addSubview:_selectTable];
_selectTable.mm_width(self.view.mm_w).mm_top(self.topStartPosition + 10).mm_flexToBottom(0);
}
return _selectTable;
}
- (UIActivityIndicatorView *)indicatorView {
if (_indicatorView == nil) {
_indicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
_indicatorView.hidesWhenStopped = YES;
}
return _indicatorView;
}
- (void)updateUserPanel {
self.userPanel.mm_height(self.userPanelHeight).mm_left(kUserPanelLeftSpacing).mm_flexToRight(0).mm_top(self.topStartPosition);
self.selectTable.mm_width(self.view.mm_w).mm_top(self.userPanel.mm_maxY).mm_flexToBottom(0);
@weakify(self);
[self.userPanel
performBatchUpdates:^{
@strongify(self);
[self.userPanel reloadSections:[NSIndexSet indexSetWithIndex:0]];
}
completion:nil];
[self.selectTable reloadData];
self.doneBtn.alpha = (self.selectedUsers.count == 0 ? 0.5 : 1);
}
#pragma mark action
- (void)onNext {
if (self.selectedUsers.count == 0) {
return;
}
NSMutableArray *users = [NSMutableArray array];
for (TUIUserModel *model in self.selectedUsers) {
[users addObject:[model copy]];
}
if (self.selectedFinished) {
[self cancel];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
self.selectedFinished(users);
});
}
if (self.optionalStyle == TUISelectMemberOptionalStyleTransferOwner) {
[self cancel];
return;
}
[self cancel];
NSDictionary *result = @{TUICore_TUIContactObjectFactory_SelectGroupMemberVC_ResultUserList : users};
if (self.navigateValueCallback) {
self.navigateValueCallback(result);
}
}
- (void)cancel {
if (self.isModal) {
[self dismissViewControllerAnimated:YES completion:nil];
} else {
[self.navigationController popViewControllerAnimated:YES];
}
}
- (BOOL)isModal {
NSArray *viewControllers = self.navigationController.viewControllers;
if (viewControllers.count > 1 && [viewControllers.lastObject isEqual:self]) {
return NO;
}
return YES;
}
#pragma mark UITableViewDelegate
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.memberList.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellIdentifier = @"TUISelectGroupMemberCell";
TUISelectGroupMemberCell *cell = (TUISelectGroupMemberCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (!cell) {
cell = [[TUISelectGroupMemberCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
if (indexPath.row < self.memberList.count) {
TUIUserModel *model = self.memberList[indexPath.row];
BOOL isSelect = [self isUserSelected:model];
[cell fillWithData:model isSelect:isSelect];
}
return cell;
}
- (void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section {
UITableViewHeaderFooterView *footer = (UITableViewHeaderFooterView *)view;
footer.textLabel.textColor = [UIColor d_systemGrayColor];
footer.textLabel.font = [UIFont systemFontOfSize:14];
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
return TIMCommonLocalizableString(TUIKitGroupProfileMember);
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(nonnull NSIndexPath *)indexPath {
return 44;
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
return YES;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
BOOL isSelected = NO;
TUIUserModel *userSelected = [[TUIUserModel alloc] init];
if (indexPath.row < self.memberList.count) {
TUIUserModel *user = self.memberList[indexPath.row];
isSelected = [self isUserSelected:user];
userSelected = [user copy];
}
if (userSelected.userId.length == 0) {
return;
}
if ([userSelected.userId isEqualToString:kImSDK_MesssageAtALL]) {
[self.selectedUsers removeAllObjects];
[self.selectedUsers addObject:userSelected];
[self onNext];
return;
}
if (self.optionalStyle == TUISelectMemberOptionalStyleTransferOwner) {
[self.selectedUsers removeAllObjects];
}
if (isSelected) {
for (TUIUserModel *user in self.selectedUsers) {
if ([user.userId isEqualToString:userSelected.userId]) {
[self.selectedUsers removeObject:user];
break;
}
}
} else {
[self.selectedUsers addObject:userSelected];
}
[self updateUserPanel];
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
if (scrollView.contentOffset.y > 0 && (scrollView.contentOffset.y >= scrollView.bounds.origin.y)) {
if (self.indicatorView.isAnimating) {
return;
}
[self.indicatorView startAnimating];
@weakify(self);
[self loadData:^(BOOL success, NSString *desc, NSArray<TUIUserModel *> *datas) {
@strongify(self);
[self.indicatorView stopAnimating];
if (!success) {
return;
}
[self.memberList addObjectsFromArray:datas];
[self.selectTable reloadData];
[self.selectTable layoutIfNeeded];
if (datas.count == 0) {
[self.selectTable setContentOffset:CGPointMake(0, scrollView.contentOffset.y - TMessageController_Header_Height) animated:YES];
}
}];
}
}
#pragma mark UICollectionViewDelegate
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
return 1;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return self.selectedUsers.count;
}
- (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellIdentifier = @"TUIMemberPanelCell";
TUIMemberPanelCell *cell = (TUIMemberPanelCell *)[collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
if (indexPath.row < self.selectedUsers.count) {
[cell fillWithData:self.selectedUsers[indexPath.row]];
}
return cell;
}
- (CGSize)collectionView:(UICollectionView *)collectionView
layout:(UICollectionViewLayout *)collectionViewLayout
sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
return CGSizeMake(kUserBorder, kUserBorder);
}
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
[collectionView deselectItemAtIndexPath:indexPath animated:NO];
if (indexPath.row < self.selectedUsers.count) {
// to do
}
}
#pragma mark data
- (NSInteger)userPanelColumnCount {
if (self.selectedUsers.count == 0) {
return 0;
}
CGFloat totalWidth = self.view.mm_w - kUserPanelLeftSpacing;
int columnCount = (int)(totalWidth / (kUserBorder + kUserSpacing));
return columnCount;
}
- (CGFloat)realSpacing {
CGFloat totalWidth = self.view.mm_w - kUserPanelLeftSpacing;
if (self.userPanelColumnCount == 0 || self.userPanelColumnCount == 1) {
return 0;
}
return (totalWidth - (CGFloat)self.userPanelColumnCount * kUserBorder) / ((CGFloat)self.userPanelColumnCount - 1);
}
- (NSInteger)userPanelRowCount {
NSInteger userCount = self.selectedUsers.count;
NSInteger columnCount = MAX(self.userPanelColumnCount, 1);
NSInteger rowCount = userCount / columnCount;
if (userCount % columnCount != 0) {
rowCount += 1;
}
return rowCount;
}
- (CGFloat)userPanelWidth {
return (CGFloat)self.userPanelColumnCount * kUserBorder + ((CGFloat)self.userPanelColumnCount - 1) * self.realSpacing;
}
- (CGFloat)userPanelHeight {
return (CGFloat)self.userPanelRowCount * kUserBorder + ((CGFloat)self.userPanelRowCount - 1) * self.realSpacing;
}
- (void)getMembers {
@weakify(self);
[self getMembersWithOptionalStyle];
[self loadData:^(BOOL success, NSString *desc, NSArray<TUIUserModel *> *datas) {
@strongify(self);
if (!success) {
return;
}
[self.memberList addObjectsFromArray:datas];
[self.selectTable reloadData];
}];
}
- (void)loadData:(void (^)(BOOL, NSString *, NSArray<TUIUserModel *> *))completion {
if (self.isNoData) {
if (completion) {
completion(YES, @"there is no more data", @[]);
}
return;
}
__weak typeof(self) weakSelf = self;
[[V2TIMManager sharedInstance] getGroupMemberList:self.groupId
filter:V2TIM_GROUP_MEMBER_FILTER_ALL
nextSeq:self.pageIndex
succ:^(uint64_t nextSeq, NSArray<V2TIMGroupMemberFullInfo *> *memberList) {
weakSelf.pageIndex = nextSeq;
weakSelf.isNoData = (nextSeq == 0);
NSMutableArray *arrayM = [NSMutableArray array];
for (V2TIMGroupMemberFullInfo *info in memberList) {
if ([info.userID isEqualToString:[[V2TIMManager sharedInstance] getLoginUser]]) {
continue;
}
if (weakSelf.optionalStyle & TUISelectMemberOptionalStylePublicMan) {
BOOL isSuper = (info.role == V2TIM_GROUP_MEMBER_ROLE_SUPER);
BOOL isAdMin = (info.role == V2TIM_GROUP_MEMBER_ROLE_ADMIN);
if (isSuper || isAdMin) {
continue;
}
}
if (self.selectedUserIDList && [self.selectedUserIDList containsObject:info.userID]) {
continue;
}
TUIUserModel *model = [[TUIUserModel alloc] init];
model.userId = info.userID;
if (info.nameCard.length > 0) {
model.name = info.nameCard;
} else if (info.friendRemark.length > 0) {
model.name = info.friendRemark;
} else if (info.nickName.length > 0) {
model.name = info.nickName;
} else {
model.name = info.userID;
}
if (info.faceURL != nil) {
model.avatar = info.faceURL;
}
[arrayM addObject:model];
}
if (completion) {
completion(YES, nil, [NSArray arrayWithArray:arrayM]);
}
}
fail:^(int code, NSString *desc) {
if (completion) {
completion(NO, desc, @[]);
}
}];
}
- (void)getMembersWithOptionalStyle {
if (!NSThread.isMainThread) {
__weak typeof(self) weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
[weakSelf getMembersWithOptionalStyle];
});
return;
}
if (self.optionalStyle == TUISelectMemberOptionalStyleNone) {
return;
}
if (self.optionalStyle & TUISelectMemberOptionalStyleAtAll) {
TUIUserModel *model = [[TUIUserModel alloc] init];
model.userId = kImSDK_MesssageAtALL;
model.name = TIMCommonLocalizableString(All);
[self.memberList addObject:model];
}
}
- (BOOL)isUserSelected:(TUIUserModel *)user {
BOOL isSelected = NO;
for (TUIUserModel *selectUser in self.selectedUsers) {
if ([selectUser.userId isEqualToString:user.userId] && ![selectUser.userId isEqualToString:[[V2TIMManager sharedInstance] getLoginUser]]) {
isSelected = YES;
break;
}
}
return isSelected;
}
@end

View File

@@ -0,0 +1,20 @@
//
// TUISettingAdminController.h
// TUIGroup
//
// Created by harvy on 2021/12/28.
// Copyright © 2023 Tencent. All rights reserved.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface TUISettingAdminController : UIViewController
@property(nonatomic, copy) NSString *groupID;
@property(nonatomic, copy) void (^settingAdminDissmissCallBack)(void);
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,171 @@
//
// TUISettingAdminController.m
// TUIGroup
//
// Created by harvy on 2021/12/28.
// Copyright © 2023 Tencent. All rights reserved.
//
#import "TUISettingAdminController.h"
#import <TUICore/TUIGlobalization.h>
#import <TUICore/TUIThemeManager.h>
#import "TUIMemberInfoCell.h"
#import "TUIMemberInfoCellData.h"
#import "TUISelectGroupMemberViewController.h"
#import "TUISettingAdminDataProvider.h"
@interface TUISettingAdminController () <UITableViewDataSource, UITableViewDelegate>
@property(nonatomic, strong) UITableView *tableView;
@property(nonatomic, strong) TUISettingAdminDataProvider *dataProvider;
@end
@implementation TUISettingAdminController
- (void)dealloc {
if (self.settingAdminDissmissCallBack) {
self.settingAdminDissmissCallBack();
}
}
- (void)viewDidLoad {
[super viewDidLoad];
[self setupViews];
__weak typeof(self) weakSelf = self;
self.dataProvider.groupID = self.groupID;
[self.dataProvider loadData:^(int code, NSString *error) {
[weakSelf.tableView reloadData];
if (code != 0) {
[weakSelf.view makeToast:error];
}
}];
}
- (void)setupViews {
UILabel *titleLabel = [[UILabel alloc] init];
titleLabel.text = TIMCommonLocalizableString(TUIKitGroupManageAdminSetting);
titleLabel.font = [UIFont boldSystemFontOfSize:17.0];
titleLabel.textColor = TIMCommonDynamicColor(@"nav_title_text_color", @"#000000");
[titleLabel sizeToFit];
self.navigationItem.titleView = titleLabel;
[self.view addSubview:self.tableView];
}
#pragma mark - UITableViewDataSource, UITableViewDelegate
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return self.dataProvider.datas.count;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSArray *subArray = self.dataProvider.datas[section];
return subArray.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
TUIMemberInfoCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
NSArray *subArray = self.dataProvider.datas[indexPath.section];
TUIMemberInfoCellData *cellData = subArray[indexPath.row];
cell.data = cellData;
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:NO];
if (indexPath.section == 1 && indexPath.row == 0) {
__weak typeof(self) weakSelf = self;
TUISelectGroupMemberViewController *vc = [[TUISelectGroupMemberViewController alloc] init];
vc.groupId = self.groupID;
vc.name = TIMCommonLocalizableString(TUIKitGroupManageAdminSetting);
vc.selectedFinished = ^(NSMutableArray<TUIUserModel *> *_Nonnull modelList) {
[weakSelf.dataProvider settingAdmins:modelList
callback:^(int code, NSString *errorMsg) {
if (code != 0) {
[weakSelf.view makeToast:errorMsg];
}
[weakSelf.tableView reloadData];
}];
};
[self.navigationController pushViewController:vc animated:YES];
}
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
return indexPath.section == 1 && indexPath.row > 0;
}
- (NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath {
return TIMCommonLocalizableString(Delete);
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
NSArray *subArray = self.dataProvider.datas[indexPath.section];
TUIMemberInfoCellData *cellData = subArray[indexPath.row];
__weak typeof(self) weakSelf = self;
[self.dataProvider removeAdmin:cellData.identifier
callback:^(int code, NSString *err) {
if (code != 0) {
[weakSelf.view makeToast:err];
}
[weakSelf.tableView reloadData];
}];
}
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
NSArray *subArray = self.dataProvider.datas[section];
NSString *title = TIMCommonLocalizableString(TUIKitGroupOwner);
if (section == 1) {
title = [NSString stringWithFormat:TIMCommonLocalizableString(TUIKitGroupManagerFormat), subArray.count - 1, 10];
}
UIView *view = [[UIView alloc] init];
view.backgroundColor = [UIColor groupTableViewBackgroundColor];
UILabel *label = [[UILabel alloc] init];
label.text = title;
label.textColor = [UIColor colorWithRed:136 / 255.0 green:136 / 255.0 blue:136 / 255.0 alpha:1 / 1.0];
label.font = [UIFont systemFontOfSize:14.0];
[view addSubview:label];
[label sizeToFit];
label.mm_x = 20;
label.mm_y = 10;
return view;
}
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {
return [UIView new];
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return 30;
}
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
return 0;
}
- (UITableView *)tableView {
if (_tableView == nil) {
_tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStyleGrouped];
_tableView.backgroundColor = TIMCommonDynamicColor(@"controller_bg_color", @"#F2F3F5");
_tableView.delaysContentTouches = NO;
_tableView.delegate = self;
_tableView.dataSource = self;
[_tableView registerClass:TUIMemberInfoCell.class forCellReuseIdentifier:@"cell"];
}
return _tableView;
}
- (TUISettingAdminDataProvider *)dataProvider {
if (_dataProvider == nil) {
_dataProvider = [[TUISettingAdminDataProvider alloc] init];
}
return _dataProvider;
}
@end

View File

@@ -0,0 +1,52 @@
//
// TUISettingController.h
// TUIKitDemo
//
// Created by lynxzhang on 2018/10/19.
// Copyright © 2018 Tencent. All rights reserved.
//
/** IM Demo
* Tencent Cloud Chat Demo settings main interface view
* - This file implements the setting interface, that is, the view corresponding to the "Me" button in the TabBar.
* - Here you can view and modify your personal information, or perform operations such as logging out.
* - This class depends on Tencent Cloud TUIKit and IMSDK
*/
#import <TIMCommon/TIMCommonModel.h>
#import <TIMCommon/TIMDefine.h>
#import <UIKit/UIKit.h>
#define SHEET_COMMON 1
#define SHEET_AGREE 2
#define SHEET_SEX 3
#define SHEET_V2API 4
@protocol TUISettingControllerDelegate <NSObject>
@optional
- (void)onSwitchMsgReadStatus:(BOOL)isOn;
- (void)onSwitchOnlineStatus:(BOOL)isOn;
- (void)onSwitchCallsRecord:(BOOL)isOn;
- (void)onClickAboutIM;
- (void)onClickLogout;
- (void)onChangeStyle;
- (void)onChangeTheme;
@end
@interface TUISettingController : UITableViewController
@property(nonatomic, strong) NSString *lastLoginUser;
@property(nonatomic, weak) id<TUISettingControllerDelegate> delegate;
@property(nonatomic, assign) BOOL showPersonalCell;
@property(nonatomic, assign) BOOL showMessageReadStatusCell;
@property(nonatomic, assign) BOOL showDisplayOnlineStatusCell;
@property(nonatomic, assign) BOOL showSelectStyleCell;
@property(nonatomic, assign) BOOL showChangeThemeCell;
@property(nonatomic, assign) BOOL showCallsRecordCell;
@property(nonatomic, assign) BOOL showAboutIMCell;
@property(nonatomic, assign) BOOL showLoginOutCell;
@property(nonatomic, assign) BOOL msgNeedReadReceipt;
@property(nonatomic, assign) BOOL displayCallsRecord;
@property(nonatomic, strong) NSString *aboutIMCellText;
@end

View File

@@ -0,0 +1,457 @@
//
// SettingController.m
// TUIKitDemo
//
// Created by lynxzhang on 2018/10/19.
// Copyright © 2018 Tencent. All rights reserved.
//
#import "TUISettingController.h"
#import <TIMCommon/TIMCommonModel.h>
#import <TIMCommon/TIMConfig.h>
#import <TUICore/TUICore.h>
#import "TUIProfileController.h"
#import "TUIStyleSelectViewController.h"
#import "TUIThemeSelectController.h"
static NSString *const kKeyWeight = @"weight";
static NSString *const kKeyItems = @"items";
static NSString *const kKeyViews = @"views"; // Used to pass custom views from extensions.
@interface TUISettingController () <UIActionSheetDelegate,
V2TIMSDKListener,
TUIProfileCardDelegate,
TUIStyleSelectControllerDelegate,
TUIThemeSelectControllerDelegate>
@property(nonatomic, strong) NSMutableArray *dataList;
@property(nonatomic, strong) V2TIMUserFullInfo *profile;
@property(nonatomic, strong) TUIProfileCardCellData *profileCellData;
@property(nonatomic, strong) NSString *styleName;
@property(nonatomic, strong) NSString *themeName;
@property(nonatomic, copy) NSArray *sortedDataList;
@end
@implementation TUISettingController
- (instancetype)init {
self = [super init];
if (self) {
self.showPersonalCell = YES;
self.showMessageReadStatusCell = YES;
self.showDisplayOnlineStatusCell = YES;
self.showCallsRecordCell = YES;
self.showSelectStyleCell = NO;
self.showChangeThemeCell = NO;
self.showAboutIMCell = YES;
self.showLoginOutCell = YES;
}
return self;
}
#pragma mark - Life cycle
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
self.navigationController.navigationBarHidden = NO;
[self.tableView reloadData];
}
- (void)viewDidLoad {
[super viewDidLoad];
[self setupViews];
[[V2TIMManager sharedInstance] addIMSDKListener:self];
NSString *loginUser = [[V2TIMManager sharedInstance] getLoginUser];
if (!loginUser) {
loginUser = self.lastLoginUser;
}
if (loginUser.length > 0) {
@weakify(self);
[[V2TIMManager sharedInstance] getUsersInfo:@[ loginUser ]
succ:^(NSArray<V2TIMUserFullInfo *> *infoList) {
@strongify(self);
self.profile = infoList.firstObject;
[self setupData];
}
fail:nil];
}
[TUITool addUnsupportNotificationInVC:self debugOnly:NO];
}
#pragma mark - Private
- (void)setupViews {
self.tableView.delaysContentTouches = NO;
self.tableView.tableFooterView = [[UIView alloc] init];
self.tableView.backgroundColor = TIMCommonDynamicColor(@"controller_bg_color", @"#F2F3F5");
CGRect rect = self.view.bounds;
[self.tableView registerClass:[TUICommonTextCell class] forCellReuseIdentifier:@"textCell"];
[self.tableView registerClass:[TUIProfileCardCell class] forCellReuseIdentifier:@"personalCell"];
[self.tableView registerClass:[TUIButtonCell class] forCellReuseIdentifier:@"buttonCell"];
[self.tableView registerClass:[TUICommonSwitchCell class] forCellReuseIdentifier:@"switchCell"];
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"containerCell"];
if (@available(iOS 15.0, *)) {
self.tableView.sectionHeaderTopPadding = 0;
}
}
#pragma mark - V2TIMSDKListener
- (void)onSelfInfoUpdated:(V2TIMUserFullInfo *)Info {
self.profile = Info;
[self setupData];
}
#pragma mark - UITableView DataSource & Delegate
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return self.sortedDataList.count;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
UIView *view = [[UIView alloc] init];
view.backgroundColor = [UIColor clearColor];
return view;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return section == 0 ? 0 : 10;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSDictionary *dict = self.sortedDataList[section];
// Extension settings.
if (dict[kKeyViews] && [dict[kKeyViews] isKindOfClass:NSArray.class]) {
NSArray *views = dict[kKeyViews];
return views.count;
}
// Built-in settings.
NSArray *items = dict[kKeyItems];
return items.count;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
NSDictionary *dict = self.sortedDataList[indexPath.section];
// Extension settings.
if (dict[kKeyViews] && [dict[kKeyViews] isKindOfClass:NSArray.class]) {
UIView *view = dict[kKeyViews][indexPath.row];
return view.bounds.size.height;
}
// Built-in settings.
NSArray *array = dict[kKeyItems];
TUICommonCellData *data = array[indexPath.row];
return [data heightOfWidth:Screen_Width];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSDictionary *dict = self.sortedDataList[indexPath.section];
// Extension settings.
if (dict[kKeyViews] && [dict[kKeyViews] isKindOfClass:NSArray.class]) {
UIView *view = dict[kKeyViews][indexPath.row];
if ([view isKindOfClass:[UITableViewCell class]] ) {
return (id)view;
}
else {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"containerCell" forIndexPath:indexPath];
[cell addSubview:view];
return cell;
}
}
// Built-in settings.
NSArray *array = dict[kKeyItems];
NSDictionary *data = array[indexPath.row];
if ([data isKindOfClass:[TUIProfileCardCellData class]]) {
TUIProfileCardCell *cell = [tableView dequeueReusableCellWithIdentifier:@"personalCell" forIndexPath:indexPath];
cell.delegate = self;
[cell fillWithData:(TUIProfileCardCellData *)data];
return cell;
} else if ([data isKindOfClass:[TUIButtonCellData class]]) {
TUIButtonCell *cell = [tableView dequeueReusableCellWithIdentifier:TButtonCell_ReuseId];
if (!cell) {
cell = [[TUIButtonCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:TButtonCell_ReuseId];
}
[cell fillWithData:(TUIButtonCellData *)data];
return cell;
} else if ([data isKindOfClass:[TUICommonTextCellData class]]) {
TUICommonTextCell *cell = [tableView dequeueReusableCellWithIdentifier:@"textCell" forIndexPath:indexPath];
[cell fillWithData:(TUICommonTextCellData *)data];
return cell;
} else if ([data isKindOfClass:[TUICommonSwitchCellData class]]) {
TUICommonSwitchCell *cell = [tableView dequeueReusableCellWithIdentifier:@"switchCell" forIndexPath:indexPath];
[cell fillWithData:(TUICommonSwitchCellData *)data];
return cell;
}
return nil;
}
#pragma mark - Private
- (void)setupData {
self.dataList = [NSMutableArray array];
if (self.showPersonalCell) {
TUIProfileCardCellData *personal = [[TUIProfileCardCellData alloc] init];
personal.identifier = self.profile.userID;
personal.avatarImage = DefaultAvatarImage;
personal.avatarUrl = [NSURL URLWithString:self.profile.faceURL];
personal.name = [self.profile showName];
personal.genderString = [self.profile showGender];
personal.signature = self.profile.selfSignature.length
? [NSString stringWithFormat:TIMCommonLocalizableString(SignatureFormat), self.profile.selfSignature]
: TIMCommonLocalizableString(no_personal_signature);
personal.cselector = @selector(didSelectCommon);
personal.showAccessory = YES;
personal.showSignature = YES;
self.profileCellData = personal;
[self.dataList addObject:@{kKeyWeight : @1000, kKeyItems : @[ personal ]}];
}
TUICommonTextCellData *friendApply = [TUICommonTextCellData new];
friendApply.key = TIMCommonLocalizableString(MeFriendRequest);
friendApply.showAccessory = YES;
friendApply.cselector = @selector(onEditFriendApply);
if (self.profile.allowType == V2TIM_FRIEND_ALLOW_ANY) {
friendApply.value = TIMCommonLocalizableString(MeFriendRequestMethodAgreeAll);
}
if (self.profile.allowType == V2TIM_FRIEND_NEED_CONFIRM) {
friendApply.value = TIMCommonLocalizableString(MeFriendRequestMethodNeedConfirm);
}
if (self.profile.allowType == V2TIM_FRIEND_DENY_ANY) {
friendApply.value = TIMCommonLocalizableString(MeFriendRequestMethodDenyAll);
}
[self.dataList addObject:@{kKeyWeight : @900, kKeyItems : @[ friendApply ]}];
if (self.showMessageReadStatusCell) {
TUICommonSwitchCellData *msgReadStatus = [TUICommonSwitchCellData new];
msgReadStatus.title = TIMCommonLocalizableString(MeMessageReadStatus);
msgReadStatus.desc =
self.msgNeedReadReceipt ? TIMCommonLocalizableString(MeMessageReadStatusOpenDesc) : TIMCommonLocalizableString(MeMessageReadStatusCloseDesc);
msgReadStatus.cswitchSelector = @selector(onSwitchMsgReadStatus:);
msgReadStatus.on = self.msgNeedReadReceipt;
[self.dataList addObject:@{kKeyWeight : @800, kKeyItems : @[ msgReadStatus ]}];
}
if (self.showDisplayOnlineStatusCell) {
TUICommonSwitchCellData *onlineStatus = [TUICommonSwitchCellData new];
onlineStatus.title = TIMCommonLocalizableString(ShowOnlineStatus);
onlineStatus.desc = [TUIConfig defaultConfig].displayOnlineStatusIcon ? TIMCommonLocalizableString(ShowOnlineStatusOpenDesc)
: TIMCommonLocalizableString(ShowOnlineStatusCloseDesc);
onlineStatus.cswitchSelector = @selector(onSwitchOnlineStatus:);
onlineStatus.on = [TUIConfig defaultConfig].displayOnlineStatusIcon;
[self.dataList addObject:@{kKeyWeight : @700, kKeyItems : @[ onlineStatus ]}];
}
if (self.showSelectStyleCell) {
TUICommonTextCellData *styleApply = [TUICommonTextCellData new];
styleApply.key = TIMCommonLocalizableString(TIMAppSelectStyle);
styleApply.showAccessory = YES;
styleApply.cselector = @selector(onClickChangeStyle);
[[RACObserve(self, styleName) distinctUntilChanged] subscribeNext:^(NSString *styleName) {
styleApply.value = self.styleName;
}];
self.styleName =
[TUIStyleSelectViewController isClassicEntrance] ? TIMCommonLocalizableString(TUIKitClassic) : TIMCommonLocalizableString(TUIKitMinimalist);
[self.dataList addObject:@{kKeyWeight : @600, kKeyItems : @[ styleApply ]}];
}
if (self.showChangeThemeCell && [self.styleName isEqualToString:TIMCommonLocalizableString(TUIKitClassic)]) {
TUICommonTextCellData *themeApply = [TUICommonTextCellData new];
themeApply.key = TIMCommonLocalizableString(TIMAppChangeTheme);
themeApply.showAccessory = YES;
themeApply.cselector = @selector(onClickChangeTheme);
[[RACObserve(self, themeName) distinctUntilChanged] subscribeNext:^(NSString *themeName) {
themeApply.value = self.themeName;
}];
self.themeName = [TUIThemeSelectController getLastThemeName];
[self.dataList addObject:@{kKeyWeight : @500, kKeyItems : @[ themeApply ]}];
}
if (self.showCallsRecordCell) {
TUICommonSwitchCellData *record = [TUICommonSwitchCellData new];
record.title = TIMCommonLocalizableString(ShowCallsRecord);
record.desc = @"";
record.cswitchSelector = @selector(onSwitchCallsRecord:);
record.on = self.displayCallsRecord;
[self.dataList addObject:@{kKeyWeight : @400, kKeyItems : @[ record ]}];
}
if (self.showAboutIMCell) {
TUICommonTextCellData *about = [TUICommonTextCellData new];
about.key = self.aboutIMCellText;
about.showAccessory = YES;
about.cselector = @selector(onClickAboutIM:);
[self.dataList addObject:@{kKeyWeight : @300, kKeyItems : @[ about ]}];
}
if (self.showLoginOutCell) {
TUIButtonCellData *button = [[TUIButtonCellData alloc] init];
button.title = TIMCommonLocalizableString(logout);
button.style = ButtonRedText;
button.cbuttonSelector = @selector(onClickLogout:);
button.hideSeparatorLine = YES;
[self.dataList addObject:@{kKeyWeight : @200, kKeyItems : @[ button ]}];
}
[self setupExtensionsData];
[self sortDataList];
[self.tableView reloadData];
}
- (void)setupExtensionsData {
NSMutableDictionary *param = [NSMutableDictionary dictionary];
param[TUICore_TUIContactExtension_MeSettingMenu_Nav] = self.navigationController;
NSArray *extensionList = [TUICore getExtensionList:TUICore_TUIContactExtension_MeSettingMenu_ClassicExtensionID param:param];
for (TUIExtensionInfo *info in extensionList) {
NSAssert(info.data, @"extension for setting is invalid, check data");
UIView *view = info.data[TUICore_TUIContactExtension_MeSettingMenu_View];
NSInteger weight = [info.data[TUICore_TUIContactExtension_MeSettingMenu_Weight] integerValue];
if (view) {
[self.dataList addObject:@{kKeyWeight : @(weight), kKeyViews : @[ view ]}];
}
}
}
- (void)sortDataList {
NSArray *sortedArray = [self.dataList sortedArrayUsingComparator:^NSComparisonResult(NSDictionary *obj1, NSDictionary *obj2) {
if ([obj1[kKeyWeight] integerValue] <= [obj2[kKeyWeight] integerValue]) {
return NSOrderedDescending;
} else {
return NSOrderedAscending;
}
}];
self.sortedDataList = sortedArray;
}
#pragma mark-- Event
- (void)didSelectCommon {
[self setupData];
TUIProfileController *test = [[TUIProfileController alloc] init];
[self.navigationController pushViewController:test animated:YES];
}
- (void)onEditFriendApply {
UIActionSheet *sheet = [[UIActionSheet alloc] init];
sheet.tag = SHEET_AGREE;
[sheet addButtonWithTitle:TIMCommonLocalizableString(MeFriendRequestMethodAgreeAll)];
[sheet addButtonWithTitle:TIMCommonLocalizableString(MeFriendRequestMethodNeedConfirm)];
[sheet addButtonWithTitle:TIMCommonLocalizableString(MeFriendRequestMethodDenyAll)];
[sheet setCancelButtonIndex:[sheet addButtonWithTitle:TIMCommonLocalizableString(Cancel)]];
[sheet setDelegate:self];
[sheet showInView:self.view];
[self setupData];
}
#pragma mark UIActionSheetDelegate
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
if (actionSheet.tag == SHEET_AGREE) {
if (buttonIndex >= 3) return;
self.profile.allowType = buttonIndex;
[self setupData];
V2TIMUserFullInfo *info = [[V2TIMUserFullInfo alloc] init];
info.allowType = [NSNumber numberWithInteger:buttonIndex].intValue;
[[V2TIMManager sharedInstance] setSelfInfo:info succ:nil fail:nil];
}
// PRIVATEMARK
}
- (void)didTapOnAvatar:(TUIProfileCardCell *)cell {
TUIAvatarViewController *image = [[TUIAvatarViewController alloc] init];
image.avatarData = cell.cardData;
[self.navigationController pushViewController:image animated:YES];
}
- (void)onSwitchMsgReadStatus:(TUICommonSwitchCell *)cell {
BOOL on = cell.switcher.isOn;
if (self.delegate && [self.delegate respondsToSelector:@selector(onSwitchMsgReadStatus:)]) {
[self.delegate onSwitchMsgReadStatus:on];
}
TUICommonSwitchCellData *switchData = cell.switchData;
switchData.on = on;
if (on) {
switchData.desc = TIMCommonLocalizableString(MeMessageReadStatusOpenDesc);
[TUITool hideToast];
[TUITool makeToast:TIMCommonLocalizableString(ShowPackageToast)];
} else {
switchData.desc = TIMCommonLocalizableString(MeMessageReadStatusCloseDesc);
}
[cell fillWithData:switchData];
}
- (void)onSwitchOnlineStatus:(TUICommonSwitchCell *)cell {
BOOL on = cell.switcher.isOn;
if (self.delegate && [self.delegate respondsToSelector:@selector(onSwitchOnlineStatus:)]) {
[self.delegate onSwitchOnlineStatus:on];
}
TUIConfig.defaultConfig.displayOnlineStatusIcon = on;
TUICommonSwitchCellData *switchData = cell.switchData;
switchData.on = on;
if (on) {
switchData.desc = TIMCommonLocalizableString(ShowOnlineStatusOpenDesc);
} else {
switchData.desc = TIMCommonLocalizableString(ShowOnlineStatusCloseDesc);
}
if (on) {
[TUITool hideToast];
[TUITool makeToast:TIMCommonLocalizableString(ShowPackageToast)];
}
[cell fillWithData:switchData];
}
- (void)onSwitchCallsRecord:(TUICommonSwitchCell *)cell {
BOOL on = cell.switcher.isOn;
if (self.delegate && [self.delegate respondsToSelector:@selector(onSwitchCallsRecord:)]) {
[self.delegate onSwitchCallsRecord:on];
}
TUICommonSwitchCellData *data = cell.switchData;
data.on = on;
[cell fillWithData:data];
}
- (void)onClickAboutIM:(TUICommonTextCell *)cell {
if (self.delegate && [self.delegate respondsToSelector:@selector(onClickAboutIM)]) {
[self.delegate onClickAboutIM];
}
}
- (void)onClickChangeStyle {
TUIStyleSelectViewController *styleVC = [[TUIStyleSelectViewController alloc] init];
styleVC.delegate = self;
[self.navigationController pushViewController:styleVC animated:YES];
}
- (void)onClickChangeTheme {
TUIThemeSelectController *vc = [[TUIThemeSelectController alloc] init];
vc.delegate = self;
[self.navigationController pushViewController:vc animated:YES];
}
#pragma mark TUIStyleSelectControllerDelegate
- (void)onSelectStyle:(TUIStyleSelectCellModel *)cellModel {
if (![cellModel.styleName isEqualToString:self.styleName]) {
self.styleName = cellModel.styleName;
if (self.delegate && [self.delegate respondsToSelector:@selector(onChangeStyle)]) {
[self.delegate onChangeStyle];
}
}
}
#pragma mark TUIThemeSelectControllerDelegate
- (void)onSelectTheme:(TUIThemeSelectCollectionViewCellModel *)cellModel {
if (![cellModel.themeName isEqualToString:self.themeName]) {
self.themeName = cellModel.themeName;
if (self.delegate && [self.delegate respondsToSelector:@selector(onChangeTheme)]) {
[self.delegate onChangeTheme];
}
}
}
- (void)onClickLogout:(TUIButtonCell *)cell {
if (self.delegate && [self.delegate respondsToSelector:@selector(onClickLogout)]) {
[self.delegate onClickLogout];
}
}
@end

View File

@@ -0,0 +1,19 @@
//
// TTextEditController.h
// TUIKit
//
// Created by annidyfeng on 2019/3/11.
// Copyright © 2019 annidyfeng. All rights reserved.
//
#import <UIKit/UIKit.h>
@class TUITextEditController;
@interface TUITextEditController : UIViewController
@property UITextField *inputTextField;
@property NSString *textValue;
- (instancetype)initWithText:(NSString *)text;
@end

View File

@@ -0,0 +1,74 @@
//
// EditInfoViewController.m
// TUIKit
//
// Created by annidyfeng on 2019/3/11.
// Copyright © 2019 annidyfeng. All rights reserved.
//
#import "TUITextEditController.h"
#import <TIMCommon/TIMDefine.h>
#import <TUICore/TUIThemeManager.h>
@interface TTextField : UITextField
@property int margin;
@end
@implementation TTextField
- (CGRect)textRectForBounds:(CGRect)bounds {
int margin = self.margin;
CGRect inset = CGRectMake(bounds.origin.x + margin, bounds.origin.y, bounds.size.width - margin, bounds.size.height);
return inset;
}
- (CGRect)editingRectForBounds:(CGRect)bounds {
int margin = self.margin;
CGRect inset = CGRectMake(bounds.origin.x + margin, bounds.origin.y, bounds.size.width - margin, bounds.size.height);
return inset;
}
@end
@interface TUITextEditController ()
@end
@implementation TUITextEditController
- (BOOL)willDealloc {
return NO;
}
- (instancetype)initWithText:(NSString *)text;
{
if (self = [super init]) {
_textValue = text;
self.edgesForExtendedLayout = UIRectEdgeNone;
}
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:TIMCommonLocalizableString(Save)
style:UIBarButtonItemStylePlain
target:self
action:@selector(onSave)];
self.view.backgroundColor = TIMCommonDynamicColor(@"controller_bg_color", @"#F2F3F5");
_inputTextField = [[TTextField alloc] initWithFrame:CGRectZero];
_inputTextField.text = [self.textValue stringByTrimmingCharactersInSet:[NSCharacterSet illegalCharacterSet]];
[(TTextField *)_inputTextField setMargin:10];
_inputTextField.backgroundColor = TIMCommonDynamicColor(@"search_textfield_bg_color", @"#FEFEFE");
_inputTextField.frame = CGRectMake(0, 10, self.view.frame.size.width, 40);
_inputTextField.clearButtonMode = UITextFieldViewModeWhileEditing;
[self.view addSubview:_inputTextField];
}
- (void)onSave {
self.textValue = [self.inputTextField.text stringByTrimmingCharactersInSet:[NSCharacterSet illegalCharacterSet]];
[self.navigationController popViewControllerAnimated:YES];
}
@end

View File

@@ -0,0 +1,33 @@
// Created by Tencent on 2023/06/09.
// Copyright © 2023 Tencent. All rights reserved.
/**
*
* Tencent Cloud Communication Service Interface Components TUIKIT - User Information View Interface
* This file implements the user profile view controller. User refers to other users who are not friends.
* If friend, use TUIFriendProfileController
*/
#import <TIMCommon/TIMCommonModel.h>
#import <TIMCommon/TIMDefine.h>
#import <UIKit/UIKit.h>
#import "TUICommonPendencyCellData.h"
typedef enum : NSUInteger {
PCA_NONE,
PCA_ADD_FRIEND,
PCA_PENDENDY_CONFIRM,
PCA_GROUP_CONFIRM,
} ProfileControllerAction;
@interface TUIUserProfileController : UITableViewController
@property V2TIMUserFullInfo *userFullInfo;
@property TUIGroupPendencyCellData *groupPendency;
@property TUICommonPendencyCellData *pendency;
@property ProfileControllerAction actionType;
@end

View File

@@ -0,0 +1,306 @@
//
// TUIProfileController.m
// TUIKit
//
// Created by annidyfeng on 2019/3/11.
// Copyright © 2019 kennethmiao. All rights reserved.
//
#import "TUIUserProfileController.h"
#import <TIMCommon/TIMCommonModel.h>
#import <TUICore/TUIThemeManager.h>
#import "TUICommonContactProfileCardCell.h"
#import "TUICommonContactTextCell.h"
#import "TUICommonPendencyCellData.h"
#import "TUIContactAvatarViewController.h"
#import "TUIContactConversationCellData.h"
#import "TUIFriendRequestViewController.h"
#import "TUIContactConfig.h"
@interface TUIUserProfileController () <TUIContactProfileCardDelegate>
@property NSMutableArray<NSArray *> *dataList;
@property(nonatomic, strong) TUINaviBarIndicatorView *titleView;
@end
@implementation TUIUserProfileController
- (instancetype)init {
self = [super initWithStyle:UITableViewStyleGrouped];
return self;
}
- (void)willMoveToParentViewController:(nullable UIViewController *)parent {
[super willMoveToParentViewController:parent];
}
- (void)viewDidLoad {
[super viewDidLoad];
_titleView = [[TUINaviBarIndicatorView alloc] init];
[_titleView setTitle:TIMCommonLocalizableString(ProfileDetails)];
self.navigationItem.titleView = _titleView;
self.navigationItem.title = @"";
self.clearsSelectionOnViewWillAppear = YES;
if (@available(iOS 15.0, *)) {
self.tableView.sectionHeaderTopPadding = 0;
}
[self.tableView registerClass:[TUICommonContactTextCell class] forCellReuseIdentifier:@"TextCell"];
[self.tableView registerClass:[TUICommonContactProfileCardCell class] forCellReuseIdentifier:@"CardCell"];
[self.tableView registerClass:[TUIButtonCell class] forCellReuseIdentifier:@"ButtonCell"];
self.tableView.delaysContentTouches = NO;
self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
[self loadData];
}
- (void)loadData {
NSMutableArray *list = @[].mutableCopy;
[list addObject:({
NSMutableArray *inlist = @[].mutableCopy;
[inlist addObject:({
TUICommonContactProfileCardCellData *personal = [[TUICommonContactProfileCardCellData alloc] init];
personal.identifier = self.userFullInfo.userID;
personal.avatarImage = DefaultAvatarImage;
personal.avatarUrl = [NSURL URLWithString:self.userFullInfo.faceURL];
personal.name = [self.userFullInfo showName];
personal.genderString = [self.userFullInfo showGender];
personal.signature = [self.userFullInfo showSignature];
personal.reuseId = @"CardCell";
personal;
})];
inlist;
})];
if (self.pendency || self.groupPendency) {
[list addObject:({
NSMutableArray *inlist = @[].mutableCopy;
[inlist addObject:({
TUICommonContactTextCellData *data = TUICommonContactTextCellData.new;
data.key = TIMCommonLocalizableString(FriendAddVerificationMessage);
data.keyColor = [UIColor colorWithRed:136 / 255.0 green:136 / 255.0 blue:136 / 255.0 alpha:1 / 1.0];
data.valueColor = [UIColor colorWithRed:68 / 255.0 green:68 / 255.0 blue:68 / 255.0 alpha:1 / 1.0];
if (self.pendency) {
data.value = self.pendency.addWording;
} else if (self.groupPendency) {
data.value = self.groupPendency.requestMsg;
}
data.reuseId = @"TextCell";
data.enableMultiLineValue = YES;
data;
})];
inlist;
})];
}
self.dataList = list;
if (self.actionType == PCA_ADD_FRIEND) {
[[V2TIMManager sharedInstance] checkFriend:@[ self.userFullInfo.userID ]
checkType:V2TIM_FRIEND_TYPE_BOTH
succ:^(NSArray<V2TIMFriendCheckResult *> *resultList) {
if (resultList.count == 0) {
return;
}
V2TIMFriendCheckResult *result = resultList.firstObject;
if (result.relationType == V2TIM_FRIEND_RELATION_TYPE_IN_MY_FRIEND_LIST ||
result.relationType == V2TIM_FRIEND_RELATION_TYPE_BOTH_WAY) {
return;
}
if (![TUIContactConfig.sharedConfig isItemHiddenInContactConfig:TUIContactConfigItem_AddFriend]) {
[self.dataList addObject:({
NSMutableArray *inlist = @[].mutableCopy;
[inlist addObject:({
TUIButtonCellData *data = TUIButtonCellData.new;
data.title = TIMCommonLocalizableString(FriendAddTitle);
data.style = ButtonWhite;
data.cbuttonSelector = @selector(onAddFriend);
data.reuseId = @"ButtonCell";
data.hideSeparatorLine = YES;
data;
})];
inlist;
})];
[self.tableView reloadData];
}
}
fail:^(int code, NSString *desc) {
NSLog(@"");
}];
}
if (self.actionType == PCA_PENDENDY_CONFIRM) {
[self.dataList addObject:({
NSMutableArray *inlist = @[].mutableCopy;
[inlist addObject:({
TUIButtonCellData *data = TUIButtonCellData.new;
data.title = TIMCommonLocalizableString(Accept);
data.style = ButtonWhite;
data.textColor = [UIColor colorWithRed:20 / 255.0 green:122 / 255.0 blue:255 / 255.0 alpha:1 / 1.0];
data.cbuttonSelector = @selector(onAgreeFriend);
data.reuseId = @"ButtonCell";
data;
})];
[inlist addObject:({
TUIButtonCellData *data = TUIButtonCellData.new;
data.title = TIMCommonLocalizableString(Decline);
data.style = ButtonRedText;
data.cbuttonSelector = @selector(onRejectFriend);
data.reuseId = @"ButtonCell";
data;
})];
inlist;
})];
}
if (self.actionType == PCA_GROUP_CONFIRM) {
[self.dataList addObject:({
NSMutableArray *inlist = @[].mutableCopy;
[inlist addObject:({
TUIButtonCellData *data = TUIButtonCellData.new;
data.title = TIMCommonLocalizableString(Accept);
data.style = ButtonWhite;
data.textColor = TIMCommonDynamicColor(@"primary_theme_color", @"#147AFF");
data.cbuttonSelector = @selector(onAgreeGroup);
data.reuseId = @"ButtonCell";
data;
})];
[inlist addObject:({
TUIButtonCellData *data = TUIButtonCellData.new;
data.title = TIMCommonLocalizableString(Decline);
data.style = ButtonRedText;
data.cbuttonSelector = @selector(onRejectGroup);
data.reuseId = @"ButtonCell";
data;
})];
inlist;
})];
}
[self.tableView reloadData];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return self.dataList.count;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.dataList[section].count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
TUICommonCellData *data = self.dataList[indexPath.section][indexPath.row];
TUICommonTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:data.reuseId forIndexPath:indexPath];
if ([cell isKindOfClass:[TUICommonContactProfileCardCell class]]) {
TUICommonContactProfileCardCell *cardCell = (TUICommonContactProfileCardCell *)cell;
cardCell.delegate = self;
cell = cardCell;
}
[cell fillWithData:data];
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(nonnull NSIndexPath *)indexPath {
TUICommonCellData *data = self.dataList[indexPath.section][indexPath.row];
return [data heightOfWidth:Screen_Width];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return 0;
}
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
return section == 0 ? 0 : 10;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
UIView *view = [[UIView alloc] init];
view.backgroundColor = [UIColor clearColor];
return view;
}
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {
UIView *view = [[UIView alloc] init];
view.backgroundColor = [UIColor clearColor];
return view;
}
- (void)onSendMessage {
// TUIChatConversationModel *data = [[TUIChatConversationModel alloc] init];
// data.conversationID = [NSString stringWithFormat:@"c2c_%@",self.userFullInfo.userID];
// data.userID = self.userFullInfo.userID;
// data.title = [self.userFullInfo showName];
// ChatViewController *chat = [[ChatViewController alloc] init];
// chat.conversationData = data;
// [self.navigationController pushViewController:chat animated:YES];
}
- (void)onAddFriend {
TUIFriendRequestViewController *vc = [TUIFriendRequestViewController new];
vc.profile = self.userFullInfo;
[self.navigationController pushViewController:vc animated:YES];
}
- (void)onAgreeFriend {
__weak typeof(self)weakSelf = self;
[self.pendency agreeWithSuccess:^{
[weakSelf.navigationController popViewControllerAnimated:YES];
} failure:^(int code, NSString * _Nonnull msg) {
}];
}
- (void)onRejectFriend {
__weak typeof(self)weakSelf = self;
[self.pendency rejectWithSuccess:^{
[weakSelf.navigationController popViewControllerAnimated:YES];
} failure:^(int code, NSString * _Nonnull msg) {
}];
}
- (void)onAgreeGroup {
__weak typeof(self)weakSelf = self;
[self.groupPendency agreeWithSuccess:^{
[weakSelf.navigationController popViewControllerAnimated:YES];
} failure:^(int code, NSString * _Nonnull msg) {
}];;
}
- (void)onRejectGroup {
__weak typeof(self)weakSelf = self;
[self.groupPendency rejectWithSuccess:^{
[weakSelf.navigationController popViewControllerAnimated:YES];
} failure:^(int code, NSString * _Nonnull msg) {
}];
}
- (UIView *)toastView {
return [UIApplication sharedApplication].keyWindow;
}
- (void)didSelectAvatar {
TUIContactAvatarViewController *image = [[TUIContactAvatarViewController alloc] init];
image.avatarData.avatarUrl = [NSURL URLWithString:self.userFullInfo.faceURL];
NSArray *list = self.dataList;
NSLog(@"%@", list);
[self.navigationController pushViewController:image animated:YES];
}
- (void)didTapOnAvatar:(TUICommonContactProfileCardCell *)cell {
TUIContactAvatarViewController *image = [[TUIContactAvatarViewController alloc] init];
image.avatarData = cell.cardData;
[self.navigationController pushViewController:image animated:YES];
}
@end