From 7d53422e65959134362d7179cef62bbac51aad4a Mon Sep 17 00:00:00 2001 From: Benjamin Reis Date: Tue, 24 Oct 2017 11:39:10 +0200 Subject: [PATCH] all needed view for creating/editing a chatroom --- ...ionCreateConfirmCollectionViewController.h | 12 -- ...ionCreateConfirmCollectionViewController.m | 30 ---- Classes/ChatConversationCreateConfirmView.h | 23 --- Classes/ChatConversationCreateConfirmView.m | 120 ------------- Classes/ChatConversationCreateConfirmView.xib | 105 ----------- Classes/ChatConversationCreateTableView.h | 1 + Classes/ChatConversationCreateTableView.m | 11 ++ Classes/ChatConversationCreateView.h | 5 + Classes/ChatConversationCreateView.m | 16 +- Classes/ChatConversationInfoView.h | 29 +++ Classes/ChatConversationInfoView.m | 121 +++++++++++++ Classes/ChatConversationInfoView.xib | 167 ++++++++++++++++++ .../UIChatConversationInfoTableViewCell.h | 21 +++ .../UIChatConversationInfoTableViewCell.m | 61 +++++++ .../UIChatConversationInfoTableViewCell.xib | 89 ++++++++++ .../UIChatCreateConfirmCollectionViewCell.h | 17 -- .../UIChatCreateConfirmCollectionViewCell.m | 33 ---- .../UIChatCreateConfirmCollectionViewCell.xib | 48 ----- Classes/PhoneMainView.h | 2 +- Resources/images/chat_group_add.png | Bin 0 -> 1837 bytes Resources/images/chat_group_add@2x.png | Bin 0 -> 6581 bytes Resources/images/check_unselected.png | Bin 0 -> 1320 bytes Resources/images/check_unselected@2x.png | Bin 0 -> 4597 bytes linphone.xcodeproj/project.pbxproj | 62 ++++--- 24 files changed, 552 insertions(+), 421 deletions(-) delete mode 100644 Classes/ChatConversationCreateConfirmCollectionViewController.h delete mode 100644 Classes/ChatConversationCreateConfirmCollectionViewController.m delete mode 100644 Classes/ChatConversationCreateConfirmView.h delete mode 100644 Classes/ChatConversationCreateConfirmView.m delete mode 100644 Classes/ChatConversationCreateConfirmView.xib create mode 100644 Classes/ChatConversationInfoView.h create mode 100644 Classes/ChatConversationInfoView.m create mode 100644 Classes/ChatConversationInfoView.xib create mode 100644 Classes/LinphoneUI/UIChatConversationInfoTableViewCell.h create mode 100644 Classes/LinphoneUI/UIChatConversationInfoTableViewCell.m create mode 100644 Classes/LinphoneUI/UIChatConversationInfoTableViewCell.xib delete mode 100644 Classes/LinphoneUI/UIChatCreateConfirmCollectionViewCell.h delete mode 100644 Classes/LinphoneUI/UIChatCreateConfirmCollectionViewCell.m delete mode 100644 Classes/LinphoneUI/UIChatCreateConfirmCollectionViewCell.xib create mode 100644 Resources/images/chat_group_add.png create mode 100644 Resources/images/chat_group_add@2x.png create mode 100644 Resources/images/check_unselected.png create mode 100644 Resources/images/check_unselected@2x.png diff --git a/Classes/ChatConversationCreateConfirmCollectionViewController.h b/Classes/ChatConversationCreateConfirmCollectionViewController.h deleted file mode 100644 index 35a61034b..000000000 --- a/Classes/ChatConversationCreateConfirmCollectionViewController.h +++ /dev/null @@ -1,12 +0,0 @@ -// -// ChatConversationCreateConfirmCollectionViewController.h -// linphone -// -// Created by REIS Benjamin on 05/10/2017. -// - -#import - -@interface ChatConversationCreateConfirmCollectionViewController : UICollectionViewController - -@end diff --git a/Classes/ChatConversationCreateConfirmCollectionViewController.m b/Classes/ChatConversationCreateConfirmCollectionViewController.m deleted file mode 100644 index 0a1457ab9..000000000 --- a/Classes/ChatConversationCreateConfirmCollectionViewController.m +++ /dev/null @@ -1,30 +0,0 @@ -// -// ChatConversationCreateConfirmCollectionViewController.m -// linphone -// -// Created by REIS Benjamin on 05/10/2017. -// - -#import "ChatConversationCreateConfirmCollectionViewController.h" -#import "UIChatCreateConfirmCollectionViewCell.h" - -@interface ChatConversationCreateConfirmCollectionViewController () - -@end - -@implementation ChatConversationCreateConfirmCollectionViewController - -static NSString * const reuseIdentifier = @"Cell"; - -- (void)viewDidLoad { - [super viewDidLoad]; - - // Register cell classes - [self.collectionView registerClass:[UIChatCreateConfirmCollectionViewCell class] forCellWithReuseIdentifier:reuseIdentifier]; -} - -- (void)didReceiveMemoryWarning { - [super didReceiveMemoryWarning]; -} - -@end diff --git a/Classes/ChatConversationCreateConfirmView.h b/Classes/ChatConversationCreateConfirmView.h deleted file mode 100644 index 95c316048..000000000 --- a/Classes/ChatConversationCreateConfirmView.h +++ /dev/null @@ -1,23 +0,0 @@ -// -// ChatConversationCreateConfirmView.h -// linphone -// -// Created by REIS Benjamin on 04/10/2017. -// - -#import -#import "UICompositeView.h" -#import "ChatConversationCreateConfirmCollectionViewController.h" - -@interface ChatConversationCreateConfirmView : UIViewController -@property (weak, nonatomic) IBOutlet UITextField *nameField; -@property (weak, nonatomic) IBOutlet UIIconButton *validateButton; -@property(nonatomic, strong) NSMutableDictionary *contacts; -@property(nonatomic, strong) NSMutableArray *contactsGroup; -@property (weak, nonatomic) IBOutlet UICollectionView *collectionView; -@property(strong, nonatomic) IBOutlet ChatConversationCreateConfirmCollectionViewController *collectionController; -- (IBAction)onBackClick:(id)sender; -- (IBAction)onValidateClick:(id)sender; -- (void)deleteContact:(NSString *)uri; - -@end diff --git a/Classes/ChatConversationCreateConfirmView.m b/Classes/ChatConversationCreateConfirmView.m deleted file mode 100644 index 653fadc6d..000000000 --- a/Classes/ChatConversationCreateConfirmView.m +++ /dev/null @@ -1,120 +0,0 @@ -// -// ChatConversationCreateConfirmView.m -// linphone -// -// Created by REIS Benjamin on 04/10/2017. -// - -#import "ChatConversationCreateConfirmView.h" -#import "PhoneMainView.h" -#import "UIChatCreateConfirmCollectionViewCell.h" - -@implementation ChatConversationCreateConfirmView - -static UICompositeViewDescription *compositeDescription = nil; - -+ (UICompositeViewDescription *)compositeViewDescription { - if (compositeDescription == nil) { - compositeDescription = [[UICompositeViewDescription alloc] init:self.class - statusBar:StatusBarView.class - tabBar:TabBarView.class - sideMenu:SideMenuView.class - fullscreen:false - isLeftFragment:NO - fragmentWith:ChatsListView.class]; - } - return compositeDescription; -} - -- (UICompositeViewDescription *)compositeViewDescription { - return self.class.compositeViewDescription; -} - -- (void)viewDidLoad { - [super viewDidLoad]; - _contactsGroup = [[NSMutableArray alloc] init]; - _nameField.delegate = self; - UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] - initWithTarget:self - action:@selector(dismissKeyboards)]; - tap.delegate = self; - [self.view addGestureRecognizer:tap]; - UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init]; - layout.scrollDirection = UICollectionViewScrollDirectionVertical; - layout.itemSize = CGSizeMake(100.0 , 50.0); - _collectionController.collectionView = _collectionView; - _collectionController = (ChatConversationCreateConfirmCollectionViewController *)[[UICollectionViewController alloc] initWithCollectionViewLayout:layout]; - _collectionView.dataSource = self; - [_collectionView setCollectionViewLayout:layout]; -} - -- (void) viewWillAppear:(BOOL)animated { - for(id uri in _contacts.allKeys) { - [_collectionView registerClass:UIChatCreateConfirmCollectionViewCell.class forCellWithReuseIdentifier:uri]; - if(![_contactsGroup containsObject:uri]) - [_contactsGroup addObject:uri]; - } - [_collectionView reloadData]; -} - -- (void)viewWillDisappear:(BOOL)animated { - [_contactsGroup removeAllObjects]; - [_contacts removeAllObjects]; -} - -- (void)dismissKeyboards { - if ([_nameField isFirstResponder]) { - [_nameField resignFirstResponder]; - } -} - -- (IBAction)onBackClick:(id)sender { - [PhoneMainView.instance popToView:ChatConversationCreateView.compositeViewDescription]; -} - -- (IBAction)onValidateClick:(id)sender { - LinphoneChatRoom *room = linphone_core_create_client_group_chat_room(LC, _nameField.text.UTF8String); - bctbx_list_t *addresses = NULL; - for (id object in _contactsGroup) { - LinphoneAddress *addr = linphone_address_new(((NSString *)object).UTF8String); - if(addresses) - bctbx_list_append(addresses, addr); - else - addresses = bctbx_list_new(addr); - } - linphone_chat_room_add_participants(room, addresses); -} - -- (void)deleteContact:(NSString *)uri { - [_contacts removeObjectForKey:uri]; - [_contactsGroup removeObject:uri]; - [_collectionView reloadData]; -} - -#pragma mark - UITextFieldDelegate - -- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { - _validateButton.enabled = !((string.length == 0 || string == nil || [string isEqual:@""]) && (textField.text.length == 1)); - return TRUE; -} - -#pragma mark - UICollectionViewDataSource - -- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { - return _contacts.count; -} - -- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView { - return 1; -} - -- (UIChatCreateConfirmCollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { - NSString *uri = _contactsGroup[indexPath.item]; - UIChatCreateConfirmCollectionViewCell *cell = (UIChatCreateConfirmCollectionViewCell *)[_collectionView dequeueReusableCellWithReuseIdentifier:uri forIndexPath:indexPath]; - cell.uri = uri; - cell.confirmController = self; - cell = [cell initWithName:_contacts[uri]]; - return cell; -} - -@end diff --git a/Classes/ChatConversationCreateConfirmView.xib b/Classes/ChatConversationCreateConfirmView.xib deleted file mode 100644 index 6cc74775d..000000000 --- a/Classes/ChatConversationCreateConfirmView.xib +++ /dev/null @@ -1,105 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Classes/ChatConversationCreateTableView.h b/Classes/ChatConversationCreateTableView.h index 2ed3446fc..568f15cd1 100644 --- a/Classes/ChatConversationCreateTableView.h +++ b/Classes/ChatConversationCreateTableView.h @@ -11,6 +11,7 @@ @interface ChatConversationCreateTableView : UITableViewController @property(weak, nonatomic) IBOutlet UISearchBar *searchBar; @property(nonatomic) Boolean allFilter; +@property(nonatomic) Boolean notFirstTime; @property(nonatomic, strong) NSMutableArray *contactsGroup; @property(nonatomic, strong) NSMutableDictionary *contactsDict; @property (weak, nonatomic) IBOutlet UICollectionView *collectionView; diff --git a/Classes/ChatConversationCreateTableView.m b/Classes/ChatConversationCreateTableView.m index 84c334061..ca3c3e160 100644 --- a/Classes/ChatConversationCreateTableView.m +++ b/Classes/ChatConversationCreateTableView.m @@ -24,6 +24,13 @@ [super viewWillAppear:animated]; _allContacts = [[NSDictionary alloc] initWithDictionary:LinphoneManager.instance.fastAddressBook.addressBookMap]; + if(_notFirstTime) { + _notFirstTime = FALSE; + for(NSString *addr in _contactsGroup) { + [_collectionView registerClass:UIChatCreateCollectionViewCell.class forCellWithReuseIdentifier:addr]; + } + return; + } _contacts = [[NSMutableDictionary alloc] initWithCapacity:_allContacts.count]; _contactsGroup = [[NSMutableArray alloc] init]; _contactsDict = [[NSMutableDictionary alloc] init]; @@ -33,6 +40,10 @@ self.tableView.accessibilityIdentifier = @"Suggested addresses"; } +- (void) viewWillDisappear:(BOOL)animated { + _notFirstTime = FALSE; +} + - (void) loadData { [self reloadDataWithFilter:_searchBar.text]; } diff --git a/Classes/ChatConversationCreateView.h b/Classes/ChatConversationCreateView.h index 15e529eb4..1a5faad5c 100644 --- a/Classes/ChatConversationCreateView.h +++ b/Classes/ChatConversationCreateView.h @@ -6,6 +6,9 @@ // // +#ifndef ChatConversationCreateView_h +#define ChatConversationCreateView_h + #import #import "ChatConversationCreateTableView.h" #import "ChatConversationCreateCollectionViewController.h" @@ -28,3 +31,5 @@ - (IBAction)onNextClick:(id)sender; @end + +#endif /* ChatConversationCreateView_h */ diff --git a/Classes/ChatConversationCreateView.m b/Classes/ChatConversationCreateView.m index 4e68af554..39978c2e1 100644 --- a/Classes/ChatConversationCreateView.m +++ b/Classes/ChatConversationCreateView.m @@ -57,13 +57,16 @@ static UICompositeViewDescription *compositeDescription = nil; - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; - _nextButton.enabled = FALSE; - _tableController.tableView.frame = CGRectMake(_tableController.tableView.frame.origin.x, - _tableController.searchBar.frame.origin.y + _tableController.searchBar.frame.size.height, - _tableController.tableView.frame.size.width, - _tableController.tableView.frame.size.height + _collectionView.frame.size.height); + if(_tableController.contactsGroup.count == 0) { + _nextButton.enabled = FALSE; + _tableController.tableView.frame = CGRectMake(_tableController.tableView.frame.origin.x, + _tableController.searchBar.frame.origin.y + _tableController.searchBar.frame.size.height, + _tableController.tableView.frame.size.width, + _tableController.tableView.frame.size.height + _collectionView.frame.size.height); + } [_collectionView reloadData]; [self changeView:ContactsAll]; + [_tableController loadData]; } #pragma mark - searchBar delegate @@ -75,8 +78,9 @@ static UICompositeViewDescription *compositeDescription = nil; } - (IBAction)onNextClick:(id)sender { - ChatConversationCreateConfirmView *view = VIEW(ChatConversationCreateConfirmView); + ChatConversationInfoView *view = VIEW(ChatConversationInfoView); view.contacts = _tableController.contactsDict; + view.create = TRUE; [PhoneMainView.instance changeCurrentView:view.compositeViewDescription]; } diff --git a/Classes/ChatConversationInfoView.h b/Classes/ChatConversationInfoView.h new file mode 100644 index 000000000..d001e703a --- /dev/null +++ b/Classes/ChatConversationInfoView.h @@ -0,0 +1,29 @@ +// +// ChatConversationInfoView.h +// linphone +// +// Created by REIS Benjamin on 23/10/2017. +// + +#import + +#import "UICompositeView.h" +#import "UIRoundBorderedButton.h" + +@interface ChatConversationInfoView : UIViewController + +@property(nonatomic, strong) NSMutableDictionary *contacts; +@property(nonatomic, strong) NSMutableArray *admins; +@property(nonatomic) BOOL create; + +@property (weak, nonatomic) IBOutlet UIIconButton *nextButton; +@property (weak, nonatomic) IBOutlet UIIconButton *backButton; +@property (weak, nonatomic) IBOutlet UIRoundBorderedButton *quitButton; +@property (weak, nonatomic) IBOutlet UITextField *nameLabel; +@property (weak, nonatomic) IBOutlet UITableView *tableView; + +- (IBAction)onNextClick:(id)sender; +- (IBAction)onBackClick:(id)sender; +- (IBAction)onQuitClick:(id)sender; + +@end diff --git a/Classes/ChatConversationInfoView.m b/Classes/ChatConversationInfoView.m new file mode 100644 index 000000000..b76bf8fb0 --- /dev/null +++ b/Classes/ChatConversationInfoView.m @@ -0,0 +1,121 @@ +// +// ChatConversationInfoView.m +// linphone +// +// Created by REIS Benjamin on 23/10/2017. +// + +#import + +#import "ChatConversationInfoView.h" +#import "PhoneMainView.h" +#import "UIChatConversationInfoTableViewCell.h" + +@implementation ChatConversationInfoView + +#pragma mark - UICompositeViewDelegate Functions + +static UICompositeViewDescription *compositeDescription = nil; + ++ (UICompositeViewDescription *)compositeViewDescription { + if (compositeDescription == nil) { + compositeDescription = [[UICompositeViewDescription alloc] init:self.class + statusBar:StatusBarView.class + tabBar:TabBarView.class + sideMenu:SideMenuView.class + fullscreen:false + isLeftFragment:NO + fragmentWith:ChatsListView.class]; + } + return compositeDescription; +} + +- (UICompositeViewDescription *)compositeViewDescription { + return self.class.compositeViewDescription; +} + +- (void)viewDidLoad { + [super viewDidLoad]; + // if we use fragments, remove back button + if (IPAD) { + _backButton.hidden = YES; + } + UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] + initWithTarget:self + action:@selector(dismissKeyboards)]; + tap.delegate = self; + [self.view addGestureRecognizer:tap]; + _nameLabel.delegate = self; + _tableView.dataSource = self; + _tableView.delegate = self; + _admins = [[NSMutableArray alloc] init]; +} + +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; + _nextButton.enabled = _nameLabel.text.length > 0 && _contacts.count > 0; + [_tableView reloadData]; + _quitButton.hidden = _create; +} + +#pragma mark - Buttons responders + +- (IBAction)onNextClick:(id)sender { +} + +- (IBAction)onBackClick:(id)sender { + if(_create) { + ChatConversationCreateView *view = VIEW(ChatConversationCreateView); + view.tableController.contactsDict = _contacts; + view.tableController.contactsGroup = [[_contacts allKeys] mutableCopy]; + view.tableController.notFirstTime = TRUE; + [PhoneMainView.instance popToView:view.compositeViewDescription]; + } +} + +- (IBAction)onQuitClick:(id)sender { +} + +#pragma mark - TableView + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { + return 1; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { + return _contacts.count; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { + NSString *kCellId = NSStringFromClass(UIChatConversationInfoTableViewCell.class); + UIChatConversationInfoTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellId]; + if (cell == nil) { + cell = [[UIChatConversationInfoTableViewCell alloc] initWithIdentifier:kCellId]; + } + cell.uri = _contacts.allKeys[indexPath.row]; + cell.nameLabel.text = [_contacts objectForKey:cell.uri]; + cell.controllerView = self; + if(![_admins containsObject:cell.uri]) { + cell.adminLabel.enabled = FALSE; + cell.adminImage.image = [UIImage imageNamed:@"check_unselected.png"]; + } + return cell; +} + +#pragma mark - searchBar delegate + +- (void)dismissKeyboards { + if ([_nameLabel isFirstResponder]) { + [_nameLabel resignFirstResponder]; + } +} + +#pragma mark - UITextFieldDelegate + +- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { + _nextButton.enabled = (!((string.length == 0 || string == nil || [string isEqual:@""]) && (textField.text.length == 1)) + && _contacts.count > 0); + return TRUE; +} + +@end diff --git a/Classes/ChatConversationInfoView.xib b/Classes/ChatConversationInfoView.xib new file mode 100644 index 000000000..191aba537 --- /dev/null +++ b/Classes/ChatConversationInfoView.xib @@ -0,0 +1,167 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Classes/LinphoneUI/UIChatConversationInfoTableViewCell.h b/Classes/LinphoneUI/UIChatConversationInfoTableViewCell.h new file mode 100644 index 000000000..07390ffaa --- /dev/null +++ b/Classes/LinphoneUI/UIChatConversationInfoTableViewCell.h @@ -0,0 +1,21 @@ +// +// UIChatConversationInfoTableViewCell.h +// linphone +// +// Created by REIS Benjamin on 23/10/2017. +// + +#import +#import "ChatConversationInfoView.h" + +@interface UIChatConversationInfoTableViewCell : UITableViewCell + +@property (weak, nonatomic) IBOutlet UIView *adminButton; +@property (weak, nonatomic) IBOutlet UILabel *adminLabel; +@property (weak, nonatomic) IBOutlet UIImageView *adminImage; +@property (weak, nonatomic) IBOutlet UILabel *nameLabel; +@property (weak, nonatomic) ChatConversationInfoView *controllerView; +@property (strong) NSString *uri; + +- (id)initWithIdentifier:(NSString *)identifier; +@end diff --git a/Classes/LinphoneUI/UIChatConversationInfoTableViewCell.m b/Classes/LinphoneUI/UIChatConversationInfoTableViewCell.m new file mode 100644 index 000000000..20120fc6c --- /dev/null +++ b/Classes/LinphoneUI/UIChatConversationInfoTableViewCell.m @@ -0,0 +1,61 @@ +// +// UIChatConversationInfoTableViewCell.m +// linphone +// +// Created by REIS Benjamin on 23/10/2017. +// + +#import "PhoneMainView.h" +#import "UIChatConversationInfoTableViewCell.h" + +@implementation UIChatConversationInfoTableViewCell + +- (void)awakeFromNib { + [super awakeFromNib]; + // Initialization code +} + +- (id)initWithIdentifier:(NSString *)identifier { + self = [super initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier]; + if (self != nil) { + NSArray *arrayOfViews = + [[NSBundle mainBundle] loadNibNamed:NSStringFromClass(self.class) owner:self options:nil]; + if ([arrayOfViews count] >= 1) { + UIChatConversationInfoTableViewCell *sub = ((UIChatConversationInfoTableViewCell *)[arrayOfViews objectAtIndex:0]); + self = sub; + } + } + + UITapGestureRecognizer *adminTap = [[UITapGestureRecognizer alloc] + initWithTarget:self + action:@selector(onAdmin)]; + adminTap.delegate = self; + adminTap.numberOfTapsRequired = 1; + [_adminButton addGestureRecognizer:adminTap]; + return self; +} + +- (IBAction)onDelete:(id)sender { + [_controllerView.contacts removeObjectForKey:_uri]; + if ([_controllerView.admins containsObject:_uri]) + [_controllerView.admins removeObject:_uri]; + + [_controllerView.tableView reloadData]; + _controllerView.nextButton.enabled = _controllerView.nameLabel.text.length > 0 && _controllerView.contacts.count > 0; +} + +- (void)onAdmin { + _adminLabel.enabled = !_adminLabel.enabled; + NSString *content = _adminLabel.enabled + ? @"check_selected.png" + : @"check_unselected.png"; + + _adminImage.image = [UIImage imageNamed:content]; + + if (_adminLabel.enabled) + [_controllerView.admins addObject:_uri]; + else + [_controllerView.admins removeObject:_uri]; +} + +@end diff --git a/Classes/LinphoneUI/UIChatConversationInfoTableViewCell.xib b/Classes/LinphoneUI/UIChatConversationInfoTableViewCell.xib new file mode 100644 index 000000000..0e281a62f --- /dev/null +++ b/Classes/LinphoneUI/UIChatConversationInfoTableViewCell.xib @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Classes/LinphoneUI/UIChatCreateConfirmCollectionViewCell.h b/Classes/LinphoneUI/UIChatCreateConfirmCollectionViewCell.h deleted file mode 100644 index f5881b11c..000000000 --- a/Classes/LinphoneUI/UIChatCreateConfirmCollectionViewCell.h +++ /dev/null @@ -1,17 +0,0 @@ -// -// UIChatCreateConfirmCollectionViewCell.h -// linphone -// -// Created by REIS Benjamin on 05/10/2017. -// - -#import -#import "UIChatCreateCollectionViewCell.h" -#import "ChatConversationCreateConfirmView.h" - -@interface UIChatCreateConfirmCollectionViewCell : UICollectionViewCell -@property (weak, nonatomic) IBOutlet UILabel *displayNameLabel; -@property (strong, nonatomic) ChatConversationCreateConfirmView *confirmController; -@property (strong, nonatomic) NSString *uri; -- (id)initWithName:(NSString *)identifier; -@end diff --git a/Classes/LinphoneUI/UIChatCreateConfirmCollectionViewCell.m b/Classes/LinphoneUI/UIChatCreateConfirmCollectionViewCell.m deleted file mode 100644 index fe1de1ae9..000000000 --- a/Classes/LinphoneUI/UIChatCreateConfirmCollectionViewCell.m +++ /dev/null @@ -1,33 +0,0 @@ -// -// UIChatCreateConfirmCollectionViewCell.m -// linphone -// -// Created by REIS Benjamin on 05/10/2017. -// - -#import "UIChatCreateConfirmCollectionViewCell.h" - -@implementation UIChatCreateConfirmCollectionViewCell - -- (id)initWithName:(NSString *)identifier { - if (self != nil) { - NSArray *arrayOfViews = - [[NSBundle mainBundle] loadNibNamed:NSStringFromClass(self.class) owner:self options:nil]; - if ([arrayOfViews count] >= 1) { - UIChatCreateCollectionViewCell *sub = ((UIChatCreateCollectionViewCell *)[arrayOfViews objectAtIndex:0]); - [self addSubview:sub]; - _displayNameLabel = sub.nameLabel; - } - } - [_displayNameLabel setText:identifier]; - - UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onDelete)]; - tap.numberOfTouchesRequired = 1; - [self addGestureRecognizer:tap]; - return self; -} - -- (void)onDelete { - [_confirmController deleteContact:_uri]; -} -@end diff --git a/Classes/LinphoneUI/UIChatCreateConfirmCollectionViewCell.xib b/Classes/LinphoneUI/UIChatCreateConfirmCollectionViewCell.xib deleted file mode 100644 index a8007c9e7..000000000 --- a/Classes/LinphoneUI/UIChatCreateConfirmCollectionViewCell.xib +++ /dev/null @@ -1,48 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Classes/PhoneMainView.h b/Classes/PhoneMainView.h index 211803063..5b79887a0 100644 --- a/Classes/PhoneMainView.h +++ b/Classes/PhoneMainView.h @@ -31,7 +31,7 @@ #import "CallSideMenuView.h" #import "CallView.h" #import "ChatConversationCreateView.h" -#import "ChatConversationCreateConfirmView.h" +#import "ChatConversationInfoView.h" #import "ChatConversationView.h" #import "ChatsListView.h" #import "ContactDetailsView.h" diff --git a/Resources/images/chat_group_add.png b/Resources/images/chat_group_add.png new file mode 100644 index 0000000000000000000000000000000000000000..54a8954b971b1f20f4da884e97566732329494dd GIT binary patch literal 1837 zcmV+|2h#Y7P){qVm`V-=0!fTlyGB)HiDqyXLt_zL8!_w3oz;U;h5MFcc2FE6F5t7}DX zZ|@?E`Ar7H(E!~+UxSTR)z#H);p8p;fPjW}@J)=rjN(X3c_<@b&!PW*LPEmF+qP}H z9L`o)pjla26FIIO^xMN38w?-7zhgU}-EDHycLfT_1?=MI7>IQ>a&32x;II|Pr;znA zPi8I&_8{}PF#2bZc>=Ke`;+Sz=&V_@mZAJse~Qrmp>Oc{eC6@+@dr4*9+PZQQPIej zmX;aV%7Oy&b_bLPxR>hA6? z0ci`PKbdGx;#$t3s9OXftx`2C8uA4zOLh3$ze2am*btCvVO@D}; zJ*o1%>LNcse-s8vO(2om?DzYp4;7^N1H=(RW)gtDSN+Qz-?xEbhlGsE^Qnt5W5%pO zaJov9IR@8r9E*=1KW>aeOMc$GdA^jCln2I-A0J;=S9jK;o5uS3`pbodg9UkeV@^&^Jn{Dfya^%x79MV) zNmiv56ci-3x3?d{w+{9!c`(+>1NG=7!*!5nVq;_Hh65>%0VxS$ffUlS#Nxv;aciZe zrDq9)$B~glQd?qYXXk4cAqbQNO5=&2GKRn;GyoZQ#8 zMy$R{I0f(UAW#U8A<-8GB8}q7sHmt|$xxbvuJzu%ds}$eFLnDCHg9HT=FKpt>H^Wx(PcVqxYqzR`3!EN z7v^LD*#0G;)m2tj9vg08y8W1#nD3z3j-MU9gMYL;CCf+a3atC?FO^qZTpZQd*f_jidO zzvLx}9loI@N!Hu`Q$sdwaUwLp$A@_T+W-JbWW70jQwWWe9W_3Iu1%nqLyM@a(`{($ z!~8WL)@ZUJjuVz$mKb#aH3?T#R5WvyP3Gwqqm!aLfF`l4C)6Qq)vL0|^-|!&CR_1$6BgYDh}YAm)YQ}tm|2!UXq0+&L0Vc`7q7YdHD1I^ zDHjtH6W0M!!c7M$3G@{2{s&dVx=@hE5q`n0E>s1rIYuh!OXVYiMT=y__H=BoLT8dm zkC0i0?RRvZ5vY8nXl`zn5RmHM(EuuezJlrBli*2#kpW%6h5LNInrdpP zsZc@J5g$V9YdDZ1VL5~q^nM?zPhk)f9_9-Dc}`}NoBDv9v%8P7Lmy%&)y-I>JOKX8 z3B1HL_ER|B0Ra^wp%=U7m@a3h9W`S(M=BqHM*&y@z;9H#+kC)4EhF-Yg|8RS09L*r zXEM5e_O|o@cMjPq#vR1s_WokglGn$GfvN_q&)$T^1OUh`OHZO-rAtytqDg`saQl3Y bOxX4>_4D^V8u%D`00000NkvXXu0mjf=8kg_ literal 0 HcmV?d00001 diff --git a/Resources/images/chat_group_add@2x.png b/Resources/images/chat_group_add@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..7a3522e190458be4c74434585c4b91b3d9a673ab GIT binary patch literal 6581 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 Xz9c@ZTF@Tp2MeI5YXq;>v48bH5?@!y literal 0 HcmV?d00001 diff --git a/Resources/images/check_unselected.png b/Resources/images/check_unselected.png new file mode 100644 index 0000000000000000000000000000000000000000..3e8704632c858f1dcca9e66663a4bfccc6b2a15b GIT binary patch literal 1320 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