diff --git a/.gitignore b/.gitignore index 41684545a..5286f4739 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,8 @@ liblinphone-iphone-sdk*.zip xcuserdata/ Classes/LinphoneIOSVersion.h Pods/ +Podfile.lock +GoogleService-Info.plist build test-reports WORK diff --git a/.gitmodules b/.gitmodules index 4a8a9c0e8..83d60c91b 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,122 +1,4 @@ -[submodule "submodules/linphone"] - path = submodules/linphone - url = https://gitlab.linphone.org/BC/public/linphone.git -[submodule "submodules/externals/gsm"] - path = submodules/externals/gsm - url = https://gitlab.linphone.org/BC/public/external/gsm.git -[submodule "submodules/externals/speex"] - path = submodules/externals/speex - url = https://gitlab.linphone.org/BC/public/external/speex.git -[submodule "submodules/externals/opencore-amr"] - path = submodules/externals/opencore-amr - url = https://gitlab.linphone.org/BC/public/external/opencore-amr.git - ignore = dirty -[submodule "submodules/msamr"] - path = submodules/msamr - url = https://gitlab.linphone.org/BC/public/msamr.git -[submodule "submodules/externals/ffmpeg"] - path = submodules/externals/ffmpeg - url = https://gitlab.linphone.org/BC/public/external/ffmpeg.git -[submodule "submodules/externals/x264"] - path = submodules/externals/x264 - url = https://gitlab.linphone.org/BC/public/external/x264.git - ignore = dirty -[submodule "submodules/msx264"] - path = submodules/msx264 - url = https://gitlab.linphone.org/BC/public/msx264.git -[submodule "submodules/externals/libvpx"] - path = submodules/externals/libvpx - url = https://gitlab.linphone.org/BC/public/external/libvpx.git - ignore = dirty -[submodule "submodules/bzrtp"] - path = submodules/bzrtp - url = https://gitlab.linphone.org/BC/public/bzrtp.git -[submodule "submodules/mssilk"] - path = submodules/mssilk - url = https://gitlab.linphone.org/BC/public/mssilk.git -[submodule "submodules/externals/srtp"] - path = submodules/externals/srtp - url = https://gitlab.linphone.org/BC/public/external/srtp.git -[submodule "submodules/bcg729"] - path = submodules/bcg729 - url = https://gitlab.linphone.org/BC/public/bcg729.git -[submodule "submodules/belle-sip"] - path = submodules/belle-sip - url = https://gitlab.linphone.org/BC/public/belle-sip.git -[submodule "submodules/externals/opus"] - path = submodules/externals/opus - url = https://gitlab.linphone.org/BC/public/external/opus.git - ignore = dirty -[submodule "submodules/externals/libxml2"] - path = submodules/externals/libxml2 - url = https://gitlab.linphone.org/BC/public/external/libxml2.git - ignore = dirty -[submodule "submodules/externals/openh264"] - path = submodules/externals/openh264 - url = https://gitlab.linphone.org/BC/public/external/openh264.git - ignore = dirty -[submodule "submodules/msopenh264"] - path = submodules/msopenh264 - url = https://gitlab.linphone.org/BC/public/msopenh264.git -[submodule "submodules/mswebrtc"] - path = submodules/mswebrtc - url = https://gitlab.linphone.org/BC/public/mswebrtc.git [submodule "Classes/KIF"] path = Classes/KIF url = https://github.com/kif-framework/KIF ignore = dirty -[submodule "submodules/cmake-builder"] - path = submodules/cmake-builder - url = https://gitlab.linphone.org/BC/public/linphone-cmake-builder.git -[submodule "submodules/externals/vo-amrwbenc"] - path = submodules/externals/vo-amrwbenc - url = https://gitlab.linphone.org/BC/public/external/vo-amrwbenc.git - ignore = dirty -[submodule "submodules/belr"] - path = submodules/belr - url = https://gitlab.linphone.org/BC/public/belr.git -[submodule "submodules/belcard"] - path = submodules/belcard - url = https://gitlab.linphone.org/BC/public/belcard.git -[submodule "submodules/bctoolbox"] - path = submodules/bctoolbox - url = https://gitlab.linphone.org/BC/public/bctoolbox.git -[submodule "submodules/externals/mbedtls"] - path = submodules/externals/mbedtls - url = https://gitlab.linphone.org/BC/public/external/mbedtls.git -[submodule "submodules/externals/codec2"] - path = submodules/externals/codec2 - url = https://gitlab.linphone.org/BC/public/external/codec2.git -[submodule "submodules/mscodec2"] - path = submodules/mscodec2 - url = https://gitlab.linphone.org/BC/public/mscodec2.git -[submodule "submodules/externals/bv16-floatingpoint"] - path = submodules/externals/bv16-floatingpoint - url = https://gitlab.linphone.org/BC/public/external/bv16-floatingpoint.git -[submodule "submodules/bcunit"] - path = submodules/bcunit - url = https://gitlab.linphone.org/BC/public/bcunit.git -[submodule "submodules/externals/libjpeg-turbo"] - path = submodules/externals/libjpeg-turbo - url = https://gitlab.linphone.org/BC/public/external/libjpeg-turbo.git -[submodule "submodules/mediastreamer2"] - path = submodules/mediastreamer2 - url = https://gitlab.linphone.org/BC/public/mediastreamer2.git -[submodule "submodules/ortp"] - path = submodules/ortp - url = https://gitlab.linphone.org/BC/public/ortp.git -[submodule "submodules/bcmatroska2"] - path = submodules/bcmatroska2 - url = https://gitlab.linphone.org/BC/public/bcmatroska2.git -[submodule "submodules/externals/libxsd"] - path = submodules/externals/libxsd - url = https://gitlab.linphone.org/BC/public/external/libxsd.git -[submodule "submodules/externals/xerces-c"] - path = submodules/externals/xerces-c - url = https://gitlab.linphone.org/BC/public/external/xerces-c.git -[submodule "submodules/externals/soci"] - path = submodules/externals/soci - url = https://gitlab.linphone.org/BC/public/external/soci.git -[submodule "submodules/externals/zxing-cpp"] - path = submodules/externals/zxing-cpp - url = https://gitlab.linphone.org/BC/public/external/zxing-cpp.git diff --git a/CHANGELOG.md b/CHANGELOG.md index 596b4e544..28296c025 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,23 +10,41 @@ Group changes to describe their impact on the project, as follows: Fixed for any bug fixes. Security to invite users to upgrade in case of vulnerabilities. -## [Unreleased] + +## [4.1.0] - 2019-xx-xx ### Added -- Auto-layout of images in chat messages -- Selection of multiple images to send in a chat message -- Sending text with image -- Latest Calls widget -- Latest Chatrooms widget -- Homescreen quick action : New message -- Rich message notifications with Linphone UI -- Support of H265 video format based on Apple's VideoToolbox framework. +- End-to-end encryption for instant messaging, for both one-to-one and group conversations. +- Video H.265 codec support, based on iOS VideoToolbox framework. +- Enhanced call and IM notifications, so that it is possible to answer, decline, reply or mark as read directly from them. +- Setting to request attachments to be automatically downloaded, unconditionnally or based on their size. +- Possibility to send multiple attachments (images, documents) in a same message. +- Possibility to open all kinds of documents received in a conversation. +- Possibility to share an image through Linphone from an external application (ex: photo app) +- Button to invite contacts to use Linphone by sending them a SMS. +- Possibility to record calls (audio only), and replay them from the "Recordings" menu. +- Remote provisioning from a QR code providing the http(s) url of a provisioning server. +- Optional Crashlythics support. ### Changed -- Use of Photokit instead of Asset Library for image handling +- Compilation procedure is simplified: a binary SDK containing dependencies (liblinphone) is retrieved automatically from a CocoaPods repository. + Full compilation remains absolutely supported. Please check local README.md for more details. +- Updated translations, mainly French and English. +- Use of Photokit instead of Asset Library for image handling. +- Auto-layout of images in chat messages. +- Use Xcode test navigator for tests. +- Move important files from `Documents` folder to `Application Library`. + +### Fixed +- Issues around Bluetooth devices management. +- Loss of audio after accepting a second call while already in a call. +- Crashes when during calls. +- Nowebcam when leaving conference. ### Removed -- Static build of iOS linphone SDK +- Static build of iOS linphone SDK. +- All git submodules previously containing dependencies. +- Some resource files now provided by linphone-sdk. ## [4.0.2] - 2018-10-15 diff --git a/Classes/AboutView.m b/Classes/AboutView.m index 1bc831b8f..abe327561 100644 --- a/Classes/AboutView.m +++ b/Classes/AboutView.m @@ -49,8 +49,9 @@ static UICompositeViewDescription *compositeDescription = nil; [super viewDidLoad]; NSString *name = [NSBundle.mainBundle objectForInfoDictionaryKey:@"CFBundleDisplayName"]; _nameLabel.text = name; - _appVersionLabel.text = [NSString stringWithFormat:@"%@ iOS %s", name, LINPHONE_IOS_VERSION]; - _libVersionLabel.text = [NSString stringWithFormat:@"%@ Core %s", name, linphone_core_get_version()]; + NSString *curVersion = [NSString stringWithFormat:@"version %@",[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"]]; + _appVersionLabel.text = [NSString stringWithFormat:@"%@ iOS %@", name, curVersion]; + _libVersionLabel.text = [NSString stringWithFormat:@"%@ SDK %s", name, LINPHONE_SDK_VERSION]; UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onLicenceTap)]; tapGestureRecognizer.numberOfTapsRequired = 1; @@ -74,7 +75,7 @@ static UICompositeViewDescription *compositeDescription = nil; } - (IBAction)onPolicyTap { - NSString *url = @"http://www.linphone.org/privacy-policy.html"; + NSString *url = @"https://www.linphone.org/terms-and-privacy"; if (![UIApplication.sharedApplication openURL:[NSURL URLWithString:url]]) { LOGE(@"Failed to open %@, invalid URL", url); } @@ -88,6 +89,6 @@ static UICompositeViewDescription *compositeDescription = nil; } - (IBAction)onDialerBackClick:(id)sender { - [PhoneMainView.instance popToView:DialerView.compositeViewDescription]; + [PhoneMainView.instance popCurrentView]; } @end diff --git a/Classes/AssistantLinkView.h b/Classes/AssistantLinkView.h index a97aea968..7fcdcac88 100644 --- a/Classes/AssistantLinkView.h +++ b/Classes/AssistantLinkView.h @@ -5,17 +5,18 @@ // Created by Gautier Pelloux-Prayer on 29/08/16. // // - #import "PhoneMainView.h" #import +#import "TPKeyboardAvoidingScrollView.h" @interface AssistantLinkView : UIViewController -@property(weak, nonatomic) IBOutlet UIView *linkAccountView; +@property(weak, nonatomic) IBOutlet TPKeyboardAvoidingScrollView *linkAccountView; @property(weak, nonatomic) IBOutlet UIView *activateSMSView; @property(weak, nonatomic) IBOutlet UIButton *countryButton; @property(weak, nonatomic) IBOutlet UITextField *countryCodeField; @property(weak, nonatomic) IBOutlet UITextField *activationCodeField; +@property (weak, nonatomic) IBOutlet UIRoundBorderedButton *maybeLaterButton; @property(weak, nonatomic) IBOutlet UIRoundBorderedButton *linkAccountButton; @property(weak, nonatomic) IBOutlet UIRoundBorderedButton *checkValidationButton; @property(weak, nonatomic) IBOutlet UIView *waitView; @@ -28,5 +29,6 @@ - (IBAction)onCountryClick:(id)sender; - (IBAction)onDialerClick:(id)sender; - (IBAction)onPhoneNumberDisclosureClick:(id)sender; +- (IBAction)onMaybeLater:(id)sender; @end diff --git a/Classes/AssistantLinkView.m b/Classes/AssistantLinkView.m index 06a1d7082..145ffac70 100644 --- a/Classes/AssistantLinkView.m +++ b/Classes/AssistantLinkView.m @@ -41,6 +41,7 @@ _linkAccountView.hidden = _activateSMSView.userInteractionEnabled = NO; _activateSMSView.hidden = _linkAccountView.userInteractionEnabled = YES; + [self fitScrollContentSize]; if (!account_creator) { account_creator = linphone_account_creator_new( @@ -103,6 +104,19 @@ [super viewDidDisappear:animated]; } +- (void)fitScrollContentSize { + // make view scrollable only if next button is too away + CGRect viewframe = _linkAccountView.frame; + if (UIInterfaceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation])) { + viewframe.size.height += 60; + } + [_linkAccountView setContentSize:viewframe.size]; +} + +- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation { + [self fitScrollContentSize]; +} + #pragma mark - UICompositeViewDelegate Functions static UICompositeViewDescription *compositeDescription = nil; @@ -258,7 +272,7 @@ void assistant_activate_phone_number_link(LinphoneAccountCreator *creator, Linph } - (IBAction)onDialerClick:(id)sender { - [PhoneMainView.instance popToView:DialerView.compositeViewDescription]; + [PhoneMainView.instance popCurrentView]; } - (IBAction)onPhoneNumberDisclosureClick:(id)sender { @@ -280,6 +294,10 @@ void assistant_activate_phone_number_link(LinphoneAccountCreator *creator, Linph [self presentViewController:errView animated:YES completion:nil]; } +- (IBAction)onMaybeLater:(id)sender { + [PhoneMainView.instance popToView:DialerView.compositeViewDescription]; +} + #pragma mark - select country delegate - (void)didSelectCountry:(NSDictionary *)country { diff --git a/Classes/AssistantView.h b/Classes/AssistantView.h index 20a9de39a..1b2c17ad0 100644 --- a/Classes/AssistantView.h +++ b/Classes/AssistantView.h @@ -43,6 +43,7 @@ @property(nonatomic, strong) IBOutlet UIView *waitView; @property(nonatomic, strong) IBOutlet UIButton *backButton; @property (weak, nonatomic) IBOutlet UIButton *infoLoginButton; +@property (weak, nonatomic) IBOutlet UIRoundBorderedButton *linphoneLoginButton; @property(nonatomic, strong) IBOutlet UIView *welcomeView; @property(nonatomic, strong) IBOutlet UIView *createAccountView; @@ -84,7 +85,6 @@ - (void)fillDefaultValues; - (IBAction)onBackClick:(id)sender; -- (IBAction)onDialerClick:(id)sender; - (IBAction)onGotoCreateAccountClick:(id)sender; - (IBAction)onGotoLinphoneLoginClick:(id)sender; diff --git a/Classes/AssistantView.m b/Classes/AssistantView.m index caba5b1e6..3fcba82d0 100644 --- a/Classes/AssistantView.m +++ b/Classes/AssistantView.m @@ -173,7 +173,7 @@ static UICompositeViewDescription *compositeDescription = nil; } - (void)loadAssistantConfig:(NSString *)rcFilename { - linphone_config_load_from_xml_file(linphone_core_get_config(LC), + linphone_core_load_config_from_xml(LC, [LinphoneManager bundleFile:rcFilename].UTF8String); [self changeView:nextView back:FALSE animation:TRUE]; } @@ -446,7 +446,6 @@ static UICompositeViewDescription *compositeDescription = nil; static BOOL placement_done = NO; // indicates if the button placement has been done in the assistant choice view - _backButton.hidden = (view == _welcomeView); if (view == _welcomeView) { BOOL show_logo = [LinphoneManager.instance lpConfigBoolForKey:@"show_assistant_logo_in_choice_view_preference"]; @@ -849,7 +848,7 @@ static UICompositeViewDescription *compositeDescription = nil; } case LinphoneRegistrationFailed: { _waitView.hidden = true; - UIAlertController *errView = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Registration failure", nil) + UIAlertController *errView = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Connection failure", nil) message:message preferredStyle:UIAlertControllerStyleAlert]; @@ -923,7 +922,7 @@ static UICompositeViewDescription *compositeDescription = nil; - (void)showErrorPopup:(const char *)error { const char *err = error ? error : ""; if (strcmp(err, "ERROR_BAD_CREDENTIALS") == 0) { - UIAlertController *errView = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Registration failure", nil) + UIAlertController *errView = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Connection failure", nil) message:[AssistantView StringForXMLRPCError:err] preferredStyle:UIAlertControllerStyleAlert]; @@ -1010,6 +1009,10 @@ static UICompositeViewDescription *compositeDescription = nil; defaultAction.accessibilityLabel = @"PopUpResp"; [self presentViewController:errView animated:YES completion:nil]; } + + // enable linphoneLoginButton if error + [_linphoneLoginButton setBackgroundColor:[UIColor clearColor]]; + _linphoneLoginButton.enabled = YES; } - (void)isAccountUsed:(LinphoneAccountCreatorStatus)status withResp:(const char *)resp { @@ -1309,8 +1312,13 @@ void assistant_is_account_linked(LinphoneAccountCreator *creator, LinphoneAccoun } - (IBAction)onLinphoneLoginClick:(id)sender { - ONCLICKBUTTON(sender, 100, { - _waitView.hidden = NO; + // disable button after first click + _linphoneLoginButton.enabled = NO; + [_linphoneLoginButton setBackgroundColor:[UIColor lightGrayColor]]; + _waitView.hidden = NO; + + dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (100 * NSEC_PER_MSEC)); + dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ ((UITextField *)[self findView:ViewElement_SMSCode inView:_contentView ofType:UITextField.class]).text = @""; _activationTitle.text = @"USE LINPHONE ACCOUNT"; if ((linphone_account_creator_get_phone_number(account_creator) != NULL) && @@ -1324,7 +1332,7 @@ void assistant_is_account_linked(LinphoneAccountCreator *creator, LinphoneAccoun // if not, propose it to the user linphone_account_creator_is_account_exist(account_creator); } - }); + }); } - (IBAction)onLoginClick:(id)sender { @@ -1567,15 +1575,19 @@ void assistant_is_account_linked(LinphoneAccountCreator *creator, LinphoneAccoun UIView *view = [historyViews lastObject]; [historyViews removeLastObject]; [self changeView:view back:TRUE animation:TRUE]; + } else if (currentView == _welcomeView) { + [PhoneMainView.instance popCurrentView]; } else { [self changeView:_welcomeView back:TRUE animation:TRUE]; } + } else { + [self onDialerClick:nil]; } } - (IBAction)onDialerClick:(id)sender { - [PhoneMainView.instance popToView:DialerView.compositeViewDescription]; -} + [PhoneMainView.instance popToView:DialerView.compositeViewDescription]; + } - (IBAction)onLinkTap:(id)sender { NSString *url = @"http://linphone.org/free-sip-service.html&action=recover"; diff --git a/Classes/Base.lproj/AboutView.xib b/Classes/Base.lproj/AboutView.xib index e197c4275..e209e95e9 100644 --- a/Classes/Base.lproj/AboutView.xib +++ b/Classes/Base.lproj/AboutView.xib @@ -1,11 +1,11 @@ - + - + @@ -38,14 +38,14 @@ - @@ -169,24 +178,10 @@ - - + + - - @@ -197,7 +192,7 @@ - + @@ -211,7 +206,7 @@ - + @@ -220,19 +215,19 @@ - + @@ -280,24 +275,41 @@ + + + - + - - - - + + - + - - - - + + + + diff --git a/Classes/Base.lproj/CallView.strings b/Classes/Base.lproj/CallView.strings index d3447624d..7eab58bf3 100644 Binary files a/Classes/Base.lproj/CallView.strings and b/Classes/Base.lproj/CallView.strings differ diff --git a/Classes/Base.lproj/CallView.xib b/Classes/Base.lproj/CallView.xib index ab5f35348..b450f364c 100644 --- a/Classes/Base.lproj/CallView.xib +++ b/Classes/Base.lproj/CallView.xib @@ -1,11 +1,11 @@ - - + + - + @@ -26,6 +26,7 @@ + @@ -42,6 +43,8 @@ + + @@ -70,36 +73,36 @@ - + - + - + - + - + @@ -255,11 +269,11 @@ - + - + - + - - + - + - + - + @@ -860,11 +898,11 @@ - + - + - + - - + + + +YnBsaXN0MDDUAQIDBAUGVVZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3ASAAGGoK8QEgcI +ExQZHh8jJCsuMTtDR0tPUlUkbnVsbNUJCgsMDQ4PEBESVk5TU2l6ZVYkY2xhc3NcTlNJbWFnZUZsYWdz +Vk5TUmVwc1dOU0NvbG9ygAKAERIgwAAAgAOAC1h7MzMsIDMzfdIVChYYWk5TLm9iamVjdHOhF4AEgArS +FQoaHaIbHIAFgAaACRAA0iAKISJfEBROU1RJRkZSZXByZXNlbnRhdGlvboAHgAhPERm6TU0AKgAAEQwA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQMDAxUG +BgYmBgYGIgICAgwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAACBgYGIQkJCTYJCQkxCQkJMwkJCTMDAwMUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAADAwMVCgoKNgUFBSABAQEIAgICDAgICCsJCQkxAQEBBwAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAMDAxQA +AAAGAAAAAAAAAAAAAAAAAAAAAAAAAAAGBgYjCAgIMAAAAAUAAAAAAAAAAAICAhEKCgo2AgICEgAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAgICDgoKCjUHBwcuAwMDEgAAAAEAAAAAAAAAAAAAAAAGBgYhCAgIMQEBAQcAAAAAAAAAAAMDAxQK +Cgo2AgICEAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAwMDDwkJCTIJCQk1CQkJNAQEBBkAAAAAAAAAAAAAAAAFBQUbCgoKNwUFBR8A +AAAAAAAABAcHBywJCQkzAgICDAAAAAAAAAAAAQEBBwgICCsJCQktBgYGIgICAhEAAAACAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEFBQUaCQkJMgkJCTQJCQkzCgoKNQQEBBcAAAAAAAAAAAQEBBkJ +CQkzCAgIMQMDAxcAAAAAAAAAAwUFBSIJCQk0BwcHLgICAg0AAAAAAAAABQUFBSEHBwcpCQkJMgoKCjYH +BwcoAQEBCgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQYGBh4KCgo2BwcHJwcHBygKCgo2BwcHJwAAAAIA +AAAAAwMDFAoKCjYHBwcnAQEBCQAAAAAAAAAAAAAAAAAAAAECAgISCQkJMAgICC8BAQEHAAAAAAAAAAAA +AAABAAAABgUFBRsJCQkzCAgILwICAgoAAAAAAAAAAAAAAAAAAAAAAwMDFgoKCjYGBgYhAAAAAgMDAxMI +CAguAgICCgAAAAAAAAACBwcHLAcHBywAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgICEAoKCjQF +BQUdAAAAAAAAAAAAAAAAAAAAAAAAAAADAwMPCQkJMggICCoAAAACAAAAAAAAAAAAAAAEBwcHLgcHBywA +AAAEAAAAAAAAAAAAAAACAAAAAAAAAAACAgIJCQkJNAUFBRwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAQkJCS0HBwcoAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAABAQEGgoKCjUFBQUhBQUFHwMDAxID +AwMSCgoKNgQEBBYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEICQkJMwgICC8FBQUiBQUFGgMDAxUD +AwMUAwMDFAQEBBYFBQUcBwcHJQkJCTUHBwcnAAAAAAAAAAAAAAAAAAAAAAAAAAEFBQUfCAgIMAkJCTMJ +CQk0CgoKNwUFBR8GBgYhCQkJNAEBAQoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBAQEGAcHBykI +CAgwCQkJMwkJCTUJCQk1CQkJNQkJCTQJCQkzCAgILwYGBiQCAgIOAAAAAAAAAAAAAAAAAAAAAAAAAAEF +BQUfCQkJNAkJCTQJCQk0BwcHKgAAAAQGBgYlCAgILwAAAAYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAFAgICCwMDAw8CAgIRAwMDDwMDAw4BAQEJAAAAAwAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAwMDEwkJCS0JCQkyAwMDDgAAAAABAQEHAgICDAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAwAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAMAAAABAAAAAAAAAAAAAAAAAAAAAAEBAQYCAgIMAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAEBAQcFBQUgBwcHLAgICCsFBQUcAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAACAgIKBgYGIwcHBywHBwcqBAQEGAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAABQgICCoKCgo1CAgIKAgICCsJCQk2BgYGIwAAAAEAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAEBAQkICAgvCQkJMwcHBygHBwcsCgoKNgUFBRwAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEFwoKCjYEBAQXAAAAAAAAAAIFBQUfCQkJNQMDAw8A +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUFBR8JCQk0AgICEQAAAAAAAAADBgYGJgkJCTIB +AQEJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQUFIAkJCTIAAAAEAAAAAAAAAAAC +AgIMCQkJNQQEBBcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcHBykICAgrAAAAAQAAAAAA +AAAAAwMDFAkJCTUCAgIQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEGAkJCTUC +AgIQAAAAAAAAAAAEBAQYCQkJNQICAhAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUFBSEJ +CQkxAQEBCgAAAAAAAAABBQUFIAkJCTMBAQEKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAADBgYGHgoKCjcGBgYmAAAAAAAAAAIICAguCQkJNQQEBBgAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAABQYGBiUKCgo4BQUFHwAAAAABAQEICQkJMggICDICAgIRAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAMGBgYjCQkJNgcHBycCAgINAAAAAAAAAAADAwMSCAgIKwkJCTYFBQUdAAAAAQAAAAAA +AAAAAAAAAAAAAAAAAAAGBwcHKgkJCTUGBgYjAQEBCgAAAAAAAAABAwMDFwgICC4JCQk0BAQEFgAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAUFBRoKCgo2BQUFHQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAABAYGBiQK +Cgo1AgICEQAAAAAAAAAAAAAAAAAAAAAGBgYhCgoKNQQEBBcAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQgI +CAgqCQkJMwICAgsAAAAAAAAAAAAAAAAAAAAAAAAABAkJCS0HBwcpAAAAAQAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAUICAgvBwcHJwAAAAAAAAAAAAAAAAEBAQgJCQkyBQUFIgAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAABAQEKCQkJNAUFBR4AAAAAAAAAAAAAAAAAAAAAAQEBCAkJCTEGBgYjAAAABAAAAAEA +AAAAAAAAAAAAAAAAAAAAAAAAAQEBAQYICAgqBwcHLQAAAAIAAAAAAAAAAAICAg0KCgo1BQUFHAAAAAMA +AAABAAAAAAAAAAAAAAAAAAAAAAAAAAIBAQEKCAgILwYGBiYAAAAAAAAAAAAAAAAAAAAAAAAABAcHBywJ +CQk1CAgIMQgICCkGBgYkBgYGIwYGBiMGBgYkCAgIKgkJCTIJCQk1BwcHJgAAAAAAAAAAAAAAAAEBAQkI +CAgwCQkJNQgICC8HBwcoBgYGIwYGBiMGBgYjBgYGJQcHBywJCQkzCQkJNgYGBh4AAAAAAAAAAAAAAAAA +AAAAAAAAAAEBAQkDAwMWBQUFIggICCoICAgwCAgIMQgICDAICAgvBwcHKQUFBSADAwMUAQEBBgAAAAAA +AAAAAAAAAAAAAAACAgIMBAQEGAYGBiMICAgrCAgIMAgICDAICAgwCAgILgcHBygFBQUeAwMDEgAAAAQA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAACAAAAAwAAAAIAAAACAAAAAQAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAgAAAAMAAAACAAAAAgAAAAEA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAQBAQEJAwMDDwAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAACBQUFHwcHBy0JCQkyCQkJNQMDAw8AAAAAAAAAAAAAAAAAAAAABAQEFwUFBR8A +AAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADCAgILgkJCTQJCQk0BwcHLQEBAQgAAAACAAAABQICAg0G +BgYkCgoKNgcHBycAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABgYGJQkJCTUJCQk0CQkJNAkJCS0I +CAgqCAgILgkJCTUJCQkzBAQEHwAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQUFHAoKCjYF +BQUfBQUFGgcHByYHBwcpBwcHJgUFBRsCAgIKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAQEBCwYGBiEAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAEAAAMAAAABACEAAAEBAAMAAAABACEA +AAECAAMAAAAEAAAR0gEDAAMAAAABAAEAAAEGAAMAAAABAAIAAAEKAAMAAAABAAEAAAERAAQAAAABAAAA +CAESAAMAAAABAAEAAAEVAAMAAAABAAQAAAEWAAMAAAABACEAAAEXAAQAAAABAAARBAEcAAMAAAABAAEA +AAEoAAMAAAABAAIAAAFSAAMAAAABAAEAAAFTAAMAAAAEAAAR2odzAAcAAAfYAAAR4gAAAAAACAAIAAgA +CAABAAEAAQABAAAH2GFwcGwCIAAAbW50clJHQiBYWVogB9kAAgAZAAsAGgALYWNzcEFQUEwAAAAAYXBw +bAAAAAAAAAAAAAAAAAAAAAAAAPbWAAEAAAAA0y1hcHBsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAALZGVzYwAAAQgAAABvZHNjbQAAAXgAAAWcY3BydAAABxQAAAA4d3Rw +dAAAB0wAAAAUclhZWgAAB2AAAAAUZ1hZWgAAB3QAAAAUYlhZWgAAB4gAAAAUclRSQwAAB5wAAAAOY2hh +ZAAAB6wAAAAsYlRSQwAAB5wAAAAOZ1RSQwAAB5wAAAAOZGVzYwAAAAAAAAAUR2VuZXJpYyBSR0IgUHJv +ZmlsZQAAAAAAAAAAAAAAFEdlbmVyaWMgUkdCIFByb2ZpbGUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAG1sdWMAAAAAAAAAHwAAAAxza1NLAAAAKAAAAYRkYURLAAAA +LgAAAaxjYUVTAAAAJAAAAdp2aVZOAAAAJAAAAf5wdEJSAAAAJgAAAiJ1a1VBAAAAKgAAAkhmckZVAAAA +KAAAAnJodUhVAAAAKAAAApp6aFRXAAAAFgAAAsJuYk5PAAAAJgAAAthjc0NaAAAAIgAAAv5oZUlMAAAA +HgAAAyBpdElUAAAAKAAAAz5yb1JPAAAAJAAAA2ZkZURFAAAALAAAA4prb0tSAAAAFgAAA7ZzdlNFAAAA +JgAAAth6aENOAAAAFgAAA8xqYUpQAAAAGgAAA+JlbEdSAAAAIgAAA/xwdFBPAAAAJgAABB5ubE5MAAAA +KAAABERlc0VTAAAAJgAABB50aFRIAAAAJAAABGx0clRSAAAAIgAABJBmaUZJAAAAKAAABLJockhSAAAA +KAAABNpwbFBMAAAALAAABQJydVJVAAAAIgAABS5hckVHAAAAJgAABVBlblVTAAAAJgAABXYAVgFhAGUA +bwBiAGUAYwBuAP0AIABSAEcAQgAgAHAAcgBvAGYAaQBsAEcAZQBuAGUAcgBlAGwAIABSAEcAQgAtAGIA +ZQBzAGsAcgBpAHYAZQBsAHMAZQBQAGUAcgBmAGkAbAAgAFIARwBCACAAZwBlAG4A6AByAGkAYwBDHqUA +dQAgAGgA7ABuAGgAIABSAEcAQgAgAEMAaAB1AG4AZwBQAGUAcgBmAGkAbAAgAFIARwBCACAARwBlAG4A +6QByAGkAYwBvBBcEMAQzBDAEOwRMBD0EOAQ5ACAEPwRABD4ERAQwBDkEOwAgAFIARwBCAFAAcgBvAGYA +aQBsACAAZwDpAG4A6QByAGkAcQB1AGUAIABSAFYAQgDBAGwAdABhAGwA4QBuAG8AcwAgAFIARwBCACAA +cAByAG8AZgBpAGyQGnUoACAAUgBHAEIAIIJyX2ljz4/wAEcAZQBuAGUAcgBpAHMAawAgAFIARwBCAC0A +cAByAG8AZgBpAGwATwBiAGUAYwBuAP0AIABSAEcAQgAgAHAAcgBvAGYAaQBsBeQF6AXVBeQF2QXcACAA +UgBHAEIAIAXbBdwF3AXZAFAAcgBvAGYAaQBsAG8AIABSAEcAQgAgAGcAZQBuAGUAcgBpAGMAbwBQAHIA +bwBmAGkAbAAgAFIARwBCACAAZwBlAG4AZQByAGkAYwBBAGwAbABnAGUAbQBlAGkAbgBlAHMAIABSAEcA +QgAtAFAAcgBvAGYAaQBsx3y8GAAgAFIARwBCACDVBLhc0wzHfGZukBoAIABSAEcAQgAgY8+P8GWHTvZO +AIIsACAAUgBHAEIAIDDXMO0w1TChMKQw6wOTA7UDvQO5A7oDzAAgA8ADwQO/A8YDrwO7ACAAUgBHAEIA +UABlAHIAZgBpAGwAIABSAEcAQgAgAGcAZQBuAOkAcgBpAGMAbwBBAGwAZwBlAG0AZQBlAG4AIABSAEcA +QgAtAHAAcgBvAGYAaQBlAGwOQg4bDiMORA4fDiUOTAAgAFIARwBCACAOFw4xDkgOJw5EDhsARwBlAG4A +ZQBsACAAUgBHAEIAIABQAHIAbwBmAGkAbABpAFkAbABlAGkAbgBlAG4AIABSAEcAQgAtAHAAcgBvAGYA +aQBpAGwAaQBHAGUAbgBlAHIAaQENAGsAaQAgAFIARwBCACAAcAByAG8AZgBpAGwAVQBuAGkAdwBlAHIA +cwBhAGwAbgB5ACAAcAByAG8AZgBpAGwAIABSAEcAQgQeBDEESQQ4BDkAIAQ/BEAEPgREBDgEOwRMACAA +UgBHAEIGRQZEBkEAIAYqBjkGMQZKBkEAIABSAEcAQgAgBicGRAY5BicGRQBHAGUAbgBlAHIAaQBjACAA +UgBHAEIAIABQAHIAbwBmAGkAbABldGV4dAAAAABDb3B5cmlnaHQgMjAwNyBBcHBsZSBJbmMuLCBhbGwg +cmlnaHRzIHJlc2VydmVkLgBYWVogAAAAAAAA81IAAQAAAAEWz1hZWiAAAAAAAAB0TQAAPe4AAAPQWFla +IAAAAAAAAFp1AACscwAAFzRYWVogAAAAAAAAKBoAABWfAAC4NmN1cnYAAAAAAAAAAQHNAABzZjMyAAAA +AAABDEIAAAXe///zJgAAB5IAAP2R///7ov///aMAAAPcAADAbNIlJicoWiRjbGFzc25hbWVYJGNsYXNz +ZXNfEBBOU0JpdG1hcEltYWdlUmVwoycpKlpOU0ltYWdlUmVwWE5TT2JqZWN00iUmLC1XTlNBcnJheaIs +KtIlJi8wXk5TTXV0YWJsZUFycmF5oy8sKtUyMzQ1CjY3ODk6V05TV2hpdGVcTlNDb21wb25lbnRzXE5T +Q29sb3JTcGFjZV8QEk5TQ3VzdG9tQ29sb3JTcGFjZUQwIDAAQzAgMBADgAyAENQ8PT4KP0BBQlROU0lE +VU5TSUNDV05TTW9kZWwQCYANEACAD9JECkVGV05TLmRhdGFPERFoAAARaGFwcGwCAAAAbW50ckdSQVlY +WVogB9wACAAXAA8ALgAPYWNzcEFQUEwAAAAAbm9uZQAAAAAAAAAAAAAAAAAAAAAAAPbWAAEAAAAA0y1h +cHBsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFZGVzYwAAAMAA +AAB5ZHNjbQAAATwAAAfoY3BydAAACSQAAAAjd3RwdAAACUgAAAAUa1RSQwAACVwAAAgMZGVzYwAAAAAA +AAAfR2VuZXJpYyBHcmF5IEdhbW1hIDIuMiBQcm9maWxlAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAG1sdWMA +AAAAAAAAHwAAAAxza1NLAAAALgAAAYRkYURLAAAAOAAAAbJjYUVTAAAAOAAAAep2aVZOAAAAQAAAAiJw +dEJSAAAASgAAAmJ1a1VBAAAALAAAAqxmckZVAAAAPgAAAthodUhVAAAANAAAAxZ6aFRXAAAAHgAAA0pu +Yk5PAAAAOgAAA2hjc0NaAAAAKAAAA6JoZUlMAAAAJAAAA8ppdElUAAAATgAAA+5yb1JPAAAAKgAABDxk +ZURFAAAATgAABGZrb0tSAAAAIgAABLRzdlNFAAAAOAAAAbJ6aENOAAAAHgAABNZqYUpQAAAAJgAABPRl +bEdSAAAAKgAABRpwdFBPAAAAUgAABURubE5MAAAAQAAABZZlc0VTAAAATAAABdZ0aFRIAAAAMgAABiJ0 +clRSAAAAJAAABlRmaUZJAAAARgAABnhockhSAAAAPgAABr5wbFBMAAAASgAABvxydVJVAAAAOgAAB0Zl +blVTAAAAPAAAB4BhckVHAAAALAAAB7wAVgFhAGUAbwBiAGUAYwBuAOEAIABzAGkAdgDhACAAZwBhAG0A +YQAgADIALAAyAEcAZQBuAGUAcgBpAHMAawAgAGcAcgDlACAAMgAsADIAIABnAGEAbQBtAGEAcAByAG8A +ZgBpAGwARwBhAG0AbQBhACAAZABlACAAZwByAGkAcwBvAHMAIABnAGUAbgDoAHIAaQBjAGEAIAAyAC4A +MgBDHqUAdQAgAGgA7ABuAGgAIABNAOAAdQAgAHgA4QBtACAAQwBoAHUAbgBnACAARwBhAG0AbQBhACAA +MgAuADIAUABlAHIAZgBpAGwAIABHAGUAbgDpAHIAaQBjAG8AIABkAGEAIABHAGEAbQBhACAAZABlACAA +QwBpAG4AegBhAHMAIAAyACwAMgQXBDAEMwQwBDsETAQ9BDAAIABHAHIAYQB5AC0EMwQwBDwEMAAgADIA +LgAyAFAAcgBvAGYAaQBsACAAZwDpAG4A6QByAGkAcQB1AGUAIABnAHIAaQBzACAAZwBhAG0AbQBhACAA +MgAsADIAwQBsAHQAYQBsAOEAbgBvAHMAIABzAHoA/AByAGsAZQAgAGcAYQBtAG0AYQAgADIALgAykBp1 +KHBwlo5RSV6mACAAMgAuADIAIIJyX2ljz4/wAEcAZQBuAGUAcgBpAHMAawAgAGcAcgDlACAAZwBhAG0A +bQBhACAAMgAsADIALQBwAHIAbwBmAGkAbABPAGIAZQBjAG4A4QAgAWEAZQBkAOEAIABnAGEAbQBhACAA +MgAuADIF0gXQBd4F1AAgBdAF5AXVBegAIAXbBdwF3AXZACAAMgAuADIAUAByAG8AZgBpAGwAbwAgAGcA +cgBpAGcAaQBvACAAZwBlAG4AZQByAGkAYwBvACAAZABlAGwAbABhACAAZwBhAG0AbQBhACAAMgAsADIA +RwBhAG0AYQAgAGcAcgBpACAAZwBlAG4AZQByAGkAYwEDACAAMgAsADIAQQBsAGwAZwBlAG0AZQBpAG4A +ZQBzACAARwByAGEAdQBzAHQAdQBmAGUAbgAtAFAAcgBvAGYAaQBsACAARwBhAG0AbQBhACAAMgAsADLH +fLwYACDWjMDJACCsELnIACAAMgAuADIAINUEuFzTDMd8Zm6QGnBwXqZ8+2VwACAAMgAuADIAIGPPj/Bl +h072TgCCLDCwMOwwpDCsMPMw3gAgADIALgAyACAw1zDtMNUwoTCkMOsDkwO1A70DuQO6A8wAIAOTA7oD +wQO5ACADkwOsA7wDvAOxACAAMgAuADIAUABlAHIAZgBpAGwAIABnAGUAbgDpAHIAaQBjAG8AIABkAGUA +IABjAGkAbgB6AGUAbgB0AG8AcwAgAGQAYQAgAEcAYQBtAG0AYQAgADIALAAyAEEAbABnAGUAbQBlAGUA +bgAgAGcAcgBpAGoAcwAgAGcAYQBtAG0AYQAgADIALAAyAC0AcAByAG8AZgBpAGUAbABQAGUAcgBmAGkA +bAAgAGcAZQBuAOkAcgBpAGMAbwAgAGQAZQAgAGcAYQBtAG0AYQAgAGQAZQAgAGcAcgBpAHMAZQBzACAA +MgAsADIOIw4xDgcOKg41DkEOAQ4hDiEOMg5ADgEOIw4iDkwOFw4xDkgOJw5EDhsAIAAyAC4AMgBHAGUA +bgBlAGwAIABHAHIAaQAgAEcAYQBtAGEAIAAyACwAMgBZAGwAZQBpAG4AZQBuACAAaABhAHIAbQBhAGEA +bgAgAGcAYQBtAG0AYQAgADIALAAyACAALQBwAHIAbwBmAGkAaQBsAGkARwBlAG4AZQByAGkBDQBrAGkA +IABHAHIAYQB5ACAARwBhAG0AbQBhACAAMgAuADIAIABwAHIAbwBmAGkAbABVAG4AaQB3AGUAcgBzAGEA +bABuAHkAIABwAHIAbwBmAGkAbAAgAHMAegBhAHIAbwFbAGMAaQAgAGcAYQBtAG0AYQAgADIALAAyBB4E +MQRJBDAETwAgBEEENQRABDAETwAgBDMEMAQ8BDwEMAAgADIALAAyAC0EPwRABD4ERAQ4BDsETABHAGUA +bgBlAHIAaQBjACAARwByAGEAeQAgAEcAYQBtAG0AYQAgADIALgAyACAAUAByAG8AZgBpAGwAZQY6BicG +RQYnACAAMgAuADIAIAZEBkgGRgAgBjEGRQYnBi8GSgAgBjkGJwZFdGV4dAAAAABDb3B5cmlnaHQgQXBw +bGUgSW5jLiwgMjAxMgAAWFlaIAAAAAAAAPNRAAEAAAABFsxjdXJ2AAAAAAAABAAAAAAFAAoADwAUABkA +HgAjACgALQAyADcAOwBAAEUASgBPAFQAWQBeAGMAaABtAHIAdwB8AIEAhgCLAJAAlQCaAJ8ApACpAK4A +sgC3ALwAwQDGAMsA0ADVANsA4ADlAOsA8AD2APsBAQEHAQ0BEwEZAR8BJQErATIBOAE+AUUBTAFSAVkB +YAFnAW4BdQF8AYMBiwGSAZoBoQGpAbEBuQHBAckB0QHZAeEB6QHyAfoCAwIMAhQCHQImAi8COAJBAksC +VAJdAmcCcQJ6AoQCjgKYAqICrAK2AsECywLVAuAC6wL1AwADCwMWAyEDLQM4A0MDTwNaA2YDcgN+A4oD +lgOiA64DugPHA9MD4APsA/kEBgQTBCAELQQ7BEgEVQRjBHEEfgSMBJoEqAS2BMQE0wThBPAE/gUNBRwF +KwU6BUkFWAVnBXcFhgWWBaYFtQXFBdUF5QX2BgYGFgYnBjcGSAZZBmoGewaMBp0GrwbABtEG4wb1BwcH +GQcrBz0HTwdhB3QHhgeZB6wHvwfSB+UH+AgLCB8IMghGCFoIbgiCCJYIqgi+CNII5wj7CRAJJQk6CU8J +ZAl5CY8JpAm6Cc8J5Qn7ChEKJwo9ClQKagqBCpgKrgrFCtwK8wsLCyILOQtRC2kLgAuYC7ALyAvhC/kM +EgwqDEMMXAx1DI4MpwzADNkM8w0NDSYNQA1aDXQNjg2pDcMN3g34DhMOLg5JDmQOfw6bDrYO0g7uDwkP +JQ9BD14Peg+WD7MPzw/sEAkQJhBDEGEQfhCbELkQ1xD1ERMRMRFPEW0RjBGqEckR6BIHEiYSRRJkEoQS +oxLDEuMTAxMjE0MTYxODE6QTxRPlFAYUJxRJFGoUixStFM4U8BUSFTQVVhV4FZsVvRXgFgMWJhZJFmwW +jxayFtYW+hcdF0EXZReJF64X0hf3GBsYQBhlGIoYrxjVGPoZIBlFGWsZkRm3Gd0aBBoqGlEadxqeGsUa +7BsUGzsbYxuKG7Ib2hwCHCocUhx7HKMczBz1HR4dRx1wHZkdwx3sHhYeQB5qHpQevh7pHxMfPh9pH5Qf +vx/qIBUgQSBsIJggxCDwIRwhSCF1IaEhziH7IiciVSKCIq8i3SMKIzgjZiOUI8Ij8CQfJE0kfCSrJNol +CSU4JWgllyXHJfcmJyZXJocmtyboJxgnSSd6J6sn3CgNKD8ocSiiKNQpBik4KWspnSnQKgIqNSpoKpsq +zysCKzYraSudK9EsBSw5LG4soizXLQwtQS12Last4S4WLkwugi63Lu4vJC9aL5Evxy/+MDUwbDCkMNsx +EjFKMYIxujHyMioyYzKbMtQzDTNGM38zuDPxNCs0ZTSeNNg1EzVNNYc1wjX9Njc2cjauNuk3JDdgN5w3 +1zgUOFA4jDjIOQU5Qjl/Obw5+To2OnQ6sjrvOy07azuqO+g8JzxlPKQ84z0iPWE9oT3gPiA+YD6gPuA/ +IT9hP6I/4kAjQGRApkDnQSlBakGsQe5CMEJyQrVC90M6Q31DwEQDREdEikTORRJFVUWaRd5GIkZnRqtG +8Ec1R3tHwEgFSEtIkUjXSR1JY0mpSfBKN0p9SsRLDEtTS5pL4kwqTHJMuk0CTUpNk03cTiVObk63TwBP +SU+TT91QJ1BxULtRBlFQUZtR5lIxUnxSx1MTU19TqlP2VEJUj1TbVShVdVXCVg9WXFapVvdXRFeSV+BY +L1h9WMtZGllpWbhaB1pWWqZa9VtFW5Vb5Vw1XIZc1l0nXXhdyV4aXmxevV8PX2Ffs2AFYFdgqmD8YU9h +omH1YklinGLwY0Njl2PrZEBklGTpZT1lkmXnZj1mkmboZz1nk2fpaD9olmjsaUNpmmnxakhqn2r3a09r +p2v/bFdsr20IbWBtuW4SbmtuxG8eb3hv0XArcIZw4HE6cZVx8HJLcqZzAXNdc7h0FHRwdMx1KHWFdeF2 +Pnabdvh3VnezeBF4bnjMeSp5iXnnekZ6pXsEe2N7wnwhfIF84X1BfaF+AX5ifsJ/I3+Ef+WAR4CogQqB +a4HNgjCCkoL0g1eDuoQdhICE44VHhauGDoZyhteHO4efiASIaYjOiTOJmYn+imSKyoswi5aL/IxjjMqN +MY2Yjf+OZo7OjzaPnpAGkG6Q1pE/kaiSEZJ6kuOTTZO2lCCUipT0lV+VyZY0lp+XCpd1l+CYTJi4mSSZ +kJn8mmia1ZtCm6+cHJyJnPedZJ3SnkCerp8dn4uf+qBpoNihR6G2oiailqMGo3aj5qRWpMelOKWpphqm +i6b9p26n4KhSqMSpN6mpqhyqj6sCq3Wr6axcrNCtRK24ri2uoa8Wr4uwALB1sOqxYLHWskuywrM4s660 +JbSctRO1irYBtnm28Ldot+C4WbjRuUq5wro7urW7LrunvCG8m70VvY++Cr6Evv+/er/1wHDA7MFnwePC +X8Lbw1jD1MRRxM7FS8XIxkbGw8dBx7/IPci8yTrJuco4yrfLNsu2zDXMtc01zbXONs62zzfPuNA50LrR +PNG+0j/SwdNE08bUSdTL1U7V0dZV1tjXXNfg2GTY6Nls2fHadtr724DcBdyK3RDdlt4c3qLfKd+v4Dbg +veFE4cziU+Lb42Pj6+Rz5PzlhOYN5pbnH+ep6DLovOlG6dDqW+rl63Dr++yG7RHtnO4o7rTvQO/M8Fjw +5fFy8f/yjPMZ86f0NPTC9VD13vZt9vv3ivgZ+Kj5OPnH+lf65/t3/Af8mP0p/br+S/7c/23//4AO0iUm +SEldTlNNdXRhYmxlRGF0YaNISipWTlNEYXRh0iUmTE1cTlNDb2xvclNwYWNlok4qXE5TQ29sb3JTcGFj +ZdIlJlBRV05TQ29sb3KiUCrSJSZTVFdOU0ltYWdlolMqXxAPTlNLZXllZEFyY2hpdmVy0VdYVHJvb3SA +AQAIABEAGgAjAC0AMgA3AEwAUgBdAGQAawB4AH8AhwCJAIsAkACSAJQAnQCiAK0ArwCxALMAuAC7AL0A +vwDBAMMAyADfAOEA4xqhGqYasRq6Gs0a0RrcGuUa6hryGvUa+hsJGw0bGBsgGy0bOhtPG1QbWBtaG1wb +XhtnG2wbcht6G3wbfhuAG4IbhxuPLPss/S0CLRAtFC0bLSAtLS0wLT0tQi1KLU0tUi1aLV0tby1yLXcA +AAAAAAACAQAAAAAAAABZAAAAAAAAAAAAAAAAAAAteQ + + + + +YnBsaXN0MDDUAQIDBAUGVVZYJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3ASAAGGoK8QEgcI +ExQZHh8jJCsuMTtDR0tPUlUkbnVsbNUJCgsMDQ4PEBESVk5TU2l6ZVYkY2xhc3NcTlNJbWFnZUZsYWdz +Vk5TUmVwc1dOU0NvbG9ygAKAERIgwAAAgAOAC1h7NDAsIDM2fdIVChYYWk5TLm9iamVjdHOhF4AEgArS +FQoaHaIbHIAFgAaACRAA0iAKISJfEBROU1RJRkZSZXByZXNlbnRhdGlvboAHgAhPER82TU0AKgAAFogA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAUAAAYYAAAZGAAAGQUAAAYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADsAATyb +AASeyAAFzMgABcydAASgPwABQQEAAAIAAAAAAAAAAAAAAAAAAAAAAgICAgEBAQEAAAAACgoKCgQEBAQA +AAAAAAAAAAkJCQkJCQkJAAAAAAAAAAAAAAAAAAAAAAAAAAAJCQkJBwcHBwAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEkAAkvYAAbc+wAH//sAB//7AAf/+wAH/9sABt9Q +AAJSAAAAAAAAAAAAAAAAAAAAAFtbW1uioqKimZmZmdvb29tgYGBiCAgICIeHh4nJycnJycnJynp6enwH +BwcHAAAAABISEhKTk5OV0tLS08vLy8x4eHh6BwcHBwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAABYAABe8AAXA+wAH//sAB//7AAf/+wAH//sAB//7AAf/wAAFxBoAABsAAAAAAAAAAAAAAABw +cHBw/////4GBgYMoKCgqDQ0NDYiIiIqurq6vFxcXFxcXFxm5ubm5cnJycgAAAACYmJiZwcHBwSgoKCgt +LS0v09PT1FdXV1cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABEAAFG6wAG7/sAB//7 +AAf/+wAH//sAB//7AAf/+wAH/+wABvBKAAJMAAAAAAAAAAAAAAAAdHR0dNDQ0NAAAAAAAAAAAAcHBwfU +1NTVkZGRk2NjY2NjY2Njo6Ojo8jIyMgWFhYW3d3d3Ts7Oz0AAAAAAAAAABcXFxkVFRUVAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUgACVPIABvb7AAf/+wAH//sAB//7AAf/+wAH//sAB//0 +AAb4XAACXgAAAAAAAAAAAAAAAHZ2dna3t7e3AAAAAAAAAAAODg4O4ODg4aGhoaGMjIyMjIyMjIaGhoZS +UlJUHBwcHOHh4eIqKioqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAADgAATnkAAbo+wAH//sAB//7AAf/+wAH//sAB//7AAf/5gAG6j4AAT8AAAAAAAAAAAAAAAB2 +dnZ2uLi4uAAAAAAAAAAABAQEBMLCwsNiYmJiAAAAAAAAAAAzMzMzXl5eXgkJCQnNzc3OaWlpaQAAAAAA +AAAAcXFxc1lZWVsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALAAAMogAEpfsAB//7 +AAf/+wAH//sAB//7AAf/+wAH/6YABKkPAAAQAAAAAAAAAAAAAAAAeHh4eLy8vLwAAAAAAAAAAAAAAABI +SEhI19fX2JmZmZqLi4uN2tra22JiYmQAAAAAUVFRU9/f39+bm5ucnp6en9zc3N05OTk5AAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACoAASu0AAW39QAG+fsAB//7AAf/9gAG+rYABbks +AAEtAAAAAAAAAAAAAAAAAAAAACoqKipBQUFDAAAAAAAAAAAAAAAAAAAAACYmJihubm5wcXFxczIyMjQA +AAAAAAAAAAAAAAAwMDAwdHR0dGxsbG4jIyMjAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAGQAAGmMAAmWWAASZlQAEmGUAAmccAAAdAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAABQAABgQAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +EAEAAAMAAAABACgAAAEBAAMAAAABACQAAAECAAMAAAAEAAAXTgEDAAMAAAABAAEAAAEGAAMAAAABAAIA +AAEKAAMAAAABAAEAAAERAAQAAAABAAAACAESAAMAAAABAAEAAAEVAAMAAAABAAQAAAEWAAMAAAABACQA +AAEXAAQAAAABAAAWgAEcAAMAAAABAAEAAAEoAAMAAAABAAIAAAFSAAMAAAABAAEAAAFTAAMAAAAEAAAX +VodzAAcAAAfYAAAXXgAAAAAACAAIAAgACAABAAEAAQABAAAH2GFwcGwCIAAAbW50clJHQiBYWVogB9kA +AgAZAAsAGgALYWNzcEFQUEwAAAAAYXBwbAAAAAAAAAAAAAAAAAAAAAAAAPbWAAEAAAAA0y1hcHBsAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALZGVzYwAAAQgAAABvZHNj +bQAAAXgAAAWcY3BydAAABxQAAAA4d3RwdAAAB0wAAAAUclhZWgAAB2AAAAAUZ1hZWgAAB3QAAAAUYlhZ +WgAAB4gAAAAUclRSQwAAB5wAAAAOY2hhZAAAB6wAAAAsYlRSQwAAB5wAAAAOZ1RSQwAAB5wAAAAOZGVz +YwAAAAAAAAAUR2VuZXJpYyBSR0IgUHJvZmlsZQAAAAAAAAAAAAAAFEdlbmVyaWMgUkdCIFByb2ZpbGUA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAG1sdWMAAAAAAAAA +HwAAAAxza1NLAAAAKAAAAYRkYURLAAAALgAAAaxjYUVTAAAAJAAAAdp2aVZOAAAAJAAAAf5wdEJSAAAA +JgAAAiJ1a1VBAAAAKgAAAkhmckZVAAAAKAAAAnJodUhVAAAAKAAAApp6aFRXAAAAFgAAAsJuYk5PAAAA +JgAAAthjc0NaAAAAIgAAAv5oZUlMAAAAHgAAAyBpdElUAAAAKAAAAz5yb1JPAAAAJAAAA2ZkZURFAAAA +LAAAA4prb0tSAAAAFgAAA7ZzdlNFAAAAJgAAAth6aENOAAAAFgAAA8xqYUpQAAAAGgAAA+JlbEdSAAAA +IgAAA/xwdFBPAAAAJgAABB5ubE5MAAAAKAAABERlc0VTAAAAJgAABB50aFRIAAAAJAAABGx0clRSAAAA +IgAABJBmaUZJAAAAKAAABLJockhSAAAAKAAABNpwbFBMAAAALAAABQJydVJVAAAAIgAABS5hckVHAAAA +JgAABVBlblVTAAAAJgAABXYAVgFhAGUAbwBiAGUAYwBuAP0AIABSAEcAQgAgAHAAcgBvAGYAaQBsAEcA +ZQBuAGUAcgBlAGwAIABSAEcAQgAtAGIAZQBzAGsAcgBpAHYAZQBsAHMAZQBQAGUAcgBmAGkAbAAgAFIA +RwBCACAAZwBlAG4A6AByAGkAYwBDHqUAdQAgAGgA7ABuAGgAIABSAEcAQgAgAEMAaAB1AG4AZwBQAGUA +cgBmAGkAbAAgAFIARwBCACAARwBlAG4A6QByAGkAYwBvBBcEMAQzBDAEOwRMBD0EOAQ5ACAEPwRABD4E +RAQwBDkEOwAgAFIARwBCAFAAcgBvAGYAaQBsACAAZwDpAG4A6QByAGkAcQB1AGUAIABSAFYAQgDBAGwA +dABhAGwA4QBuAG8AcwAgAFIARwBCACAAcAByAG8AZgBpAGyQGnUoACAAUgBHAEIAIIJyX2ljz4/wAEcA +ZQBuAGUAcgBpAHMAawAgAFIARwBCAC0AcAByAG8AZgBpAGwATwBiAGUAYwBuAP0AIABSAEcAQgAgAHAA +cgBvAGYAaQBsBeQF6AXVBeQF2QXcACAAUgBHAEIAIAXbBdwF3AXZAFAAcgBvAGYAaQBsAG8AIABSAEcA +QgAgAGcAZQBuAGUAcgBpAGMAbwBQAHIAbwBmAGkAbAAgAFIARwBCACAAZwBlAG4AZQByAGkAYwBBAGwA +bABnAGUAbQBlAGkAbgBlAHMAIABSAEcAQgAtAFAAcgBvAGYAaQBsx3y8GAAgAFIARwBCACDVBLhc0wzH +fGZukBoAIABSAEcAQgAgY8+P8GWHTvZOAIIsACAAUgBHAEIAIDDXMO0w1TChMKQw6wOTA7UDvQO5A7oD +zAAgA8ADwQO/A8YDrwO7ACAAUgBHAEIAUABlAHIAZgBpAGwAIABSAEcAQgAgAGcAZQBuAOkAcgBpAGMA +bwBBAGwAZwBlAG0AZQBlAG4AIABSAEcAQgAtAHAAcgBvAGYAaQBlAGwOQg4bDiMORA4fDiUOTAAgAFIA +RwBCACAOFw4xDkgOJw5EDhsARwBlAG4AZQBsACAAUgBHAEIAIABQAHIAbwBmAGkAbABpAFkAbABlAGkA +bgBlAG4AIABSAEcAQgAtAHAAcgBvAGYAaQBpAGwAaQBHAGUAbgBlAHIAaQENAGsAaQAgAFIARwBCACAA +cAByAG8AZgBpAGwAVQBuAGkAdwBlAHIAcwBhAGwAbgB5ACAAcAByAG8AZgBpAGwAIABSAEcAQgQeBDEE +SQQ4BDkAIAQ/BEAEPgREBDgEOwRMACAAUgBHAEIGRQZEBkEAIAYqBjkGMQZKBkEAIABSAEcAQgAgBicG +RAY5BicGRQBHAGUAbgBlAHIAaQBjACAAUgBHAEIAIABQAHIAbwBmAGkAbABldGV4dAAAAABDb3B5cmln +aHQgMjAwNyBBcHBsZSBJbmMuLCBhbGwgcmlnaHRzIHJlc2VydmVkLgBYWVogAAAAAAAA81IAAQAAAAEW +z1hZWiAAAAAAAAB0TQAAPe4AAAPQWFlaIAAAAAAAAFp1AACscwAAFzRYWVogAAAAAAAAKBoAABWfAAC4 +NmN1cnYAAAAAAAAAAQHNAABzZjMyAAAAAAABDEIAAAXe///zJgAAB5IAAP2R///7ov///aMAAAPcAADA +bNIlJicoWiRjbGFzc25hbWVYJGNsYXNzZXNfEBBOU0JpdG1hcEltYWdlUmVwoycpKlpOU0ltYWdlUmVw +WE5TT2JqZWN00iUmLC1XTlNBcnJheaIsKtIlJi8wXk5TTXV0YWJsZUFycmF5oy8sKtUyMzQ1CjY3ODk6 +V05TV2hpdGVcTlNDb21wb25lbnRzXE5TQ29sb3JTcGFjZV8QEk5TQ3VzdG9tQ29sb3JTcGFjZUQwIDAA +QzAgMBADgAyAENQ8PT4KP0BBQlROU0lEVU5TSUNDV05TTW9kZWwQCYANEACAD9JECkVGV05TLmRhdGFP +ERFoAAARaGFwcGwCAAAAbW50ckdSQVlYWVogB9wACAAXAA8ALgAPYWNzcEFQUEwAAAAAbm9uZQAAAAAA +AAAAAAAAAAAAAAAAAPbWAAEAAAAA0y1hcHBsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAFZGVzYwAAAMAAAAB5ZHNjbQAAATwAAAfoY3BydAAACSQAAAAjd3RwdAAACUgA +AAAUa1RSQwAACVwAAAgMZGVzYwAAAAAAAAAfR2VuZXJpYyBHcmF5IEdhbW1hIDIuMiBQcm9maWxlAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAG1sdWMAAAAAAAAAHwAAAAxza1NLAAAALgAAAYRkYURLAAAAOAAAAbJj +YUVTAAAAOAAAAep2aVZOAAAAQAAAAiJwdEJSAAAASgAAAmJ1a1VBAAAALAAAAqxmckZVAAAAPgAAAtho +dUhVAAAANAAAAxZ6aFRXAAAAHgAAA0puYk5PAAAAOgAAA2hjc0NaAAAAKAAAA6JoZUlMAAAAJAAAA8pp +dElUAAAATgAAA+5yb1JPAAAAKgAABDxkZURFAAAATgAABGZrb0tSAAAAIgAABLRzdlNFAAAAOAAAAbJ6 +aENOAAAAHgAABNZqYUpQAAAAJgAABPRlbEdSAAAAKgAABRpwdFBPAAAAUgAABURubE5MAAAAQAAABZZl +c0VTAAAATAAABdZ0aFRIAAAAMgAABiJ0clRSAAAAJAAABlRmaUZJAAAARgAABnhockhSAAAAPgAABr5w +bFBMAAAASgAABvxydVJVAAAAOgAAB0ZlblVTAAAAPAAAB4BhckVHAAAALAAAB7wAVgFhAGUAbwBiAGUA +YwBuAOEAIABzAGkAdgDhACAAZwBhAG0AYQAgADIALAAyAEcAZQBuAGUAcgBpAHMAawAgAGcAcgDlACAA +MgAsADIAIABnAGEAbQBtAGEAcAByAG8AZgBpAGwARwBhAG0AbQBhACAAZABlACAAZwByAGkAcwBvAHMA +IABnAGUAbgDoAHIAaQBjAGEAIAAyAC4AMgBDHqUAdQAgAGgA7ABuAGgAIABNAOAAdQAgAHgA4QBtACAA +QwBoAHUAbgBnACAARwBhAG0AbQBhACAAMgAuADIAUABlAHIAZgBpAGwAIABHAGUAbgDpAHIAaQBjAG8A +IABkAGEAIABHAGEAbQBhACAAZABlACAAQwBpAG4AegBhAHMAIAAyACwAMgQXBDAEMwQwBDsETAQ9BDAA +IABHAHIAYQB5AC0EMwQwBDwEMAAgADIALgAyAFAAcgBvAGYAaQBsACAAZwDpAG4A6QByAGkAcQB1AGUA +IABnAHIAaQBzACAAZwBhAG0AbQBhACAAMgAsADIAwQBsAHQAYQBsAOEAbgBvAHMAIABzAHoA/AByAGsA +ZQAgAGcAYQBtAG0AYQAgADIALgAykBp1KHBwlo5RSV6mACAAMgAuADIAIIJyX2ljz4/wAEcAZQBuAGUA +cgBpAHMAawAgAGcAcgDlACAAZwBhAG0AbQBhACAAMgAsADIALQBwAHIAbwBmAGkAbABPAGIAZQBjAG4A +4QAgAWEAZQBkAOEAIABnAGEAbQBhACAAMgAuADIF0gXQBd4F1AAgBdAF5AXVBegAIAXbBdwF3AXZACAA +MgAuADIAUAByAG8AZgBpAGwAbwAgAGcAcgBpAGcAaQBvACAAZwBlAG4AZQByAGkAYwBvACAAZABlAGwA +bABhACAAZwBhAG0AbQBhACAAMgAsADIARwBhAG0AYQAgAGcAcgBpACAAZwBlAG4AZQByAGkAYwEDACAA +MgAsADIAQQBsAGwAZwBlAG0AZQBpAG4AZQBzACAARwByAGEAdQBzAHQAdQBmAGUAbgAtAFAAcgBvAGYA +aQBsACAARwBhAG0AbQBhACAAMgAsADLHfLwYACDWjMDJACCsELnIACAAMgAuADIAINUEuFzTDMd8Zm6Q +GnBwXqZ8+2VwACAAMgAuADIAIGPPj/Blh072TgCCLDCwMOwwpDCsMPMw3gAgADIALgAyACAw1zDtMNUw +oTCkMOsDkwO1A70DuQO6A8wAIAOTA7oDwQO5ACADkwOsA7wDvAOxACAAMgAuADIAUABlAHIAZgBpAGwA +IABnAGUAbgDpAHIAaQBjAG8AIABkAGUAIABjAGkAbgB6AGUAbgB0AG8AcwAgAGQAYQAgAEcAYQBtAG0A +YQAgADIALAAyAEEAbABnAGUAbQBlAGUAbgAgAGcAcgBpAGoAcwAgAGcAYQBtAG0AYQAgADIALAAyAC0A +cAByAG8AZgBpAGUAbABQAGUAcgBmAGkAbAAgAGcAZQBuAOkAcgBpAGMAbwAgAGQAZQAgAGcAYQBtAG0A +YQAgAGQAZQAgAGcAcgBpAHMAZQBzACAAMgAsADIOIw4xDgcOKg41DkEOAQ4hDiEOMg5ADgEOIw4iDkwO +Fw4xDkgOJw5EDhsAIAAyAC4AMgBHAGUAbgBlAGwAIABHAHIAaQAgAEcAYQBtAGEAIAAyACwAMgBZAGwA +ZQBpAG4AZQBuACAAaABhAHIAbQBhAGEAbgAgAGcAYQBtAG0AYQAgADIALAAyACAALQBwAHIAbwBmAGkA +aQBsAGkARwBlAG4AZQByAGkBDQBrAGkAIABHAHIAYQB5ACAARwBhAG0AbQBhACAAMgAuADIAIABwAHIA +bwBmAGkAbABVAG4AaQB3AGUAcgBzAGEAbABuAHkAIABwAHIAbwBmAGkAbAAgAHMAegBhAHIAbwFbAGMA +aQAgAGcAYQBtAG0AYQAgADIALAAyBB4EMQRJBDAETwAgBEEENQRABDAETwAgBDMEMAQ8BDwEMAAgADIA +LAAyAC0EPwRABD4ERAQ4BDsETABHAGUAbgBlAHIAaQBjACAARwByAGEAeQAgAEcAYQBtAG0AYQAgADIA +LgAyACAAUAByAG8AZgBpAGwAZQY6BicGRQYnACAAMgAuADIAIAZEBkgGRgAgBjEGRQYnBi8GSgAgBjkG +JwZFdGV4dAAAAABDb3B5cmlnaHQgQXBwbGUgSW5jLiwgMjAxMgAAWFlaIAAAAAAAAPNRAAEAAAABFsxj +dXJ2AAAAAAAABAAAAAAFAAoADwAUABkAHgAjACgALQAyADcAOwBAAEUASgBPAFQAWQBeAGMAaABtAHIA +dwB8AIEAhgCLAJAAlQCaAJ8ApACpAK4AsgC3ALwAwQDGAMsA0ADVANsA4ADlAOsA8AD2APsBAQEHAQ0B +EwEZAR8BJQErATIBOAE+AUUBTAFSAVkBYAFnAW4BdQF8AYMBiwGSAZoBoQGpAbEBuQHBAckB0QHZAeEB +6QHyAfoCAwIMAhQCHQImAi8COAJBAksCVAJdAmcCcQJ6AoQCjgKYAqICrAK2AsECywLVAuAC6wL1AwAD +CwMWAyEDLQM4A0MDTwNaA2YDcgN+A4oDlgOiA64DugPHA9MD4APsA/kEBgQTBCAELQQ7BEgEVQRjBHEE +fgSMBJoEqAS2BMQE0wThBPAE/gUNBRwFKwU6BUkFWAVnBXcFhgWWBaYFtQXFBdUF5QX2BgYGFgYnBjcG +SAZZBmoGewaMBp0GrwbABtEG4wb1BwcHGQcrBz0HTwdhB3QHhgeZB6wHvwfSB+UH+AgLCB8IMghGCFoI +bgiCCJYIqgi+CNII5wj7CRAJJQk6CU8JZAl5CY8JpAm6Cc8J5Qn7ChEKJwo9ClQKagqBCpgKrgrFCtwK +8wsLCyILOQtRC2kLgAuYC7ALyAvhC/kMEgwqDEMMXAx1DI4MpwzADNkM8w0NDSYNQA1aDXQNjg2pDcMN +3g34DhMOLg5JDmQOfw6bDrYO0g7uDwkPJQ9BD14Peg+WD7MPzw/sEAkQJhBDEGEQfhCbELkQ1xD1ERMR +MRFPEW0RjBGqEckR6BIHEiYSRRJkEoQSoxLDEuMTAxMjE0MTYxODE6QTxRPlFAYUJxRJFGoUixStFM4U +8BUSFTQVVhV4FZsVvRXgFgMWJhZJFmwWjxayFtYW+hcdF0EXZReJF64X0hf3GBsYQBhlGIoYrxjVGPoZ +IBlFGWsZkRm3Gd0aBBoqGlEadxqeGsUa7BsUGzsbYxuKG7Ib2hwCHCocUhx7HKMczBz1HR4dRx1wHZkd +wx3sHhYeQB5qHpQevh7pHxMfPh9pH5Qfvx/qIBUgQSBsIJggxCDwIRwhSCF1IaEhziH7IiciVSKCIq8i +3SMKIzgjZiOUI8Ij8CQfJE0kfCSrJNolCSU4JWgllyXHJfcmJyZXJocmtyboJxgnSSd6J6sn3CgNKD8o +cSiiKNQpBik4KWspnSnQKgIqNSpoKpsqzysCKzYraSudK9EsBSw5LG4soizXLQwtQS12Last4S4WLkwu +gi63Lu4vJC9aL5Evxy/+MDUwbDCkMNsxEjFKMYIxujHyMioyYzKbMtQzDTNGM38zuDPxNCs0ZTSeNNg1 +EzVNNYc1wjX9Njc2cjauNuk3JDdgN5w31zgUOFA4jDjIOQU5Qjl/Obw5+To2OnQ6sjrvOy07azuqO+g8 +JzxlPKQ84z0iPWE9oT3gPiA+YD6gPuA/IT9hP6I/4kAjQGRApkDnQSlBakGsQe5CMEJyQrVC90M6Q31D +wEQDREdEikTORRJFVUWaRd5GIkZnRqtG8Ec1R3tHwEgFSEtIkUjXSR1JY0mpSfBKN0p9SsRLDEtTS5pL +4kwqTHJMuk0CTUpNk03cTiVObk63TwBPSU+TT91QJ1BxULtRBlFQUZtR5lIxUnxSx1MTU19TqlP2VEJU +j1TbVShVdVXCVg9WXFapVvdXRFeSV+BYL1h9WMtZGllpWbhaB1pWWqZa9VtFW5Vb5Vw1XIZc1l0nXXhd +yV4aXmxevV8PX2Ffs2AFYFdgqmD8YU9homH1YklinGLwY0Njl2PrZEBklGTpZT1lkmXnZj1mkmboZz1n +k2fpaD9olmjsaUNpmmnxakhqn2r3a09rp2v/bFdsr20IbWBtuW4SbmtuxG8eb3hv0XArcIZw4HE6cZVx +8HJLcqZzAXNdc7h0FHRwdMx1KHWFdeF2Pnabdvh3VnezeBF4bnjMeSp5iXnnekZ6pXsEe2N7wnwhfIF8 +4X1BfaF+AX5ifsJ/I3+Ef+WAR4CogQqBa4HNgjCCkoL0g1eDuoQdhICE44VHhauGDoZyhteHO4efiASI +aYjOiTOJmYn+imSKyoswi5aL/IxjjMqNMY2Yjf+OZo7OjzaPnpAGkG6Q1pE/kaiSEZJ6kuOTTZO2lCCU +ipT0lV+VyZY0lp+XCpd1l+CYTJi4mSSZkJn8mmia1ZtCm6+cHJyJnPedZJ3SnkCerp8dn4uf+qBpoNih +R6G2oiailqMGo3aj5qRWpMelOKWpphqmi6b9p26n4KhSqMSpN6mpqhyqj6sCq3Wr6axcrNCtRK24ri2u +oa8Wr4uwALB1sOqxYLHWskuywrM4s660JbSctRO1irYBtnm28Ldot+C4WbjRuUq5wro7urW7LrunvCG8 +m70VvY++Cr6Evv+/er/1wHDA7MFnwePCX8Lbw1jD1MRRxM7FS8XIxkbGw8dBx7/IPci8yTrJuco4yrfL +Nsu2zDXMtc01zbXONs62zzfPuNA50LrRPNG+0j/SwdNE08bUSdTL1U7V0dZV1tjXXNfg2GTY6Nls2fHa +dtr724DcBdyK3RDdlt4c3qLfKd+v4DbgveFE4cziU+Lb42Pj6+Rz5PzlhOYN5pbnH+ep6DLovOlG6dDq +W+rl63Dr++yG7RHtnO4o7rTvQO/M8Fjw5fFy8f/yjPMZ86f0NPTC9VD13vZt9vv3ivgZ+Kj5OPnH+lf6 +5/t3/Af8mP0p/br+S/7c/23//4AO0iUmSEldTlNNdXRhYmxlRGF0YaNISipWTlNEYXRh0iUmTE1cTlND +b2xvclNwYWNlok4qXE5TQ29sb3JTcGFjZdIlJlBRV05TQ29sb3KiUCrSJSZTVFdOU0ltYWdlolMqXxAP +TlNLZXllZEFyY2hpdmVy0VdYVHJvb3SAAQAIABEAGgAjAC0AMgA3AEwAUgBdAGQAawB4AH8AhwCJAIsA +kACSAJQAnQCiAK0ArwCxALMAuAC7AL0AvwDBAMMAyADfAOEA4yAdICIgLSA2IEkgTSBYIGEgZiBuIHEg +diCFIIkglCCcIKkgtiDLINAg1CDWINgg2iDjIOgg7iD2IPgg+iD8IP4hAyELMncyeTJ+MowykDKXMpwy +qTKsMrkyvjLGMskyzjLWMtky6zLuMvMAAAAAAAACAQAAAAAAAABZAAAAAAAAAAAAAAAAAAAy9Q + + @@ -1351,6 +1829,8 @@ + + diff --git a/Classes/Base.lproj/CallView~ipad.strings b/Classes/Base.lproj/CallView~ipad.strings index d3447624d..743293f4d 100644 Binary files a/Classes/Base.lproj/CallView~ipad.strings and b/Classes/Base.lproj/CallView~ipad.strings differ diff --git a/Classes/Base.lproj/CallView~ipad.xib b/Classes/Base.lproj/CallView~ipad.xib index 9de664410..0ba449ff4 100644 --- a/Classes/Base.lproj/CallView~ipad.xib +++ b/Classes/Base.lproj/CallView~ipad.xib @@ -1,14 +1,19 @@ - - + + + + + - + + + - + @@ -21,6 +26,7 @@ + @@ -37,6 +43,8 @@ + + @@ -64,14 +72,14 @@ - + - + @@ -89,14 +97,14 @@ - + - - + + @@ -107,14 +115,14 @@ - + - + @@ -135,32 +143,32 @@ - + - + - + - + - + - - + + + + + + - + - - + + @@ -255,11 +274,11 @@ @@ -280,7 +299,7 @@ - + @@ -290,7 +309,7 @@ - + @@ -300,7 +319,7 @@ - + @@ -310,7 +329,7 @@ - + @@ -320,7 +339,7 @@ - + @@ -330,7 +349,7 @@ - + @@ -340,7 +359,7 @@ - + @@ -350,7 +369,7 @@ - + @@ -360,7 +379,7 @@ - + @@ -370,12 +389,12 @@ - + - + @@ -520,7 +552,7 @@ - + @@ -534,7 +566,7 @@ - + @@ -543,7 +575,7 @@ - + @@ -565,11 +597,11 @@ - + - + @@ -587,7 +619,7 @@ - + @@ -606,7 +638,7 @@ - + @@ -618,7 +650,7 @@ - + @@ -630,7 +662,7 @@ - + @@ -645,7 +677,7 @@ - + @@ -659,12 +691,12 @@ - + - + - + @@ -682,14 +714,14 @@ - + - - + + @@ -700,14 +732,14 @@ - + - + @@ -728,32 +760,32 @@ - + - + - + - + - + - - + + + + + + - + - - + + @@ -848,11 +891,11 @@ @@ -873,7 +916,7 @@ - + @@ -883,7 +926,7 @@ - + @@ -893,7 +936,7 @@ - + @@ -903,7 +946,7 @@ - + @@ -913,7 +956,7 @@ - + @@ -923,7 +966,7 @@ - + @@ -933,7 +976,7 @@ - + @@ -943,7 +986,7 @@ - + @@ -953,7 +996,7 @@ - + @@ -963,12 +1006,12 @@ - + - + @@ -1118,7 +1174,7 @@ - + @@ -1133,7 +1189,7 @@ - + @@ -1145,7 +1201,7 @@ - + @@ -1157,7 +1213,7 @@ - + @@ -1172,7 +1228,7 @@ - + @@ -1196,7 +1252,7 @@ - + @@ -1210,7 +1266,7 @@ - + @@ -1219,7 +1275,7 @@ - + @@ -1241,101 +1297,102 @@ - + - + - + - - + - + - - - - - - - - + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Classes/Base.lproj/ChatConversationCreateView.xib b/Classes/Base.lproj/ChatConversationCreateView.xib index 2b6129977..e16e2bc14 100644 --- a/Classes/Base.lproj/ChatConversationCreateView.xib +++ b/Classes/Base.lproj/ChatConversationCreateView.xib @@ -1,11 +1,11 @@ - + - + @@ -13,16 +13,25 @@ + + + + + + + + + @@ -40,7 +49,7 @@ - + + + + + + + + + + + + + + + + + + + + + + + - - + - + - + @@ -293,6 +294,14 @@ + @@ -301,7 +310,7 @@ - + @@ -349,7 +358,7 @@ - - + @@ -555,7 +564,7 @@ - + @@ -569,29 +578,28 @@ - - - - - - - - - - - + + + + + + + + + + + - - - + + + - - - - - - - + + + + + + diff --git a/Classes/Base.lproj/ChatsListView.strings b/Classes/Base.lproj/ChatsListView.strings index 0b47e4e67..2273c8280 100644 Binary files a/Classes/Base.lproj/ChatsListView.strings and b/Classes/Base.lproj/ChatsListView.strings differ diff --git a/Classes/Base.lproj/ChatsListView.xib b/Classes/Base.lproj/ChatsListView.xib index 54d4b1188..ba8d35376 100644 --- a/Classes/Base.lproj/ChatsListView.xib +++ b/Classes/Base.lproj/ChatsListView.xib @@ -1,17 +1,18 @@ - + - + + @@ -44,12 +45,27 @@ - + + - + + + + + + + + + + + + + + + + + + + - + @@ -141,19 +173,19 @@ - - + - + - + - + - + + + + + + + + + + + + + + + + + + + - - + - + @@ -329,6 +390,7 @@ - + + diff --git a/Classes/Base.lproj/HistoryListView.xib b/Classes/Base.lproj/HistoryListView.xib index bd1aab325..dcd63f4c8 100644 --- a/Classes/Base.lproj/HistoryListView.xib +++ b/Classes/Base.lproj/HistoryListView.xib @@ -1,8 +1,12 @@ - - + + + + + - + + @@ -16,7 +20,7 @@ - + @@ -30,7 +34,6 @@ - @@ -39,11 +42,10 @@ - - - + - + @@ -157,21 +150,17 @@ - - + - - - - + + @@ -183,27 +172,25 @@ - + - - + + - - - - - - - - - - - - - + + + + + + + + + + + diff --git a/Classes/Base.lproj/SettingsView.xib b/Classes/Base.lproj/SettingsView.xib index 32dc99fa4..989b417c2 100644 --- a/Classes/Base.lproj/SettingsView.xib +++ b/Classes/Base.lproj/SettingsView.xib @@ -1,9 +1,12 @@ - - + + + + + - - + + @@ -18,53 +21,35 @@ - + - + - + - + - - - - + - - + - - + - - - - + + @@ -97,7 +77,6 @@ - @@ -106,11 +85,9 @@ - - + + - - diff --git a/Classes/Base.lproj/ShopView.xib b/Classes/Base.lproj/ShopView.xib index 3e494c1a7..032ec7e1a 100644 --- a/Classes/Base.lproj/ShopView.xib +++ b/Classes/Base.lproj/ShopView.xib @@ -1,8 +1,11 @@ - - + + + + + - + @@ -15,37 +18,37 @@ - + - + - + - + - - + + @@ -62,12 +65,12 @@ - - + - + + + - - - - - - - diff --git a/Classes/CallIncomingView.h b/Classes/CallIncomingView.h index 05d12b915..6007993cb 100644 --- a/Classes/CallIncomingView.h +++ b/Classes/CallIncomingView.h @@ -34,6 +34,9 @@ @interface CallIncomingView : TPMultiLayoutViewController { } + +@property(nonatomic) Boolean earlyMedia; + @property(weak, nonatomic) IBOutlet UILabel *nameLabel; @property(nonatomic, strong) IBOutlet UILabel *addressLabel; @property(nonatomic, strong) IBOutlet UIRoundedImageView *avatarImage; @@ -41,6 +44,8 @@ @property(nonatomic, strong) id delegate; @property(weak, nonatomic) IBOutlet UIView *tabVideoBar; @property(weak, nonatomic) IBOutlet UIView *tabBar; +@property (weak, nonatomic) IBOutlet UIView *earlyMediaView; + - (IBAction)onAcceptClick:(id)event; - (IBAction)onDeclineClick:(id)event; diff --git a/Classes/CallIncomingView.m b/Classes/CallIncomingView.m index c81d20549..a91a80b92 100644 --- a/Classes/CallIncomingView.m +++ b/Classes/CallIncomingView.m @@ -66,6 +66,10 @@ static UICompositeViewDescription *compositeDescription = nil; - (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation { [super didRotateFromInterfaceOrientation:fromInterfaceOrientation]; + if (_earlyMedia && [LinphoneManager.instance lpConfigBoolForKey:@"pref_accept_early_media"] && linphone_core_get_calls_nb(LC) < 2) { + _earlyMediaView.hidden = NO; + linphone_core_set_native_video_window_id(LC, (__bridge void *)(_earlyMediaView)); + } if (_call) { [self update]; } @@ -105,9 +109,26 @@ static UICompositeViewDescription *compositeDescription = nil; } #pragma mark - Property Functions +static void hideSpinner(LinphoneCall *call, void *user_data) { + CallIncomingView *thiz = (__bridge CallIncomingView *)user_data; + thiz.earlyMedia = TRUE; + thiz.earlyMediaView.hidden = NO; + linphone_core_set_native_video_window_id(LC, (__bridge void *)(thiz.earlyMediaView)); +} - (void)setCall:(LinphoneCall *)call { _call = call; + _earlyMedia = FALSE; + if ([LinphoneManager.instance lpConfigBoolForKey:@"pref_accept_early_media"] && linphone_core_get_calls_nb(LC) < 2) { + linphone_call_accept_early_media(_call); + // linphone_call_params_get_used_video_codec return 0 if no video stream enabled + if (linphone_call_params_get_used_video_codec(linphone_call_get_current_params(_call))) { + linphone_call_set_next_video_frame_decoded_callback(call, hideSpinner, (__bridge void *)(self)); + } + } else { + _earlyMediaView.hidden = YES; + } + [self update]; [self callUpdate:_call state:linphone_call_get_state(call)]; } diff --git a/Classes/CallView.h b/Classes/CallView.h index 67ed65566..ad058daa5 100644 --- a/Classes/CallView.h +++ b/Classes/CallView.h @@ -42,6 +42,7 @@ NSTimer *hideControlsTimer; NSTimer *videoDismissTimer; BOOL videoHidden; + BOOL callRecording; VideoZoomHandler *videoZoomHandler; } @@ -74,6 +75,8 @@ @property(weak, nonatomic) IBOutlet UIPauseButton *conferencePauseButton; @property(weak, nonatomic) IBOutlet UIBouncingView *chatNotificationView; @property(weak, nonatomic) IBOutlet UILabel *chatNotificationLabel; +@property (weak, nonatomic) IBOutlet UIButton *recordButton; +@property (weak, nonatomic) IBOutlet UIButton *recordButtonOnView; @property(weak, nonatomic) IBOutlet UIView *bottomBar; @property(nonatomic, strong) IBOutlet UIDigitButton *oneButton; @@ -96,6 +99,7 @@ @property(weak, nonatomic) IBOutlet UIView *conferenceView; @property(strong, nonatomic) IBOutlet CallPausedTableView *conferenceCallsTable; @property (weak, nonatomic) IBOutlet UIView *waitView; +@property (weak, nonatomic) IBOutlet UIView *infoView; - (IBAction)onRoutesClick:(id)sender; - (IBAction)onRoutesBluetoothClick:(id)sender; @@ -107,5 +111,6 @@ - (IBAction)onOptionsConferenceClick:(id)sender; - (IBAction)onNumpadClick:(id)sender; - (IBAction)onChatClick:(id)sender; +- (IBAction)onRecordClick:(id)sender; @end diff --git a/Classes/CallView.m b/Classes/CallView.m index 4e3c18bd7..77d94815e 100644 --- a/Classes/CallView.m +++ b/Classes/CallView.m @@ -48,6 +48,9 @@ const NSInteger SECURE_BUTTON_TAG = 5; singleFingerTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(toggleControls:)]; videoZoomHandler = [[VideoZoomHandler alloc] init]; videoHidden = TRUE; + CGRect frame = _callPauseButton.frame; + frame.origin.y = _recordButtonOnView.frame.origin.y; + _callPauseButton.frame = frame; } return self; } @@ -137,6 +140,9 @@ static UICompositeViewDescription *compositeDescription = nil; [super viewWillAppear:animated]; _waitView.hidden = TRUE; LinphoneManager.instance.nextCallIsTransfer = NO; + + callRecording = FALSE; + _recordButtonOnView.hidden = TRUE; // Update on show [self hideRoutes:TRUE animated:FALSE]; @@ -227,6 +233,24 @@ static UICompositeViewDescription *compositeDescription = nil; // reseting speaker button because no more call _speakerButton.selected = FALSE; } + + NSString *address = [LinphoneManager.instance lpConfigStringForKey:@"sas_dialog_denied"]; + if (address) { + UIConfirmationDialog *securityDialog = [UIConfirmationDialog ShowWithMessage:NSLocalizedString(@"Trust has been denied. Make a call to start the authentication process again.", nil) + cancelMessage:NSLocalizedString(@"CANCEL", nil) + confirmMessage:NSLocalizedString(@"CALL", nil) + onCancelClick:^() { + } + onConfirmationClick:^() { + LinphoneAddress *addr = linphone_address_new(address.UTF8String); + [LinphoneManager.instance doCallWithSas:addr isSas:TRUE]; + linphone_address_unref(addr); + } ]; + [securityDialog.securityImage setImage:[UIImage imageNamed:@"security_alert_indicator.png"]]; + securityDialog.securityImage.hidden = FALSE; + [securityDialog setSpecialColor]; + [LinphoneManager.instance lpConfigSetString:nil forKey:@"sas_dialog_denied"]; + } } - (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation { @@ -234,10 +258,26 @@ static UICompositeViewDescription *compositeDescription = nil; [self updateUnreadMessage:NO]; [self previewTouchLift]; [self hideStatusBar:!videoHidden && (_nameLabel.alpha <= 0.f)]; + [_recordButtonOnView setHidden:!callRecording]; + [self updateInfoView]; } #pragma mark - UI modification +- (void)updateInfoView { + CGRect infoFrame = _infoView.frame; + CGRect frame = _callPauseButton.frame; + if (videoHidden) { + infoFrame.origin.y = (_avatarImage.frame.origin.y-66)/2; + frame.origin.y = _recordButtonOnView.frame.origin.y; + } else { + infoFrame.origin.y = 0; + frame.origin.y = _videoCameraSwitch.frame.origin.y+_videoGroup.frame.origin.y; + } + _infoView.frame = infoFrame; + _callPauseButton.frame = frame; +} + - (void)hideSpinnerIndicator:(LinphoneCall *)call { _videoWaitingForFirstImage.hidden = TRUE; } @@ -526,6 +566,11 @@ static void hideSpinner(LinphoneCall *call, void *user_data) { [self displayAudioCall:animated]; } } + // camera is diabled duiring conference, it must be activated after leaving conference. + if (!shouldDisableVideo && !linphone_core_is_in_conference(LC)) { + linphone_call_enable_camera(call, TRUE); + } + [self updateInfoView]; if (state != LinphoneCallPausedByRemote) { _pausedByRemoteView.hidden = YES; @@ -713,7 +758,41 @@ static void hideSpinner(LinphoneCall *call, void *user_data) { - (IBAction)onChatClick:(id)sender { const LinphoneCall *currentCall = linphone_core_get_current_call(LC); const LinphoneAddress *addr = currentCall ? linphone_call_get_remote_address(currentCall) : NULL; - [PhoneMainView.instance getOrCreateOneToOneChatRoom:addr waitView:_waitView]; + // TODO encrpted or unencrpted + [PhoneMainView.instance getOrCreateOneToOneChatRoom:addr waitView:_waitView isEncrypted:FALSE]; +} + +- (IBAction)onRecordClick:(id)sender { + if (![_optionsView isHidden]) + [self hideOptions:TRUE animated:ANIMATED]; + if (callRecording) { + LOGD(@"Recording Stops"); + [_recordButton setImage:[UIImage imageNamed:@"rec_on_default.png"] forState:UIControlStateNormal]; + [_recordButtonOnView setHidden:TRUE]; + + LinphoneCall *call = linphone_core_get_current_call(LC); + linphone_call_stop_recording(call); + + callRecording = FALSE; + + NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES); + NSString *writablePath = [paths objectAtIndex:0]; + writablePath = [writablePath stringByAppendingString:@"/"]; + NSArray *directoryContent = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:writablePath error:NULL]; + if (directoryContent) { + return; + } + } else { + LOGD(@"Recording Starts"); + + [_recordButton setImage:[UIImage imageNamed:@"rec_off_default.png"] forState:UIControlStateNormal]; + [_recordButtonOnView setHidden:FALSE]; + + LinphoneCall *call = linphone_core_get_current_call(LC); + linphone_call_start_recording(call); + + callRecording = TRUE; + } } - (IBAction)onRoutesBluetoothClick:(id)sender { diff --git a/Classes/ChatConversationCreateTableView.h b/Classes/ChatConversationCreateTableView.h index 5de6fc8d4..cc6cc0349 100644 --- a/Classes/ChatConversationCreateTableView.h +++ b/Classes/ChatConversationCreateTableView.h @@ -20,6 +20,8 @@ @property (weak, nonatomic) IBOutlet UIView *waitView; @property(nonatomic) Boolean isForEditing; +@property(nonatomic) Boolean isGroupChat; +@property(nonatomic) Boolean isEncrypted; - (void) loadData; @end diff --git a/Classes/ChatConversationCreateTableView.m b/Classes/ChatConversationCreateTableView.m index cc1fb0e0d..3e6397a2d 100644 --- a/Classes/ChatConversationCreateTableView.m +++ b/Classes/ChatConversationCreateTableView.m @@ -16,6 +16,7 @@ @property(nonatomic, strong) NSMutableArray *addresses; @property(nonatomic, strong) NSMutableArray *phoneOrAddr; +@property(nonatomic, strong) NSMutableArray *addressesCached; @end @implementation ChatConversationCreateTableView @@ -40,6 +41,7 @@ _addresses = [[NSMutableArray alloc] initWithCapacity:LinphoneManager.instance.fastAddressBook.addressBookMap.allKeys.count]; _phoneOrAddr = [[NSMutableArray alloc] initWithCapacity:LinphoneManager.instance.fastAddressBook.addressBookMap.allKeys.count]; + _addressesCached = [[NSMutableArray alloc] initWithCapacity:LinphoneManager.instance.fastAddressBook.addressBookMap.allKeys.count]; if(_notFirstTime) { for(NSString *addr in _contactsGroup) { [_collectionView registerClass:UIChatCreateCollectionViewCell.class forCellWithReuseIdentifier:addr]; @@ -66,6 +68,7 @@ - (void)reloadDataWithFilter:(NSString *)filter { [_addresses removeAllObjects]; [_phoneOrAddr removeAllObjects]; + [_addressesCached removeAllObjects]; if (!_magicSearch) return; @@ -75,7 +78,17 @@ LinphoneSearchResult *result = results->data; const LinphoneAddress *addr = linphone_search_result_get_address(result); const char *phoneNumber = NULL; - if (!addr) { + + Contact *contact = nil; + char *uri = nil; + NSString *address = nil; + if (addr) { + uri = linphone_address_as_string_uri_only(addr); + address = [NSString stringWithUTF8String:uri]; + contact = [LinphoneManager.instance.fastAddressBook.addressBookMap objectForKey:[FastAddressBook normalizeSipURI:address]]; + } + + if (!addr || (!contact && linphone_search_result_get_friend(result))) { phoneNumber = linphone_search_result_get_phone_number(result); if (!phoneNumber) { results = results->next; @@ -85,6 +98,8 @@ LinphoneProxyConfig *cfg = linphone_core_get_default_proxy_config(LC); const char *normalizedPhoneNumber = linphone_proxy_config_normalize_phone_number(cfg, phoneNumber); addr = linphone_proxy_config_normalize_sip_uri(cfg, normalizedPhoneNumber); + uri = linphone_address_as_string_uri_only(addr); + address = [NSString stringWithUTF8String:uri]; } if (!addr) { @@ -92,11 +107,11 @@ continue; } - char *uri = linphone_address_as_string_uri_only(addr); - NSString *address = [NSString stringWithUTF8String:uri]; - ms_free(uri); + ms_free(uri); + [_addresses addObject:address]; [_phoneOrAddr addObject:phoneNumber ? [NSString stringWithUTF8String:phoneNumber] : address]; + [_addressesCached addObject:[NSString stringWithFormat:@"%d",linphone_search_result_get_capabilities(result)]]; results = results->next; } @@ -114,6 +129,10 @@ return _addresses.count; } +- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(nonnull NSIndexPath *)indexPath { + return 60.0; +} + - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { NSString *kCellId = NSStringFromClass(UIChatCreateCell.class); UIChatCreateCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellId]; @@ -122,30 +141,41 @@ NSString *key = [_addresses objectAtIndex:indexPath.row]; NSString *phoneOrAddr = [_phoneOrAddr objectAtIndex:indexPath.row]; - Contact *contact = [LinphoneManager.instance.fastAddressBook.addressBookMap objectForKey:key]; + Contact *contact = [LinphoneManager.instance.fastAddressBook.addressBookMap objectForKey:[FastAddressBook normalizeSipURI:key]]; + const LinphonePresenceModel *model = contact.friend ? linphone_friend_get_presence_model(contact.friend) : NULL; Boolean linphoneContact = [FastAddressBook contactHasValidSipDomain:contact] - || (contact.friend && linphone_presence_model_get_basic_status(linphone_friend_get_presence_model(contact.friend)) == LinphonePresenceBasicStatusOpen); + || (model && linphone_presence_model_get_basic_status(model) == LinphonePresenceBasicStatusOpen); LinphoneAddress *addr = [LinphoneUtils normalizeSipOrPhoneAddress:key]; if (!addr) return cell; cell.linphoneImage.hidden = !linphoneContact; + cell.securityImage.hidden = !(model && linphone_presence_model_has_capability(model, LinphoneFriendCapabilityLimeX3dh)); + int capabilities = [[_addressesCached objectAtIndex:indexPath.row] intValue]; + BOOL greyCellForEncryptedChat = _isEncrypted ? capabilities > 1 : TRUE; + BOOL greyCellForGroupChat = _isGroupChat ? capabilities > 0 : TRUE; + cell.userInteractionEnabled = cell.greyView.hidden = greyCellForEncryptedChat && greyCellForGroupChat; cell.displayNameLabel.text = [FastAddressBook displayNameForAddress:addr]; cell.addressLabel.text = linphoneContact ? [NSString stringWithUTF8String:linphone_address_as_string(addr)] : phoneOrAddr; cell.selectedImage.hidden = ![_contactsGroup containsObject:cell.addressLabel.text]; + [cell.avatarImage setImage:[FastAddressBook imageForAddress:addr] bordered:NO withRoundedRadius:YES]; return cell; } - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { UIChatCreateCell *cell = [tableView cellForRowAtIndexPath:indexPath]; - - if (!linphone_proxy_config_get_conference_factory_uri(linphone_core_get_default_proxy_config(LC))) { - // Create directly a basic chat room if there's no factory uri - bctbx_list_t *addresses = NULL; + if (!cell.userInteractionEnabled) + return; + + if (!linphone_proxy_config_get_conference_factory_uri(linphone_core_get_default_proxy_config(LC)) || !_isGroupChat) { LinphoneAddress *addr = linphone_address_new(cell.addressLabel.text.UTF8String); - addresses = bctbx_list_append(addresses, addr); - [PhoneMainView.instance createChatRoomWithSubject:NULL addresses:addresses andWaitView:NULL]; - linphone_address_unref(addr); + [PhoneMainView.instance getOrCreateOneToOneChatRoom:addr waitView:_waitView isEncrypted:_isEncrypted]; + if (!addr) { + LOGE(@"Chat room could not be created on server, because null address."); + [ChatConversationInfoView displayCreationError]; + } else { + linphone_address_unref(addr); + } return; } diff --git a/Classes/ChatConversationCreateView.h b/Classes/ChatConversationCreateView.h index 1557650e2..d5f6029a6 100644 --- a/Classes/ChatConversationCreateView.h +++ b/Classes/ChatConversationCreateView.h @@ -25,11 +25,18 @@ @property (weak, nonatomic) IBOutlet UIIconButton *linphoneButton; @property (weak, nonatomic) IBOutlet UIImageView *selectedButtonImage; @property (weak, nonatomic) IBOutlet UIView *waitView; +@property (weak, nonatomic) IBOutlet UIView *chiffreOptionView; +@property (weak, nonatomic) IBOutlet UIView *switchView; +@property (weak, nonatomic) IBOutlet UIImageView *chiffreImage; +@property (weak, nonatomic) IBOutlet UIButton *chiffreButton; @property(nonatomic) Boolean isForEditing; +@property(nonatomic) Boolean isGroupChat; +@property(nonatomic) Boolean isEncrypted; - (IBAction)onBackClick:(id)sender; - (IBAction)onNextClick:(id)sender; +- (IBAction)onChiffreClick:(id)sender; @end diff --git a/Classes/ChatConversationCreateView.m b/Classes/ChatConversationCreateView.m index 72d225601..9d88f4bb8 100644 --- a/Classes/ChatConversationCreateView.m +++ b/Classes/ChatConversationCreateView.m @@ -49,11 +49,41 @@ static UICompositeViewDescription *compositeDescription = nil; [_collectionView setCollectionViewLayout:layout]; _tableController.collectionView = _collectionView; _tableController.controllerNextButton = _nextButton; - _isForEditing = FALSE; + _isForEditing = FALSE; } - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; + [self viewUpdateEvent:nil]; + + if (IPAD) + [NSNotificationCenter.defaultCenter addObserver:self + selector:@selector(viewUpdateEvent:) + name:kLinphoneChatCreateViewChange + object:nil]; +} + +- (void)viewUpdateEvent:(NSNotification *)notif { + CGRect frame = _chiffreOptionView.frame; + if (_isGroupChat) { + _nextButton.hidden = FALSE; + _switchView.hidden = TRUE; + frame.origin.x = (self.view.frame.size.width - _chiffreOptionView.frame.size.width)/2; + } else { + _nextButton.hidden = TRUE; + _switchView.hidden = FALSE; + frame.origin.x = self.view.frame.size.width * 0.192; + } + _chiffreOptionView.frame = frame; + _isEncrypted = FALSE; + CGRect buttonFrame = _chiffreButton.frame; + _tableController.isEncrypted = _isEncrypted; + + // no encrypted by default + buttonFrame.origin.x = 2; + [_chiffreImage setImage:[UIImage imageNamed:@"security_toogle_background_grey.png"]]; + _chiffreButton.frame = buttonFrame; + _waitView.hidden = YES; _backButton.hidden = IPAD; if(_tableController.contactsGroup.count == 0) { @@ -72,7 +102,15 @@ static UICompositeViewDescription *compositeDescription = nil; } [_collectionView reloadData]; _tableController.isForEditing = _isForEditing; - [self changeView:ContactsLinphone]; + _tableController.isGroupChat = _isGroupChat; + _tableController.isEncrypted = _isEncrypted; + [self changeView:ContactsLinphone]; +} + +- (void)viewWillDisappear:(BOOL)animated { + [super viewWillDisappear:animated]; + if (IPAD) + [NSNotificationCenter.defaultCenter removeObserver:self]; } #pragma mark - Chat room functions @@ -80,7 +118,7 @@ static UICompositeViewDescription *compositeDescription = nil; - (void)createChatRoom { NSString *addr = _tableController.contactsGroup[0]; LinphoneAddress *remoteAddress = linphone_address_new(addr.UTF8String); - [PhoneMainView.instance getOrCreateOneToOneChatRoom:remoteAddress waitView:_waitView]; + [PhoneMainView.instance getOrCreateOneToOneChatRoom:remoteAddress waitView:_waitView isEncrypted:_isEncrypted]; linphone_address_unref(remoteAddress); } @@ -95,17 +133,30 @@ static UICompositeViewDescription *compositeDescription = nil; } - (IBAction)onNextClick:(id)sender { - if (_tableController.contactsGroup.count == 1 && !_isForEditing) { - [self createChatRoom]; - return; - } - ChatConversationInfoView *view = VIEW(ChatConversationInfoView); view.contacts = _tableController.contactsGroup; view.create = !_isForEditing; + view.encrypted = _isEncrypted; [PhoneMainView.instance changeCurrentView:view.compositeViewDescription]; } +- (IBAction)onChiffreClick:(id)sender { + CGRect frame = _chiffreButton.frame; + _isEncrypted = !_isEncrypted; + _tableController.isEncrypted = _isEncrypted; + if (_isEncrypted) { + // encrypted + frame.origin.x = 20; + [_chiffreImage setImage:[UIImage imageNamed:@"security_toogle_background_green.png"]]; + } else { + // no encrypted + frame.origin.x = 2; + [_chiffreImage setImage:[UIImage imageNamed:@"security_toogle_background_grey.png"]]; + } + _chiffreButton.frame = frame; + [_tableController.tableView reloadData]; +} + - (void)dismissKeyboards { if ([self.tableController.searchBar isFirstResponder]) [self.tableController.searchBar resignFirstResponder]; diff --git a/Classes/ChatConversationImdnView.h b/Classes/ChatConversationImdnView.h index 9872e8ea5..2d6b9d84c 100644 --- a/Classes/ChatConversationImdnView.h +++ b/Classes/ChatConversationImdnView.h @@ -14,6 +14,10 @@ #import "UIRoundBorderedButton.h" @interface ChatConversationImdnView : UIViewController +{ + @private + NSString *messageText; +} @property(nonatomic) LinphoneChatMessage *msg; @property(nonatomic) bctbx_list_t *displayedList; @@ -30,6 +34,7 @@ @property (weak, nonatomic) IBOutlet UITableView *tableView; - (IBAction)onBackClick:(id)sender; +- (void)updateImdnList; @end diff --git a/Classes/ChatConversationImdnView.m b/Classes/ChatConversationImdnView.m index 9ce5f031b..60c075085 100644 --- a/Classes/ChatConversationImdnView.m +++ b/Classes/ChatConversationImdnView.m @@ -47,33 +47,37 @@ static UICompositeViewDescription *compositeDescription = nil; [LinphoneUtils timeToString:linphone_chat_message_get_time(_msg) withFormat:LinphoneDateChatBubble], [FastAddressBook displayNameForAddress:addr]]; _msgAvatarImage.image = outgoing ? [LinphoneUtils selfAvatar] : [FastAddressBook imageForAddress:addr]; - if (linphone_chat_message_has_text_content(_msg)) - _msgText.text = [NSString stringWithUTF8String:linphone_chat_message_get_text(_msg)]; - else - _msgText.text = [NSString stringWithUTF8String: linphone_content_get_name(linphone_chat_message_get_file_transfer_information(_msg))]; - + _msgText.text = messageText; _msgBackgroundColorImage.image = _msgBottomBar.image = [UIImage imageNamed:(outgoing ? @"color_A.png" : @"color_D.png")]; _msgDateLabel.textColor = [UIColor colorWithPatternImage:_msgBackgroundColorImage.image]; _tableView.delegate = self; _tableView.dataSource = self; - _displayedList = linphone_chat_message_get_participants_by_imdn_state(_msg, LinphoneChatMessageStateDisplayed); - _receivedList = linphone_chat_message_get_participants_by_imdn_state(_msg, LinphoneChatMessageStateDeliveredToUser); - _notReceivedList = linphone_chat_message_get_participants_by_imdn_state(_msg, LinphoneChatMessageStateDelivered); - _errorList = linphone_chat_message_get_participants_by_imdn_state(_msg, LinphoneChatMessageStateNotDelivered); + [self updateImdnList]; +} - [_tableView reloadData]; +- (void)updateImdnList { + if (_msg) { + _displayedList = linphone_chat_message_get_participants_by_imdn_state(_msg, LinphoneChatMessageStateDisplayed); + _receivedList = linphone_chat_message_get_participants_by_imdn_state(_msg, LinphoneChatMessageStateDeliveredToUser); + _notReceivedList = linphone_chat_message_get_participants_by_imdn_state(_msg, LinphoneChatMessageStateDelivered); + _errorList = linphone_chat_message_get_participants_by_imdn_state(_msg, LinphoneChatMessageStateNotDelivered); + + [_tableView reloadData]; + } } - (void)fitContent { + [self setMessageText]; + BOOL outgoing = linphone_chat_message_is_outgoing(_msg); _msgBackgroundColorImage.image = _msgBottomBar.image = [UIImage imageNamed:(outgoing ? @"color_A.png" : @"color_D.png")]; _msgDateLabel.textColor = [UIColor colorWithPatternImage:_msgBackgroundColorImage.image]; [_msgView setFrame:CGRectMake(_msgView.frame.origin.x, _msgView.frame.origin.y, _msgView.frame.size.width, - [UIChatBubbleTextCell ViewHeightForMessage:_msg withWidth:self.view.frame.size.width].height)]; + [UIChatBubbleTextCell ViewHeightForMessageText:_msg withWidth:self.view.frame.size.width textForImdn:messageText].height)]; [_tableView setFrame:CGRectMake(_tableView.frame.origin.x, _msgView.frame.origin.y + _msgView.frame.size.height + 10, @@ -85,6 +89,18 @@ static UICompositeViewDescription *compositeDescription = nil; [self fitContent]; } +- (void)setMessageText { + const char *utf8Text= linphone_chat_message_get_text_content(_msg); + LinphoneContent *fileContent = linphone_chat_message_get_file_transfer_information(_msg); + messageText = nil; + if (utf8Text) { + messageText = [NSString stringWithUTF8String:utf8Text]; + if (fileContent) + messageText = [NSString stringWithFormat:@"%@\n%@", messageText, [NSString stringWithUTF8String: linphone_content_get_name(fileContent)]]; + } else { + messageText = [NSString stringWithUTF8String: linphone_content_get_name(fileContent)]; + } +} #pragma mark - TableView - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { diff --git a/Classes/ChatConversationInfoView.h b/Classes/ChatConversationInfoView.h index cf7951acd..962157c0e 100644 --- a/Classes/ChatConversationInfoView.h +++ b/Classes/ChatConversationInfoView.h @@ -14,6 +14,7 @@ @property(nonatomic) BOOL create; @property(nonatomic) BOOL imAdmin; +@property(nonatomic) BOOL encrypted; @property(nonatomic, strong) NSMutableArray *contacts; @property(nonatomic, strong) NSMutableArray *admins; @property(nonatomic, strong) NSMutableArray *oldContacts; diff --git a/Classes/ChatConversationInfoView.m b/Classes/ChatConversationInfoView.m index 5a3094a40..f60ee2974 100644 --- a/Classes/ChatConversationInfoView.m +++ b/Classes/ChatConversationInfoView.m @@ -142,7 +142,7 @@ static UICompositeViewDescription *compositeDescription = nil; } addresses = bctbx_list_append(addresses, (void *)linphoneAddress); } - [PhoneMainView.instance createChatRoomWithSubject:_nameLabel.text.UTF8String addresses:addresses andWaitView:_waitView]; + [PhoneMainView.instance createChatRoom:_nameLabel.text.UTF8String addresses:addresses andWaitView:_waitView isEncrypted:_encrypted isGroup:TRUE]; bctbx_list_free_with_data(addresses, (void (*)(void *))linphone_address_unref); } @@ -159,6 +159,7 @@ static UICompositeViewDescription *compositeDescription = nil; continue; LinphoneAddress *addr = linphone_address_new(uri.UTF8String); + linphone_address_clean(addr);//keep only username@domain if (addedPartipants) addedPartipants = bctbx_list_append(addedPartipants, addr); else @@ -261,6 +262,7 @@ static UICompositeViewDescription *compositeDescription = nil; ChatConversationCreateView *view = VIEW(ChatConversationCreateView); view.tableController.notFirstTime = TRUE; view.isForEditing = !_create; + view.isGroupChat = TRUE; view.tableController.contactsGroup = [_contacts mutableCopy]; [PhoneMainView.instance popToView:view.compositeViewDescription]; } diff --git a/Classes/ChatConversationTableView.h b/Classes/ChatConversationTableView.h index a29288367..b603ab3f4 100644 --- a/Classes/ChatConversationTableView.h +++ b/Classes/ChatConversationTableView.h @@ -38,9 +38,11 @@ @interface ChatConversationTableView : UICheckBoxTableView { @private NSMutableArray *eventList; + NSMutableArray *totalEventList; } @property(nonatomic) LinphoneChatRoom *chatRoom; +@property(nonatomic) NSInteger currentIndex; @property(nonatomic, strong) id chatRoomDelegate; @property NSMutableDictionary *imagesInChatroom; @@ -48,5 +50,6 @@ - (void)scrollToBottom:(BOOL)animated; - (void)scrollToLastUnread:(BOOL)animated; - (void)updateEventEntry:(LinphoneEventLog *)event; +- (void)refreshData; @end diff --git a/Classes/ChatConversationTableView.m b/Classes/ChatConversationTableView.m index 20842d192..71efb2925 100644 --- a/Classes/ChatConversationTableView.m +++ b/Classes/ChatConversationTableView.m @@ -40,16 +40,18 @@ [super viewWillAppear:animated]; self.tableView.accessibilityIdentifier = @"ChatRoom list"; _imagesInChatroom = [NSMutableDictionary dictionary]; + _currentIndex = 0; } #pragma mark - - (void)clearEventList { - for (NSValue *value in eventList) { + for (NSValue *value in totalEventList) { LinphoneEventLog *event = value.pointerValue; linphone_event_log_unref(event); } [eventList removeAllObjects]; + [totalEventList removeAllObjects]; } - (void)updateData { @@ -62,15 +64,21 @@ ? linphone_chat_room_get_history_message_events(_chatRoom, 0) : linphone_chat_room_get_history_events(_chatRoom, 0); bctbx_list_t *head = chatRoomEvents; - eventList = [[NSMutableArray alloc] initWithCapacity:bctbx_list_size(chatRoomEvents)]; + size_t listSize = bctbx_list_size(chatRoomEvents); + totalEventList = [[NSMutableArray alloc] initWithCapacity:listSize]; + eventList = [[NSMutableArray alloc] initWithCapacity:MIN(listSize, BASIC_EVENT_LIST)]; while (chatRoomEvents) { - LinphoneEventLog *event = (LinphoneEventLog *)chatRoomEvents->data; - [eventList addObject:[NSValue valueWithPointer:linphone_event_log_ref(event)]]; + LinphoneEventLog *event = (LinphoneEventLog *)chatRoomEvents->data; + [totalEventList addObject:[NSValue valueWithPointer:linphone_event_log_ref(event)]]; + if (listSize <= BASIC_EVENT_LIST) { + [eventList addObject:[NSValue valueWithPointer:linphone_event_log_ref(event)]]; + } chatRoomEvents = chatRoomEvents->next; + listSize -= 1; } bctbx_list_free_with_data(head, (bctbx_list_free_func)linphone_event_log_unref); - for (FileTransferDelegate *ftd in [LinphoneManager.instance fileTransferDelegates]) { + /*for (FileTransferDelegate *ftd in [LinphoneManager.instance fileTransferDelegates]) { const LinphoneAddress *ftd_peer = linphone_chat_room_get_peer_address(linphone_chat_message_get_chat_room(ftd.message)); const LinphoneAddress *peer = linphone_chat_room_get_peer_address(_chatRoom); @@ -78,7 +86,23 @@ LOGI(@"Appending transient upload message %p", ftd.message); //TODO : eventList = bctbx_list_append(eventList, linphone_chat_message_ref(ftd.event)); } - } + }*/ +} + +- (void)refreshData { + if (totalEventList.count <= eventList.count) { + _currentIndex = 0; + return; + } + + NSUInteger num = MIN(totalEventList.count-eventList.count, BASIC_EVENT_LIST); + _currentIndex = num - 1; + while (num) { + NSInteger index = totalEventList.count - eventList.count - 1; + [eventList insertObject:[totalEventList objectAtIndex:index] atIndex:0]; + index -= 1; + num -= 1; + } } - (void)reloadData { @@ -89,10 +113,12 @@ - (void)addEventEntry:(LinphoneEventLog *)event { [eventList addObject:[NSValue valueWithPointer:linphone_event_log_ref(event)]]; + [totalEventList addObject:[NSValue valueWithPointer:linphone_event_log_ref(event)]]; int pos = (int)eventList.count - 1; NSIndexPath *indexPath = [NSIndexPath indexPathForRow:pos inSection:0]; [self.tableView beginUpdates]; [self.tableView insertRowsAtIndexPaths:@[ indexPath ] withRowAnimation:UITableViewRowAnimationFade]; + [self.tableView reloadData]; [self.tableView endUpdates]; } @@ -165,6 +191,56 @@ [self reloadData]; } +static const int MAX_AGGLOMERATED_TIME=300; +static const int BASIC_EVENT_LIST=15; + +- (BOOL)isFirstIndexInTableView:(NSIndexPath *)indexPath chat:(LinphoneChatMessage *)chat { + LinphoneEventLog *previousEvent = nil; + NSInteger indexOfPreviousEvent = indexPath.row - 1; + while (!previousEvent && indexOfPreviousEvent > -1) { + LinphoneEventLog *tmp = [[eventList objectAtIndex:indexOfPreviousEvent] pointerValue]; + if (linphone_event_log_get_type(tmp) == LinphoneEventLogTypeConferenceChatMessage) { + previousEvent = tmp; + } + --indexOfPreviousEvent; + } + if (!previousEvent) + return TRUE; + + LinphoneChatMessage *previousChat = linphone_event_log_get_chat_message(previousEvent); + if (!linphone_address_equal(linphone_chat_message_get_from_address(previousChat), linphone_chat_message_get_from_address(chat))) { + return TRUE; + } + // the maximum interval between 2 agglomerated chats at 5mn + if ((linphone_chat_message_get_time(chat)-linphone_chat_message_get_time(previousChat)) > MAX_AGGLOMERATED_TIME) { + return TRUE; + } + + return FALSE; +} + +- (BOOL)isLastIndexInTableView:(NSIndexPath *)indexPath chat:(LinphoneChatMessage *)chat { + LinphoneEventLog *nextEvent = nil; + NSInteger indexOfNextEvent = indexPath.row + 1; + while (!nextEvent && indexOfNextEvent < [eventList count]) { + LinphoneEventLog *tmp = [[eventList objectAtIndex:indexOfNextEvent] pointerValue]; + if (linphone_event_log_get_type(tmp) == LinphoneEventLogTypeConferenceChatMessage) { + nextEvent = tmp; + } + ++indexOfNextEvent; + } + + if (!nextEvent) + return TRUE; + + LinphoneChatMessage *nextChat = linphone_event_log_get_chat_message(nextEvent); + if (!linphone_address_equal(linphone_chat_message_get_from_address(nextChat), linphone_chat_message_get_from_address(chat))) { + return TRUE; + } + + return FALSE; +} + #pragma mark - UITableViewDataSource Functions - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { @@ -190,8 +266,11 @@ cell = [[NSClassFromString(kCellId) alloc] initWithIdentifier:kCellId]; } [cell setEvent:event]; - if (chat) - [cell update]; + if (chat) { + cell.isFirst = [self isFirstIndexInTableView:indexPath chat:chat]; + cell.isLast = [self isLastIndexInTableView:indexPath chat:chat]; + [cell update]; + } [cell setChatRoomDelegate:_chatRoomDelegate]; [super accessoryForCell:cell atPath:indexPath]; @@ -216,7 +295,7 @@ [_chatRoomDelegate tableViewIsScrolling]; } -static const CGFloat MESSAGE_SPACING_PERCENTAGE = 0.f; +static const CGFloat MESSAGE_SPACING_PERCENTAGE = 1.f; - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { LinphoneEventLog *event = [[eventList objectAtIndex:indexPath.row] pointerValue]; @@ -225,21 +304,11 @@ static const CGFloat MESSAGE_SPACING_PERCENTAGE = 0.f; //If the message is followed by another one that is not from the same address, we add a little space under it CGFloat height = 0; - LinphoneEventLog *nextEvent = nil; - NSInteger indexOfNextEvent = indexPath.row + 1; - while (!nextEvent && indexOfNextEvent < [eventList count]) { - LinphoneEventLog *tmp = [[eventList objectAtIndex:indexOfNextEvent] pointerValue]; - if (linphone_event_log_get_type(tmp) == LinphoneEventLogTypeConferenceChatMessage) { - nextEvent = tmp; - } - ++indexOfNextEvent; - } - if (nextEvent) { - LinphoneChatMessage *nextChat = linphone_event_log_get_chat_message(nextEvent); - if (!linphone_address_equal(linphone_chat_message_get_from_address(nextChat), linphone_chat_message_get_from_address(chat))) { - height += tableView.frame.size.height * MESSAGE_SPACING_PERCENTAGE / 100; - } - } + if ([self isLastIndexInTableView:indexPath chat:chat]) + height += tableView.frame.size.height * MESSAGE_SPACING_PERCENTAGE / 100; + if (![self isFirstIndexInTableView:indexPath chat:chat]) + height -= 20; + return [UIChatBubbleTextCell ViewHeightForMessage:chat withWidth:self.view.frame.size.width].height + height; } return [UIChatNotifiedEventCell height]; @@ -249,11 +318,15 @@ static const CGFloat MESSAGE_SPACING_PERCENTAGE = 0.f; [tableView beginUpdates]; LinphoneEventLog *event = [[eventList objectAtIndex:indexPath.row] pointerValue]; linphone_event_log_delete_from_database(event); + NSInteger index = indexPath.row + _currentIndex + (totalEventList.count - eventList.count); + if (index < totalEventList.count) + [totalEventList removeObjectAtIndex:index]; [eventList removeObjectAtIndex:indexPath.row]; [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationBottom]; [tableView endUpdates]; + [self loadData]; } - (NSArray *)tableView:(UITableView *)tableView @@ -293,6 +366,9 @@ static const CGFloat MESSAGE_SPACING_PERCENTAGE = 0.f; [super removeSelectionUsing:^(NSIndexPath *indexPath) { LinphoneEventLog *event = [[eventList objectAtIndex:indexPath.row] pointerValue]; linphone_event_log_delete_from_database(event); + NSInteger index = indexPath.row + _currentIndex + (totalEventList.count - eventList.count); + if (index < totalEventList.count) + [totalEventList removeObjectAtIndex:index]; [eventList removeObjectAtIndex:indexPath.row]; }]; } diff --git a/Classes/ChatConversationView.h b/Classes/ChatConversationView.h index 3fa69519f..ef2171bbd 100644 --- a/Classes/ChatConversationView.h +++ b/Classes/ChatConversationView.h @@ -18,6 +18,8 @@ */ #import +#import +#import #import "UIToggleButton.h" #import "UICompositeView.h" @@ -28,21 +30,37 @@ #import "UIBackToCallButton.h" #import "Utils/HPGrowingTextView/HPGrowingTextView.h" #import "UIImageViewDeletable.h" +#import "UIConfirmationDialog.h" #include "linphone/linphonecore.h" +//Quicklook Preview Item +@interface PreviewItem : NSObject +@property(readonly, nonatomic) NSURL *previewItemURL; +@property(readonly, nonatomic) NSString *previewItemTitle; +@end + +//QuickLook Datasource for rending PDF docs +@interface FileDataSource : NSObject +@property (strong, nonatomic) PreviewItem *item; +@end + @interface ChatConversationView : TPMultiLayoutViewController { + UIDocumentInteractionControllerDelegate, UISearchBarDelegate, UIImageViewDeletableDelegate,QLPreviewControllerDelegate, UICollectionViewDataSource,UIDocumentMenuDelegate,UIDocumentPickerDelegate> { OrderedDictionary *imageQualities; BOOL scrollOnGrowingEnabled; BOOL composingVisible; + UIConfirmationDialog *securityDialog; + UIRefreshControl *refreshControl; } @property(nonatomic) LinphoneChatRoom *chatRoom; @property(nonatomic) LinphoneChatRoomCbs *chatRoomCbs; @property(nonatomic) Boolean markAsRead; +@property (strong, nonatomic) FileDataSource *FileDataSource; + @property(weak, nonatomic) IBOutlet UIIconButton *backButton; @property(nonatomic, strong) IBOutlet ChatConversationTableView *tableController; @property(weak, nonatomic) IBOutlet HPGrowingTextView *messageField; @@ -60,12 +78,13 @@ @property(weak, nonatomic) IBOutlet UIBackToCallButton *backToCallButton; @property (weak, nonatomic) IBOutlet UIIconButton *infoButton; @property (weak, nonatomic) IBOutlet UILabel *particpantsLabel; -@property (nonatomic, strong) UIDocumentInteractionController *documentInteractionController; +//@property (nonatomic, strong) UIDocumentInteractionController *documentInteractionController; @property NSMutableArray *imagesArray; @property NSMutableArray *assetIdsArray; @property NSMutableArray *qualitySettingsArray; @property (weak, nonatomic) IBOutlet UICollectionView *imagesCollectionView; @property (weak, nonatomic) IBOutlet UIView *imagesView; +@property (weak, nonatomic) IBOutlet UIButton *encryptedButton; + (void)markAsRead:(LinphoneChatRoom *)chatRoom; @@ -79,8 +98,14 @@ - (IBAction)onCallClick:(id)sender; - (IBAction)onDeleteClick:(id)sender; - (IBAction)onEditionChangeClick:(id)sender; +- (IBAction)onEncryptedDevicesClick:(id)sender; - (void)update; -- (void)openFile:(NSString *) filePath; +- (void)openFileWithURL:(NSURL *)url; - (void)clearMessageView; +- (void)showFileDownloadError; +- (void)autoDownload:(LinphoneChatMessage *)message view:(ChatConversationView *)view; +- (NSURL *)getICloudFileUrl:(NSString *)name; +- (BOOL)writeFileInICloud:(NSData *)data fileURL:(NSURL *)fileURL; + @end diff --git a/Classes/ChatConversationView.m b/Classes/ChatConversationView.m index 840cc3d7f..71f42f2d0 100644 --- a/Classes/ChatConversationView.m +++ b/Classes/ChatConversationView.m @@ -24,9 +24,39 @@ #import "Utils.h" #import "FileTransferDelegate.h" #import "UIChatBubbleTextCell.h" +#import "DevicesListView.h" +#import "SVProgressHUD.h" + + +@implementation PreviewItem +- (instancetype)initPreviewURL:(NSURL *)docURL + WithTitle:(NSString *)title { + self = [super init]; + if (self) { + _previewItemURL = [docURL copy]; + _previewItemTitle = [title copy]; + } + return self; +} +@end + +@implementation FileDataSource +- (instancetype)initWithPreviewItem:(PreviewItem *)item { + self = [super init]; + if (self) { + _item = item; + } + return self; +} +- (NSInteger)numberOfPreviewItemsInPreviewController:(QLPreviewController *)controller { + return 1; +} +- (id)previewController:(QLPreviewController *)controller previewItemAtIndex:(NSInteger)index { + return self.item; +} +@end @implementation ChatConversationView -static NSString* groupName = @"group.belledonne-communications.linphone"; #pragma mark - Lifecycle Functions @@ -36,6 +66,7 @@ static NSString* groupName = @"group.belledonne-communications.linphone"; scrollOnGrowingEnabled = TRUE; _chatRoom = NULL; _chatRoomCbs = NULL; + securityDialog = NULL; imageQualities = [[OrderedDictionary alloc] initWithObjectsAndKeys:[NSNumber numberWithFloat:0.9], NSLocalizedString(@"Maximum", nil), [NSNumber numberWithFloat:0.5], NSLocalizedString(@"Average", nil), @@ -93,7 +124,11 @@ static UICompositeViewDescription *compositeDescription = nil; _backButton.hidden = YES; _backButton.alpha = 0; } - + + refreshControl = [[UIRefreshControl alloc]init]; + [refreshControl addTarget:self action:@selector(refreshData) forControlEvents:UIControlEventValueChanged]; + _tableController.refreshControl = refreshControl; + _messageField.minNumberOfLines = 1; _messageField.maxNumberOfLines = IPAD ? 10 : 3; _messageField.delegate = self; @@ -105,6 +140,17 @@ static UICompositeViewDescription *compositeDescription = nil; [_imagesCollectionView setDataSource:self]; } +- (void)refreshData { + [_tableController refreshData]; + [refreshControl endRefreshing]; + if (_tableController.totalNumberOfItems == 0) + return; + [_tableController loadData]; + [_tableController.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:_tableController.currentIndex inSection:0] + atScrollPosition:UITableViewScrollPositionTop + animated:false]; +} + - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; [NSNotificationCenter.defaultCenter addObserver:self @@ -145,6 +191,8 @@ static UICompositeViewDescription *compositeDescription = nil; } completion:nil]; } + [self configureForRoom:self.editing]; + } - (void)viewWillDisappear:(BOOL)animated { @@ -196,6 +244,7 @@ static UICompositeViewDescription *compositeDescription = nil; linphone_chat_room_cbs_set_is_composing_received(_chatRoomCbs, on_chat_room_is_composing_received); linphone_chat_room_cbs_set_conference_joined(_chatRoomCbs, on_chat_room_conference_joined); linphone_chat_room_cbs_set_conference_left(_chatRoomCbs, on_chat_room_conference_left); + linphone_chat_room_cbs_set_security_event(_chatRoomCbs, on_chat_room_conference_alert); linphone_chat_room_cbs_set_user_data(_chatRoomCbs, (__bridge void*)self); linphone_chat_room_add_callbacks(_chatRoom, _chatRoomCbs); } @@ -227,11 +276,16 @@ static UICompositeViewDescription *compositeDescription = nil; [_tableController setChatRoom:_chatRoom]; _chatView.hidden = NO; + UIImage *image = [FastAddressBook imageForSecurityLevel:linphone_chat_room_get_security_level(_chatRoom)]; + [_encryptedButton setImage:image forState:UIControlStateNormal]; + _encryptedButton.hidden = image ? FALSE : TRUE; [self update]; [self shareFile]; } - (void)shareFile { + NSString* groupName = [NSString stringWithFormat:@"group.%@.linphoneExtension",[[NSBundle mainBundle] bundleIdentifier]]; + NSUserDefaults *defaults = [[NSUserDefaults alloc] initWithSuiteName:groupName]; NSDictionary *dict = [defaults valueForKey:@"photoData"]; NSDictionary *dictFile = [defaults valueForKey:@"icloudData"]; @@ -239,13 +293,18 @@ static UICompositeViewDescription *compositeDescription = nil; if (dict) { //file shared from photo lib NSString *fileName = dict[@"url"]; + [_messageField setText:dict[@"message"]]; NSString *key = [[fileName componentsSeparatedByString:@"."] firstObject]; NSMutableDictionary * assetDict = [LinphoneUtils photoAssetsDictionary]; - if ([fileName hasSuffix:@"JPG"] || [fileName hasSuffix:@"PNG"]) { + PHAsset *phasset = [assetDict objectForKey:key]; + if (!phasset) { + // for the images or videos not really in the photo album + [self confirmShare:dict[@"nsData"] url:nil fileName:fileName assetId:nil]; + } else if ([fileName hasSuffix:@"JPG"] || [fileName hasSuffix:@"PNG"] || [fileName hasSuffix:@"jpg"] || [fileName hasSuffix:@"png"]) { UIImage *image = [[UIImage alloc] initWithData:dict[@"nsData"]]; - [self chooseImageQuality:image assetId:[[assetDict objectForKey:key] localIdentifier]]; - } else if ([fileName hasSuffix:@"MOV"]) { - [self confirmShare:dict[@"nsData"] url:nil fileName:nil assetId:[[assetDict objectForKey:key] localIdentifier]]; + [self chooseImageQuality:image assetId:[phasset localIdentifier]]; + } else if ([fileName hasSuffix:@"MOV"] || [fileName hasSuffix:@"mov"]) { + [self confirmShare:dict[@"nsData"] url:nil fileName:nil assetId:[phasset localIdentifier]]; } else { LOGE(@"Unable to parse file %@",fileName); } @@ -253,11 +312,13 @@ static UICompositeViewDescription *compositeDescription = nil; [defaults removeObjectForKey:@"photoData"]; } else if (dictFile) { NSString *fileName = dictFile[@"url"]; + [_messageField setText:dictFile[@"message"]]; [self confirmShare:dictFile[@"nsData"] url:nil fileName:fileName assetId:nil]; [defaults removeObjectForKey:@"icloudData"]; } else if (dictUrl) { NSString *url = dictUrl[@"url"]; + [_messageField setText:dictUrl[@"message"]]; [self confirmShare:nil url:url fileName:nil assetId:nil]; [defaults removeObjectForKey:@"url"]; @@ -272,7 +333,7 @@ static UICompositeViewDescription *compositeDescription = nil; } - (void)callUpdateEvent:(NSNotification *)notif { - [_backToCallButton update]; + [self updateSuperposedButtons]; } - (void)update { @@ -335,6 +396,9 @@ static UICompositeViewDescription *compositeDescription = nil; } - (void)chooseImageQuality:(UIImage *)image assetId:(NSString *)phAssetId { + [SVProgressHUD show]; + NSMutableDictionary *optionsBlock = [[NSMutableDictionary alloc] init]; + NSMutableDictionary *optionsText = [[NSMutableDictionary alloc] init]; DTActionSheet *sheet = [[DTActionSheet alloc] initWithTitle:NSLocalizedString(@"Choose the image size", nil)]; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ for (NSString *key in [imageQualities allKeys]) { @@ -342,13 +406,17 @@ static UICompositeViewDescription *compositeDescription = nil; NSData *data = UIImageJPEGRepresentation(image, [quality floatValue]); NSNumber *size = [NSNumber numberWithInteger:[data length]]; NSString *text = [NSString stringWithFormat:@"%@ (%@)", key, [size toHumanReadableSize]]; - [sheet addButtonWithTitle:text - block:^() { - [self saveAndSend:image assetId:phAssetId withQuality:[quality floatValue]]; - }]; + [optionsBlock setObject:^() { + [self saveAndSend:image assetId:phAssetId withQuality:[quality floatValue]]; + } forKey:key]; + [optionsText setObject:text forKey:key]; } - [sheet addCancelButtonWithTitle:NSLocalizedString(@"Cancel", nil) block:nil]; dispatch_async(dispatch_get_main_queue(), ^{ + for (NSString *key in [imageQualities allKeys]) { + [sheet addButtonWithTitle:[optionsText objectForKey:key] block:[optionsBlock objectForKey:key]]; + } + [sheet addCancelButtonWithTitle:NSLocalizedString(@"Cancel", nil) block:nil]; + [SVProgressHUD dismiss]; [sheet showInView:PhoneMainView.instance.view]; }); }); @@ -359,6 +427,9 @@ static UICompositeViewDescription *compositeDescription = nil; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ [sheet addButtonWithTitle:@"send to this friend" block:^() { + if (![[self.messageField text] isEqualToString:@""]) { + [self sendMessageInMessageField]; + } if (url) [self sendMessage:url withExterlBodyUrl:nil withInternalURL:nil]; else if (fileName) @@ -429,8 +500,10 @@ static UICompositeViewDescription *compositeDescription = nil; - (void)updateParticipantLabel { LinphoneChatRoomCapabilitiesMask capabilities = linphone_chat_room_get_capabilities(_chatRoom); + CGRect frame = _addressLabel.frame; if (capabilities & LinphoneChatRoomCapabilitiesOneToOne) { _particpantsLabel.hidden = TRUE; + frame.origin.y = (_topBar.frame.size.height - _addressLabel.frame.size.height)/2; } else { _particpantsLabel.hidden = FALSE; bctbx_list_t *participants = linphone_chat_room_get_participants(_chatRoom); @@ -444,7 +517,18 @@ static UICompositeViewDescription *compositeDescription = nil; [FastAddressBook displayNameForAddress:linphone_participant_get_address(participant)]]; participants = participants->next; } + frame.origin.y = 0; } + _addressLabel.frame = frame; +} + +- (void)sendMessageInMessageField { + if ([self sendMessage:[_messageField text] withExterlBodyUrl:nil withInternalURL:nil]) { + scrollOnGrowingEnabled = FALSE; + [_messageField setText:@""]; + scrollOnGrowingEnabled = TRUE; + [self onMessageChange:nil]; + } } #pragma mark - UITextFieldDelegate Functions @@ -524,16 +608,20 @@ static UICompositeViewDescription *compositeDescription = nil; for (i = 0; i < [_imagesArray count] - 1; ++i) { [self startImageUpload:[_imagesArray objectAtIndex:i] assetId:[_assetIdsArray objectAtIndex:i] withQuality:[_qualitySettingsArray objectAtIndex:i].floatValue]; } - [self startImageUpload:[_imagesArray objectAtIndex:i] assetId:[_assetIdsArray objectAtIndex:i] withQuality:[_qualitySettingsArray objectAtIndex:i].floatValue andMessage:[self.messageField text]]; + BOOL isOneToOneChat = linphone_chat_room_get_capabilities(_chatRoom) & LinphoneChatRoomCapabilitiesOneToOne; + if (isOneToOneChat) { + [self startImageUpload:[_imagesArray objectAtIndex:i] assetId:[_assetIdsArray objectAtIndex:i] withQuality:[_qualitySettingsArray objectAtIndex:i].floatValue]; + if (![[self.messageField text] isEqualToString:@""]) { + [self sendMessage:[_messageField text] withExterlBodyUrl:nil withInternalURL:nil]; + } + } else { + [self startImageUpload:[_imagesArray objectAtIndex:i] assetId:[_assetIdsArray objectAtIndex:i] withQuality:[_qualitySettingsArray objectAtIndex:i].floatValue andMessage:[self.messageField text]]; + } + [self clearMessageView]; return; } - if ([self sendMessage:[_messageField text] withExterlBodyUrl:nil withInternalURL:nil]) { - scrollOnGrowingEnabled = FALSE; - [_messageField setText:@""]; - scrollOnGrowingEnabled = TRUE; - [self onMessageChange:nil]; - } + [self sendMessageInMessageField]; } - (IBAction)onListTap:(id)sender { @@ -561,6 +649,44 @@ static UICompositeViewDescription *compositeDescription = nil; [self updateSuperposedButtons]; } +- (IBAction)onEncryptedDevicesClick:(id)sender { + BOOL isOneToOne = linphone_chat_room_get_capabilities(_chatRoom) & LinphoneChatRoomCapabilitiesOneToOne; + NSString *message = NSLocalizedString(@"Instant messages are end-to-end encrypted in secured conversations. It is possible to upgrade the security level of a conversation by authenticating participants. To do so, call the contact and follow the authentification process.",nil); + BOOL notAskAgain = [LinphoneManager.instance lpConfigBoolForKey:@"confirmation_dialog_before_sas_call_not_ask_again"]; + if (isOneToOne) { + bctbx_list_t *participants = linphone_chat_room_get_participants(_chatRoom); + + LinphoneParticipant *firstParticipant = participants ? (LinphoneParticipant *)participants->data : NULL; + const LinphoneAddress *addr = firstParticipant ? linphone_participant_get_address(firstParticipant) : linphone_chat_room_get_peer_address(_chatRoom); + if (bctbx_list_size(linphone_participant_get_devices(firstParticipant)) == 1) { + if (notAskAgain) { + [LinphoneManager.instance doCallWithSas:addr isSas:TRUE]; + } else { + securityDialog = [UIConfirmationDialog ShowWithMessage:message cancelMessage:NSLocalizedString(@"CANCEL", nil) confirmMessage:NSLocalizedString(@"CALL", nil) onCancelClick:^() { + } onConfirmationClick:^() { + [LinphoneManager.instance doCallWithSas:addr isSas:TRUE]; + }]; + [_messageField resignFirstResponder]; + securityDialog.authView.hidden = FALSE; + [securityDialog setSpecialColor]; + } + return; + } + } + + if (notAskAgain) { + [self goToDeviceListView]; + } else { + securityDialog = [UIConfirmationDialog ShowWithMessage:message cancelMessage:NSLocalizedString(@"CANCEL", nil) confirmMessage:NSLocalizedString(@"OK", nil) onCancelClick:^() { + } onConfirmationClick:^() { + [self goToDeviceListView]; + }]; + [_messageField resignFirstResponder]; + securityDialog.authView.hidden = FALSE; + [securityDialog setSpecialColor]; + } +} + - (IBAction)onCallClick:(id)sender { bctbx_list_t *participants = linphone_chat_room_get_participants(_chatRoom); LinphoneParticipant *firstParticipant = participants ? (LinphoneParticipant *)participants->data : NULL; @@ -582,7 +708,8 @@ static UICompositeViewDescription *compositeDescription = nil; - (IBAction)onPictureClick:(id)event { [_messageField resignFirstResponder]; - [ImagePickerView SelectImageFromDevice:self atPosition:_pictureButton inView:self.view]; + [ImagePickerView SelectImageFromDevice:self atPosition:_pictureButton inView:self.view withDocumentMenuDelegate:self]; + } - (IBAction)onInfoClick:(id)sender { @@ -663,6 +790,83 @@ static UICompositeViewDescription *compositeDescription = nil; [self chooseImageQuality:image assetId:phAssetId]; } + +- (void)imagePickerDelegateVideo:(NSURL*)url info:(NSDictionary *)info { + NSURL * mediaURL = [info objectForKey:UIImagePickerControllerMediaURL]; + [SVProgressHUD show]; + AVAsset *video = [AVAsset assetWithURL:mediaURL]; + AVAssetExportSession *exportSession = [AVAssetExportSession exportSessionWithAsset:video presetName:AVAssetExportPresetMediumQuality]; + exportSession.shouldOptimizeForNetworkUse = YES; + exportSession.outputFileType = AVFileTypeMPEG4; + + NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); + NSString *documentsDirectory = [paths objectAtIndex:0]; + + NSString *localname = [[[mediaURL absoluteString] md5] stringByAppendingString:@".mp4"]; + NSURL *compressedVideoUrl=[[NSURL fileURLWithPath:documentsDirectory] URLByAppendingPathComponent:localname]; + exportSession.outputURL = compressedVideoUrl; + [exportSession exportAsynchronouslyWithCompletionHandler:^{ + dispatch_async(dispatch_get_main_queue(), ^{ + [SVProgressHUD dismiss]; + [self startFileUpload:[NSData dataWithContentsOfURL:compressedVideoUrl] withName:localname]; + }); + }]; + + if (![info valueForKey:UIImagePickerControllerReferenceURL]) { + [self writeVideoToGallery:mediaURL]; + } +} + + +-(void) writeVideoToGallery:(NSURL *)url { + NSString *localIdentifier; + PHFetchResult *assetCollections = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:nil]; + for (PHAssetCollection *assetCollection in assetCollections) { + if([[assetCollection localizedTitle] isEqualToString:[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleDisplayName"]] ){ + localIdentifier = assetCollection.localIdentifier; + break; + } + } + if(localIdentifier ){ + PHFetchResult *fetchResult = [PHAssetCollection fetchAssetCollectionsWithLocalIdentifiers:@[localIdentifier] options:nil]; + PHAssetCollection *assetCollection = fetchResult.firstObject; + + [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{ + PHAssetChangeRequest *assetChangeRequest = [PHAssetChangeRequest creationRequestForAssetFromVideoAtFileURL:url]; + + PHAssetCollectionChangeRequest *assetCollectionChangeRequest = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:assetCollection]; + [assetCollectionChangeRequest addAssets:@[[assetChangeRequest placeholderForCreatedAsset]]]; + } completionHandler:^(BOOL success, NSError *error) { + if (!success) { + NSLog(@"Error creating asset: %@", error); + } + }]; + }else{ + __block PHObjectPlaceholder *albumPlaceholder; + [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{ + PHAssetCollectionChangeRequest *changeRequest = [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleDisplayName"]]; + albumPlaceholder = changeRequest.placeholderForCreatedAssetCollection; + } completionHandler:^(BOOL success, NSError *error) { + if (success) { + PHFetchResult *fetchResult = [PHAssetCollection fetchAssetCollectionsWithLocalIdentifiers:@[albumPlaceholder.localIdentifier] options:nil]; + PHAssetCollection *assetCollection = fetchResult.firstObject; + + [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{ + PHAssetChangeRequest *assetChangeRequest = [PHAssetChangeRequest creationRequestForAssetFromVideoAtFileURL:url]; + PHAssetCollectionChangeRequest *assetCollectionChangeRequest = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:assetCollection]; + [assetCollectionChangeRequest addAssets:@[[assetChangeRequest placeholderForCreatedAsset]]]; + } completionHandler:^(BOOL success, NSError *error) { + if (!success) { + NSLog(@"Error creating asset: %@", error); + } + }]; + } else { + NSLog(@"Error creating album: %@", error); + } + }]; + } +} + - (void)tableViewIsScrolling { // if user is scrolling in table view, we should hide the keyboard if ([_messageField isFirstResponder]) { @@ -852,6 +1056,8 @@ void on_chat_room_participant_removed(LinphoneChatRoom *cr, const LinphoneEventL [view.tableController addEventEntry:(LinphoneEventLog *)event_log]; [view updateParticipantLabel]; [view.tableController scrollToBottom:true]; + UIImage *image = [FastAddressBook imageForSecurityLevel:linphone_chat_room_get_security_level(cr)]; + [view.encryptedButton setImage:image forState:UIControlStateNormal]; } void on_chat_room_participant_admin_status_changed(LinphoneChatRoom *cr, const LinphoneEventLog *event_log) { @@ -866,19 +1072,32 @@ void on_chat_room_chat_message_received(LinphoneChatRoom *cr, const LinphoneEven LinphoneChatMessage *chat = linphone_event_log_get_chat_message(event_log); if (!chat) return; - - if (!linphone_chat_message_is_file_transfer(chat) && !linphone_chat_message_is_text(chat)) /*probably an imdn*/ + + BOOL hasFile = FALSE; + // if auto_download is available and file is downloaded + if ((linphone_core_get_max_size_for_auto_download_incoming_files(LC) > -1) && linphone_chat_message_get_file_transfer_information(chat)) + hasFile = TRUE; + + if (!linphone_chat_message_is_file_transfer(chat) && !linphone_chat_message_is_text(chat) && !hasFile) /*probably an imdn*/ return; const LinphoneAddress *from = linphone_chat_message_get_from_address(chat); if (!from) return; + + if (hasFile) { + [view autoDownload:chat view:view]; + [view.tableController addEventEntry:(LinphoneEventLog *)event_log]; + return; + } [view.tableController addEventEntry:(LinphoneEventLog *)event_log]; [NSNotificationCenter.defaultCenter postNotificationName:kLinphoneMessageReceived object:view]; [view.tableController scrollToLastUnread:TRUE]; } + + void on_chat_room_chat_message_sent(LinphoneChatRoom *cr, const LinphoneEventLog *event_log) { ChatConversationView *view = (__bridge ChatConversationView *)linphone_chat_room_cbs_get_user_data(linphone_chat_room_get_current_callbacks(cr)); [view.tableController addEventEntry:(LinphoneEventLog *)event_log]; @@ -899,6 +1118,8 @@ void on_chat_room_conference_joined(LinphoneChatRoom *cr, const LinphoneEventLog ChatConversationView *view = (__bridge ChatConversationView *)linphone_chat_room_cbs_get_user_data(linphone_chat_room_get_current_callbacks(cr)); [view configureForRoom:false]; [view.tableController scrollToBottom:true]; + if (IPAD) + [NSNotificationCenter.defaultCenter postNotificationName:kLinphoneMessageReceived object:nil]; } void on_chat_room_conference_left(LinphoneChatRoom *cr, const LinphoneEventLog *event_log) { @@ -907,17 +1128,93 @@ void on_chat_room_conference_left(LinphoneChatRoom *cr, const LinphoneEventLog * [view.tableController scrollToBottom:true]; } -- (void)openFile:(NSString *) filePath +- (void)goToDeviceListView { + DevicesListView *view = VIEW(DevicesListView); + view.room = _chatRoom; + [PhoneMainView.instance popToView:view.compositeViewDescription]; +} + +void on_chat_room_conference_alert(LinphoneChatRoom *cr, const LinphoneEventLog *event_log) { + ChatConversationView *view = (__bridge ChatConversationView *)linphone_chat_room_cbs_get_user_data(linphone_chat_room_get_current_callbacks(cr)); + [view.tableController addEventEntry:(LinphoneEventLog *)event_log]; + [view.tableController scrollToBottom:true]; + UIImage *image = [FastAddressBook imageForSecurityLevel:linphone_chat_room_get_security_level(cr)]; + [view.encryptedButton setImage:image forState:UIControlStateNormal]; +} + +- (void)openFileWithURL:(NSURL *)url { - // Open the controller. - _documentInteractionController = [UIDocumentInteractionController interactionControllerWithURL:[NSURL fileURLWithPath:filePath]]; - _documentInteractionController.delegate = self; + //create the Quicklook controller. + QLPreviewController *qlController = [[QLPreviewController alloc] init]; - BOOL canOpen = [_documentInteractionController presentOpenInMenuFromRect:CGRectZero inView:self.view animated:YES]; - //NO app can open the file - if (canOpen == NO) { - [[[UIAlertView alloc] initWithTitle:@"Info" message:@"There is no app found to open it" delegate:nil cancelButtonTitle:@"cancel" otherButtonTitles:nil, nil] show]; + PreviewItem *item = [[PreviewItem alloc] initPreviewURL:url WithTitle:[url lastPathComponent]]; + self.FileDataSource = [[FileDataSource alloc] initWithPreviewItem:item]; + + qlController.dataSource = self.FileDataSource; + qlController.delegate = self; + + //present the document. + [self presentViewController:qlController animated:YES completion:nil]; +} + + +- (void)previewControllerDidDismiss:(QLPreviewController *)controller +{ + // QuickLook: When done button is pushed + [PhoneMainView.instance fullScreen:NO]; +} + +- (NSURL *)getICloudFileUrl:(NSString *)name { + if (@available(iOS 11.0, *)) { + return [NSURL fileURLWithPath:[LinphoneManager documentFile:name]]; + } + + NSFileManager *fileManager = [NSFileManager defaultManager]; + NSURL *icloudPath = [[fileManager URLForUbiquityContainerIdentifier:nil] URLByAppendingPathComponent:@"Documents"]; + + if (icloudPath) { + if (![fileManager fileExistsAtPath:icloudPath.path isDirectory:nil]) { + LOGI(@"Create directory"); + [fileManager createDirectoryAtURL:icloudPath withIntermediateDirectories:YES attributes:nil error:nil]; + } + return [icloudPath URLByAppendingPathComponent:name]; + } + + return nil; +} + +- (BOOL)writeFileInICloud:(NSData *)data fileURL:(NSURL *)fileURL { + NSFileManager *fileManager = [NSFileManager defaultManager]; + BOOL useMyDevice = FALSE; + if (@available(iOS 11.0, *)) { + useMyDevice = TRUE; + } + + if (!useMyDevice && ![[fileManager URLForUbiquityContainerIdentifier:nil]URLByAppendingPathComponent:@"Documents"]) { + //notify : set configuration to use icloud + [[[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Info", nil) message:NSLocalizedString(@"ICloud Drive is unavailable.", nil) delegate:nil cancelButtonTitle:NSLocalizedString(@"Cancel", nil) otherButtonTitles:nil, nil] show]; + return FALSE; + } + + if ([fileManager fileExistsAtPath:[fileURL path]]) { + // if it exists, replace the file + return [data writeToURL:fileURL atomically:TRUE]; + } else { + // get the url of localfile + NSString *filePath = [[LinphoneManager cacheDirectory] stringByAppendingPathComponent:fileURL.lastPathComponent]; + NSURL *localURL = nil; + if ([fileManager createFileAtPath:filePath contents:data attributes:nil]) { + localURL = [NSURL fileURLWithPath:filePath]; + } + + NSError *error; + if ([[NSFileManager defaultManager] setUbiquitous:YES itemAtURL:localURL destinationURL:fileURL error:&error]) { + return TRUE; + } else { + LOGE(@"Cannot write file in Icloud file [%@]",[error localizedDescription]); + return FALSE; + } } } @@ -997,4 +1294,154 @@ void on_chat_room_conference_left(LinphoneChatRoom *cr, const LinphoneEventLog * } } +- (void)showFileDownloadError { + UIAlertController *errView = [UIAlertController + alertControllerWithTitle:NSLocalizedString(@"File download error", nil) + message:NSLocalizedString(@"Error while downloading the file.\n" + @"The file is probably encrypted.\n" + @"Please retry to download this file after activating LIME.", + nil) + preferredStyle:UIAlertControllerStyleAlert]; + + UIAlertAction *defaultAction = [UIAlertAction actionWithTitle:@"OK" + style:UIAlertActionStyleDefault + handler:^(UIAlertAction *action){ + }]; + + [errView addAction:defaultAction]; + [PhoneMainView.instance presentViewController:errView animated:YES completion:nil]; +} + +- (void)autoDownload:(LinphoneChatMessage *)message view:(ChatConversationView *)view { + //TODO: migrate with "linphone_iphone_file_transfer_recv" + LinphoneContent *content = linphone_chat_message_get_file_transfer_information(message); + NSString *name = [NSString stringWithUTF8String:linphone_content_get_name(content)]; + // get download path + NSString *filePath = [[LinphoneManager cacheDirectory] stringByAppendingPathComponent:name]; + NSFileManager *fileManager = [NSFileManager defaultManager]; + if ([fileManager fileExistsAtPath:filePath]) { + NSData* data = [NSData dataWithContentsOfFile:filePath]; + NSString *fileType = [NSString stringWithUTF8String:linphone_content_get_type(content)]; + + // define a block , not called immediately. To avoid crash when saving photo before PHAuthorizationStatusNotDetermined. + void (^block)(void)= ^ { + if ([fileType isEqualToString:@"image"]) { + // we're finished, save the image and update the message + UIImage *image = [UIImage imageWithData:data]; + if (!image) { + [self showFileDownloadError]; + return; + } + __block PHObjectPlaceholder *placeHolder; + [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{ + PHAssetCreationRequest *request = [PHAssetCreationRequest creationRequestForAssetFromImage:image]; + placeHolder = [request placeholderForCreatedAsset]; + } completionHandler:^(BOOL success, NSError *error) { + dispatch_async(dispatch_get_main_queue(), ^{ + if (error) { + LOGE(@"Cannot save image data downloaded [%@]", [error localizedDescription]); + [LinphoneManager setValueInMessageAppData:nil forKey:@"localimage" inMessage:message]; + UIAlertController *errView = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Transfer error", nil) + message:NSLocalizedString(@"Cannot write image to photo library", + nil) + preferredStyle:UIAlertControllerStyleAlert]; + + UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:@"OK" + style:UIAlertActionStyleDefault + handler:^(UIAlertAction * action) {}]; + + [errView addAction:defaultAction]; + [PhoneMainView.instance presentViewController:errView animated:YES completion:nil]; + } else { + LOGI(@"Image saved to [%@]", [placeHolder localIdentifier]); + [LinphoneManager setValueInMessageAppData:[placeHolder localIdentifier] + forKey:@"localimage" + inMessage:message]; + } + [NSNotificationCenter.defaultCenter postNotificationName:kLinphoneMessageReceived object:view]; + [view.tableController scrollToLastUnread:TRUE]; + }); + }]; + } else if([fileType isEqualToString:@"video"]) { + // until image is properly saved, keep a reminder on it so that the + // chat bubble is aware of the fact that image is being saved to device + + __block PHObjectPlaceholder *placeHolder; + [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{ + PHAssetCreationRequest *request = [PHAssetCreationRequest creationRequestForAssetFromVideoAtFileURL:[NSURL fileURLWithPath:filePath]]; + placeHolder = [request placeholderForCreatedAsset]; + } completionHandler:^(BOOL success, NSError * _Nullable error) { + dispatch_async(dispatch_get_main_queue(), ^{ + if (error) { + LOGE(@"Cannot save video data downloaded [%@]", [error localizedDescription]); + [LinphoneManager setValueInMessageAppData:nil forKey:@"localvideo" inMessage:message]; + UIAlertController *errView = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Transfer error", nil) + message:NSLocalizedString(@"Cannot write video to photo library", + nil) + preferredStyle:UIAlertControllerStyleAlert]; + + UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:@"OK" + style:UIAlertActionStyleDefault + handler:^(UIAlertAction * action) {}]; + + [errView addAction:defaultAction]; + [PhoneMainView.instance presentViewController:errView animated:YES completion:nil]; + } else { + LOGI(@"video saved to [%@]", [placeHolder localIdentifier]); + [LinphoneManager setValueInMessageAppData:[placeHolder localIdentifier] + forKey:@"localvideo" + inMessage:message]; + } + [NSNotificationCenter.defaultCenter postNotificationName:kLinphoneMessageReceived object:view]; + [view.tableController scrollToLastUnread:TRUE]; + }); + }]; + } + }; + + // When you save an image or video to a photo library, make sure that it is allowed. Otherwise, there will be a backup error. + if ([fileType isEqualToString:@"image"] || [fileType isEqualToString:@"video"]) { + if ([PHPhotoLibrary authorizationStatus] == PHAuthorizationStatusAuthorized) { + block(); + } else { + [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) { + dispatch_async(dispatch_get_main_queue(), ^{ + if ([PHPhotoLibrary authorizationStatus] == PHAuthorizationStatusAuthorized) { + block(); + } else { + [[[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Photo's permission", nil) message:NSLocalizedString(@"Photo not authorized", nil) delegate:nil cancelButtonTitle:nil otherButtonTitles:@"Continue", nil] show]; + } + }); + }]; + } + } else { + NSString *key = @"localfile"; + //write file to path + if([view writeFileInICloud:data fileURL:[view getICloudFileUrl:name]]) { + dispatch_async(dispatch_get_main_queue(), ^{ + [LinphoneManager setValueInMessageAppData:name forKey:key inMessage:message]; + //[LinphoneManager setValueInMessageAppData:filePath forKey:@"cachedfile" inMessage:message]; + [NSNotificationCenter.defaultCenter postNotificationName:kLinphoneMessageReceived object:view]; + [view.tableController scrollToLastUnread:TRUE]; + });} + } + } +} + +-(void) documentMenu:(UIDocumentMenuViewController *)documentMenu didPickDocumentPicker:(UIDocumentPickerViewController *)documentPicker { + documentPicker.delegate = self; + [PhoneMainView.instance presentViewController:documentPicker animated:YES completion:nil]; +} + +-(void) documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentAtURL:(NSURL *)url { + [url startAccessingSecurityScopedResource]; + NSFileCoordinator *co =[[NSFileCoordinator alloc] init]; + NSError *error = nil; + [co coordinateReadingItemAtURL:url options:0 error:&error byAccessor:^(NSURL * _Nonnull newURL) { + [self startFileUpload:[NSData dataWithContentsOfURL:newURL] withName:[newURL lastPathComponent]]; + }]; + [url stopAccessingSecurityScopedResource]; +} + + @end diff --git a/Classes/ChatsListTableView.m b/Classes/ChatsListTableView.m index ad78cb768..439341c61 100644 --- a/Classes/ChatsListTableView.m +++ b/Classes/ChatsListTableView.m @@ -98,7 +98,12 @@ static int sorted_history_comparison(LinphoneChatRoom *to_insert, LinphoneChatRo while (iter) { // store last message in user data LinphoneChatRoom *chat_room = iter->data; - sorted = bctbx_list_insert_sorted(sorted, chat_room, (bctbx_compare_func)sorted_history_comparison); + // hide empty one-to-one chat room + LinphoneChatRoomCapabilitiesMask capabilities = linphone_chat_room_get_capabilities(chat_room); + ChatConversationView *view = VIEW(ChatConversationView); + if (linphone_chat_room_get_history_size(chat_room) > 0 || !(capabilities & LinphoneChatRoomCapabilitiesOneToOne) || (IPAD && view.chatRoom == chat_room)) { + sorted = bctbx_list_insert_sorted(sorted, chat_room, (bctbx_compare_func)sorted_history_comparison); + } iter = iter->next; } return sorted; @@ -152,19 +157,23 @@ static int sorted_history_comparison(LinphoneChatRoom *to_insert, LinphoneChatRo forKey:@"peer"]; [dict setObject:[NSString stringWithUTF8String:linphone_address_as_string_uri_only(local_address)] forKey:@"local"]; - if (linphone_chat_room_get_conference_address(cr)) { + LinphoneChatRoomCapabilitiesMask capabilities = linphone_chat_room_get_capabilities(cr); + if (!(capabilities & LinphoneChatRoomCapabilitiesOneToOne)) { if (!linphone_chat_room_get_subject(cr)) { sorted = sorted->next; continue; } display = [NSString stringWithUTF8String:linphone_chat_room_get_subject(cr)]; } else { - if (!linphone_address_get_username(peer_address)) { + bctbx_list_t *participants = linphone_chat_room_get_participants(cr); + LinphoneParticipant *firstParticipant = participants ? (LinphoneParticipant *)participants->data : NULL; + const LinphoneAddress *addr = firstParticipant ? linphone_participant_get_address(firstParticipant) : peer_address; + if (!linphone_address_get_username(addr)) { sorted = sorted->next; continue; } - display = [NSString stringWithUTF8String:linphone_address_get_display_name(peer_address)?:linphone_address_get_username(peer_address)]; - if ([FastAddressBook imageForAddress:peer_address]) + display = [NSString stringWithUTF8String:linphone_address_get_display_name(addr)?:linphone_address_get_username(addr)]; + if ([FastAddressBook imageForAddress:addr]) [dict setObject:UIImageJPEGRepresentation([UIImage resizeImage:[FastAddressBook imageForAddress:peer_address] withMaxWidth:200 andMaxHeight:200], @@ -173,14 +182,15 @@ static int sorted_history_comparison(LinphoneChatRoom *to_insert, LinphoneChatRo } [dict setObject:display forKey:@"display"]; - [dict setObject:[NSNumber numberWithBool:!!linphone_chat_room_get_conference_address(cr)] + BOOL isGroupChat = linphone_chat_room_get_capabilities(cr) & LinphoneChatRoomCapabilitiesConference; + [dict setObject:[NSNumber numberWithBool:isGroupChat] forKey:@"nbParticipants"]; [addresses addObject:dict]; if (addresses.count >= 4) //send no more data than needed break; sorted = sorted->next; - } - + } + [defaults setObject:addresses forKey:@"chatrooms"]; } @@ -215,6 +225,10 @@ static int sorted_history_comparison(LinphoneChatRoom *to_insert, LinphoneChatRo return cell; } +- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(nonnull NSIndexPath *)indexPath { + return 86.0; +} + #pragma mark - UITableViewDelegate Functions - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { diff --git a/Classes/ChatsListView.h b/Classes/ChatsListView.h index 07ec17698..25fa8e88c 100644 --- a/Classes/ChatsListView.h +++ b/Classes/ChatsListView.h @@ -30,9 +30,11 @@ @property(nonatomic, strong) IBOutlet ChatsListTableView *tableController; @property(weak, nonatomic) IBOutlet UIButton *addButton; +@property (weak, nonatomic) IBOutlet UIButton *addGroupChatButton; @property(weak, nonatomic) IBOutlet UIBackToCallButton *backToCallButton; @property (weak, nonatomic) IBOutlet UIView *waitView; +- (IBAction)onAddGroupChatClick:(id)event; - (IBAction)onAddClick:(id)event; - (IBAction)onEditionChangeClick:(id)sender; - (IBAction)onDeleteClick:(id)sender; diff --git a/Classes/ChatsListView.m b/Classes/ChatsListView.m index e7c556ec8..a48149dc4 100644 --- a/Classes/ChatsListView.m +++ b/Classes/ChatsListView.m @@ -43,7 +43,7 @@ - (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; - [NSNotificationCenter.defaultCenter removeObserver:self name:kLinphoneMessageReceived object:nil]; + [NSNotificationCenter.defaultCenter removeObserver:self]; self.view = NULL; } @@ -80,12 +80,25 @@ static UICompositeViewDescription *compositeDescription = nil; #pragma mark - Action Functions +- (void)newChatCreate:(BOOL)isGroup { + ChatConversationCreateView *view = VIEW(ChatConversationCreateView); + view.isForEditing = false; + view.isGroupChat = isGroup; + view.tableController.notFirstTime = FALSE; + [view.tableController.contactsGroup removeAllObjects]; + [PhoneMainView.instance changeCurrentView:view.compositeViewDescription]; +} + +- (IBAction)onAddGroupChatClick:(id)event { + [self newChatCreate:TRUE]; + if (IPAD) + [NSNotificationCenter.defaultCenter postNotificationName:kLinphoneChatCreateViewChange object:VIEW(ChatConversationCreateView) userInfo:nil]; +} + - (IBAction)onAddClick:(id)event { - ChatConversationCreateView *view = VIEW(ChatConversationCreateView); - view.isForEditing = false; - view.tableController.notFirstTime = FALSE; - [view.tableController.contactsGroup removeAllObjects]; - [PhoneMainView.instance changeCurrentView:view.compositeViewDescription]; + [self newChatCreate:FALSE]; + if (IPAD) + [NSNotificationCenter.defaultCenter postNotificationName:kLinphoneChatCreateViewChange object:VIEW(ChatConversationCreateView) userInfo:nil]; } - (IBAction)onEditionChangeClick:(id)sender { diff --git a/Classes/Contact.m b/Classes/Contact.m index d01d1b759..2161be31a 100644 --- a/Classes/Contact.m +++ b/Classes/Contact.m @@ -208,6 +208,7 @@ } NSString *normSip = [sip hasPrefix:@" "] ? [sip substringFromIndex:1] : sip; + normSip = [normSip hasPrefix:@"sip:"] ? [normSip substringFromIndex:4] : normSip; CNInstantMessageAddress *cNSipMsgAddr = [[CNInstantMessageAddress alloc] initWithUsername:normSip service:@"SIP"]; CNLabeledValue *sipAddress = [CNLabeledValue labeledValueWithLabel:NULL value:cNSipMsgAddr]; NSMutableArray *> *tmpSipAddresses = [_person.instantMessageAddresses mutableCopy]; diff --git a/Classes/ContactDetailsView.m b/Classes/ContactDetailsView.m index 5ff5b20cd..a137081b6 100644 --- a/Classes/ContactDetailsView.m +++ b/Classes/ContactDetailsView.m @@ -85,6 +85,21 @@ } PhoneMainView.instance.currentName = _contact.displayName; _nameLabel.text = PhoneMainView.instance.currentName; + + // fix no sipaddresses in contact.friend + const MSList *sips = linphone_friend_get_addresses(_contact.friend); + while (sips) { + linphone_friend_remove_address(_contact.friend, sips->data); + sips = sips->next; + } + + for (NSString *sipAddr in _contact.sipAddresses) { + LinphoneAddress *addr = linphone_core_interpret_url(LC, sipAddr.UTF8String); + if (addr) { + linphone_friend_add_address(_contact.friend, addr); + linphone_address_destroy(addr); + } + } [LinphoneManager.instance.fastAddressBook saveContact:_contact]; } @@ -247,6 +262,8 @@ } _cancelButton.hidden = TRUE; } + + [self recomputeTableViewSize:_editButton.hidden]; } - (void)viewWillDisappear:(BOOL)animated { @@ -360,23 +377,25 @@ static UICompositeViewDescription *compositeDescription = nil; _nameLabel.hidden = editing; [ContactDisplay setDisplayNameLabel:_nameLabel forContact:_contact]; - if ([self viewIsCurrentlyPortrait]) { - CGRect frame = _tableController.tableView.frame; - frame.origin.y = _avatarImage.frame.size.height + _avatarImage.frame.origin.y; - if (!editing) { - frame.origin.y += _nameLabel.frame.size.height; - } - - frame.size.height = _tableController.tableView.contentSize.height; - _tableController.tableView.frame = frame; - [self recomputeContentViewSize]; - } + [self recomputeTableViewSize:editing]; if (animated) { [UIView commitAnimations]; } } +- (void)recomputeTableViewSize:(BOOL)editing { + CGRect frame = _tableController.tableView.frame; + frame.origin.y = _avatarImage.frame.size.height + _avatarImage.frame.origin.y; + if ([self viewIsCurrentlyPortrait] && !editing) { + frame.origin.y += _nameLabel.frame.size.height; + } + + frame.size.height = _tableController.tableView.contentSize.height; + _tableController.tableView.frame = frame; + [self recomputeContentViewSize]; +} + - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change @@ -507,7 +526,7 @@ static UICompositeViewDescription *compositeDescription = nil; - (IBAction)onAvatarClick:(id)sender { [LinphoneUtils findAndResignFirstResponder:self.view]; if (_tableController.isEditing) { - [ImagePickerView SelectImageFromDevice:self atPosition:_avatarImage inView:self.view]; + [ImagePickerView SelectImageFromDevice:self atPosition:_avatarImage inView:self.view withDocumentMenuDelegate:nil]; } } @@ -567,5 +586,8 @@ static UICompositeViewDescription *compositeDescription = nil; [_avatarImage setImage:[FastAddressBook imageForContact:_contact] bordered:NO withRoundedRadius:YES]; } +- (void)imagePickerDelegateVideo:(NSURL*)url info:(NSDictionary *)info { + return; +} @end diff --git a/Classes/DevicesListView.h b/Classes/DevicesListView.h new file mode 100644 index 000000000..c2a6776d8 --- /dev/null +++ b/Classes/DevicesListView.h @@ -0,0 +1,29 @@ +// +// DevicesListView.h +// linphone +// +// Created by Danmei Chen on 06/11/2018. +// +#import +#import "UICompositeView.h" + +@interface DevicesMenuEntry : NSObject { +@public + LinphoneParticipant *participant; + NSInteger numberOfDevices; +}; +@end + +@interface DevicesListView : UIViewController + +@property (weak, nonatomic) IBOutlet UILabel *addressLabel; +@property (weak, nonatomic) IBOutlet UITableView *tableView; + +@property(nonatomic) LinphoneChatRoom *room; +@property bctbx_list_t *devices; +@property NSMutableArray *devicesMenuEntries; +@property BOOL isOneToOne; + +- (IBAction)onBackClick:(id)sender; + +@end diff --git a/Classes/DevicesListView.m b/Classes/DevicesListView.m new file mode 100644 index 000000000..615cb16e5 --- /dev/null +++ b/Classes/DevicesListView.m @@ -0,0 +1,145 @@ +// +// DevicesListView.m +// linphone +// +// Created by Danmei Chen on 06/11/2018. +// + +#import "DevicesListView.h" +#import "PhoneMainView.h" +#import "UIDevicesDetails.h" +#import "UIDeviceCell.h" + +@implementation DevicesMenuEntry + +- (id)initWithTitle:(LinphoneParticipant *)par number:(NSInteger)num { + if ((self = [super init])) { + participant = par; + numberOfDevices = num; + } + return self; +} + +@end + +@implementation DevicesListView +#pragma mark - UICompositeViewDelegate Functions + +static UICompositeViewDescription *compositeDescription = nil; + ++ (UICompositeViewDescription *)compositeViewDescription { + if (compositeDescription == nil) { + compositeDescription = [[UICompositeViewDescription alloc] init:self.class + statusBar:StatusBarView.class + tabBar:TabBarView.class + sideMenu:SideMenuView.class + fullscreen:false + isLeftFragment:NO + fragmentWith:ChatsListView.class]; + } + return compositeDescription; +} + +- (UICompositeViewDescription *)compositeViewDescription { + return self.class.compositeViewDescription; +} + +#pragma mark - ViewController Functions +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; + _tableView.dataSource = self; + _tableView.delegate = self; + _isOneToOne = linphone_chat_room_get_capabilities(_room) & LinphoneChatRoomCapabilitiesOneToOne; + bctbx_list_t *participants = linphone_chat_room_get_participants(_room); + _devicesMenuEntries = [NSMutableArray array]; + + if (_isOneToOne) { + LinphoneParticipant *firstParticipant = participants ? (LinphoneParticipant *)participants->data : NULL; + const LinphoneAddress *addr = firstParticipant ? linphone_participant_get_address(firstParticipant) : linphone_chat_room_get_peer_address(_room); + [ContactDisplay setDisplayNameLabel:_addressLabel forAddress:addr]; + _devices = linphone_participant_get_devices(firstParticipant); + } else { + LinphoneParticipant *participant; + for (int i=0; inumberOfDevices > 1 ? (entry->numberOfDevices + 1) * 56.0 : 56.0; + } + return 56.0; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + if (_isOneToOne) { + NSString *kCellId = NSStringFromClass(UIDeviceCell.class); + UIDeviceCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellId]; + + if (cell == nil) { + cell = [[UIDeviceCell alloc] initWithIdentifier:kCellId]; + } + LinphoneParticipantDevice *device = (LinphoneParticipantDevice *)bctbx_list_nth_data(_devices, (int)[indexPath row]); + cell.device = device; + cell.isOneToOne = TRUE; + [cell update]; + + return cell; + } + + NSString *kCellId = NSStringFromClass(UIDevicesDetails.class); + UIDevicesDetails *cell = [tableView dequeueReusableCellWithIdentifier:kCellId]; + + if (cell == nil) { + cell = [[UIDevicesDetails alloc] initWithIdentifier:kCellId]; + } + + DevicesMenuEntry *entry = [_devicesMenuEntries objectAtIndex:indexPath.row]; + + [ContactDisplay setDisplayNameLabel:cell.addressLabel forAddress:linphone_participant_get_address(entry->participant)]; + cell.participant = entry->participant; + [cell update:(entry->numberOfDevices != 0)]; + + return cell; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { + if (!_isOneToOne) { + DevicesMenuEntry *entry = [_devicesMenuEntries objectAtIndex:indexPath.row]; + NSInteger num = (entry->numberOfDevices != 0) ? 0: bctbx_list_size(linphone_participant_get_devices(entry->participant)); + [_devicesMenuEntries replaceObjectAtIndex:indexPath.row withObject:[[DevicesMenuEntry alloc] initWithTitle:entry->participant number:num]]; + [_tableView reloadData]; + } +} + +@end diff --git a/Classes/DevicesListView.xib b/Classes/DevicesListView.xib new file mode 100644 index 000000000..99070c503 --- /dev/null +++ b/Classes/DevicesListView.xib @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Classes/DialerView.m b/Classes/DialerView.m index 8a0606a8b..c07438ffd 100644 --- a/Classes/DialerView.m +++ b/Classes/DialerView.m @@ -321,9 +321,9 @@ static UICompositeViewDescription *compositeDescription = nil; LOGW(@"Exception while destroying linphone core: %@", e); } @finally { if ([NSFileManager.defaultManager - isDeletableFileAtPath:[LinphoneManager documentFile:@"linphonerc"]] == YES) { + isDeletableFileAtPath:[LinphoneManager preferenceFile:@"linphonerc"]] == YES) { [NSFileManager.defaultManager - removeItemAtPath:[LinphoneManager documentFile:@"linphonerc"] + removeItemAtPath:[LinphoneManager preferenceFile:@"linphonerc"] error:nil]; } #ifdef DEBUG diff --git a/Classes/FirstLoginView.m b/Classes/FirstLoginView.m index d4eea95f5..3d6358c3a 100644 --- a/Classes/FirstLoginView.m +++ b/Classes/FirstLoginView.m @@ -200,18 +200,7 @@ static UICompositeViewDescription *compositeDescription = nil; - (void)onLoginClick:(id)sender { if (!linphone_core_is_network_reachable(LC)) { - UIAlertController *errView = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Network Error", nil) - message:NSLocalizedString(@"There is no network connection available, enable " - @"WIFI or WWAN prior to configure an account", - nil) - preferredStyle:UIAlertControllerStyleAlert]; - - UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"Cancel", nil) - style:UIAlertActionStyleDefault - handler:^(UIAlertAction * action) {}]; - - [errView addAction:defaultAction]; - [self presentViewController:errView animated:YES completion:nil]; + [PhoneMainView.instance presentViewController:[LinphoneUtils networkErrorView] animated:YES completion:nil]; return; } diff --git a/Classes/HistoryDetailsView.h b/Classes/HistoryDetailsView.h index dcae22794..d109e645d 100644 --- a/Classes/HistoryDetailsView.h +++ b/Classes/HistoryDetailsView.h @@ -39,11 +39,15 @@ @property(strong, nonatomic) IBOutlet HistoryDetailsTableView *tableView; @property(weak, nonatomic) IBOutlet UILabel *emptyLabel; @property (weak, nonatomic) IBOutlet UIView *waitView; +@property (weak, nonatomic) IBOutlet UIRoundedImageView *linphoneImage; +@property (weak, nonatomic) IBOutlet UIView *optionsView; +@property (weak, nonatomic) IBOutlet UIView *encryptedChatView; - (IBAction)onBackClick:(id)event; - (IBAction)onAddContactClick:(id)event; - (IBAction)onCallClick:(id)event; - (IBAction)onChatClick:(id)event; +- (IBAction)onEncryptedChatClick:(id)sender; - (void)setCallLogId:(NSString *)acallLogId; @end diff --git a/Classes/HistoryDetailsView.m b/Classes/HistoryDetailsView.m index 708a10185..f7f3bf159 100644 --- a/Classes/HistoryDetailsView.m +++ b/Classes/HistoryDetailsView.m @@ -111,9 +111,7 @@ static UICompositeViewDescription *compositeDescription = nil; } - (void) deviceOrientationDidChange:(NSNotification*) notif { - if (IPAD) { - [self update]; - } + [self update]; } #pragma mark - @@ -146,12 +144,29 @@ static UICompositeViewDescription *compositeDescription = nil; _addContactButton.hidden = ([FastAddressBook getContactWithAddress:addr] != nil); [ContactDisplay setDisplayNameLabel:_contactLabel forAddress:addr withAddressLabel:_addressLabel]; [_avatarImage setImage:[FastAddressBook imageForAddress:addr] bordered:NO withRoundedRadius:YES]; + Contact *contact = [FastAddressBook getContactWithAddress:addr]; + const LinphonePresenceModel *model = contact.friend ? linphone_friend_get_presence_model(contact.friend) : NULL; + _linphoneImage.hidden = + ! ((model && linphone_presence_model_get_basic_status(model) == LinphonePresenceBasicStatusOpen) || [FastAddressBook contactHasValidSipDomain:contact]); + [self shouldHideEncryptedChatView:model && linphone_presence_model_has_capability(model, LinphoneFriendCapabilityLimeX3dh)]; char *addrURI = linphone_address_as_string_uri_only(addr); ms_free(addrURI); [_tableView loadDataForAddress:(callLog ? linphone_call_log_get_remote_address(callLog) : NULL)]; } +- (void)shouldHideEncryptedChatView:(BOOL)hasLime { + _encryptedChatView.hidden = !hasLime; + CGRect newFrame = _optionsView.frame; + if (!hasLime) { + newFrame.origin.x = _encryptedChatView.frame.size.width * 2/3; + + } else { + newFrame.origin.x = 0; + } + _optionsView.frame = newFrame; +} + #pragma mark - Action Functions - (IBAction)onBackClick:(id)event { @@ -174,7 +189,9 @@ static UICompositeViewDescription *compositeDescription = nil; const LinphoneAddress *addr = linphone_call_log_get_remote_address(callLog); char *lAddress = linphone_address_as_string_uri_only(addr); if (lAddress != NULL) { - [ContactSelection setAddAddress:[NSString stringWithUTF8String:lAddress]]; + NSString *normSip = [NSString stringWithUTF8String:lAddress]; + normSip = [normSip hasPrefix:@"sip:"] ? [normSip substringFromIndex:4] : normSip; + [ContactSelection setAddAddress:normSip]; [ContactSelection setSelectionMode:ContactSelectionModeEdit]; [ContactSelection setSipFilter:nil]; @@ -192,7 +209,12 @@ static UICompositeViewDescription *compositeDescription = nil; - (IBAction)onChatClick:(id)event { const LinphoneAddress *addr = linphone_call_log_get_remote_address(callLog); - [PhoneMainView.instance getOrCreateOneToOneChatRoom:addr waitView:_waitView]; + [PhoneMainView.instance getOrCreateOneToOneChatRoom:addr waitView:_waitView isEncrypted:FALSE]; +} + +- (IBAction)onEncryptedChatClick:(id)sender { + const LinphoneAddress *addr = linphone_call_log_get_remote_address(callLog); + [PhoneMainView.instance getOrCreateOneToOneChatRoom:addr waitView:_waitView isEncrypted:TRUE]; } @end diff --git a/Classes/ImagePickerView.h b/Classes/ImagePickerView.h index bc02c7a15..c00bad7cf 100644 --- a/Classes/ImagePickerView.h +++ b/Classes/ImagePickerView.h @@ -22,7 +22,7 @@ @protocol ImagePickerDelegate - (void)imagePickerDelegateImage:(UIImage *)image info:(NSString *)phAssetId; - +- (void)imagePickerDelegateVideo:(NSURL*)url info:(NSDictionary *)info; @end @interface ImagePickerView : UIViewController )delegate - atPosition:(UIView *)ipadPopoverPosition - inView:(UIView *)view; + atPosition:(UIView *)ipadPopoverView + inView:(UIView *)ipadView + withDocumentMenuDelegate:(id)documentMenuDelegate; @end diff --git a/Classes/ImagePickerView.m b/Classes/ImagePickerView.m index f5a0cc62f..d906ab5d7 100644 --- a/Classes/ImagePickerView.m +++ b/Classes/ImagePickerView.m @@ -22,6 +22,9 @@ #import #import "ImagePickerView.h" #import "PhoneMainView.h" +#import "SVProgressHUD.h" +#import "ShareViewController.h" + @implementation ImagePickerView @@ -160,40 +163,112 @@ static UICompositeViewDescription *compositeDescription = nil; #pragma mark - UIImagePickerControllerDelegate Functions - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info { - [self dismiss]; - - NSURL *alassetURL = [info objectForKey:UIImagePickerControllerReferenceURL]; - PHAsset *phasset = nil; - // when photo from camera, it hasn't be saved - if (alassetURL) { - PHFetchResult *phFetchResult = [PHAsset fetchAssetsWithALAssetURLs:@[alassetURL] options:nil]; - phasset = [phFetchResult firstObject]; - } - - UIImage *image = [info objectForKey:UIImagePickerControllerEditedImage] ? [info objectForKey:UIImagePickerControllerEditedImage] : [info objectForKey:UIImagePickerControllerOriginalImage]; - if (!phasset) { - __block PHObjectPlaceholder *placeHolder; - [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{ - PHAssetCreationRequest *request = [PHAssetCreationRequest creationRequestForAssetFromImage:image]; - placeHolder = [request placeholderForCreatedAsset]; - } completionHandler:^(BOOL success, NSError *error) { - if (success) { - LOGI(@"Image saved to [%@]", [placeHolder localIdentifier]); - [self passImageToDelegate:image PHAssetId:[placeHolder localIdentifier]]; - } else { - LOGE(@"Cannot save image data downloaded [%@]", [error localizedDescription]); - } - } - ]; - return; - } - [self passImageToDelegate:image PHAssetId:[phasset localIdentifier]]; + + dispatch_async(dispatch_get_main_queue(), ^{ + + [self dismiss]; + + NSString *type = [info objectForKey:UIImagePickerControllerMediaType]; + if ([type isEqualToString:(NSString *)kUTTypeVideo] || + [type isEqualToString:(NSString *)kUTTypeMovie]) { + NSURL *urlvideo = [info objectForKey:UIImagePickerControllerMediaURL]; + if(urlvideo != nil && self.imagePickerDelegate != nil) { + [imagePickerDelegate imagePickerDelegateVideo:urlvideo info:info]; + } + } else { + NSURL *alassetURL = [info objectForKey:UIImagePickerControllerReferenceURL]; + PHAsset *phasset = nil; + // when photo from camera, it hasn't be saved + if (alassetURL) { + PHFetchResult *phFetchResult = [PHAsset fetchAssetsWithALAssetURLs:@[alassetURL] options:nil]; + phasset = [phFetchResult firstObject]; + } + + UIImage *image = [info objectForKey:UIImagePickerControllerEditedImage] ? [info objectForKey:UIImagePickerControllerEditedImage] : [info objectForKey:UIImagePickerControllerOriginalImage]; + if (!phasset) { + [self writeImageToGallery:image]; + return; + } + [self passImageToDelegate:image PHAssetId:[phasset localIdentifier]]; + } + }); + } + +-(void) writeImageToGallery:(UIImage *)image { + NSString *localIdentifier; + [SVProgressHUD show]; + + PHFetchResult *assetCollections = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:nil]; + __block PHObjectPlaceholder *placeHolder; + + for (PHAssetCollection *assetCollection in assetCollections) { + if([[assetCollection localizedTitle] isEqualToString:[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleDisplayName"]] ){ + localIdentifier = assetCollection.localIdentifier; + break; + } + } + + if(localIdentifier ){ + PHFetchResult *fetchResult = [PHAssetCollection fetchAssetCollectionsWithLocalIdentifiers:@[localIdentifier] options:nil]; + PHAssetCollection *assetCollection = fetchResult.firstObject; + + [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{ + PHAssetChangeRequest *assetChangeRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:image]; + PHAssetCollectionChangeRequest *assetCollectionChangeRequest = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:assetCollection]; + [assetCollectionChangeRequest addAssets:@[[assetChangeRequest placeholderForCreatedAsset]]]; + placeHolder = [assetChangeRequest placeholderForCreatedAsset]; + } completionHandler:^(BOOL success, NSError *error) { + dispatch_async(dispatch_get_main_queue(), ^{ + [SVProgressHUD dismiss]; + if (!success) { + NSLog(@"Error creating asset: %@", error); + } else { + [self passImageToDelegate:image PHAssetId:[placeHolder localIdentifier]]; + } + }); + }]; + }else{ + __block PHObjectPlaceholder *albumPlaceholder; + [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{ + PHAssetCollectionChangeRequest *changeRequest = [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleDisplayName"]]; + albumPlaceholder = changeRequest.placeholderForCreatedAssetCollection; + } completionHandler:^(BOOL success, NSError *error) { + if (success) { + PHFetchResult *fetchResult = [PHAssetCollection fetchAssetCollectionsWithLocalIdentifiers:@[albumPlaceholder.localIdentifier] options:nil]; + PHAssetCollection *assetCollection = fetchResult.firstObject; + + [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{ + PHAssetChangeRequest *assetChangeRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:image]; + PHAssetCollectionChangeRequest *assetCollectionChangeRequest = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:assetCollection]; + [assetCollectionChangeRequest addAssets:@[[assetChangeRequest placeholderForCreatedAsset]]]; + placeHolder = [assetChangeRequest placeholderForCreatedAsset]; + } completionHandler:^(BOOL success, NSError *error) { + dispatch_async(dispatch_get_main_queue(), ^{ + + [SVProgressHUD dismiss]; + if (!success) { + NSLog(@"Error creating asset: %@", error); + } else { + [self passImageToDelegate:image PHAssetId:[placeHolder localIdentifier]]; + } + }); + }]; + } else { + [SVProgressHUD dismiss]; + NSLog(@"Error creating album: %@", error); + } + }]; + + } +} + + - (void) passImageToDelegate:(UIImage *)image PHAssetId:(NSString *)assetId { - if (imagePickerDelegate != nil) { - [imagePickerDelegate imagePickerDelegateImage:image info:(NSString *)assetId]; - } + if (imagePickerDelegate != nil) { + [imagePickerDelegate imagePickerDelegateImage:image info:(NSString *)assetId]; + } } /* if (imagePickerDelegate != nil) { @@ -223,14 +298,15 @@ static UICompositeViewDescription *compositeDescription = nil; + (void)SelectImageFromDevice:(id)delegate atPosition:(UIView *)ipadPopoverView - inView:(UIView *)ipadView { + inView:(UIView *)ipadView + withDocumentMenuDelegate:(id)documentMenuDelegate { void (^block)(UIImagePickerControllerSourceType) = ^(UIImagePickerControllerSourceType type) { ImagePickerView *view = VIEW(ImagePickerView); view.sourceType = type; // Displays a control that allows the user to choose picture or // movie capture, if both are available: - view.mediaTypes = [NSArray arrayWithObject:(NSString *)kUTTypeImage]; + view.mediaTypes = [NSArray arrayWithObjects:(NSString *)kUTTypeMovie,(NSString *)kUTTypeImage,nil]; // Hides the controls for moving & scaling pictures, or for // trimming movies. To instead show the controls, use YES. @@ -271,6 +347,12 @@ static UICompositeViewDescription *compositeDescription = nil; block(UIImagePickerControllerSourceTypePhotoLibrary); }]; } + + if (documentMenuDelegate) { + [sheet addButtonWithTitle:NSLocalizedString(@"Document",nil) block:^(){ + [self pickDocumentForDelegate:documentMenuDelegate]; + }]; + } [sheet addCancelButtonWithTitle:NSLocalizedString(@"Cancel", nil) block:nil]; [sheet showInView:PhoneMainView.instance.view]; @@ -295,6 +377,11 @@ static UICompositeViewDescription *compositeDescription = nil; block(UIImagePickerControllerSourceTypePhotoLibrary); }]; } + if (documentMenuDelegate) { + [sheet addButtonWithTitle:NSLocalizedString(@"Document",nil) block:^(){ + [self pickDocumentForDelegate:documentMenuDelegate]; + }]; + } [sheet addCancelButtonWithTitle:NSLocalizedString(@"Cancel", nil) block:nil]; [sheet showInView:PhoneMainView.instance.view]; @@ -306,4 +393,10 @@ static UICompositeViewDescription *compositeDescription = nil; } } ++(void) pickDocumentForDelegate:(id)documentMenuDelegate { + UIDocumentMenuViewController *documentProviderMenu = [[UIDocumentMenuViewController alloc] initWithDocumentTypes:SUPPORTED_EXTENTIONS inMode:UIDocumentPickerModeImport]; + documentProviderMenu.delegate = documentMenuDelegate; + [PhoneMainView.instance presentViewController:documentProviderMenu animated:YES completion:nil]; +} + @end diff --git a/Classes/InAppProductsManager.m b/Classes/InAppProductsManager.m index d367464b3..cda0cad80 100644 --- a/Classes/InAppProductsManager.m +++ b/Classes/InAppProductsManager.m @@ -473,7 +473,7 @@ LOGE(@"Failed with error %@", response); NSString *errorMsg; if ([response isEqualToString:@"ERROR_ACCOUNT_ALREADY_EXISTS"]) { - errorMsg = NSLocalizedString(@"This account is already registered.", nil); + errorMsg = NSLocalizedString(@"This account is already connected.", nil); } else if ([response isEqualToString:@"ERROR_UID_ALREADY_IN_USE"]) { errorMsg = NSLocalizedString(@"You already own an account.", nil); } else if ([response isEqualToString:@"ERROR_ACCOUNT_DOESNT_EXIST"]) { diff --git a/Classes/LinphoneAppDelegate.m b/Classes/LinphoneAppDelegate.m index ca5863cff..6db97e0af 100644 --- a/Classes/LinphoneAppDelegate.m +++ b/Classes/LinphoneAppDelegate.m @@ -31,6 +31,10 @@ #include "LinphoneManager.h" #include "linphone/linphonecore.h" +#ifdef USE_CRASHLYTHICSS +#include "FIRApp.h" +#endif + @implementation LinphoneAppDelegate @synthesize configURL; @@ -91,11 +95,6 @@ } [instance.fastAddressBook fetchContactsInBackGroundThread]; instance.fastAddressBook.needToUpdate = FALSE; - const MSList *lists = linphone_core_get_friends_lists(LC); - while (lists) { - linphone_friend_list_update_subscriptions(lists->data); - lists = lists->next; - } } LinphoneCall *call = linphone_core_get_current_call(LC); @@ -155,7 +154,7 @@ self.voipRegistry.delegate = self; // Initiate registration. - LOGI(@"[PushKit] Registering for push notifications"); + LOGI(@"[PushKit] Connecting for push notifications"); self.voipRegistry.desiredPushTypes = [NSSet setWithObject:PKPushTypeVoIP]; [self configureUINotification]; @@ -165,7 +164,7 @@ if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_9_x_Max) return; - LOGI(@"Registering for UNNotifications"); + LOGI(@"Connecting for UNNotifications"); // Call category UNNotificationAction *act_ans = [UNNotificationAction actionWithIdentifier:@"Answer" @@ -238,6 +237,14 @@ #pragma deploymate pop - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { +#ifdef USE_CRASHLYTHICSS + NSString *pathForFile=[[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:@"GoogleService-Info.plist"]; + if ([[NSFileManager defaultManager] fileExistsAtPath:pathForFile]){ + // If GoogleService-Info.plist doesn't exist, not call this function avoiding a crash. + [FIRApp configure]; + } +#endif + UIApplication *app = [UIApplication sharedApplication]; UIApplicationState state = app.applicationState; @@ -335,7 +342,7 @@ completionHandler([self handleShortcut:shortcutItem]); } -- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url { +- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary *)options{ NSString *scheme = [[url scheme] lowercaseString]; if ([scheme isEqualToString:@"linphone-config"] || [scheme isEqualToString:@"linphone-config"]) { NSString *encodedURL = @@ -434,7 +441,7 @@ } NSString *callId = [aps objectForKey:@"call-id"] ?: @""; - if ([self addLongTaskIDforCallID:callId] && [UIApplication sharedApplication].applicationState != UIApplicationStateActive) + if ([UIApplication sharedApplication].applicationState != UIApplicationStateActive && [self addLongTaskIDforCallID:callId]) [LinphoneManager.instance startPushLongRunningTask:loc_key callId:callId]; // if we receive a push notification, it is probably because our TCP background socket was no more working. @@ -636,9 +643,13 @@ linphone_call_set_authentication_token_verified(call, NO); } else if ([response.actionIdentifier isEqual:@"Call"]) { return; - } else { // in this case the value is : com.apple.UNNotificationDefaultActionIdentifier + } else { // in this case the value is : com.apple.UNNotificationDefaultActionIdentifier or com.apple.UNNotificationDismissActionIdentifier if ([response.notification.request.content.categoryIdentifier isEqual:@"call_cat"]) { - [PhoneMainView.instance displayIncomingCall:call]; + if ([response.actionIdentifier isEqualToString:@"com.apple.UNNotificationDismissActionIdentifier"]) + // clear notification + linphone_call_decline(call, LinphoneReasonDeclined); + else + [PhoneMainView.instance displayIncomingCall:call]; } else if ([response.notification.request.content.categoryIdentifier isEqual:@"msg_cat"]) { NSString *peer_address = [response.notification.request.content.userInfo objectForKey:@"peer_addr"]; NSString *local_address = [response.notification.request.content.userInfo objectForKey:@"local_addr"]; @@ -701,7 +712,7 @@ NSString *message = [NSString stringWithFormat:NSLocalizedString(@"Confirm the following SAS with peer:\n" @"Say : %@\n" @"Your correspondant should say : %@", nil), myCode, correspondantCode]; - [UIConfirmationDialog ShowWithMessage:message + UIConfirmationDialog *securityDialog = [UIConfirmationDialog ShowWithMessage:message cancelMessage:NSLocalizedString(@"DENY", nil) confirmMessage:NSLocalizedString(@"ACCEPT", nil) onCancelClick:^() { @@ -712,6 +723,7 @@ if (linphone_core_get_current_call(LC) == call) linphone_call_set_authentication_token_verified(call, YES); }]; + [securityDialog setSpecialColor]; } else if ([response.notification.request.content.categoryIdentifier isEqual:@"lime"]) { return; } else { // Missed call diff --git a/Classes/LinphoneCoreSettingsStore.m b/Classes/LinphoneCoreSettingsStore.m index 81f182c78..614a3681f 100644 --- a/Classes/LinphoneCoreSettingsStore.m +++ b/Classes/LinphoneCoreSettingsStore.m @@ -330,12 +330,17 @@ [self setBool:[lm lpConfigBoolForKey:@"repeat_call_notification"] forKey:@"repeat_call_notification_preference"]; + [self setBool:[lm lpConfigBoolForKey:@"pref_accept_early_media"] + forKey:@"pref_accept_early_media_preference"]; } // chat section { [self setInteger:linphone_core_lime_enabled(LC) forKey:@"use_lime_preference"]; [self setCString:linphone_core_get_file_transfer_server(LC) forKey:@"file_transfer_server_url_preference"]; + int maxSize = linphone_core_get_max_size_for_auto_download_incoming_files(LC); + [self setObject:maxSize==0 ? @"Always" : (maxSize==-1 ? @"Nerver" : @"Customize") forKey:@"auto_download_mode"]; + [self setInteger:maxSize forKey:@"auto_download_incoming_files_max_size"]; } // network section @@ -764,6 +769,7 @@ linphone_core_set_in_call_timeout(LC, [self integerForKey:@"in_call_timeout_preference"]); [lm lpConfigSetString:[self stringForKey:@"voice_mail_uri_preference"] forKey:@"voice_mail_uri"]; [lm lpConfigSetBool:[self boolForKey:@"repeat_call_notification_preference"] forKey:@"repeat_call_notification"]; + [lm lpConfigSetBool:[self boolForKey:@"pref_accept_early_media_preference"] forKey:@"pref_accept_early_media"]; // chat section int val = [self integerForKey:@"use_lime_preference"]; @@ -784,6 +790,17 @@ [PhoneMainView.instance presentViewController:errView animated:YES completion:nil]; } linphone_core_set_file_transfer_server(LC, [self stringForKey:@"file_transfer_server_url_preference"].UTF8String); + int maxSize; + NSString *downloadMode = [self stringForKey:@"auto_download_mode"]; + if ([downloadMode isEqualToString:@"Never"]) { + maxSize = -1; + } else if ([downloadMode isEqualToString:@"Always"]) { + maxSize = 0; + } else { + maxSize = [[self stringForKey:@"auto_download_incoming_files_max_size"] intValue]; + } + linphone_core_set_max_size_for_auto_download_incoming_files(LC, maxSize); + [lm lpConfigSetString:[self stringForKey:@"auto_download_mode"] forKey:@"auto_download_mode"]; // network section BOOL edgeOpt = [self boolForKey:@"edge_opt_preference"]; @@ -912,11 +929,7 @@ } [lm lpConfigSetInt:[self integerForKey:@"use_rls_presence"] forKey:@"use_rls_presence"]; - const MSList *lists = linphone_core_get_friends_lists(LC); - while (lists) { - linphone_friend_list_enable_subscriptions(lists->data, [self integerForKey:@"use_rls_presence"]); - lists = lists->next; - } + linphone_core_enable_friend_list_subscription(LC, [self integerForKey:@"use_rls_presence"]); BOOL firstloginview = [self boolForKey:@"enable_first_login_view_preference"]; [lm lpConfigSetInt:firstloginview forKey:@"enable_first_login_view_preference"]; diff --git a/Classes/LinphoneManager.h b/Classes/LinphoneManager.h index 9dd0454de..6617115aa 100644 --- a/Classes/LinphoneManager.h +++ b/Classes/LinphoneManager.h @@ -57,6 +57,7 @@ extern NSString *const kLinphoneCallEncryptionChanged; extern NSString *const kLinphoneFileTransferSendUpdate; extern NSString *const kLinphoneFileTransferRecvUpdate; extern NSString *const kLinphoneQRCodeFound; +extern NSString *const kLinphoneChatCreateViewChange; typedef enum _NetworkType { network_none = 0, @@ -157,14 +158,18 @@ typedef struct _LinphoneManagerSounds { - (void)configureVbrCodecs; + (BOOL)copyFile:(NSString*)src destination:(NSString*)dst override:(BOOL)override; ++ (PHFetchResult *)getPHAssets:(NSString *)key; + (NSString*)bundleFile:(NSString*)file; -+ (NSString*)documentFile:(NSString*)file; ++ (NSString *)preferenceFile:(NSString *)file; ++ (NSString *)documentFile:(NSString *)file; ++ (NSString*)dataFile:(NSString*)file; + (NSString*)cacheDirectory; - (void)acceptCall:(LinphoneCall *)call evenWithVideo:(BOOL)video; - (void)send:(NSString *)replyText toChatRoom:(LinphoneChatRoom *)room; - (void)call:(const LinphoneAddress *)address; - (BOOL)doCall:(const LinphoneAddress *)iaddr; +- (BOOL)doCallWithSas:(const LinphoneAddress *)iaddr isSas:(BOOL)isSas; +(id)getMessageAppDataForKey:(NSString*)key inMessage:(LinphoneChatMessage*)msg; +(void)setValueInMessageAppData:(id)value forKey:(NSString*)key inMessage:(LinphoneChatMessage*)msg; diff --git a/Classes/LinphoneManager.m b/Classes/LinphoneManager.m index 4986e4940..bf5883f35 100644 --- a/Classes/LinphoneManager.m +++ b/Classes/LinphoneManager.m @@ -77,6 +77,7 @@ NSString *const kLinphoneCallEncryptionChanged = @"LinphoneCallEncryptionChanged NSString *const kLinphoneFileTransferSendUpdate = @"LinphoneFileTransferSendUpdate"; NSString *const kLinphoneFileTransferRecvUpdate = @"LinphoneFileTransferRecvUpdate"; NSString *const kLinphoneQRCodeFound = @"LinphoneQRCodeFound"; +NSString *const kLinphoneChatCreateViewChange = @"LinphoneChatCreateViewChange"; const int kLinphoneAudioVbrCodecDefaultBitrate = 36; /*you can override this from linphonerc or linphonerc-factory*/ @@ -265,6 +266,7 @@ struct codec_name_pref_table codec_pref_table[] = {{"speex", 8000, "speex_8k_pre _linphoneManagerAddressBookMap = [[OrderedDictionary alloc] init]; pushCallIDs = [[NSMutableArray alloc] init]; _isTesting = [LinphoneManager isRunningTests]; + [self migrateImportantFiles]; [self renameDefaultSettings]; [self copyDefaultSettings]; [self overrideDefaultSettings]; @@ -329,6 +331,7 @@ struct codec_name_pref_table codec_pref_table[] = {{"speex", 8000, "speex_8k_pre - (void)migrationAllPost { [self migrationLinphoneSettings]; [self migratePushNotificationPerAccount]; + [self migrateLimeSettings]; } - (void)migrationAllPre { @@ -341,6 +344,7 @@ struct codec_name_pref_table codec_pref_table[] = {{"speex", 8000, "speex_8k_pre [self lpConfigSetBool:YES forKey:@"migration_xmlrpc"]; } [self lpConfigSetBool:NO forKey:@"store_friends" inSection:@"misc"]; //so far, storing friends in files is not needed. may change in the future. + } static int check_should_migrate_images(void *data, int argc, char **argv, char **cnames) { @@ -472,6 +476,20 @@ static void migrateWizardToAssistant(const char *entry, void *user_data) { } } +- (void)migrateLimeSettings { + if ([self lpConfigBoolForKey:@"lime_migration_done"] == FALSE) { + const MSList *proxies = linphone_core_get_proxy_config_list(LC); + while (proxies) { + if (!strcmp(linphone_proxy_config_get_domain((LinphoneProxyConfig *)proxies->data),"sip.linphone.org")) { + linphone_core_set_lime_x3dh_server_url(LC, "https://lime.linphone.org/lime-server/lime-server.php"); + break; + } + proxies = proxies->next; + } + [self lpConfigSetBool:TRUE forKey:@"lime_migration_done"]; + } +} + #pragma mark - Linphone Core Functions + (LinphoneCore *)getLc { @@ -604,18 +622,22 @@ static void linphone_iphone_display_status(struct _LinphoneCore *lc, const char if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_9_x_Max) { if (call && (linphone_core_get_calls_nb(LC) < 2)) { + if ([LinphoneManager.instance lpConfigBoolForKey:@"accept_early_media" inSection:@"app"] && [LinphoneManager.instance lpConfigBoolForKey:@"pref_accept_early_media"]) { + [PhoneMainView.instance displayIncomingCall:call]; + } else { #if !TARGET_IPHONE_SIMULATOR - NSString *callId = [NSString stringWithUTF8String:linphone_call_log_get_call_id(linphone_call_get_call_log(call))]; - NSUUID *uuid = [NSUUID UUID]; - [LinphoneManager.instance.providerDelegate.calls setObject:callId forKey:uuid]; - [LinphoneManager.instance.providerDelegate.uuids setObject:uuid forKey:callId]; - BOOL video = ([UIApplication sharedApplication].applicationState == UIApplicationStateActive && - linphone_video_activation_policy_get_automatically_accept(linphone_core_get_video_activation_policy(LC)) && - linphone_call_params_video_enabled(linphone_call_get_remote_params(call))); - [LinphoneManager.instance.providerDelegate reportIncomingCall:call withUUID:uuid handle:address video:video]; + NSString *callId = [NSString stringWithUTF8String:linphone_call_log_get_call_id(linphone_call_get_call_log(call))]; + NSUUID *uuid = [NSUUID UUID]; + [LinphoneManager.instance.providerDelegate.calls setObject:callId forKey:uuid]; + [LinphoneManager.instance.providerDelegate.uuids setObject:uuid forKey:callId]; + BOOL video = ([UIApplication sharedApplication].applicationState == UIApplicationStateActive && + linphone_video_activation_policy_get_automatically_accept(linphone_core_get_video_activation_policy(LC)) && + linphone_call_params_video_enabled(linphone_call_get_remote_params(call))); + [LinphoneManager.instance.providerDelegate reportIncomingCall:call withUUID:uuid handle:address video:video]; #else - [PhoneMainView.instance displayIncomingCall:call]; + [PhoneMainView.instance displayIncomingCall:call]; #endif + } } else if ([UIApplication sharedApplication].applicationState != UIApplicationStateActive) { // Create a UNNotification UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init]; @@ -933,7 +955,7 @@ static void linphone_iphone_configuring_status_changed(LinphoneCore *lc, Linphon - (void)onConfiguringStatusChanged:(LinphoneConfiguringState)status withMessage:(const char *)message { LOGI(@"onConfiguringStatusChanged: %s %@", linphone_configuring_state_to_string(status), message ? [NSString stringWithFormat:@"(message: %s)", message] : @""); - + NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:status], @"state", [NSString stringWithUTF8String:message ? message : ""], @"message", nil]; @@ -1058,7 +1080,7 @@ static void linphone_iphone_popup_password_request(LinphoneCore *lc, LinphoneAut NSString *username = [NSString stringWithUTF8String:usernameC]; NSString *domain = [NSString stringWithUTF8String:domainC]; alertView = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Authentification needed", nil) - message:[NSString stringWithFormat:NSLocalizedString(@"Registration failed because authentication is " + message:[NSString stringWithFormat:NSLocalizedString(@"Connection failed because authentication is " @"missing or invalid for %@@%@.\nYou can " @"provide password again, or check your " @"account configuration in the settings.", nil), username, realm] @@ -1143,9 +1165,19 @@ static void linphone_iphone_popup_password_request(LinphoneCore *lc, LinphoneAut [[UIApplication sharedApplication] endBackgroundTask:pushBgTaskMsg]; pushBgTaskMsg = 0; } + + BOOL hasFile = FALSE; + // if auto_download is available and file is downloaded + if ((linphone_core_get_max_size_for_auto_download_incoming_files(LC) > -1) && linphone_chat_message_get_file_transfer_information(msg)) + hasFile = TRUE; - if (!linphone_chat_message_is_file_transfer(msg) && !linphone_chat_message_is_text(msg)) + if (!linphone_chat_message_is_file_transfer(msg) && !linphone_chat_message_is_text(msg) && !hasFile) return; + + if (hasFile) { + ChatConversationView *view = VIEW(ChatConversationView); + [view autoDownload:msg view:nil]; + } // Post event NSDictionary *dict = @{ @@ -1446,8 +1478,9 @@ static void linphone_iphone_call_encryption_changed(LinphoneCore *lc, LinphoneCa } void linphone_iphone_chatroom_state_changed(LinphoneCore *lc, LinphoneChatRoom *cr, LinphoneChatRoomState state) { - if (state == LinphoneChatRoomStateCreated) - [NSNotificationCenter.defaultCenter postNotificationName:kLinphoneMessageReceived object:nil]; + if (state == LinphoneChatRoomStateCreated) { + [NSNotificationCenter.defaultCenter postNotificationName:kLinphoneMessageReceived object:nil]; + } } void linphone_iphone_version_update_check_result_received (LinphoneCore *lc, LinphoneVersionUpdateCheckResult result, const char *version, const char *url) { @@ -1822,18 +1855,17 @@ void networkReachabilityCallBack(SCNetworkReachabilityRef target, SCNetworkReach linphone_core_enable_keep_alive(theLinphoneCore, true); // get default config from bundle - NSString *zrtpSecretsFileName = [LinphoneManager documentFile:@"zrtp_secrets"]; - NSString *chatDBFileName = [LinphoneManager documentFile:kLinphoneInternalChatDBFilename]; + NSString *zrtpSecretsFileName = [LinphoneManager dataFile:@"zrtp_secrets"]; + NSString *chatDBFileName = [LinphoneManager dataFile:kLinphoneInternalChatDBFilename]; NSString *device = [[NSMutableString alloc] initWithString:[NSString - stringWithFormat:@"%@_%@_iOS%@", - [NSBundle.mainBundle objectForInfoDictionaryKey:@"CFBundleDisplayName"], - [LinphoneUtils deviceModelIdentifier], - UIDevice.currentDevice.systemVersion]]; - device = [device stringByReplacingOccurrencesOfString:@"," withString:@"."]; - device = [device stringByReplacingOccurrencesOfString:@" " withString:@"."]; - linphone_core_set_user_agent(theLinphoneCore, device.UTF8String, LINPHONE_IOS_VERSION); + stringWithFormat:@"%@iOS/%@ (%@) LinphoneSDK", + [NSBundle.mainBundle objectForInfoDictionaryKey:@"CFBundleDisplayName"], + [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"], + [[UIDevice currentDevice] name]]]; + + linphone_core_set_user_agent(theLinphoneCore, device.UTF8String, LINPHONE_SDK_VERSION); _contactSipField = [self lpConfigStringForKey:@"contact_im_type_value" inSection:@"sip" withDefault:@"SIP"]; @@ -1842,7 +1874,7 @@ void networkReachabilityCallBack(SCNetworkReachabilityRef target, SCNetworkReach } linphone_core_set_zrtp_secrets_file(theLinphoneCore, [zrtpSecretsFileName UTF8String]); - linphone_core_set_chat_database_path(theLinphoneCore, [chatDBFileName UTF8String]); + //linphone_core_set_chat_database_path(theLinphoneCore, [chatDBFileName UTF8String]); linphone_core_set_call_logs_database_path(theLinphoneCore, [chatDBFileName UTF8String]); [self setupNetworkReachabilityCallback]; @@ -2076,6 +2108,8 @@ void popup_link_account_cb(LinphoneAccountCreator *creator, LinphoneAccountCreat linphone_core_reload_ms_plugins(theLinphoneCore, NULL); [self migrationAllPost]; + /* Use the rootca from framework, which is already set*/ + //linphone_core_set_root_ca(theLinphoneCore, [LinphoneManager bundleFile:@"rootca.pem"].UTF8String); linphone_core_set_user_certificates_path(theLinphoneCore, [LinphoneManager cacheDirectory].UTF8String); /* The core will call the linphone_iphone_configuring_status_changed callback when the remote provisioning is loaded @@ -2285,30 +2319,12 @@ static int comp_call_state_paused(const LinphoneCall *call, const void *param) { [[UIApplication sharedApplication] endBackgroundTask:pushBgTaskCall]; pushBgTaskCall = 0; pushBgTaskCall = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{ - if ([UIApplication sharedApplication].applicationState != UIApplicationStateActive) { - LOGW(@"Incomming call with call-id [%@] couldn't be received", callId); - UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init]; - content.title = NSLocalizedString(@"Missed call", nil); - content.body = NSLocalizedString(@"You have missed a call.", nil); - content.categoryIdentifier = @"push_call"; - - UNNotificationRequest *req = - [UNNotificationRequest requestWithIdentifier:@"push_call" content:content trigger:NULL]; - [[UNUserNotificationCenter currentNotificationCenter] - addNotificationRequest:req - withCompletionHandler:^(NSError *_Nullable error) { - // Enable or disable features based on authorization. - if (error) { - LOGD(@"Error while adding notification request :"); - LOGD(error.description); - } - }]; - } - for (NSString *key in [LinphoneManager.instance.pushDict allKeys]) { - [LinphoneManager.instance.pushDict setValue:[NSNumber numberWithInt:0] forKey:key]; - } - [[UIApplication sharedApplication] endBackgroundTask:pushBgTaskCall]; - pushBgTaskCall = 0; + //does not make sens to notify user as we have no information on this missed called + for (NSString *key in [LinphoneManager.instance.pushDict allKeys]) { + [LinphoneManager.instance.pushDict setValue:[NSNumber numberWithInt:0] forKey:key]; + } + [[UIApplication sharedApplication] endBackgroundTask:pushBgTaskCall]; + pushBgTaskCall = 0; }]; LOGI(@"Call long running task started for call-id [%@], remaining [%@] because a push has been received", callId, [LinphoneUtils intervalToString:[[UIApplication sharedApplication] backgroundTimeRemaining]]); @@ -2356,11 +2372,12 @@ static int comp_call_state_paused(const LinphoneCall *call, const void *param) { [self iterate]; } + /*linphone_core_enable_friend_list_subscription(LC, enabled && [LinphoneManager.instance lpConfigBoolForKey:@"use_rls_presence"]); const MSList *lists = linphone_core_get_friends_lists(LC); while (lists) { linphone_friend_list_enable_subscriptions(lists->data, enabled && [LinphoneManager.instance lpConfigBoolForKey:@"use_rls_presence"]); lists = lists->next; - } + }*/ } - (BOOL)enterBackgroundMode { @@ -2508,12 +2525,34 @@ static int comp_call_state_paused(const LinphoneCall *call, const void *param) { linphone_core_refresh_registers(theLinphoneCore); // just to make sure REGISTRATION is up to date } +- (void)migrateImportantFiles { + if ([LinphoneManager copyFile:[LinphoneManager documentFile:@"linphonerc"] destination:[LinphoneManager preferenceFile:@"linphonerc"] override:TRUE]) + [NSFileManager.defaultManager + removeItemAtPath:[LinphoneManager documentFile:@"linphonerc"] + error:nil]; + + if ([LinphoneManager copyFile:[LinphoneManager documentFile:@"linphone_chats.db"] destination:[LinphoneManager dataFile:@"linphone_chats.db"] override:TRUE]) + [NSFileManager.defaultManager + removeItemAtPath:[LinphoneManager documentFile:@"linphone_chats.db"] + error:nil]; + + if ([LinphoneManager copyFile:[LinphoneManager documentFile:@"zrtp_secrets"] destination:[LinphoneManager dataFile:@"zrtp_secrets"] override:TRUE]) + [NSFileManager.defaultManager + removeItemAtPath:[LinphoneManager documentFile:@"zrtp_secrets"] + error:nil]; + + if ([LinphoneManager copyFile:[LinphoneManager documentFile:@"zrtp_secrets.bkp"] destination:[LinphoneManager dataFile:@"zrtp_secrets.bkp"] override:TRUE]) + [NSFileManager.defaultManager + removeItemAtPath:[LinphoneManager documentFile:@"zrtp_secrets.bkp"] + error:nil]; +} + - (void)renameDefaultSettings { // rename .linphonerc to linphonerc to ease debugging: when downloading // containers from MacOSX, Finder do not display hidden files leading // to useless painful operations to display the .linphonerc file NSString *src = [LinphoneManager documentFile:@".linphonerc"]; - NSString *dst = [LinphoneManager documentFile:@"linphonerc"]; + NSString *dst = [LinphoneManager preferenceFile:@"linphonerc"]; NSFileManager *fileManager = [NSFileManager defaultManager]; NSError *fileError = nil; if ([fileManager fileExistsAtPath:src]) { @@ -2534,7 +2573,7 @@ static int comp_call_state_paused(const LinphoneCall *call, const void *param) { if (IPAD && [[NSFileManager defaultManager] fileExistsAtPath:srcIpad]) { src = srcIpad; } - NSString *dst = [LinphoneManager documentFile:@"linphonerc"]; + NSString *dst = [LinphoneManager preferenceFile:@"linphonerc"]; [LinphoneManager copyFile:src destination:dst override:FALSE]; } @@ -2544,7 +2583,7 @@ static int comp_call_state_paused(const LinphoneCall *call, const void *param) { if (IPAD && [[NSFileManager defaultManager] fileExistsAtPath:factoryIpad]) { factory = factoryIpad; } - NSString *confiFileName = [LinphoneManager documentFile:@"linphonerc"]; + NSString *confiFileName = [LinphoneManager preferenceFile:@"linphonerc"]; _configDb = lp_config_new_with_factory([confiFileName UTF8String], [factory UTF8String]); } #pragma mark - Audio route Functions @@ -2657,6 +2696,12 @@ static int comp_call_state_paused(const LinphoneCall *call, const void *param) { } linphone_call_params_enable_video(lcallParams, video); + //We set the record file name here because we can't do it after the call is started. + NSString *writablePath = [LinphoneUtils recordingFilePathFromCall:linphone_call_log_get_from_address(linphone_call_get_call_log(call))]; + LOGD(@"record file path: %@\n", writablePath); + + linphone_call_params_set_record_file(lcallParams, [writablePath cStringUsingEncoding:NSUTF8StringEncoding]); + linphone_call_accept_with_params(call, lcallParams); linphone_call_params_unref(lcallParams); } @@ -2674,16 +2719,7 @@ static int comp_call_state_paused(const LinphoneCall *call, const void *param) { - (void)call:(const LinphoneAddress *)iaddr { // First verify that network is available, abort otherwise. if (!linphone_core_is_network_reachable(theLinphoneCore)) { - UIAlertController *errView = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Network Error", nil) - message:NSLocalizedString(@"There is no network connection available, enable WIFI or WWAN prior to place a call", nil) - preferredStyle:UIAlertControllerStyleAlert]; - - UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"OK", nil) - style:UIAlertActionStyleDefault - handler:^(UIAlertAction * action) {}]; - - [errView addAction:defaultAction]; - [PhoneMainView.instance presentViewController:errView animated:YES completion:nil]; + [PhoneMainView.instance presentViewController:[LinphoneUtils networkErrorView] animated:YES completion:nil]; return; } @@ -2741,50 +2777,60 @@ static int comp_call_state_paused(const LinphoneCall *call, const void *param) { } - (BOOL)doCall:(const LinphoneAddress *)iaddr { - LinphoneAddress *addr = linphone_address_clone(iaddr); - NSString *displayName = [FastAddressBook displayNameForAddress:addr]; + return [self doCallWithSas:iaddr isSas:false]; +} - // Finally we can make the call - LinphoneCallParams *lcallParams = linphone_core_create_call_params(theLinphoneCore, NULL); - if ([self lpConfigBoolForKey:@"edge_opt_preference"] && (self.network == network_2g)) { - LOGI(@"Enabling low bandwidth mode"); - linphone_call_params_enable_low_bandwidth(lcallParams, YES); - } - - if (displayName != nil) { - linphone_address_set_display_name(addr, displayName.UTF8String); - } - if ([LinphoneManager.instance lpConfigBoolForKey:@"override_domain_with_default_one"]) { - linphone_address_set_domain( - addr, [[LinphoneManager.instance lpConfigStringForKey:@"domain" inSection:@"assistant"] UTF8String]); - } - - LinphoneCall *call; - if (LinphoneManager.instance.nextCallIsTransfer) { - char *caddr = linphone_address_as_string(addr); - call = linphone_core_get_current_call(theLinphoneCore); - linphone_call_transfer(call, caddr); - LinphoneManager.instance.nextCallIsTransfer = NO; - ms_free(caddr); - } else { - call = linphone_core_invite_address_with_params(theLinphoneCore, addr, lcallParams); - if (call) { - // The LinphoneCallAppData object should be set on call creation with callback - // - (void)onCall:StateChanged:withMessage:. If not, we are in big trouble and expect it to crash - // We are NOT responsible for creating the AppData. - LinphoneCallAppData *data = (__bridge LinphoneCallAppData *)linphone_call_get_user_data(call); - if (data == nil) { - LOGE(@"New call instanciated but app data was not set. Expect it to crash."); - /* will be used later to notify user if video was not activated because of the linphone core*/ - } else { - data->videoRequested = linphone_call_params_video_enabled(lcallParams); - } - } - } - linphone_address_destroy(addr); - linphone_call_params_destroy(lcallParams); - - return TRUE; +- (BOOL)doCallWithSas:(const LinphoneAddress *)iaddr isSas:(BOOL)isSas { + LinphoneAddress *addr = linphone_address_clone(iaddr); + NSString *displayName = [FastAddressBook displayNameForAddress:addr]; + + // Finally we can make the call + LinphoneCallParams *lcallParams = linphone_core_create_call_params(theLinphoneCore, NULL); + if ([self lpConfigBoolForKey:@"edge_opt_preference"] && (self.network == network_2g)) { + LOGI(@"Enabling low bandwidth mode"); + linphone_call_params_enable_low_bandwidth(lcallParams, YES); + } + + if (displayName != nil) { + linphone_address_set_display_name(addr, displayName.UTF8String); + } + if ([LinphoneManager.instance lpConfigBoolForKey:@"override_domain_with_default_one"]) { + linphone_address_set_domain( + addr, [[LinphoneManager.instance lpConfigStringForKey:@"domain" inSection:@"assistant"] UTF8String]); + } + + LinphoneCall *call; + if (LinphoneManager.instance.nextCallIsTransfer) { + char *caddr = linphone_address_as_string(addr); + call = linphone_core_get_current_call(theLinphoneCore); + linphone_call_transfer(call, caddr); + LinphoneManager.instance.nextCallIsTransfer = NO; + ms_free(caddr); + } else { + //We set the record file name here because we can't do it after the call is started. + NSString *writablePath = [LinphoneUtils recordingFilePathFromCall:addr]; + LOGD(@"record file path: %@\n", writablePath); + linphone_call_params_set_record_file(lcallParams, [writablePath cStringUsingEncoding:NSUTF8StringEncoding]); + if (isSas) + linphone_call_params_set_media_encryption(lcallParams, LinphoneMediaEncryptionZRTP); + call = linphone_core_invite_address_with_params(theLinphoneCore, addr, lcallParams); + if (call) { + // The LinphoneCallAppData object should be set on call creation with callback + // - (void)onCall:StateChanged:withMessage:. If not, we are in big trouble and expect it to crash + // We are NOT responsible for creating the AppData. + LinphoneCallAppData *data = (__bridge LinphoneCallAppData *)linphone_call_get_user_data(call); + if (data == nil) { + LOGE(@"New call instanciated but app data was not set. Expect it to crash."); + /* will be used later to notify user if video was not activated because of the linphone core*/ + } else { + data->videoRequested = linphone_call_params_video_enabled(lcallParams); + } + } + } + linphone_address_destroy(addr); + linphone_call_params_destroy(lcallParams); + + return TRUE; } #pragma mark - Property Functions @@ -2858,15 +2904,61 @@ static int comp_call_state_paused(const LinphoneCall *call, const void *param) { } #pragma mark - Misc Functions ++ (PHFetchResult *)getPHAssets:(NSString *)key { + PHFetchResult *assets; + if ([key hasPrefix:@"assets-library"]) { + // compability with previous linphone version + assets = [PHAsset fetchAssetsWithALAssetURLs:@[[NSURL URLWithString:key]] options:nil]; + } else { + assets = [PHAsset fetchAssetsWithLocalIdentifiers:[NSArray arrayWithObject:key] options:nil]; + } + return assets; +} + (NSString *)bundleFile:(NSString *)file { return [[NSBundle mainBundle] pathForResource:[file stringByDeletingPathExtension] ofType:[file pathExtension]]; } + (NSString *)documentFile:(NSString *)file { - NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); - NSString *documentsPath = [paths objectAtIndex:0]; - return [documentsPath stringByAppendingPathComponent:file]; + NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); + NSString *documentsPath = [paths objectAtIndex:0]; + return [documentsPath stringByAppendingPathComponent:file]; +} + ++ (NSString *)preferenceFile:(NSString *)file { + NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES); + NSString *writablePath = [paths objectAtIndex:0]; + NSString *fullPath = [writablePath stringByAppendingString:@"/Preferences/linphone/"]; + if (![[NSFileManager defaultManager] fileExistsAtPath:fullPath]) { + NSError *error; + LOGI(@"Preference path %@ does not exist, creating it.",fullPath); + if (![[NSFileManager defaultManager] createDirectoryAtPath:fullPath + withIntermediateDirectories:YES + attributes:nil + error:&error]) { + LOGE(@"Create preference path directory error: %@",error.description); + } + } + + return [fullPath stringByAppendingPathComponent:file]; +} + ++ (NSString *)dataFile:(NSString *)file { + NSArray *paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES); + NSString *writablePath = [paths objectAtIndex:0]; + NSString *fullPath = [writablePath stringByAppendingString:@"/linphone/"]; + if (![[NSFileManager defaultManager] fileExistsAtPath:fullPath]) { + NSError *error; + LOGI(@"Data path %@ does not exist, creating it.",fullPath); + if (![[NSFileManager defaultManager] createDirectoryAtPath:fullPath + withIntermediateDirectories:YES + attributes:nil + error:&error]) { + LOGE(@"Create data path directory error: %@",error.description); + } + } + + return [fullPath stringByAppendingPathComponent:file]; } + (NSString *)cacheDirectory { diff --git a/Classes/LinphoneUI/Base.lproj/UIChatBubbleFile.xib b/Classes/LinphoneUI/Base.lproj/UIChatBubbleFile.xib deleted file mode 100644 index 6ed90765a..000000000 --- a/Classes/LinphoneUI/Base.lproj/UIChatBubbleFile.xib +++ /dev/null @@ -1,74 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Classes/LinphoneUI/Base.lproj/UIChatBubblePhotoCell.strings b/Classes/LinphoneUI/Base.lproj/UIChatBubblePhotoCell.strings index 65cf7f21d..9af3a1d6a 100644 Binary files a/Classes/LinphoneUI/Base.lproj/UIChatBubblePhotoCell.strings and b/Classes/LinphoneUI/Base.lproj/UIChatBubblePhotoCell.strings differ diff --git a/Classes/LinphoneUI/Base.lproj/UIChatBubblePhotoCell.xib b/Classes/LinphoneUI/Base.lproj/UIChatBubblePhotoCell.xib index c453ff689..bfc9f5d1b 100644 --- a/Classes/LinphoneUI/Base.lproj/UIChatBubblePhotoCell.xib +++ b/Classes/LinphoneUI/Base.lproj/UIChatBubblePhotoCell.xib @@ -1,20 +1,18 @@ - + - + - - @@ -28,155 +26,131 @@ - + - - + + + + + + + + + + - + - - + + - - - - - - - - - - - + + - + - - - - - - - - - - - - - - + + - + - - - - - - - - - - - - - - - - + - - + + - - - + @@ -114,5 +158,6 @@ + diff --git a/Classes/LinphoneUI/StatusBarView.m b/Classes/LinphoneUI/StatusBarView.m index 78a76e600..317131a5e 100644 --- a/Classes/LinphoneUI/StatusBarView.m +++ b/Classes/LinphoneUI/StatusBarView.m @@ -204,17 +204,17 @@ switch (state) { case LinphoneRegistrationOk: - message = NSLocalizedString(@"Registered", nil); + message = NSLocalizedString(@"Connected", nil); break; case LinphoneRegistrationNone: case LinphoneRegistrationCleared: - message = NSLocalizedString(@"Not registered", nil); + message = NSLocalizedString(@"Not connected", nil); break; case LinphoneRegistrationFailed: - message = NSLocalizedString(@"Registration failed", nil); + message = NSLocalizedString(@"Connection failed", nil); break; case LinphoneRegistrationProgress: - message = NSLocalizedString(@"Registration in progress", nil); + message = NSLocalizedString(@"Connection in progress", nil); break; default: break; @@ -330,12 +330,13 @@ myCode = [code substringFromIndex:2]; } NSString *message = - [NSString stringWithFormat:NSLocalizedString(@"Confirm the following SAS with peer:\n" - @"Say : %@\n" - @"Your correspondant should say : %@", + [NSString stringWithFormat:NSLocalizedString(@"\nConfirmation security\n\n" + @"Say: %@\n" + @"Confirm that your interlocutor\n" + @"says: %@", nil), - myCode, correspondantCode]; - + myCode.uppercaseString, correspondantCode.uppercaseString]; + if ([UIApplication sharedApplication].applicationState != UIApplicationStateActive && floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_9_x_Max) { UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init]; @@ -361,7 +362,18 @@ } else { if (securityDialog == nil) { __block __strong StatusBarView *weakSelf = self; - securityDialog = [UIConfirmationDialog ShowWithMessage:message + // define font of message + NSMutableAttributedString *attrString = [[NSMutableAttributedString alloc] initWithString:message]; + NSUInteger length = [message length]; + UIFont *baseFont = [UIFont systemFontOfSize:21.0]; + [attrString addAttribute:NSFontAttributeName value:baseFont range:NSMakeRange(0, length)]; + UIFont *boldFont = [UIFont boldSystemFontOfSize:23.0]; + [attrString addAttribute:NSFontAttributeName value:boldFont range:[message rangeOfString:@"Confirmation security"]]; + UIColor *color = [UIColor colorWithRed:(150 / 255.0) green:(193 / 255.0) blue:(31 / 255.0) alpha:1.0]; + [attrString addAttribute:NSForegroundColorAttributeName value:color range:[message rangeOfString:myCode.uppercaseString]]; + [attrString addAttribute:NSForegroundColorAttributeName value:color range:[message rangeOfString:correspondantCode.uppercaseString]]; + + securityDialog = [UIConfirmationDialog ShowWithAttributedMessage:attrString cancelMessage:NSLocalizedString(@"DENY", nil) confirmMessage:NSLocalizedString(@"ACCEPT", nil) onCancelClick:^() { @@ -369,13 +381,18 @@ linphone_call_set_authentication_token_verified(call, NO); } weakSelf->securityDialog = nil; + [LinphoneManager.instance lpConfigSetString:[NSString stringWithUTF8String:linphone_call_get_remote_address_as_string(call)] forKey:@"sas_dialog_denied"]; } onConfirmationClick:^() { if (linphone_core_get_current_call(LC) == call) { linphone_call_set_authentication_token_verified(call, YES); } weakSelf->securityDialog = nil; - }]; + [LinphoneManager.instance lpConfigSetString:nil forKey:@"sas_dialog_denied"]; + } ]; + + securityDialog.securityImage.hidden = FALSE; + [securityDialog setSpecialColor]; } } } diff --git a/Classes/LinphoneUI/UIChatBubblePhotoCell.m b/Classes/LinphoneUI/UIChatBubblePhotoCell.m index c9e4ed27c..66a183cd8 100644 --- a/Classes/LinphoneUI/UIChatBubblePhotoCell.m +++ b/Classes/LinphoneUI/UIChatBubblePhotoCell.m @@ -105,22 +105,23 @@ [_messageImageView setAsset:asset]; [_messageImageView stopLoading]; _messageImageView.hidden = YES; - _imageGestureRecognizer.enabled = YES; _finalImage.hidden = NO; + _fileView.hidden = YES; [self layoutSubviews]; }); } +static const CGFloat CELL_IMAGE_X_MARGIN = 100; + - (void) loadAsset:(PHAsset *) asset { PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init]; options.synchronous = TRUE; [[PHImageManager defaultManager] requestImageForAsset:asset targetSize:PHImageManagerMaximumSize contentMode:PHImageContentModeDefault options:options resultHandler:^(UIImage *image, NSDictionary * info) { if (image) { - imageSize = [UIChatBubbleTextCell getMediaMessageSizefromOriginalSize:[image size] withWidth:chatTableView.tableView.frame.size.width - 40]; - UIImage *newImage = [UIImage UIImageResize:image toSize:imageSize]; - [chatTableView.imagesInChatroom setObject:newImage forKey:[asset localIdentifier]]; - [self loadImageAsset:asset image:newImage]; + imageSize = [UIChatBubbleTextCell getMediaMessageSizefromOriginalSize:[image size] withWidth:chatTableView.tableView.frame.size.width - CELL_IMAGE_X_MARGIN]; + [chatTableView.imagesInChatroom setObject:image forKey:[asset localIdentifier]]; + [self loadImageAsset:asset image:image]; } else { LOGE(@"Can't read image"); @@ -160,9 +161,11 @@ NSString *localImage = [LinphoneManager getMessageAppDataForKey:@"localimage" inMessage:self.message]; NSString *localVideo = [LinphoneManager getMessageAppDataForKey:@"localvideo" inMessage:self.message]; NSString *localFile = [LinphoneManager getMessageAppDataForKey:@"localfile" inMessage:self.message]; - BOOL fullScreenImage = NO; assert(is_external || localImage || localVideo || localFile); + LinphoneContent *fileContent = linphone_chat_message_get_file_transfer_information(self.message); + NSString *type = fileContent ? [NSString stringWithUTF8String:linphone_content_get_type(fileContent)] : nil; + if (!(localImage || localVideo || localFile)) { _playButton.hidden = YES; _fileName.hidden = _fileView.hidden = _fileButton.hidden = YES; @@ -173,56 +176,67 @@ // file is being saved on device - just wait for it if ([localImage isEqualToString:@"saving..."] || [localVideo isEqualToString:@"saving..."] || [localFile isEqualToString:@"saving..."]) { _cancelButton.hidden = _fileTransferProgress.hidden = _downloadButton.hidden = _playButton.hidden = _fileName.hidden = _fileView.hidden = _fileButton.hidden = YES; - fullScreenImage = YES; - } else if(!assetIsLoaded) { - assetIsLoaded = TRUE; - if (localImage) { - // we did not load the image yet, so start doing so - if (_messageImageView.image == nil) { - [self loadFirstImage:localImage type:PHAssetMediaTypeImage]; - } - } - else if (localVideo) { - if (_messageImageView.image == nil) { - [self loadFirstImage:localVideo type:PHAssetMediaTypeVideo]; - _imageGestureRecognizer.enabled = NO; - } - } - else if (localFile) { - NSString *text = [NSString stringWithFormat:@"📎 %@",localFile]; - _fileName.text = text; - [self loadFileAsset]; - } - - // we are uploading the image - if (_ftd.message != nil) { - _cancelButton.hidden = NO; - _fileTransferProgress.hidden = NO; - _downloadButton.hidden = YES; - _playButton.hidden = YES; - _fileName.hidden = _fileView.hidden = _fileButton.hidden =YES; - } else { - _cancelButton.hidden = _fileTransferProgress.hidden = _downloadButton.hidden = YES; - fullScreenImage = YES; - _playButton.hidden = localVideo ? NO : YES; - _fileName.hidden = _fileView.hidden = _fileButton.hidden = localFile ? NO : YES; - // Should fix cell not resizing after doanloading image. - [self layoutSubviews]; - } - } + } else { + if(!assetIsLoaded) { + assetIsLoaded = TRUE; + if (localImage) { + // we did not load the image yet, so start doing so + if (_messageImageView.image == nil) { + [self loadFirstImage:localImage type:PHAssetMediaTypeImage]; + _imageGestureRecognizer.enabled = YES; + } + } + else if (localVideo) { + if (_messageImageView.image == nil) { + [self loadFirstImage:localVideo type:PHAssetMediaTypeVideo]; + _imageGestureRecognizer.enabled = NO; + } + } + else if (localFile) { + if ([type isEqualToString:@"video"]) { + UIImage* image = [UIChatBubbleTextCell getImageFromVideoUrl:[VIEW(ChatConversationView) getICloudFileUrl:localFile]]; + [self loadImageAsset:nil image:image]; + _imageGestureRecognizer.enabled = NO; + } else if ([localFile hasSuffix:@"JPG"] || [localFile hasSuffix:@"PNG"] || [localFile hasSuffix:@"jpg"] || [localFile hasSuffix:@"png"]) { + NSData *data = [NSData dataWithContentsOfURL:[VIEW(ChatConversationView) getICloudFileUrl:localFile]]; + UIImage *image = [[UIImage alloc] initWithData:data]; + [self loadImageAsset:nil image:image]; + _imageGestureRecognizer.enabled = YES; + } else { + NSString *text = [NSString stringWithFormat:@"📎 %@",localFile]; + _fileName.text = text; + [self loadFileAsset]; + } + } + } + } + // we are uploading the image + if (_ftd.message != nil) { + _cancelButton.hidden = NO; + _fileTransferProgress.hidden = NO; + _downloadButton.hidden = YES; + _playButton.hidden = YES; + _fileName.hidden = _fileView.hidden = _fileButton.hidden =YES; + } else { + _cancelButton.hidden = _fileTransferProgress.hidden = _downloadButton.hidden = YES; + _playButton.hidden = ![type isEqualToString:@"video"]; + _fileName.hidden = _fileView.hidden = _fileButton.hidden = localFile ? NO : YES; + // Should fix cell not resizing after doanloading image. + //[self layoutSubviews]; + } } } - (void)loadFirstImage:(NSString *)key type:(PHAssetMediaType)type { [_messageImageView startLoading]; - PHFetchResult *assets = [PHAsset fetchAssetsWithLocalIdentifiers:[NSArray arrayWithObject:key] options:nil]; + PHFetchResult *assets = [LinphoneManager getPHAssets:key]; UIImage *img = nil; img = [chatTableView.imagesInChatroom objectForKey:key]; PHAsset *asset = [assets firstObject]; if (!asset) [self loadPlaceholder]; - else if (asset.mediaType == type) + else if (asset.mediaType != type) img = nil; if (img) [self loadImageAsset:asset image:img]; @@ -240,6 +254,13 @@ }); } +- (void)playVideoByPlayer:(AVPlayer *)player { + AVPlayerViewController *controller = [[AVPlayerViewController alloc] init]; + [PhoneMainView.instance presentViewController:controller animated:YES completion:nil]; + controller.player = player; + [player play]; +} + - (IBAction)onDownloadClick:(id)event { [_ftd cancel]; _ftd = [[FileTransferDelegate alloc] init]; @@ -253,17 +274,19 @@ - (IBAction)onPlayClick:(id)sender { PHAsset *asset = [_messageImageView asset]; + if (!asset) { + NSString *localFile = [LinphoneManager getMessageAppDataForKey:@"localfile" inMessage:self.message]; + AVPlayer *player = [AVPlayer playerWithURL:[VIEW(ChatConversationView) getICloudFileUrl:localFile]]; + [self playVideoByPlayer:player]; + return; + } PHVideoRequestOptions *options = [[PHVideoRequestOptions alloc] init]; // options.synchronous = TRUE; [[PHImageManager defaultManager] requestPlayerItemForVideo:asset options:options resultHandler:^(AVPlayerItem * _Nullable playerItem, NSDictionary * _Nullable info) { if(playerItem) { AVPlayer *player = [AVPlayer playerWithPlayerItem:playerItem]; - AVPlayerViewController *controller = [[AVPlayerViewController alloc] init]; - [PhoneMainView.instance presentViewController:controller animated:YES completion:nil]; - controller.player = player; - [player play]; - } - else { + [self playVideoByPlayer:player]; + } else { [self fileErrorBlock]; } }]; @@ -271,18 +294,8 @@ - (IBAction)onFileClick:(id)sender { ChatConversationView *view = VIEW(ChatConversationView); - NSString *cachedFile = [LinphoneManager getMessageAppDataForKey:@"cachedfile" inMessage:self.message]; - if (cachedFile) { - NSFileManager *fileManager = [NSFileManager defaultManager]; - if ([fileManager fileExistsAtPath:cachedFile]) { - [view openFile:cachedFile]; - } else { - [self fileErrorBlock]; - } - } else { - [LinphoneManager setValueInMessageAppData:@"onFileClick" forKey:@"icloudFileOption" inMessage:self.message]; - [super getIcloudFiles]; - } + NSString *name = [LinphoneManager getMessageAppDataForKey:@"localfile" inMessage:self.message]; + [view openFileWithURL:[view getICloudFileUrl:name]]; } @@ -291,6 +304,9 @@ [self disconnectFromFileDelegate]; _fileTransferProgress.progress = 0; [tmp cancel]; + if (!linphone_core_is_network_reachable(LC)) { + [self update]; + } } - (void)onResendClick:(id)event { @@ -313,6 +329,18 @@ ImageView *view = VIEW(ImageView); [PhoneMainView.instance changeCurrentView:view.compositeViewDescription]; PHAsset *asset = [_messageImageView asset]; + if (!asset) { + NSString *localFile = [LinphoneManager getMessageAppDataForKey:@"localfile" inMessage:self.message]; + if ([localFile hasSuffix:@"JPG"] || [localFile hasSuffix:@"PNG"] || [localFile hasSuffix:@"jpg"] || [localFile hasSuffix:@"png"]) { + NSData *data = [NSData dataWithContentsOfURL:[VIEW(ChatConversationView) getICloudFileUrl:localFile]]; + UIImage *image = [[UIImage alloc] initWithData:data]; + if (image) + [view setImage:image]; + else + LOGE(@"Can't read image"); + } + return; + } PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init]; options.synchronous = TRUE; [[PHImageManager defaultManager] requestImageForAsset:asset targetSize:PHImageManagerMaximumSize contentMode:PHImageContentModeDefault options:options @@ -359,7 +387,7 @@ - (void)onFileTransferSendUpdate:(NSNotification *)notif { LinphoneChatMessageState state = [[[notif userInfo] objectForKey:@"state"] intValue]; - if (state == LinphoneChatMessageStateInProgress) { + if (state == LinphoneChatMessageStateInProgress || state == LinphoneChatMessageStateFileTransferInProgress) { float progress = [[[notif userInfo] objectForKey:@"progress"] floatValue]; // When uploading a file, the self.message file is first uploaded to the server, // so we are in progress state. Then state goes to filetransfertdone. Then, @@ -375,7 +403,7 @@ } - (void)onFileTransferRecvUpdate:(NSNotification *)notif { LinphoneChatMessageState state = [[[notif userInfo] objectForKey:@"state"] intValue]; - if (state == LinphoneChatMessageStateInProgress) { + if (state == LinphoneChatMessageStateInProgress || state == LinphoneChatMessageStateFileTransferInProgress) { float progress = [[[notif userInfo] objectForKey:@"progress"] floatValue]; _fileTransferProgress.progress = MAX(_fileTransferProgress.progress, progress); _fileTransferProgress.hidden = _cancelButton.hidden = (_fileTransferProgress.progress == 1.f); @@ -406,25 +434,28 @@ // Resizing Image view if (_finalImage.image) { - CGRect imgFrame = self.finalAssetView.frame; - imgFrame.size = [UIChatBubbleTextCell getMediaMessageSizefromOriginalSize:[_finalImage.image size] withWidth:chatTableView.tableView.frame.size.width - 40]; - imgFrame.origin.x = (bubbleFrame.size.width - imgFrame.size.width)/2; + CGRect imgFrame = self.finalAssetView.frame; + imgFrame.size = [UIChatBubbleTextCell getMediaMessageSizefromOriginalSize:[_finalImage.image size] withWidth:chatTableView.tableView.frame.size.width - CELL_IMAGE_X_MARGIN]; + imgFrame.origin.x = (self.innerView.frame.size.width - imgFrame.size.width-17)/2; self.finalAssetView.frame = imgFrame; - - // Positioning text message - const char *utf8Text = linphone_chat_message_get_text_content(self.message); - - CGRect textFrame = self.messageText.frame; - textFrame.origin = CGPointMake(textFrame.origin.x, self.finalAssetView.frame.origin.y + self.finalAssetView.frame.size.height); - if (!utf8Text) { - textFrame.size.height = 0; - } else { - textFrame.size.height = bubbleFrame.size.height - textFrame.origin.x; - } - - self.messageText.frame = textFrame; - LOGD([NSString stringWithFormat:@"Text of the photoCell: %@, size of the text of the photoCell: %@", [self.messageText text], NSStringFromCGSize(textFrame.size)]); } + + // Positioning text message + const char *utf8Text = linphone_chat_message_get_text_content(self.message); + + CGRect textFrame = self.messageText.frame; + if (_finalImage.image) + textFrame.origin = CGPointMake(textFrame.origin.x, self.finalAssetView.frame.origin.y + self.finalAssetView.frame.size.height); + else + // When image hasn't be download + textFrame.origin = CGPointMake(textFrame.origin.x, _imageSubView.frame.size.height + _imageSubView.frame.origin.y - 10); + if (!utf8Text) { + textFrame.size.height = 0; + } else { + textFrame.size.height = bubbleFrame.size.height - 90;//textFrame.origin.x; + } + + self.messageText.frame = textFrame; } @end diff --git a/Classes/LinphoneUI/UIChatBubbleTextCell.h b/Classes/LinphoneUI/UIChatBubbleTextCell.h index 1d66bc5b8..69797cea3 100644 --- a/Classes/LinphoneUI/UIChatBubbleTextCell.h +++ b/Classes/LinphoneUI/UIChatBubbleTextCell.h @@ -30,24 +30,28 @@ @property(nonatomic, weak) IBOutlet UIImageView *backgroundColorImage; @property(nonatomic, weak) IBOutlet UIRoundedImageView *avatarImage; @property(nonatomic, weak) IBOutlet UILabel *contactDateLabel; -@property(weak, nonatomic) IBOutlet UIActivityIndicatorView *statusInProgressSpinner; +//@property(weak, nonatomic) IBOutlet UIActivityIndicatorView *statusInProgressSpinner; @property(nonatomic, weak) IBOutlet UITextViewNoDefine *messageText; -@property(weak, nonatomic) IBOutlet UIImageView *bottomBarColor; +//@property(weak, nonatomic) IBOutlet UIImageView *bottomBarColor; @property(nonatomic, strong) id chatRoomDelegate; @property(strong, nonatomic) IBOutlet UIView *bubbleView; @property(strong, nonatomic) IBOutlet UITapGestureRecognizer *resendRecognizer; -@property(weak, nonatomic) IBOutlet UIImageView *LIMEKO; +//@property(weak, nonatomic) IBOutlet UIImageView *LIMEKO; @property(weak, nonatomic) IBOutlet UIImageView *imdmIcon; -@property(weak, nonatomic) IBOutlet UILabel *imdmLabel; - +//@property(weak, nonatomic) IBOutlet UILabel *imdmLabel; @property (nonatomic, strong) UIDocumentPickerViewController *documentPicker; +@property (weak, nonatomic) IBOutlet UIView *innerView; + +@property(nonatomic) Boolean isFirst; +@property(nonatomic) Boolean isLast; + (CGSize)ViewSizeForMessage:(LinphoneChatMessage *)chat withWidth:(int)width; ++ (CGSize)ViewHeightForMessageText:(LinphoneChatMessage *)chat withWidth:(int)width textForImdn:(NSString *)imdnText; + (CGSize)getMediaMessageSizefromOriginalSize:(CGSize)originalSize withWidth:(int)width; ++ (UIImage *)getImageFromVideoUrl:(NSURL *)url; - (void)setEvent:(LinphoneEventLog *)event; - (void)setChatMessage:(LinphoneChatMessage *)message; -- (void)getIcloudFiles; - (void)onDelete; - (void)onResend; diff --git a/Classes/LinphoneUI/UIChatBubbleTextCell.m b/Classes/LinphoneUI/UIChatBubbleTextCell.m index 8e207f682..b5ffb87cb 100644 --- a/Classes/LinphoneUI/UIChatBubbleTextCell.m +++ b/Classes/LinphoneUI/UIChatBubbleTextCell.m @@ -44,8 +44,8 @@ UITapGestureRecognizer *limeRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onLime)]; limeRecognizer.numberOfTapsRequired = 1; - [_LIMEKO addGestureRecognizer:limeRecognizer]; - _LIMEKO.userInteractionEnabled = YES; + //[_LIMEKO addGestureRecognizer:limeRecognizer]; + //_LIMEKO.userInteractionEnabled = YES; UITapGestureRecognizer *resendRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onResend)]; resendRecognizer.numberOfTapsRequired = 1; @@ -54,8 +54,8 @@ UITapGestureRecognizer *resendRecognizer2 = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onResend)]; resendRecognizer2.numberOfTapsRequired = 1; - [_imdmLabel addGestureRecognizer:resendRecognizer2]; - _imdmLabel.userInteractionEnabled = YES; + //[_imdmLabel addGestureRecognizer:resendRecognizer2]; + //_imdmLabel.userInteractionEnabled = YES; return self; } @@ -88,6 +88,7 @@ linphone_chat_message_set_user_data(_message, (void *)CFBridgingRetain(self)); LinphoneChatMessageCbs *cbs = linphone_chat_message_get_callbacks(_message); linphone_chat_message_cbs_set_msg_state_changed(cbs, message_status); + linphone_chat_message_cbs_set_participant_imdn_state_changed(cbs, participant_imdn_status); linphone_chat_message_cbs_set_user_data(cbs, (void *)_event); } @@ -126,10 +127,9 @@ return; } - _statusInProgressSpinner.accessibilityLabel = @"Delivery in progress"; + //_statusInProgressSpinner.accessibilityLabel = @"Delivery in progress"; if (_messageText && ![LinphoneManager getMessageAppDataForKey:@"localvideo" inMessage:_message]) { - LOGD(_messageText.text); [_messageText setHidden:FALSE]; /* We need to use an attributed string here so that data detector don't mess * with the text style. See http://stackoverflow.com/a/20669356 */ @@ -145,27 +145,84 @@ LinphoneChatMessageState state = linphone_chat_message_get_state(_message); BOOL outgoing = linphone_chat_message_is_outgoing(_message); + + + _contactDateLabel.hidden = !_isFirst; + if (outgoing) { + _contactDateLabel.text = [LinphoneUtils timeToString:linphone_chat_message_get_time(_message) + withFormat:LinphoneDateChatBubble]; + _contactDateLabel.textAlignment = NSTextAlignmentRight; + _avatarImage.hidden = TRUE; + + } else { + [_avatarImage setImage:[FastAddressBook imageForAddress:linphone_chat_message_get_from_address(_message)] + bordered:NO + withRoundedRadius:YES]; + _contactDateLabel.text = [self.class ContactDateForChat:_message]; + _contactDateLabel.textAlignment = NSTextAlignmentLeft; + _avatarImage.hidden = !_isFirst; + } + + // Not use [UIImage imageNamed], it takes too much time + NSString *imageName = outgoing ? @"color_A.png" : @"color_D.png"; + _backgroundColorImage.image = + [UIImage imageWithContentsOfFile:[NSString stringWithFormat:@"%@/%@",[[NSBundle mainBundle] bundlePath],imageName]]; + + // set maskedCorners + if (@available(iOS 11.0, *)) { + _backgroundColorImage.layer.cornerRadius = 10; + if (outgoing) { + _backgroundColorImage.layer.maskedCorners = kCALayerMinXMaxYCorner | kCALayerMinXMinYCorner; + if (_isFirst) + _backgroundColorImage.layer.maskedCorners = _backgroundColorImage.layer.maskedCorners | kCALayerMaxXMinYCorner; + if (_isLast) + _backgroundColorImage.layer.maskedCorners = _backgroundColorImage.layer.maskedCorners | kCALayerMaxXMaxYCorner; + } else { + _backgroundColorImage.layer.maskedCorners = kCALayerMaxXMinYCorner | kCALayerMaxXMaxYCorner; + if (_isFirst) + _backgroundColorImage.layer.maskedCorners = _backgroundColorImage.layer.maskedCorners | kCALayerMinXMinYCorner; + if (_isLast) + _backgroundColorImage.layer.maskedCorners = _backgroundColorImage.layer.maskedCorners | kCALayerMinXMaxYCorner; + } + _backgroundColorImage.layer.masksToBounds = YES; + } else { + // TODO it doesn't work for ios < 11.0 + UIRectCorner corner; + if (outgoing) { + corner = UIRectCornerTopLeft | UIRectCornerBottomLeft; + if (_isFirst) + corner = corner | UIRectCornerTopRight; + if (_isLast) + corner = corner | UIRectCornerBottomRight; + } else { + corner = UIRectCornerTopRight | UIRectCornerBottomRight; + if (_isFirst) + corner = corner | UIRectCornerTopLeft; + if (_isLast) + corner = corner | UIRectCornerBottomLeft; + } + UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:_backgroundColorImage.frame byRoundingCorners:corner cornerRadii:CGSizeMake(10,10)]; + CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init]; + maskLayer.frame = _backgroundColorImage.frame; + maskLayer.path = maskPath.CGPath; + _backgroundColorImage.layer.mask = maskLayer; + } + + // need space for dateLabel + CGRect frame = _innerView.frame; + frame.origin.y = _isFirst ? 20 : 0; + _innerView.frame = frame; + + + //_contactDateLabel.textColor = [UIColor colorWithPatternImage:_backgroundColorImage.image]; - if (outgoing) { - _avatarImage.image = [LinphoneUtils selfAvatar]; - } else { - [_avatarImage setImage:[FastAddressBook imageForAddress:linphone_chat_message_get_from_address(_message)] - bordered:NO - withRoundedRadius:YES]; - } - _contactDateLabel.text = [self.class ContactDateForChat:_message]; - - _backgroundColorImage.image = _bottomBarColor.image = - [UIImage imageNamed:(outgoing ? @"color_A.png" : @"color_D.png")]; - _contactDateLabel.textColor = [UIColor colorWithPatternImage:_backgroundColorImage.image]; - - if (outgoing && state == LinphoneChatMessageStateInProgress) { + /*if (outgoing && state == LinphoneChatMessageStateInProgress) { [_statusInProgressSpinner startAnimating]; } else if (!outgoing && state == LinphoneChatMessageStateFileTransferError) { [_statusInProgressSpinner stopAnimating]; } else { [_statusInProgressSpinner stopAnimating]; - } + }*/ [_messageText setAccessibilityLabel:outgoing ? @"Outgoing message" : @"Incoming message"]; if (outgoing && @@ -175,12 +232,12 @@ } else [self displayImdmStatus:LinphoneChatMessageStateInProgress]; - if (!outgoing && !linphone_chat_message_is_secured(_message) && + /*if (!outgoing && !linphone_chat_message_is_secured(_message) && linphone_core_lime_enabled(LC) == LinphoneLimeMandatory) { _LIMEKO.hidden = FALSE; } else { _LIMEKO.hidden = TRUE; - } + }*/ } - (void)setEditing:(BOOL)editing { @@ -207,36 +264,6 @@ [PhoneMainView.instance presentViewController:errView animated:YES completion:nil]; } -- (void)getIcloudFiles { - _documentPicker = [[UIDocumentPickerViewController alloc] initWithDocumentTypes:@[@"public.data"] - inMode:UIDocumentPickerModeImport]; - _documentPicker.delegate = self; - - _documentPicker.modalPresentationStyle = UIModalPresentationOverCurrentContext ; - ChatConversationView *view = VIEW(ChatConversationView); - [view presentViewController:_documentPicker animated:YES completion:nil]; - } - - - (void)documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentAtURL:(NSURL *)url { - NSFileCoordinator *fileCoordinator = [[NSFileCoordinator alloc] initWithFilePresenter:nil]; - [fileCoordinator coordinateReadingItemAtURL:url options:NSFileCoordinatorReadingWithoutChanges error:nil byAccessor:^(NSURL * _Nonnull newURL) { - - NSString *fileName = [newURL lastPathComponent]; - NSData *data = [NSData dataWithContentsOfURL:newURL]; - NSString *option = [LinphoneManager getMessageAppDataForKey:@"icloudFileOption" inMessage:self.message]; - - if ([option isEqualToString:@"onResend"]) - [_chatRoomDelegate startFileUpload:data withName:fileName]; - else if ([option isEqualToString:@"onFileClick"]) { - ChatConversationView *view = VIEW(ChatConversationView); - NSString *filePath = [[LinphoneManager cacheDirectory] stringByAppendingPathComponent:fileName]; - [[NSFileManager defaultManager] createFileAtPath:filePath contents:data attributes:nil]; - [view openFile:filePath]; - } - }]; -} - - #pragma mark - Action Functions - (void)onDelete { @@ -250,8 +277,8 @@ } - (void)onLime { - if (!_LIMEKO.hidden) - [self displayLIMEWarning]; + /*if (!_LIMEKO.hidden) + [self displayLIMEWarning];*/ } - (void)onResend { @@ -273,12 +300,12 @@ ChatConversationTableView *tableView = VIEW(ChatConversationView).tableController; UIImage *img = [tableView.imagesInChatroom objectForKey:localImage]; if (img) { - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, (unsigned long)NULL), - ^(void) { + dispatch_async(dispatch_get_main_queue(), ^ { [_chatRoomDelegate startImageUpload:img assetId:localImage withQuality:(uploadQuality ? [uploadQuality floatValue] : 0.9)]; }); } else { - PHFetchResult *assets = [PHAsset fetchAssetsWithLocalIdentifiers:[NSArray arrayWithObject:localImage] options:nil]; + PHFetchResult *assets = [LinphoneManager getPHAssets:localImage]; + if (![assets firstObject]) return; PHAsset *asset = [assets firstObject]; @@ -290,7 +317,7 @@ [[PHImageManager defaultManager] requestImageForAsset:asset targetSize:PHImageManagerMaximumSize contentMode:PHImageContentModeDefault options:options resultHandler:^(UIImage *image, NSDictionary * info) { if (image) { - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, (unsigned long)NULL), + dispatch_async(dispatch_get_main_queue(), ^(void) { [_chatRoomDelegate startImageUpload:img assetId:localImage withQuality:(uploadQuality ? [uploadQuality floatValue] : 0.9)]; }); @@ -316,18 +343,15 @@ NSURL *url = urlAsset.URL; NSData *data = [NSData dataWithContentsOfURL:url]; - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, (unsigned long)NULL), + dispatch_async(dispatch_get_main_queue(), ^(void) { [_chatRoomDelegate startFileUpload:data assetId:localVideo]; }); }]; } else if (localFile) { - [LinphoneManager setValueInMessageAppData:@"onResend" forKey:@"icloudFileOption" inMessage:_message]; - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, (unsigned long)NULL), - ^(void) { - [self getIcloudFiles]; - }); + NSData *data = [NSData dataWithContentsOfURL:[VIEW(ChatConversationView) getICloudFileUrl:localFile]]; + [_chatRoomDelegate startFileUpload:data withName:localFile]; } } else { [self onDelete]; @@ -346,29 +370,36 @@ static void message_status(LinphoneChatMessage *msg, LinphoneChatMessageState st [view.tableController updateEventEntry:event]; } +static void participant_imdn_status(LinphoneChatMessage* msg, const LinphoneParticipantImdnState *state) { + ChatConversationImdnView *imdnView = VIEW(ChatConversationImdnView); + [imdnView updateImdnList]; +} + - (void)displayImdmStatus:(LinphoneChatMessageState)state { + NSString *imageName = nil; if (state == LinphoneChatMessageStateDeliveredToUser) { - [_imdmIcon setImage:[UIImage imageNamed:@"chat_delivered"]]; - [_imdmLabel setText:NSLocalizedString(@"Delivered", nil)]; - [_imdmLabel setTextColor:[UIColor grayColor]]; + imageName = @"chat_delivered.png"; + //[_imdmLabel setText:NSLocalizedString(@"Delivered", nil)]; + //[_imdmLabel setTextColor:[UIColor grayColor]]; [_imdmIcon setHidden:FALSE]; - [_imdmLabel setHidden:FALSE]; + //[_imdmLabel setHidden:FALSE]; } else if (state == LinphoneChatMessageStateDisplayed) { - [_imdmIcon setImage:[UIImage imageNamed:@"chat_read"]]; - [_imdmLabel setText:NSLocalizedString(@"Read", nil)]; - [_imdmLabel setTextColor:([UIColor colorWithRed:(24 / 255.0) green:(167 / 255.0) blue:(175 / 255.0) alpha:1.0])]; + imageName = @"chat_read"; + //[_imdmLabel setText:NSLocalizedString(@"Read", nil)]; + //[_imdmLabel setTextColor:([UIColor colorWithRed:(24 / 255.0) green:(167 / 255.0) blue:(175 / 255.0) alpha:1.0])]; [_imdmIcon setHidden:FALSE]; - [_imdmLabel setHidden:FALSE]; + //[_imdmLabel setHidden:FALSE]; } else if (state == LinphoneChatMessageStateNotDelivered || state == LinphoneChatMessageStateFileTransferError) { - [_imdmIcon setImage:[UIImage imageNamed:@"chat_error"]]; - [_imdmLabel setText:NSLocalizedString(@"Resend", nil)]; - [_imdmLabel setTextColor:[UIColor redColor]]; + imageName = @"chat_error"; + //[_imdmLabel setText:NSLocalizedString(@"Resend", nil)]; + //[_imdmLabel setTextColor:[UIColor redColor]]; [_imdmIcon setHidden:FALSE]; - [_imdmLabel setHidden:FALSE]; + //[_imdmLabel setHidden:FALSE]; } else { [_imdmIcon setHidden:TRUE]; - [_imdmLabel setHidden:TRUE]; + //[_imdmLabel setHidden:TRUE]; } + [_imdmIcon setImage:[UIImage imageWithContentsOfFile:[NSString stringWithFormat:@"%@/%@",[[NSBundle mainBundle] bundlePath],imageName]]]; } #pragma mark - Bubble size computing @@ -386,69 +417,104 @@ static void message_status(LinphoneChatMessage *msg, LinphoneChatMessageState st context:nil].size; } -static const CGFloat CELL_MIN_HEIGHT = 60.0f; +static const CGFloat CELL_MIN_HEIGHT = 65.0f; static const CGFloat CELL_MIN_WIDTH = 190.0f; -static const CGFloat CELL_MESSAGE_X_MARGIN = 78 + 10.0f; -static const CGFloat CELL_MESSAGE_Y_MARGIN = 52; // 44; +static const CGFloat CELL_MESSAGE_X_MARGIN = 68 + 10.0f; +static const CGFloat CELL_MESSAGE_Y_MARGIN = 44; +static const CGFloat CELL_IMAGE_X_MARGIN = 100; + (CGSize)ViewHeightForMessage:(LinphoneChatMessage *)chat withWidth:(int)width { - NSString *messageText = [UIChatBubbleTextCell TextMessageForChat:chat]; - static UIFont *messageFont = nil; - + return [self ViewHeightForMessageText:chat withWidth:width textForImdn:nil]; +} + ++ (CGSize)ViewHeightForMessageText:(LinphoneChatMessage *)chat withWidth:(int)width textForImdn:(NSString *)imdnText{ + NSString *messageText = [UIChatBubbleTextCell TextMessageForChat:chat]; + static UIFont *messageFont = nil; + if (!messageFont) { UIChatBubbleTextCell *cell = [[UIChatBubbleTextCell alloc] initWithIdentifier:NSStringFromClass(UIChatBubbleTextCell.class)]; messageFont = cell.messageText.font; } - width -= 40; /*checkbox */ + width -= CELL_IMAGE_X_MARGIN; CGSize size; const char *url = linphone_chat_message_get_external_body_url(chat); - if (url == nil && linphone_chat_message_get_file_transfer_information(chat) == NULL) { - size = [self computeBoundingBox:messageText - size:CGSizeMake(width - CELL_MESSAGE_X_MARGIN - 4, CGFLOAT_MAX) - font:messageFont]; - } else { - NSString *localImage = [LinphoneManager getMessageAppDataForKey:@"localimage" inMessage:chat]; + + if (imdnText) { + size = [self computeBoundingBox:imdnText + size:CGSizeMake(width - 4, CGFLOAT_MAX) + font:messageFont]; + size.width = MAX(size.width + CELL_MESSAGE_X_MARGIN, CELL_MIN_WIDTH); + size.height = MAX(size.height + CELL_MESSAGE_Y_MARGIN + 50, CELL_MIN_HEIGHT); + return size; + } + + LinphoneContent *fileContent = linphone_chat_message_get_file_transfer_information(chat); + if (url == nil && fileContent == NULL) { + size = [self computeBoundingBox:messageText + size:CGSizeMake(width - CELL_MESSAGE_X_MARGIN - 4, CGFLOAT_MAX) + font:messageFont]; + } else { + NSString *localImage = [LinphoneManager getMessageAppDataForKey:@"localimage" inMessage:chat]; NSString *localFile = [LinphoneManager getMessageAppDataForKey:@"localfile" inMessage:chat]; NSString *localVideo = [LinphoneManager getMessageAppDataForKey:@"localvideo" inMessage:chat]; + CGSize textSize = CGSizeMake(0, 0); + if (![messageText isEqualToString:@"🗻"]) { + textSize = [self computeBoundingBox:messageText + size:CGSizeMake(width - CELL_MESSAGE_X_MARGIN - 4, CGFLOAT_MAX) + font:messageFont]; + size.height += textSize.height; + } + if(localFile) { - CGSize fileSize = CGSizeMake(200, 80); - size = [self getMediaMessageSizefromOriginalSize:fileSize withWidth:width]; + UIImage *image = nil; + NSString *type = [NSString stringWithUTF8String:linphone_content_get_type(fileContent)]; + if ([type isEqualToString:@"video"]) { + image = [self getImageFromVideoUrl:[VIEW(ChatConversationView) getICloudFileUrl:localFile]]; + } else if ([localFile hasSuffix:@"JPG"] || [localFile hasSuffix:@"PNG"] || [localFile hasSuffix:@"jpg"] || [localFile hasSuffix:@"png"]) { + NSData *data = [NSData dataWithContentsOfURL:[VIEW(ChatConversationView) getICloudFileUrl:localFile]]; + image = [[UIImage alloc] initWithData:data]; + } + + if (image) { + size = [self getMediaMessageSizefromOriginalSize:image.size withWidth:width]; + // add size for message text + size.height += textSize.height; + size.width = MAX(textSize.width, size.width); + } else { + CGSize fileSize = CGSizeMake(230, 50); + size = [self getMediaMessageSizefromOriginalSize:fileSize withWidth:width]; + } } else { if (!localImage && !localVideo) { //We are loading the image - return CGSizeMake(CELL_MIN_WIDTH + CELL_MESSAGE_X_MARGIN, CELL_MIN_HEIGHT + CELL_MESSAGE_Y_MARGIN); + return CGSizeMake(CELL_MIN_WIDTH + CELL_MESSAGE_X_MARGIN, CELL_MIN_HEIGHT + CELL_MESSAGE_Y_MARGIN + textSize.height + 20); } PHFetchResult *assets; if(localImage) - assets = [PHAsset fetchAssetsWithLocalIdentifiers:[NSArray arrayWithObject:localImage] options:nil]; + assets = [LinphoneManager getPHAssets:localImage]; else assets = [PHAsset fetchAssetsWithLocalIdentifiers:[NSArray arrayWithObject:localVideo] options:nil]; if (![assets firstObject]) { - return CGSizeMake(CELL_MIN_WIDTH, CELL_MIN_HEIGHT); - } - PHAsset *asset = [assets firstObject]; - CGSize originalImageSize = CGSizeMake([asset pixelWidth], [asset pixelHeight]); - size = [self getMediaMessageSizefromOriginalSize:originalImageSize withWidth:width]; - //This fixes the image being too small. I think the issue comes form the fact that the display is retina. This should probably be changed in the future. - size.height += 40; - size.width -= CELL_MESSAGE_X_MARGIN; - - if (![messageText isEqualToString:@"🗻"]) { - CGSize textSize = [self computeBoundingBox:messageText - size:CGSizeMake(width - CELL_MESSAGE_X_MARGIN - 4, CGFLOAT_MAX) - font:messageFont]; + return CGSizeMake(CELL_MIN_WIDTH, CELL_MIN_WIDTH + CELL_MESSAGE_Y_MARGIN + textSize.height); + } else { + PHAsset *asset = [assets firstObject]; + CGSize originalImageSize = CGSizeMake([asset pixelWidth], [asset pixelHeight]); + size = [self getMediaMessageSizefromOriginalSize:originalImageSize withWidth:width]; + + // add size for message text size.height += textSize.height; size.width = MAX(textSize.width, size.width); } } - } - - size.width = MAX(size.width + CELL_MESSAGE_X_MARGIN, CELL_MIN_WIDTH); - size.height = MAX(size.height + CELL_MESSAGE_Y_MARGIN, CELL_MIN_HEIGHT); - return size; + } + + size.width = MAX(size.width + CELL_MESSAGE_X_MARGIN, CELL_MIN_WIDTH); + size.height = MAX(size.height + CELL_MESSAGE_Y_MARGIN, CELL_MIN_HEIGHT); + return size; } + + (CGSize)ViewSizeForMessage:(LinphoneChatMessage *)chat withWidth:(int)width { static UIFont *dateFont = nil; static CGSize dateViewSize; @@ -464,10 +530,18 @@ static const CGFloat CELL_MESSAGE_Y_MARGIN = 52; // 44; CGSize messageSize = [self ViewHeightForMessage:chat withWidth:width]; CGSize dateSize = [self computeBoundingBox:[self ContactDateForChat:chat] size:dateViewSize font:dateFont]; messageSize.width = MAX(MAX(messageSize.width, MIN(dateSize.width + CELL_MESSAGE_X_MARGIN, width)), CELL_MIN_WIDTH); + messageSize.width = MAX(MAX(messageSize.width, MIN(CELL_MESSAGE_X_MARGIN, width)), CELL_MIN_WIDTH); return messageSize; } ++ (UIImage *)getImageFromVideoUrl:(NSURL *)url { + AVURLAsset* asset = [AVURLAsset URLAssetWithURL:url options:nil]; + AVAssetImageGenerator* generator = [AVAssetImageGenerator assetImageGeneratorWithAsset:asset]; + generator.appliesPreferredTrackTransform = YES; + return [UIImage imageWithCGImage:[generator copyCGImageAtTime:CMTimeMake(0, 1) actualTime:nil error:nil]]; +} + - (void)layoutSubviews { [super layoutSubviews]; if (_message != nil) { @@ -494,16 +568,22 @@ static const CGFloat CELL_MESSAGE_Y_MARGIN = 52; // 44; + (CGSize)getMediaMessageSizefromOriginalSize:(CGSize)originalSize withWidth:(int)width { CGSize mediaSize = CGSizeMake(0, 0); int availableWidth = width; - if (UIInterfaceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation])) { - availableWidth = availableWidth /3; + if (UIInterfaceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation]) || IPAD) { + availableWidth = availableWidth /1.7; } + int newHeight = originalSize.height; float originalAspectRatio = originalSize.width / originalSize.height; // We resize in width and crop in height if (originalSize.width > availableWidth) { newHeight = availableWidth / originalAspectRatio; } - mediaSize.height = MIN(newHeight, availableWidth); + + if (newHeight > availableWidth) { + newHeight = availableWidth; + availableWidth = newHeight * originalAspectRatio; + } + mediaSize.height = newHeight; mediaSize.width = MIN(availableWidth, originalSize.width); return mediaSize; } diff --git a/Classes/LinphoneUI/UIChatCell.h b/Classes/LinphoneUI/UIChatCell.h index 75cc7e7d4..e63dfb5ea 100644 --- a/Classes/LinphoneUI/UIChatCell.h +++ b/Classes/LinphoneUI/UIChatCell.h @@ -30,6 +30,7 @@ } @property(nonatomic, strong) IBOutlet UIRoundedImageView *avatarImage; +@property (weak, nonatomic) IBOutlet UIImageView *securityImage; @property(nonatomic, strong) IBOutlet UILabel *addressLabel; @property(nonatomic, strong) IBOutlet UILabel *chatContentLabel; @property(weak, nonatomic) IBOutlet UILabel *chatLatestTimeLabel; diff --git a/Classes/LinphoneUI/UIChatCell.m b/Classes/LinphoneUI/UIChatCell.m index 9dd2d7247..1df3d50c7 100644 --- a/Classes/LinphoneUI/UIChatCell.m +++ b/Classes/LinphoneUI/UIChatCell.m @@ -81,6 +81,8 @@ _addressLabel.text = [NSString stringWithUTF8String:subject ?: LINPHONE_DUMMY_SUBJECT]; [_avatarImage setImage:[UIImage imageNamed:@"chat_group_avatar.png"] bordered:NO withRoundedRadius:YES]; } + // TODO update security image when security level changed + [_securityImage setImage:[FastAddressBook imageForSecurityLevel:linphone_chat_room_get_security_level(chatRoom)]]; _chatLatestTimeLabel.text = [LinphoneUtils timeToString:linphone_chat_room_get_last_update_time(chatRoom) withFormat:LinphoneDateChatList]; @@ -92,8 +94,8 @@ NSString *text = [UIChatBubbleTextCell TextMessageForChat:last_msg]; if (outgoing) { // shorten long messages - if ([text length] > 50) - text = [[text substringToIndex:50] stringByAppendingString:@"[...]"]; + /*if ([text length] > 50) + text = [[text substringToIndex:50] stringByAppendingString:@"[...]"];*/ _chatContentLabel.attributedText = nil; _chatContentLabel.text = text; } else { @@ -105,10 +107,10 @@ UIFont *boldFont = [UIFont boldSystemFontOfSize:fontSize]; NSMutableAttributedString *boldText = [[NSMutableAttributedString alloc] initWithString:name attributes:@{ NSFontAttributeName : boldFont }]; text = [@" : " stringByAppendingString:text]; - NSString *fullText = [name stringByAppendingString:text]; - if ([fullText length] > 50) { + //NSString *fullText = [name stringByAppendingString:text]; + /*if ([fullText length] > 50) { text = [[text substringToIndex: (50 - [name length])] stringByAppendingString:@"[...]"]; - } + }*/ [boldText appendAttributedString:[[NSAttributedString alloc] initWithString:text]]; _chatContentLabel.text = nil; _chatContentLabel.attributedText = boldText; @@ -119,24 +121,24 @@ if (outgoing && (state == LinphoneChatMessageStateDeliveredToUser || state == LinphoneChatMessageStateDisplayed || state == LinphoneChatMessageStateNotDelivered || state == LinphoneChatMessageStateFileTransferError)) { [self displayImdmStatus:state]; CGRect newFrame = _chatContentLabel.frame; - newFrame.origin.x = 80; + newFrame.origin.x = 89; _chatContentLabel.frame = newFrame; } else { // We displace the message 20 pixels to the left [_imdmIcon setHidden:TRUE]; CGRect newFrame = _chatContentLabel.frame; - newFrame.origin.x = 60; + newFrame.origin.x = 69; _chatContentLabel.frame = newFrame; } } else { NSString *text = [[FastAddressBook displayNameForAddress:linphone_chat_message_get_from_address(last_msg)] stringByAppendingFormat:@" : %@", [UIChatBubbleTextCell TextMessageForChat:last_msg]]; // shorten long messages - if ([text length] > 50) - text = [[text substringToIndex:50] stringByAppendingString:@"[...]"]; + /*if ([text length] > 50) + text = [[text substringToIndex:50] stringByAppendingString:@"[...]"];*/ [_imdmIcon setHidden:TRUE]; CGRect newFrame = _chatContentLabel.frame; - newFrame.origin.x = 60; + newFrame.origin.x = 69; _chatContentLabel.frame = newFrame; _chatContentLabel.text = text; } @@ -156,7 +158,7 @@ } else { [_unreadCountView stopAnimating:YES]; } - UIFont *addressFont = (count <= 0) ? [UIFont systemFontOfSize:25] : [UIFont boldSystemFontOfSize:25]; + UIFont *addressFont = (count <= 0) ? [UIFont systemFontOfSize:21] : [UIFont boldSystemFontOfSize:21]; _addressLabel.font = addressFont; } diff --git a/Classes/LinphoneUI/UIChatCreateCell.h b/Classes/LinphoneUI/UIChatCreateCell.h index 424683497..0a035ec01 100644 --- a/Classes/LinphoneUI/UIChatCreateCell.h +++ b/Classes/LinphoneUI/UIChatCreateCell.h @@ -13,6 +13,9 @@ @property(weak, nonatomic) IBOutlet UILabel *addressLabel; @property (weak, nonatomic) IBOutlet UIImageView *selectedImage; @property (weak, nonatomic) IBOutlet UIImageView *linphoneImage; +@property (weak, nonatomic) IBOutlet UIRoundedImageView *avatarImage; +@property (weak, nonatomic) IBOutlet UIImageView *securityImage; +@property (weak, nonatomic) IBOutlet UIView *greyView; - (id)initWithIdentifier:(NSString *)identifier; diff --git a/Classes/LinphoneUI/UIChatNotifiedEventCell.m b/Classes/LinphoneUI/UIChatNotifiedEventCell.m index 6b093f8c2..5fcb68701 100644 --- a/Classes/LinphoneUI/UIChatNotifiedEventCell.m +++ b/Classes/LinphoneUI/UIChatNotifiedEventCell.m @@ -59,6 +59,7 @@ static const CGFloat NOTIFIED_CELL_HEIGHT = 44; - (void)setEvent:(LinphoneEventLog *)event { _event = event; NSString *eventString; + UIColor *eventColor = [UIColor grayColor]; switch (linphone_event_log_get_type(event)) { case LinphoneEventLogTypeConferenceSubjectChanged: { NSString *subject = [NSString stringWithUTF8String:linphone_event_log_get_subject(event) ?: LINPHONE_DUMMY_SUBJECT]; @@ -93,6 +94,47 @@ static const CGFloat NOTIFIED_CELL_HEIGHT = 44; eventString = [NSString stringWithFormat:NSLocalizedString(@"You have joined the group", nil)]; break; } + case LinphoneEventLogTypeConferenceSecurityEvent: { + LinphoneSecurityEventType type = linphone_event_log_get_security_event_type(event); + NSString *participant = [FastAddressBook displayNameForAddress:linphone_event_log_get_security_event_faulty_device_address(event)]; + switch (type) { + case LinphoneSecurityEventTypeSecurityLevelDowngraded: + if (!participant) + eventString = [NSString stringWithFormat:NSLocalizedString(@"Security level decreased", nil)]; + else + eventString = [NSString stringWithFormat:NSLocalizedString(@"Security level decreased because of %@", nil),participant]; + eventColor = [UIColor grayColor]; + break; + case LinphoneSecurityEventTypeParticipantMaxDeviceCountExceeded: + if (!participant) + eventString = [NSString stringWithFormat:NSLocalizedString(@"Max participant count exceeded", nil)]; + else + eventString = [NSString stringWithFormat:NSLocalizedString(@"Max participant count exceeded by %@", nil),participant]; + eventColor = [UIColor redColor]; + break; + case LinphoneSecurityEventTypeEncryptionIdentityKeyChanged: + if (!participant) + eventString = [NSString stringWithFormat:NSLocalizedString(@"LIME identity key changed", nil)]; + else + eventString = [NSString stringWithFormat:NSLocalizedString(@"LIME identity key changed for %@", nil),participant]; + eventColor = [UIColor redColor]; + break; + case LinphoneSecurityEventTypeManInTheMiddleDetected: + if (!participant) + eventString = [NSString stringWithFormat:NSLocalizedString(@"Man-in-the-middle attack detected", nil)]; + else + eventString = [NSString stringWithFormat:NSLocalizedString(@"Man-in-the-middle attack detected for %@", nil),participant]; + eventColor = [UIColor redColor]; + break; + + case LinphoneSecurityEventTypeNone: + default: + break; + } + + break; + } + default: return; } diff --git a/Classes/LinphoneUI/UIConfirmationDialog.h b/Classes/LinphoneUI/UIConfirmationDialog.h index 072bad3be..0ed2416d9 100644 --- a/Classes/LinphoneUI/UIConfirmationDialog.h +++ b/Classes/LinphoneUI/UIConfirmationDialog.h @@ -26,11 +26,22 @@ typedef void (^UIConfirmationBlock)(void); onCancelClick:(UIConfirmationBlock)onCancel onConfirmationClick:(UIConfirmationBlock)onConfirm inController:(UIViewController *)controller; ++ (UIConfirmationDialog *)ShowWithAttributedMessage:(NSMutableAttributedString *)attributedText + cancelMessage:(NSString *)cancel + confirmMessage:(NSString *)confirm + onCancelClick:(UIConfirmationBlock)onCancel + onConfirmationClick:(UIConfirmationBlock)onConfirm; @property(weak, nonatomic) IBOutlet UIRoundBorderedButton *cancelButton; +@property (weak, nonatomic) IBOutlet UIImageView *securityImage; @property(weak, nonatomic) IBOutlet UIRoundBorderedButton *confirmationButton; +@property (weak, nonatomic) IBOutlet UIView *authView; @property(weak, nonatomic) IBOutlet UILabel *titleLabel; +@property (weak, nonatomic) IBOutlet UIButton *authButton; + +- (void)setSpecialColor; - (IBAction)onCancelClick:(id)sender; - (IBAction)onConfirmationClick:(id)sender; +- (IBAction)onAuthClick:(id)sender; - (void)dismiss; @end diff --git a/Classes/LinphoneUI/UIConfirmationDialog.m b/Classes/LinphoneUI/UIConfirmationDialog.m index 19211d558..795039437 100644 --- a/Classes/LinphoneUI/UIConfirmationDialog.m +++ b/Classes/LinphoneUI/UIConfirmationDialog.m @@ -10,6 +10,35 @@ #import "PhoneMainView.h" @implementation UIConfirmationDialog ++ (UIConfirmationDialog *)initDialog:(NSString *)cancel + confirmMessage:(NSString *)confirm + onCancelClick:(UIConfirmationBlock)onCancel + onConfirmationClick:(UIConfirmationBlock)onConfirm + inController:(UIViewController *)controller { + UIConfirmationDialog *dialog = + [[UIConfirmationDialog alloc] initWithNibName:NSStringFromClass(self.class) bundle:NSBundle.mainBundle]; + + dialog.view.frame = PhoneMainView.instance.mainViewController.view.frame; + [controller.view addSubview:dialog.view]; + [controller addChildViewController:dialog]; + + dialog->onCancelCb = onCancel; + dialog->onConfirmCb = onConfirm; + + if (cancel) { + [dialog.cancelButton setTitle:cancel forState:UIControlStateNormal]; + } + if (confirm) { + [dialog.confirmationButton setTitle:confirm forState:UIControlStateNormal]; + } + + dialog.confirmationButton.layer.borderColor = + [[UIColor colorWithPatternImage:[UIImage imageNamed:@"color_A.png"]] CGColor]; + dialog.cancelButton.layer.borderColor = + [[UIColor colorWithPatternImage:[UIImage imageNamed:@"color_F.png"]] CGColor]; + return dialog; +} + + (UIConfirmationDialog *)ShowWithMessage:(NSString *)message cancelMessage:(NSString *)cancel confirmMessage:(NSString *)confirm @@ -17,27 +46,8 @@ onConfirmationClick:(UIConfirmationBlock)onConfirm inController:(UIViewController *)controller { UIConfirmationDialog *dialog = - [[UIConfirmationDialog alloc] initWithNibName:NSStringFromClass(self.class) bundle:NSBundle.mainBundle]; - - dialog.view.frame = PhoneMainView.instance.mainViewController.view.frame; - [controller.view addSubview:dialog.view]; - [controller addChildViewController:dialog]; - - dialog->onCancelCb = onCancel; - dialog->onConfirmCb = onConfirm; - - [dialog.titleLabel setText:message]; - if (cancel) { - [dialog.cancelButton setTitle:cancel forState:UIControlStateNormal]; - } - if (confirm) { - [dialog.confirmationButton setTitle:confirm forState:UIControlStateNormal]; - } - - dialog.confirmationButton.layer.borderColor = - [[UIColor colorWithPatternImage:[UIImage imageNamed:@"color_A.png"]] CGColor]; - dialog.cancelButton.layer.borderColor = - [[UIColor colorWithPatternImage:[UIImage imageNamed:@"color_F.png"]] CGColor]; + [UIConfirmationDialog initDialog:cancel confirmMessage:confirm onCancelClick:onCancel onConfirmationClick:onConfirm inController:controller]; + [dialog.titleLabel setText:message]; return dialog; } @@ -54,6 +64,28 @@ inController:PhoneMainView.instance.mainViewController]; } ++ (UIConfirmationDialog *)ShowWithAttributedMessage:(NSMutableAttributedString *)attributedText + cancelMessage:(NSString *)cancel + confirmMessage:(NSString *)confirm + onCancelClick:(UIConfirmationBlock)onCancel + onConfirmationClick:(UIConfirmationBlock)onConfirm { + UIConfirmationDialog *dialog = + [UIConfirmationDialog initDialog:cancel confirmMessage:confirm onCancelClick:onCancel onConfirmationClick:onConfirm inController:PhoneMainView.instance.mainViewController]; + dialog.titleLabel.attributedText = attributedText; + return dialog; +} + +- (void)setSpecialColor { + [_confirmationButton setBackgroundImage:[UIImage imageNamed:@"color_L.png"] forState:UIControlStateNormal]; + [_cancelButton setBackgroundImage:[UIImage imageNamed:@"color_I.png"] forState:UIControlStateNormal]; + [_cancelButton setTitleColor:[UIColor colorWithPatternImage:[UIImage imageNamed:@"color_H.png"]] forState:UIControlStateNormal]; + + _confirmationButton.layer.borderColor = + [[UIColor colorWithPatternImage:[UIImage imageNamed:@"color_L.png"]] CGColor]; + _cancelButton.layer.borderColor = + [[UIColor colorWithPatternImage:[UIImage imageNamed:@"color_A.png"]] CGColor]; +} + - (IBAction)onCancelClick:(id)sender { [self.view removeFromSuperview]; [self removeFromParentViewController]; @@ -70,6 +102,13 @@ } } +- (IBAction)onAuthClick:(id)sender { + BOOL notAskAgain = ![LinphoneManager.instance lpConfigBoolForKey:@"confirmation_dialog_before_sas_call_not_ask_again"]; + UIImage *image = notAskAgain ? [UIImage imageNamed:@"checkbox_checked.png"] : [UIImage imageNamed:@"checkbox_unchecked.png"]; + [_authButton setImage:image forState:UIControlStateNormal]; + [LinphoneManager.instance lpConfigSetBool:notAskAgain forKey:@"confirmation_dialog_before_sas_call_not_ask_again"]; +} + - (void)dismiss { [self onCancelClick:nil]; } diff --git a/Classes/LinphoneUI/UIContactCell.m b/Classes/LinphoneUI/UIContactCell.m index 148f561e3..fb65439f4 100644 --- a/Classes/LinphoneUI/UIContactCell.m +++ b/Classes/LinphoneUI/UIContactCell.m @@ -63,8 +63,8 @@ - (void)onPresenceChanged:(NSNotification *)k { LinphoneFriend *f = [[k.userInfo valueForKey:@"friend"] pointerValue]; - // only consider event if it's about us - if (_contact && _nameLabel.text == PhoneMainView.instance.currentName) { + // only consider event if it's about us when not in ContactsListView + if (_contact && (PhoneMainView.instance.currentView == ContactsListView.compositeViewDescription || _nameLabel.text == PhoneMainView.instance.currentName)) { if (!_contact.friend || f != _contact.friend) { return; } diff --git a/Classes/LinphoneUI/UIContactDetailsCell.h b/Classes/LinphoneUI/UIContactDetailsCell.h index 4832d5d77..ec5da8d20 100644 --- a/Classes/LinphoneUI/UIContactDetailsCell.h +++ b/Classes/LinphoneUI/UIContactDetailsCell.h @@ -18,6 +18,7 @@ */ #import +#import #import "UIIconButton.h" @@ -36,6 +37,9 @@ @property(weak, nonatomic) IBOutlet UIIconButton *chatButton; @property (weak, nonatomic) IBOutlet UIImageView *linphoneImage; @property (weak, nonatomic) UIView *waitView; +@property (strong, nonatomic) IBOutlet UIButton *inviteButton; +@property (weak, nonatomic) IBOutlet UIView *encryptedChatView; +@property (weak, nonatomic) IBOutlet UIView *optionsView; - (id)initWithIdentifier:(NSString *)identifier; - (void)setAddress:(NSString *)address; @@ -44,5 +48,7 @@ - (IBAction)onCallClick:(id)sender; - (IBAction)onChatClick:(id)sender; +- (IBAction)onEncrptedChatClick:(id)sender; - (IBAction)onDeleteClick:(id)sender; +- (IBAction)onSMSInviteClick:(id)sender; @end diff --git a/Classes/LinphoneUI/UIContactDetailsCell.m b/Classes/LinphoneUI/UIContactDetailsCell.m index 90c79066e..f3fba5a98 100644 --- a/Classes/LinphoneUI/UIContactDetailsCell.m +++ b/Classes/LinphoneUI/UIContactDetailsCell.m @@ -61,13 +61,16 @@ _linphoneImage.hidden = TRUE; if (contact) { + const LinphonePresenceModel *model = contact.friend ? linphone_friend_get_presence_model_for_uri_or_tel(contact.friend, _addressLabel.text.UTF8String) : NULL; + self.linphoneImage.hidden = - !((contact.friend && - linphone_presence_model_get_basic_status(linphone_friend_get_presence_model_for_uri_or_tel( - contact.friend, _addressLabel.text.UTF8String)) == LinphonePresenceBasicStatusOpen) || + !((model && linphone_presence_model_get_basic_status(model) == LinphonePresenceBasicStatusOpen) || (!linphone_proxy_config_is_phone_number(linphone_core_get_default_proxy_config(LC), _addressLabel.text.UTF8String) && [FastAddressBook isSipURIValid:_addressLabel.text])); + ContactDetailsView *contactDetailsView = VIEW(ContactDetailsView); + self.inviteButton.hidden = !ENABLE_SMS_INVITE || [[contactDetailsView.contact sipAddresses] count] > 0 || !self.linphoneImage.hidden; + [self shouldHideEncryptedChatView:model && linphone_presence_model_has_capability(model, LinphoneFriendCapabilityLimeX3dh)]; } if (addr) { @@ -75,6 +78,18 @@ } } +- (void)shouldHideEncryptedChatView:(BOOL)hasLime { + _encryptedChatView.hidden = !hasLime; + CGRect newFrame = _optionsView.frame; + if (!hasLime) { + newFrame.origin.x = _addressLabel.frame.origin.x + _callButton.frame.size.width * 2/3; + + } else { + newFrame.origin.x = _addressLabel.frame.origin.x; + } + _optionsView.frame = newFrame; +} + - (void)shouldHideLinphoneImageOfAddress { if (!_addressLabel.text) { return; @@ -135,10 +150,16 @@ - (IBAction)onChatClick:(id)event { LinphoneAddress *addr = [LinphoneUtils normalizeSipOrPhoneAddress:_addressLabel.text]; - [PhoneMainView.instance getOrCreateOneToOneChatRoom:addr waitView:_waitView]; + [PhoneMainView.instance getOrCreateOneToOneChatRoom:addr waitView:_waitView isEncrypted:FALSE]; linphone_address_destroy(addr); } +- (IBAction)onEncrptedChatClick:(id)sender { + LinphoneAddress *addr = [LinphoneUtils normalizeSipOrPhoneAddress:_addressLabel.text]; + [PhoneMainView.instance getOrCreateOneToOneChatRoom:addr waitView:_waitView isEncrypted:TRUE]; + linphone_address_destroy(addr); +} + - (IBAction)onDeleteClick:(id)sender { UITableView *tableView = VIEW(ContactDetailsView).tableController.tableView; NSIndexPath *indexPath = [tableView indexPathForCell:self]; @@ -147,4 +168,17 @@ forRowAtIndexPath:indexPath]; } +#pragma mark - SMS invite + +- (IBAction)onSMSInviteClick:(id)sender { + MFMessageComposeViewController *controller = [[MFMessageComposeViewController alloc] init]; + if([MFMessageComposeViewController canSendText]) { + controller.body = NSLocalizedString(@"Hello! Join me on Linphone! You can download it for free at: https://www.linphone.org/download",nil); + controller.recipients = [NSArray arrayWithObjects:[self.addressLabel text], nil]; + + controller.messageComposeDelegate = PhoneMainView.instance; + [PhoneMainView.instance presentViewController:controller animated:YES completion:nil]; + } +} + @end diff --git a/Classes/LinphoneUI/UIDeviceCell.h b/Classes/LinphoneUI/UIDeviceCell.h new file mode 100644 index 000000000..bee4bafe4 --- /dev/null +++ b/Classes/LinphoneUI/UIDeviceCell.h @@ -0,0 +1,20 @@ +// +// UIDeviceCell.h +// linphone +// +// Created by Danmei Chen on 07/11/2018. +// + +#import + +@interface UIDeviceCell : UITableViewCell + +@property (weak, nonatomic) IBOutlet UILabel *deviceLabel; +@property (weak, nonatomic) IBOutlet UIButton *securityButton; +@property LinphoneParticipantDevice *device; +@property BOOL isOneToOne; + +- (IBAction)onSecurityCallClick:(id)sender; +- (id)initWithIdentifier:(NSString *)identifier; +- (void)update; +@end diff --git a/Classes/LinphoneUI/UIDeviceCell.m b/Classes/LinphoneUI/UIDeviceCell.m new file mode 100644 index 000000000..f5a687034 --- /dev/null +++ b/Classes/LinphoneUI/UIDeviceCell.m @@ -0,0 +1,48 @@ +// +// UIDeviceCell.m +// linphone +// +// Created by Danmei Chen on 07/11/2018. +// + +#import "UIDeviceCell.h" + +@implementation UIDeviceCell +#pragma mark - Lifecycle Functions +- (id)initWithIdentifier:(NSString *)identifier { + if ((self = [super initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier]) != nil) { + NSArray *arrayOfViews = + [[NSBundle mainBundle] loadNibNamed:NSStringFromClass(self.class) owner:self options:nil]; + + // 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)update { + [_securityButton setImage:[FastAddressBook imageForSecurityLevel:linphone_participant_device_get_security_level(_device)] forState:UIControlStateNormal]; + + _deviceLabel.text = [NSString stringWithUTF8String:linphone_participant_device_get_name(_device) ? : + linphone_address_as_string_uri_only(linphone_participant_device_get_address(_device))]; + if (_isOneToOne) { + CGRect frame =_deviceLabel.frame; + frame.origin.x = 30; + _deviceLabel.frame = frame; + } + + self.selectionStyle =UITableViewCellSelectionStyleNone; +} + +- (IBAction)onSecurityCallClick:(id)sender { + const LinphoneAddress *addr = linphone_participant_device_get_address(_device); + if (addr) + [LinphoneManager.instance doCallWithSas:addr isSas:TRUE]; + else + LOGE(@"CallKit : No call address"); +} + +@end diff --git a/Classes/LinphoneUI/UIDeviceCell.xib b/Classes/LinphoneUI/UIDeviceCell.xib new file mode 100644 index 000000000..01f730bf3 --- /dev/null +++ b/Classes/LinphoneUI/UIDeviceCell.xib @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Classes/LinphoneUI/UIDevicesDetails.h b/Classes/LinphoneUI/UIDevicesDetails.h new file mode 100644 index 000000000..36a91a1df --- /dev/null +++ b/Classes/LinphoneUI/UIDevicesDetails.h @@ -0,0 +1,24 @@ +// +// UIDevicesDetails.h +// linphone +// +// Created by Danmei Chen on 06/11/2018. +// + +#import + +@interface UIDevicesDetails : UITableViewCell + +@property (weak, nonatomic) IBOutlet UIButton *dropMenuButton; +@property (weak, nonatomic) IBOutlet UILabel *addressLabel; +@property (weak, nonatomic) IBOutlet UIRoundedImageView *avatarImage; +@property (weak, nonatomic) IBOutlet UIImageView *securityImage; +@property (weak, nonatomic) IBOutlet UIButton *securityButton; +@property (weak, nonatomic) IBOutlet UITableView *devicesTable; +@property bctbx_list_t *devices; +@property LinphoneParticipant *participant; + +- (IBAction)onSecurityCallClick:(id)sender; +- (id)initWithIdentifier:(NSString *)identifier; +- (void)update:(BOOL)listOpen; +@end diff --git a/Classes/LinphoneUI/UIDevicesDetails.m b/Classes/LinphoneUI/UIDevicesDetails.m new file mode 100644 index 000000000..602e26d92 --- /dev/null +++ b/Classes/LinphoneUI/UIDevicesDetails.m @@ -0,0 +1,90 @@ +// +// UIDevicesDetails.m +// linphone +// +// Created by Danmei Chen on 06/11/2018. +// + +#import "UIDevicesDetails.h" +#import "UIDeviceCell.h" + +@implementation UIDevicesDetails +#pragma mark - Lifecycle Functions +- (id)initWithIdentifier:(NSString *)identifier { + if ((self = [super initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier]) != nil) { + NSArray *arrayOfViews = + [[NSBundle mainBundle] loadNibNamed:NSStringFromClass(self.class) owner:self options:nil]; + + // 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]; + _devicesTable.dataSource = self; + _devicesTable.delegate = self; + } + return self; +} + +- (void)update:(BOOL)listOpen { + _devices = linphone_participant_get_devices(_participant); + UIImage *image = [FastAddressBook imageForSecurityLevel:linphone_participant_get_security_level(_participant)]; + if (bctbx_list_size(_devices) == 1) { + [_securityButton setImage:image forState:UIControlStateNormal]; + _securityButton.hidden = FALSE; + _dropMenuButton.hidden = TRUE; + } else { + UIImage *image = listOpen ? [UIImage imageNamed:@"chevron_list_open"] : [UIImage imageNamed:@"chevron_list_close"]; + [_dropMenuButton setImage:image forState:UIControlStateNormal]; + } + [_securityImage setImage:image]; +} + +- (IBAction)onSecurityCallClick:(id)sender { + LinphoneParticipantDevice *device = (LinphoneParticipantDevice *)bctbx_list_nth_data(_devices, 0); + const LinphoneAddress *addr = linphone_participant_device_get_address(device); + if (addr) + [LinphoneManager.instance doCallWithSas:addr isSas:TRUE]; + else + LOGE(@"CallKit : No call address"); +} + +#pragma mark - TableView + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { + return 1; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { + return bctbx_list_size(_devices); +} + +- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(nonnull NSIndexPath *)indexPath { + return 56.0; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + + NSString *kCellId = NSStringFromClass(UIDeviceCell.class); + UIDeviceCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellId]; + + if (cell == nil) { + cell = [[UIDeviceCell alloc] initWithIdentifier:kCellId]; + } + LinphoneParticipantDevice *device = (LinphoneParticipantDevice *)bctbx_list_nth_data(_devices, (int)[indexPath row]); + cell.device = device; + cell.isOneToOne = FALSE; + [cell update]; + + return cell; +} + +- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath + +{ + cell.backgroundColor = [UIColor colorWithRed:(245 / 255.0) green:(245 / 255.0) blue:(245 / 255.0) alpha:1.0]; + +} + +@end diff --git a/Classes/LinphoneUI/UIDevicesDetails.xib b/Classes/LinphoneUI/UIDevicesDetails.xib new file mode 100644 index 000000000..165f8a872 --- /dev/null +++ b/Classes/LinphoneUI/UIDevicesDetails.xib @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Classes/LinphoneUI/UILinphoneAudioPlayer.h b/Classes/LinphoneUI/UILinphoneAudioPlayer.h new file mode 100644 index 000000000..ef9e5ce5a --- /dev/null +++ b/Classes/LinphoneUI/UILinphoneAudioPlayer.h @@ -0,0 +1,26 @@ +// +// UILinphoneAudioPlayer.h +// linphone +// +// Created by David Idmansour on 13/07/2018. +// + +#import + +@interface UILinphoneAudioPlayer : UIViewController +@property (weak, nonatomic) IBOutlet UIButton *playButton; +@property (weak, nonatomic) IBOutlet UIButton *stopButton; +@property (weak, nonatomic) IBOutlet UILabel *timeLabel; +@property (weak, nonatomic) IBOutlet UIProgressView *timeProgress; +@property (weak, nonatomic) NSString *file; + ++ (id)audioPlayerWithFilePath:(NSString *)filePath; +- (void)close; +- (BOOL)isOpened; +- (void)open; +- (void)pause; +- (void)setFile:(NSString *)fileName; +- (IBAction)onPlay:(id)sender; +- (IBAction)onStop:(id)sender; +- (IBAction)onTapTimeBar:(UITapGestureRecognizer *)sender; +@end diff --git a/Classes/LinphoneUI/UILinphoneAudioPlayer.m b/Classes/LinphoneUI/UILinphoneAudioPlayer.m new file mode 100644 index 000000000..4f157c833 --- /dev/null +++ b/Classes/LinphoneUI/UILinphoneAudioPlayer.m @@ -0,0 +1,207 @@ +// +// UILinphoneAudioPlayer.m +// linphone +// +// Created by David Idmansour on 13/07/2018. +// + +#import "UILinphoneAudioPlayer.h" +#import "Utils.h" + +@implementation UILinphoneAudioPlayer { + @private + LinphonePlayer *player; + LinphonePlayerCbs *cbs; + int duration; + BOOL eofReached; +} + +@synthesize file; + +#pragma mark - Factory + ++ (id)audioPlayerWithFilePath:(NSString *)filePath { + return [[self alloc] initWithFilePath:filePath]; +} + +#pragma mark - Life cycle + +- (instancetype)initWithFilePath:(NSString *)filePath { + if (self = [super initWithNibName:NSStringFromClass(self.class) bundle:[NSBundle mainBundle]]) { + player = linphone_core_create_local_player(LC, NULL, NULL, NULL); + cbs = linphone_player_get_callbacks(player); + linphone_player_set_user_data(player, (__bridge void *)self); + linphone_player_cbs_set_eof_reached(cbs, on_eof_reached); + file = filePath; + eofReached = NO; + } + return self; +} + +- (void)dealloc { + [self close]; +} + +- (void)close { + if (player) { + linphone_player_unref(player); + player = NULL; + } + [self.view removeFromSuperview]; +} + +- (void)viewDidAppear:(BOOL)animated { + [_playButton setTitle:@"" forState:UIControlStateNormal]; + if (player && linphone_player_get_state(player) == LinphonePlayerPlaying) + [_playButton setImage:[UIImage imageFromSystemBarButton:UIBarButtonSystemItemPause:[UIColor blackColor]] forState:UIControlStateNormal]; + else + [_playButton setImage:[UIImage imageFromSystemBarButton:UIBarButtonSystemItemPlay:[UIColor blackColor]] forState:UIControlStateNormal]; + [_stopButton setTitle:@"" forState:UIControlStateNormal]; + [_stopButton setImage:[UIImage imageFromSystemBarButton:UIBarButtonSystemItemRefresh:[UIColor blackColor]] forState:UIControlStateNormal]; +} + +- (void)open { + linphone_player_open(player, file.UTF8String); + duration = linphone_player_get_duration(player); + [self updateTimeLabel:0]; + _timeProgress.progress = 0; + eofReached = NO; + [_playButton setTitle:@"" forState:UIControlStateNormal]; + [_playButton setImage:[UIImage imageFromSystemBarButton:UIBarButtonSystemItemPlay:[UIColor blackColor]] forState:UIControlStateNormal]; + [_stopButton setTitle:@"" forState:UIControlStateNormal]; + [_stopButton setImage:[UIImage imageFromSystemBarButton:UIBarButtonSystemItemRefresh:[UIColor blackColor]] forState:UIControlStateNormal]; +} + +- (BOOL)isOpened { + return player && linphone_player_get_state(player) != LinphonePlayerClosed; +} + +- (void)setFile:(NSString *)fileName { + linphone_player_close(player); + file = fileName; +} + +#pragma mark - Callbacks + +void on_eof_reached(LinphonePlayer *pl) { + NSLog(@"EOF reached"); + UILinphoneAudioPlayer *player = (__bridge UILinphoneAudioPlayer *)linphone_player_get_user_data(pl); + dispatch_async(dispatch_get_main_queue(), ^{ + [player.playButton setTitle:@"" forState:UIControlStateNormal]; + [player.playButton setImage:[UIImage imageFromSystemBarButton:UIBarButtonSystemItemPlay:[UIColor blackColor]] forState:UIControlStateNormal]; + }); + player->eofReached = YES; +} + +#pragma mark - ViewController methods + +- (void)viewDidLoad { + [super viewDidLoad]; +} + +- (void)didReceiveMemoryWarning { + [super didReceiveMemoryWarning]; +} + +#pragma mark - Utils + ++ (NSString *)timeToString:(int)time { + time /= 1000; + int hours = time / 3600; + time %= 3600; + int minutes = time / 60; + int seconds = time % 60; + NSNumberFormatter *formatter = [NSNumberFormatter new]; + formatter.maximumIntegerDigits = 2; + formatter.minimumIntegerDigits = 2; + NSString *ret = [NSString stringWithFormat:@"%@:%@", + [formatter stringFromNumber:[NSNumber numberWithInt:minutes]], + [formatter stringFromNumber:[NSNumber numberWithInt:seconds]]]; + ret = (hours == 0)?ret:[[NSString stringWithFormat:@"%d:", hours] stringByAppendingString:ret]; + return ret; +} + +#pragma mark - Updating + +- (void)updateTimeLabel:(int)currentTime { + _timeLabel.text = [NSString stringWithFormat:@"%@ / %@", [self.class timeToString:currentTime], [self.class timeToString:duration]]; +} + +- (void)update { + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ + while (player && linphone_player_get_state(player) == LinphonePlayerPlaying) { + int start = linphone_player_get_current_position(player); + while (player && start + 100 < duration && start + 100 > linphone_player_get_current_position(player)) { + [NSThread sleepForTimeInterval:0.01]; + if (!player || linphone_player_get_state(player) == LinphonePlayerPaused) + break; + } + start = player ? linphone_player_get_current_position(player) : start; + dispatch_async(dispatch_get_main_queue(), ^{ + _timeProgress.progress = (float)start / (float)duration; + [self updateTimeLabel:start]; + }); + } + }); +} + +- (void)pause { + if ([self isOpened]) { + linphone_player_pause(player); + [_playButton setTitle:@"" forState:UIControlStateNormal]; + [_playButton setImage:[UIImage imageFromSystemBarButton:UIBarButtonSystemItemPlay:[UIColor blackColor]] forState:UIControlStateNormal]; + } +} + +#pragma mark - Event handlers + +- (IBAction)onPlay:(id)sender { + if (eofReached) { + linphone_player_seek(player, 0); + eofReached = NO; + } + LinphonePlayerState state = linphone_player_get_state(player); + switch (state) { + case LinphonePlayerClosed: + break; + case LinphonePlayerPaused: + NSLog(@"Play"); + [_playButton setTitle:@"" forState:UIControlStateNormal]; + [_playButton setImage:[UIImage imageFromSystemBarButton:UIBarButtonSystemItemPause:[UIColor blackColor]] forState:UIControlStateNormal]; + linphone_player_start(player); + break; + case LinphonePlayerPlaying: + NSLog(@"Pause"); + [_playButton setTitle:@"" forState:UIControlStateNormal]; + [_playButton setImage:[UIImage imageFromSystemBarButton:UIBarButtonSystemItemPlay:[UIColor blackColor]] forState:UIControlStateNormal]; + linphone_player_pause(player); + break; + } + [self update]; +} + +- (IBAction)onStop:(id)sender { + NSLog(@"Stop"); + linphone_player_pause(player); + linphone_player_seek(player, 0); + eofReached = NO; + [_playButton setTitle:@"" forState:UIControlStateNormal]; + [_playButton setImage:[UIImage imageFromSystemBarButton:UIBarButtonSystemItemPlay:[UIColor blackColor]] forState:UIControlStateNormal]; + _timeProgress.progress = 0; + [self updateTimeLabel:0]; +} + +- (IBAction)onTapTimeBar:(UITapGestureRecognizer *)sender { + if (sender.state != UIGestureRecognizerStateEnded) + return; + CGPoint loc = [sender locationInView:self.view]; + CGPoint timeLoc = _timeProgress.frame.origin; + CGSize timeSize = _timeProgress.frame.size; + if (loc.x >= timeLoc.x && loc.x <= timeLoc.x + timeSize.width && loc.y >= timeLoc.y - 10 && loc.y <= timeLoc.y + timeSize.height + 10) { + float progress = (loc.x - timeLoc.x) / timeSize.width; + _timeProgress.progress = progress; + [self updateTimeLabel:(int)(progress * duration)]; + linphone_player_seek(player, (int)(progress * duration)); + } +} +@end diff --git a/Classes/LinphoneUI/UILinphoneAudioPlayer.xib b/Classes/LinphoneUI/UILinphoneAudioPlayer.xib new file mode 100644 index 000000000..1349da0cf --- /dev/null +++ b/Classes/LinphoneUI/UILinphoneAudioPlayer.xib @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Classes/LinphoneUI/UIRecordingCell.h b/Classes/LinphoneUI/UIRecordingCell.h new file mode 100644 index 000000000..d39999448 --- /dev/null +++ b/Classes/LinphoneUI/UIRecordingCell.h @@ -0,0 +1,24 @@ +// +// UIRecordingCell.h +// linphone +// +// Created by benjamin_verdier on 25/07/2018. +// + +#import + +@interface UIRecordingCell : UITableViewCell + +@property (weak, nonatomic) IBOutlet UIView *playerView; +@property (weak, nonatomic) IBOutlet UILabel *nameLabel; +@property (strong, nonatomic) IBOutlet UIToolbar *toolbar; +@property (weak, nonatomic) IBOutlet UIBarButtonItem *shareButton; + + +@property(nonatomic, assign) __block NSString *recording; + +- (id)initWithIdentifier:(NSString*)identifier; + +- (void)updateFrame; + +@end diff --git a/Classes/LinphoneUI/UIRecordingCell.m b/Classes/LinphoneUI/UIRecordingCell.m new file mode 100644 index 000000000..7c0af3e97 --- /dev/null +++ b/Classes/LinphoneUI/UIRecordingCell.m @@ -0,0 +1,126 @@ +// +// UIRecordingCell.m +// linphone +// +// Created by benjamin_verdier on 25/07/2018. +// + +#import "UIRecordingCell.h" +#import "PhoneMainView.h" +#import "UILabel+Boldify.h" +#import "Utils.h" +#import "UILinphoneAudioPlayer.h" + +@implementation UIRecordingCell + +static UILinphoneAudioPlayer *player; + +#pragma mark - Lifecycle Functions +/* + * TODO: + * - When we scroll past a selected row, the player loads incorrectly (no buttons). Probably a problem in the player code. + * - mkv recording is probably buggy, wrong eof. wav playing works but does not display the length/timestamp. + * - The share button is greyed out when not clicking it. idk why, it's really weird. +*/ +- (id)initWithIdentifier:(NSString *)identifier { + if ((self = [super initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier])) { + NSArray *arrayOfViews = + [[NSBundle mainBundle] loadNibNamed:NSStringFromClass(self.class) owner:self options:nil]; + + // resize cell to match .nib size. It is needed when resized the cell to + // correctly adapt its height too + UIRecordingCell *sub = [arrayOfViews objectAtIndex:0]; + [self setFrame:CGRectMake(0, 0, sub.frame.size.width, 40)]; + self = sub; + self.recording = NULL; + _shareButton.target = self; + _shareButton.action = @selector(onShareButtonPressed); + } + return self; +} + +- (void)dealloc { + self.recording = NULL; + [NSNotificationCenter.defaultCenter removeObserver:self]; +} + +#pragma mark - Property Functions + +- (void)setRecording:(NSString *)arecording { + _recording = arecording; + if(_recording) { + NSArray *parsedRecording = [LinphoneUtils parseRecordingName:_recording]; + NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init]; + [dateFormat setDateFormat:@"HH:mm:ss"]; + _nameLabel.text = [[[parsedRecording objectAtIndex:0] stringByAppendingString:@" @ "] stringByAppendingString:[dateFormat stringFromDate:[parsedRecording objectAtIndex:1]]]; + } +} + +#pragma mark - + +- (NSString *)accessibilityLabel { + return _nameLabel.text; +} + +- (void)setEditing:(BOOL)editing { + [self setEditing:editing animated:FALSE]; +} + +- (void)setEditing:(BOOL)editing animated:(BOOL)animated { + if (animated) { + [UIView beginAnimations:nil context:nil]; + [UIView setAnimationDuration:0.3]; + } + if (animated) { + [UIView commitAnimations]; + } +} + +- (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated { + self.selectionStyle = UITableViewCellSelectionStyleNone; +} + +- (void)updateFrame { + CGRect frame = self.frame; + if (!self.selected) { + frame.size.height = 40; + } else { + frame.size.height = 150; + } + [self setFrame:frame]; +} + +-(void)setSelected:(BOOL)selected animated:(BOOL)animated{ + [super setSelected:selected animated:animated]; + _toolbar.hidden = !selected; + if (!selected) { + return; + } + if (!player) + player = [UILinphoneAudioPlayer audioPlayerWithFilePath:[self recording]]; + else + [player setFile:[self recording]]; + if ([player isOpened]) + [player close]; + [player.view removeFromSuperview]; + [self addSubview:player.view]; + [self bringSubviewToFront:player.view]; + player.view.frame = _playerView.frame; + player.view.bounds = _playerView.bounds; + [player open]; +} + +- (void)onShareButtonPressed { + UIActivityViewController *activityVC = [[UIActivityViewController alloc] initWithActivityItems:@[[NSURL fileURLWithPath:_recording]] applicationActivities:nil]; + [activityVC setCompletionWithItemsHandler:^(UIActivityType __nullable activityType, BOOL completed, NSArray * __nullable returnedItems, NSError * __nullable activityError) { + //This is used to select the same row when we get back to the recordings view. + NSString *file = player.file; + //This reloads the view, if don't it's empty for some reason. Idealy we'd want to do this before closing the view but it's functionnal. + [PhoneMainView.instance popCurrentView]; + [PhoneMainView.instance changeCurrentView:RecordingsListView.compositeViewDescription]; + [[(RecordingsListView *)VIEW(RecordingsListView) tableController] setSelected:file]; + }]; + [PhoneMainView.instance presentViewController:activityVC animated:YES completion:nil]; +} + +@end diff --git a/Classes/LinphoneUI/UIRecordingCell.xib b/Classes/LinphoneUI/UIRecordingCell.xib new file mode 100644 index 000000000..f8fcd6aba --- /dev/null +++ b/Classes/LinphoneUI/UIRecordingCell.xib @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Classes/LinphoneUI/ar.lproj/UIChatBubblePhotoCell.strings b/Classes/LinphoneUI/ar.lproj/UIChatBubblePhotoCell.strings index 2c8264725..8460ae012 100644 Binary files a/Classes/LinphoneUI/ar.lproj/UIChatBubblePhotoCell.strings and b/Classes/LinphoneUI/ar.lproj/UIChatBubblePhotoCell.strings differ diff --git a/Classes/LinphoneUI/ar.lproj/UIChatBubbleTextCell.strings b/Classes/LinphoneUI/ar.lproj/UIChatBubbleTextCell.strings index 85c3c716f..7cfb33387 100644 Binary files a/Classes/LinphoneUI/ar.lproj/UIChatBubbleTextCell.strings and b/Classes/LinphoneUI/ar.lproj/UIChatBubbleTextCell.strings differ diff --git a/Classes/LinphoneUI/ar.lproj/UIChatCell.strings b/Classes/LinphoneUI/ar.lproj/UIChatCell.strings index 95994e306..033313d54 100644 Binary files a/Classes/LinphoneUI/ar.lproj/UIChatCell.strings and b/Classes/LinphoneUI/ar.lproj/UIChatCell.strings differ diff --git a/Classes/LinphoneUI/ar.lproj/UIConfirmationDialog.strings b/Classes/LinphoneUI/ar.lproj/UIConfirmationDialog.strings index 2691f5142..74a766b08 100644 Binary files a/Classes/LinphoneUI/ar.lproj/UIConfirmationDialog.strings and b/Classes/LinphoneUI/ar.lproj/UIConfirmationDialog.strings differ diff --git a/Classes/LinphoneUI/ar.lproj/UIContactDetailsCell.strings b/Classes/LinphoneUI/ar.lproj/UIContactDetailsCell.strings index 8d911cc2a..3532146a4 100644 Binary files a/Classes/LinphoneUI/ar.lproj/UIContactDetailsCell.strings and b/Classes/LinphoneUI/ar.lproj/UIContactDetailsCell.strings differ diff --git a/Classes/LinphoneUI/cs.lproj/UICallConferenceCell.strings b/Classes/LinphoneUI/cs.lproj/UICallConferenceCell.strings new file mode 100644 index 000000000..4c2cd3ced Binary files /dev/null and b/Classes/LinphoneUI/cs.lproj/UICallConferenceCell.strings differ diff --git a/Classes/LinphoneUI/cs.lproj/UICallPausedCell.strings b/Classes/LinphoneUI/cs.lproj/UICallPausedCell.strings new file mode 100644 index 000000000..2fea9e515 Binary files /dev/null and b/Classes/LinphoneUI/cs.lproj/UICallPausedCell.strings differ diff --git a/Classes/LinphoneUI/cs.lproj/UIChatBubblePhotoCell.strings b/Classes/LinphoneUI/cs.lproj/UIChatBubblePhotoCell.strings new file mode 100644 index 000000000..b215dc793 Binary files /dev/null and b/Classes/LinphoneUI/cs.lproj/UIChatBubblePhotoCell.strings differ diff --git a/Classes/LinphoneUI/cs.lproj/UIChatBubbleTextCell.strings b/Classes/LinphoneUI/cs.lproj/UIChatBubbleTextCell.strings new file mode 100644 index 000000000..3e5e81837 Binary files /dev/null and b/Classes/LinphoneUI/cs.lproj/UIChatBubbleTextCell.strings differ diff --git a/Classes/LinphoneUI/cs.lproj/UIChatCell.strings b/Classes/LinphoneUI/cs.lproj/UIChatCell.strings new file mode 100644 index 000000000..6e4ac4599 Binary files /dev/null and b/Classes/LinphoneUI/cs.lproj/UIChatCell.strings differ diff --git a/Classes/LinphoneUI/cs.lproj/UIChatConversationImdnTableViewCell.strings b/Classes/LinphoneUI/cs.lproj/UIChatConversationImdnTableViewCell.strings new file mode 100644 index 000000000..1942d3fca Binary files /dev/null and b/Classes/LinphoneUI/cs.lproj/UIChatConversationImdnTableViewCell.strings differ diff --git a/Classes/LinphoneUI/cs.lproj/UIChatConversationInfoTableViewCell.strings b/Classes/LinphoneUI/cs.lproj/UIChatConversationInfoTableViewCell.strings new file mode 100644 index 000000000..a4c11bafe Binary files /dev/null and b/Classes/LinphoneUI/cs.lproj/UIChatConversationInfoTableViewCell.strings differ diff --git a/Classes/LinphoneUI/cs.lproj/UIContactDetailsCell.strings b/Classes/LinphoneUI/cs.lproj/UIContactDetailsCell.strings new file mode 100644 index 000000000..b657794af Binary files /dev/null and b/Classes/LinphoneUI/cs.lproj/UIContactDetailsCell.strings differ diff --git a/Classes/LinphoneUI/de.lproj/UIChatBubblePhotoCell.strings b/Classes/LinphoneUI/de.lproj/UIChatBubblePhotoCell.strings index 2653018d9..cec096dca 100644 Binary files a/Classes/LinphoneUI/de.lproj/UIChatBubblePhotoCell.strings and b/Classes/LinphoneUI/de.lproj/UIChatBubblePhotoCell.strings differ diff --git a/Classes/LinphoneUI/de.lproj/UIChatBubbleTextCell.strings b/Classes/LinphoneUI/de.lproj/UIChatBubbleTextCell.strings index 4b0a55da6..8d4b51f36 100644 Binary files a/Classes/LinphoneUI/de.lproj/UIChatBubbleTextCell.strings and b/Classes/LinphoneUI/de.lproj/UIChatBubbleTextCell.strings differ diff --git a/Classes/LinphoneUI/de.lproj/UIChatCell.strings b/Classes/LinphoneUI/de.lproj/UIChatCell.strings index e318fe365..687a0d86e 100644 Binary files a/Classes/LinphoneUI/de.lproj/UIChatCell.strings and b/Classes/LinphoneUI/de.lproj/UIChatCell.strings differ diff --git a/Classes/LinphoneUI/de.lproj/UIConfirmationDialog.strings b/Classes/LinphoneUI/de.lproj/UIConfirmationDialog.strings index 654f6dff9..a36c833b2 100644 Binary files a/Classes/LinphoneUI/de.lproj/UIConfirmationDialog.strings and b/Classes/LinphoneUI/de.lproj/UIConfirmationDialog.strings differ diff --git a/Classes/LinphoneUI/de.lproj/UIContactDetailsCell.strings b/Classes/LinphoneUI/de.lproj/UIContactDetailsCell.strings index 1709d49fb..991091c8b 100644 Binary files a/Classes/LinphoneUI/de.lproj/UIContactDetailsCell.strings and b/Classes/LinphoneUI/de.lproj/UIContactDetailsCell.strings differ diff --git a/Classes/LinphoneUI/es.lproj/UIChatBubblePhotoCell.strings b/Classes/LinphoneUI/es.lproj/UIChatBubblePhotoCell.strings index 5c337f87f..270de3220 100644 Binary files a/Classes/LinphoneUI/es.lproj/UIChatBubblePhotoCell.strings and b/Classes/LinphoneUI/es.lproj/UIChatBubblePhotoCell.strings differ diff --git a/Classes/LinphoneUI/es.lproj/UIChatBubbleTextCell.strings b/Classes/LinphoneUI/es.lproj/UIChatBubbleTextCell.strings index 19c247041..9ae512e79 100644 Binary files a/Classes/LinphoneUI/es.lproj/UIChatBubbleTextCell.strings and b/Classes/LinphoneUI/es.lproj/UIChatBubbleTextCell.strings differ diff --git a/Classes/LinphoneUI/es.lproj/UIChatCell.strings b/Classes/LinphoneUI/es.lproj/UIChatCell.strings index 8c3c5d032..eedfd842e 100644 Binary files a/Classes/LinphoneUI/es.lproj/UIChatCell.strings and b/Classes/LinphoneUI/es.lproj/UIChatCell.strings differ diff --git a/Classes/LinphoneUI/es.lproj/UIConfirmationDialog.strings b/Classes/LinphoneUI/es.lproj/UIConfirmationDialog.strings index af4fe4ff8..1e1fc91c0 100644 Binary files a/Classes/LinphoneUI/es.lproj/UIConfirmationDialog.strings and b/Classes/LinphoneUI/es.lproj/UIConfirmationDialog.strings differ diff --git a/Classes/LinphoneUI/es.lproj/UIContactDetailsCell.strings b/Classes/LinphoneUI/es.lproj/UIContactDetailsCell.strings index c41a166fc..02c451498 100644 Binary files a/Classes/LinphoneUI/es.lproj/UIContactDetailsCell.strings and b/Classes/LinphoneUI/es.lproj/UIContactDetailsCell.strings differ diff --git a/Classes/LinphoneUI/es_AR.lproj/UIChatBubblePhotoCell.strings b/Classes/LinphoneUI/es_AR.lproj/UIChatBubblePhotoCell.strings index e3df98863..270de3220 100644 Binary files a/Classes/LinphoneUI/es_AR.lproj/UIChatBubblePhotoCell.strings and b/Classes/LinphoneUI/es_AR.lproj/UIChatBubblePhotoCell.strings differ diff --git a/Classes/LinphoneUI/es_AR.lproj/UIChatBubbleTextCell.strings b/Classes/LinphoneUI/es_AR.lproj/UIChatBubbleTextCell.strings index 90d8b1cd0..9ae512e79 100644 Binary files a/Classes/LinphoneUI/es_AR.lproj/UIChatBubbleTextCell.strings and b/Classes/LinphoneUI/es_AR.lproj/UIChatBubbleTextCell.strings differ diff --git a/Classes/LinphoneUI/es_AR.lproj/UIChatCell.strings b/Classes/LinphoneUI/es_AR.lproj/UIChatCell.strings index 8c3c5d032..eedfd842e 100644 Binary files a/Classes/LinphoneUI/es_AR.lproj/UIChatCell.strings and b/Classes/LinphoneUI/es_AR.lproj/UIChatCell.strings differ diff --git a/Classes/LinphoneUI/es_AR.lproj/UIConfirmationDialog.strings b/Classes/LinphoneUI/es_AR.lproj/UIConfirmationDialog.strings index af4fe4ff8..1e1fc91c0 100644 Binary files a/Classes/LinphoneUI/es_AR.lproj/UIConfirmationDialog.strings and b/Classes/LinphoneUI/es_AR.lproj/UIConfirmationDialog.strings differ diff --git a/Classes/LinphoneUI/es_AR.lproj/UIContactDetailsCell.strings b/Classes/LinphoneUI/es_AR.lproj/UIContactDetailsCell.strings index c41a166fc..02c451498 100644 Binary files a/Classes/LinphoneUI/es_AR.lproj/UIContactDetailsCell.strings and b/Classes/LinphoneUI/es_AR.lproj/UIContactDetailsCell.strings differ diff --git a/Classes/LinphoneUI/fr.lproj/UIChatBubblePhotoCell.strings b/Classes/LinphoneUI/fr.lproj/UIChatBubblePhotoCell.strings index abf3f9b34..2959335b4 100644 Binary files a/Classes/LinphoneUI/fr.lproj/UIChatBubblePhotoCell.strings and b/Classes/LinphoneUI/fr.lproj/UIChatBubblePhotoCell.strings differ diff --git a/Classes/LinphoneUI/fr.lproj/UIChatBubbleTextCell.strings b/Classes/LinphoneUI/fr.lproj/UIChatBubbleTextCell.strings index 36c359ced..68e6fff9a 100644 Binary files a/Classes/LinphoneUI/fr.lproj/UIChatBubbleTextCell.strings and b/Classes/LinphoneUI/fr.lproj/UIChatBubbleTextCell.strings differ diff --git a/Classes/LinphoneUI/fr.lproj/UIChatCell.strings b/Classes/LinphoneUI/fr.lproj/UIChatCell.strings index 68b814db2..0caff72dc 100644 Binary files a/Classes/LinphoneUI/fr.lproj/UIChatCell.strings and b/Classes/LinphoneUI/fr.lproj/UIChatCell.strings differ diff --git a/Classes/LinphoneUI/fr.lproj/UIConfirmationDialog.strings b/Classes/LinphoneUI/fr.lproj/UIConfirmationDialog.strings index 8fce37804..558d67110 100644 Binary files a/Classes/LinphoneUI/fr.lproj/UIConfirmationDialog.strings and b/Classes/LinphoneUI/fr.lproj/UIConfirmationDialog.strings differ diff --git a/Classes/LinphoneUI/fr.lproj/UIContactDetailsCell.strings b/Classes/LinphoneUI/fr.lproj/UIContactDetailsCell.strings index 2a6b8f684..755b5bdb5 100644 Binary files a/Classes/LinphoneUI/fr.lproj/UIContactDetailsCell.strings and b/Classes/LinphoneUI/fr.lproj/UIContactDetailsCell.strings differ diff --git a/Classes/LinphoneUI/it.lproj/StatusBarView.strings b/Classes/LinphoneUI/it.lproj/StatusBarView.strings new file mode 100644 index 000000000..fb8b02c03 Binary files /dev/null and b/Classes/LinphoneUI/it.lproj/StatusBarView.strings differ diff --git a/Classes/LinphoneUI/it.lproj/TabBarView.strings b/Classes/LinphoneUI/it.lproj/TabBarView.strings new file mode 100644 index 000000000..afb90f810 Binary files /dev/null and b/Classes/LinphoneUI/it.lproj/TabBarView.strings differ diff --git a/Classes/LinphoneUI/it.lproj/UICallConferenceCell.strings b/Classes/LinphoneUI/it.lproj/UICallConferenceCell.strings new file mode 100644 index 000000000..80860330f Binary files /dev/null and b/Classes/LinphoneUI/it.lproj/UICallConferenceCell.strings differ diff --git a/Classes/LinphoneUI/it.lproj/UICallPausedCell.strings b/Classes/LinphoneUI/it.lproj/UICallPausedCell.strings new file mode 100644 index 000000000..a1ec8e047 Binary files /dev/null and b/Classes/LinphoneUI/it.lproj/UICallPausedCell.strings differ diff --git a/Classes/LinphoneUI/it.lproj/UIChatBubblePhotoCell.strings b/Classes/LinphoneUI/it.lproj/UIChatBubblePhotoCell.strings new file mode 100644 index 000000000..bf232708c Binary files /dev/null and b/Classes/LinphoneUI/it.lproj/UIChatBubblePhotoCell.strings differ diff --git a/Classes/LinphoneUI/it.lproj/UIChatBubbleTextCell.strings b/Classes/LinphoneUI/it.lproj/UIChatBubbleTextCell.strings new file mode 100644 index 000000000..8878f1b0d Binary files /dev/null and b/Classes/LinphoneUI/it.lproj/UIChatBubbleTextCell.strings differ diff --git a/Classes/LinphoneUI/it.lproj/UIChatCell.strings b/Classes/LinphoneUI/it.lproj/UIChatCell.strings new file mode 100644 index 000000000..9b38e3f6a Binary files /dev/null and b/Classes/LinphoneUI/it.lproj/UIChatCell.strings differ diff --git a/Classes/LinphoneUI/it.lproj/UIChatConversationImdnTableViewCell.strings b/Classes/LinphoneUI/it.lproj/UIChatConversationImdnTableViewCell.strings new file mode 100644 index 000000000..2af25db3c Binary files /dev/null and b/Classes/LinphoneUI/it.lproj/UIChatConversationImdnTableViewCell.strings differ diff --git a/Classes/LinphoneUI/it.lproj/UIChatConversationInfoTableViewCell.strings b/Classes/LinphoneUI/it.lproj/UIChatConversationInfoTableViewCell.strings new file mode 100644 index 000000000..a1ca26d0c Binary files /dev/null and b/Classes/LinphoneUI/it.lproj/UIChatConversationInfoTableViewCell.strings differ diff --git a/Classes/LinphoneUI/it.lproj/UIChatCreateCell.strings b/Classes/LinphoneUI/it.lproj/UIChatCreateCell.strings new file mode 100644 index 000000000..25d0f2f51 Binary files /dev/null and b/Classes/LinphoneUI/it.lproj/UIChatCreateCell.strings differ diff --git a/Classes/LinphoneUI/it.lproj/UIChatCreateCollectionViewCell.strings b/Classes/LinphoneUI/it.lproj/UIChatCreateCollectionViewCell.strings new file mode 100644 index 000000000..1e1e09866 Binary files /dev/null and b/Classes/LinphoneUI/it.lproj/UIChatCreateCollectionViewCell.strings differ diff --git a/Classes/LinphoneUI/it.lproj/UIConfirmationDialog.strings b/Classes/LinphoneUI/it.lproj/UIConfirmationDialog.strings new file mode 100644 index 000000000..065ce6e41 Binary files /dev/null and b/Classes/LinphoneUI/it.lproj/UIConfirmationDialog.strings differ diff --git a/Classes/LinphoneUI/it.lproj/UIContactCell.strings b/Classes/LinphoneUI/it.lproj/UIContactCell.strings new file mode 100644 index 000000000..b34226d30 Binary files /dev/null and b/Classes/LinphoneUI/it.lproj/UIContactCell.strings differ diff --git a/Classes/LinphoneUI/it.lproj/UIContactDetailsCell.strings b/Classes/LinphoneUI/it.lproj/UIContactDetailsCell.strings new file mode 100644 index 000000000..9e3622c54 Binary files /dev/null and b/Classes/LinphoneUI/it.lproj/UIContactDetailsCell.strings differ diff --git a/Classes/LinphoneUI/it.lproj/UIHistoryCell.strings b/Classes/LinphoneUI/it.lproj/UIHistoryCell.strings new file mode 100644 index 000000000..fe850ab28 Binary files /dev/null and b/Classes/LinphoneUI/it.lproj/UIHistoryCell.strings differ diff --git a/Classes/LinphoneUI/ja.lproj/UIChatBubblePhotoCell.strings b/Classes/LinphoneUI/ja.lproj/UIChatBubblePhotoCell.strings index a38d10297..d5d576801 100644 Binary files a/Classes/LinphoneUI/ja.lproj/UIChatBubblePhotoCell.strings and b/Classes/LinphoneUI/ja.lproj/UIChatBubblePhotoCell.strings differ diff --git a/Classes/LinphoneUI/ja.lproj/UIChatBubbleTextCell.strings b/Classes/LinphoneUI/ja.lproj/UIChatBubbleTextCell.strings index db63a5c44..3c85b2cb5 100644 Binary files a/Classes/LinphoneUI/ja.lproj/UIChatBubbleTextCell.strings and b/Classes/LinphoneUI/ja.lproj/UIChatBubbleTextCell.strings differ diff --git a/Classes/LinphoneUI/ja.lproj/UIChatCell.strings b/Classes/LinphoneUI/ja.lproj/UIChatCell.strings index 8991b3394..dbdb6124d 100644 Binary files a/Classes/LinphoneUI/ja.lproj/UIChatCell.strings and b/Classes/LinphoneUI/ja.lproj/UIChatCell.strings differ diff --git a/Classes/LinphoneUI/ja.lproj/UIConfirmationDialog.strings b/Classes/LinphoneUI/ja.lproj/UIConfirmationDialog.strings index ebd85b310..2da6f44a5 100644 Binary files a/Classes/LinphoneUI/ja.lproj/UIConfirmationDialog.strings and b/Classes/LinphoneUI/ja.lproj/UIConfirmationDialog.strings differ diff --git a/Classes/LinphoneUI/ja.lproj/UIContactDetailsCell.strings b/Classes/LinphoneUI/ja.lproj/UIContactDetailsCell.strings index cec1d7d62..c356a7d7a 100644 Binary files a/Classes/LinphoneUI/ja.lproj/UIContactDetailsCell.strings and b/Classes/LinphoneUI/ja.lproj/UIContactDetailsCell.strings differ diff --git a/Classes/LinphoneUI/ka.lproj/UIChatBubblePhotoCell.strings b/Classes/LinphoneUI/ka.lproj/UIChatBubblePhotoCell.strings index b3f6df066..fcacb39e6 100644 Binary files a/Classes/LinphoneUI/ka.lproj/UIChatBubblePhotoCell.strings and b/Classes/LinphoneUI/ka.lproj/UIChatBubblePhotoCell.strings differ diff --git a/Classes/LinphoneUI/ka.lproj/UIChatBubbleTextCell.strings b/Classes/LinphoneUI/ka.lproj/UIChatBubbleTextCell.strings index e14ead4a4..36b6f65c2 100644 Binary files a/Classes/LinphoneUI/ka.lproj/UIChatBubbleTextCell.strings and b/Classes/LinphoneUI/ka.lproj/UIChatBubbleTextCell.strings differ diff --git a/Classes/LinphoneUI/ka.lproj/UIChatCell.strings b/Classes/LinphoneUI/ka.lproj/UIChatCell.strings index 7891cf6bb..9554fe3f8 100644 Binary files a/Classes/LinphoneUI/ka.lproj/UIChatCell.strings and b/Classes/LinphoneUI/ka.lproj/UIChatCell.strings differ diff --git a/Classes/LinphoneUI/ka.lproj/UIConfirmationDialog.strings b/Classes/LinphoneUI/ka.lproj/UIConfirmationDialog.strings index 60f04981a..252a4a03a 100644 Binary files a/Classes/LinphoneUI/ka.lproj/UIConfirmationDialog.strings and b/Classes/LinphoneUI/ka.lproj/UIConfirmationDialog.strings differ diff --git a/Classes/LinphoneUI/ka.lproj/UIContactDetailsCell.strings b/Classes/LinphoneUI/ka.lproj/UIContactDetailsCell.strings index 051026beb..1bf2537c6 100644 Binary files a/Classes/LinphoneUI/ka.lproj/UIContactDetailsCell.strings and b/Classes/LinphoneUI/ka.lproj/UIContactDetailsCell.strings differ diff --git a/Classes/LinphoneUI/nl.lproj/UIChatBubblePhotoCell.strings b/Classes/LinphoneUI/nl.lproj/UIChatBubblePhotoCell.strings index dd5e4faec..496d6fffe 100644 Binary files a/Classes/LinphoneUI/nl.lproj/UIChatBubblePhotoCell.strings and b/Classes/LinphoneUI/nl.lproj/UIChatBubblePhotoCell.strings differ diff --git a/Classes/LinphoneUI/nl.lproj/UIChatBubbleTextCell.strings b/Classes/LinphoneUI/nl.lproj/UIChatBubbleTextCell.strings index 87b54144e..24f415f1f 100644 Binary files a/Classes/LinphoneUI/nl.lproj/UIChatBubbleTextCell.strings and b/Classes/LinphoneUI/nl.lproj/UIChatBubbleTextCell.strings differ diff --git a/Classes/LinphoneUI/nl.lproj/UIChatCell.strings b/Classes/LinphoneUI/nl.lproj/UIChatCell.strings index 064b7ca46..e71e37f14 100644 Binary files a/Classes/LinphoneUI/nl.lproj/UIChatCell.strings and b/Classes/LinphoneUI/nl.lproj/UIChatCell.strings differ diff --git a/Classes/LinphoneUI/nl.lproj/UIContactDetailsCell.strings b/Classes/LinphoneUI/nl.lproj/UIContactDetailsCell.strings index 7c015f94d..811247b0c 100644 Binary files a/Classes/LinphoneUI/nl.lproj/UIContactDetailsCell.strings and b/Classes/LinphoneUI/nl.lproj/UIContactDetailsCell.strings differ diff --git a/Classes/LinphoneUI/pl.lproj/UIChatBubblePhotoCell.strings b/Classes/LinphoneUI/pl.lproj/UIChatBubblePhotoCell.strings index 75f84d0a7..429cac58e 100644 Binary files a/Classes/LinphoneUI/pl.lproj/UIChatBubblePhotoCell.strings and b/Classes/LinphoneUI/pl.lproj/UIChatBubblePhotoCell.strings differ diff --git a/Classes/LinphoneUI/pl.lproj/UIChatBubbleTextCell.strings b/Classes/LinphoneUI/pl.lproj/UIChatBubbleTextCell.strings index af3435a85..f08b70ddd 100644 Binary files a/Classes/LinphoneUI/pl.lproj/UIChatBubbleTextCell.strings and b/Classes/LinphoneUI/pl.lproj/UIChatBubbleTextCell.strings differ diff --git a/Classes/LinphoneUI/pl.lproj/UIChatCell.strings b/Classes/LinphoneUI/pl.lproj/UIChatCell.strings index 2bee13f7e..ec8047db1 100644 Binary files a/Classes/LinphoneUI/pl.lproj/UIChatCell.strings and b/Classes/LinphoneUI/pl.lproj/UIChatCell.strings differ diff --git a/Classes/LinphoneUI/pl.lproj/UIConfirmationDialog.strings b/Classes/LinphoneUI/pl.lproj/UIConfirmationDialog.strings index 684f5043a..624cd0cc0 100644 Binary files a/Classes/LinphoneUI/pl.lproj/UIConfirmationDialog.strings and b/Classes/LinphoneUI/pl.lproj/UIConfirmationDialog.strings differ diff --git a/Classes/LinphoneUI/pl.lproj/UIContactDetailsCell.strings b/Classes/LinphoneUI/pl.lproj/UIContactDetailsCell.strings index adb9053ff..172a32ed2 100644 Binary files a/Classes/LinphoneUI/pl.lproj/UIContactDetailsCell.strings and b/Classes/LinphoneUI/pl.lproj/UIContactDetailsCell.strings differ diff --git a/Classes/LinphoneUI/pt_BR.lproj/UIChatBubblePhotoCell.strings b/Classes/LinphoneUI/pt_BR.lproj/UIChatBubblePhotoCell.strings index fd7092ed1..c59e795bb 100644 Binary files a/Classes/LinphoneUI/pt_BR.lproj/UIChatBubblePhotoCell.strings and b/Classes/LinphoneUI/pt_BR.lproj/UIChatBubblePhotoCell.strings differ diff --git a/Classes/LinphoneUI/pt_BR.lproj/UIChatBubbleTextCell.strings b/Classes/LinphoneUI/pt_BR.lproj/UIChatBubbleTextCell.strings index 94c00ed77..532d94e8a 100644 Binary files a/Classes/LinphoneUI/pt_BR.lproj/UIChatBubbleTextCell.strings and b/Classes/LinphoneUI/pt_BR.lproj/UIChatBubbleTextCell.strings differ diff --git a/Classes/LinphoneUI/pt_BR.lproj/UIChatCell.strings b/Classes/LinphoneUI/pt_BR.lproj/UIChatCell.strings index ce2b07ceb..6272b7c09 100644 Binary files a/Classes/LinphoneUI/pt_BR.lproj/UIChatCell.strings and b/Classes/LinphoneUI/pt_BR.lproj/UIChatCell.strings differ diff --git a/Classes/LinphoneUI/pt_BR.lproj/UIChatConversationImdnTableViewCell.strings b/Classes/LinphoneUI/pt_BR.lproj/UIChatConversationImdnTableViewCell.strings index 022b94686..1d11499c1 100644 Binary files a/Classes/LinphoneUI/pt_BR.lproj/UIChatConversationImdnTableViewCell.strings and b/Classes/LinphoneUI/pt_BR.lproj/UIChatConversationImdnTableViewCell.strings differ diff --git a/Classes/LinphoneUI/pt_BR.lproj/UIConfirmationDialog.strings b/Classes/LinphoneUI/pt_BR.lproj/UIConfirmationDialog.strings index de22d4693..9859038a2 100644 Binary files a/Classes/LinphoneUI/pt_BR.lproj/UIConfirmationDialog.strings and b/Classes/LinphoneUI/pt_BR.lproj/UIConfirmationDialog.strings differ diff --git a/Classes/LinphoneUI/pt_BR.lproj/UIContactDetailsCell.strings b/Classes/LinphoneUI/pt_BR.lproj/UIContactDetailsCell.strings index 39841b683..7401466e4 100644 Binary files a/Classes/LinphoneUI/pt_BR.lproj/UIContactDetailsCell.strings and b/Classes/LinphoneUI/pt_BR.lproj/UIContactDetailsCell.strings differ diff --git a/Classes/LinphoneUI/ru.lproj/StatusBarView.strings b/Classes/LinphoneUI/ru.lproj/StatusBarView.strings index dd4d7dadc..9a48b1e5b 100644 Binary files a/Classes/LinphoneUI/ru.lproj/StatusBarView.strings and b/Classes/LinphoneUI/ru.lproj/StatusBarView.strings differ diff --git a/Classes/LinphoneUI/ru.lproj/UICallConferenceCell.strings b/Classes/LinphoneUI/ru.lproj/UICallConferenceCell.strings index 1c337daf7..b464a9b5d 100644 Binary files a/Classes/LinphoneUI/ru.lproj/UICallConferenceCell.strings and b/Classes/LinphoneUI/ru.lproj/UICallConferenceCell.strings differ diff --git a/Classes/LinphoneUI/ru.lproj/UICallPausedCell.strings b/Classes/LinphoneUI/ru.lproj/UICallPausedCell.strings index 1334b5315..4f5e4241b 100644 Binary files a/Classes/LinphoneUI/ru.lproj/UICallPausedCell.strings and b/Classes/LinphoneUI/ru.lproj/UICallPausedCell.strings differ diff --git a/Classes/LinphoneUI/ru.lproj/UIChatBubblePhotoCell.strings b/Classes/LinphoneUI/ru.lproj/UIChatBubblePhotoCell.strings index 6808700a8..b9ffacc6a 100644 Binary files a/Classes/LinphoneUI/ru.lproj/UIChatBubblePhotoCell.strings and b/Classes/LinphoneUI/ru.lproj/UIChatBubblePhotoCell.strings differ diff --git a/Classes/LinphoneUI/ru.lproj/UIChatBubbleTextCell.strings b/Classes/LinphoneUI/ru.lproj/UIChatBubbleTextCell.strings index 59a609edc..bcebe71c6 100644 Binary files a/Classes/LinphoneUI/ru.lproj/UIChatBubbleTextCell.strings and b/Classes/LinphoneUI/ru.lproj/UIChatBubbleTextCell.strings differ diff --git a/Classes/LinphoneUI/ru.lproj/UIChatCell.strings b/Classes/LinphoneUI/ru.lproj/UIChatCell.strings index 5312fc79e..9db126230 100644 Binary files a/Classes/LinphoneUI/ru.lproj/UIChatCell.strings and b/Classes/LinphoneUI/ru.lproj/UIChatCell.strings differ diff --git a/Classes/LinphoneUI/ru.lproj/UIChatConversationImdnTableViewCell.strings b/Classes/LinphoneUI/ru.lproj/UIChatConversationImdnTableViewCell.strings index 25b34f232..5db05ba21 100644 Binary files a/Classes/LinphoneUI/ru.lproj/UIChatConversationImdnTableViewCell.strings and b/Classes/LinphoneUI/ru.lproj/UIChatConversationImdnTableViewCell.strings differ diff --git a/Classes/LinphoneUI/ru.lproj/UIChatConversationInfoTableViewCell.strings b/Classes/LinphoneUI/ru.lproj/UIChatConversationInfoTableViewCell.strings index e36677a54..378c577b7 100644 Binary files a/Classes/LinphoneUI/ru.lproj/UIChatConversationInfoTableViewCell.strings and b/Classes/LinphoneUI/ru.lproj/UIChatConversationInfoTableViewCell.strings differ diff --git a/Classes/LinphoneUI/ru.lproj/UIChatCreateCell.strings b/Classes/LinphoneUI/ru.lproj/UIChatCreateCell.strings index 78b8b6620..21e71a185 100644 Binary files a/Classes/LinphoneUI/ru.lproj/UIChatCreateCell.strings and b/Classes/LinphoneUI/ru.lproj/UIChatCreateCell.strings differ diff --git a/Classes/LinphoneUI/ru.lproj/UIConfirmationDialog.strings b/Classes/LinphoneUI/ru.lproj/UIConfirmationDialog.strings index 883fc080c..7f850628a 100644 Binary files a/Classes/LinphoneUI/ru.lproj/UIConfirmationDialog.strings and b/Classes/LinphoneUI/ru.lproj/UIConfirmationDialog.strings differ diff --git a/Classes/LinphoneUI/ru.lproj/UIContactCell.strings b/Classes/LinphoneUI/ru.lproj/UIContactCell.strings index 5a5a8e4c0..b28b6a083 100644 Binary files a/Classes/LinphoneUI/ru.lproj/UIContactCell.strings and b/Classes/LinphoneUI/ru.lproj/UIContactCell.strings differ diff --git a/Classes/LinphoneUI/ru.lproj/UIContactDetailsCell.strings b/Classes/LinphoneUI/ru.lproj/UIContactDetailsCell.strings index ab04faacd..c521206a4 100644 Binary files a/Classes/LinphoneUI/ru.lproj/UIContactDetailsCell.strings and b/Classes/LinphoneUI/ru.lproj/UIContactDetailsCell.strings differ diff --git a/Classes/LinphoneUI/ru.lproj/UIHistoryCell.strings b/Classes/LinphoneUI/ru.lproj/UIHistoryCell.strings index c2bcb90cb..658926e58 100644 Binary files a/Classes/LinphoneUI/ru.lproj/UIHistoryCell.strings and b/Classes/LinphoneUI/ru.lproj/UIHistoryCell.strings differ diff --git a/Classes/LinphoneUI/sv.lproj/StatusBarView.strings b/Classes/LinphoneUI/sv.lproj/StatusBarView.strings index 179d2bab3..1a41aa2d6 100644 Binary files a/Classes/LinphoneUI/sv.lproj/StatusBarView.strings and b/Classes/LinphoneUI/sv.lproj/StatusBarView.strings differ diff --git a/Classes/LinphoneUI/sv.lproj/TabBarView.strings b/Classes/LinphoneUI/sv.lproj/TabBarView.strings index 3b36c511c..e99aef7eb 100644 Binary files a/Classes/LinphoneUI/sv.lproj/TabBarView.strings and b/Classes/LinphoneUI/sv.lproj/TabBarView.strings differ diff --git a/Classes/LinphoneUI/sv.lproj/UIChatBubblePhotoCell.strings b/Classes/LinphoneUI/sv.lproj/UIChatBubblePhotoCell.strings index ad7018ccf..843363871 100644 Binary files a/Classes/LinphoneUI/sv.lproj/UIChatBubblePhotoCell.strings and b/Classes/LinphoneUI/sv.lproj/UIChatBubblePhotoCell.strings differ diff --git a/Classes/LinphoneUI/sv.lproj/UIChatBubbleTextCell.strings b/Classes/LinphoneUI/sv.lproj/UIChatBubbleTextCell.strings index ec8f89f30..b9ed74c6c 100644 Binary files a/Classes/LinphoneUI/sv.lproj/UIChatBubbleTextCell.strings and b/Classes/LinphoneUI/sv.lproj/UIChatBubbleTextCell.strings differ diff --git a/Classes/LinphoneUI/sv.lproj/UIChatCell.strings b/Classes/LinphoneUI/sv.lproj/UIChatCell.strings index f09880909..82db68abc 100644 Binary files a/Classes/LinphoneUI/sv.lproj/UIChatCell.strings and b/Classes/LinphoneUI/sv.lproj/UIChatCell.strings differ diff --git a/Classes/LinphoneUI/sv.lproj/UIChatConversationImdnTableViewCell.strings b/Classes/LinphoneUI/sv.lproj/UIChatConversationImdnTableViewCell.strings index 440b65f09..f7c53a65c 100644 Binary files a/Classes/LinphoneUI/sv.lproj/UIChatConversationImdnTableViewCell.strings and b/Classes/LinphoneUI/sv.lproj/UIChatConversationImdnTableViewCell.strings differ diff --git a/Classes/LinphoneUI/sv.lproj/UIChatConversationInfoTableViewCell.strings b/Classes/LinphoneUI/sv.lproj/UIChatConversationInfoTableViewCell.strings index 87a98a0ec..353d704cf 100644 Binary files a/Classes/LinphoneUI/sv.lproj/UIChatConversationInfoTableViewCell.strings and b/Classes/LinphoneUI/sv.lproj/UIChatConversationInfoTableViewCell.strings differ diff --git a/Classes/LinphoneUI/sv.lproj/UIConfirmationDialog.strings b/Classes/LinphoneUI/sv.lproj/UIConfirmationDialog.strings index 2d9b3c980..c9cadb199 100644 Binary files a/Classes/LinphoneUI/sv.lproj/UIConfirmationDialog.strings and b/Classes/LinphoneUI/sv.lproj/UIConfirmationDialog.strings differ diff --git a/Classes/LinphoneUI/sv.lproj/UIContactDetailsCell.strings b/Classes/LinphoneUI/sv.lproj/UIContactDetailsCell.strings index a5de17a75..ffb0281e5 100644 Binary files a/Classes/LinphoneUI/sv.lproj/UIContactDetailsCell.strings and b/Classes/LinphoneUI/sv.lproj/UIContactDetailsCell.strings differ diff --git a/Classes/LinphoneUI/tr.lproj/UIChatBubblePhotoCell.strings b/Classes/LinphoneUI/tr.lproj/UIChatBubblePhotoCell.strings index 953d905df..8e8c7a027 100644 Binary files a/Classes/LinphoneUI/tr.lproj/UIChatBubblePhotoCell.strings and b/Classes/LinphoneUI/tr.lproj/UIChatBubblePhotoCell.strings differ diff --git a/Classes/LinphoneUI/tr.lproj/UIChatBubbleTextCell.strings b/Classes/LinphoneUI/tr.lproj/UIChatBubbleTextCell.strings index 6f4c7ca82..2656fcb8b 100644 Binary files a/Classes/LinphoneUI/tr.lproj/UIChatBubbleTextCell.strings and b/Classes/LinphoneUI/tr.lproj/UIChatBubbleTextCell.strings differ diff --git a/Classes/LinphoneUI/tr.lproj/UIChatCell.strings b/Classes/LinphoneUI/tr.lproj/UIChatCell.strings index 5409b33cf..af350eac6 100644 Binary files a/Classes/LinphoneUI/tr.lproj/UIChatCell.strings and b/Classes/LinphoneUI/tr.lproj/UIChatCell.strings differ diff --git a/Classes/LinphoneUI/tr.lproj/UIConfirmationDialog.strings b/Classes/LinphoneUI/tr.lproj/UIConfirmationDialog.strings index 3a347d04f..f6c25fac5 100644 Binary files a/Classes/LinphoneUI/tr.lproj/UIConfirmationDialog.strings and b/Classes/LinphoneUI/tr.lproj/UIConfirmationDialog.strings differ diff --git a/Classes/LinphoneUI/tr.lproj/UIContactDetailsCell.strings b/Classes/LinphoneUI/tr.lproj/UIContactDetailsCell.strings index 881199c78..880ef5bb8 100644 Binary files a/Classes/LinphoneUI/tr.lproj/UIContactDetailsCell.strings and b/Classes/LinphoneUI/tr.lproj/UIContactDetailsCell.strings differ diff --git a/Classes/LinphoneUI/uk.lproj/StatusBarView.strings b/Classes/LinphoneUI/uk.lproj/StatusBarView.strings new file mode 100644 index 000000000..e1ed7ee4a Binary files /dev/null and b/Classes/LinphoneUI/uk.lproj/StatusBarView.strings differ diff --git a/Classes/LinphoneUI/uk.lproj/TabBarView.strings b/Classes/LinphoneUI/uk.lproj/TabBarView.strings new file mode 100644 index 000000000..24344edb6 Binary files /dev/null and b/Classes/LinphoneUI/uk.lproj/TabBarView.strings differ diff --git a/Classes/LinphoneUI/uk.lproj/UICallConferenceCell.strings b/Classes/LinphoneUI/uk.lproj/UICallConferenceCell.strings new file mode 100644 index 000000000..6711f86e9 Binary files /dev/null and b/Classes/LinphoneUI/uk.lproj/UICallConferenceCell.strings differ diff --git a/Classes/LinphoneUI/uk.lproj/UICallPausedCell.strings b/Classes/LinphoneUI/uk.lproj/UICallPausedCell.strings new file mode 100644 index 000000000..a8ba34de3 Binary files /dev/null and b/Classes/LinphoneUI/uk.lproj/UICallPausedCell.strings differ diff --git a/Classes/LinphoneUI/uk.lproj/UIChatBubblePhotoCell.strings b/Classes/LinphoneUI/uk.lproj/UIChatBubblePhotoCell.strings new file mode 100644 index 000000000..4e0160345 Binary files /dev/null and b/Classes/LinphoneUI/uk.lproj/UIChatBubblePhotoCell.strings differ diff --git a/Classes/LinphoneUI/uk.lproj/UIChatBubbleTextCell.strings b/Classes/LinphoneUI/uk.lproj/UIChatBubbleTextCell.strings new file mode 100644 index 000000000..3a12c6bc1 Binary files /dev/null and b/Classes/LinphoneUI/uk.lproj/UIChatBubbleTextCell.strings differ diff --git a/Classes/LinphoneUI/uk.lproj/UIChatCell.strings b/Classes/LinphoneUI/uk.lproj/UIChatCell.strings new file mode 100644 index 000000000..114a37fbf Binary files /dev/null and b/Classes/LinphoneUI/uk.lproj/UIChatCell.strings differ diff --git a/Classes/LinphoneUI/uk.lproj/UIChatConversationImdnTableViewCell.strings b/Classes/LinphoneUI/uk.lproj/UIChatConversationImdnTableViewCell.strings new file mode 100644 index 000000000..1e53ebcc8 Binary files /dev/null and b/Classes/LinphoneUI/uk.lproj/UIChatConversationImdnTableViewCell.strings differ diff --git a/Classes/LinphoneUI/uk.lproj/UIChatConversationInfoTableViewCell.strings b/Classes/LinphoneUI/uk.lproj/UIChatConversationInfoTableViewCell.strings new file mode 100644 index 000000000..4ca38384f Binary files /dev/null and b/Classes/LinphoneUI/uk.lproj/UIChatConversationInfoTableViewCell.strings differ diff --git a/Classes/LinphoneUI/uk.lproj/UIChatCreateCell.strings b/Classes/LinphoneUI/uk.lproj/UIChatCreateCell.strings new file mode 100644 index 000000000..b9dbbb12e Binary files /dev/null and b/Classes/LinphoneUI/uk.lproj/UIChatCreateCell.strings differ diff --git a/Classes/LinphoneUI/uk.lproj/UIChatCreateCollectionViewCell.strings b/Classes/LinphoneUI/uk.lproj/UIChatCreateCollectionViewCell.strings new file mode 100644 index 000000000..e36ba3f3a Binary files /dev/null and b/Classes/LinphoneUI/uk.lproj/UIChatCreateCollectionViewCell.strings differ diff --git a/Classes/LinphoneUI/uk.lproj/UIConfirmationDialog.strings b/Classes/LinphoneUI/uk.lproj/UIConfirmationDialog.strings new file mode 100644 index 000000000..4bdb418b0 Binary files /dev/null and b/Classes/LinphoneUI/uk.lproj/UIConfirmationDialog.strings differ diff --git a/Classes/LinphoneUI/uk.lproj/UIContactCell.strings b/Classes/LinphoneUI/uk.lproj/UIContactCell.strings new file mode 100644 index 000000000..3736603d7 Binary files /dev/null and b/Classes/LinphoneUI/uk.lproj/UIContactCell.strings differ diff --git a/Classes/LinphoneUI/uk.lproj/UIContactDetailsCell.strings b/Classes/LinphoneUI/uk.lproj/UIContactDetailsCell.strings new file mode 100644 index 000000000..78789cce3 Binary files /dev/null and b/Classes/LinphoneUI/uk.lproj/UIContactDetailsCell.strings differ diff --git a/Classes/LinphoneUI/uk.lproj/UIHistoryCell.strings b/Classes/LinphoneUI/uk.lproj/UIHistoryCell.strings new file mode 100644 index 000000000..66f0d06f1 Binary files /dev/null and b/Classes/LinphoneUI/uk.lproj/UIHistoryCell.strings differ diff --git a/Classes/LinphoneUI/zh_CN.lproj/UIChatBubblePhotoCell.strings b/Classes/LinphoneUI/zh_CN.lproj/UIChatBubblePhotoCell.strings index 8a951e630..bb5fb0545 100644 Binary files a/Classes/LinphoneUI/zh_CN.lproj/UIChatBubblePhotoCell.strings and b/Classes/LinphoneUI/zh_CN.lproj/UIChatBubblePhotoCell.strings differ diff --git a/Classes/LinphoneUI/zh_CN.lproj/UIChatBubbleTextCell.strings b/Classes/LinphoneUI/zh_CN.lproj/UIChatBubbleTextCell.strings index 5bd484735..53a366e62 100644 Binary files a/Classes/LinphoneUI/zh_CN.lproj/UIChatBubbleTextCell.strings and b/Classes/LinphoneUI/zh_CN.lproj/UIChatBubbleTextCell.strings differ diff --git a/Classes/LinphoneUI/zh_CN.lproj/UIChatCell.strings b/Classes/LinphoneUI/zh_CN.lproj/UIChatCell.strings index da88c39e6..9cdd76c8c 100644 Binary files a/Classes/LinphoneUI/zh_CN.lproj/UIChatCell.strings and b/Classes/LinphoneUI/zh_CN.lproj/UIChatCell.strings differ diff --git a/Classes/LinphoneUI/zh_CN.lproj/UIConfirmationDialog.strings b/Classes/LinphoneUI/zh_CN.lproj/UIConfirmationDialog.strings index e3c6c1553..c47145c83 100644 Binary files a/Classes/LinphoneUI/zh_CN.lproj/UIConfirmationDialog.strings and b/Classes/LinphoneUI/zh_CN.lproj/UIConfirmationDialog.strings differ diff --git a/Classes/LinphoneUI/zh_CN.lproj/UIContactDetailsCell.strings b/Classes/LinphoneUI/zh_CN.lproj/UIContactDetailsCell.strings index 154f2b973..3c2f1562a 100644 Binary files a/Classes/LinphoneUI/zh_CN.lproj/UIContactDetailsCell.strings and b/Classes/LinphoneUI/zh_CN.lproj/UIContactDetailsCell.strings differ diff --git a/Classes/LinphoneUI/zh_TW.lproj/UIChatBubblePhotoCell.strings b/Classes/LinphoneUI/zh_TW.lproj/UIChatBubblePhotoCell.strings index 266f5a054..bfa6fe56e 100644 Binary files a/Classes/LinphoneUI/zh_TW.lproj/UIChatBubblePhotoCell.strings and b/Classes/LinphoneUI/zh_TW.lproj/UIChatBubblePhotoCell.strings differ diff --git a/Classes/LinphoneUI/zh_TW.lproj/UIChatBubbleTextCell.strings b/Classes/LinphoneUI/zh_TW.lproj/UIChatBubbleTextCell.strings index ea6cb8ed6..5e0ec4c7f 100644 Binary files a/Classes/LinphoneUI/zh_TW.lproj/UIChatBubbleTextCell.strings and b/Classes/LinphoneUI/zh_TW.lproj/UIChatBubbleTextCell.strings differ diff --git a/Classes/LinphoneUI/zh_TW.lproj/UIChatCell.strings b/Classes/LinphoneUI/zh_TW.lproj/UIChatCell.strings index 07fc5394b..8a2c9920f 100644 Binary files a/Classes/LinphoneUI/zh_TW.lproj/UIChatCell.strings and b/Classes/LinphoneUI/zh_TW.lproj/UIChatCell.strings differ diff --git a/Classes/LinphoneUI/zh_TW.lproj/UIConfirmationDialog.strings b/Classes/LinphoneUI/zh_TW.lproj/UIConfirmationDialog.strings index c4727cc63..17adc01a8 100644 Binary files a/Classes/LinphoneUI/zh_TW.lproj/UIConfirmationDialog.strings and b/Classes/LinphoneUI/zh_TW.lproj/UIConfirmationDialog.strings differ diff --git a/Classes/LinphoneUI/zh_TW.lproj/UIContactDetailsCell.strings b/Classes/LinphoneUI/zh_TW.lproj/UIContactDetailsCell.strings index 32e2a298f..2eb4675c3 100644 Binary files a/Classes/LinphoneUI/zh_TW.lproj/UIContactDetailsCell.strings and b/Classes/LinphoneUI/zh_TW.lproj/UIContactDetailsCell.strings differ diff --git a/Classes/PhoneMainView.h b/Classes/PhoneMainView.h index 710aaa97b..c64ab398a 100644 --- a/Classes/PhoneMainView.h +++ b/Classes/PhoneMainView.h @@ -18,6 +18,7 @@ */ #import +#import /* These imports are here so that we can import PhoneMainView.h without bothering to import all the rest of the view headers */ #import "StatusBarView.h" @@ -44,6 +45,7 @@ #import "HistoryDetailsView.h" #import "HistoryListView.h" #import "ImageView.h" +#import "RecordingsListView.h" #import "SettingsView.h" #import "SideMenuView.h" #import "UIConfirmationDialog.h" @@ -74,7 +76,7 @@ @end -@interface PhoneMainView : UIViewController { +@interface PhoneMainView : UIViewController { @private NSMutableArray *inhibitedEvents; } @@ -104,13 +106,14 @@ - (void)startUp; - (void)displayIncomingCall:(LinphoneCall*) call; - (void)setVolumeHidden:(BOOL)hidden; +- (void)messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult)result; - (void)addInhibitedEvent:(id)event; - (BOOL)removeInhibitedEvent:(id)event; - (void)updateApplicationBadgeNumber; -- (void)getOrCreateOneToOneChatRoom:(const LinphoneAddress *)remoteAddress waitView:(UIView *)waitView; -- (void)createChatRoomWithSubject:(const char *)subject addresses:(bctbx_list_t *)addresses andWaitView:(UIView *)waitView; +- (void)getOrCreateOneToOneChatRoom:(const LinphoneAddress *)remoteAddress waitView:(UIView *)waitView isEncrypted:(BOOL)isEncrypted; +- (LinphoneChatRoom *)createChatRoom:(const char *)subject addresses:(bctbx_list_t *)addresses andWaitView:(UIView *)waitView isEncrypted:(BOOL)isEncrypted isGroup:(BOOL)isGroup; - (void)goToChatRoom:(LinphoneChatRoom *)cr; + (PhoneMainView*) instance; diff --git a/Classes/PhoneMainView.m b/Classes/PhoneMainView.m index 619757655..e03787da7 100644 --- a/Classes/PhoneMainView.m +++ b/Classes/PhoneMainView.m @@ -319,7 +319,7 @@ static RootViewManager *rootViewManagerInstance = nil; LinphoneRegistrationState state = [[notif.userInfo objectForKey:@"state"] intValue]; if (state == LinphoneRegistrationFailed && ![currentView equal:AssistantView.compositeViewDescription] && [UIApplication sharedApplication].applicationState == UIApplicationStateActive) { - UIAlertController *errView = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Registration failure", nil) + UIAlertController *errView = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Connection failure", nil) message:[notif.userInfo objectForKey:@"message"] preferredStyle:UIAlertControllerStyleAlert]; @@ -329,7 +329,11 @@ static RootViewManager *rootViewManagerInstance = nil; [errView addAction:defaultAction]; [self presentViewController:errView animated:YES completion:nil]; - } + } else if (state == LinphoneRegistrationOk && [currentView equal:ChatsListView.compositeViewDescription]) { + // update avatarImages + //ChatsListView *view = VIEW(ChatsListView); + //[view.tableController loadData]; + } } - (void)onGlobalStateChanged:(NSNotification *)notif { @@ -421,19 +425,13 @@ static RootViewManager *rootViewManagerInstance = nil; } else { linphone_call_resume((LinphoneCall *)calls->data); while (calls) { - if ( - linphone_call_get_state((LinphoneCall *)calls->data) == LinphoneCallIncomingReceived || - linphone_call_get_state((LinphoneCall *)calls->data) == LinphoneCallIncomingEarlyMedia - ) { - [self displayIncomingCall:(LinphoneCall *)calls->data]; - break; - } else if (linphone_call_get_state((LinphoneCall *)calls->data) == LinphoneCallOutgoingRinging) { - [self changeCurrentView:CallOutgoingView.compositeViewDescription]; - break; - } + if (calls->next) { + [self changeCurrentView:CallView.compositeViewDescription]; + break; + } calls = calls->next; } - if (!calls) { + if (calls == NULL) { [self changeCurrentView:CallView.compositeViewDescription]; } } @@ -762,7 +760,7 @@ static RootViewManager *rootViewManagerInstance = nil; switch (linphone_call_get_reason(call)) { case LinphoneReasonNotFound: - lMessage = [NSString stringWithFormat:NSLocalizedString(@"%@ is not registered.", nil), lUserName]; + lMessage = [NSString stringWithFormat:NSLocalizedString(@"%@ is not connected.", nil), lUserName]; break; case LinphoneReasonBusy: lMessage = [NSString stringWithFormat:NSLocalizedString(@"%@ is busy.", nil), lUserName]; @@ -874,17 +872,22 @@ static RootViewManager *rootViewManagerInstance = nil; #pragma mark - Chat room Functions -- (void)getOrCreateOneToOneChatRoom:(const LinphoneAddress *)remoteAddress waitView:(UIView *)waitView { +- (void)getOrCreateOneToOneChatRoom:(const LinphoneAddress *)remoteAddress waitView:(UIView *)waitView isEncrypted:(BOOL)isEncrypted{ if (!remoteAddress) { [self changeCurrentView:ChatsListView.compositeViewDescription]; return; } - + + if (!linphone_core_is_network_reachable(LC)) { + [PhoneMainView.instance presentViewController:[LinphoneUtils networkErrorView] animated:YES completion:nil]; + return; + } + const LinphoneAddress *local = linphone_proxy_config_get_contact(linphone_core_get_default_proxy_config(LC)); - LinphoneChatRoom *room = linphone_core_find_one_to_one_chat_room(LC, local, remoteAddress); + LinphoneChatRoom *room = linphone_core_find_one_to_one_chat_room_2(LC, local, remoteAddress, isEncrypted); if (!room) { bctbx_list_t *addresses = bctbx_list_new((void*)remoteAddress); - [self createChatRoomWithSubject:LINPHONE_DUMMY_SUBJECT addresses:addresses andWaitView:waitView]; + [self createChatRoom:LINPHONE_DUMMY_SUBJECT addresses:addresses andWaitView:waitView isEncrypted:isEncrypted isGroup:FALSE]; bctbx_list_free(addresses); return; } @@ -892,42 +895,48 @@ static RootViewManager *rootViewManagerInstance = nil; [self goToChatRoom:room]; } -- (void)createChatRoomWithSubject:(const char *)subject addresses:(bctbx_list_t *)addresses andWaitView:(UIView *)waitView { - if (!linphone_proxy_config_get_conference_factory_uri(linphone_core_get_default_proxy_config(LC)) - || ([[LinphoneManager instance] lpConfigBoolForKey:@"prefer_basic_chat_room" inSection:@"misc"] && bctbx_list_size(addresses) == 1)) { - // If there's no factory uri, create a basic chat room - if (bctbx_list_size(addresses) != 1) { - // Display Error: unsuported group chat - UIAlertController *errView = - [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Conversation creation error", nil) - message:NSLocalizedString(@"Group conversation is not supported.", nil) - preferredStyle:UIAlertControllerStyleAlert]; - - UIAlertAction *defaultAction = [UIAlertAction actionWithTitle:@"OK" - style:UIAlertActionStyleDefault - handler:^(UIAlertAction *action) {}]; - [errView addAction:defaultAction]; - [self presentViewController:errView animated:YES completion:nil]; - return; - } - LinphoneChatRoom *basicRoom = linphone_core_get_chat_room(LC, addresses->data); - [self goToChatRoom:basicRoom]; - return; - } - - _waitView = waitView; - _waitView.hidden = NO; - LinphoneChatRoom *room = linphone_core_create_client_group_chat_room(LC, subject ?: LINPHONE_DUMMY_SUBJECT, bctbx_list_size(addresses) == 1); - if (!room) { - _waitView.hidden = YES; - return; - } - - LinphoneChatRoomCbs *cbs = linphone_factory_create_chat_room_cbs(linphone_factory_get()); - linphone_chat_room_cbs_set_state_changed(cbs, main_view_chat_room_state_changed); - linphone_chat_room_add_callbacks(room, cbs); - - linphone_chat_room_add_participants(room, addresses); +- (LinphoneChatRoom *)createChatRoom:(const char *)subject addresses:(bctbx_list_t *)addresses andWaitView:(UIView *)waitView isEncrypted:(BOOL)isEncrypted isGroup:(BOOL)isGroup{ + if (!linphone_proxy_config_get_conference_factory_uri(linphone_core_get_default_proxy_config(LC)) + || ((bctbx_list_size(addresses) == 1) && !isGroup && ([[LinphoneManager instance] lpConfigBoolForKey:@"prefer_basic_chat_room" inSection:@"misc"] || !isEncrypted))) { + // If there's no factory uri, create a basic chat room + if (bctbx_list_size(addresses) != 1) { + // Display Error: unsuported group chat + UIAlertController *errView = + [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Conversation creation error", nil) + message:NSLocalizedString(@"Group conversation is not supported.", nil) + preferredStyle:UIAlertControllerStyleAlert]; + + UIAlertAction *defaultAction = [UIAlertAction actionWithTitle:@"OK" + style:UIAlertActionStyleDefault + handler:^(UIAlertAction *action) {}]; + [errView addAction:defaultAction]; + [self presentViewController:errView animated:YES completion:nil]; + return nil; + } + LinphoneChatRoom *basicRoom = linphone_core_create_chat_room_5(LC, addresses->data); + [self goToChatRoom:basicRoom]; + return nil; + } + + _waitView = waitView; + _waitView.hidden = NO; + // always use group chatroom + LinphoneChatRoomParams *param = linphone_core_create_default_chat_room_params(LC); + linphone_chat_room_params_enable_group(param, isGroup); + linphone_chat_room_params_enable_encryption(param, isEncrypted); + + LinphoneChatRoom *room = linphone_core_create_chat_room_2(LC, param, subject ?: LINPHONE_DUMMY_SUBJECT, addresses); + + if (!room) { + _waitView.hidden = YES; + return nil; + } + + LinphoneChatRoomCbs *cbs = linphone_factory_create_chat_room_cbs(linphone_factory_get()); + linphone_chat_room_cbs_set_state_changed(cbs, main_view_chat_room_state_changed); + linphone_chat_room_add_callbacks(room, cbs); + + return room; } - (void)goToChatRoom:(LinphoneChatRoom *)cr { @@ -981,4 +990,10 @@ void main_view_chat_room_state_changed(LinphoneChatRoom *cr, LinphoneChatRoomSta } } +#pragma mark - SMS invite callback + +- (void)messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult)result { + [controller dismissModalViewControllerAnimated:YES]; +} + @end diff --git a/Classes/ProviderDelegate.m b/Classes/ProviderDelegate.m index 96770e696..63f544fc7 100644 --- a/Classes/ProviderDelegate.m +++ b/Classes/ProviderDelegate.m @@ -59,6 +59,17 @@ LOGE(@"Unable to change audio session because: %@", err.localizedDescription); err = nil; } + [audioSession setMode:AVAudioSessionModeVoiceChat error:&err]; + if (err) { + LOGE(@"Unable to change audio mode because : %@", err.localizedDescription); + err = nil; + } + double sampleRate = 48000.0; + [audioSession setPreferredSampleRate:sampleRate error:&err]; + if (err) { + LOGE(@"Unable to change preferred sample rate because : %@", err.localizedDescription); + err = nil; + } } - (void)reportIncomingCall:(LinphoneCall *) call withUUID:(NSUUID *)uuid handle:(NSString *)handle video:(BOOL)video; { @@ -91,7 +102,10 @@ - (void)setPendingCall:(LinphoneCall *)pendingCall { if (pendingCall) { _pendingCall = pendingCall; + if (_pendingCall) + linphone_call_ref(_pendingCall); } else if (_pendingCall) { + linphone_call_unref(_pendingCall); _pendingCall = NULL; } } @@ -109,7 +123,7 @@ return; self.callKitCalls++; - _pendingCall = call; + self.pendingCall = call; } - (void)provider:(CXProvider *)provider performStartCallAction:(CXStartCallAction *)action { @@ -126,6 +140,7 @@ call = [LinphoneManager.instance callByCallId:callID]; } if (call != NULL) { + self.callKitCalls++; self.pendingCall = call; } } @@ -240,7 +255,7 @@ } } - self.pendingCall = NULL; + [self setPendingCall:NULL]; if (_pendingAddr) linphone_address_unref(_pendingAddr); _pendingAddr = NULL; @@ -248,9 +263,8 @@ } - (void)provider:(CXProvider *)provider didDeactivateAudioSession:(nonnull AVAudioSession *)audioSession { - LOGD(@"CallKit: Audio session deactivated"); - - self.pendingCall = NULL; + LOGD(@"CallKit : Audio session deactivated"); + [self setPendingCall:NULL]; if (_pendingAddr) linphone_address_unref(_pendingAddr); _pendingAddr = NULL; diff --git a/Classes/RecordingsListTableView.h b/Classes/RecordingsListTableView.h new file mode 100644 index 000000000..97b672d11 --- /dev/null +++ b/Classes/RecordingsListTableView.h @@ -0,0 +1,23 @@ +// +// RecordingsListTableView.h +// linphone +// +// Created by benjamin_verdier on 25/07/2018. +// + +#import + +#import "UICheckBoxTableView.h" + +@interface RecordingsListTableView : UICheckBoxTableView { +@private + NSMutableDictionary *recordings; + //This has sub arrays indexed with the date of the recordings, themselves containings the recordings. + NSString *writablePath; + //This is the path to the folder where we write the recordings to. We should probably define it in LinphoneManager though. +} +- (void)loadData; +- (void)removeAllRecordings; +- (void)setSelected:(NSString *)filepath; + +@end diff --git a/Classes/RecordingsListTableView.m b/Classes/RecordingsListTableView.m new file mode 100644 index 000000000..52b4f2ab4 --- /dev/null +++ b/Classes/RecordingsListTableView.m @@ -0,0 +1,249 @@ +// +// RecordingsListTableView.m +// linphone +// +// Created by benjamin_verdier on 25/07/2018. +// + +#import "RecordingsListTableView.h" +#import "UIRecordingCell.h" +#import "LinphoneManager.h" +#import "PhoneMainView.h" +#import "Utils.h" + +@implementation RecordingsListTableView + +#pragma mark - Lifecycle Functions + +- (void)initRecordingsTableViewController { + recordings = [NSMutableDictionary dictionary]; + NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES); + writablePath = [paths objectAtIndex:0]; + writablePath = [writablePath stringByAppendingString:@"/"]; +} + +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; + if (![self selectFirstRow]) { + //TODO: Make first cell expand to show player + } + [self loadData]; +} + +- (id)init { + self = [super init]; + if (self) { + [self initRecordingsTableViewController]; + } + return self; +} + +- (id)initWithCoder:(NSCoder *)decoder { + self = [super initWithCoder:decoder]; + if (self) { + [self initRecordingsTableViewController]; + } + return self; +} + +- (void)dealloc { + [[NSNotificationCenter defaultCenter] removeObserver:self]; + [self removeAllRecordings]; +} + +- (void)removeAllRecordings { + for (NSInteger j = 0; j < [self.tableView numberOfSections]; ++j) { + for (NSInteger i = 0; i < [self.tableView numberOfRowsInSection:j]; ++i) { + [[self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:i inSection:j]] setRecording:nil]; + } + } +} + + +- (void)loadData { + LOGI(@"====>>>> Load recording list - Start"); + + recordings = [NSMutableDictionary dictionary]; + NSArray *directoryContent = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:writablePath error:NULL]; + for (NSString *file in directoryContent) { + if (![file hasPrefix:@"recording_"]) { + continue; + } + NSArray *parsedName = [LinphoneUtils parseRecordingName:file]; + NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init]; + [dateFormat setDateFormat:@"EEEE, MMM d, yyyy"]; + NSString *dayPretty = [dateFormat stringFromDate:[parsedName objectAtIndex:1]]; + NSMutableArray *recOfDay = [recordings objectForKey:dayPretty]; + if (recOfDay) { + // Loop through the object until a later object, then insert it right before + int i; + for (i = 0; i < [recOfDay count]; ++i) { + NSString *fileAtIndex = [recOfDay objectAtIndex:i]; + NSArray *parsedNameAtIndex = [LinphoneUtils parseRecordingName:fileAtIndex]; + if ([[parsedName objectAtIndex:1] compare:[parsedNameAtIndex objectAtIndex:1]] == NSOrderedDescending) { + break; + } + } + [recOfDay insertObject:[writablePath stringByAppendingString:file] atIndex:i]; + } else { + recOfDay = [NSMutableArray arrayWithObjects:[writablePath stringByAppendingString:file], nil]; + [recordings setObject:recOfDay forKey:dayPretty]; + } + } + + + LOGI(@"====>>>> Load recording list - End"); + [super loadData]; +} + +- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { + NSIndexPath *selectedRow = [self.tableView indexPathForSelectedRow]; + if (selectedRow && [selectedRow compare:indexPath] == NSOrderedSame) { + return 150; + } else { + return 40; + } +} + +#pragma mark - UITableViewDataSource Functions + +- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView { + return nil; +} + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { + return [recordings count]; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { + NSArray *sortedKey = [self getSortedKeys]; + return [(NSArray *)[recordings objectForKey:[sortedKey objectAtIndex:section]] count]; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { + NSString *kCellId = NSStringFromClass(UIRecordingCell.class); + UIRecordingCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellId]; + if (cell == nil) { + cell = [[UIRecordingCell alloc] initWithIdentifier:kCellId]; + } + NSString *date = [[self getSortedKeys] objectAtIndex:[indexPath section]]; + NSMutableArray *subAr = [recordings objectForKey:date]; + NSString *recordingPath = subAr[indexPath.row]; + [cell setRecording:recordingPath]; + [super accessoryForCell:cell atPath:indexPath]; + //accessoryForCell set it to gray but we don't want it + cell.selectionStyle = UITableViewCellSelectionStyleNone; + [cell updateFrame]; + return cell; +} + +- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section { + CGRect frame = CGRectMake(0, 0, tableView.frame.size.width, tableView.sectionHeaderHeight); + UIView *tempView = [[UIView alloc] initWithFrame:frame]; + tempView.backgroundColor = [UIColor whiteColor]; + + UILabel *tempLabel = [[UILabel alloc] initWithFrame:frame]; + tempLabel.backgroundColor = [UIColor clearColor]; + tempLabel.textColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"color_A.png"]]; + tempLabel.text = [[self getSortedKeys] objectAtIndex:section]; + tempLabel.textAlignment = NSTextAlignmentCenter; + tempLabel.font = [UIFont boldSystemFontOfSize:17]; + tempLabel.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin; + [tempView addSubview:tempLabel]; + + return tempView; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { + [super tableView:tableView didSelectRowAtIndexPath:indexPath]; + if (![self isEditing]) { + [tableView beginUpdates]; + [(UIRecordingCell *)[self tableView:tableView cellForRowAtIndexPath:indexPath] updateFrame]; + [tableView endUpdates]; + } +} + +- (void)tableView:(UITableView *)tableView +commitEditingStyle:(UITableViewCellEditingStyle)editingStyle +forRowAtIndexPath:(NSIndexPath *)indexPath { + if (editingStyle == UITableViewCellEditingStyleDelete) { + [NSNotificationCenter.defaultCenter removeObserver:self]; + [tableView beginUpdates]; + + + NSString *date = [[self getSortedKeys] objectAtIndex:[indexPath section]]; + NSMutableArray *subAr = [recordings objectForKey:date]; + NSString *recordingPath = subAr[indexPath.row]; + [subAr removeObjectAtIndex:indexPath.row]; + if (subAr.count == 0) { + [recordings removeObjectForKey:date]; + [tableView deleteSections:[NSIndexSet indexSetWithIndex:indexPath.section] + withRowAnimation:UITableViewRowAnimationFade]; + } + + UIRecordingCell* cell = [self.tableView cellForRowAtIndexPath:indexPath]; + [cell setRecording:NULL]; + + remove([recordingPath cStringUsingEncoding:NSUTF8StringEncoding]); + + [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; + [tableView endUpdates]; + + [self loadData]; + } +} + +- (void)removeSelectionUsing:(void (^)(NSIndexPath *))remover { + [super removeSelectionUsing:^(NSIndexPath *indexPath) { + [NSNotificationCenter.defaultCenter removeObserver:self]; + + NSString *date = [[self getSortedKeys] objectAtIndex:[indexPath section]]; + NSMutableArray *subAr = [recordings objectForKey:date]; + NSString *recordingPath = subAr[indexPath.row]; + [subAr removeObjectAtIndex:indexPath.row]; + if (subAr.count == 0) { + [recordings removeObjectForKey:date]; + } + UIRecordingCell* cell = [self.tableView cellForRowAtIndexPath:indexPath]; + [cell setRecording:NULL]; + remove([recordingPath cStringUsingEncoding:NSUTF8StringEncoding]); + }]; +} + +- (void)setSelected:(NSString *)filepath { + NSArray *parsedName = [LinphoneUtils parseRecordingName:filepath]; + NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init]; + [dateFormat setDateFormat:@"EEEE, MMM d, yyyy"]; + NSString *dayPretty = [dateFormat stringFromDate:[parsedName objectAtIndex:1]]; + NSUInteger section; + NSArray *keys = [recordings allKeys]; + for (section = 0; section < [keys count]; ++section) { + if ([dayPretty isEqualToString:(NSString *)[keys objectAtIndex:section]]) { + break; + } + } + NSUInteger row; + NSArray *recs = [recordings objectForKey:dayPretty]; + for (row = 0; row < [recs count]; ++row) { + if ([filepath isEqualToString:(NSString *)[recs objectAtIndex:row]]) { + break; + } + } + NSUInteger indexes[] = {section, row}; + [self.tableView selectRowAtIndexPath:[NSIndexPath indexPathWithIndexes:indexes length:2] animated:TRUE scrollPosition:UITableViewScrollPositionNone]; +} + +#pragma mark - Utilities + +- (NSArray *)getSortedKeys { + return [[recordings allKeys] sortedArrayUsingComparator:^NSComparisonResult(NSString *day2, NSString *day1){ + NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init]; + [dateFormat setDateFormat:@"EEEE, MMM d, yyyy"]; + NSDate *date1 = [dateFormat dateFromString:day1]; + NSDate *date2 = [dateFormat dateFromString:day2]; + return [date1 compare:date2]; + }]; +} + + +@end diff --git a/Classes/RecordingsListView.h b/Classes/RecordingsListView.h new file mode 100644 index 000000000..8d93e67c3 --- /dev/null +++ b/Classes/RecordingsListView.h @@ -0,0 +1,35 @@ +// +// RecordingsListView.h +// linphone +// +// Created by benjamin_verdier on 25/07/2018. +// + +#import + +#import "UICompositeView.h" +#import "RecordingsListTableView.h" +#import "UIIconButton.h" + +typedef enum _RecordingSelectionMode { RecordingSelectionModeNone, RecordingSelectionModeEdit } RecordingSelectionMode; + +@interface RecordingSelection : NSObject { +} + ++ (void)setSelectionMode:(RecordingSelectionMode)selectionMode; ++ (RecordingSelectionMode)getSelectionMode; + +@end + +@interface RecordingsListView : UIViewController + +@property(strong, nonatomic) IBOutlet RecordingsListTableView *tableController; +@property(strong, nonatomic) IBOutlet UIView *topBar; +@property(weak, nonatomic) IBOutlet UIIconButton *deleteButton; +@property (strong, nonatomic) IBOutlet UIIconButton *backButton; + +- (IBAction)onDeleteClick:(id)sender; +- (IBAction)onEditionChangeClick:(id)sender; +- (IBAction)onBackPressed:(id)sender; + +@end diff --git a/Classes/RecordingsListView.m b/Classes/RecordingsListView.m new file mode 100644 index 000000000..dc5abd220 --- /dev/null +++ b/Classes/RecordingsListView.m @@ -0,0 +1,101 @@ +// +// RecordingsListView.m +// linphone +// +// Created by benjamin_verdier on 25/07/2018. +// + +#import "RecordingsListView.h" +#import "PhoneMainView.h" + +@implementation RecordingSelection + +static RecordingSelectionMode sSelectionMode = RecordingSelectionModeNone; + ++ (void)setSelectionMode:(RecordingSelectionMode)selectionMode { + sSelectionMode = selectionMode; +} + ++ (RecordingSelectionMode)getSelectionMode { + return sSelectionMode; +} + +@end + +@implementation RecordingsListView + +@synthesize tableController; +@synthesize topBar; + +#pragma mark - UICompositeViewDelegate Functions + +static UICompositeViewDescription *compositeDescription = nil; + ++ (UICompositeViewDescription *)compositeViewDescription { + if (compositeDescription == nil) { + compositeDescription = [[UICompositeViewDescription alloc] init:self.class + statusBar:StatusBarView.class + tabBar:TabBarView.class + sideMenu:SideMenuView.class + fullscreen:false + isLeftFragment:YES + fragmentWith:ContactDetailsView.class]; + } + return compositeDescription; +} + +- (UICompositeViewDescription *)compositeViewDescription { + return self.class.compositeViewDescription; +} + +#pragma mark - ViewController Functions + +- (void)viewDidLoad { + [super viewDidLoad]; + tableController.tableView.accessibilityIdentifier = @"Recordings table"; + tableController.tableView.tableFooterView = [[UIView alloc] init]; +} + +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; + if (tableController.isEditing) { + tableController.editing = NO; + } +} + +- (void)viewDidAppear:(BOOL)animated { + [super viewDidAppear:animated]; +} + +- (void) viewWillDisappear:(BOOL)animated { + self.view = NULL; + [self.tableController removeAllRecordings]; +} + +#pragma mark - Action Functions + +- (IBAction)onDeleteClick:(id)sender { + NSString *msg = [NSString stringWithFormat:NSLocalizedString(@"Do you want to delete selected recordings?", nil)]; + [LinphoneManager.instance setContactsUpdated:TRUE]; + [UIConfirmationDialog ShowWithMessage:msg + cancelMessage:nil + confirmMessage:nil + onCancelClick:^() { + [self onEditionChangeClick:nil]; + } + onConfirmationClick:^() { + [tableController removeSelectionUsing:nil]; + [tableController loadData]; + [self onEditionChangeClick:nil]; + }]; +} + +- (IBAction)onEditionChangeClick:(id)sender { + _backButton.hidden = self.tableController.isEditing; +} + +- (IBAction)onBackPressed:(id)sender { + [PhoneMainView.instance popCurrentView]; +} + +@end diff --git a/Classes/RecordingsListView.xib b/Classes/RecordingsListView.xib new file mode 100644 index 000000000..a66db6357 --- /dev/null +++ b/Classes/RecordingsListView.xib @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Classes/SettingsView.h b/Classes/SettingsView.h index 5fb0e72ce..ce43ef5f5 100644 --- a/Classes/SettingsView.h +++ b/Classes/SettingsView.h @@ -27,6 +27,7 @@ : UIViewController { @private LinphoneCoreSettingsStore *settingsStore; + BOOL isRoot; } @property(nonatomic, strong) IBOutlet UINavigationController *navigationController; diff --git a/Classes/SettingsView.m b/Classes/SettingsView.m index 94d87f908..7875f6063 100644 --- a/Classes/SettingsView.m +++ b/Classes/SettingsView.m @@ -35,8 +35,8 @@ #ifdef DEBUG @interface UIDevice (debug) -- (void)_setBatteryLevel:(float)level; -- (void)_setBatteryState:(int)state; +- (void)setBatteryLevel:(float)level; +- (void)setBatteryState:(int)state; @end #endif @@ -506,7 +506,13 @@ void update_hash_cbs(LinphoneAccountCreator *creator, LinphoneAccountCreatorStat removeFromHiddenKeys = [video_preset isEqualToString:@"custom"]; [keys addObject:@"video_preferred_fps_preference"]; [keys addObject:@"download_bandwidth_preference"]; - } + } else if ([@"auto_download_mode" compare:notif.object] == NSOrderedSame) { + NSString *download_mode = [notif.userInfo objectForKey:@"auto_download_mode"]; + removeFromHiddenKeys = [download_mode isEqualToString:@"Customize"]; + if (removeFromHiddenKeys) + [LinphoneManager.instance lpConfigSetInt:10000000 forKey:@"auto_download_incoming_files_max_size"]; + [keys addObject:@"auto_download_incoming_files_max_size"]; + } for (NSString *key in keys) { if (removeFromHiddenKeys) @@ -701,6 +707,14 @@ void update_hash_cbs(LinphoneAccountCreator *creator, LinphoneAccountCreatorStat if ([[UIDevice currentDevice].systemVersion floatValue] < 8) { [hiddenKeys addObject:@"repeat_call_notification_preference"]; } + + if (![lm lpConfigBoolForKey:@"accept_early_media" inSection:@"app"]) { + [hiddenKeys addObject:@"pref_accept_early_media_preference"]; + } + + if (![[lm lpConfigStringForKey:@"auto_download_mode"] isEqualToString:@"Customize"]) { + [hiddenKeys addObject:@"auto_download_incoming_files_max_size"]; + } return hiddenKeys; } @@ -722,7 +736,7 @@ void update_hash_cbs(LinphoneAccountCreator *creator, LinphoneAccountCreatorStat } - (void)settingsViewControllerWillAppear:(IASKAppSettingsViewController *)sender { - _backButton.hidden = (sender.file == nil || [sender.file isEqualToString:@"Root"]); + isRoot = (sender.file == nil || [sender.file isEqualToString:@"Root"]); _titleLabel.text = sender.title; // going to account: fill account specific info @@ -749,8 +763,8 @@ void update_hash_cbs(LinphoneAccountCreator *creator, LinphoneAccountCreatorStat [PhoneMainView.instance.mainViewController clearCache:[NSArray arrayWithObject:[PhoneMainView.instance currentView]]]; } else if ([key isEqual:@"battery_alert_button"]) { - [[UIDevice currentDevice] _setBatteryState:UIDeviceBatteryStateUnplugged]; - [[UIDevice currentDevice] _setBatteryLevel:0.01f]; + [[UIDevice currentDevice] setBatteryState:UIDeviceBatteryStateUnplugged]; + [[UIDevice currentDevice] setBatteryLevel:0.01f]; [NSNotificationCenter.defaultCenter postNotificationName:UIDeviceBatteryLevelDidChangeNotification object:self]; } else if ([key isEqual:@"flush_images_button"]) { const MSList *rooms = linphone_core_get_chat_rooms(LC); @@ -987,11 +1001,11 @@ void update_hash_cbs(LinphoneAccountCreator *creator, LinphoneAccountCreatorStat if ([LinphoneManager.instance lpConfigBoolForKey:@"send_logs_include_linphonerc_and_chathistory"]) { // retrieve linphone rc [attachments - addObject:@[ [LinphoneManager documentFile:@"linphonerc"], @"text/plain", @"linphone-configuration.rc" ]]; + addObject:@[ [LinphoneManager preferenceFile:@"linphonerc"], @"text/plain", @"linphone-configuration.rc" ]]; // retrieve historydb [attachments addObject:@[ - [LinphoneManager documentFile:@"linphone_chats.db"], + [LinphoneManager dataFile:@"linphone_chats.db"], @"application/x-sqlite3", @"linphone-chats-history.db" ]]; @@ -1079,6 +1093,11 @@ void update_hash_cbs(LinphoneAccountCreator *creator, LinphoneAccountCreatorStat } - (IBAction)onBackClick:(id)sender { - [_settingsController.navigationController popViewControllerAnimated:YES]; + if (isRoot) { + [_settingsController.navigationController popViewControllerAnimated:NO]; + [PhoneMainView.instance popCurrentView]; + } else { + [_settingsController.navigationController popViewControllerAnimated:YES]; + } } @end diff --git a/Classes/SideMenuTableView.h b/Classes/SideMenuTableView.h index 6884e6b1c..779b7d6d1 100644 --- a/Classes/SideMenuTableView.h +++ b/Classes/SideMenuTableView.h @@ -13,6 +13,7 @@ typedef void (^SideMenuEntryBlock)(void); @interface SideMenuEntry : NSObject { @public + UIImage *img; NSString *title; SideMenuEntryBlock onTapBlock; }; diff --git a/Classes/SideMenuTableView.m b/Classes/SideMenuTableView.m index 223908d4e..f7b149dd7 100644 --- a/Classes/SideMenuTableView.m +++ b/Classes/SideMenuTableView.m @@ -15,11 +15,13 @@ #import "StatusBarView.h" #import "ShopView.h" #import "LinphoneManager.h" +#import "RecordingsListView.h" @implementation SideMenuEntry -- (id)initWithTitle:(NSString *)atitle tapBlock:(SideMenuEntryBlock)tapBlock { +- (id)initWithTitle:(NSString *)atitle image:(UIImage *)image tapBlock:(SideMenuEntryBlock)tapBlock { if ((self = [super init])) { + img = image; title = atitle; onTapBlock = tapBlock; } @@ -46,6 +48,7 @@ [_sideMenuEntries addObject:[[SideMenuEntry alloc] initWithTitle:NSLocalizedString(@"Assistant", nil) + image:[UIImage imageNamed:@"menu_assistant.png"] tapBlock:^() { [PhoneMainView.instance changeCurrentView:AssistantView.compositeViewDescription]; @@ -54,28 +57,40 @@ if (mustLink) { [_sideMenuEntries addObject:[[SideMenuEntry alloc] initWithTitle:NSLocalizedString(@"Link my account", nil) + image:[UIImage imageNamed:@"menu_link_account.png"] tapBlock:^() { [PhoneMainView.instance changeCurrentView:AssistantLinkView.compositeViewDescription]; }]]; } + [_sideMenuEntries addObject:[[SideMenuEntry alloc] initWithTitle:NSLocalizedString(@"Settings", nil) + image:[UIImage imageNamed:@"menu_options.png"] tapBlock:^() { [PhoneMainView.instance changeCurrentView:SettingsView.compositeViewDescription]; }]]; + [_sideMenuEntries + addObject:[[SideMenuEntry alloc] initWithTitle:NSLocalizedString(@"Recordings", nil) + image:[UIImage imageNamed:@"menu_recordings.png"] + tapBlock:^() { + [PhoneMainView.instance + changeCurrentView:RecordingsListView.compositeViewDescription]; + }]]; InAppProductsManager *iapm = LinphoneManager.instance.iapManager; if (iapm.enabled){ [_sideMenuEntries addObject:[[SideMenuEntry alloc] initWithTitle:NSLocalizedString(@"Shop", nil) + image:nil tapBlock:^() { [PhoneMainView.instance changeCurrentView:ShopView.compositeViewDescription]; }]]; } [_sideMenuEntries addObject:[[SideMenuEntry alloc] initWithTitle:NSLocalizedString(@"About", nil) + image:[UIImage imageNamed:@"menu_about.png"] tapBlock:^() { [PhoneMainView.instance changeCurrentView:AboutView.compositeViewDescription]; @@ -121,6 +136,7 @@ cell.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"color_G.png"]]; } else { SideMenuEntry *entry = [_sideMenuEntries objectAtIndex:indexPath.row]; + cell.imageView.image = entry->img; cell.textLabel.text = entry->title; } return cell; diff --git a/Classes/SideMenuView.m b/Classes/SideMenuView.m index 8a57f81d8..62d09399c 100644 --- a/Classes/SideMenuView.m +++ b/Classes/SideMenuView.m @@ -90,7 +90,7 @@ if (!IPAD) { [PhoneMainView.instance.mainViewController hideSideMenu:YES]; } - [ImagePickerView SelectImageFromDevice:self atPosition:_avatarImage inView:self.view]; + [ImagePickerView SelectImageFromDevice:self atPosition:_avatarImage inView:self.view withDocumentMenuDelegate:nil]; } - (IBAction)onBackgroundClicked:(id)sender { @@ -126,4 +126,8 @@ } } +- (void)imagePickerDelegateVideo:(NSURL*)url info:(NSDictionary *)info { + return; // Avatar video not supported (yet ;) ) +} + @end diff --git a/Classes/Utils/DTFoundation/DTActionSheet.m b/Classes/Utils/DTFoundation/DTActionSheet.m index ae091c824..48124e36b 100755 --- a/Classes/Utils/DTFoundation/DTActionSheet.m +++ b/Classes/Utils/DTFoundation/DTActionSheet.m @@ -176,4 +176,4 @@ } } -@end \ No newline at end of file +@end diff --git a/Classes/Utils/FastAddressBook.h b/Classes/Utils/FastAddressBook.h index 1d008b036..d0e505517 100644 --- a/Classes/Utils/FastAddressBook.h +++ b/Classes/Utils/FastAddressBook.h @@ -44,6 +44,7 @@ + (UIImage *)imageForContact:(Contact *)contact; + (UIImage *)imageForAddress:(const LinphoneAddress *)addr; ++ (UIImage *)imageForSecurityLevel:(LinphoneChatRoomSecurityLevel)level; + (BOOL)contactHasValidSipDomain:(Contact *)person; + (BOOL)isSipURIValid:(NSString*)addr; diff --git a/Classes/Utils/FastAddressBook.m b/Classes/Utils/FastAddressBook.m index aa0e6f32d..d9c610d41 100644 --- a/Classes/Utils/FastAddressBook.m +++ b/Classes/Utils/FastAddressBook.m @@ -48,6 +48,20 @@ return [FastAddressBook imageForContact:[FastAddressBook getContactWithAddress:addr]]; } ++ (UIImage *)imageForSecurityLevel:(LinphoneChatRoomSecurityLevel)level { + switch (level) { + case LinphoneChatRoomSecurityLevelUnsafe: + return [UIImage imageNamed:@"security_alert_indicator.png"]; + case LinphoneChatRoomSecurityLevelEncrypted: + return [UIImage imageNamed:@"security_1_indicator.png.png"]; + case LinphoneChatRoomSecurityLevelSafe: + return [UIImage imageNamed:@"security_2_indicator.png.png"]; + + default: + return nil; + } +} + + (Contact *)getContact:(NSString *)address { if (LinphoneManager.instance.fastAddressBook != nil) { @synchronized(LinphoneManager.instance.fastAddressBook.addressBookMap) { diff --git a/Classes/Utils/FileTransferDelegate.m b/Classes/Utils/FileTransferDelegate.m index 4b2fd6915..def684007 100644 --- a/Classes/Utils/FileTransferDelegate.m +++ b/Classes/Utils/FileTransferDelegate.m @@ -45,156 +45,153 @@ static void linphone_iphone_file_transfer_recv(LinphoneChatMessage *message, con LOGI(@"Transfer of %s (%d bytes): download finished", linphone_content_get_name(content), size); assert([thiz.data length] == linphone_content_get_file_size(content)); NSString *fileType = [NSString stringWithUTF8String:linphone_content_get_type(content)]; - if ([fileType isEqualToString:@"image"]) { - // we're finished, save the image and update the message - UIImage *image = [UIImage imageWithData:thiz.data]; - if (!image) { - UIAlertController *errView = [UIAlertController - alertControllerWithTitle:NSLocalizedString(@"File download error", nil) - message:NSLocalizedString(@"Error while downloading the file.\n" - @"The file is probably encrypted.\n" - @"Please retry to download this file after activating LIME.", - nil) - preferredStyle:UIAlertControllerStyleAlert]; - - UIAlertAction *defaultAction = [UIAlertAction actionWithTitle:@"OK" - style:UIAlertActionStyleDefault - handler:^(UIAlertAction *action){ - }]; - - [errView addAction:defaultAction]; - [PhoneMainView.instance presentViewController:errView animated:YES completion:nil]; - [thiz stopAndDestroy]; - return; + ChatConversationView *view = VIEW(ChatConversationView); + void (^block)(void)= ^ { + if ([fileType isEqualToString:@"image"]) { + // we're finished, save the image and update the message + UIImage *image = [UIImage imageWithData:thiz.data]; + if (!image) { + [view showFileDownloadError]; + [thiz stopAndDestroy]; + return; + } + + CFBridgingRetain(thiz); + [[LinphoneManager.instance fileTransferDelegates] removeObject:thiz]; + + // until image is properly saved, keep a reminder on it so that the + // chat bubble is aware of the fact that image is being saved to device + [LinphoneManager setValueInMessageAppData:@"saving..." forKey:@"localimage" inMessage:message]; + __block PHObjectPlaceholder *placeHolder; + [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{ + PHAssetCreationRequest *request = [PHAssetCreationRequest creationRequestForAssetFromImage:image]; + placeHolder = [request placeholderForCreatedAsset]; + } completionHandler:^(BOOL success, NSError *error) { + dispatch_async(dispatch_get_main_queue(), ^{ + if (error) { + LOGE(@"Cannot save image data downloaded [%@]", [error localizedDescription]); + [LinphoneManager setValueInMessageAppData:nil forKey:@"localimage" inMessage:message]; + UIAlertController *errView = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Transfer error", nil) + message:NSLocalizedString(@"Cannot write image to photo library", + nil) + preferredStyle:UIAlertControllerStyleAlert]; + + UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:@"OK" + style:UIAlertActionStyleDefault + handler:^(UIAlertAction * action) {}]; + + [errView addAction:defaultAction]; + [PhoneMainView.instance presentViewController:errView animated:YES completion:nil]; + } else { + LOGI(@"Image saved to [%@]", [placeHolder localIdentifier]); + [LinphoneManager setValueInMessageAppData:[placeHolder localIdentifier] + forKey:@"localimage" + inMessage:message]; + } + [NSNotificationCenter.defaultCenter + postNotificationName:kLinphoneFileTransferRecvUpdate + object:thiz + userInfo:@{ + @"state" : @(LinphoneChatMessageStateDelivered), // we dont want to + // trigger + // FileTransferDone here + @"image" : image, + @"progress" : @(1.f), + }]; + + [thiz stopAndDestroy]; + CFRelease((__bridge CFTypeRef)thiz); + }); + }]; + } else if([fileType isEqualToString:@"video"]) { + CFBridgingRetain(thiz); + [[LinphoneManager.instance fileTransferDelegates] removeObject:thiz]; + NSString *name =[NSString stringWithUTF8String:linphone_content_get_name(content)]; + NSString *filePath = [[LinphoneManager cacheDirectory] stringByAppendingPathComponent:name]; + [[NSFileManager defaultManager] createFileAtPath:filePath + contents:thiz.data + attributes:nil]; + // until image is properly saved, keep a reminder on it so that the + // chat bubble is aware of the fact that image is being saved to device + [LinphoneManager setValueInMessageAppData:@"saving..." forKey:@"localvideo" inMessage:message]; + + __block PHObjectPlaceholder *placeHolder; + [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{ + PHAssetCreationRequest *request = [PHAssetCreationRequest creationRequestForAssetFromVideoAtFileURL:[NSURL fileURLWithPath:filePath]]; + placeHolder = [request placeholderForCreatedAsset]; + } completionHandler:^(BOOL success, NSError * _Nullable error) { + dispatch_async(dispatch_get_main_queue(), ^{ + if (error) { + LOGE(@"Cannot save video data downloaded [%@]", [error localizedDescription]); + [LinphoneManager setValueInMessageAppData:nil forKey:@"localvideo" inMessage:message]; + UIAlertController *errView = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Transfer error", nil) + message:NSLocalizedString(@"Cannot write video to photo library", + nil) + preferredStyle:UIAlertControllerStyleAlert]; + + UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:@"OK" + style:UIAlertActionStyleDefault + handler:^(UIAlertAction * action) {}]; + + [errView addAction:defaultAction]; + [PhoneMainView.instance presentViewController:errView animated:YES completion:nil]; + } else { + LOGI(@"video saved to [%@]", [placeHolder localIdentifier]); + [LinphoneManager setValueInMessageAppData:[placeHolder localIdentifier] + forKey:@"localvideo" + inMessage:message]; + } + [NSNotificationCenter.defaultCenter + postNotificationName:kLinphoneFileTransferRecvUpdate + object:thiz + userInfo:@{ + @"state" : @(LinphoneChatMessageStateDelivered), // we dont want to + // trigger + // FileTransferDone here + @"progress" : @(1.f), + }]; + + [thiz stopAndDestroy]; + CFRelease((__bridge CFTypeRef)thiz); + }); + }]; + } + }; + // When you save an image or video to a photo library, make sure that it is allowed. Otherwise, there will be a backup error. + if ([fileType isEqualToString:@"image"] || [fileType isEqualToString:@"video"]) { + if ([PHPhotoLibrary authorizationStatus] == PHAuthorizationStatusAuthorized) { + block(); + } else { + [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) { + dispatch_async(dispatch_get_main_queue(), ^{ + if ([PHPhotoLibrary authorizationStatus] == PHAuthorizationStatusAuthorized) { + block(); + } else { + [[[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Photo's permission", nil) message:NSLocalizedString(@"Photo not authorized", nil) delegate:nil cancelButtonTitle:nil otherButtonTitles:@"Continue", nil] show]; + [thiz stopAndDestroy]; + } + }); + }]; } - - CFBridgingRetain(thiz); - [[LinphoneManager.instance fileTransferDelegates] removeObject:thiz]; - - // until image is properly saved, keep a reminder on it so that the - // chat bubble is aware of the fact that image is being saved to device - [LinphoneManager setValueInMessageAppData:@"saving..." forKey:@"localimage" inMessage:message]; - - __block PHObjectPlaceholder *placeHolder; - [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{ - PHAssetCreationRequest *request = [PHAssetCreationRequest creationRequestForAssetFromImage:image]; - placeHolder = [request placeholderForCreatedAsset]; - } completionHandler:^(BOOL success, NSError *error) { - dispatch_async(dispatch_get_main_queue(), ^{ - if (error) { - LOGE(@"Cannot save image data downloaded [%@]", [error localizedDescription]); - [LinphoneManager setValueInMessageAppData:nil forKey:@"localimage" inMessage:message]; - UIAlertController *errView = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Transfer error", nil) - message:NSLocalizedString(@"Cannot write image to photo library", - nil) - preferredStyle:UIAlertControllerStyleAlert]; - - UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:@"OK" - style:UIAlertActionStyleDefault - handler:^(UIAlertAction * action) {}]; - - [errView addAction:defaultAction]; - [PhoneMainView.instance presentViewController:errView animated:YES completion:nil]; - } else { - LOGI(@"Image saved to [%@]", [placeHolder localIdentifier]); - [LinphoneManager setValueInMessageAppData:[placeHolder localIdentifier] - forKey:@"localimage" - inMessage:message]; - } - [NSNotificationCenter.defaultCenter - postNotificationName:kLinphoneFileTransferRecvUpdate - object:thiz - userInfo:@{ - @"state" : @(LinphoneChatMessageStateDelivered), // we dont want to - // trigger - // FileTransferDone here - @"image" : image, - @"progress" : @(1.f), - }]; - - [thiz stopAndDestroy]; - CFRelease((__bridge CFTypeRef)thiz); - }); - }]; - } else if([fileType isEqualToString:@"video"]) { - CFBridgingRetain(thiz); - [[LinphoneManager.instance fileTransferDelegates] removeObject:thiz]; - NSString *name =[NSString stringWithUTF8String:linphone_content_get_name(content)]; - NSString *filePath = [[LinphoneManager cacheDirectory] stringByAppendingPathComponent:name]; - [[NSFileManager defaultManager] createFileAtPath:filePath - contents:thiz.data - attributes:nil]; - // until image is properly saved, keep a reminder on it so that the - // chat bubble is aware of the fact that image is being saved to device - [LinphoneManager setValueInMessageAppData:@"saving..." forKey:@"localvideo" inMessage:message]; - - __block PHObjectPlaceholder *placeHolder; - [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{ - PHAssetCreationRequest *request = [PHAssetCreationRequest creationRequestForAssetFromVideoAtFileURL:[NSURL fileURLWithPath:filePath]]; - placeHolder = [request placeholderForCreatedAsset]; - } completionHandler:^(BOOL success, NSError * _Nullable error) { - dispatch_async(dispatch_get_main_queue(), ^{ - if (error) { - LOGE(@"Cannot save video data downloaded [%@]", [error localizedDescription]); - [LinphoneManager setValueInMessageAppData:nil forKey:@"localvideo" inMessage:message]; - UIAlertController *errView = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Transfer error", nil) - message:NSLocalizedString(@"Cannot write video to photo library", - nil) - preferredStyle:UIAlertControllerStyleAlert]; - - UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:@"OK" - style:UIAlertActionStyleDefault - handler:^(UIAlertAction * action) {}]; - - [errView addAction:defaultAction]; - [PhoneMainView.instance presentViewController:errView animated:YES completion:nil]; - } else { - LOGI(@"video saved to [%@]", [placeHolder localIdentifier]); - [LinphoneManager setValueInMessageAppData:[placeHolder localIdentifier] - forKey:@"localvideo" - inMessage:message]; - } - [NSNotificationCenter.defaultCenter - postNotificationName:kLinphoneFileTransferRecvUpdate - object:thiz - userInfo:@{ - @"state" : @(LinphoneChatMessageStateDelivered), // we dont want to - // trigger - // FileTransferDone here - @"progress" : @(1.f), - }]; - - [thiz stopAndDestroy]; - CFRelease((__bridge CFTypeRef)thiz); - }); - }]; - } else { [[LinphoneManager.instance fileTransferDelegates] removeObject:thiz]; NSString *key = @"localfile" ; NSString *name =[NSString stringWithUTF8String:linphone_content_get_name(content)]; - [LinphoneManager setValueInMessageAppData:@"saving..." forKey:key inMessage:message]; //write file to path dispatch_async(dispatch_get_main_queue(), ^{ - NSString *filePath = [[LinphoneManager cacheDirectory] stringByAppendingPathComponent:name]; - //NSString *filePath = [LinphoneManager documentFile:name]; - [[NSFileManager defaultManager] createFileAtPath:filePath - contents:thiz.data - attributes:nil]; - - [LinphoneManager setValueInMessageAppData:name forKey:key inMessage:message]; - [LinphoneManager setValueInMessageAppData:filePath forKey:@"cachedfile" inMessage:message]; - - [NSNotificationCenter.defaultCenter - postNotificationName:kLinphoneFileTransferRecvUpdate - object:thiz - userInfo:@{ - @"state" : @(LinphoneChatMessageStateDelivered), // we dont want to trigger - @"progress" : @(1.f), // FileTransferDone here - }]; - + if([view writeFileInICloud:thiz.data fileURL:[view getICloudFileUrl:name]]) { + [LinphoneManager setValueInMessageAppData:name forKey:key inMessage:message]; + + [NSNotificationCenter.defaultCenter + postNotificationName:kLinphoneFileTransferRecvUpdate + object:thiz + userInfo:@{ + @"state" : @(LinphoneChatMessageStateDelivered), // we dont want to trigger + @"progress" : @(1.f), // FileTransferDone here + }]; + } [thiz stopAndDestroy]; }); } @@ -243,6 +240,11 @@ static LinphoneBuffer *linphone_iphone_file_transfer_send(LinphoneChatMessage *m linphone_chat_message_cbs_set_file_transfer_send(linphone_chat_message_get_callbacks(thiz.message), NULL); thiz.message = NULL; [thiz stopAndDestroy]; + //workaround fix : avoid chatconversationtableview scrolling + [NSNotificationCenter.defaultCenter postNotificationName:kLinphoneFileTransferSendUpdate + object:thiz + userInfo:@{@"state" : @(LinphoneChatMessageStateDelivered), + }]; } return buffer; } else { @@ -263,14 +265,15 @@ static LinphoneBuffer *linphone_iphone_file_transfer_send(LinphoneChatMessage *m linphone_content_set_name(content, [name UTF8String]); linphone_content_set_size(content, _data.length); _message = linphone_chat_room_create_file_transfer_message(chatRoom, content); - //linphone_chat_message_add_text_content(_message, [_text UTF8String]); + BOOL isOneToOneChat = linphone_chat_room_get_capabilities(chatRoom) & LinphoneChatRoomCapabilitiesOneToOne; + if (!isOneToOneChat && ![_text isEqualToString:@""]) + linphone_chat_message_add_text_content(_message, [_text UTF8String]); linphone_content_unref(content); linphone_chat_message_cbs_set_file_transfer_send(linphone_chat_message_get_callbacks(_message), linphone_iphone_file_transfer_send); // internal url is saved in the appdata for display and later save - LOGE(@"nnnn %@ %@",key, keyData); [LinphoneManager setValueInMessageAppData:keyData forKey:key inMessage:_message]; [LinphoneManager setValueInMessageAppData:qualityData forKey:@"uploadQuality" inMessage:_message]; @@ -299,7 +302,18 @@ static LinphoneBuffer *linphone_iphone_file_transfer_send(LinphoneChatMessage *m } - (void)uploadFile:(NSData *)data forChatRoom:(LinphoneChatRoom *)chatRoom withName:(NSString *)name { - [self uploadData:data forChatRoom:chatRoom type:@"file" subtype:nil name:name key:@"localfile" keyData:name qualityData:nil]; + // we will write local files into ours folder of icloud + ChatConversationView *view = VIEW(ChatConversationView); + NSURL *url = [view getICloudFileUrl:name]; + if ([view writeFileInICloud:data fileURL:url]) { + AVAsset *asset = [AVURLAsset URLAssetWithURL:url options:nil]; + if ([[asset tracksWithMediaType:AVMediaTypeVideo] count] > 0) { + // if it's a video + [self uploadData:data forChatRoom:chatRoom type:@"video" subtype:nil name:name key:@"localfile" keyData:name qualityData:nil]; + } else { + [self uploadData:data forChatRoom:chatRoom type:@"file" subtype:nil name:name key:@"localfile" keyData:name qualityData:nil]; + } + } } diff --git a/Classes/Utils/Log.m b/Classes/Utils/Log.m index 791d46f92..eb996cb8b 100644 --- a/Classes/Utils/Log.m +++ b/Classes/Utils/Log.m @@ -21,6 +21,10 @@ #import #import +#ifdef USE_CRASHLYTHICSS +#import +#endif + @implementation Log #define FILE_SIZE 17 @@ -114,11 +118,20 @@ void linphone_iphone_log_handler(const char *domain, OrtpLogLevel lev, const cha for (int i = 0; i < myWords.count; i++) { NSString *tab = i > 0 ? @"\t" : @""; if (((NSString *)myWords[i]).length > 0) { +#ifdef USE_CRASHLYTHICSS + CLSNSLog(@"[%@] %@%@", lvl, tab, (NSString *)myWords[i]); +#else NSLog(@"[%@] %@%@", lvl, tab, (NSString *)myWords[i]); +#endif + } } } else { +#ifdef USE_CRASHLYTHICSS + CLSNSLog(@"[%@] %@", lvl, [formatedString stringByReplacingOccurrencesOfString:@"\r\n" withString:@"\n"]); +#else NSLog(@"[%@] %@", lvl, [formatedString stringByReplacingOccurrencesOfString:@"\r\n" withString:@"\n"]); +#endif } } diff --git a/Classes/Utils/Utils.h b/Classes/Utils/Utils.h index aa3ceeda7..ec0b87f9e 100644 --- a/Classes/Utils/Utils.h +++ b/Classes/Utils/Utils.h @@ -33,6 +33,7 @@ + (NSString *)deviceModelIdentifier; + (LinphoneAddress *)normalizeSipOrPhoneAddress:(NSString *)addr; ++ (UIAlertController *)networkErrorView; typedef enum { LinphoneDateHistoryList, @@ -51,6 +52,9 @@ typedef enum { + (NSMutableDictionary *)photoAssetsDictionary; ++ (NSString *)recordingFilePathFromCall:(const LinphoneAddress *)iaddr; ++ (NSArray *)parseRecordingName:(NSString *)filename; + @end @interface NSNumber (HumanReadableSize) @@ -59,6 +63,12 @@ typedef enum { @end +@interface UIImage (systemIcons) + ++ (UIImage *)imageFromSystemBarButton:(UIBarButtonSystemItem)systemItem :(UIColor *) color; + +@end + @interface NSString (linphoneExt) - (NSString *)md5; diff --git a/Classes/Utils/Utils.m b/Classes/Utils/Utils.m index 089902852..42533f69f 100644 --- a/Classes/Utils/Utils.m +++ b/Classes/Utils/Utils.m @@ -73,23 +73,6 @@ return assetDict; } -/*+ (NSMutableDictionary *)videoAssetsDictionary { - NSMutableDictionary *assetDict = [NSMutableDictionary dictionary]; - - PHFetchOptions *options = [[PHFetchOptions alloc] init]; - [options setIncludeHiddenAssets:YES]; - [options setIncludeAllBurstAssets:YES]; - - PHFetchResult *fetchRes = [PHAsset fetchAssetsWithMediaType:PHAssetMediaTypeVideo options:options]; - - for (PHAsset *asset in fetchRes) { - NSString *key = [asset valueForKey:@"filename"]; - [assetDict setObject:asset forKey:[[key componentsSeparatedByString:@"."] firstObject]]; - } - - return assetDict; -}*/ - + (NSString *)timeToString:(time_t)time withFormat:(LinphoneDateFormat)format { NSString *formatstr; NSDate *todayDate = [[NSDate alloc] init]; @@ -505,11 +488,66 @@ if (addr && cfg) { const char *username = linphone_proxy_config_get_dial_escape_plus(cfg) ? normvalue : value.UTF8String; if (linphone_proxy_config_is_phone_number(cfg, username)) - linphone_address_set_username(addr, username); + linphone_address_set_username(addr, linphone_proxy_config_normalize_phone_number(cfg, username)); } return addr; } ++ (NSString *)recordingFilePathFromCall:(const LinphoneAddress *)iaddr { + NSString *filepath = @"recording_"; + const char *address = linphone_address_get_username(iaddr); + filepath = [filepath stringByAppendingString:[NSString stringWithCString:address encoding:NSUTF8StringEncoding]]; + NSDate * now = [NSDate date]; + NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init]; + [dateFormat setDateFormat:@"E-d-MMM-yyyy-HH-mm-ss"]; + NSString *date = [dateFormat stringFromDate:now]; + + filepath = [filepath stringByAppendingString:@"_"]; + filepath = [filepath stringByAppendingString:date]; + filepath = [filepath stringByAppendingString:@".mkv"]; + + NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES); + NSString *writablePath = [paths objectAtIndex:0]; + writablePath = [writablePath stringByAppendingString:@"/"]; + writablePath = [writablePath stringByAppendingString:filepath]; + LOGD(@"file path is: %@\n", writablePath); + return writablePath; + //file name is recording_contact-name_dayName-day-monthName-year-hour-minutes-seconds + //The recording prefix is used to identify recordings in the cache directory. + //We will use name_dayName-day-monthName-year to separate recordings by days, then hour-minutes-seconds to order them in each day. +} + ++ (NSArray *)parseRecordingName:(NSString *)filename { + NSString *rec = @"recording_"; //key that helps find recordings + NSString *subName = [filename substringFromIndex:[filename rangeOfString:rec].location]; //We remove the parent folders if they exist in the filename + NSArray *splitString = [subName componentsSeparatedByString:@"_"]; + //splitString: first element is the 'recording' prefix, last element is the date with the "E-d-MMM-yyyy-HH-mm-ss" format. + NSString *name = [[splitString subarrayWithRange:NSMakeRange(1, [splitString count] -2)] componentsJoinedByString:@""]; + NSDateFormatter *format = [[NSDateFormatter alloc] init]; + [format setDateFormat:@"E-d-MMM-yyyy-HH-mm-ss"]; + NSString *dateWithMkv = [splitString objectAtIndex:[splitString count]-1]; //this will be in the form "E-d-MMM-yyyy-HH-mm-ss.mkv", we have to delete the extension + NSDate *date = [format dateFromString:[dateWithMkv substringToIndex:[dateWithMkv length] - 4]]; + NSArray *res = [NSArray arrayWithObjects:name, date, nil]; + return res; +} + ++ (UIAlertController *)networkErrorView { + UIAlertController *errView = + [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Network Error", nil) + message:NSLocalizedString(@"There is no network connection available, " + @"enable WIFI or WWAN prior to place a call", + nil) + preferredStyle:UIAlertControllerStyleAlert]; + + UIAlertAction *defaultAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"OK", nil) + style:UIAlertActionStyleDefault + handler:^(UIAlertAction *action){ + }]; + + [errView addAction:defaultAction]; + return errView; +} + @end @implementation NSNumber (HumanReadableSize) @@ -531,6 +569,29 @@ @end +@implementation UIImage (systemIcons) + ++ (UIImage *)imageFromSystemBarButton:(UIBarButtonSystemItem)systemItem :(UIColor *) color { + // thanks to Renetik https://stackoverflow.com/a/49822488 + UIToolbar *bar = UIToolbar.new; + UIBarButtonItem *buttonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:systemItem target:nil action:nil]; + [bar setItems:@[buttonItem] animated:NO]; + [bar snapshotViewAfterScreenUpdates:YES]; + for (UIView *view in [(id) buttonItem view].subviews) + if ([view isKindOfClass:UIButton.class]) { + UIImage *image = [((UIButton *) view).imageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; + UIGraphicsBeginImageContextWithOptions(image.size, NO, image.scale); + //[color set]; + [image drawInRect:CGRectMake(0, 0, image.size.width, image.size.height)]; + image = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); + return image; + } + return nil; +} + +@end + @implementation NSString (md5) - (NSString *)md5 { @@ -580,17 +641,23 @@ + (void)setDisplayNameLabel:(UILabel *)label forAddress:(const LinphoneAddress *)addr withAddressLabel:(UILabel*)addressLabel{ Contact *contact = [FastAddressBook getContactWithAddress:addr]; + NSString *tmpAddress = nil; if (contact) { [ContactDisplay setDisplayNameLabel:label forContact:contact]; - addressLabel.text = [NSString stringWithUTF8String:linphone_address_as_string_uri_only(addr)]; + tmpAddress = [NSString stringWithUTF8String:linphone_address_as_string_uri_only(addr)]; addressLabel.hidden = FALSE; } else { label.text = [FastAddressBook displayNameForAddress:addr]; if([LinphoneManager.instance lpConfigBoolForKey:@"display_phone_only" inSection:@"app"]) addressLabel.hidden = TRUE; else - addressLabel.text = [NSString stringWithUTF8String:linphone_address_as_string_uri_only(addr)]; + tmpAddress = [NSString stringWithUTF8String:linphone_address_as_string_uri_only(addr)]; } + NSRange range = [tmpAddress rangeOfString:@";"]; + if (range.location != NSNotFound) { + tmpAddress = [tmpAddress substringToIndex:range.location]; + } + addressLabel.text = tmpAddress; } diff --git a/Classes/ar.lproj/AboutView.strings b/Classes/ar.lproj/AboutView.strings index 809cb3715..282106250 100644 Binary files a/Classes/ar.lproj/AboutView.strings and b/Classes/ar.lproj/AboutView.strings differ diff --git a/Classes/ar.lproj/AssistantViewScreens.strings b/Classes/ar.lproj/AssistantViewScreens.strings index 3f90b396a..2becf0ea1 100644 Binary files a/Classes/ar.lproj/AssistantViewScreens.strings and b/Classes/ar.lproj/AssistantViewScreens.strings differ diff --git a/Classes/ar.lproj/CallView.strings b/Classes/ar.lproj/CallView.strings index da1140245..6544e6570 100644 Binary files a/Classes/ar.lproj/CallView.strings and b/Classes/ar.lproj/CallView.strings differ diff --git a/Classes/ar.lproj/CallView~ipad.strings b/Classes/ar.lproj/CallView~ipad.strings index da1140245..148582360 100644 Binary files a/Classes/ar.lproj/CallView~ipad.strings and b/Classes/ar.lproj/CallView~ipad.strings differ diff --git a/Classes/ar.lproj/ChatsListView.strings b/Classes/ar.lproj/ChatsListView.strings index 60a475f33..1d2ec4081 100644 Binary files a/Classes/ar.lproj/ChatsListView.strings and b/Classes/ar.lproj/ChatsListView.strings differ diff --git a/Classes/ar.lproj/HistoryDetailsView.strings b/Classes/ar.lproj/HistoryDetailsView.strings index 3a508049f..c98d7d693 100644 Binary files a/Classes/ar.lproj/HistoryDetailsView.strings and b/Classes/ar.lproj/HistoryDetailsView.strings differ diff --git a/Classes/cs.lproj/AssistantView.strings b/Classes/cs.lproj/AssistantView.strings index 9a5202b81..6076e7487 100644 Binary files a/Classes/cs.lproj/AssistantView.strings and b/Classes/cs.lproj/AssistantView.strings differ diff --git a/Classes/cs.lproj/AssistantViewScreens.strings b/Classes/cs.lproj/AssistantViewScreens.strings index a10a0a4df..dada1da2f 100644 Binary files a/Classes/cs.lproj/AssistantViewScreens.strings and b/Classes/cs.lproj/AssistantViewScreens.strings differ diff --git a/Classes/cs.lproj/CallIncomingView.strings b/Classes/cs.lproj/CallIncomingView.strings new file mode 100644 index 000000000..e194df66c Binary files /dev/null and b/Classes/cs.lproj/CallIncomingView.strings differ diff --git a/Classes/cs.lproj/CallOutgoingView.strings b/Classes/cs.lproj/CallOutgoingView.strings new file mode 100644 index 000000000..733f84332 Binary files /dev/null and b/Classes/cs.lproj/CallOutgoingView.strings differ diff --git a/Classes/cs.lproj/CallView.strings b/Classes/cs.lproj/CallView.strings new file mode 100644 index 000000000..637bba88b Binary files /dev/null and b/Classes/cs.lproj/CallView.strings differ diff --git a/Classes/cs.lproj/CallView~ipad.strings b/Classes/cs.lproj/CallView~ipad.strings new file mode 100644 index 000000000..015efd7df Binary files /dev/null and b/Classes/cs.lproj/CallView~ipad.strings differ diff --git a/Classes/cs.lproj/ChatConversationCreateView.strings b/Classes/cs.lproj/ChatConversationCreateView.strings new file mode 100644 index 000000000..64b2c0b40 Binary files /dev/null and b/Classes/cs.lproj/ChatConversationCreateView.strings differ diff --git a/Classes/cs.lproj/ChatConversationImdnView.strings b/Classes/cs.lproj/ChatConversationImdnView.strings new file mode 100644 index 000000000..34af07f2b Binary files /dev/null and b/Classes/cs.lproj/ChatConversationImdnView.strings differ diff --git a/Classes/cs.lproj/ChatConversationInfoView.strings b/Classes/cs.lproj/ChatConversationInfoView.strings new file mode 100644 index 000000000..ee371f212 Binary files /dev/null and b/Classes/cs.lproj/ChatConversationInfoView.strings differ diff --git a/Classes/cs.lproj/ChatConversationView.strings b/Classes/cs.lproj/ChatConversationView.strings new file mode 100644 index 000000000..b3bd8abbe Binary files /dev/null and b/Classes/cs.lproj/ChatConversationView.strings differ diff --git a/Classes/cs.lproj/ContactDetailsView.strings b/Classes/cs.lproj/ContactDetailsView.strings new file mode 100644 index 000000000..6b3e0e61e Binary files /dev/null and b/Classes/cs.lproj/ContactDetailsView.strings differ diff --git a/Classes/cs.lproj/CountryListView.strings b/Classes/cs.lproj/CountryListView.strings new file mode 100644 index 000000000..8fc5648a4 Binary files /dev/null and b/Classes/cs.lproj/CountryListView.strings differ diff --git a/Classes/cs.lproj/DialerView.strings b/Classes/cs.lproj/DialerView.strings new file mode 100644 index 000000000..c7ce6f964 Binary files /dev/null and b/Classes/cs.lproj/DialerView.strings differ diff --git a/Classes/cs.lproj/DialerView~ipad.strings b/Classes/cs.lproj/DialerView~ipad.strings new file mode 100644 index 000000000..1a869cc13 Binary files /dev/null and b/Classes/cs.lproj/DialerView~ipad.strings differ diff --git a/Classes/cs.lproj/HistoryDetailsView.strings b/Classes/cs.lproj/HistoryDetailsView.strings new file mode 100644 index 000000000..09c521fbb Binary files /dev/null and b/Classes/cs.lproj/HistoryDetailsView.strings differ diff --git a/Classes/cs.lproj/SettingsView.strings b/Classes/cs.lproj/SettingsView.strings index d715cb306..4a9364003 100644 Binary files a/Classes/cs.lproj/SettingsView.strings and b/Classes/cs.lproj/SettingsView.strings differ diff --git a/Classes/de.lproj/AssistantViewScreens.strings b/Classes/de.lproj/AssistantViewScreens.strings index 50d2db428..a6af9d538 100644 Binary files a/Classes/de.lproj/AssistantViewScreens.strings and b/Classes/de.lproj/AssistantViewScreens.strings differ diff --git a/Classes/de.lproj/CallView.strings b/Classes/de.lproj/CallView.strings index 308243cf7..a965ca76c 100644 Binary files a/Classes/de.lproj/CallView.strings and b/Classes/de.lproj/CallView.strings differ diff --git a/Classes/de.lproj/CallView~ipad.strings b/Classes/de.lproj/CallView~ipad.strings index 308243cf7..3395287b7 100644 Binary files a/Classes/de.lproj/CallView~ipad.strings and b/Classes/de.lproj/CallView~ipad.strings differ diff --git a/Classes/de.lproj/ChatsListView.strings b/Classes/de.lproj/ChatsListView.strings index 0f73cd7b0..b145a2d79 100644 Binary files a/Classes/de.lproj/ChatsListView.strings and b/Classes/de.lproj/ChatsListView.strings differ diff --git a/Classes/de.lproj/HistoryDetailsView.strings b/Classes/de.lproj/HistoryDetailsView.strings index ef34696af..9aece229f 100644 Binary files a/Classes/de.lproj/HistoryDetailsView.strings and b/Classes/de.lproj/HistoryDetailsView.strings differ diff --git a/Classes/es.lproj/AssistantViewScreens.strings b/Classes/es.lproj/AssistantViewScreens.strings index d3c83f6d6..967527b6f 100644 Binary files a/Classes/es.lproj/AssistantViewScreens.strings and b/Classes/es.lproj/AssistantViewScreens.strings differ diff --git a/Classes/es.lproj/CallView.strings b/Classes/es.lproj/CallView.strings index 062954d56..9d9fdd31e 100644 Binary files a/Classes/es.lproj/CallView.strings and b/Classes/es.lproj/CallView.strings differ diff --git a/Classes/es.lproj/CallView~ipad.strings b/Classes/es.lproj/CallView~ipad.strings index 062954d56..088cb5445 100644 Binary files a/Classes/es.lproj/CallView~ipad.strings and b/Classes/es.lproj/CallView~ipad.strings differ diff --git a/Classes/es.lproj/ChatsListView.strings b/Classes/es.lproj/ChatsListView.strings index c5db3d35b..aa6e38c83 100644 Binary files a/Classes/es.lproj/ChatsListView.strings and b/Classes/es.lproj/ChatsListView.strings differ diff --git a/Classes/es.lproj/HistoryDetailsView.strings b/Classes/es.lproj/HistoryDetailsView.strings index 0b8f1d344..51fb27ebd 100644 Binary files a/Classes/es.lproj/HistoryDetailsView.strings and b/Classes/es.lproj/HistoryDetailsView.strings differ diff --git a/Classes/es_AR.lproj/AssistantViewScreens.strings b/Classes/es_AR.lproj/AssistantViewScreens.strings index 0dca27403..8afb9629d 100644 Binary files a/Classes/es_AR.lproj/AssistantViewScreens.strings and b/Classes/es_AR.lproj/AssistantViewScreens.strings differ diff --git a/Classes/es_AR.lproj/CallView.strings b/Classes/es_AR.lproj/CallView.strings index 062954d56..9d9fdd31e 100644 Binary files a/Classes/es_AR.lproj/CallView.strings and b/Classes/es_AR.lproj/CallView.strings differ diff --git a/Classes/es_AR.lproj/CallView~ipad.strings b/Classes/es_AR.lproj/CallView~ipad.strings index 062954d56..088cb5445 100644 Binary files a/Classes/es_AR.lproj/CallView~ipad.strings and b/Classes/es_AR.lproj/CallView~ipad.strings differ diff --git a/Classes/es_AR.lproj/ChatsListView.strings b/Classes/es_AR.lproj/ChatsListView.strings index c5db3d35b..aa6e38c83 100644 Binary files a/Classes/es_AR.lproj/ChatsListView.strings and b/Classes/es_AR.lproj/ChatsListView.strings differ diff --git a/Classes/es_AR.lproj/HistoryDetailsView.strings b/Classes/es_AR.lproj/HistoryDetailsView.strings index 0b8f1d344..51fb27ebd 100644 Binary files a/Classes/es_AR.lproj/HistoryDetailsView.strings and b/Classes/es_AR.lproj/HistoryDetailsView.strings differ diff --git a/Classes/fr.lproj/AboutView.strings b/Classes/fr.lproj/AboutView.strings index 5d22ce69d..72b62a748 100644 Binary files a/Classes/fr.lproj/AboutView.strings and b/Classes/fr.lproj/AboutView.strings differ diff --git a/Classes/fr.lproj/AssistantLinkView.strings b/Classes/fr.lproj/AssistantLinkView.strings index 2ecf6c760..dd872acd5 100644 Binary files a/Classes/fr.lproj/AssistantLinkView.strings and b/Classes/fr.lproj/AssistantLinkView.strings differ diff --git a/Classes/fr.lproj/AssistantViewScreens.strings b/Classes/fr.lproj/AssistantViewScreens.strings index 1b826ffae..3b2d48592 100644 Binary files a/Classes/fr.lproj/AssistantViewScreens.strings and b/Classes/fr.lproj/AssistantViewScreens.strings differ diff --git a/Classes/fr.lproj/CallView.strings b/Classes/fr.lproj/CallView.strings index c675adc72..8303fcfed 100644 Binary files a/Classes/fr.lproj/CallView.strings and b/Classes/fr.lproj/CallView.strings differ diff --git a/Classes/fr.lproj/CallView~ipad.strings b/Classes/fr.lproj/CallView~ipad.strings index 6521b86f7..b4c093b13 100644 Binary files a/Classes/fr.lproj/CallView~ipad.strings and b/Classes/fr.lproj/CallView~ipad.strings differ diff --git a/Classes/fr.lproj/ChatsListView.strings b/Classes/fr.lproj/ChatsListView.strings index 8bb9000ec..fc08a6c9c 100644 Binary files a/Classes/fr.lproj/ChatsListView.strings and b/Classes/fr.lproj/ChatsListView.strings differ diff --git a/Classes/fr.lproj/HistoryDetailsView.strings b/Classes/fr.lproj/HistoryDetailsView.strings index 11b0cfe7e..5f60ea629 100644 Binary files a/Classes/fr.lproj/HistoryDetailsView.strings and b/Classes/fr.lproj/HistoryDetailsView.strings differ diff --git a/Classes/fr.lproj/ShopView.strings b/Classes/fr.lproj/ShopView.strings index f4103ddb4..4574faceb 100644 Binary files a/Classes/fr.lproj/ShopView.strings and b/Classes/fr.lproj/ShopView.strings differ diff --git a/Classes/it.lproj/AboutView.strings b/Classes/it.lproj/AboutView.strings new file mode 100644 index 000000000..abf6ed6ef Binary files /dev/null and b/Classes/it.lproj/AboutView.strings differ diff --git a/Classes/it.lproj/AssistantLinkView.strings b/Classes/it.lproj/AssistantLinkView.strings new file mode 100644 index 000000000..5f362da29 Binary files /dev/null and b/Classes/it.lproj/AssistantLinkView.strings differ diff --git a/Classes/it.lproj/AssistantView.strings b/Classes/it.lproj/AssistantView.strings new file mode 100644 index 000000000..9bb799569 Binary files /dev/null and b/Classes/it.lproj/AssistantView.strings differ diff --git a/Classes/it.lproj/AssistantViewScreens.strings b/Classes/it.lproj/AssistantViewScreens.strings new file mode 100644 index 000000000..46a456a83 Binary files /dev/null and b/Classes/it.lproj/AssistantViewScreens.strings differ diff --git a/Classes/it.lproj/CallIncomingView.strings b/Classes/it.lproj/CallIncomingView.strings new file mode 100644 index 000000000..2572d25fb Binary files /dev/null and b/Classes/it.lproj/CallIncomingView.strings differ diff --git a/Classes/it.lproj/CallOutgoingView.strings b/Classes/it.lproj/CallOutgoingView.strings new file mode 100644 index 000000000..5d00860aa Binary files /dev/null and b/Classes/it.lproj/CallOutgoingView.strings differ diff --git a/Classes/it.lproj/CallView.strings b/Classes/it.lproj/CallView.strings new file mode 100644 index 000000000..c6af2cf49 Binary files /dev/null and b/Classes/it.lproj/CallView.strings differ diff --git a/Classes/it.lproj/CallView~ipad.strings b/Classes/it.lproj/CallView~ipad.strings new file mode 100644 index 000000000..e55ff2b99 Binary files /dev/null and b/Classes/it.lproj/CallView~ipad.strings differ diff --git a/Classes/it.lproj/ChatConversationCreateView.strings b/Classes/it.lproj/ChatConversationCreateView.strings new file mode 100644 index 000000000..088942672 Binary files /dev/null and b/Classes/it.lproj/ChatConversationCreateView.strings differ diff --git a/Classes/it.lproj/ChatConversationImdnView.strings b/Classes/it.lproj/ChatConversationImdnView.strings new file mode 100644 index 000000000..f76e02d85 Binary files /dev/null and b/Classes/it.lproj/ChatConversationImdnView.strings differ diff --git a/Classes/it.lproj/ChatConversationInfoView.strings b/Classes/it.lproj/ChatConversationInfoView.strings new file mode 100644 index 000000000..126a910ba Binary files /dev/null and b/Classes/it.lproj/ChatConversationInfoView.strings differ diff --git a/Classes/it.lproj/ChatConversationView.strings b/Classes/it.lproj/ChatConversationView.strings new file mode 100644 index 000000000..a185204e5 Binary files /dev/null and b/Classes/it.lproj/ChatConversationView.strings differ diff --git a/Classes/it.lproj/ChatsListView.strings b/Classes/it.lproj/ChatsListView.strings new file mode 100644 index 000000000..22a7f3b13 Binary files /dev/null and b/Classes/it.lproj/ChatsListView.strings differ diff --git a/Classes/it.lproj/ContactDetailsView.strings b/Classes/it.lproj/ContactDetailsView.strings new file mode 100644 index 000000000..cbe47cfd7 Binary files /dev/null and b/Classes/it.lproj/ContactDetailsView.strings differ diff --git a/Classes/it.lproj/ContactsListView.strings b/Classes/it.lproj/ContactsListView.strings new file mode 100644 index 000000000..645a03695 Binary files /dev/null and b/Classes/it.lproj/ContactsListView.strings differ diff --git a/Classes/it.lproj/CountryListView.strings b/Classes/it.lproj/CountryListView.strings new file mode 100644 index 000000000..95a6145e2 Binary files /dev/null and b/Classes/it.lproj/CountryListView.strings differ diff --git a/Classes/it.lproj/DialerView.strings b/Classes/it.lproj/DialerView.strings new file mode 100644 index 000000000..a00dbf1d0 Binary files /dev/null and b/Classes/it.lproj/DialerView.strings differ diff --git a/Classes/it.lproj/DialerView~ipad.strings b/Classes/it.lproj/DialerView~ipad.strings new file mode 100644 index 000000000..2101c5f8a Binary files /dev/null and b/Classes/it.lproj/DialerView~ipad.strings differ diff --git a/Classes/it.lproj/FirstLoginView.strings b/Classes/it.lproj/FirstLoginView.strings new file mode 100644 index 000000000..55637334f Binary files /dev/null and b/Classes/it.lproj/FirstLoginView.strings differ diff --git a/Classes/it.lproj/HistoryDetailsView.strings b/Classes/it.lproj/HistoryDetailsView.strings new file mode 100644 index 000000000..a4eefd0bd Binary files /dev/null and b/Classes/it.lproj/HistoryDetailsView.strings differ diff --git a/Classes/it.lproj/HistoryListView.strings b/Classes/it.lproj/HistoryListView.strings new file mode 100644 index 000000000..5f37d555e Binary files /dev/null and b/Classes/it.lproj/HistoryListView.strings differ diff --git a/Classes/it.lproj/ImageView.strings b/Classes/it.lproj/ImageView.strings new file mode 100644 index 000000000..8985da6de Binary files /dev/null and b/Classes/it.lproj/ImageView.strings differ diff --git a/Classes/it.lproj/SettingsView.strings b/Classes/it.lproj/SettingsView.strings new file mode 100644 index 000000000..83ece1a85 Binary files /dev/null and b/Classes/it.lproj/SettingsView.strings differ diff --git a/Classes/it.lproj/ShopView.strings b/Classes/it.lproj/ShopView.strings new file mode 100644 index 000000000..49a0ff00f Binary files /dev/null and b/Classes/it.lproj/ShopView.strings differ diff --git a/Classes/it.lproj/SideMenuView.strings b/Classes/it.lproj/SideMenuView.strings new file mode 100644 index 000000000..f3ede4222 Binary files /dev/null and b/Classes/it.lproj/SideMenuView.strings differ diff --git a/Classes/it.lproj/SideMenuView~ipad.strings b/Classes/it.lproj/SideMenuView~ipad.strings new file mode 100644 index 000000000..35e94722a Binary files /dev/null and b/Classes/it.lproj/SideMenuView~ipad.strings differ diff --git a/Classes/ja.lproj/AssistantViewScreens.strings b/Classes/ja.lproj/AssistantViewScreens.strings index ee6dc59f1..1b1459324 100644 Binary files a/Classes/ja.lproj/AssistantViewScreens.strings and b/Classes/ja.lproj/AssistantViewScreens.strings differ diff --git a/Classes/ja.lproj/CallView.strings b/Classes/ja.lproj/CallView.strings index 49e4ce890..4e78b356f 100644 Binary files a/Classes/ja.lproj/CallView.strings and b/Classes/ja.lproj/CallView.strings differ diff --git a/Classes/ja.lproj/CallView~ipad.strings b/Classes/ja.lproj/CallView~ipad.strings index 49e4ce890..1e4321267 100644 Binary files a/Classes/ja.lproj/CallView~ipad.strings and b/Classes/ja.lproj/CallView~ipad.strings differ diff --git a/Classes/ja.lproj/ChatsListView.strings b/Classes/ja.lproj/ChatsListView.strings index 3825ff74d..cf6b012f9 100644 Binary files a/Classes/ja.lproj/ChatsListView.strings and b/Classes/ja.lproj/ChatsListView.strings differ diff --git a/Classes/ja.lproj/HistoryDetailsView.strings b/Classes/ja.lproj/HistoryDetailsView.strings index cd8b641bc..357016ca4 100644 Binary files a/Classes/ja.lproj/HistoryDetailsView.strings and b/Classes/ja.lproj/HistoryDetailsView.strings differ diff --git a/Classes/ka.lproj/AboutView.strings b/Classes/ka.lproj/AboutView.strings index ec6a3d3dd..70ee53399 100644 Binary files a/Classes/ka.lproj/AboutView.strings and b/Classes/ka.lproj/AboutView.strings differ diff --git a/Classes/ka.lproj/AssistantViewScreens.strings b/Classes/ka.lproj/AssistantViewScreens.strings index 0784dd4e0..beb7f44ea 100644 Binary files a/Classes/ka.lproj/AssistantViewScreens.strings and b/Classes/ka.lproj/AssistantViewScreens.strings differ diff --git a/Classes/ka.lproj/CallView.strings b/Classes/ka.lproj/CallView.strings index 61ac3d57d..7c9961668 100644 Binary files a/Classes/ka.lproj/CallView.strings and b/Classes/ka.lproj/CallView.strings differ diff --git a/Classes/ka.lproj/CallView~ipad.strings b/Classes/ka.lproj/CallView~ipad.strings index 61ac3d57d..5f3a58b53 100644 Binary files a/Classes/ka.lproj/CallView~ipad.strings and b/Classes/ka.lproj/CallView~ipad.strings differ diff --git a/Classes/ka.lproj/ChatsListView.strings b/Classes/ka.lproj/ChatsListView.strings index f70da0e7d..949ce45db 100644 Binary files a/Classes/ka.lproj/ChatsListView.strings and b/Classes/ka.lproj/ChatsListView.strings differ diff --git a/Classes/ka.lproj/HistoryDetailsView.strings b/Classes/ka.lproj/HistoryDetailsView.strings index d307b91d1..2c595b0c8 100644 Binary files a/Classes/ka.lproj/HistoryDetailsView.strings and b/Classes/ka.lproj/HistoryDetailsView.strings differ diff --git a/Classes/nl.lproj/AssistantViewScreens.strings b/Classes/nl.lproj/AssistantViewScreens.strings index 9b37ef2aa..d219ac502 100644 Binary files a/Classes/nl.lproj/AssistantViewScreens.strings and b/Classes/nl.lproj/AssistantViewScreens.strings differ diff --git a/Classes/nl.lproj/CallView.strings b/Classes/nl.lproj/CallView.strings index 31c93b287..402d6f312 100644 Binary files a/Classes/nl.lproj/CallView.strings and b/Classes/nl.lproj/CallView.strings differ diff --git a/Classes/nl.lproj/CallView~ipad.strings b/Classes/nl.lproj/CallView~ipad.strings index 31c93b287..713fd0063 100644 Binary files a/Classes/nl.lproj/CallView~ipad.strings and b/Classes/nl.lproj/CallView~ipad.strings differ diff --git a/Classes/nl.lproj/ChatsListView.strings b/Classes/nl.lproj/ChatsListView.strings index 1c12e43fd..82c059477 100644 Binary files a/Classes/nl.lproj/ChatsListView.strings and b/Classes/nl.lproj/ChatsListView.strings differ diff --git a/Classes/nl.lproj/HistoryDetailsView.strings b/Classes/nl.lproj/HistoryDetailsView.strings index 17d6e5616..b1efc77cf 100644 Binary files a/Classes/nl.lproj/HistoryDetailsView.strings and b/Classes/nl.lproj/HistoryDetailsView.strings differ diff --git a/Classes/pl.lproj/AssistantViewScreens.strings b/Classes/pl.lproj/AssistantViewScreens.strings index d4889cced..31e6ffc73 100644 Binary files a/Classes/pl.lproj/AssistantViewScreens.strings and b/Classes/pl.lproj/AssistantViewScreens.strings differ diff --git a/Classes/pl.lproj/CallView.strings b/Classes/pl.lproj/CallView.strings index 6214c3b92..c3e48f40c 100644 Binary files a/Classes/pl.lproj/CallView.strings and b/Classes/pl.lproj/CallView.strings differ diff --git a/Classes/pl.lproj/CallView~ipad.strings b/Classes/pl.lproj/CallView~ipad.strings index df9bac64d..73b306a4a 100644 Binary files a/Classes/pl.lproj/CallView~ipad.strings and b/Classes/pl.lproj/CallView~ipad.strings differ diff --git a/Classes/pl.lproj/ChatsListView.strings b/Classes/pl.lproj/ChatsListView.strings index 11dfbdf7c..98f4b1fc1 100644 Binary files a/Classes/pl.lproj/ChatsListView.strings and b/Classes/pl.lproj/ChatsListView.strings differ diff --git a/Classes/pl.lproj/HistoryDetailsView.strings b/Classes/pl.lproj/HistoryDetailsView.strings index c841966ed..1c07396fc 100644 Binary files a/Classes/pl.lproj/HistoryDetailsView.strings and b/Classes/pl.lproj/HistoryDetailsView.strings differ diff --git a/Classes/pt_BR.lproj/AboutView.strings b/Classes/pt_BR.lproj/AboutView.strings index ae9405d88..5b4555d47 100644 Binary files a/Classes/pt_BR.lproj/AboutView.strings and b/Classes/pt_BR.lproj/AboutView.strings differ diff --git a/Classes/pt_BR.lproj/AssistantViewScreens.strings b/Classes/pt_BR.lproj/AssistantViewScreens.strings index 5104a7e17..83d121c43 100644 Binary files a/Classes/pt_BR.lproj/AssistantViewScreens.strings and b/Classes/pt_BR.lproj/AssistantViewScreens.strings differ diff --git a/Classes/pt_BR.lproj/CallView.strings b/Classes/pt_BR.lproj/CallView.strings index 183ce58fb..5b91d20d1 100644 Binary files a/Classes/pt_BR.lproj/CallView.strings and b/Classes/pt_BR.lproj/CallView.strings differ diff --git a/Classes/pt_BR.lproj/CallView~ipad.strings b/Classes/pt_BR.lproj/CallView~ipad.strings index 99d0410ec..2caede80c 100644 Binary files a/Classes/pt_BR.lproj/CallView~ipad.strings and b/Classes/pt_BR.lproj/CallView~ipad.strings differ diff --git a/Classes/pt_BR.lproj/ChatConversationCreateView.strings b/Classes/pt_BR.lproj/ChatConversationCreateView.strings index fa2e3a707..3b3d778ce 100644 Binary files a/Classes/pt_BR.lproj/ChatConversationCreateView.strings and b/Classes/pt_BR.lproj/ChatConversationCreateView.strings differ diff --git a/Classes/pt_BR.lproj/ChatConversationImdnView.strings b/Classes/pt_BR.lproj/ChatConversationImdnView.strings index d8c55f9e6..fc24762e5 100644 Binary files a/Classes/pt_BR.lproj/ChatConversationImdnView.strings and b/Classes/pt_BR.lproj/ChatConversationImdnView.strings differ diff --git a/Classes/pt_BR.lproj/ChatConversationInfoView.strings b/Classes/pt_BR.lproj/ChatConversationInfoView.strings index 9e60506f0..a1adcfa71 100644 Binary files a/Classes/pt_BR.lproj/ChatConversationInfoView.strings and b/Classes/pt_BR.lproj/ChatConversationInfoView.strings differ diff --git a/Classes/pt_BR.lproj/ChatConversationView.strings b/Classes/pt_BR.lproj/ChatConversationView.strings index 3e445f7a3..de453b44f 100644 Binary files a/Classes/pt_BR.lproj/ChatConversationView.strings and b/Classes/pt_BR.lproj/ChatConversationView.strings differ diff --git a/Classes/pt_BR.lproj/ChatsListView.strings b/Classes/pt_BR.lproj/ChatsListView.strings index 593a91c64..cca414694 100644 Binary files a/Classes/pt_BR.lproj/ChatsListView.strings and b/Classes/pt_BR.lproj/ChatsListView.strings differ diff --git a/Classes/pt_BR.lproj/HistoryDetailsView.strings b/Classes/pt_BR.lproj/HistoryDetailsView.strings index 7d8c401b7..5decd8c7a 100644 Binary files a/Classes/pt_BR.lproj/HistoryDetailsView.strings and b/Classes/pt_BR.lproj/HistoryDetailsView.strings differ diff --git a/Classes/ru.lproj/AboutView.strings b/Classes/ru.lproj/AboutView.strings index 092bb753c..6dd506899 100644 Binary files a/Classes/ru.lproj/AboutView.strings and b/Classes/ru.lproj/AboutView.strings differ diff --git a/Classes/ru.lproj/AssistantLinkView.strings b/Classes/ru.lproj/AssistantLinkView.strings index 7243c4f6c..5f73bc5e4 100644 Binary files a/Classes/ru.lproj/AssistantLinkView.strings and b/Classes/ru.lproj/AssistantLinkView.strings differ diff --git a/Classes/ru.lproj/AssistantView.strings b/Classes/ru.lproj/AssistantView.strings index 5ad352a2d..551b98d6b 100644 Binary files a/Classes/ru.lproj/AssistantView.strings and b/Classes/ru.lproj/AssistantView.strings differ diff --git a/Classes/ru.lproj/AssistantViewScreens.strings b/Classes/ru.lproj/AssistantViewScreens.strings index f49f9128b..a0f1f518a 100644 Binary files a/Classes/ru.lproj/AssistantViewScreens.strings and b/Classes/ru.lproj/AssistantViewScreens.strings differ diff --git a/Classes/ru.lproj/CallIncomingView.strings b/Classes/ru.lproj/CallIncomingView.strings index 35bd6d675..f433ea682 100644 Binary files a/Classes/ru.lproj/CallIncomingView.strings and b/Classes/ru.lproj/CallIncomingView.strings differ diff --git a/Classes/ru.lproj/CallOutgoingView.strings b/Classes/ru.lproj/CallOutgoingView.strings index fc68c6947..5e66f9f28 100644 Binary files a/Classes/ru.lproj/CallOutgoingView.strings and b/Classes/ru.lproj/CallOutgoingView.strings differ diff --git a/Classes/ru.lproj/CallView.strings b/Classes/ru.lproj/CallView.strings index 366b14bc1..c3217f4ee 100644 Binary files a/Classes/ru.lproj/CallView.strings and b/Classes/ru.lproj/CallView.strings differ diff --git a/Classes/ru.lproj/CallView~ipad.strings b/Classes/ru.lproj/CallView~ipad.strings index 366b14bc1..7108f5ce4 100644 Binary files a/Classes/ru.lproj/CallView~ipad.strings and b/Classes/ru.lproj/CallView~ipad.strings differ diff --git a/Classes/ru.lproj/ChatConversationCreateView.strings b/Classes/ru.lproj/ChatConversationCreateView.strings index bc1312c47..bdaefb33f 100644 Binary files a/Classes/ru.lproj/ChatConversationCreateView.strings and b/Classes/ru.lproj/ChatConversationCreateView.strings differ diff --git a/Classes/ru.lproj/ChatConversationImdnView.strings b/Classes/ru.lproj/ChatConversationImdnView.strings index c69dd13a4..c9053785e 100644 Binary files a/Classes/ru.lproj/ChatConversationImdnView.strings and b/Classes/ru.lproj/ChatConversationImdnView.strings differ diff --git a/Classes/ru.lproj/ChatConversationInfoView.strings b/Classes/ru.lproj/ChatConversationInfoView.strings index 77b88e76d..8de0928db 100644 Binary files a/Classes/ru.lproj/ChatConversationInfoView.strings and b/Classes/ru.lproj/ChatConversationInfoView.strings differ diff --git a/Classes/ru.lproj/ChatConversationView.strings b/Classes/ru.lproj/ChatConversationView.strings index 8e3f1e998..ea0ff7b07 100644 Binary files a/Classes/ru.lproj/ChatConversationView.strings and b/Classes/ru.lproj/ChatConversationView.strings differ diff --git a/Classes/ru.lproj/ChatsListView.strings b/Classes/ru.lproj/ChatsListView.strings index ef61d7b28..f5adeea9e 100644 Binary files a/Classes/ru.lproj/ChatsListView.strings and b/Classes/ru.lproj/ChatsListView.strings differ diff --git a/Classes/ru.lproj/ContactDetailsView.strings b/Classes/ru.lproj/ContactDetailsView.strings index b5fe41bd1..e19a91292 100644 Binary files a/Classes/ru.lproj/ContactDetailsView.strings and b/Classes/ru.lproj/ContactDetailsView.strings differ diff --git a/Classes/ru.lproj/ContactsListView.strings b/Classes/ru.lproj/ContactsListView.strings index 3818c755e..cd1fed03a 100644 Binary files a/Classes/ru.lproj/ContactsListView.strings and b/Classes/ru.lproj/ContactsListView.strings differ diff --git a/Classes/ru.lproj/CountryListView.strings b/Classes/ru.lproj/CountryListView.strings index dbd4de05f..e0a3d8f8f 100644 Binary files a/Classes/ru.lproj/CountryListView.strings and b/Classes/ru.lproj/CountryListView.strings differ diff --git a/Classes/ru.lproj/DialerView.strings b/Classes/ru.lproj/DialerView.strings index 3ccf318a5..1ce421ca0 100644 Binary files a/Classes/ru.lproj/DialerView.strings and b/Classes/ru.lproj/DialerView.strings differ diff --git a/Classes/ru.lproj/DialerView~ipad.strings b/Classes/ru.lproj/DialerView~ipad.strings index fc76e4951..1da7cd9e8 100644 Binary files a/Classes/ru.lproj/DialerView~ipad.strings and b/Classes/ru.lproj/DialerView~ipad.strings differ diff --git a/Classes/ru.lproj/FirstLoginView.strings b/Classes/ru.lproj/FirstLoginView.strings index 0cef2d481..def64200c 100644 Binary files a/Classes/ru.lproj/FirstLoginView.strings and b/Classes/ru.lproj/FirstLoginView.strings differ diff --git a/Classes/ru.lproj/HistoryDetailsView.strings b/Classes/ru.lproj/HistoryDetailsView.strings index 6dd58ffcb..5eb797adc 100644 Binary files a/Classes/ru.lproj/HistoryDetailsView.strings and b/Classes/ru.lproj/HistoryDetailsView.strings differ diff --git a/Classes/ru.lproj/HistoryListView.strings b/Classes/ru.lproj/HistoryListView.strings index cce605716..22bb61cb3 100644 Binary files a/Classes/ru.lproj/HistoryListView.strings and b/Classes/ru.lproj/HistoryListView.strings differ diff --git a/Classes/ru.lproj/SettingsView.strings b/Classes/ru.lproj/SettingsView.strings index 825bfd1e1..6d0f43acc 100644 Binary files a/Classes/ru.lproj/SettingsView.strings and b/Classes/ru.lproj/SettingsView.strings differ diff --git a/Classes/ru.lproj/ShopView.strings b/Classes/ru.lproj/ShopView.strings index 0620a1096..053e78cb8 100644 Binary files a/Classes/ru.lproj/ShopView.strings and b/Classes/ru.lproj/ShopView.strings differ diff --git a/Classes/ru.lproj/SideMenuView.strings b/Classes/ru.lproj/SideMenuView.strings index 2985951e5..16e47bdbc 100644 Binary files a/Classes/ru.lproj/SideMenuView.strings and b/Classes/ru.lproj/SideMenuView.strings differ diff --git a/Classes/ru.lproj/SideMenuView~ipad.strings b/Classes/ru.lproj/SideMenuView~ipad.strings index fbe432155..767c92271 100644 Binary files a/Classes/ru.lproj/SideMenuView~ipad.strings and b/Classes/ru.lproj/SideMenuView~ipad.strings differ diff --git a/Classes/sv.lproj/AboutView.strings b/Classes/sv.lproj/AboutView.strings index cb52e4464..36bdd7a6a 100644 Binary files a/Classes/sv.lproj/AboutView.strings and b/Classes/sv.lproj/AboutView.strings differ diff --git a/Classes/sv.lproj/AssistantLinkView.strings b/Classes/sv.lproj/AssistantLinkView.strings index e56721bf6..b911b3b73 100644 Binary files a/Classes/sv.lproj/AssistantLinkView.strings and b/Classes/sv.lproj/AssistantLinkView.strings differ diff --git a/Classes/sv.lproj/AssistantView.strings b/Classes/sv.lproj/AssistantView.strings index b4ff158bb..7c7d7fae8 100644 Binary files a/Classes/sv.lproj/AssistantView.strings and b/Classes/sv.lproj/AssistantView.strings differ diff --git a/Classes/sv.lproj/AssistantViewScreens.strings b/Classes/sv.lproj/AssistantViewScreens.strings index 3f25a0653..1ec30815b 100644 Binary files a/Classes/sv.lproj/AssistantViewScreens.strings and b/Classes/sv.lproj/AssistantViewScreens.strings differ diff --git a/Classes/sv.lproj/CallView.strings b/Classes/sv.lproj/CallView.strings index bff7f06f5..1c2825241 100644 Binary files a/Classes/sv.lproj/CallView.strings and b/Classes/sv.lproj/CallView.strings differ diff --git a/Classes/sv.lproj/CallView~ipad.strings b/Classes/sv.lproj/CallView~ipad.strings index bff7f06f5..5e21cf873 100644 Binary files a/Classes/sv.lproj/CallView~ipad.strings and b/Classes/sv.lproj/CallView~ipad.strings differ diff --git a/Classes/sv.lproj/ChatConversationCreateView.strings b/Classes/sv.lproj/ChatConversationCreateView.strings index 2bc2ea72f..563648ef8 100644 Binary files a/Classes/sv.lproj/ChatConversationCreateView.strings and b/Classes/sv.lproj/ChatConversationCreateView.strings differ diff --git a/Classes/sv.lproj/ChatConversationImdnView.strings b/Classes/sv.lproj/ChatConversationImdnView.strings index ec42bdd47..bf9318fc5 100644 Binary files a/Classes/sv.lproj/ChatConversationImdnView.strings and b/Classes/sv.lproj/ChatConversationImdnView.strings differ diff --git a/Classes/sv.lproj/ChatConversationInfoView.strings b/Classes/sv.lproj/ChatConversationInfoView.strings index 8e524399e..8261f1183 100644 Binary files a/Classes/sv.lproj/ChatConversationInfoView.strings and b/Classes/sv.lproj/ChatConversationInfoView.strings differ diff --git a/Classes/sv.lproj/ChatConversationView.strings b/Classes/sv.lproj/ChatConversationView.strings index aa24c93ed..c53f6d2dc 100644 Binary files a/Classes/sv.lproj/ChatConversationView.strings and b/Classes/sv.lproj/ChatConversationView.strings differ diff --git a/Classes/sv.lproj/ChatsListView.strings b/Classes/sv.lproj/ChatsListView.strings index 7620d76c1..903f672cb 100644 Binary files a/Classes/sv.lproj/ChatsListView.strings and b/Classes/sv.lproj/ChatsListView.strings differ diff --git a/Classes/sv.lproj/ContactDetailsView.strings b/Classes/sv.lproj/ContactDetailsView.strings index 95c62e2f3..e4a9f97c6 100644 Binary files a/Classes/sv.lproj/ContactDetailsView.strings and b/Classes/sv.lproj/ContactDetailsView.strings differ diff --git a/Classes/sv.lproj/ContactsListView.strings b/Classes/sv.lproj/ContactsListView.strings index ac8f6bb76..85bde852a 100644 Binary files a/Classes/sv.lproj/ContactsListView.strings and b/Classes/sv.lproj/ContactsListView.strings differ diff --git a/Classes/sv.lproj/CountryListView.strings b/Classes/sv.lproj/CountryListView.strings index dd6155b41..be7e0b848 100644 Binary files a/Classes/sv.lproj/CountryListView.strings and b/Classes/sv.lproj/CountryListView.strings differ diff --git a/Classes/sv.lproj/FirstLoginView.strings b/Classes/sv.lproj/FirstLoginView.strings index c90701b1f..bf7e4ffc3 100644 Binary files a/Classes/sv.lproj/FirstLoginView.strings and b/Classes/sv.lproj/FirstLoginView.strings differ diff --git a/Classes/sv.lproj/HistoryDetailsView.strings b/Classes/sv.lproj/HistoryDetailsView.strings index 931bbb0bf..84a8b1a30 100644 Binary files a/Classes/sv.lproj/HistoryDetailsView.strings and b/Classes/sv.lproj/HistoryDetailsView.strings differ diff --git a/Classes/sv.lproj/HistoryListView.strings b/Classes/sv.lproj/HistoryListView.strings index 18544db61..7c5b42960 100644 Binary files a/Classes/sv.lproj/HistoryListView.strings and b/Classes/sv.lproj/HistoryListView.strings differ diff --git a/Classes/sv.lproj/ShopView.strings b/Classes/sv.lproj/ShopView.strings index 790881116..77ca21f70 100644 Binary files a/Classes/sv.lproj/ShopView.strings and b/Classes/sv.lproj/ShopView.strings differ diff --git a/Classes/tr.lproj/AssistantViewScreens.strings b/Classes/tr.lproj/AssistantViewScreens.strings index 1cd775994..9d8d930c0 100644 Binary files a/Classes/tr.lproj/AssistantViewScreens.strings and b/Classes/tr.lproj/AssistantViewScreens.strings differ diff --git a/Classes/tr.lproj/CallView.strings b/Classes/tr.lproj/CallView.strings index e34846067..bba4cac59 100644 Binary files a/Classes/tr.lproj/CallView.strings and b/Classes/tr.lproj/CallView.strings differ diff --git a/Classes/tr.lproj/CallView~ipad.strings b/Classes/tr.lproj/CallView~ipad.strings index 4e89bd0f2..168baadf3 100644 Binary files a/Classes/tr.lproj/CallView~ipad.strings and b/Classes/tr.lproj/CallView~ipad.strings differ diff --git a/Classes/tr.lproj/ChatsListView.strings b/Classes/tr.lproj/ChatsListView.strings index 85663bcf4..da0f45e2f 100644 Binary files a/Classes/tr.lproj/ChatsListView.strings and b/Classes/tr.lproj/ChatsListView.strings differ diff --git a/Classes/tr.lproj/HistoryDetailsView.strings b/Classes/tr.lproj/HistoryDetailsView.strings index 4c1d31c26..944c29ad2 100644 Binary files a/Classes/tr.lproj/HistoryDetailsView.strings and b/Classes/tr.lproj/HistoryDetailsView.strings differ diff --git a/Classes/uk.lproj/AboutView.strings b/Classes/uk.lproj/AboutView.strings new file mode 100644 index 000000000..8a34a9be8 Binary files /dev/null and b/Classes/uk.lproj/AboutView.strings differ diff --git a/Classes/uk.lproj/AssistantLinkView.strings b/Classes/uk.lproj/AssistantLinkView.strings new file mode 100644 index 000000000..1874bbb60 Binary files /dev/null and b/Classes/uk.lproj/AssistantLinkView.strings differ diff --git a/Classes/uk.lproj/AssistantView.strings b/Classes/uk.lproj/AssistantView.strings new file mode 100644 index 000000000..9df526714 Binary files /dev/null and b/Classes/uk.lproj/AssistantView.strings differ diff --git a/Classes/uk.lproj/AssistantViewScreens.strings b/Classes/uk.lproj/AssistantViewScreens.strings new file mode 100644 index 000000000..8dfdab69a Binary files /dev/null and b/Classes/uk.lproj/AssistantViewScreens.strings differ diff --git a/Classes/uk.lproj/CallIncomingView.strings b/Classes/uk.lproj/CallIncomingView.strings new file mode 100644 index 000000000..6d54b8204 Binary files /dev/null and b/Classes/uk.lproj/CallIncomingView.strings differ diff --git a/Classes/uk.lproj/CallOutgoingView.strings b/Classes/uk.lproj/CallOutgoingView.strings new file mode 100644 index 000000000..46877ee38 Binary files /dev/null and b/Classes/uk.lproj/CallOutgoingView.strings differ diff --git a/Classes/uk.lproj/CallView.strings b/Classes/uk.lproj/CallView.strings new file mode 100644 index 000000000..a0d32550f Binary files /dev/null and b/Classes/uk.lproj/CallView.strings differ diff --git a/Classes/uk.lproj/CallView~ipad.strings b/Classes/uk.lproj/CallView~ipad.strings new file mode 100644 index 000000000..4b61fc909 Binary files /dev/null and b/Classes/uk.lproj/CallView~ipad.strings differ diff --git a/Classes/uk.lproj/ChatConversationCreateView.strings b/Classes/uk.lproj/ChatConversationCreateView.strings new file mode 100644 index 000000000..157fd322b Binary files /dev/null and b/Classes/uk.lproj/ChatConversationCreateView.strings differ diff --git a/Classes/uk.lproj/ChatConversationImdnView.strings b/Classes/uk.lproj/ChatConversationImdnView.strings new file mode 100644 index 000000000..1e7158caf Binary files /dev/null and b/Classes/uk.lproj/ChatConversationImdnView.strings differ diff --git a/Classes/uk.lproj/ChatConversationInfoView.strings b/Classes/uk.lproj/ChatConversationInfoView.strings new file mode 100644 index 000000000..36bba7452 Binary files /dev/null and b/Classes/uk.lproj/ChatConversationInfoView.strings differ diff --git a/Classes/uk.lproj/ChatConversationView.strings b/Classes/uk.lproj/ChatConversationView.strings new file mode 100644 index 000000000..aac05227f Binary files /dev/null and b/Classes/uk.lproj/ChatConversationView.strings differ diff --git a/Classes/uk.lproj/ChatsListView.strings b/Classes/uk.lproj/ChatsListView.strings new file mode 100644 index 000000000..b590bca46 Binary files /dev/null and b/Classes/uk.lproj/ChatsListView.strings differ diff --git a/Classes/uk.lproj/ContactDetailsView.strings b/Classes/uk.lproj/ContactDetailsView.strings new file mode 100644 index 000000000..ddfd15e3c Binary files /dev/null and b/Classes/uk.lproj/ContactDetailsView.strings differ diff --git a/Classes/uk.lproj/ContactsListView.strings b/Classes/uk.lproj/ContactsListView.strings new file mode 100644 index 000000000..8c7faa0d2 Binary files /dev/null and b/Classes/uk.lproj/ContactsListView.strings differ diff --git a/Classes/uk.lproj/CountryListView.strings b/Classes/uk.lproj/CountryListView.strings new file mode 100644 index 000000000..1c20f7a25 Binary files /dev/null and b/Classes/uk.lproj/CountryListView.strings differ diff --git a/Classes/uk.lproj/DialerView.strings b/Classes/uk.lproj/DialerView.strings new file mode 100644 index 000000000..3daa0ddc0 Binary files /dev/null and b/Classes/uk.lproj/DialerView.strings differ diff --git a/Classes/uk.lproj/DialerView~ipad.strings b/Classes/uk.lproj/DialerView~ipad.strings new file mode 100644 index 000000000..5a3ea4c64 Binary files /dev/null and b/Classes/uk.lproj/DialerView~ipad.strings differ diff --git a/Classes/uk.lproj/FirstLoginView.strings b/Classes/uk.lproj/FirstLoginView.strings new file mode 100644 index 000000000..6bbb063f6 Binary files /dev/null and b/Classes/uk.lproj/FirstLoginView.strings differ diff --git a/Classes/uk.lproj/HistoryDetailsView.strings b/Classes/uk.lproj/HistoryDetailsView.strings new file mode 100644 index 000000000..b0806b8ef Binary files /dev/null and b/Classes/uk.lproj/HistoryDetailsView.strings differ diff --git a/Classes/uk.lproj/HistoryListView.strings b/Classes/uk.lproj/HistoryListView.strings new file mode 100644 index 000000000..82555fd50 Binary files /dev/null and b/Classes/uk.lproj/HistoryListView.strings differ diff --git a/Classes/uk.lproj/ImageView.strings b/Classes/uk.lproj/ImageView.strings new file mode 100644 index 000000000..b20eefbff Binary files /dev/null and b/Classes/uk.lproj/ImageView.strings differ diff --git a/Classes/uk.lproj/SettingsView.strings b/Classes/uk.lproj/SettingsView.strings new file mode 100644 index 000000000..d43c4ef91 Binary files /dev/null and b/Classes/uk.lproj/SettingsView.strings differ diff --git a/Classes/uk.lproj/ShopView.strings b/Classes/uk.lproj/ShopView.strings new file mode 100644 index 000000000..48af54cdb Binary files /dev/null and b/Classes/uk.lproj/ShopView.strings differ diff --git a/Classes/uk.lproj/SideMenuView.strings b/Classes/uk.lproj/SideMenuView.strings new file mode 100644 index 000000000..2fd20c6a8 Binary files /dev/null and b/Classes/uk.lproj/SideMenuView.strings differ diff --git a/Classes/uk.lproj/SideMenuView~ipad.strings b/Classes/uk.lproj/SideMenuView~ipad.strings new file mode 100644 index 000000000..d1980668d Binary files /dev/null and b/Classes/uk.lproj/SideMenuView~ipad.strings differ diff --git a/Classes/zh_CN.lproj/AssistantViewScreens.strings b/Classes/zh_CN.lproj/AssistantViewScreens.strings index 0fd1efbf9..fd787b547 100644 Binary files a/Classes/zh_CN.lproj/AssistantViewScreens.strings and b/Classes/zh_CN.lproj/AssistantViewScreens.strings differ diff --git a/Classes/zh_CN.lproj/CallView.strings b/Classes/zh_CN.lproj/CallView.strings index ca77a6177..1b0270967 100644 Binary files a/Classes/zh_CN.lproj/CallView.strings and b/Classes/zh_CN.lproj/CallView.strings differ diff --git a/Classes/zh_CN.lproj/CallView~ipad.strings b/Classes/zh_CN.lproj/CallView~ipad.strings index 017289e1f..013f8faca 100644 Binary files a/Classes/zh_CN.lproj/CallView~ipad.strings and b/Classes/zh_CN.lproj/CallView~ipad.strings differ diff --git a/Classes/zh_CN.lproj/ChatsListView.strings b/Classes/zh_CN.lproj/ChatsListView.strings index 1d5d3d39a..7bd04c740 100644 Binary files a/Classes/zh_CN.lproj/ChatsListView.strings and b/Classes/zh_CN.lproj/ChatsListView.strings differ diff --git a/Classes/zh_CN.lproj/HistoryDetailsView.strings b/Classes/zh_CN.lproj/HistoryDetailsView.strings index 4e1c3d6c2..6388539d9 100644 Binary files a/Classes/zh_CN.lproj/HistoryDetailsView.strings and b/Classes/zh_CN.lproj/HistoryDetailsView.strings differ diff --git a/Classes/zh_TW.lproj/AssistantViewScreens.strings b/Classes/zh_TW.lproj/AssistantViewScreens.strings index 95ce07506..d22115a9d 100644 Binary files a/Classes/zh_TW.lproj/AssistantViewScreens.strings and b/Classes/zh_TW.lproj/AssistantViewScreens.strings differ diff --git a/Classes/zh_TW.lproj/CallView.strings b/Classes/zh_TW.lproj/CallView.strings index 1e542d651..4238dc63d 100644 Binary files a/Classes/zh_TW.lproj/CallView.strings and b/Classes/zh_TW.lproj/CallView.strings differ diff --git a/Classes/zh_TW.lproj/CallView~ipad.strings b/Classes/zh_TW.lproj/CallView~ipad.strings index fc558476d..f7f369f1c 100644 Binary files a/Classes/zh_TW.lproj/CallView~ipad.strings and b/Classes/zh_TW.lproj/CallView~ipad.strings differ diff --git a/Classes/zh_TW.lproj/ChatsListView.strings b/Classes/zh_TW.lproj/ChatsListView.strings index 92d59f925..ace9c07d6 100644 Binary files a/Classes/zh_TW.lproj/ChatsListView.strings and b/Classes/zh_TW.lproj/ChatsListView.strings differ diff --git a/Classes/zh_TW.lproj/HistoryDetailsView.strings b/Classes/zh_TW.lproj/HistoryDetailsView.strings index 712e6c37d..2deb22cd4 100644 Binary files a/Classes/zh_TW.lproj/HistoryDetailsView.strings and b/Classes/zh_TW.lproj/HistoryDetailsView.strings differ diff --git a/GoogleService-Info.plist b/GoogleService-Info.plist new file mode 100644 index 000000000..e3fe76c08 --- /dev/null +++ b/GoogleService-Info.plist @@ -0,0 +1,24 @@ + + + + + AD_UNIT_ID_FOR_BANNER_TEST + + AD_UNIT_ID_FOR_INTERSTITIAL_TEST + + CLIENT_ID + + REVERSED_CLIENT_ID + + API_KEY + + GCM_SENDER_ID + + BUNDLE_ID + + PROJECT_ID + + STORAGE_BUCKET + + + diff --git a/LiblinphoneTester/DetailTableView.m b/LiblinphoneTester/DetailTableView.m index a5873164b..784564265 100644 --- a/LiblinphoneTester/DetailTableView.m +++ b/LiblinphoneTester/DetailTableView.m @@ -215,8 +215,9 @@ static NSString *const kAllTestsName = @"Run All tests"; LOGI(@"Test Passed!"); test.state = TestStatePassed; } - [self.tableView scrollToRowAtIndexPath:index atScrollPosition:UITableViewScrollPositionMiddle animated:YES]; + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + [self.tableView scrollToRowAtIndexPath:index atScrollPosition:UITableViewScrollPositionMiddle animated:YES]; [self updateItem:paths withAnimation:TRUE]; }); } diff --git a/LiblinphoneTester/MasterView.m b/LiblinphoneTester/MasterView.m index f12532d63..3aefe7b55 100644 --- a/LiblinphoneTester/MasterView.m +++ b/LiblinphoneTester/MasterView.m @@ -31,31 +31,22 @@ [super awakeFromNib]; } -- (void)setupLogging { - [Log enableLogs:ORTP_DEBUG]; - linphone_core_enable_log_collection(YES); -} - -void tester_logs_handler(int level, const char *fmt, va_list args) { - linphone_iphone_log_handler("Tester", level, fmt, args); -} - - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. self.detailViewController = (DetailTableView *)[[self.splitViewController.viewControllers lastObject] topViewController]; - //[self setupLogging]; + liblinphone_tester_init(NULL); + [Log enableLogs:ORTP_DEBUG]; liblinphone_tester_keep_accounts(TRUE); - bundlePath = [[NSBundle mainBundle] bundlePath]; + bundlePath = [NSString stringWithFormat:@"%@/liblinphone_tester/", [[NSBundle mainBundle] bundlePath]]; NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES); writablePath = [paths objectAtIndex:0]; - liblinphone_tester_init(NULL); + // bc_tester_init(tester_logs_handler, ORTP_MESSAGE, ORTP_ERROR, "rcfiles"); // liblinphone_tester_add_suites(); - linphone_core_set_log_level_mask((OrtpLogLevel)(ORTP_MESSAGE | ORTP_WARNING | ORTP_ERROR | ORTP_FATAL)); bc_tester_set_resource_dir_prefix([bundlePath UTF8String]); bc_tester_set_writable_dir_prefix([writablePath UTF8String]); @@ -63,16 +54,7 @@ void tester_logs_handler(int level, const char *fmt, va_list args) { LOGI(@"Bundle path: %@", bundlePath); LOGI(@"Writable path: %@", writablePath); -#if TARGET_OS_SIMULATOR - char *xmlFile = bc_tester_file("LibLinphoneIOS.xml"); - char *args[] = {"--xml-file", xmlFile}; - bc_tester_parse_args(2, args, 0); - - char *logFile = bc_tester_file("LibLinphoneIOS.txt"); - liblinphone_tester_set_log_file(logFile); -#endif - - liblinphonetester_ipv6 = true; + //liblinphonetester_ipv6 = true; int count = bc_tester_nb_suites(); _objects = [[NSMutableArray alloc] initWithCapacity:count + 1]; diff --git a/LiblinphoneTester/main.m b/LiblinphoneTester/main.m index 8c5f1d3d6..857c258f0 100644 --- a/LiblinphoneTester/main.m +++ b/LiblinphoneTester/main.m @@ -8,6 +8,9 @@ #import #import "AppDelegate.h" +#import "Log.h" +#import +#include "linphonetester/liblinphone_tester.h" #ifdef DEBUG @@ -24,6 +27,23 @@ int main(int argc, char *argv[]) { #ifdef DEBUG NSSetUncaughtExceptionHandler(&uncaughtExceptionHandler); #endif + int i; + for(i = 1; i < argc; ++i) { + if (strcmp(argv[i], "--verbose") == 0) { + linphone_core_set_log_level(ORTP_MESSAGE); + } else if (strcmp(argv[i],"--log-file")==0){ +#if TARGET_OS_SIMULATOR + char *xmlFile = bc_tester_file("LibLinphoneIOS.xml"); + char *args[] = {"--xml-file", xmlFile}; + bc_tester_parse_args(2, args, 0); + + char *logFile = bc_tester_file("LibLinphoneIOS.txt"); + liblinphone_tester_set_log_file(logFile); +#endif + } else if (strcmp(argv[i],"--no-ipv6")==0){ + liblinphonetester_ipv6 = FALSE; + } + } @autoreleasepool { return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); } diff --git a/Podfile b/Podfile new file mode 100644 index 000000000..dae3067a7 --- /dev/null +++ b/Podfile @@ -0,0 +1,125 @@ +# Uncomment the next line to define a global platform for your project +platform :ios, '9.0' +source "https://gitlab.linphone.org/BC/public/podspec.git" +source "https://github.com/CocoaPods/Specs.git" + +def basic_pods + if ENV['PODFILE_PATH'].nil? + pod 'linphone-sdk', '~> 4.1-366-g1b22291' + else + pod 'linphone-sdk', :path => ENV['PODFILE_PATH'] # loacl sdk + end + + if not ENV['USE_CRASHLYTHICS'].nil? + # activate crashlythics + pod 'Firebase/Core' + pod 'Fabric', '~> 1.9.0' + pod 'Crashlytics', '~> 3.12.0' + pod 'Firebase/Performance' + end +end + +target 'liblinphoneTester' do + # Uncomment the next line if you're using Swift or would like to use dynamic frameworks + use_frameworks! + + # Pods for liblinphoneTester + basic_pods + + target 'liblinphoneTesterTests' do + inherit! :search_paths + # Pods for testing + end + +end + +target 'linphone' do + # Uncomment the next line if you're using Swift or would like to use dynamic frameworks + use_frameworks! + + # Pods for linphone + basic_pods + pod 'SVProgressHUD' + + target 'linphoneTests' do + inherit! :search_paths + # Pods for testing + end + +end + +target 'linphoneExtension' do + # Uncomment the next line if you're using Swift or would like to use dynamic frameworks + use_frameworks! + + # Pods for linphoneExtension + +end + +=begin +target 'latestCallsWidget' do + # Uncomment the next line if you're using Swift or would like to use dynamic frameworks + use_frameworks! + + # Pods for latestCallsWidget + +end + +target 'latestChatroomsWidget' do + # Uncomment the next line if you're using Swift or would like to use dynamic frameworks + use_frameworks! + + # Pods for latestChatroomsWidget +end + + +target 'richNotifications' do + # Uncomment the next line if you're using Swift or would like to use dynamic frameworks + use_frameworks! + + # Pods for richNotifications + +end +=end + +post_install do |installer| + # Get the version of linphone-sdk + installer.pod_targets.each do |target| + if target.pod_name == 'linphone-sdk' + target.specs.each do |spec| + $linphone_sdk_version = spec.version + end + end + end + + app_project = Xcodeproj::Project.open(Dir.glob("*.xcodeproj")[0]) + app_project.native_targets.each do |target| + if target.name == 'linphone' + target.build_configurations.each do |config| + if ENV['USE_CRASHLYTHICS'].nil? + if config.name == "Debug" then + config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] = '$(inherited) DEBUG=1' + else + config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] = '$(inherited)' + end + else + # activate crashlythics + if config.name == "Debug" then + config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] = '$(inherited) DEBUG=1 USE_CRASHLYTHICSS=1' + else + config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] = '$(inherited) USE_CRASHLYTHICSS=1' + end + end + + config.build_settings['OTHER_CFLAGS'] = '-DBCTBX_LOG_DOMAIN=\"ios\"', + '-DCHECK_VERSION_UPDATE=FALSE', + '-DENABLE_QRCODE=TRUE', + '-DENABLE_SMS_INVITE=TRUE', + '$(inherited)', + "-DLINPHONE_SDK_VERSION=\\\"#{$linphone_sdk_version}\\\"" + + app_project.save + end + end + end +end diff --git a/README.md b/README.md index 50ec7eccb..0daad0031 100644 --- a/README.md +++ b/README.md @@ -24,12 +24,10 @@ If you want to dig through Linphone code or report a bug, please read `CONTRIBUT ## How to be a beta tester ? Enter the Beta : - - Download TestFlight from the App Store and log in it with your apple-id - - Send an email to linphone-iphone@belledonne-communications.com, with object : [Beta test - Request], where you precise your apple-id you logged in TestFlight with - - You will receive an invitation code to the beta in the following days via your email associated to your apple-id - - Enter the invitation code received into TestFlight - - Download Linphone from TestFlight - - And voilà ! TestFlight will send you a notification every time a new beta test is available. +- Download TestFlight from the App Store and log in it with your apple-id +-Tap the public link on your iOS device. The public link : https://testflight.apple.com/join/LUlmZWjH +-Touch View in TestFlight or Start Testing. You can also touch Accept, Install, or Update for Linphone app. +-And voilà ! You can update your beta version with the same public link when a new one is available Send a crash report : - It is done automatically by TestFlight @@ -46,108 +44,70 @@ Report a bug : - Change the object to [Beta test - Bug report] - Send the mail -# Building and customizing the SDK - -Linphone for iPhone depends on liblinphone SDK. This SDK is generated from makefiles and shell scripts. - - Steps to customize the liblinphone SDK options are: - - 1. Install [HomeBrew, a package manager for OS X](http://brew.sh) (MacPorts is supported but deprecated). - 2. Install Linphone dependencies: open iTerm.app in the current directory and list dependencies to install using: - `./prepare.py` - 3. Reorder your path so that brew tools are used instead of Apple's ones which are obsolete: - `export PATH=/usr/local/bin:$PATH` - 4. Build SDK (see below for options and explanations): - `./prepare.py -c && ./prepare.py && make` - - For instance to generate the liblinphone multi-arch SDK in GPL mode, simply invoke: - - ./prepare.py [options] && make - -**The resulting SDK is located in `liblinphone-sdk/` root directory.** - -## Incorporating our SDK in your project - -After the SDK has been built, add all the `.framework` files located in `liblinphone-sdk/apple-darwin/Frameworks` to your XCode project Embedded Frameworks and linked binaries. -Make sure that your project FRAMEWORK_SEARCH_PATHS contains "$(PROJECT_DIR)/liblinphone-sdk/apple-darwin/Frameworks" -Make sure that your project LD_RUNPATH_SEARCH_PATHS contains "$(inherited) @executable_path/Frameworks"; -Add a Run Script step to your build steps, put it after your step to embed frameworks, set it to use our `deploy.sh` script located in the `Tools` folder of linphone-iphone root directory. - -## Licensing: GPL third parties versus non GPL third parties - -This SDK can be generated in 2 flavors: - -* GPL third parties enabled means that liblinphone includes GPL third parties like FFmpeg. If you choose this flavor, your final application **must comply with GPL in any case**. This is the default mode. - -* NO GPL third parties means that Linphone will only use non GPL code except for `liblinphone`, `mediastreamer2`, `oRTP` and `belle-sip`. If you choose this flavor, your final application is **still subject to GPL except if you have a [commercial license for the mentioned libraries](http://www.belledonne-communications.com/products.html)**. - To generate the liblinphone multi arch SDK without GPL third parties, invoke: - - ./prepare.py -DENABLE_GPL_THIRD_PARTIES=NO -DENABLE_FFMPEG=NO [other options] && make - -## Customizing features - -You can enable non-free codecs by using `-DENABLE_NON_FREE_CODECS=ON` and `-DENABLE_=ON`. To get a list of all features, the simplest way is to invoke `prepare.py` with `--list-features`: - - ./prepare.py --list-features - -You can for instance enable X264 using: - - ./prepare.py -DENABLE_NON_FREE_CODECS=ON -DENABLE_X264=ON [other options] - -## Built architectures - -4 architectures currently exists on iOS: - -- 64 bits ARM64 for iPhone 5s, iPad Air, iPad mini 2, iPhone 6, iPhone 6 Plus, iPad Air 2, iPad mini 3. -- 32 bits ARMv7 for older devices. -- 64 bits x86_64 for simulator for all ARM64 devices. -- 32 bits i386 for simulator for all ARMv7 older devices. - - Note: We are not compiling for the 32 bits i386 simulator by default because Xcode default device (iPhone 6) runs in 64 bits. If you want to enable it, you should invoke `prepare.py` with `i386` argument: `./prepare.py i386 [other options]`. - -## Upgrading your iOS SDK - -Simply re-invoking `make` should update your SDK. If compilation fails, you may need to rebuilding everything by invoking: - - ./prepare.py -c && ./prepare.py [options] && make - # Building the application -After the SDK is built, just open the Linphone Xcode project with Xcode, and press `Run`. +## What's new -## Note regarding third party components subject to license +Now the default way of building linphone-iphone is to use CocoaPods to retrieve the linphone-sdk frameworks. +Compared to previous versions, this project no longer uses submodules developper has to build in order to get a working app. +However, if you wish to use a locally compiled SDK, read paragraph "Using a local linphone SDK" below to know how to proceed. - The liblinphone SDK is compiled with third parties code that are subject to patent license, specially: AMR, SILK G729 and H264 codecs. - Linphone controls the embedding of these codecs by generating dummy libraries when there are not available. You can enable them using `prepare.py` - script (see `-DENABLE_NON_FREE_CODECS=OFF` option). Before embedding these 4 codecs in the final application, **make sure to have the right to do so**. +## Building the app + +If you don't have CocoaPods already, you can download and install it using : +``` + sudo gem install cocoapods +``` + +- Install the app's dependencies with cocoapods first: +``` + pod install +``` + It will download the linphone-sdk from our gitlab repository so you don't have to build anything yourself. +- Then open `linphone.xcworkspace` file (**NOT linphone.xcodeproj**) with XCode to build and run the app. # Testing the application -We are using the KIF framework to test the UI of Linphone. It is used as a submodule (instead of CocoaPods) for ease. - -Simply press `⌘U` and the default simulator / device will launch and try to pass all the tests. +We are using the Xcode test navigator to test the UI of Linphone. +Change the Scheme to LinphoneTester. Press the test navigator button and all the tests will show. +See: https://developer.apple.com/library/archive/documentation/DeveloperTools/Conceptual/testing_with_xcode/chapters/05-running_tests.html # Limitations and known bugs * Video capture will not work in simulator (not implemented in it). -# Debugging the SDK -Sometime it can be useful to step into liblinphone SDK functions. To allow Xcode to enable breakpoint within liblinphone, SDK must be built with debug symbols by using option `--debug`: +# Using a local linphone SDK - ./prepare.py --debug [other options] && make +- Clone the linphone-sdk repository from out gitlab: +``` + git clone https://gitlab.linphone.org/BC/public/linphone-sdk.git --recursive +``` -## Debugging mediastreamer2 +- Follow the instructions in the linphone-sdk/README file to build the SDK. -For iOS specific media development like audio video capture/playback it may be interesting to use `mediastream` test tool. -You can build it using the following: +- Rebuild the project: +``` + PODFILE_PATH= pod install +``` + where is your build directory of the linphone-sdk project, containing the `linphone-sdk.podspec` file and a `linphone-sdk` ouptut directory comprising built frameworks and resources. - ./prepare.py -G Xcode -g && make - # then open the project for a given architecture (here x86_64, to run on simulator): - open WORK/ios-x86_64/Build/linphone_builder/EP_linphone_builder.xcodeproj +- Then open linphone.xcworkspace with Xcode to build and run the app. -Then you can select mediastream target and launch it on device. You can configure scheme to pass custom parameters. +# Enabling crashlythics + +We've integrated Crashlythics into liphone-iphone, which can automatically send crash reports. It is disabled by default. +To activate it: + +- Replace the GoogleService-Info.plist for this project with yours (specific to your crashlytics account). + +- Rebuild the project: +``` + USE_CRASHLYTHICS=true pod install +``` +` +- Then open `linphone.xcworkspace` with Xcode to build and run the app. # Quick UI reference diff --git a/Resources/ar.lproj/Localizable.strings b/Resources/ar.lproj/Localizable.strings index 903f73d6c..e44719c9b 100644 Binary files a/Resources/ar.lproj/Localizable.strings and b/Resources/ar.lproj/Localizable.strings differ diff --git a/Resources/assistant_linphone_create.rc b/Resources/assistant_linphone_create.rc index ff9143579..ab962dde8 100644 --- a/Resources/assistant_linphone_create.rc +++ b/Resources/assistant_linphone_create.rc @@ -36,4 +36,7 @@ 1 ^[a-z0-9+_.\-]*$ +
+ https://lime.linphone.org/lime-server/lime-server.php +
diff --git a/Resources/assistant_linphone_existing.rc b/Resources/assistant_linphone_existing.rc index b0e2068dc..c427675e8 100644 --- a/Resources/assistant_linphone_existing.rc +++ b/Resources/assistant_linphone_existing.rc @@ -37,4 +37,7 @@ ^[a-z0-9+_.\-]*$ https://subscribe.linphone.org:444/wizard.php +
+ https://lime.linphone.org/lime-server/lime-server.php +
diff --git a/Resources/cs.lproj/Localizable.strings b/Resources/cs.lproj/Localizable.strings new file mode 100644 index 000000000..db1873874 Binary files /dev/null and b/Resources/cs.lproj/Localizable.strings differ diff --git a/Resources/de.lproj/Localizable.strings b/Resources/de.lproj/Localizable.strings index 395794683..7e2638334 100644 Binary files a/Resources/de.lproj/Localizable.strings and b/Resources/de.lproj/Localizable.strings differ diff --git a/Resources/en.lproj/Localizable.strings b/Resources/en.lproj/Localizable.strings index c533f2ec3..b7f9ddaba 100644 Binary files a/Resources/en.lproj/Localizable.strings and b/Resources/en.lproj/Localizable.strings differ diff --git a/Resources/es.lproj/Localizable.strings b/Resources/es.lproj/Localizable.strings index 258e5b524..d2f3221b6 100644 Binary files a/Resources/es.lproj/Localizable.strings and b/Resources/es.lproj/Localizable.strings differ diff --git a/Resources/es_AR.lproj/Localizable.strings b/Resources/es_AR.lproj/Localizable.strings index 8e4658176..3c751d8e8 100644 Binary files a/Resources/es_AR.lproj/Localizable.strings and b/Resources/es_AR.lproj/Localizable.strings differ diff --git a/Resources/fr.lproj/Localizable.strings b/Resources/fr.lproj/Localizable.strings index 2af0c21fd..0102c0a47 100644 Binary files a/Resources/fr.lproj/Localizable.strings and b/Resources/fr.lproj/Localizable.strings differ diff --git a/Resources/images/chat_add_default.png b/Resources/images/chat_add_default.png index 1c0fccebf..e481b4337 100644 Binary files a/Resources/images/chat_add_default.png and b/Resources/images/chat_add_default.png differ diff --git a/Resources/images/chat_add_default@2x.png b/Resources/images/chat_add_default@2x.png index fd7c444c7..9c60be92d 100644 Binary files a/Resources/images/chat_add_default@2x.png and b/Resources/images/chat_add_default@2x.png differ diff --git a/Resources/images/chat_add_group.png b/Resources/images/chat_add_group.png new file mode 100644 index 000000000..721a3d7e5 Binary files /dev/null and b/Resources/images/chat_add_group.png differ diff --git a/Resources/images/chat_add_group@2x.png b/Resources/images/chat_add_group@2x.png new file mode 100644 index 000000000..9d2013833 Binary files /dev/null and b/Resources/images/chat_add_group@2x.png differ diff --git a/Resources/images/chat_delivered.png b/Resources/images/chat_delivered.png index 9d741055d..356b8ecd1 100644 Binary files a/Resources/images/chat_delivered.png and b/Resources/images/chat_delivered.png differ diff --git a/Resources/images/chat_error.png b/Resources/images/chat_error.png index 3791317c2..b7789c9a0 100644 Binary files a/Resources/images/chat_error.png and b/Resources/images/chat_error.png differ diff --git a/Resources/images/chat_list_indicator.png b/Resources/images/chat_list_indicator.png new file mode 100644 index 000000000..3e51b8857 Binary files /dev/null and b/Resources/images/chat_list_indicator.png differ diff --git a/Resources/images/chat_list_indicator@2x.png b/Resources/images/chat_list_indicator@2x.png new file mode 100644 index 000000000..3e51b8857 Binary files /dev/null and b/Resources/images/chat_list_indicator@2x.png differ diff --git a/Resources/images/chat_read.png b/Resources/images/chat_read.png index b7ae0d29a..8f8f467c1 100644 Binary files a/Resources/images/chat_read.png and b/Resources/images/chat_read.png differ diff --git a/Resources/images/chevron_list_close.png b/Resources/images/chevron_list_close.png new file mode 100644 index 000000000..a82d1d38b Binary files /dev/null and b/Resources/images/chevron_list_close.png differ diff --git a/Resources/images/chevron_list_close@2x.png b/Resources/images/chevron_list_close@2x.png new file mode 100644 index 000000000..893c9c77b Binary files /dev/null and b/Resources/images/chevron_list_close@2x.png differ diff --git a/Resources/images/chevron_list_open.png b/Resources/images/chevron_list_open.png new file mode 100644 index 000000000..f1ec597cf Binary files /dev/null and b/Resources/images/chevron_list_open.png differ diff --git a/Resources/images/chevron_list_open@2x.png b/Resources/images/chevron_list_open@2x.png new file mode 100644 index 000000000..a5b95a924 Binary files /dev/null and b/Resources/images/chevron_list_open@2x.png differ diff --git a/Resources/images/invite_linphone.png b/Resources/images/invite_linphone.png new file mode 100644 index 000000000..20606be43 Binary files /dev/null and b/Resources/images/invite_linphone.png differ diff --git a/Resources/images/invite_linphone@2x.png b/Resources/images/invite_linphone@2x.png new file mode 100644 index 000000000..20606be43 Binary files /dev/null and b/Resources/images/invite_linphone@2x.png differ diff --git a/Resources/images/menu_about.png b/Resources/images/menu_about.png new file mode 100644 index 000000000..0fccc59c1 Binary files /dev/null and b/Resources/images/menu_about.png differ diff --git a/Resources/images/menu_about@2x.png b/Resources/images/menu_about@2x.png new file mode 100644 index 000000000..f4c1115c0 Binary files /dev/null and b/Resources/images/menu_about@2x.png differ diff --git a/Resources/images/menu_assistant.png b/Resources/images/menu_assistant.png new file mode 100644 index 000000000..f5f432e16 Binary files /dev/null and b/Resources/images/menu_assistant.png differ diff --git a/Resources/images/menu_assistant@2x.png b/Resources/images/menu_assistant@2x.png new file mode 100644 index 000000000..a79bba4c0 Binary files /dev/null and b/Resources/images/menu_assistant@2x.png differ diff --git a/Resources/images/menu_link_account.png b/Resources/images/menu_link_account.png new file mode 100644 index 000000000..0b84e1478 Binary files /dev/null and b/Resources/images/menu_link_account.png differ diff --git a/Resources/images/menu_link_account@2x.png b/Resources/images/menu_link_account@2x.png new file mode 100644 index 000000000..2b266ea63 Binary files /dev/null and b/Resources/images/menu_link_account@2x.png differ diff --git a/Resources/images/menu_options.png b/Resources/images/menu_options.png new file mode 100644 index 000000000..e123c23e8 Binary files /dev/null and b/Resources/images/menu_options.png differ diff --git a/Resources/images/menu_options@2x.png b/Resources/images/menu_options@2x.png new file mode 100644 index 000000000..a9a8fe427 Binary files /dev/null and b/Resources/images/menu_options@2x.png differ diff --git a/Resources/images/menu_recordings.png b/Resources/images/menu_recordings.png new file mode 100644 index 000000000..65f7f1331 Binary files /dev/null and b/Resources/images/menu_recordings.png differ diff --git a/Resources/images/menu_recordings@2x.png b/Resources/images/menu_recordings@2x.png new file mode 100644 index 000000000..47e658bc5 Binary files /dev/null and b/Resources/images/menu_recordings@2x.png differ diff --git a/Resources/images/rec_off_default.png b/Resources/images/rec_off_default.png new file mode 100644 index 000000000..55ab37a87 Binary files /dev/null and b/Resources/images/rec_off_default.png differ diff --git a/Resources/images/rec_off_default@2x.png b/Resources/images/rec_off_default@2x.png new file mode 100644 index 000000000..b41988ca6 Binary files /dev/null and b/Resources/images/rec_off_default@2x.png differ diff --git a/Resources/images/rec_on_default.png b/Resources/images/rec_on_default.png new file mode 100644 index 000000000..a2db83deb Binary files /dev/null and b/Resources/images/rec_on_default.png differ diff --git a/Resources/images/rec_on_default@2x.png b/Resources/images/rec_on_default@2x.png new file mode 100644 index 000000000..2a01c5973 Binary files /dev/null and b/Resources/images/rec_on_default@2x.png differ diff --git a/Resources/images/recording.png b/Resources/images/recording.png new file mode 100644 index 000000000..a214abd94 Binary files /dev/null and b/Resources/images/recording.png differ diff --git a/Resources/images/recording@2x.png b/Resources/images/recording@2x.png new file mode 100644 index 000000000..a8827fef9 Binary files /dev/null and b/Resources/images/recording@2x.png differ diff --git a/Resources/images/security_1_indicator.png b/Resources/images/security_1_indicator.png new file mode 100644 index 000000000..0aa4a2e04 Binary files /dev/null and b/Resources/images/security_1_indicator.png differ diff --git a/Resources/images/security_1_indicator@2x.png b/Resources/images/security_1_indicator@2x.png new file mode 100644 index 000000000..0aa4a2e04 Binary files /dev/null and b/Resources/images/security_1_indicator@2x.png differ diff --git a/Resources/images/security_2_indicator.png b/Resources/images/security_2_indicator.png new file mode 100644 index 000000000..910e3d124 Binary files /dev/null and b/Resources/images/security_2_indicator.png differ diff --git a/Resources/images/security_2_indicator@2x.png b/Resources/images/security_2_indicator@2x.png new file mode 100644 index 000000000..910e3d124 Binary files /dev/null and b/Resources/images/security_2_indicator@2x.png differ diff --git a/Resources/images/security_alert_indicator.png b/Resources/images/security_alert_indicator.png new file mode 100644 index 000000000..54a340667 Binary files /dev/null and b/Resources/images/security_alert_indicator.png differ diff --git a/Resources/images/security_alert_indicator@2x.png b/Resources/images/security_alert_indicator@2x.png new file mode 100644 index 000000000..54a340667 Binary files /dev/null and b/Resources/images/security_alert_indicator@2x.png differ diff --git a/Resources/images/security_toogle_background_green.png b/Resources/images/security_toogle_background_green.png new file mode 100644 index 000000000..2a01da72e Binary files /dev/null and b/Resources/images/security_toogle_background_green.png differ diff --git a/Resources/images/security_toogle_background_green@2x.png b/Resources/images/security_toogle_background_green@2x.png new file mode 100644 index 000000000..2a01da72e Binary files /dev/null and b/Resources/images/security_toogle_background_green@2x.png differ diff --git a/Resources/images/security_toogle_background_grey.png b/Resources/images/security_toogle_background_grey.png new file mode 100644 index 000000000..6ff74ca8b Binary files /dev/null and b/Resources/images/security_toogle_background_grey.png differ diff --git a/Resources/images/security_toogle_background_grey@2x.png b/Resources/images/security_toogle_background_grey@2x.png new file mode 100644 index 000000000..6ff74ca8b Binary files /dev/null and b/Resources/images/security_toogle_background_grey@2x.png differ diff --git a/Resources/images/security_toogle_button.png b/Resources/images/security_toogle_button.png new file mode 100644 index 000000000..b2d565561 Binary files /dev/null and b/Resources/images/security_toogle_button.png differ diff --git a/Resources/images/security_toogle_button@2x.png b/Resources/images/security_toogle_button@2x.png new file mode 100644 index 000000000..b2d565561 Binary files /dev/null and b/Resources/images/security_toogle_button@2x.png differ diff --git a/Resources/images/security_toogle_icon_green.png b/Resources/images/security_toogle_icon_green.png new file mode 100644 index 000000000..c8b537fe2 Binary files /dev/null and b/Resources/images/security_toogle_icon_green.png differ diff --git a/Resources/images/security_toogle_icon_green@2x.png b/Resources/images/security_toogle_icon_green@2x.png new file mode 100644 index 000000000..320dd4570 Binary files /dev/null and b/Resources/images/security_toogle_icon_green@2x.png differ diff --git a/Resources/images/security_toogle_icon_grey.png b/Resources/images/security_toogle_icon_grey.png new file mode 100644 index 000000000..61514c02b Binary files /dev/null and b/Resources/images/security_toogle_icon_grey.png differ diff --git a/Resources/images/security_toogle_icon_grey@2x.png b/Resources/images/security_toogle_icon_grey@2x.png new file mode 100644 index 000000000..8627c1ab9 Binary files /dev/null and b/Resources/images/security_toogle_icon_grey@2x.png differ diff --git a/Resources/it.lproj/Localizable.strings b/Resources/it.lproj/Localizable.strings new file mode 100644 index 000000000..0ae764f96 Binary files /dev/null and b/Resources/it.lproj/Localizable.strings differ diff --git a/Resources/ja.lproj/Localizable.strings b/Resources/ja.lproj/Localizable.strings index 8fbc68dcf..75c51b4ad 100644 Binary files a/Resources/ja.lproj/Localizable.strings and b/Resources/ja.lproj/Localizable.strings differ diff --git a/Resources/ka.lproj/Localizable.strings b/Resources/ka.lproj/Localizable.strings index d1aabbead..634fd94e0 100644 Binary files a/Resources/ka.lproj/Localizable.strings and b/Resources/ka.lproj/Localizable.strings differ diff --git a/Resources/linphonerc b/Resources/linphonerc index 65c31b407..8da793545 100644 --- a/Resources/linphonerc +++ b/Resources/linphonerc @@ -14,6 +14,8 @@ stun_preference=stun.linphone.org voiceproc_preference=1 repeat_call_notification=1 display_phone_only=0 +auto_download_incoming_files_max_size=0 +lime_migration_done=0 [in_app_purchase] #set to 1 if in-app purchases are to be shown in the application @@ -47,6 +49,7 @@ reg_expires=1314000 file_transfer_server_url=https://www.linphone.org:444/lft.php max_calls=3 real_early_media=1 +prefer_basic_chat_room=0 [net] edge_bw=10 diff --git a/Resources/linphonerc-factory b/Resources/linphonerc-factory index 6316e5bcc..33477010c 100644 --- a/Resources/linphonerc-factory +++ b/Resources/linphonerc-factory @@ -23,6 +23,8 @@ send_logs_include_linphonerc_and_chathistory=0 publish_presence=0 backgroundmode_preference=0 +accept_early_media=0 + [assistant] password_length=-1 username_length=-1 @@ -37,7 +39,7 @@ sip_random_port=0 #whether SIP passwords must be encrypted in configuration storage file store_ha1_passwd=0 deliver_imdn=1 -linphone_specs=groupchat +linphone_specs=groupchat,lime #to avoid app to not detect broken sockets when in long running task. tcp_tls_keepalive=30000 @@ -47,6 +49,7 @@ history_max_size=-1 enable_basic_to_client_group_chat_room_migration=0 aggregate_imdn=1 version_check_url_root=https://linphone.org/releases +prefer_basic_chat_room=0 [sound] dtmf_player_amp=0.007 @@ -57,3 +60,4 @@ ringer_dev_id=AQ: Audio Queue Device [video] display_filter_auto_rotate=0 + diff --git a/Resources/nl.lproj/Localizable.strings b/Resources/nl.lproj/Localizable.strings index c1a1f93c6..ffb1aa037 100644 Binary files a/Resources/nl.lproj/Localizable.strings and b/Resources/nl.lproj/Localizable.strings differ diff --git a/Resources/pl.lproj/Localizable.strings b/Resources/pl.lproj/Localizable.strings index 2988a8631..a1e9ea4c0 100644 Binary files a/Resources/pl.lproj/Localizable.strings and b/Resources/pl.lproj/Localizable.strings differ diff --git a/Resources/pt_BR.lproj/Localizable.strings b/Resources/pt_BR.lproj/Localizable.strings index e70052dc8..52b155b20 100644 Binary files a/Resources/pt_BR.lproj/Localizable.strings and b/Resources/pt_BR.lproj/Localizable.strings differ diff --git a/Resources/ru.lproj/Localizable.strings b/Resources/ru.lproj/Localizable.strings index 767166b34..6708f04e1 100644 Binary files a/Resources/ru.lproj/Localizable.strings and b/Resources/ru.lproj/Localizable.strings differ diff --git a/Resources/sv.lproj/Localizable.strings b/Resources/sv.lproj/Localizable.strings index 3b36a711b..46622b787 100644 Binary files a/Resources/sv.lproj/Localizable.strings and b/Resources/sv.lproj/Localizable.strings differ diff --git a/Resources/tr.lproj/Localizable.strings b/Resources/tr.lproj/Localizable.strings index 9e08a0fe3..23f65bd9f 100644 Binary files a/Resources/tr.lproj/Localizable.strings and b/Resources/tr.lproj/Localizable.strings differ diff --git a/Resources/uk.lproj/Localizable.strings b/Resources/uk.lproj/Localizable.strings new file mode 100644 index 000000000..c551e1649 Binary files /dev/null and b/Resources/uk.lproj/Localizable.strings differ diff --git a/Resources/zh_CN.lproj/Localizable.strings b/Resources/zh_CN.lproj/Localizable.strings index 16d50ec0e..b3a13cfd9 100644 Binary files a/Resources/zh_CN.lproj/Localizable.strings and b/Resources/zh_CN.lproj/Localizable.strings differ diff --git a/Resources/zh_TW.lproj/Localizable.strings b/Resources/zh_TW.lproj/Localizable.strings new file mode 100644 index 000000000..8d5e8f0dd Binary files /dev/null and b/Resources/zh_TW.lproj/Localizable.strings differ diff --git a/Settings/InAppSettings.bundle/Call.plist b/Settings/InAppSettings.bundle/Call.plist index d7c407cc8..8438e369e 100644 --- a/Settings/InAppSettings.bundle/Call.plist +++ b/Settings/InAppSettings.bundle/Call.plist @@ -88,6 +88,16 @@ Type PSToggleSwitchSpecifier + + DefaultValue + + Key + pref_accept_early_media_preference + Title + Accept early-media + Type + PSToggleSwitchSpecifier + diff --git a/Settings/InAppSettings.bundle/Chat.plist b/Settings/InAppSettings.bundle/Chat.plist index 17739d229..7a79b86d0 100644 --- a/Settings/InAppSettings.bundle/Chat.plist +++ b/Settings/InAppSettings.bundle/Chat.plist @@ -4,6 +4,42 @@ PreferenceSpecifiers + + DefaultValue + Never + Key + auto_download_mode + Title + Auto download incoming files policy + Titles + + Never + Always + If lighter than max size + + Type + PSMultiValueSpecifier + Values + + Never + Always + Customize + + + + Key + auto_download_incoming_files_max_size + Title + Max size (in bytes) + DefaultValue + -1 + Type + PSTextFieldSpecifier + KeyboardType + NumbersAndPunctuation + IASKTextAlignment + IASKUITextAlignmentRight + DefaultValue 0 diff --git a/Settings/InAppSettings.bundle/ar.lproj/Chat.strings b/Settings/InAppSettings.bundle/ar.lproj/Chat.strings index dc2602135..669e88953 100644 Binary files a/Settings/InAppSettings.bundle/ar.lproj/Chat.strings and b/Settings/InAppSettings.bundle/ar.lproj/Chat.strings differ diff --git a/Settings/InAppSettings.bundle/ar.lproj/Video.strings b/Settings/InAppSettings.bundle/ar.lproj/Video.strings index 3f7ecd87a..072ab4225 100644 Binary files a/Settings/InAppSettings.bundle/ar.lproj/Video.strings and b/Settings/InAppSettings.bundle/ar.lproj/Video.strings differ diff --git a/Settings/InAppSettings.bundle/cs.lproj/Root.strings b/Settings/InAppSettings.bundle/cs.lproj/Root.strings new file mode 100644 index 000000000..09866ecda Binary files /dev/null and b/Settings/InAppSettings.bundle/cs.lproj/Root.strings differ diff --git a/Settings/InAppSettings.bundle/de.lproj/Chat.strings b/Settings/InAppSettings.bundle/de.lproj/Chat.strings index ed6dea56e..93750fd27 100644 Binary files a/Settings/InAppSettings.bundle/de.lproj/Chat.strings and b/Settings/InAppSettings.bundle/de.lproj/Chat.strings differ diff --git a/Settings/InAppSettings.bundle/de.lproj/Video.strings b/Settings/InAppSettings.bundle/de.lproj/Video.strings index f18b0d635..a95779d89 100644 Binary files a/Settings/InAppSettings.bundle/de.lproj/Video.strings and b/Settings/InAppSettings.bundle/de.lproj/Video.strings differ diff --git a/Settings/InAppSettings.bundle/en.lproj/Chat.strings b/Settings/InAppSettings.bundle/en.lproj/Chat.strings index 51086e9f7..7e1f8f803 100644 --- a/Settings/InAppSettings.bundle/en.lproj/Chat.strings +++ b/Settings/InAppSettings.bundle/en.lproj/Chat.strings @@ -1,3 +1,5 @@ +"Auto download incoming files policy" = "Auto download incoming files policy"; +"Max size (in bytes)" = "Max size (in bytes)"; "Encrypt messages with LIME" = "Encrypt messages with LIME"; "File sharing" = "File sharing"; "Server URL" = "Server URL"; diff --git a/Settings/InAppSettings.bundle/en.lproj/Video.strings b/Settings/InAppSettings.bundle/en.lproj/Video.strings index 6beb39c51..c570eda5d 100644 --- a/Settings/InAppSettings.bundle/en.lproj/Video.strings +++ b/Settings/InAppSettings.bundle/en.lproj/Video.strings @@ -9,4 +9,5 @@ "Codecs" = "Codecs"; "VP8" = "VP8"; "H.264" = "H.264"; +"H.265" = "H.265"; "MPEG-4" = "MPEG-4"; diff --git a/Settings/InAppSettings.bundle/es.lproj/Chat.strings b/Settings/InAppSettings.bundle/es.lproj/Chat.strings index 82b1fe1de..978a935e5 100644 Binary files a/Settings/InAppSettings.bundle/es.lproj/Chat.strings and b/Settings/InAppSettings.bundle/es.lproj/Chat.strings differ diff --git a/Settings/InAppSettings.bundle/es.lproj/Video.strings b/Settings/InAppSettings.bundle/es.lproj/Video.strings index 59314e3db..125d843eb 100644 Binary files a/Settings/InAppSettings.bundle/es.lproj/Video.strings and b/Settings/InAppSettings.bundle/es.lproj/Video.strings differ diff --git a/Settings/InAppSettings.bundle/es_AR.lproj/Chat.strings b/Settings/InAppSettings.bundle/es_AR.lproj/Chat.strings index 82b1fe1de..978a935e5 100644 Binary files a/Settings/InAppSettings.bundle/es_AR.lproj/Chat.strings and b/Settings/InAppSettings.bundle/es_AR.lproj/Chat.strings differ diff --git a/Settings/InAppSettings.bundle/es_AR.lproj/Video.strings b/Settings/InAppSettings.bundle/es_AR.lproj/Video.strings index 59314e3db..125d843eb 100644 Binary files a/Settings/InAppSettings.bundle/es_AR.lproj/Video.strings and b/Settings/InAppSettings.bundle/es_AR.lproj/Video.strings differ diff --git a/Settings/InAppSettings.bundle/fr.lproj/Call.strings b/Settings/InAppSettings.bundle/fr.lproj/Call.strings index 7ba96833f..6a37d55a0 100644 Binary files a/Settings/InAppSettings.bundle/fr.lproj/Call.strings and b/Settings/InAppSettings.bundle/fr.lproj/Call.strings differ diff --git a/Settings/InAppSettings.bundle/fr.lproj/Chat.strings b/Settings/InAppSettings.bundle/fr.lproj/Chat.strings index 90ebcafc7..848ad3e21 100644 Binary files a/Settings/InAppSettings.bundle/fr.lproj/Chat.strings and b/Settings/InAppSettings.bundle/fr.lproj/Chat.strings differ diff --git a/Settings/InAppSettings.bundle/fr.lproj/Video.strings b/Settings/InAppSettings.bundle/fr.lproj/Video.strings index a36edef6d..56f07a118 100644 Binary files a/Settings/InAppSettings.bundle/fr.lproj/Video.strings and b/Settings/InAppSettings.bundle/fr.lproj/Video.strings differ diff --git a/Settings/InAppSettings.bundle/it.lproj/Account.strings b/Settings/InAppSettings.bundle/it.lproj/Account.strings new file mode 100644 index 000000000..63656d194 Binary files /dev/null and b/Settings/InAppSettings.bundle/it.lproj/Account.strings differ diff --git a/Settings/InAppSettings.bundle/it.lproj/Advanced.strings b/Settings/InAppSettings.bundle/it.lproj/Advanced.strings new file mode 100644 index 000000000..da183468b Binary files /dev/null and b/Settings/InAppSettings.bundle/it.lproj/Advanced.strings differ diff --git a/Settings/InAppSettings.bundle/it.lproj/Audio.strings b/Settings/InAppSettings.bundle/it.lproj/Audio.strings new file mode 100644 index 000000000..4fcc0a5b0 Binary files /dev/null and b/Settings/InAppSettings.bundle/it.lproj/Audio.strings differ diff --git a/Settings/InAppSettings.bundle/it.lproj/Call.strings b/Settings/InAppSettings.bundle/it.lproj/Call.strings new file mode 100644 index 000000000..e7347da39 Binary files /dev/null and b/Settings/InAppSettings.bundle/it.lproj/Call.strings differ diff --git a/Settings/InAppSettings.bundle/it.lproj/Chat.strings b/Settings/InAppSettings.bundle/it.lproj/Chat.strings new file mode 100644 index 000000000..0d63a3a17 Binary files /dev/null and b/Settings/InAppSettings.bundle/it.lproj/Chat.strings differ diff --git a/Settings/InAppSettings.bundle/it.lproj/Network.strings b/Settings/InAppSettings.bundle/it.lproj/Network.strings new file mode 100644 index 000000000..9eb37c6c1 Binary files /dev/null and b/Settings/InAppSettings.bundle/it.lproj/Network.strings differ diff --git a/Settings/InAppSettings.bundle/it.lproj/Root.strings b/Settings/InAppSettings.bundle/it.lproj/Root.strings new file mode 100644 index 000000000..495c4d1af Binary files /dev/null and b/Settings/InAppSettings.bundle/it.lproj/Root.strings differ diff --git a/Settings/InAppSettings.bundle/it.lproj/Tunnel.strings b/Settings/InAppSettings.bundle/it.lproj/Tunnel.strings new file mode 100644 index 000000000..fa7385fe5 Binary files /dev/null and b/Settings/InAppSettings.bundle/it.lproj/Tunnel.strings differ diff --git a/Settings/InAppSettings.bundle/it.lproj/Video.strings b/Settings/InAppSettings.bundle/it.lproj/Video.strings new file mode 100644 index 000000000..f4ea4d485 Binary files /dev/null and b/Settings/InAppSettings.bundle/it.lproj/Video.strings differ diff --git a/Settings/InAppSettings.bundle/ja.lproj/Audio.strings b/Settings/InAppSettings.bundle/ja.lproj/Audio.strings index d3571c9a5..bf0f4210b 100644 Binary files a/Settings/InAppSettings.bundle/ja.lproj/Audio.strings and b/Settings/InAppSettings.bundle/ja.lproj/Audio.strings differ diff --git a/Settings/InAppSettings.bundle/ja.lproj/Chat.strings b/Settings/InAppSettings.bundle/ja.lproj/Chat.strings index fc8c7bb2e..f62486f46 100644 Binary files a/Settings/InAppSettings.bundle/ja.lproj/Chat.strings and b/Settings/InAppSettings.bundle/ja.lproj/Chat.strings differ diff --git a/Settings/InAppSettings.bundle/ja.lproj/Video.strings b/Settings/InAppSettings.bundle/ja.lproj/Video.strings index a777309a3..1a736e8e5 100644 Binary files a/Settings/InAppSettings.bundle/ja.lproj/Video.strings and b/Settings/InAppSettings.bundle/ja.lproj/Video.strings differ diff --git a/Settings/InAppSettings.bundle/ka.lproj/Chat.strings b/Settings/InAppSettings.bundle/ka.lproj/Chat.strings index b5cabd720..66984f5b5 100644 Binary files a/Settings/InAppSettings.bundle/ka.lproj/Chat.strings and b/Settings/InAppSettings.bundle/ka.lproj/Chat.strings differ diff --git a/Settings/InAppSettings.bundle/ka.lproj/Video.strings b/Settings/InAppSettings.bundle/ka.lproj/Video.strings index b217afe27..d3933e77a 100644 Binary files a/Settings/InAppSettings.bundle/ka.lproj/Video.strings and b/Settings/InAppSettings.bundle/ka.lproj/Video.strings differ diff --git a/Settings/InAppSettings.bundle/nl.lproj/Chat.strings b/Settings/InAppSettings.bundle/nl.lproj/Chat.strings index 8f40f2244..2a3697347 100644 Binary files a/Settings/InAppSettings.bundle/nl.lproj/Chat.strings and b/Settings/InAppSettings.bundle/nl.lproj/Chat.strings differ diff --git a/Settings/InAppSettings.bundle/nl.lproj/Video.strings b/Settings/InAppSettings.bundle/nl.lproj/Video.strings index 969a55455..533b5eb72 100644 Binary files a/Settings/InAppSettings.bundle/nl.lproj/Video.strings and b/Settings/InAppSettings.bundle/nl.lproj/Video.strings differ diff --git a/Settings/InAppSettings.bundle/pl.lproj/Chat.strings b/Settings/InAppSettings.bundle/pl.lproj/Chat.strings index 95c447d76..0f3fe9178 100644 Binary files a/Settings/InAppSettings.bundle/pl.lproj/Chat.strings and b/Settings/InAppSettings.bundle/pl.lproj/Chat.strings differ diff --git a/Settings/InAppSettings.bundle/pl.lproj/Video.strings b/Settings/InAppSettings.bundle/pl.lproj/Video.strings index cd54104e5..1a4693cd5 100644 Binary files a/Settings/InAppSettings.bundle/pl.lproj/Video.strings and b/Settings/InAppSettings.bundle/pl.lproj/Video.strings differ diff --git a/Settings/InAppSettings.bundle/pt_BR.lproj/Advanced.strings b/Settings/InAppSettings.bundle/pt_BR.lproj/Advanced.strings index eafbe8e2b..2738578b3 100644 Binary files a/Settings/InAppSettings.bundle/pt_BR.lproj/Advanced.strings and b/Settings/InAppSettings.bundle/pt_BR.lproj/Advanced.strings differ diff --git a/Settings/InAppSettings.bundle/pt_BR.lproj/Chat.strings b/Settings/InAppSettings.bundle/pt_BR.lproj/Chat.strings index b6de012ff..ef4434f19 100644 Binary files a/Settings/InAppSettings.bundle/pt_BR.lproj/Chat.strings and b/Settings/InAppSettings.bundle/pt_BR.lproj/Chat.strings differ diff --git a/Settings/InAppSettings.bundle/pt_BR.lproj/Video.strings b/Settings/InAppSettings.bundle/pt_BR.lproj/Video.strings index fffa6f2a6..f4a60a062 100644 Binary files a/Settings/InAppSettings.bundle/pt_BR.lproj/Video.strings and b/Settings/InAppSettings.bundle/pt_BR.lproj/Video.strings differ diff --git a/Settings/InAppSettings.bundle/ru.lproj/Account.strings b/Settings/InAppSettings.bundle/ru.lproj/Account.strings index cf8c34072..f1126856b 100644 Binary files a/Settings/InAppSettings.bundle/ru.lproj/Account.strings and b/Settings/InAppSettings.bundle/ru.lproj/Account.strings differ diff --git a/Settings/InAppSettings.bundle/ru.lproj/Advanced.strings b/Settings/InAppSettings.bundle/ru.lproj/Advanced.strings index e340e2dd7..fe502064f 100644 Binary files a/Settings/InAppSettings.bundle/ru.lproj/Advanced.strings and b/Settings/InAppSettings.bundle/ru.lproj/Advanced.strings differ diff --git a/Settings/InAppSettings.bundle/ru.lproj/Call.strings b/Settings/InAppSettings.bundle/ru.lproj/Call.strings index e87d0e697..af07c512c 100644 Binary files a/Settings/InAppSettings.bundle/ru.lproj/Call.strings and b/Settings/InAppSettings.bundle/ru.lproj/Call.strings differ diff --git a/Settings/InAppSettings.bundle/ru.lproj/Chat.strings b/Settings/InAppSettings.bundle/ru.lproj/Chat.strings index 2e78b595d..66fb372ae 100644 Binary files a/Settings/InAppSettings.bundle/ru.lproj/Chat.strings and b/Settings/InAppSettings.bundle/ru.lproj/Chat.strings differ diff --git a/Settings/InAppSettings.bundle/ru.lproj/Network.strings b/Settings/InAppSettings.bundle/ru.lproj/Network.strings index 23a58a798..36587602b 100644 Binary files a/Settings/InAppSettings.bundle/ru.lproj/Network.strings and b/Settings/InAppSettings.bundle/ru.lproj/Network.strings differ diff --git a/Settings/InAppSettings.bundle/ru.lproj/Root.strings b/Settings/InAppSettings.bundle/ru.lproj/Root.strings index 4c3371f00..74631aa1f 100644 Binary files a/Settings/InAppSettings.bundle/ru.lproj/Root.strings and b/Settings/InAppSettings.bundle/ru.lproj/Root.strings differ diff --git a/Settings/InAppSettings.bundle/ru.lproj/Tunnel.strings b/Settings/InAppSettings.bundle/ru.lproj/Tunnel.strings index a53a82ffa..73d270b3a 100644 Binary files a/Settings/InAppSettings.bundle/ru.lproj/Tunnel.strings and b/Settings/InAppSettings.bundle/ru.lproj/Tunnel.strings differ diff --git a/Settings/InAppSettings.bundle/ru.lproj/Video.strings b/Settings/InAppSettings.bundle/ru.lproj/Video.strings index 974772188..53c428c75 100644 Binary files a/Settings/InAppSettings.bundle/ru.lproj/Video.strings and b/Settings/InAppSettings.bundle/ru.lproj/Video.strings differ diff --git a/Settings/InAppSettings.bundle/sv.lproj/Account.strings b/Settings/InAppSettings.bundle/sv.lproj/Account.strings index c3d6e397f..8b43f49ec 100644 Binary files a/Settings/InAppSettings.bundle/sv.lproj/Account.strings and b/Settings/InAppSettings.bundle/sv.lproj/Account.strings differ diff --git a/Settings/InAppSettings.bundle/sv.lproj/Advanced.strings b/Settings/InAppSettings.bundle/sv.lproj/Advanced.strings index 52d30c491..e17fca473 100644 Binary files a/Settings/InAppSettings.bundle/sv.lproj/Advanced.strings and b/Settings/InAppSettings.bundle/sv.lproj/Advanced.strings differ diff --git a/Settings/InAppSettings.bundle/sv.lproj/Audio.strings b/Settings/InAppSettings.bundle/sv.lproj/Audio.strings index 2b5575b44..c0e7eb516 100644 Binary files a/Settings/InAppSettings.bundle/sv.lproj/Audio.strings and b/Settings/InAppSettings.bundle/sv.lproj/Audio.strings differ diff --git a/Settings/InAppSettings.bundle/sv.lproj/Call.strings b/Settings/InAppSettings.bundle/sv.lproj/Call.strings index 400d46c2c..6692e23e5 100644 Binary files a/Settings/InAppSettings.bundle/sv.lproj/Call.strings and b/Settings/InAppSettings.bundle/sv.lproj/Call.strings differ diff --git a/Settings/InAppSettings.bundle/sv.lproj/Chat.strings b/Settings/InAppSettings.bundle/sv.lproj/Chat.strings index eb6b0530a..76e92ff28 100644 Binary files a/Settings/InAppSettings.bundle/sv.lproj/Chat.strings and b/Settings/InAppSettings.bundle/sv.lproj/Chat.strings differ diff --git a/Settings/InAppSettings.bundle/sv.lproj/Network.strings b/Settings/InAppSettings.bundle/sv.lproj/Network.strings index f01a883e4..20842d98a 100644 Binary files a/Settings/InAppSettings.bundle/sv.lproj/Network.strings and b/Settings/InAppSettings.bundle/sv.lproj/Network.strings differ diff --git a/Settings/InAppSettings.bundle/sv.lproj/Root.strings b/Settings/InAppSettings.bundle/sv.lproj/Root.strings index d9ac69972..636b256c6 100644 Binary files a/Settings/InAppSettings.bundle/sv.lproj/Root.strings and b/Settings/InAppSettings.bundle/sv.lproj/Root.strings differ diff --git a/Settings/InAppSettings.bundle/sv.lproj/Video.strings b/Settings/InAppSettings.bundle/sv.lproj/Video.strings index e9ffbe04e..34256b495 100644 Binary files a/Settings/InAppSettings.bundle/sv.lproj/Video.strings and b/Settings/InAppSettings.bundle/sv.lproj/Video.strings differ diff --git a/Settings/InAppSettings.bundle/tr.lproj/Chat.strings b/Settings/InAppSettings.bundle/tr.lproj/Chat.strings index dacd59ae5..28162cb46 100644 Binary files a/Settings/InAppSettings.bundle/tr.lproj/Chat.strings and b/Settings/InAppSettings.bundle/tr.lproj/Chat.strings differ diff --git a/Settings/InAppSettings.bundle/tr.lproj/Video.strings b/Settings/InAppSettings.bundle/tr.lproj/Video.strings index 0e82d86ce..b6f430d2a 100644 Binary files a/Settings/InAppSettings.bundle/tr.lproj/Video.strings and b/Settings/InAppSettings.bundle/tr.lproj/Video.strings differ diff --git a/Settings/InAppSettings.bundle/uk.lproj/Account.strings b/Settings/InAppSettings.bundle/uk.lproj/Account.strings new file mode 100644 index 000000000..0a3a5cca1 Binary files /dev/null and b/Settings/InAppSettings.bundle/uk.lproj/Account.strings differ diff --git a/Settings/InAppSettings.bundle/uk.lproj/Advanced.strings b/Settings/InAppSettings.bundle/uk.lproj/Advanced.strings new file mode 100644 index 000000000..dc11c697b Binary files /dev/null and b/Settings/InAppSettings.bundle/uk.lproj/Advanced.strings differ diff --git a/Settings/InAppSettings.bundle/uk.lproj/Audio.strings b/Settings/InAppSettings.bundle/uk.lproj/Audio.strings new file mode 100644 index 000000000..c0b68a11a Binary files /dev/null and b/Settings/InAppSettings.bundle/uk.lproj/Audio.strings differ diff --git a/Settings/InAppSettings.bundle/uk.lproj/Call.strings b/Settings/InAppSettings.bundle/uk.lproj/Call.strings new file mode 100644 index 000000000..0bee7934b Binary files /dev/null and b/Settings/InAppSettings.bundle/uk.lproj/Call.strings differ diff --git a/Settings/InAppSettings.bundle/uk.lproj/Chat.strings b/Settings/InAppSettings.bundle/uk.lproj/Chat.strings new file mode 100644 index 000000000..34c9596be Binary files /dev/null and b/Settings/InAppSettings.bundle/uk.lproj/Chat.strings differ diff --git a/Settings/InAppSettings.bundle/uk.lproj/Network.strings b/Settings/InAppSettings.bundle/uk.lproj/Network.strings new file mode 100644 index 000000000..bfea05457 Binary files /dev/null and b/Settings/InAppSettings.bundle/uk.lproj/Network.strings differ diff --git a/Settings/InAppSettings.bundle/uk.lproj/Root.strings b/Settings/InAppSettings.bundle/uk.lproj/Root.strings new file mode 100644 index 000000000..4d1eea03a Binary files /dev/null and b/Settings/InAppSettings.bundle/uk.lproj/Root.strings differ diff --git a/Settings/InAppSettings.bundle/uk.lproj/Tunnel.strings b/Settings/InAppSettings.bundle/uk.lproj/Tunnel.strings new file mode 100644 index 000000000..8089ce91d Binary files /dev/null and b/Settings/InAppSettings.bundle/uk.lproj/Tunnel.strings differ diff --git a/Settings/InAppSettings.bundle/uk.lproj/Video.strings b/Settings/InAppSettings.bundle/uk.lproj/Video.strings new file mode 100644 index 000000000..1cbb0ce9d Binary files /dev/null and b/Settings/InAppSettings.bundle/uk.lproj/Video.strings differ diff --git a/Settings/InAppSettings.bundle/zh_CN.lproj/Chat.strings b/Settings/InAppSettings.bundle/zh_CN.lproj/Chat.strings index 85c20e465..513757feb 100644 Binary files a/Settings/InAppSettings.bundle/zh_CN.lproj/Chat.strings and b/Settings/InAppSettings.bundle/zh_CN.lproj/Chat.strings differ diff --git a/Settings/InAppSettings.bundle/zh_CN.lproj/Video.strings b/Settings/InAppSettings.bundle/zh_CN.lproj/Video.strings index ff2ab71f9..09b1c54b6 100644 Binary files a/Settings/InAppSettings.bundle/zh_CN.lproj/Video.strings and b/Settings/InAppSettings.bundle/zh_CN.lproj/Video.strings differ diff --git a/Settings/InAppSettings.bundle/zh_TW.lproj/Chat.strings b/Settings/InAppSettings.bundle/zh_TW.lproj/Chat.strings index 664103d80..f99db8f96 100644 Binary files a/Settings/InAppSettings.bundle/zh_TW.lproj/Chat.strings and b/Settings/InAppSettings.bundle/zh_TW.lproj/Chat.strings differ diff --git a/Settings/InAppSettings.bundle/zh_TW.lproj/Video.strings b/Settings/InAppSettings.bundle/zh_TW.lproj/Video.strings index 44c90eac3..085e40d1f 100644 Binary files a/Settings/InAppSettings.bundle/zh_TW.lproj/Video.strings and b/Settings/InAppSettings.bundle/zh_TW.lproj/Video.strings differ diff --git a/TestsLiblinphone/LinphoneTester_Tests.m b/TestsLiblinphone/LinphoneTester_Tests.m index badded809..bb2493121 100644 --- a/TestsLiblinphone/LinphoneTester_Tests.m +++ b/TestsLiblinphone/LinphoneTester_Tests.m @@ -12,55 +12,366 @@ #import "NSObject+DTRuntime.h" #import "Utils.h" #import "Log.h" - -@interface LinphoneTester_Tests : XCTestCase +extern bool_t liblinphonetester_ipv6; +@interface LinphoneTesterBase : XCTestCase @end -@implementation LinphoneTester_Tests +@implementation LinphoneTesterBase + (NSString *)safetyTestString:(NSString *)testString { NSCharacterSet *charactersToRemove = [[NSCharacterSet alphanumericCharacterSet] invertedSet]; return [[testString componentsSeparatedByCharactersInSet:charactersToRemove] componentsJoinedByString:@"_"]; } + void dummy_logger(const char *domain, OrtpLogLevel lev, const char *fmt, va_list args) { } + (void)initialize { - // turn off ALL logs because xcodebuild has problems with it - // linphone_core_enable_logs_with_cb(dummy_logger); - bc_tester_start(NULL); - bc_tester_uninit(); - /*for (int i = 0; i < bc_tester_nb_suites(); i++) { - const char *suite = bc_tester_suite_name(i); - LOGE(@"suite = %s", suite); - int test_count = bc_tester_nb_tests(suite); - for (int k = 0; k < test_count; k++) { - const char *test = bc_tester_test_name(suite, k); - LOGE(@"\ttest = %s", test); - if (suite) { - NSString *sSuite = [NSString stringWithUTF8String:suite]; - if (test) { - NSString *sTest = [NSString stringWithUTF8String:test]; - - // prepend "test_" so that it gets found by introspection - NSString *safesTest = [self safetyTestString:sTest]; - NSString *safesSuite = [self safetyTestString:sSuite]; - NSString *selectorName = [NSString stringWithFormat:@"test_%@__%@", safesSuite, safesTest]; - - [LinphoneTester_Tests addInstanceMethodWithSelectorName:selectorName - block:^(LinphoneTester_Tests *myself) { - [myself testForSuite:sSuite andTest:sTest]; - }]; - } - } - } - }*/ } -- (void)testForSuite:(NSString *)suite andTest:(NSString *)test { - LOGI(@"Launching test %@ from suite %@", test, suite); ++ (void)testForSuite:(NSString *)sSuite { + LOGI(@"[message] Launching tests from suite %@", sSuite); + const char *suite = sSuite.UTF8String; + bc_tester_register_suite_by_name(suite); + int test_count = bc_tester_nb_tests(suite); + for (int k = 0; k < test_count; k++) { + const char *test = bc_tester_test_name(suite, k); + if (test) { + NSString *sTest = [NSString stringWithUTF8String:test]; + + // prepend "test_" so that it gets found by introspection + NSString *safesTest = [LinphoneTesterBase safetyTestString:sTest]; + NSString *safesSuite = [LinphoneTesterBase safetyTestString:sSuite]; + // ordering tests + NSString *safesIndex = nil; + if (k < 10) { + safesIndex = [NSString stringWithFormat:@"00%d",k]; + } else if (k <100) { + safesIndex = [NSString stringWithFormat:@"0%d",k]; + } else if (k <1000) { + safesIndex = [NSString stringWithFormat:@"%d",k]; + } + NSString *selectorName = [NSString stringWithFormat:@"test%@_%@__%@", safesIndex, safesSuite, safesTest]; + + [self addInstanceMethodWithSelectorName:selectorName + block:^(LinphoneTesterBase *myself) { + [myself testForSuiteTest:sSuite andTest:sTest]; + }]; + } + } +} + +- (void)testForSuiteTest:(NSString *)suite andTest:(NSString *)test { + LOGI(@"[message] Launching test %@ from suite %@", test, suite); XCTAssertFalse(bc_tester_run_tests(suite.UTF8String, test.UTF8String, NULL), @"Suite '%@' / Test '%@' failed", suite, test); } @end + +@interface SetupTests : LinphoneTesterBase +@end + +@implementation SetupTests ++ (void)initialize { + [self testForSuite:@"Setup"]; +} +@end + +@interface TunnelTests : LinphoneTesterBase +@end + +@implementation TunnelTests ++ (void)initialize { + [self testForSuite:@"Tunnel"]; +} +@end + +@interface OfferAnswerTests : LinphoneTesterBase +@end + +@implementation OfferAnswerTests ++ (void)initialize { + [self testForSuite:@"Offer-answer"]; +} +@end + +@interface PresenceTests : LinphoneTesterBase +@end + +@implementation PresenceTests ++ (void)initialize { + [self testForSuite:@"Presence"]; +} +@end + +@interface AccountCreatorTests : LinphoneTesterBase +@end + +@implementation AccountCreatorTests ++ (void)initialize { + [self testForSuite:@"Account creator"]; +} +@end + +@interface ConferenceEventTests : LinphoneTesterBase +@end + +@implementation ConferenceEventTests ++ (void)initialize { + [self testForSuite:@"Conference event"]; +} +@end + +@interface LogCollectionTests : LinphoneTesterBase +@end + +@implementation LogCollectionTests ++ (void)initialize { + [self testForSuite:@"LogCollection"]; +} +@end + +@interface PlayerTests : LinphoneTesterBase +@end + +@implementation PlayerTests ++ (void)initialize { + [self testForSuite:@"Player"]; +} +@end + +@interface DTMFTests : LinphoneTesterBase +@end + +@implementation DTMFTests ++ (void)initialize { + [self testForSuite:@"DTMF"]; +} +@end + +/*@interface CpimTests : LinphoneTesterBase +@end + +@implementation CpimTests ++ (void)initialize { + [self testForSuite:@"Cpim"]; +} +@end*/ + +@interface MultipartTests : LinphoneTesterBase +@end + +@implementation MultipartTests ++ (void)initialize { + [self testForSuite:@"Multipart"]; +} +@end + +@interface ClonableObjectTests : LinphoneTesterBase +@end + +@implementation ClonableObjectTests ++ (void)initialize { + [self testForSuite:@"ClonableObject"]; +} +@end + +@interface MainDbTests : LinphoneTesterBase +@end + +@implementation MainDbTests ++ (void)initialize { + [self testForSuite:@"MainDb"]; +} +@end + +@interface PropertyContainerTests : LinphoneTesterBase +@end + +@implementation PropertyContainerTests ++ (void)initialize { + [self testForSuite:@"PropertyContainer"]; +} +@end + +@interface ProxyConfigTests : LinphoneTesterBase +@end + +@implementation ProxyConfigTests ++ (void)initialize { + [self testForSuite:@"Proxy config"]; +} +@end + +@interface VCardTests : LinphoneTesterBase +@end + +@implementation VCardTests ++ (void)initialize { + [self testForSuite:@"VCard"]; +} +@end + +@interface VideoCallTests : LinphoneTesterBase +@end + +@implementation VideoCallTests ++ (void)initialize { + [self testForSuite:@"Video Call"]; +} +@end + +@interface AudioBypassTests : LinphoneTesterBase +@end + +@implementation AudioBypassTests ++ (void)initialize { + [self testForSuite:@"Audio Bypass"]; +} +@end + +@interface ContentsTests : LinphoneTesterBase +@end + +@implementation ContentsTests ++ (void)initialize { + [self testForSuite:@"Contents"]; +} +@end + +@interface VideoTests : LinphoneTesterBase +@end + +@implementation VideoTests ++ (void)initialize { + [self testForSuite:@"Video"]; +} +@end + +@interface MulticastCallTests : LinphoneTesterBase +@end + +@implementation MulticastCallTests ++ (void)initialize { + [self testForSuite:@"Multicast Call"]; +} +@end + +@interface StunTests : LinphoneTesterBase +@end + +@implementation StunTests ++ (void)initialize { + [self testForSuite:@"Stun"]; +} +@end + +@interface EventTests : LinphoneTesterBase +@end + +@implementation EventTests ++ (void)initialize { + [self testForSuite:@"Event"]; +} +@end + +@interface MessageTests : LinphoneTesterBase +@end + +@implementation MessageTests ++ (void)initialize { + [self testForSuite:@"Message"]; +} +@end + +@interface RemoteProvisioningTests : LinphoneTesterBase +@end + +@implementation RemoteProvisioningTests ++ (void)initialize { + [self testForSuite:@"RemoteProvisioning"]; +} +@end + +@interface QualityReportingTests : LinphoneTesterBase +@end + +@implementation QualityReportingTests ++ (void)initialize { + [self testForSuite:@"QualityReporting"]; +} +@end + +@interface RegisterTests : LinphoneTesterBase +@end + +@implementation RegisterTests ++ (void)initialize { + [self testForSuite:@"Register"]; +} +@end + +@interface GroupChatTests : LinphoneTesterBase +@end + +@implementation GroupChatTests ++ (void)initialize { + [self testForSuite:@"Group Chat"]; +} +@end + +@interface FlexisipTests : LinphoneTesterBase +@end + +@implementation FlexisipTests ++ (void)initialize { + [self testForSuite:@"Flexisip"]; +} +@end + +@interface MultiCallTests : LinphoneTesterBase +@end + +@implementation MultiCallTests ++ (void)initialize { + [self testForSuite:@"Multi call"]; +} +@end + +@interface SingleCallTests : LinphoneTesterBase +@end + +@implementation SingleCallTests ++ (void)initialize { + [self testForSuite:@"Single Call"]; +} +@end + +@interface PresenceUsingServerTests : LinphoneTesterBase +@end + +@implementation PresenceUsingServerTests ++ (void)initialize { + [self testForSuite:@"Presence using server"]; +} +@end + +@interface CallRecoveryTests : LinphoneTesterBase +@end + +@implementation CallRecoveryTests ++ (void)initialize { + [self testForSuite:@"Call recovery"]; +} +@end + +@interface CallWithICETests : LinphoneTesterBase +@end + +@implementation CallWithICETests ++ (void)initialize { + [self testForSuite:@"Call with ICE"]; +} +@end + diff --git a/TestsUI/AssistantTester.m b/TestsUI/AssistantTester.m index 075197df8..4208add22 100644 --- a/TestsUI/AssistantTester.m +++ b/TestsUI/AssistantTester.m @@ -98,7 +98,7 @@ [self setInvalidAccountSet:true]; UIView *alertViewText = - [tester waitForViewWithAccessibilityLabel:@"Registration failure" traits:UIAccessibilityTraitStaticText]; + [tester waitForViewWithAccessibilityLabel:@"Connection failure" traits:UIAccessibilityTraitStaticText]; if (alertViewText) { UIView *reason = [tester waitForViewWithAccessibilityLabel:@"Bad credentials, check your account settings" traits:UIAccessibilityTraitStaticText]; diff --git a/TestsUI/ContactsTester.m b/TestsUI/ContactsTester.m index d6fc89b38..fe1e17c21 100644 --- a/TestsUI/ContactsTester.m +++ b/TestsUI/ContactsTester.m @@ -84,7 +84,7 @@ NSString *phone = @"+5 15 #0664;447*46"; [self createContact:contactName lastName:@"dummy" phoneNumber:phone SIPAddress:nil]; [tester tapViewWithAccessibilityLabel:[@"Call " stringByAppendingString:phone]]; - [tester waitForViewWithAccessibilityLabel:[phone stringByAppendingString:@" is not registered."]]; + [tester waitForViewWithAccessibilityLabel:[phone stringByAppendingString:@" is not connected."]]; [tester tapViewWithAccessibilityLabel:@"Cancel"]; } diff --git a/TestsUI/LinphoneTestCase.m b/TestsUI/LinphoneTestCase.m index 5ca6f0da5..3cbda1d9e 100644 --- a/TestsUI/LinphoneTestCase.m +++ b/TestsUI/LinphoneTestCase.m @@ -169,18 +169,18 @@ } - (void)waitForRegistration { - // wait for account to be registered + // wait for account to be connected int timeout = 15; while (timeout && ![tester tryFindingViewWithAccessibilityLabel:@"Registration state" - value:@"Registered" + value:@"Connected" traits:UIAccessibilityTraitButton error:nil]) { [tester waitForTimeInterval:1]; timeout--; } [tester waitForViewWithAccessibilityLabel:@"Registration state" - value:@"Registered" + value:@"Connected" traits:UIAccessibilityTraitButton]; } diff --git a/cmake_builder/CMakeLists.txt b/cmake_builder/CMakeLists.txt deleted file mode 100644 index d4492aa27..000000000 --- a/cmake_builder/CMakeLists.txt +++ /dev/null @@ -1,22 +0,0 @@ -############################################################################ -# CMakeLists.txt -# Copyright (C) 2017-2018 Belledonne Communications, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# -############################################################################ - diff --git a/latestCallsWidget/Info.plist b/latestCallsWidget/Info.plist index e1db1a68f..191930909 100644 --- a/latestCallsWidget/Info.plist +++ b/latestCallsWidget/Info.plist @@ -17,9 +17,9 @@ CFBundlePackageType XPC! CFBundleShortVersionString - 1.0 + 4.1 CFBundleVersion - 1 + 27 NSExtension NSExtensionMainStoryboard diff --git a/latestChatroomsWidget/Info.plist b/latestChatroomsWidget/Info.plist index 43f038dd9..7f232370a 100644 --- a/latestChatroomsWidget/Info.plist +++ b/latestChatroomsWidget/Info.plist @@ -17,9 +17,9 @@ CFBundlePackageType XPC! CFBundleShortVersionString - 1.0 + 4.1 CFBundleVersion - 1 + 27 NSExtension NSExtensionMainStoryboard diff --git a/linphone-Info.plist b/linphone-Info.plist index d658c41e2..75bbb45c6 100644 --- a/linphone-Info.plist +++ b/linphone-Info.plist @@ -24,7 +24,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 4.0.2 + 4.1 CFBundleURLTypes @@ -77,7 +77,7 @@ CFBundleVersion - 6 + 27 ITSAppUsesNonExemptEncryption ITSEncryptionExportComplianceCode @@ -96,6 +96,18 @@ Add tranfered files to your library NSPhotoLibraryUsageDescription Share photos with your friends and customize avatars + NSUbiquitousContainers + + iCloud.org.linphone.phone + + NSUbiquitousContainerIsDocumentScopePublic + + NSUbiquitousContainerName + Linphone + NSUbiquitousContainerSupportedFolderLevels + Any + + NSVoIPUsageDescription Make audio/video calls UIApplicationExitsOnSuspend @@ -111,8 +123,6 @@ linphone.phone.action.newMessage - UIApplicationShortcutWidget - $(PRODUCT_BUNDLE_IDENTIFIER).widget.latestChatrooms UIBackgroundModes audio @@ -147,6 +157,8 @@ UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationPortrait + UISupportsDocumentBrowser + UIViewControllerBasedStatusBarAppearance diff --git a/linphone.entitlements b/linphone.entitlements index 371282fab..afde86dcc 100644 --- a/linphone.entitlements +++ b/linphone.entitlements @@ -4,10 +4,24 @@ aps-environment development + com.apple.developer.icloud-container-identifiers + + iCloud.$(CFBundleIdentifier) + + com.apple.developer.icloud-services + + CloudDocuments + + com.apple.developer.ubiquity-container-identifiers + + iCloud.$(CFBundleIdentifier) + + com.apple.developer.ubiquity-kvstore-identifier + $(TeamIdentifierPrefix)$(CFBundleIdentifier) com.apple.security.application-groups + group.org.linphone.phone.linphoneExtension group.belledonne-communications.linphone.widget - group.belledonne-communications.linphone diff --git a/linphone.xcodeproj/project.pbxproj b/linphone.xcodeproj/project.pbxproj old mode 100755 new mode 100644 index 002ed7d61..6686e63f7 --- a/linphone.xcodeproj/project.pbxproj +++ b/linphone.xcodeproj/project.pbxproj @@ -7,11 +7,7 @@ objects = { /* Begin PBXBuildFile section */ - 1523F17A2174B096009E32C0 /* mediastreamer2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8C601FD220B462B0004FF95C /* mediastreamer2.framework */; }; - 1523F1812174B0BA009E32C0 /* mediastreamer2.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 15F12E672174AB4B00B7DE49 /* mediastreamer2.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 152F22361B15E889008C0621 /* libxml2.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 152F22351B15E889008C0621 /* libxml2.dylib */; }; - 15F12E682174AB4B00B7DE49 /* mediastreamer2.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 15F12E672174AB4B00B7DE49 /* mediastreamer2.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 15F12E692174AB9000B7DE49 /* mediastreamer2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 15F12E672174AB4B00B7DE49 /* mediastreamer2.framework */; }; 15F728741B16FF9A00A1C901 /* libxml2.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 152F22351B15E889008C0621 /* libxml2.dylib */; }; 1D3623260D0F684500981E51 /* LinphoneAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D3623250D0F684500981E51 /* LinphoneAppDelegate.m */; }; 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; @@ -62,6 +58,7 @@ 340751E7150F38FD00B89C47 /* UIVideoButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 340751E6150F38FD00B89C47 /* UIVideoButton.m */; }; 34216F401547EBCD00EA9777 /* VideoZoomHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 34216F3F1547EBCD00EA9777 /* VideoZoomHandler.m */; }; 344ABDF114850AE9007420B6 /* libc++.1.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 344ABDEF14850AE9007420B6 /* libc++.1.dylib */; settings = {ATTRIBUTES = (Weak, ); }; }; + 3C4CCF18D4DA173FC144654A /* Pods_linphoneExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BEBE8FB918176C388C01CFF7 /* Pods_linphoneExtension.framework */; }; 570742581D5A0691004B9C84 /* ShopView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 570742561D5A0691004B9C84 /* ShopView.xib */; }; 570742611D5A09B8004B9C84 /* ShopView.m in Sources */ = {isa = PBXBuildFile; fileRef = 5707425F1D5A09B8004B9C84 /* ShopView.m */; }; 570742671D5A63DB004B9C84 /* StoreKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 570742661D5A63DB004B9C84 /* StoreKit.framework */; }; @@ -71,7 +68,6 @@ 5E31290120D7A37E00CF3AAE /* NotificationCenter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5EF0C33820C806A5005081B0 /* NotificationCenter.framework */; }; 5E31290520D7A37E00CF3AAE /* TodayViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E31290420D7A37E00CF3AAE /* TodayViewController.m */; }; 5E31290820D7A37E00CF3AAE /* MainInterface.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5E31290620D7A37E00CF3AAE /* MainInterface.storyboard */; }; - 5E31290C20D7A37E00CF3AAE /* latestChatroomsWidget.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 5E31290020D7A37E00CF3AAE /* latestChatroomsWidget.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 5E31291320D7AAA100CF3AAE /* avatar.png in Resources */ = {isa = PBXBuildFile; fileRef = 633FEBE61D3CD5570014B822 /* avatar.png */; }; 5E31291A20D7AAAD00CF3AAE /* chat_group_avatar.png in Resources */ = {isa = PBXBuildFile; fileRef = 8C2A81941F87B8000012A66B /* chat_group_avatar.png */; }; 5E32944520E4C29000BBA896 /* chat_delivered.png in Resources */ = {isa = PBXBuildFile; fileRef = 244523AC1E8266CC0037A187 /* chat_delivered.png */; }; @@ -83,14 +79,59 @@ 5E58962620DCE5700030868C /* UserNotificationsUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5E58962520DCE5700030868C /* UserNotificationsUI.framework */; }; 5E58962A20DCE5700030868C /* NotificationViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E58962920DCE5700030868C /* NotificationViewController.m */; }; 5E58962D20DCE5700030868C /* MainInterface.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5E58962B20DCE5700030868C /* MainInterface.storyboard */; }; - 5E58963120DCE5710030868C /* richNotifications.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 5E58962320DCE5700030868C /* richNotifications.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 5EEE8F9B20C80C23006E4176 /* NotificationCenter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5EF0C33820C806A5005081B0 /* NotificationCenter.framework */; }; 5EEE8F9F20C80C23006E4176 /* TodayViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 5EEE8F9E20C80C23006E4176 /* TodayViewController.m */; }; 5EEE8FA220C80C23006E4176 /* MainInterface.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5EEE8FA020C80C23006E4176 /* MainInterface.storyboard */; }; - 5EEE8FA620C80C23006E4176 /* latestCallsWidget.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 5EEE8F9A20C80C23006E4176 /* latestCallsWidget.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; + 614D09CE21E74D5400C43EDF /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 614D09CD21E74D5400C43EDF /* GoogleService-Info.plist */; }; + 61586B81217A16EE0038AC45 /* menu_about.png in Resources */ = {isa = PBXBuildFile; fileRef = 61586B7A217A16EE0038AC45 /* menu_about.png */; }; + 61586B83217A16FD0038AC45 /* menu_about@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 61586B82217A16FD0038AC45 /* menu_about@2x.png */; }; + 61586B85217A17070038AC45 /* menu_assistant.png in Resources */ = {isa = PBXBuildFile; fileRef = 61586B84217A17070038AC45 /* menu_assistant.png */; }; + 61586B87217A17160038AC45 /* menu_assistant@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 61586B86217A17150038AC45 /* menu_assistant@2x.png */; }; + 61586B89217A17220038AC45 /* menu_link_account.png in Resources */ = {isa = PBXBuildFile; fileRef = 61586B88217A17220038AC45 /* menu_link_account.png */; }; + 61586B8B217A17320038AC45 /* menu_link_account@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 61586B8A217A17320038AC45 /* menu_link_account@2x.png */; }; + 61586B8D217A173F0038AC45 /* menu_options.png in Resources */ = {isa = PBXBuildFile; fileRef = 61586B8C217A173F0038AC45 /* menu_options.png */; }; + 61586B8F217A174F0038AC45 /* menu_options@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 61586B8E217A174F0038AC45 /* menu_options@2x.png */; }; + 61586B91217A175D0038AC45 /* menu_recordings.png in Resources */ = {isa = PBXBuildFile; fileRef = 61586B90217A175C0038AC45 /* menu_recordings.png */; }; + 61586B93217A17700038AC45 /* menu_recordings@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 61586B92217A176F0038AC45 /* menu_recordings@2x.png */; }; + 615A280F217F1FD50060F920 /* chat_add_group.png in Resources */ = {isa = PBXBuildFile; fileRef = 615A2808217F1FD40060F920 /* chat_add_group.png */; }; + 615A2811217F1FDE0060F920 /* chat_add_group@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 615A2810217F1FDE0060F920 /* chat_add_group@2x.png */; }; + 615A2813217F24D40060F920 /* security_1_indicator.png in Resources */ = {isa = PBXBuildFile; fileRef = 615A2812217F24D40060F920 /* security_1_indicator.png */; }; + 615A2815217F24E00060F920 /* security_1_indicator@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 615A2814217F24E00060F920 /* security_1_indicator@2x.png */; }; + 615A2817217F280C0060F920 /* chat_list_indicator.png in Resources */ = {isa = PBXBuildFile; fileRef = 615A2816217F280C0060F920 /* chat_list_indicator.png */; }; + 615A2819217F28160060F920 /* chat_list_indicator@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 615A2818217F28160060F920 /* chat_list_indicator@2x.png */; }; + 615A281B217F6F9C0060F920 /* security_2_indicator.png in Resources */ = {isa = PBXBuildFile; fileRef = 615A281A217F6F9B0060F920 /* security_2_indicator.png */; }; + 615A281D217F6FA80060F920 /* security_2_indicator@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 615A281C217F6FA80060F920 /* security_2_indicator@2x.png */; }; + 615A281F217F6FB40060F920 /* security_alert_indicator.png in Resources */ = {isa = PBXBuildFile; fileRef = 615A281E217F6FB30060F920 /* security_alert_indicator.png */; }; + 615A2821217F6FBF0060F920 /* security_alert_indicator@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 615A2820217F6FBF0060F920 /* security_alert_indicator@2x.png */; }; + 615A282421805B260060F920 /* security_toogle_icon_green.png in Resources */ = {isa = PBXBuildFile; fileRef = 615A282321805B250060F920 /* security_toogle_icon_green.png */; }; + 615A282621805B320060F920 /* security_toogle_icon_green@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 615A282521805B320060F920 /* security_toogle_icon_green@2x.png */; }; + 615A282821805B400060F920 /* security_toogle_icon_grey.png in Resources */ = {isa = PBXBuildFile; fileRef = 615A282721805B400060F920 /* security_toogle_icon_grey.png */; }; + 615A282A21805B4C0060F920 /* security_toogle_icon_grey@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 615A282921805B4C0060F920 /* security_toogle_icon_grey@2x.png */; }; + 615A2830218071E80060F920 /* security_toogle_background_green.png in Resources */ = {isa = PBXBuildFile; fileRef = 615A282F218071E80060F920 /* security_toogle_background_green.png */; }; + 615A2832218071F30060F920 /* security_toogle_background_green@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 615A2831218071F30060F920 /* security_toogle_background_green@2x.png */; }; + 615A2834218071FF0060F920 /* security_toogle_background_grey.png in Resources */ = {isa = PBXBuildFile; fileRef = 615A2833218071FF0060F920 /* security_toogle_background_grey.png */; }; + 615A28362180720D0060F920 /* security_toogle_background_grey@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 615A28352180720D0060F920 /* security_toogle_background_grey@2x.png */; }; + 615A283A2180788E0060F920 /* security_toogle_button.png in Resources */ = {isa = PBXBuildFile; fileRef = 615A28392180788E0060F920 /* security_toogle_button.png */; }; + 615A283C2180789C0060F920 /* security_toogle_button@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 615A283B2180789C0060F920 /* security_toogle_button@2x.png */; }; + 615A283E2180A2560060F920 /* invite_linphone.png in Resources */ = {isa = PBXBuildFile; fileRef = 615A283D2180A2550060F920 /* invite_linphone.png */; }; + 615A28402180A2620060F920 /* invite_linphone@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 615A283F2180A2620060F920 /* invite_linphone@2x.png */; }; + 615A28422180C0870060F920 /* recording.png in Resources */ = {isa = PBXBuildFile; fileRef = 615A28412180C0820060F920 /* recording.png */; }; + 615A28442180C0900060F920 /* recording@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 615A28432180C08F0060F920 /* recording@2x.png */; }; + 6180D6FE21EE41A800AD9CB6 /* QuickLook.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6180D6FD21EE41A800AD9CB6 /* QuickLook.framework */; }; 61AE364F20C00B370089D9D3 /* ShareViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 61AE364E20C00B370089D9D3 /* ShareViewController.m */; }; 61AE365220C00B370089D9D3 /* MainInterface.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 61AE365020C00B370089D9D3 /* MainInterface.storyboard */; }; 61AE365620C00B370089D9D3 /* linphoneExtension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 61AE364B20C00B370089D9D3 /* linphoneExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; + 61AEBEA321906AFC00F35E7F /* BuildFile in Frameworks */ = {isa = PBXBuildFile; }; + 61AEBEBD2191990A00F35E7F /* DevicesListView.m in Sources */ = {isa = PBXBuildFile; fileRef = 61AEBEBC2191990A00F35E7F /* DevicesListView.m */; }; + 61AEBEBF2191991F00F35E7F /* DevicesListView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 61AEBEBE2191991F00F35E7F /* DevicesListView.xib */; }; + 61AEBEC22191D7C800F35E7F /* UIDevicesDetails.m in Sources */ = {isa = PBXBuildFile; fileRef = 61AEBEC12191D7C800F35E7F /* UIDevicesDetails.m */; }; + 61AEBEC42191D7D900F35E7F /* UIDevicesDetails.xib in Resources */ = {isa = PBXBuildFile; fileRef = 61AEBEC32191D7D900F35E7F /* UIDevicesDetails.xib */; }; + 61AEBEC62191E47500F35E7F /* chevron_list_close.png in Resources */ = {isa = PBXBuildFile; fileRef = 61AEBEC52191E47500F35E7F /* chevron_list_close.png */; }; + 61AEBEC82191E48400F35E7F /* chevron_list_close@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 61AEBEC72191E48400F35E7F /* chevron_list_close@2x.png */; }; + 61AEBECA2191E49300F35E7F /* chevron_list_open.png in Resources */ = {isa = PBXBuildFile; fileRef = 61AEBEC92191E49200F35E7F /* chevron_list_open.png */; }; + 61AEBECC2191E4A300F35E7F /* chevron_list_open@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 61AEBECB2191E4A300F35E7F /* chevron_list_open@2x.png */; }; + 61CCC3DF21933B580060EDEA /* UIDeviceCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 61CCC3DE21933B580060EDEA /* UIDeviceCell.m */; }; + 61CCC3E121933B660060EDEA /* UIDeviceCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 61CCC3E021933B660060EDEA /* UIDeviceCell.xib */; }; 61F1997520C6B1D5006B069A /* AVKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 61F1996E20C6B1D5006B069A /* AVKit.framework */; }; 630589E71B4E810900EFAE36 /* ChatTester.m in Sources */ = {isa = PBXBuildFile; fileRef = 630589DF1B4E810900EFAE36 /* ChatTester.m */; }; 630589E81B4E810900EFAE36 /* ContactsTester.m in Sources */ = {isa = PBXBuildFile; fileRef = 630589E11B4E810900EFAE36 /* ContactsTester.m */; }; @@ -111,18 +152,6 @@ 63058A3E1B4E822F00EFAE36 /* LinphoneTester_Tests.m in Sources */ = {isa = PBXBuildFile; fileRef = 63058A381B4E822F00EFAE36 /* LinphoneTester_Tests.m */; }; 63058A3F1B4E823000EFAE36 /* NSObject+DTRuntime.m in Sources */ = {isa = PBXBuildFile; fileRef = 63058A3A1B4E822F00EFAE36 /* NSObject+DTRuntime.m */; }; 63058A4F1B4E835200EFAE36 /* libKIF.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 630589FD1B4E816A00EFAE36 /* libKIF.a */; }; - 63058ACF1B4E922500EFAE36 /* certificates in Resources */ = {isa = PBXBuildFile; fileRef = 63058AC81B4E922500EFAE36 /* certificates */; }; - 63058AD01B4E922500EFAE36 /* flexisip in Resources */ = {isa = PBXBuildFile; fileRef = 63058AC91B4E922500EFAE36 /* flexisip */; }; - 63058AD11B4E922500EFAE36 /* images in Resources */ = {isa = PBXBuildFile; fileRef = 63058ACA1B4E922500EFAE36 /* images */; }; - 63058AD41B4E922500EFAE36 /* rcfiles in Resources */ = {isa = PBXBuildFile; fileRef = 63058ACD1B4E922500EFAE36 /* rcfiles */; }; - 63058AD51B4E922500EFAE36 /* sounds in Resources */ = {isa = PBXBuildFile; fileRef = 63058ACE1B4E922500EFAE36 /* sounds */; }; - 63058ADA1B4E937300EFAE36 /* certificates in Resources */ = {isa = PBXBuildFile; fileRef = 63058AC81B4E922500EFAE36 /* certificates */; }; - 63058ADB1B4E937300EFAE36 /* flexisip in Resources */ = {isa = PBXBuildFile; fileRef = 63058AC91B4E922500EFAE36 /* flexisip */; }; - 63058ADC1B4E937300EFAE36 /* images in Resources */ = {isa = PBXBuildFile; fileRef = 63058ACA1B4E922500EFAE36 /* images */; }; - 63058ADF1B4E937300EFAE36 /* rcfiles in Resources */ = {isa = PBXBuildFile; fileRef = 63058ACD1B4E922500EFAE36 /* rcfiles */; }; - 63058AE01B4E937300EFAE36 /* sounds in Resources */ = {isa = PBXBuildFile; fileRef = 63058ACE1B4E922500EFAE36 /* sounds */; }; - 63058AE21B4E93A100EFAE36 /* tester_hosts in Resources */ = {isa = PBXBuildFile; fileRef = 63058AE11B4E93A100EFAE36 /* tester_hosts */; }; - 63058AE31B4E93B300EFAE36 /* tester_hosts in Resources */ = {isa = PBXBuildFile; fileRef = 63058AE11B4E93A100EFAE36 /* tester_hosts */; }; 6306440E1BECB08500134C72 /* FirstLoginView.m in Sources */ = {isa = PBXBuildFile; fileRef = 6306440C1BECB08500134C72 /* FirstLoginView.m */; }; 6308F9C51BF0DD6600D1234B /* XMLRPCHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 6308F9C41BF0DD6600D1234B /* XMLRPCHelper.m */; }; 630CF5571AF7CE1500539F7A /* UITextField+DoneButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 630CF5561AF7CE1500539F7A /* UITextField+DoneButton.m */; }; @@ -572,7 +601,6 @@ 635173F91BA082A40095EB0A /* UIChatBubblePhotoCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 635173F81BA082A40095EB0A /* UIChatBubblePhotoCell.m */; }; 6352A5751BE0D4B800594C1C /* CallSideMenuView.m in Sources */ = {isa = PBXBuildFile; fileRef = 6352A5731BE0D4B800594C1C /* CallSideMenuView.m */; }; 6352A5761BE0D4B800594C1C /* CallSideMenuView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6352A5741BE0D4B800594C1C /* CallSideMenuView.xib */; }; - 635598821C96AFFA006ED99A /* vcards in Resources */ = {isa = PBXBuildFile; fileRef = 635598811C96AFFA006ED99A /* vcards */; }; 635775251B6673EC00C8B704 /* HistoryDetailsTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = 635775241B6673EC00C8B704 /* HistoryDetailsTableView.m */; }; 636316D11A1DEBCB0009B839 /* AboutView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 636316D31A1DEBCB0009B839 /* AboutView.xib */; }; 636316D41A1DEC650009B839 /* SettingsView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 636316D61A1DEC650009B839 /* SettingsView.xib */; }; @@ -629,20 +657,21 @@ 63CE58451C85EC1000304800 /* VideoToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 63CE583F1C85EBF400304800 /* VideoToolbox.framework */; settings = {ATTRIBUTES = (Required, ); }; }; 63D11C531C3D501200E8FCEE /* Log.m in Sources */ = {isa = PBXBuildFile; fileRef = 63D11C521C3D501200E8FCEE /* Log.m */; }; 63D11C551C3D50A100E8FCEE /* Log.m in Sources */ = {isa = PBXBuildFile; fileRef = 63D11C521C3D501200E8FCEE /* Log.m */; }; - 63D8038D1C96E74100336B6F /* vcards in Resources */ = {isa = PBXBuildFile; fileRef = 635598811C96AFFA006ED99A /* vcards */; }; 63DFE04B1C40161700DA5E87 /* notes_of_the_optimistic.caf in Resources */ = {isa = PBXBuildFile; fileRef = 63DFE0451C40161700DA5E87 /* notes_of_the_optimistic.caf */; }; 63E27A321C4FECD000D332AE /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 63E27A311C4FECD000D332AE /* LaunchScreen.xib */; }; 63E27A521C50EDB000D332AE /* hold.mkv in Resources */ = {isa = PBXBuildFile; fileRef = 63E27A511C50EB2700D332AE /* hold.mkv */; }; 63E59A3F1ADE70D900646FB3 /* InAppProductsManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 63E59A3E1ADE70D900646FB3 /* InAppProductsManager.m */; }; - 63E802DB1C625AEF000D5509 /* (null) in Resources */ = {isa = PBXBuildFile; }; + 63E802DB1C625AEF000D5509 /* BuildFile in Resources */ = {isa = PBXBuildFile; }; 63EC8D391D7438660066547B /* AssistantLinkView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 63EC8D3B1D7438660066547B /* AssistantLinkView.xib */; }; 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 */; }; + 64092B369D63DBEAA8C824CE /* Pods_liblinphoneTester.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9CBD6E980619195CB7EE32AC /* Pods_liblinphoneTester.framework */; }; 70E542F313E147E3002BA2C0 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 70E542F213E147E3002BA2C0 /* OpenGLES.framework */; }; 70E542F513E147EB002BA2C0 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 70E542F413E147EB002BA2C0 /* QuartzCore.framework */; }; + 7F568BF9C9BFDA3A0311DF18 /* Pods_linphoneTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F325590DD6CD7F6CC8F60C03 /* Pods_linphoneTests.framework */; }; 8C1B67061E671826001EA2FE /* AudioHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C1B67051E671826001EA2FE /* AudioHelper.m */; }; 8C2595DD1DEDC92D007A6424 /* ProviderDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C2595DC1DEDC92D007A6424 /* ProviderDelegate.m */; }; 8C2595DF1DEDCC8E007A6424 /* CallKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8C2595DE1DEDCC8E007A6424 /* CallKit.framework */; }; @@ -650,59 +679,7 @@ 8C2A81961F87B8000012A66B /* chat_group_avatar.png in Resources */ = {isa = PBXBuildFile; fileRef = 8C2A81941F87B8000012A66B /* chat_group_avatar.png */; }; 8C300D9A1E40E0CC00728EF3 /* lime_ko.png in Resources */ = {isa = PBXBuildFile; fileRef = 8C300D981E40E0CC00728EF3 /* lime_ko.png */; }; 8C300D9B1E40E0CC00728EF3 /* lime_ko@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8C300D991E40E0CC00728EF3 /* lime_ko@2x.png */; }; - 8C3EA9E31EB892D600B732B6 /* msamr.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8C3EA9E01EB892D600B732B6 /* msamr.framework */; }; - 8C3EA9E41EB892D600B732B6 /* msamr.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 8C3EA9E01EB892D600B732B6 /* msamr.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 8C3EA9E51EB892D600B732B6 /* mscodec2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8C3EA9E11EB892D600B732B6 /* mscodec2.framework */; }; - 8C3EA9E61EB892D600B732B6 /* mscodec2.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 8C3EA9E11EB892D600B732B6 /* mscodec2.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 8C3EA9E71EB892D600B732B6 /* msopenh264.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8C3EA9E21EB892D600B732B6 /* msopenh264.framework */; }; - 8C3EA9E81EB892D600B732B6 /* msopenh264.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 8C3EA9E21EB892D600B732B6 /* msopenh264.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 8C3EA9F01EB8A78C00B732B6 /* msx264.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8C3EA9EF1EB8A78C00B732B6 /* msx264.framework */; }; - 8C3EA9F11EB8A78C00B732B6 /* msx264.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 8C3EA9EF1EB8A78C00B732B6 /* msx264.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 8C3EA9FB1EB8CEE600B732B6 /* bctoolbox-tester.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8C5BCEC61EB3859200A9AAEF /* bctoolbox-tester.framework */; }; - 8C3EA9FC1EB8CEE600B732B6 /* bctoolbox-tester.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8C5BCEC61EB3859200A9AAEF /* bctoolbox-tester.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 8C3EA9FD1EB8CEE700B732B6 /* msx264.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8C3EA9EF1EB8A78C00B732B6 /* msx264.framework */; }; - 8C3EA9FE1EB8CEE700B732B6 /* msx264.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8C3EA9EF1EB8A78C00B732B6 /* msx264.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 8C3EA9FF1EB8CEE700B732B6 /* msamr.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8C3EA9E01EB892D600B732B6 /* msamr.framework */; }; - 8C3EAA001EB8CEE700B732B6 /* msamr.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8C3EA9E01EB892D600B732B6 /* msamr.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 8C3EAA011EB8CEE700B732B6 /* mscodec2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8C3EA9E11EB892D600B732B6 /* mscodec2.framework */; }; - 8C3EAA021EB8CEE700B732B6 /* mscodec2.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8C3EA9E11EB892D600B732B6 /* mscodec2.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 8C3EAA031EB8CEE700B732B6 /* msopenh264.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8C3EA9E21EB892D600B732B6 /* msopenh264.framework */; }; - 8C3EAA041EB8CEE700B732B6 /* msopenh264.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8C3EA9E21EB892D600B732B6 /* msopenh264.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 8C3EAA051EB8CEE700B732B6 /* bctoolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8C5BCEC71EB3859200A9AAEF /* bctoolbox.framework */; }; - 8C3EAA061EB8CEE700B732B6 /* bctoolbox.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8C5BCEC71EB3859200A9AAEF /* bctoolbox.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 8C3EAA071EB8CEE700B732B6 /* linphone.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8C5BCEC81EB3859200A9AAEF /* linphone.framework */; }; - 8C3EAA081EB8CEE700B732B6 /* linphone.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8C5BCEC81EB3859200A9AAEF /* linphone.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 8C3EAA0D1EB8CEE700B732B6 /* mssilk.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8C5BCECB1EB3859200A9AAEF /* mssilk.framework */; }; - 8C3EAA0E1EB8CEE700B732B6 /* mssilk.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8C5BCECB1EB3859200A9AAEF /* mssilk.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 8C3EAA0F1EB8CEE700B732B6 /* mswebrtc.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8C5BCECC1EB3859200A9AAEF /* mswebrtc.framework */; }; - 8C3EAA101EB8CEE700B732B6 /* mswebrtc.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8C5BCECC1EB3859200A9AAEF /* mswebrtc.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 8C3EAA111EB8CEE700B732B6 /* ortp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8C5BCECD1EB3859200A9AAEF /* ortp.framework */; }; - 8C3EAA121EB8CEE700B732B6 /* ortp.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8C5BCECD1EB3859200A9AAEF /* ortp.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 8C3EAA1A1EB8D9C300B732B6 /* linphonetester.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8C3EAA191EB8D9C300B732B6 /* linphonetester.framework */; }; - 8C3EAA1B1EB8D9C300B732B6 /* linphonetester.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8C3EAA191EB8D9C300B732B6 /* linphonetester.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 8C3EAA1C1EB8D9DB00B732B6 /* linphonetester.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8C3EAA191EB8D9C300B732B6 /* linphonetester.framework */; }; - 8C3EAA1D1EB8DBD000B732B6 /* linphonetester.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 8C3EAA191EB8D9C300B732B6 /* linphonetester.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 8C435F9420BBF863004CCA25 /* belcard.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8C435F8B20BBF862004CCA25 /* belcard.framework */; }; - 8C435F9620BBF867004CCA25 /* belcard.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 8C435F8B20BBF862004CCA25 /* belcard.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 8C435F9720BBF874004CCA25 /* belcard.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8C435F8B20BBF862004CCA25 /* belcard.framework */; }; - 8C435F9820BBF874004CCA25 /* belcard.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8C435F8B20BBF862004CCA25 /* belcard.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 8C435FB320BC3685004CCA25 /* belr.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8C435FA520BC34DA004CCA25 /* belr.framework */; }; - 8C435FB420BC3685004CCA25 /* belr.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8C435FA520BC34DA004CCA25 /* belr.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 8C435FB520BC368D004CCA25 /* belr.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8C435FA520BC34DA004CCA25 /* belr.framework */; }; - 8C435FB620BC368D004CCA25 /* belr.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 8C435FA520BC34DA004CCA25 /* belr.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 8C56289F20236C25007A8ECC /* db in Resources */ = {isa = PBXBuildFile; fileRef = 8C56289120236AA6007A8ECC /* db */; }; - 8C5BCED01EB3859200A9AAEF /* bctoolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8C5BCEC71EB3859200A9AAEF /* bctoolbox.framework */; }; - 8C5BCED11EB3859200A9AAEF /* bctoolbox.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 8C5BCEC71EB3859200A9AAEF /* bctoolbox.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 8C5BCED21EB3859200A9AAEF /* linphone.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8C5BCEC81EB3859200A9AAEF /* linphone.framework */; }; - 8C5BCED31EB3859200A9AAEF /* linphone.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 8C5BCEC81EB3859200A9AAEF /* linphone.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 8C5BCED81EB3859300A9AAEF /* mssilk.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8C5BCECB1EB3859200A9AAEF /* mssilk.framework */; }; - 8C5BCED91EB3859300A9AAEF /* mssilk.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 8C5BCECB1EB3859200A9AAEF /* mssilk.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 8C5BCEDA1EB3859300A9AAEF /* mswebrtc.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8C5BCECC1EB3859200A9AAEF /* mswebrtc.framework */; }; - 8C5BCEDB1EB3859300A9AAEF /* mswebrtc.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 8C5BCECC1EB3859200A9AAEF /* mswebrtc.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 8C5BCEDC1EB3859300A9AAEF /* ortp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8C5BCECD1EB3859200A9AAEF /* ortp.framework */; }; - 8C5BCEDD1EB3859300A9AAEF /* ortp.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 8C5BCECD1EB3859200A9AAEF /* ortp.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 8C5BCEDF1EB385B100A9AAEF /* bctoolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8C5BCEC71EB3859200A9AAEF /* bctoolbox.framework */; }; - 8C5BCEE01EB385B100A9AAEF /* linphone.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8C5BCEC81EB3859200A9AAEF /* linphone.framework */; }; 8C73477C1D9BA3A00022EE8C /* UserNotifications.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8C73477B1D9BA3A00022EE8C /* UserNotifications.framework */; }; 8C92ABE81FA773190006FB5D /* UIChatNotifiedEventCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 8C92ABE71FA773190006FB5D /* UIChatNotifiedEventCell.xib */; }; 8C92ABF31FA773E50006FB5D /* UIChatNotifiedEventCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C92ABF21FA773E50006FB5D /* UIChatNotifiedEventCell.m */; }; @@ -737,9 +714,22 @@ 8CF25D961F9F336100BEA0C1 /* check_unselected.png in Resources */ = {isa = PBXBuildFile; fileRef = 8CF25D941F9F336100BEA0C1 /* check_unselected.png */; }; 8CF25D9D1F9F76BD00BEA0C1 /* chat_group_informations.png in Resources */ = {isa = PBXBuildFile; fileRef = 8CF25D9B1F9F76BC00BEA0C1 /* chat_group_informations.png */; }; 8CF25D9E1F9F76BD00BEA0C1 /* chat_group_informations@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8CF25D9C1F9F76BD00BEA0C1 /* chat_group_informations@2x.png */; }; + A634ABAFCB39B6AAE4CA991D /* Pods_linphone.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 65CEDD144CABFAA70A29AF27 /* Pods_linphone.framework */; }; + C5D3371994961EDAE2311A1E /* Pods_liblinphoneTesterTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D252FEC7DD06DD5695A320A1 /* Pods_liblinphoneTesterTests.framework */; }; C90FAA7915AF54E6002091CB /* HistoryDetailsView.m in Sources */ = {isa = PBXBuildFile; fileRef = C90FAA7715AF54E6002091CB /* HistoryDetailsView.m */; }; CF15F21E20E4F9A3008B1DE6 /* UIImageViewDeletable.m in Sources */ = {isa = PBXBuildFile; fileRef = CF15F21C20E4F9A3008B1DE6 /* UIImageViewDeletable.m */; }; CF15F21F20E4F9A3008B1DE6 /* UIImageViewDeletable.xib in Resources */ = {isa = PBXBuildFile; fileRef = CF15F21D20E4F9A3008B1DE6 /* UIImageViewDeletable.xib */; }; + CF1DE92D210A0F5D00A0A97E /* UILinphoneAudioPlayer.m in Sources */ = {isa = PBXBuildFile; fileRef = CF1DE924210A0F5A00A0A97E /* UILinphoneAudioPlayer.m */; }; + CF1DE92E210A0F5D00A0A97E /* UILinphoneAudioPlayer.xib in Resources */ = {isa = PBXBuildFile; fileRef = CF1DE92B210A0F5B00A0A97E /* UILinphoneAudioPlayer.xib */; }; + CF7602D7210867E800749F76 /* RecordingsListView.m in Sources */ = {isa = PBXBuildFile; fileRef = CF7602D5210867E800749F76 /* RecordingsListView.m */; }; + CF7602D8210867E800749F76 /* RecordingsListView.xib in Resources */ = {isa = PBXBuildFile; fileRef = CF7602D6210867E800749F76 /* RecordingsListView.xib */; }; + CF7602E221086EB200749F76 /* RecordingsListTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = CF7602E021086EB200749F76 /* RecordingsListTableView.m */; }; + CF7602E72108759A00749F76 /* UIRecordingCell.m in Sources */ = {isa = PBXBuildFile; fileRef = CF7602E52108759A00749F76 /* UIRecordingCell.m */; }; + CF7602E82108759A00749F76 /* UIRecordingCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = CF7602E62108759A00749F76 /* UIRecordingCell.xib */; }; + CF7602F5210898CC00749F76 /* rec_off_default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = CF7602EB210898C100749F76 /* rec_off_default@2x.png */; }; + CF7602F6210898CC00749F76 /* rec_on_default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = CF7602F2210898C400749F76 /* rec_on_default@2x.png */; }; + CF7602F7210898CC00749F76 /* rec_off_default.png in Resources */ = {isa = PBXBuildFile; fileRef = CF7602F3210898C600749F76 /* rec_off_default.png */; }; + CF7602F8210898CC00749F76 /* rec_on_default.png in Resources */ = {isa = PBXBuildFile; fileRef = CF7602F4210898C800749F76 /* rec_on_default.png */; }; CFBD7A2A20E504AE007C5286 /* delete_img.png in Resources */ = {isa = PBXBuildFile; fileRef = CFBD7A2320E504AD007C5286 /* delete_img.png */; }; D306459E1611EC2A00BB571E /* UILoadingImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = D306459D1611EC2900BB571E /* UILoadingImageView.m */; }; D3128FE115AABC7E00A2147A /* ContactDetailsView.m in Sources */ = {isa = PBXBuildFile; fileRef = D3128FDF15AABC7E00A2147A /* ContactDetailsView.m */; }; @@ -835,27 +825,6 @@ /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ - 5E31290A20D7A37E00CF3AAE /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */; - proxyType = 1; - remoteGlobalIDString = 5E3128FF20D7A37E00CF3AAE; - remoteInfo = latestChatroomsWidget; - }; - 5E58962F20DCE5710030868C /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */; - proxyType = 1; - remoteGlobalIDString = 5E58962220DCE5700030868C; - remoteInfo = richNotifications; - }; - 5EEE8FA420C80C23006E4176 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */; - proxyType = 1; - remoteGlobalIDString = 5EEE8F9920C80C23006E4176; - remoteInfo = latestCallsWidget; - }; 61AE365420C00B370089D9D3 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */; @@ -936,9 +905,6 @@ dstSubfolderSpec = 13; files = ( 61AE365620C00B370089D9D3 /* linphoneExtension.appex in Embed App Extensions */, - 5E31290C20D7A37E00CF3AAE /* latestChatroomsWidget.appex in Embed App Extensions */, - 5EEE8FA620C80C23006E4176 /* latestCallsWidget.appex in Embed App Extensions */, - 5E58963120DCE5710030868C /* richNotifications.appex in Embed App Extensions */, ); name = "Embed App Extensions"; runOnlyForDeploymentPostprocessing = 0; @@ -949,61 +915,15 @@ dstPath = ""; dstSubfolderSpec = 10; files = ( - 15F12E682174AB4B00B7DE49 /* mediastreamer2.framework in Embed Frameworks */, - 8C435FB620BC368D004CCA25 /* belr.framework in Embed Frameworks */, - 8C5BCED31EB3859200A9AAEF /* linphone.framework in Embed Frameworks */, - 8C5BCEDB1EB3859300A9AAEF /* mswebrtc.framework in Embed Frameworks */, - 8C3EA9F11EB8A78C00B732B6 /* msx264.framework in Embed Frameworks */, - 8C3EA9E61EB892D600B732B6 /* mscodec2.framework in Embed Frameworks */, - 8C435F9620BBF867004CCA25 /* belcard.framework in Embed Frameworks */, - 8C5BCED91EB3859300A9AAEF /* mssilk.framework in Embed Frameworks */, - 8C3EA9E41EB892D600B732B6 /* msamr.framework in Embed Frameworks */, - 8C5BCED11EB3859200A9AAEF /* bctoolbox.framework in Embed Frameworks */, - 8C3EA9E81EB892D600B732B6 /* msopenh264.framework in Embed Frameworks */, - 8C5BCEDD1EB3859300A9AAEF /* ortp.framework in Embed Frameworks */, ); name = "Embed Frameworks"; runOnlyForDeploymentPostprocessing = 0; }; - 8CDC89111EAF89B7006B5652 /* Embed Frameworks */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 10; - files = ( - 8C3EAA1D1EB8DBD000B732B6 /* linphonetester.framework in Embed Frameworks */, - ); - name = "Embed Frameworks"; - runOnlyForDeploymentPostprocessing = 0; - }; - 8CDC89151EAF8CE2006B5652 /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 10; - files = ( - 1523F1812174B0BA009E32C0 /* mediastreamer2.framework in CopyFiles */, - 8C435F9820BBF874004CCA25 /* belcard.framework in CopyFiles */, - 8C3EAA0E1EB8CEE700B732B6 /* mssilk.framework in CopyFiles */, - 8C3EAA081EB8CEE700B732B6 /* linphone.framework in CopyFiles */, - 8C435FB420BC3685004CCA25 /* belr.framework in CopyFiles */, - 8C3EAA1B1EB8D9C300B732B6 /* linphonetester.framework in CopyFiles */, - 8C3EA9FE1EB8CEE700B732B6 /* msx264.framework in CopyFiles */, - 8C3EA9FC1EB8CEE600B732B6 /* bctoolbox-tester.framework in CopyFiles */, - 8C3EAA021EB8CEE700B732B6 /* mscodec2.framework in CopyFiles */, - 8C3EAA101EB8CEE700B732B6 /* mswebrtc.framework in CopyFiles */, - 8C3EAA041EB8CEE700B732B6 /* msopenh264.framework in CopyFiles */, - 8C3EAA001EB8CEE700B732B6 /* msamr.framework in CopyFiles */, - 8C3EAA061EB8CEE700B732B6 /* bctoolbox.framework in CopyFiles */, - 8C3EAA121EB8CEE700B732B6 /* ortp.framework in CopyFiles */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 046DEFE77AD0675DA9932C4C /* Pods-liblinphoneTesterTests.distributionadhoc.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-liblinphoneTesterTests.distributionadhoc.xcconfig"; path = "Pods/Target Support Files/Pods-liblinphoneTesterTests/Pods-liblinphoneTesterTests.distributionadhoc.xcconfig"; sourceTree = ""; }; 152F22351B15E889008C0621 /* libxml2.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libxml2.dylib; path = usr/lib/libxml2.dylib; sourceTree = SDKROOT; }; - 15F12E672174AB4B00B7DE49 /* mediastreamer2.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = mediastreamer2.framework; path = "liblinphone-sdk/apple-darwin/Frameworks/mediastreamer2.framework"; sourceTree = ""; }; 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 1D3623240D0F684500981E51 /* LinphoneAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LinphoneAppDelegate.h; sourceTree = ""; }; 1D3623250D0F684500981E51 /* LinphoneAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LinphoneAppDelegate.m; sourceTree = ""; }; @@ -1047,6 +967,8 @@ 244523AD1E8266CC0037A187 /* chat_error.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = chat_error.png; sourceTree = ""; }; 244523AE1E8266CC0037A187 /* chat_read.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = chat_read.png; sourceTree = ""; }; 244523BC1E8D3A6C0037A187 /* chat_unsecure.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = chat_unsecure.png; sourceTree = ""; }; + 24585CBE78DA4F005C7F9D71 /* Pods-liblinphoneTester.distribution.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-liblinphoneTester.distribution.xcconfig"; path = "Pods/Target Support Files/Pods-liblinphoneTester/Pods-liblinphoneTester.distribution.xcconfig"; sourceTree = ""; }; + 248C326F4AD75E654C1CB37A /* Pods-liblinphoneTesterTests.distribution.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-liblinphoneTesterTests.distribution.xcconfig"; path = "Pods/Target Support Files/Pods-liblinphoneTesterTests/Pods-liblinphoneTesterTests.distribution.xcconfig"; sourceTree = ""; }; 249660941FD6A359001D55AA /* Photos.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Photos.framework; path = System/Library/Frameworks/Photos.framework; sourceTree = SDKROOT; }; 24A3459D1D95797700881A5C /* UIShopTableCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = UIShopTableCell.xib; sourceTree = ""; }; 24A345A51D95798A00881A5C /* UIShopTableCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIShopTableCell.m; sourceTree = ""; }; @@ -1064,6 +986,7 @@ 24BFAA9C209B062F004F47A7 /* contacts_sip_selected@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "contacts_sip_selected@2x.png"; sourceTree = ""; }; 24BFAA9D209B0630004F47A7 /* linphone_logo@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "linphone_logo@2x.png"; sourceTree = ""; }; 24E1C7B91F9A235500D3F981 /* Contacts.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Contacts.framework; path = System/Library/Frameworks/Contacts.framework; sourceTree = SDKROOT; }; + 283F127CA480E2E2CF0DE9C2 /* Pods-linphoneExtension.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-linphoneExtension.release.xcconfig"; path = "Pods/Target Support Files/Pods-linphoneExtension/Pods-linphoneExtension.release.xcconfig"; sourceTree = ""; }; 288765FC0DF74451002DB57D /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 32CA4F630368D1EE00C91783 /* linphone_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = linphone_Prefix.pch; sourceTree = ""; }; @@ -1074,6 +997,8 @@ 34216F3F1547EBCD00EA9777 /* VideoZoomHandler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = VideoZoomHandler.m; path = LinphoneUI/VideoZoomHandler.m; sourceTree = ""; }; 344ABDEF14850AE9007420B6 /* libc++.1.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = "libc++.1.dylib"; path = "usr/lib/libc++.1.dylib"; sourceTree = SDKROOT; }; 344ABDF014850AE9007420B6 /* libstdc++.6.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = "libstdc++.6.dylib"; path = "usr/lib/libstdc++.6.dylib"; sourceTree = SDKROOT; }; + 38A3AE51B9E09ABF29222E5F /* Pods-liblinphoneTester.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-liblinphoneTester.release.xcconfig"; path = "Pods/Target Support Files/Pods-liblinphoneTester/Pods-liblinphoneTester.release.xcconfig"; sourceTree = ""; }; + 38DF35D11A7C0F45E990C83A /* Pods-linphone.distribution.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-linphone.distribution.xcconfig"; path = "Pods/Target Support Files/Pods-linphone/Pods-linphone.distribution.xcconfig"; sourceTree = ""; }; 570742571D5A0691004B9C84 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/ShopView.xib; sourceTree = ""; }; 5707425F1D5A09B8004B9C84 /* ShopView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ShopView.m; sourceTree = ""; }; 570742601D5A09B8004B9C84 /* ShopView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ShopView.h; sourceTree = ""; }; @@ -1100,13 +1025,64 @@ 5EEE8FA320C80C23006E4176 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 5EEE8FB320C81334006E4176 /* latestCallsWidget.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = latestCallsWidget.entitlements; sourceTree = ""; }; 5EF0C33820C806A5005081B0 /* NotificationCenter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = NotificationCenter.framework; path = System/Library/Frameworks/NotificationCenter.framework; sourceTree = SDKROOT; }; + 614D09CD21E74D5400C43EDF /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; + 61586B7A217A16EE0038AC45 /* menu_about.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = menu_about.png; sourceTree = ""; }; + 61586B82217A16FD0038AC45 /* menu_about@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "menu_about@2x.png"; sourceTree = ""; }; + 61586B84217A17070038AC45 /* menu_assistant.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = menu_assistant.png; sourceTree = ""; }; + 61586B86217A17150038AC45 /* menu_assistant@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "menu_assistant@2x.png"; sourceTree = ""; }; + 61586B88217A17220038AC45 /* menu_link_account.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = menu_link_account.png; sourceTree = ""; }; + 61586B8A217A17320038AC45 /* menu_link_account@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "menu_link_account@2x.png"; sourceTree = ""; }; + 61586B8C217A173F0038AC45 /* menu_options.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = menu_options.png; sourceTree = ""; }; + 61586B8E217A174F0038AC45 /* menu_options@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "menu_options@2x.png"; sourceTree = ""; }; + 61586B90217A175C0038AC45 /* menu_recordings.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = menu_recordings.png; sourceTree = ""; }; + 61586B92217A176F0038AC45 /* menu_recordings@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "menu_recordings@2x.png"; sourceTree = ""; }; + 615A2808217F1FD40060F920 /* chat_add_group.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = chat_add_group.png; sourceTree = ""; }; + 615A2810217F1FDE0060F920 /* chat_add_group@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "chat_add_group@2x.png"; sourceTree = ""; }; + 615A2812217F24D40060F920 /* security_1_indicator.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = security_1_indicator.png; sourceTree = ""; }; + 615A2814217F24E00060F920 /* security_1_indicator@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "security_1_indicator@2x.png"; sourceTree = ""; }; + 615A2816217F280C0060F920 /* chat_list_indicator.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = chat_list_indicator.png; sourceTree = ""; }; + 615A2818217F28160060F920 /* chat_list_indicator@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "chat_list_indicator@2x.png"; sourceTree = ""; }; + 615A281A217F6F9B0060F920 /* security_2_indicator.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = security_2_indicator.png; sourceTree = ""; }; + 615A281C217F6FA80060F920 /* security_2_indicator@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "security_2_indicator@2x.png"; sourceTree = ""; }; + 615A281E217F6FB30060F920 /* security_alert_indicator.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = security_alert_indicator.png; sourceTree = ""; }; + 615A2820217F6FBF0060F920 /* security_alert_indicator@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "security_alert_indicator@2x.png"; sourceTree = ""; }; + 615A282321805B250060F920 /* security_toogle_icon_green.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = security_toogle_icon_green.png; sourceTree = ""; }; + 615A282521805B320060F920 /* security_toogle_icon_green@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "security_toogle_icon_green@2x.png"; sourceTree = ""; }; + 615A282721805B400060F920 /* security_toogle_icon_grey.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = security_toogle_icon_grey.png; sourceTree = ""; }; + 615A282921805B4C0060F920 /* security_toogle_icon_grey@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "security_toogle_icon_grey@2x.png"; sourceTree = ""; }; + 615A282F218071E80060F920 /* security_toogle_background_green.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = security_toogle_background_green.png; sourceTree = ""; }; + 615A2831218071F30060F920 /* security_toogle_background_green@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "security_toogle_background_green@2x.png"; sourceTree = ""; }; + 615A2833218071FF0060F920 /* security_toogle_background_grey.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = security_toogle_background_grey.png; sourceTree = ""; }; + 615A28352180720D0060F920 /* security_toogle_background_grey@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "security_toogle_background_grey@2x.png"; sourceTree = ""; }; + 615A28392180788E0060F920 /* security_toogle_button.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = security_toogle_button.png; sourceTree = ""; }; + 615A283B2180789C0060F920 /* security_toogle_button@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "security_toogle_button@2x.png"; sourceTree = ""; }; + 615A283D2180A2550060F920 /* invite_linphone.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = invite_linphone.png; sourceTree = ""; }; + 615A283F2180A2620060F920 /* invite_linphone@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "invite_linphone@2x.png"; sourceTree = ""; }; + 615A28412180C0820060F920 /* recording.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = recording.png; sourceTree = ""; }; + 615A28432180C08F0060F920 /* recording@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "recording@2x.png"; sourceTree = ""; }; + 6180D6FD21EE41A800AD9CB6 /* QuickLook.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuickLook.framework; path = System/Library/Frameworks/QuickLook.framework; sourceTree = SDKROOT; }; 61AE364B20C00B370089D9D3 /* linphoneExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = linphoneExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; }; 61AE364D20C00B370089D9D3 /* ShareViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ShareViewController.h; sourceTree = ""; }; 61AE364E20C00B370089D9D3 /* ShareViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ShareViewController.m; sourceTree = ""; }; 61AE365120C00B370089D9D3 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/MainInterface.storyboard; sourceTree = ""; }; 61AE365320C00B370089D9D3 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 61AE366320C00C810089D9D3 /* linphoneExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = linphoneExtension.entitlements; sourceTree = ""; }; + 61AEBEB5219198EF00F35E7F /* DevicesListView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DevicesListView.h; sourceTree = ""; }; + 61AEBEBC2191990A00F35E7F /* DevicesListView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DevicesListView.m; sourceTree = ""; }; + 61AEBEBE2191991F00F35E7F /* DevicesListView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = DevicesListView.xib; sourceTree = ""; }; + 61AEBEC02191D7B400F35E7F /* UIDevicesDetails.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = UIDevicesDetails.h; sourceTree = ""; }; + 61AEBEC12191D7C800F35E7F /* UIDevicesDetails.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = UIDevicesDetails.m; sourceTree = ""; }; + 61AEBEC32191D7D900F35E7F /* UIDevicesDetails.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = UIDevicesDetails.xib; sourceTree = ""; }; + 61AEBEC52191E47500F35E7F /* chevron_list_close.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = chevron_list_close.png; sourceTree = ""; }; + 61AEBEC72191E48400F35E7F /* chevron_list_close@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "chevron_list_close@2x.png"; sourceTree = ""; }; + 61AEBEC92191E49200F35E7F /* chevron_list_open.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = chevron_list_open.png; sourceTree = ""; }; + 61AEBECB2191E4A300F35E7F /* chevron_list_open@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "chevron_list_open@2x.png"; sourceTree = ""; }; + 61BD122D222EA29300563181 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/AssistantLinkView.strings; sourceTree = ""; }; + 61CCC3D721933B380060EDEA /* UIDeviceCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = UIDeviceCell.h; sourceTree = ""; }; + 61CCC3DE21933B580060EDEA /* UIDeviceCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = UIDeviceCell.m; sourceTree = ""; }; + 61CCC3E021933B660060EDEA /* UIDeviceCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = UIDeviceCell.xib; sourceTree = ""; }; 61F1996E20C6B1D5006B069A /* AVKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVKit.framework; path = System/Library/Frameworks/AVKit.framework; sourceTree = SDKROOT; }; + 620DFD020AC0182319853127 /* Pods-linphoneExtension.distributionadhoc.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-linphoneExtension.distributionadhoc.xcconfig"; path = "Pods/Target Support Files/Pods-linphoneExtension/Pods-linphoneExtension.distributionadhoc.xcconfig"; sourceTree = ""; }; 630589DE1B4E810900EFAE36 /* ChatTester.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ChatTester.h; sourceTree = ""; }; 630589DF1B4E810900EFAE36 /* ChatTester.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ChatTester.m; sourceTree = ""; }; 630589E01B4E810900EFAE36 /* ContactsTester.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContactsTester.h; sourceTree = ""; }; @@ -1142,13 +1118,6 @@ 63058A3A1B4E822F00EFAE36 /* NSObject+DTRuntime.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSObject+DTRuntime.m"; sourceTree = ""; }; 63058A401B4E82C400EFAE36 /* LinphoneTesterTests-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "LinphoneTesterTests-Info.plist"; sourceTree = ""; }; 63058A411B4E82C400EFAE36 /* LinphoneTesterTests-Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "LinphoneTesterTests-Prefix.pch"; sourceTree = ""; }; - 63058AC81B4E922500EFAE36 /* certificates */ = {isa = PBXFileReference; lastKnownFileType = folder; name = certificates; path = ../submodules/linphone/tester/certificates; sourceTree = ""; }; - 63058AC91B4E922500EFAE36 /* flexisip */ = {isa = PBXFileReference; lastKnownFileType = folder; name = flexisip; path = ../submodules/linphone/tester/flexisip; sourceTree = ""; }; - 63058ACA1B4E922500EFAE36 /* images */ = {isa = PBXFileReference; lastKnownFileType = folder; name = images; path = ../submodules/linphone/tester/images; sourceTree = ""; }; - 63058ACD1B4E922500EFAE36 /* rcfiles */ = {isa = PBXFileReference; lastKnownFileType = folder; name = rcfiles; path = ../submodules/linphone/tester/rcfiles; sourceTree = ""; }; - 63058ACE1B4E922500EFAE36 /* sounds */ = {isa = PBXFileReference; lastKnownFileType = folder; name = sounds; path = ../submodules/linphone/tester/sounds; sourceTree = ""; }; - 63058AE11B4E93A100EFAE36 /* tester_hosts */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = tester_hosts; path = submodules/linphone/tester/tester_hosts; sourceTree = SOURCE_ROOT; }; - 63058AE41B4E952E00EFAE36 /* share */ = {isa = PBXFileReference; lastKnownFileType = folder; name = share; path = "../liblinphone-sdk/apple-darwin/share"; sourceTree = ""; }; 6306440B1BECB08500134C72 /* FirstLoginView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FirstLoginView.h; sourceTree = ""; }; 6306440C1BECB08500134C72 /* FirstLoginView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FirstLoginView.m; sourceTree = ""; }; 6308F9C31BF0DD6600D1234B /* XMLRPCHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = XMLRPCHelper.h; path = Utils/XMLRPCHelper.h; sourceTree = ""; }; @@ -1616,7 +1585,6 @@ 6352A5721BE0D4B800594C1C /* CallSideMenuView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CallSideMenuView.h; sourceTree = ""; }; 6352A5731BE0D4B800594C1C /* CallSideMenuView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CallSideMenuView.m; sourceTree = ""; }; 6352A5741BE0D4B800594C1C /* CallSideMenuView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = CallSideMenuView.xib; sourceTree = ""; }; - 635598811C96AFFA006ED99A /* vcards */ = {isa = PBXFileReference; lastKnownFileType = folder; name = vcards; path = ../submodules/linphone/tester/vcards; sourceTree = ""; }; 635775231B6673EC00C8B704 /* HistoryDetailsTableView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HistoryDetailsTableView.h; sourceTree = ""; }; 635775241B6673EC00C8B704 /* HistoryDetailsTableView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HistoryDetailsTableView.m; sourceTree = ""; }; 636316D21A1DEBCB0009B839 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/AboutView.xib; sourceTree = ""; }; @@ -1713,8 +1681,17 @@ 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 = ""; }; + 65CEDD144CABFAA70A29AF27 /* Pods_linphone.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_linphone.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 68D9EC27FCECD5DE2E19CD3C /* Pods-liblinphoneTester.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-liblinphoneTester.debug.xcconfig"; path = "Pods/Target Support Files/Pods-liblinphoneTester/Pods-liblinphoneTester.debug.xcconfig"; sourceTree = ""; }; + 6E1BC45342F5201DABD7FE55 /* Pods_latestCallsWidget.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_latestCallsWidget.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 70E542F213E147E3002BA2C0 /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = System/Library/Frameworks/OpenGLES.framework; sourceTree = SDKROOT; }; 70E542F413E147EB002BA2C0 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; + 7513CBF7F2BA0A9F99977C2B /* Pods_richNotifications.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_richNotifications.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 78C7025E626D12D2F04EAC87 /* Pods-linphoneExtension.distribution.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-linphoneExtension.distribution.xcconfig"; path = "Pods/Target Support Files/Pods-linphoneExtension/Pods-linphoneExtension.distribution.xcconfig"; sourceTree = ""; }; + 799BA1104845EB01ACE764D8 /* Pods-linphone.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-linphone.debug.xcconfig"; path = "Pods/Target Support Files/Pods-linphone/Pods-linphone.debug.xcconfig"; sourceTree = ""; }; + 7D8CCFE176C634813E3A2593 /* Pods-liblinphoneTesterTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-liblinphoneTesterTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-liblinphoneTesterTests/Pods-liblinphoneTesterTests.debug.xcconfig"; sourceTree = ""; }; + 85FB19B6A8124D942C8471F1 /* Pods-linphoneTests.distribution.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-linphoneTests.distribution.xcconfig"; path = "Pods/Target Support Files/Pods-linphoneTests/Pods-linphoneTests.distribution.xcconfig"; sourceTree = ""; }; + 8B488C393394746F9D630789 /* Pods_latestChatroomsWidget.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_latestChatroomsWidget.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 8C1A1F7C1FA331D40064BE00 /* libsoci_sqlite3.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libsoci_sqlite3.a; path = "liblinphone-sdk/apple-darwin/lib/libsoci_sqlite3.a"; sourceTree = ""; }; 8C1B67051E671826001EA2FE /* AudioHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AudioHelper.m; sourceTree = ""; }; 8C1B67081E6718BC001EA2FE /* AudioHelper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = AudioHelper.h; path = Utils/AudioHelper.h; sourceTree = ""; }; @@ -1726,25 +1703,11 @@ 8C2A81941F87B8000012A66B /* chat_group_avatar.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = chat_group_avatar.png; sourceTree = ""; }; 8C300D981E40E0CC00728EF3 /* lime_ko.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = lime_ko.png; sourceTree = ""; }; 8C300D991E40E0CC00728EF3 /* lime_ko@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "lime_ko@2x.png"; sourceTree = ""; }; - 8C3EA9E01EB892D600B732B6 /* msamr.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = msamr.framework; path = "liblinphone-sdk/apple-darwin/Frameworks/msamr.framework"; sourceTree = ""; }; - 8C3EA9E11EB892D600B732B6 /* mscodec2.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = mscodec2.framework; path = "liblinphone-sdk/apple-darwin/Frameworks/mscodec2.framework"; sourceTree = ""; }; - 8C3EA9E21EB892D600B732B6 /* msopenh264.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = msopenh264.framework; path = "liblinphone-sdk/apple-darwin/Frameworks/msopenh264.framework"; sourceTree = ""; }; - 8C3EA9EF1EB8A78C00B732B6 /* msx264.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = msx264.framework; path = "liblinphone-sdk/apple-darwin/Frameworks/msx264.framework"; sourceTree = ""; }; 8C3EAA191EB8D9C300B732B6 /* linphonetester.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = linphonetester.framework; path = "liblinphone-sdk/apple-darwin/Frameworks/linphonetester.framework"; sourceTree = ""; }; - 8C435F8B20BBF862004CCA25 /* belcard.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = belcard.framework; path = "liblinphone-sdk/apple-darwin/Frameworks/belcard.framework"; sourceTree = ""; }; - 8C435FA520BC34DA004CCA25 /* belr.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = belr.framework; path = "liblinphone-sdk/apple-darwin/Frameworks/belr.framework"; sourceTree = ""; }; 8C435FC320BD41C6004CCA25 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Localizable.strings; sourceTree = ""; }; - 8C56289120236AA6007A8ECC /* db */ = {isa = PBXFileReference; lastKnownFileType = folder; name = db; path = submodules/linphone/tester/db; sourceTree = SOURCE_ROOT; }; 8C5BCEC61EB3859200A9AAEF /* bctoolbox-tester.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = "bctoolbox-tester.framework"; path = "liblinphone-sdk/apple-darwin/Frameworks/bctoolbox-tester.framework"; sourceTree = ""; }; - 8C5BCEC71EB3859200A9AAEF /* bctoolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = bctoolbox.framework; path = "liblinphone-sdk/apple-darwin/Frameworks/bctoolbox.framework"; sourceTree = ""; }; - 8C5BCEC81EB3859200A9AAEF /* linphone.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = linphone.framework; path = "liblinphone-sdk/apple-darwin/Frameworks/linphone.framework"; sourceTree = ""; }; - 8C5BCECB1EB3859200A9AAEF /* mssilk.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = mssilk.framework; path = "liblinphone-sdk/apple-darwin/Frameworks/mssilk.framework"; sourceTree = ""; }; - 8C5BCECC1EB3859200A9AAEF /* mswebrtc.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = mswebrtc.framework; path = "liblinphone-sdk/apple-darwin/Frameworks/mswebrtc.framework"; sourceTree = ""; }; - 8C5BCECD1EB3859200A9AAEF /* ortp.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ortp.framework; path = "liblinphone-sdk/apple-darwin/Frameworks/ortp.framework"; sourceTree = ""; }; 8C5D1B991D9BC48100DC6539 /* UIShopTableCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIShopTableCell.h; sourceTree = ""; }; - 8C5D1B9A1D9BC48100DC6539 /* UIShopTableCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIShopTableCell.m; sourceTree = ""; }; 8C5D1B9B1D9BC48100DC6539 /* UIShopTableCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = UIShopTableCell.xib; sourceTree = ""; }; - 8C601FD220B462B0004FF95C /* mediastreamer2.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = mediastreamer2.framework; path = "liblinphone-sdk/apple-darwin/Frameworks/mediastreamer2.framework"; sourceTree = ""; }; 8C73477B1D9BA3A00022EE8C /* UserNotifications.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UserNotifications.framework; path = System/Library/Frameworks/UserNotifications.framework; sourceTree = SDKROOT; }; 8C92ABE71FA773190006FB5D /* UIChatNotifiedEventCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = UIChatNotifiedEventCell.xib; sourceTree = ""; }; 8C92ABF11FA773C20006FB5D /* UIChatNotifiedEventCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = UIChatNotifiedEventCell.h; sourceTree = ""; }; @@ -1769,7 +1732,6 @@ 8CBD7BAA20B6B82A00E5DCC0 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/UIChatConversationImdnTableViewCell.xib; sourceTree = ""; }; 8CBD7BAD20B6B82F00E5DCC0 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/UIChatCreateCollectionViewCell.xib; sourceTree = ""; }; 8CBD7BAF20B6B86800E5DCC0 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/AboutView.strings; sourceTree = ""; }; - 8CBD7BB020B6B86800E5DCC0 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/AssistantLinkView.strings; sourceTree = ""; }; 8CBD7BB120B6B86900E5DCC0 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/AssistantView.strings; sourceTree = ""; }; 8CBD7BB220B6B86A00E5DCC0 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/AssistantViewScreens.strings; sourceTree = ""; }; 8CBD7BB320B6B86B00E5DCC0 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/CallIncomingView.strings; sourceTree = ""; }; @@ -1835,13 +1797,34 @@ 8CF25D941F9F336100BEA0C1 /* check_unselected.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = check_unselected.png; sourceTree = ""; }; 8CF25D9B1F9F76BC00BEA0C1 /* chat_group_informations.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = chat_group_informations.png; sourceTree = ""; }; 8CF25D9C1F9F76BD00BEA0C1 /* chat_group_informations@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "chat_group_informations@2x.png"; sourceTree = ""; }; + 9CBD6E980619195CB7EE32AC /* Pods_liblinphoneTester.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_liblinphoneTester.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + ABB887316C42EE876A3051A9 /* Pods-linphoneTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-linphoneTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-linphoneTests/Pods-linphoneTests.debug.xcconfig"; sourceTree = ""; }; + BE06BDE664323B2A53469696 /* Pods-liblinphoneTesterTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-liblinphoneTesterTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-liblinphoneTesterTests/Pods-liblinphoneTesterTests.release.xcconfig"; sourceTree = ""; }; + BEBE8FB918176C388C01CFF7 /* Pods_linphoneExtension.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_linphoneExtension.framework; sourceTree = BUILT_PRODUCTS_DIR; }; C90FAA7615AF54E6002091CB /* HistoryDetailsView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HistoryDetailsView.h; sourceTree = ""; }; C90FAA7715AF54E6002091CB /* HistoryDetailsView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HistoryDetailsView.m; sourceTree = ""; }; C9B3A6FD15B485DB006F52EE /* Utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Utils.h; path = Utils/Utils.h; sourceTree = ""; }; + CE119C214B6B8B2740622BBD /* Pods-linphoneTests.distributionadhoc.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-linphoneTests.distributionadhoc.xcconfig"; path = "Pods/Target Support Files/Pods-linphoneTests/Pods-linphoneTests.distributionadhoc.xcconfig"; sourceTree = ""; }; CF15F21B20E4F9A3008B1DE6 /* UIImageViewDeletable.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = UIImageViewDeletable.h; sourceTree = ""; }; CF15F21C20E4F9A3008B1DE6 /* UIImageViewDeletable.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = UIImageViewDeletable.m; sourceTree = ""; }; CF15F21D20E4F9A3008B1DE6 /* UIImageViewDeletable.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = UIImageViewDeletable.xib; sourceTree = ""; }; + CF1DE924210A0F5A00A0A97E /* UILinphoneAudioPlayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UILinphoneAudioPlayer.m; sourceTree = ""; }; + CF1DE92B210A0F5B00A0A97E /* UILinphoneAudioPlayer.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = UILinphoneAudioPlayer.xib; sourceTree = ""; }; + CF1DE92C210A0F5C00A0A97E /* UILinphoneAudioPlayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UILinphoneAudioPlayer.h; sourceTree = ""; }; + CF7602D4210867E800749F76 /* RecordingsListView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RecordingsListView.h; sourceTree = ""; }; + CF7602D5210867E800749F76 /* RecordingsListView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RecordingsListView.m; sourceTree = ""; }; + CF7602D6210867E800749F76 /* RecordingsListView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = RecordingsListView.xib; sourceTree = ""; }; + CF7602DF21086EB100749F76 /* RecordingsListTableView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RecordingsListTableView.h; sourceTree = ""; }; + CF7602E021086EB200749F76 /* RecordingsListTableView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RecordingsListTableView.m; sourceTree = ""; }; + CF7602E42108759A00749F76 /* UIRecordingCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = UIRecordingCell.h; sourceTree = ""; }; + CF7602E52108759A00749F76 /* UIRecordingCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = UIRecordingCell.m; sourceTree = ""; }; + CF7602E62108759A00749F76 /* UIRecordingCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = UIRecordingCell.xib; sourceTree = ""; }; + CF7602EB210898C100749F76 /* rec_off_default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "rec_off_default@2x.png"; sourceTree = ""; }; + CF7602F2210898C400749F76 /* rec_on_default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "rec_on_default@2x.png"; sourceTree = ""; }; + CF7602F3210898C600749F76 /* rec_off_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = rec_off_default.png; sourceTree = ""; }; + CF7602F4210898C800749F76 /* rec_on_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = rec_on_default.png; sourceTree = ""; }; CFBD7A2320E504AD007C5286 /* delete_img.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = delete_img.png; sourceTree = ""; }; + D252FEC7DD06DD5695A320A1 /* Pods_liblinphoneTesterTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_liblinphoneTesterTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; D306459C1611EC2900BB571E /* UILoadingImageView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UILoadingImageView.h; sourceTree = ""; }; D306459D1611EC2900BB571E /* UILoadingImageView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UILoadingImageView.m; sourceTree = ""; }; D3128FDE15AABC7E00A2147A /* ContactDetailsView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContactDetailsView.h; sourceTree = ""; }; @@ -1955,6 +1938,7 @@ D3F83EEA1582021700336684 /* CallView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CallView.m; sourceTree = ""; }; D3F83F8C158229C500336684 /* PhoneMainView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PhoneMainView.h; sourceTree = ""; }; D3F83F8D15822ABD00336684 /* PhoneMainView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PhoneMainView.m; sourceTree = ""; }; + E5074CFA3AAD5A8B72956DDE /* Pods-linphoneExtension.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-linphoneExtension.debug.xcconfig"; path = "Pods/Target Support Files/Pods-linphoneExtension/Pods-linphoneExtension.debug.xcconfig"; sourceTree = ""; }; F0181B6B18BF7B1200A9A357 /* SenTestingKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SenTestingKit.framework; path = Library/Frameworks/SenTestingKit.framework; sourceTree = DEVELOPER_DIR; }; F03A9B9418C0DAE100C4D7FE /* libstdc++.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = "libstdc++.dylib"; path = "usr/lib/libstdc++.dylib"; sourceTree = SDKROOT; }; F03A9B9718C0DB6F00C4D7FE /* libc++.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = "libc++.dylib"; path = "usr/lib/libc++.dylib"; sourceTree = SDKROOT; }; @@ -2019,6 +2003,11 @@ F0BB8C4A193631B300974404 /* ImageIO.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ImageIO.framework; path = System/Library/Frameworks/ImageIO.framework; sourceTree = SDKROOT; }; F0F952001A6AEB1000254160 /* linphoneTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = linphoneTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; F0FF66AA1ACAEEB0008A4486 /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = ../../../../Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/System/Library/Frameworks/IOKit.framework; sourceTree = ""; }; + F325590DD6CD7F6CC8F60C03 /* Pods_linphoneTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_linphoneTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + F6373F9231918DECD2B3004D /* Pods-linphoneTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-linphoneTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-linphoneTests/Pods-linphoneTests.release.xcconfig"; sourceTree = ""; }; + FD22CA9E3EFBFEFFF1B80BA2 /* Pods-liblinphoneTester.distributionadhoc.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-liblinphoneTester.distributionadhoc.xcconfig"; path = "Pods/Target Support Files/Pods-liblinphoneTester/Pods-liblinphoneTester.distributionadhoc.xcconfig"; sourceTree = ""; }; + FE7D89A821FDC1BCA9BB9F8F /* Pods-linphone.distributionadhoc.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-linphone.distributionadhoc.xcconfig"; path = "Pods/Target Support Files/Pods-linphone/Pods-linphone.distributionadhoc.xcconfig"; sourceTree = ""; }; + FEAFB5AD0E3AA409BBD1136E /* Pods-linphone.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-linphone.release.xcconfig"; path = "Pods/Target Support Files/Pods-linphone/Pods-linphone.release.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -2026,18 +2015,15 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 15F12E692174AB9000B7DE49 /* mediastreamer2.framework in Frameworks */, + 6180D6FE21EE41A800AD9CB6 /* QuickLook.framework in Frameworks */, + 61AEBEA321906AFC00F35E7F /* BuildFile in Frameworks */, + D37DC7181594AF3400B2A5EB /* MessageUI.framework in Frameworks */, 61F1997520C6B1D5006B069A /* AVKit.framework in Frameworks */, 249660951FD6A35F001D55AA /* Photos.framework in Frameworks */, 24E1C7C01F9A235600D3F981 /* Contacts.framework in Frameworks */, 8C2595DF1DEDCC8E007A6424 /* CallKit.framework in Frameworks */, - 8C5BCED81EB3859300A9AAEF /* mssilk.framework in Frameworks */, - 8C3EA9E31EB892D600B732B6 /* msamr.framework in Frameworks */, - 8C3EA9E51EB892D600B732B6 /* mscodec2.framework in Frameworks */, 8C73477C1D9BA3A00022EE8C /* UserNotifications.framework in Frameworks */, - 8C3EA9E71EB892D600B732B6 /* msopenh264.framework in Frameworks */, 8CA2004C1D8158440095F859 /* PushKit.framework in Frameworks */, - 8C5BCEDA1EB3859300A9AAEF /* mswebrtc.framework in Frameworks */, 340751971506459A00B89C47 /* CoreTelephony.framework in Frameworks */, 63177FBF1C86E68C00ADE58D /* CoreVideo.framework in Frameworks */, 63CE58401C85EBF400304800 /* VideoToolbox.framework in Frameworks */, @@ -2045,30 +2031,24 @@ 152F22361B15E889008C0621 /* libxml2.dylib in Frameworks */, 570742671D5A63DB004B9C84 /* StoreKit.framework in Frameworks */, 22405EEE1600B4E400B92522 /* AssetsLibrary.framework in Frameworks */, - 8C435FB520BC368D004CCA25 /* belr.framework in Frameworks */, 2274402F106F335E006EC466 /* AudioToolbox.framework in Frameworks */, 224567C2107B968500F10948 /* AVFoundation.framework in Frameworks */, 228697C411AC29B800E9E0CA /* CFNetwork.framework in Frameworks */, 2274401A106F31BD006EC466 /* CoreAudio.framework in Frameworks */, - 8C5BCED21EB3859200A9AAEF /* linphone.framework in Frameworks */, 288765FD0DF74451002DB57D /* CoreGraphics.framework in Frameworks */, 22276E8913C73DC000210156 /* CoreMedia.framework in Frameworks */, 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, F0B89C2218DC89E30050B60E /* MediaPlayer.framework in Frameworks */, - D37DC7181594AF3400B2A5EB /* MessageUI.framework in Frameworks */, 226EF06C15FA256B005865C7 /* MobileCoreServices.framework in Frameworks */, - 8C3EA9F01EB8A78C00B732B6 /* msx264.framework in Frameworks */, 70E542F313E147E3002BA2C0 /* OpenGLES.framework in Frameworks */, 70E542F513E147EB002BA2C0 /* QuartzCore.framework in Frameworks */, 2264B6D211200342002C2C53 /* SystemConfiguration.framework in Frameworks */, - 8C435F9420BBF863004CCA25 /* belcard.framework in Frameworks */, 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, F0B026F31AA710AF00FF49F7 /* libiconv.dylib in Frameworks */, F05BAA621A5D594E00411815 /* libz.dylib in Frameworks */, 344ABDF114850AE9007420B6 /* libc++.1.dylib in Frameworks */, - 8C5BCEDC1EB3859300A9AAEF /* ortp.framework in Frameworks */, 22D1B68112A3E0BE001AE361 /* libresolv.dylib in Frameworks */, - 8C5BCED01EB3859200A9AAEF /* bctoolbox.framework in Frameworks */, + A634ABAFCB39B6AAE4CA991D /* Pods_linphone.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2101,6 +2081,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 3C4CCF18D4DA173FC144654A /* Pods_linphoneExtension.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2112,6 +2093,7 @@ 8C3EAA1C1EB8D9DB00B732B6 /* linphonetester.framework in Frameworks */, F08F118719C09C6B007D70C2 /* UIKit.framework in Frameworks */, F08F118619C09C6B007D70C2 /* Foundation.framework in Frameworks */, + C5D3371994961EDAE2311A1E /* Pods_liblinphoneTesterTests.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2119,33 +2101,20 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 1523F17A2174B096009E32C0 /* mediastreamer2.framework in Frameworks */, - 8C3EA9FD1EB8CEE700B732B6 /* msx264.framework in Frameworks */, 63CE58451C85EC1000304800 /* VideoToolbox.framework in Frameworks */, 15F728741B16FF9A00A1C901 /* libxml2.dylib in Frameworks */, F0A54B0C1AD56F4600C22733 /* libc++.dylib in Frameworks */, - 8C3EAA0D1EB8CEE700B732B6 /* mssilk.framework in Frameworks */, - 8C3EA9FF1EB8CEE700B732B6 /* msamr.framework in Frameworks */, - 8C3EAA011EB8CEE700B732B6 /* mscodec2.framework in Frameworks */, - 8C3EAA071EB8CEE700B732B6 /* linphone.framework in Frameworks */, - 8C3EAA111EB8CEE700B732B6 /* ortp.framework in Frameworks */, F08D468D1AA86849001E8CB5 /* libiconv.dylib in Frameworks */, F05BAA631A5D75BC00411815 /* libz.dylib in Frameworks */, - 8C435F9720BBF874004CCA25 /* belcard.framework in Frameworks */, - 8C3EA9FB1EB8CEE600B732B6 /* bctoolbox-tester.framework in Frameworks */, F0BB8C4D193631DF00974404 /* AVFoundation.framework in Frameworks */, - 8C3EAA051EB8CEE700B732B6 /* bctoolbox.framework in Frameworks */, F0BB8C4C193631D200974404 /* CoreMedia.framework in Frameworks */, - 8C3EAA0F1EB8CEE700B732B6 /* mswebrtc.framework in Frameworks */, F0BB8C35193624C800974404 /* libresolv.9.dylib in Frameworks */, - 8C435FB320BC3685004CCA25 /* belr.framework in Frameworks */, F0BB8C331936247C00974404 /* libsqlite3.dylib in Frameworks */, F0BB8C301936246600974404 /* AudioToolbox.framework in Frameworks */, F0BB8BD71936208100974404 /* CoreGraphics.framework in Frameworks */, - 8C3EAA1A1EB8D9C300B732B6 /* linphonetester.framework in Frameworks */, F0BB8BD81936208100974404 /* UIKit.framework in Frameworks */, - 8C3EAA031EB8CEE700B732B6 /* msopenh264.framework in Frameworks */, F0BB8BD61936208100974404 /* Foundation.framework in Frameworks */, + 64092B369D63DBEAA8C824CE /* Pods_liblinphoneTester.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2153,10 +2122,9 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 8C5BCEDF1EB385B100A9AAEF /* bctoolbox.framework in Frameworks */, - 8C5BCEE01EB385B100A9AAEF /* linphone.framework in Frameworks */, 63058A4F1B4E835200EFAE36 /* libKIF.a in Frameworks */, F0FF66AC1ACAEF4F008A4486 /* IOKit.framework in Frameworks */, + 7F568BF9C9BFDA3A0311DF18 /* Pods_linphoneTests.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2193,12 +2161,6 @@ D3F83EEA1582021700336684 /* CallView.m */, D381881C15FE3FCA00C3EDCA /* CallView.xib */, 638F1A861C2167C2004B8E02 /* CallView~ipad.xib */, - 8CA70ACF1F9E0ABA00A3D2EB /* ChatConversationInfoView.h */, - 8CA70AD01F9E0AE100A3D2EB /* ChatConversationInfoView.m */, - 8CBD7BA220B6B7FD00E5DCC0 /* ChatConversationInfoView.xib */, - 8CD99A3D2090BA24008A7CDA /* ChatConversationImdnView.h */, - 8CD99A3B2090B9FA008A7CDA /* ChatConversationImdnView.m */, - 8CBD7BA520B6B80D00E5DCC0 /* ChatConversationImdnView.xib */, 8C9C5E0B1F83B2EF006987FA /* ChatConversationCreateCollectionViewController.h */, 8C9C5E0C1F83B2EF006987FA /* ChatConversationCreateCollectionViewController.m */, 6341807A1BBC103100F71761 /* ChatConversationCreateTableView.h */, @@ -2206,6 +2168,12 @@ 6336715E1BCBAAD200BFCBDE /* ChatConversationCreateView.h */, 6336715F1BCBAAD200BFCBDE /* ChatConversationCreateView.m */, 63B8D68E1BCBE65600C12B09 /* ChatConversationCreateView.xib */, + 8CD99A3D2090BA24008A7CDA /* ChatConversationImdnView.h */, + 8CD99A3B2090B9FA008A7CDA /* ChatConversationImdnView.m */, + 8CBD7BA520B6B80D00E5DCC0 /* ChatConversationImdnView.xib */, + 8CA70ACF1F9E0ABA00A3D2EB /* ChatConversationInfoView.h */, + 8CA70AD01F9E0AE100A3D2EB /* ChatConversationInfoView.m */, + 8CBD7BA220B6B7FD00E5DCC0 /* ChatConversationInfoView.xib */, D32B6E2715A5BC430033019F /* ChatConversationTableView.h */, D32B6E2815A5BC430033019F /* ChatConversationTableView.m */, D3F795D315A582800077328B /* ChatConversationView.h */, @@ -2226,9 +2194,12 @@ D35497FB15875372000081D8 /* ContactsListView.h */, D35497FC15875372000081D8 /* ContactsListView.m */, D38187C015FE342800C3EDCA /* ContactsListView.xib */, + 631098501D4660630041F2B3 /* CountryListView.xib */, 631098471D4660580041F2B3 /* CountryListView.h */, 631098481D4660580041F2B3 /* CountryListView.m */, - 631098501D4660630041F2B3 /* CountryListView.xib */, + 61AEBEB5219198EF00F35E7F /* DevicesListView.h */, + 61AEBEBC2191990A00F35E7F /* DevicesListView.m */, + 61AEBEBE2191991F00F35E7F /* DevicesListView.xib */, 22F2508B107141E100AC9B3F /* DialerView.h */, 22F2508C107141E100AC9B3F /* DialerView.m */, D38187C415FE345B00C3EDCA /* DialerView.xib */, @@ -2256,8 +2227,6 @@ 63E27A311C4FECD000D332AE /* LaunchScreen.xib */, 1D3623240D0F684500981E51 /* LinphoneAppDelegate.h */, 1D3623250D0F684500981E51 /* LinphoneAppDelegate.m */, - 8C2595D51DEDC8E1007A6424 /* ProviderDelegate.h */, - 8C2595DC1DEDC92D007A6424 /* ProviderDelegate.m */, D37DC6BF1594AE1800B2A5EB /* LinphoneCoreSettingsStore.h */, D37DC6C01594AE1800B2A5EB /* LinphoneCoreSettingsStore.m */, D3EA53FB159850E80037DC6B /* LinphoneManager.h */, @@ -2267,6 +2236,13 @@ D3F83F8C158229C500336684 /* PhoneMainView.h */, D3F83F8D15822ABD00336684 /* PhoneMainView.m */, 639E9CB31C0DB88200019A75 /* PhoneMainView.xib */, + 8C2595D51DEDC8E1007A6424 /* ProviderDelegate.h */, + 8C2595DC1DEDC92D007A6424 /* ProviderDelegate.m */, + CF7602DF21086EB100749F76 /* RecordingsListTableView.h */, + CF7602E021086EB200749F76 /* RecordingsListTableView.m */, + CF7602D4210867E800749F76 /* RecordingsListView.h */, + CF7602D5210867E800749F76 /* RecordingsListView.m */, + CF7602D6210867E800749F76 /* RecordingsListView.xib */, D35E759C159460B50066B1C1 /* SettingsView.h */, D35E759D159460B50066B1C1 /* SettingsView.m */, 636316D61A1DEC650009B839 /* SettingsView.xib */, @@ -2312,9 +2288,6 @@ 2214EB7012F84668002A5394 /* LinphoneUI */ = { isa = PBXGroup; children = ( - CF15F21B20E4F9A3008B1DE6 /* UIImageViewDeletable.h */, - CF15F21C20E4F9A3008B1DE6 /* UIImageViewDeletable.m */, - CF15F21D20E4F9A3008B1DE6 /* UIImageViewDeletable.xib */, 63F1DF421BCE618E00EDED90 /* UIAddressTextField.h */, 63F1DF431BCE618E00EDED90 /* UIAddressTextField.m */, 63C441C11BBC23ED0053DC5E /* UIAssistantTextField.h */, @@ -2343,27 +2316,24 @@ D3A8BB6E15A6C7D500F96BE5 /* UIChatBubbleTextCell.h */, D3A8BB6F15A6C7D500F96BE5 /* UIChatBubbleTextCell.m */, 639E9CA51C0DB7EA00019A75 /* UIChatBubbleTextCell.xib */, - 8C92ABF11FA773C20006FB5D /* UIChatNotifiedEventCell.h */, - 8C92ABF21FA773E50006FB5D /* UIChatNotifiedEventCell.m */, - 8C92ABE71FA773190006FB5D /* UIChatNotifiedEventCell.xib */, D3EA540F159853750037DC6B /* UIChatCell.h */, D3EA5410159853750037DC6B /* UIChatCell.m */, 639CEB0B1A1DF4FA004DE38F /* UIChatCell.xib */, - 8CA70AE11F9E39E400A3D2EB /* UIChatConversationInfoTableViewCell.h */, - 8CA70AE21F9E39E400A3D2EB /* UIChatConversationInfoTableViewCell.m */, - 8CBD7BA820B6B82400E5DCC0 /* UIChatConversationInfoTableViewCell.xib */, 8CD99A402090CE25008A7CDA /* UIChatConversationImdnTableViewCell.h */, 8CD99A412090CE6F008A7CDA /* UIChatConversationImdnTableViewCell.m */, 8CBD7BAB20B6B82A00E5DCC0 /* UIChatConversationImdnTableViewCell.xib */, - 8C9C5E0E1F83BD97006987FA /* UIChatCreateCollectionViewCell.h */, - 8C9C5E0F1F83BD97006987FA /* UIChatCreateCollectionViewCell.m */, - 8CBD7BAE20B6B82F00E5DCC0 /* UIChatCreateCollectionViewCell.xib */, + 8CA70AE11F9E39E400A3D2EB /* UIChatConversationInfoTableViewCell.h */, + 8CA70AE21F9E39E400A3D2EB /* UIChatConversationInfoTableViewCell.m */, + 8CBD7BA820B6B82400E5DCC0 /* UIChatConversationInfoTableViewCell.xib */, 63B8D69F1BCBF43100C12B09 /* UIChatCreateCell.h */, 63B8D6A01BCBF43100C12B09 /* UIChatCreateCell.m */, 639E9CA81C0DB7F200019A75 /* UIChatCreateCell.xib */, - 8C5D1B991D9BC48100DC6539 /* UIShopTableCell.h */, - 8C5D1B9A1D9BC48100DC6539 /* UIShopTableCell.m */, - 8C5D1B9B1D9BC48100DC6539 /* UIShopTableCell.xib */, + 8C9C5E0E1F83BD97006987FA /* UIChatCreateCollectionViewCell.h */, + 8C9C5E0F1F83BD97006987FA /* UIChatCreateCollectionViewCell.m */, + 8CBD7BAE20B6B82F00E5DCC0 /* UIChatCreateCollectionViewCell.xib */, + 8C92ABF11FA773C20006FB5D /* UIChatNotifiedEventCell.h */, + 8C92ABF21FA773E50006FB5D /* UIChatNotifiedEventCell.m */, + 8C92ABE71FA773190006FB5D /* UIChatNotifiedEventCell.xib */, 639E9C7E1C0DB13D00019A75 /* UICheckBoxTableView.h */, 639E9C7F1C0DB13D00019A75 /* UICheckBoxTableView.m */, D31B4B1E159876C0002E6C72 /* UICompositeView.h */, @@ -2376,14 +2346,17 @@ D3A55FBA15877E5E003FD403 /* UIContactCell.h */, D3A55FBB15877E5E003FD403 /* UIContactCell.m */, F088488D19FF8C41007FFCF3 /* UIContactCell.xib */, - 24A345A71D95799900881A5C /* UIShopTableCell.h */, - 24A345A51D95798A00881A5C /* UIShopTableCell.m */, - 24A3459D1D95797700881A5C /* UIShopTableCell.xib */, D3C6526515AC1A8F0092A874 /* UIContactDetailsCell.h */, D3C6526615AC1A8F0092A874 /* UIContactDetailsCell.m */, 639E9CAE1C0DB80300019A75 /* UIContactDetailsCell.xib */, 2248E90C12F7E4CF00220D9C /* UIDigitButton.h */, 2248E90D12F7E4CF00220D9C /* UIDigitButton.m */, + 61CCC3D721933B380060EDEA /* UIDeviceCell.h */, + 61CCC3DE21933B580060EDEA /* UIDeviceCell.m */, + 61CCC3E021933B660060EDEA /* UIDeviceCell.xib */, + 61AEBEC02191D7B400F35E7F /* UIDevicesDetails.h */, + 61AEBEC12191D7C800F35E7F /* UIDevicesDetails.m */, + 61AEBEC32191D7D900F35E7F /* UIDevicesDetails.xib */, 2214EB8712F84EBB002A5394 /* UIHangUpButton.h */, 2214EB8812F84EBB002A5394 /* UIHangUpButton.m */, D31C9C96158A1CDE00756B45 /* UIHistoryCell.h */, @@ -2391,18 +2364,30 @@ 639CEB021A1DF4E4004DE38F /* UIHistoryCell.xib */, 636BC9951B5F921B00C754CE /* UIIconButton.h */, 636BC9961B5F921B00C754CE /* UIIconButton.m */, + CF15F21B20E4F9A3008B1DE6 /* UIImageViewDeletable.h */, + CF15F21C20E4F9A3008B1DE6 /* UIImageViewDeletable.m */, + CF15F21D20E4F9A3008B1DE6 /* UIImageViewDeletable.xib */, 634610041B61330300548952 /* UILabel+Boldify.h */, 634610051B61330300548952 /* UILabel+Boldify.m */, + CF1DE92C210A0F5C00A0A97E /* UILinphoneAudioPlayer.h */, + CF1DE924210A0F5A00A0A97E /* UILinphoneAudioPlayer.m */, + CF1DE92B210A0F5B00A0A97E /* UILinphoneAudioPlayer.xib */, D306459C1611EC2900BB571E /* UILoadingImageView.h */, D306459D1611EC2900BB571E /* UILoadingImageView.m */, 2214EBF112F86360002A5394 /* UIMutedMicroButton.h */, 2214EBF212F86360002A5394 /* UIMutedMicroButton.m */, D36FB2D31589EF7C0036F6F2 /* UIPauseButton.h */, D36FB2D41589EF7C0036F6F2 /* UIPauseButton.m */, + CF7602E42108759A00749F76 /* UIRecordingCell.h */, + CF7602E52108759A00749F76 /* UIRecordingCell.m */, + CF7602E62108759A00749F76 /* UIRecordingCell.xib */, 6313482E1B6F7B6600C6BDCB /* UIRoundBorderedButton.h */, 6313482F1B6F7B6600C6BDCB /* UIRoundBorderedButton.m */, 63FB30331A680E73008CA393 /* UIRoundedImageView.h */, 63FB30341A680E73008CA393 /* UIRoundedImageView.m */, + 8C5D1B991D9BC48100DC6539 /* UIShopTableCell.h */, + 8C5D1B9B1D9BC48100DC6539 /* UIShopTableCell.xib */, + 24A345A71D95799900881A5C /* UIShopTableCell.h */, 22968A5D12F875C600588287 /* UISpeakerButton.h */, 22968A5E12F875C600588287 /* UISpeakerButton.m */, 630CF5551AF7CE1500539F7A /* UITextField+DoneButton.h */, @@ -2413,15 +2398,17 @@ D32648431588F6FB00930C67 /* UIToggleButton.m */, 340751E5150F38FC00B89C47 /* UIVideoButton.h */, 340751E6150F38FD00B89C47 /* UIVideoButton.m */, + 24A345A51D95798A00881A5C /* UIShopTableCell.m */, + 24A3459D1D95797700881A5C /* UIShopTableCell.xib */, ); path = LinphoneUI; sourceTree = ""; }; - 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { + 29B97314FDCFA39411CA2CEA = { isa = PBXGroup; children = ( - 15F12E672174AB4B00B7DE49 /* mediastreamer2.framework */, 8C23BCB71D82AAC3005F19BB /* linphone.entitlements */, + 614D09CD21E74D5400C43EDF /* GoogleService-Info.plist */, 080E96DDFE201D6D7F000001 /* Classes */, 61AE364C20C00B370089D9D3 /* linphoneExtension */, 5EEE8F9C20C80C23006E4176 /* latestCallsWidget */, @@ -2437,6 +2424,7 @@ D398D3031594B0FB00FD553C /* Settings */, 63058A301B4E822F00EFAE36 /* TestsLiblinphoneTester */, 630589DD1B4E810900EFAE36 /* TestsLinphone */, + 561D0FD932DE3595BE512375 /* Pods */, ); name = CustomTemplate; sourceTree = ""; @@ -2453,37 +2441,18 @@ 29B97323FDCFA39411CA2CEA /* Frameworks */ = { isa = PBXGroup; children = ( - 61F1996E20C6B1D5006B069A /* AVKit.framework */, - 8C435FA520BC34DA004CCA25 /* belr.framework */, - 8C435F8B20BBF862004CCA25 /* belcard.framework */, - 8C601FD220B462B0004FF95C /* mediastreamer2.framework */, - 8C1A1F7C1FA331D40064BE00 /* libsoci_sqlite3.a */, - 8CD0B3BE1FA22CBA008FEB16 /* libsoci_core.a */, - 249660941FD6A359001D55AA /* Photos.framework */, - 24E1C7B91F9A235500D3F981 /* Contacts.framework */, - 8C3EAA191EB8D9C300B732B6 /* linphonetester.framework */, - 8C5BCEC61EB3859200A9AAEF /* bctoolbox-tester.framework */, - 8C3EA9EF1EB8A78C00B732B6 /* msx264.framework */, - 8C3EA9E01EB892D600B732B6 /* msamr.framework */, - 8C3EA9E11EB892D600B732B6 /* mscodec2.framework */, - 8C3EA9E21EB892D600B732B6 /* msopenh264.framework */, - 8C5BCEC71EB3859200A9AAEF /* bctoolbox.framework */, - 8C5BCEC81EB3859200A9AAEF /* linphone.framework */, - 8C5BCECB1EB3859200A9AAEF /* mssilk.framework */, - 8C5BCECC1EB3859200A9AAEF /* mswebrtc.framework */, - 8C5BCECD1EB3859200A9AAEF /* ortp.framework */, - 8C2595DE1DEDCC8E007A6424 /* CallKit.framework */, - 8C73477B1D9BA3A00022EE8C /* UserNotifications.framework */, - 8CA2004B1D8158440095F859 /* PushKit.framework */, - 570742661D5A63DB004B9C84 /* StoreKit.framework */, - 63CE583F1C85EBF400304800 /* VideoToolbox.framework */, + 6180D6FD21EE41A800AD9CB6 /* QuickLook.framework */, 22B5F03410CE6B2F00777D97 /* AddressBook.framework */, 22B5EFA210CE50BD00777D97 /* AddressBookUI.framework */, 22405EED1600B4E400B92522 /* AssetsLibrary.framework */, 2274402E106F335E006EC466 /* AudioToolbox.framework */, F0BB8C311936246600974404 /* AudioUnit.framework */, 224567C1107B968500F10948 /* AVFoundation.framework */, + 61F1996E20C6B1D5006B069A /* AVKit.framework */, + 8C5BCEC61EB3859200A9AAEF /* bctoolbox-tester.framework */, + 8C2595DE1DEDCC8E007A6424 /* CallKit.framework */, 228697C311AC29B800E9E0CA /* CFNetwork.framework */, + 24E1C7B91F9A235500D3F981 /* Contacts.framework */, 22744019106F31BD006EC466 /* CoreAudio.framework */, 22744056106F9BC9006EC466 /* CoreFoundation.framework */, 288765FC0DF74451002DB57D /* CoreGraphics.framework */, @@ -2499,6 +2468,8 @@ 63EEE40D1BBA9B250087D3AF /* libiconv.tbd */, F0BB8C34193624C800974404 /* libresolv.9.dylib */, 22D1B68012A3E0BE001AE361 /* libresolv.dylib */, + 8CD0B3BE1FA22CBA008FEB16 /* libsoci_core.a */, + 8C1A1F7C1FA331D40064BE00 /* libsoci_sqlite3.a */, D32B6E2E15A5C0AC0033019F /* libsqlite3.dylib */, 63EEE40B1BBA9B1B0087D3AF /* libsqlite3.tbd */, 344ABDF014850AE9007420B6 /* libstdc++.6.dylib */, @@ -2506,21 +2477,62 @@ 152F22351B15E889008C0621 /* libxml2.dylib */, 63EEE4091BBA9B110087D3AF /* libxml2.tbd */, F05BAA611A5D594E00411815 /* libz.dylib */, + 8C3EAA191EB8D9C300B732B6 /* linphonetester.framework */, F0B89C2118DC89E30050B60E /* MediaPlayer.framework */, D37DC7171594AF3400B2A5EB /* MessageUI.framework */, 226EF06B15FA256B005865C7 /* MobileCoreServices.framework */, + 5EF0C33820C806A5005081B0 /* NotificationCenter.framework */, 70E542F213E147E3002BA2C0 /* OpenGLES.framework */, + 249660941FD6A359001D55AA /* Photos.framework */, + 8CA2004B1D8158440095F859 /* PushKit.framework */, 70E542F413E147EB002BA2C0 /* QuartzCore.framework */, 22744043106F33FC006EC466 /* Security.framework */, F0181B6B18BF7B1200A9A357 /* SenTestingKit.framework */, + 570742661D5A63DB004B9C84 /* StoreKit.framework */, 2264B6D111200342002C2C53 /* SystemConfiguration.framework */, 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, - 5EF0C33820C806A5005081B0 /* NotificationCenter.framework */, + 8C73477B1D9BA3A00022EE8C /* UserNotifications.framework */, 5E58962520DCE5700030868C /* UserNotificationsUI.framework */, + 63CE583F1C85EBF400304800 /* VideoToolbox.framework */, + 6E1BC45342F5201DABD7FE55 /* Pods_latestCallsWidget.framework */, + 8B488C393394746F9D630789 /* Pods_latestChatroomsWidget.framework */, + 9CBD6E980619195CB7EE32AC /* Pods_liblinphoneTester.framework */, + D252FEC7DD06DD5695A320A1 /* Pods_liblinphoneTesterTests.framework */, + 65CEDD144CABFAA70A29AF27 /* Pods_linphone.framework */, + BEBE8FB918176C388C01CFF7 /* Pods_linphoneExtension.framework */, + F325590DD6CD7F6CC8F60C03 /* Pods_linphoneTests.framework */, + 7513CBF7F2BA0A9F99977C2B /* Pods_richNotifications.framework */, ); name = Frameworks; sourceTree = ""; }; + 561D0FD932DE3595BE512375 /* Pods */ = { + isa = PBXGroup; + children = ( + 68D9EC27FCECD5DE2E19CD3C /* Pods-liblinphoneTester.debug.xcconfig */, + 38A3AE51B9E09ABF29222E5F /* Pods-liblinphoneTester.release.xcconfig */, + 24585CBE78DA4F005C7F9D71 /* Pods-liblinphoneTester.distribution.xcconfig */, + FD22CA9E3EFBFEFFF1B80BA2 /* Pods-liblinphoneTester.distributionadhoc.xcconfig */, + 7D8CCFE176C634813E3A2593 /* Pods-liblinphoneTesterTests.debug.xcconfig */, + BE06BDE664323B2A53469696 /* Pods-liblinphoneTesterTests.release.xcconfig */, + 248C326F4AD75E654C1CB37A /* Pods-liblinphoneTesterTests.distribution.xcconfig */, + 046DEFE77AD0675DA9932C4C /* Pods-liblinphoneTesterTests.distributionadhoc.xcconfig */, + 799BA1104845EB01ACE764D8 /* Pods-linphone.debug.xcconfig */, + FEAFB5AD0E3AA409BBD1136E /* Pods-linphone.release.xcconfig */, + 38DF35D11A7C0F45E990C83A /* Pods-linphone.distribution.xcconfig */, + FE7D89A821FDC1BCA9BB9F8F /* Pods-linphone.distributionadhoc.xcconfig */, + E5074CFA3AAD5A8B72956DDE /* Pods-linphoneExtension.debug.xcconfig */, + 283F127CA480E2E2CF0DE9C2 /* Pods-linphoneExtension.release.xcconfig */, + 78C7025E626D12D2F04EAC87 /* Pods-linphoneExtension.distribution.xcconfig */, + 620DFD020AC0182319853127 /* Pods-linphoneExtension.distributionadhoc.xcconfig */, + ABB887316C42EE876A3051A9 /* Pods-linphoneTests.debug.xcconfig */, + F6373F9231918DECD2B3004D /* Pods-linphoneTests.release.xcconfig */, + 85FB19B6A8124D942C8471F1 /* Pods-linphoneTests.distribution.xcconfig */, + CE119C214B6B8B2740622BBD /* Pods-linphoneTests.distributionadhoc.xcconfig */, + ); + name = Pods; + sourceTree = ""; + }; 5E31290220D7A37E00CF3AAE /* latestChatroomsWidget */ = { isa = PBXGroup; children = ( @@ -2608,15 +2620,6 @@ 63058A0C1B4E821E00EFAE36 /* LiblinphoneTester */ = { isa = PBXGroup; children = ( - 8C56289120236AA6007A8ECC /* db */, - 635598811C96AFFA006ED99A /* vcards */, - 63058AE41B4E952E00EFAE36 /* share */, - 63058AE11B4E93A100EFAE36 /* tester_hosts */, - 63058AC81B4E922500EFAE36 /* certificates */, - 63058AC91B4E922500EFAE36 /* flexisip */, - 63058ACA1B4E922500EFAE36 /* images */, - 63058ACD1B4E922500EFAE36 /* rcfiles */, - 63058ACE1B4E922500EFAE36 /* sounds */, 63058A0D1B4E821E00EFAE36 /* AppDelegate.h */, 63058A0E1B4E821E00EFAE36 /* AppDelegate.m */, 63058A0F1B4E821E00EFAE36 /* InfoPlist.strings */, @@ -2670,41 +2673,7 @@ 633FEBE11D3CD5570014B822 /* images */ = { isa = PBXGroup; children = ( - CFBD7A2320E504AD007C5286 /* delete_img.png */, - 24BFAA9B209B062F004F47A7 /* callkit_logo.png */, - 24BFAA99209B062E004F47A7 /* contacts_sip_default.png */, - 24BFAA94209B062C004F47A7 /* contacts_sip_default@2x.png */, - 24BFAA97209B062E004F47A7 /* contacts_sip_selected.png */, - 24BFAA9C209B062F004F47A7 /* contacts_sip_selected@2x.png */, - 24BFAA8C209B062B004F47A7 /* dialer_background.png */, - 24BFAA98209B062E004F47A7 /* linphone_logo.png */, - 24BFAA9D209B0630004F47A7 /* linphone_logo@2x.png */, - 24BFAA93209B062C004F47A7 /* linphone_user.png */, - 24BFAA95209B062D004F47A7 /* linphone_user@2x.png */, - 24BFAA9A209B062F004F47A7 /* linphone_user~ipad.png */, - 24BFAA96209B062D004F47A7 /* linphone_user~ipad@2x.png */, - 8CF25D9B1F9F76BC00BEA0C1 /* chat_group_informations.png */, - 8CF25D9C1F9F76BD00BEA0C1 /* chat_group_informations@2x.png */, - 8CF25D941F9F336100BEA0C1 /* check_unselected.png */, - 8CF25D8B1F9F336000BEA0C1 /* check_unselected@2x.png */, - 8CA70AD31F9E285B00A3D2EB /* chat_group_add.png */, - 8CA70AD21F9E285B00A3D2EB /* chat_group_add@2x.png */, - 8C2A81941F87B8000012A66B /* chat_group_avatar.png */, - 8C2A81931F87B7FF0012A66B /* chat_group_avatar@2x.png */, - 8CB2B8F61F86229B0015CEE2 /* chat_secure.png */, - 8CB2B8F71F86229C0015CEE2 /* next_disabled.png */, - 8CB2B8F81F86229D0015CEE2 /* next_disabled@2x.png */, - 8CDC61961F84D9270087CF7F /* check_selected@2x.png */, - 8CDC618C1F84D89B0087CF7F /* check_selected.png */, - 8CE24F551F8268840077AC0A /* conference_delete.png */, - 8CE24F561F8268840077AC0A /* conference_delete@2x.png */, - 8CE24F491F8234A20077AC0A /* next_default.png */, - 8CE24F4A1F8234A30077AC0A /* next_default@2x.png */, - 8C300D981E40E0CC00728EF3 /* lime_ko.png */, - 8C300D991E40E0CC00728EF3 /* lime_ko@2x.png */, - 8CD99A1B20908C27008A7CDA /* callkit_logo@2x.png */, 633FEBE21D3CD5570014B822 /* add_field_default.png */, - 244523BC1E8D3A6C0037A187 /* chat_unsecure.png */, 633FEBE31D3CD5570014B822 /* add_field_default@2x.png */, 633FEBE41D3CD5570014B822 /* add_field_over.png */, 633FEBE51D3CD5570014B822 /* add_field_over@2x.png */, @@ -2757,9 +2726,6 @@ 633FEC141D3CD5570014B822 /* call_quality_indicator_1.png */, 633FEC151D3CD5570014B822 /* call_quality_indicator_1@2x.png */, 633FEC161D3CD5570014B822 /* call_quality_indicator_2.png */, - 244523AC1E8266CC0037A187 /* chat_delivered.png */, - 244523AD1E8266CC0037A187 /* chat_error.png */, - 244523AE1E8266CC0037A187 /* chat_read.png */, 633FEC171D3CD5570014B822 /* call_quality_indicator_2@2x.png */, 633FEC181D3CD5570014B822 /* call_quality_indicator_3.png */, 633FEC191D3CD5570014B822 /* call_quality_indicator_3@2x.png */, @@ -2797,6 +2763,8 @@ 633FEC391D3CD5570014B822 /* call_video_start_default@2x.png */, 633FEC3A1D3CD5570014B822 /* call_video_start_disabled.png */, 633FEC3B1D3CD5570014B822 /* call_video_start_disabled@2x.png */, + 24BFAA9B209B062F004F47A7 /* callkit_logo.png */, + 8CD99A1B20908C27008A7CDA /* callkit_logo@2x.png */, 633FEC3C1D3CD5570014B822 /* camera_default.png */, 633FEC3D1D3CD5570014B822 /* camera_default@2x.png */, 633FEC3E1D3CD5570014B822 /* camera_disabled.png */, @@ -2817,16 +2785,30 @@ 633FEC4D1D3CD5570014B822 /* chat_add_default@2x.png */, 633FEC4E1D3CD5570014B822 /* chat_add_disabled.png */, 633FEC4F1D3CD5570014B822 /* chat_add_disabled@2x.png */, + 615A2808217F1FD40060F920 /* chat_add_group.png */, + 615A2810217F1FDE0060F920 /* chat_add_group@2x.png */, 633FEC501D3CD5570014B822 /* chat_attachment_default.png */, 633FEC511D3CD5570014B822 /* chat_attachment_default@2x.png */, 633FEC521D3CD5570014B822 /* chat_attachment_disabled.png */, 633FEC531D3CD5570014B822 /* chat_attachment_disabled@2x.png */, 633FEC541D3CD5570014B822 /* chat_attachment_over.png */, 633FEC551D3CD5570014B822 /* chat_attachment_over@2x.png */, + 244523AC1E8266CC0037A187 /* chat_delivered.png */, + 244523AD1E8266CC0037A187 /* chat_error.png */, + 8CA70AD31F9E285B00A3D2EB /* chat_group_add.png */, + 8CA70AD21F9E285B00A3D2EB /* chat_group_add@2x.png */, + 8C2A81941F87B8000012A66B /* chat_group_avatar.png */, + 8C2A81931F87B7FF0012A66B /* chat_group_avatar@2x.png */, + 8CF25D9B1F9F76BC00BEA0C1 /* chat_group_informations.png */, + 8CF25D9C1F9F76BD00BEA0C1 /* chat_group_informations@2x.png */, + 615A2816217F280C0060F920 /* chat_list_indicator.png */, + 615A2818217F28160060F920 /* chat_list_indicator@2x.png */, 633FEC561D3CD5570014B822 /* chat_list_indicator~ipad.png */, 633FEC571D3CD5570014B822 /* chat_list_indicator~ipad@2x.png */, 633FEC581D3CD5570014B822 /* chat_message_not_delivered.png */, 633FEC591D3CD5570014B822 /* chat_message_not_delivered@2x.png */, + 244523AE1E8266CC0037A187 /* chat_read.png */, + 8CB2B8F61F86229B0015CEE2 /* chat_secure.png */, 633FEC5A1D3CD5570014B822 /* chat_send_default.png */, 633FEC5B1D3CD5570014B822 /* chat_send_default@2x.png */, 633FEC5C1D3CD5570014B822 /* chat_send_disabled.png */, @@ -2845,10 +2827,19 @@ 633FEC691D3CD5570014B822 /* chat_start_body_over@2x.png */, 633FEC6A1D3CD5570014B822 /* chat_start_body_over~ipad.png */, 633FEC6B1D3CD5570014B822 /* chat_start_body_over~ipad@2x.png */, + 244523BC1E8D3A6C0037A187 /* chat_unsecure.png */, + 8CDC618C1F84D89B0087CF7F /* check_selected.png */, + 8CDC61961F84D9270087CF7F /* check_selected@2x.png */, + 8CF25D941F9F336100BEA0C1 /* check_unselected.png */, + 8CF25D8B1F9F336000BEA0C1 /* check_unselected@2x.png */, 633FEC6C1D3CD5570014B822 /* checkbox_checked.png */, 633FEC6D1D3CD5570014B822 /* checkbox_checked@2x.png */, 633FEC6E1D3CD5570014B822 /* checkbox_unchecked.png */, 633FEC6F1D3CD5570014B822 /* checkbox_unchecked@2x.png */, + 61AEBEC52191E47500F35E7F /* chevron_list_close.png */, + 61AEBEC72191E48400F35E7F /* chevron_list_close@2x.png */, + 61AEBEC92191E49200F35E7F /* chevron_list_open.png */, + 61AEBECB2191E4A300F35E7F /* chevron_list_open@2x.png */, 633FEC701D3CD5570014B822 /* color_A.png */, 633FEC711D3CD5570014B822 /* color_C.png */, 633FEC721D3CD5570014B822 /* color_D.png */, @@ -2859,6 +2850,8 @@ 633FEC771D3CD5570014B822 /* color_I.png */, 633FEC781D3CD5570014B822 /* color_L.png */, 633FEC791D3CD5570014B822 /* color_M.png */, + 8CE24F551F8268840077AC0A /* conference_delete.png */, + 8CE24F561F8268840077AC0A /* conference_delete@2x.png */, 633FEC7A1D3CD5570014B822 /* conference_exit_default.png */, 633FEC7B1D3CD5570014B822 /* conference_exit_default@2x.png */, 633FEC7C1D3CD5570014B822 /* conference_exit_over.png */, @@ -2873,6 +2866,10 @@ 633FEC851D3CD5570014B822 /* contacts_all_disabled@2x.png */, 633FEC861D3CD5570014B822 /* contacts_all_selected.png */, 633FEC871D3CD5570014B822 /* contacts_all_selected@2x.png */, + 24BFAA99209B062E004F47A7 /* contacts_sip_default.png */, + 24BFAA94209B062C004F47A7 /* contacts_sip_default@2x.png */, + 24BFAA97209B062E004F47A7 /* contacts_sip_selected.png */, + 24BFAA9C209B062F004F47A7 /* contacts_sip_selected@2x.png */, 633FEC8E1D3CD5570014B822 /* delete_default.png */, 633FEC8F1D3CD5570014B822 /* delete_default@2x.png */, 633FEC901D3CD5570014B822 /* delete_disabled.png */, @@ -2881,6 +2878,7 @@ 633FEC931D3CD5570014B822 /* delete_field_default@2x.png */, 633FEC941D3CD5570014B822 /* delete_field_over.png */, 633FEC951D3CD5570014B822 /* delete_field_over@2x.png */, + CFBD7A2320E504AD007C5286 /* delete_img.png */, 633FEC961D3CD5570014B822 /* deselect_all.png */, 633FEC971D3CD5570014B822 /* deselect_all@2x.png */, 633FEC981D3CD5570014B822 /* dialer_alt_back.png */, @@ -2889,6 +2887,7 @@ 633FEC9B1D3CD5570014B822 /* dialer_back_default@2x.png */, 633FEC9C1D3CD5570014B822 /* dialer_back_disabled.png */, 633FEC9D1D3CD5570014B822 /* dialer_back_disabled@2x.png */, + 24BFAA8C209B062B004F47A7 /* dialer_background.png */, 633FECA01D3CD5570014B822 /* edit_default.png */, 633FECA11D3CD5570014B822 /* edit_default@2x.png */, 633FECA21D3CD5570014B822 /* edit_disabled.png */, @@ -2898,8 +2897,8 @@ 633FECA61D3CD5570014B822 /* edit_list_disabled.png */, 633FECA71D3CD5570014B822 /* edit_list_disabled@2x.png */, 633FECA81D3CD5570014B822 /* footer_chat_default.png */, - 633FECAA1D3CD5570014B822 /* footer_chat_disabled.png */, 633FECA91D3CD5570014B822 /* footer_chat_default@2x.png */, + 633FECAA1D3CD5570014B822 /* footer_chat_disabled.png */, 633FECAB1D3CD5570014B822 /* footer_chat_disabled@2x.png */, 633FECAC1D3CD5570014B822 /* footer_contacts_default.png */, 633FECAD1D3CD5570014B822 /* footer_contacts_default@2x.png */, @@ -2927,6 +2926,8 @@ 633FECC31D3CD5570014B822 /* history_missed_disabled@2x.png */, 633FECC41D3CD5570014B822 /* history_missed_selected.png */, 633FECC51D3CD5570014B822 /* history_missed_selected@2x.png */, + 615A283D2180A2550060F920 /* invite_linphone.png */, + 615A283F2180A2620060F920 /* invite_linphone@2x.png */, 633FECC61D3CD5570014B822 /* led_connected.png */, 633FECC71D3CD5570014B822 /* led_connected@2x.png */, 633FECC81D3CD5570014B822 /* led_disconnected.png */, @@ -2935,18 +2936,40 @@ 633FECCB1D3CD5570014B822 /* led_error@2x.png */, 633FECCC1D3CD5570014B822 /* led_inprogress.png */, 633FECCD1D3CD5570014B822 /* led_inprogress@2x.png */, + 8C300D981E40E0CC00728EF3 /* lime_ko.png */, + 8C300D991E40E0CC00728EF3 /* lime_ko@2x.png */, + 24BFAA98209B062E004F47A7 /* linphone_logo.png */, + 24BFAA9D209B0630004F47A7 /* linphone_logo@2x.png */, + 24BFAA93209B062C004F47A7 /* linphone_user.png */, + 24BFAA95209B062D004F47A7 /* linphone_user@2x.png */, + 24BFAA9A209B062F004F47A7 /* linphone_user~ipad.png */, + 24BFAA96209B062D004F47A7 /* linphone_user~ipad@2x.png */, 633FECD41D3CD5580014B822 /* list_details_default.png */, 633FECD51D3CD5580014B822 /* list_details_default@2x.png */, 633FECD61D3CD5580014B822 /* list_details_over.png */, 633FECD71D3CD5580014B822 /* list_details_over@2x.png */, 633FECD81D3CD5580014B822 /* menu.png */, 633FECD91D3CD5580014B822 /* menu@2x.png */, + 61586B7A217A16EE0038AC45 /* menu_about.png */, + 61586B82217A16FD0038AC45 /* menu_about@2x.png */, + 61586B84217A17070038AC45 /* menu_assistant.png */, + 61586B86217A17150038AC45 /* menu_assistant@2x.png */, + 61586B88217A17220038AC45 /* menu_link_account.png */, + 61586B8A217A17320038AC45 /* menu_link_account@2x.png */, + 61586B8C217A173F0038AC45 /* menu_options.png */, + 61586B8E217A174F0038AC45 /* menu_options@2x.png */, + 61586B90217A175C0038AC45 /* menu_recordings.png */, + 61586B92217A176F0038AC45 /* menu_recordings@2x.png */, 633FECDA1D3CD5580014B822 /* micro_default.png */, 633FECDB1D3CD5580014B822 /* micro_default@2x.png */, 633FECDC1D3CD5580014B822 /* micro_disabled.png */, 633FECDD1D3CD5580014B822 /* micro_disabled@2x.png */, 633FECDE1D3CD5580014B822 /* micro_selected.png */, 633FECDF1D3CD5580014B822 /* micro_selected@2x.png */, + 8CE24F491F8234A20077AC0A /* next_default.png */, + 8CE24F4A1F8234A30077AC0A /* next_default@2x.png */, + 8CB2B8F71F86229C0015CEE2 /* next_disabled.png */, + 8CB2B8F81F86229D0015CEE2 /* next_disabled@2x.png */, 633FECE01D3CD5580014B822 /* nowebcamCIF.jpg */, 633FECE11D3CD5580014B822 /* numpad_0_default.png */, 633FECE21D3CD5580014B822 /* numpad_0_default@2x.png */, @@ -3083,6 +3106,12 @@ 633FED651D3CD5590014B822 /* presence_online@2x.png */, 633FED661D3CD5590014B822 /* presence_unregistered.png */, 633FED671D3CD5590014B822 /* presence_unregistered@2x.png */, + CF7602F3210898C600749F76 /* rec_off_default.png */, + CF7602EB210898C100749F76 /* rec_off_default@2x.png */, + CF7602F4210898C800749F76 /* rec_on_default.png */, + CF7602F2210898C400749F76 /* rec_on_default@2x.png */, + 615A28412180C0820060F920 /* recording.png */, + 615A28432180C08F0060F920 /* recording@2x.png */, 633FED681D3CD5590014B822 /* route_bluetooth_default.png */, 633FED691D3CD5590014B822 /* route_bluetooth_default@2x.png */, 633FED6A1D3CD5590014B822 /* route_bluetooth_disabled.png */, @@ -3107,24 +3136,40 @@ 633FED7D1D3CD5590014B822 /* routes_disabled@2x.png */, 633FED7E1D3CD5590014B822 /* routes_selected.png */, 633FED7F1D3CD5590014B822 /* routes_selected@2x.png */, + 615A2812217F24D40060F920 /* security_1_indicator.png */, + 615A2814217F24E00060F920 /* security_1_indicator@2x.png */, + 615A281A217F6F9B0060F920 /* security_2_indicator.png */, + 615A281C217F6FA80060F920 /* security_2_indicator@2x.png */, + 615A281E217F6FB30060F920 /* security_alert_indicator.png */, + 615A2820217F6FBF0060F920 /* security_alert_indicator@2x.png */, 633FED801D3CD5590014B822 /* security_ko.png */, 633FED811D3CD5590014B822 /* security_ko@2x.png */, 633FED821D3CD5590014B822 /* security_ok.png */, 633FED831D3CD5590014B822 /* security_ok@2x.png */, 633FED841D3CD5590014B822 /* security_pending.png */, 633FED851D3CD5590014B822 /* security_pending@2x.png */, + 615A282F218071E80060F920 /* security_toogle_background_green.png */, + 615A2831218071F30060F920 /* security_toogle_background_green@2x.png */, + 615A2833218071FF0060F920 /* security_toogle_background_grey.png */, + 615A28352180720D0060F920 /* security_toogle_background_grey@2x.png */, + 615A28392180788E0060F920 /* security_toogle_button.png */, + 615A283B2180789C0060F920 /* security_toogle_button@2x.png */, + 615A282321805B250060F920 /* security_toogle_icon_green.png */, + 615A282521805B320060F920 /* security_toogle_icon_green@2x.png */, + 615A282721805B400060F920 /* security_toogle_icon_grey.png */, + 615A282921805B4C0060F920 /* security_toogle_icon_grey@2x.png */, 633FED861D3CD5590014B822 /* select_all_default.png */, 633FED871D3CD5590014B822 /* select_all_default@2x.png */, 633FED881D3CD5590014B822 /* select_all_disabled.png */, 633FED891D3CD5590014B822 /* select_all_disabled@2x.png */, - 8CD99A362090A824008A7CDA /* splashscreen.png */, - 8CD99A352090A823008A7CDA /* splashscreen@2x.png */, 633FED8A1D3CD5590014B822 /* speaker_default.png */, 633FED8B1D3CD5590014B822 /* speaker_default@2x.png */, 633FED8C1D3CD5590014B822 /* speaker_disabled.png */, 633FED8D1D3CD5590014B822 /* speaker_disabled@2x.png */, 633FED8E1D3CD5590014B822 /* speaker_selected.png */, 633FED8F1D3CD5590014B822 /* speaker_selected@2x.png */, + 8CD99A362090A824008A7CDA /* splashscreen.png */, + 8CD99A352090A823008A7CDA /* splashscreen@2x.png */, 633FED941D3CD5590014B822 /* valid_default.png */, 633FED951D3CD5590014B822 /* valid_default@2x.png */, 633FED961D3CD5590014B822 /* valid_disabled.png */, @@ -3348,7 +3393,7 @@ isa = PBXNativeTarget; buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "linphone" */; buildPhases = ( - 639002451D4106CA00BEFC78 /* ShellScript */, + 20EEEF6D60A7B77C2EFF85DB /* [CP] Check Pods Manifest.lock */, 1D60588D0D05DD3D006BFB54 /* Resources */, 63DCC71D1A07B08E00916627 /* Run Script */, 1D60588E0D05DD3D006BFB54 /* Sources */, @@ -3356,14 +3401,14 @@ 8CDC89061EAF89A8006B5652 /* Embed Frameworks */, 8CB438A61EE6A65D0006F944 /* ShellScript */, 5EF0C35020C806A5005081B0 /* Embed App Extensions */, + 4D22DCAAC0231865D78AC1E6 /* [CP] Embed Pods Frameworks */, + A73A24C4B99B11012FDAA7CF /* [CP] Copy Pods Resources */, + 614D0A1821E77F5300C43EDF /* ShellScript */, ); buildRules = ( ); dependencies = ( 61AE365520C00B370089D9D3 /* PBXTargetDependency */, - 5EEE8FA520C80C23006E4176 /* PBXTargetDependency */, - 5E31290B20D7A37E00CF3AAE /* PBXTargetDependency */, - 5E58963020DCE5710030868C /* PBXTargetDependency */, ); name = linphone; productName = linphone; @@ -3425,6 +3470,7 @@ isa = PBXNativeTarget; buildConfigurationList = 61AE366120C00B370089D9D3 /* Build configuration list for PBXNativeTarget "linphoneExtension" */; buildPhases = ( + F43E063274A630F02AB2AAEC /* [CP] Check Pods Manifest.lock */, 61AE364720C00B370089D9D3 /* Sources */, 61AE364820C00B370089D9D3 /* Frameworks */, 61AE364920C00B370089D9D3 /* Resources */, @@ -3442,6 +3488,7 @@ isa = PBXNativeTarget; buildConfigurationList = F08F119319C09C6B007D70C2 /* Build configuration list for PBXNativeTarget "liblinphoneTesterTests" */; buildPhases = ( + 5599CB1883357B4D67CCC202 /* [CP] Check Pods Manifest.lock */, F08F118019C09C6A007D70C2 /* Sources */, F08F118119C09C6A007D70C2 /* Frameworks */, F08F118219C09C6A007D70C2 /* Resources */, @@ -3460,11 +3507,12 @@ isa = PBXNativeTarget; buildConfigurationList = F0BB8C051936208200974404 /* Build configuration list for PBXNativeTarget "liblinphoneTester" */; buildPhases = ( - 8CDC89151EAF8CE2006B5652 /* CopyFiles */, + 9B9A5E3BD753D3A8A6E82117 /* [CP] Check Pods Manifest.lock */, F0BB8BD11936208100974404 /* Sources */, F0BB8BD21936208100974404 /* Frameworks */, F0BB8BD31936208100974404 /* Resources */, - 8CDC89111EAF89B7006B5652 /* Embed Frameworks */, + A68C4E88E4EC059C04D389FE /* [CP] Embed Pods Frameworks */, + 61C84B4200D58AABECCE326E /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -3479,6 +3527,7 @@ isa = PBXNativeTarget; buildConfigurationList = F0F9520C1A6AEB1100254160 /* Build configuration list for PBXNativeTarget "linphoneTests" */; buildPhases = ( + 7FF8A712621CDB927700B916 /* [CP] Check Pods Manifest.lock */, F0F951FC1A6AEB1000254160 /* Sources */, F0F951FD1A6AEB1000254160 /* Frameworks */, F0F951FE1A6AEB1000254160 /* Resources */, @@ -3519,7 +3568,7 @@ enabled = 1; }; com.apple.iCloud = { - enabled = 0; + enabled = 1; }; }; }; @@ -3595,7 +3644,8 @@ zh_CN, fr, ); - mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + mainGroup = 29B97314FDCFA39411CA2CEA; + productRefGroup = 19C28FACFE9D520D11CA2CBB /* Products */; projectDirPath = ""; projectReferences = ( { @@ -3674,6 +3724,7 @@ 636316D11A1DEBCB0009B839 /* AboutView.xib in Resources */, 8CBD7BA620B6B82400E5DCC0 /* UIChatConversationInfoTableViewCell.xib in Resources */, 244523AF1E8266CC0037A187 /* chat_delivered.png in Resources */, + CF7602F8210898CC00749F76 /* rec_on_default.png in Resources */, 633FEF481D3CD55A0014B822 /* speaker_selected.png in Resources */, 633FEED91D3CD55A0014B822 /* numpad_7~ipad.png in Resources */, 633FEE2B1D3CD5590014B822 /* color_C.png in Resources */, @@ -3695,6 +3746,7 @@ 633FEDC61D3CD5590014B822 /* call_incoming.png in Resources */, 633FEF2D1D3CD55A0014B822 /* route_earpiece_selected@2x.png in Resources */, 638F1A621C2021B2004B8E02 /* DialerView~ipad.xib in Resources */, + 615A2817217F280C0060F920 /* chat_list_indicator.png in Resources */, 633FEEFF1D3CD55A0014B822 /* options_add_call_disabled@2x.png in Resources */, 633FEF091D3CD55A0014B822 /* options_start_conference_disabled@2x.png in Resources */, 633FEE051D3CD5590014B822 /* cancel_edit_disabled@2x.png in Resources */, @@ -3707,7 +3759,7 @@ 633FEED41D3CD55A0014B822 /* numpad_7_default@2x.png in Resources */, 633FEEE01D3CD55A0014B822 /* numpad_8_over~ipad@2x.png in Resources */, 633FEDDC1D3CD5590014B822 /* call_start_body_disabled~ipad.png in Resources */, - 63E802DB1C625AEF000D5509 /* (null) in Resources */, + 63E802DB1C625AEF000D5509 /* BuildFile in Resources */, 633FEE2E1D3CD5590014B822 /* color_F.png in Resources */, 633FEDC51D3CD5590014B822 /* call_hangup_disabled@2x.png in Resources */, 633FEEDF1D3CD55A0014B822 /* numpad_8_over~ipad.png in Resources */, @@ -3720,6 +3772,7 @@ 633FEF0B1D3CD55A0014B822 /* options_transfer_call_default@2x.png in Resources */, 633FEDE81D3CD5590014B822 /* call_status_missed~ipad.png in Resources */, 63AADBFF1B6A0FF200AA16FD /* assistant_external_sip.rc in Resources */, + 61CCC3E121933B660060EDEA /* UIDeviceCell.xib in Resources */, 633FEE9E1D3CD55A0014B822 /* numpad_0_over@2x.png in Resources */, 634610121B6140A500548952 /* CallOutgoingView.xib in Resources */, 8CE24F581F8268850077AC0A /* conference_delete@2x.png in Resources */, @@ -3757,6 +3810,7 @@ 633FEF191D3CD55A0014B822 /* pause_small_over_selected@2x.png in Resources */, 633FEDA71D3CD5590014B822 /* back_disabled@2x.png in Resources */, 633FEDBD1D3CD5590014B822 /* call_audio_start_disabled@2x.png in Resources */, + 615A2815217F24E00060F920 /* security_1_indicator@2x.png in Resources */, 633FEE981D3CD55A0014B822 /* micro_selected.png in Resources */, 633FEEB51D3CD55A0014B822 /* numpad_3_over.png in Resources */, 633FEE041D3CD5590014B822 /* cancel_edit_disabled.png in Resources */, @@ -3777,6 +3831,7 @@ 633FEE491D3CD5590014B822 /* delete_default@2x.png in Resources */, 633FEF291D3CD55A0014B822 /* route_earpiece_default@2x.png in Resources */, 633FEE271D3CD5590014B822 /* checkbox_checked@2x.png in Resources */, + 61586B85217A17070038AC45 /* menu_assistant.png in Resources */, 633FEDCC1D3CD5590014B822 /* call_quality_indicator_0.png in Resources */, 633FEDEB1D3CD5590014B822 /* call_status_outgoing@2x.png in Resources */, 633FEDEE1D3CD5590014B822 /* call_transfer_default.png in Resources */, @@ -3788,6 +3843,7 @@ 633FEEB11D3CD55A0014B822 /* numpad_2~ipad.png in Resources */, 633FEE521D3CD5590014B822 /* dialer_alt_back.png in Resources */, 633FEE341D3CD5590014B822 /* conference_exit_default.png in Resources */, + 615A283E2180A2560060F920 /* invite_linphone.png in Resources */, 633FEF281D3CD55A0014B822 /* route_earpiece_default.png in Resources */, 633FEE4F1D3CD5590014B822 /* delete_field_over@2x.png in Resources */, 633FEE531D3CD5590014B822 /* dialer_alt_back@2x.png in Resources */, @@ -3804,6 +3860,8 @@ 633FEDE91D3CD5590014B822 /* call_status_missed~ipad@2x.png in Resources */, 8CE24F4C1F8234A30077AC0A /* next_default@2x.png in Resources */, 244523B11E8266CC0037A187 /* chat_read.png in Resources */, + 61AEBEC62191E47500F35E7F /* chevron_list_close.png in Resources */, + CF7602D8210867E800749F76 /* RecordingsListView.xib in Resources */, 639E9CAC1C0DB80300019A75 /* UIContactDetailsCell.xib in Resources */, 633FEE511D3CD5590014B822 /* deselect_all@2x.png in Resources */, 8CF25D951F9F336100BEA0C1 /* check_unselected@2x.png in Resources */, @@ -3811,6 +3869,8 @@ 633FEE381D3CD5590014B822 /* contact_add_default.png in Resources */, 633FEE6F1D3CD5590014B822 /* footer_history_default@2x.png in Resources */, 633FEF201D3CD55A0014B822 /* presence_unregistered.png in Resources */, + 61586B8D217A173F0038AC45 /* menu_options.png in Resources */, + 61AEBEC82191E48400F35E7F /* chevron_list_close@2x.png in Resources */, 633FEF341D3CD55A0014B822 /* routes_default.png in Resources */, 633FEE061D3CD5590014B822 /* chat_add_default.png in Resources */, 633FEDF21D3CD5590014B822 /* call_video_start_default.png in Resources */, @@ -3825,6 +3885,7 @@ 633FEE2D1D3CD5590014B822 /* color_E.png in Resources */, 633FEED01D3CD55A0014B822 /* numpad_6_over~ipad@2x.png in Resources */, 633FEEC81D3CD55A0014B822 /* numpad_5_over~ipad@2x.png in Resources */, + 61586B91217A175D0038AC45 /* menu_recordings.png in Resources */, 633FEF1B1D3CD55A0014B822 /* presence_away@2x.png in Resources */, 633FEE281D3CD5590014B822 /* checkbox_unchecked.png in Resources */, 633FEE9D1D3CD55A0014B822 /* numpad_0_over.png in Resources */, @@ -3840,9 +3901,11 @@ 633FEE3B1D3CD5590014B822 /* contact_add_disabled@2x.png in Resources */, 633FEF011D3CD55A0014B822 /* options_default@2x.png in Resources */, 633FEEC01D3CD55A0014B822 /* numpad_4_over~ipad@2x.png in Resources */, + 61586B8B217A17320038AC45 /* menu_link_account@2x.png in Resources */, 63CDC4661C3BDE370085F529 /* shortring.caf in Resources */, 633FEDD51D3CD5590014B822 /* call_quality_indicator_4@2x.png in Resources */, 633FEDE71D3CD5590014B822 /* call_status_missed@2x.png in Resources */, + 615A2821217F6FBF0060F920 /* security_alert_indicator@2x.png in Resources */, 633FEE1E1D3CD5590014B822 /* chat_start_body_disabled.png in Resources */, 639CEB001A1DF4E4004DE38F /* UIHistoryCell.xib in Resources */, 633FEE841D3CD5590014B822 /* led_error.png in Resources */, @@ -3862,6 +3925,7 @@ D38187B115FE340500C3EDCA /* ChatsListView.xib in Resources */, 633FEDA41D3CD5590014B822 /* back_default.png in Resources */, 633FEE2C1D3CD5590014B822 /* color_D.png in Resources */, + 615A280F217F1FD50060F920 /* chat_add_group.png in Resources */, 633FEEC41D3CD55A0014B822 /* numpad_5_default@2x.png in Resources */, 633FEDAC1D3CD5590014B822 /* backspace_over.png in Resources */, 639E9C9D1C0DB7DF00019A75 /* UICallPausedCell.xib in Resources */, @@ -3878,9 +3942,11 @@ 633FEDFD1D3CD5590014B822 /* camera_switch_default@2x.png in Resources */, 633FEEC51D3CD55A0014B822 /* numpad_5_over.png in Resources */, 633FEE721D3CD5590014B822 /* history_all_default.png in Resources */, + 615A283C2180789C0060F920 /* security_toogle_button@2x.png in Resources */, 633FEF0A1D3CD55A0014B822 /* options_transfer_call_default.png in Resources */, 633FEDA51D3CD5590014B822 /* back_default@2x.png in Resources */, 633FEF311D3CD55A0014B822 /* route_speaker_disabled@2x.png in Resources */, + 61586B81217A16EE0038AC45 /* menu_about.png in Resources */, 633FEEE41D3CD55A0014B822 /* numpad_9_default@2x.png in Resources */, 8C2A81961F87B8000012A66B /* chat_group_avatar.png in Resources */, 633FEDA31D3CD5590014B822 /* avatar~ipad@2x.png in Resources */, @@ -3900,6 +3966,7 @@ 633FEEA41D3CD55A0014B822 /* numpad_1_default@2x.png in Resources */, 63E27A321C4FECD000D332AE /* LaunchScreen.xib in Resources */, 633FEED11D3CD55A0014B822 /* numpad_6~ipad.png in Resources */, + CF7602E82108759A00749F76 /* UIRecordingCell.xib in Resources */, 633FEED21D3CD55A0014B822 /* numpad_6~ipad@2x.png in Resources */, 633FEDCD1D3CD5590014B822 /* call_quality_indicator_0@2x.png in Resources */, 636316D41A1DEC650009B839 /* SettingsView.xib in Resources */, @@ -3908,6 +3975,8 @@ 633FEEAD1D3CD55A0014B822 /* numpad_2_over.png in Resources */, 633FEE801D3CD5590014B822 /* led_connected.png in Resources */, 633FEEF41D3CD55A0014B822 /* numpad_star_default.png in Resources */, + 61586B93217A17700038AC45 /* menu_recordings@2x.png in Resources */, + 615A2834218071FF0060F920 /* security_toogle_background_grey.png in Resources */, 633FEDDE1D3CD5590014B822 /* call_start_body_over.png in Resources */, 24BFAAA0209B0630004F47A7 /* contacts_sip_default@2x.png in Resources */, 8CF25D9D1F9F76BD00BEA0C1 /* chat_group_informations.png in Resources */, @@ -3920,13 +3989,18 @@ 633FEE031D3CD5590014B822 /* cancel_edit_default@2x.png in Resources */, 633FEDE01D3CD5590014B822 /* call_start_body_over~ipad.png in Resources */, 8CBD7BA920B6B82A00E5DCC0 /* UIChatConversationImdnTableViewCell.xib in Resources */, + 615A28442180C0900060F920 /* recording@2x.png in Resources */, + 615A2813217F24D40060F920 /* security_1_indicator.png in Resources */, 24BFAAA7209B0630004F47A7 /* callkit_logo.png in Resources */, + 615A2811217F1FDE0060F920 /* chat_add_group@2x.png in Resources */, D34F6F9E1594D3FB0095705B /* InAppSettings.bundle in Resources */, 633FEE4D1D3CD5590014B822 /* delete_field_default@2x.png in Resources */, + 615A28362180720D0060F920 /* security_toogle_background_grey@2x.png in Resources */, 639CEB091A1DF4FA004DE38F /* UIChatCell.xib in Resources */, 633FEE961D3CD55A0014B822 /* micro_disabled.png in Resources */, 63AADBF61B6A0FF200AA16FD /* linphonerc-factory in Resources */, 633FEE671D3CD5590014B822 /* footer_contacts_default@2x.png in Resources */, + 615A2830218071E80060F920 /* security_toogle_background_green.png in Resources */, 63B8D68C1BCBE65600C12B09 /* ChatConversationCreateView.xib in Resources */, D38187D915FE347700C3EDCA /* CallIncomingView.xib in Resources */, 63CDC45F1C3BDE370085F529 /* ringback.wav in Resources */, @@ -3934,12 +4008,14 @@ 633FEE251D3CD5590014B822 /* chat_start_body_over~ipad@2x.png in Resources */, 633FEDF91D3CD5590014B822 /* camera_disabled@2x.png in Resources */, 633FEE161D3CD5590014B822 /* chat_send_disabled.png in Resources */, + 615A282421805B260060F920 /* security_toogle_icon_green.png in Resources */, 633FEE1A1D3CD5590014B822 /* chat_start_body_default.png in Resources */, 633FEF041D3CD55A0014B822 /* options_selected.png in Resources */, 633FEEE61D3CD55A0014B822 /* numpad_9_over@2x.png in Resources */, 63E27A521C50EDB000D332AE /* hold.mkv in Resources */, 633FEEDC1D3CD55A0014B822 /* numpad_8_default@2x.png in Resources */, 633FEDAE1D3CD5590014B822 /* call_add_default.png in Resources */, + 61AEBEC42191D7D900F35E7F /* UIDevicesDetails.xib in Resources */, 633FEE1D1D3CD5590014B822 /* chat_start_body_default~ipad@2x.png in Resources */, 633FEEEB1D3CD55A0014B822 /* numpad_hash_default.png in Resources */, 633FEF221D3CD55A0014B822 /* route_bluetooth_default.png in Resources */, @@ -3951,13 +4027,17 @@ 633FEF271D3CD55A0014B822 /* route_bluetooth_selected@2x.png in Resources */, 633FEE111D3CD5590014B822 /* chat_list_indicator~ipad@2x.png in Resources */, 633FEEFC1D3CD55A0014B822 /* options_add_call_default.png in Resources */, + 615A2819217F28160060F920 /* chat_list_indicator@2x.png in Resources */, + 61AEBECC2191E4A300F35E7F /* chevron_list_open@2x.png in Resources */, 24BFAAA5209B0630004F47A7 /* contacts_sip_default.png in Resources */, 633FEF441D3CD55A0014B822 /* speaker_default.png in Resources */, 639CEB031A1DF4EB004DE38F /* UICompositeView.xib in Resources */, 633FEF3A1D3CD55A0014B822 /* security_ko.png in Resources */, + 615A283A2180788E0060F920 /* security_toogle_button.png in Resources */, 633FEDA01D3CD5590014B822 /* avatar.png in Resources */, 633FEEBC1D3CD55A0014B822 /* numpad_4_default@2x.png in Resources */, 633FEEA91D3CD55A0014B822 /* numpad_1~ipad.png in Resources */, + 615A28402180A2620060F920 /* invite_linphone@2x.png in Resources */, 633FEDF71D3CD5590014B822 /* camera_default@2x.png in Resources */, 633FEDB31D3CD5590014B822 /* call_alt_back_default@2x.png in Resources */, 633FEDCF1D3CD5590014B822 /* call_quality_indicator_1@2x.png in Resources */, @@ -3967,11 +4047,14 @@ 63AADBF81B6A0FF200AA16FD /* linphonerc~ipad in Resources */, 633FEE8F1D3CD55A0014B822 /* list_details_default@2x.png in Resources */, 633FEE5E1D3CD5590014B822 /* edit_list_default.png in Resources */, + 615A282621805B320060F920 /* security_toogle_icon_green@2x.png in Resources */, 633FEDB11D3CD5590014B822 /* call_add_disabled@2x.png in Resources */, + CF7602F7210898CC00749F76 /* rec_off_default.png in Resources */, 633FEDB21D3CD5590014B822 /* call_alt_back_default.png in Resources */, 633FEE3D1D3CD5590014B822 /* contacts_all_default@2x.png in Resources */, 633FEF251D3CD55A0014B822 /* route_bluetooth_disabled@2x.png in Resources */, 633FEDD81D3CD5590014B822 /* call_start_body_default~ipad.png in Resources */, + 61586B83217A16FD0038AC45 /* menu_about@2x.png in Resources */, 633FEED81D3CD55A0014B822 /* numpad_7_over~ipad@2x.png in Resources */, 633FEDD71D3CD5590014B822 /* call_start_body_default@2x.png in Resources */, 633FEE571D3CD5590014B822 /* dialer_back_disabled@2x.png in Resources */, @@ -4000,7 +4083,9 @@ 633FEDF01D3CD5590014B822 /* call_transfer_disabled.png in Resources */, 633FEE351D3CD5590014B822 /* conference_exit_default@2x.png in Resources */, 633FEECF1D3CD55A0014B822 /* numpad_6_over~ipad.png in Resources */, + 61586B87217A17160038AC45 /* menu_assistant@2x.png in Resources */, 633FEE9A1D3CD55A0014B822 /* nowebcamCIF.jpg in Resources */, + 61586B89217A17220038AC45 /* menu_link_account.png in Resources */, 633FEF351D3CD55A0014B822 /* routes_default@2x.png in Resources */, 633FEEDB1D3CD55A0014B822 /* numpad_8_default.png in Resources */, 633FEE5C1D3CD5590014B822 /* edit_disabled.png in Resources */, @@ -4018,7 +4103,9 @@ 633FEEA81D3CD55A0014B822 /* numpad_1_over~ipad@2x.png in Resources */, D38187AD15FE340100C3EDCA /* ChatConversationView.xib in Resources */, 633FEE7C1D3CD5590014B822 /* history_missed_disabled.png in Resources */, + CF1DE92E210A0F5D00A0A97E /* UILinphoneAudioPlayer.xib in Resources */, 633FEDF11D3CD5590014B822 /* call_transfer_disabled@2x.png in Resources */, + 615A282821805B400060F920 /* security_toogle_icon_grey.png in Resources */, 633FEDFF1D3CD5590014B822 /* camera_switch_disabled@2x.png in Resources */, 633FEDDF1D3CD5590014B822 /* call_start_body_over@2x.png in Resources */, 633FEEFA1D3CD55A0014B822 /* numpad_star~ipad.png in Resources */, @@ -4029,6 +4116,7 @@ 633FEE391D3CD5590014B822 /* contact_add_default@2x.png in Resources */, 633FEE741D3CD5590014B822 /* history_all_disabled.png in Resources */, 633FEE081D3CD5590014B822 /* chat_add_disabled.png in Resources */, + 615A28422180C0870060F920 /* recording.png in Resources */, 633FEF1D1D3CD55A0014B822 /* presence_offline@2x.png in Resources */, 24A3459E1D95797700881A5C /* UIShopTableCell.xib in Resources */, 633FEE231D3CD5590014B822 /* chat_start_body_over@2x.png in Resources */, @@ -4084,6 +4172,7 @@ 633FEE851D3CD5590014B822 /* led_error@2x.png in Resources */, 633FEDBE1D3CD5590014B822 /* call_back_default.png in Resources */, 633FEF0F1D3CD55A0014B822 /* pause_big_default@2x.png in Resources */, + CF7602F6210898CC00749F76 /* rec_on_default@2x.png in Resources */, 633FEF081D3CD55A0014B822 /* options_start_conference_disabled.png in Resources */, 63F1DF511BCE986A00EDED90 /* UICallConferenceCell.xib in Resources */, 633FEE301D3CD5590014B822 /* color_H.png in Resources */, @@ -4093,10 +4182,12 @@ 633FEE761D3CD5590014B822 /* history_all_selected.png in Resources */, 8C300D9B1E40E0CC00728EF3 /* lime_ko@2x.png in Resources */, 633FEF321D3CD55A0014B822 /* route_speaker_selected.png in Resources */, + 61AEBEBF2191991F00F35E7F /* DevicesListView.xib in Resources */, 633FEDF51D3CD5590014B822 /* call_video_start_disabled@2x.png in Resources */, 63B81A0C1B57DA33009604A6 /* LICENSE.txt in Resources */, 633FEEDA1D3CD55A0014B822 /* numpad_7~ipad@2x.png in Resources */, 633FEE5D1D3CD5590014B822 /* edit_disabled@2x.png in Resources */, + 615A2832218071F30060F920 /* security_toogle_background_green@2x.png in Resources */, 633FEEC11D3CD55A0014B822 /* numpad_4~ipad.png in Resources */, 633FEE6B1D3CD5590014B822 /* footer_dialer_default@2x.png in Resources */, 633FEE0E1D3CD5590014B822 /* chat_attachment_over.png in Resources */, @@ -4123,11 +4214,13 @@ 633FEE3F1D3CD5590014B822 /* contacts_all_disabled@2x.png in Resources */, 633FEF3B1D3CD55A0014B822 /* security_ko@2x.png in Resources */, 633FEE4A1D3CD5590014B822 /* delete_disabled.png in Resources */, + 614D09CE21E74D5400C43EDF /* GoogleService-Info.plist in Resources */, 633FEF151D3CD55A0014B822 /* pause_small_default@2x.png in Resources */, 633FEEF91D3CD55A0014B822 /* numpad_star_over~ipad@2x.png in Resources */, 633FEDCB1D3CD5590014B822 /* call_outgoing@2x.png in Resources */, 633FEF501D3CD55A0014B822 /* valid_disabled.png in Resources */, 633FEEB31D3CD55A0014B822 /* numpad_3_default.png in Resources */, + 61AEBECA2191E49300F35E7F /* chevron_list_open.png in Resources */, 633FEE1C1D3CD5590014B822 /* chat_start_body_default~ipad.png in Resources */, 633FEE011D3CD5590014B822 /* camera_switch_over@2x.png in Resources */, 633FEEA01D3CD55A0014B822 /* numpad_0_over~ipad@2x.png in Resources */, @@ -4144,6 +4237,7 @@ 633FEECB1D3CD55A0014B822 /* numpad_6_default.png in Resources */, 633FEDC71D3CD5590014B822 /* call_incoming@2x.png in Resources */, 633FEDB81D3CD5590014B822 /* call_alt_start_disabled.png in Resources */, + 615A281D217F6FA80060F920 /* security_2_indicator@2x.png in Resources */, 633FEF3C1D3CD55A0014B822 /* security_ok.png in Resources */, 633FEEAF1D3CD55A0014B822 /* numpad_2_over~ipad.png in Resources */, 633FEEB81D3CD55A0014B822 /* numpad_3_over~ipad@2x.png in Resources */, @@ -4154,8 +4248,11 @@ 639E9CA91C0DB7FB00019A75 /* UIConfirmationDialog.xib in Resources */, 633FEF111D3CD55A0014B822 /* pause_big_disabled@2x.png in Resources */, 633FEE321D3CD5590014B822 /* color_L.png in Resources */, + 615A281F217F6FB40060F920 /* security_alert_indicator.png in Resources */, + CF7602F5210898CC00749F76 /* rec_off_default@2x.png in Resources */, 633FEDB41D3CD5590014B822 /* call_alt_back_disabled.png in Resources */, 633FEE631D3CD5590014B822 /* footer_chat_default@2x.png in Resources */, + 615A281B217F6F9C0060F920 /* security_2_indicator.png in Resources */, 633FEE661D3CD5590014B822 /* footer_contacts_default.png in Resources */, 633FEDC11D3CD5590014B822 /* call_back_disabled@2x.png in Resources */, 633FEEEE1D3CD55A0014B822 /* numpad_hash_over@2x.png in Resources */, @@ -4166,7 +4263,9 @@ 633FEDF31D3CD5590014B822 /* call_video_start_default@2x.png in Resources */, 24BFAAA2209B0630004F47A7 /* linphone_user~ipad@2x.png in Resources */, 633FEDBA1D3CD5590014B822 /* call_audio_start_default.png in Resources */, + 61586B8F217A174F0038AC45 /* menu_options@2x.png in Resources */, 633FEE131D3CD5590014B822 /* chat_message_not_delivered@2x.png in Resources */, + 615A282A21805B4C0060F920 /* security_toogle_icon_grey@2x.png in Resources */, 63AADBF51B6A0FF200AA16FD /* linphonerc in Resources */, 633FEF0C1D3CD55A0014B822 /* options_transfer_call_disabled.png in Resources */, 633FEE911D3CD55A0014B822 /* list_details_over@2x.png in Resources */, @@ -4246,13 +4345,6 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 63D8038D1C96E74100336B6F /* vcards in Resources */, - 63058AE31B4E93B300EFAE36 /* tester_hosts in Resources */, - 63058ACF1B4E922500EFAE36 /* certificates in Resources */, - 63058AD01B4E922500EFAE36 /* flexisip in Resources */, - 63058AD11B4E922500EFAE36 /* images in Resources */, - 63058AD41B4E922500EFAE36 /* rcfiles in Resources */, - 63058AD51B4E922500EFAE36 /* sounds in Resources */, 63058A3B1B4E822F00EFAE36 /* InfoPlist.strings in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -4261,15 +4353,7 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 8C56289F20236C25007A8ECC /* db in Resources */, - 635598821C96AFFA006ED99A /* vcards in Resources */, - 63058ADA1B4E937300EFAE36 /* certificates in Resources */, 63B21A7D1C623DA80074DFF8 /* test_inprogress.png in Resources */, - 63058ADB1B4E937300EFAE36 /* flexisip in Resources */, - 63058ADC1B4E937300EFAE36 /* images in Resources */, - 63058ADF1B4E937300EFAE36 /* rcfiles in Resources */, - 63058AE01B4E937300EFAE36 /* sounds in Resources */, - 63058AE21B4E93A100EFAE36 /* tester_hosts in Resources */, 221234461D9E682100DEFA1F /* Images.xcassets in Resources */, 63058A2F1B4E821E00EFAE36 /* TesterImages.xcassets in Resources */, 63058A251B4E821E00EFAE36 /* InfoPlist.strings in Resources */, @@ -4292,18 +4376,126 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ - 639002451D4106CA00BEFC78 /* ShellScript */ = { + 20EEEF6D60A7B77C2EFF85DB /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-linphone-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + 4D22DCAAC0231865D78AC1E6 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-linphone/Pods-linphone-frameworks.sh", + "${PODS_ROOT}/linphone-sdk/linphone-sdk/apple-darwin/Frameworks/bctoolbox.framework", + "${PODS_ROOT}/linphone-sdk/linphone-sdk/apple-darwin/Frameworks/belcard.framework", + "${PODS_ROOT}/linphone-sdk/linphone-sdk/apple-darwin/Frameworks/belr.framework", + "${PODS_ROOT}/linphone-sdk/linphone-sdk/apple-darwin/Frameworks/lime.framework", + "${PODS_ROOT}/linphone-sdk/linphone-sdk/apple-darwin/Frameworks/linphone.framework", + "${PODS_ROOT}/linphone-sdk/linphone-sdk/apple-darwin/Frameworks/linphonetester.framework", + "${PODS_ROOT}/linphone-sdk/linphone-sdk/apple-darwin/Frameworks/mediastreamer2.framework", + "${PODS_ROOT}/linphone-sdk/linphone-sdk/apple-darwin/Frameworks/msamr.framework", + "${PODS_ROOT}/linphone-sdk/linphone-sdk/apple-darwin/Frameworks/mscodec2.framework", + "${PODS_ROOT}/linphone-sdk/linphone-sdk/apple-darwin/Frameworks/msopenh264.framework", + "${PODS_ROOT}/linphone-sdk/linphone-sdk/apple-darwin/Frameworks/mssilk.framework", + "${PODS_ROOT}/linphone-sdk/linphone-sdk/apple-darwin/Frameworks/mswebrtc.framework", + "${PODS_ROOT}/linphone-sdk/linphone-sdk/apple-darwin/Frameworks/msx264.framework", + "${PODS_ROOT}/linphone-sdk/linphone-sdk/apple-darwin/Frameworks/ortp.framework", + "${BUILT_PRODUCTS_DIR}/SVProgressHUD/SVProgressHUD.framework", + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/bctoolbox.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/belcard.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/belr.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/lime.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/linphone.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/linphonetester.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/mediastreamer2.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/msamr.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/mscodec2.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/msopenh264.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/mssilk.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/mswebrtc.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/msx264.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ortp.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SVProgressHUD.framework", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-linphone/Pods-linphone-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + 5599CB1883357B4D67CCC202 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-liblinphoneTesterTests-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + 614D0A1821E77F5300C43EDF /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + outputFileListPaths = ( ); outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "if [ ! -f \"$SRCROOT/liblinphone-sdk/apple-darwin/share/linphone/rootca.pem\" ]; then\necho '********************************************************************'\necho 'warning: Liblinphone SDK missing! Downloading it (latest release)...'\n#$SRCROOT/Tools/sdk_download.sh \"latest\"\necho 'Deactivated'\necho '********************************************************************'\nfi"; + shellScript = "if USE_CRASHLYTHICS; then\n ${PODS_ROOT}/Fabric/run\nfi\n"; + }; + 61C84B4200D58AABECCE326E /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-liblinphoneTester/Pods-liblinphoneTester-resources.sh", + "${PODS_ROOT}/linphone-sdk/linphone-sdk/apple-darwin/Resources/liblinphone_tester", + ); + name = "[CP] Copy Pods Resources"; + outputFileListPaths = ( + ); + outputPaths = ( + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/liblinphone_tester", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-liblinphoneTester/Pods-liblinphoneTester-resources.sh\"\n"; + showEnvVarsInLog = 0; }; 63DCC71D1A07B08E00916627 /* Run Script */ = { isa = PBXShellScriptBuildPhase; @@ -4317,7 +4509,25 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = $SRCROOT/Tools/git_version.sh; + shellScript = "$SRCROOT/Tools/git_version.sh\n"; + }; + 7FF8A712621CDB927700B916 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-linphoneTests-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; }; 8CB438A61EE6A65D0006F944 /* ShellScript */ = { isa = PBXShellScriptBuildPhase; @@ -4330,7 +4540,109 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = $SRCROOT/Tools/deploy.sh; + shellScript = "$SRCROOT/Tools/deploy.sh\n"; + }; + 9B9A5E3BD753D3A8A6E82117 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-liblinphoneTester-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + A68C4E88E4EC059C04D389FE /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-liblinphoneTester/Pods-liblinphoneTester-frameworks.sh", + "${PODS_ROOT}/linphone-sdk/linphone-sdk/apple-darwin/Frameworks/bctoolbox.framework", + "${PODS_ROOT}/linphone-sdk/linphone-sdk/apple-darwin/Frameworks/belcard.framework", + "${PODS_ROOT}/linphone-sdk/linphone-sdk/apple-darwin/Frameworks/belr.framework", + "${PODS_ROOT}/linphone-sdk/linphone-sdk/apple-darwin/Frameworks/lime.framework", + "${PODS_ROOT}/linphone-sdk/linphone-sdk/apple-darwin/Frameworks/linphone.framework", + "${PODS_ROOT}/linphone-sdk/linphone-sdk/apple-darwin/Frameworks/linphonetester.framework", + "${PODS_ROOT}/linphone-sdk/linphone-sdk/apple-darwin/Frameworks/mediastreamer2.framework", + "${PODS_ROOT}/linphone-sdk/linphone-sdk/apple-darwin/Frameworks/msamr.framework", + "${PODS_ROOT}/linphone-sdk/linphone-sdk/apple-darwin/Frameworks/mscodec2.framework", + "${PODS_ROOT}/linphone-sdk/linphone-sdk/apple-darwin/Frameworks/msopenh264.framework", + "${PODS_ROOT}/linphone-sdk/linphone-sdk/apple-darwin/Frameworks/mssilk.framework", + "${PODS_ROOT}/linphone-sdk/linphone-sdk/apple-darwin/Frameworks/mswebrtc.framework", + "${PODS_ROOT}/linphone-sdk/linphone-sdk/apple-darwin/Frameworks/msx264.framework", + "${PODS_ROOT}/linphone-sdk/linphone-sdk/apple-darwin/Frameworks/ortp.framework", + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/bctoolbox.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/belcard.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/belr.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/lime.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/linphone.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/linphonetester.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/mediastreamer2.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/msamr.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/mscodec2.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/msopenh264.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/mssilk.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/mswebrtc.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/msx264.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ortp.framework", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-liblinphoneTester/Pods-liblinphoneTester-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + A73A24C4B99B11012FDAA7CF /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-linphone/Pods-linphone-resources.sh", + "${PODS_ROOT}/linphone-sdk/linphone-sdk/apple-darwin/Resources/liblinphone_tester", + ); + name = "[CP] Copy Pods Resources"; + outputFileListPaths = ( + ); + outputPaths = ( + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/liblinphone_tester", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-linphone/Pods-linphone-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; + F43E063274A630F02AB2AAEC /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-linphoneExtension-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; }; /* End PBXShellScriptBuildPhase section */ @@ -4340,6 +4652,7 @@ buildActionMask = 2147483647; files = ( 63B81A0F1B57DA33009604A6 /* TPKeyboardAvoidingTableView.m in Sources */, + CF1DE92D210A0F5D00A0A97E /* UILinphoneAudioPlayer.m in Sources */, 1D60589B0D05DD56006BFB54 /* main.m in Sources */, 8CD99A3C2090B9FA008A7CDA /* ChatConversationImdnView.m in Sources */, 1D3623260D0F684500981E51 /* LinphoneAppDelegate.m in Sources */, @@ -4369,12 +4682,14 @@ 34216F401547EBCD00EA9777 /* VideoZoomHandler.m in Sources */, D3F83EEC1582021700336684 /* CallView.m in Sources */, 8C2595DD1DEDC92D007A6424 /* ProviderDelegate.m in Sources */, + CF7602D7210867E800749F76 /* RecordingsListView.m in Sources */, 63F1DF4B1BCE983200EDED90 /* CallConferenceTableView.m in Sources */, D3F83F8E15822ABE00336684 /* PhoneMainView.m in Sources */, 6377AC801BDE4069007F7625 /* UIBackToCallButton.m in Sources */, 6308F9C51BF0DD6600D1234B /* XMLRPCHelper.m in Sources */, D3ED3E871586291E006C0DE4 /* TabBarView.m in Sources */, D3ED3EA71587334E006C0DE4 /* HistoryListTableView.m in Sources */, + 61AEBEBD2191990A00F35E7F /* DevicesListView.m in Sources */, D3ED3EB81587392C006C0DE4 /* HistoryListView.m in Sources */, 24A345A61D95798A00881A5C /* UIShopTableCell.m in Sources */, 8C1B67061E671826001EA2FE /* AudioHelper.m in Sources */, @@ -4413,6 +4728,7 @@ D32B9DFC15A2F131000B6DEC /* FastAddressBook.m in Sources */, D350F20E15A43BB100149E54 /* AssistantView.m in Sources */, D3F795D615A582810077328B /* ChatConversationView.m in Sources */, + 61AEBEC22191D7C800F35E7F /* UIDevicesDetails.m in Sources */, D32B6E2915A5BC440033019F /* ChatConversationTableView.m in Sources */, D3A8BB7015A6C7D500F96BE5 /* UIChatBubbleTextCell.m in Sources */, 63D11C531C3D501200E8FCEE /* Log.m in Sources */, @@ -4430,8 +4746,10 @@ D3F7998115BD32370018C273 /* TPMultiLayoutViewController.m in Sources */, D3807FBF15C28940005BE9BC /* DCRoundSwitch.m in Sources */, D3807FC115C28940005BE9BC /* DCRoundSwitchKnobLayer.m in Sources */, + 61CCC3DF21933B580060EDEA /* UIDeviceCell.m in Sources */, 6306440E1BECB08500134C72 /* FirstLoginView.m in Sources */, D3807FC315C28940005BE9BC /* DCRoundSwitchOutlineLayer.m in Sources */, + CF7602E221086EB200749F76 /* RecordingsListTableView.m in Sources */, D3807FC515C28940005BE9BC /* DCRoundSwitchToggleLayer.m in Sources */, 633E41821D74259000320475 /* AssistantLinkView.m in Sources */, D3807FE815C2894A005BE9BC /* IASKAppSettingsViewController.m in Sources */, @@ -4444,6 +4762,7 @@ D3807FF215C2894A005BE9BC /* IASKSettingsStoreFile.m in Sources */, D3807FF415C2894A005BE9BC /* IASKSettingsStoreUserDefaults.m in Sources */, 639E9C801C0DB13D00019A75 /* UICheckBoxTableView.m in Sources */, + CF7602E72108759A00749F76 /* UIRecordingCell.m in Sources */, D3807FF615C2894A005BE9BC /* IASKSpecifier.m in Sources */, D3807FF815C2894A005BE9BC /* IASKPSSliderSpecifierViewCell.m in Sources */, D3807FFA15C2894A005BE9BC /* IASKPSTextFieldSpecifierViewCell.m in Sources */, @@ -4536,21 +4855,6 @@ /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ - 5E31290B20D7A37E00CF3AAE /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 5E3128FF20D7A37E00CF3AAE /* latestChatroomsWidget */; - targetProxy = 5E31290A20D7A37E00CF3AAE /* PBXContainerItemProxy */; - }; - 5E58963020DCE5710030868C /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 5E58962220DCE5700030868C /* richNotifications */; - targetProxy = 5E58962F20DCE5710030868C /* PBXContainerItemProxy */; - }; - 5EEE8FA520C80C23006E4176 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 5EEE8F9920C80C23006E4176 /* latestCallsWidget */; - targetProxy = 5EEE8FA420C80C23006E4176 /* PBXContainerItemProxy */; - }; 61AE365520C00B370089D9D3 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 61AE364A20C00B370089D9D3 /* linphoneExtension */; @@ -4891,7 +5195,7 @@ isa = PBXVariantGroup; children = ( 63EC8D3A1D7438660066547B /* Base */, - 8CBD7BB020B6B86800E5DCC0 /* fr */, + 61BD122D222EA29300563181 /* fr */, ); name = AssistantLinkView.xib; sourceTree = ""; @@ -5112,6 +5416,7 @@ /* Begin XCBuildConfiguration section */ 1D6058940D05DD3E006BFB54 /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 799BA1104845EB01ACE764D8 /* Pods-linphone.debug.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; @@ -5125,44 +5430,41 @@ COMPRESS_PNG_FILES = NO; COPY_PHASE_STRIP = NO; DEVELOPMENT_TEAM = Z2V957B3D6; - ENABLE_BITCODE = YES; - FRAMEWORK_SEARCH_PATHS = ( - "$(PROJECT_DIR)/liblinphone-sdk/x86_64-apple-darwin.ios/lib", - "$(PROJECT_DIR)/liblinphone-sdk/apple-darwin/Frameworks", - "$(PROJECT_DIR)/liblinphone-sdk/x86_64-apple-darwin.ios/Frameworks", - ); GCC_C_LANGUAGE_STANDARD = c99; GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = linphone_Prefix.pch; - GCC_PREPROCESSOR_DEFINITIONS = DEBUG; + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(inherited)", + "DEBUG=1", + ); GCC_SYMBOLS_PRIVATE_EXTERN = NO; GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES; GCC_TREAT_WARNINGS_AS_ERRORS = YES; GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO; HEADER_SEARCH_PATHS = ( - "$(SRCROOT)/Classes/Utils/NinePatch/", "$(SRCROOT)/Classes/Utils/XMLRPC/", + "$(SRCROOT)/Classes/Utils/NinePatch/", + "$(inherited)", ); INFOPLIST_FILE = "linphone-Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 9.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LIBRARY_SEARCH_PATHS = "$(BUILT_PRODUCTS_DIR)"; LINK_WITH_STANDARD_LIBRARIES = YES; - ORDER_FILE = ""; OTHER_CFLAGS = ( "-DBCTBX_LOG_DOMAIN=\\\"ios\\\"", "-DCHECK_VERSION_UPDATE=FALSE", - "-DENABLE_QRCODE=FALSE", + "-DENABLE_QRCODE=TRUE", + "-DENABLE_SMS_INVITE=TRUE", + "$(inherited)", + "-DLINPHONE_SDK_VERSION=\\\"4.1-366-g1b22291\\\"", ); - OTHER_LDFLAGS = "-ObjC"; PRODUCT_BUNDLE_IDENTIFIER = org.linphone.phone; PRODUCT_NAME = linphone; PROVISIONING_PROFILE = ""; PROVISIONING_PROFILE_SPECIFIER = ""; SKIP_INSTALL = NO; - TARGETED_DEVICE_FAMILY = "1,2"; WARNING_CFLAGS = ( "-Werror=objc-method-access", "-Werror=incomplete-implementation", @@ -5192,7 +5494,6 @@ CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = "iPhone Distribution: jehan monnier"; - ENABLE_BITCODE = YES; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_NO_COMMON_BLOCKS = YES; GCC_THUMB_SUPPORT = NO; @@ -5218,6 +5519,7 @@ }; 228B19A71302902F00F154D3 /* DistributionAdhoc */ = { isa = XCBuildConfiguration; + baseConfigurationReference = FE7D89A821FDC1BCA9BB9F8F /* Pods-linphone.distributionadhoc.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; @@ -5231,43 +5533,38 @@ COMPRESS_PNG_FILES = NO; COPY_PHASE_STRIP = NO; DEVELOPMENT_TEAM = Z2V957B3D6; - ENABLE_BITCODE = YES; - FRAMEWORK_SEARCH_PATHS = ( - "$(PROJECT_DIR)/liblinphone-sdk/x86_64-apple-darwin.ios/lib", - "$(PROJECT_DIR)/liblinphone-sdk/apple-darwin/Frameworks", - "$(PROJECT_DIR)/liblinphone-sdk/x86_64-apple-darwin.ios/Frameworks", - ); GCC_C_LANGUAGE_STANDARD = c99; GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = s; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = linphone_Prefix.pch; + GCC_PREPROCESSOR_DEFINITIONS = "$(inherited)"; GCC_SYMBOLS_PRIVATE_EXTERN = NO; GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES; GCC_TREAT_WARNINGS_AS_ERRORS = YES; GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO; HEADER_SEARCH_PATHS = ( - "$(SRCROOT)/Classes/Utils/NinePatch/", "$(SRCROOT)/Classes/Utils/XMLRPC/", + "$(SRCROOT)/Classes/Utils/NinePatch/", + "$(inherited)", ); INFOPLIST_FILE = "linphone-Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 9.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LIBRARY_SEARCH_PATHS = "$(BUILT_PRODUCTS_DIR)"; LINK_WITH_STANDARD_LIBRARIES = YES; - ORDER_FILE = ""; OTHER_CFLAGS = ( "-DBCTBX_LOG_DOMAIN=\\\"ios\\\"", "-DCHECK_VERSION_UPDATE=FALSE", - "-DENABLE_QRCODE=FALSE", + "-DENABLE_QRCODE=TRUE", + "-DENABLE_SMS_INVITE=TRUE", + "$(inherited)", + "-DLINPHONE_SDK_VERSION=\\\"4.1-366-g1b22291\\\"", ); - OTHER_LDFLAGS = "-ObjC"; PRODUCT_BUNDLE_IDENTIFIER = org.linphone.phone; PRODUCT_NAME = linphone; PROVISIONING_PROFILE = ""; PROVISIONING_PROFILE_SPECIFIER = ""; SKIP_INSTALL = NO; - TARGETED_DEVICE_FAMILY = "1,2"; WARNING_CFLAGS = ( "-Werror=objc-method-access", "-Werror=incomplete-implementation", @@ -5297,7 +5594,6 @@ CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = "iPhone Developer"; - ENABLE_BITCODE = YES; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_NO_COMMON_BLOCKS = YES; GCC_THUMB_SUPPORT = NO; @@ -5323,6 +5619,7 @@ }; 22F3D55613CC3C9100A0DA02 /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = FEAFB5AD0E3AA409BBD1136E /* Pods-linphone.release.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; @@ -5336,43 +5633,38 @@ COMPRESS_PNG_FILES = NO; COPY_PHASE_STRIP = NO; DEVELOPMENT_TEAM = Z2V957B3D6; - ENABLE_BITCODE = YES; - FRAMEWORK_SEARCH_PATHS = ( - "$(PROJECT_DIR)/liblinphone-sdk/x86_64-apple-darwin.ios/lib", - "$(PROJECT_DIR)/liblinphone-sdk/apple-darwin/Frameworks", - "$(PROJECT_DIR)/liblinphone-sdk/x86_64-apple-darwin.ios/Frameworks", - ); GCC_C_LANGUAGE_STANDARD = c99; GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = s; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = linphone_Prefix.pch; + GCC_PREPROCESSOR_DEFINITIONS = "$(inherited)"; GCC_SYMBOLS_PRIVATE_EXTERN = NO; GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES; GCC_TREAT_WARNINGS_AS_ERRORS = YES; GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO; HEADER_SEARCH_PATHS = ( - "$(SRCROOT)/Classes/Utils/NinePatch/", "$(SRCROOT)/Classes/Utils/XMLRPC/", + "$(SRCROOT)/Classes/Utils/NinePatch/", + "$(inherited)", ); INFOPLIST_FILE = "linphone-Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 9.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LIBRARY_SEARCH_PATHS = "$(BUILT_PRODUCTS_DIR)"; LINK_WITH_STANDARD_LIBRARIES = YES; - ORDER_FILE = ""; OTHER_CFLAGS = ( "-DBCTBX_LOG_DOMAIN=\\\"ios\\\"", "-DCHECK_VERSION_UPDATE=FALSE", - "-DENABLE_QRCODE=FALSE", + "-DENABLE_QRCODE=TRUE", + "-DENABLE_SMS_INVITE=TRUE", + "$(inherited)", + "-DLINPHONE_SDK_VERSION=\\\"4.1-366-g1b22291\\\"", ); - OTHER_LDFLAGS = "-ObjC"; PRODUCT_BUNDLE_IDENTIFIER = org.linphone.phone; PRODUCT_NAME = linphone; PROVISIONING_PROFILE = ""; PROVISIONING_PROFILE_SPECIFIER = ""; SKIP_INSTALL = NO; - TARGETED_DEVICE_FAMILY = "1,2"; WARNING_CFLAGS = ( "-Werror=objc-method-access", "-Werror=incomplete-implementation", @@ -5402,7 +5694,6 @@ CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = "iPhone Distribution: jehan monnier"; - ENABLE_BITCODE = YES; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_NO_COMMON_BLOCKS = YES; GCC_THUMB_SUPPORT = NO; @@ -5428,6 +5719,7 @@ }; 22F51EE8107FA53D00F98953 /* Distribution */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 38DF35D11A7C0F45E990C83A /* Pods-linphone.distribution.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; @@ -5441,43 +5733,38 @@ COMPRESS_PNG_FILES = NO; COPY_PHASE_STRIP = NO; DEVELOPMENT_TEAM = Z2V957B3D6; - ENABLE_BITCODE = YES; - FRAMEWORK_SEARCH_PATHS = ( - "$(PROJECT_DIR)/liblinphone-sdk/x86_64-apple-darwin.ios/lib", - "$(PROJECT_DIR)/liblinphone-sdk/apple-darwin/Frameworks", - "$(PROJECT_DIR)/liblinphone-sdk/x86_64-apple-darwin.ios/Frameworks", - ); GCC_C_LANGUAGE_STANDARD = c99; GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = s; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = linphone_Prefix.pch; + GCC_PREPROCESSOR_DEFINITIONS = "$(inherited)"; GCC_SYMBOLS_PRIVATE_EXTERN = NO; GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES; GCC_TREAT_WARNINGS_AS_ERRORS = YES; GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO; HEADER_SEARCH_PATHS = ( - "$(SRCROOT)/Classes/Utils/NinePatch/", "$(SRCROOT)/Classes/Utils/XMLRPC/", + "$(SRCROOT)/Classes/Utils/NinePatch/", + "$(inherited)", ); INFOPLIST_FILE = "linphone-Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 9.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LIBRARY_SEARCH_PATHS = "$(BUILT_PRODUCTS_DIR)"; LINK_WITH_STANDARD_LIBRARIES = YES; - ORDER_FILE = ""; OTHER_CFLAGS = ( "-DBCTBX_LOG_DOMAIN=\\\"ios\\\"", "-DCHECK_VERSION_UPDATE=FALSE", - "-DENABLE_QRCODE=FALSE", + "-DENABLE_QRCODE=TRUE", + "-DENABLE_SMS_INVITE=TRUE", + "$(inherited)", + "-DLINPHONE_SDK_VERSION=\\\"4.1-366-g1b22291\\\"", ); - OTHER_LDFLAGS = "-ObjC"; PRODUCT_BUNDLE_IDENTIFIER = org.linphone.phone; PRODUCT_NAME = linphone; PROVISIONING_PROFILE = ""; PROVISIONING_PROFILE_SPECIFIER = ""; SKIP_INSTALL = NO; - TARGETED_DEVICE_FAMILY = "1,2"; WARNING_CFLAGS = ( "-Werror=objc-method-access", "-Werror=incomplete-implementation", @@ -5510,30 +5797,19 @@ COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = Z2V957B3D6; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/liblinphone-sdk/apple-darwin/Frameworks", - ); GCC_C_LANGUAGE_STANDARD = gnu11; GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; INFOPLIST_FILE = latestChatroomsWidget/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; MTL_ENABLE_DEBUG_INFO = YES; - PRODUCT_BUNDLE_IDENTIFIER = org.linphone.phone.widget.latestChatrooms; + PRODUCT_BUNDLE_IDENTIFIER = org.linphone.phone.latestChatroomsWidget; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = ""; PROVISIONING_PROFILE_SPECIFIER = ""; SKIP_INSTALL = YES; - TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; }; @@ -5562,19 +5838,14 @@ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = Z2V957B3D6; ENABLE_NS_ASSERTIONS = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/liblinphone-sdk/apple-darwin/Frameworks", - ); GCC_C_LANGUAGE_STANDARD = gnu11; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; INFOPLIST_FILE = latestChatroomsWidget/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 9.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; MTL_ENABLE_DEBUG_INFO = NO; - PRODUCT_BUNDLE_IDENTIFIER = org.linphone.phone.widget.latestChatrooms; + PRODUCT_BUNDLE_IDENTIFIER = org.linphone.phone.latestChatroomsWidget; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = ""; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -5609,19 +5880,14 @@ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = Z2V957B3D6; ENABLE_NS_ASSERTIONS = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/liblinphone-sdk/apple-darwin/Frameworks", - ); GCC_C_LANGUAGE_STANDARD = gnu11; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; INFOPLIST_FILE = latestChatroomsWidget/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 9.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; MTL_ENABLE_DEBUG_INFO = NO; - PRODUCT_BUNDLE_IDENTIFIER = org.linphone.phone.widget.latestChatrooms; + PRODUCT_BUNDLE_IDENTIFIER = org.linphone.phone.latestChatroomsWidget; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = ""; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -5656,19 +5922,14 @@ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = Z2V957B3D6; ENABLE_NS_ASSERTIONS = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/liblinphone-sdk/apple-darwin/Frameworks", - ); GCC_C_LANGUAGE_STANDARD = gnu11; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; INFOPLIST_FILE = latestChatroomsWidget/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 9.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; MTL_ENABLE_DEBUG_INFO = NO; - PRODUCT_BUNDLE_IDENTIFIER = org.linphone.phone.widget.latestChatrooms; + PRODUCT_BUNDLE_IDENTIFIER = org.linphone.phone.latestChatroomsWidget; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = ""; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -5704,16 +5965,11 @@ GCC_C_LANGUAGE_STANDARD = gnu11; GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; INFOPLIST_FILE = richNotifications/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; MTL_ENABLE_DEBUG_INFO = YES; PRODUCT_BUNDLE_IDENTIFIER = org.linphone.phone.richNotifications; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -5753,8 +6009,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; INFOPLIST_FILE = richNotifications/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; MTL_ENABLE_DEBUG_INFO = NO; PRODUCT_BUNDLE_IDENTIFIER = org.linphone.phone.richNotifications; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -5795,8 +6050,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; INFOPLIST_FILE = richNotifications/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; MTL_ENABLE_DEBUG_INFO = NO; PRODUCT_BUNDLE_IDENTIFIER = org.linphone.phone.richNotifications; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -5837,8 +6091,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; INFOPLIST_FILE = richNotifications/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; MTL_ENABLE_DEBUG_INFO = NO; PRODUCT_BUNDLE_IDENTIFIER = org.linphone.phone.richNotifications; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -5874,25 +6127,16 @@ COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = Z2V957B3D6; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/liblinphone-sdk/apple-darwin/Frameworks", - ); GCC_C_LANGUAGE_STANDARD = gnu11; GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; INFOPLIST_FILE = latestCallsWidget/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 9.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; MTL_ENABLE_DEBUG_INFO = YES; - PRODUCT_BUNDLE_IDENTIFIER = org.linphone.phone.widget.latestCalls; + PRODUCT_BUNDLE_IDENTIFIER = org.linphone.phone.latestCallsWidget; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = ""; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -5926,19 +6170,14 @@ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = Z2V957B3D6; ENABLE_NS_ASSERTIONS = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/liblinphone-sdk/apple-darwin/Frameworks", - ); GCC_C_LANGUAGE_STANDARD = gnu11; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; INFOPLIST_FILE = latestCallsWidget/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 9.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; MTL_ENABLE_DEBUG_INFO = NO; - PRODUCT_BUNDLE_IDENTIFIER = org.linphone.phone.widget.latestCalls; + PRODUCT_BUNDLE_IDENTIFIER = org.linphone.phone.latestCallsWidget; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = ""; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -5973,19 +6212,14 @@ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = Z2V957B3D6; ENABLE_NS_ASSERTIONS = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/liblinphone-sdk/apple-darwin/Frameworks", - ); GCC_C_LANGUAGE_STANDARD = gnu11; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; INFOPLIST_FILE = latestCallsWidget/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 9.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; MTL_ENABLE_DEBUG_INFO = NO; - PRODUCT_BUNDLE_IDENTIFIER = org.linphone.phone.widget.latestCalls; + PRODUCT_BUNDLE_IDENTIFIER = org.linphone.phone.latestCallsWidget; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = ""; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -6020,19 +6254,14 @@ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = Z2V957B3D6; ENABLE_NS_ASSERTIONS = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/liblinphone-sdk/apple-darwin/Frameworks", - ); GCC_C_LANGUAGE_STANDARD = gnu11; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; INFOPLIST_FILE = latestCallsWidget/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 9.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; MTL_ENABLE_DEBUG_INFO = NO; - PRODUCT_BUNDLE_IDENTIFIER = org.linphone.phone.widget.latestCalls; + PRODUCT_BUNDLE_IDENTIFIER = org.linphone.phone.latestCallsWidget; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = ""; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -6044,6 +6273,7 @@ }; 61AE365720C00B370089D9D3 /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = E5074CFA3AAD5A8B72956DDE /* Pods-linphoneExtension.debug.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; @@ -6066,16 +6296,11 @@ GCC_C_LANGUAGE_STANDARD = gnu11; GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; INFOPLIST_FILE = linphoneExtension/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 11.2; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; MTL_ENABLE_DEBUG_INFO = YES; PRODUCT_BUNDLE_IDENTIFIER = org.linphone.phone.linphoneExtension; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -6087,6 +6312,7 @@ }; 61AE365820C00B370089D9D3 /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 283F127CA480E2E2CF0DE9C2 /* Pods-linphoneExtension.release.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; @@ -6112,8 +6338,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; INFOPLIST_FILE = linphoneExtension/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 11.2; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; MTL_ENABLE_DEBUG_INFO = NO; PRODUCT_BUNDLE_IDENTIFIER = org.linphone.phone.linphoneExtension; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -6125,6 +6350,7 @@ }; 61AE365920C00B370089D9D3 /* Distribution */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 78C7025E626D12D2F04EAC87 /* Pods-linphoneExtension.distribution.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; @@ -6150,8 +6376,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; INFOPLIST_FILE = linphoneExtension/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 11.2; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; MTL_ENABLE_DEBUG_INFO = NO; PRODUCT_BUNDLE_IDENTIFIER = org.linphone.phone.linphoneExtension; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -6164,6 +6389,7 @@ }; 61AE365A20C00B370089D9D3 /* DistributionAdhoc */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 620DFD020AC0182319853127 /* Pods-linphoneExtension.distributionadhoc.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; @@ -6189,8 +6415,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; INFOPLIST_FILE = linphoneExtension/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 11.2; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; MTL_ENABLE_DEBUG_INFO = NO; PRODUCT_BUNDLE_IDENTIFIER = org.linphone.phone.linphoneExtension; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -6222,7 +6447,6 @@ CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = "iPhone Developer: jehan monnier (E8MYPN2NXL)"; - ENABLE_BITCODE = YES; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; GCC_NO_COMMON_BLOCKS = YES; @@ -6250,6 +6474,7 @@ }; F08F119419C09C6B007D70C2 /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 7D8CCFE176C634813E3A2593 /* Pods-liblinphoneTesterTests.debug.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; BUNDLE_LOADER = "$(TEST_HOST)"; @@ -6274,10 +6499,6 @@ GCC_OPTIMIZATION_LEVEL = 0; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "TestsLiblinphone/LinphoneTesterTests-Prefix.pch"; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); GCC_SYMBOLS_PRIVATE_EXTERN = NO; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; @@ -6287,6 +6508,7 @@ HEADER_SEARCH_PATHS = ( Classes/Utils/NinePatch/, Classes/Utils/XMLRPC/, + "$(inherited)", ); INFOPLIST_FILE = "TestsLiblinphone/LinphoneTesterTests-Info.plist"; LIBRARY_SEARCH_PATHS = "$(inherited)"; @@ -6300,6 +6522,7 @@ }; F08F119519C09C6B007D70C2 /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = BE06BDE664323B2A53469696 /* Pods-liblinphoneTesterTests.release.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; BUNDLE_LOADER = "$(TEST_HOST)"; @@ -6331,6 +6554,7 @@ HEADER_SEARCH_PATHS = ( Classes/Utils/NinePatch/, Classes/Utils/XMLRPC/, + "$(inherited)", ); INFOPLIST_FILE = "TestsLiblinphone/LinphoneTesterTests-Info.plist"; LIBRARY_SEARCH_PATHS = "$(inherited)"; @@ -6344,6 +6568,7 @@ }; F08F119619C09C6B007D70C2 /* Distribution */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 248C326F4AD75E654C1CB37A /* Pods-liblinphoneTesterTests.distribution.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; BUNDLE_LOADER = "$(TEST_HOST)"; @@ -6375,6 +6600,7 @@ HEADER_SEARCH_PATHS = ( Classes/Utils/NinePatch/, Classes/Utils/XMLRPC/, + "$(inherited)", ); INFOPLIST_FILE = "TestsLiblinphone/LinphoneTesterTests-Info.plist"; LIBRARY_SEARCH_PATHS = "$(inherited)"; @@ -6388,6 +6614,7 @@ }; F08F119719C09C6B007D70C2 /* DistributionAdhoc */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 046DEFE77AD0675DA9932C4C /* Pods-liblinphoneTesterTests.distributionadhoc.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; BUNDLE_LOADER = "$(TEST_HOST)"; @@ -6419,6 +6646,7 @@ HEADER_SEARCH_PATHS = ( Classes/Utils/NinePatch/, Classes/Utils/XMLRPC/, + "$(inherited)", ); INFOPLIST_FILE = "TestsLiblinphone/LinphoneTesterTests-Info.plist"; LIBRARY_SEARCH_PATHS = "$(inherited)"; @@ -6432,6 +6660,7 @@ }; F0BB8C061936208200974404 /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 68D9EC27FCECD5DE2E19CD3C /* Pods-liblinphoneTester.debug.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; @@ -6460,10 +6689,6 @@ GCC_OPTIMIZATION_LEVEL = 0; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "LiblinphoneTester/LinphoneTester-Prefix.pch"; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); GCC_SYMBOLS_PRIVATE_EXTERN = NO; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; @@ -6473,6 +6698,7 @@ HEADER_SEARCH_PATHS = ( Classes/Utils/NinePatch/, Classes/Utils/XMLRPC/, + "$(inherited)", ); INFOPLIST_FILE = "LiblinphoneTester/LinphoneTester-Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; @@ -6488,6 +6714,7 @@ }; F0BB8C071936208200974404 /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 38A3AE51B9E09ABF29222E5F /* Pods-liblinphoneTester.release.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; @@ -6523,6 +6750,7 @@ HEADER_SEARCH_PATHS = ( Classes/Utils/NinePatch/, Classes/Utils/XMLRPC/, + "$(inherited)", ); INFOPLIST_FILE = "LiblinphoneTester/LinphoneTester-Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; @@ -6538,6 +6766,7 @@ }; F0BB8C081936208200974404 /* Distribution */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 24585CBE78DA4F005C7F9D71 /* Pods-liblinphoneTester.distribution.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; @@ -6573,6 +6802,7 @@ HEADER_SEARCH_PATHS = ( Classes/Utils/NinePatch/, Classes/Utils/XMLRPC/, + "$(inherited)", ); INFOPLIST_FILE = "LiblinphoneTester/LinphoneTester-Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; @@ -6588,6 +6818,7 @@ }; F0BB8C091936208200974404 /* DistributionAdhoc */ = { isa = XCBuildConfiguration; + baseConfigurationReference = FD22CA9E3EFBFEFFF1B80BA2 /* Pods-liblinphoneTester.distributionadhoc.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; @@ -6623,6 +6854,7 @@ HEADER_SEARCH_PATHS = ( Classes/Utils/NinePatch/, Classes/Utils/XMLRPC/, + "$(inherited)", ); INFOPLIST_FILE = "LiblinphoneTester/LinphoneTester-Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; @@ -6638,6 +6870,7 @@ }; F0F952081A6AEB1000254160 /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = ABB887316C42EE876A3051A9 /* Pods-linphoneTests.debug.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; BUNDLE_LOADER = "$(TEST_HOST)"; @@ -6660,10 +6893,6 @@ GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); GCC_SYMBOLS_PRIVATE_EXTERN = NO; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; @@ -6691,6 +6920,7 @@ }; F0F952091A6AEB1000254160 /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = F6373F9231918DECD2B3004D /* Pods-linphoneTests.release.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; BUNDLE_LOADER = "$(TEST_HOST)"; @@ -6738,6 +6968,7 @@ }; F0F9520A1A6AEB1000254160 /* Distribution */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 85FB19B6A8124D942C8471F1 /* Pods-linphoneTests.distribution.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; BUNDLE_LOADER = "$(TEST_HOST)"; @@ -6785,6 +7016,7 @@ }; F0F9520B1A6AEB1000254160 /* DistributionAdhoc */ = { isa = XCBuildConfiguration; + baseConfigurationReference = CE119C214B6B8B2740622BBD /* Pods-linphoneTests.distributionadhoc.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; BUNDLE_LOADER = "$(TEST_HOST)"; diff --git a/linphone.xcodeproj/xcshareddata/xcschemes/linphone.xcscheme b/linphone.xcodeproj/xcshareddata/xcschemes/linphone.xcscheme index 504339055..c5e98385c 100644 --- a/linphone.xcodeproj/xcshareddata/xcschemes/linphone.xcscheme +++ b/linphone.xcodeproj/xcshareddata/xcschemes/linphone.xcscheme @@ -40,6 +40,7 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" + language = "" shouldUseLaunchSchemeArgsEnv = "YES"> + + + + + + diff --git a/linphoneExtension/Info.plist b/linphoneExtension/Info.plist index 53c1b33b9..c0f49bea4 100644 --- a/linphoneExtension/Info.plist +++ b/linphoneExtension/Info.plist @@ -17,15 +17,30 @@ CFBundlePackageType XPC! CFBundleShortVersionString - 1.0 + 4.1 CFBundleVersion - 1 + 27 NSExtension NSExtensionAttributes NSExtensionActivationRule - TRUEPREDICATE + + NSExtensionActivationSupportsAttachmentsWithMaxCount + 1 + NSExtensionActivationSupportsFileWithMaxCount + 1 + NSExtensionActivationSupportsImageWithMaxCount + 1 + NSExtensionActivationSupportsMovieWithMaxCount + 1 + NSExtensionActivationSupportsText + + NSExtensionActivationSupportsWebPageWithMaxCount + 1 + NSExtensionActivationSupportsWebURLWithMaxCount + 1 + NSExtensionMainStoryboard MainInterface diff --git a/linphoneExtension/ShareViewController.h b/linphoneExtension/ShareViewController.h index 6f55e6d10..4929afc5a 100644 --- a/linphoneExtension/ShareViewController.h +++ b/linphoneExtension/ShareViewController.h @@ -8,6 +8,9 @@ #import #import + +#define SUPPORTED_EXTENTIONS @[@"public.jpeg",@"com.compuserve.gif",@"public.url",@"public.movie",@"com.apple.mapkit.map-item",@"com.adobe.pdf",@"public.png",@"public.image"] + @interface ShareViewController : SLComposeServiceViewController @end diff --git a/linphoneExtension/ShareViewController.m b/linphoneExtension/ShareViewController.m index 788ac49af..b79804e5b 100644 --- a/linphoneExtension/ShareViewController.m +++ b/linphoneExtension/ShareViewController.m @@ -10,7 +10,7 @@ @interface ShareViewController () @end -static NSString* groupName = @"group.belledonne-communications.linphone"; + @implementation ShareViewController - (BOOL)isContentValid { @@ -18,7 +18,10 @@ static NSString* groupName = @"group.belledonne-communications.linphone"; return YES; } + - (void)didSelectPost { + NSString* groupName = [NSString stringWithFormat:@"group.%@",[[NSBundle mainBundle] bundleIdentifier]]; + NSLog(@"[SHARE EXTENSTION] using group name inside EXTENSION %@",groupName); // This is called after the user selects Post. Do the upload of contentText and/or NSExtensionContext attachments. BOOL support = TRUE; // Inform the host that we're done, so it un-blocks its UI. Note: Alternatively you could call super's -didSelectPost, which will similarly complete the extension context. @@ -27,24 +30,17 @@ static NSString* groupName = @"group.belledonne-communications.linphone"; NSUserDefaults *defaults = [[NSUserDefaults alloc] initWithSuiteName:groupName]; // TODO: Use [provider registeredTypeIdentifiersWithFileOptions:0]; to get all type identifiers of the provider instead of this if/else if structure support = TRUE; - if ([provider hasItemConformingToTypeIdentifier:@"public.jpeg"]) { - [self loadItem:provider typeIdentifier:@"public.jpeg" defaults:defaults]; - } else if ([provider hasItemConformingToTypeIdentifier:@"com.compuserve.gif"]) { - [self loadItem:provider typeIdentifier:@"com.compuserve.gif" defaults:defaults]; - } else if ([provider hasItemConformingToTypeIdentifier:@"public.url"]) { - [self loadItem:provider typeIdentifier:@"public.url" defaults:defaults]; - } else if ([provider hasItemConformingToTypeIdentifier:@"public.movie"]) { - [self loadItem:provider typeIdentifier:@"public.movie" defaults:defaults]; - } else if ([provider hasItemConformingToTypeIdentifier:@"com.apple.mapkit.map-item"]) { - [self loadItem:provider typeIdentifier:@"com.apple.mapkit.map-item" defaults:defaults]; - } else if ([provider hasItemConformingToTypeIdentifier:@"com.adobe.pdf"]) { - [self loadItem:provider typeIdentifier:@"com.adobe.pdf" defaults:defaults]; - } else if ([provider hasItemConformingToTypeIdentifier:@"public.png"]) { - [self loadItem:provider typeIdentifier:@"public.png" defaults:defaults]; - } else{ - NSLog(@"Unkown itemprovider = %@", provider); - support = false; - } + bool found = false; + for (NSString *ti in SUPPORTED_EXTENTIONS) { + if ([provider hasItemConformingToTypeIdentifier:ti]) { + found=true; + [self loadItem:provider typeIdentifier:ti defaults:defaults]; + } + } + if (!found){ + NSLog(@"Unkown itemprovider = %@", provider); + support = false; + } } } if (!support) @@ -59,12 +55,6 @@ static NSString* groupName = @"group.belledonne-communications.linphone"; - (void)loadItem:(NSItemProvider *)provider typeIdentifier:(NSString *)typeIdentifier defaults:(NSUserDefaults *)defaults { [provider loadItemForTypeIdentifier:typeIdentifier options:nil completionHandler:^(id _Nullable item, NSError * _Null_unspecified error) { - /*if([(NSObject*)item isKindOfClass:[NSDictionary class]]) { - NSDictionary *dico = (NSDictionary *)item; - if (dico) { - return; - } - }*/ if([(NSObject*)item isKindOfClass:[NSURL class]]) { NSURL *url = (NSURL *)item; NSData *nsData = [NSData dataWithContentsOfURL:url]; @@ -75,39 +65,56 @@ static NSString* groupName = @"group.belledonne-communications.linphone"; if([imgPath containsString:@"var/mobile/Media/PhotoData"]) { // We get the corresponding PHAsset identifier so we can display the image in the app without having to duplicate it. NSDictionary *dict = @{@"nsData" : nsData, - @"url" : filename}; + @"url" : filename, + @"message" : self.contentText}; [defaults setObject:dict forKey:@"photoData"]; } else if ([imgPath containsString:@"var/mobile/Library/Mobile Documents/com~apple~CloudDocs"] || [[url scheme] isEqualToString:@"file"]) { // shared files from icloud drive NSDictionary *dict = @{@"nsData" : nsData, - @"url" : filename}; + @"url" : filename, + @"message" : self.contentText}; [defaults setObject:dict forKey:@"icloudData"]; - } else { - //Others - NSDictionary *dict = @{@"url" : [url absoluteString]}; + } else { + NSDictionary *dict = @{@"url" : [url absoluteString], + @"message" : self.contentText}; [defaults setObject:dict forKey:@"url"]; } } else { - NSLog(@"NSExtensionItem Error, provider = %@", provider); - [self.extensionContext completeRequestReturningItems:@[] completionHandler:nil]; + //Others + NSDictionary *dict = @{@"url" : [url absoluteString], + @"message" : self.contentText}; + [defaults setObject:dict forKey:@"url"]; } + + [self respondUrl:defaults]; + } else if ([(NSObject*)item isKindOfClass:[UIImage class]]) { + UIImage *image = (UIImage*)item; + NSDictionary *dict = @{@"nsData" : UIImagePNGRepresentation(image), + @"url" : [NSString stringWithFormat:@"IMAGE_%f.PNG", [[NSDate date] timeIntervalSince1970]], + @"message" : self.contentText}; + [defaults setObject:dict forKey:@"photoData"]; - UIResponder *responder = self; - while (responder != nil) { - if ([responder respondsToSelector:@selector(openURL:)]) { - [responder performSelector:@selector(openURL:) - withObject:[NSURL URLWithString:@"message-linphone://" ]]; - [self.extensionContext completeRequestReturningItems:@[] completionHandler:nil]; - break; - } - responder = [responder nextResponder]; - } - [defaults synchronize]; + [self respondUrl:defaults]; } else { //share text NSLog(@"Unsupported provider = %@", provider); + [self.extensionContext completeRequestReturningItems:@[] completionHandler:nil]; } }]; } +- (void)respondUrl:(NSUserDefaults *)defaults { + UIResponder *responder = self; + while (responder != nil) { + if ([responder respondsToSelector:@selector(openURL:)]) { + [responder performSelector:@selector(openURL:) + withObject:[NSURL URLWithString:@"message-linphone://" ]]; + [self.extensionContext completeRequestReturningItems:@[] completionHandler:nil]; + break; + } + responder = [responder nextResponder]; + } + [defaults synchronize]; +} + @end diff --git a/linphoneExtension/linphoneExtension.entitlements b/linphoneExtension/linphoneExtension.entitlements index bfb9af2e1..36778db04 100644 --- a/linphoneExtension/linphoneExtension.entitlements +++ b/linphoneExtension/linphoneExtension.entitlements @@ -4,7 +4,7 @@ com.apple.security.application-groups - group.belledonne-communications.linphone + group.org.linphone.phone.linphoneExtension diff --git a/prepare.conf b/prepare.conf new file mode 100644 index 000000000..bc4c93b42 --- /dev/null +++ b/prepare.conf @@ -0,0 +1,5 @@ +-DENABLE_LIME_X3DH=yes +-DENABLE_LIME=no +-DENABLE_SOCI=yes +-DENABLE_QRCODE=yes + diff --git a/richNotifications/Info.plist b/richNotifications/Info.plist index f6e516e4d..c16b97f7c 100644 --- a/richNotifications/Info.plist +++ b/richNotifications/Info.plist @@ -17,17 +17,17 @@ CFBundlePackageType XPC! CFBundleShortVersionString - 1.0 + 4.1 CFBundleVersion - 1 + 27 NSExtension NSExtensionAttributes - UNNotificationExtensionDefaultContentHidden - UNNotificationExtensionCategory msg_cat + UNNotificationExtensionDefaultContentHidden + UNNotificationExtensionInitialContentSizeRatio 1 diff --git a/submodules/bcg729 b/submodules/bcg729 deleted file mode 160000 index fdd4b15cd..000000000 --- a/submodules/bcg729 +++ /dev/null @@ -1 +0,0 @@ -Subproject commit fdd4b15cd773ecdd01c4aeb65a8ec2cbde65637e diff --git a/submodules/bcmatroska2 b/submodules/bcmatroska2 deleted file mode 160000 index f4b87c521..000000000 --- a/submodules/bcmatroska2 +++ /dev/null @@ -1 +0,0 @@ -Subproject commit f4b87c521a513b540f34a72ef82a52364929d0be diff --git a/submodules/bctoolbox b/submodules/bctoolbox deleted file mode 160000 index d5713996c..000000000 --- a/submodules/bctoolbox +++ /dev/null @@ -1 +0,0 @@ -Subproject commit d5713996c2ae100594ebf319c54d95297b02a2e1 diff --git a/submodules/bcunit b/submodules/bcunit deleted file mode 160000 index 8f5e72c34..000000000 --- a/submodules/bcunit +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 8f5e72c3428ad6ff9bfa59da5a83524ff0764fa5 diff --git a/submodules/belcard b/submodules/belcard deleted file mode 160000 index b5283c188..000000000 --- a/submodules/belcard +++ /dev/null @@ -1 +0,0 @@ -Subproject commit b5283c18809bfdfb4c3c0a871601b0137b001cc4 diff --git a/submodules/belle-sip b/submodules/belle-sip deleted file mode 160000 index c9979fe37..000000000 --- a/submodules/belle-sip +++ /dev/null @@ -1 +0,0 @@ -Subproject commit c9979fe3766f7961207a2a792fa409da4ddf5dd1 diff --git a/submodules/belr b/submodules/belr deleted file mode 160000 index a201f11fc..000000000 --- a/submodules/belr +++ /dev/null @@ -1 +0,0 @@ -Subproject commit a201f11fc5a2872d6cbd280dc3c3aeca199ed2ff diff --git a/submodules/bzrtp b/submodules/bzrtp deleted file mode 160000 index 41b2163c8..000000000 --- a/submodules/bzrtp +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 41b2163c865fed835abc013ecaa25267fa2b1d63 diff --git a/submodules/cmake-builder b/submodules/cmake-builder deleted file mode 160000 index 210a3c55c..000000000 --- a/submodules/cmake-builder +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 210a3c55cd75c70e7f807cf08464493ea62e4458 diff --git a/submodules/externals/bv16-floatingpoint b/submodules/externals/bv16-floatingpoint deleted file mode 160000 index 5de7c0185..000000000 --- a/submodules/externals/bv16-floatingpoint +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 5de7c01854af468a9c7694eb88ba0a302e9e9d20 diff --git a/submodules/externals/codec2 b/submodules/externals/codec2 deleted file mode 160000 index 4e154e6bb..000000000 --- a/submodules/externals/codec2 +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 4e154e6bbbe92cc76e333a0b4acb365b5c042ec6 diff --git a/submodules/externals/ffmpeg b/submodules/externals/ffmpeg deleted file mode 160000 index 644296e73..000000000 --- a/submodules/externals/ffmpeg +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 644296e736ee219cd02f7b7d7b7b4c7c5a464217 diff --git a/submodules/externals/gsm b/submodules/externals/gsm deleted file mode 160000 index 50802f80d..000000000 --- a/submodules/externals/gsm +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 50802f80dee88367c6699ca71799b69d8e571531 diff --git a/submodules/externals/libjpeg-turbo b/submodules/externals/libjpeg-turbo deleted file mode 160000 index 0e99446a2..000000000 --- a/submodules/externals/libjpeg-turbo +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 0e99446a237bef6704d45f74d504ae8aafa45f9a diff --git a/submodules/externals/libvpx b/submodules/externals/libvpx deleted file mode 160000 index 93770ec52..000000000 --- a/submodules/externals/libvpx +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 93770ec52ef7db1c039ce9a93f6599f155ec348f diff --git a/submodules/externals/libxml2 b/submodules/externals/libxml2 deleted file mode 160000 index c943f708f..000000000 --- a/submodules/externals/libxml2 +++ /dev/null @@ -1 +0,0 @@ -Subproject commit c943f708f1853de4eb15e5a94cf0b35d108da87a diff --git a/submodules/externals/libxsd b/submodules/externals/libxsd deleted file mode 160000 index 34af5de2e..000000000 --- a/submodules/externals/libxsd +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 34af5de2ee71dde72a010fde336d2efa9c386abd diff --git a/submodules/externals/mbedtls b/submodules/externals/mbedtls deleted file mode 160000 index 83d21d543..000000000 --- a/submodules/externals/mbedtls +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 83d21d543c26a31943b2bd08c66b029f2ef742be diff --git a/submodules/externals/opencore-amr b/submodules/externals/opencore-amr deleted file mode 160000 index cf4409e03..000000000 --- a/submodules/externals/opencore-amr +++ /dev/null @@ -1 +0,0 @@ -Subproject commit cf4409e03ec56b1cd85a2f9532f58bc1fa9db274 diff --git a/submodules/externals/openh264 b/submodules/externals/openh264 deleted file mode 160000 index 50daa8f73..000000000 --- a/submodules/externals/openh264 +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 50daa8f737fe174d723a10f97fa7ec24f54a6178 diff --git a/submodules/externals/opus b/submodules/externals/opus deleted file mode 160000 index 35b371a85..000000000 --- a/submodules/externals/opus +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 35b371a85bf2cf21ab4b12b5475c76a2775b25d1 diff --git a/submodules/externals/soci b/submodules/externals/soci deleted file mode 160000 index 510164af9..000000000 --- a/submodules/externals/soci +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 510164af9b23f7f53cf3cc73f2f6a5de7814163f diff --git a/submodules/externals/speex b/submodules/externals/speex deleted file mode 160000 index a86ed3c99..000000000 --- a/submodules/externals/speex +++ /dev/null @@ -1 +0,0 @@ -Subproject commit a86ed3c99794f20a5a525d71ca37d2b7788d6ba6 diff --git a/submodules/externals/srtp b/submodules/externals/srtp deleted file mode 160000 index a1e31c958..000000000 --- a/submodules/externals/srtp +++ /dev/null @@ -1 +0,0 @@ -Subproject commit a1e31c958811b2a03571f5d824913be940288e93 diff --git a/submodules/externals/vo-amrwbenc b/submodules/externals/vo-amrwbenc deleted file mode 160000 index 080af7540..000000000 --- a/submodules/externals/vo-amrwbenc +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 080af7540562e4adfbd3312837fe5fc6771c4cd0 diff --git a/submodules/externals/x264 b/submodules/externals/x264 deleted file mode 160000 index 1840d2a6d..000000000 --- a/submodules/externals/x264 +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 1840d2a6de0e832d5c770e0810bcaf5c5ca7a7ff diff --git a/submodules/externals/xerces-c b/submodules/externals/xerces-c deleted file mode 160000 index 9c15b9917..000000000 --- a/submodules/externals/xerces-c +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 9c15b9917507c584eadace89636b91af27b59b9c diff --git a/submodules/externals/zxing-cpp b/submodules/externals/zxing-cpp deleted file mode 160000 index 8906fb7b2..000000000 --- a/submodules/externals/zxing-cpp +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 8906fb7b243fa455fd9b091e4ac611536b2dbba4 diff --git a/submodules/linphone b/submodules/linphone deleted file mode 160000 index 065c01983..000000000 --- a/submodules/linphone +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 065c019834939323d5d43c472fceaf6432e0ff78 diff --git a/submodules/mediastreamer2 b/submodules/mediastreamer2 deleted file mode 160000 index 749dafa26..000000000 --- a/submodules/mediastreamer2 +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 749dafa269616d51cfa1892112ea6cbaf7298e58 diff --git a/submodules/msamr b/submodules/msamr deleted file mode 160000 index a94801cba..000000000 --- a/submodules/msamr +++ /dev/null @@ -1 +0,0 @@ -Subproject commit a94801cbae83da9d1b68293c4c9b1c75312a5a2e diff --git a/submodules/mscodec2 b/submodules/mscodec2 deleted file mode 160000 index 9e2397607..000000000 --- a/submodules/mscodec2 +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 9e2397607933104f9361869ff9e309fbb99adaeb diff --git a/submodules/msopenh264 b/submodules/msopenh264 deleted file mode 160000 index fd330d26e..000000000 --- a/submodules/msopenh264 +++ /dev/null @@ -1 +0,0 @@ -Subproject commit fd330d26ecd368f6ee71e81c4f72ca6b935b8b33 diff --git a/submodules/mssilk b/submodules/mssilk deleted file mode 160000 index 5359c58f3..000000000 --- a/submodules/mssilk +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 5359c58f3a89cc581fadb7f76ac3a82672e574b8 diff --git a/submodules/mswebrtc b/submodules/mswebrtc deleted file mode 160000 index df80ca502..000000000 --- a/submodules/mswebrtc +++ /dev/null @@ -1 +0,0 @@ -Subproject commit df80ca50229d889226a1dfd556e5caec38f46f3b diff --git a/submodules/msx264 b/submodules/msx264 deleted file mode 160000 index f4fe74056..000000000 --- a/submodules/msx264 +++ /dev/null @@ -1 +0,0 @@ -Subproject commit f4fe74056d0474b42025d95449ec859e984d78ea diff --git a/submodules/ortp b/submodules/ortp deleted file mode 160000 index a88be02b9..000000000 --- a/submodules/ortp +++ /dev/null @@ -1 +0,0 @@ -Subproject commit a88be02b93e2274ae3fcf80e1e0032adc43c0448