From e3525432737daa245a0a881005984accedbff752 Mon Sep 17 00:00:00 2001 From: Yann Diorcet Date: Tue, 17 Jul 2012 17:30:58 +0200 Subject: [PATCH] Improve history and chat --- Classes/ChatRoomTableViewController.h | 9 +- Classes/ChatRoomTableViewController.m | 88 +++++-- Classes/ChatRoomViewController.h | 11 +- Classes/ChatRoomViewController.m | 155 ++++++++++- Classes/ChatRoomViewController.xib | 215 ++++++++++----- Classes/ChatTableViewController.h | 2 + Classes/ChatTableViewController.m | 4 +- Classes/ChatViewController.m | 4 +- Classes/HistoryDetailsViewController.m | 5 +- Classes/LinphoneApp.xib | 3 +- Classes/LinphoneAppDelegate.m | 21 +- Classes/LinphoneManager.h | 3 +- Classes/LinphoneManager.m | 5 +- Classes/LinphoneUI/UIChatCell.h | 4 +- Classes/LinphoneUI/UIChatCell.m | 43 ++- Classes/LinphoneUI/UIChatCell.xib | 31 +-- Classes/LinphoneUI/UIChatRoomCell.h | 4 + Classes/LinphoneUI/UIChatRoomCell.m | 46 +++- Classes/LinphoneUI/UIChatRoomCell.xib | 92 +++++-- Classes/LinphoneUI/UIChatRoomHeader.h | 37 --- Classes/LinphoneUI/UIChatRoomHeader.m | 71 ----- Classes/LinphoneUI/UIChatRoomHeader.xib | 245 ------------------ .../LinphoneUI/UICompositeViewController.m | 32 +++ Classes/LinphoneUI/UIHistoryCell.m | 3 + Classes/LinphoneUI/UIMainBar.m | 105 +++++--- Classes/LinphoneUI/UIMainBar.xib | 13 +- Classes/Model/ChatModel.m | 22 +- Classes/PhoneMainView.m | 137 ++++++++-- Classes/PhoneMainView.xib | 11 +- linphone.xcodeproj/project.pbxproj | 14 - 30 files changed, 805 insertions(+), 630 deletions(-) delete mode 100644 Classes/LinphoneUI/UIChatRoomHeader.h delete mode 100644 Classes/LinphoneUI/UIChatRoomHeader.m delete mode 100644 Classes/LinphoneUI/UIChatRoomHeader.xib diff --git a/Classes/ChatRoomTableViewController.h b/Classes/ChatRoomTableViewController.h index d118a363a..1a0e3256c 100644 --- a/Classes/ChatRoomTableViewController.h +++ b/Classes/ChatRoomTableViewController.h @@ -19,13 +19,16 @@ #import +#import "ChatModel.h" @interface ChatRoomTableViewController : UITableViewController { @private - NSArray *data; - NSString *remoteContact; + NSMutableArray *data; + NSString *remoteAddress; } -@property (nonatomic, retain) NSString *remoteContact; +@property (nonatomic, retain) NSString *remoteAddress; + +- (void)addChatEntry:(ChatModel*)chat; @end diff --git a/Classes/ChatRoomTableViewController.m b/Classes/ChatRoomTableViewController.m index 818776705..32d7b9676 100644 --- a/Classes/ChatRoomTableViewController.m +++ b/Classes/ChatRoomTableViewController.m @@ -19,13 +19,13 @@ #import "ChatRoomTableViewController.h" #import "UIChatRoomCell.h" -#import "UIChatRoomHeader.h" +#import "Utils.h" #import @implementation ChatRoomTableViewController -@synthesize remoteContact; +@synthesize remoteAddress; #pragma mark - ViewController @@ -38,27 +38,75 @@ - (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; [TUNinePatchCache flushCache]; // Clear cache + if(data != nil) { + [data removeAllObjects]; + [data release]; + data = nil; + } } #pragma mark - - (void)loadData { - if(data != nil) + if(data != nil) { + [data removeAllObjects]; [data release]; - data = [[ChatModel listMessages:remoteContact] retain]; + } + data = [[ChatModel listMessages:remoteAddress] retain]; [[self tableView] reloadData]; + [self scrollToLastUnread:false]; } +- (void)addChatEntry:(ChatModel*)chat { + if(data == nil) { + [LinphoneLogger logc:LinphoneLoggerWarning format:"Cannot add entry: null data"]; + return; + } + [self.tableView beginUpdates]; + int pos = [data count]; + [data insertObject:chat atIndex:pos]; + [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:pos inSection:0]] withRowAnimation:UITableViewRowAnimationFade]; + [self.tableView endUpdates]; + [self scrollToLastUnread:true]; +} + +- (void)scrollToLastUnread:(BOOL)animated { + if(data == nil) { + [LinphoneLogger logc:LinphoneLoggerWarning format:"Cannot add entry: null data"]; + return; + } + + int index = -1; + // Find first unread & set all entry read + for(int i = 0; i <[data count]; ++i) { + ChatModel *chat = [data objectAtIndex:i]; + if([[chat read] intValue] == 0) { + [chat setRead:[NSNumber numberWithInt:1]]; + if(index == -1) + index = i; + } + } + if(index == -1) { + index = [data count] - 1; + } + + // Scroll to unread + [self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:index inSection:0] atScrollPosition:UITableViewScrollPositionMiddle animated:animated]; +} #pragma mark - Property Functions -- (void)setRemoteContact:(NSString *)aremoteContact { - self->remoteContact = aremoteContact; - [ChatModel readConversation:aremoteContact]; - [[NSNotificationCenter defaultCenter] postNotificationName:@"LinphoneTextReceived" object:self]; +- (void)setRemoteAddress:(NSString *)aremoteAddress { + if(remoteAddress != nil) { + [remoteAddress release]; + } + self->remoteAddress = [aremoteAddress copy]; [self loadData]; + [ChatModel readConversation:remoteAddress]; + [[NSNotificationCenter defaultCenter] postNotificationName:@"LinphoneTextReceived" object:self]; } + #pragma mark - UITableViewDataSource Functions - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { @@ -82,20 +130,20 @@ } +- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { + if(editingStyle == UITableViewCellEditingStyleDelete) { + [tableView beginUpdates]; + ChatModel *chat = [data objectAtIndex:[indexPath row]]; + [data removeObjectAtIndex:[indexPath row]]; + [chat delete]; + [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; + [tableView endUpdates]; + } +} + + #pragma mark - UITableViewDelegate Functions -- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section { - UIChatRoomHeader *headerController = [[UIChatRoomHeader alloc] init]; - UIView *headerView = [headerController view]; - [headerController setContact:remoteContact]; - [headerController release]; - return headerView; -} - -- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { - return [UIChatRoomHeader height]; -} - - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { ChatModel *chat = [data objectAtIndex:[indexPath row]]; return [UIChatRoomCell height:chat]; diff --git a/Classes/ChatRoomViewController.h b/Classes/ChatRoomViewController.h index 21c874e9d..d716f582e 100644 --- a/Classes/ChatRoomViewController.h +++ b/Classes/ChatRoomViewController.h @@ -24,20 +24,27 @@ #import "ChatRoomTableViewController.h" #import "ChatModel.h" +#include "linphonecore.h" + @interface ChatRoomViewController : UIViewController { ChatRoomTableViewController *tableController; UITextField *messageField; UIButton *sendButton; - NSString *remoteContact; + NSString *remoteAddress; UIToggleButton *editButton; + LinphoneChatRoom *chatRoom; + UILabel *addressLabel; + UIImageView *avatarImage; } -- (void) setRemoteContact:(NSString*)remoteContact; @property (nonatomic, retain) IBOutlet ChatRoomTableViewController* tableController; @property (nonatomic, retain) IBOutlet UIToggleButton *editButton; @property (nonatomic, retain) IBOutlet UITextField* messageField; @property (nonatomic, retain) IBOutlet UIButton* sendButton; +@property (nonatomic, retain) IBOutlet UILabel *addressLabel; +@property (nonatomic, retain) IBOutlet UIImageView *avatarImage; +@property (nonatomic, copy) NSString *remoteAddress; - (IBAction)onBackClick:(id)event; - (IBAction)onEditClick:(id)event; diff --git a/Classes/ChatRoomViewController.m b/Classes/ChatRoomViewController.m index 28c6b6632..ade4c61e6 100644 --- a/Classes/ChatRoomViewController.m +++ b/Classes/ChatRoomViewController.m @@ -24,16 +24,22 @@ @implementation ChatRoomViewController - @synthesize tableController; @synthesize sendButton; @synthesize messageField; @synthesize editButton; +@synthesize remoteAddress; +@synthesize addressLabel; +@synthesize avatarImage; #pragma mark - Lifecycle Functions - (id)init { - return [super initWithNibName:@"ChatRoomViewController" bundle:[NSBundle mainBundle]]; + self = [super initWithNibName:@"ChatRoomViewController" bundle:[NSBundle mainBundle]]; + if (self != nil) { + self->chatRoom = NULL; + } + return self; } - (void)dealloc { @@ -42,9 +48,13 @@ [messageField release]; [sendButton release]; [editButton release]; + [remoteAddress release]; + [addressLabel release]; + [avatarImage release]; [super dealloc]; } + #pragma mark - UICompositeViewDelegate Functions + (UICompositeViewDescription*) compositeViewDescription { @@ -73,6 +83,14 @@ - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(keyboardWillShow:) + name:UIKeyboardWillShowNotification + object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(keyboardWillHide:) + name:UIKeyboardWillHideNotification + object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textReceivedEvent:) name:@"LinphoneTextReceived" @@ -85,6 +103,16 @@ - (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; + if(chatRoom != NULL) { + linphone_chat_room_destroy(chatRoom); + chatRoom = NULL; + } + [[NSNotificationCenter defaultCenter] removeObserver:self + name:UIKeyboardWillShowNotification + object:nil]; + [[NSNotificationCenter defaultCenter] removeObserver:self + name:UIKeyboardWillHideNotification + object:nil]; [[NSNotificationCenter defaultCenter] removeObserver:self name:@"LinphoneTextReceived" object:nil]; @@ -97,9 +125,66 @@ #pragma mark - -- (void)setRemoteContact:(NSString*)aRemoteContact { - remoteContact = aRemoteContact; - [tableController setRemoteContact: remoteContact]; +- (void)setRemoteAddress:(NSString*)aRemoteAddress { + if(remoteAddress != nil) { + [remoteAddress release]; + } + remoteAddress = [aRemoteAddress copy]; + [tableController setRemoteAddress: remoteAddress]; + + if(remoteAddress == NULL) { + [LinphoneLogger logc:LinphoneLoggerWarning format:"Cannot update chat room header: null contact"]; + return; + } + + NSString *displayName = nil; + UIImage *image = nil; + NSString *normalizedSipAddress = [FastAddressBook normalizeSipURI:remoteAddress]; + ABRecordRef acontact =[[[LinphoneManager instance] fastAddressBook] getContact:normalizedSipAddress]; + if(acontact != nil) { + displayName = [FastAddressBook getContactDisplayName:acontact]; + image = [FastAddressBook getContactImage:acontact thumbnail:true]; + } + + // Display name + if(displayName == nil) { + displayName = remoteAddress; + } + [addressLabel setText:displayName]; + + // Avatar + if(image == nil) { + image = [UIImage imageNamed:@"avatar_unknown_small.png"]; + } + [avatarImage setImage:image]; +} + +- (BOOL)sendMessage:(NSString *)message { + if(![LinphoneManager isLcReady]) { + [LinphoneLogger logc:LinphoneLoggerWarning format:"Cannot send message: Linphone core not ready"]; + return FALSE; + } + if(remoteAddress == nil) { + [LinphoneLogger logc:LinphoneLoggerWarning format:"Cannot send message: Null remoteAddress"]; + return FALSE; + } + if(chatRoom == NULL) { + chatRoom = linphone_core_create_chat_room([LinphoneManager getLc], [remoteAddress UTF8String]); + } + + // Save message in database + ChatModel *chat = [[ChatModel alloc] init]; + [chat setRemoteContact:remoteAddress]; + [chat setMessage:message]; + [chat setDirection:[NSNumber numberWithInt:0]]; + [chat setTime:[NSDate date]]; + [chat setRead:[NSNumber numberWithInt:1]]; + [chat create]; + [tableController addChatEntry:chat]; + [chat release]; + + linphone_chat_room_send_message(chatRoom, [message UTF8String]); + return TRUE; } @@ -107,13 +192,19 @@ - (void)textReceivedEvent:(NSNotification *)notif { //LinphoneChatRoom *room = [[[notif userInfo] objectForKey:@"room"] pointerValue]; + //NSString *message = [[notif userInfo] objectForKey:@"message"]; LinphoneAddress *from = [[[notif userInfo] objectForKey:@"from"] pointerValue]; - if(from != NULL) { - //NSString *message = [[notif userInfo] objectForKey:@"message"]; - if([[NSString stringWithUTF8String:linphone_address_get_username(from)] - caseInsensitiveCompare:remoteContact] == NSOrderedSame) { - [[tableController tableView] reloadData]; + ChatModel *chat = [[notif userInfo] objectForKey:@"chat"]; + if(from != NULL && chat != NULL) { + if([[NSString stringWithUTF8String:linphone_address_as_string_uri_only(from)] + caseInsensitiveCompare:remoteAddress] == NSOrderedSame) { + [chat setRead:[NSNumber numberWithInt:1]]; + [chat update]; + [[NSNotificationCenter defaultCenter] postNotificationName:@"LinphoneTextReceived" object:self]; + [tableController addChatEntry:chat]; } + } else { + [LinphoneLogger logc:LinphoneLoggerWarning format:"Invalid textReceivedEvent"]; } } @@ -137,7 +228,9 @@ } - (IBAction)onSendClick:(id)event { - [messageField endEditing:TRUE]; + if([self sendMessage:[messageField text]]) { + [messageField setText:@""]; + } } - (IBAction)onMessageChange:(id)sender { @@ -148,4 +241,44 @@ } } +#pragma mark - Keyboard Event Functions + +- (void)keyboardWillHide:(NSNotification *)notif { + CGRect beginFrame = [[[notif userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue]; + UIViewAnimationCurve curve = [[[notif userInfo] objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue]; + NSTimeInterval duration = [[[notif userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]; + [UIView beginAnimations:@"resize" context:nil]; + [UIView setAnimationDuration:duration]; + [UIView setAnimationCurve:curve]; + [UIView setAnimationBeginsFromCurrentState:TRUE]; + CGRect endFrame = [[[notif userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue]; + CGRect frame = [[self view] frame]; + /* + CGPoint pos = {0, 0}; + CGPoint gPos = [[self view] convertPoint:pos toView:nil]; + frame.size.height = endFrame.origin.y - gPos.y; + */ + frame.origin.y += endFrame.origin.y - beginFrame.origin.y; + [[self view] setFrame:frame]; + [UIView commitAnimations]; +} + +- (void)keyboardWillShow:(NSNotification *)notif { + CGRect beginFrame = [[[notif userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue]; + UIViewAnimationCurve curve = [[[notif userInfo] objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue]; + NSTimeInterval duration = [[[notif userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]; + [UIView beginAnimations:@"resize" context:nil]; + [UIView setAnimationDuration:duration]; + [UIView setAnimationCurve:curve]; + [UIView setAnimationBeginsFromCurrentState:TRUE]; + CGRect endFrame = [[[notif userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue]; + CGRect frame = [[self view] frame]; + /*CGPoint pos = {0, 0}; + CGPoint gPos = [[self view] convertPoint:pos toView:nil]; + frame.size.height = endFrame.origin.y - gPos.y;*/ + frame.origin.y += endFrame.origin.y - beginFrame.origin.y; + [[self view] setFrame:frame]; + [UIView commitAnimations]; +} + @end diff --git a/Classes/ChatRoomViewController.xib b/Classes/ChatRoomViewController.xib index 0d2dede5d..2d19178d5 100644 --- a/Classes/ChatRoomViewController.xib +++ b/Classes/ChatRoomViewController.xib @@ -14,6 +14,7 @@ IBUIView IBUIImageView IBProxyObject + IBUILabel IBUITextField IBUITableViewController IBUITableView @@ -87,7 +88,7 @@ {{160, 0}, {160, 58}} - + _NS:9 NO @@ -128,83 +129,104 @@ IBCocoaTouchFramework + + + 292 + + + + 292 + {{-13, -5}, {131, 107}} + + + + _NS:9 + NO + IBCocoaTouchFramework + + NSImage + avatar_shadow_small.png + + + + + 274 + {{20, 6}, {65, 65}} + + + + _NS:9 + NO + IBCocoaTouchFramework + + NSImage + avatar_unknown_small.png + + + + + 292 + {{101, 37}, {199, 43}} + + + + _NS:9 + NO + YES + 7 + NO + IBCocoaTouchFramework + Contact1 + + 3 + MC4zMzMzMzMzMzMzAA + + + 0 + 10 + + 1 + 22 + + + Helvetica + 22 + 16 + + + + {{0, 58}, {320, 80}} + + + + _NS:9 + + 3 + MCAwAA + + YES + IBCocoaTouchFramework + 274 - {{0, 58}, {320, 344}} + {{0, 138}, {320, 263}} _NS:9 - 10 - - 549453824 - {512, 1} - - - - - - TU0AKgAACAjFzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/ -y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/ -xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/ -xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/ -xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/ -xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/ -xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/ -y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/ -y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/ -xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/ -xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/ -xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/ -xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/ -xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/ -y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/ -y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/ -xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/ -xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/ -xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/ -xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/ -xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/ -y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/ -y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/ -xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/ -xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/ -xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/ -xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/ -xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/ -y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/ -y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/ -xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/ -xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/ -xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/ -xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/ -xczS/8vS2P/L0tj/xczU/wANAQAAAwAAAAECAAAAAQEAAwAAAAEAAQAAAQIAAwAAAAQAAAiqAQMAAwAA -AAEAAQAAAQYAAwAAAAEAAgAAAREABAAAAAEAAAAIARIAAwAAAAEAAQAAARUAAwAAAAEABAAAARYAAwAA -AAEAAQAAARcABAAAAAEAAAgAARwAAwAAAAEAAQAAAVIAAwAAAAEAAQAAAVMAAwAAAAQAAAiyAAAAAAAI -AAgACAAIAAEAAQABAAE - - - - - - 3 - MCAwAA - - - groupTableViewBackgroundColor + 3 + MQA YES IBCocoaTouchFramework YES - 1 - 2 0 YES 44 - 10 - 10 + 22 + 22 @@ -216,7 +238,6 @@ AAgACAAIAAEAAQABAAE {{250, 0}, {70, 59}} - _NS:9 NO @@ -368,6 +389,22 @@ AAgACAAIAAEAAQABAAE 35 + + + addressLabel + + + + 43 + + + + avatarImage + + + + 44 + dataSource @@ -463,6 +500,7 @@ AAgACAAIAAEAAQABAAE + @@ -474,7 +512,7 @@ AAgACAAIAAEAAQABAAE - header + toolsView 8 @@ -530,6 +568,35 @@ AAgACAAIAAEAAQABAAE tableController + + 39 + + + + + + + + headerView + + + 42 + + + avatarShadowBackground + + + 41 + + + avatarImage + + + 40 + + + addressLabel + @@ -547,6 +614,10 @@ AAgACAAIAAEAAQABAAE com.apple.InterfaceBuilder.IBCocoaTouchPlugin ChatRoomTableViewController com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin TPKeyboardAvoidingTableView @@ -558,7 +629,7 @@ AAgACAAIAAEAAQABAAE - 35 + 44 @@ -598,12 +669,22 @@ AAgACAAIAAEAAQABAAE + UILabel + UIImageView UIToggleButton UITextField UIButton ChatRoomTableViewController + + addressLabel + UILabel + + + avatarImage + UIImageView + editButton UIToggleButton @@ -653,6 +734,8 @@ AAgACAAIAAEAAQABAAE YES 3 + {262, 214} + {131, 131} {320, 117} {320, 117} {320, 117} diff --git a/Classes/ChatTableViewController.h b/Classes/ChatTableViewController.h index 9dfa4e7ef..3c61220fc 100644 --- a/Classes/ChatTableViewController.h +++ b/Classes/ChatTableViewController.h @@ -24,4 +24,6 @@ NSMutableArray *data; } +- (void)loadData; + @end diff --git a/Classes/ChatTableViewController.m b/Classes/ChatTableViewController.m index 30e900622..3e5431f17 100644 --- a/Classes/ChatTableViewController.m +++ b/Classes/ChatTableViewController.m @@ -91,9 +91,9 @@ ChatModel *chat = [data objectAtIndex:[indexPath row]]; // Go to ChatRoom view - ChatRoomTableViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeView:PhoneView_ChatRoom push:TRUE], ChatRoomTableViewController); + ChatRoomViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeView:PhoneView_ChatRoom push:TRUE], ChatRoomViewController); if(controller != nil) { - [controller setRemoteContact:[chat remoteContact]]; + [controller setRemoteAddress:[chat remoteContact]]; } } diff --git a/Classes/ChatViewController.m b/Classes/ChatViewController.m index 8afbf7dc6..d35917c48 100644 --- a/Classes/ChatViewController.m +++ b/Classes/ChatViewController.m @@ -61,7 +61,7 @@ if([tableController isEditing]) [tableController setEditing:FALSE animated:FALSE]; [editButton setOff]; - [[tableController tableView] reloadData]; + [tableController loadData]; } - (void)viewWillDisappear:(BOOL)animated { @@ -76,7 +76,7 @@ #pragma mark - Event Functions - (void)textReceivedEvent:(NSNotification *)notif { - [[tableController tableView] reloadData]; + [tableController loadData]; } diff --git a/Classes/HistoryDetailsViewController.m b/Classes/HistoryDetailsViewController.m index fb7101e0b..5822e5cc7 100644 --- a/Classes/HistoryDetailsViewController.m +++ b/Classes/HistoryDetailsViewController.m @@ -215,12 +215,11 @@ // Date NSDate *startData = [NSDate dateWithTimeIntervalSince1970:callLog->start_date_time]; NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; - [dateFormatter setTimeStyle:NSDateFormatterNoStyle]; + [dateFormatter setTimeStyle:NSDateFormatterMediumStyle]; [dateFormatter setDateStyle:NSDateFormatterMediumStyle]; - NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US"]; + NSLocale *locale = [NSLocale currentLocale]; [dateFormatter setLocale:locale]; [dateLabel setText:[dateFormatter stringFromDate:startData]]; - [locale release]; [dateFormatter release]; // Duration diff --git a/Classes/LinphoneApp.xib b/Classes/LinphoneApp.xib index ed352e92e..32ea92f39 100644 --- a/Classes/LinphoneApp.xib +++ b/Classes/LinphoneApp.xib @@ -42,10 +42,9 @@ {320, 480} - 1 - MSAxIDEAA + MCAxIDAuMTkxOTQ1NDc1NQA NO NO diff --git a/Classes/LinphoneAppDelegate.m b/Classes/LinphoneAppDelegate.m index 3233247dd..e0146a9de 100644 --- a/Classes/LinphoneAppDelegate.m +++ b/Classes/LinphoneAppDelegate.m @@ -209,13 +209,22 @@ int __aeabi_idiv(int a, int b) { } - (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification { - LinphoneCall* call; - [(NSData*)([notification.userInfo objectForKey:@"call"]) getBytes:&call]; - if (!call) { - [LinphoneLogger logc:LinphoneLoggerWarning format:"Local notification received with nil call"]; - return; + if([notification.userInfo objectForKey:@"call"] != nil) { + LinphoneCall* call; + [(NSData*)[notification.userInfo objectForKey:@"call"] getBytes:&call]; + if (!call) { + [LinphoneLogger logc:LinphoneLoggerWarning format:"Local notification received with nil call"]; + return; + } + linphone_core_accept_call([LinphoneManager getLc], call); + } else if([notification.userInfo objectForKey:@"chat"] != nil) { + NSString *remoteContact = (NSString*)[notification.userInfo objectForKey:@"chat"]; + // Go to ChatRoom view + ChatRoomViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeView:PhoneView_ChatRoom push:TRUE], ChatRoomViewController); + if(controller != nil) { + [controller setRemoteAddress:remoteContact]; + } } - linphone_core_accept_call([LinphoneManager getLc], call); } @end diff --git a/Classes/LinphoneManager.h b/Classes/LinphoneManager.h index 3fec4a53f..1f3c456ae 100644 --- a/Classes/LinphoneManager.h +++ b/Classes/LinphoneManager.h @@ -52,8 +52,7 @@ struct NetworkReachabilityContext { typedef struct _LinphoneCallAppData { bool_t batteryWarningShown; - // transfer data - int transferButtonIndex; + UILocalNotification *notification; } LinphoneCallAppData; @interface LinphoneManager : NSObject { diff --git a/Classes/LinphoneManager.m b/Classes/LinphoneManager.m index 021416385..9292eb920 100644 --- a/Classes/LinphoneManager.m +++ b/Classes/LinphoneManager.m @@ -265,6 +265,7 @@ static void linphone_iphone_display_status(struct _LinphoneCore * lc, const char if (!linphone_call_get_user_pointer(call)) { LinphoneCallAppData* data = (LinphoneCallAppData*) malloc(sizeof(LinphoneCallAppData)); data->batteryWarningShown = FALSE; + data->notification = nil; linphone_call_set_user_pointer(call, data); } @@ -317,7 +318,7 @@ static void linphone_iphone_registration_state(LinphoneCore *lc, LinphoneProxyCo // Save message in database ChatModel *chat = [[ChatModel alloc] init]; - [chat setRemoteContact:[NSString stringWithUTF8String:linphone_address_get_username(from)]]; + [chat setRemoteContact:[NSString stringWithUTF8String:linphone_address_as_string_uri_only(from)]]; [chat setMessage:[NSString stringWithUTF8String:message]]; [chat setDirection:[NSNumber numberWithInt:1]]; [chat setTime:[NSDate date]]; @@ -329,8 +330,10 @@ static void linphone_iphone_registration_state(LinphoneCore *lc, LinphoneProxyCo [NSValue valueWithPointer:room], @"room", [NSValue valueWithPointer:from], @"from", [NSString stringWithUTF8String:message], @"message", + chat, @"chat", nil] autorelease]; [[NSNotificationCenter defaultCenter] postNotificationName:@"LinphoneTextReceived" object:self userInfo:dict]; + [chat release]; } static void linphone_iphone_text_received(LinphoneCore *lc, LinphoneChatRoom *room, const LinphoneAddress *from, const char *message) { diff --git a/Classes/LinphoneUI/UIChatCell.h b/Classes/LinphoneUI/UIChatCell.h index 5f7bad19b..126310b04 100644 --- a/Classes/LinphoneUI/UIChatCell.h +++ b/Classes/LinphoneUI/UIChatCell.h @@ -23,7 +23,7 @@ @interface UIChatCell : UITableViewCell { UIImageView *avatarImage; - UILabel *displayNameLabel; + UILabel *addressLabel; UILabel *chatContentLabel; UIButton *detailsButton; UIButton *deleteButton; @@ -33,7 +33,7 @@ @property (nonatomic, retain) ChatModel *chat; @property (nonatomic, retain) IBOutlet UIImageView *avatarImage; -@property (nonatomic, retain) IBOutlet UILabel* displayNameLabel; +@property (nonatomic, retain) IBOutlet UILabel* addressLabel; @property (nonatomic, retain) IBOutlet UILabel* chatContentLabel; @property (nonatomic, retain) IBOutlet UIButton *detailsButton; @property (nonatomic, retain) IBOutlet UIButton * deleteButton; diff --git a/Classes/LinphoneUI/UIChatCell.m b/Classes/LinphoneUI/UIChatCell.m index dc98f86b6..522aabd62 100644 --- a/Classes/LinphoneUI/UIChatCell.m +++ b/Classes/LinphoneUI/UIChatCell.m @@ -19,12 +19,13 @@ #import "UIChatCell.h" #import "PhoneMainView.h" +#import "LinphoneManager.h" #import "Utils.h" @implementation UIChatCell @synthesize avatarImage; -@synthesize displayNameLabel; +@synthesize addressLabel; @synthesize chatContentLabel; @synthesize detailsButton; @synthesize deleteButton; @@ -47,7 +48,7 @@ } - (void)dealloc { - [displayNameLabel release]; + [addressLabel release]; [chatContentLabel release]; [avatarImage release]; [detailsButton release]; @@ -75,30 +76,50 @@ return; } - [avatarImage setImage:[UIImage imageNamed:@"avatar_unknown_small.png"]]; - [displayNameLabel setText:[chat remoteContact]]; + NSString *displayName = nil; + UIImage *image = nil; + NSString *normalizedSipAddress = [FastAddressBook normalizeSipURI:[chat remoteContact]]; + ABRecordRef contact =[[[LinphoneManager instance] fastAddressBook] getContact:normalizedSipAddress]; + if(contact != nil) { + displayName = [FastAddressBook getContactDisplayName:contact]; + image = [FastAddressBook getContactImage:contact thumbnail:true]; + } + + // Display name + if(displayName == nil) { + displayName = [chat remoteContact]; + } + [addressLabel setText:displayName]; + + // Avatar + if(image == nil) { + image = [UIImage imageNamed:@"avatar_unknown_small.png"]; + } + [avatarImage setImage:image]; + + // Message [chatContentLabel setText:[chat message]]; // // Adapt size // - CGRect displayNameFrame = [displayNameLabel frame]; + CGRect displayNameFrame = [addressLabel frame]; CGRect chatContentFrame = [chatContentLabel frame]; chatContentFrame.origin.x -= displayNameFrame.size.width; // Compute firstName size CGSize contraints; - contraints.height = [displayNameLabel frame].size.height; - contraints.width = ([chatContentLabel frame].size.width + [chatContentLabel frame].origin.x) - [displayNameLabel frame].origin.x; - CGSize firstNameSize = [[displayNameLabel text] sizeWithFont:[displayNameLabel font] constrainedToSize: contraints]; + contraints.height = [addressLabel frame].size.height; + contraints.width = ([chatContentLabel frame].size.width + [chatContentLabel frame].origin.x) - [addressLabel frame].origin.x; + CGSize firstNameSize = [[addressLabel text] sizeWithFont:[addressLabel font] constrainedToSize: contraints]; displayNameFrame.size.width = firstNameSize.width; // Compute lastName size & position chatContentFrame.origin.x += displayNameFrame.size.width; - chatContentFrame.size.width = (contraints.width + [displayNameLabel frame].origin.x) - chatContentFrame.origin.x; + chatContentFrame.size.width = (contraints.width + [addressLabel frame].origin.x) - chatContentFrame.origin.x; - [displayNameLabel setFrame: displayNameFrame]; + [addressLabel setFrame: displayNameFrame]; [chatContentLabel setFrame: chatContentFrame]; } @@ -129,7 +150,7 @@ // Go to Chat room view ChatRoomViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeView:PhoneView_ChatRoom push:TRUE], ChatRoomViewController); if(controller !=nil) { - [controller setRemoteContact:[chat remoteContact]]; + [controller setRemoteAddress:[chat remoteContact]]; } } diff --git a/Classes/LinphoneUI/UIChatCell.xib b/Classes/LinphoneUI/UIChatCell.xib index d64d8a989..92cdf036a 100644 --- a/Classes/LinphoneUI/UIChatCell.xib +++ b/Classes/LinphoneUI/UIChatCell.xib @@ -166,6 +166,7 @@ {{276, 0}, {44, 44}} + _NS:9 NO IBCocoaTouchFramework @@ -203,14 +204,6 @@ - - - displayNameLabel - - - - 23 - chatContentLabel @@ -243,6 +236,14 @@ 35 + + + addressLabel + + + + 38 + onDetailsClick: @@ -309,7 +310,7 @@ 20 - displayNameLabel + addressLabel 21 @@ -345,7 +346,7 @@ - 37 + 38 @@ -367,13 +368,17 @@ + UILabel UIImageView UILabel UIButton UIButton - UILabel + + addressLabel + UILabel + avatarImage UIImageView @@ -390,10 +395,6 @@ detailsButton UIButton - - displayNameLabel - UILabel - IBProjectSource diff --git a/Classes/LinphoneUI/UIChatRoomCell.h b/Classes/LinphoneUI/UIChatRoomCell.h index 2c24c3915..22891bdbb 100644 --- a/Classes/LinphoneUI/UIChatRoomCell.h +++ b/Classes/LinphoneUI/UIChatRoomCell.h @@ -24,17 +24,21 @@ @interface UIChatRoomCell : UITableViewCell { UIImageView *backgroundImage; UIView *contentView; + UIView *messageView; UILabel *messageLabel; UIButton *deleteButton; + UILabel *dateLabel; ChatModel *chat; } @property (nonatomic, retain) ChatModel *chat; @property (nonatomic, retain) IBOutlet UIView *contentView; +@property (nonatomic, retain) IBOutlet UIView *messageView; @property (nonatomic, retain) IBOutlet UIImageView* backgroundImage; @property (nonatomic, retain) IBOutlet UILabel *messageLabel; @property (nonatomic, retain) IBOutlet UIButton *deleteButton; +@property (nonatomic, retain) IBOutlet UILabel *dateLabel; - (id)initWithIdentifier:(NSString*)identifier; + (CGFloat)height:(ChatModel*)chat; diff --git a/Classes/LinphoneUI/UIChatRoomCell.m b/Classes/LinphoneUI/UIChatRoomCell.m index a18150915..4ce7739f2 100644 --- a/Classes/LinphoneUI/UIChatRoomCell.m +++ b/Classes/LinphoneUI/UIChatRoomCell.m @@ -25,9 +25,11 @@ @implementation UIChatRoomCell @synthesize contentView; +@synthesize messageView; @synthesize backgroundImage; @synthesize messageLabel; @synthesize deleteButton; +@synthesize dateLabel; @synthesize chat; static const CGFloat CELL_MIN_HEIGHT = 65.0f; @@ -50,8 +52,10 @@ static UIFont *CELL_FONT = nil; - (void)dealloc { [backgroundImage release]; [contentView release]; + [messageView release]; [messageLabel release]; [deleteButton release]; + [dateLabel release]; [chat release]; @@ -69,8 +73,10 @@ static UIFont *CELL_FONT = nil; [self update]; } - -#pragma mark - +- (void)prepareForReuse { + [super prepareForReuse]; + self->chat = nil; +} - (void)update { if(chat == nil) { @@ -78,6 +84,15 @@ static UIFont *CELL_FONT = nil; return; } [messageLabel setText:[chat message]]; + + // Date + NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; + [dateFormatter setTimeStyle:NSDateFormatterMediumStyle]; + [dateFormatter setDateStyle:NSDateFormatterMediumStyle]; + NSLocale *locale = [NSLocale currentLocale]; + [dateFormatter setLocale:locale]; + [dateLabel setText:[dateFormatter stringFromDate:[chat time]]]; + [dateFormatter release]; } - (void)setEditing:(BOOL)editing { @@ -110,20 +125,24 @@ static UIFont *CELL_FONT = nil; } if(chat != nil) { - if([chat direction]) { + CGPoint center = [contentView center]; + if(![[chat direction] intValue]) { // Inverted [backgroundImage setImage:[TUNinePatchCache imageOfSize:[backgroundImage bounds].size forNinePatchNamed:@"chat_bubble_incoming"]]; + center.y += 6; } else { [backgroundImage setImage:[TUNinePatchCache imageOfSize:[backgroundImage bounds].size forNinePatchNamed:@"chat_bubble_outgoing"]]; + center.y -= 6; } + [messageView setCenter:center]; } - // Resize message + // Resize messageView { - CGRect frame = [messageLabel frame]; - frame.size.height = [UIChatRoomCell messageHeight:[chat message]]; - [messageLabel setFrame:frame]; + CGRect frame = [messageView frame]; + frame.size.height = [UIChatRoomCell messageHeight:[chat message]] + 10; + [messageView setFrame:frame]; } } @@ -139,7 +158,7 @@ static UIFont *CELL_FONT = nil; + (CGFloat)height:(ChatModel*)chat { CGFloat height = [UIChatRoomCell messageHeight:[chat message]]; - height += 20; + height += 40; if(height < CELL_MIN_HEIGHT) height = CELL_MIN_HEIGHT; return height; @@ -158,9 +177,14 @@ static UIFont *CELL_FONT = nil; - (IBAction)onDeleteClick: (id) event { if(chat != NULL) { - [chat delete]; - UITableView *parentTable = (UITableView *)self.superview; - [parentTable reloadData]; + UIView *view = [self superview]; + // Find TableViewCell + if(view != nil && ![view isKindOfClass:[UITableView class]]) view = [view superview]; + if(view != nil) { + UITableView *tableView = (UITableView*) view; + NSIndexPath *indexPath = [tableView indexPathForCell:self]; + [[tableView dataSource] tableView:tableView commitEditingStyle:UITableViewCellEditingStyleDelete forRowAtIndexPath:indexPath]; + } } } diff --git a/Classes/LinphoneUI/UIChatRoomCell.xib b/Classes/LinphoneUI/UIChatRoomCell.xib index 5cc6c4476..3939cee62 100644 --- a/Classes/LinphoneUI/UIChatRoomCell.xib +++ b/Classes/LinphoneUI/UIChatRoomCell.xib @@ -59,7 +59,7 @@ 274 - {280, 100} + {280, 90} @@ -91,21 +91,22 @@ - 297 - {{236, 28}, {44, 44}} + 289 + {{236, 0}, {44, 44}} + _NS:9 NO IBCocoaTouchFramework 0 0 NO - 11 - 11 - 11 - 11 - + 2 + 20 + 20 + 2 + 3 MC41AA @@ -127,8 +128,37 @@ 16 + + + 265 + {{0, 90}, {280, 10}} + + + + _NS:9 + NO + YES + 7 + NO + IBCocoaTouchFramework + 09/09/2009 at 09:09 + + + 0 + 10 + 2 + + 1 + 12 + + + Helvetica + 12 + 16 + + - {{20, 25}, {280, 100}} + {{20, 20}, {280, 100}} @@ -152,21 +182,17 @@ IBCocoaTouchFramework - + 292 {100, 100} - - _NS:9 IBCocoaTouchFramework - + 292 {100, 100} - - _NS:9 IBCocoaTouchFramework @@ -222,6 +248,22 @@ 19 + + + messageView + + + + 21 + + + + dateLabel + + + + 24 + onDeleteClick: @@ -285,6 +327,7 @@ + messageView @@ -301,6 +344,12 @@ deleteButton + + 22 + + + timestampLabel + @@ -314,6 +363,7 @@ com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin @@ -322,7 +372,7 @@ - 20 + 24 @@ -343,8 +393,10 @@ UIImageView UIView + UILabel UIButton UILabel + UIView @@ -355,6 +407,10 @@ contentView UIView + + dateLabel + UILabel + deleteButton UIButton @@ -363,6 +419,10 @@ messageLabel UILabel + + messageView + UIView + IBProjectSource diff --git a/Classes/LinphoneUI/UIChatRoomHeader.h b/Classes/LinphoneUI/UIChatRoomHeader.h deleted file mode 100644 index 2af647bc9..000000000 --- a/Classes/LinphoneUI/UIChatRoomHeader.h +++ /dev/null @@ -1,37 +0,0 @@ -/* UIChatRoomHeader.h - * - * Copyright (C) 2012 Belledonne Comunications, Grenoble, France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#import -#import "ChatModel.h" - -@interface UIChatRoomHeader : UIViewController { - UILabel *addressLabel; - UIImageView *avatarImage; - - NSString *contact; -} - -@property (nonatomic, copy) NSString *contact; - -@property (nonatomic, retain) IBOutlet UILabel *addressLabel; -@property (nonatomic, retain) IBOutlet UIImageView *avatarImage; - -+ (CGFloat)height; - -@end diff --git a/Classes/LinphoneUI/UIChatRoomHeader.m b/Classes/LinphoneUI/UIChatRoomHeader.m deleted file mode 100644 index 6b862c155..000000000 --- a/Classes/LinphoneUI/UIChatRoomHeader.m +++ /dev/null @@ -1,71 +0,0 @@ -/* UIChatRoomHeader.m - * - * Copyright (C) 2012 Belledonne Comunications, Grenoble, France - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#import "UIChatRoomHeader.h" -#import "Utils.h" - -@implementation UIChatRoomHeader - -@synthesize avatarImage; -@synthesize addressLabel; -@synthesize contact; - - -#pragma mark - Lifecycle Functions - -- (id)init { - return [super initWithNibName:@"UIChatRoomHeader" bundle:[NSBundle mainBundle]]; -} - -- (void)dealloc { - [avatarImage release]; - [addressLabel release]; - [contact release]; - [super dealloc]; -} - - -#pragma mark - Property Functions - -- (void)setContact:(NSString *)acontact { - if(contact != nil) { - [contact release]; - } - contact = [acontact copy]; - [self update]; -} - - -#pragma mark - - -- (void)update { - if(contact == NULL) { - [LinphoneLogger logc:LinphoneLoggerWarning format:"Cannot update chat room header: null contact"]; - return; - } - - [avatarImage setImage:[UIImage imageNamed:@"avatar_unknown_small.png"]]; - [addressLabel setText:contact]; -} - -+ (CGFloat)height { - return 80.0f; -} - -@end diff --git a/Classes/LinphoneUI/UIChatRoomHeader.xib b/Classes/LinphoneUI/UIChatRoomHeader.xib deleted file mode 100644 index 7f6464409..000000000 --- a/Classes/LinphoneUI/UIChatRoomHeader.xib +++ /dev/null @@ -1,245 +0,0 @@ - - - - 1296 - 11D50 - 2182 - 1138.32 - 568.00 - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - 1181 - - - IBUIImageView - IBUIView - IBUILabel - IBProxyObject - - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - PluginDependencyRecalculationVersion - - - - - IBFilesOwner - IBCocoaTouchFramework - - - IBFirstResponder - IBCocoaTouchFramework - - - - 292 - - - - 292 - {{-13, -5}, {131, 107}} - - - - _NS:9 - NO - IBCocoaTouchFramework - - NSImage - avatar_shadow_small.png - - - - - 274 - {{20, 6}, {65, 65}} - - - - _NS:9 - NO - IBCocoaTouchFramework - - NSImage - avatar_unknown_small.png - - - - - 292 - {{101, 37}, {199, 43}} - - - - _NS:9 - NO - YES - 7 - NO - IBCocoaTouchFramework - Contact1 - - 3 - MC4zMzMzMzMzMzMzAA - - - 0 - 10 - - 1 - 22 - - - Helvetica - 22 - 16 - - - - {320, 80} - - - - _NS:9 - - 3 - MCAwAA - - IBCocoaTouchFramework - - - - - - - view - - - - 5 - - - - avatarImage - - - - 9 - - - - addressLabel - - - - 12 - - - - - - 0 - - - - - - -1 - - - File's Owner - - - -2 - - - - - 4 - - - - - - - - - - 6 - - - avatarImage - - - 7 - - - avatarShadowBackground - - - 8 - - - addressLabel - - - - - UIChatRoomHeader - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - UIResponder - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - - - - 12 - - - - - UIChatRoomHeader - UIViewController - - UILabel - UIImageView - - - - addressLabel - UILabel - - - avatarImage - UIImageView - - - - IBProjectSource - ./Classes/UIChatRoomHeader.h - - - - - 0 - IBCocoaTouchFramework - - com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS - - - YES - 3 - - {262, 214} - {131, 131} - - 1181 - - diff --git a/Classes/LinphoneUI/UICompositeViewController.m b/Classes/LinphoneUI/UICompositeViewController.m index 7279cef15..96687ab65 100644 --- a/Classes/LinphoneUI/UICompositeViewController.m +++ b/Classes/LinphoneUI/UICompositeViewController.m @@ -97,6 +97,38 @@ [super dealloc]; } + +#pragma mark - ViewController Functions + +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; + [contentViewController viewWillAppear:animated]; + [tabBarViewController viewWillAppear:animated]; + [stateBarViewController viewWillAppear:animated]; +} + +- (void)viewDidAppear:(BOOL)animated { + [super viewDidAppear:animated]; + [contentViewController viewDidAppear:animated]; + [tabBarViewController viewDidAppear:animated]; + [stateBarViewController viewDidAppear:animated]; +} + +- (void)viewWillDisappear:(BOOL)animated { + [super viewWillDisappear:animated]; + [contentViewController viewWillDisappear:animated]; + [tabBarViewController viewWillDisappear:animated]; + [stateBarViewController viewWillDisappear:animated]; +} + +- (void)viewDidDisappear:(BOOL)animated { + [super viewDidDisappear:animated]; + [contentViewController viewDidDisappear:animated]; + [tabBarViewController viewDidDisappear:animated]; + [stateBarViewController viewDidDisappear:animated]; +} + + #pragma mark - + (void)addSubView:(UIViewController*)controller view:(UIView*)view { diff --git a/Classes/LinphoneUI/UIHistoryCell.m b/Classes/LinphoneUI/UIHistoryCell.m index 5b6cefe12..631013361 100644 --- a/Classes/LinphoneUI/UIHistoryCell.m +++ b/Classes/LinphoneUI/UIHistoryCell.m @@ -136,6 +136,9 @@ address = [NSString stringWithUTF8String:lUserName]; } } + if(address == nil) { + address = @"Unknown"; + } [addressLabel setText:address]; [imageView setImage: image]; diff --git a/Classes/LinphoneUI/UIMainBar.m b/Classes/LinphoneUI/UIMainBar.m index b6c3237a3..a5c9eff9f 100644 --- a/Classes/LinphoneUI/UIMainBar.m +++ b/Classes/LinphoneUI/UIMainBar.m @@ -73,15 +73,11 @@ selector:@selector(textReceived:) name:@"LinphoneTextReceived" object:nil]; - - // Update current view - [self updateView:[[PhoneMainView instance] currentView]]; - if([LinphoneManager isLcReady]) { - [self updateMissedCall:linphone_core_get_missed_calls_count([LinphoneManager getLc])]; - } else { - [self updateMissedCall:0]; - } - [self updateUnreadMessage:[ChatModel unreadMessages]]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(applicationWillResignActive:) + name:UIApplicationWillResignActiveNotification + object:nil]; + [self update]; } - (void)viewWillDisappear:(BOOL)animated { @@ -96,75 +92,82 @@ [[NSNotificationCenter defaultCenter] removeObserver:self name:@"LinphoneTextReceived" object:nil]; + [[NSNotificationCenter defaultCenter] removeObserver:self + name:UIApplicationWillResignActiveNotification + object:nil]; } #pragma mark - Event Functions -- (void)callUpdate: (NSNotification*) notif { +- (void)applicationWillResignActive:(NSNotification*)notif { + // Refresh notifications + [historyNotificationView setHidden:TRUE]; + [chatNotificationView setHidden:TRUE]; + [self update]; +} + +- (void)callUpdate:(NSNotification*)notif { //LinphoneCall *call = [[notif.userInfo objectForKey: @"call"] pointerValue]; //LinphoneCallState state = [[notif.userInfo objectForKey: @"state"] intValue]; [self updateMissedCall:linphone_core_get_missed_calls_count([LinphoneManager getLc])]; } -- (void)changeViewEvent: (NSNotification*) notif { +- (void)changeViewEvent:(NSNotification*)notif { NSNumber *viewNumber = [notif.userInfo objectForKey: @"view"]; if(viewNumber != nil) [self updateView:[viewNumber intValue]]; } -- (void)textReceived: (NSNotification*) notif { +- (void)textReceived:(NSNotification*)notif { [self updateUnreadMessage:[ChatModel unreadMessages]]; } #pragma mark - -- (void)updateUnreadMessage:(int)unreadMessage { +- (void)update { + [self updateView:[[PhoneMainView instance] currentView]]; + if([LinphoneManager isLcReady]) { + [self updateMissedCall:linphone_core_get_missed_calls_count([LinphoneManager getLc])]; + } else { + [self updateMissedCall:0]; + } + [self updateUnreadMessage:[ChatModel unreadMessages]]; +} + +- (void)updateUnreadMessage:(int)unreadMessage{ if (unreadMessage > 0) { if([chatNotificationView isHidden]) { - chatNotificationView.transform = CGAffineTransformIdentity; - [self startBounceAnimation:@"Bounce" target:chatNotificationView]; [chatNotificationView setHidden:FALSE]; + [self appearAnimation:@"Appear" target:chatNotificationView completion:^(BOOL finished){ + [self startBounceAnimation:@"Bounce" target:chatNotificationView]; + }]; } [chatNotificationLabel setText:[NSString stringWithFormat:@"%i", unreadMessage]]; } else { if(![chatNotificationView isHidden]) { [self stopBounceAnimation:@"Bounce" target:chatNotificationView]; - CGAffineTransform startCGA = [chatNotificationView transform]; - [UIView animateWithDuration:0.4 - delay:0 - options:UIViewAnimationOptionCurveEaseOut | UIViewAnimationOptionAllowUserInteraction - animations:^{ - chatNotificationView.transform = CGAffineTransformConcat(startCGA, CGAffineTransformMakeScale(0.01f, 0.01f)); - } - completion:^(BOOL finished){ - [chatNotificationView setHidden:TRUE]; - } - ]; + [self disappearAnimation:@"Disappear" target:chatNotificationView completion:^(BOOL finished){ + [chatNotificationView setHidden:TRUE]; + }]; } } } -- (void)updateMissedCall:(int)missedCall { +- (void)updateMissedCall:(int)missedCall{ if (missedCall > 0) { if([historyNotificationView isHidden]) { - historyNotificationView.transform = CGAffineTransformIdentity; - [self startBounceAnimation:@"Bounce" target:historyNotificationView]; [historyNotificationView setHidden:FALSE]; + [self appearAnimation:@"Appear" target:historyNotificationView completion:^(BOOL finished){ + [self startBounceAnimation:@"Bounce" target:historyNotificationView]; + }]; } [historyNotificationLabel setText:[NSString stringWithFormat:@"%i", missedCall]]; } else { if(![historyNotificationView isHidden]) { [self stopBounceAnimation:@"Bounce" target:historyNotificationView]; - CGAffineTransform startCGA = [historyNotificationView transform]; - [UIView animateWithDuration:0.4 - delay:0 - options:UIViewAnimationOptionCurveEaseOut | UIViewAnimationOptionAllowUserInteraction - animations:^{ - historyNotificationView.transform = CGAffineTransformConcat(startCGA, CGAffineTransformMakeScale(0.01f, 0.01f)); - } - completion:^(BOOL finished){ + [self disappearAnimation:@"Disappear" target:historyNotificationView completion:^(BOOL finished){ [historyNotificationView setHidden:TRUE]; } ]; @@ -172,8 +175,30 @@ } } -- (void)startBounceAnimation:(NSString *)animationID target:(UIView *)target { - [target setTransform:CGAffineTransformMakeTranslation(0, -4)]; +- (void)appearAnimation:(NSString*)animationID target:(UIView*)target completion:(void (^)(BOOL finished))completion { + target.transform = CGAffineTransformMakeScale(0.01f, 0.01f); + [UIView animateWithDuration:0.4 + delay:0 + options:UIViewAnimationOptionCurveEaseOut | UIViewAnimationOptionAllowUserInteraction + animations:^{ + target.transform = CGAffineTransformIdentity; + } + completion:completion]; +} + +- (void)disappearAnimation:(NSString*)animationID target:(UIView*)target completion:(void (^)(BOOL finished))completion { + CGAffineTransform startCGA = [target transform]; + [UIView animateWithDuration:0.4 + delay:0 + options:UIViewAnimationOptionCurveEaseOut | UIViewAnimationOptionAllowUserInteraction + animations:^{ + target.transform = CGAffineTransformConcat(startCGA, CGAffineTransformMakeScale(0.01f, 0.01f)); + } + completion:completion]; +} + +- (void)startBounceAnimation:(NSString *)animationID target:(UIView *)target { + CGAffineTransform startCGA = [target transform]; [UIView animateWithDuration: 0.3 delay: 0 options: UIViewAnimationOptionRepeat | @@ -181,7 +206,7 @@ UIViewAnimationOptionAllowUserInteraction | UIViewAnimationOptionCurveEaseIn animations:^{ - [target setTransform:CGAffineTransformMakeTranslation(0, 4)]; + [target setTransform: CGAffineTransformConcat(startCGA, CGAffineTransformMakeTranslation(0, 8))]; } completion:^(BOOL finished){ }]; diff --git a/Classes/LinphoneUI/UIMainBar.xib b/Classes/LinphoneUI/UIMainBar.xib index 6330d597c..1b5260d8b 100644 --- a/Classes/LinphoneUI/UIMainBar.xib +++ b/Classes/LinphoneUI/UIMainBar.xib @@ -119,8 +119,8 @@ - 292 - {21, 21} + 256 + {{2, 2}, {17, 17}} @@ -150,7 +150,7 @@ - {{38, 5}, {21, 21}} + {{38, 1}, {21, 21}} @@ -309,10 +309,11 @@ - 292 - {21, 21} + 256 + {{2, 2}, {17, 17}} + _NS:9 NO YES @@ -329,7 +330,7 @@ - {{261, 5}, {21, 21}} + {{261, 1}, {21, 21}} diff --git a/Classes/Model/ChatModel.m b/Classes/Model/ChatModel.m index 575442316..e09d131e9 100644 --- a/Classes/Model/ChatModel.m +++ b/Classes/Model/ChatModel.m @@ -42,7 +42,7 @@ self.direction = [NSNumber numberWithInt:sqlite3_column_int(sqlStatement, 3)]; self.message = [NSString stringWithUTF8String: (const char*) sqlite3_column_text(sqlStatement, 4)]; self.time = [NSDate dateWithTimeIntervalSince1970:sqlite3_column_int(sqlStatement, 5)]; - self.read = [NSDate dateWithTimeIntervalSince1970:sqlite3_column_int(sqlStatement, 6)]; + self.read = [NSNumber numberWithInt:sqlite3_column_int(sqlStatement, 6)]; } return self; } @@ -80,6 +80,12 @@ [LinphoneLogger logc:LinphoneLoggerError format:"Error during execution of query: %s (%s)", sql, sqlite3_errmsg(database)]; sqlite3_finalize(sqlStatement); } + + if([self chatId] != nil) { + [self->chatId release]; + } + self->chatId = [[NSNumber alloc] initWithInt:sqlite3_last_insert_rowid(database)]; + sqlite3_finalize(sqlStatement); } + (ChatModel*)read:(NSNumber*)chatId { @@ -89,8 +95,8 @@ return nil; } - const char *sql = [[NSString stringWithFormat:@"SELECT id, localContact, remoteContact, direction, message, time, read FROM chat WHERE id=%@", - chatId] UTF8String]; + const char *sql = [[NSString stringWithFormat:@"SELECT id, localContact, remoteContact, direction, message, time, read FROM chat WHERE id=%i", + [chatId intValue]] UTF8String]; sqlite3_stmt *sqlStatement; if (sqlite3_prepare(database, sql, -1, &sqlStatement, NULL) != SQLITE_OK) { [LinphoneLogger logc:LinphoneLoggerError format:"Can't prepare the query: %s (%s)", sql, sqlite3_errmsg(database)]; @@ -118,8 +124,8 @@ return; } - const char *sql = [[NSString stringWithFormat:@"UPDATE chat SET localContact=\"%@\", remoteContact=\"%@\", direction=%i, message=\"%@\", time=%f, read=%i WHERE id=%@", - localContact, remoteContact, [direction intValue], message, [time timeIntervalSince1970], read, [chatId intValue]] UTF8String]; + const char *sql = [[NSString stringWithFormat:@"UPDATE chat SET localContact=\"%@\", remoteContact=\"%@\", direction=%i, message=\"%@\", time=%f, read=%i WHERE id=%i", + localContact, remoteContact, [direction intValue], message, [time timeIntervalSince1970], [read intValue], [chatId intValue]] UTF8String]; sqlite3_stmt *sqlStatement; if (sqlite3_prepare(database, sql, -1, &sqlStatement, NULL) != SQLITE_OK) { [LinphoneLogger logc:LinphoneLoggerError format:"Can't prepare the query: %s (%s)", sql, sqlite3_errmsg(database)]; @@ -142,8 +148,8 @@ return; } - const char *sql = [[NSString stringWithFormat:@"DELETE FROM chat WHERE id=%@", - chatId] UTF8String]; + const char *sql = [[NSString stringWithFormat:@"DELETE FROM chat WHERE id=%i", + [chatId intValue]] UTF8String]; sqlite3_stmt *sqlStatement; if (sqlite3_prepare(database, sql, -1, &sqlStatement, NULL) != SQLITE_OK) { [LinphoneLogger logc:LinphoneLoggerError format:"Can't prepare the query: %s (%s)", sql, sqlite3_errmsg(database)]; @@ -201,7 +207,7 @@ return array; } - const char *sql = [[NSString stringWithFormat:@"SELECT id, localContact, remoteContact, direction, message, time, read FROM chat WHERE remoteContact=\"%@\" ORDER BY time DESC", + const char *sql = [[NSString stringWithFormat:@"SELECT id, localContact, remoteContact, direction, message, time, read FROM chat WHERE remoteContact=\"%@\" ORDER BY time ASC", contact] UTF8String]; sqlite3_stmt *sqlStatement; if (sqlite3_prepare(database, sql, -1, &sqlStatement, NULL) != SQLITE_OK) { diff --git a/Classes/PhoneMainView.m b/Classes/PhoneMainView.m index e2077c354..94e6431e6 100644 --- a/Classes/PhoneMainView.m +++ b/Classes/PhoneMainView.m @@ -18,6 +18,7 @@ */ #import +#import #import "PhoneMainView.h" #import "Utils.h" @@ -108,6 +109,10 @@ static PhoneMainView* phoneMainViewInstance=nil; - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; + if ([[UIDevice currentDevice].systemVersion doubleValue] < 5.0) { + [mainViewController viewWillAppear:NO]; + } + // Set observers [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(callUpdate:) @@ -117,7 +122,10 @@ static PhoneMainView* phoneMainViewInstance=nil; selector:@selector(registrationUpdate:) name:@"LinphoneRegistrationUpdate" object:nil]; - + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(textReceived:) + name:@"LinphoneTextReceived" + object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(batteryLevelChanged:) name:UIDeviceBatteryLevelDidChangeNotification @@ -127,6 +135,10 @@ static PhoneMainView* phoneMainViewInstance=nil; - (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; + if ([[UIDevice currentDevice].systemVersion doubleValue] < 5.0) { + [mainViewController viewWillDisappear:NO]; + } + // Remove observers [[NSNotificationCenter defaultCenter] removeObserver:self name:@"LinphoneCallUpdate" @@ -134,11 +146,28 @@ static PhoneMainView* phoneMainViewInstance=nil; [[NSNotificationCenter defaultCenter] removeObserver:self name:@"LinphoneRegistrationUpdate" object:nil]; + [[NSNotificationCenter defaultCenter] removeObserver:self + name:@"LinphoneTextReceived" + object:nil]; [[NSNotificationCenter defaultCenter] removeObserver:self name:UIDeviceBatteryLevelDidChangeNotification object:nil]; } +- (void)viewDidAppear:(BOOL)animated { + [super viewDidAppear:animated]; + if ([[UIDevice currentDevice].systemVersion doubleValue] < 5.0) { + [mainViewController viewDidAppear:NO]; + } +} + +- (void)viewDidDisappear:(BOOL)animated { + [super viewDidDisappear:animated]; + if ([[UIDevice currentDevice].systemVersion doubleValue] < 5.0) { + [mainViewController viewDidDisappear:NO]; + } +} + - (void)viewDidUnload { [super viewDidUnload]; @@ -149,6 +178,13 @@ static PhoneMainView* phoneMainViewInstance=nil; #pragma mark - Event Functions +- (void)textReceived:(NSNotification*)notif { + ChatModel *chat = [[notif userInfo] objectForKey:@"chat"]; + if(chat != nil) { + [self displayMessage:chat]; + } +} + - (void)registrationUpdate:(NSNotification*)notif { LinphoneRegistrationState state = [[notif.userInfo objectForKey: @"state"] intValue]; LinphoneProxyConfig *cfg = [[notif.userInfo objectForKey: @"cfg"] pointerValue]; @@ -396,40 +432,89 @@ static PhoneMainView* phoneMainViewInstance=nil; } - (void)dismissIncomingCall:(LinphoneCall*)call { - //cancel local notification, just in case - if ([[UIDevice currentDevice] respondsToSelector:@selector(isMultitaskingSupported)] - && [UIApplication sharedApplication].applicationState == UIApplicationStateBackground) { - // cancel local notif if needed - [[UIApplication sharedApplication] cancelAllLocalNotifications]; - } -} + LinphoneCallAppData* appData = (LinphoneCallAppData*) linphone_call_get_user_pointer(call); + if(appData != nil && appData->notification != nil) { + // cancel local notif if needed + [[UIApplication sharedApplication] cancelLocalNotification:appData->notification]; + [appData->notification release]; + } +} #pragma mark - ActionSheet Functions -- (void)displayIncomingCall:(LinphoneCall*) call{ - - const char* userNameChars=linphone_address_get_username(linphone_call_get_remote_address(call)); - NSString* userName = userNameChars?[[[NSString alloc] initWithUTF8String:userNameChars] autorelease]:NSLocalizedString(@"Unknown",nil); - const char* displayNameChars = linphone_address_get_display_name(linphone_call_get_remote_address(call)); - NSString* displayName = [displayNameChars?[[NSString alloc] initWithUTF8String:displayNameChars]:@"" autorelease]; - - //TODO - //[mMainScreenWithVideoPreview showPreview:NO]; - if ([[UIDevice currentDevice] respondsToSelector:@selector(isMultitaskingSupported)] +- (void)displayMessage:(ChatModel*)chat { + if ([[UIDevice currentDevice] respondsToSelector:@selector(isMultitaskingSupported)] && [UIApplication sharedApplication].applicationState != UIApplicationStateActive) { + + NSString* address = [chat remoteContact]; + NSString *normalizedSipAddress = [FastAddressBook normalizeSipURI:address]; + ABRecordRef contact = [[[LinphoneManager instance] fastAddressBook] getContact:normalizedSipAddress]; + if(contact) { + address = [FastAddressBook getContactDisplayName:contact]; + } + if(address == nil) { + address = @"Unknown"; + } + // Create a new notification UILocalNotification* notif = [[[UILocalNotification alloc] init] autorelease]; - if (notif) - { + if (notif) { notif.repeatInterval = 0; - notif.alertBody =[NSString stringWithFormat:NSLocalizedString(@" %@ is calling you",nil),[displayName length]>0?displayName:userName]; - notif.alertAction = @"Answer"; - notif.soundName = @"oldphone-mono-30s.caf"; - NSData *callData = [NSData dataWithBytes:&call length:sizeof(call)]; - notif.userInfo = [NSDictionary dictionaryWithObject:callData forKey:@"call"]; + notif.alertBody = [NSString stringWithFormat:NSLocalizedString(@"%@ sent you a message",nil), address]; + notif.alertAction = NSLocalizedString(@"Show", nil); + notif.soundName = UILocalNotificationDefaultSoundName; + notif.userInfo = [NSDictionary dictionaryWithObject:[chat remoteContact] forKey:@"chat"]; - [[UIApplication sharedApplication] presentLocalNotificationNow:notif]; + [[UIApplication sharedApplication] presentLocalNotificationNow:notif]; + } + } else { + AudioServicesPlaySystemSound(kSystemSoundID_Vibrate); + } +} + +- (void)displayIncomingCall:(LinphoneCall*) call{ + LinphoneCallAppData* appData = (LinphoneCallAppData*) linphone_call_get_user_pointer(call); + if ([[UIDevice currentDevice] respondsToSelector:@selector(isMultitaskingSupported)] + && [UIApplication sharedApplication].applicationState != UIApplicationStateActive) { + + const LinphoneAddress *addr = linphone_call_get_remote_address(call); + NSString* address = nil; + if(addr != NULL) { + BOOL useLinphoneAddress = true; + // contact name + const char* lAddress = linphone_address_as_string_uri_only(addr); + if(lAddress) { + NSString *normalizedSipAddress = [FastAddressBook normalizeSipURI:[NSString stringWithUTF8String:lAddress]]; + ABRecordRef contact = [[[LinphoneManager instance] fastAddressBook] getContact:normalizedSipAddress]; + if(contact) { + address = [FastAddressBook getContactDisplayName:contact]; + useLinphoneAddress = false; + } + } + if(useLinphoneAddress) { + const char* lDisplayName = linphone_address_get_display_name(addr); + const char* lUserName = linphone_address_get_username(addr); + if (lDisplayName) + address = [NSString stringWithUTF8String:lDisplayName]; + else if(lUserName) + address = [NSString stringWithUTF8String:lUserName]; + } + } + if(address == nil) { + address = @"Unknown"; + } + + // Create a new notification + appData->notification = [[UILocalNotification alloc] init]; + if (appData->notification) { + appData->notification.repeatInterval = 0; + appData->notification.alertBody =[NSString stringWithFormat:NSLocalizedString(@" %@ is calling you",nil), address]; + appData->notification.alertAction = NSLocalizedString(@"Answer", nil); + appData->notification.soundName = @"oldphone-mono-30s.caf"; + appData->notification.userInfo = [NSDictionary dictionaryWithObject:[NSData dataWithBytes:&call length:sizeof(call)] forKey:@"call"]; + + [[UIApplication sharedApplication] presentLocalNotificationNow:appData->notification]; } } else { IncomingCallViewController *controller = [[IncomingCallViewController alloc] init]; diff --git a/Classes/PhoneMainView.xib b/Classes/PhoneMainView.xib index db8ede993..db9eb2b82 100644 --- a/Classes/PhoneMainView.xib +++ b/Classes/PhoneMainView.xib @@ -46,7 +46,6 @@ {320, 460} - _NS:9 NO IBCocoaTouchFramework @@ -62,11 +61,8 @@ _NS:9 - 3 - MQA - - 2 - + 1 + MSAwLjI4MzE1ODM3MjYgMC4wNTY3ODY4OTE2MQA IBCocoaTouchFramework @@ -132,7 +128,6 @@ - root 208 @@ -276,7 +271,7 @@ 3 background.png - {16, 16} + {640, 523} 1181 diff --git a/linphone.xcodeproj/project.pbxproj b/linphone.xcodeproj/project.pbxproj index cac80fa0c..6e90abf59 100755 --- a/linphone.xcodeproj/project.pbxproj +++ b/linphone.xcodeproj/project.pbxproj @@ -531,10 +531,6 @@ D3C6526E15AC228A0092A874 /* contact_ok_over.png in Resources */ = {isa = PBXBuildFile; fileRef = D3C6526A15AC228A0092A874 /* contact_ok_over.png */; }; D3C714B3159DB84400705B8E /* toy-mono.wav in Resources */ = {isa = PBXBuildFile; fileRef = D3C714B2159DB84400705B8E /* toy-mono.wav */; }; D3C714B4159DB84400705B8E /* toy-mono.wav in Resources */ = {isa = PBXBuildFile; fileRef = D3C714B2159DB84400705B8E /* toy-mono.wav */; }; - D3D14E7715A70EE30074A527 /* UIChatRoomHeader.m in Sources */ = {isa = PBXBuildFile; fileRef = D3D14E7515A70EE20074A527 /* UIChatRoomHeader.m */; }; - D3D14E7815A70EE30074A527 /* UIChatRoomHeader.m in Sources */ = {isa = PBXBuildFile; fileRef = D3D14E7515A70EE20074A527 /* UIChatRoomHeader.m */; }; - D3D14E7915A70EE30074A527 /* UIChatRoomHeader.xib in Resources */ = {isa = PBXBuildFile; fileRef = D3D14E7615A70EE30074A527 /* UIChatRoomHeader.xib */; }; - D3D14E7A15A70EE30074A527 /* UIChatRoomHeader.xib in Resources */ = {isa = PBXBuildFile; fileRef = D3D14E7615A70EE30074A527 /* UIChatRoomHeader.xib */; }; D3D14E7C15A711700074A527 /* avatar_shadow_small.png in Resources */ = {isa = PBXBuildFile; fileRef = D3D14E7B15A711700074A527 /* avatar_shadow_small.png */; }; D3D14E7D15A711700074A527 /* avatar_shadow_small.png in Resources */ = {isa = PBXBuildFile; fileRef = D3D14E7B15A711700074A527 /* avatar_shadow_small.png */; }; D3D6A39E159B0EEF005F692C /* add_call_default.png in Resources */ = {isa = PBXBuildFile; fileRef = D3D6A39B159B0EEF005F692C /* add_call_default.png */; }; @@ -1334,9 +1330,6 @@ D3C6526915AC228A0092A874 /* contact_ok_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = contact_ok_default.png; path = Resources/contact_ok_default.png; sourceTree = ""; }; D3C6526A15AC228A0092A874 /* contact_ok_over.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = contact_ok_over.png; path = Resources/contact_ok_over.png; sourceTree = ""; }; D3C714B2159DB84400705B8E /* toy-mono.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; name = "toy-mono.wav"; path = "Resources/toy-mono.wav"; sourceTree = ""; }; - D3D14E7415A70EE20074A527 /* UIChatRoomHeader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIChatRoomHeader.h; sourceTree = ""; }; - D3D14E7515A70EE20074A527 /* UIChatRoomHeader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIChatRoomHeader.m; sourceTree = ""; }; - D3D14E7615A70EE30074A527 /* UIChatRoomHeader.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = UIChatRoomHeader.xib; sourceTree = ""; }; D3D14E7B15A711700074A527 /* avatar_shadow_small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = avatar_shadow_small.png; path = Resources/avatar_shadow_small.png; sourceTree = ""; }; D3D6A39B159B0EEF005F692C /* add_call_default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = add_call_default.png; path = Resources/add_call_default.png; sourceTree = ""; }; D3D6A39C159B0EEF005F692C /* add_call_disabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = add_call_disabled.png; path = Resources/add_call_disabled.png; sourceTree = ""; }; @@ -1881,9 +1874,6 @@ D3A8BB6E15A6C7D500F96BE5 /* UIChatRoomCell.h */, D3A8BB6F15A6C7D500F96BE5 /* UIChatRoomCell.m */, D3A8BB7315A6C81A00F96BE5 /* UIChatRoomCell.xib */, - D3D14E7415A70EE20074A527 /* UIChatRoomHeader.h */, - D3D14E7515A70EE20074A527 /* UIChatRoomHeader.m */, - D3D14E7615A70EE30074A527 /* UIChatRoomHeader.xib */, D31B4B1E159876C0002E6C72 /* UICompositeViewController.h */, D31B4B1F159876C0002E6C72 /* UICompositeViewController.m */, D31B4B20159876C0002E6C72 /* UICompositeViewController.xib */, @@ -2798,7 +2788,6 @@ D3A8BB8315A6CC3200F96BE5 /* setup_start_disabled.png in Resources */, D389363915A6D53200A3A3AA /* chat_bubble_incoming.9.png in Resources */, D389363B15A6D53200A3A3AA /* chat_bubble_outgoing.9.png in Resources */, - D3D14E7915A70EE30074A527 /* UIChatRoomHeader.xib in Resources */, D3D14E7C15A711700074A527 /* avatar_shadow_small.png in Resources */, D3128FE315AABC7E00A2147A /* ContactDetailsViewController.xib in Resources */, D3128FEF15AABE4E00A2147A /* contact_back_default.png in Resources */, @@ -3049,7 +3038,6 @@ D3A8BB8415A6CC3200F96BE5 /* setup_start_disabled.png in Resources */, D389363A15A6D53200A3A3AA /* chat_bubble_incoming.9.png in Resources */, D389363C15A6D53200A3A3AA /* chat_bubble_outgoing.9.png in Resources */, - D3D14E7A15A70EE30074A527 /* UIChatRoomHeader.xib in Resources */, D3D14E7D15A711700074A527 /* avatar_shadow_small.png in Resources */, D3128FE415AABC7E00A2147A /* ContactDetailsViewController.xib in Resources */, D3128FF015AABE4E00A2147A /* contact_back_default.png in Resources */, @@ -3165,7 +3153,6 @@ D3A8BB7015A6C7D500F96BE5 /* UIChatRoomCell.m in Sources */, D389362615A6D19800A3A3AA /* CPAnimationSequence.m in Sources */, D389362815A6D19800A3A3AA /* CPAnimationStep.m in Sources */, - D3D14E7715A70EE30074A527 /* UIChatRoomHeader.m in Sources */, D3128FE115AABC7E00A2147A /* ContactDetailsViewController.m in Sources */, D37C639515AADDAF009D0BAC /* UIContactDetailsHeader.m in Sources */, D37C639B15AADEF6009D0BAC /* ContactDetailsTableViewController.m in Sources */, @@ -3255,7 +3242,6 @@ D3A8BB7115A6C7D500F96BE5 /* UIChatRoomCell.m in Sources */, D389362715A6D19800A3A3AA /* CPAnimationSequence.m in Sources */, D389362915A6D19800A3A3AA /* CPAnimationStep.m in Sources */, - D3D14E7815A70EE30074A527 /* UIChatRoomHeader.m in Sources */, D3128FE215AABC7E00A2147A /* ContactDetailsViewController.m in Sources */, D37C639615AADDAF009D0BAC /* UIContactDetailsHeader.m in Sources */, D37C639C15AADEF6009D0BAC /* ContactDetailsTableViewController.m in Sources */,