зеркало из https://github.com/nextcloud/talk-ios.git
Add 'audio-only' calls feature.
Signed-off-by: Ivan Sein <ivan@nextcloud.com>
This commit is contained in:
Родитель
86a3f38db0
Коммит
998313fb8d
|
@ -28,6 +28,6 @@
|
|||
@property (nonatomic, strong) IBOutlet UIImageView *waitingImageView;
|
||||
@property (nonatomic, strong) IBOutlet UILabel *waitingLabel;
|
||||
|
||||
- (instancetype)initCallInRoom:(NCRoom *)room asUser:(NSString*)displayName;
|
||||
- (instancetype)initCallInRoom:(NCRoom *)room asUser:(NSString*)displayName audioOnly:(BOOL)audioOnly;
|
||||
|
||||
@end
|
||||
|
|
|
@ -34,6 +34,7 @@ typedef NS_ENUM(NSInteger, CallState) {
|
|||
NCCallController *_callController;
|
||||
ARDCaptureController *_captureController;
|
||||
NSTimer *_detailedViewTimer;
|
||||
BOOL _isAudioOnly;
|
||||
BOOL _userDisabledVideo;
|
||||
}
|
||||
|
||||
|
@ -51,17 +52,18 @@ typedef NS_ENUM(NSInteger, CallState) {
|
|||
|
||||
@synthesize delegate = _delegate;
|
||||
|
||||
- (instancetype)initCallInRoom:(NCRoom *)room asUser:(NSString*)displayName
|
||||
- (instancetype)initCallInRoom:(NCRoom *)room asUser:(NSString*)displayName audioOnly:(BOOL)audioOnly
|
||||
{
|
||||
self = [super init];
|
||||
if (!self) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
_callController = [[NCCallController alloc] initWithDelegate:self];
|
||||
_callController = [[NCCallController alloc] initWithDelegate:self forAudioOnlyCall:audioOnly];
|
||||
_callController.room = room;
|
||||
_callController.userDisplayName = displayName;
|
||||
_room = room;
|
||||
_isAudioOnly = audioOnly;
|
||||
_peersInCall = [[NSMutableArray alloc] init];
|
||||
_renderersDict = [[NSMutableDictionary alloc] init];
|
||||
|
||||
|
@ -94,7 +96,7 @@ typedef NS_ENUM(NSInteger, CallState) {
|
|||
|
||||
[self setWaitingScreen];
|
||||
|
||||
if ([[[NCSettingsController sharedInstance] videoSettingsModel] videoDisabledSettingFromStore]) {
|
||||
if ([[[NCSettingsController sharedInstance] videoSettingsModel] videoDisabledSettingFromStore] || _isAudioOnly) {
|
||||
_userDisabledVideo = YES;
|
||||
[self disableLocalVideo];
|
||||
}
|
||||
|
@ -342,7 +344,7 @@ typedef NS_ENUM(NSInteger, CallState) {
|
|||
[cell setUserAvatar:[_callController getUserIdFromSessionId:peerConnection.peerId]];
|
||||
[cell setDisplayName:peerConnection.peerName];
|
||||
[cell setAudioDisabled:peerConnection.isRemoteAudioDisabled];
|
||||
[cell setVideoDisabled:peerConnection.isRemoteVideoDisabled];
|
||||
[cell setVideoDisabled: (_isAudioOnly) ? YES : peerConnection.isRemoteVideoDisabled];
|
||||
|
||||
return cell;
|
||||
}
|
||||
|
@ -430,9 +432,11 @@ typedef NS_ENUM(NSInteger, CallState) {
|
|||
[cell setAudioDisabled:peer.isRemoteAudioDisabled];
|
||||
}];
|
||||
} else if ([message isEqualToString:@"videoOn"] || [message isEqualToString:@"videoOff"]) {
|
||||
[self updatePeer:peer block:^(CallParticipantViewCell *cell) {
|
||||
[cell setVideoDisabled:peer.isRemoteVideoDisabled];
|
||||
}];
|
||||
if (!_isAudioOnly) {
|
||||
[self updatePeer:peer block:^(CallParticipantViewCell *cell) {
|
||||
[cell setVideoDisabled:peer.isRemoteVideoDisabled];
|
||||
}];
|
||||
}
|
||||
}
|
||||
}
|
||||
- (void)callController:(NCCallController *)callController didReceiveNick:(NSString *)nick fromPeer:(NCPeerConnection *)peer
|
||||
|
|
|
@ -8,6 +8,9 @@
|
|||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
extern NSString * const NCSelectedContactForVoiceCallNotification;
|
||||
extern NSString * const NCSelectedContactForVideoCallNotification;
|
||||
|
||||
@interface ContactsTableViewController : UITableViewController
|
||||
|
||||
@end
|
||||
|
|
|
@ -17,6 +17,9 @@
|
|||
#import "UIImageView+Letters.h"
|
||||
#import "UIImageView+AFNetworking.h"
|
||||
|
||||
NSString * const NCSelectedContactForVoiceCallNotification = @"NCSelectedContactForVoiceCallNotification";
|
||||
NSString * const NCSelectedContactForVideoCallNotification = @"NCSelectedContactForVideoCallNotification";
|
||||
|
||||
@interface ContactsTableViewController () <UISearchBarDelegate, UISearchControllerDelegate, UISearchResultsUpdating>
|
||||
{
|
||||
NSMutableArray *_contacts;
|
||||
|
@ -162,6 +165,62 @@
|
|||
}];
|
||||
}
|
||||
|
||||
- (void)presentJoinCallOptionsForContactAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
NCUser *contact = [_contacts objectAtIndex:indexPath.row];
|
||||
if (_searchController.active) {
|
||||
contact = [_resultTableViewController.filteredContacts objectAtIndex:indexPath.row];
|
||||
}
|
||||
|
||||
UIAlertController *optionsActionSheet =
|
||||
[UIAlertController alertControllerWithTitle:contact.name
|
||||
message:nil
|
||||
preferredStyle:UIAlertControllerStyleActionSheet];
|
||||
|
||||
[optionsActionSheet addAction:[UIAlertAction actionWithTitle:@"Call"
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^void (UIAlertAction *action) {
|
||||
[self createCallWithContact:contact audioOnly:YES];
|
||||
}]];
|
||||
|
||||
[optionsActionSheet addAction:[UIAlertAction actionWithTitle:@"Videocall"
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^void (UIAlertAction *action) {
|
||||
[self createCallWithContact:contact audioOnly:NO];
|
||||
}]];
|
||||
|
||||
[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];
|
||||
}
|
||||
|
||||
- (void)createCallWithContact:(NCUser *)contact audioOnly:(BOOL)audioOnly
|
||||
{
|
||||
[[NCAPIController sharedInstance] createRoomWith:contact.userId
|
||||
ofType:kNCRoomTypeOneToOneCall
|
||||
andName:nil
|
||||
withCompletionBlock:^(NSString *token, NSError *error) {
|
||||
if (!error) {
|
||||
NSLog(@"Room %@ with %@ created", token, contact.name);
|
||||
if (audioOnly) {
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:NCSelectedContactForVoiceCallNotification
|
||||
object:self
|
||||
userInfo:@{@"token":token}];
|
||||
} else {
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:NCSelectedContactForVideoCallNotification
|
||||
object:self
|
||||
userInfo:@{@"token":token}];
|
||||
}
|
||||
} else {
|
||||
NSLog(@"Failed creating a room with %@", contact.name);
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
#pragma mark - Search controller
|
||||
|
||||
- (void)updateSearchResultsForSearchController:(UISearchController *)searchController
|
||||
|
@ -213,25 +272,7 @@
|
|||
if ([NCConnectionController sharedInstance].connectionState == kConnectionStateDisconnected) {
|
||||
[[NCUserInterfaceController sharedInstance] presentOfflineWarningAlert];
|
||||
} else {
|
||||
NCUser *contact = [_contacts objectAtIndex:indexPath.row];
|
||||
if (_searchController.active) {
|
||||
contact = [_resultTableViewController.filteredContacts objectAtIndex:indexPath.row];
|
||||
}
|
||||
|
||||
[[NCAPIController sharedInstance] createRoomWith:contact.userId
|
||||
ofType:kNCRoomTypeOneToOneCall
|
||||
andName:nil
|
||||
withCompletionBlock:^(NSString *token, NSError *error) {
|
||||
if (!error) {
|
||||
// Join created room.
|
||||
NSLog(@"Room %@ with %@ created", token, contact.name);
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:NCRoomCreatedNotification
|
||||
object:self
|
||||
userInfo:@{@"token":token}];
|
||||
} else {
|
||||
NSLog(@"Failed creating a room with %@", contact.name);
|
||||
}
|
||||
}];
|
||||
[self presentJoinCallOptionsForContactAtIndexPath:indexPath];
|
||||
}
|
||||
|
||||
[tableView deselectRowAtIndexPath:indexPath animated:YES];
|
||||
|
|
|
@ -45,8 +45,6 @@ typedef void (^UnsubscribeToNextcloudServerCompletionBlock)(NSError *error);
|
|||
typedef void (^SubscribeToPushProxyCompletionBlock)(NSError *error);
|
||||
typedef void (^UnsubscribeToPushProxyCompletionBlock)(NSError *error);
|
||||
|
||||
extern NSString * const NCRoomCreatedNotification;
|
||||
|
||||
|
||||
@interface NCAPIController : NSObject
|
||||
|
||||
|
|
|
@ -15,8 +15,6 @@
|
|||
NSString * const kNCOCSAPIVersion = @"/ocs/v2.php";
|
||||
NSString * const kNCSpreedAPIVersion = @"/apps/spreed/api/v1";
|
||||
|
||||
NSString * const NCRoomCreatedNotification = @"NCRoomCreatedNotification";
|
||||
|
||||
@interface NCAPIController () <NSURLSessionTaskDelegate, NSURLSessionDelegate>
|
||||
{
|
||||
NSString *_serverUrl;
|
||||
|
|
|
@ -44,7 +44,7 @@ typedef void (^GetUserIdForSessionIdCompletionBlock)(NSString *userId, NSError *
|
|||
@property (nonatomic, strong) NSMutableArray *renderers;
|
||||
|
||||
|
||||
- (instancetype)initWithDelegate:(id<NCCallControllerDelegate>)delegate;
|
||||
- (instancetype)initWithDelegate:(id<NCCallControllerDelegate>)delegate forAudioOnlyCall:(BOOL)audioOnly;
|
||||
- (void)startCall;
|
||||
- (void)leaveCall;
|
||||
- (void)toggleCamera;
|
||||
|
|
|
@ -29,6 +29,7 @@ static NSString * const kNCVideoTrackKind = @"video";
|
|||
|
||||
@interface NCCallController () <NCPeerConnectionDelegate, NCSignalingControllerObserver>
|
||||
|
||||
@property (nonatomic, assign) BOOL isAudioOnly;
|
||||
@property (nonatomic, assign) BOOL leavingCall;
|
||||
@property (nonatomic, strong) NSTimer *pingTimer;
|
||||
@property (nonatomic, strong) AVAudioRecorder *recorder;
|
||||
|
@ -46,12 +47,13 @@ static NSString * const kNCVideoTrackKind = @"video";
|
|||
|
||||
@implementation NCCallController
|
||||
|
||||
- (instancetype)initWithDelegate:(id<NCCallControllerDelegate>)delegate
|
||||
- (instancetype)initWithDelegate:(id<NCCallControllerDelegate>)delegate forAudioOnlyCall:(BOOL)audioOnly
|
||||
{
|
||||
self = [super init];
|
||||
|
||||
if (self) {
|
||||
_delegate = delegate;
|
||||
_isAudioOnly = audioOnly;
|
||||
_peerConnectionFactory = [[RTCPeerConnectionFactory alloc] init];
|
||||
_connectionsDict = [[NSMutableDictionary alloc] init];
|
||||
_usersInRoom = [[NSArray alloc] init];
|
||||
|
@ -285,7 +287,9 @@ static NSString * const kNCVideoTrackKind = @"video";
|
|||
RTCMediaStream *localMediaStream = [_peerConnectionFactory mediaStreamWithStreamId:kNCMediaStreamId];
|
||||
self.localStream = localMediaStream;
|
||||
[self createLocalAudioTrack];
|
||||
[self createLocalVideoTrack];
|
||||
if (!_isAudioOnly) {
|
||||
[self createLocalVideoTrack];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Audio session configuration
|
||||
|
@ -334,7 +338,7 @@ static NSString * const kNCVideoTrackKind = @"video";
|
|||
NSLog(@"Creating a peer for %@", sessionId);
|
||||
|
||||
NSArray *iceServers = [_signalingController getIceServers];
|
||||
peerConnectionWrapper = [[NCPeerConnection alloc] initWithSessionId:sessionId andICEServers:iceServers];
|
||||
peerConnectionWrapper = [[NCPeerConnection alloc] initWithSessionId:sessionId andICEServers:iceServers forAudioOnlyCall:_isAudioOnly];
|
||||
peerConnectionWrapper.delegate = self;
|
||||
// TODO: Try to get display name here
|
||||
[peerConnectionWrapper.peerConnection addStream:_localStream];
|
||||
|
@ -542,7 +546,7 @@ static NSString * const kNCVideoTrackKind = @"video";
|
|||
}
|
||||
|
||||
// Send current video state
|
||||
if (self.isVideoEnabled) {
|
||||
if (self.isVideoEnabled && !_isAudioOnly) {
|
||||
NSLog(@"Send videoOn");
|
||||
[peerConnection sendDataChannelMessageOfType:@"videoOn" withPayload:nil];
|
||||
} else {
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
|
||||
@property (nonatomic, copy) NSString *peerId;
|
||||
@property (nonatomic, copy) NSString *peerName;
|
||||
@property (nonatomic, assign) BOOL isAudioOnly;
|
||||
@property (nonatomic, strong) RTCPeerConnection *peerConnection;
|
||||
@property (nonatomic, strong) RTCDataChannel *localDataChannel;
|
||||
@property (nonatomic, strong) RTCDataChannel *remoteDataChannel;
|
||||
|
@ -54,7 +55,7 @@
|
|||
@property (nonatomic, strong, readonly) NSMutableArray *queuedRemoteCandidates;
|
||||
@property (nonatomic, strong) RTCMediaStream *remoteStream;
|
||||
|
||||
- (instancetype)initWithSessionId:(NSString *)sessionId andICEServers:(NSArray *)iceServers;
|
||||
- (instancetype)initWithSessionId:(NSString *)sessionId andICEServers:(NSArray *)iceServers forAudioOnlyCall:(BOOL)audioOnly;
|
||||
- (void)addICECandidate:(RTCIceCandidate *)candidate;
|
||||
- (void)setRemoteDescription:(RTCSessionDescription *)sessionDescription;
|
||||
- (void)sendOffer;
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
|
||||
@implementation NCPeerConnection
|
||||
|
||||
- (instancetype)initWithSessionId:(NSString *)sessionId andICEServers:(NSArray *)iceServers
|
||||
- (instancetype)initWithSessionId:(NSString *)sessionId andICEServers:(NSArray *)iceServers forAudioOnlyCall:(BOOL)audioOnly
|
||||
{
|
||||
self = [super init];
|
||||
|
||||
|
@ -47,6 +47,7 @@
|
|||
|
||||
_peerConnection = peerConnection;
|
||||
_peerId = sessionId;
|
||||
_isAudioOnly = audioOnly;
|
||||
}
|
||||
|
||||
return self;
|
||||
|
@ -376,6 +377,13 @@
|
|||
@"OfferToReceiveVideo" : @"true"
|
||||
};
|
||||
|
||||
if (_isAudioOnly) {
|
||||
mandatoryConstraints = @{
|
||||
@"OfferToReceiveAudio" : @"true",
|
||||
@"OfferToReceiveVideo" : @"false"
|
||||
};
|
||||
}
|
||||
|
||||
NSDictionary *optionalConstraints = @{
|
||||
@"internalSctpDataChannels": @"true",
|
||||
@"DtlsSrtpKeyAgreement": @"true"
|
||||
|
|
|
@ -23,7 +23,8 @@ extern NSString * const kNCPNTypeCallKey;
|
|||
extern NSString * const kNCPNTypeRoomKey;
|
||||
extern NSString * const kNCPNTypeChatKey;
|
||||
|
||||
extern NSString * const NCPushNotificationJoinCallAcceptedNotification;
|
||||
extern NSString * const NCPushNotificationJoinAudioCallAcceptedNotification;
|
||||
extern NSString * const NCPushNotificationJoinVideoCallAcceptedNotification;
|
||||
|
||||
@interface NCPushNotification : NSObject
|
||||
|
||||
|
|
|
@ -19,7 +19,8 @@ NSString * const kNCPNTypeCallKey = @"call";
|
|||
NSString * const kNCPNTypeRoomKey = @"room";
|
||||
NSString * const kNCPNTypeChatKey = @"chat";
|
||||
|
||||
NSString * const NCPushNotificationJoinCallAcceptedNotification = @"NCPushNotificationJoinCallAcceptedNotification";
|
||||
NSString * const NCPushNotificationJoinAudioCallAcceptedNotification = @"NCPushNotificationJoinAudioCallAcceptedNotification";
|
||||
NSString * const NCPushNotificationJoinVideoCallAcceptedNotification = @"NCPushNotificationJoinVideoCallAcceptedNotification";
|
||||
|
||||
|
||||
+ (instancetype)pushNotificationFromDecryptedString:(NSString *)decryptedString
|
||||
|
|
|
@ -106,22 +106,33 @@
|
|||
message:@"Do you want to join this call?"
|
||||
preferredStyle:UIAlertControllerStyleAlert];
|
||||
|
||||
UIAlertAction *joinButton = [UIAlertAction
|
||||
actionWithTitle:@"Join call"
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * _Nonnull action) {
|
||||
NSDictionary *userInfo = [NSDictionary dictionaryWithObject:pushNotification forKey:@"pushNotification"];
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:NCPushNotificationJoinCallAcceptedNotification
|
||||
object:self
|
||||
userInfo:userInfo];
|
||||
}];
|
||||
UIAlertAction *joinAudioButton = [UIAlertAction
|
||||
actionWithTitle:@"Join call (audio only)"
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * _Nonnull action) {
|
||||
NSDictionary *userInfo = [NSDictionary dictionaryWithObject:pushNotification forKey:@"pushNotification"];
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:NCPushNotificationJoinAudioCallAcceptedNotification
|
||||
object:self
|
||||
userInfo:userInfo];
|
||||
}];
|
||||
|
||||
UIAlertAction *joinVideoButton = [UIAlertAction
|
||||
actionWithTitle:@"Join call with video"
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * _Nonnull action) {
|
||||
NSDictionary *userInfo = [NSDictionary dictionaryWithObject:pushNotification forKey:@"pushNotification"];
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:NCPushNotificationJoinVideoCallAcceptedNotification
|
||||
object:self
|
||||
userInfo:userInfo];
|
||||
}];
|
||||
|
||||
UIAlertAction* cancelButton = [UIAlertAction
|
||||
actionWithTitle:@"Cancel"
|
||||
style:UIAlertActionStyleCancel
|
||||
handler:nil];
|
||||
|
||||
[alert addAction:joinButton];
|
||||
[alert addAction:joinAudioButton];
|
||||
[alert addAction:joinVideoButton];
|
||||
[alert addAction:cancelButton];
|
||||
|
||||
// Do not show join call dialog until we don't handle 'hangup current call'/'join new one' properly.
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
#import "AFNetworking.h"
|
||||
#import "CallViewController.h"
|
||||
#import "ContactsTableViewController.h"
|
||||
#import "AddParticipantsTableViewController.h"
|
||||
#import "RoomTableViewCell.h"
|
||||
#import "CCCertificate.h"
|
||||
|
@ -58,10 +59,12 @@ typedef void (^FetchRoomsCompletionBlock)(BOOL success);
|
|||
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(joinCallAccepted:) name:NCPushNotificationJoinCallAcceptedNotification 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(roomHasBeenCreated:) name:NCRoomCreatedNotification 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
|
||||
|
@ -95,10 +98,16 @@ typedef void (^FetchRoomsCompletionBlock)(BOOL success);
|
|||
}
|
||||
}
|
||||
|
||||
- (void)joinCallAccepted:(NSNotification *)notification
|
||||
- (void)joinAudioCallAccepted:(NSNotification *)notification
|
||||
{
|
||||
NCPushNotification *pushNotification = [notification.userInfo objectForKey:@"pushNotification"];
|
||||
[self joinCallWithCallId:pushNotification.pnId];
|
||||
[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
|
||||
|
@ -113,10 +122,16 @@ typedef void (^FetchRoomsCompletionBlock)(BOOL success);
|
|||
[self adaptInterfaceForConnectionState:connectionState];
|
||||
}
|
||||
|
||||
- (void)roomHasBeenCreated:(NSNotification *)notification
|
||||
- (void)userSelectedContactForVoiceCall:(NSNotification *)notification
|
||||
{
|
||||
NSString *roomToken = [notification.userInfo objectForKey:@"token"];
|
||||
[self joinCallWithCallToken:roomToken];
|
||||
[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
|
||||
|
@ -477,6 +492,39 @@ typedef void (^FetchRoomsCompletionBlock)(BOOL success);
|
|||
}];
|
||||
}
|
||||
|
||||
- (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
|
||||
|
@ -550,37 +598,37 @@ typedef void (^FetchRoomsCompletionBlock)(BOOL success);
|
|||
return room;
|
||||
}
|
||||
|
||||
- (void)startCallInRoom:(NCRoom *)room
|
||||
- (void)startCallInRoom:(NCRoom *)room audioOnly:(BOOL)audioOnly
|
||||
{
|
||||
CallViewController *callVC = [[CallViewController alloc] initCallInRoom:room asUser:[[NCSettingsController sharedInstance] ncUserDisplayName]];
|
||||
CallViewController *callVC = [[CallViewController alloc] initCallInRoom:room asUser:[[NCSettingsController sharedInstance] ncUserDisplayName] audioOnly:audioOnly];
|
||||
[[NCUserInterfaceController sharedInstance] presentCallViewController:callVC];
|
||||
}
|
||||
|
||||
- (void)joinCallWithCallId:(NSInteger)callId
|
||||
- (void)joinCallWithCallId:(NSInteger)callId audioOnly:(BOOL)audioOnly
|
||||
{
|
||||
NCRoom *room = [self getRoomForId:callId];
|
||||
if (room) {
|
||||
[self startCallInRoom:room];
|
||||
[self startCallInRoom:room audioOnly:audioOnly];
|
||||
} else {
|
||||
//TODO: Show spinner?
|
||||
[[NCAPIController sharedInstance] getRoomWithId:callId withCompletionBlock:^(NCRoom *room, NSError *error) {
|
||||
if (!error) {
|
||||
[self startCallInRoom:room];
|
||||
[self startCallInRoom:room audioOnly:audioOnly];
|
||||
}
|
||||
}];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)joinCallWithCallToken:(NSString *)token
|
||||
- (void)joinCallWithCallToken:(NSString *)token audioOnly:(BOOL)audioOnly
|
||||
{
|
||||
NCRoom *room = [self getRoomForToken:token];
|
||||
if (room) {
|
||||
[self startCallInRoom:room];
|
||||
[self startCallInRoom:room audioOnly:audioOnly];
|
||||
} else {
|
||||
//TODO: Show spinner?
|
||||
[[NCAPIController sharedInstance] getRoomWithToken:token withCompletionBlock:^(NCRoom *room, NSError *error) {
|
||||
if (!error) {
|
||||
[self startCallInRoom:room];
|
||||
[self startCallInRoom:room audioOnly:audioOnly];
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
@ -783,8 +831,7 @@ typedef void (^FetchRoomsCompletionBlock)(BOOL success);
|
|||
if ([NCConnectionController sharedInstance].connectionState == kConnectionStateDisconnected) {
|
||||
[[NCUserInterfaceController sharedInstance] presentOfflineWarningAlert];
|
||||
} else {
|
||||
NCRoom *room = [_rooms objectAtIndex:indexPath.row];
|
||||
[self startCallInRoom:room];
|
||||
[self presentJoinCallOptionsForRoomAtIndexPath:indexPath];
|
||||
}
|
||||
[tableView deselectRowAtIndexPath:indexPath animated:YES];
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче