talk-ios/NextcloudTalk/RoomCreation2TableViewContr...

425 строки
17 KiB
Objective-C

/**
* @copyright Copyright (c) 2020 Ivan Sein <ivan@nextcloud.com>
*
* @author Ivan Sein <ivan@nextcloud.com>
*
* @license GNU GPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#import "RoomCreation2TableViewController.h"
#import "UIImageView+AFNetworking.h"
#import "ContactsTableViewCell.h"
#import "NCAPIController.h"
#import "NCAppBranding.h"
#import "NCDatabaseManager.h"
#import "NCUser.h"
#import "RoomNameTableViewCell.h"
typedef enum CreationSection {
kCreationSectionName = 0,
kCreationSectionParticipantsOrPassword,
kCreationSectionNumber
} CreationSection;
NSString * const NCRoomCreatedNotification = @"NCRoomCreatedNotification";
@interface RoomCreation2TableViewController () <UITextFieldDelegate>
@property (nonatomic, assign) BOOL publicRoom;
@property (nonatomic, strong) NSMutableArray *participants;
@property (nonatomic, strong) NSString *roomName;
@property (nonatomic, strong) UITextField *roomNameTextField;
@property (nonatomic, strong) UITextField *passwordTextField;
@property (nonatomic, strong) UIBarButtonItem *createRoomButton;
@property (nonatomic, strong) UIActivityIndicatorView *creatingRoomView;
@property (nonatomic, assign) NSInteger participantsToBeAdded;
@property (nonatomic, strong) NSString *passwordToBeSet;
@property (nonatomic, strong) NSString *createdRoomToken;
@property (nonatomic, assign) BOOL didFocusRoomNameOnce;
@end
@implementation RoomCreation2TableViewController
- (instancetype)initForGroupRoomWithParticipants:(NSMutableArray *)participants
{
self = [super init];
if (self) {
_publicRoom = NO;
_participants = participants;
}
return self;
}
- (instancetype)initForPublicRoom
{
self = [super init];
if (self) {
_publicRoom = YES;
_participants = [[NSMutableArray alloc] init];
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.navigationItem.title = (_publicRoom) ? NSLocalizedString(@"New public conversation", nil) : NSLocalizedString(@"New group conversation", nil);
[self.navigationController.navigationBar setTitleTextAttributes:
@{NSForegroundColorAttributeName:[NCAppBranding themeTextColor]}];
self.navigationController.navigationBar.tintColor = [NCAppBranding themeTextColor];
self.navigationController.navigationBar.translucent = NO;
self.navigationController.navigationBar.barTintColor = [NCAppBranding themeColor];
UIColor *themeColor = [NCAppBranding themeColor];
UINavigationBarAppearance *appearance = [[UINavigationBarAppearance alloc] init];
[appearance configureWithOpaqueBackground];
appearance.backgroundColor = themeColor;
appearance.titleTextAttributes = @{NSForegroundColorAttributeName:[NCAppBranding themeTextColor]};
self.navigationItem.standardAppearance = appearance;
self.navigationItem.compactAppearance = appearance;
self.navigationItem.scrollEdgeAppearance = appearance;
_passwordTextField = [[UITextField alloc] initWithFrame:CGRectMake(180, 10, 115, 30)];
_passwordTextField.textAlignment = NSTextAlignmentRight;
_passwordTextField.placeholder = NSLocalizedString(@"No password", nil);
_passwordTextField.adjustsFontSizeToFitWidth = YES;
_passwordTextField.secureTextEntry = YES;
_passwordTextField.accessibilityLabel = NSLocalizedString(@"Password field for public conversation", nil);
_creatingRoomView = [[UIActivityIndicatorView alloc] init];
_creatingRoomView.color = [NCAppBranding themeTextColor];
_createRoomButton = [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(@"Create", nil) style:UIBarButtonItemStyleDone
target:self action:@selector(createButtonPressed)];
_createRoomButton.enabled = NO;
_createRoomButton.accessibilityHint = NSLocalizedString(@"Double tap to create the conversation", nil);
self.navigationItem.rightBarButtonItem = _createRoomButton;
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissKeyboard)];
[self.view addGestureRecognizer:tap];
[self.tableView registerNib:[UINib nibWithNibName:kContactsTableCellNibName bundle:nil] forCellReuseIdentifier:kContactCellIdentifier];
[self.tableView registerNib:[UINib nibWithNibName:kRoomNameTableCellNibName bundle:nil] forCellReuseIdentifier:kRoomNameCellIdentifier];
}
- (void)createButtonPressed
{
[self startRoomCreation];
}
- (void)dismissKeyboard
{
[_roomNameTextField resignFirstResponder];
[_passwordTextField resignFirstResponder];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Room creation
- (void)startRoomCreation
{
[self disableInteraction];
[_creatingRoomView startAnimating];
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:_creatingRoomView];
self.navigationController.navigationBar.userInteractionEnabled = NO;
NSString *roomName = [_roomNameTextField.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
NSString *password = [_passwordTextField.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
if (![password isEqualToString:@""] && _publicRoom) {
_passwordToBeSet = password;
}
_participantsToBeAdded = _participants.count;
[self createGroupRoomWithName:roomName public:_publicRoom];
}
- (void)createGroupRoomWithName:(NSString *)roomName public:(BOOL)public
{
[[NCAPIController sharedInstance] createRoomForAccount:[[NCDatabaseManager sharedInstance] activeAccount] with:nil
ofType:public ? kNCRoomTypePublic : kNCRoomTypeGroup
andName:roomName
withCompletionBlock:^(NSString *token, NSError *error) {
if (!error) {
self->_createdRoomToken = token;
[self checkRoomCreationCompletion];
} else {
NSLog(@"Error creating new room: %@", error.description);
[self cancelRoomCreation];
}
}];
}
- (void)addParticipants
{
for (NCUser *participant in _participants) {
[self addParticipant:participant];
}
}
- (void)addParticipant:(NCUser *)participant
{
[[NCAPIController sharedInstance] addParticipant:participant.userId ofType:participant.source toRoom:_createdRoomToken forAccount:[[NCDatabaseManager sharedInstance] activeAccount] withCompletionBlock:^(NSError *error) {
if (!error) {
[self participantHasBeenAdded];
} else {
NSLog(@"Error creating new room: %@", error.description);
[self cancelRoomCreation];
}
}];
}
- (void)participantHasBeenAdded
{
_participantsToBeAdded --;
if (_participantsToBeAdded == 0) {
[self checkRoomCreationCompletion];
}
}
- (void)setPassword
{
[[NCAPIController sharedInstance] setPassword:_passwordToBeSet toRoom:_createdRoomToken forAccount:[[NCDatabaseManager sharedInstance] activeAccount] withCompletionBlock:^(NSError *error, NSString *errorDescription) {
if (!error) {
self->_passwordToBeSet = nil;
[self checkRoomCreationCompletion];
} else {
NSLog(@"Error setting room password: %@", error.description);
[self cancelRoomCreationWithMessage:errorDescription];
}
}];
}
- (void)checkRoomCreationCompletion
{
if (_participantsToBeAdded > 0) {
[self addParticipants];
} else if (_passwordToBeSet) {
[self setPassword];
} else {
[self finishRoomCreation];
}
}
- (void)finishRoomCreation
{
[self.navigationController dismissViewControllerAnimated:YES completion:^{
[[NSNotificationCenter defaultCenter] postNotificationName:NCRoomCreatedNotification
object:self
userInfo:@{@"token":self->_createdRoomToken}];
}];
}
- (void)cancelRoomCreation
{
[self cancelRoomCreationWithMessage:nil];
}
- (void)cancelRoomCreationWithMessage:(NSString *)message
{
[self enableInteraction];
[_creatingRoomView stopAnimating];
self.navigationItem.rightBarButtonItem = _createRoomButton;
if (message == nil) {
message = NSLocalizedString(@"An error occurred while creating the conversation", nil);
}
UIAlertController * alert = [UIAlertController
alertControllerWithTitle:NSLocalizedString(@"Could not create conversation", nil)
message:message
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* okButton = [UIAlertAction
actionWithTitle:NSLocalizedString(@"OK", nil)
style:UIAlertActionStyleDefault
handler:nil];
[alert addAction:okButton];
[self.navigationController presentViewController:alert animated:YES completion:nil];
}
- (void)enableInteraction
{
self.navigationController.navigationBar.userInteractionEnabled = YES;
_roomNameTextField.enabled = YES;
_passwordTextField.enabled = YES;
}
- (void)disableInteraction
{
self.navigationController.navigationBar.userInteractionEnabled = NO;
_roomNameTextField.enabled = NO;
_passwordTextField.enabled = NO;
}
#pragma mark - UITextField delegate
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
if (textField == _roomNameTextField) {
// Prevent crashing undo bug
// https://stackoverflow.com/questions/433337/set-the-maximum-character-length-of-a-uitextfield
if (range.length + range.location > textField.text.length) {
return NO;
}
// Set maximum character length
NSUInteger newLength = [textField.text length] + [string length] - range.length;
BOOL hasAllowedLength = newLength <= 200;
// Enable/Disable create button
if (hasAllowedLength) {
NSString *roomName = [[textField.text stringByReplacingCharactersInRange:range withString:string] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
_createRoomButton.enabled = roomName.length > 0;
}
return hasAllowedLength;
}
return YES;
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return kCreationSectionNumber;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (section == kCreationSectionParticipantsOrPassword && !_publicRoom) {
return _participants.count;
}
return 1;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.section == kCreationSectionName) {
return 80.0f;
} else if (indexPath.section == kCreationSectionParticipantsOrPassword && !_publicRoom) {
return kContactsTableCellHeight;
}
return 48;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
if (section == kCreationSectionParticipantsOrPassword && !_publicRoom && _participants.count > 0) {
return [NSString localizedStringWithFormat:NSLocalizedString(@"%ld participants", nil), _participants.count];
}
return nil;
}
- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section
{
if (section == kCreationSectionName) {
return NSLocalizedString(@"Please, set a name for this conversation.", nil);
} else if (section == kCreationSectionParticipantsOrPassword && _publicRoom ) {
return NSLocalizedString(@"Anyone who knows the link to this conversation will be able to access it. You can protect it by setting a password.", nil);
}
return nil;
}
- (void)tableView:(UITableView *)tableView willDisplayCell:(nonnull UITableViewCell *)cell forRowAtIndexPath:(nonnull NSIndexPath *)indexPath
{
BOOL isRoomNameCell = indexPath.row == 0 && indexPath.section == kCreationSectionName;
if (isRoomNameCell && !_didFocusRoomNameOnce) {
RoomNameTableViewCell *roomNameCell = (RoomNameTableViewCell *)cell;
[roomNameCell.roomNameTextField becomeFirstResponder];
_didFocusRoomNameOnce = YES;
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = nil;
static NSString *publicCellIdentifier = @"PublicConversationCellIdentifier";
switch (indexPath.section) {
case kCreationSectionName:
{
RoomNameTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kRoomNameCellIdentifier];
if (!cell) {
cell = [[RoomNameTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kRoomNameCellIdentifier];
}
if (_publicRoom) {
[cell.roomImage setImage:[UIImage imageNamed:@"public"]];
} else {
[cell.roomImage setImage:[UIImage imageNamed:@"group"]];
}
cell.roomNameTextField.text = _roomName;
_roomNameTextField = cell.roomNameTextField;
_roomNameTextField.delegate = self;
[_roomNameTextField setReturnKeyType:UIReturnKeyDone];
cell.userInteractionEnabled = YES;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
}
break;
case kCreationSectionParticipantsOrPassword:
{
if (_publicRoom) {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:publicCellIdentifier];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:publicCellIdentifier];
}
cell.textLabel.text = NSLocalizedString(@"Password", nil);
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.accessoryView = _passwordTextField;
[cell.imageView setImage:[UIImage imageNamed:@"password-settings"]];
return cell;
} else {
NCUser *participant = [_participants objectAtIndex:indexPath.row];
ContactsTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kContactCellIdentifier forIndexPath:indexPath];
if (!cell) {
cell = [[ContactsTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kContactCellIdentifier];
}
cell.labelTitle.text = participant.name;
if ([participant.source isEqualToString:kParticipantTypeUser]) {
[cell.contactImage setImageWithURLRequest:[[NCAPIController sharedInstance] createAvatarRequestForUser:participant.userId withStyle:self.traitCollection.userInterfaceStyle andSize:96 usingAccount:[[NCDatabaseManager sharedInstance] activeAccount]]
placeholderImage:nil success:nil failure:nil];
[cell.contactImage setContentMode:UIViewContentModeScaleToFill];
} else if ([participant.source isEqualToString:kParticipantTypeEmail]) {
[cell.contactImage setImage:[UIImage imageNamed:@"mail"]];
} else {
[cell.contactImage setImage:[UIImage imageNamed:@"group"]];
}
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.layoutMargins = UIEdgeInsetsMake(0, 72, 0, 0);
return cell;
}
}
break;
}
return cell;
}
@end