From 4ab45b7aca64c364e825e3369ce611fe187d7616 Mon Sep 17 00:00:00 2001 From: Gautier Pelloux-Prayer Date: Wed, 14 Oct 2015 16:40:37 +0200 Subject: [PATCH] Conference: add view --- Classes/Base.lproj/CallView.xib | 87 ++++++++++---- Classes/CallConferenceTableView.h | 16 +++ Classes/CallConferenceTableView.m | 100 ++++++++++++++++ Classes/CallIncomingView.m | 12 +- Classes/CallOutgoingView.m | 2 +- Classes/CallPausedTableView.m | 24 ++-- Classes/CallView.h | 5 +- Classes/CallView.m | 107 ++++++++---------- Classes/ChatConversationView.m | 2 +- Classes/HistoryDetailsView.m | 4 +- Classes/LinphoneCoreSettingsStore.m | 8 +- Classes/LinphoneManager.m | 12 +- .../Base.lproj/UICallConferenceCell.xib | 103 +++++++++++++++++ Classes/LinphoneUI/UICallConferenceCell.h | 22 ++++ Classes/LinphoneUI/UICallConferenceCell.m | 49 ++++++++ Classes/LinphoneUI/UICallPausedCell.m | 3 +- Classes/LinphoneUI/UIChatCell.m | 3 +- Classes/LinphoneUI/UIHistoryCell.m | 2 +- Classes/Utils/FastAddressBook.h | 2 +- Classes/Utils/FastAddressBook.m | 4 +- Classes/Utils/Utils.m | 6 +- Settings/InAppSettings.bundle/Root.plist | 10 ++ linphone.xcodeproj/project.pbxproj | 42 +++++-- 23 files changed, 500 insertions(+), 125 deletions(-) create mode 100644 Classes/CallConferenceTableView.h create mode 100644 Classes/CallConferenceTableView.m create mode 100644 Classes/LinphoneUI/Base.lproj/UICallConferenceCell.xib create mode 100644 Classes/LinphoneUI/UICallConferenceCell.h create mode 100644 Classes/LinphoneUI/UICallConferenceCell.m diff --git a/Classes/Base.lproj/CallView.xib b/Classes/Base.lproj/CallView.xib index 90df395d4..4d2faa4f1 100644 --- a/Classes/Base.lproj/CallView.xib +++ b/Classes/Base.lproj/CallView.xib @@ -9,6 +9,9 @@ + + + @@ -28,7 +31,7 @@ - + @@ -59,6 +62,13 @@ + + + + + + + @@ -67,7 +77,42 @@ - + + + + + + + + + + + + + + + + + + + + - + @@ -166,27 +211,27 @@ - + diff --git a/Classes/CallConferenceTableView.h b/Classes/CallConferenceTableView.h new file mode 100644 index 000000000..d7d8b201f --- /dev/null +++ b/Classes/CallConferenceTableView.h @@ -0,0 +1,16 @@ +// +// CallConferenceTableView.h +// linphone +// +// Created by Gautier Pelloux-Prayer on 14/10/15. +// +// + +#import + +@interface CallConferenceTableView : UITableViewController { + @private + NSTimer *updateTime; +} + +@end diff --git a/Classes/CallConferenceTableView.m b/Classes/CallConferenceTableView.m new file mode 100644 index 000000000..134d08278 --- /dev/null +++ b/Classes/CallConferenceTableView.m @@ -0,0 +1,100 @@ +/* InCallTableViewController.h + * + * Copyright (C) 2012 Belledonne Comunications, Grenoble, France + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#import "CallConferenceTableView.h" +#import "UICallConferenceCell.h" +#import "UIConferenceHeader.h" +#import "LinphoneManager.h" +#import "Utils.h" + +@implementation CallConferenceTableView + +#pragma mark - ViewController Functions + +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; + updateTime = + [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(update) userInfo:nil repeats:YES]; +} + +- (void)viewWillDisappear:(BOOL)animated { + [super viewWillDisappear:animated]; + if (updateTime != nil) { + [updateTime invalidate]; + updateTime = nil; + } +} + +#pragma mark - UI change + +- (void)update { + [self.tableView reloadData]; +} + +#pragma mark - UITableViewDataSource Functions +- (LinphoneCall *)conferenceCallForRow:(NSInteger)row { + const MSList *calls = linphone_core_get_calls([LinphoneManager getLc]); + int i = -1; + while (calls) { + if (linphone_call_is_in_conference(calls->data)) { + i++; + if (i == row) + break; + } + calls = calls->next; + } + return (calls ? calls->data : NULL); +} + +#pragma mark - UITableViewDataSource Functions + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { + NSString *kCellId = NSStringFromClass(UICallConferenceCell.class); + UICallConferenceCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellId]; + if (cell == nil) { + cell = [[UICallConferenceCell alloc] initWithIdentifier:kCellId]; + } + [cell setCall:[self conferenceCallForRow:indexPath.row]]; + return cell; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { + const MSList *calls = linphone_core_get_calls([LinphoneManager getLc]); + int count = 0; + while (calls) { + if (linphone_call_is_in_conference(calls->data)) { + count++; + } + calls = calls->next; + } + return count; +} + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { + return 1; +} + +- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section { + return 1e-5; +} +- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { + return 1e-5; +} + +@end diff --git a/Classes/CallIncomingView.m b/Classes/CallIncomingView.m index a4ba4856a..4bc0a1c76 100644 --- a/Classes/CallIncomingView.m +++ b/Classes/CallIncomingView.m @@ -76,15 +76,20 @@ static UICompositeViewDescription *compositeDescription = nil; [self callUpdate:acall state:astate]; } -#pragma mark - - - (void)callUpdate:(LinphoneCall *)acall state:(LinphoneCallState)astate { if (call == acall && (astate == LinphoneCallEnd || astate == LinphoneCallError)) { [delegate incomingCallAborted:call]; [self dismiss]; + } else if ([LinphoneManager.instance lpConfigBoolForKey:@"auto_answer"]) { + LinphoneCallState state = linphone_call_get_state(call); + if (state == LinphoneCallIncomingReceived || state == LinphoneCallIncomingEarlyMedia) { + [self onAcceptClick:nil]; + } } } +#pragma mark - + - (void)dismiss { if ([[PhoneMainView.instance currentView] equal:CallIncomingView.compositeViewDescription]) { [PhoneMainView.instance popCurrentView]; @@ -99,8 +104,7 @@ static UICompositeViewDescription *compositeDescription = nil; char *uri = linphone_address_as_string_uri_only(addr); addressLabel.text = [NSString stringWithUTF8String:uri]; ms_free(uri); - avatarImage.image = - [FastAddressBook getContactImage:[FastAddressBook getContactWithLinphoneAddress:addr] thumbnail:NO]; + avatarImage.image = [FastAddressBook getContactImage:[FastAddressBook getContactWithAddress:addr] thumbnail:NO]; } #pragma mark - Property Functions diff --git a/Classes/CallOutgoingView.m b/Classes/CallOutgoingView.m index 6493cd859..1eb3272ab 100644 --- a/Classes/CallOutgoingView.m +++ b/Classes/CallOutgoingView.m @@ -56,7 +56,7 @@ static UICompositeViewDescription *compositeDescription = nil; _addressLabel.text = [NSString stringWithUTF8String:uri]; ms_free(uri); _avatarImage.image = - [FastAddressBook getContactImage:[FastAddressBook getContactWithLinphoneAddress:addr] thumbnail:NO]; + [FastAddressBook getContactImage:[FastAddressBook getContactWithAddress:addr] thumbnail:NO]; } } diff --git a/Classes/CallPausedTableView.m b/Classes/CallPausedTableView.m index 7a402f71b..e8e48a3a8 100644 --- a/Classes/CallPausedTableView.m +++ b/Classes/CallPausedTableView.m @@ -54,13 +54,14 @@ } #pragma mark - UITableViewDataSource Functions -- (LinphoneCall *)pausedCallForRow:(NSInteger)row { +- (LinphoneCall *)conferenceCallForRow:(NSInteger)row { const MSList *calls = linphone_core_get_calls([LinphoneManager getLc]); - LinphoneCall *currentCall = linphone_core_get_current_call([LinphoneManager getLc]); - int i = 0; - while (calls && i < row) { - if (calls->data != currentCall) { + int i = -1; + while (calls) { + if (linphone_call_get_state(calls->data) == LinphoneCallPaused) { i++; + if (i == row) + break; } calls = calls->next; } @@ -75,13 +76,20 @@ if (cell == nil) { cell = [[UICallPausedCell alloc] initWithIdentifier:kCellId]; } - [cell setCall:[self pausedCallForRow:indexPath.row]]; + [cell setCall:[self conferenceCallForRow:indexPath.row]]; return cell; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { - return ms_list_size(linphone_core_get_calls([LinphoneManager getLc])) - - (linphone_core_get_current_call([LinphoneManager getLc]) ? 1 : 0); + const MSList *calls = linphone_core_get_calls([LinphoneManager getLc]); + int count = 0; + while (calls) { + if (linphone_call_get_state(calls->data) == LinphoneCallPaused) { + count++; + } + calls = calls->next; + } + return count; } - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { diff --git a/Classes/CallView.h b/Classes/CallView.h index 0e2f8a3a1..c031cf845 100644 --- a/Classes/CallView.h +++ b/Classes/CallView.h @@ -43,7 +43,7 @@ VideoZoomHandler *videoZoomHandler; } -@property(nonatomic, strong) IBOutlet CallPausedTableView *pausedCallsTableView; +@property(nonatomic, strong) IBOutlet CallPausedTableView *pausedCallsTable; @property(nonatomic, strong) IBOutlet UIView *videoGroup; @property(nonatomic, strong) IBOutlet UIView *videoView; @@ -89,6 +89,9 @@ @property(weak, nonatomic) IBOutlet UILabel *durationLabel; @property(weak, nonatomic) IBOutlet UIView *pausedByRemoteView; @property(weak, nonatomic) IBOutlet UIView *noActiveCallView; +@property(weak, nonatomic) IBOutlet UIView *conferenceView; +@property(strong, nonatomic) IBOutlet CallPausedTableView *conferenceCallsTable; +@property(weak, nonatomic) IBOutlet UIPauseButton *conferencePauseButton; - (IBAction)onRoutesClick:(id)sender; - (IBAction)onRoutesBluetoothClick:(id)sender; diff --git a/Classes/CallView.m b/Classes/CallView.m index 0425915b8..8095d3ffc 100644 --- a/Classes/CallView.m +++ b/Classes/CallView.m @@ -183,8 +183,6 @@ static UICompositeViewDescription *compositeDescription = nil; dragndrop.minimumNumberOfTouches = 1; [_videoPreview addGestureRecognizer:dragndrop]; - [_pauseButton setType:UIPauseButtonType_CurrentCall call:nil]; - [_zeroButton setDigit:'0']; [_zeroButton setDtmf:true]; [_oneButton setDigit:'1']; @@ -235,18 +233,14 @@ static UICompositeViewDescription *compositeDescription = nil; [_speakerButton update]; [_microButton update]; [_pauseButton update]; + [_conferencePauseButton update]; [_videoButton update]; [_hangupButton update]; - _optionsButton.enabled = - (state == LinphoneCallPaused || state == LinphoneCallPausing || state == LinphoneCallStreamsRunning); + _optionsButton.enabled = !linphone_call_media_in_progress(call); // Show Pause/Conference button following call count if (linphone_core_get_calls_nb(lc) > 1) { - if (![_pauseButton isHidden]) { - [_pauseButton setHidden:true]; - [_optionsConferenceButton setHidden:false]; - } bool enabled = true; const MSList *list = linphone_core_get_calls(lc); while (list != NULL) { @@ -259,12 +253,9 @@ static UICompositeViewDescription *compositeDescription = nil; } list = list->next; } - [_optionsConferenceButton setEnabled:enabled]; + _optionsConferenceButton.enabled = enabled; } else { - if ([_pauseButton isHidden]) { - [_pauseButton setHidden:false]; - [_optionsConferenceButton setHidden:true]; - } + _optionsConferenceButton.enabled = NO; } // Disable transfert in conference @@ -307,7 +298,7 @@ static UICompositeViewDescription *compositeDescription = nil; [UIView setAnimationDuration:0.3]; [PhoneMainView.instance showTabBar:true]; [PhoneMainView.instance showStatusBar:true]; - [_pausedCallsTableView.tableView setAlpha:1.0]; + [_pausedCallsTable.tableView setAlpha:1.0]; [_videoCameraSwitch setAlpha:1.0]; [UIView commitAnimations]; @@ -330,7 +321,7 @@ static UICompositeViewDescription *compositeDescription = nil; [UIView beginAnimations:nil context:nil]; [UIView setAnimationDuration:0.3]; [_videoCameraSwitch setAlpha:0.0]; - [_pausedCallsTableView.tableView setAlpha:0.0]; + [_pausedCallsTable.tableView setAlpha:0.0]; [UIView commitAnimations]; [PhoneMainView.instance showTabBar:false]; @@ -352,11 +343,11 @@ static UICompositeViewDescription *compositeDescription = nil; } [_videoGroup setAlpha:1.0]; - [_pausedCallsTableView.tableView setAlpha:0.0]; + [_pausedCallsTable.tableView setAlpha:0.0]; - UIEdgeInsets insets = {33, 0, 25, 0}; - [_pausedCallsTableView.tableView setContentInset:insets]; - [_pausedCallsTableView.tableView setScrollIndicatorInsets:insets]; + // UIEdgeInsets insets = {33, 0, 25, 0}; + // [_pausedCallsTableView.tableView setContentInset:insets]; + // [_pausedCallsTableView.tableView setScrollIndicatorInsets:insets]; if (animation) { [UIView commitAnimations]; @@ -413,7 +404,7 @@ static UICompositeViewDescription *compositeDescription = nil; // UIEdgeInsets insets = {10, 0, 25, 0}; // [_pausedCallsTableView.tableView setContentInset:insets]; // [_pausedCallsTableView.tableView setScrollIndicatorInsets:insets]; - [_pausedCallsTableView.tableView setAlpha:1.0]; + [_pausedCallsTable.tableView setAlpha:1.0]; [_videoCameraSwitch setHidden:TRUE]; @@ -460,17 +451,23 @@ static void hideSpinner(LinphoneCall *call, void *user_data) { - (void)onCurrentCallChange { LinphoneCall *call = linphone_core_get_current_call([LinphoneManager getLc]); - if (call) { + if (!call) { + _noActiveCallView.hidden = NO; + return; + } + + _callView.hidden = linphone_call_is_in_conference(call); + _conferenceView.hidden = !_callView.hidden; + _noActiveCallView.hidden = YES; + + if (call && !linphone_call_is_in_conference(call)) { const LinphoneAddress *addr = linphone_call_get_remote_address(call); [ContactDisplay setDisplayNameLabel:_nameLabel forAddress:addr]; char *uri = linphone_address_as_string_uri_only(addr); _addressLabel.text = [NSString stringWithUTF8String:uri]; ms_free(uri); _avatarImage.image = - [FastAddressBook getContactImage:[FastAddressBook getContactWithLinphoneAddress:addr] thumbnail:NO]; - _noActiveCallView.hidden = YES; - } else { - _noActiveCallView.hidden = NO; + [FastAddressBook getContactImage:[FastAddressBook getContactWithAddress:addr] thumbnail:NO]; } } @@ -478,8 +475,7 @@ static void hideSpinner(LinphoneCall *call, void *user_data) { [_numpadButton setOn]; if ([_numpadView isHidden]) { if (animated) { - [self showAnimation:@"show" - target:_numpadView + [self showAnimation:_numpadView completion:^(BOOL finished){ }]; } else { @@ -492,8 +488,7 @@ static void hideSpinner(LinphoneCall *call, void *user_data) { [_numpadButton setOff]; if (![_numpadView isHidden]) { if (animated) { - [self hideAnimation:@"hide" - target:_numpadView + [self hideAnimation:_numpadView completion:^(BOOL finished){ }]; } else { @@ -511,8 +506,7 @@ static void hideSpinner(LinphoneCall *call, void *user_data) { [[LinphoneManager instance] speakerEnabled])]; if ([_routesView isHidden]) { if (animated) { - [self showAnimation:@"show" - target:_routesView + [self showAnimation:_routesView completion:^(BOOL finished){ }]; } else { @@ -527,8 +521,7 @@ static void hideSpinner(LinphoneCall *call, void *user_data) { [_routesButton setOff]; if (![_routesView isHidden]) { if (animated) { - [self hideAnimation:@"hide" - target:_routesView + [self hideAnimation:_routesView completion:^(BOOL finished){ }]; } else { @@ -542,8 +535,7 @@ static void hideSpinner(LinphoneCall *call, void *user_data) { [_optionsButton setOn]; if ([_optionsView isHidden]) { if (animated) { - [self showAnimation:@"show" - target:_optionsView + [self showAnimation:_optionsView completion:^(BOOL finished){ }]; } else { @@ -556,8 +548,7 @@ static void hideSpinner(LinphoneCall *call, void *user_data) { [_optionsButton setOff]; if (![_optionsView isHidden]) { if (animated) { - [self hideAnimation:@"hide" - target:_optionsView + [self hideAnimation:_optionsView completion:^(BOOL finished){ }]; } else { @@ -601,8 +592,9 @@ static void hideSpinner(LinphoneCall *call, void *user_data) { hiddenVolume = FALSE; } - // Update table - [_pausedCallsTableView.tableView reloadData]; + // Update tables + [_pausedCallsTable.tableView reloadData]; + [_conferenceCallsTable.tableView reloadData]; static LinphoneCall *currentCall = NULL; if (!currentCall || linphone_core_get_current_call(lc) != currentCall) { @@ -837,44 +829,39 @@ static void hideSpinner(LinphoneCall *call, void *user_data) { #pragma mark - Animation -- (void)showAnimation:(NSString *)animationID target:(UIView *)target completion:(void (^)(BOOL finished))completion { - CGRect frame = [target frame]; +- (void)showAnimation:(UIView *)target completion:(void (^)(BOOL finished))completion { + CGRect frame = target.frame; int original_y = frame.origin.y; - frame.origin.y = [[self view] frame].size.height; - [target setFrame:frame]; - [target setHidden:FALSE]; + frame.origin.y = self.view.frame.size.height; + target.frame = frame; + frame.origin.y = original_y; + target.hidden = NO; [UIView animateWithDuration:0.5 delay:0.0 options:UIViewAnimationOptionCurveEaseOut animations:^{ - CGRect frame = [target frame]; - frame.origin.y = original_y; - [target setFrame:frame]; + target.frame = frame; } completion:^(BOOL finished) { - CGRect frame = [target frame]; - frame.origin.y = original_y; - [target setFrame:frame]; completion(finished); }]; } -- (void)hideAnimation:(NSString *)animationID target:(UIView *)target completion:(void (^)(BOOL finished))completion { - CGRect frame = [target frame]; - int original_y = frame.origin.y; +- (void)hideAnimation:(UIView *)target completion:(void (^)(BOOL finished))completion { + int original_y = target.frame.origin.y; + CGRect newFrame = target.frame; + newFrame.origin.y = self.view.frame.size.height; [UIView animateWithDuration:0.5 delay:0.0 options:UIViewAnimationOptionCurveEaseIn animations:^{ - CGRect frame = [target frame]; - frame.origin.y = [[self view] frame].size.height; - [target setFrame:frame]; + target.frame = newFrame; } completion:^(BOOL finished) { - CGRect frame = [target frame]; - frame.origin.y = original_y; - [target setHidden:TRUE]; - [target setFrame:frame]; + CGRect originFrame = target.frame; + originFrame.origin.y = original_y; + target.hidden = YES; + target.frame = originFrame; completion(finished); }]; } diff --git a/Classes/ChatConversationView.m b/Classes/ChatConversationView.m index ace86ab88..54c8263dc 100644 --- a/Classes/ChatConversationView.m +++ b/Classes/ChatConversationView.m @@ -190,7 +190,7 @@ static UICompositeViewDescription *compositeDescription = nil; [ContactDisplay setDisplayNameLabel:_addressLabel forAddress:linphoneAddress]; _addressLabel.accessibilityValue = _addressLabel.text; _avatarImage.image = - [FastAddressBook getContactImage:[FastAddressBook getContactWithLinphoneAddress:linphoneAddress] thumbnail:YES]; + [FastAddressBook getContactImage:[FastAddressBook getContactWithAddress:linphoneAddress] thumbnail:YES]; } static void message_status(LinphoneChatMessage *msg, LinphoneChatMessageState state, void *ud) { diff --git a/Classes/HistoryDetailsView.m b/Classes/HistoryDetailsView.m index 57ac70496..7b1b6a015 100644 --- a/Classes/HistoryDetailsView.m +++ b/Classes/HistoryDetailsView.m @@ -159,7 +159,7 @@ static UICompositeViewDescription *compositeDescription = nil; } LinphoneAddress *addr = linphone_call_log_get_remote_address(callLog); - ABRecordRef contact = [FastAddressBook getContactWithLinphoneAddress:addr]; + ABRecordRef contact = [FastAddressBook getContactWithAddress:addr]; _addContactButton.hidden = (contact != nil); [ContactDisplay setDisplayNameLabel:_contactLabel forAddress:addr]; _avatarImage.image = [FastAddressBook getContactImage:contact thumbnail:NO]; @@ -176,7 +176,7 @@ static UICompositeViewDescription *compositeDescription = nil; - (IBAction)onContactClick:(id)event { LinphoneAddress *addr = linphone_call_log_get_remote_address(callLog); - ABRecordRef contact = [FastAddressBook getContactWithLinphoneAddress:addr]; + ABRecordRef contact = [FastAddressBook getContactWithAddress:addr]; ContactDetailsView *view = VIEW(ContactDetailsView); [PhoneMainView.instance changeCurrentView:view.compositeViewDescription push:TRUE]; [ContactSelection setSelectionMode:ContactSelectionModeNone]; diff --git a/Classes/LinphoneCoreSettingsStore.m b/Classes/LinphoneCoreSettingsStore.m index 9fb252597..55584ead6 100644 --- a/Classes/LinphoneCoreSettingsStore.m +++ b/Classes/LinphoneCoreSettingsStore.m @@ -130,6 +130,10 @@ extern void linphone_iphone_log_handler(int lev, const char *fmt, va_list args); [self setCString:linphone_address_get_username(linphone_proxy_config_get_identity_address(proxy)) forKey:key]; } + + [self setBool:linphone_core_video_enabled(lc) forKey:@"enable_video_preference"]; + [self setBool:[LinphoneManager.instance lpConfigBoolForKey:@"auto_answer"] + forKey:@"enable_auto_answer_preference"]; } // account section { @@ -173,7 +177,6 @@ extern void linphone_iphone_log_handler(int lev, const char *fmt, va_list args); [self setCString:tname forKey:@"transport_preference"]; [self setBool:(linphone_proxy_config_get_route(cfg) != NULL)forKey:@"outbound_proxy_preference"]; [self setBool:linphone_proxy_config_avpf_enabled(cfg) forKey:@"avpf_preference"]; - [self setBool:linphone_core_video_enabled(lc) forKey:@"enable_video_preference"]; // actually in Advanced section but proxy config dependent [self setInteger:linphone_proxy_config_get_expires(cfg) forKey:@"expire_preference"]; @@ -591,6 +594,9 @@ extern void linphone_iphone_log_handler(int lev, const char *fmt, va_list args); bool enableVideo = [self boolForKey:@"enable_video_preference"]; linphone_core_enable_video(lc, enableVideo, enableVideo); + + bool enableAutoAnswer = [self boolForKey:@"enable_auto_answer_preference"]; + [LinphoneManager.instance lpConfigSetBool:enableAutoAnswer forKey:@"auto_answer"]; } // audio section diff --git a/Classes/LinphoneManager.m b/Classes/LinphoneManager.m index 171cbded5..6ca5f58dc 100644 --- a/Classes/LinphoneManager.m +++ b/Classes/LinphoneManager.m @@ -1316,9 +1316,9 @@ static LinphoneCoreVTable linphonec_vtable = {.show = NULL, const char *lRingBack = [[LinphoneManager bundleFile:@"ringback.wav"] cStringUsingEncoding:[NSString defaultCStringEncoding]]; linphone_core_set_ringback(theLinphoneCore, lRingBack); - const char *lPlay = - [[LinphoneManager bundleFile:@"hold.wav"] cStringUsingEncoding:[NSString defaultCStringEncoding]]; - linphone_core_set_play_file(theLinphoneCore, lPlay); + // const char *lPlay = + // [[LinphoneManager bundleFile:@"hold.wav"] cStringUsingEncoding:[NSString defaultCStringEncoding]]; + // linphone_core_set_play_file(theLinphoneCore, lPlay); linphone_core_set_zrtp_secrets_file(theLinphoneCore, [zrtpSecretsFileName cStringUsingEncoding:[NSString defaultCStringEncoding]]); @@ -1444,9 +1444,9 @@ static BOOL libStarted = FALSE; const char *lRingBack = [[LinphoneManager bundleFile:@"ringback.wav"] cStringUsingEncoding:[NSString defaultCStringEncoding]]; lp_config_set_string(configDb, "sound", "ringback_tone", lRingBack); - const char *lPlay = - [[LinphoneManager bundleFile:@"hold.wav"] cStringUsingEncoding:[NSString defaultCStringEncoding]]; - lp_config_set_string(configDb, "sound", "hold_music", lPlay); + // const char *lPlay = + // [[LinphoneManager bundleFile:@"hold.wav"] cStringUsingEncoding:[NSString defaultCStringEncoding]]; + // lp_config_set_string(configDb, "sound", "hold_music", lPlay); theLinphoneCore = linphone_core_new_with_config(&linphonec_vtable, configDb, (__bridge void *)(self) /* user_data */); diff --git a/Classes/LinphoneUI/Base.lproj/UICallConferenceCell.xib b/Classes/LinphoneUI/Base.lproj/UICallConferenceCell.xib new file mode 100644 index 000000000..12e94423a --- /dev/null +++ b/Classes/LinphoneUI/Base.lproj/UICallConferenceCell.xib @@ -0,0 +1,103 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Classes/LinphoneUI/UICallConferenceCell.h b/Classes/LinphoneUI/UICallConferenceCell.h new file mode 100644 index 000000000..ce00eed21 --- /dev/null +++ b/Classes/LinphoneUI/UICallConferenceCell.h @@ -0,0 +1,22 @@ +// +// UIPausedCallCell.h +// linphone +// +// Created by Gautier Pelloux-Prayer on 11/09/15. +// +// + +#import "UIRoundedImageView.h" +#import "LinphoneManager.h" + +@interface UICallConferenceCell : UITableViewCell + +@property(weak, nonatomic) IBOutlet UIRoundedImageView *avatarImage; +@property(weak, nonatomic) IBOutlet UILabel *nameLabel; +@property(weak, nonatomic) IBOutlet UILabel *durationLabel; +@property(nonatomic, setter=setCall:) LinphoneCall *call; + +- (id)initWithIdentifier:(NSString *)identifier; +- (IBAction)onKickClick:(id)sender; + +@end diff --git a/Classes/LinphoneUI/UICallConferenceCell.m b/Classes/LinphoneUI/UICallConferenceCell.m new file mode 100644 index 000000000..2e9c21ca6 --- /dev/null +++ b/Classes/LinphoneUI/UICallConferenceCell.m @@ -0,0 +1,49 @@ +// +// UIPausedCallCell.m +// linphone +// +// Created by Gautier Pelloux-Prayer on 11/09/15. +// +// + +#import "UICallConferenceCell.h" +#import "Utils.h" + +@implementation UICallConferenceCell + +- (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) { + // resize cell to match .nib size. It is needed when resized the cell to + // correctly adapt its height too + UIView *sub = ((UIView *)[arrayOfViews objectAtIndex:0]); + [self setFrame:CGRectMake(0, 0, sub.frame.size.width, sub.frame.size.height)]; + [self addSubview:sub]; + } + } + return self; +} + +- (void)setCall:(LinphoneCall *)call { + _call = call; + if (!call || !linphone_call_is_in_conference(call)) { + LOGF(@"Invalid call: either NULL or not in conference."); + return; + } + + const LinphoneAddress *addr = linphone_call_get_remote_address(call); + [ContactDisplay setDisplayNameLabel:_nameLabel forAddress:addr]; + + _avatarImage.image = [FastAddressBook getContactImage:[FastAddressBook getContactWithAddress:addr] thumbnail:YES]; + + int duration = linphone_call_get_duration(call); + [_durationLabel setText:[NSString stringWithFormat:@"%02i:%02i", (duration / 60), (duration % 60), nil]]; +} + +- (IBAction)onKickClick:(id)sender { + linphone_core_remove_from_conference([LinphoneManager getLc], _call); +} +@end diff --git a/Classes/LinphoneUI/UICallPausedCell.m b/Classes/LinphoneUI/UICallPausedCell.m index 5c39d0969..ac8b474e9 100644 --- a/Classes/LinphoneUI/UICallPausedCell.m +++ b/Classes/LinphoneUI/UICallPausedCell.m @@ -36,8 +36,7 @@ const LinphoneAddress *addr = linphone_call_get_remote_address(call); [ContactDisplay setDisplayNameLabel:_nameLabel forAddress:addr]; - _avatarImage.image = - [FastAddressBook getContactImage:[FastAddressBook getContactWithLinphoneAddress:addr] thumbnail:NO]; + _avatarImage.image = [FastAddressBook getContactImage:[FastAddressBook getContactWithAddress:addr] thumbnail:NO]; int duration = linphone_call_get_duration(call); [_durationLabel setText:[NSString stringWithFormat:@"%02i:%02i", (duration / 60), (duration % 60), nil]]; diff --git a/Classes/LinphoneUI/UIChatCell.m b/Classes/LinphoneUI/UIChatCell.m index 3133ba4cb..fc60a292e 100644 --- a/Classes/LinphoneUI/UIChatCell.m +++ b/Classes/LinphoneUI/UIChatCell.m @@ -71,8 +71,7 @@ } const LinphoneAddress *addr = linphone_chat_room_get_peer_address(chatRoom); [ContactDisplay setDisplayNameLabel:addressLabel forAddress:addr]; - avatarImage.image = - [FastAddressBook getContactImage:[FastAddressBook getContactWithLinphoneAddress:addr] thumbnail:NO]; + avatarImage.image = [FastAddressBook getContactImage:[FastAddressBook getContactWithAddress:addr] thumbnail:NO]; LinphoneChatMessage *last_message = linphone_chat_room_get_user_data(chatRoom); if (last_message) { diff --git a/Classes/LinphoneUI/UIHistoryCell.m b/Classes/LinphoneUI/UIHistoryCell.m index 19216bc3c..70358eafa 100644 --- a/Classes/LinphoneUI/UIHistoryCell.m +++ b/Classes/LinphoneUI/UIHistoryCell.m @@ -95,7 +95,7 @@ _stateImage.image = image; [ContactDisplay setDisplayNameLabel:displayNameLabel forAddress:addr]; - ABRecordRef contact = [FastAddressBook getContactWithLinphoneAddress:addr]; + ABRecordRef contact = [FastAddressBook getContactWithAddress:addr]; _avatarImage.image = [FastAddressBook getContactImage:contact thumbnail:TRUE]; } diff --git a/Classes/Utils/FastAddressBook.h b/Classes/Utils/FastAddressBook.h index 7dfdad41d..b07018c1d 100644 --- a/Classes/Utils/FastAddressBook.h +++ b/Classes/Utils/FastAddressBook.h @@ -37,7 +37,7 @@ // TOOLS + (ABRecordRef)getContact:(NSString *)address; -+ (ABRecordRef)getContactWithLinphoneAddress:(const LinphoneAddress *)address; ++ (ABRecordRef)getContactWithAddress:(const LinphoneAddress *)address; + (NSString *)getContactDisplayName:(ABRecordRef)contact; + (UIImage *)getContactImage:(ABRecordRef)contact thumbnail:(BOOL)thumbnail; diff --git a/Classes/Utils/FastAddressBook.m b/Classes/Utils/FastAddressBook.m index e12a9f897..24c8e5c9f 100644 --- a/Classes/Utils/FastAddressBook.m +++ b/Classes/Utils/FastAddressBook.m @@ -60,7 +60,7 @@ static void sync_address_book(ABAddressBookRef addressBook, CFDictionaryRef info return nil; } -+ (ABRecordRef)getContactWithLinphoneAddress:(const LinphoneAddress *)address { ++ (ABRecordRef)getContactWithAddress:(const LinphoneAddress *)address { ABRecordRef contact = nil; if (address) { char *uri = linphone_address_as_string_uri_only(address); @@ -324,7 +324,7 @@ void sync_address_book(ABAddressBookRef addressBook, CFDictionaryRef info, void + (NSString *)displayNameForAddress:(const LinphoneAddress *)addr { NSString *ret = NSLocalizedString(@"Unknown", nil); - ABRecordRef contact = [FastAddressBook getContactWithLinphoneAddress:addr]; + ABRecordRef contact = [FastAddressBook getContactWithAddress:addr]; if (contact) { ret = [FastAddressBook displayNameForContact:contact]; } else { diff --git a/Classes/Utils/Utils.m b/Classes/Utils/Utils.m index 2b901290e..865d911fc 100644 --- a/Classes/Utils/Utils.m +++ b/Classes/Utils/Utils.m @@ -36,8 +36,8 @@ int filesize = 20; const char *filename = strchr(file, '/') ? strrchr(file, '/') + 1 : file; if (severity <= ORTP_DEBUG) { - // lol: ortp_debug(XXX) can be disabled at compile time, but ortp_log(ORTP_DEBUG, xxx) will always be valid even - // not in debug build... + // ortp_debug(XXX) can be disabled at compile time, but ortp_log(ORTP_DEBUG, xxx) will always be valid even + // not in debug build... ortp_debug("%*s:%3d - %s", filesize, filename + MAX((int)strlen(filename) - filesize, 0), line, str.UTF8String); } else { ortp_log(severity, "%*s:%3d - %s", filesize, filename + MAX((int)strlen(filename) - filesize, 0), line, @@ -362,7 +362,7 @@ void linphone_iphone_log_handler(int lev, const char *fmt, va_list args) { } + (void)setDisplayNameLabel:(UILabel *)label forAddress:(const LinphoneAddress *)addr { - ABRecordRef contact = [FastAddressBook getContactWithLinphoneAddress:addr]; + ABRecordRef contact = [FastAddressBook getContactWithAddress:addr]; if (contact) { [ContactDisplay setDisplayNameLabel:label forContact:contact]; } else { diff --git a/Settings/InAppSettings.bundle/Root.plist b/Settings/InAppSettings.bundle/Root.plist index f0bc35b8c..f9c3a6492 100644 --- a/Settings/InAppSettings.bundle/Root.plist +++ b/Settings/InAppSettings.bundle/Root.plist @@ -188,6 +188,16 @@ Type IASKButtonSpecifier + + Type + PSToggleSwitchSpecifier + Title + Auto answer call immediately + Key + enable_auto_answer + DefaultValue + + StringsTable Root diff --git a/linphone.xcodeproj/project.pbxproj b/linphone.xcodeproj/project.pbxproj index 09e719f6b..9eed6f550 100755 --- a/linphone.xcodeproj/project.pbxproj +++ b/linphone.xcodeproj/project.pbxproj @@ -359,6 +359,9 @@ 63EEE4071BBA9B010087D3AF /* libmediastreamer_voip.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 22405EEA16006F0700B92522 /* libmediastreamer_voip.a */; }; 63EEE4081BBA9B010087D3AF /* libortp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 220FAD2C10765B400068D98F /* libortp.a */; }; 63F1DF441BCE618E00EDED90 /* UIAddressTextField.m in Sources */ = {isa = PBXBuildFile; fileRef = 63F1DF431BCE618E00EDED90 /* UIAddressTextField.m */; }; + 63F1DF4B1BCE983200EDED90 /* CallConferenceTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = 63F1DF4A1BCE983200EDED90 /* CallConferenceTableView.m */; }; + 63F1DF4F1BCE985F00EDED90 /* UICallConferenceCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 63F1DF4D1BCE985F00EDED90 /* UICallConferenceCell.m */; }; + 63F1DF511BCE986A00EDED90 /* UICallConferenceCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 63F1DF531BCE986A00EDED90 /* UICallConferenceCell.xib */; }; 63FB30351A680E73008CA393 /* UIRoundedImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 63FB30341A680E73008CA393 /* UIRoundedImageView.m */; }; 70E542F313E147E3002BA2C0 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 70E542F213E147E3002BA2C0 /* OpenGLES.framework */; }; 70E542F513E147EB002BA2C0 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 70E542F413E147EB002BA2C0 /* QuartzCore.framework */; }; @@ -974,6 +977,11 @@ 63EF7FDC1A24B5810017A416 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/AboutView.strings; sourceTree = ""; }; 63F1DF421BCE618E00EDED90 /* UIAddressTextField.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIAddressTextField.h; sourceTree = ""; }; 63F1DF431BCE618E00EDED90 /* UIAddressTextField.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIAddressTextField.m; sourceTree = ""; }; + 63F1DF491BCE983100EDED90 /* CallConferenceTableView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CallConferenceTableView.h; sourceTree = ""; }; + 63F1DF4A1BCE983200EDED90 /* CallConferenceTableView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CallConferenceTableView.m; sourceTree = ""; }; + 63F1DF4C1BCE985F00EDED90 /* UICallConferenceCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UICallConferenceCell.h; sourceTree = ""; }; + 63F1DF4D1BCE985F00EDED90 /* UICallConferenceCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UICallConferenceCell.m; sourceTree = ""; }; + 63F1DF521BCE986A00EDED90 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/UICallConferenceCell.xib; sourceTree = ""; }; 63FB30331A680E73008CA393 /* UIRoundedImageView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIRoundedImageView.h; sourceTree = ""; }; 63FB30341A680E73008CA393 /* UIRoundedImageView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIRoundedImageView.m; sourceTree = ""; }; 7066FC0B13E830E400EFC6DC /* libvpx.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libvpx.a; path = "liblinphone-sdk/apple-darwin/lib/libvpx.a"; sourceTree = ""; }; @@ -1358,6 +1366,8 @@ D350F20B15A43BB100149E54 /* AssistantView.h */, D350F20C15A43BB100149E54 /* AssistantView.m */, D38187E015FE348A00C3EDCA /* AssistantView.xib */, + 63F1DF491BCE983100EDED90 /* CallConferenceTableView.h */, + 63F1DF4A1BCE983200EDED90 /* CallConferenceTableView.m */, D3F26BEE15986B71005F9CAB /* CallIncomingView.h */, D3F26BEF15986B71005F9CAB /* CallIncomingView.m */, D38187DC15FE347700C3EDCA /* CallIncomingView.xib */, @@ -1465,10 +1475,17 @@ 2214EB7012F84668002A5394 /* LinphoneUI */ = { isa = PBXGroup; children = ( + 63F1DF421BCE618E00EDED90 /* UIAddressTextField.h */, + 63F1DF431BCE618E00EDED90 /* UIAddressTextField.m */, + 63C441C11BBC23ED0053DC5E /* UIAssistantTextField.h */, + 63C441C21BBC23ED0053DC5E /* UIAssistantTextField.m */, 22C7555E1317E59C007BC101 /* UIBluetoothButton.h */, 22C7555F1317E59C007BC101 /* UIBluetoothButton.m */, 2214EB7812F846B1002A5394 /* UICallButton.h */, 2214EB7912F846B1002A5394 /* UICallButton.m */, + 63F1DF4C1BCE985F00EDED90 /* UICallConferenceCell.h */, + 63F1DF4D1BCE985F00EDED90 /* UICallConferenceCell.m */, + 63F1DF531BCE986A00EDED90 /* UICallConferenceCell.xib */, 63BC49E01BA2CDFC004EC273 /* UICallPausedCell.h */, 63BC49E11BA2CDFC004EC273 /* UICallPausedCell.m */, 63BC49E91BA2CEDF004EC273 /* UICallPausedCell.xib */, @@ -1483,6 +1500,11 @@ D3EA540F159853750037DC6B /* UIChatCell.h */, D3EA5410159853750037DC6B /* UIChatCell.m */, 639CEB0B1A1DF4FA004DE38F /* UIChatCell.xib */, + 63B8D69F1BCBF43100C12B09 /* UIChatCreateCell.h */, + 63B8D6A01BCBF43100C12B09 /* UIChatCreateCell.m */, + 63B8D6A11BCBF43100C12B09 /* UIChatCreateCell.xib */, + 6334DDFE1BBAD5AA00631900 /* UICheckBoxTVTableViewController.h */, + 6334DDFF1BBAD5AA00631900 /* UICheckBoxTVTableViewController.m */, D31B4B1E159876C0002E6C72 /* UICompositeView.h */, D31B4B1F159876C0002E6C72 /* UICompositeView.m */, 639CEB051A1DF4EB004DE38F /* UICompositeView.xib */, @@ -1530,15 +1552,6 @@ D3196D3D15A32BD8007FEEBA /* UITransferButton.m */, 340751E5150F38FC00B89C47 /* UIVideoButton.h */, 340751E6150F38FD00B89C47 /* UIVideoButton.m */, - 6334DDFE1BBAD5AA00631900 /* UICheckBoxTVTableViewController.h */, - 6334DDFF1BBAD5AA00631900 /* UICheckBoxTVTableViewController.m */, - 63F1DF421BCE618E00EDED90 /* UIAddressTextField.h */, - 63F1DF431BCE618E00EDED90 /* UIAddressTextField.m */, - 63C441C11BBC23ED0053DC5E /* UIAssistantTextField.h */, - 63C441C21BBC23ED0053DC5E /* UIAssistantTextField.m */, - 63B8D69F1BCBF43100C12B09 /* UIChatCreateCell.h */, - 63B8D6A01BCBF43100C12B09 /* UIChatCreateCell.m */, - 63B8D6A11BCBF43100C12B09 /* UIChatCreateCell.xib */, ); path = LinphoneUI; sourceTree = ""; @@ -2476,6 +2489,7 @@ 637528071BBA8EF700FDEA6F /* conference_exit_over.png in Resources */, 63158FAD1B468E0E00969917 /* ImageOptim.sh in Resources */, 637528391BBA8EF700FDEA6F /* numpad_7.png in Resources */, + 63F1DF511BCE986A00EDED90 /* UICallConferenceCell.xib in Resources */, 637528661BBA8EF700FDEA6F /* status_available.png in Resources */, 63AADBE91B6A0FF200AA16FD /* hold.wav in Resources */, 637528471BBA8EF700FDEA6F /* options_start_conference.png in Resources */, @@ -2672,6 +2686,7 @@ 340751E7150F38FD00B89C47 /* UIVideoButton.m in Sources */, 34216F401547EBCD00EA9777 /* VideoZoomHandler.m in Sources */, D3F83EEC1582021700336684 /* CallView.m in Sources */, + 63F1DF4B1BCE983200EDED90 /* CallConferenceTableView.m in Sources */, D3F83F8E15822ABE00336684 /* PhoneMainView.m in Sources */, D3ED3E871586291E006C0DE4 /* TabBarView.m in Sources */, D3ED3EA71587334E006C0DE4 /* HistoryListTableView.m in Sources */, @@ -2691,6 +2706,7 @@ 63B81A101B57DA33009604A6 /* UIScrollView+TPKeyboardAvoidingAdditions.m in Sources */, F03CA84318C72F1A0008889D /* UITextViewNoDefine.m in Sources */, 63B81A0D1B57DA33009604A6 /* TPKeyboardAvoidingCollectionView.m in Sources */, + 63F1DF4F1BCE985F00EDED90 /* UICallConferenceCell.m in Sources */, D37DC6C11594AE1800B2A5EB /* LinphoneCoreSettingsStore.m in Sources */, 63CD4B4F1A5AAC8C00B84282 /* DTAlertView.m in Sources */, D3EA53FD159850E80037DC6B /* LinphoneManager.m in Sources */, @@ -2961,6 +2977,14 @@ name = ChatConversationCreateView.xib; sourceTree = ""; }; + 63F1DF531BCE986A00EDED90 /* UICallConferenceCell.xib */ = { + isa = PBXVariantGroup; + children = ( + 63F1DF521BCE986A00EDED90 /* Base */, + ); + name = UICallConferenceCell.xib; + sourceTree = ""; + }; D37EE11016035793003608A6 /* ImageView.xib */ = { isa = PBXVariantGroup; children = (