talk-ios/VideoCalls/RoomsTableViewController.m

841 строка
35 KiB
Objective-C

//
// RoomsTableViewController.m
// VideoCalls
//
// Created by Ivan Sein on 27.06.17.
// Copyright © 2017 struktur AG. All rights reserved.
//
#import "RoomsTableViewController.h"
#import "AFNetworking.h"
#import "CallViewController.h"
#import "ContactsTableViewController.h"
#import "AddParticipantsTableViewController.h"
#import "RoomTableViewCell.h"
#import "CCCertificate.h"
#import "NCAPIController.h"
#import "NCImageSessionManager.h"
#import "NCConnectionController.h"
#import "NCPushNotification.h"
#import "NCSettingsController.h"
#import "NCUserInterfaceController.h"
#import "NSDate+DateTools.h"
#import "UIImageView+Letters.h"
#import "AFImageDownloader.h"
#import "UIImageView+AFNetworking.h"
typedef void (^FetchRoomsCompletionBlock)(BOOL success);
@interface RoomsTableViewController () <CCCertificateDelegate>
{
NSMutableArray *_rooms;
UIRefreshControl *_refreshControl;
BOOL _allowEmptyGroupRooms;
}
@end
@implementation RoomsTableViewController
- (void)viewDidLoad
{
[super viewDidLoad];
_rooms = [[NSMutableArray alloc] init];
[self createRefreshControl];
AFImageDownloader *imageDownloader = [[AFImageDownloader alloc]
initWithSessionManager:[NCImageSessionManager sharedInstance]
downloadPrioritization:AFImageDownloadPrioritizationFIFO
maximumActiveDownloads:4
imageCache:[[AFAutoPurgingImageCache alloc] init]];
[UIImageView setSharedImageDownloader:imageDownloader];
self.navigationItem.titleView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"navigationLogo"]];
self.navigationController.navigationBar.barTintColor = [UIColor colorWithRed:0.00 green:0.51 blue:0.79 alpha:1.0]; //#0082C9
self.tabBarController.tabBar.tintColor = [UIColor colorWithRed:0.00 green:0.51 blue:0.79 alpha:1.0]; //#0082C9
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(serverCapabilitiesReceived:) name:NCServerCapabilitiesReceivedNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(joinAudioCallAccepted:) name:NCPushNotificationJoinAudioCallAcceptedNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(joinVideoCallAccepted:) name:NCPushNotificationJoinVideoCallAcceptedNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appStateHasChanged:) name:NCAppStateHasChangedNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(connectionStateHasChanged:) name:NCConnectionStateHasChangedNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(userSelectedContactForVoiceCall:) name:NCSelectedContactForVoiceCallNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(userSelectedContactForVideoCall:) name:NCSelectedContactForVideoCallNotification object:nil];
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
[self adaptInterfaceForAppState:[NCConnectionController sharedInstance].appState];
[self adaptInterfaceForConnectionState:[NCConnectionController sharedInstance].connectionState];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Notifications
- (void)serverCapabilitiesReceived:(NSNotification *)notification
{
NSDictionary *talkCapabilities = [NCSettingsController sharedInstance].ncTalkCapabilities;
if (talkCapabilities) {
NSArray *talkFeatures = [talkCapabilities objectForKey:@"features"];
if ([talkFeatures containsObject:@"empty-group-room"]) {
_allowEmptyGroupRooms = YES;
}
}
}
- (void)joinAudioCallAccepted:(NSNotification *)notification
{
NCPushNotification *pushNotification = [notification.userInfo objectForKey:@"pushNotification"];
[self joinCallWithCallId:pushNotification.pnId audioOnly:YES];
}
- (void)joinVideoCallAccepted:(NSNotification *)notification
{
NCPushNotification *pushNotification = [notification.userInfo objectForKey:@"pushNotification"];
[self joinCallWithCallId:pushNotification.pnId audioOnly:NO];
}
- (void)appStateHasChanged:(NSNotification *)notification
{
AppState appState = [[notification.userInfo objectForKey:@"appState"] intValue];
[self adaptInterfaceForAppState:appState];
}
- (void)connectionStateHasChanged:(NSNotification *)notification
{
ConnectionState connectionState = [[notification.userInfo objectForKey:@"connectionState"] intValue];
[self adaptInterfaceForConnectionState:connectionState];
}
- (void)userSelectedContactForVoiceCall:(NSNotification *)notification
{
NSString *roomToken = [notification.userInfo objectForKey:@"token"];
[self joinCallWithCallToken:roomToken audioOnly:YES];
}
- (void)userSelectedContactForVideoCall:(NSNotification *)notification
{
NSString *roomToken = [notification.userInfo objectForKey:@"token"];
[self joinCallWithCallToken:roomToken audioOnly:NO];
}
#pragma mark - Interface Builder Actions
- (IBAction)addButtonPressed:(id)sender
{
UIAlertController *optionsActionSheet =
[UIAlertController alertControllerWithTitle:nil
message:nil
preferredStyle:UIAlertControllerStyleActionSheet];
if (_allowEmptyGroupRooms) {
[optionsActionSheet addAction:[UIAlertAction actionWithTitle:@"New group call"
style:UIAlertActionStyleDefault
handler:^void (UIAlertAction *action) {
[self startRoomCreationFlowForPublicRoom:NO];
}]];
}
[optionsActionSheet addAction:[UIAlertAction actionWithTitle:@"New public call"
style:UIAlertActionStyleDefault
handler:^void (UIAlertAction *action) {
[self startRoomCreationFlowForPublicRoom:YES];
}]];
[optionsActionSheet addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:nil]];
// Presentation on iPads
UIPopoverPresentationController *popController = [optionsActionSheet popoverPresentationController];
popController.permittedArrowDirections = UIPopoverArrowDirectionAny;
popController.barButtonItem = self.navigationItem.rightBarButtonItem;
[self presentViewController:optionsActionSheet animated:YES completion:nil];
}
#pragma mark - Refresh Control
- (void)createRefreshControl
{
_refreshControl = [UIRefreshControl new];
_refreshControl.tintColor = [UIColor colorWithRed:0.00 green:0.51 blue:0.79 alpha:1.0]; //#0082C9
_refreshControl.backgroundColor = [UIColor colorWithRed:235.0/255.0 green:235.0/255.0 blue:235.0/255.0 alpha:1.0];
[_refreshControl addTarget:self action:@selector(refreshControlTarget) forControlEvents:UIControlEventValueChanged];
[self setRefreshControl:_refreshControl];
}
- (void)deleteRefreshControl
{
[_refreshControl endRefreshing];
self.refreshControl = nil;
}
- (void)refreshControlTarget
{
[self fetchRoomsWithCompletionBlock:nil];
// Actuate `Peek` feedback (weak boom)
AudioServicesPlaySystemSound(1519);
}
#pragma mark - User Interface
- (void)adaptInterfaceForAppState:(AppState)appState
{
switch (appState) {
case kAppStateReady:
{
[self fetchRoomsWithCompletionBlock:nil];
}
break;
default:
break;
}
}
- (void)adaptInterfaceForConnectionState:(ConnectionState)connectionState
{
switch (connectionState) {
case kConnectionStateConnected:
{
[self setOnlineAppearance];
}
break;
case kConnectionStateDisconnected:
{
[self setOfflineAppearance];
}
break;
default:
break;
}
}
- (void)setOfflineAppearance
{
self.addButton.enabled = NO;
self.navigationItem.titleView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"navigationLogoOffline"]];
}
- (void)setOnlineAppearance
{
self.addButton.enabled = YES;
self.navigationItem.titleView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"navigationLogo"]];
}
#pragma mark - Rooms
- (void)fetchRoomsWithCompletionBlock:(FetchRoomsCompletionBlock)block
{
[[NCAPIController sharedInstance] getRoomsWithCompletionBlock:^(NSMutableArray *rooms, NSError *error, NSInteger statusCode) {
if (!error) {
_rooms = rooms;
[self.tableView reloadData];
NSLog(@"Rooms updated");
if (block) {
block(YES);
}
} else {
NSLog(@"Error while trying to get rooms: %@", error);
if ([error code] == NSURLErrorServerCertificateUntrusted) {
NSLog(@"Untrusted certificate");
dispatch_async(dispatch_get_main_queue(), ^{
[[CCCertificate sharedManager] presentViewControllerCertificateWithTitle:[error localizedDescription] viewController:self delegate:self];
});
}
if (block) {
block(NO);
}
}
[_refreshControl endRefreshing];
}];
}
- (void)trustedCerticateAccepted
{
[self fetchRoomsWithCompletionBlock:nil];
}
#pragma mark - Room actions
- (void)addParticipantInRoomAtIndexPath:(NSIndexPath *)indexPath
{
NCRoom *room = [_rooms objectAtIndex:indexPath.row];
AddParticipantsTableViewController *addParticipantsVC = [[AddParticipantsTableViewController alloc] initForRoom:room];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:addParticipantsVC];
[self presentViewController:navigationController animated:YES completion:nil];
}
- (void)renameRoomAtIndexPath:(NSIndexPath *)indexPath
{
NCRoom *room = [_rooms objectAtIndex:indexPath.row];
UIAlertController *renameDialog =
[UIAlertController alertControllerWithTitle:@"Enter new name:"
message:nil
preferredStyle:UIAlertControllerStyleAlert];
[renameDialog addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
textField.placeholder = @"Name";
textField.text = room.displayName;
textField.autocapitalizationType = UITextAutocapitalizationTypeSentences;
textField.autocorrectionType = UITextAutocorrectionTypeDefault;
}];
UIAlertAction *confirmAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
NSString *newRoomName = [[renameDialog textFields][0] text];
NSString *trimmedName = [newRoomName stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
[[NCAPIController sharedInstance] renameRoom:room.token withName:trimmedName andCompletionBlock:^(NSError *error) {
if (!error) {
[self fetchRoomsWithCompletionBlock:nil];
} else {
NSLog(@"Error renaming the room: %@", error.description);
//TODO: Error handling
}
}];
}];
[renameDialog addAction:confirmAction];
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:nil];
[renameDialog addAction:cancelAction];
[self presentViewController:renameDialog animated:YES completion:nil];
}
- (void)shareLinkFromRoomAtIndexPath:(NSIndexPath *)indexPath
{
NCRoom *room = [_rooms objectAtIndex:indexPath.row];
NSString *shareMessage = [NSString stringWithFormat:@"Join the conversation at %@/index.php/call/%@",
[[NCAPIController sharedInstance] currentServerUrl], room.token];
if (room.name && ![room.name isEqualToString:@""]) {
shareMessage = [NSString stringWithFormat:@"Join the conversation%@ at %@/index.php/call/%@",
[NSString stringWithFormat:@" \"%@\"", room.name], [[NCAPIController sharedInstance] currentServerUrl], room.token];
}
NSArray *items = @[shareMessage];
UIActivityViewController *controller = [[UIActivityViewController alloc]initWithActivityItems:items applicationActivities:nil];
NSString *appDisplayName = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleDisplayName"];
NSString *emailSubject = [NSString stringWithFormat:@"%@ invitation", appDisplayName];
[controller setValue:emailSubject forKey:@"subject"];
// Presentation on iPads
controller.popoverPresentationController.sourceView = self.tableView;
controller.popoverPresentationController.sourceRect = [self.tableView rectForRowAtIndexPath:indexPath];
[self presentViewController:controller animated:YES completion:nil];
controller.completionWithItemsHandler = ^(NSString *activityType,
BOOL completed,
NSArray *returnedItems,
NSError *error) {
if (error) {
NSLog(@"An Error occured sharing room: %@, %@", error.localizedDescription, error.localizedFailureReason);
}
};
}
- (void)makePublicRoomAtIndexPath:(NSIndexPath *)indexPath
{
NCRoom *room = [_rooms objectAtIndex:indexPath.row];
[[NCAPIController sharedInstance] makeRoomPublic:room.token withCompletionBlock:^(NSError *error) {
if (!error) {
NSString *title = [NSString stringWithFormat:@"%@ is now public", room.name];
// Room type condition should be removed when we don't set room names by default on OneToOne calls.
if (room.type == kNCRoomTypeOneToOneCall || !room.name || [room.name isEqualToString:@""]) {
title = @"This call is now public";
}
[self showShareDialogForRoom:room withTitle:title];
[self fetchRoomsWithCompletionBlock:nil];
} else {
NSLog(@"Error making public the room: %@", error.description);
//TODO: Error handling
}
}];
}
- (void)makePrivateRoomAtIndexPath:(NSIndexPath *)indexPath
{
NCRoom *room = [_rooms objectAtIndex:indexPath.row];
[[NCAPIController sharedInstance] makeRoomPrivate:room.token withCompletionBlock:^(NSError *error) {
if (!error) {
[self fetchRoomsWithCompletionBlock:nil];
} else {
NSLog(@"Error making private the room: %@", error.description);
//TODO: Error handling
}
}];
}
- (void)setPasswordToRoomAtIndexPath:(NSIndexPath *)indexPath
{
NCRoom *room = [_rooms objectAtIndex:indexPath.row];
NSString *alertTitle = room.hasPassword ? @"Set new password:" : @"Set password:";
UIAlertController *renameDialog =
[UIAlertController alertControllerWithTitle:alertTitle
message:nil
preferredStyle:UIAlertControllerStyleAlert];
[renameDialog addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
textField.placeholder = @"Password";
textField.secureTextEntry = YES;
}];
NSString *actionTitle = room.hasPassword ? @"Change password" : @"OK";
UIAlertAction *confirmAction = [UIAlertAction actionWithTitle:actionTitle style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
NSString *password = [[renameDialog textFields][0] text];
NSString *trimmedPassword = [password stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
[[NCAPIController sharedInstance] setPassword:trimmedPassword toRoom:room.token withCompletionBlock:^(NSError *error) {
if (!error) {
[self fetchRoomsWithCompletionBlock:nil];
} else {
NSLog(@"Error setting room password: %@", error.description);
//TODO: Error handling
}
}];
}];
[renameDialog addAction:confirmAction];
if (room.hasPassword) {
UIAlertAction *removePasswordAction = [UIAlertAction actionWithTitle:@"Remove password" style:UIAlertActionStyleDestructive handler:^(UIAlertAction * _Nonnull action) {
[[NCAPIController sharedInstance] setPassword:@"" toRoom:room.token withCompletionBlock:^(NSError *error) {
if (!error) {
[self fetchRoomsWithCompletionBlock:nil];
} else {
NSLog(@"Error changing room password: %@", error.description);
//TODO: Error handling
}
}];
}];
[renameDialog addAction:removePasswordAction];
}
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:nil];
[renameDialog addAction:cancelAction];
[self presentViewController:renameDialog animated:YES completion:nil];
}
- (void)leaveRoomAtIndexPath:(NSIndexPath *)indexPath
{
NCRoom *room = [_rooms objectAtIndex:indexPath.row];
[[NCAPIController sharedInstance] removeSelfFromRoom:room.token withCompletionBlock:^(NSError *error) {
if (error) {
//TODO: Error handling
}
}];
[_rooms removeObjectAtIndex:indexPath.row];
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
- (void)deleteRoomAtIndexPath:(NSIndexPath *)indexPath
{
NCRoom *room = [_rooms objectAtIndex:indexPath.row];
[[NCAPIController sharedInstance] deleteRoom:room.token withCompletionBlock:^(NSError *error) {
if (error) {
//TODO: Error handling
}
}];
[_rooms removeObjectAtIndex:indexPath.row];
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
- (void)createNewRoomWithName:(NSString *)roomName public:(BOOL)public
{
[[NCAPIController sharedInstance] createRoomWith:nil
ofType:public ? kNCRoomTypePublicCall : kNCRoomTypeGroupCall
andName:roomName
withCompletionBlock:^(NSString *token, NSError *error) {
if (!error) {
[self fetchRoomsWithCompletionBlock:^(BOOL success) {
NCRoom *newRoom = [self getRoomForToken:token];
NSInteger roomIndex = [_rooms indexOfObject:newRoom];
if (roomIndex != NSNotFound) {
dispatch_async(dispatch_get_main_queue(), ^{
NSIndexPath *roomIndexPath = [NSIndexPath indexPathForRow:roomIndex inSection:0];
[self.tableView scrollToRowAtIndexPath:roomIndexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];
});
}
if (public) {
NSString *title = newRoom.name;
if (!title || [title isEqualToString:@""]) {
title = @"New public call";
}
[self showShareDialogForRoom:newRoom withTitle:title];
}
}];
} else {
NSLog(@"Error creating new group room: %@", error.description);
//TODO: Error handling
}
}];
}
- (void)presentJoinCallOptionsForRoomAtIndexPath:(NSIndexPath *)indexPath
{
NCRoom *room = [_rooms objectAtIndex:indexPath.row];
UIAlertController *optionsActionSheet =
[UIAlertController alertControllerWithTitle:room.displayName
message:nil
preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction *callAction = [UIAlertAction actionWithTitle:@"Call"
style:UIAlertActionStyleDefault
handler:^void (UIAlertAction *action) {
[self startCallInRoom:room audioOnly:YES];
}];
UIAlertAction *videocallAction = [UIAlertAction actionWithTitle:@"Videocall"
style:UIAlertActionStyleDefault
handler:^void (UIAlertAction *action) {
[self startCallInRoom:room audioOnly:NO];
}];
[optionsActionSheet addAction:callAction];
[optionsActionSheet addAction:videocallAction];
[optionsActionSheet addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:nil]];
// Presentation on iPads
optionsActionSheet.popoverPresentationController.sourceView = self.tableView;
optionsActionSheet.popoverPresentationController.sourceRect = [self.tableView rectForRowAtIndexPath:indexPath];
[self presentViewController:optionsActionSheet animated:YES completion:nil];
}
#pragma mark - Public Calls
- (void)startRoomCreationFlowForPublicRoom:(BOOL)public
{
NSString *alertTitle = public ? @"New public call" : @"New group call";
UIAlertController *setNameDialog = [UIAlertController alertControllerWithTitle:alertTitle
message:@"Set a name for this call"
preferredStyle:UIAlertControllerStyleAlert];
[setNameDialog addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
textField.placeholder = @"Name";
textField.autocapitalizationType = UITextAutocapitalizationTypeSentences;
textField.autocorrectionType = UITextAutocorrectionTypeDefault;
}];
UIAlertAction *confirmAction = [UIAlertAction actionWithTitle:@"Create" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
NSString *publicCallName = [[setNameDialog textFields][0] text];
NSString *trimmedName = [publicCallName stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
[self createNewRoomWithName:trimmedName public:public];
}];
[setNameDialog addAction:confirmAction];
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:nil];
[setNameDialog addAction:cancelAction];
[self presentViewController:setNameDialog animated:YES completion:nil];
}
- (void)showShareDialogForRoom:(NCRoom *)room withTitle:(NSString *)title
{
NSInteger roomIndex = [_rooms indexOfObject:room];
NSIndexPath *roomIndexPath = [NSIndexPath indexPathForRow:roomIndex inSection:0];
UIAlertController *shareRoomDialog =
[UIAlertController alertControllerWithTitle:title
message:@"Do you want to share this call with others?"
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *confirmAction = [UIAlertAction actionWithTitle:@"Yes" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
[self shareLinkFromRoomAtIndexPath:roomIndexPath];
}];
[shareRoomDialog addAction:confirmAction];
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"Not now" style:UIAlertActionStyleCancel handler:nil];
[shareRoomDialog addAction:cancelAction];
[self presentViewController:shareRoomDialog animated:YES completion:nil];
}
#pragma mark - Calls
- (NCRoom *)getRoomForToken:(NSString *)token
{
NCRoom *room = nil;
for (NCRoom *localRoom in _rooms) {
if (localRoom.token == token) {
room = localRoom;
}
}
return room;
}
- (NCRoom *)getRoomForId:(NSInteger)roomId
{
NCRoom *room = nil;
for (NCRoom *localRoom in _rooms) {
if (localRoom.roomId == roomId) {
room = localRoom;
}
}
return room;
}
- (void)startCallInRoom:(NCRoom *)room audioOnly:(BOOL)audioOnly
{
CallViewController *callVC = [[CallViewController alloc] initCallInRoom:room asUser:[[NCSettingsController sharedInstance] ncUserDisplayName] audioOnly:audioOnly];
[[NCUserInterfaceController sharedInstance] presentCallViewController:callVC];
}
- (void)joinCallWithCallId:(NSInteger)callId audioOnly:(BOOL)audioOnly
{
NCRoom *room = [self getRoomForId:callId];
if (room) {
[self startCallInRoom:room audioOnly:audioOnly];
} else {
//TODO: Show spinner?
[[NCAPIController sharedInstance] getRoomWithId:callId withCompletionBlock:^(NCRoom *room, NSError *error) {
if (!error) {
[self startCallInRoom:room audioOnly:audioOnly];
}
}];
}
}
- (void)joinCallWithCallToken:(NSString *)token audioOnly:(BOOL)audioOnly
{
NCRoom *room = [self getRoomForToken:token];
if (room) {
[self startCallInRoom:room audioOnly:audioOnly];
} else {
//TODO: Show spinner?
[[NCAPIController sharedInstance] getRoomWithToken:token withCompletionBlock:^(NCRoom *room, NSError *error) {
if (!error) {
[self startCallInRoom:room audioOnly:audioOnly];
}
}];
}
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return _rooms.count;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 60.0f;
}
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
return UITableViewCellEditingStyleDelete;
}
- (NSString *)tableView:(UITableView *)tableView titleForSwipeAccessoryButtonForRowAtIndexPath:(NSIndexPath *)indexPath
{
NCRoom *room = [_rooms objectAtIndex:indexPath.row];
if (room.canModerate || room.isPublic) {
NSString *moreButtonText = @"More";
return moreButtonText;
}
return nil;
}
- (void)tableView:(UITableView *)tableView swipeAccessoryButtonPushedForRowAtIndexPath:(NSIndexPath *)indexPath
{
NCRoom *room = [_rooms objectAtIndex:indexPath.row];
UIAlertController *optionsActionSheet =
[UIAlertController alertControllerWithTitle:room.displayName
message:nil
preferredStyle:UIAlertControllerStyleActionSheet];
// Share link of public calls even if you are not a moderator
if (!room.canModerate && room.isPublic) {
// Share Link
[optionsActionSheet addAction:[UIAlertAction actionWithTitle:@"Share link"
style:UIAlertActionStyleDefault
handler:^void (UIAlertAction *action) {
[self shareLinkFromRoomAtIndexPath:indexPath];
}]];
// Moderator options
} else {
// Add participant
[optionsActionSheet addAction:[UIAlertAction actionWithTitle:@"Add participant"
style:UIAlertActionStyleDefault
handler:^void (UIAlertAction *action) {
[self addParticipantInRoomAtIndexPath:indexPath];
}]];
// Rename
if (room.isNameEditable) {
[optionsActionSheet addAction:[UIAlertAction actionWithTitle:@"Rename"
style:UIAlertActionStyleDefault
handler:^void (UIAlertAction *action) {
[self renameRoomAtIndexPath:indexPath];
}]];
}
// Public/Private room options
if (room.isPublic) {
// Set Password
NSString *passwordOptionTitle = @"Set password";
if (room.hasPassword) {
passwordOptionTitle = @"Change password";
}
[optionsActionSheet addAction:[UIAlertAction actionWithTitle:passwordOptionTitle
style:UIAlertActionStyleDefault
handler:^void (UIAlertAction *action) {
[self setPasswordToRoomAtIndexPath:indexPath];
}]];
// Share Link
[optionsActionSheet addAction:[UIAlertAction actionWithTitle:@"Share link"
style:UIAlertActionStyleDefault
handler:^void (UIAlertAction *action) {
[self shareLinkFromRoomAtIndexPath:indexPath];
}]];
// Make call private
[optionsActionSheet addAction:[UIAlertAction actionWithTitle:@"Make call private"
style:UIAlertActionStyleDefault
handler:^void (UIAlertAction *action) {
[self makePrivateRoomAtIndexPath:indexPath];
}]];
} else {
// Make call public
[optionsActionSheet addAction:[UIAlertAction actionWithTitle:@"Make call public"
style:UIAlertActionStyleDefault
handler:^void (UIAlertAction *action) {
[self makePublicRoomAtIndexPath:indexPath];
}]];
}
// Delete room
if (room.isDeletable) {
[optionsActionSheet addAction:[UIAlertAction actionWithTitle:@"Delete call"
style:UIAlertActionStyleDestructive
handler:^void (UIAlertAction *action) {
[self deleteRoomAtIndexPath:indexPath];
}]];
}
}
[optionsActionSheet addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:nil]];
// Presentation on iPads
optionsActionSheet.popoverPresentationController.sourceView = tableView;
optionsActionSheet.popoverPresentationController.sourceRect = [tableView rectForRowAtIndexPath:indexPath];
[self presentViewController:optionsActionSheet animated:YES completion:nil];
}
- (NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *deleteButtonText = @"Leave";
return deleteButtonText;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
[self leaveRoomAtIndexPath:indexPath];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NCRoom *room = [_rooms objectAtIndex:indexPath.row];
RoomTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kRoomCellIdentifier];
if (!cell) {
cell = [[RoomTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kRoomCellIdentifier];
}
// Set room name
cell.labelTitle.text = room.displayName;
// Set last ping
NSDate *date = [[NSDate alloc] initWithTimeIntervalSince1970:room.lastPing];
cell.labelSubTitle.text = [date timeAgoSinceNow];
if (room.lastPing == 0) {
cell.labelSubTitle.text = @"Never joined";
}
// Set room image
switch (room.type) {
case kNCRoomTypeOneToOneCall:
{
// Create avatar for every OneToOne call
[cell.roomImage setImageWithString:room.displayName color:nil circular:true];
// Request user avatar to the server and set it if exist
[cell.roomImage setImageWithURLRequest:[[NCAPIController sharedInstance] createAvatarRequestForUser:room.name andSize:96]
placeholderImage:nil success:nil failure:nil];
}
break;
case kNCRoomTypeGroupCall:
[cell.roomImage setImage:[UIImage imageNamed:@"group-white"]];
cell.roomImage.backgroundColor = [UIColor colorWithRed:0.84 green:0.84 blue:0.84 alpha:1.0]; /*#d5d5d5*/
cell.roomImage.contentMode = UIViewContentModeCenter;
break;
case kNCRoomTypePublicCall:
[cell.roomImage setImage:[UIImage imageNamed:@"public-white"]];
cell.roomImage.backgroundColor = [UIColor colorWithRed:0.84 green:0.84 blue:0.84 alpha:1.0]; /*#d5d5d5*/
cell.roomImage.contentMode = UIViewContentModeCenter;
if (room.hasPassword) {
[cell.roomPasswordImage setImage:[UIImage imageNamed:@"password"]];
}
break;
default:
break;
}
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if ([NCConnectionController sharedInstance].connectionState == kConnectionStateDisconnected) {
[[NCUserInterfaceController sharedInstance] presentOfflineWarningAlert];
} else {
[self presentJoinCallOptionsForRoomAtIndexPath:indexPath];
}
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
@end