diff --git a/Classes/LinphoneUI/UIRecordingCell.h b/Classes/LinphoneUI/UIRecordingCell.h
index accb53837..e82954b14 100644
--- a/Classes/LinphoneUI/UIRecordingCell.h
+++ b/Classes/LinphoneUI/UIRecordingCell.h
@@ -10,10 +10,11 @@
@interface UIRecordingCell : UITableViewCell
@property (weak, nonatomic) IBOutlet UILabel *nameLabel;
-@property (weak, nonatomic) IBOutlet UILabel *dateLabel;
@property(nonatomic, assign) NSString *recording;
- (id)initWithIdentifier:(NSString*)identifier;
+- (void)updateFrame;
+
@end
diff --git a/Classes/LinphoneUI/UIRecordingCell.m b/Classes/LinphoneUI/UIRecordingCell.m
index 7451aa98a..41596d2f8 100644
--- a/Classes/LinphoneUI/UIRecordingCell.m
+++ b/Classes/LinphoneUI/UIRecordingCell.m
@@ -15,15 +15,15 @@
#pragma mark - Lifecycle Functions
- (id)initWithIdentifier:(NSString *)identifier {
- if ((self = [super initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier]) != nil) {
+ 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
- UIView *sub = ((UIView *)[arrayOfViews objectAtIndex:0]);
- [self setFrame:CGRectMake(0, 0, sub.frame.size.width, sub.frame.size.height)];
- [self addSubview:sub];
+ UIRecordingCell *sub = [arrayOfViews objectAtIndex:0];
+ [self setFrame:CGRectMake(0, 0, sub.frame.size.width, 40)];
+ self = sub;
self.recording = NULL;
}
return self;
@@ -40,19 +40,15 @@
_recording = arecording;
if(_recording) {
//TODO: Parse file name to get name of contact and date
+ 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 -
-- (void)touchUp:(id)sender {
- [self setHighlighted:true animated:true];
-}
-
-- (void)touchDown:(id)sender {
- [self setHighlighted:false animated:true];
-}
-
- (NSString *)accessibilityLabel {
return _nameLabel.text;
}
@@ -71,5 +67,19 @@
}
}
+- (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];
+}
+
@end
diff --git a/Classes/LinphoneUI/UIRecordingCell.xib b/Classes/LinphoneUI/UIRecordingCell.xib
index cc5ad8588..802728a30 100644
--- a/Classes/LinphoneUI/UIRecordingCell.xib
+++ b/Classes/LinphoneUI/UIRecordingCell.xib
@@ -12,35 +12,33 @@
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
+
-
-
+
+
diff --git a/Classes/RecordingsListTableView.h b/Classes/RecordingsListTableView.h
index d8c003927..45e32626b 100644
--- a/Classes/RecordingsListTableView.h
+++ b/Classes/RecordingsListTableView.h
@@ -9,14 +9,13 @@
#import "UICheckBoxTableView.h"
-#import "OrderedDictionary.h"
-
@interface RecordingsListTableView : UICheckBoxTableView {
@private
- OrderedDictionary *recordings;
+ 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.
}
-@property(nonatomic) BOOL ongoing;
- (void)loadData;
- (void)removeAllRecordings;
diff --git a/Classes/RecordingsListTableView.m b/Classes/RecordingsListTableView.m
index b90dafbd7..66f22450b 100644
--- a/Classes/RecordingsListTableView.m
+++ b/Classes/RecordingsListTableView.m
@@ -12,13 +12,14 @@
#import "Utils.h"
@implementation RecordingsListTableView
-NSArray *sortedRecordings;
#pragma mark - Lifecycle Functions
- (void)initRecordingsTableViewController {
- recordings = [[OrderedDictionary alloc] init];
- sortedRecordings = [[NSArray alloc] init];
+ recordings = [NSMutableDictionary dictionary];
+ NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
+ writablePath = [paths objectAtIndex:0];
+ writablePath = [writablePath stringByAppendingString:@"/"];
}
- (void)viewWillAppear:(BOOL)animated {
@@ -26,6 +27,7 @@ NSArray *sortedRecordings;
if (![self selectFirstRow]) {
//TODO: Make first cell expand to show player
}
+ [self loadData];
}
- (id)init {
@@ -33,7 +35,6 @@ NSArray *sortedRecordings;
if (self) {
[self initRecordingsTableViewController];
}
- _ongoing = FALSE;
return self;
}
@@ -60,7 +61,6 @@ NSArray *sortedRecordings;
- (void)loadData {
- _ongoing = TRUE;
LOGI(@"====>>>> Load recording list - Start");
//Clear recording cells
@@ -70,18 +70,52 @@ NSArray *sortedRecordings;
[[self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:i inSection:j]] setRecording:nil];
}
}
+ 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];
+ }
+ }
- //TODO: Fill the recordings dictionnary with the recording names, keys are dates
LOGI(@"====>>>> Load recording list - End");
[super loadData];
- _ongoing = FALSE;
+}
+
+- (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 [recordings allKeys];
+ return nil;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
@@ -89,7 +123,8 @@ NSArray *sortedRecordings;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
- return [(OrderedDictionary *)[recordings objectForKey:[recordings keyAtIndex:section]] count];
+ NSArray *sortedKey = [self getSortedKeys];
+ return [(NSArray *)[recordings objectForKey:[sortedKey objectAtIndex:section]] count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
@@ -98,11 +133,14 @@ NSArray *sortedRecordings;
if (cell == nil) {
cell = [[UIRecordingCell alloc] initWithIdentifier:kCellId];
}
- NSString *recording = @"";
- //TODO: Set recording to the path of the recording
- [cell setRecording:recording];
+ 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;
}
@@ -114,7 +152,7 @@ NSArray *sortedRecordings;
UILabel *tempLabel = [[UILabel alloc] initWithFrame:frame];
tempLabel.backgroundColor = [UIColor clearColor];
tempLabel.textColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"color_A.png"]];
- tempLabel.text = [recordings keyAtIndex:section];
+ tempLabel.text = [[self getSortedKeys] objectAtIndex:section];
tempLabel.textAlignment = NSTextAlignmentCenter;
tempLabel.font = [UIFont boldSystemFontOfSize:17];
tempLabel.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
@@ -126,7 +164,9 @@ NSArray *sortedRecordings;
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[super tableView:tableView didSelectRowAtIndexPath:indexPath];
if (![self isEditing]) {
- //TODO: Expand selected cell to display player
+ [tableView beginUpdates];
+ [(UIRecordingCell *)[self tableView:tableView cellForRowAtIndexPath:indexPath] updateFrame];
+ [tableView endUpdates];
}
}
@@ -138,9 +178,9 @@ forRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView beginUpdates];
- NSString *date = [recordings keyAtIndex:[indexPath section]];
+ NSString *date = [[self getSortedKeys] objectAtIndex:[indexPath section]];
NSMutableArray *subAr = [recordings objectForKey:date];
- //NSString *recording = subAr[indexPath.row];
+ NSString *recordingPath = subAr[indexPath.row];
[subAr removeObjectAtIndex:indexPath.row];
if (subAr.count == 0) {
[recordings removeObjectForKey:date];
@@ -150,7 +190,9 @@ forRowAtIndexPath:(NSIndexPath *)indexPath {
UIRecordingCell* cell = [self.tableView cellForRowAtIndexPath:indexPath];
[cell setRecording:NULL];
- //TODO: Delete recording file here
+
+ remove([recordingPath cStringUsingEncoding:NSUTF8StringEncoding]);
+
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[tableView endUpdates];
@@ -162,16 +204,28 @@ forRowAtIndexPath:(NSIndexPath *)indexPath {
[super removeSelectionUsing:^(NSIndexPath *indexPath) {
[NSNotificationCenter.defaultCenter removeObserver:self];
- NSString *date = [recordings keyAtIndex:[indexPath section]];
+ NSString *date = [[self getSortedKeys] objectAtIndex:[indexPath section]];
NSMutableArray *subAr = [recordings objectForKey:date];
- //NSString *recording = subAr[indexPath.row];
+ 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];
- //TODO: Delete recording file here
+ remove([recordingPath cStringUsingEncoding:NSUTF8StringEncoding]);
+ }];
+}
+
+#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];
}];
}
diff --git a/Classes/RecordingsListView.m b/Classes/RecordingsListView.m
index 14c4e4d4a..9b91c5675 100644
--- a/Classes/RecordingsListView.m
+++ b/Classes/RecordingsListView.m
@@ -53,6 +53,7 @@ static UICompositeViewDescription *compositeDescription = nil;
- (void)viewDidLoad {
[super viewDidLoad];
tableController.tableView.accessibilityIdentifier = @"Recordings table";
+ tableController.tableView.tableFooterView = [[UIView alloc] init];
}
- (void)viewWillAppear:(BOOL)animated {
diff --git a/Classes/RecordingsListView.xib b/Classes/RecordingsListView.xib
index bee02a58e..a508993d9 100644
--- a/Classes/RecordingsListView.xib
+++ b/Classes/RecordingsListView.xib
@@ -86,13 +86,12 @@
-
-
+
@@ -101,6 +100,14 @@
+
@@ -111,6 +118,7 @@
+
diff --git a/Classes/Utils/Utils.h b/Classes/Utils/Utils.h
index e010ce711..1f03d9fb4 100644
--- a/Classes/Utils/Utils.h
+++ b/Classes/Utils/Utils.h
@@ -52,6 +52,7 @@ typedef enum {
+ (NSMutableDictionary *)photoAssetsDictionary;
+ (NSString *)recordingFilePathFromCall:(const LinphoneAddress *)iaddr;
++ (NSArray *)parseRecordingName:(NSString *)filename;
@end
diff --git a/Classes/Utils/Utils.m b/Classes/Utils/Utils.m
index f895b8cef..039f64248 100644
--- a/Classes/Utils/Utils.m
+++ b/Classes/Utils/Utils.m
@@ -510,7 +510,6 @@
return addr;
}
-
+ (NSString *)recordingFilePathFromCall:(const LinphoneAddress *)iaddr {
NSString *filepath = @"recording_";
const char *address = linphone_address_get_username(iaddr);
@@ -530,10 +529,25 @@
writablePath = [writablePath stringByAppendingString:filepath];
LOGD(@"file path is: %@\n", writablePath);
return writablePath;
- //file name is contact-name_dayName-day-monthName-year-hour-minutes-seconds
+ //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)