mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-01-17 11:08:06 +00:00
Merge branch 'dev_group_chat'
This commit is contained in:
commit
f65f0af7c0
55 changed files with 3121 additions and 383 deletions
3
.gitmodules
vendored
3
.gitmodules
vendored
|
|
@ -117,3 +117,6 @@
|
|||
[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
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
#import "UICompositeView.h"
|
||||
#import "TPKeyboardAvoidingScrollView.h"
|
||||
#import "PhoneMainView.h"
|
||||
#import <AVFoundation/AVFoundation.h>
|
||||
|
||||
@interface AssistantView : UIViewController <UITextFieldDelegate, UICompositeViewDelegate> {
|
||||
|
||||
|
|
@ -51,6 +52,7 @@
|
|||
@property(nonatomic, strong) IBOutlet UIView *remoteProvisioningLoginView;
|
||||
@property(strong, nonatomic) IBOutlet UIView *remoteProvisioningView;
|
||||
@property (strong, nonatomic) IBOutlet UIView *createAccountActivateSMSView;
|
||||
@property (strong, nonatomic) IBOutlet UIView *qrCodeView;
|
||||
|
||||
@property(nonatomic, strong) IBOutlet UIImageView *welcomeLogoImage;
|
||||
@property(nonatomic, strong) IBOutlet UIButton *gotoCreateAccountButton;
|
||||
|
|
@ -64,6 +66,9 @@
|
|||
@property (weak, nonatomic) IBOutlet UILabel *activationSMSText;
|
||||
|
||||
@property (weak, nonatomic) IBOutlet UILabel *accountLabel;
|
||||
@property (weak, nonatomic) IBOutlet UIButton *qrCodeButton;
|
||||
@property (weak, nonatomic) IBOutlet UIButton *downloadButton;
|
||||
@property (weak, nonatomic) IBOutlet UITextField *urlLabel;
|
||||
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *createAccountNextButtonPositionConstraint;
|
||||
|
||||
+ (NSString *)StringForXMLRPCError:(const char *)err;
|
||||
|
|
@ -92,6 +97,7 @@
|
|||
- (IBAction)onLoginClick:(id)sender;
|
||||
- (IBAction)onRemoteProvisioningLoginClick:(id)sender;
|
||||
- (IBAction)onRemoteProvisioningDownloadClick:(id)sender;
|
||||
- (IBAction)onLaunchQRCodeView:(id)sender;
|
||||
- (IBAction)onCreateAccountCheckActivatedClick:(id)sender;
|
||||
- (IBAction)onLinkAccountClick:(id)sender;
|
||||
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
#import "PhoneMainView.h"
|
||||
#import "UIAssistantTextField.h"
|
||||
#import "UITextField+DoneButton.h"
|
||||
#import "LinphoneAppDelegate.h"
|
||||
|
||||
typedef enum _ViewElement {
|
||||
ViewElement_Username = 100,
|
||||
|
|
@ -117,6 +118,7 @@ static UICompositeViewDescription *compositeDescription = nil;
|
|||
}
|
||||
mustRestoreView = NO;
|
||||
_outgoingView = DialerView.compositeViewDescription;
|
||||
_qrCodeButton.hidden = !ENABLE_QRCODE;
|
||||
[self resetLiblinphone:FALSE];
|
||||
}
|
||||
|
||||
|
|
@ -134,6 +136,8 @@ static UICompositeViewDescription *compositeDescription = nil;
|
|||
|
||||
[_contentView setContentSize:frame.size];
|
||||
[_contentView contentSizeToFit];
|
||||
|
||||
_qrCodeView.frame = [[UIScreen mainScreen] bounds];
|
||||
}
|
||||
|
||||
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
|
||||
|
|
@ -474,6 +478,13 @@ static UICompositeViewDescription *compositeDescription = nil;
|
|||
view = _linphoneLoginView;
|
||||
}
|
||||
}
|
||||
|
||||
if (currentView == _qrCodeView) {
|
||||
linphone_core_enable_video_preview(LC, FALSE);
|
||||
linphone_core_enable_qrcode_video_preview(LC, FALSE);
|
||||
LinphoneAppDelegate *delegate = (LinphoneAppDelegate *)UIApplication.sharedApplication.delegate;
|
||||
delegate.onlyPortrait = FALSE;
|
||||
}
|
||||
|
||||
// Animation
|
||||
if (animation && ANIMATED) {
|
||||
|
|
@ -1246,9 +1257,9 @@ void assistant_is_account_linked(LinphoneAccountCreator *creator, LinphoneAccoun
|
|||
- (IBAction)onGotoRemoteProvisioningClick:(id)sender {
|
||||
ONCLICKBUTTON(sender, 100, {
|
||||
nextView = _remoteProvisioningView;
|
||||
[self loadAssistantConfig:@"assistant_remote.rc"];
|
||||
[self findTextField:ViewElement_URL].text =
|
||||
[LinphoneManager.instance lpConfigStringForKey:@"config-uri" inSection:@"misc"];
|
||||
[self loadAssistantConfig:@"assistant_remote.rc"];
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -1396,6 +1407,49 @@ void assistant_is_account_linked(LinphoneAccountCreator *creator, LinphoneAccoun
|
|||
});
|
||||
}
|
||||
|
||||
- (IBAction)onLaunchQRCodeView:(id)sender {
|
||||
[NSNotificationCenter.defaultCenter addObserver:self
|
||||
selector:@selector(qrCodeFound:)
|
||||
name:kLinphoneQRCodeFound
|
||||
object:nil];
|
||||
LinphoneAppDelegate *delegate = (LinphoneAppDelegate *)UIApplication.sharedApplication.delegate;
|
||||
delegate.onlyPortrait = TRUE;
|
||||
NSNumber *value = [NSNumber numberWithInt:UIDeviceOrientationPortrait];
|
||||
[[UIDevice currentDevice] setValue:value forKey:@"orientation"];
|
||||
//[UIViewController attemptRotationToDeviceOrientation];
|
||||
AVCaptureDevice *backCamera = [AVCaptureDevice defaultDeviceWithDeviceType:AVCaptureDeviceTypeBuiltInWideAngleCamera mediaType:AVMediaTypeVideo position:AVCaptureDevicePositionBack];
|
||||
if (![[NSString stringWithUTF8String:linphone_core_get_video_device(LC)] containsString:[backCamera uniqueID]]) {
|
||||
|
||||
bctbx_list_t *deviceList = linphone_core_get_video_devices_list(LC);
|
||||
NSMutableArray *devices = [NSMutableArray array];
|
||||
|
||||
while (deviceList) {
|
||||
char *data = deviceList->data;
|
||||
[devices addObject:[NSString stringWithUTF8String:data]];
|
||||
deviceList = deviceList->next;
|
||||
}
|
||||
bctbx_list_free(deviceList);
|
||||
|
||||
for (NSString *device in devices) {
|
||||
if ([device containsString:backCamera.uniqueID]) {
|
||||
linphone_core_set_video_device(LC, device.UTF8String);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
linphone_core_set_native_preview_window_id(LC, (__bridge void *)(_qrCodeView));
|
||||
linphone_core_enable_video_preview(LC, TRUE);
|
||||
linphone_core_enable_qrcode_video_preview(LC, TRUE);
|
||||
|
||||
[NSNotificationCenter.defaultCenter addObserver:self
|
||||
selector:@selector(qrCodeFound:)
|
||||
name:kLinphoneQRCodeFound
|
||||
object:nil];
|
||||
|
||||
[self changeView:_qrCodeView back:FALSE animation:TRUE];
|
||||
}
|
||||
|
||||
- (void)refreshYourUsername {
|
||||
UIAssistantTextField *username = [self findTextField:ViewElement_Username];
|
||||
UIAssistantTextField *phone = [self findTextField:ViewElement_Phone];
|
||||
|
|
@ -1509,7 +1563,7 @@ void assistant_is_account_linked(LinphoneAccountCreator *creator, LinphoneAccoun
|
|||
|
||||
- (IBAction)onBackClick:(id)sender {
|
||||
if ([historyViews count] > 0) {
|
||||
if (currentView == _createAccountActivateSMSView || currentView == _createAccountActivateEmailView) {
|
||||
if (currentView == _createAccountActivateSMSView || currentView == _createAccountActivateEmailView || currentView == _qrCodeView) {
|
||||
UIView *view = [historyViews lastObject];
|
||||
[historyViews removeLastObject];
|
||||
[self changeView:view back:TRUE animation:TRUE];
|
||||
|
|
@ -1532,7 +1586,7 @@ void assistant_is_account_linked(LinphoneAccountCreator *creator, LinphoneAccoun
|
|||
|
||||
#pragma mark - select country delegate
|
||||
|
||||
- (void)didSelectCountry:(NSDictionary *)country{
|
||||
- (void)didSelectCountry:(NSDictionary *)country {
|
||||
UIRoundBorderedButton *phoneButton = [self findButton:ViewElement_PhoneButton];
|
||||
[phoneButton setTitle:[country objectForKey:@"name"] forState:UIControlStateNormal];
|
||||
UIAssistantTextField* countryCodeField = [self findTextField:ViewElement_PhoneCC];
|
||||
|
|
@ -1541,4 +1595,23 @@ void assistant_is_account_linked(LinphoneAccountCreator *creator, LinphoneAccoun
|
|||
[self shouldEnableNextButton];
|
||||
}
|
||||
|
||||
-(void)qrCodeFound:(NSNotification *)notif {
|
||||
if ([notif.userInfo count] == 0){
|
||||
return;
|
||||
}
|
||||
[NSNotificationCenter.defaultCenter removeObserver:self name:kLinphoneQRCodeFound object:nil];
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
self.urlLabel.text = [notif.userInfo objectForKey:@"qrcode"];
|
||||
});
|
||||
if ([historyViews count] > 0) {
|
||||
if (currentView == _qrCodeView) {
|
||||
UIView *view = [historyViews lastObject];
|
||||
[historyViews removeLastObject];
|
||||
[self changeView:view back:TRUE animation:TRUE];
|
||||
} else {
|
||||
[self changeView:_welcomeView back:TRUE animation:TRUE];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
|||
|
|
@ -1,13 +1,12 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="11542" systemVersion="16B2555" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14113" 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="11524"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14088"/>
|
||||
<capability name="Alignment constraints to the first baseline" minToolsVersion="6.0"/>
|
||||
<capability name="Alignment constraints with different attributes" minToolsVersion="5.1"/>
|
||||
<capability name="Aspect ratio constraints" minToolsVersion="5.1"/>
|
||||
<capability name="Constraints to layout margins" minToolsVersion="6.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
|
|
@ -22,6 +21,7 @@
|
|||
<outlet property="createAccountActivateEmailView" destination="Zd9-Ms-s7X" id="6Qs-np-oqS"/>
|
||||
<outlet property="createAccountActivateSMSView" destination="101" id="SAS-8i-4Ao"/>
|
||||
<outlet property="createAccountView" destination="44" id="70"/>
|
||||
<outlet property="downloadButton" destination="eM0-bn-v3C" id="hsP-3U-clZ"/>
|
||||
<outlet property="gotoCreateAccountButton" destination="36" id="bZf-lI-yJp"/>
|
||||
<outlet property="gotoLinphoneLoginButton" destination="38" id="K1E-r5-WiL"/>
|
||||
<outlet property="gotoLoginButton" destination="39" id="uSY-cr-j4w"/>
|
||||
|
|
@ -31,9 +31,12 @@
|
|||
<outlet property="loginView" destination="56" id="bJH-N8-uPi"/>
|
||||
<outlet property="phoneLabel" destination="ZSJ-Lv-n60" id="5Qi-xR-wyK"/>
|
||||
<outlet property="phoneTitle" destination="rAy-0V-sqv" id="MZq-EF-6HF"/>
|
||||
<outlet property="qrCodeButton" destination="2T9-bt-FHD" id="5M5-Fj-q4E"/>
|
||||
<outlet property="qrCodeView" destination="Z2R-SD-yFJ" id="dcs-rK-HgK"/>
|
||||
<outlet property="remoteProvisioningLoginView" destination="xVK-hL-6pe" id="pKL-9M-Vsa"/>
|
||||
<outlet property="remoteProvisioningView" destination="Zuh-Sd-pcd" id="3pa-2M-5Xq"/>
|
||||
<outlet property="subtileLabel_useLinphoneAccount" destination="4n3-ZD-KVi" id="8d9-0f-2Vi"/>
|
||||
<outlet property="urlLabel" destination="Ffg-Of-xyh" id="IhC-hf-1OG"/>
|
||||
<outlet property="welcomeView" destination="33" id="46a-AR-5mN"/>
|
||||
</connections>
|
||||
</placeholder>
|
||||
|
|
@ -338,7 +341,7 @@
|
|||
<rect key="frame" x="0.0" y="426" width="375" height="237"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="EMAIL" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="E7B-Ag-ltX" userLabel="emailLabel">
|
||||
<rect key="frame" x="38" y="0.0" width="299" height="14"/>
|
||||
<rect key="frame" x="38" y="0.0" width="291" height="14"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="14" id="1pi-x8-d7G"/>
|
||||
</constraints>
|
||||
|
|
@ -347,7 +350,7 @@
|
|||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<textField opaque="NO" clipsSubviews="YES" tag="103" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" adjustsFontSizeToFit="NO" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="IXr-i2-LEh" userLabel="emailField" customClass="UIAssistantTextField">
|
||||
<rect key="frame" x="38" y="22" width="299" height="30"/>
|
||||
<rect key="frame" x="38" y="22" width="291" height="30"/>
|
||||
<color key="backgroundColor" red="0.85415387153625488" green="0.85412830114364624" blue="0.85414278507232666" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<accessibility key="accessibilityConfiguration" label="Email"/>
|
||||
<color key="textColor" red="0.20521381497383118" green="0.20520767569541931" blue="0.20521116256713867" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
|
|
@ -359,7 +362,7 @@
|
|||
</connections>
|
||||
</textField>
|
||||
<label opaque="NO" userInteractionEnabled="NO" tag="410" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Invalid email" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" translatesAutoresizingMaskIntoConstraints="NO" id="1r3-gy-l29" userLabel="emailErrorLabel">
|
||||
<rect key="frame" x="38" y="52" width="299" height="10"/>
|
||||
<rect key="frame" x="38" y="52" width="291" height="10"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="10" id="DxN-0P-gw6"/>
|
||||
</constraints>
|
||||
|
|
@ -368,7 +371,7 @@
|
|||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="PASSWORD" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="p25-jF-I9X" userLabel="passwordLabel">
|
||||
<rect key="frame" x="38" y="76" width="299" height="14"/>
|
||||
<rect key="frame" x="38" y="76" width="291" height="14"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="14" id="yWO-rf-S2R"/>
|
||||
</constraints>
|
||||
|
|
@ -377,7 +380,7 @@
|
|||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<textField opaque="NO" clipsSubviews="YES" tag="101" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" adjustsFontSizeToFit="NO" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="t14-fe-grq" userLabel="passwordField" customClass="UIAssistantTextField">
|
||||
<rect key="frame" x="38" y="101" width="299" height="30"/>
|
||||
<rect key="frame" x="38" y="101" width="291" height="30"/>
|
||||
<color key="backgroundColor" red="0.85415387153625488" green="0.85412830114364624" blue="0.85414278507232666" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<accessibility key="accessibilityConfiguration" label="Password "/>
|
||||
<color key="textColor" red="0.20521381497383118" green="0.20520767569541931" blue="0.20521116256713867" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
|
|
@ -389,7 +392,7 @@
|
|||
</connections>
|
||||
</textField>
|
||||
<label opaque="NO" userInteractionEnabled="NO" tag="410" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Invalid password" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" translatesAutoresizingMaskIntoConstraints="NO" id="J5q-GY-AW4" userLabel="passwordErrorLabel">
|
||||
<rect key="frame" x="38" y="131" width="299" height="10"/>
|
||||
<rect key="frame" x="38" y="131" width="291" height="10"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="10" id="EZT-D6-c3H"/>
|
||||
</constraints>
|
||||
|
|
@ -398,7 +401,7 @@
|
|||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="PASSWORD CONFIRMATION" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="fpk-Vv-LB0" userLabel="password2Label">
|
||||
<rect key="frame" x="38" y="153" width="299" height="14"/>
|
||||
<rect key="frame" x="38" y="153" width="291" height="14"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="14" id="aRv-BL-3ug"/>
|
||||
</constraints>
|
||||
|
|
@ -407,7 +410,7 @@
|
|||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<textField opaque="NO" clipsSubviews="YES" tag="102" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" adjustsFontSizeToFit="NO" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="kHS-3H-oHM" userLabel="password2Field" customClass="UIAssistantTextField">
|
||||
<rect key="frame" x="38" y="175" width="299" height="30"/>
|
||||
<rect key="frame" x="38" y="175" width="291" height="30"/>
|
||||
<color key="backgroundColor" red="0.85415387153625488" green="0.85412830114364624" blue="0.85414278507232666" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<accessibility key="accessibilityConfiguration" label="Password confirmation"/>
|
||||
<color key="textColor" red="0.20521381497383118" green="0.20520767569541931" blue="0.20521116256713867" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
|
|
@ -418,7 +421,7 @@
|
|||
</connections>
|
||||
</textField>
|
||||
<label opaque="NO" userInteractionEnabled="NO" tag="410" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Passwords do not match" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" translatesAutoresizingMaskIntoConstraints="NO" id="DgP-rE-2dp" userLabel="password2ErrorLabel">
|
||||
<rect key="frame" x="38" y="205" width="299" height="10"/>
|
||||
<rect key="frame" x="38" y="205" width="291" height="10"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="10" id="gT0-em-DfO"/>
|
||||
</constraints>
|
||||
|
|
@ -1273,11 +1276,11 @@ Once it is done, come back here and click on the button.</string>
|
|||
<point key="canvasLocation" x="1490" y="264"/>
|
||||
</view>
|
||||
<view contentMode="scaleToFill" id="Zuh-Sd-pcd" userLabel="remoteProvisioningView">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="241"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="347"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<subviews>
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="FETCH REMOTE CONFIGURATION" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="dpv-8C-qt6" userLabel="titleLabel">
|
||||
<rect key="frame" x="36" y="0.0" width="303" height="59"/>
|
||||
<rect key="frame" x="36" y="0.0" width="303" height="29"/>
|
||||
<accessibility key="accessibilityConfiguration" label="Account setup assistant"/>
|
||||
<fontDescription key="fontDescription" type="system" weight="light" pointSize="24"/>
|
||||
<color key="textColor" red="0.20521381497383118" green="0.20520767569541931" blue="0.20521116256713867" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
|
|
@ -1285,7 +1288,7 @@ Once it is done, come back here and click on the button.</string>
|
|||
<size key="shadowOffset" width="-1" height="-1"/>
|
||||
</label>
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Please provide your provisioning URL." textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="3" baselineAdjustment="alignBaselines" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="hEy-Xe-afq" userLabel="subtitleLabel">
|
||||
<rect key="frame" x="36" y="66" width="303" height="29"/>
|
||||
<rect key="frame" x="36" y="36" width="303" height="29"/>
|
||||
<accessibility key="accessibilityConfiguration" label="Account setup assistant"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="29" id="vbU-BF-C6f"/>
|
||||
|
|
@ -1296,7 +1299,7 @@ Once it is done, come back here and click on the button.</string>
|
|||
<size key="shadowOffset" width="-1" height="-1"/>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="URL" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="0tr-gN-2Ce" userLabel="urlLabel">
|
||||
<rect key="frame" x="38" y="131" width="299" height="14"/>
|
||||
<rect key="frame" x="38" y="101" width="299" height="14"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="14" id="1xT-bm-Ag5"/>
|
||||
</constraints>
|
||||
|
|
@ -1305,7 +1308,7 @@ Once it is done, come back here and click on the button.</string>
|
|||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<textField opaque="NO" clipsSubviews="YES" tag="105" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" adjustsFontSizeToFit="NO" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="Ffg-Of-xyh" userLabel="urlField" customClass="UIAssistantTextField">
|
||||
<rect key="frame" x="38" y="153" width="299" height="30"/>
|
||||
<rect key="frame" x="38" y="123" width="299" height="30"/>
|
||||
<color key="backgroundColor" red="0.85415387153625488" green="0.85412830114364624" blue="0.85414278507232666" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<accessibility key="accessibilityConfiguration" label="URL"/>
|
||||
<constraints>
|
||||
|
|
@ -1320,7 +1323,7 @@ Once it is done, come back here and click on the button.</string>
|
|||
</connections>
|
||||
</textField>
|
||||
<label opaque="NO" userInteractionEnabled="NO" tag="410" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Invalid URL" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" translatesAutoresizingMaskIntoConstraints="NO" id="uEq-Gk-9iy" userLabel="urlErrorLabel">
|
||||
<rect key="frame" x="38" y="183" width="299" height="10"/>
|
||||
<rect key="frame" x="38" y="153" width="299" height="10"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="10" id="VcL-Iz-4n4"/>
|
||||
</constraints>
|
||||
|
|
@ -1328,8 +1331,8 @@ Once it is done, come back here and click on the button.</string>
|
|||
<color key="textColor" red="0.98594832420349121" green="0.0" blue="0.026950567960739136" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<button opaque="NO" tag="130" contentMode="scaleToFill" enabled="NO" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="eM0-bn-v3C" userLabel="downloadButton" customClass="UIRoundBorderedButton">
|
||||
<rect key="frame" x="38" y="201" width="299" height="40"/>
|
||||
<button opaque="NO" tag="130" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="eM0-bn-v3C" userLabel="downloadButton" customClass="UIRoundBorderedButton">
|
||||
<rect key="frame" x="38" y="171" width="299" height="40"/>
|
||||
<accessibility key="accessibilityConfiguration" label="Fetch and apply">
|
||||
<bool key="isElement" value="YES"/>
|
||||
</accessibility>
|
||||
|
|
@ -1348,6 +1351,26 @@ Once it is done, come back here and click on the button.</string>
|
|||
<action selector="onRemoteProvisioningDownloadClick:" destination="-1" eventType="touchUpInside" id="6yF-1w-Hpa"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button hidden="YES" opaque="NO" tag="130" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="2T9-bt-FHD" userLabel="qrcodeButton" customClass="UIRoundBorderedButton">
|
||||
<rect key="frame" x="38" y="219" width="299" height="40"/>
|
||||
<accessibility key="accessibilityConfiguration" label="Fetch and apply">
|
||||
<bool key="isElement" value="YES"/>
|
||||
</accessibility>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="40" id="Wcc-Sn-c0r"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="16"/>
|
||||
<state key="normal" title="QR CODE">
|
||||
<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="onLaunchQRCodeView:" destination="-1" eventType="touchUpInside" id="i1k-Su-mAZ"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
|
|
@ -1366,14 +1389,16 @@ Once it is done, come back here and click on the button.</string>
|
|||
<constraint firstItem="0tr-gN-2Ce" firstAttribute="trailing" secondItem="Ffg-Of-xyh" secondAttribute="trailing" id="d5L-lU-eEr"/>
|
||||
<constraint firstItem="hEy-Xe-afq" firstAttribute="centerX" secondItem="0tr-gN-2Ce" secondAttribute="centerX" id="dQg-gY-T2t"/>
|
||||
<constraint firstItem="Ffg-Of-xyh" firstAttribute="top" secondItem="0tr-gN-2Ce" secondAttribute="bottom" constant="8" symbolic="YES" id="deZ-RJ-Tac"/>
|
||||
<constraint firstItem="2T9-bt-FHD" firstAttribute="top" secondItem="eM0-bn-v3C" secondAttribute="bottom" constant="8" id="hPc-df-UEy"/>
|
||||
<constraint firstItem="hEy-Xe-afq" firstAttribute="top" secondItem="dpv-8C-qt6" secondAttribute="bottom" constant="7" id="j4R-8z-ku5"/>
|
||||
<constraint firstItem="dpv-8C-qt6" firstAttribute="leading" secondItem="hEy-Xe-afq" secondAttribute="leading" id="jKd-Ac-gLa"/>
|
||||
<constraint firstAttribute="bottom" secondItem="eM0-bn-v3C" secondAttribute="bottom" id="kCn-do-O9N"/>
|
||||
<constraint firstItem="uEq-Gk-9iy" firstAttribute="trailing" secondItem="eM0-bn-v3C" secondAttribute="trailing" id="kFa-lR-RH4"/>
|
||||
<constraint firstItem="2T9-bt-FHD" firstAttribute="leading" secondItem="eM0-bn-v3C" secondAttribute="leading" id="kP2-1p-Fpw"/>
|
||||
<constraint firstItem="2T9-bt-FHD" firstAttribute="trailing" secondItem="eM0-bn-v3C" secondAttribute="trailing" id="vXZ-nV-P1E"/>
|
||||
</constraints>
|
||||
<nil key="simulatedStatusBarMetrics"/>
|
||||
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
|
||||
<point key="canvasLocation" x="1917.5" y="96.5"/>
|
||||
<point key="canvasLocation" x="1917.5" y="149.5"/>
|
||||
</view>
|
||||
<view contentMode="scaleToFill" id="xVK-hL-6pe" userLabel="remoteProvisioningLoginView">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="379"/>
|
||||
|
|
@ -1524,13 +1549,19 @@ Once it is done, come back here and click on the button.</string>
|
|||
</constraints>
|
||||
<nil key="simulatedStatusBarMetrics"/>
|
||||
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
|
||||
<point key="canvasLocation" x="1917.5" y="457.5"/>
|
||||
<point key="canvasLocation" x="2422" y="410"/>
|
||||
</view>
|
||||
<tapGestureRecognizer id="VEO-W5-GDl" userLabel="onLinkTap">
|
||||
<connections>
|
||||
<action selector="onLinkTap:" destination="-1" id="xXJ-65-gxy"/>
|
||||
</connections>
|
||||
</tapGestureRecognizer>
|
||||
<view contentMode="scaleToFill" id="Z2R-SD-yFJ" userLabel="qrCodeView">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<point key="canvasLocation" x="1918" y="554"/>
|
||||
</view>
|
||||
</objects>
|
||||
<resources>
|
||||
<image name="color_F.png" width="2" height="2"/>
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="13196" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" colorMatched="YES">
|
||||
<device id="retina4_7" orientation="landscape">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14113" 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="13174"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14088"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
|
|
@ -35,23 +35,23 @@
|
|||
</placeholder>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||
<view contentMode="scaleToFill" id="v2I-ka-LYa" userLabel="iphone6MetricsView">
|
||||
<rect key="frame" x="0.0" y="0.0" width="667" height="375"/>
|
||||
<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" id="6">
|
||||
<rect key="frame" x="0.0" y="42" width="667" height="267"/>
|
||||
<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" id="7" userLabel="topBar">
|
||||
<rect key="frame" x="0.0" y="0.0" width="667" height="66"/>
|
||||
<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" image="color_F.png" id="v5G-Qf-X82" userLabel="backgroundColor">
|
||||
<rect key="frame" x="0.0" y="0.0" width="667" height="66"/>
|
||||
<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" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" lineBreakMode="middleTruncation" id="9" userLabel="backButton" customClass="UIIconButton">
|
||||
<rect key="frame" x="0.0" y="0.0" width="133" height="66"/>
|
||||
<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"/>
|
||||
|
|
@ -66,7 +66,7 @@
|
|||
</connections>
|
||||
</button>
|
||||
<button hidden="YES" opaque="NO" tag="11" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="bci-3K-AcG" userLabel="cancelButton" customClass="UIIconButton">
|
||||
<rect key="frame" x="0.0" y="0.0" width="133" height="66"/>
|
||||
<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="Cancel"/>
|
||||
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
|
||||
|
|
@ -81,7 +81,7 @@
|
|||
</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="133" y="0.0" width="253" height="66"/>
|
||||
<rect key="frame" x="75" y="0.0" width="142" height="66"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
|
||||
<accessibility key="accessibilityConfiguration" label="Contact name">
|
||||
<accessibilityTraits key="traits" none="YES"/>
|
||||
|
|
@ -91,7 +91,7 @@
|
|||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<button opaque="NO" tag="6" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="Wzg-i0-spp" userLabel="callButton" customClass="UIIconButton">
|
||||
<rect key="frame" x="400" y="0.0" width="134" height="66"/>
|
||||
<rect key="frame" x="225" y="0.0" width="75" height="66"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
|
||||
<state key="normal" image="call_alt_start_default.png">
|
||||
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
|
|
@ -103,7 +103,7 @@
|
|||
</connections>
|
||||
</button>
|
||||
<button hidden="YES" opaque="NO" tag="7" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="Hc0-GX-fC5" userLabel="backToCallButton" customClass="UIBackToCallButton">
|
||||
<rect key="frame" x="400" y="0.0" width="134" height="66"/>
|
||||
<rect key="frame" x="225" 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"/>
|
||||
|
|
@ -116,7 +116,7 @@
|
|||
</connections>
|
||||
</button>
|
||||
<button hidden="YES" opaque="NO" tag="8" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="Wag-Nx-kd6" userLabel="deleteButton" customClass="UIIconButton">
|
||||
<rect key="frame" x="534" y="0.0" width="133" height="66"/>
|
||||
<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="Delete all"/>
|
||||
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
|
||||
|
|
@ -130,7 +130,7 @@
|
|||
</connections>
|
||||
</button>
|
||||
<button opaque="NO" tag="9" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="FqM-Ud-i58" userLabel="editButton" customClass="UIIconButton">
|
||||
<rect key="frame" x="534" y="0.0" width="133" height="66"/>
|
||||
<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="Edit"/>
|
||||
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
|
||||
|
|
@ -145,7 +145,7 @@
|
|||
</connections>
|
||||
</button>
|
||||
<button hidden="YES" opaque="NO" tag="10" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" reversesTitleShadowWhenHighlighted="YES" showsTouchWhenHighlighted="YES" lineBreakMode="middleTruncation" id="c9z-aq-2UP" userLabel="toggleSelectionButton" customClass="UIIconButton">
|
||||
<rect key="frame" x="400" y="0.0" width="134" height="66"/>
|
||||
<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"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||
|
|
@ -161,7 +161,7 @@
|
|||
</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">
|
||||
<rect key="frame" x="400" y="0.0" width="134" height="66"/>
|
||||
<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"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||
|
|
@ -177,7 +177,7 @@
|
|||
</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="133" y="41" width="253" height="25"/>
|
||||
<rect key="frame" x="75" y="41" width="142" height="25"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
|
||||
<accessibility key="accessibilityConfiguration" label="Contact name">
|
||||
<accessibilityTraits key="traits" none="YES"/>
|
||||
|
|
@ -189,11 +189,11 @@
|
|||
</subviews>
|
||||
</view>
|
||||
<view tag="12" contentMode="scaleToFill" id="49" userLabel="contentView">
|
||||
<rect key="frame" x="0.0" y="66" width="667" height="201"/>
|
||||
<rect key="frame" x="0.0" y="66" width="375" height="493"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES" flexibleMaxY="YES"/>
|
||||
<subviews>
|
||||
<tableView clipsSubviews="YES" tag="13" contentMode="scaleToFill" alwaysBounceVertical="YES" style="plain" separatorStyle="none" allowsSelection="NO" allowsSelectionDuringEditing="YES" allowsMultipleSelectionDuringEditing="YES" rowHeight="60" sectionHeaderHeight="22" sectionFooterHeight="22" id="8" userLabel="messagesTableView">
|
||||
<rect key="frame" x="0.0" y="0.0" width="667" height="113"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="405"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<gestureRecognizers/>
|
||||
|
|
@ -205,11 +205,11 @@
|
|||
</connections>
|
||||
</tableView>
|
||||
<view hidden="YES" tag="14" contentMode="scaleToFill" id="fx4-ao-53M" userLabel="composeIndicatorView">
|
||||
<rect key="frame" x="0.0" y="113" width="667" height="22"/>
|
||||
<rect key="frame" x="0.0" y="405" width="375" height="22"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
||||
<subviews>
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" tag="15" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="%@ is composing..." lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" id="fpY-Fv-ht2" userLabel="composeLabel">
|
||||
<rect key="frame" x="0.0" y="1" width="667" height="22"/>
|
||||
<rect key="frame" x="0.0" y="1" width="375" height="22"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<accessibility key="accessibilityConfiguration" label=""/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
|
|
@ -219,7 +219,7 @@
|
|||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</view>
|
||||
<label hidden="YES" opaque="NO" userInteractionEnabled="NO" tag="16" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="No conversation." textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="p7C-WH-uR1" userLabel="emptyTableLabel">
|
||||
<rect key="frame" x="0.0" y="0.0" width="667" height="174"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="427"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
|
|
@ -227,11 +227,11 @@
|
|||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<view tag="17" contentMode="scaleToFill" id="14" userLabel="messageView">
|
||||
<rect key="frame" x="0.0" y="135" width="667" height="66"/>
|
||||
<rect key="frame" x="0.0" y="427" width="375" height="66"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
||||
<subviews>
|
||||
<imageView userInteractionEnabled="NO" tag="18" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="color_F.png" id="pGT-LQ-zpg" userLabel="backgroundColor">
|
||||
<rect key="frame" x="0.0" y="0.0" width="667" height="66"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="66"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
</imageView>
|
||||
<button opaque="NO" tag="19" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="73" userLabel="pictureButton">
|
||||
|
|
@ -248,7 +248,7 @@
|
|||
</connections>
|
||||
</button>
|
||||
<button opaque="NO" tag="21" contentMode="scaleToFill" enabled="NO" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="15" userLabel="sendButton">
|
||||
<rect key="frame" x="602" y="0.0" width="66" height="66"/>
|
||||
<rect key="frame" x="310" y="0.0" width="66" height="66"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
|
||||
<accessibility key="accessibilityConfiguration" label="Send"/>
|
||||
<inset key="titleEdgeInsets" minX="0.0" minY="30" maxX="0.0" maxY="0.0"/>
|
||||
|
|
@ -262,7 +262,7 @@
|
|||
</connections>
|
||||
</button>
|
||||
<view tag="20" contentMode="scaleToFill" id="pqa-tg-5ml" userLabel="messageField" customClass="HPGrowingTextView">
|
||||
<rect key="frame" x="117" y="13" width="433" height="40"/>
|
||||
<rect key="frame" x="66" y="13" width="243" height="40"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<accessibility key="accessibilityConfiguration" label="Message field"/>
|
||||
|
|
@ -280,23 +280,23 @@
|
|||
<point key="canvasLocation" x="228.5" y="-40.5"/>
|
||||
</view>
|
||||
<view contentMode="scaleToFill" id="680-UL-sil" userLabel="iphone6MetricsView">
|
||||
<rect key="frame" x="0.0" y="0.0" width="667" height="375"/>
|
||||
<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" id="VoU-7Q-fgp">
|
||||
<rect key="frame" x="90" y="42" width="577" height="333"/>
|
||||
<rect key="frame" x="90" y="42" width="285" height="625"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<view tag="2" contentMode="scaleToFill" id="Z3y-hY-5xp" userLabel="topBar">
|
||||
<rect key="frame" x="0.0" y="0.0" width="577" height="66"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="285" 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="Uvs-m3-GPj" userLabel="backgroundColor">
|
||||
<rect key="frame" x="0.0" y="0.0" width="577" height="66"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="285" 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="N2g-vL-3x8" userLabel="backButton" customClass="UIIconButton">
|
||||
<rect key="frame" x="0.0" y="0.0" width="67" height="66"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="33" 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"/>
|
||||
|
|
@ -311,7 +311,7 @@
|
|||
</connections>
|
||||
</button>
|
||||
<button hidden="YES" opaque="NO" tag="11" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="Bqf-Gg-2Rw" userLabel="cancelButton" customClass="UIIconButton">
|
||||
<rect key="frame" x="0.0" y="0.0" width="67" height="66"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="33" height="66"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
|
||||
<accessibility key="accessibilityConfiguration" label="Cancel"/>
|
||||
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
|
||||
|
|
@ -336,7 +336,7 @@
|
|||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<button hidden="YES" opaque="NO" tag="8" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="RDW-7W-25T" userLabel="deleteButton" customClass="UIIconButton">
|
||||
<rect key="frame" x="508" y="0.0" width="69" height="66"/>
|
||||
<rect key="frame" x="251" y="0.0" width="34" height="66"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
|
||||
<accessibility key="accessibilityConfiguration" label="Delete all"/>
|
||||
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
|
||||
|
|
@ -350,7 +350,7 @@
|
|||
</connections>
|
||||
</button>
|
||||
<button opaque="NO" tag="9" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="KeL-Ej-92j" userLabel="editButton" customClass="UIIconButton">
|
||||
<rect key="frame" x="508" y="0.0" width="69" height="66"/>
|
||||
<rect key="frame" x="251" y="0.0" width="34" height="66"/>
|
||||
<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"/>
|
||||
|
|
@ -365,7 +365,7 @@
|
|||
</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">
|
||||
<rect key="frame" x="441" y="0.0" width="67" height="66"/>
|
||||
<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"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||
|
|
@ -381,7 +381,7 @@
|
|||
</connections>
|
||||
</button>
|
||||
<button opaque="NO" tag="6" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="wag-QV-oUD" userLabel="callButton" customClass="UIIconButton">
|
||||
<rect key="frame" x="441" y="0.0" width="67" height="66"/>
|
||||
<rect key="frame" x="218" y="0.0" width="33" height="66"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
|
||||
<state key="normal" image="call_alt_start_default.png">
|
||||
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
|
|
@ -393,7 +393,7 @@
|
|||
</connections>
|
||||
</button>
|
||||
<button hidden="YES" opaque="NO" tag="7" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="t25-en-4LP" userLabel="backToCallButton" customClass="UIBackToCallButton">
|
||||
<rect key="frame" x="441" y="0.0" width="67" height="66"/>
|
||||
<rect key="frame" x="218" y="0.0" width="33" 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"/>
|
||||
|
|
@ -405,7 +405,7 @@
|
|||
</connections>
|
||||
</button>
|
||||
<button hidden="YES" opaque="NO" tag="10" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" reversesTitleShadowWhenHighlighted="YES" showsTouchWhenHighlighted="YES" lineBreakMode="middleTruncation" id="4RV-US-Kr1" userLabel="toggleSelectionButton" customClass="UIIconButton">
|
||||
<rect key="frame" x="441" y="0.0" width="67" height="66"/>
|
||||
<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"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||
|
|
@ -433,11 +433,11 @@
|
|||
</subviews>
|
||||
</view>
|
||||
<view tag="12" contentMode="scaleToFill" id="OTt-fc-941" userLabel="contentView">
|
||||
<rect key="frame" x="0.0" y="66" width="577" height="267"/>
|
||||
<rect key="frame" x="0.0" y="66" width="285" height="559"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES" flexibleMaxY="YES"/>
|
||||
<subviews>
|
||||
<tableView clipsSubviews="YES" tag="13" contentMode="scaleToFill" alwaysBounceVertical="YES" style="plain" separatorStyle="none" allowsSelection="NO" allowsSelectionDuringEditing="YES" allowsMultipleSelectionDuringEditing="YES" rowHeight="60" sectionHeaderHeight="22" sectionFooterHeight="22" id="CU7-Za-RwN" userLabel="messagesTableView">
|
||||
<rect key="frame" x="0.0" y="0.0" width="577" height="179"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="285" height="471"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<gestureRecognizers/>
|
||||
|
|
@ -447,7 +447,7 @@
|
|||
</connections>
|
||||
</tableView>
|
||||
<label hidden="YES" opaque="NO" userInteractionEnabled="NO" tag="16" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="No conversation." textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="pzm-tk-LH0" userLabel="emptyTableLabel">
|
||||
<rect key="frame" x="0.0" y="0.0" width="577" height="209"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="285" height="438"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
|
|
@ -455,11 +455,11 @@
|
|||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<view hidden="YES" tag="14" contentMode="scaleToFill" id="nTf-7h-Z4z" userLabel="composeIndicatorView">
|
||||
<rect key="frame" x="0.0" y="179" width="577" height="22"/>
|
||||
<rect key="frame" x="0.0" y="471" width="285" height="22"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
||||
<subviews>
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" tag="15" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="%@ is composing..." lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" id="I34-aL-yuS" userLabel="composeLabel">
|
||||
<rect key="frame" x="0.0" y="0.0" width="577" height="22"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="285" height="22"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<accessibility key="accessibilityConfiguration" label=""/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
|
|
@ -469,11 +469,11 @@
|
|||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</view>
|
||||
<view tag="17" contentMode="scaleToFill" id="LA5-wD-ftj" userLabel="messageView">
|
||||
<rect key="frame" x="0.0" y="201" width="577" height="66"/>
|
||||
<rect key="frame" x="0.0" y="493" width="285" height="66"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
||||
<subviews>
|
||||
<imageView userInteractionEnabled="NO" tag="18" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="color_F.png" id="kKc-DG-gwg" userLabel="backgroundColor">
|
||||
<rect key="frame" x="0.0" y="0.0" width="577" height="66"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="285" height="66"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
</imageView>
|
||||
<button opaque="NO" tag="19" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="gSL-jE-GYO" userLabel="pictureButton">
|
||||
|
|
@ -490,13 +490,13 @@
|
|||
</connections>
|
||||
</button>
|
||||
<view tag="20" contentMode="scaleToFill" id="C02-2r-vXK" userLabel="messageField" customClass="HPGrowingTextView">
|
||||
<rect key="frame" x="59" y="13" width="457" height="40"/>
|
||||
<rect key="frame" x="29" y="13" width="226" height="40"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<accessibility key="accessibilityConfiguration" label="Message field"/>
|
||||
</view>
|
||||
<button opaque="NO" tag="21" contentMode="scaleToFill" enabled="NO" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="nV9-xZ-oSM" userLabel="sendButton">
|
||||
<rect key="frame" x="511" y="0.0" width="66" height="66"/>
|
||||
<rect key="frame" x="219" y="0.0" width="66" height="66"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
|
||||
<accessibility key="accessibilityConfiguration" label="Send"/>
|
||||
<inset key="titleEdgeInsets" minX="0.0" minY="30" maxX="0.0" maxY="0.0"/>
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
@protocol ChatConversationDelegate <NSObject>
|
||||
|
||||
- (BOOL)startImageUpload:(UIImage *)image url:(NSURL *)url withQuality:(float)quality;
|
||||
- (BOOL)startFileUpload:(NSData *)data withUrl:(NSURL *)url;
|
||||
- (void)resendChat:(NSString *)message withExternalUrl:(NSString *)url;
|
||||
- (void)tableViewIsScrolling;
|
||||
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@
|
|||
[self clearEventList];
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - ViewController Functions
|
||||
|
||||
- (void)viewWillAppear:(BOOL)animated {
|
||||
|
|
@ -173,15 +174,15 @@
|
|||
LinphoneEventLog *event = [[eventList objectAtIndex:indexPath.row] pointerValue];
|
||||
if (linphone_event_log_get_type(event) == LinphoneEventLogTypeConferenceChatMessage) {
|
||||
LinphoneChatMessage *chat = linphone_event_log_get_chat_message(event);
|
||||
if (linphone_chat_message_get_file_transfer_information(chat) || linphone_chat_message_get_external_body_url(chat))
|
||||
kCellId = NSStringFromClass(UIChatBubblePhotoCell.class);
|
||||
if (linphone_chat_message_get_file_transfer_information(chat) || linphone_chat_message_get_external_body_url(chat))
|
||||
kCellId = NSStringFromClass(UIChatBubblePhotoCell.class);
|
||||
else
|
||||
kCellId = NSStringFromClass(UIChatBubbleTextCell.class);
|
||||
|
||||
|
||||
UIChatBubbleTextCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellId];
|
||||
if (!cell)
|
||||
if (!cell) {
|
||||
cell = [[NSClassFromString(kCellId) alloc] initWithIdentifier:kCellId];
|
||||
|
||||
}
|
||||
[cell setEvent:event];
|
||||
if (chat)
|
||||
[cell update];
|
||||
|
|
@ -209,14 +210,34 @@
|
|||
[_chatRoomDelegate tableViewIsScrolling];
|
||||
}
|
||||
|
||||
static const CGFloat MESSAGE_SPACING_PERCENTAGE = 5.f;
|
||||
|
||||
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||
LinphoneEventLog *event = [[eventList objectAtIndex:indexPath.row] pointerValue];
|
||||
if (linphone_event_log_get_type(event) == LinphoneEventLogTypeConferenceChatMessage) {
|
||||
LinphoneChatMessage *chat = linphone_event_log_get_chat_message(event);
|
||||
return [UIChatBubbleTextCell ViewHeightForMessage:chat withWidth:self.view.frame.size.width].height;
|
||||
} else {
|
||||
return [UIChatNotifiedEventCell height];
|
||||
LinphoneChatMessage *chat = linphone_event_log_get_chat_message(event);
|
||||
|
||||
//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))) {
|
||||
LOGD(@"BITE");
|
||||
height += tableView.frame.size.height * MESSAGE_SPACING_PERCENTAGE / 100;
|
||||
}
|
||||
}
|
||||
return [UIChatBubbleTextCell ViewHeightForMessage:chat withWidth:self.view.frame.size.width].height + height;
|
||||
}
|
||||
return [UIChatNotifiedEventCell height];
|
||||
}
|
||||
|
||||
- (void) tableView:(UITableView *)tableView deleteRowAtIndex:(NSIndexPath *)indexPath {
|
||||
|
|
|
|||
|
|
@ -31,8 +31,8 @@
|
|||
#include "linphone/linphonecore.h"
|
||||
|
||||
@interface ChatConversationView
|
||||
: TPMultiLayoutViewController <HPGrowingTextViewDelegate, UICompositeViewDelegate, ImagePickerDelegate,
|
||||
ChatConversationDelegate, UISearchBarDelegate> {
|
||||
: TPMultiLayoutViewController <HPGrowingTextViewDelegate, UICompositeViewDelegate, ImagePickerDelegate, ChatConversationDelegate,
|
||||
UIDocumentInteractionControllerDelegate, UISearchBarDelegate> {
|
||||
OrderedDictionary *imageQualities;
|
||||
BOOL scrollOnGrowingEnabled;
|
||||
BOOL composingVisible;
|
||||
|
|
@ -40,6 +40,7 @@
|
|||
|
||||
@property(nonatomic) LinphoneChatRoom *chatRoom;
|
||||
@property(nonatomic) LinphoneChatRoomCbs *chatRoomCbs;
|
||||
@property(nonatomic) Boolean markAsRead;
|
||||
|
||||
@property(weak, nonatomic) IBOutlet UIIconButton *backButton;
|
||||
@property(nonatomic, strong) IBOutlet ChatConversationTableView *tableController;
|
||||
|
|
@ -58,7 +59,7 @@
|
|||
@property(weak, nonatomic) IBOutlet UIBackToCallButton *backToCallButton;
|
||||
@property (weak, nonatomic) IBOutlet UIIconButton *infoButton;
|
||||
@property (weak, nonatomic) IBOutlet UILabel *particpantsLabel;
|
||||
|
||||
@property (nonatomic, strong) UIDocumentInteractionController *documentInteractionController;
|
||||
+ (void)markAsRead:(LinphoneChatRoom *)chatRoom;
|
||||
|
||||
- (void)configureForRoom:(BOOL)editing;
|
||||
|
|
@ -72,5 +73,6 @@
|
|||
- (IBAction)onDeleteClick:(id)sender;
|
||||
- (IBAction)onEditionChangeClick:(id)sender;
|
||||
- (void)update;
|
||||
- (void)openResults:(NSString *) filePath;
|
||||
|
||||
@end
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
#import "UIChatBubbleTextCell.h"
|
||||
|
||||
@implementation ChatConversationView
|
||||
static NSString* groupName = @"group.belledonne-communications.linphone";
|
||||
|
||||
#pragma mark - Lifecycle Functions
|
||||
|
||||
|
|
@ -84,7 +85,7 @@ static UICompositeViewDescription *compositeDescription = nil;
|
|||
|
||||
- (void)viewDidLoad {
|
||||
[super viewDidLoad];
|
||||
|
||||
_markAsRead = TRUE;
|
||||
// if we use fragments, remove back button
|
||||
if (IPAD) {
|
||||
_backButton.hidden = YES;
|
||||
|
|
@ -205,11 +206,51 @@ static UICompositeViewDescription *compositeDescription = nil;
|
|||
|
||||
_chatView.hidden = NO;
|
||||
[self update];
|
||||
[self shareFile];
|
||||
}
|
||||
|
||||
- (void)shareFile {
|
||||
NSUserDefaults *defaults = [[NSUserDefaults alloc] initWithSuiteName:groupName];
|
||||
|
||||
NSDictionary *dict = [defaults valueForKey:@"img"];
|
||||
NSDictionary *dictWeb = [defaults valueForKey:@"web"];
|
||||
NSDictionary *dictFile = [defaults valueForKey:@"mov"];
|
||||
NSDictionary *dictText = [defaults valueForKey:@"text"];
|
||||
if (dict) {
|
||||
//share photo
|
||||
NSData *data = dict[@"nsData"];
|
||||
UIImage *image = [[UIImage alloc] initWithData:data];
|
||||
[self chooseImageQuality:image url:nil];
|
||||
[defaults removeObjectForKey:@"img"];
|
||||
} else if (dictWeb) {
|
||||
//share url, if local file, then upload file
|
||||
NSString *url = dictWeb[@"url"];
|
||||
NSURL *fileUrl = [NSURL fileURLWithPath:url];
|
||||
if ([url hasPrefix:@"file"]) {
|
||||
//local file
|
||||
NSData *data = dictWeb[@"nsData"];
|
||||
[self confirmShare:data url:fileUrl text:nil];
|
||||
} else {
|
||||
[self confirmShare:nil url:nil text:url];
|
||||
}
|
||||
[defaults removeObjectForKey:@"web"];
|
||||
}else if (dictFile) {
|
||||
//share file
|
||||
NSData *data = dictFile[@"nsData"];
|
||||
[self confirmShare:data url:[NSURL fileURLWithPath:dictFile[@"url"]] text:nil];
|
||||
[defaults removeObjectForKey:@"mov"];
|
||||
}else if (dictText) {
|
||||
//share text
|
||||
[self confirmShare:nil url:nil text:dictText[@"name"]];
|
||||
[defaults removeObjectForKey:@"text"];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)applicationWillEnterForeground:(NSNotification *)notif {
|
||||
if (_chatRoom)
|
||||
if (_chatRoom && _markAsRead)
|
||||
[ChatConversationView markAsRead:_chatRoom];
|
||||
|
||||
_markAsRead = TRUE;
|
||||
}
|
||||
|
||||
- (void)callUpdateEvent:(NSNotification *)notif {
|
||||
|
|
@ -253,8 +294,8 @@ static UICompositeViewDescription *compositeDescription = nil;
|
|||
}
|
||||
|
||||
if (internalUrl) {
|
||||
// internal url is saved in the appdata for display and later save
|
||||
[LinphoneManager setValueInMessageAppData:[internalUrl absoluteString] forKey:@"localimage" inMessage:msg];
|
||||
// internal url is saved in the appdata for display and later save
|
||||
[LinphoneManager setValueInMessageAppData:[internalUrl absoluteString] forKey:@"localimage" inMessage:msg];
|
||||
}
|
||||
|
||||
// we must ref & unref message because in case of error, it will be destroy otherwise
|
||||
|
|
@ -318,6 +359,26 @@ static UICompositeViewDescription *compositeDescription = nil;
|
|||
});
|
||||
}
|
||||
|
||||
- (void)confirmShare:(NSData *)data url:(NSURL *)url text:(NSString *)text {
|
||||
DTActionSheet *sheet = [[DTActionSheet alloc] initWithTitle:NSLocalizedString(@"", nil)];
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||
|
||||
[sheet addButtonWithTitle:@"send to this friend"
|
||||
block:^() {
|
||||
if(data && url)
|
||||
[self startFileUpload:data withUrl:url];
|
||||
else
|
||||
[self sendMessage:text withExterlBodyUrl:nil withInternalURL:nil];
|
||||
|
||||
}];
|
||||
|
||||
[sheet addCancelButtonWithTitle:NSLocalizedString(@"Cancel", nil) block:nil];
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[sheet showInView:PhoneMainView.instance.view];
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
- (void)setComposingVisible:(BOOL)visible withDelay:(CGFloat)delay {
|
||||
Boolean shouldAnimate = composingVisible != visible;
|
||||
CGRect keyboardFrame = [_messageView frame];
|
||||
|
|
@ -547,6 +608,13 @@ static UICompositeViewDescription *compositeDescription = nil;
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
- (BOOL)startFileUpload:(NSData *)data withUrl:(NSURL *)url {
|
||||
FileTransferDelegate *fileTransfer = [[FileTransferDelegate alloc] init];
|
||||
[fileTransfer uploadFile:data forChatRoom:_chatRoom withUrl:url];
|
||||
[_tableController scrollToBottom:true];
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
- (void)resendChat:(NSString *)message withExternalUrl:(NSString *)url {
|
||||
[self sendMessage:message withExterlBodyUrl:[NSURL URLWithString:url] withInternalURL:nil];
|
||||
}
|
||||
|
|
@ -760,6 +828,7 @@ void on_chat_room_chat_message_sent(LinphoneChatRoom *cr, const LinphoneEventLog
|
|||
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];
|
||||
[ChatsListTableView saveDataToUserDefaults];
|
||||
|
||||
if (IPAD)
|
||||
[NSNotificationCenter.defaultCenter postNotificationName:kLinphoneMessageReceived object:view];
|
||||
|
|
@ -783,4 +852,18 @@ void on_chat_room_conference_left(LinphoneChatRoom *cr, const LinphoneEventLog *
|
|||
[view.tableController scrollToBottom:true];
|
||||
}
|
||||
|
||||
- (void)openResults:(NSString *) filePath
|
||||
{
|
||||
// Open the controller.
|
||||
_documentInteractionController = [UIDocumentInteractionController interactionControllerWithURL:[NSURL fileURLWithPath:filePath]];
|
||||
_documentInteractionController.delegate = self;
|
||||
|
||||
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];
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
|||
|
|
@ -30,4 +30,5 @@
|
|||
|
||||
- (void)loadData;
|
||||
- (void)markCellAsRead:(LinphoneChatRoom *)chatRoom;
|
||||
+ (void)saveDataToUserDefaults;
|
||||
@end
|
||||
|
|
|
|||
|
|
@ -123,6 +123,55 @@ static int sorted_history_comparison(LinphoneChatRoom *to_insert, LinphoneChatRo
|
|||
}
|
||||
}
|
||||
|
||||
+ (void) saveDataToUserDefaults {
|
||||
NSUserDefaults *defaults = [[NSUserDefaults alloc] initWithSuiteName:@"group.belledonne-communications.linphone.widget"];
|
||||
MSList *sorted = nil;
|
||||
const MSList *unsorted = linphone_core_get_chat_rooms(LC);
|
||||
const MSList *iter = unsorted;
|
||||
|
||||
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);
|
||||
iter = iter->next;
|
||||
}
|
||||
|
||||
NSMutableArray *addresses = [NSMutableArray array];
|
||||
|
||||
while (sorted) {
|
||||
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
|
||||
LinphoneChatRoom *cr = sorted->data;
|
||||
const LinphoneAddress *peer_address = linphone_chat_room_get_peer_address(cr);
|
||||
const LinphoneAddress *local_address = linphone_chat_room_get_local_address(cr);
|
||||
NSString *display;
|
||||
[dict setObject:[NSString stringWithUTF8String:linphone_address_as_string_uri_only(peer_address)]
|
||||
forKey:@"peer"];
|
||||
[dict setObject:[NSString stringWithUTF8String:linphone_address_as_string_uri_only(local_address)]
|
||||
forKey:@"local"];
|
||||
if (linphone_chat_room_get_conference_address(cr))
|
||||
display = [NSString stringWithUTF8String:linphone_chat_room_get_subject(cr)];
|
||||
else {
|
||||
display = [NSString stringWithUTF8String:linphone_address_get_display_name(peer_address)?:linphone_address_get_username(peer_address)];
|
||||
if ([FastAddressBook imageForAddress:peer_address])
|
||||
[dict setObject:UIImageJPEGRepresentation([UIImage resizeImage:[FastAddressBook imageForAddress:peer_address]
|
||||
withMaxWidth:200
|
||||
andMaxHeight:200],
|
||||
1)
|
||||
forKey:@"img"];
|
||||
}
|
||||
[dict setObject:display
|
||||
forKey:@"display"];
|
||||
[dict setObject:[NSNumber numberWithBool:linphone_chat_room_get_conference_address(cr)]
|
||||
forKey:@"nbParticipants"];
|
||||
[addresses addObject:dict];
|
||||
if (addresses.count >= 4) //send no more data than needed
|
||||
break;
|
||||
sorted = sorted->next;
|
||||
}
|
||||
|
||||
[defaults setObject:addresses forKey:@"chatrooms"];
|
||||
}
|
||||
|
||||
- (void)markCellAsRead:(LinphoneChatRoom *)chatRoom {
|
||||
int idx = bctbx_list_index(_data, VIEW(ChatConversationView).chatRoom);
|
||||
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:idx inSection:0];
|
||||
|
|
|
|||
|
|
@ -29,4 +29,5 @@
|
|||
@property(strong, nonatomic) NSMutableDictionary *sections;
|
||||
@property(strong, nonatomic) NSMutableArray *sortedDays;
|
||||
|
||||
+ (void) saveDataToUserDefaults;
|
||||
@end
|
||||
|
|
|
|||
|
|
@ -158,7 +158,7 @@
|
|||
[self computeSections];
|
||||
|
||||
[super loadData];
|
||||
|
||||
|
||||
if (IPAD) {
|
||||
if (![self selectFirstRow]) {
|
||||
HistoryDetailsView *view = VIEW(HistoryDetailsView);
|
||||
|
|
@ -167,6 +167,64 @@
|
|||
}
|
||||
}
|
||||
|
||||
+ (void) saveDataToUserDefaults {
|
||||
const bctbx_list_t *logs = linphone_core_get_call_logs(LC);
|
||||
NSUserDefaults *mySharedDefaults = [[NSUserDefaults alloc] initWithSuiteName: @"group.belledonne-communications.linphone.widget"];
|
||||
NSMutableArray *logsShare = [NSMutableArray array];
|
||||
NSMutableDictionary *tmpStoreDict = [NSMutableDictionary dictionary];
|
||||
NSMutableArray *addedContacts = [NSMutableArray array];
|
||||
while (logs) {
|
||||
LinphoneCallLog *log = (LinphoneCallLog *)logs->data;
|
||||
const LinphoneAddress *address = linphone_call_log_get_remote_address(log);
|
||||
|
||||
// if contact is already to be display, skip
|
||||
if ([addedContacts containsObject:[NSString stringWithUTF8String:linphone_address_as_string_uri_only(address)]]) {
|
||||
logs = bctbx_list_next(logs);
|
||||
continue;
|
||||
}
|
||||
// if null log id, skip
|
||||
if (!linphone_call_log_get_call_id(log)) {
|
||||
logs = bctbx_list_next(logs);
|
||||
continue;
|
||||
}
|
||||
|
||||
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
|
||||
|
||||
[dict setObject:[NSString stringWithUTF8String:linphone_call_log_get_call_id(log)]
|
||||
forKey:@"id"];
|
||||
[dict setObject:[NSString stringWithUTF8String:linphone_address_get_display_name(address)?:linphone_address_get_username(address)]
|
||||
forKey:@"display"];
|
||||
UIImage *avatar = [FastAddressBook imageForAddress:address];
|
||||
if (avatar) {
|
||||
UIImage *image = [UIImage resizeImage:avatar
|
||||
withMaxWidth:200
|
||||
andMaxHeight:200];
|
||||
NSData *imageData = UIImageJPEGRepresentation(image, 1);
|
||||
[dict setObject:imageData
|
||||
forKey:@"img"];
|
||||
}
|
||||
[tmpStoreDict setObject:dict
|
||||
forKey:[NSDate dateWithTimeIntervalSince1970:linphone_call_log_get_start_date(log)]];
|
||||
[addedContacts addObject:[NSString stringWithUTF8String:linphone_address_as_string_uri_only(address)]];
|
||||
|
||||
logs = bctbx_list_next(logs);
|
||||
}
|
||||
|
||||
NSArray *sortedDates = [[NSMutableArray alloc]
|
||||
initWithArray:[tmpStoreDict.allKeys sortedArrayUsingComparator:^NSComparisonResult(NSDate *d1, NSDate *d2) {
|
||||
return [d2 compare:d1];
|
||||
}]];
|
||||
|
||||
// sort logs array on date
|
||||
for (NSDate *date in sortedDates) {
|
||||
[logsShare addObject:[tmpStoreDict objectForKey:date]];
|
||||
if (logsShare.count >= 4) //send no more data than needed
|
||||
break;
|
||||
}
|
||||
|
||||
[mySharedDefaults setObject:logsShare forKey:@"logs"];
|
||||
}
|
||||
|
||||
- (void)computeSections {
|
||||
NSArray *unsortedDays = [self.sections allKeys];
|
||||
_sortedDays = [[NSMutableArray alloc]
|
||||
|
|
|
|||
|
|
@ -37,4 +37,4 @@
|
|||
|
||||
- (IBAction)onBackClick:(id)sender;
|
||||
|
||||
@end
|
||||
@end
|
||||
|
|
|
|||
|
|
@ -39,6 +39,8 @@
|
|||
@property PKPushRegistry* voipRegistry;
|
||||
@property ProviderDelegate *del;
|
||||
@property BOOL alreadyRegisteredForNotification;
|
||||
@property BOOL onlyPortrait;
|
||||
@property UIApplicationShortcutItem *shortcutItem;
|
||||
|
||||
@end
|
||||
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@
|
|||
startedInBackground = FALSE;
|
||||
}
|
||||
_alreadyRegisteredForNotification = false;
|
||||
_onlyPortrait = FALSE;
|
||||
return self;
|
||||
[[UIApplication sharedApplication] setDelegate:self];
|
||||
}
|
||||
|
|
@ -135,6 +136,12 @@
|
|||
}
|
||||
}
|
||||
[LinphoneManager.instance.iapManager check];
|
||||
if (_shortcutItem) {
|
||||
[self handleShortcut:_shortcutItem];
|
||||
_shortcutItem = nil;
|
||||
}
|
||||
[HistoryListTableView saveDataToUserDefaults];
|
||||
[ChatsListTableView saveDataToUserDefaults];
|
||||
}
|
||||
|
||||
#pragma deploymate push "ignored-api-availability"
|
||||
|
|
@ -223,6 +230,7 @@
|
|||
if (error)
|
||||
LOGD(error.description);
|
||||
}];
|
||||
|
||||
NSSet *categories = [NSSet setWithObjects:cat_call, cat_msg, video_call, cat_zrtp, nil];
|
||||
[[UNUserNotificationCenter currentNotificationCenter] setNotificationCategories:categories];
|
||||
}
|
||||
|
|
@ -279,6 +287,12 @@
|
|||
//output what state the app is in. This will be used to see when the app is started in the background
|
||||
LOGI(@"app launched with state : %li", (long)application.applicationState);
|
||||
LOGI(@"FINISH LAUNCHING WITH OPTION : %@", launchOptions.description);
|
||||
|
||||
UIApplicationShortcutItem *shortcutItem = [launchOptions objectForKey:@"UIApplicationLaunchOptionsShortcutItemKey"];
|
||||
if (shortcutItem) {
|
||||
_shortcutItem = shortcutItem;
|
||||
return NO;
|
||||
}
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
|
@ -308,6 +322,19 @@
|
|||
[LinphoneManager.instance destroyLinphoneCore];
|
||||
}
|
||||
|
||||
- (BOOL)handleShortcut:(UIApplicationShortcutItem *)shortcutItem {
|
||||
BOOL success = NO;
|
||||
if ([shortcutItem.type isEqualToString:@"linphone.phone.action.newMessage"]) {
|
||||
[PhoneMainView.instance changeCurrentView:ChatConversationCreateView.compositeViewDescription];
|
||||
success = YES;
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
- (void)application:(UIApplication *)application performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem completionHandler:(void (^)(BOOL))completionHandler {
|
||||
completionHandler([self handleShortcut:shortcutItem]);
|
||||
}
|
||||
|
||||
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
|
||||
NSString *scheme = [[url scheme] lowercaseString];
|
||||
if ([scheme isEqualToString:@"linphone-config"] || [scheme isEqualToString:@"linphone-config"]) {
|
||||
|
|
@ -333,16 +360,41 @@
|
|||
[errView addAction:yesAction];
|
||||
|
||||
[PhoneMainView.instance presentViewController:errView animated:YES completion:nil];
|
||||
} else {
|
||||
if ([[url scheme] isEqualToString:@"sip"]) {
|
||||
// remove "sip://" from the URI, and do it correctly by taking resourceSpecifier and removing leading and
|
||||
// trailing "/"
|
||||
NSString *sipUri = [[url resourceSpecifier]
|
||||
stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"/"]];
|
||||
[VIEW(DialerView) setAddress:sipUri];
|
||||
}
|
||||
}
|
||||
return YES;
|
||||
} else if([[url scheme] isEqualToString:@"message-linphone"]) {
|
||||
[PhoneMainView.instance popToView:ChatsListView.compositeViewDescription];
|
||||
} else if ([scheme isEqualToString:@"sip"]) {
|
||||
// remove "sip://" from the URI, and do it correctly by taking resourceSpecifier and removing leading and
|
||||
// trailing "/"
|
||||
NSString *sipUri = [[url resourceSpecifier] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"/"]];
|
||||
[VIEW(DialerView) setAddress:sipUri];
|
||||
} else if ([scheme isEqualToString:@"linphone-widget"]) {
|
||||
if ([[url host] isEqualToString:@"call_log"] &&
|
||||
[[url path] isEqualToString:@"/show"]) {
|
||||
[VIEW(HistoryDetailsView) setCallLogId:[url query]];
|
||||
[PhoneMainView.instance changeCurrentView:HistoryDetailsView.compositeViewDescription];
|
||||
} else if ([[url host] isEqualToString:@"chatroom"] && [[url path] isEqualToString:@"/show"]) {
|
||||
NSURLComponents *urlComponents = [NSURLComponents componentsWithURL:url
|
||||
resolvingAgainstBaseURL:NO];
|
||||
NSArray *queryItems = urlComponents.queryItems;
|
||||
NSString *peerAddress = [self valueForKey:@"peer" fromQueryItems:queryItems];
|
||||
NSString *localAddress = [self valueForKey:@"local" fromQueryItems:queryItems];
|
||||
LinphoneAddress *peer = linphone_address_new(peerAddress.UTF8String);
|
||||
LinphoneAddress *local = linphone_address_new(localAddress.UTF8String);
|
||||
LinphoneChatRoom *cr = linphone_core_find_chat_room(LC, peer, local);
|
||||
linphone_address_unref(peer);
|
||||
linphone_address_unref(local);
|
||||
// TODO : Find a better fix
|
||||
VIEW(ChatConversationView).markAsRead = FALSE;
|
||||
[PhoneMainView.instance goToChatRoom:cr];
|
||||
}
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (NSString *)valueForKey:(NSString *)key fromQueryItems:(NSArray *)queryItems {
|
||||
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name=%@", key];
|
||||
NSURLQueryItem *queryItem = [[queryItems filteredArrayUsingPredicate:predicate] firstObject];
|
||||
return queryItem.value;
|
||||
}
|
||||
|
||||
- (void)fixRing {
|
||||
|
|
@ -659,7 +711,7 @@
|
|||
}];
|
||||
} else if ([response.notification.request.content.categoryIdentifier isEqual:@"lime"]) {
|
||||
return;
|
||||
} else { // Missed call
|
||||
} else { // Missed call
|
||||
[PhoneMainView.instance changeCurrentView:HistoryListView.compositeViewDescription];
|
||||
}
|
||||
}
|
||||
|
|
@ -830,14 +882,13 @@
|
|||
#pragma mark - Prevent ImagePickerView from rotating
|
||||
|
||||
- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
|
||||
if ([[(PhoneMainView*)self.window.rootViewController currentView] equal:ImagePickerView.compositeViewDescription])
|
||||
if ([[(PhoneMainView*)self.window.rootViewController currentView] equal:ImagePickerView.compositeViewDescription] || _onlyPortrait)
|
||||
{
|
||||
//Prevent rotation of camera
|
||||
NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationPortrait];
|
||||
[[UIDevice currentDevice] setValue:value forKey:@"orientation"];
|
||||
return UIInterfaceOrientationMaskPortrait;
|
||||
}
|
||||
else return UIInterfaceOrientationMaskAllButUpsideDown;
|
||||
} else return UIInterfaceOrientationMaskAllButUpsideDown;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ extern NSString *const kLinphoneNotifyPresenceReceivedForUriOrTel;
|
|||
extern NSString *const kLinphoneCallEncryptionChanged;
|
||||
extern NSString *const kLinphoneFileTransferSendUpdate;
|
||||
extern NSString *const kLinphoneFileTransferRecvUpdate;
|
||||
extern NSString *const kLinphoneQRCodeFound;
|
||||
|
||||
typedef enum _NetworkType {
|
||||
network_none = 0,
|
||||
|
|
@ -205,6 +206,8 @@ typedef struct _LinphoneManagerSounds {
|
|||
- (void) setContactsUpdated:(BOOL) updated;
|
||||
- (BOOL) getContactsUpdated;
|
||||
|
||||
- (void)checkNewVersion;
|
||||
|
||||
@property ProviderDelegate *providerDelegate;
|
||||
|
||||
@property (readonly) BOOL isTesting;
|
||||
|
|
|
|||
|
|
@ -76,6 +76,7 @@ NSString *const kLinphoneNotifyPresenceReceivedForUriOrTel = @"LinphoneNotifyPre
|
|||
NSString *const kLinphoneCallEncryptionChanged = @"LinphoneCallEncryptionChanged";
|
||||
NSString *const kLinphoneFileTransferSendUpdate = @"LinphoneFileTransferSendUpdate";
|
||||
NSString *const kLinphoneFileTransferRecvUpdate = @"LinphoneFileTransferRecvUpdate";
|
||||
NSString *const kLinphoneQRCodeFound = @"LinphoneQRCodeFound";
|
||||
|
||||
const int kLinphoneAudioVbrCodecDefaultBitrate = 36; /*you can override this from linphonerc or linphonerc-factory*/
|
||||
|
||||
|
|
@ -718,6 +719,7 @@ static void linphone_iphone_display_status(struct _LinphoneCore *lc, const char
|
|||
|
||||
// Disable speaker when no more call
|
||||
if ((state == LinphoneCallEnd || state == LinphoneCallError)) {
|
||||
[HistoryListTableView saveDataToUserDefaults];
|
||||
[[UIDevice currentDevice] setProximityMonitoringEnabled:FALSE];
|
||||
speaker_already_enabled = FALSE;
|
||||
if (linphone_core_get_calls_nb(theLinphoneCore) == 0) {
|
||||
|
|
@ -1041,18 +1043,18 @@ static void linphone_iphone_popup_password_request(LinphoneCore *lc, LinphoneAut
|
|||
@"provide password again, or check your "
|
||||
@"account configuration in the settings.", nil), username, realm]
|
||||
preferredStyle:UIAlertControllerStyleAlert];
|
||||
|
||||
|
||||
UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"Cancel", nil)
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {}];
|
||||
|
||||
|
||||
[alertView addTextFieldWithConfigurationHandler:^(UITextField *textField) {
|
||||
textField.placeholder = NSLocalizedString(@"Password", nil);
|
||||
textField.clearButtonMode = UITextFieldViewModeWhileEditing;
|
||||
textField.borderStyle = UITextBorderStyleRoundedRect;
|
||||
textField.secureTextEntry = YES;
|
||||
}];
|
||||
|
||||
|
||||
UIAlertAction* continueAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"Confirm password", nil)
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
|
|
@ -1063,13 +1065,13 @@ static void linphone_iphone_popup_password_request(LinphoneCore *lc, LinphoneAut
|
|||
linphone_core_add_auth_info(LC, info);
|
||||
[LinphoneManager.instance refreshRegisters];
|
||||
}];
|
||||
|
||||
|
||||
UIAlertAction* settingsAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"Go to settings", nil)
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
[PhoneMainView.instance changeCurrentView:SettingsView.compositeViewDescription];
|
||||
}];
|
||||
|
||||
|
||||
[alertView addAction:defaultAction];
|
||||
[alertView addAction:continueAction];
|
||||
[alertView addAction:settingsAction];
|
||||
|
|
@ -1145,7 +1147,7 @@ static void linphone_iphone_popup_password_request(LinphoneCore *lc, LinphoneAut
|
|||
if (PhoneMainView.instance.currentView == ChatConversationView.compositeViewDescription && room == PhoneMainView.instance.currentRoom)
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Create a new notification
|
||||
if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_9_x_Max) {
|
||||
NSArray *actions;
|
||||
|
|
@ -1241,6 +1243,8 @@ static void linphone_iphone_popup_password_request(LinphoneCore *lc, LinphoneAut
|
|||
}
|
||||
}];
|
||||
}
|
||||
[ChatsListTableView saveDataToUserDefaults];
|
||||
[HistoryListTableView saveDataToUserDefaults];
|
||||
}
|
||||
|
||||
static void linphone_iphone_message_received(LinphoneCore *lc, LinphoneChatRoom *room, LinphoneChatMessage *message) {
|
||||
|
|
@ -1394,6 +1398,34 @@ void linphone_iphone_chatroom_state_changed(LinphoneCore *lc, LinphoneChatRoom *
|
|||
[NSNotificationCenter.defaultCenter postNotificationName:kLinphoneMessageReceived object:nil];
|
||||
}
|
||||
|
||||
void linphone_iphone_version_update_check_result_received (LinphoneCore *lc, LinphoneVersionUpdateCheckResult result, const char *version, const char *url) {
|
||||
if (result == LinphoneVersionUpdateCheckUpToDate || result == LinphoneVersionUpdateCheckError) {
|
||||
return;
|
||||
}
|
||||
NSString *title = NSLocalizedString(@"Outdated Version", nil);
|
||||
NSString *body = NSLocalizedString(@"A new version of your app is available, use the button below to download it.", nil);
|
||||
|
||||
UIAlertController *versVerifView = [UIAlertController alertControllerWithTitle:title
|
||||
message:body
|
||||
preferredStyle:UIAlertControllerStyleAlert];
|
||||
|
||||
NSString *ObjCurl = [NSString stringWithUTF8String:url];
|
||||
UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"Download", nil)
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:ObjCurl]];
|
||||
}];
|
||||
|
||||
[versVerifView addAction:defaultAction];
|
||||
[PhoneMainView.instance presentViewController:versVerifView animated:YES completion:nil];
|
||||
}
|
||||
|
||||
void linphone_iphone_qr_code_found(LinphoneCore *lc, const char *result) {
|
||||
NSDictionary *eventDic = [NSDictionary dictionaryWithObject:[NSString stringWithCString:result encoding:[NSString defaultCStringEncoding]] forKey:@"qrcode"];
|
||||
LOGD(@"QRCODE FOUND");
|
||||
[NSNotificationCenter.defaultCenter postNotificationName:kLinphoneQRCodeFound object:nil userInfo:eventDic];
|
||||
}
|
||||
|
||||
#pragma mark - Message composition start
|
||||
- (void)alertLIME:(LinphoneChatRoom *)room {
|
||||
NSString *title = NSLocalizedString(@"LIME warning", nil);
|
||||
|
|
@ -1572,7 +1604,7 @@ static void networkReachabilityNotification(CFNotificationCenterRef center, void
|
|||
if ([newSSID compare:mgr.SSID] == NSOrderedSame)
|
||||
return;
|
||||
|
||||
|
||||
|
||||
if (newSSID != Nil && newSSID.length > 0 && mgr.SSID != Nil && newSSID.length > 0) {
|
||||
if (SCNetworkReachabilityGetFlags([mgr getProxyReachability], &flags)) {
|
||||
LOGI(@"Wifi SSID changed, resesting transports.");
|
||||
|
|
@ -1798,10 +1830,13 @@ void networkReachabilityCallBack(SCNetworkReachabilityRef target, SCNetworkReach
|
|||
linphone_core_enable_video_display(theLinphoneCore, FALSE);
|
||||
linphone_core_enable_video_capture(theLinphoneCore, FALSE);
|
||||
}
|
||||
|
||||
|
||||
[self enableProxyPublish:([UIApplication sharedApplication].applicationState == UIApplicationStateActive)];
|
||||
|
||||
LOGI(@"Linphone [%s] started on [%s]", linphone_core_get_version(), [[UIDevice currentDevice].model UTF8String]);
|
||||
//update UserDefaults for widgets
|
||||
[HistoryListTableView saveDataToUserDefaults];
|
||||
|
||||
LOGI(@"Linphone [%s] started on [%s]", linphone_core_get_version(), [[UIDevice currentDevice].model UTF8String]);
|
||||
|
||||
// Post event
|
||||
NSDictionary *dict = [NSDictionary dictionaryWithObject:[NSValue valueWithPointer:theLinphoneCore] forKey:@"core"];
|
||||
|
|
@ -1847,11 +1882,11 @@ static BOOL libStarted = FALSE;
|
|||
UIAlertController *errView = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"No microphone", nil)
|
||||
message:NSLocalizedString(@"You need to plug a microphone to your device to use the application.", 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];
|
||||
}
|
||||
|
|
@ -1877,11 +1912,11 @@ void popup_link_account_cb(LinphoneAccountCreator *creator, LinphoneAccountCreat
|
|||
message:[NSString stringWithFormat:NSLocalizedString(@"Link your Linphone.org account %s to your phone number.", nil),
|
||||
linphone_address_get_username(linphone_proxy_config_get_identity_address(cfg))]
|
||||
preferredStyle:UIAlertControllerStyleAlert];
|
||||
|
||||
|
||||
UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"Maybe later", nil)
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {}];
|
||||
|
||||
|
||||
UIAlertAction* continueAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"Let's go", nil)
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
|
|
@ -1929,7 +1964,7 @@ void popup_link_account_cb(LinphoneAccountCreator *creator, LinphoneAccountCreat
|
|||
LOGI(@"linphonecore is already created");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
connectivity = none;
|
||||
|
||||
// Set audio assets
|
||||
|
|
@ -1964,11 +1999,14 @@ void popup_link_account_cb(LinphoneAccountCreator *creator, LinphoneAccountCreat
|
|||
linphone_core_cbs_set_notify_received(cbs, linphone_iphone_notify_received);
|
||||
linphone_core_cbs_set_call_encryption_changed(cbs, linphone_iphone_call_encryption_changed);
|
||||
linphone_core_cbs_set_chat_room_state_changed(cbs, linphone_iphone_chatroom_state_changed);
|
||||
linphone_core_cbs_set_version_update_check_result_received(cbs, linphone_iphone_version_update_check_result_received);
|
||||
linphone_core_cbs_set_qrcode_found(cbs, linphone_iphone_qr_code_found);
|
||||
linphone_core_cbs_set_user_data(cbs, (__bridge void *)(self));
|
||||
|
||||
|
||||
theLinphoneCore = linphone_factory_create_core_with_config_3(factory, _configDb, NULL);
|
||||
linphone_core_add_callbacks(theLinphoneCore, cbs);
|
||||
linphone_core_start(theLinphoneCore);
|
||||
|
||||
// Let the core handle cbs
|
||||
linphone_core_cbs_unref(cbs);
|
||||
|
||||
|
|
@ -1982,7 +2020,7 @@ void popup_link_account_cb(LinphoneAccountCreator *creator, LinphoneAccountCreat
|
|||
libmsopenh264_init(f);
|
||||
libmswebrtc_init(f);
|
||||
libmscodec2_init(f);
|
||||
|
||||
|
||||
linphone_core_reload_ms_plugins(theLinphoneCore, NULL);
|
||||
[self migrationAllPost];
|
||||
|
||||
|
|
@ -2248,7 +2286,7 @@ static int comp_call_state_paused(const LinphoneCall *call, const void *param) {
|
|||
if (linphone_core_get_global_state(LC) != LinphoneGlobalOn || !linphone_core_get_default_friend_list(LC)) {
|
||||
LOGW(@"Not changing presence configuration because linphone core not ready yet");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ([self lpConfigBoolForKey:@"publish_presence"]) {
|
||||
// set present to "tv", because "available" does not work yet
|
||||
|
|
@ -2283,7 +2321,7 @@ static int comp_call_state_paused(const LinphoneCall *call, const void *param) {
|
|||
|
||||
// disable presence
|
||||
[self enableProxyPublish:NO];
|
||||
|
||||
|
||||
// handle proxy config if any
|
||||
if (proxyCfg) {
|
||||
const char *refkey = proxyCfg ? linphone_proxy_config_get_ref_key(proxyCfg) : NULL;
|
||||
|
|
@ -2336,6 +2374,8 @@ static int comp_call_state_paused(const LinphoneCall *call, const void *param) {
|
|||
- (void)becomeActive {
|
||||
linphone_core_enter_foreground(LC);
|
||||
|
||||
[self checkNewVersion];
|
||||
|
||||
// enable presence
|
||||
if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_9_x_Max || self.connectivity == none) {
|
||||
[self refreshRegisters];
|
||||
|
|
@ -2563,11 +2603,11 @@ static int comp_call_state_paused(const LinphoneCall *call, const void *param) {
|
|||
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];
|
||||
return;
|
||||
|
|
@ -2596,11 +2636,11 @@ static int comp_call_state_paused(const LinphoneCall *call, const void *param) {
|
|||
message:NSLocalizedString(@"Either configure a SIP proxy server from settings prior to place a "
|
||||
@"call or use a valid SIP address (I.E sip:john@example.net)", 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];
|
||||
return;
|
||||
|
|
@ -3026,4 +3066,14 @@ static int comp_call_state_paused(const LinphoneCall *call, const void *param) {
|
|||
- (void)exportSymbolsForUITests {
|
||||
linphone_address_set_header(NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
- (void)checkNewVersion {
|
||||
if (!CHECK_VERSION_UPDATE)
|
||||
return;
|
||||
if (theLinphoneCore == nil)
|
||||
return;
|
||||
NSString *curVersion = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"];
|
||||
const char *curVersionCString = [curVersion cStringUsingEncoding:NSUTF8StringEncoding];
|
||||
linphone_core_check_for_update(theLinphoneCore, curVersionCString);
|
||||
}
|
||||
@end
|
||||
|
|
|
|||
74
Classes/LinphoneUI/Base.lproj/UIChatBubbleFile.xib
Normal file
74
Classes/LinphoneUI/Base.lproj/UIChatBubbleFile.xib
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
<?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>
|
||||
|
|
@ -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">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14113" 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="13527"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14088"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
|
|
@ -15,16 +15,20 @@
|
|||
<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="8qr-kw-dSx"/>
|
||||
<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"/>
|
||||
<outlet property="downloadButton" destination="N75-gL-R6t" id="EgN-Ab-Ded"/>
|
||||
<outlet property="fileName" destination="Dho-UV-6Ev" id="Iro-II-w8a"/>
|
||||
<outlet property="fileTransferProgress" destination="USm-wC-GvG" id="POt-YD-NCG"/>
|
||||
<outlet property="finalImage" destination="gzv-K4-5OL" id="YIw-kM-Ld6"/>
|
||||
<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="messageImageView" destination="yMW-cT-bpU" id="MNr-F2-abQ"/>
|
||||
<outlet property="openRecognizer" destination="NYA-II-xYn" id="pVM-vD-4Rg"/>
|
||||
<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"/>
|
||||
|
|
@ -32,15 +36,15 @@
|
|||
</placeholder>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||
<view contentMode="scaleToFill" misplaced="YES" id="UGz-WT-BUv">
|
||||
<rect key="frame" x="0.0" y="0.0" width="334" height="161"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="377" height="301"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
|
||||
<subviews>
|
||||
<view clipsSubviews="YES" contentMode="scaleToFill" id="Y7i-Gm-AdY" userLabel="innerView">
|
||||
<rect key="frame" x="6" y="5" width="322" height="151"/>
|
||||
<rect key="frame" x="6" y="5" width="365" height="291"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<imageView userInteractionEnabled="NO" alpha="0.20000000298023224" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="color_A.png" id="U2P-5n-gg8" userLabel="backgroundColorImage">
|
||||
<rect key="frame" x="0.0" y="0.0" width="322" height="151"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="365" height="291"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES" flexibleMaxY="YES"/>
|
||||
</imageView>
|
||||
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" image="avatar.png" id="hD2-19-7IH" userLabel="avatarImage" customClass="UIRoundedImageView">
|
||||
|
|
@ -52,35 +56,40 @@
|
|||
</accessibility>
|
||||
</imageView>
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="11:35 John Doe" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="JyR-RQ-uwF" userLabel="contactDateLabel">
|
||||
<rect key="frame" x="55" y="8" width="246" height="14"/>
|
||||
<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" id="8I3-n2-0kS" userLabel="view">
|
||||
<rect key="frame" x="55" y="24" width="259" height="100"/>
|
||||
<view contentMode="scaleToFill" misplaced="YES" id="8I3-n2-0kS" userLabel="view">
|
||||
<rect key="frame" x="39" y="55" width="298" height="190"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES" flexibleMaxY="YES"/>
|
||||
<subviews>
|
||||
<imageView contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="linphone_logo.png" id="yMW-cT-bpU" userLabel="image" customClass="UILoadingImageView">
|
||||
<rect key="frame" x="0.0" y="0.0" width="259" height="68"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="298" height="122"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES" flexibleMaxY="YES"/>
|
||||
<gestureRecognizers/>
|
||||
<connections>
|
||||
<outletCollection property="gestureRecognizers" destination="aDF-hC-ddO" appends="YES" id="7kE-0j-s1g"/>
|
||||
</connections>
|
||||
</imageView>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" text="Label" textAlignment="center" lineBreakMode="middleTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="Dho-UV-6Ev" userLabel="fileName">
|
||||
<rect key="frame" x="0.0" y="0.0" width="200" height="50"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<color key="backgroundColor" white="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<view contentMode="scaleToFill" id="GmN-7v-uuO" userLabel="imageSubView">
|
||||
<rect key="frame" x="0.0" y="68" width="258" height="32"/>
|
||||
<rect key="frame" x="0.0" y="128" width="297" height="62"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<progressView opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="750" progress="0.5" id="USm-wC-GvG" userLabel="transferProgress">
|
||||
<rect key="frame" x="10" y="0.0" width="238" height="2"/>
|
||||
<rect key="frame" x="10" y="29" width="277" height="2"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
||||
</progressView>
|
||||
<button opaque="NO" contentMode="scaleToFill" misplaced="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" id="N75-gL-R6t" userLabel="downloadButton" customClass="UIRoundBorderedButton">
|
||||
<rect key="frame" x="66" y="4" width="115" height="27"/>
|
||||
<rect key="frame" x="84" y="33" 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">
|
||||
|
|
@ -92,7 +101,7 @@
|
|||
</connections>
|
||||
</button>
|
||||
<button opaque="NO" contentMode="scaleToFill" misplaced="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" id="6dl-Nz-rdv" userLabel="cancelButton" customClass="UIRoundBorderedButton">
|
||||
<rect key="frame" x="66" y="4" width="115" height="27"/>
|
||||
<rect key="frame" x="84" y="33" 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"/>
|
||||
|
|
@ -108,28 +117,56 @@
|
|||
</view>
|
||||
</subviews>
|
||||
</view>
|
||||
<view contentMode="scaleToFill" misplaced="YES" id="VYJ-RC-Jmg">
|
||||
<rect key="frame" x="8" y="55" width="349" height="213"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<imageView hidden="YES" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" id="gzv-K4-5OL" userLabel="finalImage">
|
||||
<rect key="frame" x="0.0" y="0.0" width="349" height="213"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<gestureRecognizers/>
|
||||
</imageView>
|
||||
<button opaque="NO" contentMode="scaleToFill" misplaced="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" id="cvc-tl-Pcf" userLabel="playButton" customClass="UIRoundBorderedButton">
|
||||
<rect key="frame" x="125" y="93" width="50" height="25"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<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>
|
||||
</subviews>
|
||||
<connections>
|
||||
<outletCollection property="gestureRecognizers" destination="aDF-hC-ddO" appends="YES" id="lKJ-ra-dwR"/>
|
||||
<outletCollection property="gestureRecognizers" destination="NYA-II-xYn" appends="YES" id="fK6-ld-zOX"/>
|
||||
</connections>
|
||||
</view>
|
||||
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="color_A.png" id="6dA-3U-OPW" userLabel="bottomBarColor">
|
||||
<rect key="frame" x="0.0" y="150" width="322" height="1"/>
|
||||
<rect key="frame" x="0.0" y="290" width="365" height="1"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
||||
</imageView>
|
||||
<activityIndicatorView opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" hidesWhenStopped="YES" animating="YES" style="gray" id="Eab-ND-ix3" userLabel="statusInprogressSpinner">
|
||||
<rect key="frame" x="302" y="0.0" width="20" height="20"/>
|
||||
<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" misplaced="YES" image="chat_unsecure.png" id="IST-5o-DCu" userLabel="LIMEKO">
|
||||
<rect key="frame" x="308" y="6" width="8" height="12"/>
|
||||
<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>
|
||||
<label hidden="YES" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" text="Delivered" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="44j-me-Iqi" userLabel="imdmLabel">
|
||||
<rect key="frame" x="240" y="134" width="64" height="20"/>
|
||||
<rect key="frame" x="283" y="274" 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" misplaced="YES" image="valid_default.png" id="LPj-VT-0fH" userLabel="imdmIcon">
|
||||
<rect key="frame" x="306" y="136" width="13" height="13"/>
|
||||
<rect key="frame" x="349" y="276" width="13" height="13"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
|
||||
<accessibility key="accessibilityConfiguration" label="Delivery failed"/>
|
||||
</imageView>
|
||||
|
|
@ -142,16 +179,21 @@
|
|||
<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="-95" y="176.5"/>
|
||||
<point key="canvasLocation" x="-73.5" y="246.5"/>
|
||||
</view>
|
||||
<tapGestureRecognizer id="5ZI-Ip-lGl" userLabel="resendClick">
|
||||
<connections>
|
||||
<action selector="onResendClick:" destination="-1" id="XOF-AF-Hes"/>
|
||||
</connections>
|
||||
</tapGestureRecognizer>
|
||||
<tapGestureRecognizer id="aDF-hC-ddO" userLabel="imageClick">
|
||||
<connections>
|
||||
<action selector="onImageClick:" destination="-1" id="feN-LT-89b"/>
|
||||
</connections>
|
||||
</tapGestureRecognizer>
|
||||
<tapGestureRecognizer id="5ZI-Ip-lGl" userLabel="resendClick">
|
||||
<tapGestureRecognizer id="NYA-II-xYn" userLabel="openClick">
|
||||
<connections>
|
||||
<action selector="onResendClick:" destination="-1" id="XOF-AF-Hes"/>
|
||||
<action selector="onOpenClick:" destination="-1" id="XaJ-Or-uQQ"/>
|
||||
</connections>
|
||||
</tapGestureRecognizer>
|
||||
</objects>
|
||||
|
|
@ -162,7 +204,7 @@
|
|||
<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="22"/>
|
||||
<image name="linphone_logo.png" width="26" height="26"/>
|
||||
<image name="valid_default.png" width="28" height="19"/>
|
||||
</resources>
|
||||
</document>
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="13196" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" colorMatched="YES">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="13771" 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="13174"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13772"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
|
|
|
|||
|
|
@ -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="14113" 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="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="UIChatCell">
|
||||
|
|
@ -11,6 +15,7 @@
|
|||
<outlet property="avatarImage" destination="19" id="30"/>
|
||||
<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="unreadCountLabel" destination="ZXq-Do-7Ua" id="anx-Na-sYz"/>
|
||||
<outlet property="unreadCountView" destination="7DE-KJ-9Q3" id="hkt-rA-EKa"/>
|
||||
</connections>
|
||||
|
|
@ -29,7 +34,7 @@
|
|||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<accessibility key="accessibilityConfiguration" label=""/>
|
||||
<fontDescription key="fontDescription" type="boldSystem" pointSize="25"/>
|
||||
<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>
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" tag="2" contentMode="left" text="John Doe" lineBreakMode="tailTruncation" minimumFontSize="10" adjustsFontSizeToFit="NO" id="20" userLabel="addressLabel">
|
||||
|
|
@ -37,15 +42,7 @@
|
|||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
|
||||
<accessibility key="accessibilityConfiguration" label="Contact name"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="25"/>
|
||||
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" tag="2" contentMode="left" text="This is a placeholder message" lineBreakMode="tailTruncation" numberOfLines="3" adjustsFontSizeToFit="NO" id="21" userLabel="chatContentLabel">
|
||||
<rect key="frame" x="59" y="31" width="316" height="29"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES"/>
|
||||
<accessibility key="accessibilityConfiguration" label="Message"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="12"/>
|
||||
<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>
|
||||
<view hidden="YES" autoresizesSubviews="NO" userInteractionEnabled="NO" tag="7" contentMode="scaleToFill" id="7DE-KJ-9Q3" userLabel="unreadCountView" customClass="UIBouncingView">
|
||||
|
|
@ -64,12 +61,27 @@
|
|||
<bool key="isElement" value="NO"/>
|
||||
</accessibility>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</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>
|
||||
<imageView 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"/>
|
||||
<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"/>
|
||||
<accessibility key="accessibilityConfiguration" label="Message"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="12"/>
|
||||
<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"/>
|
||||
|
|
@ -77,7 +89,8 @@
|
|||
</view>
|
||||
</objects>
|
||||
<resources>
|
||||
<image name="avatar.png" width="255" height="255"/>
|
||||
<image name="history_chat_indicator.png" width="13" height="13"/>
|
||||
<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"/>
|
||||
</resources>
|
||||
</document>
|
||||
|
|
|
|||
|
|
@ -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" useTraitCollections="YES" colorMatched="YES">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14113" 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"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13772"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
|
|
@ -25,18 +25,18 @@
|
|||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
|
||||
<subviews>
|
||||
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" fixedFrame="YES" insetsLayoutMarginsFromSafeArea="NO" image="avatar.png" translatesAutoresizingMaskIntoConstraints="NO" id="Z2U-vm-azg" userLabel="avatarImage" customClass="UIRoundedImageView">
|
||||
<rect key="frame" x="0.0" y="5" width="44" height="29"/>
|
||||
<rect key="frame" x="0.0" y="5" width="44" height="28"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
|
||||
</imageView>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" insetsLayoutMarginsFromSafeArea="NO" text="John Doe" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="f3q-pd-EF5" userLabel="displayNameLabel">
|
||||
<rect key="frame" x="43" y="11" width="185" height="17"/>
|
||||
<rect key="frame" x="43" y="11" width="185" height="16"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" fixedFrame="YES" insetsLayoutMarginsFromSafeArea="NO" text="Today - 18h42" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="hEV-7I-B0v" userLabel="contactDateLabel">
|
||||
<rect key="frame" x="200" y="13" width="159" height="13"/>
|
||||
<rect key="frame" x="200" y="13" width="159" height="12"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" heightSizable="YES"/>
|
||||
<accessibility key="accessibilityConfiguration" label="Contact name"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="12"/>
|
||||
|
|
|
|||
|
|
@ -29,10 +29,14 @@
|
|||
|
||||
@property(nonatomic, strong) IBOutlet UILoadingImageView *messageImageView;
|
||||
@property(nonatomic, strong) IBOutlet UIButton *downloadButton;
|
||||
@property (weak, nonatomic) IBOutlet UILabel *fileName;
|
||||
@property(nonatomic, strong) IBOutlet UIButton *playButton;
|
||||
@property(weak, nonatomic) IBOutlet UIProgressView *fileTransferProgress;
|
||||
@property(weak, nonatomic) IBOutlet UIButton *cancelButton;
|
||||
@property(weak, nonatomic) IBOutlet UIView *imageSubView;
|
||||
@property (strong, nonatomic) IBOutlet UITapGestureRecognizer *openRecognizer;
|
||||
@property(weak, nonatomic) IBOutlet UIView *totalView;
|
||||
@property (weak, nonatomic) IBOutlet UIImageView *finalImage;
|
||||
@property(strong, nonatomic) IBOutlet UITapGestureRecognizer *imageGestureRecognizer;
|
||||
|
||||
- (void)setEvent:(LinphoneEventLog *)event;
|
||||
|
|
@ -42,5 +46,10 @@
|
|||
- (IBAction)onImageClick:(id)event;
|
||||
- (IBAction)onCancelClick:(id)sender;
|
||||
- (IBAction)onResendClick:(id)event;
|
||||
- (IBAction)onPlayClick:(id)sender;
|
||||
- (IBAction)onOpenClick:(id)event;
|
||||
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -23,9 +23,16 @@
|
|||
|
||||
#import <AssetsLibrary/ALAsset.h>
|
||||
#import <AssetsLibrary/ALAssetRepresentation.h>
|
||||
#import <AVFoundation/AVFoundation.h>
|
||||
#import <AudioToolbox/AudioToolbox.h>
|
||||
#import <AVKit/AVKit.h>
|
||||
|
||||
@implementation UIChatBubblePhotoCell {
|
||||
FileTransferDelegate *_ftd;
|
||||
CGSize imageSize, bubbleSize, videoDefaultSize;
|
||||
int actualAvailableWidth;
|
||||
ChatConversationTableView *chatTableView;
|
||||
//CGImageRef displayedImage;
|
||||
}
|
||||
|
||||
#pragma mark - Lifecycle Functions
|
||||
|
|
@ -44,8 +51,11 @@
|
|||
break;
|
||||
}
|
||||
}
|
||||
[self setFrame:CGRectMake(0, 0, sub.frame.size.width, sub.frame.size.height)];
|
||||
[self setFrame:CGRectMake(0, 0, 5, 100)];
|
||||
[self addSubview:sub];
|
||||
chatTableView = VIEW(ChatConversationView).tableController;
|
||||
actualAvailableWidth = chatTableView.tableView.frame.size.width;
|
||||
videoDefaultSize = CGSizeMake(320, 240);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
|
@ -61,7 +71,10 @@
|
|||
|
||||
- (void)setChatMessage:(LinphoneChatMessage *)amessage {
|
||||
_imageGestureRecognizer.enabled = NO;
|
||||
_openRecognizer.enabled = NO;
|
||||
_messageImageView.image = nil;
|
||||
_finalImage.image = nil;
|
||||
_finalImage.hidden = TRUE;
|
||||
_fileTransferProgress.progress = 0;
|
||||
[self disconnectFromFileDelegate];
|
||||
|
||||
|
|
@ -85,15 +98,62 @@
|
|||
[super setChatMessage:amessage];
|
||||
}
|
||||
|
||||
- (void) loadImageAsset:(ALAsset*) asset thumb:(UIImage *)thumb image:(UIImage *)image {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[_finalImage setImage:image];
|
||||
[_messageImageView setImage:thumb];
|
||||
[_messageImageView setFullImageUrl:asset];
|
||||
[_messageImageView stopLoading];
|
||||
_messageImageView.hidden = YES;
|
||||
_imageGestureRecognizer.enabled = YES;
|
||||
_finalImage.hidden = NO;
|
||||
});
|
||||
}
|
||||
|
||||
- (void) loadAsset:(ALAsset*) asset {
|
||||
UIImage *image = [[UIImage alloc] initWithCGImage:[asset thumbnail]];
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[_messageImageView setImage:image];
|
||||
[_messageImageView setFullImageUrl:asset];
|
||||
[_messageImageView stopLoading];
|
||||
_messageImageView.hidden = NO;
|
||||
_imageGestureRecognizer.enabled = YES;
|
||||
});
|
||||
UIImage *thumb = [[UIImage alloc] initWithCGImage:[asset thumbnail]];
|
||||
ALAssetRepresentation *representation = [asset defaultRepresentation];
|
||||
imageSize = [UIChatBubbleTextCell getMediaMessageSizefromOriginalSize:[representation dimensions] withWidth:chatTableView.tableView.frame.size.width];
|
||||
CGImageRef tmpImg = [self cropImageFromRepresentation:representation];
|
||||
UIImage *image = [[UIImage alloc] initWithCGImage:tmpImg];
|
||||
[self loadImageAsset:asset thumb:thumb image:image];
|
||||
}
|
||||
|
||||
- (void) loadVideoAsset: (AVAsset *) asset {
|
||||
// Calculate a time for the snapshot - I'm using the half way mark.
|
||||
CMTime duration = [asset duration];
|
||||
CMTime snapshot = CMTimeMake(duration.value / 2, duration.timescale);
|
||||
// Create a generator and copy image at the time.
|
||||
// I'm not capturing the actual time or an error.
|
||||
AVAssetImageGenerator *generator =
|
||||
[AVAssetImageGenerator assetImageGeneratorWithAsset:asset];
|
||||
CGImageRef imageRef = [generator copyCGImageAtTime:snapshot
|
||||
actualTime:nil
|
||||
error:nil];
|
||||
|
||||
UIImage *thumb = [UIImage imageWithCGImage:imageRef];
|
||||
CGImageRelease(imageRef);
|
||||
|
||||
UIGraphicsBeginImageContext(videoDefaultSize);
|
||||
[thumb drawInRect:CGRectMake(0, 0, videoDefaultSize.width, videoDefaultSize.height)];
|
||||
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
|
||||
UIGraphicsEndImageContext();
|
||||
|
||||
[self loadImageAsset:nil thumb:thumb image:image];
|
||||
|
||||
// put the play button in the top
|
||||
CGRect newFrame = _playButton.frame;
|
||||
newFrame.origin.x = _finalImage.frame.origin.x/2;
|
||||
newFrame.origin.y = _finalImage.frame.origin.y/2;
|
||||
_playButton.frame = newFrame;
|
||||
}
|
||||
|
||||
- (void) loadFileAsset {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
_fileName.hidden = NO;
|
||||
_imageGestureRecognizer.enabled = NO;
|
||||
_openRecognizer.enabled = YES;
|
||||
});
|
||||
}
|
||||
|
||||
- (void)update {
|
||||
|
|
@ -107,77 +167,107 @@
|
|||
BOOL is_external =
|
||||
(url && (strstr(url, "http") == url)) || linphone_chat_message_get_file_transfer_information(self.message);
|
||||
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);
|
||||
if (localImage) {
|
||||
// image is being saved on device - just wait for it
|
||||
if ([localImage isEqualToString:@"saving..."]) {
|
||||
_cancelButton.hidden = _fileTransferProgress.hidden = _downloadButton.hidden = YES;
|
||||
fullScreenImage = YES;
|
||||
} else {
|
||||
// we did not load the image yet, so start doing so
|
||||
if (_messageImageView.image == nil) {
|
||||
NSURL *imageUrl = [NSURL URLWithString:localImage];
|
||||
[_messageImageView startLoading];
|
||||
__block LinphoneChatMessage *achat = self.message;
|
||||
[LinphoneManager.instance.photoLibrary assetForURL:imageUrl
|
||||
resultBlock:^(ALAsset *asset) {
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, (unsigned long)NULL),
|
||||
^(void) {
|
||||
if (achat != self.message) // Avoid glitch and scrolling
|
||||
return;
|
||||
|
||||
if (asset)
|
||||
[self loadAsset:asset];
|
||||
else {
|
||||
[LinphoneManager.instance.photoLibrary
|
||||
enumerateGroupsWithTypes:ALAssetsGroupAll
|
||||
usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
|
||||
[group enumerateAssetsWithOptions:NSEnumerationReverse
|
||||
usingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) {
|
||||
if([result.defaultRepresentation.url isEqual:imageUrl]) {
|
||||
[self loadAsset:result];
|
||||
*stop = YES;
|
||||
}
|
||||
}];
|
||||
}
|
||||
failureBlock:^(NSError *error) {
|
||||
LOGE(@"Error: Cannot load asset from photo stream - %@", [error localizedDescription]);
|
||||
}];
|
||||
}
|
||||
});
|
||||
}
|
||||
failureBlock:^(NSError *error) {
|
||||
LOGE(@"Can't read image");
|
||||
}];
|
||||
}
|
||||
// we are uploading the image
|
||||
if (_ftd.message != nil) {
|
||||
_cancelButton.hidden = NO;
|
||||
_fileTransferProgress.hidden = NO;
|
||||
_downloadButton.hidden = YES;
|
||||
} else {
|
||||
_cancelButton.hidden = _fileTransferProgress.hidden = _downloadButton.hidden = YES;
|
||||
fullScreenImage = YES;
|
||||
}
|
||||
}
|
||||
// we must download the image: either it has already started (show cancel button) or not yet (show download
|
||||
// button)
|
||||
} else {
|
||||
_messageImageView.hidden = _cancelButton.hidden = (_ftd.message == nil);
|
||||
_downloadButton.hidden = !_cancelButton.hidden;
|
||||
_fileTransferProgress.hidden = NO;
|
||||
}
|
||||
assert(is_external || localImage || localVideo || localFile);
|
||||
|
||||
if (!(localImage || localVideo || localFile)) {
|
||||
_playButton.hidden = YES;
|
||||
_fileName.hidden = YES;
|
||||
_messageImageView.hidden = _cancelButton.hidden = (_ftd.message == nil);
|
||||
_downloadButton.hidden = !_cancelButton.hidden;
|
||||
_fileTransferProgress.hidden = NO;
|
||||
} else {
|
||||
// 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 = YES;
|
||||
fullScreenImage = YES;
|
||||
} else {
|
||||
if (localImage) {
|
||||
// we did not load the image yet, so start doing so
|
||||
if (_messageImageView.image == nil) {
|
||||
NSURL *imageUrl = [NSURL URLWithString:localImage];
|
||||
[_messageImageView startLoading];
|
||||
__block LinphoneChatMessage *achat = self.message;
|
||||
[LinphoneManager.instance.photoLibrary assetForURL:imageUrl resultBlock:^(ALAsset *asset) { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, (unsigned long)NULL), ^(void) {
|
||||
if (achat != self.message) // Avoid glitch and scrolling
|
||||
return;
|
||||
|
||||
if (asset) {
|
||||
[self loadAsset:asset];
|
||||
}
|
||||
else {
|
||||
[LinphoneManager.instance.photoLibrary
|
||||
enumerateGroupsWithTypes:ALAssetsGroupAll
|
||||
usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
|
||||
[group enumerateAssetsWithOptions:NSEnumerationReverse
|
||||
usingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) {
|
||||
if([result.defaultRepresentation.url isEqual:imageUrl]) {
|
||||
[self loadAsset:result];
|
||||
*stop = YES;
|
||||
}
|
||||
}];
|
||||
}
|
||||
failureBlock:^(NSError *error) {
|
||||
LOGE(@"Error: Cannot load asset from photo stream - %@", [error localizedDescription]);
|
||||
}];
|
||||
}
|
||||
});
|
||||
} failureBlock:^(NSError *error) {
|
||||
LOGE(@"Can't read image");
|
||||
}];
|
||||
}
|
||||
} else if (localVideo) {
|
||||
if (_messageImageView.image == nil) {
|
||||
[_messageImageView startLoading];
|
||||
// read video from Documents
|
||||
NSString *filePath = [LinphoneManager documentFile:localVideo];
|
||||
NSURL *url = [NSURL fileURLWithPath:filePath];
|
||||
AVAsset *asset = [AVAsset assetWithURL:url];
|
||||
if (asset)
|
||||
[self loadVideoAsset:asset];
|
||||
}
|
||||
} 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 = YES;
|
||||
} else {
|
||||
_cancelButton.hidden = _fileTransferProgress.hidden = _downloadButton.hidden = YES;
|
||||
fullScreenImage = YES;
|
||||
_playButton.hidden = localVideo ? NO : YES;
|
||||
_fileName.hidden = localFile ? NO : YES;
|
||||
}
|
||||
}
|
||||
}
|
||||
// resize image so that it take the full bubble space available
|
||||
CGRect newFrame = _totalView.frame;
|
||||
newFrame.origin.x = newFrame.origin.y = 0;
|
||||
if (!fullScreenImage) {
|
||||
newFrame.size.height -= _imageSubView.frame.size.height;
|
||||
}
|
||||
}
|
||||
_messageImageView.frame = newFrame;
|
||||
}
|
||||
|
||||
- (void)fileErrorBlock {
|
||||
DTActionSheet *sheet = [[DTActionSheet alloc] initWithTitle:NSLocalizedString(@"Can't open this file", nil)];
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||
[sheet addCancelButtonWithTitle:NSLocalizedString(@"OK", nil) block:nil];
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[sheet showInView:PhoneMainView.instance.view];
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
- (IBAction)onDownloadClick:(id)event {
|
||||
[_ftd cancel];
|
||||
_ftd = [[FileTransferDelegate alloc] init];
|
||||
|
|
@ -185,8 +275,41 @@
|
|||
[_ftd download:self.message];
|
||||
_cancelButton.hidden = NO;
|
||||
_downloadButton.hidden = YES;
|
||||
_playButton.hidden = YES;
|
||||
_fileName.hidden = YES;
|
||||
}
|
||||
|
||||
- (IBAction)onPlayClick:(id)sender {
|
||||
NSString *localVideo = [LinphoneManager getMessageAppDataForKey:@"localvideo" inMessage:self.message];
|
||||
NSString *filePath = [LinphoneManager documentFile:localVideo];
|
||||
NSFileManager *fileManager = [NSFileManager defaultManager];
|
||||
|
||||
if ([fileManager fileExistsAtPath:filePath]) {
|
||||
// create a player view controller
|
||||
AVPlayer *player = [AVPlayer playerWithURL:[[NSURL alloc] initFileURLWithPath:filePath]];
|
||||
AVPlayerViewController *controller = [[AVPlayerViewController alloc] init];
|
||||
[PhoneMainView.instance presentViewController:controller animated:YES completion:nil];
|
||||
controller.player = player;
|
||||
[player play];
|
||||
} else {
|
||||
[self fileErrorBlock];
|
||||
}
|
||||
}
|
||||
|
||||
- (IBAction)onOpenClick:(id)event {
|
||||
NSString *localFile = [LinphoneManager getMessageAppDataForKey:@"localfile" inMessage:self.message];
|
||||
NSString *filePath = [LinphoneManager documentFile:localFile];
|
||||
NSFileManager *fileManager = [NSFileManager defaultManager];
|
||||
|
||||
if ([fileManager fileExistsAtPath:filePath]) {
|
||||
ChatConversationView *view = VIEW(ChatConversationView);
|
||||
[view openResults:filePath];
|
||||
} else {
|
||||
[self fileErrorBlock];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (IBAction)onCancelClick:(id)sender {
|
||||
FileTransferDelegate *tmp = _ftd;
|
||||
[self disconnectFromFileDelegate];
|
||||
|
|
@ -200,7 +323,7 @@
|
|||
[self onDownloadClick:event];
|
||||
} else if (_cancelButton.hidden == NO) {
|
||||
[self onCancelClick:event];
|
||||
} else {
|
||||
} else {
|
||||
[super onResend];
|
||||
}
|
||||
}
|
||||
|
|
@ -276,4 +399,70 @@
|
|||
}
|
||||
}
|
||||
|
||||
+ (CGImageRef)resizeCGImage:(CGImageRef)image toWidth:(int)width andHeight:(int)height {
|
||||
// create context, keeping original image properties
|
||||
CGColorSpaceRef colorspace = CGImageGetColorSpace(image);
|
||||
CGContextRef context = CGBitmapContextCreate(NULL, width, height,
|
||||
CGImageGetBitsPerComponent(image),
|
||||
CGImageGetBytesPerRow(image),
|
||||
colorspace,
|
||||
CGImageGetAlphaInfo(image));
|
||||
CGColorSpaceRelease(colorspace);
|
||||
|
||||
if(context == NULL)
|
||||
return nil;
|
||||
|
||||
// draw image to context (resizing it)
|
||||
CGContextDrawImage(context, CGRectMake(0, 0, width, height), image);
|
||||
// extract resulting image from context
|
||||
CGImageRef imgRef = CGBitmapContextCreateImage(context);
|
||||
CGContextRelease(context);
|
||||
|
||||
return imgRef;
|
||||
}
|
||||
|
||||
- (void)layoutSubviews {
|
||||
[super layoutSubviews];
|
||||
//if (!isAssetLoaded) return;
|
||||
UITableView *tableView = VIEW(ChatConversationView).tableController.tableView;
|
||||
BOOL is_outgoing = linphone_chat_message_is_outgoing(super.message);
|
||||
CGRect bubbleFrame = super.bubbleView.frame;
|
||||
int origin_x;
|
||||
|
||||
bubbleSize = [UIChatBubbleTextCell ViewSizeForMessage:[self message] withWidth:chatTableView.tableView.frame.size.width];
|
||||
|
||||
bubbleFrame.size = bubbleSize;
|
||||
|
||||
if (tableView.isEditing) {
|
||||
origin_x = 0;
|
||||
} else {
|
||||
origin_x = (is_outgoing ? self.frame.size.width - bubbleFrame.size.width : 0);
|
||||
}
|
||||
|
||||
bubbleFrame.origin.x = origin_x;
|
||||
|
||||
super.bubbleView.frame = bubbleFrame;
|
||||
}
|
||||
|
||||
- (CGImageRef)cropImageFromRepresentation:(ALAssetRepresentation*)rep {
|
||||
CGImageRef newImage = [rep fullResolutionImage];
|
||||
CGSize originalSize = [rep dimensions];
|
||||
float originalAspectRatio = originalSize.width / originalSize.height;
|
||||
// We resize in width and crop in height
|
||||
if (originalSize.width > imageSize.width) {
|
||||
int height = imageSize.width / originalAspectRatio;
|
||||
newImage = [self.class resizeCGImage:newImage toWidth:imageSize.width andHeight:height];
|
||||
originalSize.height = height;
|
||||
}
|
||||
CGRect cropRect = CGRectMake(0, 0, imageSize.width, imageSize.height);
|
||||
if (imageSize.height < originalSize.height) cropRect.origin.y = (originalSize.height - imageSize.height)/2;
|
||||
newImage = CGImageCreateWithImageInRect(newImage, cropRect);
|
||||
LOGD([NSString stringWithFormat:@"Image size : width = %g, height = %g", imageSize.width, imageSize.height]);
|
||||
LOGD([NSString stringWithFormat:@"Bubble size : width = %g, height = %g", super.bubbleView.frame.size.width, super.bubbleView.frame.size.height]);
|
||||
return newImage;
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@
|
|||
@property(weak, nonatomic) IBOutlet UILabel *imdmLabel;
|
||||
|
||||
+ (CGSize)ViewSizeForMessage:(LinphoneChatMessage *)chat withWidth:(int)width;
|
||||
+ (CGSize)getMediaMessageSizefromOriginalSize:(CGSize)originalSize withWidth:(int)width;
|
||||
|
||||
- (void)setEvent:(LinphoneEventLog *)event;
|
||||
- (void)setChatMessage:(LinphoneChatMessage *)message;
|
||||
|
|
|
|||
|
|
@ -232,19 +232,27 @@
|
|||
if (linphone_chat_message_get_file_transfer_information(_message) != NULL) {
|
||||
NSString *localImage = [LinphoneManager getMessageAppDataForKey:@"localimage" inMessage:_message];
|
||||
NSNumber *uploadQuality =[LinphoneManager getMessageAppDataForKey:@"uploadQuality" inMessage:_message];
|
||||
NSString *localVideo = [LinphoneManager getMessageAppDataForKey:@"localvideo" inMessage:_message];
|
||||
NSString *localFile = [LinphoneManager getMessageAppDataForKey:@"localfile" inMessage:_message];
|
||||
NSString *fileName = localVideo ? localVideo : localFile;
|
||||
NSURL *imageUrl = [NSURL URLWithString:localImage];
|
||||
[self onDelete];
|
||||
[LinphoneManager.instance.photoLibrary assetForURL:imageUrl
|
||||
resultBlock:^(ALAsset *asset) {
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, (unsigned long)NULL),
|
||||
^(void) {
|
||||
UIImage *image = [[UIImage alloc] initWithCGImage:[[asset defaultRepresentation] fullResolutionImage]];
|
||||
[_chatRoomDelegate startImageUpload:image url:imageUrl withQuality:(uploadQuality ? [uploadQuality floatValue] : 0.9)];
|
||||
});
|
||||
}
|
||||
failureBlock:^(NSError *error) {
|
||||
LOGE(@"Can't read image");
|
||||
}];
|
||||
if(localImage){
|
||||
[LinphoneManager.instance.photoLibrary assetForURL:imageUrl
|
||||
resultBlock:^(ALAsset *asset) {
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, (unsigned long)NULL),
|
||||
^(void) {
|
||||
UIImage *image = [[UIImage alloc] initWithCGImage:[[asset defaultRepresentation] fullResolutionImage]];
|
||||
[_chatRoomDelegate startImageUpload:image url:imageUrl withQuality:(uploadQuality ? [uploadQuality floatValue] : 0.9)];
|
||||
});
|
||||
}
|
||||
failureBlock:^(NSError *error) {
|
||||
LOGE(@"Can't read image");
|
||||
}];
|
||||
} else if(fileName) {
|
||||
NSString *filePath = [LinphoneManager documentFile:fileName];
|
||||
[_chatRoomDelegate startFileUpload:[NSData dataWithContentsOfFile:filePath] withUrl:[NSURL URLWithString:filePath]];
|
||||
}
|
||||
} else {
|
||||
[self onDelete];
|
||||
double delayInSeconds = 0.4;
|
||||
|
|
@ -306,12 +314,11 @@ static const CGFloat CELL_MIN_HEIGHT = 60.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_IMAGE_HEIGHT = 100.0f;
|
||||
static const CGFloat CELL_IMAGE_WIDTH = 100.0f;
|
||||
|
||||
+ (CGSize)ViewHeightForMessage:(LinphoneChatMessage *)chat withWidth:(int)width {
|
||||
NSString *messageText = [UIChatBubbleTextCell TextMessageForChat:chat];
|
||||
static UIFont *messageFont = nil;
|
||||
|
||||
if (!messageFont) {
|
||||
UIChatBubbleTextCell *cell =
|
||||
[[UIChatBubbleTextCell alloc] initWithIdentifier:NSStringFromClass(UIChatBubbleTextCell.class)];
|
||||
|
|
@ -328,8 +335,39 @@ static const CGFloat CELL_IMAGE_WIDTH = 100.0f;
|
|||
font:messageFont];
|
||||
} else {
|
||||
NSString *localImage = [LinphoneManager getMessageAppDataForKey:@"localimage" inMessage:chat];
|
||||
size = (localImage != nil) ? CGSizeMake(CELL_IMAGE_WIDTH, CELL_IMAGE_HEIGHT) : CGSizeMake(50, 50);
|
||||
NSString *localFile = [LinphoneManager getMessageAppDataForKey:@"localfile" inMessage:chat];
|
||||
NSString *localVideo = [LinphoneManager getMessageAppDataForKey:@"localvideo" inMessage:chat];
|
||||
|
||||
if(localFile) {
|
||||
CGSize fileSize = CGSizeMake(200, 80);
|
||||
size = [self getMediaMessageSizefromOriginalSize:fileSize withWidth:width];
|
||||
} else if (localVideo) {
|
||||
CGSize videoSize = CGSizeMake(320, 240);
|
||||
size = [self getMediaMessageSizefromOriginalSize:videoSize withWidth:width];
|
||||
size.height += CELL_MESSAGE_X_MARGIN;
|
||||
} else {
|
||||
NSURL *imageUrl = [NSURL URLWithString:localImage];
|
||||
__block CGSize originalImageSize = CGSizeMake(0, 0);
|
||||
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) {
|
||||
[LinphoneManager.instance.photoLibrary assetForURL:imageUrl
|
||||
resultBlock:^(ALAsset *asset) {
|
||||
originalImageSize = [[asset defaultRepresentation] dimensions];
|
||||
dispatch_semaphore_signal(sema);
|
||||
}
|
||||
failureBlock:^(NSError *error) {
|
||||
LOGE(@"Can't read image");
|
||||
dispatch_semaphore_signal(sema);
|
||||
}];
|
||||
});
|
||||
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
|
||||
|
||||
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 += CELL_MESSAGE_X_MARGIN;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
|
@ -375,4 +413,22 @@ static const CGFloat CELL_IMAGE_WIDTH = 100.0f;
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
+ (CGSize)getMediaMessageSizefromOriginalSize:(CGSize)originalSize withWidth:(int)width {
|
||||
CGSize mediaSize = CGSizeMake(0, 0);
|
||||
int availableWidth = width - CELL_MESSAGE_X_MARGIN;
|
||||
if (UIInterfaceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation])) {
|
||||
availableWidth = availableWidth /3;
|
||||
}
|
||||
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);
|
||||
mediaSize.width = MIN(availableWidth, originalSize.width);
|
||||
return mediaSize;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@
|
|||
@property(weak, nonatomic) IBOutlet UILabel *chatLatestTimeLabel;
|
||||
@property(weak, nonatomic) IBOutlet UIBouncingView *unreadCountView;
|
||||
@property(weak, nonatomic) IBOutlet UILabel *unreadCountLabel;
|
||||
@property (weak, nonatomic) IBOutlet UIImageView *imdmIcon;
|
||||
|
||||
- (id)initWithIdentifier:(NSString*)identifier;
|
||||
|
||||
|
|
|
|||
|
|
@ -85,17 +85,66 @@
|
|||
|
||||
LinphoneChatMessage *last_msg = linphone_chat_room_get_last_message_in_history(chatRoom);
|
||||
if (last_msg) {
|
||||
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:@"[...]"];
|
||||
BOOL imdnInSnap = FALSE;
|
||||
if (imdnInSnap) {
|
||||
BOOL outgoing = linphone_chat_message_is_outgoing(last_msg);
|
||||
NSString *text = [UIChatBubbleTextCell TextMessageForChat:last_msg];
|
||||
if (outgoing) {
|
||||
// shorten long messages
|
||||
if ([text length] > 50)
|
||||
text = [[text substringToIndex:50] stringByAppendingString:@"[...]"];
|
||||
_chatContentLabel.attributedText = nil;
|
||||
_chatContentLabel.text = text;
|
||||
}
|
||||
else {
|
||||
NSString *name = [FastAddressBook displayNameForAddress:linphone_chat_message_get_from_address(last_msg)];
|
||||
if ([name length] > 25) {
|
||||
name = [[name substringToIndex:25] stringByAppendingString:@"[...]"];
|
||||
}
|
||||
CGFloat fontSize = _chatContentLabel.font.pointSize;
|
||||
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) {
|
||||
text = [[text substringToIndex: (50 - [name length])] stringByAppendingString:@"[...]"];
|
||||
}
|
||||
[boldText appendAttributedString:[[NSAttributedString alloc] initWithString:text]];
|
||||
_chatContentLabel.text = nil;
|
||||
_chatContentLabel.attributedText = boldText;
|
||||
}
|
||||
|
||||
_chatContentLabel.text = text;
|
||||
|
||||
LinphoneChatMessageState state = linphone_chat_message_get_state(last_msg);
|
||||
if (outgoing && (state == LinphoneChatMessageStateDeliveredToUser || state == LinphoneChatMessageStateDisplayed || state == LinphoneChatMessageStateNotDelivered || state == LinphoneChatMessageStateFileTransferError)) {
|
||||
[self displayImdmStatus:state];
|
||||
CGRect newFrame = _chatContentLabel.frame;
|
||||
newFrame.origin.x = 80;
|
||||
_chatContentLabel.frame = newFrame;
|
||||
} else {
|
||||
// We displace the message 20 pixels to the left
|
||||
[_imdmIcon setHidden:TRUE];
|
||||
CGRect newFrame = _chatContentLabel.frame;
|
||||
newFrame.origin.x = 60;
|
||||
_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:@"[...]"];
|
||||
[_imdmIcon setHidden:TRUE];
|
||||
CGRect newFrame = _chatContentLabel.frame;
|
||||
newFrame.origin.x = 60;
|
||||
_chatContentLabel.frame = newFrame;
|
||||
_chatContentLabel.text = text;
|
||||
}
|
||||
|
||||
linphone_chat_message_unref(last_msg);
|
||||
} else
|
||||
_chatContentLabel.text = nil;
|
||||
|
||||
|
||||
[self updateUnreadBadge];
|
||||
}
|
||||
|
||||
|
|
@ -142,4 +191,20 @@
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
- (void)displayImdmStatus:(LinphoneChatMessageState)state {
|
||||
if (state == LinphoneChatMessageStateDeliveredToUser) {
|
||||
[_imdmIcon setImage:[UIImage imageNamed:@"chat_delivered"]];
|
||||
[_imdmIcon setHidden:FALSE];
|
||||
} else if (state == LinphoneChatMessageStateDisplayed) {
|
||||
[_imdmIcon setImage:[UIImage imageNamed:@"chat_read"]];
|
||||
[_imdmIcon setHidden:FALSE];
|
||||
} else if (state == LinphoneChatMessageStateNotDelivered || state == LinphoneChatMessageStateFileTransferError) {
|
||||
[_imdmIcon setImage:[UIImage imageNamed:@"chat_error"]];
|
||||
[_imdmIcon setHidden:FALSE];
|
||||
} else {
|
||||
[_imdmIcon setHidden:TRUE];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
|||
|
|
@ -82,6 +82,7 @@
|
|||
}
|
||||
|
||||
- (void)stopLoading {
|
||||
|
||||
[waitIndicatorView stopAnimating];
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -762,6 +762,8 @@ void update_hash_cbs(LinphoneAccountCreator *creator, LinphoneAccountCreatorStat
|
|||
if (!linphone_chat_message_is_outgoing(msg)) {
|
||||
[LinphoneManager setValueInMessageAppData:nil forKey:@"localimage" inMessage:msg];
|
||||
[LinphoneManager setValueInMessageAppData:nil forKey:@"uploadQuality" inMessage:msg];
|
||||
[LinphoneManager setValueInMessageAppData:nil forKey:@"localvideo" inMessage:msg];
|
||||
[LinphoneManager setValueInMessageAppData:nil forKey:@"localfile" inMessage:msg];
|
||||
}
|
||||
events = events->next;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
@interface FileTransferDelegate : NSObject
|
||||
|
||||
- (void)upload:(UIImage *)image withURL:(NSURL *)url forChatRoom:(LinphoneChatRoom *)chatRoom withQuality:(float)quality;
|
||||
- (void)uploadFile:(NSData *)data forChatRoom:(LinphoneChatRoom *)chatRoom withUrl:(NSURL *)url;
|
||||
- (void)cancel;
|
||||
- (BOOL)download:(LinphoneChatMessage *)message;
|
||||
- (void)stopAndDestroy;
|
||||
|
|
|
|||
|
|
@ -44,62 +44,63 @@ static void linphone_iphone_file_transfer_recv(LinphoneChatMessage *message, con
|
|||
if (size == 0) {
|
||||
LOGI(@"Transfer of %s (%d bytes): download finished", linphone_content_get_name(content), size);
|
||||
assert([thiz.data length] == linphone_content_get_file_size(content));
|
||||
NSString *fileType = [NSString stringWithUTF8String:linphone_content_get_type(content)];
|
||||
if ([fileType isEqualToString:@"image"]) {
|
||||
// we're finished, save the image and update the message
|
||||
UIImage *image = [UIImage imageWithData:thiz.data];
|
||||
if (!image) {
|
||||
UIAlertController *errView = [UIAlertController
|
||||
alertControllerWithTitle:NSLocalizedString(@"File download error", nil)
|
||||
message:NSLocalizedString(@"Error while downloading the file.\n"
|
||||
@"The file is probably encrypted.\n"
|
||||
@"Please retry to download this file after activating LIME.",
|
||||
nil)
|
||||
preferredStyle:UIAlertControllerStyleAlert];
|
||||
|
||||
// we're finished, save the image and update the message
|
||||
UIImage *image = [UIImage imageWithData:thiz.data];
|
||||
if (!image) {
|
||||
UIAlertController *errView = [UIAlertController
|
||||
alertControllerWithTitle:NSLocalizedString(@"File download error", nil)
|
||||
message:NSLocalizedString(@"Error while downloading the file.\n"
|
||||
@"The file is probably encrypted.\n"
|
||||
@"Please retry to download this file after activating LIME.",
|
||||
nil)
|
||||
preferredStyle:UIAlertControllerStyleAlert];
|
||||
UIAlertAction *defaultAction = [UIAlertAction actionWithTitle:@"OK"
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction *action){
|
||||
}];
|
||||
|
||||
UIAlertAction *defaultAction = [UIAlertAction actionWithTitle:@"OK"
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction *action){
|
||||
}];
|
||||
[errView addAction:defaultAction];
|
||||
[PhoneMainView.instance presentViewController:errView animated:YES completion:nil];
|
||||
[thiz stopAndDestroy];
|
||||
return;
|
||||
}
|
||||
|
||||
[errView addAction:defaultAction];
|
||||
[PhoneMainView.instance presentViewController:errView animated:YES completion:nil];
|
||||
[thiz stopAndDestroy];
|
||||
return;
|
||||
}
|
||||
CFBridgingRetain(thiz);
|
||||
[[LinphoneManager.instance fileTransferDelegates] removeObject:thiz];
|
||||
|
||||
CFBridgingRetain(thiz);
|
||||
[[LinphoneManager.instance fileTransferDelegates] removeObject:thiz];
|
||||
// until image is properly saved, keep a reminder on it so that the
|
||||
// chat bubble is aware of the fact that image is being saved to device
|
||||
[LinphoneManager setValueInMessageAppData:@"saving..." forKey:@"localimage" inMessage:message];
|
||||
|
||||
// until image is properly saved, keep a reminder on it so that the
|
||||
// chat bubble is aware of the fact that image is being saved to device
|
||||
[LinphoneManager setValueInMessageAppData:@"saving..." forKey:@"localimage" inMessage:message];
|
||||
|
||||
[LinphoneManager.instance.photoLibrary
|
||||
writeImageToSavedPhotosAlbum:image.CGImage
|
||||
orientation:(ALAssetOrientation)[image imageOrientation]
|
||||
completionBlock:^(NSURL *assetURL, NSError *error) {
|
||||
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)
|
||||
[LinphoneManager.instance.photoLibrary
|
||||
writeImageToSavedPhotosAlbum:image.CGImage
|
||||
orientation:(ALAssetOrientation)[image imageOrientation]
|
||||
completionBlock:^(NSURL *assetURL, NSError *error) {
|
||||
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"
|
||||
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 [%@]", [assetURL absoluteString]);
|
||||
[LinphoneManager setValueInMessageAppData:[assetURL absoluteString]
|
||||
[errView addAction:defaultAction];
|
||||
[PhoneMainView.instance presentViewController:errView animated:YES completion:nil];
|
||||
} else {
|
||||
LOGI(@"Image saved to [%@]", [assetURL absoluteString]);
|
||||
[LinphoneManager setValueInMessageAppData:[assetURL absoluteString]
|
||||
forKey:@"localimage"
|
||||
inMessage:message];
|
||||
}
|
||||
[NSNotificationCenter.defaultCenter
|
||||
postNotificationName:kLinphoneFileTransferRecvUpdate
|
||||
}
|
||||
[NSNotificationCenter.defaultCenter
|
||||
postNotificationName:kLinphoneFileTransferRecvUpdate
|
||||
object:thiz
|
||||
userInfo:@{
|
||||
@"state" : @(LinphoneChatMessageStateDelivered), // we dont want to
|
||||
|
|
@ -109,10 +110,38 @@ static void linphone_iphone_file_transfer_recv(LinphoneChatMessage *message, con
|
|||
@"progress" : @(1.f),
|
||||
}];
|
||||
|
||||
[thiz stopAndDestroy];
|
||||
CFRelease((__bridge CFTypeRef)thiz);
|
||||
}];
|
||||
} else {
|
||||
[thiz stopAndDestroy];
|
||||
CFRelease((__bridge CFTypeRef)thiz);
|
||||
}];
|
||||
} else {
|
||||
[[LinphoneManager.instance fileTransferDelegates] removeObject:thiz];
|
||||
|
||||
NSString *key = [fileType isEqualToString:@"file"] ? @"localfile" : @"localvideo";
|
||||
NSString *name =[NSString stringWithUTF8String:linphone_content_get_name(content)];
|
||||
|
||||
[LinphoneManager setValueInMessageAppData:@"saving..." forKey:key inMessage:message];
|
||||
|
||||
//write file to path
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
NSString *filePath = [LinphoneManager documentFile:name];
|
||||
[[NSFileManager defaultManager] createFileAtPath:filePath
|
||||
contents:thiz.data
|
||||
attributes:nil];
|
||||
|
||||
[LinphoneManager setValueInMessageAppData:name forKey:key inMessage:message];
|
||||
|
||||
[NSNotificationCenter.defaultCenter
|
||||
postNotificationName:kLinphoneFileTransferRecvUpdate
|
||||
object:thiz
|
||||
userInfo:@{
|
||||
@"state" : @(LinphoneChatMessageStateDelivered), // we dont want to trigger
|
||||
@"progress" : @(1.f), // FileTransferDone here
|
||||
}];
|
||||
|
||||
[thiz stopAndDestroy];
|
||||
});
|
||||
}
|
||||
} else {
|
||||
LOGD(@"Transfer of %s (%d bytes): already %ld sent, adding %ld", linphone_content_get_name(content),
|
||||
linphone_content_get_file_size(content), [thiz.data length], size);
|
||||
[thiz.data appendBytes:linphone_buffer_get_string_content(buffer) length:size];
|
||||
|
|
@ -124,6 +153,7 @@ static void linphone_iphone_file_transfer_recv(LinphoneChatMessage *message, con
|
|||
@"progress" : @([thiz.data length] * 1.f / linphone_content_get_file_size(content)),
|
||||
}];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static LinphoneBuffer *linphone_iphone_file_transfer_send(LinphoneChatMessage *message, const LinphoneContent *content,
|
||||
|
|
@ -166,38 +196,58 @@ static LinphoneBuffer *linphone_iphone_file_transfer_send(LinphoneChatMessage *m
|
|||
return NULL;
|
||||
}
|
||||
|
||||
- (void)upload:(UIImage *)image withURL:(NSURL *)url forChatRoom:(LinphoneChatRoom *)chatRoom withQuality:(float)quality {
|
||||
[LinphoneManager.instance.fileTransferDelegates addObject:self];
|
||||
- (void)uploadData:(NSData *)data forChatRoom:(LinphoneChatRoom *)chatRoom type:(NSString *)type subtype:(NSString *)subtype name:(NSString *)name key:(NSString *)key keyData:(NSString *)keyData qualityData:(NSNumber *)qualityData {
|
||||
[LinphoneManager.instance.fileTransferDelegates addObject:self];
|
||||
|
||||
LinphoneContent *content = linphone_core_create_content(linphone_chat_room_get_core(chatRoom));
|
||||
_data = [NSMutableData dataWithData:data];
|
||||
linphone_content_set_type(content, [type UTF8String]);
|
||||
linphone_content_set_subtype(content, [subtype UTF8String]);
|
||||
linphone_content_set_name(content, [name UTF8String]);
|
||||
linphone_content_set_size(content, _data.length);
|
||||
|
||||
_message = linphone_chat_room_create_file_transfer_message(chatRoom, content);
|
||||
linphone_content_unref(content);
|
||||
|
||||
linphone_chat_message_cbs_set_file_transfer_send(linphone_chat_message_get_callbacks(_message),
|
||||
linphone_iphone_file_transfer_send);
|
||||
|
||||
LinphoneContent *content = linphone_core_create_content(linphone_chat_room_get_core(chatRoom));
|
||||
_data = [NSMutableData dataWithData:UIImageJPEGRepresentation(image, quality)];
|
||||
linphone_content_set_type(content, "image");
|
||||
linphone_content_set_subtype(content, "jpeg");
|
||||
linphone_content_set_name(
|
||||
content, [[NSString stringWithFormat:@"%li-%f.jpg", (long)image.hash, [NSDate timeIntervalSinceReferenceDate]]
|
||||
UTF8String]);
|
||||
linphone_content_set_size(content, _data.length);
|
||||
|
||||
_message = linphone_chat_room_create_file_transfer_message(chatRoom, content);
|
||||
linphone_content_unref(content);
|
||||
|
||||
linphone_chat_message_cbs_set_file_transfer_send(linphone_chat_message_get_callbacks(_message),
|
||||
linphone_iphone_file_transfer_send);
|
||||
|
||||
if (url) {
|
||||
// internal url is saved in the appdata for display and later save
|
||||
[LinphoneManager setValueInMessageAppData:[url absoluteString] forKey:@"localimage" inMessage:_message];
|
||||
[LinphoneManager setValueInMessageAppData:[NSNumber numberWithFloat:quality] forKey:@"uploadQuality" inMessage:_message];
|
||||
}
|
||||
|
||||
LOGI(@"%p Uploading content from message %p", self, _message);
|
||||
linphone_chat_room_send_chat_message(chatRoom, _message);
|
||||
|
||||
if (linphone_core_lime_enabled(LC) == LinphoneLimeMandatory && !linphone_chat_room_lime_available(chatRoom)) {
|
||||
[LinphoneManager.instance alertLIME:chatRoom];
|
||||
}
|
||||
// internal url is saved in the appdata for display and later save
|
||||
[LinphoneManager setValueInMessageAppData:keyData forKey:key inMessage:_message];
|
||||
[LinphoneManager setValueInMessageAppData:qualityData forKey:@"uploadQuality" inMessage:_message];
|
||||
|
||||
LOGI(@"%p Uploading content from message %p", self, _message);
|
||||
linphone_chat_room_send_chat_message(chatRoom, _message);
|
||||
|
||||
if (linphone_core_lime_enabled(LC) == LinphoneLimeMandatory && !linphone_chat_room_lime_available(chatRoom)) {
|
||||
[LinphoneManager.instance alertLIME:chatRoom];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)upload:(UIImage *)image withURL:(NSURL *)url forChatRoom:(LinphoneChatRoom *)chatRoom withQuality:(float)quality {
|
||||
NSString *name = [NSString stringWithFormat:@"%li-%f.jpg", (long)image.hash, [NSDate timeIntervalSinceReferenceDate]];
|
||||
if (url)
|
||||
[self uploadData:UIImageJPEGRepresentation(image, quality) forChatRoom:chatRoom type:@"image" subtype:@"jpeg" name:name key:@"localimage" keyData:[url absoluteString] qualityData:[NSNumber numberWithFloat:quality]];
|
||||
else
|
||||
[self uploadData:UIImageJPEGRepresentation(image, quality) forChatRoom:chatRoom type:@"image" subtype:@"jpeg" name:name key:@"localimage" keyData:nil qualityData:nil];
|
||||
}
|
||||
|
||||
- (void)uploadFile:(NSData *)data forChatRoom:(LinphoneChatRoom *)chatRoom withUrl:(NSURL *)url {
|
||||
NSString *name = [url lastPathComponent];
|
||||
//save file to Documents
|
||||
NSString *filePath = [LinphoneManager documentFile:name];
|
||||
[[NSFileManager defaultManager] createFileAtPath:filePath
|
||||
contents:[NSMutableData dataWithData:data]
|
||||
attributes:nil];
|
||||
|
||||
if ([[url pathExtension] isEqualToString:@"MOV"])
|
||||
[self uploadData:data forChatRoom:chatRoom type:nil subtype:nil name:name key:@"localvideo" keyData:name qualityData:nil];
|
||||
else
|
||||
[self uploadData:data forChatRoom:chatRoom type:@"file" subtype:nil name:name key:@"localfile" keyData:name qualityData:nil];
|
||||
}
|
||||
|
||||
|
||||
|
||||
- (BOOL)download:(LinphoneChatMessage *)message {
|
||||
[[LinphoneManager.instance fileTransferDelegates] addObject:self];
|
||||
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@ typedef enum {
|
|||
|
||||
- (UIImage *)squareCrop;
|
||||
- (UIImage *)scaleToSize:(CGSize)size squared:(BOOL)squared;
|
||||
+ (UIImage *)resizeImage:(UIImage *)image withMaxWidth:(float)maxWidth andMaxHeight:(float)maxHeight;
|
||||
|
||||
@end
|
||||
|
||||
|
|
|
|||
|
|
@ -644,6 +644,36 @@
|
|||
return scaledImage;
|
||||
}
|
||||
|
||||
+ (UIImage *)resizeImage:(UIImage *)image withMaxWidth:(float)maxWidth andMaxHeight:(float)maxHeight {
|
||||
float actualHeight = image.size.height;
|
||||
float actualWidth = image.size.width;
|
||||
float imgRatio = actualWidth / actualHeight;
|
||||
float maxRatio = maxWidth / maxHeight;
|
||||
float compressionQuality = 1;
|
||||
if (actualHeight > maxHeight || actualWidth > maxWidth)
|
||||
{
|
||||
if (imgRatio < maxRatio) {
|
||||
imgRatio = maxHeight / actualHeight;
|
||||
actualWidth = imgRatio * actualWidth;
|
||||
actualHeight = maxHeight;
|
||||
} else if (imgRatio > maxRatio) {
|
||||
imgRatio = maxWidth / actualWidth;
|
||||
actualHeight = imgRatio * actualHeight;
|
||||
actualWidth = maxWidth;
|
||||
} else {
|
||||
actualHeight = maxHeight;
|
||||
actualWidth = maxWidth;
|
||||
}
|
||||
}
|
||||
CGRect rect = CGRectMake(0.0, 0.0, actualWidth, actualHeight);
|
||||
UIGraphicsBeginImageContext(rect.size);
|
||||
[image drawInRect:rect];
|
||||
UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
|
||||
NSData *imageData = UIImageJPEGRepresentation(img, compressionQuality);
|
||||
UIGraphicsEndImageContext();
|
||||
return [UIImage imageWithData:imageData];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation UIColor (LightAndDark)
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ tcp_tls_keepalive=30000
|
|||
history_max_size=-1
|
||||
enable_basic_to_client_group_chat_room_migration=0
|
||||
aggregate_imdn=1
|
||||
version_check_url_root=https://linphone.org/releases
|
||||
|
||||
[sound]
|
||||
dtmf_player_amp=0.007
|
||||
|
|
|
|||
153
latestCallsWidget/Base.lproj/MainInterface.storyboard
Normal file
153
latestCallsWidget/Base.lproj/MainInterface.storyboard
Normal file
|
|
@ -0,0 +1,153 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14113" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="M4Y-Lb-cyx">
|
||||
<device id="retina4_7" orientation="portrait">
|
||||
<adaptation id="fullscreen"/>
|
||||
</device>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14088"/>
|
||||
<capability name="Constraints to layout margins" minToolsVersion="6.0"/>
|
||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--Today View Controller-->
|
||||
<scene sceneID="cwh-vc-ff4">
|
||||
<objects>
|
||||
<viewController id="M4Y-Lb-cyx" customClass="TodayViewController" sceneMemberID="viewController">
|
||||
<view key="view" contentMode="scaleToFill" simulatedAppContext="notificationCenter" id="S3S-Oj-5AN">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="37"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" distribution="equalSpacing" translatesAutoresizingMaskIntoConstraints="NO" id="acy-Dv-HTU">
|
||||
<rect key="frame" x="16" y="-25" width="288" height="87.5"/>
|
||||
<subviews>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="10" translatesAutoresizingMaskIntoConstraints="NO" id="ndj-Mq-Hl7">
|
||||
<rect key="frame" x="0.0" y="0.0" width="60" height="87.5"/>
|
||||
<subviews>
|
||||
<button opaque="NO" contentMode="scaleAspectFit" contentHorizontalAlignment="center" contentVerticalAlignment="center" showsTouchWhenHighlighted="YES" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Wm5-Qb-p3S">
|
||||
<rect key="frame" x="0.0" y="0.0" width="60" height="60.5"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="60" id="0Ak-Qk-GO3"/>
|
||||
<constraint firstAttribute="width" constant="60" id="ZqS-ba-Lu5"/>
|
||||
</constraints>
|
||||
<state key="normal" image="avatar.png"/>
|
||||
<connections>
|
||||
<action selector="firstButtonTapped" destination="M4Y-Lb-cyx" eventType="touchUpInside" id="hiI-LE-Zgn"/>
|
||||
</connections>
|
||||
</button>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text=" " textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ZCh-k6-wlC">
|
||||
<rect key="frame" x="0.0" y="70.5" width="60" height="17"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="ZCh-k6-wlC" firstAttribute="centerX" secondItem="ndj-Mq-Hl7" secondAttribute="centerX" id="7gN-E9-QSN"/>
|
||||
</constraints>
|
||||
</stackView>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="10" translatesAutoresizingMaskIntoConstraints="NO" id="aDd-1O-GG5">
|
||||
<rect key="frame" x="76" y="0.0" width="60" height="87.5"/>
|
||||
<subviews>
|
||||
<button opaque="NO" contentMode="scaleAspectFit" contentHorizontalAlignment="center" contentVerticalAlignment="center" showsTouchWhenHighlighted="YES" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="YV6-7A-P4J">
|
||||
<rect key="frame" x="0.0" y="0.0" width="60" height="60"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="60" id="7Mf-cY-51s"/>
|
||||
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="60" id="b1f-XQ-h9r"/>
|
||||
<constraint firstAttribute="width" constant="60" id="pF3-4V-DIz"/>
|
||||
</constraints>
|
||||
<state key="normal" image="avatar.png"/>
|
||||
<connections>
|
||||
<action selector="secondButtonTapped" destination="M4Y-Lb-cyx" eventType="touchUpInside" id="VD4-JL-D57"/>
|
||||
</connections>
|
||||
</button>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text=" " textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="vzp-zG-86G">
|
||||
<rect key="frame" x="0.0" y="70" width="60" height="17.5"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="vzp-zG-86G" firstAttribute="centerX" secondItem="aDd-1O-GG5" secondAttribute="centerX" id="Reb-Z7-yZx"/>
|
||||
</constraints>
|
||||
</stackView>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="10" translatesAutoresizingMaskIntoConstraints="NO" id="Jda-ED-Hck">
|
||||
<rect key="frame" x="152" y="0.0" width="60" height="87.5"/>
|
||||
<subviews>
|
||||
<button opaque="NO" contentMode="scaleAspectFit" contentHorizontalAlignment="center" contentVerticalAlignment="center" showsTouchWhenHighlighted="YES" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="R1m-4P-62J">
|
||||
<rect key="frame" x="0.0" y="0.0" width="60" height="60"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="60" id="Jwm-Hh-flO"/>
|
||||
<constraint firstAttribute="width" constant="60" id="Lv0-kT-oOL"/>
|
||||
</constraints>
|
||||
<state key="normal" image="avatar.png"/>
|
||||
<connections>
|
||||
<action selector="thirdButtonTapped" destination="M4Y-Lb-cyx" eventType="touchUpInside" id="A6r-gZ-0Be"/>
|
||||
</connections>
|
||||
</button>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text=" " textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="1km-2d-H8g">
|
||||
<rect key="frame" x="0.0" y="70" width="60" height="17.5"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="1km-2d-H8g" firstAttribute="centerX" secondItem="Jda-ED-Hck" secondAttribute="centerX" id="Jaw-30-wJW"/>
|
||||
</constraints>
|
||||
</stackView>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="10" translatesAutoresizingMaskIntoConstraints="NO" id="Vem-dd-m97">
|
||||
<rect key="frame" x="228" y="0.0" width="60" height="87.5"/>
|
||||
<subviews>
|
||||
<button opaque="NO" contentMode="scaleAspectFit" contentHorizontalAlignment="center" contentVerticalAlignment="center" showsTouchWhenHighlighted="YES" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="EgK-EE-9vt">
|
||||
<rect key="frame" x="0.0" y="0.0" width="60" height="60"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="60" id="T6s-2z-6yf"/>
|
||||
<constraint firstAttribute="height" constant="60" id="yoB-Mx-9iw"/>
|
||||
</constraints>
|
||||
<state key="normal" image="avatar.png"/>
|
||||
<connections>
|
||||
<action selector="fourthButtonTapped" destination="M4Y-Lb-cyx" eventType="touchUpInside" id="MfV-kR-GEH"/>
|
||||
</connections>
|
||||
</button>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text=" " textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Z4D-W4-T9E">
|
||||
<rect key="frame" x="0.0" y="70" width="60" height="17.5"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="Z4D-W4-T9E" firstAttribute="centerX" secondItem="Vem-dd-m97" secondAttribute="centerX" id="TU4-tO-i4b"/>
|
||||
</constraints>
|
||||
</stackView>
|
||||
</subviews>
|
||||
</stackView>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="acy-Dv-HTU" firstAttribute="centerX" secondItem="S3S-Oj-5AN" secondAttribute="centerX" id="Thu-fq-hKU"/>
|
||||
<constraint firstItem="acy-Dv-HTU" firstAttribute="centerY" secondItem="S3S-Oj-5AN" secondAttribute="centerY" id="Wku-rc-Ij6"/>
|
||||
<constraint firstItem="acy-Dv-HTU" firstAttribute="leading" secondItem="S3S-Oj-5AN" secondAttribute="leadingMargin" id="fWT-EJ-zhi"/>
|
||||
</constraints>
|
||||
<viewLayoutGuide key="safeArea" id="ssy-KU-ocm"/>
|
||||
</view>
|
||||
<extendedEdge key="edgesForExtendedLayout"/>
|
||||
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
|
||||
<size key="freeformSize" width="320" height="37"/>
|
||||
<connections>
|
||||
<outletCollection property="stackViews" destination="ndj-Mq-Hl7" id="NTd-tl-hho"/>
|
||||
<outletCollection property="stackViews" destination="aDd-1O-GG5" id="y3m-I8-kYi"/>
|
||||
<outletCollection property="stackViews" destination="Jda-ED-Hck" id="VR1-hK-wc3"/>
|
||||
<outletCollection property="stackViews" destination="Vem-dd-m97" id="9Eh-UN-U3f"/>
|
||||
</connections>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="vXp-U4-Rya" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
</scene>
|
||||
</scenes>
|
||||
<resources>
|
||||
<image name="avatar.png" width="259" height="259"/>
|
||||
</resources>
|
||||
</document>
|
||||
31
latestCallsWidget/Info.plist
Normal file
31
latestCallsWidget/Info.plist
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>Linphone - Latest Calls</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>XPC!</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>NSExtension</key>
|
||||
<dict>
|
||||
<key>NSExtensionMainStoryboard</key>
|
||||
<string>MainInterface</string>
|
||||
<key>NSExtensionPointIdentifier</key>
|
||||
<string>com.apple.widget-extension</string>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
||||
20
latestCallsWidget/TodayViewController.h
Normal file
20
latestCallsWidget/TodayViewController.h
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
//
|
||||
// TodayViewController.h
|
||||
// latestCallsWidget
|
||||
//
|
||||
// Created by David Idmansour on 06/06/2018.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface TodayViewController : UIViewController
|
||||
@property (strong, nonatomic) IBOutletCollection(UIStackView) NSArray *stackViews;
|
||||
@property (strong, nonatomic) NSMutableArray *imgs;
|
||||
@property (strong, nonatomic) NSMutableArray *logIds;
|
||||
@property (strong, nonatomic) NSMutableArray *displayNames;
|
||||
|
||||
- (IBAction)firstButtonTapped;
|
||||
- (IBAction)secondButtonTapped;
|
||||
- (IBAction)thirdButtonTapped;
|
||||
- (IBAction)fourthButtonTapped;
|
||||
@end
|
||||
109
latestCallsWidget/TodayViewController.m
Normal file
109
latestCallsWidget/TodayViewController.m
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
//
|
||||
// TodayViewController.m
|
||||
// latestCallsWidget
|
||||
//
|
||||
// Created by David Idmansour on 06/06/2018.
|
||||
//
|
||||
|
||||
#import "TodayViewController.h"
|
||||
#import <NotificationCenter/NotificationCenter.h>
|
||||
|
||||
@interface TodayViewController () <NCWidgetProviding>
|
||||
|
||||
@end
|
||||
|
||||
@implementation TodayViewController
|
||||
|
||||
- (void)loadData {
|
||||
NSUserDefaults *mySharedDefaults = [[NSUserDefaults alloc] initWithSuiteName: @"group.belledonne-communications.linphone.widget"];
|
||||
[_imgs removeAllObjects];
|
||||
[_logIds removeAllObjects];
|
||||
[_displayNames removeAllObjects];
|
||||
NSMutableArray *logs = [NSMutableArray arrayWithArray:[mySharedDefaults objectForKey:@"logs"]];
|
||||
for (NSDictionary *dict in logs) {
|
||||
[_logIds addObject:[dict objectForKey:@"id"]];
|
||||
[_displayNames addObject:[dict objectForKey:@"display"]];
|
||||
[_imgs addObject:[dict objectForKey:@"img"]?:[NSNull null]];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)draw {
|
||||
int i = 0;
|
||||
for (i = 0 ; i < 4 && i < _logIds.count ; i++) {
|
||||
UIStackView *stack = _stackViews[i];
|
||||
UIButton *button = stack.subviews[0];
|
||||
UILabel *name = stack.subviews[1];
|
||||
if (_imgs[i] != [NSNull null]) {
|
||||
[button setImage:[UIImage imageWithData:_imgs[i]] forState:UIControlStateNormal];
|
||||
}
|
||||
[stack setAlpha:1];
|
||||
button.enabled = YES;
|
||||
[name setText:_displayNames[i]];
|
||||
}
|
||||
|
||||
while (i < 4) {
|
||||
UIStackView *stack = _stackViews[i];
|
||||
UIButton *button = stack.subviews[0];
|
||||
[stack setAlpha:0];
|
||||
button.enabled = NO;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)viewDidLoad {
|
||||
[super viewDidLoad];
|
||||
// Do any additional setup after loading the view from its nib.
|
||||
for (UIStackView *stack in _stackViews) {
|
||||
UIButton *button = stack.subviews[0];
|
||||
// making rounded image
|
||||
UIImageView *imageView = button.imageView;
|
||||
imageView.layer.cornerRadius = imageView.frame.size.height / 2;
|
||||
imageView.clipsToBounds = YES;
|
||||
}
|
||||
_logIds = [NSMutableArray array];
|
||||
_imgs = [NSMutableArray array];
|
||||
_displayNames = [NSMutableArray array];
|
||||
}
|
||||
|
||||
- (void)didReceiveMemoryWarning {
|
||||
[super didReceiveMemoryWarning];
|
||||
// Dispose of any resources that can be recreated.
|
||||
[_imgs removeAllObjects];
|
||||
}
|
||||
|
||||
- (void)widgetPerformUpdateWithCompletionHandler:(void (^)(NCUpdateResult))completionHandler {
|
||||
// Perform any setup necessary in order to update the view.
|
||||
|
||||
// If an error is encountered, use NCUpdateResultFailed
|
||||
// If there's no update required, use NCUpdateResultNoData
|
||||
// If there's an update, use NCUpdateResultNewData
|
||||
[self loadData];
|
||||
[self draw];
|
||||
completionHandler(NCUpdateResultNewData);
|
||||
}
|
||||
|
||||
- (void)launchAppWithURL:(NSURL *) url {
|
||||
[self.extensionContext openURL:url
|
||||
completionHandler:nil];
|
||||
}
|
||||
|
||||
- (void)launchOnHistoryDetailsWithId:(NSString *)logId {
|
||||
[self launchAppWithURL:[NSURL URLWithString:[@"linphone-widget://call_log/show?" stringByAppendingString:logId]]];
|
||||
}
|
||||
|
||||
- (IBAction)firstButtonTapped {
|
||||
[self launchOnHistoryDetailsWithId:_logIds[0]];
|
||||
}
|
||||
|
||||
- (IBAction)secondButtonTapped {
|
||||
[self launchOnHistoryDetailsWithId:_logIds[1]];
|
||||
}
|
||||
|
||||
- (IBAction)thirdButtonTapped {
|
||||
[self launchOnHistoryDetailsWithId:_logIds[2]];
|
||||
}
|
||||
|
||||
- (IBAction)fourthButtonTapped {
|
||||
[self launchOnHistoryDetailsWithId:_logIds[3]];
|
||||
}
|
||||
@end
|
||||
10
latestCallsWidget/latestCallsWidget.entitlements
Normal file
10
latestCallsWidget/latestCallsWidget.entitlements
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>com.apple.security.application-groups</key>
|
||||
<array>
|
||||
<string>group.belledonne-communications.linphone.widget</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
152
latestChatroomsWidget/Base.lproj/MainInterface.storyboard
Normal file
152
latestChatroomsWidget/Base.lproj/MainInterface.storyboard
Normal file
|
|
@ -0,0 +1,152 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14113" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="M4Y-Lb-cyx">
|
||||
<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>
|
||||
<scenes>
|
||||
<!--Today View Controller-->
|
||||
<scene sceneID="cwh-vc-ff4">
|
||||
<objects>
|
||||
<viewController id="M4Y-Lb-cyx" customClass="TodayViewController" sceneMemberID="viewController">
|
||||
<view key="view" contentMode="scaleToFill" simulatedAppContext="notificationCenter" id="S3S-Oj-5AN">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="37"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" distribution="equalSpacing" translatesAutoresizingMaskIntoConstraints="NO" id="kvZ-RU-0JV">
|
||||
<rect key="frame" x="16" y="-26" width="288" height="87.5"/>
|
||||
<subviews>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="10" translatesAutoresizingMaskIntoConstraints="NO" id="P4U-hP-N9F">
|
||||
<rect key="frame" x="0.0" y="0.0" width="60" height="87.5"/>
|
||||
<subviews>
|
||||
<button opaque="NO" contentMode="scaleAspectFit" contentHorizontalAlignment="center" contentVerticalAlignment="center" showsTouchWhenHighlighted="YES" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="dGY-Wo-tng">
|
||||
<rect key="frame" x="0.0" y="0.0" width="60" height="60.5"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="60" id="a43-Du-y1b"/>
|
||||
<constraint firstAttribute="height" constant="60" id="gNd-AG-oLn"/>
|
||||
</constraints>
|
||||
<state key="normal" image="avatar.png"/>
|
||||
<connections>
|
||||
<action selector="firstButtonTapped" destination="M4Y-Lb-cyx" eventType="touchUpInside" id="n6M-cY-cWU"/>
|
||||
</connections>
|
||||
</button>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text=" " textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="fpJ-Wl-BT1">
|
||||
<rect key="frame" x="0.0" y="70.5" width="60" height="17"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="fpJ-Wl-BT1" firstAttribute="centerX" secondItem="P4U-hP-N9F" secondAttribute="centerX" id="3Zz-Mm-hxc"/>
|
||||
</constraints>
|
||||
</stackView>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="10" translatesAutoresizingMaskIntoConstraints="NO" id="79U-UR-Bp2">
|
||||
<rect key="frame" x="76" y="0.0" width="60" height="87.5"/>
|
||||
<subviews>
|
||||
<button opaque="NO" contentMode="scaleAspectFit" contentHorizontalAlignment="center" contentVerticalAlignment="center" showsTouchWhenHighlighted="YES" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="aiZ-1q-Ssd">
|
||||
<rect key="frame" x="0.0" y="0.0" width="60" height="60"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="60" id="0Me-vh-jt4"/>
|
||||
<constraint firstAttribute="height" constant="60" id="9hj-Pa-s8F"/>
|
||||
<constraint firstAttribute="width" constant="60" id="iil-bF-24j"/>
|
||||
</constraints>
|
||||
<state key="normal" image="avatar.png"/>
|
||||
<connections>
|
||||
<action selector="secondButtonTapped" destination="M4Y-Lb-cyx" eventType="touchUpInside" id="e09-4G-NJf"/>
|
||||
</connections>
|
||||
</button>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text=" " textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="fEo-fa-uyD">
|
||||
<rect key="frame" x="0.0" y="70" width="60" height="17.5"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="fEo-fa-uyD" firstAttribute="centerX" secondItem="79U-UR-Bp2" secondAttribute="centerX" id="FPk-ST-xe3"/>
|
||||
</constraints>
|
||||
</stackView>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="10" translatesAutoresizingMaskIntoConstraints="NO" id="Xgm-go-u3S">
|
||||
<rect key="frame" x="152" y="0.0" width="60" height="87.5"/>
|
||||
<subviews>
|
||||
<button opaque="NO" contentMode="scaleAspectFit" contentHorizontalAlignment="center" contentVerticalAlignment="center" showsTouchWhenHighlighted="YES" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="VgA-lq-CQL">
|
||||
<rect key="frame" x="0.0" y="0.0" width="60" height="60"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="60" id="TEZ-z7-Yce"/>
|
||||
<constraint firstAttribute="height" constant="60" id="rtD-OM-bmH"/>
|
||||
</constraints>
|
||||
<state key="normal" image="avatar.png"/>
|
||||
<connections>
|
||||
<action selector="thirdButtonTapped" destination="M4Y-Lb-cyx" eventType="touchUpInside" id="OtO-nr-X1J"/>
|
||||
</connections>
|
||||
</button>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text=" " textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="zM6-aO-Pes">
|
||||
<rect key="frame" x="0.0" y="70" width="60" height="17.5"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="zM6-aO-Pes" firstAttribute="centerX" secondItem="Xgm-go-u3S" secondAttribute="centerX" id="lGV-8K-Ol0"/>
|
||||
</constraints>
|
||||
</stackView>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="10" translatesAutoresizingMaskIntoConstraints="NO" id="nHe-ID-vxE">
|
||||
<rect key="frame" x="228" y="0.0" width="60" height="87.5"/>
|
||||
<subviews>
|
||||
<button opaque="NO" contentMode="scaleAspectFit" contentHorizontalAlignment="center" contentVerticalAlignment="center" showsTouchWhenHighlighted="YES" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="7je-G1-IfQ">
|
||||
<rect key="frame" x="0.0" y="0.0" width="60" height="60"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="60" id="Pm8-lw-PB4"/>
|
||||
<constraint firstAttribute="height" constant="60" id="SYf-Yl-EDf"/>
|
||||
</constraints>
|
||||
<state key="normal" image="avatar.png"/>
|
||||
<connections>
|
||||
<action selector="fourthButtonTapped" destination="M4Y-Lb-cyx" eventType="touchUpInside" id="a2u-BT-Fkp"/>
|
||||
</connections>
|
||||
</button>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text=" " textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="bpY-VL-FDz">
|
||||
<rect key="frame" x="0.0" y="70" width="60" height="17.5"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="bpY-VL-FDz" firstAttribute="centerX" secondItem="nHe-ID-vxE" secondAttribute="centerX" id="PD7-gj-AXr"/>
|
||||
</constraints>
|
||||
</stackView>
|
||||
</subviews>
|
||||
</stackView>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="kvZ-RU-0JV" firstAttribute="centerY" secondItem="S3S-Oj-5AN" secondAttribute="centerY" id="1dD-eI-ohO"/>
|
||||
<constraint firstItem="kvZ-RU-0JV" firstAttribute="leading" secondItem="S3S-Oj-5AN" secondAttribute="leading" constant="16" id="9XT-er-59s"/>
|
||||
<constraint firstItem="kvZ-RU-0JV" firstAttribute="centerX" secondItem="S3S-Oj-5AN" secondAttribute="centerX" id="l30-a1-mDN"/>
|
||||
</constraints>
|
||||
<viewLayoutGuide key="safeArea" id="ssy-KU-ocm"/>
|
||||
</view>
|
||||
<extendedEdge key="edgesForExtendedLayout"/>
|
||||
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
|
||||
<size key="freeformSize" width="320" height="37"/>
|
||||
<connections>
|
||||
<outletCollection property="stackViews" destination="P4U-hP-N9F" id="3f1-th-6ZO"/>
|
||||
<outletCollection property="stackViews" destination="79U-UR-Bp2" id="ix2-7S-Rim"/>
|
||||
<outletCollection property="stackViews" destination="Xgm-go-u3S" id="VYM-Ld-joW"/>
|
||||
<outletCollection property="stackViews" destination="nHe-ID-vxE" id="iGd-Ix-Pj6"/>
|
||||
</connections>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="vXp-U4-Rya" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
</scene>
|
||||
</scenes>
|
||||
<resources>
|
||||
<image name="avatar.png" width="259" height="259"/>
|
||||
</resources>
|
||||
</document>
|
||||
31
latestChatroomsWidget/Info.plist
Normal file
31
latestChatroomsWidget/Info.plist
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>Linphone - Latest Chatrooms</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>XPC!</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>NSExtension</key>
|
||||
<dict>
|
||||
<key>NSExtensionMainStoryboard</key>
|
||||
<string>MainInterface</string>
|
||||
<key>NSExtensionPointIdentifier</key>
|
||||
<string>com.apple.widget-extension</string>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
||||
22
latestChatroomsWidget/TodayViewController.h
Normal file
22
latestChatroomsWidget/TodayViewController.h
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
//
|
||||
// TodayViewController.h
|
||||
// latestChatroomsWidget
|
||||
//
|
||||
// Created by David Idmansour on 18/06/2018.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface TodayViewController : UIViewController
|
||||
@property (strong, nonatomic) IBOutletCollection(UIStackView) NSArray *stackViews;
|
||||
@property (strong, nonatomic) NSMutableArray *addresses;
|
||||
@property (strong, nonatomic) NSMutableArray *localAddress;
|
||||
@property (strong, nonatomic) NSMutableArray *displayNames;
|
||||
@property (strong, nonatomic) NSMutableArray *isConf;
|
||||
@property (strong, nonatomic) NSMutableArray *imgs;
|
||||
|
||||
- (IBAction)firstButtonTapped;
|
||||
- (IBAction)secondButtonTapped;
|
||||
- (IBAction)thirdButtonTapped;
|
||||
- (IBAction)fourthButtonTapped;
|
||||
@end
|
||||
119
latestChatroomsWidget/TodayViewController.m
Normal file
119
latestChatroomsWidget/TodayViewController.m
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
//
|
||||
// TodayViewController.m
|
||||
// latestChatroomsWidget
|
||||
//
|
||||
// Created by David Idmansour on 18/06/2018.
|
||||
//
|
||||
|
||||
#import "TodayViewController.h"
|
||||
#import <NotificationCenter/NotificationCenter.h>
|
||||
|
||||
@interface TodayViewController () <NCWidgetProviding>
|
||||
|
||||
@end
|
||||
|
||||
@implementation TodayViewController
|
||||
|
||||
- (void)loadData {
|
||||
NSUserDefaults *mySharedDefaults = [[NSUserDefaults alloc] initWithSuiteName: @"group.belledonne-communications.linphone.widget"];
|
||||
[_imgs removeAllObjects];
|
||||
[_addresses removeAllObjects];
|
||||
[_localAddress removeAllObjects];
|
||||
[_displayNames removeAllObjects];
|
||||
[_isConf removeAllObjects];
|
||||
NSMutableArray *chatrooms = [NSMutableArray arrayWithArray:[mySharedDefaults objectForKey:@"chatrooms"]];
|
||||
for (NSDictionary *dict in chatrooms) {
|
||||
[_addresses addObject:[dict objectForKey:@"peer"]];
|
||||
[_localAddress addObject:[dict objectForKey:@"local"]];
|
||||
[_displayNames addObject:[dict objectForKey:@"display"]];
|
||||
[_isConf addObject:(NSNumber *)[dict objectForKey:@"nbParticipants"]];
|
||||
[_imgs addObject:[dict objectForKey:@"img"]?:[NSNull null]];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)draw {
|
||||
int i = 0;
|
||||
for (i = 0 ; i < 4 && i < _addresses.count ; i++) {
|
||||
UIStackView *stack = _stackViews[i];
|
||||
UIButton *button = stack.subviews[0];
|
||||
UILabel *name = stack.subviews[1];
|
||||
if (_imgs[i] != [NSNull null]) {
|
||||
[button setImage:[UIImage imageWithData:_imgs[i]] forState:UIControlStateNormal];
|
||||
} else if (((NSNumber *)_isConf[i]).boolValue) {
|
||||
[button setImage:[UIImage imageNamed:@"chat_group_avatar.png"] forState:UIControlStateNormal];
|
||||
}
|
||||
[stack setAlpha:1];
|
||||
button.enabled = YES;
|
||||
[name setText:_displayNames[i]];
|
||||
}
|
||||
|
||||
while (i < 4) {
|
||||
UIStackView *stack = _stackViews[i];
|
||||
UIButton *button = stack.subviews[0];
|
||||
[stack setAlpha:0];
|
||||
button.enabled = NO;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)viewDidLoad {
|
||||
[super viewDidLoad];
|
||||
// Do any additional setup after loading the view from its nib.
|
||||
for (UIStackView *stack in _stackViews) {
|
||||
UIButton *button = stack.subviews[0];
|
||||
// making rounded image
|
||||
UIImageView *imageView = button.imageView;
|
||||
imageView.layer.cornerRadius = imageView.frame.size.height / 2;
|
||||
imageView.clipsToBounds = YES;
|
||||
}
|
||||
|
||||
_addresses = [NSMutableArray array];
|
||||
_localAddress = [NSMutableArray array];
|
||||
_displayNames = [NSMutableArray array];
|
||||
_imgs = [NSMutableArray array];
|
||||
_isConf = [NSMutableArray array];
|
||||
}
|
||||
|
||||
- (void)didReceiveMemoryWarning {
|
||||
[super didReceiveMemoryWarning];
|
||||
// Dispose of any resources that can be recreated.
|
||||
[_imgs removeAllObjects];
|
||||
}
|
||||
|
||||
- (void)widgetPerformUpdateWithCompletionHandler:(void (^)(NCUpdateResult))completionHandler {
|
||||
// Perform any setup necessary in order to update the view.
|
||||
|
||||
// If an error is encountered, use NCUpdateResultFailed
|
||||
// If there's no update required, use NCUpdateResultNoData
|
||||
// If there's an update, use NCUpdateResultNewData
|
||||
[self loadData];
|
||||
[self draw];
|
||||
|
||||
completionHandler(NCUpdateResultNewData);
|
||||
}
|
||||
|
||||
- (void)launchAppWithURL:(NSURL *) url {
|
||||
[self.extensionContext openURL:url
|
||||
completionHandler:nil];
|
||||
}
|
||||
|
||||
- (void)launchOnChatConversationViewWithPeerAddress:(NSString *)peerAddress andLocalAddress:(NSString *)localAddress {
|
||||
[self launchAppWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"linphone-widget://chatroom/show?peer=%@&local=%@", peerAddress, localAddress]]];
|
||||
}
|
||||
|
||||
- (IBAction)firstButtonTapped {
|
||||
[self launchOnChatConversationViewWithPeerAddress:_addresses[0] andLocalAddress:_localAddress[0]];
|
||||
}
|
||||
|
||||
- (IBAction)secondButtonTapped {
|
||||
[self launchOnChatConversationViewWithPeerAddress:_addresses[1] andLocalAddress:_localAddress[1]];
|
||||
}
|
||||
|
||||
- (IBAction)thirdButtonTapped {
|
||||
[self launchOnChatConversationViewWithPeerAddress:_addresses[2] andLocalAddress:_localAddress[2]];
|
||||
}
|
||||
|
||||
- (IBAction)fourthButtonTapped {
|
||||
[self launchOnChatConversationViewWithPeerAddress:_addresses[3] andLocalAddress:_localAddress[3]];
|
||||
}
|
||||
@end
|
||||
10
latestChatroomsWidget/latestChatroomsWidget.entitlements
Normal file
10
latestChatroomsWidget/latestChatroomsWidget.entitlements
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>com.apple.security.application-groups</key>
|
||||
<array>
|
||||
<string>group.belledonne-communications.linphone.widget</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
@ -51,6 +51,30 @@
|
|||
<string>linphone-config</string>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
<key>CFBundleURLIconFile</key>
|
||||
<string>linphone_icon_72@2x</string>
|
||||
<key>CFBundleURLName</key>
|
||||
<string>org.linphone.phone</string>
|
||||
<key>CFBundleURLSchemes</key>
|
||||
<array>
|
||||
<string>message-linphone</string>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Viewer</string>
|
||||
<key>CFBundleURLIconFile</key>
|
||||
<string>linphone_icon_72@2x</string>
|
||||
<key>CFBundleURLName</key>
|
||||
<string>org.linphone.phone</string>
|
||||
<key>CFBundleURLSchemes</key>
|
||||
<array>
|
||||
<string>linphone-widget</string>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
|
|
@ -76,6 +100,19 @@
|
|||
<string>Make audio/video calls</string>
|
||||
<key>UIApplicationExitsOnSuspend</key>
|
||||
<false/>
|
||||
<key>UIApplicationShortcutItems</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>UIApplicationShortcutItemIconType</key>
|
||||
<string>UIApplicationShortcutIconTypeCompose</string>
|
||||
<key>UIApplicationShortcutItemTitle</key>
|
||||
<string>New Message</string>
|
||||
<key>UIApplicationShortcutItemType</key>
|
||||
<string>linphone.phone.action.newMessage</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>UIApplicationShortcutWidget</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER).widget.latestChatrooms</string>
|
||||
<key>UIBackgroundModes</key>
|
||||
<array>
|
||||
<string>audio</string>
|
||||
|
|
|
|||
|
|
@ -4,5 +4,10 @@
|
|||
<dict>
|
||||
<key>aps-environment</key>
|
||||
<string>development</string>
|
||||
<key>com.apple.security.application-groups</key>
|
||||
<array>
|
||||
<string>group.belledonne-communications.linphone.widget</string>
|
||||
<string>group.belledonne-communications.linphone</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
24
linphoneExtension/Base.lproj/MainInterface.storyboard
Normal file
24
linphoneExtension/Base.lproj/MainInterface.storyboard
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13122.16" systemVersion="17A278a" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="j1y-V4-xli">
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13104.12"/>
|
||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--Share View Controller-->
|
||||
<scene sceneID="ceB-am-kn3">
|
||||
<objects>
|
||||
<viewController id="j1y-V4-xli" customClass="ShareViewController" customModuleProvider="" sceneMemberID="viewController">
|
||||
<view key="view" opaque="NO" contentMode="scaleToFill" id="wbc-yd-nQP">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<viewLayoutGuide key="safeArea" id="1Xd-am-t49"/>
|
||||
</view>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="CEy-Cv-SGf" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
</scene>
|
||||
</scenes>
|
||||
</document>
|
||||
36
linphoneExtension/Info.plist
Normal file
36
linphoneExtension/Info.plist
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>linphone</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>XPC!</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>NSExtension</key>
|
||||
<dict>
|
||||
<key>NSExtensionAttributes</key>
|
||||
<dict>
|
||||
<key>NSExtensionActivationRule</key>
|
||||
<string>TRUEPREDICATE</string>
|
||||
</dict>
|
||||
<key>NSExtensionMainStoryboard</key>
|
||||
<string>MainInterface</string>
|
||||
<key>NSExtensionPointIdentifier</key>
|
||||
<string>com.apple.share-services</string>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
||||
13
linphoneExtension/ShareViewController.h
Normal file
13
linphoneExtension/ShareViewController.h
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
//
|
||||
// ShareViewController.h
|
||||
// linphoneExtension
|
||||
//
|
||||
// Created by Danmei Chen on 31/05/2018.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <Social/Social.h>
|
||||
|
||||
@interface ShareViewController : SLComposeServiceViewController
|
||||
|
||||
@end
|
||||
99
linphoneExtension/ShareViewController.m
Normal file
99
linphoneExtension/ShareViewController.m
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
//
|
||||
// ShareViewController.m
|
||||
// linphoneExtension
|
||||
//
|
||||
// Created by Danmei Chen on 31/05/2018.
|
||||
//
|
||||
|
||||
#import "ShareViewController.h"
|
||||
|
||||
@interface ShareViewController ()
|
||||
|
||||
@end
|
||||
static NSString* groupName = @"group.belledonne-communications.linphone";
|
||||
@implementation ShareViewController
|
||||
|
||||
- (BOOL)isContentValid {
|
||||
// Do validation of contentText and/or NSExtensionContext attachments here
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)didSelectPost {
|
||||
// This is called after the user selects Post. Do the upload of contentText and/or NSExtensionContext attachments.
|
||||
|
||||
// Inform the host that we're done, so it un-blocks its UI. Note: Alternatively you could call super's -didSelectPost, which will similarly complete the extension context.
|
||||
for (NSExtensionItem *item in self.extensionContext.inputItems) {
|
||||
for (NSItemProvider *provider in item.attachments) {
|
||||
NSUserDefaults *defaults = [[NSUserDefaults alloc] initWithSuiteName:groupName];
|
||||
|
||||
if ([provider hasItemConformingToTypeIdentifier:@"public.jpeg"]) {
|
||||
[self loadItem:provider typeIdentifier:@"public.jpeg" defaults:defaults key:@"img"];
|
||||
} else if ([provider hasItemConformingToTypeIdentifier:@"public.url"]) {
|
||||
[self loadItem:provider typeIdentifier:@"public.url" defaults:defaults key:@"web"];
|
||||
} else if ([provider hasItemConformingToTypeIdentifier:@"public.movie"]) {
|
||||
[self loadItem:provider typeIdentifier:@"public.movie" defaults:defaults key:@"mov"];
|
||||
} else if ([provider hasItemConformingToTypeIdentifier:@"public.plain-text"]) {
|
||||
[self loadItem:provider typeIdentifier:@"public.plain-text" defaults:defaults key:@"text"];
|
||||
} else if ([provider hasItemConformingToTypeIdentifier:@"com.adobe.pdf"]) {
|
||||
[self loadItem:provider typeIdentifier:@"com.adobe.pdf" defaults:defaults key:@"web"];
|
||||
}
|
||||
/*else if ([provider hasItemConformingToTypeIdentifier:@"public.png"]) {
|
||||
[self loadItem:provider typeIdentifier:@"public.png" defaults:defaults key:@"img"];
|
||||
}*/
|
||||
else{
|
||||
NSLog(@"Unkown itemprovider = %@", provider);
|
||||
[self.extensionContext completeRequestReturningItems:@[] completionHandler:nil];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (NSArray *)configurationItems {
|
||||
// To add configuration options via table cells at the bottom of the sheet, return an array of SLComposeSheetConfigurationItem here.
|
||||
return @[];
|
||||
}
|
||||
|
||||
- (void)loadItem:(NSItemProvider *)provider typeIdentifier:(NSString *)typeIdentifier defaults:(NSUserDefaults *)defaults key:(NSString *)key {
|
||||
[provider loadItemForTypeIdentifier:typeIdentifier options:nil completionHandler:^(id<NSSecureCoding> _Nullable item, NSError * _Null_unspecified error) {
|
||||
if([(NSObject*)item isKindOfClass:[NSURL class]]) {
|
||||
NSData *nsData = [NSData dataWithContentsOfURL:(NSURL*)item];
|
||||
if (nsData) {
|
||||
NSDictionary *dict = @{@"nsData" : nsData,
|
||||
@"url" : [(NSURL*)item absoluteString]};
|
||||
[defaults setObject:dict forKey:key];
|
||||
} else {
|
||||
NSLog(@"NSExtensionItem Error, provider = %@", provider);
|
||||
[self.extensionContext completeRequestReturningItems:@[] completionHandler:nil];
|
||||
}
|
||||
}
|
||||
else if ([(NSObject*)item isKindOfClass:[UIImage class]]) {
|
||||
NSData *imgData = UIImagePNGRepresentation((UIImage*)item);
|
||||
if (imgData) {
|
||||
NSDictionary *dict = @{@"nsData" : imgData,
|
||||
};
|
||||
[defaults setObject:dict forKey:key];
|
||||
} else {
|
||||
NSLog(@"NSExtensionItem Error, provider = %@", provider);
|
||||
[self.extensionContext completeRequestReturningItems:@[] completionHandler:nil];
|
||||
}
|
||||
}
|
||||
else {
|
||||
NSDictionary *dict = @{@"name" : self.contentText};
|
||||
[defaults setObject:dict forKey:key];
|
||||
}
|
||||
|
||||
UIResponder *responder = self;
|
||||
while (responder != nil) {
|
||||
if ([responder respondsToSelector:@selector(openURL:)]) {
|
||||
[responder performSelector:@selector(openURL:)
|
||||
withObject:[NSURL URLWithString:@"message-linphone://" ]];
|
||||
[self.extensionContext completeRequestReturningItems:@[] completionHandler:nil];
|
||||
break;
|
||||
}
|
||||
responder = [responder nextResponder];
|
||||
}
|
||||
[defaults synchronize];
|
||||
}];
|
||||
}
|
||||
|
||||
@end
|
||||
10
linphoneExtension/linphoneExtension.entitlements
Normal file
10
linphoneExtension/linphoneExtension.entitlements
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>com.apple.security.application-groups</key>
|
||||
<array>
|
||||
<string>group.belledonne-communications.linphone</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
1
submodules/externals/zxing-cpp
vendored
Submodule
1
submodules/externals/zxing-cpp
vendored
Submodule
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 8906fb7b243fa455fd9b091e4ac611536b2dbba4
|
||||
Loading…
Add table
Reference in a new issue