Merge branch 'feature/integration'

This commit is contained in:
Mickaël Turnel 2019-04-19 11:28:57 +02:00
commit ff2545b8bf
630 changed files with 7424 additions and 2959 deletions

2
.gitignore vendored
View file

@ -6,6 +6,8 @@ liblinphone-iphone-sdk*.zip
xcuserdata/
Classes/LinphoneIOSVersion.h
Pods/
Podfile.lock
GoogleService-Info.plist
build
test-reports
WORK

118
.gitmodules vendored
View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -5,17 +5,18 @@
// Created by Gautier Pelloux-Prayer on 29/08/16.
//
//
#import "PhoneMainView.h"
#import <UIKit/UIKit.h>
#import "TPKeyboardAvoidingScrollView.h"
@interface AssistantLinkView : UIViewController <UITextFieldDelegate, UICompositeViewDelegate>
@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

View file

@ -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 {

View file

@ -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;

View file

@ -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";

View file

@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14109" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" colorMatched="YES">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" colorMatched="YES">
<device id="retina4_0" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14088"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14490.49"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
@ -38,14 +38,14 @@
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES" flexibleMaxY="YES"/>
</imageView>
<button opaque="NO" tag="4" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="ETk-tB-ZNl" userLabel="dialerBackButton" customClass="UIIconButton">
<rect key="frame" x="255" y="0.0" width="65" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<rect key="frame" x="0.0" y="0.0" width="82" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Add contact"/>
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
<state key="normal" image="dialer_back_default.png">
<state key="normal" image="back_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="dialer_back_disabled.png"/>
<state key="disabled" image="back_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onDialerBackClick:" destination="-1" eventType="touchUpInside" id="PJX-d2-pSh"/>
@ -64,25 +64,25 @@
<rect key="frame" x="0.0" y="66" width="320" height="535"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<subviews>
<imageView userInteractionEnabled="NO" tag="7" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" image="color_C.png" id="fbO-x9-0Ue" userLabel="backgroundColor">
<imageView userInteractionEnabled="NO" tag="7" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="color_C.png" id="fbO-x9-0Ue" userLabel="backgroundColor">
<rect key="frame" x="0.0" y="0.0" width="320" height="262"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES" flexibleMaxY="YES"/>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" tag="11" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" text="Linphone iOS 8.0" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="gLk-Bc-zvx" userLabel="appVersionLabel">
<label opaque="NO" userInteractionEnabled="NO" tag="11" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Linphone iOS 8.0" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="gLk-Bc-zvx" userLabel="appVersionLabel">
<rect key="frame" x="-8" y="221" width="320" height="21"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.85415387153625488" green="0.85412830114364624" blue="0.85414278507232666" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" tag="12" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" text="Linphone Core 3.14.0" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="ZYk-v1-CYZ" userLabel="libVersionLabel">
<label opaque="NO" userInteractionEnabled="NO" tag="12" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Linphone Core 3.14.0" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="ZYk-v1-CYZ" userLabel="libVersionLabel">
<rect key="frame" x="-8" y="241" width="320" height="21"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.85415387153625488" green="0.85412830114364624" blue="0.85414278507232666" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" tag="13" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" text="https://www.linphone.org" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="1pe-zf-cQh" userLabel="siteURLLabel">
<label opaque="NO" tag="13" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="https://www.linphone.org" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="1pe-zf-cQh" userLabel="siteURLLabel">
<rect key="frame" x="0.0" y="270" width="320" height="29"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
@ -92,18 +92,18 @@
<outletCollection property="gestureRecognizers" destination="l7c-wq-pii" appends="YES" id="olo-CD-gM3"/>
</connections>
</label>
<label opaque="NO" userInteractionEnabled="NO" tag="14" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" text="Visit our privacy policy" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="7" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" id="5Nl-Fs-ggi" userLabel="policyLabel">
<label opaque="NO" userInteractionEnabled="NO" tag="14" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Visit our privacy policy" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="7" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" id="5Nl-Fs-ggi" userLabel="policyLabel">
<rect key="frame" x="0.0" y="298" width="320" height="29"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.33333333329999998" green="0.33333333329999998" blue="0.33333333329999998" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<imageView userInteractionEnabled="NO" tag="8" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" image="splashscreen.png" id="wSQ-YD-dIQ" userLabel="logoImage">
<imageView userInteractionEnabled="NO" tag="8" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="splashscreen.png" id="wSQ-YD-dIQ" userLabel="logoImage">
<rect key="frame" x="0.0" y="8" width="320" height="166"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" tag="10" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" usesAttributedText="YES" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.10000000149011612" id="siH-xH-Z5X" userLabel="descLabel">
<label opaque="NO" userInteractionEnabled="NO" tag="10" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" usesAttributedText="YES" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.10000000149011612" id="siH-xH-Z5X" userLabel="descLabel">
<rect key="frame" x="68" y="179" width="185" height="34"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<attributedString key="attributedText">
@ -131,11 +131,11 @@
</attributedString>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" tag="14" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="7" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" id="gVK-Xc-S59" userLabel="licenseLabel">
<label opaque="NO" userInteractionEnabled="NO" tag="14" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="7" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" id="gVK-Xc-S59" userLabel="licenseLabel">
<rect key="frame" x="-8" y="335" width="320" height="61"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<string key="text">GNU General Public License V2
© 2010-2018 Belledonne Communications</string>
© 2010-2019 Belledonne Communications</string>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.33333333333333331" green="0.33333333333333331" blue="0.33333333333333331" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
@ -147,13 +147,13 @@
</view>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<point key="canvasLocation" x="235" y="318"/>
<point key="canvasLocation" x="376" y="286.05697151424289"/>
</view>
<view contentMode="scaleToFill" id="FcM-rg-Qrt" userLabel="iphone6MetricsView">
<rect key="frame" x="0.0" y="0.0" width="320" height="568"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<view tag="1" contentMode="scaleToFill" misplaced="YES" id="sVO-4a-t1s">
<view tag="1" contentMode="scaleToFill" id="sVO-4a-t1s">
<rect key="frame" x="0.0" y="66" width="320" height="391"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
@ -166,14 +166,14 @@
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES" flexibleMaxY="YES"/>
</imageView>
<button opaque="NO" tag="4" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="vX8-wO-ZEN" userLabel="dialerBackButton" customClass="UIIconButton">
<rect key="frame" x="255" y="0.0" width="65" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<rect key="frame" x="0.0" y="0.0" width="82" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Add contact"/>
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
<state key="normal" image="dialer_back_default.png">
<state key="normal" image="back_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="dialer_back_disabled.png"/>
<state key="disabled" image="back_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onDialerBackClick:" destination="-1" eventType="touchUpInside" id="vfB-jG-YPr"/>
@ -192,11 +192,11 @@
<rect key="frame" x="0.0" y="66" width="320" height="243"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<imageView userInteractionEnabled="NO" tag="7" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" image="color_C.png" id="UBx-Gi-qTi" userLabel="backgroundColor">
<imageView userInteractionEnabled="NO" tag="7" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="color_C.png" id="UBx-Gi-qTi" userLabel="backgroundColor">
<rect key="frame" x="0.0" y="0.0" width="320" height="152"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES" flexibleMaxY="YES"/>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" tag="10" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" usesAttributedText="YES" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.10000000149011612" id="ASG-VC-Riv" userLabel="descLabel">
<label opaque="NO" userInteractionEnabled="NO" tag="10" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" usesAttributedText="YES" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.10000000149011612" id="ASG-VC-Riv" userLabel="descLabel">
<rect key="frame" x="152" y="35" width="124" height="45"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<attributedString key="attributedText">
@ -224,41 +224,41 @@
</attributedString>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" tag="11" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" text="Linphone iPhone 3.0" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="oYk-ih-BBi" userLabel="appVersionLabel">
<label opaque="NO" userInteractionEnabled="NO" tag="11" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Linphone iPhone 3.0" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="oYk-ih-BBi" userLabel="appVersionLabel">
<rect key="frame" x="109" y="88" width="211" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.85415387153625488" green="0.85412830114364624" blue="0.85414278507232666" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" tag="13" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" text="https://www.linphone.org" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="jGU-DX-XcO" userLabel="siteURLLabel">
<label opaque="NO" tag="13" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="https://www.linphone.org" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="jGU-DX-XcO" userLabel="siteURLLabel">
<rect key="frame" x="0.0" y="154" width="320" height="29"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.98766469960000003" green="0.27512490750000002" blue="0.029739789660000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" tag="14" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" text="Visit our privacy policy" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="7" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" id="nld-cR-eba" userLabel="policyLabel">
<label opaque="NO" userInteractionEnabled="NO" tag="14" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Visit our privacy policy" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="7" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" id="nld-cR-eba" userLabel="policyLabel">
<rect key="frame" x="0.0" y="173" width="320" height="41"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.33333333329999998" green="0.33333333329999998" blue="0.33333333329999998" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" tag="12" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" text="Linphone Core 3.9.0" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="g2W-u5-yxg" userLabel="libVersionLabel">
<label opaque="NO" userInteractionEnabled="NO" tag="12" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Linphone Core 3.9.0" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="g2W-u5-yxg" userLabel="libVersionLabel">
<rect key="frame" x="109" y="117" width="211" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.85415387153625488" green="0.85412830114364624" blue="0.85414278507232666" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<imageView userInteractionEnabled="NO" tag="8" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" image="splashscreen.png" id="UhZ-5i-eU5" userLabel="logoImage">
<imageView userInteractionEnabled="NO" tag="8" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="splashscreen.png" id="UhZ-5i-eU5" userLabel="logoImage">
<rect key="frame" x="6" y="0.0" width="121" height="152"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
</imageView>
</subviews>
</view>
<label opaque="NO" userInteractionEnabled="NO" tag="14" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" text="GNU General Public License V2 © 2010-2018 Belledonne Communications" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="7" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" id="vqn-sI-DiC" userLabel="licenseLabel">
<label opaque="NO" userInteractionEnabled="NO" tag="14" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="GNU General Public License V2 © 2010-2019 Belledonne Communications" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="7" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" id="vqn-sI-DiC" userLabel="licenseLabel">
<rect key="frame" x="0.0" y="226" width="520" height="35"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
@ -270,7 +270,7 @@
</view>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<point key="canvasLocation" x="871" y="248"/>
<point key="canvasLocation" x="1393.5999999999999" y="223.08845577211397"/>
</view>
<tapGestureRecognizer id="l7c-wq-pii" userLabel="onLinkTap">
<connections>
@ -279,11 +279,11 @@
</tapGestureRecognizer>
</objects>
<resources>
<image name="back_default.png" width="38.400001525878906" height="35.200000762939453"/>
<image name="back_disabled.png" width="38.400001525878906" height="35.200000762939453"/>
<image name="color_C.png" width="2" height="2"/>
<image name="color_E.png" width="2" height="2"/>
<image name="color_F.png" width="2" height="2"/>
<image name="dialer_back_default.png" width="27" height="27"/>
<image name="dialer_back_disabled.png" width="27" height="27"/>
<image name="splashscreen.png" width="533" height="386"/>
<image name="splashscreen.png" width="852.79998779296875" height="617.5999755859375"/>
</resources>
</document>

View file

@ -1,21 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="11201" systemVersion="16A323" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" colorMatched="YES">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" colorMatched="YES">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11161"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14490.49"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="AssistantLinkView">
<connections>
<outlet property="activateSMSView" destination="2Nl-QG-fTA" id="kfz-Eh-D1e"/>
<outlet property="activateSMSView" destination="2Nl-QG-fTA" id="32Y-Z3-OYi"/>
<outlet property="activationCodeField" destination="PXL-cl-haZ" id="faz-N0-sjR"/>
<outlet property="checkValidationButton" destination="bIM-bh-Huy" id="yr2-9j-ejj"/>
<outlet property="countryButton" destination="rLT-uU-cJS" id="lNp-Qo-AKx"/>
<outlet property="countryCodeField" destination="DBr-NA-Ibx" id="cRz-xe-r5D"/>
<outlet property="linkAccountButton" destination="D25-6f-qRg" id="aid-PS-8mU"/>
<outlet property="linkAccountView" destination="ImD-Y4-3nC" id="8yc-Dr-cZ8"/>
<outlet property="linkAccountView" destination="ImD-Y4-3nC" id="231-q3-rGe"/>
<outlet property="linkSMSText" destination="Dvq-wa-3k8" id="4Ne-Ud-aA1"/>
<outlet property="maybeLaterButton" destination="bes-x4-C4l" id="l5a-ON-h9a"/>
<outlet property="phoneField" destination="cEN-WO-5qv" id="Ftl-EA-afz"/>
<outlet property="view" destination="FBm-gC-sIQ" id="Bhr-VA-MJs"/>
<outlet property="waitView" destination="J3A-Fb-Dpg" id="zbb-YB-ace"/>
@ -27,33 +31,33 @@
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<view tag="1" contentMode="scaleToFill" id="FBm-gC-sIQ">
<frame key="frameInset" minY="66"/>
<rect key="frame" x="0.0" y="66" width="375" height="601"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view tag="2" contentMode="scaleToFill" misplaced="YES" id="c7I-Cv-d4R" userLabel="topBar">
<frame key="frameInset" height="66" maxX="8"/>
<view tag="2" contentMode="scaleToFill" id="c7I-Cv-d4R" userLabel="topBar">
<rect key="frame" x="0.0" y="0.0" width="367" height="66"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<subviews>
<imageView userInteractionEnabled="NO" tag="3" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" image="color_F.png" id="q79-qx-kgb" userLabel="backgroundColor">
<frame key="frameInset" height="66" maxX="-8"/>
<imageView userInteractionEnabled="NO" tag="3" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="color_F.png" id="q79-qx-kgb" userLabel="backgroundColor">
<rect key="frame" x="0.0" y="0.0" width="375" height="66"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
</imageView>
<button opaque="NO" tag="4" contentMode="scaleToFill" misplaced="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="VlN-Em-1V6" userLabel="dialerBackButton" customClass="UIIconButton">
<frame key="frameInset" width="76" height="66" maxX="-9"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
<button opaque="NO" tag="4" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="VlN-Em-1V6" userLabel="dialerBackButton" customClass="UIIconButton">
<rect key="frame" x="0.0" y="0.0" width="82" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Add contact"/>
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
<state key="normal" image="dialer_back_default.png">
<state key="normal" image="back_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="dialer_back_disabled.png"/>
<state key="disabled" image="back_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onDialerClick:" destination="-1" eventType="touchUpInside" id="WUU-Oh-Ofu"/>
</connections>
</button>
<label opaque="NO" userInteractionEnabled="NO" tag="5" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="ASSISTANT" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="zrj-TX-1RP" userLabel="titleLabel">
<frame key="frameInset" width="375" height="66"/>
<rect key="frame" x="0.0" y="0.0" width="375" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="27"/>
<color key="textColor" red="0.98766469955444336" green="0.27512490749359131" blue="0.029739789664745331" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
@ -61,12 +65,12 @@
</label>
</subviews>
</view>
<view hidden="YES" contentMode="scaleToFill" id="ImD-Y4-3nC" userLabel="linkAccountView">
<frame key="frameInset" minY="66" height="535"/>
<view hidden="YES" contentMode="scaleToFill" id="ImD-Y4-3nC" userLabel="linkAccountView" customClass="TPKeyboardAvoidingScrollView">
<rect key="frame" x="0.0" y="66" width="375" height="535"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="LINK YOUR ACCOUNT" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" id="0xQ-6c-cAc" userLabel="titleLabel">
<frame key="frameInset" minX="50.00%" width="299" height="59"/>
<rect key="frame" x="38" y="0.0" width="299" height="59"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Account setup assistant"/>
<fontDescription key="fontDescription" type="system" weight="light" pointSize="24"/>
@ -75,7 +79,7 @@
<size key="shadowOffset" width="-1" height="-1"/>
</label>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Please confirm your country code and enter your phone number" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="2" baselineAdjustment="alignBaselines" minimumFontSize="11" id="RQz-tT-5vp" userLabel="subtitleLabel">
<frame key="frameInset" minX="10.13%" minY="13.04%" width="79.73%" height="29"/>
<rect key="frame" x="38" y="66" width="299" height="29"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Account setup assistant"/>
<fontDescription key="fontDescription" type="system" pointSize="15"/>
@ -83,15 +87,15 @@
<nil key="highlightedColor"/>
<size key="shadowOffset" width="-1" height="-1"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" tag="122" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" text="PHONE NUMBER" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="v2Q-jf-BdL" userLabel="phoneLabel">
<frame key="frameInset" minX="10.13%" minY="25.14%" width="79.73%" height="14"/>
<label opaque="NO" userInteractionEnabled="NO" tag="122" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="PHONE NUMBER" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="v2Q-jf-BdL" userLabel="phoneLabel">
<rect key="frame" x="38" y="131" width="299" height="14"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="13"/>
<color key="textColor" red="0.4266758859" green="0.42666310070000002" blue="0.42667034269999998" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<button opaque="NO" tag="150" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="rLT-uU-cJS" userLabel="countryButton" customClass="UIRoundBorderedButton">
<frame key="frameInset" minX="10.13%" minY="30.30%" width="79.73%" height="30"/>
<rect key="frame" x="38" y="153" width="299" height="30"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<state key="normal" title="Select your country">
<color key="titleColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
@ -101,12 +105,12 @@
<action selector="onCountryClick:" destination="-1" eventType="touchUpInside" id="AUl-nx-xOA"/>
</connections>
</button>
<view contentMode="scaleToFill" misplaced="YES" id="88g-7g-gGM" userLabel="phoneNumberView">
<frame key="frameInset" minX="10.13%" minY="189" width="79.73%" height="43"/>
<view contentMode="scaleToFill" id="88g-7g-gGM" userLabel="phoneNumberView">
<rect key="frame" x="38" y="189" width="299" height="43"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<textField opaque="NO" clipsSubviews="YES" tag="109" contentMode="scaleToFill" misplaced="YES" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="+1" textAlignment="center" minimumFontSize="5" id="DBr-NA-Ibx" userLabel="countryCodeField">
<frame key="frameInset" minX="1" minY="53.85%" width="18.12%" height="30"/>
<textField opaque="NO" clipsSubviews="YES" tag="109" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="+1" textAlignment="center" minimumFontSize="5" id="DBr-NA-Ibx" userLabel="countryCodeField">
<rect key="frame" x="1" y="7" width="54" height="30"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" red="0.85415387149999999" green="0.85412830110000004" blue="0.85414278509999997" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
@ -117,7 +121,7 @@
</connections>
</textField>
<textField opaque="NO" clipsSubviews="YES" tag="107" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" adjustsFontSizeToFit="NO" minimumFontSize="10" id="cEN-WO-5qv" userLabel="phoneField">
<frame key="frameInset" minY="53.85%" width="80.67%" height="30" maxX="-1"/>
<rect key="frame" x="58" y="7" width="242" height="30"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" red="0.85415387149999999" green="0.85412830110000004" blue="0.85414278509999997" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<accessibility key="accessibilityConfiguration" label="Username"/>
@ -129,15 +133,15 @@
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<inset key="insetFor6xAndEarlier" minX="0.0" minY="0.0" maxX="299" maxY="0.0"/>
</view>
<button opaque="NO" contentMode="scaleToFill" misplaced="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="infoDark" showsTouchWhenHighlighted="YES" lineBreakMode="middleTruncation" id="9cd-3u-fU5" userLabel="infoButton">
<frame key="frameInset" minX="84.99%" minY="24.76%" width="22" height="22"/>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="infoDark" showsTouchWhenHighlighted="YES" lineBreakMode="middleTruncation" id="9cd-3u-fU5" userLabel="infoButton">
<rect key="frame" x="300" y="127" width="22" height="22"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<connections>
<action selector="onPhoneNumberDisclosureClick:" destination="-1" eventType="touchUpInside" id="FEb-Xm-Pyx"/>
</connections>
</button>
<button opaque="NO" tag="130" contentMode="scaleToFill" misplaced="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" lineBreakMode="middleTruncation" id="D25-6f-qRg" userLabel="linkAccountButton" customClass="UIRoundBorderedButton">
<frame key="frameInset" minX="10.13%" minY="50.91%" width="79.73%" height="40"/>
<button opaque="NO" tag="130" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" lineBreakMode="middleTruncation" id="D25-6f-qRg" userLabel="linkAccountButton" customClass="UIRoundBorderedButton">
<rect key="frame" x="38" y="252" width="299" height="40"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Create account">
<bool key="isElement" value="YES"/>
@ -154,15 +158,33 @@
<action selector="onLinkAccount:" destination="-1" eventType="touchUpInside" id="wd4-6V-tMa"/>
</connections>
</button>
<button opaque="NO" tag="130" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" lineBreakMode="middleTruncation" id="bes-x4-C4l" userLabel="maybeLaterButton" customClass="UIRoundBorderedButton">
<rect key="frame" x="38" y="312" width="299" height="40"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Finish configuration">
<bool key="isElement" value="YES"/>
</accessibility>
<fontDescription key="fontDescription" type="system" pointSize="16"/>
<state key="normal" title="MAYBE LATER">
<color key="titleColor" red="0.20521381499999999" green="0.20520767570000001" blue="0.2052111626" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled">
<color key="titleColor" red="0.71885228160000003" green="0.71883076430000004" blue="0.71884298319999995" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="highlighted" backgroundImage="color_F.png"/>
<connections>
<action selector="onMaybeLater:" destination="-1" eventType="touchUpInside" id="IcP-2Y-18k"/>
</connections>
</button>
</subviews>
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
</view>
<view contentMode="scaleToFill" id="2Nl-QG-fTA" userLabel="activateSMSView">
<frame key="frameInset" minY="66" height="535"/>
<rect key="frame" x="0.0" y="66" width="375" height="535"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="LINK YOUR ACCOUNT" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" id="5aj-17-dC2" userLabel="titleLabel">
<frame key="frameInset" minX="52.78%" width="303" height="59"/>
<rect key="frame" x="38" y="0.0" width="303" height="59"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Account setup assistant"/>
<fontDescription key="fontDescription" type="system" weight="light" pointSize="24"/>
@ -171,7 +193,7 @@
<size key="shadowOffset" width="-1" height="-1"/>
</label>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="2/2" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="3" baselineAdjustment="alignBaselines" minimumFontSize="10" id="bU8-Tu-9O4" userLabel="subtitleLabel">
<frame key="frameInset" minX="10.13%" minY="13.04%" width="80.80%" height="29"/>
<rect key="frame" x="38" y="66" width="303" height="29"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Account setup assistant"/>
<fontDescription key="fontDescription" type="system" pointSize="13"/>
@ -179,15 +201,15 @@
<nil key="highlightedColor"/>
<size key="shadowOffset" width="-1" height="-1"/>
</label>
<textField opaque="NO" clipsSubviews="YES" tag="108" contentMode="scaleToFill" misplaced="YES" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="Activation code" textAlignment="center" minimumFontSize="17" clearButtonMode="always" id="PXL-cl-haZ" userLabel="activationCodeField">
<frame key="frameInset" minX="10.13%" minY="42.38%" width="80.80%" height="30"/>
<textField opaque="NO" clipsSubviews="YES" tag="108" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="Activation code" textAlignment="center" minimumFontSize="17" clearButtonMode="always" id="PXL-cl-haZ" userLabel="activationCodeField">
<rect key="frame" x="38" y="214" width="303" height="30"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" red="0.85415387153625488" green="0.85412830114364624" blue="0.85414278507232666" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<fontDescription key="fontDescription" type="system" pointSize="26"/>
<textInputTraits key="textInputTraits" autocorrectionType="no" spellCheckingType="no" keyboardType="numberPad" returnKeyType="done"/>
</textField>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" misplaced="YES" text="We have sent you a SMS with a validation code. To complete your phone number verification, please enter the 4 digit code below:" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="8" baselineAdjustment="alignBaselines" minimumFontSize="10" id="Dvq-wa-3k8" userLabel="activateDescLabel">
<frame key="frameInset" minX="10.13%" minY="23.46%" width="80.80%" height="96"/>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="We have sent you a SMS with a validation code. To complete your phone number verification, please enter the 4 digit code below:" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="8" baselineAdjustment="alignBaselines" minimumFontSize="10" id="Dvq-wa-3k8" userLabel="activateDescLabel">
<rect key="frame" x="38" y="103" width="303" height="96"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Account setup assistant"/>
<fontDescription key="fontDescription" type="system" pointSize="13"/>
@ -195,8 +217,8 @@
<nil key="highlightedColor"/>
<size key="shadowOffset" width="-1" height="-1"/>
</label>
<button opaque="NO" tag="130" contentMode="scaleToFill" misplaced="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" lineBreakMode="middleTruncation" id="bIM-bh-Huy" userLabel="checkValidationButton" customClass="UIRoundBorderedButton">
<frame key="frameInset" minX="10.13%" minY="50.91%" width="79.73%" height="40"/>
<button opaque="NO" tag="130" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" lineBreakMode="middleTruncation" id="bIM-bh-Huy" userLabel="checkValidationButton" customClass="UIRoundBorderedButton">
<rect key="frame" x="38" y="252" width="299" height="40"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Finish configuration">
<bool key="isElement" value="YES"/>
@ -217,11 +239,11 @@
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
</view>
<view hidden="YES" tag="8" contentMode="scaleToFill" id="J3A-Fb-Dpg" userLabel="waitView">
<frame key="frameInset" minY="-33" maxY="-33"/>
<rect key="frame" x="0.0" y="-33" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<activityIndicatorView opaque="NO" tag="9" contentMode="scaleToFill" animating="YES" style="gray" id="mQl-pi-5rq" userLabel="activityIndicatorView">
<frame key="frameInset" minX="50.42%" minY="49.77%" width="20" height="20"/>
<rect key="frame" x="179" y="322" width="20" height="20"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
</activityIndicatorView>
</subviews>
@ -233,18 +255,13 @@
</view>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<point key="canvasLocation" x="235.5" y="318.5"/>
<point key="canvasLocation" x="376.80000000000001" y="286.50674662668666"/>
</view>
</objects>
<resources>
<image name="back_default.png" width="38.400001525878906" height="35.200000762939453"/>
<image name="back_disabled.png" width="38.400001525878906" height="35.200000762939453"/>
<image name="color_E.png" width="2" height="2"/>
<image name="color_F.png" width="2" height="2"/>
<image name="dialer_back_default.png" width="27" height="27"/>
<image name="dialer_back_disabled.png" width="27" height="27"/>
</resources>
<simulatedMetricsContainer key="defaultSimulatedMetrics">
<simulatedStatusBarMetrics key="statusBar"/>
<simulatedOrientationMetrics key="orientation"/>
<simulatedScreenMetrics key="destination" type="retina4_7.fullscreen"/>
</simulatedMetricsContainer>
</document>

View file

@ -1,8 +1,12 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="9531" systemVersion="15C50" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none">
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" colorMatched="YES">
<device id="retina6_1" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="9529"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14490.49"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="AssistantView">
@ -15,49 +19,35 @@
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="BrP-Xy-m1Y">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<view contentMode="scaleToFill" id="12">
<rect key="frame" x="0.0" y="42" width="375" height="625"/>
<rect key="frame" x="0.0" y="42" width="414" height="854"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view tag="2" contentMode="scaleToFill" id="Vsu-Ew-BxE" userLabel="topBar">
<rect key="frame" x="0.0" y="0.0" width="375" height="66"/>
<rect key="frame" x="0.0" y="0.0" width="414" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<imageView userInteractionEnabled="NO" tag="3" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="color_F.png" id="vhv-dn-tHv" userLabel="backgroundColor">
<rect key="frame" x="0.0" y="0.0" width="375" height="66"/>
<rect key="frame" x="0.0" y="0.0" width="414" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
</imageView>
<button opaque="NO" tag="4" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="TFl-cN-1Vb" userLabel="dialerBackButton" customClass="UIIconButton">
<rect key="frame" x="300" y="0.0" width="75" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Dialer"/>
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
<state key="normal" image="dialer_back_default.png">
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
</state>
<state key="disabled" image="dialer_back_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onDialerClick:" destination="-1" eventType="touchUpInside" id="h0C-4C-ALM"/>
</connections>
</button>
<label opaque="NO" userInteractionEnabled="NO" tag="5" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="ASSISTANT" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="1EG-3g-3uU" userLabel="titleLabel">
<rect key="frame" x="83" y="0.0" width="209" height="66"/>
<rect key="frame" x="92" y="0.0" width="230" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="27"/>
<color key="textColor" red="1" green="0.36862745099999999" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color key="textColor" red="0.98766469955444336" green="0.27512490749359131" blue="0.029739789664745331" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<button opaque="NO" tag="6" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="edC-CG-eZr" userLabel="backButton" customClass="UIIconButton">
<rect key="frame" x="0.0" y="0.0" width="75" height="66"/>
<rect key="frame" x="0.0" y="0.0" width="82" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Back"/>
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
<state key="normal" image="back_default.png">
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="back_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
@ -68,37 +58,34 @@
</subviews>
</view>
<scrollView clipsSubviews="YES" multipleTouchEnabled="YES" tag="7" contentMode="scaleToFill" bounces="NO" id="98" userLabel="contentView" customClass="TPKeyboardAvoidingScrollView">
<rect key="frame" x="0.0" y="66" width="375" height="559"/>
<rect key="frame" x="0.0" y="66" width="414" height="788"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</scrollView>
<view hidden="YES" tag="8" contentMode="scaleToFill" id="91" userLabel="waitView">
<rect key="frame" x="0.0" y="0.0" width="375" height="625"/>
<rect key="frame" x="0.0" y="0.0" width="414" height="854"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<activityIndicatorView opaque="NO" tag="9" contentMode="scaleToFill" animating="YES" style="gray" id="90" userLabel="activityIndicatorView">
<rect key="frame" x="179" y="302" width="20" height="20"/>
<rect key="frame" x="199" y="416" width="20" height="20"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
</activityIndicatorView>
</subviews>
<color key="backgroundColor" white="1" alpha="0.5" colorSpace="calibratedWhite"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="0.5" colorSpace="custom" customColorSpace="sRGB"/>
<gestureRecognizers/>
</view>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
</view>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
<simulatedScreenMetrics key="simulatedDestinationMetrics" type="retina47"/>
<point key="canvasLocation" x="40.5" y="263.5"/>
<color key="backgroundColor" red="1" green="1" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<point key="canvasLocation" x="58.695652173913047" y="176.45089285714286"/>
</view>
</objects>
<resources>
<image name="back_default.png" width="24" height="21"/>
<image name="back_disabled.png" width="24" height="21"/>
<image name="back_default.png" width="38.400001525878906" height="35.200000762939453"/>
<image name="back_disabled.png" width="38.400001525878906" height="35.200000762939453"/>
<image name="color_E.png" width="2" height="2"/>
<image name="color_F.png" width="2" height="2"/>
<image name="dialer_back_default.png" width="27" height="27"/>
<image name="dialer_back_disabled.png" width="27" height="27"/>
</resources>
</document>

View file

@ -1,14 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14113" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14088"/>
<capability name="Alignment constraints to the first baseline" minToolsVersion="6.0"/>
<capability name="Aspect ratio constraints" minToolsVersion="5.1"/>
<capability name="Constraints to layout margins" minToolsVersion="6.0"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14460.20"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
@ -27,6 +24,7 @@
<outlet property="gotoLoginButton" destination="39" id="uSY-cr-j4w"/>
<outlet property="gotoRemoteProvisioningButton" destination="Kbn-dL-C5h" id="zLh-uO-x8P"/>
<outlet property="infoLoginButton" destination="ZDs-1W-ZXo" id="aoP-Mb-gPi"/>
<outlet property="linphoneLoginButton" destination="eIr-bh-JLB" id="mhf-Tc-zyb"/>
<outlet property="linphoneLoginView" destination="52" id="9NX-6W-50g"/>
<outlet property="loginView" destination="56" id="bJH-N8-uPi"/>
<outlet property="phoneLabel" destination="ZSJ-Lv-n60" id="5Qi-xR-wyK"/>
@ -745,7 +743,7 @@ Once it is done, come back here and click on the button.</string>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="USE YOUR LINPHONE ACCOUNT" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="LbS-op-QAh" userLabel="titleLabel">
<rect key="frame" x="36" y="0.0" width="303" height="40"/>
<rect key="frame" x="36" y="0.0" width="302" height="40"/>
<accessibility key="accessibilityConfiguration" label="Account setup assistant"/>
<constraints>
<constraint firstAttribute="height" constant="40" id="iKL-h4-J6A"/>

View file

@ -1,14 +1,19 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="9531" systemVersion="15C50" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none">
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" colorMatched="YES">
<device id="retina4_7" orientation="landscape">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="9529"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14460.20"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="CallIncomingView">
<connections>
<outlet property="addressLabel" destination="78f-eb-xdx" id="Qjw-7G-oqG"/>
<outlet property="avatarImage" destination="19" id="20"/>
<outlet property="earlyMediaView" destination="lUj-2n-Afx" id="cHv-3Y-lIQ"/>
<outlet property="landscapeView" destination="r7T-Et-xrQ" id="rA1-2K-fUf"/>
<outlet property="nameLabel" destination="hjQ-4P-bKP" id="Elh-o8-zM9"/>
<outlet property="portraitView" destination="25" id="6Gy-ZX-kTl"/>
@ -19,58 +24,44 @@
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="6e0-76-KvA" userLabel="iphone6MetricsView">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<rect key="frame" x="0.0" y="0.0" width="667" height="375"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<view tag="1" contentMode="scaleToFill" id="25">
<rect key="frame" x="0.0" y="42" width="375" height="625"/>
<rect key="frame" x="0.0" y="42" width="667" height="333"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView userInteractionEnabled="NO" tag="3" contentMode="scaleAspectFit" image="avatar.png" id="19" userLabel="avatarImage" customClass="UIRoundedImageView">
<rect key="frame" x="87" y="276" width="200" height="200"/>
<rect key="frame" x="155" y="147" width="355" height="107"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Contact avatar">
<accessibilityTraits key="traits" image="YES" notEnabled="YES"/>
<bool key="isElement" value="YES"/>
</accessibility>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" tag="5" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="john.doe@sip.linphone.org" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="8" id="78f-eb-xdx" userLabel="addressLabel">
<rect key="frame" x="0.0" y="209" width="375" height="34"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="18"/>
<color key="textColor" red="1" green="0.36862745099999999" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" tag="4" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="John Doe" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="19" id="hjQ-4P-bKP" userLabel="nameLabel">
<rect key="frame" x="0.0" y="149" width="375" height="52"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="33"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
<button opaque="NO" tag="2" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" id="Cro-ww-VIC" userLabel="headerBar">
<rect key="frame" x="0.0" y="0.0" width="375" height="66"/>
<rect key="frame" x="0.0" y="0.0" width="667" height="66"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration">
<accessibilityTraits key="traits" button="YES" notEnabled="YES"/>
</accessibility>
<fontDescription key="fontDescription" type="boldSystem" pointSize="27"/>
<state key="normal" title="INCOMING CALL" backgroundImage="color_F.png">
<color key="titleColor" red="1" green="0.36862745099999999" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
<color key="titleColor" red="0.98766469955444336" green="0.27512490749359131" blue="0.029739789664745331" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
</button>
<view tag="6" contentMode="scaleToFill" id="4" userLabel="tabBar">
<rect key="frame" x="0.0" y="562" width="375" height="63"/>
<rect key="frame" x="0.0" y="270" width="667" height="63"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<subviews>
<button opaque="NO" tag="7" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="6" userLabel="declineButton">
<rect key="frame" x="0.0" y="0.0" width="188" height="63"/>
<rect key="frame" x="0.0" y="0.0" width="334" height="63"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Decline"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
<state key="normal" image="call_hangup_default.png" backgroundImage="color_D.png">
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="call_hangup_disabled.png"/>
<state key="highlighted" backgroundImage="color_I.png"/>
@ -79,12 +70,12 @@
</connections>
</button>
<button opaque="NO" tag="8" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="7" userLabel="acceptButton">
<rect key="frame" x="187" y="0.0" width="188" height="63"/>
<rect key="frame" x="333" y="0.0" width="334" height="63"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Accept"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
<state key="normal" image="call_audio_start_default.png" backgroundImage="color_A.png">
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="call_audio_start_disabled.png"/>
<state key="highlighted" backgroundImage="color_L.png"/>
@ -93,19 +84,19 @@
</connections>
</button>
</subviews>
<color key="backgroundColor" red="1" green="0.36862745099999999" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color key="backgroundColor" red="0.98766469955444336" green="0.27512490749359131" blue="0.029739789664745331" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</view>
<view hidden="YES" tag="9" contentMode="scaleToFill" id="vIQ-QP-ooa" userLabel="tabVideoBar">
<rect key="frame" x="0.0" y="562" width="375" height="63"/>
<rect key="frame" x="0.0" y="270" width="667" height="63"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<subviews>
<button opaque="NO" tag="10" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="KnH-hj-g47" userLabel="declineButton">
<rect key="frame" x="0.0" y="0.0" width="125" height="63"/>
<rect key="frame" x="0.0" y="0.0" width="222" height="63"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Decline"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
<state key="normal" image="call_hangup_default.png" backgroundImage="color_D.png">
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="call_hangup_disabled.png"/>
<state key="highlighted" backgroundImage="color_I.png"/>
@ -114,12 +105,12 @@
</connections>
</button>
<button opaque="NO" tag="11" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="wYo-ty-Rwk" userLabel="acceptAudioOnlyButton">
<rect key="frame" x="125" y="0.0" width="125" height="63"/>
<rect key="frame" x="222" y="0.0" width="223" height="63"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Accept"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
<state key="normal" image="call_audio_start_default.png" backgroundImage="color_A.png">
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="call_audio_start_disabled.png"/>
<state key="highlighted" backgroundImage="color_L.png"/>
@ -128,12 +119,12 @@
</connections>
</button>
<button opaque="NO" tag="12" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="tX0-eE-di5" userLabel="acceptButton">
<rect key="frame" x="250" y="0.0" width="125" height="63"/>
<rect key="frame" x="445" y="0.0" width="222" height="63"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Accept"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
<state key="normal" image="call_video_start_default.png" backgroundImage="color_A.png">
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="call_video_start_disabled.png"/>
<state key="selected" image="call_video_start_disabled.png"/>
@ -143,15 +134,33 @@
</connections>
</button>
</subviews>
<color key="backgroundColor" red="1" green="0.36862745099999999" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color key="backgroundColor" red="0.98766469955444336" green="0.27512490749359131" blue="0.029739789664745331" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</view>
<view hidden="YES" contentMode="scaleToFill" id="lUj-2n-Afx" userLabel="earlyMediaView">
<rect key="frame" x="0.0" y="35" width="667" height="265"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</view>
<label opaque="NO" userInteractionEnabled="NO" tag="5" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="john.doe@sip.linphone.org" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="8" id="78f-eb-xdx" userLabel="addressLabel">
<rect key="frame" x="0.0" y="111" width="667" height="18"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="18"/>
<color key="textColor" red="0.98766469955444336" green="0.27512490749359131" blue="0.029739789664745331" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" tag="4" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="John Doe" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="19" id="hjQ-4P-bKP" userLabel="nameLabel">
<rect key="frame" x="0.0" y="79" width="667" height="28"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="33"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</view>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
<simulatedScreenMetrics key="simulatedDestinationMetrics" type="retina47"/>
<point key="canvasLocation" x="-88.5" y="47.5"/>
<color key="backgroundColor" red="1" green="1" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<point key="canvasLocation" x="-141.59999999999999" y="42.728635682158924"/>
</view>
<view contentMode="scaleToFill" id="Znq-C0-ZAc" userLabel="iphone6MetricsView">
<rect key="frame" x="0.0" y="0.0" width="667" height="375"/>
@ -169,24 +178,10 @@
</accessibility>
<fontDescription key="fontDescription" type="boldSystem" pointSize="27"/>
<state key="normal" title="INCOMING CALL" backgroundImage="color_F.png">
<color key="titleColor" red="1" green="0.36862745099999999" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
<color key="titleColor" red="0.98766469955444336" green="0.27512490749359131" blue="0.029739789664745331" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
</button>
<label opaque="NO" userInteractionEnabled="NO" tag="5" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="john.doe@sip.linphone.org" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="8" id="tsb-6p-cAk" userLabel="addressLabel">
<rect key="frame" x="298" y="166" width="369" height="33"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="18"/>
<color key="textColor" red="1" green="0.36862745099999999" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" tag="4" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="John Doe" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="19" id="WsB-At-ejv" userLabel="nameLabel">
<rect key="frame" x="298" y="121" width="369" height="37"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="33"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
<view tag="6" contentMode="scaleToFill" id="0Tc-7G-eqT" userLabel="tabBar">
<rect key="frame" x="0.0" y="270" width="667" height="63"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
@ -197,7 +192,7 @@
<accessibility key="accessibilityConfiguration" label="Decline"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
<state key="normal" image="call_hangup_default.png" backgroundImage="color_D.png">
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="call_hangup_disabled.png"/>
<state key="highlighted" backgroundImage="color_I.png"/>
@ -211,7 +206,7 @@
<accessibility key="accessibilityConfiguration" label="Accept"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
<state key="normal" image="call_audio_start_default.png" backgroundImage="color_A.png">
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="call_audio_start_disabled.png"/>
<state key="highlighted" backgroundImage="color_L.png"/>
@ -220,19 +215,19 @@
</connections>
</button>
</subviews>
<color key="backgroundColor" red="1" green="0.36862745099999999" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color key="backgroundColor" red="0.98766469955444336" green="0.27512490749359131" blue="0.029739789664745331" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</view>
<view hidden="YES" tag="9" contentMode="scaleToFill" id="PPE-Fd-wDf" userLabel="tabVideoBar">
<rect key="frame" x="0.0" y="270" width="667" height="63"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<subviews>
<button opaque="NO" tag="10" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="i8b-dr-IYG" userLabel="declineButton">
<rect key="frame" x="0.0" y="0.0" width="222" height="63"/>
<rect key="frame" x="0.0" y="0.0" width="221" height="63"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Decline"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
<state key="normal" image="call_hangup_default.png" backgroundImage="color_D.png">
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="call_hangup_disabled.png"/>
<state key="highlighted" backgroundImage="color_I.png"/>
@ -241,12 +236,12 @@
</connections>
</button>
<button opaque="NO" tag="11" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="QYg-9G-We0" userLabel="acceptAudioOnlyButton">
<rect key="frame" x="222" y="0.0" width="223" height="63"/>
<rect key="frame" x="221" y="0.0" width="224" height="63"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Accept"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
<state key="normal" image="call_audio_start_default.png" backgroundImage="color_A.png">
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="call_audio_start_disabled.png"/>
<state key="highlighted" backgroundImage="color_L.png"/>
@ -260,7 +255,7 @@
<accessibility key="accessibilityConfiguration" label="Accept"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
<state key="normal" image="call_video_start_default.png" backgroundImage="color_A.png">
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="call_video_start_disabled.png"/>
<state key="selected" image="call_video_start_disabled.png"/>
@ -270,7 +265,7 @@
</connections>
</button>
</subviews>
<color key="backgroundColor" red="1" green="0.36862745099999999" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color key="backgroundColor" red="0.98766469955444336" green="0.27512490749359131" blue="0.029739789664745331" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</view>
<imageView userInteractionEnabled="NO" tag="3" contentMode="scaleAspectFit" image="avatar.png" id="Q0C-CO-AYR" userLabel="avatarImage" customClass="UIRoundedImageView">
<rect key="frame" x="110" y="74" width="180" height="180"/>
@ -280,24 +275,41 @@
<bool key="isElement" value="YES"/>
</accessibility>
</imageView>
<view hidden="YES" contentMode="scaleToFill" id="F11-a0-ZL6" userLabel="earlyMediaView">
<rect key="frame" x="45" y="73" width="250" height="187"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</view>
<label opaque="NO" userInteractionEnabled="NO" tag="5" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="john.doe@sip.linphone.org" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="8" id="tsb-6p-cAk" userLabel="addressLabel">
<rect key="frame" x="297" y="166" width="370" height="33"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="18"/>
<color key="textColor" red="0.98766469955444336" green="0.27512490749359131" blue="0.029739789664745331" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" tag="4" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="John Doe" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="19" id="WsB-At-ejv" userLabel="nameLabel">
<rect key="frame" x="297" y="121" width="370" height="37"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="33"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</view>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
<simulatedOrientationMetrics key="simulatedOrientationMetrics" orientation="landscapeRight"/>
<simulatedScreenMetrics key="simulatedDestinationMetrics" type="retina47"/>
<point key="canvasLocation" x="476.5" y="-98.5"/>
<color key="backgroundColor" red="1" green="1" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<point key="canvasLocation" x="762.39999999999998" y="-88.605697151424295"/>
</view>
</objects>
<resources>
<image name="avatar.png" width="1271" height="1271"/>
<image name="avatar.png" width="259" height="259"/>
<image name="call_audio_start_default.png" width="36" height="36"/>
<image name="call_audio_start_disabled.png" width="36" height="36"/>
<image name="call_hangup_default.png" width="41" height="36"/>
<image name="call_hangup_disabled.png" width="41" height="36"/>
<image name="call_video_start_default.png" width="39" height="36"/>
<image name="call_video_start_disabled.png" width="39" height="36"/>
<image name="call_hangup_default.png" width="42" height="36"/>
<image name="call_hangup_disabled.png" width="42" height="36"/>
<image name="call_video_start_default.png" width="40" height="36"/>
<image name="call_video_start_disabled.png" width="40" height="36"/>
<image name="color_A.png" width="2" height="2"/>
<image name="color_D.png" width="2" height="2"/>
<image name="color_F.png" width="2" height="2"/>

Binary file not shown.

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14109" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" colorMatched="YES">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14088"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14460.20"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
@ -13,16 +13,25 @@
<connections>
<outlet property="allButton" destination="r3z-SM-lMq" id="DUC-gQ-gKu"/>
<outlet property="backButton" destination="fNt-yb-wsf" id="3Xj-Dv-LmO"/>
<outlet property="chiffreButton" destination="uUN-bl-g4c" id="w8f-8e-vBx"/>
<outlet property="chiffreImage" destination="jIQ-qM-GVG" id="mSL-Kf-21s"/>
<outlet property="chiffreOptionView" destination="9gK-1a-7Hl" id="gXA-hF-uGd"/>
<outlet property="collectionView" destination="KRQ-Fm-3cQ" id="otM-cN-lEg"/>
<outlet property="linphoneButton" destination="8lQ-fv-INK" id="zaP-UT-K4y"/>
<outlet property="nextButton" destination="rBc-dQ-eIj" id="QHB-Xp-PTA"/>
<outlet property="selectedButtonImage" destination="ibu-Ra-oZO" id="jvl-ay-cfh"/>
<outlet property="switchView" destination="d5Q-XR-FNz" id="Xeo-ZG-6cr"/>
<outlet property="tableController" destination="4" id="18"/>
<outlet property="view" destination="5" id="14"/>
<outlet property="waitView" destination="Ztm-hK-aBp" id="qYh-M5-heN"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<tapGestureRecognizer id="jFh-hw-yg2" userLabel="chiffreClick">
<connections>
<action selector="onChiffreClick:" destination="-1" id="Hz6-Ey-gAh"/>
</connections>
</tapGestureRecognizer>
<view contentMode="scaleToFill" id="WKv-mw-S2B" userLabel="iphone6MetricsView">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
@ -40,7 +49,7 @@
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
</imageView>
<view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="d5Q-XR-FNz" userLabel="switchView">
<rect key="frame" x="112" y="0.0" width="150" height="66"/>
<rect key="frame" x="225" y="0.0" width="150" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="r3z-SM-lMq" userLabel="allButton" customClass="UIIconButton">
@ -102,6 +111,45 @@
<action selector="onBackClick:" destination="-1" eventType="touchUpInside" id="463-Qr-hJG"/>
</connections>
</button>
<view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="9gK-1a-7Hl" userLabel="chiffreOptionView">
<rect key="frame" x="72" y="0.0" width="150" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" enabled="NO" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="4Be-pr-fmB">
<rect key="frame" x="0.0" y="0.0" width="75" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<state key="normal" image="security_toogle_icon_grey.png"/>
<state key="disabled" image="security_toogle_icon_grey.png"/>
</button>
<view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="dH1-Al-sJ7">
<rect key="frame" x="56" y="24" width="36" height="18"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="security_toogle_background_grey.png" translatesAutoresizingMaskIntoConstraints="NO" id="jIQ-qM-GVG" userLabel="chiffreImage">
<rect key="frame" x="0.0" y="0.0" width="36" height="18"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
</imageView>
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="uUN-bl-g4c" userLabel="chiffreButton">
<rect key="frame" x="0.0" y="2" width="14" height="14"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<state key="normal" image="security_toogle_button.png"/>
<connections>
<action selector="onChiffreClick:" destination="-1" eventType="touchUpInside" id="ZyW-ow-b4Y"/>
</connections>
</button>
</subviews>
<connections>
<outletCollection property="gestureRecognizers" destination="jFh-hw-yg2" appends="YES" id="kX3-iI-ZpX"/>
</connections>
</view>
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" enabled="NO" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="9Py-cO-YGv">
<rect key="frame" x="76" y="0.0" width="75" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<state key="normal" image="security_toogle_icon_green.png"/>
<state key="disabled" image="security_toogle_icon_green.png"/>
</button>
</subviews>
</view>
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="rBc-dQ-eIj" userLabel="nextButton" customClass="UIIconButton">
<rect key="frame" x="300" y="0.0" width="75" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
@ -162,7 +210,7 @@
</view>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<point key="canvasLocation" x="33.5" y="89.5"/>
<point key="canvasLocation" x="53.600000000000001" y="80.50974512743629"/>
</view>
<tableViewController autoresizesArchivedViewToFullSize="NO" id="4" userLabel="Suggested addresses" customClass="ChatConversationCreateTableView">
<extendedEdge key="edgesForExtendedLayout"/>
@ -172,7 +220,7 @@
<outlet property="view" destination="6" id="13"/>
<outlet property="waitView" destination="Ztm-hK-aBp" id="uSB-4b-n7e"/>
</connections>
<point key="canvasLocation" x="463" y="90"/>
<point key="canvasLocation" x="740.79999999999995" y="80.959520239880064"/>
</tableViewController>
</objects>
<resources>
@ -189,5 +237,9 @@
<image name="contacts_sip_selected.png" width="39" height="39"/>
<image name="next_default.png" width="24" height="22"/>
<image name="next_disabled.png" width="24" height="22"/>
<image name="security_toogle_background_grey.png" width="52" height="27"/>
<image name="security_toogle_button.png" width="21" height="21"/>
<image name="security_toogle_icon_green.png" width="21" height="24"/>
<image name="security_toogle_icon_grey.png" width="21" height="24"/>
</resources>
</document>

View file

@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14113" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" colorMatched="YES">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" colorMatched="YES">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14088"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14490.49"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
@ -18,6 +18,7 @@
<outlet property="chatView" destination="49" id="Rxt-Zy-19x"/>
<outlet property="composeIndicatorView" destination="fx4-ao-53M" id="xk5-nK-lur"/>
<outlet property="composeLabel" destination="fpY-Fv-ht2" id="4L6-ik-ZAe"/>
<outlet property="encryptedButton" destination="tjL-Vc-5gN" id="zxw-Fs-ofB"/>
<outlet property="imagesCollectionView" destination="JGQ-p2-HCX" id="6dt-1f-jpa"/>
<outlet property="imagesView" destination="3qd-ys-t2L" id="f9L-FU-PMI"/>
<outlet property="infoButton" destination="Vqb-Un-4xv" id="pa1-Iz-5QQ"/>
@ -82,9 +83,9 @@
<action selector="onEditionChangeClick:" destination="-1" eventType="touchUpInside" id="c6C-ow-Yhi"/>
</connections>
</button>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" tag="5" contentMode="left" misplaced="YES" text="Contact1" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" id="40" userLabel="addressLabel">
<rect key="frame" x="75" y="0.0" width="142" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" tag="5" contentMode="left" text="Contact1" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="40" userLabel="addressLabel">
<rect key="frame" x="75" y="0.0" width="142" height="44"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Contact name">
<accessibilityTraits key="traits" none="YES"/>
</accessibility>
@ -136,10 +137,10 @@
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Edit"/>
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
<state key="normal" image="edit_list_default.png">
<state key="normal" image="delete_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="edit_list_disabled.png"/>
<state key="disabled" image="delete_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onEditClick:" destination="29" eventType="touchUpInside" id="2Q7-xM-Shx"/>
@ -162,7 +163,7 @@
<action selector="onSelectionToggle:" destination="29" eventType="touchUpInside" id="eP5-bU-LEA"/>
</connections>
</button>
<button hidden="YES" opaque="NO" tag="10" contentMode="scaleToFill" misplaced="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" reversesTitleShadowWhenHighlighted="YES" showsTouchWhenHighlighted="YES" lineBreakMode="middleTruncation" id="Vqb-Un-4xv" userLabel="infoButton" customClass="UIIconButton">
<button hidden="YES" opaque="NO" tag="10" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" reversesTitleShadowWhenHighlighted="YES" showsTouchWhenHighlighted="YES" lineBreakMode="middleTruncation" id="Vqb-Un-4xv" userLabel="infoButton" customClass="UIIconButton">
<rect key="frame" x="225" y="0.0" width="75" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Select all"/>
@ -178,13 +179,13 @@
<action selector="onInfoClick:" destination="-1" eventType="touchUpInside" id="VfD-K7-V15"/>
</connections>
</button>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" tag="5" contentMode="left" misplaced="YES" text="addresses" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" id="Ncq-Zc-X6j" userLabel="participantsLabel">
<rect key="frame" x="75" y="41" width="142" height="25"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" tag="5" contentMode="left" text="addresses" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="Ncq-Zc-X6j" userLabel="participantsLabel">
<rect key="frame" x="75" y="36" width="142" height="25"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES"/>
<accessibility key="accessibilityConfiguration" label="Contact name">
<accessibilityTraits key="traits" none="YES"/>
</accessibility>
<fontDescription key="fontDescription" type="system" pointSize="15"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<color key="textColor" red="0.33333333329999998" green="0.33333333329999998" blue="0.33333333329999998" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
@ -271,15 +272,15 @@
</view>
</subviews>
</view>
<view clipsSubviews="YES" contentMode="scaleToFill" misplaced="YES" id="3qd-ys-t2L" userLabel="imagesView">
<view clipsSubviews="YES" contentMode="scaleToFill" id="3qd-ys-t2L" userLabel="imagesView">
<rect key="frame" x="0.0" y="427" width="375" height="0.0"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<subviews>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" image="color_F.png" id="B6X-D7-Bak" userLabel="backgroundColor">
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="color_F.png" id="B6X-D7-Bak" userLabel="backgroundColor">
<rect key="frame" x="2" y="1" width="375" height="0.0"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
</imageView>
<collectionView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" misplaced="YES" showsVerticalScrollIndicator="NO" dataMode="none" id="JGQ-p2-HCX" userLabel="imagesCollectionView">
<collectionView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" showsVerticalScrollIndicator="NO" dataMode="none" id="JGQ-p2-HCX" userLabel="imagesCollectionView">
<rect key="frame" x="2" y="0.0" width="374" height="0.0"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" red="0.98780487804878048" green="1" blue="1" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
@ -293,6 +294,14 @@
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</view>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="tjL-Vc-5gN" userLabel="encryptedButton">
<rect key="frame" x="320" y="10" width="34" height="40"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
<state key="normal" image="security_1_indicator.png"/>
<connections>
<action selector="onEncryptedDevicesClick:" destination="-1" eventType="touchUpInside" id="K1W-Ao-IDg"/>
</connections>
</button>
</subviews>
</view>
</subviews>
@ -301,7 +310,7 @@
</view>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<point key="canvasLocation" x="228.5" y="-40.5"/>
<point key="canvasLocation" x="365.60000000000002" y="-36.431784107946029"/>
</view>
<view contentMode="scaleToFill" id="680-UL-sil" userLabel="iphone6MetricsView">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
@ -349,7 +358,7 @@
<action selector="onEditionChangeClick:" destination="-1" eventType="touchUpInside" id="hGj-xz-K5n"/>
</connections>
</button>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" tag="5" contentMode="left" misplaced="YES" text="Contact1" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" id="uEp-mD-eik" userLabel="addressLabel">
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" tag="5" contentMode="left" text="Contact1" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" id="uEp-mD-eik" userLabel="addressLabel">
<rect key="frame" x="67" y="1" width="366" height="57"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Contact name">
@ -378,17 +387,17 @@
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Edit"/>
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
<state key="normal" image="edit_list_default.png">
<state key="normal" image="delete_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="edit_list_disabled.png"/>
<state key="disabled" image="delete_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onEditClick:" destination="29" eventType="touchUpInside" id="4ei-sX-oIk"/>
<action selector="onEditionChangeClick:" destination="-1" eventType="touchUpInside" id="fNp-ya-dag"/>
</connections>
</button>
<button hidden="YES" opaque="NO" tag="10" contentMode="scaleToFill" misplaced="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" reversesTitleShadowWhenHighlighted="YES" showsTouchWhenHighlighted="YES" lineBreakMode="middleTruncation" id="uVy-PC-gn9" userLabel="infoButton" customClass="UIIconButton">
<button hidden="YES" opaque="NO" tag="10" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" reversesTitleShadowWhenHighlighted="YES" showsTouchWhenHighlighted="YES" lineBreakMode="middleTruncation" id="uVy-PC-gn9" userLabel="infoButton" customClass="UIIconButton">
<rect key="frame" x="218" y="0.0" width="33" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Select all"/>
@ -444,7 +453,7 @@
<action selector="onSelectionToggle:" destination="29" eventType="touchUpInside" id="17V-y4-JHi"/>
</connections>
</button>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" tag="5" contentMode="left" misplaced="YES" text="addresses" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" id="tyU-Wy-rLs" userLabel="participantsLabel">
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" tag="5" contentMode="left" text="addresses" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" id="tyU-Wy-rLs" userLabel="participantsLabel">
<rect key="frame" x="67" y="37" width="366" height="25"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<accessibility key="accessibilityConfiguration" label="Contact name">
@ -543,7 +552,7 @@
</view>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<point key="canvasLocation" x="-546.5" y="-152.5"/>
<point key="canvasLocation" x="-874.39999999999998" y="-137.18140929535232"/>
</view>
<tableViewController autoresizesArchivedViewToFullSize="NO" id="29" userLabel="messagesTableView" customClass="ChatConversationTableView">
<extendedEdge key="edgesForExtendedLayout"/>
@ -555,7 +564,7 @@
<outlet property="toggleSelectionButton" destination="c9z-aq-2UP" id="a2J-JQ-rhX"/>
<outlet property="view" destination="8" id="g4m-ne-lbP"/>
</connections>
<point key="canvasLocation" x="639" y="328"/>
<point key="canvasLocation" x="1022.4" y="295.05247376311848"/>
</tableViewController>
<swipeGestureRecognizer direction="left" id="dzw-n4-l9i">
<connections>
@ -569,29 +578,28 @@
</tapGestureRecognizer>
</objects>
<resources>
<image name="back_default.png" width="24" height="22"/>
<image name="back_disabled.png" width="24" height="22"/>
<image name="call_alt_start_default.png" width="29" height="29"/>
<image name="call_alt_start_disabled.png" width="29" height="29"/>
<image name="call_back_default.png" width="38" height="27"/>
<image name="call_back_disabled.png" width="38" height="27"/>
<image name="cancel_edit_default.png" width="29" height="29"/>
<image name="cancel_edit_disabled.png" width="29" height="29"/>
<image name="chat_attachment_default.png" width="41" height="41"/>
<image name="chat_attachment_disabled.png" width="41" height="41"/>
<image name="chat_attachment_over.png" width="41" height="41"/>
<image name="back_default.png" width="38.400001525878906" height="35.200000762939453"/>
<image name="back_disabled.png" width="38.400001525878906" height="35.200000762939453"/>
<image name="call_alt_start_default.png" width="47.200000762939453" height="47.200000762939453"/>
<image name="call_alt_start_disabled.png" width="47.200000762939453" height="47.200000762939453"/>
<image name="call_back_default.png" width="61.599998474121094" height="44"/>
<image name="call_back_disabled.png" width="61.599998474121094" height="44"/>
<image name="cancel_edit_default.png" width="47.200000762939453" height="47.200000762939453"/>
<image name="cancel_edit_disabled.png" width="47.200000762939453" height="47.200000762939453"/>
<image name="chat_attachment_default.png" width="65.599998474121094" height="65.599998474121094"/>
<image name="chat_attachment_disabled.png" width="65.599998474121094" height="65.599998474121094"/>
<image name="chat_attachment_over.png" width="65.599998474121094" height="65.599998474121094"/>
<image name="chat_group_informations.png" width="38" height="38"/>
<image name="chat_send_default.png" width="41" height="41"/>
<image name="chat_send_disabled.png" width="41" height="41"/>
<image name="chat_send_over.png" width="41" height="41"/>
<image name="chat_send_default.png" width="65.599998474121094" height="65.599998474121094"/>
<image name="chat_send_disabled.png" width="65.599998474121094" height="65.599998474121094"/>
<image name="chat_send_over.png" width="65.599998474121094" height="65.599998474121094"/>
<image name="color_E.png" width="2" height="2"/>
<image name="color_F.png" width="2" height="2"/>
<image name="delete_default.png" width="21" height="28"/>
<image name="delete_disabled.png" width="21" height="28"/>
<image name="deselect_all.png" width="27" height="27"/>
<image name="edit_list_default.png" width="30" height="28"/>
<image name="edit_list_disabled.png" width="30" height="28"/>
<image name="select_all_default.png" width="27" height="27"/>
<image name="select_all_disabled.png" width="27" height="27"/>
<image name="delete_default.png" width="34.400001525878906" height="44.799999237060547"/>
<image name="delete_disabled.png" width="34.400001525878906" height="44.799999237060547"/>
<image name="deselect_all.png" width="43.200000762939453" height="43.200000762939453"/>
<image name="security_1_indicator.png" width="27.5" height="32.5"/>
<image name="select_all_default.png" width="43.200000762939453" height="43.200000762939453"/>
<image name="select_all_disabled.png" width="43.200000762939453" height="43.200000762939453"/>
</resources>
</document>

View file

@ -1,17 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="13771" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" colorMatched="YES">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" colorMatched="YES">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13772"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14490.49"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="ChatsListView">
<connections>
<outlet property="addButton" destination="Z5G-IF-PBY" id="Tzw-rz-Bwe"/>
<outlet property="addGroupChatButton" destination="glf-ni-nqe" id="0hy-5m-7C7"/>
<outlet property="backToCallButton" destination="Fac-hy-za4" id="8I3-TM-oJ7"/>
<outlet property="tableController" destination="4" id="18"/>
<outlet property="view" destination="5" id="14"/>
@ -44,12 +45,27 @@
<state key="normal" image="chat_add_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="chat_add_disabled.png"/>
<state key="disabled" image="chat_add_default.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onAddClick:" destination="-1" eventType="touchUpInside" id="g4q-By-6nW"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" lineBreakMode="middleTruncation" id="glf-ni-nqe" userLabel="addGroupButton">
<rect key="frame" x="75" y="0.0" width="75" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="New discussion"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
<state key="normal" image="chat_add_group.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="chat_add_group.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onAddGroupChatClick:" destination="-1" eventType="touchUpInside" id="tem-mm-w62"/>
</connections>
</button>
<button hidden="YES" opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="KhE-c3-2Zj" userLabel="cancelButton" customClass="UIIconButton">
<rect key="frame" x="0.0" y="0.0" width="75" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
@ -66,7 +82,7 @@
</connections>
</button>
<button hidden="YES" opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="Fac-hy-za4" userLabel="backToCallButton" customClass="UIBackToCallButton">
<rect key="frame" x="75" y="0.0" width="75" height="66"/>
<rect key="frame" x="150" y="0.0" width="75" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<state key="normal" image="call_back_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
@ -113,10 +129,10 @@
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Edit"/>
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
<state key="normal" image="edit_list_default.png">
<state key="normal" image="delete_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="edit_list_disabled.png"/>
<state key="disabled" image="delete_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onEditClick:" destination="4" eventType="touchUpInside" id="COv-sY-0TU"/>
@ -145,7 +161,7 @@
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<view hidden="YES" tag="8" contentMode="scaleToFill" misplaced="YES" id="cpj-Jc-imm" userLabel="waitView">
<view hidden="YES" tag="8" contentMode="scaleToFill" id="cpj-Jc-imm" userLabel="waitView">
<rect key="frame" x="0.0" y="0.0" width="375" height="559"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
@ -161,7 +177,7 @@
</view>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<point key="canvasLocation" x="32.5" y="103.5"/>
<point key="canvasLocation" x="52" y="93.103448275862078"/>
</view>
<tableViewController autoresizesArchivedViewToFullSize="NO" id="4" userLabel="tableController" customClass="ChatsListTableView">
<extendedEdge key="edgesForExtendedLayout"/>
@ -177,20 +193,18 @@
</tableViewController>
</objects>
<resources>
<image name="call_back_default.png" width="38" height="27"/>
<image name="call_back_disabled.png" width="38" height="27"/>
<image name="cancel_edit_default.png" width="29" height="29"/>
<image name="cancel_edit_disabled.png" width="29" height="29"/>
<image name="chat_add_default.png" width="33" height="29"/>
<image name="chat_add_disabled.png" width="33" height="29"/>
<image name="call_back_default.png" width="61.599998474121094" height="44"/>
<image name="call_back_disabled.png" width="61.599998474121094" height="44"/>
<image name="cancel_edit_default.png" width="47.200000762939453" height="47.200000762939453"/>
<image name="cancel_edit_disabled.png" width="47.200000762939453" height="47.200000762939453"/>
<image name="chat_add_default.png" width="50.400001525878906" height="44.799999237060547"/>
<image name="chat_add_group.png" width="64" height="42.400001525878906"/>
<image name="color_E.png" width="2" height="2"/>
<image name="color_F.png" width="2" height="2"/>
<image name="delete_default.png" width="21" height="28"/>
<image name="delete_disabled.png" width="21" height="28"/>
<image name="deselect_all.png" width="27" height="27"/>
<image name="edit_list_default.png" width="30" height="28"/>
<image name="edit_list_disabled.png" width="30" height="28"/>
<image name="select_all_default.png" width="27" height="27"/>
<image name="select_all_disabled.png" width="27" height="27"/>
<image name="delete_default.png" width="34.400001525878906" height="44.799999237060547"/>
<image name="delete_disabled.png" width="34.400001525878906" height="44.799999237060547"/>
<image name="deselect_all.png" width="43.200000762939453" height="43.200000762939453"/>
<image name="select_all_default.png" width="43.200000762939453" height="43.200000762939453"/>
<image name="select_all_disabled.png" width="43.200000762939453" height="43.200000762939453"/>
</resources>
</document>

View file

@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="11198.2" systemVersion="15G31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" colorMatched="NO">
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" colorMatched="YES">
<dependencies>
<deployment identifier="iOS"/>
<development version="7000" identifier="xcode"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11161"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14490.49"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="ContactsListView">
@ -47,12 +47,12 @@
<inset key="titleEdgeInsets" minX="-38" minY="15" maxX="0.0" maxY="0.0"/>
<inset key="imageEdgeInsets" minX="16" minY="0.0" maxX="0.0" maxY="0.0"/>
<state key="normal" image="contacts_all_default.png">
<color key="titleColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="calibratedRGB"/>
<color key="titleColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="contacts_all_disabled.png"/>
<state key="selected" image="contacts_all_selected.png">
<color key="titleColor" red="0.98766469955444336" green="0.27512490749359131" blue="0.029739789664745331" alpha="1" colorSpace="calibratedRGB"/>
<color key="titleColor" red="0.98766469955444336" green="0.27512490749359131" blue="0.029739789664745331" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
@ -69,12 +69,12 @@
<accessibility key="accessibilityConfiguration" label="Linphone contacts filter"/>
<fontDescription key="fontDescription" type="system" pointSize="9"/>
<state key="normal" image="contacts_sip_default.png">
<color key="titleColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="calibratedRGB"/>
<color key="titleColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="contacts_sip_disabled.png"/>
<state key="selected" image="contacts_sip_selected.png">
<color key="titleColor" red="0.98766469955444336" green="0.27512490749359131" blue="0.029739789664745331" alpha="1" colorSpace="calibratedRGB"/>
<color key="titleColor" red="0.98766469955444336" green="0.27512490749359131" blue="0.029739789664745331" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
@ -88,7 +88,7 @@
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Delete all"/>
<state key="normal" image="cancel_edit_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="calibratedRGB"/>
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="cancel_edit_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
@ -103,7 +103,7 @@
<accessibility key="accessibilityConfiguration" label="Delete all"/>
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
<state key="normal" image="delete_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="calibratedRGB"/>
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="delete_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
@ -116,10 +116,10 @@
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Edit"/>
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
<state key="normal" image="edit_list_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="calibratedRGB"/>
<state key="normal" image="delete_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="edit_list_disabled.png"/>
<state key="disabled" image="delete_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onEditClick:" destination="TJG-JZ-YRR" eventType="touchUpInside" id="CKU-6b-3F2"/>
@ -133,7 +133,7 @@
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
<state key="normal" image="deselect_all.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="calibratedRGB"/>
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="select_all_disabled.png"/>
<state key="selected" image="select_all_default.png"/>
@ -148,7 +148,7 @@
<accessibility key="accessibilityConfiguration" label="Add contact"/>
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
<state key="normal" image="contact_add_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="calibratedRGB"/>
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="contact_add_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
@ -169,10 +169,10 @@
<tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" style="plain" separatorStyle="default" allowsSelectionDuringEditing="YES" allowsMultipleSelectionDuringEditing="YES" rowHeight="44" sectionHeaderHeight="22" sectionFooterHeight="22" id="zOo-FS-W6l" userLabel="tableView">
<rect key="frame" x="0.0" y="110" width="375" height="449"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<inset key="contentInset" minX="0.0" minY="0.0" maxX="0.0" maxY="10"/>
<inset key="scrollIndicatorInsets" minX="0.0" minY="0.0" maxX="0.0" maxY="10"/>
<color key="separatorColor" red="0.67030966281890869" green="0.71867996454238892" blue="0.75078284740447998" alpha="1" colorSpace="calibratedRGB"/>
<color key="separatorColor" red="0.67030966281890869" green="0.71867996454238892" blue="0.75078284740447998" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<connections>
<outlet property="dataSource" destination="TJG-JZ-YRR" id="334-RR-jEi"/>
<outlet property="delegate" destination="TJG-JZ-YRR" id="V1N-gI-U4J"/>
@ -181,16 +181,16 @@
<label hidden="YES" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="No contact found in your address book" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="3" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="JR3-k7-gVP" userLabel="emptyTableLabel">
<rect key="frame" x="0.0" y="110" width="375" height="449"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</view>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
<point key="canvasLocation" x="4.5" y="212.5"/>
<color key="backgroundColor" red="1" green="1" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<point key="canvasLocation" x="6.5217391304347831" y="142.29910714285714"/>
</view>
<tableViewController id="TJG-JZ-YRR" userLabel="tableController" customClass="ContactsListTableView">
<connections>
@ -201,34 +201,27 @@
<outlet property="toggleSelectionButton" destination="5lZ-u7-Yex" id="C99-nu-2wJ"/>
<outlet property="view" destination="zOo-FS-W6l" id="cM7-Da-i7e"/>
</connections>
<point key="canvasLocation" x="510" y="206"/>
<point key="canvasLocation" x="739.13043478260875" y="137.94642857142856"/>
</tableViewController>
</objects>
<resources>
<image name="cancel_edit_default.png" width="29" height="29"/>
<image name="cancel_edit_disabled.png" width="29" height="29"/>
<image name="cancel_edit_default.png" width="23.200000762939453" height="23.200000762939453"/>
<image name="cancel_edit_disabled.png" width="23.200000762939453" height="23.200000762939453"/>
<image name="color_A.png" width="2" height="2"/>
<image name="color_E.png" width="2" height="2"/>
<image name="color_F.png" width="2" height="2"/>
<image name="contact_add_default.png" width="34" height="29"/>
<image name="contact_add_disabled.png" width="34" height="29"/>
<image name="contacts_all_default.png" width="32" height="27"/>
<image name="contacts_all_disabled.png" width="32" height="27"/>
<image name="contacts_all_selected.png" width="32" height="27"/>
<image name="contacts_sip_default.png" width="38" height="30"/>
<image name="contact_add_default.png" width="27.200000762939453" height="23.200000762939453"/>
<image name="contact_add_disabled.png" width="27.200000762939453" height="23.200000762939453"/>
<image name="contacts_all_default.png" width="25.600000381469727" height="21.600000381469727"/>
<image name="contacts_all_disabled.png" width="25.600000381469727" height="21.600000381469727"/>
<image name="contacts_all_selected.png" width="25.600000381469727" height="21.600000381469727"/>
<image name="contacts_sip_default.png" width="38" height="38"/>
<image name="contacts_sip_disabled.png" width="38" height="30"/>
<image name="contacts_sip_selected.png" width="38" height="30"/>
<image name="delete_default.png" width="21" height="28"/>
<image name="delete_disabled.png" width="21" height="28"/>
<image name="deselect_all.png" width="27" height="27"/>
<image name="edit_list_default.png" width="30" height="28"/>
<image name="edit_list_disabled.png" width="30" height="28"/>
<image name="select_all_default.png" width="27" height="27"/>
<image name="select_all_disabled.png" width="27" height="27"/>
<image name="contacts_sip_selected.png" width="38" height="38"/>
<image name="delete_default.png" width="16.799999237060547" height="21.600000381469727"/>
<image name="delete_disabled.png" width="16.799999237060547" height="21.600000381469727"/>
<image name="deselect_all.png" width="20.799999237060547" height="20.799999237060547"/>
<image name="select_all_default.png" width="20.799999237060547" height="20.799999237060547"/>
<image name="select_all_disabled.png" width="20.799999237060547" height="20.799999237060547"/>
</resources>
<simulatedMetricsContainer key="defaultSimulatedMetrics">
<simulatedStatusBarMetrics key="statusBar"/>
<simulatedOrientationMetrics key="orientation"/>
<simulatedScreenMetrics key="destination"/>
</simulatedMetricsContainer>
</document>

View file

@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="13529" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" colorMatched="YES">
<device id="retina4_7" orientation="portrait">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" colorMatched="YES">
<device id="retina4_7" orientation="landscape">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13527"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14460.20"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
@ -17,8 +17,11 @@
<outlet property="backButton" destination="9" id="Pqj-y9-hqc"/>
<outlet property="contactLabel" destination="25" id="rTL-Ut-42o"/>
<outlet property="emptyLabel" destination="hvz-CS-NME" id="Qws-r1-XMh"/>
<outlet property="encryptedChatView" destination="JU4-bf-tVI" id="j6f-qz-VKd"/>
<outlet property="headerView" destination="33" id="iv2-Rj-j3j"/>
<outlet property="landscapeView" destination="NHC-7w-48z" id="kTJ-YT-Ejm"/>
<outlet property="linphoneImage" destination="mfN-Ai-9RX" id="Ubt-oH-lra"/>
<outlet property="optionsView" destination="k0D-99-OKO" id="5uE-lN-M3B"/>
<outlet property="portraitView" destination="4" id="0gH-12-O02"/>
<outlet property="tableView" destination="baU-d4-eu3" id="3q4-5X-yCB"/>
<outlet property="view" destination="4" id="10"/>
@ -27,23 +30,23 @@
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="HKr-sq-hGv" userLabel="iphone6MetricsView">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<rect key="frame" x="0.0" y="0.0" width="667" height="375"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<view tag="1" contentMode="scaleToFill" id="4">
<rect key="frame" x="0.0" y="42" width="375" height="559"/>
<rect key="frame" x="0.0" y="42" width="667" height="267"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view tag="2" contentMode="scaleToFill" id="6" userLabel="topBar">
<rect key="frame" x="0.0" y="0.0" width="375" height="66"/>
<rect key="frame" x="0.0" y="0.0" width="667" height="66"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<subviews>
<imageView userInteractionEnabled="NO" tag="3" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="color_F.png" id="gee-PW-IqY" userLabel="backgroundColor">
<rect key="frame" x="0.0" y="0.0" width="375" height="66"/>
<rect key="frame" x="0.0" y="0.0" width="667" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
</imageView>
<button opaque="NO" tag="4" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" lineBreakMode="middleTruncation" id="9" userLabel="backButton" customClass="UIIconButton">
<rect key="frame" x="0.0" y="0.0" width="72" height="66"/>
<rect key="frame" x="0.0" y="0.0" width="128" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Back"/>
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
@ -55,7 +58,7 @@
</connections>
</button>
<button opaque="NO" tag="5" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" lineBreakMode="middleTruncation" id="50" userLabel="addButton" customClass="UIIconButton">
<rect key="frame" x="303" y="0.0" width="72" height="66"/>
<rect key="frame" x="539" y="0.0" width="128" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Add to contact"/>
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
@ -69,11 +72,11 @@
</subviews>
</view>
<view tag="7" contentMode="scaleToFill" id="33" userLabel="headerView">
<rect key="frame" x="0.0" y="66" width="375" height="250"/>
<rect key="frame" x="0.0" y="66" width="667" height="250"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<imageView userInteractionEnabled="NO" tag="8" contentMode="scaleAspectFit" image="avatar.png" id="23" userLabel="avatarImage" customClass="UIRoundedImageView">
<rect key="frame" x="137" y="8" width="100" height="100"/>
<rect key="frame" x="244" y="8" width="178" height="100"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Contact avatar">
<accessibilityTraits key="traits" image="YES" notEnabled="YES"/>
@ -81,58 +84,87 @@
</accessibility>
</imageView>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" tag="9" contentMode="left" text="John Doe" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="17" id="25" userLabel="contactLabel">
<rect key="frame" x="0.0" y="110" width="375" height="40"/>
<rect key="frame" x="0.0" y="110" width="667" height="40"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Contact name"/>
<fontDescription key="fontDescription" type="system" pointSize="33"/>
<color key="textColor" red="0.33333333333333331" green="0.33333333333333331" blue="0.33333333333333331" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<imageView hidden="YES" userInteractionEnabled="NO" tag="10" contentMode="scaleAspectFit" image="linphone_user.png" id="mfN-Ai-9RX" userLabel="linphoneImage" customClass="UIRoundedImageView">
<rect key="frame" x="245" y="39" width="21" height="37"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES" flexibleMaxY="YES"/>
<imageView userInteractionEnabled="NO" tag="10" contentMode="scaleAspectFit" image="linphone_user.png" id="mfN-Ai-9RX" userLabel="linphoneImage" customClass="UIRoundedImageView">
<rect key="frame" x="642" y="124" width="15" height="15"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Contact avatar">
<accessibilityTraits key="traits" image="YES" notEnabled="YES"/>
<bool key="isElement" value="YES"/>
</accessibility>
</imageView>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" tag="11" contentMode="left" text="johndoe@sip.linphone.org" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" id="EoB-ux-sD7" userLabel="addressLabel">
<rect key="frame" x="0.0" y="158" width="375" height="23"/>
<rect key="frame" x="0.0" y="158" width="667" height="23"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Contact name"/>
<fontDescription key="fontDescription" type="system" pointSize="18"/>
<color key="textColor" red="0.98766469955444336" green="0.27512490749359131" blue="0.029739789664745331" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<button opaque="NO" tag="12" contentMode="scaleAspectFit" contentHorizontalAlignment="left" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="obZ-W7-q8P" userLabel="chatButton">
<rect key="frame" x="202" y="189" width="51" height="51"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<state key="normal" image="chat_start_body_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="chat_start_body_disabled.png"/>
<state key="highlighted" image="chat_start_body_over.png"/>
<connections>
<action selector="onChatClick:" destination="-1" eventType="touchUpInside" id="Dd5-7a-ev8"/>
</connections>
</button>
<button opaque="NO" tag="13" contentMode="scaleAspectFit" contentHorizontalAlignment="left" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="5eX-W0-T4B" userLabel="callButton">
<rect key="frame" x="122" y="189" width="51" height="51"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<state key="normal" image="call_start_body_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="call_start_body_disabled.png"/>
<state key="highlighted" image="call_start_body_over.png"/>
<connections>
<action selector="onCallClick:" destination="-1" eventType="touchUpInside" id="Vlx-14-3CH"/>
</connections>
</button>
<view contentMode="scaleToFill" id="k0D-99-OKO" userLabel="optionsView">
<rect key="frame" x="0.0" y="189" width="667" height="44"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<button opaque="NO" tag="13" contentMode="scaleAspectFit" contentHorizontalAlignment="left" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="5eX-W0-T4B" userLabel="callButton">
<rect key="frame" x="179" y="0.0" width="51" height="51"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<state key="normal" image="call_start_body_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="call_start_body_disabled.png"/>
<state key="highlighted" image="call_start_body_over.png"/>
<connections>
<action selector="onCallClick:" destination="-1" eventType="touchUpInside" id="Vlx-14-3CH"/>
</connections>
</button>
<button opaque="NO" tag="12" contentMode="scaleAspectFit" contentHorizontalAlignment="left" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="obZ-W7-q8P" userLabel="chatButton">
<rect key="frame" x="317" y="0.0" width="50" height="51"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<state key="normal" image="chat_start_body_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="chat_start_body_disabled.png"/>
<state key="highlighted" image="chat_start_body_over.png"/>
<connections>
<action selector="onChatClick:" destination="-1" eventType="touchUpInside" id="Dd5-7a-ev8"/>
</connections>
</button>
<view contentMode="scaleToFill" id="JU4-bf-tVI" userLabel="encryptedChatView">
<rect key="frame" x="456" y="-1" width="50" height="51"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES"/>
<subviews>
<button opaque="NO" contentMode="scaleAspectFit" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="E2n-mF-saI" userLabel="encryptedChatButton" customClass="UIIconButton">
<rect key="frame" x="-1" y="0.0" width="51" height="51"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES"/>
<accessibility key="accessibilityConfiguration" label="Chat"/>
<state key="normal" image="chat_start_body_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="chat_start_body_disabled.png"/>
<state key="highlighted" image="chat_start_body_over.png"/>
<connections>
<action selector="onEncryptedChatClick:" destination="-1" eventType="touchUpInside" id="1Ci-9Q-eP2"/>
</connections>
</button>
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" image="security_toogle_icon_green.png" id="YuZ-ep-Rtj" userLabel="securityImage">
<rect key="frame" x="33" y="0.0" width="19" height="24"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
</imageView>
</subviews>
</view>
</subviews>
</view>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</view>
<tableView clipsSubviews="YES" tag="6" contentMode="scaleToFill" alwaysBounceVertical="YES" style="plain" separatorStyle="none" allowsSelection="NO" rowHeight="30" sectionHeaderHeight="28" sectionFooterHeight="28" id="k6N-Av-eOu">
<rect key="frame" x="0.0" y="316" width="375" height="243"/>
<rect key="frame" x="0.0" y="316" width="667" height="0.0"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<connections>
@ -141,19 +173,19 @@
</connections>
</tableView>
<label hidden="YES" opaque="NO" userInteractionEnabled="NO" tag="40" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="No log selected" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="hvz-CS-NME" userLabel="emptyLabel">
<rect key="frame" x="0.0" y="66" width="375" height="493"/>
<rect key="frame" x="0.0" y="66" width="667" height="201"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<view hidden="YES" tag="8" contentMode="scaleToFill" misplaced="YES" id="dEJ-xc-518" userLabel="waitView">
<rect key="frame" x="0.0" y="0.0" width="375" height="559"/>
<view hidden="YES" tag="8" contentMode="scaleToFill" id="dEJ-xc-518" userLabel="waitView">
<rect key="frame" x="0.0" y="0.0" width="667" height="267"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<activityIndicatorView opaque="NO" tag="9" contentMode="scaleToFill" animating="YES" style="gray" id="NK3-ME-9jd" userLabel="activityIndicatorView">
<rect key="frame" x="179" y="267" width="20" height="20"/>
<rect key="frame" x="326" y="122" width="20" height="20"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
</activityIndicatorView>
</subviews>
@ -165,26 +197,26 @@
</view>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<point key="canvasLocation" x="254.5" y="288.5"/>
<point key="canvasLocation" x="-3.2000000000000002" y="22.488755622188908"/>
</view>
<view contentMode="scaleToFill" id="LBc-mh-ozk" userLabel="iphone6MetricsView">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<rect key="frame" x="0.0" y="0.0" width="667" height="375"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<view tag="1" contentMode="scaleToFill" id="NHC-7w-48z">
<rect key="frame" x="0.0" y="42" width="375" height="625"/>
<rect key="frame" x="0.0" y="42" width="667" height="333"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view tag="2" contentMode="scaleToFill" id="Rtv-hu-bCz" userLabel="topBar">
<rect key="frame" x="0.0" y="0.0" width="375" height="66"/>
<rect key="frame" x="0.0" y="0.0" width="667" height="66"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<subviews>
<imageView userInteractionEnabled="NO" tag="3" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="color_F.png" id="JOe-5t-C7f" userLabel="backgroundColor">
<rect key="frame" x="0.0" y="0.0" width="375" height="66"/>
<rect key="frame" x="0.0" y="0.0" width="667" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
</imageView>
<button opaque="NO" tag="4" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" lineBreakMode="middleTruncation" id="NJl-Lb-CU6" userLabel="backButton" customClass="UIIconButton">
<rect key="frame" x="0.0" y="0.0" width="40" height="66"/>
<rect key="frame" x="0.0" y="0.0" width="71" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Back"/>
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
@ -196,7 +228,7 @@
</connections>
</button>
<button opaque="NO" tag="5" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" lineBreakMode="middleTruncation" id="O7r-6t-b7w" userLabel="addButton" customClass="UIIconButton">
<rect key="frame" x="334" y="0.0" width="41" height="66"/>
<rect key="frame" x="594" y="0.0" width="73" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Add to contact"/>
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
@ -210,7 +242,7 @@
</subviews>
</view>
<tableView clipsSubviews="YES" tag="6" contentMode="scaleToFill" alwaysBounceVertical="YES" style="plain" separatorStyle="none" allowsSelection="NO" rowHeight="30" sectionHeaderHeight="44" sectionFooterHeight="22" id="2jK-gw-ULv">
<rect key="frame" x="0.0" y="168" width="375" height="457"/>
<rect key="frame" x="0.0" y="168" width="667" height="165"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<connections>
@ -219,11 +251,11 @@
</connections>
</tableView>
<view tag="7" contentMode="scaleToFill" id="Mwp-y3-g1b" userLabel="headerView">
<rect key="frame" x="0.0" y="66" width="375" height="102"/>
<rect key="frame" x="0.0" y="66" width="667" height="102"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<imageView userInteractionEnabled="NO" tag="8" contentMode="scaleAspectFit" image="avatar.png" id="d9m-G0-1u3" userLabel="avatarImage" customClass="UIRoundedImageView">
<rect key="frame" x="16" y="8" width="49" height="86"/>
<rect key="frame" x="28" y="8" width="88" height="86"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Contact avatar">
<accessibilityTraits key="traits" image="YES" notEnabled="YES"/>
@ -231,7 +263,7 @@
</accessibility>
</imageView>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" tag="9" contentMode="left" text="John Doe" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="17" id="Qbg-hm-bd7" userLabel="contactLabel">
<rect key="frame" x="90" y="8" width="200" height="50"/>
<rect key="frame" x="160" y="8" width="356" height="50"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Contact name"/>
<fontDescription key="fontDescription" type="system" pointSize="33"/>
@ -239,39 +271,68 @@
<nil key="highlightedColor"/>
</label>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" tag="11" contentMode="left" text="johndoe@sip.linphone.org" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" id="XJa-f6-K0y" userLabel="addressLabel">
<rect key="frame" x="90" y="56" width="200" height="38"/>
<rect key="frame" x="160" y="56" width="356" height="38"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Contact name"/>
<fontDescription key="fontDescription" type="system" pointSize="18"/>
<color key="textColor" red="0.98766469955444336" green="0.27512490749359131" blue="0.029739789664745331" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<button opaque="NO" tag="12" contentMode="scaleAspectFit" contentHorizontalAlignment="left" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="MRH-yi-acw" userLabel="chatButton">
<rect key="frame" x="319" y="25" width="51" height="51"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<state key="normal" image="chat_start_body_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="chat_start_body_disabled.png"/>
<state key="highlighted" image="chat_start_body_over.png"/>
<connections>
<action selector="onChatClick:" destination="-1" eventType="touchUpInside" id="ygZ-jT-J3b"/>
</connections>
</button>
<button opaque="NO" tag="13" contentMode="scaleAspectFit" contentHorizontalAlignment="left" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="zZo-Pc-EVi" userLabel="callButton">
<rect key="frame" x="276" y="25" width="51" height="51"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<state key="normal" image="call_start_body_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="call_start_body_disabled.png"/>
<state key="highlighted" image="call_start_body_over.png"/>
<connections>
<action selector="onCallClick:" destination="-1" eventType="touchUpInside" id="xBV-3j-apE"/>
</connections>
</button>
<view contentMode="scaleToFill" id="teU-AB-8hO" userLabel="optionsView">
<rect key="frame" x="0.0" y="29" width="667" height="44"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<button opaque="NO" tag="13" contentMode="scaleAspectFit" contentHorizontalAlignment="left" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="pBo-Oo-bAW" userLabel="callButton">
<rect key="frame" x="491" y="0.0" width="51" height="51"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<state key="normal" image="call_start_body_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="call_start_body_disabled.png"/>
<state key="highlighted" image="call_start_body_over.png"/>
<connections>
<action selector="onCallClick:" destination="-1" eventType="touchUpInside" id="QPr-DZ-52f"/>
</connections>
</button>
<button opaque="NO" tag="12" contentMode="scaleAspectFit" contentHorizontalAlignment="left" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="iDG-Mn-jm2" userLabel="chatButton">
<rect key="frame" x="551" y="0.0" width="51" height="51"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<state key="normal" image="chat_start_body_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="chat_start_body_disabled.png"/>
<state key="highlighted" image="chat_start_body_over.png"/>
<connections>
<action selector="onChatClick:" destination="-1" eventType="touchUpInside" id="1Xg-su-cG3"/>
</connections>
</button>
<view contentMode="scaleToFill" id="m90-u6-x3J" userLabel="encryptedChatView">
<rect key="frame" x="611" y="0.0" width="51" height="51"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES"/>
<subviews>
<button opaque="NO" contentMode="scaleAspectFit" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="8fY-hz-ECC" userLabel="encryptedChatButton" customClass="UIIconButton">
<rect key="frame" x="0.0" y="0.0" width="51" height="51"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES"/>
<accessibility key="accessibilityConfiguration" label="Chat"/>
<state key="normal" image="chat_start_body_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="chat_start_body_disabled.png"/>
<state key="highlighted" image="chat_start_body_over.png"/>
<connections>
<action selector="onEncryptedChatClick:" destination="-1" eventType="touchUpInside" id="IYO-Rc-SGp"/>
</connections>
</button>
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" image="security_toogle_icon_green.png" id="8D9-me-ZdS" userLabel="securityImage">
<rect key="frame" x="33" y="0.0" width="19" height="24"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
</imageView>
</subviews>
</view>
</subviews>
</view>
<imageView hidden="YES" userInteractionEnabled="NO" tag="10" contentMode="scaleAspectFit" image="linphone_user.png" id="G2O-Yh-fZA" userLabel="linphoneImage">
<rect key="frame" x="69" y="8" width="17" height="25"/>
<rect key="frame" x="123" y="8" width="30" height="25"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Contact avatar">
<accessibilityTraits key="traits" image="YES" notEnabled="YES"/>
@ -282,19 +343,19 @@
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</view>
<label hidden="YES" opaque="NO" userInteractionEnabled="NO" tag="40" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="No log selected" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="IHY-Yg-pkN" userLabel="emptyLabel">
<rect key="frame" x="0.0" y="66" width="375" height="559"/>
<rect key="frame" x="0.0" y="66" width="667" height="267"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<view hidden="YES" tag="8" contentMode="scaleToFill" misplaced="YES" id="X29-vB-VIz" userLabel="waitView">
<rect key="frame" x="0.0" y="0.0" width="375" height="625"/>
<view hidden="YES" tag="8" contentMode="scaleToFill" id="X29-vB-VIz" userLabel="waitView">
<rect key="frame" x="0.0" y="0.0" width="667" height="333"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<activityIndicatorView opaque="NO" tag="9" contentMode="scaleToFill" animating="YES" style="gray" id="7l5-ZU-CbW" userLabel="activityIndicatorView">
<rect key="frame" x="179" y="300" width="20" height="20"/>
<rect key="frame" x="326" y="155" width="20" height="20"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
</activityIndicatorView>
</subviews>
@ -306,13 +367,13 @@
</view>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<point key="canvasLocation" x="348.5" y="-44.5"/>
<point key="canvasLocation" x="702.39999999999998" y="-45.877061469265371"/>
</view>
<tableViewController id="baU-d4-eu3" customClass="HistoryDetailsTableView">
<connections>
<outlet property="view" destination="k6N-Av-eOu" id="Dos-d4-5l5"/>
</connections>
<point key="canvasLocation" x="823" y="263"/>
<point key="canvasLocation" x="1316.8" y="236.58170914542731"/>
</tableViewController>
</objects>
<resources>
@ -329,6 +390,7 @@
<image name="color_F.png" width="2" height="2"/>
<image name="contact_add_default.png" width="34" height="29"/>
<image name="contact_add_disabled.png" width="34" height="29"/>
<image name="linphone_user.png" width="26" height="22"/>
<image name="linphone_user.png" width="26" height="26"/>
<image name="security_toogle_icon_green.png" width="21" height="24"/>
</resources>
</document>

View file

@ -1,8 +1,12 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="9060" systemVersion="15B42" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none">
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" colorMatched="YES">
<device id="retina6_1" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="9051"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14490.49"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="HistoryListView">
@ -16,7 +20,7 @@
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="o8E-Bz-RWL" userLabel="iphone6MetricsView">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<view contentMode="scaleToFill" id="2">
@ -30,7 +34,6 @@
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="color_F.png" id="upG-IP-6mg" userLabel="backgroundColor">
<rect key="frame" x="0.0" y="0.0" width="375" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<animations/>
</imageView>
<view contentMode="scaleToFill" id="38" userLabel="switchView">
<rect key="frame" x="0.0" y="0.0" width="150" height="66"/>
@ -39,11 +42,10 @@
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="4" userLabel="allButton" customClass="UIIconButton">
<rect key="frame" x="0.0" y="0.0" width="75" height="66"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES" flexibleMaxY="YES"/>
<animations/>
<accessibility key="accessibilityConfiguration" label="All contacts filter"/>
<inset key="titleEdgeInsets" minX="0.0" minY="16" maxX="0.0" maxY="0.0"/>
<state key="normal" image="history_all_default.png">
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="history_all_disabled.png"/>
<state key="selected" image="history_all_selected.png"/>
@ -55,10 +57,9 @@
<button opaque="NO" contentMode="bottom" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="5" userLabel="missedButton" customClass="UIIconButton">
<rect key="frame" x="75" y="0.0" width="75" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" heightSizable="YES" flexibleMaxY="YES"/>
<animations/>
<accessibility key="accessibilityConfiguration" label="Missed contacts filter"/>
<state key="normal" image="history_missed_default.png">
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="history_missed_disabled.png"/>
<state key="selected" image="history_missed_selected.png"/>
@ -70,18 +71,15 @@
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="color_A.png" id="o8E-gw-vhI" userLabel="selectedButtonImage">
<rect key="frame" x="0.0" y="63" width="75" height="3"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES"/>
<animations/>
</imageView>
</subviews>
<animations/>
</view>
<button hidden="YES" opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="00K-MU-NUc" userLabel="cancelButton" customClass="UIIconButton">
<rect key="frame" x="0.0" y="0.0" width="75" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<animations/>
<accessibility key="accessibilityConfiguration" label="Delete all"/>
<state key="normal" image="cancel_edit_default.png">
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="cancel_edit_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
@ -93,12 +91,11 @@
<button hidden="YES" opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" reversesTitleShadowWhenHighlighted="YES" showsTouchWhenHighlighted="YES" lineBreakMode="middleTruncation" id="nhN-oH-LQ9" userLabel="toggleSelectionButton" customClass="UIIconButton">
<rect key="frame" x="225" y="0.0" width="75" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<animations/>
<accessibility key="accessibilityConfiguration" label="Select all"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
<state key="normal" image="deselect_all.png">
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="select_all_disabled.png"/>
<state key="selected" image="select_all_default.png"/>
@ -110,11 +107,10 @@
<button hidden="YES" opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="35" userLabel="deleteButton" customClass="UIIconButton">
<rect key="frame" x="300" y="0.0" width="75" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<animations/>
<accessibility key="accessibilityConfiguration" label="Delete all"/>
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
<state key="normal" image="delete_default.png">
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="delete_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
@ -125,13 +121,12 @@
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="6" userLabel="editButton" customClass="UIIconButton">
<rect key="frame" x="300" y="0.0" width="75" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<animations/>
<accessibility key="accessibilityConfiguration" label="Edit"/>
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
<state key="normal" image="edit_list_default.png">
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
<state key="normal" image="delete_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="edit_list_disabled.png"/>
<state key="disabled" image="delete_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onEditClick:" destination="18" eventType="touchUpInside" id="5Ft-HW-cVh"/>
@ -139,16 +134,14 @@
</connections>
</button>
</subviews>
<animations/>
</view>
<tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" style="plain" separatorStyle="default" allowsSelectionDuringEditing="YES" allowsMultipleSelectionDuringEditing="YES" rowHeight="44" sectionHeaderHeight="35" sectionFooterHeight="1" id="17" userLabel="tableView">
<rect key="frame" x="0.0" y="66" width="375" height="493"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<animations/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<inset key="contentInset" minX="0.0" minY="0.0" maxX="0.0" maxY="10"/>
<inset key="scrollIndicatorInsets" minX="0.0" minY="0.0" maxX="0.0" maxY="10"/>
<color key="separatorColor" red="0.7254902124" green="0.76862746479999999" blue="0.79607844350000001" alpha="1" colorSpace="deviceRGB"/>
<color key="separatorColor" red="0.67030966281890869" green="0.71867996454238892" blue="0.75078284740447998" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<connections>
<outlet property="dataSource" destination="18" id="23"/>
<outlet property="delegate" destination="18" id="24"/>
@ -157,21 +150,17 @@
<label hidden="YES" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="No call in your history" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="xtr-Fp-60Z" userLabel="emptyTableLabel">
<rect key="frame" x="0.0" y="66" width="375" height="493"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<animations/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<animations/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
</view>
</subviews>
<animations/>
<color key="backgroundColor" red="1" green="1" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
<simulatedScreenMetrics key="simulatedDestinationMetrics" type="retina47"/>
<point key="canvasLocation" x="245.5" y="373.5"/>
<color key="backgroundColor" red="1" green="1" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<point key="canvasLocation" x="355.79710144927537" y="250.11160714285714"/>
</view>
<tableViewController autoresizesArchivedViewToFullSize="NO" id="18" userLabel="tableController" customClass="HistoryListTableView">
<extendedEdge key="edgesForExtendedLayout"/>
@ -183,27 +172,25 @@
<outlet property="toggleSelectionButton" destination="nhN-oH-LQ9" id="77r-l0-3Yi"/>
<outlet property="view" destination="17" id="25"/>
</connections>
<point key="canvasLocation" x="596" y="305"/>
<point key="canvasLocation" x="863.768115942029" y="204.24107142857142"/>
</tableViewController>
</objects>
<resources>
<image name="cancel_edit_default.png" width="29" height="29"/>
<image name="cancel_edit_disabled.png" width="29" height="29"/>
<image name="cancel_edit_default.png" width="47.200000762939453" height="47.200000762939453"/>
<image name="cancel_edit_disabled.png" width="47.200000762939453" height="47.200000762939453"/>
<image name="color_A.png" width="2" height="2"/>
<image name="color_E.png" width="2" height="2"/>
<image name="color_F.png" width="2" height="2"/>
<image name="delete_default.png" width="21" height="27"/>
<image name="delete_disabled.png" width="21" height="27"/>
<image name="deselect_all.png" width="26" height="26"/>
<image name="edit_list_default.png" width="29" height="28"/>
<image name="edit_list_disabled.png" width="29" height="28"/>
<image name="history_all_default.png" width="32" height="31"/>
<image name="history_all_disabled.png" width="32" height="31"/>
<image name="history_all_selected.png" width="32" height="31"/>
<image name="history_missed_default.png" width="32" height="32"/>
<image name="history_missed_disabled.png" width="32" height="32"/>
<image name="history_missed_selected.png" width="32" height="32"/>
<image name="select_all_default.png" width="26" height="26"/>
<image name="select_all_disabled.png" width="26" height="26"/>
<image name="delete_default.png" width="34.400001525878906" height="44.799999237060547"/>
<image name="delete_disabled.png" width="34.400001525878906" height="44.799999237060547"/>
<image name="deselect_all.png" width="43.200000762939453" height="43.200000762939453"/>
<image name="history_all_default.png" width="52.799999237060547" height="51.200000762939453"/>
<image name="history_all_disabled.png" width="52.799999237060547" height="51.200000762939453"/>
<image name="history_all_selected.png" width="52.799999237060547" height="51.200000762939453"/>
<image name="history_missed_default.png" width="52.799999237060547" height="52.799999237060547"/>
<image name="history_missed_disabled.png" width="52.799999237060547" height="52.799999237060547"/>
<image name="history_missed_selected.png" width="52.799999237060547" height="52.799999237060547"/>
<image name="select_all_default.png" width="43.200000762939453" height="43.200000762939453"/>
<image name="select_all_disabled.png" width="43.200000762939453" height="43.200000762939453"/>
</resources>
</document>

View file

@ -1,9 +1,12 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="9060" systemVersion="15B42" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none">
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" colorMatched="YES">
<device id="retina6_1" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<development version="6000" identifier="xcode"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="9051"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14490.49"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="SettingsView">
@ -18,53 +21,35 @@
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="20" userLabel="iphone6MetricsView">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<view contentMode="scaleToFill" id="4">
<rect key="frame" x="0.0" y="42" width="375" height="579"/>
<rect key="frame" x="0.0" y="42" width="414" height="791"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES" flexibleMaxY="YES"/>
<subviews>
<view contentMode="scaleToFill" id="SRV-nz-KWT" userLabel="topBar">
<rect key="frame" x="0.0" y="0.0" width="375" height="66"/>
<rect key="frame" x="0.0" y="0.0" width="414" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="color_F.png" id="RyH-Uy-VKo" userLabel="backgroundColor">
<rect key="frame" x="0.0" y="0.0" width="375" height="66"/>
<rect key="frame" x="0.0" y="0.0" width="414" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<animations/>
</imageView>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="Ccu-go-gvn" userLabel="dialerBackButton" customClass="UIIconButton">
<rect key="frame" x="300" y="0.0" width="75" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<animations/>
<accessibility key="accessibilityConfiguration" label="Add contact"/>
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
<state key="normal" image="dialer_back_default.png">
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
</state>
<state key="disabled" image="dialer_back_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onDialerBackClick:" destination="-1" eventType="touchUpInside" id="hSX-Xt-zaC"/>
</connections>
</button>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="SETTINGS" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="SqM-h2-idp" userLabel="titleLabel">
<rect key="frame" x="83" y="0.0" width="209" height="66"/>
<rect key="frame" x="92" y="0.0" width="230" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<animations/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="27"/>
<color key="textColor" red="1" green="0.36862745099999999" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color key="textColor" red="0.98766469955444336" green="0.27512490749359131" blue="0.029739789664745331" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<button opaque="NO" tag="6" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="gTj-vM-UtG" userLabel="backButton" customClass="UIIconButton">
<rect key="frame" x="0.0" y="0.0" width="75" height="66"/>
<rect key="frame" x="0.0" y="0.0" width="91" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<animations/>
<accessibility key="accessibilityConfiguration" label="Back"/>
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
<state key="normal" image="back_default.png">
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="back_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
@ -73,23 +58,18 @@
</connections>
</button>
</subviews>
<animations/>
</view>
<view contentMode="scaleToFill" id="Qjf-HX-coQ" userLabel="subView">
<rect key="frame" x="0.0" y="66" width="375" height="513"/>
<rect key="frame" x="0.0" y="66" width="414" height="725"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES" flexibleMaxY="YES"/>
<animations/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</view>
</subviews>
<animations/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</view>
</subviews>
<animations/>
<color key="backgroundColor" red="1" green="1" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
<simulatedScreenMetrics key="simulatedDestinationMetrics" type="retina47"/>
<point key="canvasLocation" x="-42.5" y="261.5"/>
<color key="backgroundColor" red="1" green="1" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<point key="canvasLocation" x="-61.594202898550726" y="175.11160714285714"/>
</view>
<navigationController definesPresentationContext="YES" navigationBarHidden="YES" id="10" userLabel="navigationController" customClass="UINavigationControllerEx">
<extendedEdge key="edgesForExtendedLayout"/>
@ -97,7 +77,6 @@
<nil key="simulatedTopBarMetrics"/>
<navigationBar key="navigationBar" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" barStyle="black" translucent="NO" id="11" userLabel="navigationBar" customClass="UINavigationBarEx">
<autoresizingMask key="autoresizingMask"/>
<animations/>
</navigationBar>
</navigationController>
<viewController autoresizesArchivedViewToFullSize="NO" id="6" userLabel="settingsController" customClass="IASKAppSettingsViewControllerEx">
@ -106,11 +85,9 @@
</viewController>
</objects>
<resources>
<image name="back_default.png" width="24" height="21"/>
<image name="back_disabled.png" width="24" height="21"/>
<image name="back_default.png" width="38.400001525878906" height="35.200000762939453"/>
<image name="back_disabled.png" width="38.400001525878906" height="35.200000762939453"/>
<image name="color_E.png" width="2" height="2"/>
<image name="color_F.png" width="2" height="2"/>
<image name="dialer_back_default.png" width="27" height="27"/>
<image name="dialer_back_disabled.png" width="27" height="27"/>
</resources>
</document>

View file

@ -1,8 +1,11 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="11198.2" systemVersion="15G31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" colorMatched="YES">
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" colorMatched="YES">
<device id="retina6_1" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11161"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14490.49"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
@ -15,37 +18,37 @@
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="eP3-Qs-BZl" userLabel="iphone6MetricsView">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<view tag="299" contentMode="scaleToFill" id="HJH-1o-RXN">
<frame key="frameInset" minY="66"/>
<rect key="frame" x="0.0" y="66" width="414" height="830"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view tag="2" contentMode="scaleToFill" id="Whz-oo-Pwx" userLabel="topBar">
<frame key="frameInset" height="66"/>
<rect key="frame" x="0.0" y="0.0" width="414" height="66"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<subviews>
<imageView userInteractionEnabled="NO" tag="3" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="color_F.png" id="h54-RV-eE6" userLabel="backgroundColor">
<frame key="frameInset" height="100.00%"/>
<rect key="frame" x="0.0" y="0.0" width="414" height="66"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES" flexibleMaxY="YES"/>
</imageView>
<button opaque="NO" tag="4" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="ETk-tB-ZNl" userLabel="dialerBackButton" customClass="UIIconButton">
<frame key="frameInset" minY="0.0%" width="20.80%" height="100.00%"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<rect key="frame" x="0.0" y="0.0" width="82" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Add contact"/>
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
<state key="normal" image="dialer_back_default.png">
<state key="normal" image="back_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="dialer_back_disabled.png"/>
<state key="disabled" image="back_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onDialerBackClick:" destination="-1" eventType="touchUpInside" id="IrL-W4-g5z"/>
</connections>
</button>
<label opaque="NO" userInteractionEnabled="NO" tag="5" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="SHOP" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="iNt-9d-7si" userLabel="titleLabel">
<frame key="frameInset" minX="0.0%" minY="0.0%" width="100.00%" height="100.00%"/>
<rect key="frame" x="0.0" y="0.0" width="414" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="27"/>
<color key="textColor" red="0.98766469955444336" green="0.27512490749359131" blue="0.029739789664745331" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
@ -53,8 +56,8 @@
</label>
</subviews>
</view>
<tableView clipsSubviews="YES" contentMode="scaleToFill" misplaced="YES" bounces="NO" style="plain" rowHeight="44" sectionHeaderHeight="28" sectionFooterHeight="28" id="cnd-cB-B4W">
<frame key="frameInset" minY="66"/>
<tableView clipsSubviews="YES" contentMode="scaleToFill" bounces="NO" style="plain" rowHeight="44" sectionHeaderHeight="28" sectionFooterHeight="28" id="cnd-cB-B4W">
<rect key="frame" x="0.0" y="66" width="414" height="764"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<connections>
@ -62,12 +65,12 @@
<outlet property="delegate" destination="sBe-ML-IzT" id="T0H-aj-0UQ"/>
</connections>
</tableView>
<view hidden="YES" tag="288" contentMode="scaleToFill" misplaced="YES" id="tuB-rE-DiO" userLabel="waitView">
<frame key="frameInset" minY="66" maxY="-33"/>
<view hidden="YES" tag="288" contentMode="scaleToFill" id="tuB-rE-DiO" userLabel="waitView">
<rect key="frame" x="0.0" y="66" width="414" height="797"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<activityIndicatorView opaque="NO" tag="9" contentMode="scaleToFill" animating="YES" style="gray" id="7Jb-oC-FC5" userLabel="activityIndicatorView">
<frame key="frameInset" minX="50.42%" minY="49.82%" width="20" height="20"/>
<rect key="frame" x="199" y="387" width="20" height="20"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
</activityIndicatorView>
</subviews>
@ -79,25 +82,20 @@
</view>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<point key="canvasLocation" x="-414.5" y="-738.5"/>
<point key="canvasLocation" x="-600.72463768115949" y="-494.53125"/>
</view>
<tableViewController id="sBe-ML-IzT" customClass="ShopTableView">
<simulatedStatusBarMetrics key="simulatedStatusBarMetrics"/>
<connections>
<outlet property="view" destination="cnd-cB-B4W" id="hcK-9Y-fd5"/>
</connections>
<point key="canvasLocation" x="34" y="-724"/>
<point key="canvasLocation" x="49.275362318840585" y="-484.82142857142856"/>
</tableViewController>
</objects>
<resources>
<image name="back_default.png" width="38.400001525878906" height="35.200000762939453"/>
<image name="back_disabled.png" width="38.400001525878906" height="35.200000762939453"/>
<image name="color_E.png" width="2" height="2"/>
<image name="color_F.png" width="2" height="2"/>
<image name="dialer_back_default.png" width="27" height="27"/>
<image name="dialer_back_disabled.png" width="27" height="27"/>
</resources>
<simulatedMetricsContainer key="defaultSimulatedMetrics">
<simulatedStatusBarMetrics key="statusBar"/>
<simulatedOrientationMetrics key="orientation"/>
<simulatedScreenMetrics key="destination" type="retina4_7.fullscreen"/>
</simulatedMetricsContainer>
</document>

View file

@ -34,6 +34,9 @@
@interface CallIncomingView : TPMultiLayoutViewController <UICompositeViewDelegate> {
}
@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<IncomingCallViewDelegate> 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;

View file

@ -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)];
}

View file

@ -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

View file

@ -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 {

View file

@ -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

View file

@ -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;
}

View file

@ -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

View file

@ -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];

View file

@ -14,6 +14,10 @@
#import "UIRoundBorderedButton.h"
@interface ChatConversationImdnView : UIViewController <UICompositeViewDelegate, UITableViewDelegate, UITableViewDataSource>
{
@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

View file

@ -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 {

View file

@ -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;

View file

@ -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];
}

View file

@ -38,9 +38,11 @@
@interface ChatConversationTableView : UICheckBoxTableView {
@private
NSMutableArray *eventList;
NSMutableArray *totalEventList;
}
@property(nonatomic) LinphoneChatRoom *chatRoom;
@property(nonatomic) NSInteger currentIndex;
@property(nonatomic, strong) id<ChatConversationDelegate> chatRoomDelegate;
@property NSMutableDictionary<NSString *, UIImage *> *imagesInChatroom;
@ -48,5 +50,6 @@
- (void)scrollToBottom:(BOOL)animated;
- (void)scrollToLastUnread:(BOOL)animated;
- (void)updateEventEntry:(LinphoneEventLog *)event;
- (void)refreshData;
@end

View file

@ -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<UITableViewRowAction *> *)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];
}];
}

View file

@ -18,6 +18,8 @@
*/
#import <UIKit/UIKit.h>
#import <QuickLook/QLPreviewItem.h>
#import <QuickLook/QLPreviewController.h>
#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 <QLPreviewItem>
@property(readonly, nonatomic) NSURL *previewItemURL;
@property(readonly, nonatomic) NSString *previewItemTitle;
@end
//QuickLook Datasource for rending PDF docs
@interface FileDataSource : NSObject <QLPreviewControllerDataSource>
@property (strong, nonatomic) PreviewItem *item;
@end
@interface ChatConversationView
: TPMultiLayoutViewController <HPGrowingTextViewDelegate, UICompositeViewDelegate, ImagePickerDelegate, ChatConversationDelegate,
UIDocumentInteractionControllerDelegate, UISearchBarDelegate, UIImageViewDeletableDelegate, UICollectionViewDataSource> {
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 <UIImage *> *imagesArray;
@property NSMutableArray <NSString *> *assetIdsArray;
@property NSMutableArray <NSNumber *> *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

View file

@ -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<QLPreviewItem>)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 <NSString *, PHAsset *> * 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<PHAssetCollection *> *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

View file

@ -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 {

View file

@ -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;

View file

@ -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 {

View file

@ -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<CNLabeledValue<CNInstantMessageAddress *> *> *tmpSipAddresses = [_person.instantMessageAddresses mutableCopy];

View file

@ -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

29
Classes/DevicesListView.h Normal file
View file

@ -0,0 +1,29 @@
//
// DevicesListView.h
// linphone
//
// Created by Danmei Chen on 06/11/2018.
//
#import <UIKit/UIKit.h>
#import "UICompositeView.h"
@interface DevicesMenuEntry : NSObject {
@public
LinphoneParticipant *participant;
NSInteger numberOfDevices;
};
@end
@interface DevicesListView : UIViewController <UICompositeViewDelegate, UITableViewDelegate, UITableViewDataSource>
@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

145
Classes/DevicesListView.m Normal file
View file

@ -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; i<bctbx_list_size(participants); i++) {
participant = (LinphoneParticipant *)bctbx_list_nth_data(participants,i);
[_devicesMenuEntries
addObject:[[DevicesMenuEntry alloc] initWithTitle:participant number:0]];
}
_addressLabel.text = [NSString stringWithUTF8String:linphone_chat_room_get_subject(_room) ?: LINPHONE_DUMMY_SUBJECT];
}
_addressLabel.text = [NSString stringWithFormat:NSLocalizedString(@"%@'s devices", nil), _addressLabel.text];
_tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
[_tableView reloadData];
}
#pragma mark - Action Functions
- (IBAction)onBackClick:(id)sender {
ChatConversationView *view = VIEW(ChatConversationView);
[PhoneMainView.instance popToView:view.compositeViewDescription];
}
#pragma mark - TableView
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return _isOneToOne ? bctbx_list_size(_devices) : [_devicesMenuEntries count];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(nonnull NSIndexPath *)indexPath
{
if (!_isOneToOne) {
DevicesMenuEntry *entry = [_devicesMenuEntries objectAtIndex:indexPath.row];
return entry->numberOfDevices > 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

View file

@ -0,0 +1,93 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14460.20"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="DevicesListView">
<connections>
<outlet property="addressLabel" destination="18k-7l-2Gm" id="f5j-jt-3Im"/>
<outlet property="tableView" destination="mOi-nw-XnD" id="lZn-HK-m2k"/>
<outlet property="view" destination="8ww-in-Nyd" id="EoG-R3-iy0"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="I5Q-PP-VGe" userLabel="iphone6MetricsView">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<view tag="1" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="8ww-in-Nyd">
<rect key="frame" x="0.0" y="42" width="375" height="559"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view tag="2" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="7cG-75-7JN" userLabel="topBar">
<rect key="frame" x="0.0" y="0.0" width="375" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<imageView userInteractionEnabled="NO" tag="3" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="color_F.png" translatesAutoresizingMaskIntoConstraints="NO" id="uhb-wz-8YN" userLabel="backgroundColor">
<rect key="frame" x="0.0" y="0.0" width="375" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
</imageView>
<button opaque="NO" tag="4" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="VHx-cF-BIt" userLabel="backButton" customClass="UIIconButton">
<rect key="frame" x="0.0" y="0.0" width="75" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Back"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
<state key="normal" image="back_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="back_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onBackClick:" destination="-1" eventType="touchUpInside" id="tJZ-ea-vFc"/>
</connections>
</button>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" tag="5" contentMode="left" fixedFrame="YES" usesAttributedText="YES" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="18k-7l-2Gm" userLabel="addressLabel">
<rect key="frame" x="75" y="0.0" width="300" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Contact name">
<accessibilityTraits key="traits" none="YES"/>
</accessibility>
<attributedString key="attributedText">
<fragment content="Contact1">
<attributes>
<color key="NSColor" red="0.33333333329999998" green="0.33333333329999998" blue="0.33333333329999998" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<font key="NSFont" metaFont="system" size="23"/>
<paragraphStyle key="NSParagraphStyle" alignment="left" lineBreakMode="truncatingTail" baseWritingDirection="natural" tighteningFactorForTruncation="0.0"/>
</attributes>
</fragment>
</attributedString>
<nil key="highlightedColor"/>
</label>
</subviews>
</view>
<tableView clipsSubviews="YES" contentMode="scaleToFill" fixedFrame="YES" alwaysBounceVertical="YES" style="plain" separatorStyle="default" allowsSelectionDuringEditing="YES" allowsMultipleSelectionDuringEditing="YES" rowHeight="44" sectionHeaderHeight="22" sectionFooterHeight="22" translatesAutoresizingMaskIntoConstraints="NO" id="mOi-nw-XnD">
<rect key="frame" x="0.0" y="66" width="375" height="493"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color key="separatorColor" red="0.67030966280000004" green="0.71867996450000005" blue="0.75078284740000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</tableView>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<gestureRecognizers/>
</view>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<viewLayoutGuide key="safeArea" id="GbK-eP-eYK"/>
<point key="canvasLocation" x="365.60000000000002" y="-36.431784107946029"/>
</view>
</objects>
<resources>
<image name="back_default.png" width="24" height="22"/>
<image name="back_disabled.png" width="24" height="22"/>
<image name="color_E.png" width="2" height="2"/>
<image name="color_F.png" width="2" height="2"/>
</resources>
</document>

View file

@ -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

View file

@ -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;
}

View file

@ -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

View file

@ -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

View file

@ -22,7 +22,7 @@
@protocol ImagePickerDelegate <NSObject>
- (void)imagePickerDelegateImage:(UIImage *)image info:(NSString *)phAssetId;
- (void)imagePickerDelegateVideo:(NSURL*)url info:(NSDictionary *)info;
@end
@interface ImagePickerView : UIViewController <UICompositeViewDelegate, UINavigationControllerDelegate,
@ -38,7 +38,8 @@
@property(nonatomic, readonly) UIPopoverController *popoverController;
+ (void)SelectImageFromDevice:(id<ImagePickerDelegate>)delegate
atPosition:(UIView *)ipadPopoverPosition
inView:(UIView *)view;
atPosition:(UIView *)ipadPopoverView
inView:(UIView *)ipadView
withDocumentMenuDelegate:(id<UIDocumentMenuDelegate>)documentMenuDelegate;
@end

View file

@ -22,6 +22,9 @@
#import <AVFoundation/AVFoundation.h>
#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<PHAsset *> *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<PHAsset *> *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<PHAssetCollection *> *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<ImagePickerDelegate>)delegate
atPosition:(UIView *)ipadPopoverView
inView:(UIView *)ipadView {
inView:(UIView *)ipadView
withDocumentMenuDelegate:(id<UIDocumentMenuDelegate>)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<UIDocumentMenuDelegate>)documentMenuDelegate {
UIDocumentMenuViewController *documentProviderMenu = [[UIDocumentMenuViewController alloc] initWithDocumentTypes:SUPPORTED_EXTENTIONS inMode:UIDocumentPickerModeImport];
documentProviderMenu.delegate = documentMenuDelegate;
[PhoneMainView.instance presentViewController:documentProviderMenu animated:YES completion:nil];
}
@end

View file

@ -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"]) {

View file

@ -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<UIApplicationOpenURLOptionsKey, id> *)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

View file

@ -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"];

View file

@ -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;

View file

@ -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<PHAsset *> *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 {

View file

@ -1,74 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="9060" systemVersion="15B42" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="9051"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="ImageView">
<connections>
<outlet property="backButton" destination="RW1-kp-wn7" id="DJc-Ps-J3p"/>
<outlet property="scrollView" destination="12" id="13"/>
<outlet property="view" destination="1" id="3"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="zEp-6r-r9n" userLabel="iphone6MetricsView">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<view contentMode="scaleToFill" id="1">
<rect key="frame" x="0.0" y="42" width="375" height="559"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view contentMode="scaleToFill" id="2E4-s5-jYL" userLabel="topBar">
<rect key="frame" x="0.0" y="0.0" width="375" height="66"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<subviews>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="color_F.png" id="Rir-PV-D7o" userLabel="backgroundColor">
<rect key="frame" x="0.0" y="0.0" width="375" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<animations/>
</imageView>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" lineBreakMode="middleTruncation" id="RW1-kp-wn7" userLabel="backButton">
<rect key="frame" x="0.0" y="0.0" width="75" height="66"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<animations/>
<accessibility key="accessibilityConfiguration" label="New Discussion"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
<state key="normal" image="back_default.png">
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
</state>
<state key="disabled" image="back_disabled.png"/>
<state key="highlighted" backgroundImage="color_E.png"/>
<connections>
<action selector="onBackClick:" destination="-1" eventType="touchUpInside" id="vyb-kn-xSQ"/>
</connections>
</button>
</subviews>
<animations/>
</view>
<scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" minimumZoomScale="0.0" maximumZoomScale="10" id="12" userLabel="scrollView" customClass="UIImageScrollView">
<rect key="frame" x="0.0" y="66" width="375" height="493"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<animations/>
<color key="backgroundColor" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
</scrollView>
</subviews>
<animations/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
</view>
</subviews>
<animations/>
<color key="backgroundColor" red="1" green="1" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
<simulatedScreenMetrics key="simulatedDestinationMetrics" type="retina47"/>
</view>
</objects>
<resources>
<image name="back_default.png" width="24" height="21"/>
<image name="back_disabled.png" width="24" height="21"/>
<image name="color_E.png" width="2" height="2"/>
<image name="color_F.png" width="2" height="2"/>
</resources>
</document>

View file

@ -1,20 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14113" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" colorMatched="YES">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14088"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14460.20"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="UIChatBubblePhotoCell">
<connections>
<outlet property="LIMEKO" destination="IST-5o-DCu" id="Bqt-1J-cTI"/>
<outlet property="avatarImage" destination="hD2-19-7IH" id="N1B-Jn-wTo"/>
<outlet property="backgroundColorImage" destination="U2P-5n-gg8" id="1Hn-bx-mua"/>
<outlet property="bottomBarColor" destination="6dA-3U-OPW" id="xJX-pe-zlu"/>
<outlet property="bubbleView" destination="UGz-WT-BUv" id="Usm-sg-420"/>
<outlet property="cancelButton" destination="6dl-Nz-rdv" id="ygz-nv-omC"/>
<outlet property="contactDateLabel" destination="JyR-RQ-uwF" id="Tc4-9t-i5V"/>
@ -28,155 +26,131 @@
<outlet property="imageGestureRecognizer" destination="aDF-hC-ddO" id="2jh-Rr-eKk"/>
<outlet property="imageSubView" destination="GmN-7v-uuO" id="k9r-Xc-csv"/>
<outlet property="imdmIcon" destination="LPj-VT-0fH" id="yYh-pv-EJs"/>
<outlet property="imdmLabel" destination="44j-me-Iqi" id="m5R-Dm-V8g"/>
<outlet property="innerView" destination="Y7i-Gm-AdY" id="PbL-8X-8Fi"/>
<outlet property="messageImageView" destination="yMW-cT-bpU" id="MNr-F2-abQ"/>
<outlet property="messageText" destination="cx9-0K-P9L" id="kPh-s4-Ioy"/>
<outlet property="playButton" destination="cvc-tl-Pcf" id="eKJ-2T-LUl"/>
<outlet property="resendRecognizer" destination="5ZI-Ip-lGl" id="G2r-On-6mV"/>
<outlet property="statusInProgressSpinner" destination="Eab-ND-ix3" id="UuC-eY-MSf"/>
<outlet property="totalView" destination="8I3-n2-0kS" id="aa8-j9-saW"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="UGz-WT-BUv">
<rect key="frame" x="0.0" y="0.0" width="377" height="351"/>
<rect key="frame" x="0.0" y="0.0" width="428" height="321"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<subviews>
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" fixedFrame="YES" image="avatar.png" translatesAutoresizingMaskIntoConstraints="NO" id="hD2-19-7IH" userLabel="avatarImage" customClass="UIRoundedImageView">
<rect key="frame" x="6" y="20" width="27" height="27"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Contact avatar">
<accessibilityTraits key="traits" image="YES" notEnabled="YES"/>
<bool key="isElement" value="YES"/>
</accessibility>
</imageView>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" fixedFrame="YES" text="11:35 John Doe" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="JyR-RQ-uwF" userLabel="contactDateLabel">
<rect key="frame" x="39" y="0.0" width="365" height="20"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Contact name"/>
<fontDescription key="fontDescription" type="system" pointSize="15"/>
<color key="textColor" red="0.6370989801857142" green="0.63511795339999999" blue="0.63681996232857141" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<view clipsSubviews="YES" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Y7i-Gm-AdY" userLabel="innerView">
<rect key="frame" x="6" y="5" width="365" height="341"/>
<rect key="frame" x="39" y="20" width="382" height="297"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView userInteractionEnabled="NO" alpha="0.20000000298023224" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="color_A.png" translatesAutoresizingMaskIntoConstraints="NO" id="U2P-5n-gg8" userLabel="backgroundColorImage">
<rect key="frame" x="0.0" y="0.0" width="365" height="341"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES" flexibleMaxY="YES"/>
<rect key="frame" x="0.0" y="0.0" width="365" height="297"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES" flexibleMaxY="YES"/>
</imageView>
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" fixedFrame="YES" image="avatar.png" translatesAutoresizingMaskIntoConstraints="NO" id="hD2-19-7IH" userLabel="avatarImage" customClass="UIRoundedImageView">
<rect key="frame" x="7" y="7" width="40" height="40"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Contact avatar">
<accessibilityTraits key="traits" image="YES" notEnabled="YES"/>
<bool key="isElement" value="YES"/>
</accessibility>
</imageView>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" fixedFrame="YES" text="11:35 John Doe" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="JyR-RQ-uwF" userLabel="contactDateLabel">
<rect key="frame" x="55" y="8" width="286" height="14"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Contact name"/>
<fontDescription key="fontDescription" type="system" pointSize="12"/>
<color key="textColor" red="0.98766469955444336" green="0.27512490749359131" blue="0.029739789664745331" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="8I3-n2-0kS" userLabel="view">
<rect key="frame" x="39" y="55" width="298" height="230"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES" flexibleMaxY="YES"/>
<rect key="frame" x="27" y="10" width="301" height="252"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES" flexibleMaxY="YES"/>
<subviews>
<imageView contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="linphone_logo.png" translatesAutoresizingMaskIntoConstraints="NO" id="yMW-cT-bpU" userLabel="image" customClass="UILoadingImageView">
<rect key="frame" x="0.0" y="0.0" width="298" height="148"/>
<rect key="frame" x="0.0" y="0.0" width="301" height="161"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES" flexibleMaxY="YES"/>
<gestureRecognizers/>
</imageView>
<view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="GmN-7v-uuO" userLabel="imageSubView">
<rect key="frame" x="0.0" y="155" width="297" height="75"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES"/>
<subviews>
<progressView opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="750" fixedFrame="YES" progress="0.5" translatesAutoresizingMaskIntoConstraints="NO" id="USm-wC-GvG" userLabel="transferProgress">
<rect key="frame" x="10" y="42" width="277" height="2"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
</progressView>
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="N75-gL-R6t" userLabel="downloadButton" customClass="UIRoundBorderedButton">
<rect key="frame" x="84" y="46" width="115" height="27"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES"/>
<accessibility key="accessibilityConfiguration" label="Download"/>
<state key="normal" title="DOWNLOAD" backgroundImage="color_G.png">
<color key="titleColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<connections>
<action selector="onDownloadClick:" destination="-1" eventType="touchUpInside" id="8BO-9E-iOX"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="6dl-Nz-rdv" userLabel="cancelButton" customClass="UIRoundBorderedButton">
<rect key="frame" x="84" y="46" width="115" height="27"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES"/>
<accessibility key="accessibilityConfiguration" label="Cancel"/>
<fontDescription key="fontDescription" type="system" pointSize="15"/>
<state key="normal" title="CANCEL" backgroundImage="color_I.png">
<color key="titleColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="highlighted" backgroundImage="color_M.png"/>
<connections>
<action selector="onCancelClick:" destination="-1" eventType="touchUpInside" id="D9y-vf-I4Y"/>
</connections>
</button>
</subviews>
</view>
</subviews>
</view>
<view clipsSubviews="YES" contentMode="scaleToFill" fixedFrame="YES" preservesSuperviewLayoutMargins="YES" translatesAutoresizingMaskIntoConstraints="NO" id="VYJ-RC-Jmg" userLabel="finalAssetView">
<rect key="frame" x="0.0" y="55" width="365" height="230"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<rect key="frame" x="7" y="10" width="351" height="252"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES" flexibleMaxY="YES"/>
<subviews>
<imageView hidden="YES" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="gzv-K4-5OL" userLabel="finalImage">
<rect key="frame" x="0.0" y="0.0" width="365" height="230"/>
<rect key="frame" x="0.0" y="0.0" width="351" height="262"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<gestureRecognizers/>
</imageView>
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="cvc-tl-Pcf" userLabel="playButton" customClass="UIRoundBorderedButton">
<rect key="frame" x="125" y="93" width="50" height="25"/>
<autoresizingMask key="autoresizingMask"/>
</subviews>
</view>
<view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="GmN-7v-uuO" userLabel="imageSubView">
<rect key="frame" x="31" y="50" width="299" height="87"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES" flexibleMaxY="YES"/>
<subviews>
<progressView opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="750" fixedFrame="YES" progress="0.5" translatesAutoresizingMaskIntoConstraints="NO" id="USm-wC-GvG" userLabel="transferProgress">
<rect key="frame" x="10" y="51" width="277" height="4"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
</progressView>
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="N75-gL-R6t" userLabel="downloadButton" customClass="UIRoundBorderedButton">
<rect key="frame" x="87" y="58" width="113" height="20"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES"/>
<accessibility key="accessibilityConfiguration" label="Download"/>
<state key="normal" title="DOWNLOAD" backgroundImage="color_G.png">
<color key="titleColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<connections>
<action selector="onDownloadClick:" destination="-1" eventType="touchUpInside" id="8BO-9E-iOX"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="6dl-Nz-rdv" userLabel="cancelButton" customClass="UIRoundBorderedButton">
<rect key="frame" x="87" y="58" width="113" height="20"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES"/>
<accessibility key="accessibilityConfiguration" label="Cancel"/>
<fontDescription key="fontDescription" type="system" pointSize="15"/>
<state key="normal" title="PLAY" backgroundImage="color_I.png">
<color key="titleColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<state key="normal" title="CANCEL" backgroundImage="color_I.png">
<color key="titleColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="highlighted" backgroundImage="color_M.png"/>
<connections>
<action selector="onPlayClick:" destination="-1" eventType="touchUpInside" id="B4y-PJ-4tO"/>
<action selector="onCancelClick:" destination="-1" eventType="touchUpInside" id="D9y-vf-I4Y"/>
</connections>
</button>
</subviews>
<connections>
<outletCollection property="gestureRecognizers" destination="aDF-hC-ddO" appends="YES" id="lKJ-ra-dwR"/>
</connections>
</view>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="color_A.png" translatesAutoresizingMaskIntoConstraints="NO" id="6dA-3U-OPW" userLabel="bottomBarColor">
<rect key="frame" x="0.0" y="340" width="365" height="1"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
</imageView>
<activityIndicatorView opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" fixedFrame="YES" hidesWhenStopped="YES" animating="YES" style="gray" translatesAutoresizingMaskIntoConstraints="NO" id="Eab-ND-ix3" userLabel="statusInprogressSpinner">
<rect key="frame" x="345" y="0.0" width="20" height="20"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
</activityIndicatorView>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="chat_unsecure.png" translatesAutoresizingMaskIntoConstraints="NO" id="IST-5o-DCu" userLabel="LIMEKO">
<rect key="frame" x="351" y="6" width="8" height="12"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Delivery failed"/>
</imageView>
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="cvc-tl-Pcf" userLabel="playButton" customClass="UIRoundBorderedButton">
<rect key="frame" x="158" y="106" width="50" height="25"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Cancel"/>
<fontDescription key="fontDescription" type="system" pointSize="15"/>
<state key="normal" title="PLAY" backgroundImage="color_I.png">
<color key="titleColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</state>
<state key="highlighted" backgroundImage="color_M.png"/>
<connections>
<action selector="onPlayClick:" destination="-1" eventType="touchUpInside" id="B4y-PJ-4tO"/>
</connections>
</button>
<textView clipsSubviews="YES" contentMode="scaleToFill" fixedFrame="YES" scrollEnabled="NO" showsHorizontalScrollIndicator="NO" showsVerticalScrollIndicator="NO" editable="NO" text="Lore ipsum..." translatesAutoresizingMaskIntoConstraints="NO" id="cx9-0K-P9L" userLabel="messageText" customClass="UITextViewNoDefine">
<rect key="frame" x="8" y="285" width="349" height="47"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<rect key="frame" x="0.0" y="262" width="365" height="35"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" heightSizable="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<textInputTraits key="textInputTraits" autocapitalizationType="sentences"/>
<dataDetectorType key="dataDetectorTypes" link="YES"/>
</textView>
<label hidden="YES" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Delivered" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="44j-me-Iqi" userLabel="imdmLabel">
<rect key="frame" x="283" y="324" width="64" height="20"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="11"/>
<color key="textColor" red="1" green="0.36862745099999999" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<imageView hidden="YES" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="valid_default.png" translatesAutoresizingMaskIntoConstraints="NO" id="LPj-VT-0fH" userLabel="imdmIcon">
<rect key="frame" x="349" y="326" width="13" height="13"/>
<imageView hidden="YES" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="chat_read.png" translatesAutoresizingMaskIntoConstraints="NO" id="LPj-VT-0fH" userLabel="imdmIcon">
<rect key="frame" x="372" y="287" width="10" height="10"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
<accessibility key="accessibilityConfiguration" label="Delivery failed"/>
</imageView>
<view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="UzU-cc-LbF" userLabel="fileView">
<rect key="frame" x="0.0" y="55" width="280" height="128"/>
<rect key="frame" x="13" y="10" width="230" height="50"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Label" textAlignment="center" lineBreakMode="middleTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="WkE-rP-Y0R" userLabel="fileName">
<rect key="frame" x="25" y="0.0" width="180" height="50"/>
<rect key="frame" x="0.0" y="0.0" width="180" height="50"/>
<autoresizingMask key="autoresizingMask"/>
<color key="backgroundColor" white="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
@ -184,7 +158,7 @@
<nil key="highlightedColor"/>
</label>
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="IGl-nl-xIE" userLabel="fileButton">
<rect key="frame" x="205" y="0.0" width="50" height="50"/>
<rect key="frame" x="180" y="0.0" width="50" height="50"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" red="1" green="0.39905477280000001" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<state key="normal" title="Open"/>
@ -197,13 +171,13 @@
</subviews>
<connections>
<outletCollection property="gestureRecognizers" destination="5ZI-Ip-lGl" appends="YES" id="1iY-46-rRR"/>
<outletCollection property="gestureRecognizers" destination="aDF-hC-ddO" appends="YES" id="FIv-pl-I8J"/>
</connections>
</view>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="simulatedStatusBarMetrics"/>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<point key="canvasLocation" x="-73.5" y="271.5"/>
<point key="canvasLocation" x="-117.59999999999999" y="244.22788605697153"/>
</view>
<tapGestureRecognizer id="5ZI-Ip-lGl" userLabel="resendClick">
<connections>
@ -218,12 +192,11 @@
</objects>
<resources>
<image name="avatar.png" width="259" height="259"/>
<image name="chat_unsecure.png" width="18" height="27"/>
<image name="chat_read.png" width="25" height="25"/>
<image name="color_A.png" width="2" height="2"/>
<image name="color_G.png" width="2" height="2"/>
<image name="color_I.png" width="2" height="2"/>
<image name="color_M.png" width="2" height="2"/>
<image name="linphone_logo.png" width="26" height="26"/>
<image name="valid_default.png" width="28" height="19"/>
</resources>
</document>

View file

@ -11,85 +11,54 @@
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="UIChatBubbleTextCell">
<connections>
<outlet property="LIMEKO" destination="PqI-MR-8GC" id="tHK-Bp-80H"/>
<outlet property="avatarImage" destination="P1c-sD-eOv" id="h5P-hl-jbX"/>
<outlet property="avatarImage" destination="hBI-Xz-aEV" id="dta-af-tMe"/>
<outlet property="backgroundColorImage" destination="ZIO-Cb-28G" id="asA-a1-Rko"/>
<outlet property="bottomBarColor" destination="mlr-pl-B6T" id="4Lk-Vn-E8h"/>
<outlet property="bubbleView" destination="ucH-2r-rar" id="XWU-yi-1z8"/>
<outlet property="contactDateLabel" destination="GRe-ur-aSb" id="DQA-v4-IjX"/>
<outlet property="imdmIcon" destination="WlS-fU-Aut" id="bYC-jb-Amo"/>
<outlet property="imdmLabel" destination="yKD-pC-Nhu" id="ge9-Yl-qsr"/>
<outlet property="contactDateLabel" destination="OwE-p1-L0T" id="0lh-E9-7wp"/>
<outlet property="imdmIcon" destination="Nod-GX-0kg" id="Pa7-l6-pGh"/>
<outlet property="innerView" destination="vdk-RV-QRU" id="wQs-CR-Pm3"/>
<outlet property="messageText" destination="CYa-If-oB4" id="7xm-UF-1qB"/>
<outlet property="statusInProgressSpinner" destination="4Z8-PE-uPe" id="T9k-9x-DeB"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" misplaced="YES" id="ucH-2r-rar">
<rect key="frame" x="0.0" y="0.0" width="334" height="74"/>
<rect key="frame" x="0.0" y="0.0" width="189" height="64"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<subviews>
<imageView hidden="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" misplaced="YES" image="avatar.png" id="hBI-Xz-aEV" userLabel="avatarImage" customClass="UIRoundedImageView">
<rect key="frame" x="6" y="20" width="27" height="27"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
</imageView>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" misplaced="YES" text="11:35 John Doe" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="OwE-p1-L0T" userLabel="contactDateLabel">
<rect key="frame" x="39" y="0.0" width="126" height="18"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Contact name"/>
<fontDescription key="fontDescription" type="system" pointSize="15"/>
<color key="textColor" red="0.63529411764705879" green="0.63529411764705879" blue="0.63529411764705879" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<view clipsSubviews="YES" contentMode="scaleToFill" misplaced="YES" id="vdk-RV-QRU" userLabel="innerView">
<rect key="frame" x="6" y="9" width="322" height="56"/>
<rect key="frame" x="39" y="20" width="143" height="40"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView userInteractionEnabled="NO" alpha="0.20000000000000001" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="color_A.png" id="ZIO-Cb-28G" userLabel="backgroundColorImage">
<rect key="frame" x="0.0" y="0.0" width="322" height="56"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES" flexibleMaxY="YES"/>
</imageView>
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" image="avatar.png" id="P1c-sD-eOv" userLabel="avatarImage" customClass="UIRoundedImageView">
<rect key="frame" x="7" y="7" width="40" height="40"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Contact avatar">
<accessibilityTraits key="traits" image="YES" notEnabled="YES"/>
<bool key="isElement" value="YES"/>
</accessibility>
</imageView>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="11:35 John Doe" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="GRe-ur-aSb" userLabel="contactDateLabel">
<rect key="frame" x="55" y="8" width="246" height="14"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Contact name"/>
<fontDescription key="fontDescription" type="system" pointSize="12"/>
<color key="textColor" red="0.98766469955444336" green="0.27512490749359131" blue="0.029739789664745331" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<activityIndicatorView opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" hidesWhenStopped="YES" animating="YES" style="gray" id="4Z8-PE-uPe" userLabel="statusInprogressSpinner">
<rect key="frame" x="302" y="0.0" width="20" height="20"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
</activityIndicatorView>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="color_A.png" id="mlr-pl-B6T" userLabel="bottomBarColor">
<rect key="frame" x="0.0" y="55" width="322" height="1"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<imageView userInteractionEnabled="NO" alpha="0.20000000000000001" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" image="color_A.png" id="ZIO-Cb-28G" userLabel="backgroundColorImage">
<rect key="frame" x="0.0" y="0.0" width="126" height="40"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES" flexibleMaxY="YES"/>
</imageView>
<textView clipsSubviews="YES" contentMode="scaleToFill" misplaced="YES" scrollEnabled="NO" showsHorizontalScrollIndicator="NO" showsVerticalScrollIndicator="NO" editable="NO" text="Lore ipsum..." id="CYa-If-oB4" userLabel="messageText" customClass="UITextViewNoDefine">
<rect key="frame" x="50" y="15" width="279" height="49"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES" flexibleMaxY="YES"/>
<rect key="frame" x="0.0" y="0.0" width="126" height="40"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" heightSizable="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<textInputTraits key="textInputTraits" autocapitalizationType="sentences"/>
<dataDetectorType key="dataDetectorTypes" link="YES"/>
</textView>
<imageView hidden="YES" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" image="chat_unsecure.png" id="PqI-MR-8GC" userLabel="LIMEKO">
<rect key="frame" x="308" y="4" width="8" height="12"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Delivery failed"/>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" text="Read" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="yKD-pC-Nhu" userLabel="imdmLabel">
<rect key="frame" x="238" y="39" width="64" height="20"/>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" image="chat_read.png" id="Nod-GX-0kg" userLabel="imdmIcon">
<rect key="frame" x="133" y="30" width="10" height="10"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
<fontDescription key="fontDescription" name=".AppleSystemUIFont" family=".AppleSystemUIFont" pointSize="11"/>
<color key="textColor" red="1" green="0.36862745099999999" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" image="chat_read.png" id="WlS-fU-Aut" userLabel="imdmIcon">
<rect key="frame" x="306" y="41" width="13" height="13"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
<accessibility key="accessibilityConfiguration" label="Delivery failed">
<accessibilityTraits key="traits" button="YES" image="YES"/>
</accessibility>
</imageView>
</subviews>
</view>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="simulatedStatusBarMetrics"/>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<point key="canvasLocation" x="16" y="110"/>
@ -97,8 +66,7 @@
</objects>
<resources>
<image name="avatar.png" width="259" height="259"/>
<image name="chat_read.png" width="24" height="24"/>
<image name="chat_unsecure.png" width="18" height="27"/>
<image name="chat_read.png" width="25" height="25"/>
<image name="color_A.png" width="2" height="2"/>
</resources>
</document>

View file

@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14113" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" colorMatched="YES">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" colorMatched="YES">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14088"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14490.49"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
@ -16,40 +16,45 @@
<outlet property="chatContentLabel" destination="21" id="24"/>
<outlet property="chatLatestTimeLabel" destination="r7A-Mk-LQX" id="J0r-yr-YLk"/>
<outlet property="imdmIcon" destination="aa2-Kl-c1H" id="rnr-XY-r9K"/>
<outlet property="securityImage" destination="kdl-Ln-eWv" id="S9v-cN-u4w"/>
<outlet property="unreadCountLabel" destination="ZXq-Do-7Ua" id="anx-Na-sYz"/>
<outlet property="unreadCountView" destination="7DE-KJ-9Q3" id="hkt-rA-EKa"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="17">
<rect key="frame" x="0.0" y="0.0" width="375" height="60"/>
<rect key="frame" x="0.0" y="0.0" width="375" height="86"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" image="avatar.png" id="19" userLabel="avatarImage" customClass="UIRoundedImageView">
<rect key="frame" x="8" y="2" width="43" height="43"/>
<rect key="frame" x="10" y="11" width="42" height="42"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
</imageView>
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" image="security_1_indicator.png" id="kdl-Ln-eWv" userLabel="securityImage">
<rect key="frame" x="41" y="11" width="18" height="22"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
</imageView>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" tag="2" contentMode="left" text="11:15" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="2" minimumFontSize="1" id="r7A-Mk-LQX" userLabel="chatLatestTimeLabel">
<rect key="frame" x="8" y="45" width="43" height="15"/>
<rect key="frame" x="8" y="57" width="44" height="19"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label=""/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="25"/>
<color key="textColor" red="0.98766469955444336" green="0.27512490749359131" blue="0.029739789664745331" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" tag="2" contentMode="left" text="John Doe" lineBreakMode="tailTruncation" minimumFontSize="10" adjustsFontSizeToFit="NO" id="20" userLabel="addressLabel">
<rect key="frame" x="59" y="0.0" width="275" height="31"/>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" tag="2" contentMode="left" text="John Doe" lineBreakMode="tailTruncation" adjustsFontSizeToFit="NO" id="20" userLabel="addressLabel">
<rect key="frame" x="69" y="17" width="255" height="23"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Contact name"/>
<fontDescription key="fontDescription" type="system" pointSize="25"/>
<fontDescription key="fontDescription" name=".SFNSDisplay" family=".SF NS Display" pointSize="21"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<view hidden="YES" autoresizesSubviews="NO" userInteractionEnabled="NO" tag="7" contentMode="scaleToFill" id="7DE-KJ-9Q3" userLabel="unreadCountView" customClass="UIBouncingView">
<rect key="frame" x="350" y="7" width="21" height="22"/>
<rect key="frame" x="350" y="12" width="21" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
<subviews>
<imageView userInteractionEnabled="NO" tag="8" contentMode="scaleAspectFit" image="history_chat_indicator.png" id="NXj-A8-YLh" userLabel="unreadCountImage">
<imageView userInteractionEnabled="NO" tag="8" contentMode="scaleAspectFit" image="chat_list_indicator.png" id="NXj-A8-YLh" userLabel="unreadCountImage">
<rect key="frame" x="0.0" y="0.0" width="21" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
</imageView>
@ -67,30 +72,31 @@
</subviews>
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
</view>
<imageView hidden="YES" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" image="chat_read.png" id="aa2-Kl-c1H" userLabel="imdmIcon">
<rect key="frame" x="59" y="39" width="13" height="13"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<imageView hidden="YES" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="chat_read.png" id="aa2-Kl-c1H" userLabel="imdmIcon">
<rect key="frame" x="69" y="55" width="13" height="13"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES"/>
<accessibility key="accessibilityConfiguration" label="Delivery failed">
<accessibilityTraits key="traits" button="YES" image="YES"/>
</accessibility>
</imageView>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" tag="2" contentMode="left" misplaced="YES" text="This is a placeholder message" lineBreakMode="tailTruncation" numberOfLines="3" adjustsFontSizeToFit="NO" id="21" userLabel="chatContentLabel">
<rect key="frame" x="80" y="31" width="316" height="29"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES"/>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" tag="2" contentMode="left" text="This is a placeholder message" lineBreakMode="tailTruncation" numberOfLines="2" adjustsFontSizeToFit="NO" id="21" userLabel="chatContentLabel">
<rect key="frame" x="85" y="43" width="262" height="37"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" heightSizable="YES"/>
<accessibility key="accessibilityConfiguration" label="Message"/>
<fontDescription key="fontDescription" type="system" pointSize="12"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<nil key="simulatedStatusBarMetrics"/>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<point key="canvasLocation" x="156.5" y="240"/>
<point key="canvasLocation" x="226.81159420289856" y="160.71428571428569"/>
</view>
</objects>
<resources>
<image name="avatar.png" width="259" height="259"/>
<image name="chat_read.png" width="24" height="24"/>
<image name="history_chat_indicator.png" width="14" height="13"/>
<image name="avatar.png" width="414.39999389648438" height="414.39999389648438"/>
<image name="chat_list_indicator.png" width="28" height="28"/>
<image name="chat_read.png" width="20" height="20"/>
<image name="security_1_indicator.png" width="27.5" height="32.5"/>
</resources>
</document>

View file

@ -1,59 +1,77 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14109" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" colorMatched="YES">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" colorMatched="YES">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14088"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14460.20"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="UIChatCreateCell">
<connections>
<outlet property="addressLabel" destination="Bjy-H9-VyJ" id="YFi-IY-Omd"/>
<outlet property="avatarImage" destination="ktO-jm-Ra6" id="IFH-3K-TdW"/>
<outlet property="displayNameLabel" destination="Hrt-Iz-T2j" id="0tY-FY-dFe"/>
<outlet property="greyView" destination="THU-mJ-O0r" id="2Gs-TQ-tNh"/>
<outlet property="linphoneImage" destination="vhd-fK-M2m" id="hO8-lY-0Hh"/>
<outlet property="securityImage" destination="ioo-eB-vvQ" id="WXu-ej-Nfi"/>
<outlet property="selectedImage" destination="qMd-eD-DOW" id="m79-nU-deW"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="WTc-GF-a0y">
<rect key="frame" x="0.0" y="0.0" width="375" height="40"/>
<rect key="frame" x="0.0" y="0.0" width="375" height="60"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" text="john.doe@linphone.org" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="Bjy-H9-VyJ" userLabel="addressLabel">
<rect key="frame" x="3" y="22" width="303" height="16"/>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="john.doe@linphone.org" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="Bjy-H9-VyJ" userLabel="addressLabel">
<rect key="frame" x="65" y="30" width="238" height="22"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.98766469955444336" green="0.27512490749359131" blue="0.029739789664745331" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" text="John Doe" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="Hrt-Iz-T2j" userLabel="displayNameLabel">
<rect key="frame" x="3" y="0.0" width="303" height="22"/>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="John Doe" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="Hrt-Iz-T2j" userLabel="displayNameLabel">
<rect key="frame" x="65" y="6" width="238" height="28"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
<nil key="highlightedColor"/>
</label>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" misplaced="YES" image="check_selected.png" id="qMd-eD-DOW" userLabel="selectedImage">
<rect key="frame" x="347" y="9" width="21" height="22"/>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" image="check_selected.png" id="qMd-eD-DOW" userLabel="selectedImage">
<rect key="frame" x="347" y="21" width="21" height="22"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
</imageView>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" misplaced="YES" image="linphone_user.png" id="vhd-fK-M2m" userLabel="linphoneImage">
<rect key="frame" x="314" y="8" width="25" height="25"/>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" image="linphone_user.png" id="vhd-fK-M2m" userLabel="linphoneImage">
<rect key="frame" x="314" y="21" width="21" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Linphone"/>
</imageView>
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" image="avatar.png" id="ktO-jm-Ra6" userLabel="avatarImage" customClass="UIRoundedImageView">
<rect key="frame" x="10" y="10" width="40" height="40"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
</imageView>
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" image="security_toogle_icon_green.png" id="ioo-eB-vvQ" userLabel="securityImage">
<rect key="frame" x="40" y="11" width="18" height="23"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
</imageView>
<view hidden="YES" contentMode="scaleToFill" id="THU-mJ-O0r" userLabel="greyView">
<rect key="frame" x="0.0" y="0.0" width="375" height="60"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="0.7032625440140845" colorSpace="custom" customColorSpace="sRGB"/>
</view>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="simulatedStatusBarMetrics"/>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<point key="canvasLocation" x="556.5" y="214"/>
<point key="canvasLocation" x="890.39999999999998" y="192.50374812593705"/>
</view>
</objects>
<resources>
<image name="avatar.png" width="259" height="259"/>
<image name="check_selected.png" width="47" height="32"/>
<image name="linphone_user.png" width="26" height="26"/>
<image name="security_toogle_icon_green.png" width="21" height="24"/>
</resources>
</document>

View file

@ -1,56 +1,89 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="9531" systemVersion="15C50" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none">
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" colorMatched="YES">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="9529"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14460.20"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="UIConfirmationDialog">
<connections>
<outlet property="authButton" destination="lWW-wB-FMR" id="C7W-JM-WFQ"/>
<outlet property="authView" destination="CCn-Oz-I0M" id="fSM-6k-paN"/>
<outlet property="cancelButton" destination="B1K-CB-3of" id="KKi-Xc-ldA"/>
<outlet property="confirmationButton" destination="SbQ-re-fGQ" id="yiv-a9-o8E"/>
<outlet property="securityImage" destination="bbo-g3-bGy" id="qZa-li-yrl"/>
<outlet property="titleLabel" destination="jLz-g1-cTe" id="qaj-OB-2r1"/>
<outlet property="view" destination="2Vb-Xy-rci" id="nNw-EJ-AY3"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="2Vb-Xy-rci" userLabel="view">
<rect key="frame" x="0.0" y="0.0" width="414" height="736"/>
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView userInteractionEnabled="NO" alpha="0.89999999999999991" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="color_C.png" id="cqN-1f-6SE" userLabel="backgroundColor">
<rect key="frame" x="0.0" y="0.0" width="416" height="736"/>
<rect key="frame" x="0.0" y="0.0" width="377" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
</imageView>
<view contentMode="scaleToFill" id="2BQ-o9-xv2">
<rect key="frame" x="48" y="285" width="320" height="166"/>
<rect key="frame" x="28" y="139" width="320" height="365"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Are you sure you want to delete all your selection?" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="4" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" id="jLz-g1-cTe" userLabel="titleLabel">
<rect key="frame" x="-10" y="0.0" width="336" height="118"/>
<imageView hidden="YES" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" insetsLayoutMarginsFromSafeArea="NO" image="security_2_indicator.png" id="bbo-g3-bGy" userLabel="securityImage">
<rect key="frame" x="130" y="0.0" width="56" height="68"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Are you sure you want to delete all your selection?" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" id="jLz-g1-cTe" userLabel="titleLabel">
<rect key="frame" x="-10" y="15" width="336" height="279"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
<fontDescription key="fontDescription" type="system" pointSize="21"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" id="B1K-CB-3of" userLabel="cancelButton" customClass="UIRoundBorderedButton">
<rect key="frame" x="7" y="126" width="142" height="40"/>
<rect key="frame" x="8" y="308" width="139" height="42"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<state key="normal" title="CANCEL" backgroundImage="color_H.png">
<color key="titleColor" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
<color key="titleColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="highlighted" backgroundImage="color_F.png"/>
<connections>
<action selector="onCancelClick:" destination="-1" eventType="touchUpInside" id="LvF-N2-56g"/>
</connections>
</button>
<view hidden="YES" contentMode="scaleToFill" id="CCn-Oz-I0M" userLabel="authView">
<rect key="frame" x="61" y="273" width="240" height="27"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="lWW-wB-FMR" userLabel="authButton">
<rect key="frame" x="26" y="2" width="17" height="22"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<state key="normal" image="checkbox_unchecked.png"/>
<state key="selected" image="checkbox_checked.png"/>
<connections>
<action selector="onAuthClick:" destination="-1" eventType="touchUpInside" id="9A4-ZX-cXA"/>
</connections>
</button>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Do not show again" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="dQL-Sf-slc">
<rect key="frame" x="55" y="2" width="176" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</view>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" id="SbQ-re-fGQ" userLabel="confirmationButton" customClass="UIRoundBorderedButton">
<rect key="frame" x="169" y="126" width="142" height="40"/>
<rect key="frame" x="169" y="308" width="143" height="42"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<state key="normal" title="DELETE" backgroundImage="color_I.png">
<color key="titleColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
<color key="titleColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="highlighted" backgroundImage="color_M.png"/>
<connections>
@ -60,17 +93,19 @@
</subviews>
</view>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="simulatedStatusBarMetrics"/>
<simulatedScreenMetrics key="simulatedDestinationMetrics" type="retina55"/>
<point key="canvasLocation" x="545" y="291"/>
<point key="canvasLocation" x="872" y="261.76911544227886"/>
</view>
</objects>
<resources>
<image name="checkbox_checked.png" width="17" height="17"/>
<image name="checkbox_unchecked.png" width="17" height="17"/>
<image name="color_C.png" width="2" height="2"/>
<image name="color_F.png" width="2" height="2"/>
<image name="color_H.png" width="2" height="2"/>
<image name="color_I.png" width="2" height="2"/>
<image name="color_M.png" width="2" height="2"/>
<image name="security_2_indicator.png" width="27" height="32"/>
</resources>
</document>

View file

@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14109" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" colorMatched="YES">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" colorMatched="YES">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14088"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14460.20"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
@ -18,7 +18,10 @@
<outlet property="deleteButton" destination="C2f-aP-xjR" id="sxr-th-6rq"/>
<outlet property="editTextfield" destination="dTn-Hc-bGM" id="bkN-xg-S9D"/>
<outlet property="editView" destination="rAa-qu-PDc" id="cGz-D2-GiI"/>
<outlet property="encryptedChatView" destination="ERg-IK-XJX" id="Aam-pm-R6d"/>
<outlet property="inviteButton" destination="lgb-5W-T0c" id="iOl-Fl-AXH"/>
<outlet property="linphoneImage" destination="ZaI-29-AOK" id="dY1-vO-spk"/>
<outlet property="optionsView" destination="Ffn-KZ-0pX" id="spM-xw-9ri"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
@ -58,50 +61,91 @@
<rect key="frame" x="0.0" y="0.0" width="375" height="88"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<subviews>
<button opaque="NO" contentMode="scaleAspectFit" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="ZbV-2Z-b4y" userLabel="callButton" customClass="UIIconButton">
<rect key="frame" x="135" y="40" width="44" height="44"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES"/>
<accessibility key="accessibilityConfiguration" label="Call"/>
<state key="normal" image="call_start_body_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="call_start_body_disabled.png"/>
<state key="highlighted" image="call_start_body_over.png"/>
<connections>
<action selector="onCallClick:" destination="-1" eventType="touchUpInside" id="nVk-zG-i8I"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleAspectFit" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="FDT-HY-OQZ" userLabel="chatButton" customClass="UIIconButton">
<rect key="frame" x="195" y="40" width="44" height="44"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES"/>
<accessibility key="accessibilityConfiguration" label="Chat"/>
<state key="normal" image="chat_start_body_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="chat_start_body_disabled.png"/>
<state key="highlighted" image="chat_start_body_over.png"/>
<connections>
<action selector="onChatClick:" destination="-1" eventType="touchUpInside" id="tec-tH-uij"/>
</connections>
</button>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="john.doe@sip.linphone.org" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="frB-ep-LWi" userLabel="addressLabel">
<rect key="frame" x="8" y="0.0" width="359" height="44"/>
<rect key="frame" x="26" y="0.0" width="323" height="44"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" misplaced="YES" image="linphone_user.png" id="ZaI-29-AOK" userLabel="linphoneImage">
<rect key="frame" x="342" y="51" width="25" height="25"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" image="linphone_user.png" id="ZaI-29-AOK" userLabel="linphoneImage">
<rect key="frame" x="329" y="18" width="17" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
</imageView>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="lgb-5W-T0c">
<rect key="frame" x="314" y="14" width="47" height="20"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Invite"/>
<fontDescription key="fontDescription" type="system" pointSize="15"/>
<state key="normal" title="Invite">
<color key="titleColor" red="1" green="0.36738281249999999" blue="0.0" alpha="0.84999999999999998" colorSpace="calibratedRGB"/>
</state>
<connections>
<action selector="onSMSInviteClick:" destination="-1" eventType="touchUpInside" id="E8o-h2-mml"/>
</connections>
</button>
<view contentMode="scaleToFill" id="Ffn-KZ-0pX" userLabel="optionsView">
<rect key="frame" x="26" y="40" width="323" height="44"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<button opaque="NO" contentMode="scaleAspectFit" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="ZbV-2Z-b4y" userLabel="callButton" customClass="UIIconButton">
<rect key="frame" x="79" y="0.0" width="44" height="44"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES"/>
<accessibility key="accessibilityConfiguration" label="Call"/>
<state key="normal" image="call_start_body_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="call_start_body_disabled.png"/>
<state key="highlighted" image="call_start_body_over.png"/>
<connections>
<action selector="onCallClick:" destination="-1" eventType="touchUpInside" id="nVk-zG-i8I"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleAspectFit" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="FDT-HY-OQZ" userLabel="chatButton" customClass="UIIconButton">
<rect key="frame" x="139" y="0.0" width="44" height="44"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES"/>
<accessibility key="accessibilityConfiguration" label="Chat"/>
<state key="normal" image="chat_start_body_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="chat_start_body_disabled.png"/>
<state key="highlighted" image="chat_start_body_over.png"/>
<connections>
<action selector="onChatClick:" destination="-1" eventType="touchUpInside" id="tec-tH-uij"/>
</connections>
</button>
<view contentMode="scaleToFill" id="ERg-IK-XJX" userLabel="encryptedChatView">
<rect key="frame" x="199" y="0.0" width="44" height="44"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES"/>
<subviews>
<button opaque="NO" contentMode="scaleAspectFit" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="Red-NG-DKu" userLabel="encryptedChatButton" customClass="UIIconButton">
<rect key="frame" x="0.0" y="0.0" width="44" height="44"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES"/>
<accessibility key="accessibilityConfiguration" label="Chat"/>
<state key="normal" image="chat_start_body_default.png">
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<state key="disabled" image="chat_start_body_disabled.png"/>
<state key="highlighted" image="chat_start_body_over.png"/>
<connections>
<action selector="onEncrptedChatClick:" destination="-1" eventType="touchUpInside" id="5IN-7c-QWf"/>
</connections>
</button>
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" image="security_toogle_icon_green.png" id="Vk5-LN-LHu" userLabel="securityImage">
<rect key="frame" x="30" y="0.0" width="18" height="22"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
</imageView>
</subviews>
</view>
</subviews>
</view>
</subviews>
</view>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="simulatedStatusBarMetrics"/>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<point key="canvasLocation" x="338.5" y="43"/>
<point key="canvasLocation" x="541.60000000000002" y="38.680659670164921"/>
</view>
</objects>
<resources>
@ -114,5 +158,6 @@
<image name="delete_field_default.png" width="27" height="27"/>
<image name="delete_field_over.png" width="27" height="27"/>
<image name="linphone_user.png" width="26" height="26"/>
<image name="security_toogle_icon_green.png" width="21" height="24"/>
</resources>
</document>

View file

@ -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];
}
}
}

View file

@ -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<PHAsset *> *assets = [PHAsset fetchAssetsWithLocalIdentifiers:[NSArray arrayWithObject:key] options:nil];
PHFetchResult<PHAsset *> *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

View file

@ -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<ChatConversationDelegate> 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;

View file

@ -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<PHAsset *> *assets = [PHAsset fetchAssetsWithLocalIdentifiers:[NSArray arrayWithObject:localImage] options:nil];
PHFetchResult<PHAsset *> *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<PHAsset *> *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;
}

View file

@ -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;

View file

@ -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;
}

View file

@ -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;

View file

@ -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;
}

View file

@ -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

View file

@ -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];
}

View file

@ -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;
}

View file

@ -18,6 +18,7 @@
*/
#import <UIKit/UIKit.h>
#import <MessageUI/MessageUI.h>
#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

View file

@ -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

View file

@ -0,0 +1,20 @@
//
// UIDeviceCell.h
// linphone
//
// Created by Danmei Chen on 07/11/2018.
//
#import <UIKit/UIKit.h>
@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

View file

@ -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

View file

@ -0,0 +1,55 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14460.20"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="UIDeviceCell">
<connections>
<outlet property="deviceLabel" destination="7tu-QT-9B2" id="HXh-Cw-5Lo"/>
<outlet property="securityButton" destination="I16-aS-Ah2" id="rmi-B5-zMM"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="Sro-AN-vkC">
<rect key="frame" x="0.0" y="0.0" width="375" height="56"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="color_F.png" translatesAutoresizingMaskIntoConstraints="NO" id="GKq-qB-nT7" userLabel="selectedButtonImage">
<rect key="frame" x="0.0" y="55" width="375" height="1"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
</imageView>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" tag="2" contentMode="left" fixedFrame="YES" text="John Doe" lineBreakMode="tailTruncation" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="7tu-QT-9B2" userLabel="deviceLabel">
<rect key="frame" x="69" y="16" width="220" height="24"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Contact name"/>
<fontDescription key="fontDescription" name=".SFNSDisplay" family=".SF NS Display" pointSize="21"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="I16-aS-Ah2" userLabel="securityButton">
<rect key="frame" x="336" y="17" width="18" height="22"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
<state key="normal" image="security_1_indicator.png"/>
<connections>
<action selector="onSecurityCallClick:" destination="-1" eventType="touchUpInside" id="yLI-cZ-jfY"/>
</connections>
</button>
</subviews>
<nil key="simulatedStatusBarMetrics"/>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<viewLayoutGuide key="safeArea" id="Yad-Bp-jOq"/>
<point key="canvasLocation" x="250.40000000000001" y="215.8920539730135"/>
</view>
</objects>
<resources>
<image name="color_F.png" width="2" height="2"/>
<image name="security_1_indicator.png" width="27" height="32"/>
</resources>
</document>

View file

@ -0,0 +1,24 @@
//
// UIDevicesDetails.h
// linphone
//
// Created by Danmei Chen on 06/11/2018.
//
#import <UIKit/UIKit.h>
@interface UIDevicesDetails : UITableViewCell <UITableViewDelegate, UITableViewDataSource>
@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

View file

@ -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

View file

@ -0,0 +1,80 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14460.20"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="UIDevicesDetails">
<connections>
<outlet property="addressLabel" destination="X0O-yd-2qT" id="QJ7-lu-E5n"/>
<outlet property="avatarImage" destination="gUM-dT-1wZ" id="WPF-6b-5Hv"/>
<outlet property="devicesTable" destination="Bhw-SW-cbz" id="Fc6-BV-RrV"/>
<outlet property="dropMenuButton" destination="fqu-53-vFp" id="qwN-sh-50p"/>
<outlet property="securityButton" destination="exm-bi-aEL" id="Ht8-LX-ag7"/>
<outlet property="securityImage" destination="kEm-qC-OwR" id="SYs-Vr-JdZ"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="wsb-SF-TOc">
<rect key="frame" x="0.0" y="0.0" width="375" height="156"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="color_F.png" translatesAutoresizingMaskIntoConstraints="NO" id="Uvg-tA-8Jm" userLabel="selectedButtonImage">
<rect key="frame" x="0.0" y="55" width="375" height="1"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
</imageView>
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" fixedFrame="YES" image="avatar.png" translatesAutoresizingMaskIntoConstraints="NO" id="gUM-dT-1wZ" userLabel="avatarImage" customClass="UIRoundedImageView">
<rect key="frame" x="14" y="8" width="40" height="40"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
</imageView>
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" fixedFrame="YES" image="security_1_indicator.png" translatesAutoresizingMaskIntoConstraints="NO" id="kEm-qC-OwR" userLabel="securityImage">
<rect key="frame" x="41" y="8" width="18" height="22"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
</imageView>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" tag="2" contentMode="left" fixedFrame="YES" text="John Doe" lineBreakMode="tailTruncation" minimumFontSize="1" translatesAutoresizingMaskIntoConstraints="NO" id="X0O-yd-2qT" userLabel="addressLabel">
<rect key="frame" x="69" y="16" width="237" height="24"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" label="Contact name"/>
<fontDescription key="fontDescription" name=".SFNSDisplay" family=".SF NS Display" pointSize="21"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="fqu-53-vFp" userLabel="dropMenuButton">
<rect key="frame" x="336" y="24" width="18" height="10"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
<state key="normal" image="chevron_list_close.png"/>
</button>
<button hidden="YES" opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="exm-bi-aEL" userLabel="securityButton">
<rect key="frame" x="336" y="17" width="18" height="22"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
<state key="normal" image="security_1_indicator.png"/>
<connections>
<action selector="onSecurityCallClick:" destination="-1" eventType="touchUpInside" id="D1A-3d-K60"/>
</connections>
</button>
<tableView clipsSubviews="YES" contentMode="scaleToFill" fixedFrame="YES" alwaysBounceVertical="YES" style="plain" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="28" sectionFooterHeight="28" translatesAutoresizingMaskIntoConstraints="NO" id="Bhw-SW-cbz">
<rect key="frame" x="0.0" y="56" width="375" height="100"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" red="0.95887276789999998" green="0.96116071430000005" blue="0.95979352679999996" alpha="1" colorSpace="calibratedRGB"/>
<color key="sectionIndexBackgroundColor" red="0.95892507685714279" green="0.95990397074285716" blue="0.96240171367142868" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</tableView>
</subviews>
<nil key="simulatedStatusBarMetrics"/>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<viewLayoutGuide key="safeArea" id="TKU-h3-Vmo"/>
<point key="canvasLocation" x="250.40000000000001" y="215.8920539730135"/>
</view>
</objects>
<resources>
<image name="avatar.png" width="259" height="259"/>
<image name="chevron_list_close.png" width="17" height="10"/>
<image name="color_F.png" width="2" height="2"/>
<image name="security_1_indicator.png" width="27" height="32"/>
</resources>
</document>

View file

@ -0,0 +1,26 @@
//
// UILinphoneAudioPlayer.h
// linphone
//
// Created by David Idmansour on 13/07/2018.
//
#import <UIKit/UIKit.h>
@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

View file

@ -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

View file

@ -0,0 +1,85 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14113" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14088"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="UILinphoneAudioPlayer">
<connections>
<outlet property="playButton" destination="DUO-wG-b7H" id="Yb4-v3-wo2"/>
<outlet property="stopButton" destination="FXh-QI-38P" id="JUI-lL-g0e"/>
<outlet property="timeLabel" destination="YhA-gd-k7i" id="sLG-Mu-eAV"/>
<outlet property="timeProgress" destination="Un6-Ly-zHN" id="jpN-bN-hba"/>
<outlet property="view" destination="i5M-Pr-FkT" id="sfx-zR-JGt"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view clearsContextBeforeDrawing="NO" contentMode="scaleToFill" id="i5M-Pr-FkT">
<rect key="frame" x="0.0" y="0.0" width="375" height="244"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="DUO-wG-b7H">
<rect key="frame" x="10" y="112" width="20" height="20"/>
<constraints>
<constraint firstAttribute="width" constant="20" id="0Ih-RU-H6C"/>
<constraint firstAttribute="height" constant="20" id="SxX-FF-vrP"/>
</constraints>
<color key="tintColor" white="0.33333333333333331" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<state key="normal" title="Play"/>
<connections>
<action selector="onPlay:" destination="-1" eventType="touchUpInside" id="mdn-z8-Vx0"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="FXh-QI-38P">
<rect key="frame" x="40" y="112" width="20" height="20"/>
<gestureRecognizers/>
<constraints>
<constraint firstAttribute="height" constant="20" id="L60-0M-7lU"/>
<constraint firstAttribute="width" constant="20" id="XbH-oS-0HR"/>
</constraints>
<color key="tintColor" white="0.33333333329999998" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<state key="normal" title="Stop"/>
<connections>
<action selector="onStop:" destination="-1" eventType="touchUpInside" id="DwC-vv-yxp"/>
</connections>
</button>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="00:00 / 00:00" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="YhA-gd-k7i">
<rect key="frame" x="275.5" y="113" width="89.5" height="17"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<progressView opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Un6-Ly-zHN">
<rect key="frame" x="70" y="121" width="195.5" height="2"/>
</progressView>
</subviews>
<gestureRecognizers/>
<constraints>
<constraint firstItem="Un6-Ly-zHN" firstAttribute="centerY" secondItem="i5M-Pr-FkT" secondAttribute="centerY" id="BWM-Qg-HeY"/>
<constraint firstItem="YhA-gd-k7i" firstAttribute="leading" secondItem="Un6-Ly-zHN" secondAttribute="trailing" constant="10" id="G9J-X5-6oS"/>
<constraint firstItem="FXh-QI-38P" firstAttribute="centerY" secondItem="i5M-Pr-FkT" secondAttribute="centerY" id="NRb-Ss-DJM"/>
<constraint firstItem="DUO-wG-b7H" firstAttribute="leading" secondItem="i5M-Pr-FkT" secondAttribute="leading" constant="10" id="Oph-fo-dql"/>
<constraint firstItem="YhA-gd-k7i" firstAttribute="centerY" secondItem="i5M-Pr-FkT" secondAttribute="centerY" id="bPH-p6-5Ld"/>
<constraint firstItem="FXh-QI-38P" firstAttribute="leading" secondItem="DUO-wG-b7H" secondAttribute="trailing" constant="10" id="beC-Uz-QCv"/>
<constraint firstItem="Un6-Ly-zHN" firstAttribute="leading" secondItem="FXh-QI-38P" secondAttribute="trailing" constant="10" id="gcp-l1-wUa"/>
<constraint firstItem="DUO-wG-b7H" firstAttribute="centerY" secondItem="i5M-Pr-FkT" secondAttribute="centerY" id="rwM-cP-iOM"/>
<constraint firstAttribute="trailing" secondItem="YhA-gd-k7i" secondAttribute="trailing" constant="10" id="yxZ-qn-Oyi"/>
</constraints>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<connections>
<outletCollection property="gestureRecognizers" destination="gGk-Ya-vJQ" appends="YES" id="SS3-4b-5sv"/>
</connections>
<point key="canvasLocation" x="24.5" y="-160"/>
</view>
<tapGestureRecognizer id="gGk-Ya-vJQ" userLabel="onTapRecognizer">
<connections>
<action selector="onTapTimeBar:" destination="-1" id="2St-UF-1QP"/>
</connections>
</tapGestureRecognizer>
</objects>
</document>

View file

@ -0,0 +1,24 @@
//
// UIRecordingCell.h
// linphone
//
// Created by benjamin_verdier on 25/07/2018.
//
#import <UIKit/UIKit.h>
@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

View file

@ -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

View file

@ -0,0 +1,52 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14113" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14088"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view autoresizesSubviews="NO" clipsSubviews="YES" contentMode="scaleToFill" id="e3d-Tw-Cmt" customClass="UIRecordingCell">
<rect key="frame" x="0.0" y="0.0" width="360" height="150"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Nk9-eo-eCo">
<rect key="frame" x="0.0" y="42" width="360" height="108"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</view>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Bzd-99-LAI">
<rect key="frame" x="16" y="0.0" width="300" height="44"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<toolbar opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleAspectFill" fixedFrame="YES" translucent="NO" translatesAutoresizingMaskIntoConstraints="NO" id="xjs-iK-dSH">
<rect key="frame" x="300" y="0.0" width="60" height="44"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
<items>
<barButtonItem style="plain" systemItem="action" id="Drx-8h-kbM"/>
</items>
</toolbar>
</subviews>
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="simulatedStatusBarMetrics"/>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<viewLayoutGuide key="safeArea" id="Ak9-b1-W1C"/>
<connections>
<outlet property="nameLabel" destination="Bzd-99-LAI" id="Ubb-kU-T09"/>
<outlet property="playerView" destination="Nk9-eo-eCo" id="64I-70-nHC"/>
<outlet property="shareButton" destination="Drx-8h-kbM" id="Vhv-4D-Ptx"/>
<outlet property="toolbar" destination="xjs-iK-dSH" id="NY4-Wk-dld"/>
</connections>
<point key="canvasLocation" x="26" y="105"/>
</view>
</objects>
</document>

Some files were not shown because too many files have changed in this diff Show more