forked from mirrors/linphone-iphone
Merge branch 'feature/call_recorder' into feature/integration
This commit is contained in:
commit
be3dac0b07
25 changed files with 1941 additions and 202 deletions
File diff suppressed because it is too large
Load diff
|
|
@ -42,6 +42,7 @@
|
|||
NSTimer *hideControlsTimer;
|
||||
NSTimer *videoDismissTimer;
|
||||
BOOL videoHidden;
|
||||
BOOL callRecording;
|
||||
VideoZoomHandler *videoZoomHandler;
|
||||
}
|
||||
|
||||
|
|
@ -74,6 +75,8 @@
|
|||
@property(weak, nonatomic) IBOutlet UIPauseButton *conferencePauseButton;
|
||||
@property(weak, nonatomic) IBOutlet UIBouncingView *chatNotificationView;
|
||||
@property(weak, nonatomic) IBOutlet UILabel *chatNotificationLabel;
|
||||
@property (weak, nonatomic) IBOutlet UIButton *recordButton;
|
||||
@property (weak, nonatomic) IBOutlet UIButton *recordButtonOnView;
|
||||
|
||||
@property(weak, nonatomic) IBOutlet UIView *bottomBar;
|
||||
@property(nonatomic, strong) IBOutlet UIDigitButton *oneButton;
|
||||
|
|
@ -107,5 +110,6 @@
|
|||
- (IBAction)onOptionsConferenceClick:(id)sender;
|
||||
- (IBAction)onNumpadClick:(id)sender;
|
||||
- (IBAction)onChatClick:(id)sender;
|
||||
- (IBAction)onRecordClick:(id)sender;
|
||||
|
||||
@end
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ const NSInteger SECURE_BUTTON_TAG = 5;
|
|||
singleFingerTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(toggleControls:)];
|
||||
videoZoomHandler = [[VideoZoomHandler alloc] init];
|
||||
videoHidden = TRUE;
|
||||
callRecording = FALSE;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
|
@ -716,6 +717,39 @@ static void hideSpinner(LinphoneCall *call, void *user_data) {
|
|||
[PhoneMainView.instance getOrCreateOneToOneChatRoom:addr waitView:_waitView];
|
||||
}
|
||||
|
||||
- (IBAction)onRecordClick:(id)sender {
|
||||
if (![_optionsView isHidden])
|
||||
[self hideOptions:TRUE animated:ANIMATED];
|
||||
if (callRecording) {
|
||||
LOGD(@"Recording Stops");
|
||||
[_recordButton setImage:[UIImage imageNamed:@"rec_on_default.png"] forState:UIControlStateNormal];
|
||||
[_recordButtonOnView setHidden:TRUE];
|
||||
|
||||
LinphoneCall *call = linphone_core_get_current_call(LC);
|
||||
linphone_call_stop_recording(call);
|
||||
|
||||
callRecording = FALSE;
|
||||
|
||||
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
|
||||
NSString *writablePath = [paths objectAtIndex:0];
|
||||
writablePath = [writablePath stringByAppendingString:@"/"];
|
||||
NSArray *directoryContent = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:writablePath error:NULL];
|
||||
if (directoryContent) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
LOGD(@"Recording Starts");
|
||||
|
||||
[_recordButton setImage:[UIImage imageNamed:@"rec_off_default.png"] forState:UIControlStateNormal];
|
||||
[_recordButtonOnView setHidden:FALSE];
|
||||
|
||||
LinphoneCall *call = linphone_core_get_current_call(LC);
|
||||
linphone_call_start_recording(call);
|
||||
|
||||
callRecording = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
- (IBAction)onRoutesBluetoothClick:(id)sender {
|
||||
[self hideRoutes:TRUE animated:TRUE];
|
||||
[LinphoneManager.instance setSpeakerEnabled:FALSE];
|
||||
|
|
|
|||
|
|
@ -173,7 +173,8 @@ static int sorted_history_comparison(LinphoneChatRoom *to_insert, LinphoneChatRo
|
|||
}
|
||||
[dict setObject:display
|
||||
forKey:@"display"];
|
||||
[dict setObject:[NSNumber numberWithBool:!!linphone_chat_room_get_conference_address(cr)]
|
||||
BOOL isGroupChat = linphone_chat_room_get_capabilities(cr) & LinphoneChatRoomCapabilitiesConference;
|
||||
[dict setObject:[NSNumber numberWithBool:isGroupChat]
|
||||
forKey:@"nbParticipants"];
|
||||
[addresses addObject:dict];
|
||||
if (addresses.count >= 4) //send no more data than needed
|
||||
|
|
|
|||
|
|
@ -2617,6 +2617,12 @@ static int comp_call_state_paused(const LinphoneCall *call, const void *param) {
|
|||
}
|
||||
linphone_call_params_enable_video(lcallParams, video);
|
||||
|
||||
//We set the record file name here because we can't do it after the call is started.
|
||||
NSString *writablePath = [LinphoneUtils recordingFilePathFromCall:linphone_call_log_get_from_address(linphone_call_get_call_log(call))];
|
||||
LOGD(@"record file path: %@\n", writablePath);
|
||||
|
||||
linphone_call_params_set_record_file(lcallParams, [writablePath cStringUsingEncoding:NSUTF8StringEncoding]);
|
||||
|
||||
linphone_call_accept_with_params(call, lcallParams);
|
||||
linphone_call_params_unref(lcallParams);
|
||||
}
|
||||
|
|
@ -2727,6 +2733,10 @@ static int comp_call_state_paused(const LinphoneCall *call, const void *param) {
|
|||
LinphoneManager.instance.nextCallIsTransfer = NO;
|
||||
ms_free(caddr);
|
||||
} else {
|
||||
//We set the record file name here because we can't do it after the call is started.
|
||||
NSString *writablePath = [LinphoneUtils recordingFilePathFromCall:addr];
|
||||
LOGD(@"record file path: %@\n", writablePath);
|
||||
linphone_call_params_set_record_file(lcallParams, [writablePath cStringUsingEncoding:NSUTF8StringEncoding]);
|
||||
call = linphone_core_invite_address_with_params(theLinphoneCore, addr, lcallParams);
|
||||
if (call) {
|
||||
// The LinphoneCallAppData object should be set on call creation with callback
|
||||
|
|
|
|||
26
Classes/LinphoneUI/UILinphoneAudioPlayer.h
Normal file
26
Classes/LinphoneUI/UILinphoneAudioPlayer.h
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
//
|
||||
// UILinphoneAudioPlayer.h
|
||||
// linphone
|
||||
//
|
||||
// Created by David Idmansour on 13/07/2018.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface UILinphoneAudioPlayer : UIViewController
|
||||
@property (weak, nonatomic) IBOutlet UIButton *playButton;
|
||||
@property (weak, nonatomic) IBOutlet UIButton *stopButton;
|
||||
@property (weak, nonatomic) IBOutlet UILabel *timeLabel;
|
||||
@property (weak, nonatomic) IBOutlet UIProgressView *timeProgress;
|
||||
@property (weak, nonatomic) NSString *file;
|
||||
|
||||
+ (id)audioPlayerWithFilePath:(NSString *)filePath;
|
||||
- (void)close;
|
||||
- (BOOL)isOpened;
|
||||
- (void)open;
|
||||
- (void)pause;
|
||||
- (void)setFile:(NSString *)fileName;
|
||||
- (IBAction)onPlay:(id)sender;
|
||||
- (IBAction)onStop:(id)sender;
|
||||
- (IBAction)onTapTimeBar:(UITapGestureRecognizer *)sender;
|
||||
@end
|
||||
207
Classes/LinphoneUI/UILinphoneAudioPlayer.m
Normal file
207
Classes/LinphoneUI/UILinphoneAudioPlayer.m
Normal file
|
|
@ -0,0 +1,207 @@
|
|||
//
|
||||
// UILinphoneAudioPlayer.m
|
||||
// linphone
|
||||
//
|
||||
// Created by David Idmansour on 13/07/2018.
|
||||
//
|
||||
|
||||
#import "UILinphoneAudioPlayer.h"
|
||||
#import "Utils.h"
|
||||
|
||||
@implementation UILinphoneAudioPlayer {
|
||||
@private
|
||||
LinphonePlayer *player;
|
||||
LinphonePlayerCbs *cbs;
|
||||
int duration;
|
||||
BOOL eofReached;
|
||||
}
|
||||
|
||||
@synthesize file;
|
||||
|
||||
#pragma mark - Factory
|
||||
|
||||
+ (id)audioPlayerWithFilePath:(NSString *)filePath {
|
||||
return [[self alloc] initWithFilePath:filePath];
|
||||
}
|
||||
|
||||
#pragma mark - Life cycle
|
||||
|
||||
- (instancetype)initWithFilePath:(NSString *)filePath {
|
||||
if (self = [super initWithNibName:NSStringFromClass(self.class) bundle:[NSBundle mainBundle]]) {
|
||||
player = linphone_core_create_local_player(LC, NULL, NULL, NULL);
|
||||
cbs = linphone_player_get_callbacks(player);
|
||||
linphone_player_set_user_data(player, (__bridge void *)self);
|
||||
linphone_player_cbs_set_eof_reached(cbs, on_eof_reached);
|
||||
file = filePath;
|
||||
eofReached = NO;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
[self close];
|
||||
}
|
||||
|
||||
- (void)close {
|
||||
if (player) {
|
||||
linphone_player_unref(player);
|
||||
player = NULL;
|
||||
}
|
||||
[self.view removeFromSuperview];
|
||||
}
|
||||
|
||||
- (void)viewDidAppear:(BOOL)animated {
|
||||
[_playButton setTitle:@"" forState:UIControlStateNormal];
|
||||
if (player && linphone_player_get_state(player) == LinphonePlayerPlaying)
|
||||
[_playButton setImage:[UIImage imageFromSystemBarButton:UIBarButtonSystemItemPause:[UIColor blackColor]] forState:UIControlStateNormal];
|
||||
else
|
||||
[_playButton setImage:[UIImage imageFromSystemBarButton:UIBarButtonSystemItemPlay:[UIColor blackColor]] forState:UIControlStateNormal];
|
||||
[_stopButton setTitle:@"" forState:UIControlStateNormal];
|
||||
[_stopButton setImage:[UIImage imageFromSystemBarButton:UIBarButtonSystemItemRefresh:[UIColor blackColor]] forState:UIControlStateNormal];
|
||||
}
|
||||
|
||||
- (void)open {
|
||||
linphone_player_open(player, file.UTF8String);
|
||||
duration = linphone_player_get_duration(player);
|
||||
[self updateTimeLabel:0];
|
||||
_timeProgress.progress = 0;
|
||||
eofReached = NO;
|
||||
[_playButton setTitle:@"" forState:UIControlStateNormal];
|
||||
[_playButton setImage:[UIImage imageFromSystemBarButton:UIBarButtonSystemItemPlay:[UIColor blackColor]] forState:UIControlStateNormal];
|
||||
[_stopButton setTitle:@"" forState:UIControlStateNormal];
|
||||
[_stopButton setImage:[UIImage imageFromSystemBarButton:UIBarButtonSystemItemRefresh:[UIColor blackColor]] forState:UIControlStateNormal];
|
||||
}
|
||||
|
||||
- (BOOL)isOpened {
|
||||
return player && linphone_player_get_state(player) != LinphonePlayerClosed;
|
||||
}
|
||||
|
||||
- (void)setFile:(NSString *)fileName {
|
||||
linphone_player_close(player);
|
||||
file = fileName;
|
||||
}
|
||||
|
||||
#pragma mark - Callbacks
|
||||
|
||||
void on_eof_reached(LinphonePlayer *pl) {
|
||||
NSLog(@"EOF reached");
|
||||
UILinphoneAudioPlayer *player = (__bridge UILinphoneAudioPlayer *)linphone_player_get_user_data(pl);
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[player.playButton setTitle:@"" forState:UIControlStateNormal];
|
||||
[player.playButton setImage:[UIImage imageFromSystemBarButton:UIBarButtonSystemItemPlay:[UIColor blackColor]] forState:UIControlStateNormal];
|
||||
});
|
||||
player->eofReached = YES;
|
||||
}
|
||||
|
||||
#pragma mark - ViewController methods
|
||||
|
||||
- (void)viewDidLoad {
|
||||
[super viewDidLoad];
|
||||
}
|
||||
|
||||
- (void)didReceiveMemoryWarning {
|
||||
[super didReceiveMemoryWarning];
|
||||
}
|
||||
|
||||
#pragma mark - Utils
|
||||
|
||||
+ (NSString *)timeToString:(int)time {
|
||||
time /= 1000;
|
||||
int hours = time / 3600;
|
||||
time %= 3600;
|
||||
int minutes = time / 60;
|
||||
int seconds = time % 60;
|
||||
NSNumberFormatter *formatter = [NSNumberFormatter new];
|
||||
formatter.maximumIntegerDigits = 2;
|
||||
formatter.minimumIntegerDigits = 2;
|
||||
NSString *ret = [NSString stringWithFormat:@"%@:%@",
|
||||
[formatter stringFromNumber:[NSNumber numberWithInt:minutes]],
|
||||
[formatter stringFromNumber:[NSNumber numberWithInt:seconds]]];
|
||||
ret = (hours == 0)?ret:[[NSString stringWithFormat:@"%d:", hours] stringByAppendingString:ret];
|
||||
return ret;
|
||||
}
|
||||
|
||||
#pragma mark - Updating
|
||||
|
||||
- (void)updateTimeLabel:(int)currentTime {
|
||||
_timeLabel.text = [NSString stringWithFormat:@"%@ / %@", [self.class timeToString:currentTime], [self.class timeToString:duration]];
|
||||
}
|
||||
|
||||
- (void)update {
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
|
||||
while (player && linphone_player_get_state(player) == LinphonePlayerPlaying) {
|
||||
int start = linphone_player_get_current_position(player);
|
||||
while (player && start + 100 < duration && start + 100 > linphone_player_get_current_position(player)) {
|
||||
[NSThread sleepForTimeInterval:0.01];
|
||||
if (!player || linphone_player_get_state(player) == LinphonePlayerPaused)
|
||||
break;
|
||||
}
|
||||
start = player ? linphone_player_get_current_position(player) : start;
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
_timeProgress.progress = (float)start / (float)duration;
|
||||
[self updateTimeLabel:start];
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
- (void)pause {
|
||||
if ([self isOpened]) {
|
||||
linphone_player_pause(player);
|
||||
[_playButton setTitle:@"" forState:UIControlStateNormal];
|
||||
[_playButton setImage:[UIImage imageFromSystemBarButton:UIBarButtonSystemItemPlay:[UIColor blackColor]] forState:UIControlStateNormal];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Event handlers
|
||||
|
||||
- (IBAction)onPlay:(id)sender {
|
||||
if (eofReached) {
|
||||
linphone_player_seek(player, 0);
|
||||
eofReached = NO;
|
||||
}
|
||||
LinphonePlayerState state = linphone_player_get_state(player);
|
||||
switch (state) {
|
||||
case LinphonePlayerClosed:
|
||||
break;
|
||||
case LinphonePlayerPaused:
|
||||
NSLog(@"Play");
|
||||
[_playButton setTitle:@"" forState:UIControlStateNormal];
|
||||
[_playButton setImage:[UIImage imageFromSystemBarButton:UIBarButtonSystemItemPause:[UIColor blackColor]] forState:UIControlStateNormal];
|
||||
linphone_player_start(player);
|
||||
break;
|
||||
case LinphonePlayerPlaying:
|
||||
NSLog(@"Pause");
|
||||
[_playButton setTitle:@"" forState:UIControlStateNormal];
|
||||
[_playButton setImage:[UIImage imageFromSystemBarButton:UIBarButtonSystemItemPlay:[UIColor blackColor]] forState:UIControlStateNormal];
|
||||
linphone_player_pause(player);
|
||||
break;
|
||||
}
|
||||
[self update];
|
||||
}
|
||||
|
||||
- (IBAction)onStop:(id)sender {
|
||||
NSLog(@"Stop");
|
||||
linphone_player_pause(player);
|
||||
linphone_player_seek(player, 0);
|
||||
eofReached = NO;
|
||||
[_playButton setTitle:@"" forState:UIControlStateNormal];
|
||||
[_playButton setImage:[UIImage imageFromSystemBarButton:UIBarButtonSystemItemPlay:[UIColor blackColor]] forState:UIControlStateNormal];
|
||||
_timeProgress.progress = 0;
|
||||
[self updateTimeLabel:0];
|
||||
}
|
||||
|
||||
- (IBAction)onTapTimeBar:(UITapGestureRecognizer *)sender {
|
||||
if (sender.state != UIGestureRecognizerStateEnded)
|
||||
return;
|
||||
CGPoint loc = [sender locationInView:self.view];
|
||||
CGPoint timeLoc = _timeProgress.frame.origin;
|
||||
CGSize timeSize = _timeProgress.frame.size;
|
||||
if (loc.x >= timeLoc.x && loc.x <= timeLoc.x + timeSize.width && loc.y >= timeLoc.y - 10 && loc.y <= timeLoc.y + timeSize.height + 10) {
|
||||
float progress = (loc.x - timeLoc.x) / timeSize.width;
|
||||
_timeProgress.progress = progress;
|
||||
[self updateTimeLabel:(int)(progress * duration)];
|
||||
linphone_player_seek(player, (int)(progress * duration));
|
||||
}
|
||||
}
|
||||
@end
|
||||
85
Classes/LinphoneUI/UILinphoneAudioPlayer.xib
Normal file
85
Classes/LinphoneUI/UILinphoneAudioPlayer.xib
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14113" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
|
||||
<device id="retina4_7" orientation="portrait">
|
||||
<adaptation id="fullscreen"/>
|
||||
</device>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14088"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="UILinphoneAudioPlayer">
|
||||
<connections>
|
||||
<outlet property="playButton" destination="DUO-wG-b7H" id="Yb4-v3-wo2"/>
|
||||
<outlet property="stopButton" destination="FXh-QI-38P" id="JUI-lL-g0e"/>
|
||||
<outlet property="timeLabel" destination="YhA-gd-k7i" id="sLG-Mu-eAV"/>
|
||||
<outlet property="timeProgress" destination="Un6-Ly-zHN" id="jpN-bN-hba"/>
|
||||
<outlet property="view" destination="i5M-Pr-FkT" id="sfx-zR-JGt"/>
|
||||
</connections>
|
||||
</placeholder>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||
<view clearsContextBeforeDrawing="NO" contentMode="scaleToFill" id="i5M-Pr-FkT">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="244"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="DUO-wG-b7H">
|
||||
<rect key="frame" x="10" y="112" width="20" height="20"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="20" id="0Ih-RU-H6C"/>
|
||||
<constraint firstAttribute="height" constant="20" id="SxX-FF-vrP"/>
|
||||
</constraints>
|
||||
<color key="tintColor" white="0.33333333333333331" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<state key="normal" title="Play"/>
|
||||
<connections>
|
||||
<action selector="onPlay:" destination="-1" eventType="touchUpInside" id="mdn-z8-Vx0"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="FXh-QI-38P">
|
||||
<rect key="frame" x="40" y="112" width="20" height="20"/>
|
||||
<gestureRecognizers/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="20" id="L60-0M-7lU"/>
|
||||
<constraint firstAttribute="width" constant="20" id="XbH-oS-0HR"/>
|
||||
</constraints>
|
||||
<color key="tintColor" white="0.33333333329999998" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<state key="normal" title="Stop"/>
|
||||
<connections>
|
||||
<action selector="onStop:" destination="-1" eventType="touchUpInside" id="DwC-vv-yxp"/>
|
||||
</connections>
|
||||
</button>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="00:00 / 00:00" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="YhA-gd-k7i">
|
||||
<rect key="frame" x="275.5" y="113" width="89.5" height="17"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<progressView opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Un6-Ly-zHN">
|
||||
<rect key="frame" x="70" y="121" width="195.5" height="2"/>
|
||||
</progressView>
|
||||
</subviews>
|
||||
<gestureRecognizers/>
|
||||
<constraints>
|
||||
<constraint firstItem="Un6-Ly-zHN" firstAttribute="centerY" secondItem="i5M-Pr-FkT" secondAttribute="centerY" id="BWM-Qg-HeY"/>
|
||||
<constraint firstItem="YhA-gd-k7i" firstAttribute="leading" secondItem="Un6-Ly-zHN" secondAttribute="trailing" constant="10" id="G9J-X5-6oS"/>
|
||||
<constraint firstItem="FXh-QI-38P" firstAttribute="centerY" secondItem="i5M-Pr-FkT" secondAttribute="centerY" id="NRb-Ss-DJM"/>
|
||||
<constraint firstItem="DUO-wG-b7H" firstAttribute="leading" secondItem="i5M-Pr-FkT" secondAttribute="leading" constant="10" id="Oph-fo-dql"/>
|
||||
<constraint firstItem="YhA-gd-k7i" firstAttribute="centerY" secondItem="i5M-Pr-FkT" secondAttribute="centerY" id="bPH-p6-5Ld"/>
|
||||
<constraint firstItem="FXh-QI-38P" firstAttribute="leading" secondItem="DUO-wG-b7H" secondAttribute="trailing" constant="10" id="beC-Uz-QCv"/>
|
||||
<constraint firstItem="Un6-Ly-zHN" firstAttribute="leading" secondItem="FXh-QI-38P" secondAttribute="trailing" constant="10" id="gcp-l1-wUa"/>
|
||||
<constraint firstItem="DUO-wG-b7H" firstAttribute="centerY" secondItem="i5M-Pr-FkT" secondAttribute="centerY" id="rwM-cP-iOM"/>
|
||||
<constraint firstAttribute="trailing" secondItem="YhA-gd-k7i" secondAttribute="trailing" constant="10" id="yxZ-qn-Oyi"/>
|
||||
</constraints>
|
||||
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
|
||||
<connections>
|
||||
<outletCollection property="gestureRecognizers" destination="gGk-Ya-vJQ" appends="YES" id="SS3-4b-5sv"/>
|
||||
</connections>
|
||||
<point key="canvasLocation" x="24.5" y="-160"/>
|
||||
</view>
|
||||
<tapGestureRecognizer id="gGk-Ya-vJQ" userLabel="onTapRecognizer">
|
||||
<connections>
|
||||
<action selector="onTapTimeBar:" destination="-1" id="2St-UF-1QP"/>
|
||||
</connections>
|
||||
</tapGestureRecognizer>
|
||||
</objects>
|
||||
</document>
|
||||
24
Classes/LinphoneUI/UIRecordingCell.h
Normal file
24
Classes/LinphoneUI/UIRecordingCell.h
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
//
|
||||
// UIRecordingCell.h
|
||||
// linphone
|
||||
//
|
||||
// Created by benjamin_verdier on 25/07/2018.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface UIRecordingCell : UITableViewCell
|
||||
|
||||
@property (weak, nonatomic) IBOutlet UIView *playerView;
|
||||
@property (weak, nonatomic) IBOutlet UILabel *nameLabel;
|
||||
@property (strong, nonatomic) IBOutlet UIToolbar *toolbar;
|
||||
@property (weak, nonatomic) IBOutlet UIBarButtonItem *shareButton;
|
||||
|
||||
|
||||
@property(nonatomic, assign) __block NSString *recording;
|
||||
|
||||
- (id)initWithIdentifier:(NSString*)identifier;
|
||||
|
||||
- (void)updateFrame;
|
||||
|
||||
@end
|
||||
126
Classes/LinphoneUI/UIRecordingCell.m
Normal file
126
Classes/LinphoneUI/UIRecordingCell.m
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
//
|
||||
// UIRecordingCell.m
|
||||
// linphone
|
||||
//
|
||||
// Created by benjamin_verdier on 25/07/2018.
|
||||
//
|
||||
|
||||
#import "UIRecordingCell.h"
|
||||
#import "PhoneMainView.h"
|
||||
#import "UILabel+Boldify.h"
|
||||
#import "Utils.h"
|
||||
#import "UILinphoneAudioPlayer.h"
|
||||
|
||||
@implementation UIRecordingCell
|
||||
|
||||
static UILinphoneAudioPlayer *player;
|
||||
|
||||
#pragma mark - Lifecycle Functions
|
||||
/*
|
||||
* TODO:
|
||||
* - When we scroll past a selected row, the player loads incorrectly (no buttons). Probably a problem in the player code.
|
||||
* - mkv recording is probably buggy, wrong eof. wav playing works but does not display the length/timestamp.
|
||||
* - The share button is greyed out when not clicking it. idk why, it's really weird.
|
||||
*/
|
||||
- (id)initWithIdentifier:(NSString *)identifier {
|
||||
if ((self = [super initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier])) {
|
||||
NSArray *arrayOfViews =
|
||||
[[NSBundle mainBundle] loadNibNamed:NSStringFromClass(self.class) owner:self options:nil];
|
||||
|
||||
// resize cell to match .nib size. It is needed when resized the cell to
|
||||
// correctly adapt its height too
|
||||
UIRecordingCell *sub = [arrayOfViews objectAtIndex:0];
|
||||
[self setFrame:CGRectMake(0, 0, sub.frame.size.width, 40)];
|
||||
self = sub;
|
||||
self.recording = NULL;
|
||||
_shareButton.target = self;
|
||||
_shareButton.action = @selector(onShareButtonPressed);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
self.recording = NULL;
|
||||
[NSNotificationCenter.defaultCenter removeObserver:self];
|
||||
}
|
||||
|
||||
#pragma mark - Property Functions
|
||||
|
||||
- (void)setRecording:(NSString *)arecording {
|
||||
_recording = arecording;
|
||||
if(_recording) {
|
||||
NSArray *parsedRecording = [LinphoneUtils parseRecordingName:_recording];
|
||||
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
|
||||
[dateFormat setDateFormat:@"HH:mm:ss"];
|
||||
_nameLabel.text = [[[parsedRecording objectAtIndex:0] stringByAppendingString:@" @ "] stringByAppendingString:[dateFormat stringFromDate:[parsedRecording objectAtIndex:1]]];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
- (NSString *)accessibilityLabel {
|
||||
return _nameLabel.text;
|
||||
}
|
||||
|
||||
- (void)setEditing:(BOOL)editing {
|
||||
[self setEditing:editing animated:FALSE];
|
||||
}
|
||||
|
||||
- (void)setEditing:(BOOL)editing animated:(BOOL)animated {
|
||||
if (animated) {
|
||||
[UIView beginAnimations:nil context:nil];
|
||||
[UIView setAnimationDuration:0.3];
|
||||
}
|
||||
if (animated) {
|
||||
[UIView commitAnimations];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated {
|
||||
self.selectionStyle = UITableViewCellSelectionStyleNone;
|
||||
}
|
||||
|
||||
- (void)updateFrame {
|
||||
CGRect frame = self.frame;
|
||||
if (!self.selected) {
|
||||
frame.size.height = 40;
|
||||
} else {
|
||||
frame.size.height = 150;
|
||||
}
|
||||
[self setFrame:frame];
|
||||
}
|
||||
|
||||
-(void)setSelected:(BOOL)selected animated:(BOOL)animated{
|
||||
[super setSelected:selected animated:animated];
|
||||
_toolbar.hidden = !selected;
|
||||
if (!selected) {
|
||||
return;
|
||||
}
|
||||
if (!player)
|
||||
player = [UILinphoneAudioPlayer audioPlayerWithFilePath:[self recording]];
|
||||
else
|
||||
[player setFile:[self recording]];
|
||||
if ([player isOpened])
|
||||
[player close];
|
||||
[player.view removeFromSuperview];
|
||||
[self addSubview:player.view];
|
||||
[self bringSubviewToFront:player.view];
|
||||
player.view.frame = _playerView.frame;
|
||||
player.view.bounds = _playerView.bounds;
|
||||
[player open];
|
||||
}
|
||||
|
||||
- (void)onShareButtonPressed {
|
||||
UIActivityViewController *activityVC = [[UIActivityViewController alloc] initWithActivityItems:@[[NSURL fileURLWithPath:_recording]] applicationActivities:nil];
|
||||
[activityVC setCompletionWithItemsHandler:^(UIActivityType __nullable activityType, BOOL completed, NSArray * __nullable returnedItems, NSError * __nullable activityError) {
|
||||
//This is used to select the same row when we get back to the recordings view.
|
||||
NSString *file = player.file;
|
||||
//This reloads the view, if don't it's empty for some reason. Idealy we'd want to do this before closing the view but it's functionnal.
|
||||
[PhoneMainView.instance popCurrentView];
|
||||
[PhoneMainView.instance changeCurrentView:RecordingsListView.compositeViewDescription];
|
||||
[[(RecordingsListView *)VIEW(RecordingsListView) tableController] setSelected:file];
|
||||
}];
|
||||
[PhoneMainView.instance presentViewController:activityVC animated:YES completion:nil];
|
||||
}
|
||||
|
||||
@end
|
||||
52
Classes/LinphoneUI/UIRecordingCell.xib
Normal file
52
Classes/LinphoneUI/UIRecordingCell.xib
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14113" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
|
||||
<device id="retina4_7" orientation="portrait">
|
||||
<adaptation id="fullscreen"/>
|
||||
</device>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14088"/>
|
||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||
<view autoresizesSubviews="NO" clipsSubviews="YES" contentMode="scaleToFill" id="e3d-Tw-Cmt" customClass="UIRecordingCell">
|
||||
<rect key="frame" x="0.0" y="0.0" width="360" height="150"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Nk9-eo-eCo">
|
||||
<rect key="frame" x="0.0" y="42" width="360" height="108"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</view>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Bzd-99-LAI">
|
||||
<rect key="frame" x="16" y="0.0" width="300" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<toolbar opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleAspectFill" fixedFrame="YES" translucent="NO" translatesAutoresizingMaskIntoConstraints="NO" id="xjs-iK-dSH">
|
||||
<rect key="frame" x="300" y="0.0" width="60" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
|
||||
<items>
|
||||
<barButtonItem style="plain" systemItem="action" id="Drx-8h-kbM"/>
|
||||
</items>
|
||||
</toolbar>
|
||||
</subviews>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<nil key="simulatedStatusBarMetrics"/>
|
||||
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
|
||||
<viewLayoutGuide key="safeArea" id="Ak9-b1-W1C"/>
|
||||
<connections>
|
||||
<outlet property="nameLabel" destination="Bzd-99-LAI" id="Ubb-kU-T09"/>
|
||||
<outlet property="playerView" destination="Nk9-eo-eCo" id="64I-70-nHC"/>
|
||||
<outlet property="shareButton" destination="Drx-8h-kbM" id="Vhv-4D-Ptx"/>
|
||||
<outlet property="toolbar" destination="xjs-iK-dSH" id="NY4-Wk-dld"/>
|
||||
</connections>
|
||||
<point key="canvasLocation" x="26" y="105"/>
|
||||
</view>
|
||||
</objects>
|
||||
</document>
|
||||
|
|
@ -45,6 +45,7 @@
|
|||
#import "HistoryDetailsView.h"
|
||||
#import "HistoryListView.h"
|
||||
#import "ImageView.h"
|
||||
#import "RecordingsListView.h"
|
||||
#import "SettingsView.h"
|
||||
#import "SideMenuView.h"
|
||||
#import "UIConfirmationDialog.h"
|
||||
|
|
|
|||
23
Classes/RecordingsListTableView.h
Normal file
23
Classes/RecordingsListTableView.h
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
//
|
||||
// RecordingsListTableView.h
|
||||
// linphone
|
||||
//
|
||||
// Created by benjamin_verdier on 25/07/2018.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import "UICheckBoxTableView.h"
|
||||
|
||||
@interface RecordingsListTableView : UICheckBoxTableView {
|
||||
@private
|
||||
NSMutableDictionary *recordings;
|
||||
//This has sub arrays indexed with the date of the recordings, themselves containings the recordings.
|
||||
NSString *writablePath;
|
||||
//This is the path to the folder where we write the recordings to. We should probably define it in LinphoneManager though.
|
||||
}
|
||||
- (void)loadData;
|
||||
- (void)removeAllRecordings;
|
||||
- (void)setSelected:(NSString *)filepath;
|
||||
|
||||
@end
|
||||
249
Classes/RecordingsListTableView.m
Normal file
249
Classes/RecordingsListTableView.m
Normal file
|
|
@ -0,0 +1,249 @@
|
|||
//
|
||||
// RecordingsListTableView.m
|
||||
// linphone
|
||||
//
|
||||
// Created by benjamin_verdier on 25/07/2018.
|
||||
//
|
||||
|
||||
#import "RecordingsListTableView.h"
|
||||
#import "UIRecordingCell.h"
|
||||
#import "LinphoneManager.h"
|
||||
#import "PhoneMainView.h"
|
||||
#import "Utils.h"
|
||||
|
||||
@implementation RecordingsListTableView
|
||||
|
||||
#pragma mark - Lifecycle Functions
|
||||
|
||||
- (void)initRecordingsTableViewController {
|
||||
recordings = [NSMutableDictionary dictionary];
|
||||
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
|
||||
writablePath = [paths objectAtIndex:0];
|
||||
writablePath = [writablePath stringByAppendingString:@"/"];
|
||||
}
|
||||
|
||||
- (void)viewWillAppear:(BOOL)animated {
|
||||
[super viewWillAppear:animated];
|
||||
if (![self selectFirstRow]) {
|
||||
//TODO: Make first cell expand to show player
|
||||
}
|
||||
[self loadData];
|
||||
}
|
||||
|
||||
- (id)init {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
[self initRecordingsTableViewController];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id)initWithCoder:(NSCoder *)decoder {
|
||||
self = [super initWithCoder:decoder];
|
||||
if (self) {
|
||||
[self initRecordingsTableViewController];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
[self removeAllRecordings];
|
||||
}
|
||||
|
||||
- (void)removeAllRecordings {
|
||||
for (NSInteger j = 0; j < [self.tableView numberOfSections]; ++j) {
|
||||
for (NSInteger i = 0; i < [self.tableView numberOfRowsInSection:j]; ++i) {
|
||||
[[self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:i inSection:j]] setRecording:nil];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (void)loadData {
|
||||
LOGI(@"====>>>> Load recording list - Start");
|
||||
|
||||
recordings = [NSMutableDictionary dictionary];
|
||||
NSArray *directoryContent = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:writablePath error:NULL];
|
||||
for (NSString *file in directoryContent) {
|
||||
if (![file hasPrefix:@"recording_"]) {
|
||||
continue;
|
||||
}
|
||||
NSArray *parsedName = [LinphoneUtils parseRecordingName:file];
|
||||
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
|
||||
[dateFormat setDateFormat:@"EEEE, MMM d, yyyy"];
|
||||
NSString *dayPretty = [dateFormat stringFromDate:[parsedName objectAtIndex:1]];
|
||||
NSMutableArray *recOfDay = [recordings objectForKey:dayPretty];
|
||||
if (recOfDay) {
|
||||
// Loop through the object until a later object, then insert it right before
|
||||
int i;
|
||||
for (i = 0; i < [recOfDay count]; ++i) {
|
||||
NSString *fileAtIndex = [recOfDay objectAtIndex:i];
|
||||
NSArray *parsedNameAtIndex = [LinphoneUtils parseRecordingName:fileAtIndex];
|
||||
if ([[parsedName objectAtIndex:1] compare:[parsedNameAtIndex objectAtIndex:1]] == NSOrderedDescending) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
[recOfDay insertObject:[writablePath stringByAppendingString:file] atIndex:i];
|
||||
} else {
|
||||
recOfDay = [NSMutableArray arrayWithObjects:[writablePath stringByAppendingString:file], nil];
|
||||
[recordings setObject:recOfDay forKey:dayPretty];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
LOGI(@"====>>>> Load recording list - End");
|
||||
[super loadData];
|
||||
}
|
||||
|
||||
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||
NSIndexPath *selectedRow = [self.tableView indexPathForSelectedRow];
|
||||
if (selectedRow && [selectedRow compare:indexPath] == NSOrderedSame) {
|
||||
return 150;
|
||||
} else {
|
||||
return 40;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - UITableViewDataSource Functions
|
||||
|
||||
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
|
||||
return [recordings count];
|
||||
}
|
||||
|
||||
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
|
||||
NSArray *sortedKey = [self getSortedKeys];
|
||||
return [(NSArray *)[recordings objectForKey:[sortedKey objectAtIndex:section]] count];
|
||||
}
|
||||
|
||||
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||
NSString *kCellId = NSStringFromClass(UIRecordingCell.class);
|
||||
UIRecordingCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellId];
|
||||
if (cell == nil) {
|
||||
cell = [[UIRecordingCell alloc] initWithIdentifier:kCellId];
|
||||
}
|
||||
NSString *date = [[self getSortedKeys] objectAtIndex:[indexPath section]];
|
||||
NSMutableArray *subAr = [recordings objectForKey:date];
|
||||
NSString *recordingPath = subAr[indexPath.row];
|
||||
[cell setRecording:recordingPath];
|
||||
[super accessoryForCell:cell atPath:indexPath];
|
||||
//accessoryForCell set it to gray but we don't want it
|
||||
cell.selectionStyle = UITableViewCellSelectionStyleNone;
|
||||
[cell updateFrame];
|
||||
return cell;
|
||||
}
|
||||
|
||||
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
|
||||
CGRect frame = CGRectMake(0, 0, tableView.frame.size.width, tableView.sectionHeaderHeight);
|
||||
UIView *tempView = [[UIView alloc] initWithFrame:frame];
|
||||
tempView.backgroundColor = [UIColor whiteColor];
|
||||
|
||||
UILabel *tempLabel = [[UILabel alloc] initWithFrame:frame];
|
||||
tempLabel.backgroundColor = [UIColor clearColor];
|
||||
tempLabel.textColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"color_A.png"]];
|
||||
tempLabel.text = [[self getSortedKeys] objectAtIndex:section];
|
||||
tempLabel.textAlignment = NSTextAlignmentCenter;
|
||||
tempLabel.font = [UIFont boldSystemFontOfSize:17];
|
||||
tempLabel.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
|
||||
[tempView addSubview:tempLabel];
|
||||
|
||||
return tempView;
|
||||
}
|
||||
|
||||
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||
[super tableView:tableView didSelectRowAtIndexPath:indexPath];
|
||||
if (![self isEditing]) {
|
||||
[tableView beginUpdates];
|
||||
[(UIRecordingCell *)[self tableView:tableView cellForRowAtIndexPath:indexPath] updateFrame];
|
||||
[tableView endUpdates];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)tableView:(UITableView *)tableView
|
||||
commitEditingStyle:(UITableViewCellEditingStyle)editingStyle
|
||||
forRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||
if (editingStyle == UITableViewCellEditingStyleDelete) {
|
||||
[NSNotificationCenter.defaultCenter removeObserver:self];
|
||||
[tableView beginUpdates];
|
||||
|
||||
|
||||
NSString *date = [[self getSortedKeys] objectAtIndex:[indexPath section]];
|
||||
NSMutableArray *subAr = [recordings objectForKey:date];
|
||||
NSString *recordingPath = subAr[indexPath.row];
|
||||
[subAr removeObjectAtIndex:indexPath.row];
|
||||
if (subAr.count == 0) {
|
||||
[recordings removeObjectForKey:date];
|
||||
[tableView deleteSections:[NSIndexSet indexSetWithIndex:indexPath.section]
|
||||
withRowAnimation:UITableViewRowAnimationFade];
|
||||
}
|
||||
|
||||
UIRecordingCell* cell = [self.tableView cellForRowAtIndexPath:indexPath];
|
||||
[cell setRecording:NULL];
|
||||
|
||||
remove([recordingPath cStringUsingEncoding:NSUTF8StringEncoding]);
|
||||
|
||||
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
|
||||
[tableView endUpdates];
|
||||
|
||||
[self loadData];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)removeSelectionUsing:(void (^)(NSIndexPath *))remover {
|
||||
[super removeSelectionUsing:^(NSIndexPath *indexPath) {
|
||||
[NSNotificationCenter.defaultCenter removeObserver:self];
|
||||
|
||||
NSString *date = [[self getSortedKeys] objectAtIndex:[indexPath section]];
|
||||
NSMutableArray *subAr = [recordings objectForKey:date];
|
||||
NSString *recordingPath = subAr[indexPath.row];
|
||||
[subAr removeObjectAtIndex:indexPath.row];
|
||||
if (subAr.count == 0) {
|
||||
[recordings removeObjectForKey:date];
|
||||
}
|
||||
UIRecordingCell* cell = [self.tableView cellForRowAtIndexPath:indexPath];
|
||||
[cell setRecording:NULL];
|
||||
remove([recordingPath cStringUsingEncoding:NSUTF8StringEncoding]);
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)setSelected:(NSString *)filepath {
|
||||
NSArray *parsedName = [LinphoneUtils parseRecordingName:filepath];
|
||||
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
|
||||
[dateFormat setDateFormat:@"EEEE, MMM d, yyyy"];
|
||||
NSString *dayPretty = [dateFormat stringFromDate:[parsedName objectAtIndex:1]];
|
||||
NSUInteger section;
|
||||
NSArray *keys = [recordings allKeys];
|
||||
for (section = 0; section < [keys count]; ++section) {
|
||||
if ([dayPretty isEqualToString:(NSString *)[keys objectAtIndex:section]]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
NSUInteger row;
|
||||
NSArray *recs = [recordings objectForKey:dayPretty];
|
||||
for (row = 0; row < [recs count]; ++row) {
|
||||
if ([filepath isEqualToString:(NSString *)[recs objectAtIndex:row]]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
NSUInteger indexes[] = {section, row};
|
||||
[self.tableView selectRowAtIndexPath:[NSIndexPath indexPathWithIndexes:indexes length:2] animated:TRUE scrollPosition:UITableViewScrollPositionNone];
|
||||
}
|
||||
|
||||
#pragma mark - Utilities
|
||||
|
||||
- (NSArray *)getSortedKeys {
|
||||
return [[recordings allKeys] sortedArrayUsingComparator:^NSComparisonResult(NSString *day2, NSString *day1){
|
||||
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
|
||||
[dateFormat setDateFormat:@"EEEE, MMM d, yyyy"];
|
||||
NSDate *date1 = [dateFormat dateFromString:day1];
|
||||
NSDate *date2 = [dateFormat dateFromString:day2];
|
||||
return [date1 compare:date2];
|
||||
}];
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
35
Classes/RecordingsListView.h
Normal file
35
Classes/RecordingsListView.h
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
//
|
||||
// RecordingsListView.h
|
||||
// linphone
|
||||
//
|
||||
// Created by benjamin_verdier on 25/07/2018.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import "UICompositeView.h"
|
||||
#import "RecordingsListTableView.h"
|
||||
#import "UIIconButton.h"
|
||||
|
||||
typedef enum _RecordingSelectionMode { RecordingSelectionModeNone, RecordingSelectionModeEdit } RecordingSelectionMode;
|
||||
|
||||
@interface RecordingSelection : NSObject <UISearchBarDelegate> {
|
||||
}
|
||||
|
||||
+ (void)setSelectionMode:(RecordingSelectionMode)selectionMode;
|
||||
+ (RecordingSelectionMode)getSelectionMode;
|
||||
|
||||
@end
|
||||
|
||||
@interface RecordingsListView : UIViewController <UICompositeViewDelegate>
|
||||
|
||||
@property(strong, nonatomic) IBOutlet RecordingsListTableView *tableController;
|
||||
@property(strong, nonatomic) IBOutlet UIView *topBar;
|
||||
@property(weak, nonatomic) IBOutlet UIIconButton *deleteButton;
|
||||
@property (strong, nonatomic) IBOutlet UIIconButton *backButton;
|
||||
|
||||
- (IBAction)onDeleteClick:(id)sender;
|
||||
- (IBAction)onEditionChangeClick:(id)sender;
|
||||
- (IBAction)onBackPressed:(id)sender;
|
||||
|
||||
@end
|
||||
101
Classes/RecordingsListView.m
Normal file
101
Classes/RecordingsListView.m
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
//
|
||||
// RecordingsListView.m
|
||||
// linphone
|
||||
//
|
||||
// Created by benjamin_verdier on 25/07/2018.
|
||||
//
|
||||
|
||||
#import "RecordingsListView.h"
|
||||
#import "PhoneMainView.h"
|
||||
|
||||
@implementation RecordingSelection
|
||||
|
||||
static RecordingSelectionMode sSelectionMode = RecordingSelectionModeNone;
|
||||
|
||||
+ (void)setSelectionMode:(RecordingSelectionMode)selectionMode {
|
||||
sSelectionMode = selectionMode;
|
||||
}
|
||||
|
||||
+ (RecordingSelectionMode)getSelectionMode {
|
||||
return sSelectionMode;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation RecordingsListView
|
||||
|
||||
@synthesize tableController;
|
||||
@synthesize topBar;
|
||||
|
||||
#pragma mark - UICompositeViewDelegate Functions
|
||||
|
||||
static UICompositeViewDescription *compositeDescription = nil;
|
||||
|
||||
+ (UICompositeViewDescription *)compositeViewDescription {
|
||||
if (compositeDescription == nil) {
|
||||
compositeDescription = [[UICompositeViewDescription alloc] init:self.class
|
||||
statusBar:StatusBarView.class
|
||||
tabBar:TabBarView.class
|
||||
sideMenu:SideMenuView.class
|
||||
fullscreen:false
|
||||
isLeftFragment:YES
|
||||
fragmentWith:ContactDetailsView.class];
|
||||
}
|
||||
return compositeDescription;
|
||||
}
|
||||
|
||||
- (UICompositeViewDescription *)compositeViewDescription {
|
||||
return self.class.compositeViewDescription;
|
||||
}
|
||||
|
||||
#pragma mark - ViewController Functions
|
||||
|
||||
- (void)viewDidLoad {
|
||||
[super viewDidLoad];
|
||||
tableController.tableView.accessibilityIdentifier = @"Recordings table";
|
||||
tableController.tableView.tableFooterView = [[UIView alloc] init];
|
||||
}
|
||||
|
||||
- (void)viewWillAppear:(BOOL)animated {
|
||||
[super viewWillAppear:animated];
|
||||
if (tableController.isEditing) {
|
||||
tableController.editing = NO;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)viewDidAppear:(BOOL)animated {
|
||||
[super viewDidAppear:animated];
|
||||
}
|
||||
|
||||
- (void) viewWillDisappear:(BOOL)animated {
|
||||
self.view = NULL;
|
||||
[self.tableController removeAllRecordings];
|
||||
}
|
||||
|
||||
#pragma mark - Action Functions
|
||||
|
||||
- (IBAction)onDeleteClick:(id)sender {
|
||||
NSString *msg = [NSString stringWithFormat:NSLocalizedString(@"Do you want to delete selected recordings?", nil)];
|
||||
[LinphoneManager.instance setContactsUpdated:TRUE];
|
||||
[UIConfirmationDialog ShowWithMessage:msg
|
||||
cancelMessage:nil
|
||||
confirmMessage:nil
|
||||
onCancelClick:^() {
|
||||
[self onEditionChangeClick:nil];
|
||||
}
|
||||
onConfirmationClick:^() {
|
||||
[tableController removeSelectionUsing:nil];
|
||||
[tableController loadData];
|
||||
[self onEditionChangeClick:nil];
|
||||
}];
|
||||
}
|
||||
|
||||
- (IBAction)onEditionChangeClick:(id)sender {
|
||||
_backButton.hidden = self.tableController.isEditing;
|
||||
}
|
||||
|
||||
- (IBAction)onBackPressed:(id)sender {
|
||||
[PhoneMainView.instance popCurrentView];
|
||||
}
|
||||
|
||||
@end
|
||||
161
Classes/RecordingsListView.xib
Normal file
161
Classes/RecordingsListView.xib
Normal file
|
|
@ -0,0 +1,161 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14113" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
|
||||
<device id="retina4_7" orientation="portrait">
|
||||
<adaptation id="fullscreen"/>
|
||||
</device>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14088"/>
|
||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="RecordingsListView">
|
||||
<connections>
|
||||
<outlet property="backButton" destination="rAc-tI-AVp" id="CVb-Cy-yWP"/>
|
||||
<outlet property="deleteButton" destination="zDs-pW-vyA" id="mye-fK-RaT"/>
|
||||
<outlet property="tableController" destination="1pR-qo-CIP" id="FD0-NI-8ox"/>
|
||||
<outlet property="topBar" destination="See-Aw-LPP" id="daF-pK-NHy"/>
|
||||
<outlet property="view" destination="i5M-Pr-FkT" id="sfx-zR-JGt"/>
|
||||
</connections>
|
||||
</placeholder>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||
<view clearsContextBeforeDrawing="NO" contentMode="scaleToFill" id="i5M-Pr-FkT">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="See-Aw-LPP" userLabel="topBar">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="66"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<subviews>
|
||||
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="color_F.png" translatesAutoresizingMaskIntoConstraints="NO" id="7wu-Ow-YYU" userLabel="backgroundColor">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="66"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
|
||||
</imageView>
|
||||
<button hidden="YES" opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="CqG-tB-maQ" userLabel="cancelButton" customClass="UIIconButton">
|
||||
<rect key="frame" x="0.0" y="0.0" width="75" height="66"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
|
||||
<accessibility key="accessibilityConfiguration" label="Delete all"/>
|
||||
<state key="normal" image="cancel_edit_default.png">
|
||||
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</state>
|
||||
<state key="disabled" image="cancel_edit_disabled.png"/>
|
||||
<state key="highlighted" backgroundImage="color_E.png"/>
|
||||
<connections>
|
||||
<action selector="onCancelClick:" destination="1pR-qo-CIP" eventType="touchUpInside" id="qcZ-s6-jgK"/>
|
||||
<action selector="onEditionChangeClick:" destination="-1" eventType="touchUpInside" id="vly-0H-4W2"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button hidden="YES" opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="zDs-pW-vyA" userLabel="deleteButton" customClass="UIIconButton">
|
||||
<rect key="frame" x="300" y="0.0" width="75" height="66"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
|
||||
<accessibility key="accessibilityConfiguration" label="Delete all"/>
|
||||
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
|
||||
<state key="normal" image="delete_default.png">
|
||||
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</state>
|
||||
<state key="disabled" image="delete_disabled.png"/>
|
||||
<state key="highlighted" backgroundImage="color_E.png"/>
|
||||
<connections>
|
||||
<action selector="onDeleteClick:" destination="-1" eventType="touchUpInside" id="8LI-ry-dTU"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="CWx-9g-0JG" userLabel="editButton" customClass="UIIconButton">
|
||||
<rect key="frame" x="300" y="0.0" width="75" height="66"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
|
||||
<accessibility key="accessibilityConfiguration" label="Edit"/>
|
||||
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
|
||||
<state key="normal" image="edit_list_default.png">
|
||||
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</state>
|
||||
<state key="disabled" image="edit_list_disabled.png"/>
|
||||
<state key="highlighted" backgroundImage="color_E.png"/>
|
||||
<connections>
|
||||
<action selector="onEditClick:" destination="1pR-qo-CIP" eventType="touchUpInside" id="0LH-n9-p0c"/>
|
||||
<action selector="onEditionChangeClick:" destination="-1" eventType="touchUpInside" id="IeY-Yd-XP2"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button hidden="YES" opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="16S-9G-2cb" userLabel="toggleSelectionButton" customClass="UIIconButton">
|
||||
<rect key="frame" x="225" y="0.0" width="75" height="66"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
|
||||
<accessibility key="accessibilityConfiguration" label="Select all"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
|
||||
<state key="normal" image="deselect_all.png">
|
||||
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</state>
|
||||
<state key="disabled" image="select_all_disabled.png"/>
|
||||
<state key="selected" image="select_all_default.png"/>
|
||||
<state key="highlighted" backgroundImage="color_E.png"/>
|
||||
<connections>
|
||||
<action selector="onSelectionToggle:" destination="1pR-qo-CIP" eventType="touchUpInside" id="Hfi-f6-qfI"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button opaque="NO" tag="4" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="rAc-tI-AVp" userLabel="backButton" customClass="UIIconButton">
|
||||
<rect key="frame" x="0.0" y="0.0" width="75" height="66"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
|
||||
<accessibility key="accessibilityConfiguration" label="Back"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||
<inset key="titleEdgeInsets" minX="0.0" minY="18" maxX="0.0" maxY="0.0"/>
|
||||
<state key="normal" image="back_default.png">
|
||||
<color key="titleColor" red="0.28619974850000002" green="0.3214434981" blue="0.3598001301" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</state>
|
||||
<state key="disabled" image="back_disabled.png"/>
|
||||
<state key="highlighted" backgroundImage="color_E.png"/>
|
||||
<connections>
|
||||
<action selector="onBackPressed:" destination="-1" eventType="touchUpInside" id="Quz-zf-q3K"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
</view>
|
||||
<tableView clipsSubviews="YES" contentMode="scaleToFill" fixedFrame="YES" alwaysBounceVertical="YES" style="plain" separatorStyle="default" allowsSelectionDuringEditing="YES" allowsMultipleSelectionDuringEditing="YES" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="28" sectionFooterHeight="28" translatesAutoresizingMaskIntoConstraints="NO" id="3b0-Nd-4r0">
|
||||
<rect key="frame" x="0.0" y="74" width="375" height="593"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<connections>
|
||||
<outlet property="dataSource" destination="1pR-qo-CIP" id="z2V-Yd-AwQ"/>
|
||||
<outlet property="delegate" destination="1pR-qo-CIP" id="eJQ-AV-7ts"/>
|
||||
</connections>
|
||||
</tableView>
|
||||
<label hidden="YES" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="No recording found" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="3" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="zXd-Ic-rwm" userLabel="emptyTableLabel">
|
||||
<rect key="frame" x="0.0" y="74" width="375" height="593"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES" flexibleMaxY="YES"/>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<viewLayoutGuide key="safeArea" id="Q5M-cg-NOt"/>
|
||||
<point key="canvasLocation" x="25.5" y="51.5"/>
|
||||
</view>
|
||||
<tableViewController id="1pR-qo-CIP" customClass="RecordingsListTableView">
|
||||
<connections>
|
||||
<outlet property="cancelButton" destination="CqG-tB-maQ" id="C90-0S-5WL"/>
|
||||
<outlet property="deleteButton" destination="zDs-pW-vyA" id="mgV-PB-law"/>
|
||||
<outlet property="editButton" destination="CWx-9g-0JG" id="hAA-6f-kX8"/>
|
||||
<outlet property="emptyView" destination="zXd-Ic-rwm" id="D4k-nO-LKW"/>
|
||||
<outlet property="toggleSelectionButton" destination="16S-9G-2cb" id="6pj-Yn-hy1"/>
|
||||
<outlet property="view" destination="3b0-Nd-4r0" id="ng8-q5-bwm"/>
|
||||
</connections>
|
||||
<point key="canvasLocation" x="478" y="52"/>
|
||||
</tableViewController>
|
||||
</objects>
|
||||
<resources>
|
||||
<image name="back_default.png" width="24" height="22"/>
|
||||
<image name="back_disabled.png" width="24" height="22"/>
|
||||
<image name="cancel_edit_default.png" width="29" height="29"/>
|
||||
<image name="cancel_edit_disabled.png" width="29" height="29"/>
|
||||
<image name="color_E.png" width="2" height="2"/>
|
||||
<image name="color_F.png" width="2" height="2"/>
|
||||
<image name="delete_default.png" width="21" height="28"/>
|
||||
<image name="delete_disabled.png" width="21" height="28"/>
|
||||
<image name="deselect_all.png" width="27" height="27"/>
|
||||
<image name="edit_list_default.png" width="30" height="28"/>
|
||||
<image name="edit_list_disabled.png" width="30" height="28"/>
|
||||
<image name="select_all_default.png" width="27" height="27"/>
|
||||
<image name="select_all_disabled.png" width="27" height="27"/>
|
||||
</resources>
|
||||
</document>
|
||||
|
|
@ -15,6 +15,7 @@
|
|||
#import "StatusBarView.h"
|
||||
#import "ShopView.h"
|
||||
#import "LinphoneManager.h"
|
||||
#import "RecordingsListView.h"
|
||||
|
||||
@implementation SideMenuEntry
|
||||
|
||||
|
|
@ -60,6 +61,12 @@
|
|||
}]];
|
||||
}
|
||||
|
||||
[_sideMenuEntries
|
||||
addObject:[[SideMenuEntry alloc] initWithTitle:NSLocalizedString(@"Recordings", nil)
|
||||
tapBlock:^() {
|
||||
[PhoneMainView.instance
|
||||
changeCurrentView:RecordingsListView.compositeViewDescription];
|
||||
}]];
|
||||
[_sideMenuEntries
|
||||
addObject:[[SideMenuEntry alloc] initWithTitle:NSLocalizedString(@"Settings", nil)
|
||||
tapBlock:^() {
|
||||
|
|
|
|||
|
|
@ -51,6 +51,9 @@ typedef enum {
|
|||
|
||||
+ (NSMutableDictionary <NSString *, PHAsset *> *)photoAssetsDictionary;
|
||||
|
||||
+ (NSString *)recordingFilePathFromCall:(const LinphoneAddress *)iaddr;
|
||||
+ (NSArray *)parseRecordingName:(NSString *)filename;
|
||||
|
||||
@end
|
||||
|
||||
@interface NSNumber (HumanReadableSize)
|
||||
|
|
@ -59,6 +62,12 @@ typedef enum {
|
|||
|
||||
@end
|
||||
|
||||
@interface UIImage (systemIcons)
|
||||
|
||||
+ (UIImage *)imageFromSystemBarButton:(UIBarButtonSystemItem)systemItem :(UIColor *) color;
|
||||
|
||||
@end
|
||||
|
||||
@interface NSString (linphoneExt)
|
||||
|
||||
- (NSString *)md5;
|
||||
|
|
|
|||
|
|
@ -510,6 +510,44 @@
|
|||
return addr;
|
||||
}
|
||||
|
||||
+ (NSString *)recordingFilePathFromCall:(const LinphoneAddress *)iaddr {
|
||||
NSString *filepath = @"recording_";
|
||||
const char *address = linphone_address_get_username(iaddr);
|
||||
filepath = [filepath stringByAppendingString:[NSString stringWithCString:address encoding:NSUTF8StringEncoding]];
|
||||
NSDate * now = [NSDate date];
|
||||
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
|
||||
[dateFormat setDateFormat:@"E-d-MMM-yyyy-HH-mm-ss"];
|
||||
NSString *date = [dateFormat stringFromDate:now];
|
||||
|
||||
filepath = [filepath stringByAppendingString:@"_"];
|
||||
filepath = [filepath stringByAppendingString:date];
|
||||
filepath = [filepath stringByAppendingString:@".mkv"];
|
||||
|
||||
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
|
||||
NSString *writablePath = [paths objectAtIndex:0];
|
||||
writablePath = [writablePath stringByAppendingString:@"/"];
|
||||
writablePath = [writablePath stringByAppendingString:filepath];
|
||||
LOGD(@"file path is: %@\n", writablePath);
|
||||
return writablePath;
|
||||
//file name is recording_contact-name_dayName-day-monthName-year-hour-minutes-seconds
|
||||
//The recording prefix is used to identify recordings in the cache directory.
|
||||
//We will use name_dayName-day-monthName-year to separate recordings by days, then hour-minutes-seconds to order them in each day.
|
||||
}
|
||||
|
||||
+ (NSArray *)parseRecordingName:(NSString *)filename {
|
||||
NSString *rec = @"recording_"; //key that helps find recordings
|
||||
NSString *subName = [filename substringFromIndex:[filename rangeOfString:rec].location]; //We remove the parent folders if they exist in the filename
|
||||
NSArray *splitString = [subName componentsSeparatedByString:@"_"];
|
||||
//splitString: first element is the 'recording' prefix, last element is the date with the "E-d-MMM-yyyy-HH-mm-ss" format.
|
||||
NSString *name = [[splitString subarrayWithRange:NSMakeRange(1, [splitString count] -2)] componentsJoinedByString:@""];
|
||||
NSDateFormatter *format = [[NSDateFormatter alloc] init];
|
||||
[format setDateFormat:@"E-d-MMM-yyyy-HH-mm-ss"];
|
||||
NSString *dateWithMkv = [splitString objectAtIndex:[splitString count]-1]; //this will be in the form "E-d-MMM-yyyy-HH-mm-ss.mkv", we have to delete the extension
|
||||
NSDate *date = [format dateFromString:[dateWithMkv substringToIndex:[dateWithMkv length] - 4]];
|
||||
NSArray *res = [NSArray arrayWithObjects:name, date, nil];
|
||||
return res;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation NSNumber (HumanReadableSize)
|
||||
|
|
@ -531,6 +569,29 @@
|
|||
|
||||
@end
|
||||
|
||||
@implementation UIImage (systemIcons)
|
||||
|
||||
+ (UIImage *)imageFromSystemBarButton:(UIBarButtonSystemItem)systemItem :(UIColor *) color {
|
||||
// thanks to Renetik https://stackoverflow.com/a/49822488
|
||||
UIToolbar *bar = UIToolbar.new;
|
||||
UIBarButtonItem *buttonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:systemItem target:nil action:nil];
|
||||
[bar setItems:@[buttonItem] animated:NO];
|
||||
[bar snapshotViewAfterScreenUpdates:YES];
|
||||
for (UIView *view in [(id) buttonItem view].subviews)
|
||||
if ([view isKindOfClass:UIButton.class]) {
|
||||
UIImage *image = [((UIButton *) view).imageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
|
||||
UIGraphicsBeginImageContextWithOptions(image.size, NO, image.scale);
|
||||
//[color set];
|
||||
[image drawInRect:CGRectMake(0, 0, image.size.width, image.size.height)];
|
||||
image = UIGraphicsGetImageFromCurrentImageContext();
|
||||
UIGraphicsEndImageContext();
|
||||
return image;
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation NSString (md5)
|
||||
|
||||
- (NSString *)md5 {
|
||||
|
|
|
|||
BIN
Resources/images/rec_off_default.png
Normal file
BIN
Resources/images/rec_off_default.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 597 B |
BIN
Resources/images/rec_off_default@2x.png
Normal file
BIN
Resources/images/rec_off_default@2x.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
BIN
Resources/images/rec_on_default.png
Normal file
BIN
Resources/images/rec_on_default.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 689 B |
BIN
Resources/images/rec_on_default@2x.png
Normal file
BIN
Resources/images/rec_on_default@2x.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.2 KiB |
|
|
@ -743,6 +743,17 @@
|
|||
C90FAA7915AF54E6002091CB /* HistoryDetailsView.m in Sources */ = {isa = PBXBuildFile; fileRef = C90FAA7715AF54E6002091CB /* HistoryDetailsView.m */; };
|
||||
CF15F21E20E4F9A3008B1DE6 /* UIImageViewDeletable.m in Sources */ = {isa = PBXBuildFile; fileRef = CF15F21C20E4F9A3008B1DE6 /* UIImageViewDeletable.m */; };
|
||||
CF15F21F20E4F9A3008B1DE6 /* UIImageViewDeletable.xib in Resources */ = {isa = PBXBuildFile; fileRef = CF15F21D20E4F9A3008B1DE6 /* UIImageViewDeletable.xib */; };
|
||||
CF1DE92D210A0F5D00A0A97E /* UILinphoneAudioPlayer.m in Sources */ = {isa = PBXBuildFile; fileRef = CF1DE924210A0F5A00A0A97E /* UILinphoneAudioPlayer.m */; };
|
||||
CF1DE92E210A0F5D00A0A97E /* UILinphoneAudioPlayer.xib in Resources */ = {isa = PBXBuildFile; fileRef = CF1DE92B210A0F5B00A0A97E /* UILinphoneAudioPlayer.xib */; };
|
||||
CF7602D7210867E800749F76 /* RecordingsListView.m in Sources */ = {isa = PBXBuildFile; fileRef = CF7602D5210867E800749F76 /* RecordingsListView.m */; };
|
||||
CF7602D8210867E800749F76 /* RecordingsListView.xib in Resources */ = {isa = PBXBuildFile; fileRef = CF7602D6210867E800749F76 /* RecordingsListView.xib */; };
|
||||
CF7602E221086EB200749F76 /* RecordingsListTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = CF7602E021086EB200749F76 /* RecordingsListTableView.m */; };
|
||||
CF7602E72108759A00749F76 /* UIRecordingCell.m in Sources */ = {isa = PBXBuildFile; fileRef = CF7602E52108759A00749F76 /* UIRecordingCell.m */; };
|
||||
CF7602E82108759A00749F76 /* UIRecordingCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = CF7602E62108759A00749F76 /* UIRecordingCell.xib */; };
|
||||
CF7602F5210898CC00749F76 /* rec_off_default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = CF7602EB210898C100749F76 /* rec_off_default@2x.png */; };
|
||||
CF7602F6210898CC00749F76 /* rec_on_default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = CF7602F2210898C400749F76 /* rec_on_default@2x.png */; };
|
||||
CF7602F7210898CC00749F76 /* rec_off_default.png in Resources */ = {isa = PBXBuildFile; fileRef = CF7602F3210898C600749F76 /* rec_off_default.png */; };
|
||||
CF7602F8210898CC00749F76 /* rec_on_default.png in Resources */ = {isa = PBXBuildFile; fileRef = CF7602F4210898C800749F76 /* rec_on_default.png */; };
|
||||
CFBD7A2A20E504AE007C5286 /* delete_img.png in Resources */ = {isa = PBXBuildFile; fileRef = CFBD7A2320E504AD007C5286 /* delete_img.png */; };
|
||||
D306459E1611EC2A00BB571E /* UILoadingImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = D306459D1611EC2900BB571E /* UILoadingImageView.m */; };
|
||||
D3128FE115AABC7E00A2147A /* ContactDetailsView.m in Sources */ = {isa = PBXBuildFile; fileRef = D3128FDF15AABC7E00A2147A /* ContactDetailsView.m */; };
|
||||
|
|
@ -1763,7 +1774,6 @@
|
|||
8C5BCECC1EB3859200A9AAEF /* mswebrtc.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = mswebrtc.framework; path = "liblinphone-sdk/apple-darwin/Frameworks/mswebrtc.framework"; sourceTree = "<group>"; };
|
||||
8C5BCECD1EB3859200A9AAEF /* ortp.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ortp.framework; path = "liblinphone-sdk/apple-darwin/Frameworks/ortp.framework"; sourceTree = "<group>"; };
|
||||
8C5D1B991D9BC48100DC6539 /* UIShopTableCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIShopTableCell.h; sourceTree = "<group>"; };
|
||||
8C5D1B9A1D9BC48100DC6539 /* UIShopTableCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIShopTableCell.m; sourceTree = "<group>"; };
|
||||
8C5D1B9B1D9BC48100DC6539 /* UIShopTableCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = UIShopTableCell.xib; sourceTree = "<group>"; };
|
||||
8C601FD220B462B0004FF95C /* mediastreamer2.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = mediastreamer2.framework; path = "liblinphone-sdk/apple-darwin/Frameworks/mediastreamer2.framework"; sourceTree = "<group>"; };
|
||||
8C73477B1D9BA3A00022EE8C /* UserNotifications.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UserNotifications.framework; path = System/Library/Frameworks/UserNotifications.framework; sourceTree = SDKROOT; };
|
||||
|
|
@ -1862,6 +1872,21 @@
|
|||
CF15F21B20E4F9A3008B1DE6 /* UIImageViewDeletable.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = UIImageViewDeletable.h; sourceTree = "<group>"; };
|
||||
CF15F21C20E4F9A3008B1DE6 /* UIImageViewDeletable.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = UIImageViewDeletable.m; sourceTree = "<group>"; };
|
||||
CF15F21D20E4F9A3008B1DE6 /* UIImageViewDeletable.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = UIImageViewDeletable.xib; sourceTree = "<group>"; };
|
||||
CF1DE924210A0F5A00A0A97E /* UILinphoneAudioPlayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UILinphoneAudioPlayer.m; sourceTree = "<group>"; };
|
||||
CF1DE92B210A0F5B00A0A97E /* UILinphoneAudioPlayer.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = UILinphoneAudioPlayer.xib; sourceTree = "<group>"; };
|
||||
CF1DE92C210A0F5C00A0A97E /* UILinphoneAudioPlayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UILinphoneAudioPlayer.h; sourceTree = "<group>"; };
|
||||
CF7602D4210867E800749F76 /* RecordingsListView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RecordingsListView.h; sourceTree = "<group>"; };
|
||||
CF7602D5210867E800749F76 /* RecordingsListView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RecordingsListView.m; sourceTree = "<group>"; };
|
||||
CF7602D6210867E800749F76 /* RecordingsListView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = RecordingsListView.xib; sourceTree = "<group>"; };
|
||||
CF7602DF21086EB100749F76 /* RecordingsListTableView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RecordingsListTableView.h; sourceTree = "<group>"; };
|
||||
CF7602E021086EB200749F76 /* RecordingsListTableView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RecordingsListTableView.m; sourceTree = "<group>"; };
|
||||
CF7602E42108759A00749F76 /* UIRecordingCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = UIRecordingCell.h; sourceTree = "<group>"; };
|
||||
CF7602E52108759A00749F76 /* UIRecordingCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = UIRecordingCell.m; sourceTree = "<group>"; };
|
||||
CF7602E62108759A00749F76 /* UIRecordingCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = UIRecordingCell.xib; sourceTree = "<group>"; };
|
||||
CF7602EB210898C100749F76 /* rec_off_default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "rec_off_default@2x.png"; sourceTree = "<group>"; };
|
||||
CF7602F2210898C400749F76 /* rec_on_default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "rec_on_default@2x.png"; sourceTree = "<group>"; };
|
||||
CF7602F3210898C600749F76 /* rec_off_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = rec_off_default.png; sourceTree = "<group>"; };
|
||||
CF7602F4210898C800749F76 /* rec_on_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = rec_on_default.png; sourceTree = "<group>"; };
|
||||
CFBD7A2320E504AD007C5286 /* delete_img.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = delete_img.png; sourceTree = "<group>"; };
|
||||
D306459C1611EC2900BB571E /* UILoadingImageView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UILoadingImageView.h; sourceTree = "<group>"; };
|
||||
D306459D1611EC2900BB571E /* UILoadingImageView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UILoadingImageView.m; sourceTree = "<group>"; };
|
||||
|
|
@ -2214,12 +2239,6 @@
|
|||
D3F83EEA1582021700336684 /* CallView.m */,
|
||||
D381881C15FE3FCA00C3EDCA /* CallView.xib */,
|
||||
638F1A861C2167C2004B8E02 /* CallView~ipad.xib */,
|
||||
8CA70ACF1F9E0ABA00A3D2EB /* ChatConversationInfoView.h */,
|
||||
8CA70AD01F9E0AE100A3D2EB /* ChatConversationInfoView.m */,
|
||||
8CBD7BA220B6B7FD00E5DCC0 /* ChatConversationInfoView.xib */,
|
||||
8CD99A3D2090BA24008A7CDA /* ChatConversationImdnView.h */,
|
||||
8CD99A3B2090B9FA008A7CDA /* ChatConversationImdnView.m */,
|
||||
8CBD7BA520B6B80D00E5DCC0 /* ChatConversationImdnView.xib */,
|
||||
8C9C5E0B1F83B2EF006987FA /* ChatConversationCreateCollectionViewController.h */,
|
||||
8C9C5E0C1F83B2EF006987FA /* ChatConversationCreateCollectionViewController.m */,
|
||||
6341807A1BBC103100F71761 /* ChatConversationCreateTableView.h */,
|
||||
|
|
@ -2227,6 +2246,12 @@
|
|||
6336715E1BCBAAD200BFCBDE /* ChatConversationCreateView.h */,
|
||||
6336715F1BCBAAD200BFCBDE /* ChatConversationCreateView.m */,
|
||||
63B8D68E1BCBE65600C12B09 /* ChatConversationCreateView.xib */,
|
||||
8CD99A3D2090BA24008A7CDA /* ChatConversationImdnView.h */,
|
||||
8CD99A3B2090B9FA008A7CDA /* ChatConversationImdnView.m */,
|
||||
8CBD7BA520B6B80D00E5DCC0 /* ChatConversationImdnView.xib */,
|
||||
8CA70ACF1F9E0ABA00A3D2EB /* ChatConversationInfoView.h */,
|
||||
8CA70AD01F9E0AE100A3D2EB /* ChatConversationInfoView.m */,
|
||||
8CBD7BA220B6B7FD00E5DCC0 /* ChatConversationInfoView.xib */,
|
||||
D32B6E2715A5BC430033019F /* ChatConversationTableView.h */,
|
||||
D32B6E2815A5BC430033019F /* ChatConversationTableView.m */,
|
||||
D3F795D315A582800077328B /* ChatConversationView.h */,
|
||||
|
|
@ -2247,9 +2272,9 @@
|
|||
D35497FB15875372000081D8 /* ContactsListView.h */,
|
||||
D35497FC15875372000081D8 /* ContactsListView.m */,
|
||||
D38187C015FE342800C3EDCA /* ContactsListView.xib */,
|
||||
631098501D4660630041F2B3 /* CountryListView.xib */,
|
||||
631098471D4660580041F2B3 /* CountryListView.h */,
|
||||
631098481D4660580041F2B3 /* CountryListView.m */,
|
||||
631098501D4660630041F2B3 /* CountryListView.xib */,
|
||||
22F2508B107141E100AC9B3F /* DialerView.h */,
|
||||
22F2508C107141E100AC9B3F /* DialerView.m */,
|
||||
D38187C415FE345B00C3EDCA /* DialerView.xib */,
|
||||
|
|
@ -2277,8 +2302,6 @@
|
|||
63E27A311C4FECD000D332AE /* LaunchScreen.xib */,
|
||||
1D3623240D0F684500981E51 /* LinphoneAppDelegate.h */,
|
||||
1D3623250D0F684500981E51 /* LinphoneAppDelegate.m */,
|
||||
8C2595D51DEDC8E1007A6424 /* ProviderDelegate.h */,
|
||||
8C2595DC1DEDC92D007A6424 /* ProviderDelegate.m */,
|
||||
D37DC6BF1594AE1800B2A5EB /* LinphoneCoreSettingsStore.h */,
|
||||
D37DC6C01594AE1800B2A5EB /* LinphoneCoreSettingsStore.m */,
|
||||
D3EA53FB159850E80037DC6B /* LinphoneManager.h */,
|
||||
|
|
@ -2288,6 +2311,13 @@
|
|||
D3F83F8C158229C500336684 /* PhoneMainView.h */,
|
||||
D3F83F8D15822ABD00336684 /* PhoneMainView.m */,
|
||||
639E9CB31C0DB88200019A75 /* PhoneMainView.xib */,
|
||||
8C2595D51DEDC8E1007A6424 /* ProviderDelegate.h */,
|
||||
8C2595DC1DEDC92D007A6424 /* ProviderDelegate.m */,
|
||||
CF7602DF21086EB100749F76 /* RecordingsListTableView.h */,
|
||||
CF7602E021086EB200749F76 /* RecordingsListTableView.m */,
|
||||
CF7602D4210867E800749F76 /* RecordingsListView.h */,
|
||||
CF7602D5210867E800749F76 /* RecordingsListView.m */,
|
||||
CF7602D6210867E800749F76 /* RecordingsListView.xib */,
|
||||
D35E759C159460B50066B1C1 /* SettingsView.h */,
|
||||
D35E759D159460B50066B1C1 /* SettingsView.m */,
|
||||
636316D61A1DEC650009B839 /* SettingsView.xib */,
|
||||
|
|
@ -2333,9 +2363,6 @@
|
|||
2214EB7012F84668002A5394 /* LinphoneUI */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
CF15F21B20E4F9A3008B1DE6 /* UIImageViewDeletable.h */,
|
||||
CF15F21C20E4F9A3008B1DE6 /* UIImageViewDeletable.m */,
|
||||
CF15F21D20E4F9A3008B1DE6 /* UIImageViewDeletable.xib */,
|
||||
63F1DF421BCE618E00EDED90 /* UIAddressTextField.h */,
|
||||
63F1DF431BCE618E00EDED90 /* UIAddressTextField.m */,
|
||||
63C441C11BBC23ED0053DC5E /* UIAssistantTextField.h */,
|
||||
|
|
@ -2364,27 +2391,24 @@
|
|||
D3A8BB6E15A6C7D500F96BE5 /* UIChatBubbleTextCell.h */,
|
||||
D3A8BB6F15A6C7D500F96BE5 /* UIChatBubbleTextCell.m */,
|
||||
639E9CA51C0DB7EA00019A75 /* UIChatBubbleTextCell.xib */,
|
||||
8C92ABF11FA773C20006FB5D /* UIChatNotifiedEventCell.h */,
|
||||
8C92ABF21FA773E50006FB5D /* UIChatNotifiedEventCell.m */,
|
||||
8C92ABE71FA773190006FB5D /* UIChatNotifiedEventCell.xib */,
|
||||
D3EA540F159853750037DC6B /* UIChatCell.h */,
|
||||
D3EA5410159853750037DC6B /* UIChatCell.m */,
|
||||
639CEB0B1A1DF4FA004DE38F /* UIChatCell.xib */,
|
||||
8CA70AE11F9E39E400A3D2EB /* UIChatConversationInfoTableViewCell.h */,
|
||||
8CA70AE21F9E39E400A3D2EB /* UIChatConversationInfoTableViewCell.m */,
|
||||
8CBD7BA820B6B82400E5DCC0 /* UIChatConversationInfoTableViewCell.xib */,
|
||||
8CD99A402090CE25008A7CDA /* UIChatConversationImdnTableViewCell.h */,
|
||||
8CD99A412090CE6F008A7CDA /* UIChatConversationImdnTableViewCell.m */,
|
||||
8CBD7BAB20B6B82A00E5DCC0 /* UIChatConversationImdnTableViewCell.xib */,
|
||||
8C9C5E0E1F83BD97006987FA /* UIChatCreateCollectionViewCell.h */,
|
||||
8C9C5E0F1F83BD97006987FA /* UIChatCreateCollectionViewCell.m */,
|
||||
8CBD7BAE20B6B82F00E5DCC0 /* UIChatCreateCollectionViewCell.xib */,
|
||||
8CA70AE11F9E39E400A3D2EB /* UIChatConversationInfoTableViewCell.h */,
|
||||
8CA70AE21F9E39E400A3D2EB /* UIChatConversationInfoTableViewCell.m */,
|
||||
8CBD7BA820B6B82400E5DCC0 /* UIChatConversationInfoTableViewCell.xib */,
|
||||
63B8D69F1BCBF43100C12B09 /* UIChatCreateCell.h */,
|
||||
63B8D6A01BCBF43100C12B09 /* UIChatCreateCell.m */,
|
||||
639E9CA81C0DB7F200019A75 /* UIChatCreateCell.xib */,
|
||||
8C5D1B991D9BC48100DC6539 /* UIShopTableCell.h */,
|
||||
8C5D1B9A1D9BC48100DC6539 /* UIShopTableCell.m */,
|
||||
8C5D1B9B1D9BC48100DC6539 /* UIShopTableCell.xib */,
|
||||
8C9C5E0E1F83BD97006987FA /* UIChatCreateCollectionViewCell.h */,
|
||||
8C9C5E0F1F83BD97006987FA /* UIChatCreateCollectionViewCell.m */,
|
||||
8CBD7BAE20B6B82F00E5DCC0 /* UIChatCreateCollectionViewCell.xib */,
|
||||
8C92ABF11FA773C20006FB5D /* UIChatNotifiedEventCell.h */,
|
||||
8C92ABF21FA773E50006FB5D /* UIChatNotifiedEventCell.m */,
|
||||
8C92ABE71FA773190006FB5D /* UIChatNotifiedEventCell.xib */,
|
||||
639E9C7E1C0DB13D00019A75 /* UICheckBoxTableView.h */,
|
||||
639E9C7F1C0DB13D00019A75 /* UICheckBoxTableView.m */,
|
||||
D31B4B1E159876C0002E6C72 /* UICompositeView.h */,
|
||||
|
|
@ -2397,9 +2421,6 @@
|
|||
D3A55FBA15877E5E003FD403 /* UIContactCell.h */,
|
||||
D3A55FBB15877E5E003FD403 /* UIContactCell.m */,
|
||||
F088488D19FF8C41007FFCF3 /* UIContactCell.xib */,
|
||||
24A345A71D95799900881A5C /* UIShopTableCell.h */,
|
||||
24A345A51D95798A00881A5C /* UIShopTableCell.m */,
|
||||
24A3459D1D95797700881A5C /* UIShopTableCell.xib */,
|
||||
D3C6526515AC1A8F0092A874 /* UIContactDetailsCell.h */,
|
||||
D3C6526615AC1A8F0092A874 /* UIContactDetailsCell.m */,
|
||||
639E9CAE1C0DB80300019A75 /* UIContactDetailsCell.xib */,
|
||||
|
|
@ -2412,18 +2433,31 @@
|
|||
639CEB021A1DF4E4004DE38F /* UIHistoryCell.xib */,
|
||||
636BC9951B5F921B00C754CE /* UIIconButton.h */,
|
||||
636BC9961B5F921B00C754CE /* UIIconButton.m */,
|
||||
CF15F21B20E4F9A3008B1DE6 /* UIImageViewDeletable.h */,
|
||||
CF15F21C20E4F9A3008B1DE6 /* UIImageViewDeletable.m */,
|
||||
CF15F21D20E4F9A3008B1DE6 /* UIImageViewDeletable.xib */,
|
||||
634610041B61330300548952 /* UILabel+Boldify.h */,
|
||||
634610051B61330300548952 /* UILabel+Boldify.m */,
|
||||
CF1DE92C210A0F5C00A0A97E /* UILinphoneAudioPlayer.h */,
|
||||
CF1DE924210A0F5A00A0A97E /* UILinphoneAudioPlayer.m */,
|
||||
CF1DE92B210A0F5B00A0A97E /* UILinphoneAudioPlayer.xib */,
|
||||
D306459C1611EC2900BB571E /* UILoadingImageView.h */,
|
||||
D306459D1611EC2900BB571E /* UILoadingImageView.m */,
|
||||
2214EBF112F86360002A5394 /* UIMutedMicroButton.h */,
|
||||
2214EBF212F86360002A5394 /* UIMutedMicroButton.m */,
|
||||
D36FB2D31589EF7C0036F6F2 /* UIPauseButton.h */,
|
||||
D36FB2D41589EF7C0036F6F2 /* UIPauseButton.m */,
|
||||
CF7602E42108759A00749F76 /* UIRecordingCell.h */,
|
||||
CF7602E52108759A00749F76 /* UIRecordingCell.m */,
|
||||
CF7602E62108759A00749F76 /* UIRecordingCell.xib */,
|
||||
6313482E1B6F7B6600C6BDCB /* UIRoundBorderedButton.h */,
|
||||
6313482F1B6F7B6600C6BDCB /* UIRoundBorderedButton.m */,
|
||||
63FB30331A680E73008CA393 /* UIRoundedImageView.h */,
|
||||
63FB30341A680E73008CA393 /* UIRoundedImageView.m */,
|
||||
8C5D1B991D9BC48100DC6539 /* UIShopTableCell.h */,
|
||||
24A345A51D95798A00881A5C /* UIShopTableCell.m */,
|
||||
8C5D1B9B1D9BC48100DC6539 /* UIShopTableCell.xib */,
|
||||
24A345A71D95799900881A5C /* UIShopTableCell.h */,
|
||||
22968A5D12F875C600588287 /* UISpeakerButton.h */,
|
||||
22968A5E12F875C600588287 /* UISpeakerButton.m */,
|
||||
630CF5551AF7CE1500539F7A /* UITextField+DoneButton.h */,
|
||||
|
|
@ -2434,6 +2468,8 @@
|
|||
D32648431588F6FB00930C67 /* UIToggleButton.m */,
|
||||
340751E5150F38FC00B89C47 /* UIVideoButton.h */,
|
||||
340751E6150F38FD00B89C47 /* UIVideoButton.m */,
|
||||
24A345A51D95798A00881A5C /* UIShopTableCell.m */,
|
||||
24A3459D1D95797700881A5C /* UIShopTableCell.xib */,
|
||||
);
|
||||
path = LinphoneUI;
|
||||
sourceTree = "<group>";
|
||||
|
|
@ -2694,41 +2730,7 @@
|
|||
633FEBE11D3CD5570014B822 /* images */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
CFBD7A2320E504AD007C5286 /* delete_img.png */,
|
||||
24BFAA9B209B062F004F47A7 /* callkit_logo.png */,
|
||||
24BFAA99209B062E004F47A7 /* contacts_sip_default.png */,
|
||||
24BFAA94209B062C004F47A7 /* contacts_sip_default@2x.png */,
|
||||
24BFAA97209B062E004F47A7 /* contacts_sip_selected.png */,
|
||||
24BFAA9C209B062F004F47A7 /* contacts_sip_selected@2x.png */,
|
||||
24BFAA8C209B062B004F47A7 /* dialer_background.png */,
|
||||
24BFAA98209B062E004F47A7 /* linphone_logo.png */,
|
||||
24BFAA9D209B0630004F47A7 /* linphone_logo@2x.png */,
|
||||
24BFAA93209B062C004F47A7 /* linphone_user.png */,
|
||||
24BFAA95209B062D004F47A7 /* linphone_user@2x.png */,
|
||||
24BFAA9A209B062F004F47A7 /* linphone_user~ipad.png */,
|
||||
24BFAA96209B062D004F47A7 /* linphone_user~ipad@2x.png */,
|
||||
8CF25D9B1F9F76BC00BEA0C1 /* chat_group_informations.png */,
|
||||
8CF25D9C1F9F76BD00BEA0C1 /* chat_group_informations@2x.png */,
|
||||
8CF25D941F9F336100BEA0C1 /* check_unselected.png */,
|
||||
8CF25D8B1F9F336000BEA0C1 /* check_unselected@2x.png */,
|
||||
8CA70AD31F9E285B00A3D2EB /* chat_group_add.png */,
|
||||
8CA70AD21F9E285B00A3D2EB /* chat_group_add@2x.png */,
|
||||
8C2A81941F87B8000012A66B /* chat_group_avatar.png */,
|
||||
8C2A81931F87B7FF0012A66B /* chat_group_avatar@2x.png */,
|
||||
8CB2B8F61F86229B0015CEE2 /* chat_secure.png */,
|
||||
8CB2B8F71F86229C0015CEE2 /* next_disabled.png */,
|
||||
8CB2B8F81F86229D0015CEE2 /* next_disabled@2x.png */,
|
||||
8CDC61961F84D9270087CF7F /* check_selected@2x.png */,
|
||||
8CDC618C1F84D89B0087CF7F /* check_selected.png */,
|
||||
8CE24F551F8268840077AC0A /* conference_delete.png */,
|
||||
8CE24F561F8268840077AC0A /* conference_delete@2x.png */,
|
||||
8CE24F491F8234A20077AC0A /* next_default.png */,
|
||||
8CE24F4A1F8234A30077AC0A /* next_default@2x.png */,
|
||||
8C300D981E40E0CC00728EF3 /* lime_ko.png */,
|
||||
8C300D991E40E0CC00728EF3 /* lime_ko@2x.png */,
|
||||
8CD99A1B20908C27008A7CDA /* callkit_logo@2x.png */,
|
||||
633FEBE21D3CD5570014B822 /* add_field_default.png */,
|
||||
244523BC1E8D3A6C0037A187 /* chat_unsecure.png */,
|
||||
633FEBE31D3CD5570014B822 /* add_field_default@2x.png */,
|
||||
633FEBE41D3CD5570014B822 /* add_field_over.png */,
|
||||
633FEBE51D3CD5570014B822 /* add_field_over@2x.png */,
|
||||
|
|
@ -2781,9 +2783,6 @@
|
|||
633FEC141D3CD5570014B822 /* call_quality_indicator_1.png */,
|
||||
633FEC151D3CD5570014B822 /* call_quality_indicator_1@2x.png */,
|
||||
633FEC161D3CD5570014B822 /* call_quality_indicator_2.png */,
|
||||
244523AC1E8266CC0037A187 /* chat_delivered.png */,
|
||||
244523AD1E8266CC0037A187 /* chat_error.png */,
|
||||
244523AE1E8266CC0037A187 /* chat_read.png */,
|
||||
633FEC171D3CD5570014B822 /* call_quality_indicator_2@2x.png */,
|
||||
633FEC181D3CD5570014B822 /* call_quality_indicator_3.png */,
|
||||
633FEC191D3CD5570014B822 /* call_quality_indicator_3@2x.png */,
|
||||
|
|
@ -2821,6 +2820,8 @@
|
|||
633FEC391D3CD5570014B822 /* call_video_start_default@2x.png */,
|
||||
633FEC3A1D3CD5570014B822 /* call_video_start_disabled.png */,
|
||||
633FEC3B1D3CD5570014B822 /* call_video_start_disabled@2x.png */,
|
||||
24BFAA9B209B062F004F47A7 /* callkit_logo.png */,
|
||||
8CD99A1B20908C27008A7CDA /* callkit_logo@2x.png */,
|
||||
633FEC3C1D3CD5570014B822 /* camera_default.png */,
|
||||
633FEC3D1D3CD5570014B822 /* camera_default@2x.png */,
|
||||
633FEC3E1D3CD5570014B822 /* camera_disabled.png */,
|
||||
|
|
@ -2847,10 +2848,20 @@
|
|||
633FEC531D3CD5570014B822 /* chat_attachment_disabled@2x.png */,
|
||||
633FEC541D3CD5570014B822 /* chat_attachment_over.png */,
|
||||
633FEC551D3CD5570014B822 /* chat_attachment_over@2x.png */,
|
||||
244523AC1E8266CC0037A187 /* chat_delivered.png */,
|
||||
244523AD1E8266CC0037A187 /* chat_error.png */,
|
||||
8CA70AD31F9E285B00A3D2EB /* chat_group_add.png */,
|
||||
8CA70AD21F9E285B00A3D2EB /* chat_group_add@2x.png */,
|
||||
8C2A81941F87B8000012A66B /* chat_group_avatar.png */,
|
||||
8C2A81931F87B7FF0012A66B /* chat_group_avatar@2x.png */,
|
||||
8CF25D9B1F9F76BC00BEA0C1 /* chat_group_informations.png */,
|
||||
8CF25D9C1F9F76BD00BEA0C1 /* chat_group_informations@2x.png */,
|
||||
633FEC561D3CD5570014B822 /* chat_list_indicator~ipad.png */,
|
||||
633FEC571D3CD5570014B822 /* chat_list_indicator~ipad@2x.png */,
|
||||
633FEC581D3CD5570014B822 /* chat_message_not_delivered.png */,
|
||||
633FEC591D3CD5570014B822 /* chat_message_not_delivered@2x.png */,
|
||||
244523AE1E8266CC0037A187 /* chat_read.png */,
|
||||
8CB2B8F61F86229B0015CEE2 /* chat_secure.png */,
|
||||
633FEC5A1D3CD5570014B822 /* chat_send_default.png */,
|
||||
633FEC5B1D3CD5570014B822 /* chat_send_default@2x.png */,
|
||||
633FEC5C1D3CD5570014B822 /* chat_send_disabled.png */,
|
||||
|
|
@ -2869,6 +2880,11 @@
|
|||
633FEC691D3CD5570014B822 /* chat_start_body_over@2x.png */,
|
||||
633FEC6A1D3CD5570014B822 /* chat_start_body_over~ipad.png */,
|
||||
633FEC6B1D3CD5570014B822 /* chat_start_body_over~ipad@2x.png */,
|
||||
244523BC1E8D3A6C0037A187 /* chat_unsecure.png */,
|
||||
8CDC618C1F84D89B0087CF7F /* check_selected.png */,
|
||||
8CDC61961F84D9270087CF7F /* check_selected@2x.png */,
|
||||
8CF25D941F9F336100BEA0C1 /* check_unselected.png */,
|
||||
8CF25D8B1F9F336000BEA0C1 /* check_unselected@2x.png */,
|
||||
633FEC6C1D3CD5570014B822 /* checkbox_checked.png */,
|
||||
633FEC6D1D3CD5570014B822 /* checkbox_checked@2x.png */,
|
||||
633FEC6E1D3CD5570014B822 /* checkbox_unchecked.png */,
|
||||
|
|
@ -2883,6 +2899,8 @@
|
|||
633FEC771D3CD5570014B822 /* color_I.png */,
|
||||
633FEC781D3CD5570014B822 /* color_L.png */,
|
||||
633FEC791D3CD5570014B822 /* color_M.png */,
|
||||
8CE24F551F8268840077AC0A /* conference_delete.png */,
|
||||
8CE24F561F8268840077AC0A /* conference_delete@2x.png */,
|
||||
633FEC7A1D3CD5570014B822 /* conference_exit_default.png */,
|
||||
633FEC7B1D3CD5570014B822 /* conference_exit_default@2x.png */,
|
||||
633FEC7C1D3CD5570014B822 /* conference_exit_over.png */,
|
||||
|
|
@ -2897,6 +2915,10 @@
|
|||
633FEC851D3CD5570014B822 /* contacts_all_disabled@2x.png */,
|
||||
633FEC861D3CD5570014B822 /* contacts_all_selected.png */,
|
||||
633FEC871D3CD5570014B822 /* contacts_all_selected@2x.png */,
|
||||
24BFAA99209B062E004F47A7 /* contacts_sip_default.png */,
|
||||
24BFAA94209B062C004F47A7 /* contacts_sip_default@2x.png */,
|
||||
24BFAA97209B062E004F47A7 /* contacts_sip_selected.png */,
|
||||
24BFAA9C209B062F004F47A7 /* contacts_sip_selected@2x.png */,
|
||||
633FEC8E1D3CD5570014B822 /* delete_default.png */,
|
||||
633FEC8F1D3CD5570014B822 /* delete_default@2x.png */,
|
||||
633FEC901D3CD5570014B822 /* delete_disabled.png */,
|
||||
|
|
@ -2905,6 +2927,7 @@
|
|||
633FEC931D3CD5570014B822 /* delete_field_default@2x.png */,
|
||||
633FEC941D3CD5570014B822 /* delete_field_over.png */,
|
||||
633FEC951D3CD5570014B822 /* delete_field_over@2x.png */,
|
||||
CFBD7A2320E504AD007C5286 /* delete_img.png */,
|
||||
633FEC961D3CD5570014B822 /* deselect_all.png */,
|
||||
633FEC971D3CD5570014B822 /* deselect_all@2x.png */,
|
||||
633FEC981D3CD5570014B822 /* dialer_alt_back.png */,
|
||||
|
|
@ -2913,6 +2936,7 @@
|
|||
633FEC9B1D3CD5570014B822 /* dialer_back_default@2x.png */,
|
||||
633FEC9C1D3CD5570014B822 /* dialer_back_disabled.png */,
|
||||
633FEC9D1D3CD5570014B822 /* dialer_back_disabled@2x.png */,
|
||||
24BFAA8C209B062B004F47A7 /* dialer_background.png */,
|
||||
633FECA01D3CD5570014B822 /* edit_default.png */,
|
||||
633FECA11D3CD5570014B822 /* edit_default@2x.png */,
|
||||
633FECA21D3CD5570014B822 /* edit_disabled.png */,
|
||||
|
|
@ -2922,8 +2946,8 @@
|
|||
633FECA61D3CD5570014B822 /* edit_list_disabled.png */,
|
||||
633FECA71D3CD5570014B822 /* edit_list_disabled@2x.png */,
|
||||
633FECA81D3CD5570014B822 /* footer_chat_default.png */,
|
||||
633FECAA1D3CD5570014B822 /* footer_chat_disabled.png */,
|
||||
633FECA91D3CD5570014B822 /* footer_chat_default@2x.png */,
|
||||
633FECAA1D3CD5570014B822 /* footer_chat_disabled.png */,
|
||||
633FECAB1D3CD5570014B822 /* footer_chat_disabled@2x.png */,
|
||||
633FECAC1D3CD5570014B822 /* footer_contacts_default.png */,
|
||||
633FECAD1D3CD5570014B822 /* footer_contacts_default@2x.png */,
|
||||
|
|
@ -2959,6 +2983,14 @@
|
|||
633FECCB1D3CD5570014B822 /* led_error@2x.png */,
|
||||
633FECCC1D3CD5570014B822 /* led_inprogress.png */,
|
||||
633FECCD1D3CD5570014B822 /* led_inprogress@2x.png */,
|
||||
8C300D981E40E0CC00728EF3 /* lime_ko.png */,
|
||||
8C300D991E40E0CC00728EF3 /* lime_ko@2x.png */,
|
||||
24BFAA98209B062E004F47A7 /* linphone_logo.png */,
|
||||
24BFAA9D209B0630004F47A7 /* linphone_logo@2x.png */,
|
||||
24BFAA93209B062C004F47A7 /* linphone_user.png */,
|
||||
24BFAA95209B062D004F47A7 /* linphone_user@2x.png */,
|
||||
24BFAA9A209B062F004F47A7 /* linphone_user~ipad.png */,
|
||||
24BFAA96209B062D004F47A7 /* linphone_user~ipad@2x.png */,
|
||||
633FECD41D3CD5580014B822 /* list_details_default.png */,
|
||||
633FECD51D3CD5580014B822 /* list_details_default@2x.png */,
|
||||
633FECD61D3CD5580014B822 /* list_details_over.png */,
|
||||
|
|
@ -2971,6 +3003,10 @@
|
|||
633FECDD1D3CD5580014B822 /* micro_disabled@2x.png */,
|
||||
633FECDE1D3CD5580014B822 /* micro_selected.png */,
|
||||
633FECDF1D3CD5580014B822 /* micro_selected@2x.png */,
|
||||
8CE24F491F8234A20077AC0A /* next_default.png */,
|
||||
8CE24F4A1F8234A30077AC0A /* next_default@2x.png */,
|
||||
8CB2B8F71F86229C0015CEE2 /* next_disabled.png */,
|
||||
8CB2B8F81F86229D0015CEE2 /* next_disabled@2x.png */,
|
||||
633FECE01D3CD5580014B822 /* nowebcamCIF.jpg */,
|
||||
633FECE11D3CD5580014B822 /* numpad_0_default.png */,
|
||||
633FECE21D3CD5580014B822 /* numpad_0_default@2x.png */,
|
||||
|
|
@ -3107,6 +3143,10 @@
|
|||
633FED651D3CD5590014B822 /* presence_online@2x.png */,
|
||||
633FED661D3CD5590014B822 /* presence_unregistered.png */,
|
||||
633FED671D3CD5590014B822 /* presence_unregistered@2x.png */,
|
||||
CF7602F3210898C600749F76 /* rec_off_default.png */,
|
||||
CF7602EB210898C100749F76 /* rec_off_default@2x.png */,
|
||||
CF7602F4210898C800749F76 /* rec_on_default.png */,
|
||||
CF7602F2210898C400749F76 /* rec_on_default@2x.png */,
|
||||
633FED681D3CD5590014B822 /* route_bluetooth_default.png */,
|
||||
633FED691D3CD5590014B822 /* route_bluetooth_default@2x.png */,
|
||||
633FED6A1D3CD5590014B822 /* route_bluetooth_disabled.png */,
|
||||
|
|
@ -3141,14 +3181,14 @@
|
|||
633FED871D3CD5590014B822 /* select_all_default@2x.png */,
|
||||
633FED881D3CD5590014B822 /* select_all_disabled.png */,
|
||||
633FED891D3CD5590014B822 /* select_all_disabled@2x.png */,
|
||||
8CD99A362090A824008A7CDA /* splashscreen.png */,
|
||||
8CD99A352090A823008A7CDA /* splashscreen@2x.png */,
|
||||
633FED8A1D3CD5590014B822 /* speaker_default.png */,
|
||||
633FED8B1D3CD5590014B822 /* speaker_default@2x.png */,
|
||||
633FED8C1D3CD5590014B822 /* speaker_disabled.png */,
|
||||
633FED8D1D3CD5590014B822 /* speaker_disabled@2x.png */,
|
||||
633FED8E1D3CD5590014B822 /* speaker_selected.png */,
|
||||
633FED8F1D3CD5590014B822 /* speaker_selected@2x.png */,
|
||||
8CD99A362090A824008A7CDA /* splashscreen.png */,
|
||||
8CD99A352090A823008A7CDA /* splashscreen@2x.png */,
|
||||
633FED941D3CD5590014B822 /* valid_default.png */,
|
||||
633FED951D3CD5590014B822 /* valid_default@2x.png */,
|
||||
633FED961D3CD5590014B822 /* valid_disabled.png */,
|
||||
|
|
@ -3713,6 +3753,7 @@
|
|||
636316D11A1DEBCB0009B839 /* AboutView.xib in Resources */,
|
||||
8CBD7BA620B6B82400E5DCC0 /* UIChatConversationInfoTableViewCell.xib in Resources */,
|
||||
244523AF1E8266CC0037A187 /* chat_delivered.png in Resources */,
|
||||
CF7602F8210898CC00749F76 /* rec_on_default.png in Resources */,
|
||||
633FEF481D3CD55A0014B822 /* speaker_selected.png in Resources */,
|
||||
633FEED91D3CD55A0014B822 /* numpad_7~ipad.png in Resources */,
|
||||
633FEE2B1D3CD5590014B822 /* color_C.png in Resources */,
|
||||
|
|
@ -3843,6 +3884,7 @@
|
|||
633FEDE91D3CD5590014B822 /* call_status_missed~ipad@2x.png in Resources */,
|
||||
8CE24F4C1F8234A30077AC0A /* next_default@2x.png in Resources */,
|
||||
244523B11E8266CC0037A187 /* chat_read.png in Resources */,
|
||||
CF7602D8210867E800749F76 /* RecordingsListView.xib in Resources */,
|
||||
639E9CAC1C0DB80300019A75 /* UIContactDetailsCell.xib in Resources */,
|
||||
633FEE511D3CD5590014B822 /* deselect_all@2x.png in Resources */,
|
||||
8CF25D951F9F336100BEA0C1 /* check_unselected@2x.png in Resources */,
|
||||
|
|
@ -3939,6 +3981,7 @@
|
|||
633FEEA41D3CD55A0014B822 /* numpad_1_default@2x.png in Resources */,
|
||||
63E27A321C4FECD000D332AE /* LaunchScreen.xib in Resources */,
|
||||
633FEED11D3CD55A0014B822 /* numpad_6~ipad.png in Resources */,
|
||||
CF7602E82108759A00749F76 /* UIRecordingCell.xib in Resources */,
|
||||
633FEED21D3CD55A0014B822 /* numpad_6~ipad@2x.png in Resources */,
|
||||
633FEDCD1D3CD5590014B822 /* call_quality_indicator_0@2x.png in Resources */,
|
||||
636316D41A1DEC650009B839 /* SettingsView.xib in Resources */,
|
||||
|
|
@ -4007,6 +4050,7 @@
|
|||
633FEE8F1D3CD55A0014B822 /* list_details_default@2x.png in Resources */,
|
||||
633FEE5E1D3CD5590014B822 /* edit_list_default.png in Resources */,
|
||||
633FEDB11D3CD5590014B822 /* call_add_disabled@2x.png in Resources */,
|
||||
CF7602F7210898CC00749F76 /* rec_off_default.png in Resources */,
|
||||
633FEDB21D3CD5590014B822 /* call_alt_back_default.png in Resources */,
|
||||
633FEE3D1D3CD5590014B822 /* contacts_all_default@2x.png in Resources */,
|
||||
633FEF251D3CD55A0014B822 /* route_bluetooth_disabled@2x.png in Resources */,
|
||||
|
|
@ -4057,6 +4101,7 @@
|
|||
633FEEA81D3CD55A0014B822 /* numpad_1_over~ipad@2x.png in Resources */,
|
||||
D38187AD15FE340100C3EDCA /* ChatConversationView.xib in Resources */,
|
||||
633FEE7C1D3CD5590014B822 /* history_missed_disabled.png in Resources */,
|
||||
CF1DE92E210A0F5D00A0A97E /* UILinphoneAudioPlayer.xib in Resources */,
|
||||
633FEDF11D3CD5590014B822 /* call_transfer_disabled@2x.png in Resources */,
|
||||
633FEDFF1D3CD5590014B822 /* camera_switch_disabled@2x.png in Resources */,
|
||||
633FEDDF1D3CD5590014B822 /* call_start_body_over@2x.png in Resources */,
|
||||
|
|
@ -4123,6 +4168,7 @@
|
|||
633FEE851D3CD5590014B822 /* led_error@2x.png in Resources */,
|
||||
633FEDBE1D3CD5590014B822 /* call_back_default.png in Resources */,
|
||||
633FEF0F1D3CD55A0014B822 /* pause_big_default@2x.png in Resources */,
|
||||
CF7602F6210898CC00749F76 /* rec_on_default@2x.png in Resources */,
|
||||
633FEF081D3CD55A0014B822 /* options_start_conference_disabled.png in Resources */,
|
||||
63F1DF511BCE986A00EDED90 /* UICallConferenceCell.xib in Resources */,
|
||||
633FEE301D3CD5590014B822 /* color_H.png in Resources */,
|
||||
|
|
@ -4194,6 +4240,7 @@
|
|||
639E9CA91C0DB7FB00019A75 /* UIConfirmationDialog.xib in Resources */,
|
||||
633FEF111D3CD55A0014B822 /* pause_big_disabled@2x.png in Resources */,
|
||||
633FEE321D3CD5590014B822 /* color_L.png in Resources */,
|
||||
CF7602F5210898CC00749F76 /* rec_off_default@2x.png in Resources */,
|
||||
633FEDB41D3CD5590014B822 /* call_alt_back_disabled.png in Resources */,
|
||||
633FEE631D3CD5590014B822 /* footer_chat_default@2x.png in Resources */,
|
||||
633FEE661D3CD5590014B822 /* footer_contacts_default.png in Resources */,
|
||||
|
|
@ -4380,6 +4427,7 @@
|
|||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
63B81A0F1B57DA33009604A6 /* TPKeyboardAvoidingTableView.m in Sources */,
|
||||
CF1DE92D210A0F5D00A0A97E /* UILinphoneAudioPlayer.m in Sources */,
|
||||
1D60589B0D05DD56006BFB54 /* main.m in Sources */,
|
||||
8CD99A3C2090B9FA008A7CDA /* ChatConversationImdnView.m in Sources */,
|
||||
1D3623260D0F684500981E51 /* LinphoneAppDelegate.m in Sources */,
|
||||
|
|
@ -4409,6 +4457,7 @@
|
|||
34216F401547EBCD00EA9777 /* VideoZoomHandler.m in Sources */,
|
||||
D3F83EEC1582021700336684 /* CallView.m in Sources */,
|
||||
8C2595DD1DEDC92D007A6424 /* ProviderDelegate.m in Sources */,
|
||||
CF7602D7210867E800749F76 /* RecordingsListView.m in Sources */,
|
||||
63F1DF4B1BCE983200EDED90 /* CallConferenceTableView.m in Sources */,
|
||||
D3F83F8E15822ABE00336684 /* PhoneMainView.m in Sources */,
|
||||
6377AC801BDE4069007F7625 /* UIBackToCallButton.m in Sources */,
|
||||
|
|
@ -4472,6 +4521,7 @@
|
|||
D3807FC115C28940005BE9BC /* DCRoundSwitchKnobLayer.m in Sources */,
|
||||
6306440E1BECB08500134C72 /* FirstLoginView.m in Sources */,
|
||||
D3807FC315C28940005BE9BC /* DCRoundSwitchOutlineLayer.m in Sources */,
|
||||
CF7602E221086EB200749F76 /* RecordingsListTableView.m in Sources */,
|
||||
D3807FC515C28940005BE9BC /* DCRoundSwitchToggleLayer.m in Sources */,
|
||||
633E41821D74259000320475 /* AssistantLinkView.m in Sources */,
|
||||
D3807FE815C2894A005BE9BC /* IASKAppSettingsViewController.m in Sources */,
|
||||
|
|
@ -4484,6 +4534,7 @@
|
|||
D3807FF215C2894A005BE9BC /* IASKSettingsStoreFile.m in Sources */,
|
||||
D3807FF415C2894A005BE9BC /* IASKSettingsStoreUserDefaults.m in Sources */,
|
||||
639E9C801C0DB13D00019A75 /* UICheckBoxTableView.m in Sources */,
|
||||
CF7602E72108759A00749F76 /* UIRecordingCell.m in Sources */,
|
||||
D3807FF615C2894A005BE9BC /* IASKSpecifier.m in Sources */,
|
||||
D3807FF815C2894A005BE9BC /* IASKPSSliderSpecifierViewCell.m in Sources */,
|
||||
D3807FFA15C2894A005BE9BC /* IASKPSTextFieldSpecifierViewCell.m in Sources */,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue