forked from mirrors/linphone-iphone
First version of internal storage use for iOS
This commit is contained in:
parent
9bd9152959
commit
4a136403b4
20 changed files with 376 additions and 765 deletions
|
|
@ -19,27 +19,28 @@
|
|||
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "ChatModel.h"
|
||||
#include "linphone/linphonecore.h"
|
||||
|
||||
@protocol ChatRoomDelegate <NSObject>
|
||||
|
||||
- (BOOL)chatRoomStartImageDownload:(NSURL*)url userInfo:(id)userInfo;
|
||||
- (BOOL)chatRoomStartImageUpload:(UIImage*)image url:(NSURL*)url;
|
||||
- (void)resendChat:(NSString*)message;
|
||||
- (void)resendChat:(NSString*)message withExternalUrl:(NSString*)url;
|
||||
|
||||
@end
|
||||
|
||||
@interface ChatRoomTableViewController : UITableViewController {
|
||||
@private
|
||||
NSMutableArray *data;
|
||||
LinphoneChatRoom* chatRoom;
|
||||
MSList *messageList;
|
||||
}
|
||||
|
||||
@property (nonatomic, copy) NSString *remoteAddress;
|
||||
@property (nonatomic, retain) id<ChatRoomDelegate> chatRoomDelegate;
|
||||
|
||||
- (void)addChatEntry:(ChatModel*)chat;
|
||||
- (void)addChatEntry:(LinphoneChatMessage*)chat;
|
||||
- (void)scrollToBottom:(BOOL)animated;
|
||||
- (void)scrollToLastUnread:(BOOL)animated;
|
||||
- (void)updateChatEntry:(ChatModel*)chat;
|
||||
- (void)updateChatEntry:(LinphoneChatMessage*)chat;
|
||||
- (void)setChatRoom:(LinphoneChatRoom*)room;
|
||||
|
||||
@end
|
||||
|
|
|
|||
|
|
@ -27,14 +27,13 @@
|
|||
|
||||
@implementation ChatRoomTableViewController
|
||||
|
||||
@synthesize remoteAddress;
|
||||
@synthesize chatRoomDelegate;
|
||||
|
||||
#pragma mark - Lifecycle Functions
|
||||
|
||||
- (void)dealloc {
|
||||
[remoteAddress release];
|
||||
[chatRoomDelegate release];
|
||||
[self clearMessageList];
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
|
@ -44,82 +43,98 @@
|
|||
- (void)viewWillDisappear:(BOOL)animated {
|
||||
[super viewWillDisappear:animated];
|
||||
[TUNinePatchCache flushCache]; // Clear cache
|
||||
if(data != nil) {
|
||||
[data removeAllObjects];
|
||||
[data release];
|
||||
data = nil;
|
||||
}
|
||||
[self clearMessageList];
|
||||
chatRoom = NULL;
|
||||
}
|
||||
- (void)viewWillAppear:(BOOL)animated {
|
||||
[self loadData];
|
||||
[self reloadData];
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
- (void)loadData {
|
||||
if(data != nil) {
|
||||
[data removeAllObjects];
|
||||
[data release];
|
||||
- (void)clearMessageList {
|
||||
if (messageList){
|
||||
ms_list_free_with_data(messageList, (void(*)(void*))linphone_chat_message_unref);
|
||||
messageList = nil;
|
||||
}
|
||||
data = [[ChatModel listMessages:remoteAddress] retain];
|
||||
[[self tableView] reloadData];
|
||||
}
|
||||
|
||||
- (void)updateData {
|
||||
if( !chatRoom ) return;
|
||||
[self clearMessageList];
|
||||
self->messageList = linphone_chat_room_get_history(chatRoom, 0);
|
||||
}
|
||||
|
||||
- (void)reloadData {
|
||||
[self updateData];
|
||||
[self.tableView reloadData];
|
||||
[self scrollToLastUnread:false];
|
||||
}
|
||||
|
||||
- (void)addChatEntry:(ChatModel*)chat {
|
||||
if(data == nil) {
|
||||
[LinphoneLogger logc:LinphoneLoggerWarning format:"Cannot add entry: null data"];
|
||||
return;
|
||||
}
|
||||
- (void)addChatEntry:(LinphoneChatMessage*)chat {
|
||||
|
||||
messageList = ms_list_append(messageList, chat);
|
||||
int pos = ms_list_size(messageList) - 1;
|
||||
|
||||
[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 insertRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:pos inSection:0]] withRowAnimation:UITableViewRowAnimationFade];
|
||||
[self.tableView endUpdates];
|
||||
}
|
||||
|
||||
- (void)updateChatEntry:(ChatModel*)chat {
|
||||
if(data == nil) {
|
||||
[LinphoneLogger logc:LinphoneLoggerWarning format:"Cannot update entry: null data"];
|
||||
return;
|
||||
}
|
||||
NSInteger index = [data indexOfObject:chat];
|
||||
- (void)updateChatEntry:(LinphoneChatMessage*)chat {
|
||||
NSInteger index = ms_list_index(self->messageList, chat);
|
||||
if (index<0) {
|
||||
[LinphoneLogger logc:LinphoneLoggerWarning format:"chat entries diesn not exixt"];
|
||||
[LinphoneLogger logc:LinphoneLoggerWarning format:"chat entry doesn't exist"];
|
||||
return;
|
||||
}
|
||||
[self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:index inSection:0]] withRowAnimation:FALSE];; //just reload
|
||||
[self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:index inSection:0]] withRowAnimation:FALSE]; //just reload
|
||||
return;
|
||||
}
|
||||
|
||||
- (void)scrollToBottom:(BOOL)animated {
|
||||
[self.tableView reloadData];
|
||||
if( [data count] ){
|
||||
[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:([data count] - 1) inSection:0]
|
||||
int count = ms_list_size(messageList);
|
||||
if( count ){
|
||||
[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:(count - 1) inSection:0]
|
||||
atScrollPosition:UITableViewScrollPositionBottom
|
||||
animated:YES];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)debugMessages {
|
||||
if( !messageList ){
|
||||
NSLog(@"No data to debug");
|
||||
return;
|
||||
}
|
||||
MSList*item = self->messageList;
|
||||
int count = 0;
|
||||
while (item) {
|
||||
LinphoneChatMessage* msg = (LinphoneChatMessage*)item->data;
|
||||
NSLog(@"Message %d: %s", count++, linphone_chat_message_get_text(msg));
|
||||
item = item->next;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)scrollToLastUnread:(BOOL)animated {
|
||||
if(data == nil) {
|
||||
[LinphoneLogger logc:LinphoneLoggerWarning format:"Cannot add entry: null data"];
|
||||
if(messageList == nil || chatRoom == nil) {
|
||||
return;
|
||||
}
|
||||
|
||||
int index = -1;
|
||||
int count = ms_list_size(messageList);
|
||||
// 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]];
|
||||
for(int i = 0; i <count; ++i) {
|
||||
int read = linphone_chat_message_is_read(ms_list_nth_data(messageList, i));
|
||||
if(read == 0) {
|
||||
if(index == -1)
|
||||
index = i;
|
||||
}
|
||||
}
|
||||
if(index == -1) {
|
||||
index = [data count] - 1;
|
||||
index = count - 1;
|
||||
}
|
||||
|
||||
linphone_chat_room_mark_as_read(chatRoom);
|
||||
|
||||
// Scroll to unread
|
||||
if(index >= 0) {
|
||||
|
|
@ -132,15 +147,11 @@
|
|||
|
||||
#pragma mark - Property Functions
|
||||
|
||||
- (void)setRemoteAddress:(NSString *)aremoteAddress {
|
||||
if(remoteAddress != nil) {
|
||||
[remoteAddress release];
|
||||
}
|
||||
self->remoteAddress = [aremoteAddress copy];
|
||||
[self loadData];
|
||||
- (void)setChatRoom:(LinphoneChatRoom*)room {
|
||||
chatRoom = room;
|
||||
[self reloadData];
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - UITableViewDataSource Functions
|
||||
|
||||
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
|
||||
|
|
@ -148,7 +159,7 @@
|
|||
}
|
||||
|
||||
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
|
||||
return [data count];
|
||||
return ms_list_size(self->messageList);
|
||||
}
|
||||
|
||||
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||
|
|
@ -157,8 +168,9 @@
|
|||
if (cell == nil) {
|
||||
cell = [[[UIChatRoomCell alloc] initWithIdentifier:kCellId] autorelease];
|
||||
}
|
||||
|
||||
[cell setChat:[data objectAtIndex:[indexPath row]]];
|
||||
|
||||
LinphoneChatMessage* chat = ms_list_nth_data(self->messageList, [indexPath row]);
|
||||
[cell setChatMessage:chat];
|
||||
[cell setChatRoomDelegate:chatRoomDelegate];
|
||||
return cell;
|
||||
}
|
||||
|
|
@ -169,11 +181,16 @@
|
|||
- (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:UITableViewRowAnimationBottom];
|
||||
LinphoneChatMessage *chat = ms_list_nth_data(self->messageList, [indexPath row]);
|
||||
if( chat ){
|
||||
|
||||
linphone_chat_room_delete_message(chatRoom, chat);
|
||||
messageList = ms_list_remove(messageList, chat);
|
||||
|
||||
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationBottom];
|
||||
}
|
||||
[tableView endUpdates];
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -186,8 +203,8 @@
|
|||
}
|
||||
|
||||
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||
ChatModel *chat = [data objectAtIndex:[indexPath row]];
|
||||
return [UIChatRoomCell height:chat width:[self.view frame].size.width];
|
||||
LinphoneChatMessage* message = ms_list_nth_data(self->messageList, [indexPath row]);
|
||||
return [UIChatRoomCell height:message width:[self.view frame].size.width];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@
|
|||
#import "UICompositeViewController.h"
|
||||
#import "ChatRoomTableViewController.h"
|
||||
#import "HPGrowingTextView.h"
|
||||
#import "ChatModel.h"
|
||||
#import "ImagePickerViewController.h"
|
||||
#import "ImageSharing.h"
|
||||
#import "OrderedDictionary.h"
|
||||
|
|
@ -53,7 +52,6 @@
|
|||
@property (retain, nonatomic) IBOutlet UILabel *composeLabel;
|
||||
@property (retain, nonatomic) IBOutlet UIView *composeIndicatorView;
|
||||
|
||||
@property (nonatomic, copy) NSString *remoteAddress;
|
||||
@property (nonatomic, retain) IBOutlet UIButton* pictureButton;
|
||||
@property (nonatomic, retain) IBOutlet UIButton* cancelTransferButton;
|
||||
@property (nonatomic, retain) IBOutlet UIProgressView* imageTransferProgressBar;
|
||||
|
|
@ -68,4 +66,6 @@
|
|||
- (IBAction)onTransferCancelClick:(id)event;
|
||||
- (IBAction)onListTap:(id)sender;
|
||||
|
||||
- (void)setChatRoom:(LinphoneChatRoom*)room;
|
||||
|
||||
@end
|
||||
|
|
|
|||
|
|
@ -32,7 +32,6 @@
|
|||
@synthesize sendButton;
|
||||
@synthesize messageField;
|
||||
@synthesize editButton;
|
||||
@synthesize remoteAddress;
|
||||
@synthesize addressLabel;
|
||||
@synthesize composeLabel;
|
||||
@synthesize composeIndicatorView;
|
||||
|
|
@ -73,7 +72,6 @@
|
|||
[messageField release];
|
||||
[sendButton release];
|
||||
[editButton release];
|
||||
[remoteAddress release];
|
||||
[addressLabel release];
|
||||
[avatarImage release];
|
||||
[headerView release];
|
||||
|
|
@ -245,49 +243,32 @@ static UICompositeViewDescription *compositeDescription = nil;
|
|||
|
||||
#pragma mark -
|
||||
|
||||
- (void)setRemoteAddress:(NSString*)aRemoteAddress {
|
||||
if(remoteAddress != nil) {
|
||||
[remoteAddress release];
|
||||
}
|
||||
if ([aRemoteAddress hasPrefix:@"sip:"] || [aRemoteAddress hasPrefix:@"sips:"]) {
|
||||
remoteAddress = [aRemoteAddress copy];
|
||||
} else {
|
||||
char normalizedUserName[256];
|
||||
LinphoneCore *lc = [LinphoneManager getLc];
|
||||
LinphoneProxyConfig* proxyCfg;
|
||||
linphone_core_get_default_proxy(lc,&proxyCfg);
|
||||
LinphoneAddress* linphoneAddress = linphone_address_new(linphone_core_get_identity(lc));
|
||||
linphone_proxy_config_normalize_number(proxyCfg, [aRemoteAddress cStringUsingEncoding:[NSString defaultCStringEncoding]], normalizedUserName, sizeof(normalizedUserName));
|
||||
linphone_address_set_username(linphoneAddress, normalizedUserName);
|
||||
remoteAddress = [[NSString stringWithUTF8String:linphone_address_as_string_uri_only(linphoneAddress)] copy];
|
||||
linphone_address_destroy(linphoneAddress);
|
||||
}
|
||||
- (void)setChatRoom:(LinphoneChatRoom *)room {
|
||||
self->chatRoom = room;
|
||||
[messageField setText:@""];
|
||||
|
||||
chatRoom = linphone_core_get_or_create_chat_room([LinphoneManager getLc], [remoteAddress cStringUsingEncoding:[NSString defaultCStringEncoding]]);
|
||||
[tableController setChatRoom:room];
|
||||
[self update];
|
||||
[tableController setRemoteAddress: remoteAddress];
|
||||
[ChatModel readConversation:remoteAddress];
|
||||
linphone_chat_room_mark_as_read(chatRoom);
|
||||
[self setComposingVisible:linphone_chat_room_is_remote_composing(chatRoom) withDelay:0];
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneTextReceived object:self];
|
||||
}
|
||||
|
||||
- (void)applicationWillEnterForeground:(NSNotification*)notif {
|
||||
if(remoteAddress != nil) {
|
||||
[ChatModel readConversation:remoteAddress];
|
||||
if(chatRoom != nil) {
|
||||
linphone_chat_room_mark_as_read(chatRoom);
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneTextReceived object:self];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)update {
|
||||
if(remoteAddress == NULL) {
|
||||
if(chatRoom == NULL) {
|
||||
[LinphoneLogger logc:LinphoneLoggerWarning format:"Cannot update chat room header: null contact"];
|
||||
return;
|
||||
}
|
||||
|
||||
NSString *displayName = nil;
|
||||
UIImage *image = nil;
|
||||
LinphoneAddress* linphoneAddress = linphone_core_interpret_url([LinphoneManager getLc], [remoteAddress UTF8String]);
|
||||
const LinphoneAddress* linphoneAddress = linphone_chat_room_get_peer_address(chatRoom);
|
||||
if (linphoneAddress == NULL) {
|
||||
[[PhoneMainView instance] popCurrentView];
|
||||
UIAlertView* error = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Invalid SIP address",nil)
|
||||
|
|
@ -308,8 +289,6 @@ static UICompositeViewDescription *compositeDescription = nil;
|
|||
displayName = [FastAddressBook getContactDisplayName:acontact];
|
||||
image = [FastAddressBook getContactImage:acontact thumbnail:true];
|
||||
}
|
||||
[remoteAddress release];
|
||||
remoteAddress = [normalizedSipAddress retain];
|
||||
|
||||
// Display name
|
||||
if(displayName == nil) {
|
||||
|
|
@ -323,61 +302,33 @@ static UICompositeViewDescription *compositeDescription = nil;
|
|||
}
|
||||
[avatarImage setImage:image];
|
||||
|
||||
linphone_address_destroy(linphoneAddress);
|
||||
}
|
||||
|
||||
static void message_status(LinphoneChatMessage* msg,LinphoneChatMessageState state,void* ud) {
|
||||
ChatRoomViewController* thiz = (ChatRoomViewController*)ud;
|
||||
ChatModel *chat = (ChatModel *)linphone_chat_message_get_user_data(msg);
|
||||
const char*text = linphone_chat_message_get_text(msg);
|
||||
[LinphoneLogger log:LinphoneLoggerLog
|
||||
format:@"Delivery status for [%@] is [%s]",(chat.message?chat.message:@""),linphone_chat_message_state_to_string(state)];
|
||||
[chat setState:[NSNumber numberWithInt:state]];
|
||||
[chat update];
|
||||
[thiz.tableController updateChatEntry:chat];
|
||||
if (state != LinphoneChatMessageStateInProgress) {
|
||||
linphone_chat_message_set_user_data(msg, NULL);
|
||||
[chat release]; // no longuer need to keep reference
|
||||
}
|
||||
|
||||
format:@"Delivery status for [%s] is [%s]",text,linphone_chat_message_state_to_string(state)];
|
||||
[thiz.tableController updateChatEntry:msg];
|
||||
}
|
||||
|
||||
- (BOOL)sendMessage:(NSString *)message withExterlBodyUrl:(NSURL*)externalUrl withInternalUrl:(NSURL*)internalUrl {
|
||||
- (BOOL)sendMessage:(NSString *)message withExterlBodyUrl:(NSURL*)externalUrl {
|
||||
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"];
|
||||
if(chatRoom == NULL) {
|
||||
[LinphoneLogger logc:LinphoneLoggerWarning format:"Cannot send message: No chatroom"];
|
||||
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 setLocalContact:@""];
|
||||
if(internalUrl == nil) {
|
||||
[chat setMessage:message];
|
||||
} else {
|
||||
[chat setMessage:[internalUrl absoluteString]];
|
||||
}
|
||||
[chat setDirection:[NSNumber numberWithInt:0]];
|
||||
[chat setTime:[NSDate date]];
|
||||
[chat setRead:[NSNumber numberWithInt:1]];
|
||||
[chat setState:[NSNumber numberWithInt:1]]; //INPROGRESS
|
||||
[chat create];
|
||||
[tableController addChatEntry:chat];
|
||||
[tableController scrollToBottom:true];
|
||||
[chat release];
|
||||
|
||||
LinphoneChatMessage* msg = linphone_chat_room_create_message(chatRoom, [message UTF8String]);
|
||||
linphone_chat_message_set_user_data(msg, [chat retain]);
|
||||
if(externalUrl) {
|
||||
linphone_chat_message_set_external_body_url(msg, [[externalUrl absoluteString] UTF8String]);
|
||||
}
|
||||
[tableController addChatEntry:linphone_chat_message_ref(msg)];
|
||||
linphone_chat_room_send_message2(chatRoom, msg, message_status, self);
|
||||
[tableController scrollToBottom:true];
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
@ -476,29 +427,31 @@ static void message_status(LinphoneChatMessage* msg,LinphoneChatMessageState sta
|
|||
}
|
||||
|
||||
- (void)textReceivedEvent:(NSNotification *)notif {
|
||||
//LinphoneChatRoom *room = [[[notif userInfo] objectForKey:@"room"] pointerValue];
|
||||
//NSString *message = [[notif userInfo] objectForKey:@"message"];
|
||||
LinphoneAddress *from = [[[notif userInfo] objectForKey:@"from"] pointerValue];
|
||||
|
||||
ChatModel *chat = [[notif userInfo] objectForKey:@"chat"];
|
||||
LinphoneAddress * from = [[[notif userInfo] objectForKey:@"from_address"] pointerValue];
|
||||
LinphoneChatRoom* room = [[notif.userInfo objectForKey:@"room"] pointerValue];
|
||||
LinphoneChatMessage* chat = [[notif.userInfo objectForKey:@"message"] pointerValue];
|
||||
|
||||
if(from == NULL || chat == NULL) {
|
||||
return;
|
||||
}
|
||||
char *fromStr = linphone_address_as_string_uri_only(from);
|
||||
if(fromStr != NULL) {
|
||||
if([[NSString stringWithUTF8String:fromStr]
|
||||
caseInsensitiveCompare:remoteAddress] == NSOrderedSame) {
|
||||
const LinphoneAddress* cr_from = linphone_chat_room_get_peer_address(chatRoom);
|
||||
char* cr_from_string = linphone_address_as_string_uri_only(cr_from);
|
||||
|
||||
if(fromStr && cr_from_string ) {
|
||||
|
||||
if(strcasecmp(cr_from_string, fromStr) == 0) {
|
||||
if (![[UIDevice currentDevice] respondsToSelector:@selector(isMultitaskingSupported)]
|
||||
|| [UIApplication sharedApplication].applicationState == UIApplicationStateActive) {
|
||||
[chat setRead:[NSNumber numberWithInt:1]];
|
||||
[chat update];
|
||||
linphone_chat_room_mark_as_read(room);
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneTextReceived object:self];
|
||||
}
|
||||
[tableController addChatEntry:chat];
|
||||
[tableController scrollToLastUnread:TRUE];
|
||||
}
|
||||
ms_free(fromStr);
|
||||
}
|
||||
ms_free(fromStr);
|
||||
ms_free(cr_from_string);
|
||||
}
|
||||
|
||||
- (void)textComposeEvent:(NSNotification*)notif {
|
||||
|
|
@ -577,7 +530,7 @@ static void message_status(LinphoneChatMessage* msg,LinphoneChatMessageState sta
|
|||
}
|
||||
|
||||
- (IBAction)onSendClick:(id)event {
|
||||
if([self sendMessage:[messageField text] withExterlBodyUrl:nil withInternalUrl:nil]) {
|
||||
if([self sendMessage:[messageField text] withExterlBodyUrl:nil]) {
|
||||
scrollOnGrowingEnabled = FALSE;
|
||||
[messageField setText:@""];
|
||||
scrollOnGrowingEnabled = TRUE;
|
||||
|
|
@ -673,8 +626,8 @@ static void message_status(LinphoneChatMessage* msg,LinphoneChatMessageState sta
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
- (void)resendChat:(NSString *)message {
|
||||
[self sendMessage:message withExterlBodyUrl:nil withInternalUrl:nil];
|
||||
- (void)resendChat:(NSString *)message withExternalUrl:(NSString *)url {
|
||||
[self sendMessage:message withExterlBodyUrl:[NSURL URLWithString:url]];
|
||||
}
|
||||
|
||||
#pragma mark ImageSharingDelegate
|
||||
|
|
@ -717,9 +670,7 @@ static void message_status(LinphoneChatMessage* msg,LinphoneChatMessageState sta
|
|||
}
|
||||
|
||||
- (void)imageSharingUploadDone:(ImageSharing*)aimageSharing url:(NSURL*)url{
|
||||
NSURL *imageURL = [aimageSharing userInfo];
|
||||
|
||||
[self sendMessage:nil withExterlBodyUrl:url withInternalUrl:imageURL];
|
||||
[self sendMessage:nil withExterlBodyUrl:url];
|
||||
|
||||
[messageView setHidden:FALSE];
|
||||
[transferView setHidden:TRUE];
|
||||
|
|
@ -730,7 +681,7 @@ static void message_status(LinphoneChatMessage* msg,LinphoneChatMessageState sta
|
|||
[messageView setHidden:FALSE];
|
||||
[transferView setHidden:TRUE];
|
||||
|
||||
ChatModel *chat = (ChatModel *)[imageSharing userInfo];
|
||||
__block LinphoneChatMessage *chat = (LinphoneChatMessage *)[(NSValue*)[imageSharing userInfo] pointerValue];
|
||||
[[LinphoneManager instance].photoLibrary writeImageToSavedPhotosAlbum:image.CGImage
|
||||
orientation:(ALAssetOrientation)[image imageOrientation]
|
||||
completionBlock:^(NSURL *assetURL, NSError *error){
|
||||
|
|
@ -747,8 +698,8 @@ static void message_status(LinphoneChatMessage* msg,LinphoneChatMessageState sta
|
|||
return;
|
||||
}
|
||||
[LinphoneLogger log:LinphoneLoggerLog format:@"Image saved to [%@]", [assetURL absoluteString]];
|
||||
[chat setMessage:[assetURL absoluteString]];
|
||||
[chat update];
|
||||
linphone_chat_message_set_external_body_url(chat, [[assetURL absoluteString] UTF8String]);
|
||||
linphone_chat_room_update_url(chatRoom, chat);
|
||||
[tableController updateChatEntry:chat];
|
||||
}];
|
||||
imageSharing = nil;
|
||||
|
|
|
|||
|
|
@ -18,12 +18,10 @@
|
|||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#include "linphone/linphonecore.h"
|
||||
|
||||
@interface ChatTableViewController : UITableViewController {
|
||||
@private
|
||||
NSMutableArray *data;
|
||||
}
|
||||
|
||||
- (void)loadData;
|
||||
|
||||
@end
|
||||
|
|
|
|||
|
|
@ -26,14 +26,15 @@
|
|||
#import "UILinphone.h"
|
||||
#import "Utils.h"
|
||||
|
||||
@implementation ChatTableViewController
|
||||
@implementation ChatTableViewController {
|
||||
@private
|
||||
MSList* data;
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - Lifecycle Functions
|
||||
|
||||
- (void)dealloc {
|
||||
if(data != nil)
|
||||
[data release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
|
|
@ -49,9 +50,7 @@
|
|||
#pragma mark -
|
||||
|
||||
- (void)loadData {
|
||||
if(data != nil)
|
||||
[data release];
|
||||
data = [[ChatModel listConversations] retain];
|
||||
data = linphone_core_get_chat_rooms([LinphoneManager getLc]);
|
||||
[[self tableView] reloadData];
|
||||
}
|
||||
|
||||
|
|
@ -62,7 +61,7 @@
|
|||
}
|
||||
|
||||
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
|
||||
return [data count];
|
||||
return ms_list_size(data);
|
||||
}
|
||||
|
||||
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||
|
|
@ -78,7 +77,7 @@
|
|||
[selectedBackgroundView setBackgroundColor:LINPHONE_TABLE_CELL_BACKGROUND_COLOR];
|
||||
}
|
||||
|
||||
[cell setChat:[data objectAtIndex:[indexPath row]]];
|
||||
[cell setChatRoom:(LinphoneChatRoom*)ms_list_nth_data(data, [indexPath row])];
|
||||
|
||||
return cell;
|
||||
}
|
||||
|
|
@ -88,12 +87,12 @@
|
|||
|
||||
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||
[tableView deselectRowAtIndexPath:indexPath animated:NO];
|
||||
ChatModel *chat = [data objectAtIndex:[indexPath row]];
|
||||
LinphoneChatRoom *chatRoom = (LinphoneChatRoom*)ms_list_nth_data(data, [indexPath row]);
|
||||
|
||||
// Go to ChatRoom view
|
||||
ChatRoomViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:[ChatRoomViewController compositeViewDescription] push:TRUE], ChatRoomViewController);
|
||||
if(controller != nil) {
|
||||
[controller setRemoteAddress:[chat remoteContact]];
|
||||
[controller setChatRoom:chatRoom];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -108,9 +107,12 @@
|
|||
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||
if(editingStyle == UITableViewCellEditingStyleDelete) {
|
||||
[tableView beginUpdates];
|
||||
ChatModel *chat = [data objectAtIndex:[indexPath row]];
|
||||
[ChatModel removeConversation:[chat remoteContact]];
|
||||
[data removeObjectAtIndex:[indexPath row]];
|
||||
|
||||
LinphoneChatRoom *chatRoom = (LinphoneChatRoom*)ms_list_nth_data(data, [indexPath row]);
|
||||
linphone_chat_room_delete_history(chatRoom);
|
||||
linphone_chat_room_destroy(chatRoom);
|
||||
data = linphone_core_get_chat_rooms([LinphoneManager getLc]);
|
||||
|
||||
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
|
||||
[tableView endUpdates];
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneTextReceived object:self];
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@
|
|||
#import "ChatViewController.h"
|
||||
#import "PhoneMainView.h"
|
||||
|
||||
#import "ChatModel.h"
|
||||
@implementation ChatViewController
|
||||
|
||||
@synthesize tableController;
|
||||
|
|
@ -113,7 +112,8 @@ static UICompositeViewDescription *compositeDescription = nil;
|
|||
//Push ChatRoom
|
||||
ChatRoomViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:[ChatRoomViewController compositeViewDescription] push:TRUE], ChatRoomViewController);
|
||||
if(controller != nil) {
|
||||
[controller setRemoteAddress:[addressField text]];
|
||||
LinphoneChatRoom* room = linphone_core_get_or_create_chat_room([LinphoneManager getLc], [addressField.text UTF8String]);
|
||||
[controller setChatRoom:room];
|
||||
}
|
||||
addressField.text = @"";
|
||||
|
||||
|
|
|
|||
|
|
@ -651,7 +651,8 @@ static const ContactSections_e contactSections[ContactSections_MAX] = {ContactSe
|
|||
[[PhoneMainView instance] popToView:[ChatViewController compositeViewDescription]]; // Got to Chat and push ChatRoom
|
||||
ChatRoomViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:[ChatRoomViewController compositeViewDescription] push:TRUE], ChatRoomViewController);
|
||||
if(controller != nil) {
|
||||
[controller setRemoteAddress:dest];
|
||||
LinphoneChatRoom* room = linphone_core_get_or_create_chat_room([LinphoneManager getLc], [dest UTF8String]);
|
||||
[controller setChatRoom:room];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -401,7 +401,8 @@ static UICompositeViewDescription *compositeDescription = nil;
|
|||
[[PhoneMainView instance] changeCurrentView:[ChatViewController compositeViewDescription]];
|
||||
ChatRoomViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:[ChatRoomViewController compositeViewDescription] push:TRUE], ChatRoomViewController);
|
||||
if(controller != nil) {
|
||||
[controller setRemoteAddress:[NSString stringWithUTF8String:lAddress]];
|
||||
LinphoneChatRoom* room = linphone_core_get_or_create_chat_room([LinphoneManager getLc], lAddress);
|
||||
[controller setChatRoom:room];
|
||||
}
|
||||
ms_free(lAddress);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -256,6 +256,20 @@
|
|||
[self processRemoteNotification:userInfo];
|
||||
}
|
||||
|
||||
- (LinphoneChatRoom*)findChatRoomForContact:(NSString*)contact {
|
||||
MSList* rooms = linphone_core_get_chat_rooms([LinphoneManager getLc]);
|
||||
const char* from = [contact UTF8String];
|
||||
while (rooms) {
|
||||
const LinphoneAddress* room_from_address = linphone_chat_room_get_peer_address((LinphoneChatRoom*)rooms->data);
|
||||
char* room_from = linphone_address_as_string_uri_only(room_from_address);
|
||||
if( room_from && strcmp(from, room_from)== 0){
|
||||
return rooms->data;
|
||||
}
|
||||
rooms = rooms->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification {
|
||||
|
||||
[self fixRing];
|
||||
|
|
@ -269,13 +283,14 @@
|
|||
// auto answer only for non-timed local notifications
|
||||
[[LinphoneManager instance] acceptCallForCallId:[notification.userInfo objectForKey:@"callId"]];
|
||||
}
|
||||
} else if([notification.userInfo objectForKey:@"chat"] != nil) {
|
||||
NSString *remoteContact = (NSString*)[notification.userInfo objectForKey:@"chat"];
|
||||
} else if([notification.userInfo objectForKey:@"from"] != nil) {
|
||||
NSString *remoteContact = (NSString*)[notification.userInfo objectForKey:@"from"];
|
||||
// Go to ChatRoom view
|
||||
[[PhoneMainView instance] changeCurrentView:[ChatViewController compositeViewDescription]];
|
||||
ChatRoomViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:[ChatRoomViewController compositeViewDescription] push:TRUE], ChatRoomViewController);
|
||||
if(controller != nil) {
|
||||
[controller setRemoteAddress:remoteContact];
|
||||
LinphoneChatRoom*room = [self findChatRoomForContact:remoteContact];
|
||||
[controller setChatRoom:room];
|
||||
}
|
||||
} else if([notification.userInfo objectForKey:@"callLog"] != nil) {
|
||||
NSString *callLog = (NSString*)[notification.userInfo objectForKey:@"callLog"];
|
||||
|
|
|
|||
|
|
@ -128,6 +128,7 @@ typedef struct _LinphoneManagerSounds {
|
|||
+ (BOOL)isCodecSupported: (const char*)codecName;
|
||||
+ (NSSet *)unsupportedCodecs;
|
||||
+ (NSString *)getUserAgent;
|
||||
+ (int)unreadMessageCount;
|
||||
|
||||
|
||||
- (void)resetLinphoneCore;
|
||||
|
|
|
|||
|
|
@ -29,7 +29,6 @@
|
|||
|
||||
#import "LinphoneManager.h"
|
||||
#import "LinphoneCoreSettingsStore.h"
|
||||
#import "ChatModel.h"
|
||||
|
||||
#include "linphone/linphonecore_utils.h"
|
||||
#include "linphone/lpconfig.h"
|
||||
|
|
@ -76,6 +75,9 @@ extern void libmsbcg729_init(void);
|
|||
#define BACK_CAM_NAME "AV Capture: com.apple.avfoundation.avcapturedevice.built-in_video:0" /*"AV Capture: Back Camera"*/
|
||||
|
||||
|
||||
NSString *const kLinphoneOldChatDBFilename = @"chat_database.sqlite";
|
||||
NSString *const kLinphoneInternalChatDBFilename = @"linphone_chats.db";
|
||||
|
||||
@implementation LinphoneCallAppData
|
||||
- (id)init {
|
||||
if ((self = [super init])) {
|
||||
|
|
@ -261,7 +263,6 @@ struct codec_name_pref_table codec_pref_table[]={
|
|||
speakerEnabled = FALSE;
|
||||
bluetoothEnabled = FALSE;
|
||||
tunnelMode = FALSE;
|
||||
[self openDatabase];
|
||||
[self copyDefaultSettings];
|
||||
pendindCallIdFromRemoteNotif = [[NSMutableArray alloc] init ];
|
||||
photoLibrary = [[ALAssetsLibrary alloc] init];
|
||||
|
|
@ -291,7 +292,6 @@ struct codec_name_pref_table codec_pref_table[]={
|
|||
}
|
||||
|
||||
[fastAddressBook release];
|
||||
[self closeDatabase];
|
||||
[logs release];
|
||||
|
||||
OSStatus lStatus = AudioSessionRemovePropertyListenerWithUserData(kAudioSessionProperty_AudioRouteChange, audioRouteChangeListenerCallback, self);
|
||||
|
|
@ -311,34 +311,85 @@ struct codec_name_pref_table codec_pref_table[]={
|
|||
|
||||
#pragma mark - Database Functions
|
||||
|
||||
- (void)openDatabase {
|
||||
NSString *databasePath = [LinphoneManager documentFile:@"chat_database.sqlite"];
|
||||
NSFileManager *filemgr = [NSFileManager defaultManager];
|
||||
//[filemgr removeItemAtPath:databasePath error:nil];
|
||||
BOOL firstInstall= ![filemgr fileExistsAtPath: databasePath ];
|
||||
|
||||
if(sqlite3_open([databasePath UTF8String], &database) != SQLITE_OK) {
|
||||
[LinphoneLogger log:LinphoneLoggerError format:@"Can't open \"%@\" sqlite3 database.", databasePath];
|
||||
return;
|
||||
}
|
||||
|
||||
if (firstInstall) {
|
||||
char *errMsg;
|
||||
//better to create the db from the code
|
||||
const char *sql_stmt = "CREATE TABLE chat (id INTEGER PRIMARY KEY AUTOINCREMENT, localContact TEXT NOT NULL, remoteContact TEXT NOT NULL, direction INTEGER, message TEXT NOT NULL, time NUMERIC, read INTEGER, state INTEGER)";
|
||||
|
||||
if (sqlite3_exec(database, sql_stmt, NULL, NULL, &errMsg) != SQLITE_OK) {
|
||||
[LinphoneLogger logc:LinphoneLoggerError format:"Can't create table error[%s] ", errMsg];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
- (void)migrateChatDBIfNeeded:(LinphoneCore*)lc {
|
||||
sqlite3* newDb;
|
||||
char *errMsg;
|
||||
NSError* error;
|
||||
NSString *oldDbPath = [LinphoneManager documentFile:kLinphoneOldChatDBFilename];
|
||||
NSString *newDbPath = [LinphoneManager documentFile:kLinphoneInternalChatDBFilename];
|
||||
BOOL shouldMigrate = [[NSFileManager defaultManager] fileExistsAtPath:oldDbPath];
|
||||
LinphoneProxyConfig* default_proxy;
|
||||
const char* identity = NULL;
|
||||
|
||||
- (void)closeDatabase {
|
||||
if(database != NULL) {
|
||||
if(sqlite3_close(database) != SQLITE_OK) {
|
||||
[LinphoneLogger logc:LinphoneLoggerError format:"Can't close sqlite3 database."];
|
||||
}
|
||||
linphone_core_get_default_proxy(lc, &default_proxy);
|
||||
|
||||
if( !shouldMigrate ) return;
|
||||
|
||||
if( sqlite3_open([newDbPath UTF8String], &newDb) != SQLITE_OK) {
|
||||
[LinphoneLogger log:LinphoneLoggerError format:@"Can't open \"%@\" sqlite3 database.", newDbPath];
|
||||
return;
|
||||
}
|
||||
|
||||
// attach old database to the new one:
|
||||
char* attach_stmt = sqlite3_mprintf("ATTACH DATABASE %Q AS oldchats", [oldDbPath UTF8String]);
|
||||
if( sqlite3_exec(newDb, attach_stmt, NULL, NULL, &errMsg) != SQLITE_OK ){
|
||||
[LinphoneLogger logc:LinphoneLoggerError format:"Can't attach old chat table, error[%s] ", errMsg];
|
||||
sqlite3_free(errMsg);
|
||||
goto exit_dbmigration;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// migrate old chats to the new db
|
||||
const char* migration_statement = "INSERT INTO history (localContact,remoteContact,direction,message,time,read,status) "
|
||||
"SELECT localContact,remoteContact,direction,message,time,read,state FROM oldchats.chat";
|
||||
|
||||
if( sqlite3_exec(newDb, migration_statement, NULL, NULL, &errMsg) != SQLITE_OK ){
|
||||
[LinphoneLogger logc:LinphoneLoggerError format:"DB migration failed, error[%s] ", errMsg];
|
||||
sqlite3_free(errMsg);
|
||||
goto exit_dbmigration;
|
||||
}
|
||||
|
||||
// replace empty from: or to: by the current identity.
|
||||
if( default_proxy ){
|
||||
identity = linphone_proxy_config_get_identity(default_proxy);
|
||||
}
|
||||
if( !identity ){
|
||||
identity = "sip:unknown@sip.linphone.org";
|
||||
}
|
||||
|
||||
char* from_conversion = sqlite3_mprintf("UPDATE history SET localContact = %Q WHERE localContact = ''", identity);
|
||||
if( sqlite3_exec(newDb, from_conversion, NULL, NULL, &errMsg) != SQLITE_OK ){
|
||||
[LinphoneLogger logc:LinphoneLoggerError format:"FROM conversion failed, error[%s] ", errMsg];
|
||||
sqlite3_free(errMsg);
|
||||
}
|
||||
sqlite3_free(from_conversion);
|
||||
|
||||
char* to_conversion = sqlite3_mprintf("UPDATE history SET remoteContact = %Q WHERE remoteContact = ''", identity);
|
||||
if( sqlite3_exec(newDb, to_conversion, NULL, NULL, &errMsg) != SQLITE_OK ){
|
||||
[LinphoneLogger logc:LinphoneLoggerError format:"DB migration failed, error[%s] ", errMsg];
|
||||
sqlite3_free(errMsg);
|
||||
}
|
||||
sqlite3_free(to_conversion);
|
||||
|
||||
// move already stored images from the messages to the url field
|
||||
const char* assetslib_migration = "UPDATE history SET url=message, message='' WHERE message LIKE 'assets-library%'";
|
||||
if( sqlite3_exec(newDb, assetslib_migration, NULL, NULL, &errMsg) != SQLITE_OK ){
|
||||
[LinphoneLogger logc:LinphoneLoggerError format:"Assets-history migration failed, error[%s] ", errMsg];
|
||||
sqlite3_free(errMsg);
|
||||
}
|
||||
// We will lose received messages with remote url, they will be displayed in plain. We can't do much for them..
|
||||
|
||||
exit_dbmigration:
|
||||
|
||||
if( attach_stmt ) sqlite3_free(attach_stmt);
|
||||
|
||||
sqlite3_close(newDb);
|
||||
|
||||
// in any case, we should remove the old chat db
|
||||
if(![[NSFileManager defaultManager] removeItemAtPath:oldDbPath error:&error] ){
|
||||
[LinphoneLogger logc:LinphoneLoggerError format:"Could not remove old chat DB: %@", error];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -712,10 +763,6 @@ static void linphone_iphone_registration_state(LinphoneCore *lc, LinphoneProxyCo
|
|||
#pragma mark - Text Received Functions
|
||||
|
||||
- (void)onMessageReceived:(LinphoneCore *)lc room:(LinphoneChatRoom *)room message:(LinphoneChatMessage*)msg {
|
||||
|
||||
char *fromStr = linphone_address_as_string_uri_only(linphone_chat_message_get_from(msg));
|
||||
if(fromStr == NULL)
|
||||
return;
|
||||
|
||||
if (silentPushCompletion) {
|
||||
|
||||
|
|
@ -726,34 +773,20 @@ static void linphone_iphone_registration_state(LinphoneCore *lc, LinphoneProxyCo
|
|||
silentPushCompletion = nil;
|
||||
}
|
||||
|
||||
// Save message in database
|
||||
ChatModel *chat = [[ChatModel alloc] init];
|
||||
[chat setLocalContact:@""];
|
||||
[chat setRemoteContact:[NSString stringWithUTF8String:fromStr]];
|
||||
if (linphone_chat_message_get_external_body_url(msg)) {
|
||||
[chat setMessage:[NSString stringWithUTF8String:linphone_chat_message_get_external_body_url(msg)]];
|
||||
} else {
|
||||
[chat setMessage:[NSString stringWithUTF8String:linphone_chat_message_get_text(msg)]];
|
||||
}
|
||||
[chat setDirection:[NSNumber numberWithInt:1]];
|
||||
[chat setTime:[NSDate dateWithTimeIntervalSince1970:linphone_chat_message_get_time(msg)]];
|
||||
[chat setRead:[NSNumber numberWithInt:0]];
|
||||
[chat create];
|
||||
|
||||
ms_free(fromStr);
|
||||
|
||||
|
||||
if ([[UIDevice currentDevice] respondsToSelector:@selector(isMultitaskingSupported)]
|
||||
&& [UIApplication sharedApplication].applicationState != UIApplicationStateActive) {
|
||||
|
||||
NSString* address = [chat remoteContact];
|
||||
NSString *normalizedSipAddress = [FastAddressBook normalizeSipURI:address];
|
||||
ABRecordRef contact = [fastAddressBook getContact:normalizedSipAddress];
|
||||
const LinphoneAddress* remoteAddress = linphone_chat_message_get_from(msg);
|
||||
char* c_address = linphone_address_as_string_uri_only(remoteAddress);
|
||||
NSString* address = [NSString stringWithUTF8String:c_address];
|
||||
NSString* from_address = [address copy];
|
||||
|
||||
ABRecordRef contact = [fastAddressBook getContact:address];
|
||||
if(contact) {
|
||||
address = [FastAddressBook getContactDisplayName:contact];
|
||||
} else {
|
||||
if ([[LinphoneManager instance] lpConfigBoolForKey:@"show_contacts_emails_preference"] == true) {
|
||||
LinphoneAddress *linphoneAddress = linphone_address_new([normalizedSipAddress cStringUsingEncoding:[NSString defaultCStringEncoding]]);
|
||||
LinphoneAddress *linphoneAddress = linphone_address_new([address cStringUsingEncoding:[NSString defaultCStringEncoding]]);
|
||||
address = [NSString stringWithUTF8String:linphone_address_get_username(linphoneAddress)];
|
||||
linphone_address_destroy(linphoneAddress);
|
||||
}
|
||||
|
|
@ -765,26 +798,23 @@ static void linphone_iphone_registration_state(LinphoneCore *lc, LinphoneProxyCo
|
|||
// Create a new notification
|
||||
UILocalNotification* notif = [[[UILocalNotification alloc] init] autorelease];
|
||||
if (notif) {
|
||||
notif.repeatInterval = 0;
|
||||
notif.alertBody = [NSString stringWithFormat:NSLocalizedString(@"IM_MSG",nil), address];
|
||||
notif.alertAction = NSLocalizedString(@"Show", nil);
|
||||
notif.soundName = @"msg.caf";
|
||||
notif.userInfo = [NSDictionary dictionaryWithObject:[chat remoteContact] forKey:@"chat"];
|
||||
|
||||
notif.repeatInterval = 0;
|
||||
notif.alertBody = [NSString stringWithFormat:NSLocalizedString(@"IM_MSG",nil), address];
|
||||
notif.alertAction = NSLocalizedString(@"Show", nil);
|
||||
notif.soundName = @"msg.caf";
|
||||
notif.userInfo = @{@"from":from_address };
|
||||
|
||||
|
||||
[[UIApplication sharedApplication] presentLocalNotificationNow:notif];
|
||||
}
|
||||
[from_address release];
|
||||
}
|
||||
|
||||
// Post event
|
||||
NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
[NSValue valueWithPointer:room], @"room",
|
||||
[NSValue valueWithPointer:linphone_chat_message_get_from(msg)], @"from",
|
||||
chat.message, @"message",
|
||||
chat, @"chat",
|
||||
nil];
|
||||
NSDictionary* dict = @{@"room" :[NSValue valueWithPointer:room],
|
||||
@"from_address":[NSValue valueWithPointer:linphone_chat_message_get_from(msg)],
|
||||
@"message" :[NSValue valueWithPointer:msg]};
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneTextReceived object:self userInfo:dict];
|
||||
[chat release];
|
||||
}
|
||||
|
||||
static void linphone_iphone_message_received(LinphoneCore *lc, LinphoneChatRoom *room, LinphoneChatMessage *message) {
|
||||
|
|
@ -995,8 +1025,9 @@ static LinphoneCoreVTable linphonec_vtable = {
|
|||
- (void)finishCoreConfiguration {
|
||||
|
||||
//get default config from bundle
|
||||
NSString *zrtpSecretsFileName = [LinphoneManager documentFile:@"zrtp_secrets"];
|
||||
const char* lRootCa = [[LinphoneManager bundleFile:@"rootca.pem"] cStringUsingEncoding:[NSString defaultCStringEncoding]];
|
||||
NSString *zrtpSecretsFileName = [LinphoneManager documentFile:@"zrtp_secrets"];
|
||||
NSString *chatDBFileName = [LinphoneManager documentFile:kLinphoneInternalChatDBFilename];
|
||||
const char* lRootCa = [[LinphoneManager bundleFile:@"rootca.pem"] cStringUsingEncoding:[NSString defaultCStringEncoding]];
|
||||
|
||||
linphone_core_set_user_agent(theLinphoneCore,"LinphoneIPhone",
|
||||
[[[NSBundle mainBundle] objectForInfoDictionaryKey:(NSString*)kCFBundleVersionKey] UTF8String]);
|
||||
|
|
@ -1016,6 +1047,9 @@ static LinphoneCoreVTable linphonec_vtable = {
|
|||
linphone_core_set_play_file(theLinphoneCore, lPlay);
|
||||
|
||||
linphone_core_set_zrtp_secrets_file(theLinphoneCore, [zrtpSecretsFileName cStringUsingEncoding:[NSString defaultCStringEncoding]]);
|
||||
linphone_core_set_chat_database_path(theLinphoneCore, [chatDBFileName cStringUsingEncoding:[NSString defaultCStringEncoding]]);
|
||||
|
||||
[self migrateChatDBIfNeeded:theLinphoneCore];
|
||||
|
||||
[self setupNetworkReachabilityCallback];
|
||||
|
||||
|
|
@ -1680,6 +1714,20 @@ static void audioRouteChangeListenerCallback (
|
|||
return [documentsPath stringByAppendingPathComponent:file];
|
||||
}
|
||||
|
||||
+ (int)unreadMessageCount {
|
||||
int count = 0;
|
||||
MSList* rooms = linphone_core_get_chat_rooms([LinphoneManager getLc]);
|
||||
MSList* item = rooms;
|
||||
while (item) {
|
||||
LinphoneChatRoom* room = (LinphoneChatRoom*)item->data;
|
||||
if( room ){
|
||||
count += linphone_chat_room_get_unread_messages_count(room);
|
||||
}
|
||||
item = item->next;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
+ (BOOL)copyFile:(NSString*)src destination:(NSString*)dst override:(BOOL)override {
|
||||
NSFileManager *fileManager = [NSFileManager defaultManager];
|
||||
NSError *error = nil;
|
||||
|
|
|
|||
|
|
@ -20,13 +20,13 @@
|
|||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import "UITransparentTVCell.h"
|
||||
#import "ChatModel.h"
|
||||
|
||||
#include "linphone/linphonecore.h"
|
||||
|
||||
@interface UIChatCell : UITransparentTVCell {
|
||||
LinphoneChatRoom* chatRoom;
|
||||
}
|
||||
|
||||
@property (nonatomic, retain) ChatModel *chat;
|
||||
@property (nonatomic, retain) IBOutlet UIImageView *avatarImage;
|
||||
@property (nonatomic, retain) IBOutlet UILabel* addressLabel;
|
||||
@property (nonatomic, retain) IBOutlet UILabel* chatContentLabel;
|
||||
|
|
@ -38,4 +38,5 @@
|
|||
|
||||
- (IBAction)onDeleteClick:(id)event;
|
||||
|
||||
- (void)setChatRoom:(LinphoneChatRoom *)achat;
|
||||
@end
|
||||
|
|
|
|||
|
|
@ -31,7 +31,6 @@
|
|||
@synthesize unreadMessageLabel;
|
||||
@synthesize unreadMessageView;
|
||||
|
||||
@synthesize chat;
|
||||
|
||||
#pragma mark - Lifecycle Functions
|
||||
|
||||
|
|
@ -57,24 +56,15 @@
|
|||
[deleteButton release];
|
||||
[unreadMessageLabel release];
|
||||
[unreadMessageView release];
|
||||
|
||||
[chat release];
|
||||
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - Property Funcitons
|
||||
|
||||
- (void)setChat:(ChatModel *)achat {
|
||||
if(chat == achat)
|
||||
return;
|
||||
if(chat != nil) {
|
||||
[chat release];
|
||||
}
|
||||
if(achat) {
|
||||
chat = [achat retain];
|
||||
}
|
||||
- (void)setChatRoom:(LinphoneChatRoom *)achat {
|
||||
self->chatRoom = achat;
|
||||
[self update];
|
||||
}
|
||||
|
||||
|
|
@ -84,11 +74,12 @@
|
|||
- (void)update {
|
||||
NSString *displayName = nil;
|
||||
UIImage *image = nil;
|
||||
if(chat == nil) {
|
||||
if(chatRoom == nil) {
|
||||
[LinphoneLogger logc:LinphoneLoggerWarning format:"Cannot update chat cell: null chat"];
|
||||
return;
|
||||
}
|
||||
LinphoneAddress* linphoneAddress = linphone_core_interpret_url([LinphoneManager getLc], [[chat remoteContact] UTF8String]);
|
||||
const LinphoneAddress* linphoneAddress = linphone_chat_room_get_peer_address(chatRoom);
|
||||
|
||||
if (linphoneAddress == NULL)
|
||||
return;
|
||||
char *tmp = linphone_address_as_string_uri_only(linphoneAddress);
|
||||
|
|
@ -112,28 +103,39 @@
|
|||
image = [UIImage imageNamed:@"avatar_unknown_small.png"];
|
||||
}
|
||||
[avatarImage setImage:image];
|
||||
|
||||
// Message
|
||||
if([chat isExternalImage] || [chat isInternalImage]) {
|
||||
[chatContentLabel setText:@""];
|
||||
} else {
|
||||
NSString *message = [chat message];
|
||||
// shorten long messages
|
||||
if([message length] > 50)
|
||||
message = [[message substringToIndex:50] stringByAppendingString:@"[...]"];
|
||||
|
||||
[chatContentLabel setText:message];
|
||||
}
|
||||
|
||||
int count = [ChatModel unreadMessages:[chat remoteContact]];
|
||||
if(count > 0) {
|
||||
[unreadMessageView setHidden:FALSE];
|
||||
[unreadMessageLabel setText:[NSString stringWithFormat:@"%i", count]];
|
||||
|
||||
MSList* last_message_list = linphone_chat_room_get_history(chatRoom, 1);
|
||||
LinphoneChatMessage* last_message = last_message_list? last_message_list->data : NULL;
|
||||
|
||||
if( last_message ){
|
||||
|
||||
const char* text = linphone_chat_message_get_text(last_message);
|
||||
const char* url = linphone_chat_message_get_external_body_url(last_message);
|
||||
// Message
|
||||
if(url) {
|
||||
[chatContentLabel setText:@""];
|
||||
} else {
|
||||
NSString *message = [NSString stringWithUTF8String:text];
|
||||
// shorten long messages
|
||||
if([message length] > 50)
|
||||
message = [[message substringToIndex:50] stringByAppendingString:@"[...]"];
|
||||
|
||||
[chatContentLabel setText:message];
|
||||
}
|
||||
|
||||
int count = linphone_chat_room_get_unread_messages_count(chatRoom);
|
||||
if(count > 0) {
|
||||
[unreadMessageView setHidden:FALSE];
|
||||
[unreadMessageLabel setText:[NSString stringWithFormat:@"%i", count]];
|
||||
} else {
|
||||
[unreadMessageView setHidden:TRUE];
|
||||
}
|
||||
} else {
|
||||
chatContentLabel.text = nil;
|
||||
[unreadMessageView setHidden:TRUE];
|
||||
}
|
||||
|
||||
linphone_address_destroy(linphoneAddress);
|
||||
|
||||
ms_list_free(last_message_list);
|
||||
}
|
||||
|
||||
- (void)setEditing:(BOOL)editing {
|
||||
|
|
@ -159,7 +161,7 @@
|
|||
#pragma mark - Action Functions
|
||||
|
||||
- (IBAction)onDeleteClick: (id) event {
|
||||
if(chat != NULL) {
|
||||
if(chatRoom != NULL) {
|
||||
UIView *view = [self superview];
|
||||
// Find TableViewCell
|
||||
while( view != nil && ![view isKindOfClass:[UITableView class]]) view = [view superview];
|
||||
|
|
|
|||
|
|
@ -19,17 +19,17 @@
|
|||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import "ChatModel.h"
|
||||
#import "ChatRoomTableViewController.h"
|
||||
#import "UILoadingImageView.h"
|
||||
#import "UITransparentTVCell.h"
|
||||
#import "UITextViewNoDefine.h"
|
||||
#include "linphone/linphonecore.h"
|
||||
|
||||
|
||||
@interface UIChatRoomCell : UITransparentTVCell {
|
||||
LinphoneChatMessage* chat;
|
||||
}
|
||||
|
||||
@property (nonatomic, retain) ChatModel *chat;
|
||||
@property (nonatomic, retain) IBOutlet UIView *innerView;
|
||||
@property (nonatomic, retain) IBOutlet UIView *bubbleView;
|
||||
@property (nonatomic, retain) IBOutlet UIImageView* backgroundImage;
|
||||
|
|
@ -43,7 +43,7 @@
|
|||
@property (nonatomic, retain) IBOutlet UITapGestureRecognizer* resendTapGestureRecognizer;
|
||||
|
||||
- (id)initWithIdentifier:(NSString*)identifier;
|
||||
+ (CGFloat)height:(ChatModel*)chat width:(int)width;
|
||||
+ (CGFloat)height:(LinphoneChatMessage*)chatMessage width:(int)width;
|
||||
|
||||
@property (nonatomic, retain) id<ChatRoomDelegate> chatRoomDelegate;
|
||||
|
||||
|
|
@ -51,4 +51,6 @@
|
|||
- (IBAction)onDownloadClick:(id)event;
|
||||
- (IBAction)onImageClick:(id)event;
|
||||
|
||||
- (void)setChatMessage:(LinphoneChatMessage*)message;
|
||||
|
||||
@end
|
||||
|
|
|
|||
|
|
@ -37,7 +37,6 @@
|
|||
@synthesize messageText;
|
||||
@synthesize deleteButton;
|
||||
@synthesize dateLabel;
|
||||
@synthesize chat;
|
||||
@synthesize statusImage;
|
||||
@synthesize downloadButton;
|
||||
@synthesize chatRoomDelegate;
|
||||
|
|
@ -91,7 +90,6 @@ static UIFont *CELL_FONT = nil;
|
|||
[deleteButton release];
|
||||
[dateLabel release];
|
||||
[statusImage release];
|
||||
[chat release];
|
||||
[downloadButton release];
|
||||
[imageTapGestureRecognizer release];
|
||||
[resendTapGestureRecognizer release];
|
||||
|
|
@ -106,17 +104,8 @@ static UIFont *CELL_FONT = nil;
|
|||
|
||||
#pragma mark -
|
||||
|
||||
- (void)setChat:(ChatModel *)achat {
|
||||
if(chat != achat) {
|
||||
if(chat != nil) {
|
||||
[chat release];
|
||||
chat = nil;
|
||||
}
|
||||
|
||||
if(achat != nil) {
|
||||
chat = [achat retain];
|
||||
}
|
||||
}
|
||||
- (void)setChatMessage:(LinphoneChatMessage *)message {
|
||||
self->chat = message;
|
||||
[self update];
|
||||
|
||||
}
|
||||
|
|
@ -126,20 +115,23 @@ static UIFont *CELL_FONT = nil;
|
|||
[LinphoneLogger logc:LinphoneLoggerWarning format:"Cannot update chat room cell: null chat"];
|
||||
return;
|
||||
}
|
||||
|
||||
if([chat isExternalImage]) {
|
||||
const char*url = linphone_chat_message_get_external_body_url(chat);
|
||||
const char*text = linphone_chat_message_get_text(chat);
|
||||
BOOL is_external = url && (strstr(url, "http") == url);
|
||||
|
||||
if(is_external) {
|
||||
[messageText setHidden:TRUE];
|
||||
|
||||
[messageImageView setImage:nil];
|
||||
[messageImageView setHidden:TRUE];
|
||||
|
||||
[downloadButton setHidden:FALSE];
|
||||
} else if([chat isInternalImage]) {
|
||||
|
||||
} else if(url) {
|
||||
|
||||
[messageText setHidden:TRUE];
|
||||
[messageImageView setImage:nil];
|
||||
[messageImageView startLoading];
|
||||
ChatModel *achat = chat;
|
||||
[[LinphoneManager instance].photoLibrary assetForURL:[NSURL URLWithString:[chat message]] resultBlock:^(ALAsset *asset) {
|
||||
__block LinphoneChatMessage *achat = chat;
|
||||
[[LinphoneManager instance].photoLibrary assetForURL:[NSURL URLWithString:[NSString stringWithUTF8String:url]] resultBlock:^(ALAsset *asset) {
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, (unsigned long)NULL), ^(void) {
|
||||
ALAssetRepresentation* representation = [asset defaultRepresentation];
|
||||
UIImage *image = [UIImage imageWithCGImage:[representation fullResolutionImage]
|
||||
|
|
@ -161,7 +153,7 @@ static UIFont *CELL_FONT = nil;
|
|||
[downloadButton setHidden:TRUE];
|
||||
} else {
|
||||
[messageText setHidden:FALSE];
|
||||
[messageText setText:[chat message]];
|
||||
[messageText setText:[NSString stringWithUTF8String:text]];
|
||||
|
||||
[messageImageView setImage:nil];
|
||||
[messageImageView setHidden:TRUE];
|
||||
|
|
@ -170,20 +162,24 @@ static UIFont *CELL_FONT = nil;
|
|||
}
|
||||
|
||||
// Date
|
||||
NSDate* message_date = [NSDate dateWithTimeIntervalSince1970:linphone_chat_message_get_time(chat)];
|
||||
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
|
||||
[dateFormatter setTimeStyle:NSDateFormatterMediumStyle];
|
||||
[dateFormatter setDateStyle:NSDateFormatterMediumStyle];
|
||||
NSLocale *locale = [NSLocale currentLocale];
|
||||
[dateFormatter setLocale:locale];
|
||||
[dateLabel setText:[dateFormatter stringFromDate:[chat time]]];
|
||||
[dateLabel setText:[dateFormatter stringFromDate:message_date]];
|
||||
[dateFormatter release];
|
||||
if ([chat.state intValue] == LinphoneChatMessageStateInProgress) {
|
||||
|
||||
LinphoneChatMessageState state = linphone_chat_message_get_state(chat);
|
||||
|
||||
if (state== LinphoneChatMessageStateInProgress) {
|
||||
[statusImage setImage:[UIImage imageNamed:@"chat_message_inprogress.png"]];
|
||||
statusImage.hidden = FALSE;
|
||||
} else if ([chat.state intValue] == LinphoneChatMessageStateDelivered) {
|
||||
} else if (state == LinphoneChatMessageStateDelivered) {
|
||||
[statusImage setImage:[UIImage imageNamed:@"chat_message_delivered.png"]];
|
||||
statusImage.hidden = FALSE;
|
||||
} else if ([chat.state intValue] == LinphoneChatMessageStateNotDelivered) {
|
||||
} else if (state == LinphoneChatMessageStateNotDelivered) {
|
||||
[statusImage setImage:[UIImage imageNamed:@"chat_message_not_delivered.png"]];
|
||||
statusImage.hidden = FALSE;
|
||||
|
||||
|
|
@ -216,9 +212,12 @@ static UIFont *CELL_FONT = nil;
|
|||
}
|
||||
}
|
||||
|
||||
+ (CGSize)viewSize:(ChatModel*)chat width:(int)width {
|
||||
+ (CGSize)viewSize:(LinphoneChatMessage*)chat width:(int)width {
|
||||
CGSize messageSize;
|
||||
if(!([chat isExternalImage] || [chat isInternalImage])) {
|
||||
const char* url = linphone_chat_message_get_external_body_url(chat);
|
||||
const char* text = linphone_chat_message_get_text(chat);
|
||||
NSString* messageText = text ? [NSString stringWithUTF8String:text] : @"";
|
||||
if(url == nil) {
|
||||
if(CELL_FONT == nil) {
|
||||
CELL_FONT = [UIFont systemFontOfSize:CELL_FONT_SIZE];
|
||||
}
|
||||
|
|
@ -226,7 +225,7 @@ static UIFont *CELL_FONT = nil;
|
|||
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000
|
||||
|
||||
if( [[[UIDevice currentDevice] systemVersion] doubleValue] >= 7){
|
||||
messageSize = [[chat message]
|
||||
messageSize = [messageText
|
||||
boundingRectWithSize:CGSizeMake(width - CELL_MESSAGE_X_MARGIN, CGFLOAT_MAX)
|
||||
options:(NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingTruncatesLastVisibleLine|NSStringDrawingUsesFontLeading)
|
||||
attributes:@{NSFontAttributeName: CELL_FONT}
|
||||
|
|
@ -234,7 +233,7 @@ static UIFont *CELL_FONT = nil;
|
|||
} else
|
||||
#endif
|
||||
{
|
||||
messageSize = [[chat message] sizeWithFont: CELL_FONT
|
||||
messageSize = [messageText sizeWithFont: CELL_FONT
|
||||
constrainedToSize: CGSizeMake(width - CELL_MESSAGE_X_MARGIN, 10000.0f)
|
||||
lineBreakMode: NSLineBreakByTruncatingTail];
|
||||
}
|
||||
|
|
@ -250,8 +249,8 @@ static UIFont *CELL_FONT = nil;
|
|||
return messageSize;
|
||||
}
|
||||
|
||||
+ (CGFloat)height:(ChatModel*)chat width:(int)width {
|
||||
return [UIChatRoomCell viewSize:chat width:width].height;
|
||||
+ (CGFloat)height:(LinphoneChatMessage*)chatMessage width:(int)width {
|
||||
return [UIChatRoomCell viewSize:chatMessage width:width].height;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -262,8 +261,9 @@ static UIFont *CELL_FONT = nil;
|
|||
if(chat != nil) {
|
||||
// Resize inner
|
||||
CGRect innerFrame;
|
||||
BOOL is_outgoing = linphone_chat_message_is_outgoing(chat);
|
||||
innerFrame.size = [UIChatRoomCell viewSize:chat width:[self frame].size.width];
|
||||
if([[chat direction] intValue]) { // Inverted
|
||||
if(is_outgoing) { // Inverted
|
||||
innerFrame.origin.x = 0.0f;
|
||||
innerFrame.origin.y = 0.0f;
|
||||
} else {
|
||||
|
|
@ -274,7 +274,7 @@ static UIFont *CELL_FONT = nil;
|
|||
|
||||
CGRect messageFrame = [bubbleView frame];
|
||||
messageFrame.origin.y = ([innerView frame].size.height - messageFrame.size.height)/2;
|
||||
if([[chat direction] intValue]) { // Inverted
|
||||
if(is_outgoing) { // Inverted
|
||||
[backgroundImage setImage:[TUNinePatchCache imageOfSize:[backgroundImage bounds].size
|
||||
forNinePatchNamed:@"chat_bubble_incoming"]];
|
||||
messageFrame.origin.y += 5;
|
||||
|
|
@ -304,7 +304,9 @@ static UIFont *CELL_FONT = nil;
|
|||
}
|
||||
|
||||
- (IBAction)onDownloadClick:(id)event {
|
||||
[chatRoomDelegate chatRoomStartImageDownload:[NSURL URLWithString:chat.message] userInfo:chat];
|
||||
NSURL* url = [NSURL URLWithString:[NSString stringWithUTF8String:linphone_chat_message_get_external_body_url(chat)]];
|
||||
[chatRoomDelegate chatRoomStartImageDownload:url userInfo:[NSValue valueWithPointer:chat]];
|
||||
|
||||
}
|
||||
|
||||
- (IBAction)onImageClick:(id)event {
|
||||
|
|
@ -317,14 +319,21 @@ static UIFont *CELL_FONT = nil;
|
|||
}
|
||||
|
||||
- (IBAction)onResendClick:(id)event {
|
||||
if ([chat.state intValue] == LinphoneChatMessageStateNotDelivered) {
|
||||
NSString* message = [chat message];
|
||||
if( chat == nil ) return;
|
||||
|
||||
LinphoneChatMessageState state = linphone_chat_message_get_state(self->chat);
|
||||
if (state == LinphoneChatMessageStateNotDelivered) {
|
||||
const char* text = linphone_chat_message_get_text(self->chat);
|
||||
const char* url = linphone_chat_message_get_external_body_url(self->chat);
|
||||
NSString* message = text ? [NSString stringWithUTF8String:text] : nil;
|
||||
NSString* exturl = url ? [NSString stringWithUTF8String:url] : nil;
|
||||
|
||||
[self onDeleteClick:nil];
|
||||
|
||||
double delayInSeconds = 0.4;
|
||||
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
|
||||
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
|
||||
[chatRoomDelegate resendChat:message];
|
||||
[chatRoomDelegate resendChat:message withExternalUrl:exturl];
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@
|
|||
|
||||
#import "UIMainBar.h"
|
||||
#import "PhoneMainView.h"
|
||||
#import "ChatModel.h"
|
||||
#import "CAAnimation+Blocks.h"
|
||||
|
||||
@implementation UIMainBar
|
||||
|
|
@ -243,7 +242,7 @@ static NSString * const kDisappearAnimation = @"disappear";
|
|||
}
|
||||
|
||||
- (void)textReceived:(NSNotification*)notif {
|
||||
[self updateUnreadMessage:[ChatModel unreadMessages] appear:TRUE];
|
||||
[self updateUnreadMessage:TRUE];
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -256,10 +255,11 @@ static NSString * const kDisappearAnimation = @"disappear";
|
|||
} else {
|
||||
[self updateMissedCall:0 appear:TRUE];
|
||||
}
|
||||
[self updateUnreadMessage:[ChatModel unreadMessages] appear:appear];
|
||||
[self updateUnreadMessage:appear];
|
||||
}
|
||||
|
||||
- (void)updateUnreadMessage:(int)unreadMessage appear:(BOOL)appear{
|
||||
- (void)updateUnreadMessage:(BOOL)appear{
|
||||
int unreadMessage = [LinphoneManager unreadMessageCount];
|
||||
if (unreadMessage > 0) {
|
||||
if([chatNotificationView isHidden]) {
|
||||
[chatNotificationView setHidden:FALSE];
|
||||
|
|
|
|||
|
|
@ -1,59 +0,0 @@
|
|||
/* ChatModel.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 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 <Foundation/Foundation.h>
|
||||
|
||||
|
||||
@interface ChatModel : NSObject {
|
||||
@private
|
||||
NSNumber *chatId;
|
||||
NSString *localContact;
|
||||
NSString *remoteContact;
|
||||
NSNumber *direction; //0 outgoing 1 incoming
|
||||
NSString *message;
|
||||
NSDate *time;
|
||||
NSNumber *read;
|
||||
NSNumber *state; //0 IDLE, 1 in progress, 2 delivered, 3 not delivered see LinphoneChatMessageState
|
||||
}
|
||||
|
||||
@property (readonly) NSNumber *chatId;
|
||||
@property (copy) NSString *localContact;
|
||||
@property (copy) NSString *remoteContact;
|
||||
@property (copy) NSNumber *direction;
|
||||
@property (copy) NSString *message;
|
||||
@property (copy) NSDate *time;
|
||||
@property (copy) NSNumber *read;
|
||||
@property (copy) NSNumber *state;
|
||||
|
||||
- (BOOL)isExternalImage;
|
||||
- (BOOL)isInternalImage;
|
||||
|
||||
- (void)create;
|
||||
+ (ChatModel*)read:(NSNumber*)id;
|
||||
- (void)update;
|
||||
- (void)delete;
|
||||
|
||||
+ (NSMutableArray *)listConversations;
|
||||
+ (NSMutableArray *)listMessages:(NSString *)contact;
|
||||
+ (void)removeConversation:(NSString *)contact;
|
||||
+ (int)unreadMessages;
|
||||
+ (int)unreadMessages:(NSString *)contact;
|
||||
+ (void)readConversation:(NSString *)contact;
|
||||
|
||||
@end
|
||||
|
|
@ -1,379 +0,0 @@
|
|||
/* ChatModel.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 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 "ChatModel.h"
|
||||
#import "LinphoneManager.h"
|
||||
|
||||
@implementation ChatModel
|
||||
|
||||
@synthesize chatId;
|
||||
@synthesize localContact;
|
||||
@synthesize remoteContact;
|
||||
@synthesize message;
|
||||
@synthesize direction;
|
||||
@synthesize time;
|
||||
@synthesize read;
|
||||
@synthesize state;
|
||||
|
||||
#pragma mark - Lifecycle Functions
|
||||
|
||||
- (id)initWithData:(sqlite3_stmt *)sqlStatement {
|
||||
self = [super init];
|
||||
if (self != nil) {
|
||||
self->chatId = [[NSNumber alloc] initWithInt: sqlite3_column_int(sqlStatement, 0)];
|
||||
self.localContact = [NSString stringWithUTF8String: (const char*) sqlite3_column_text(sqlStatement, 1)];
|
||||
self.remoteContact = [NSString stringWithUTF8String: (const char*) sqlite3_column_text(sqlStatement, 2)];
|
||||
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 = [NSNumber numberWithInt:sqlite3_column_int(sqlStatement, 6)];
|
||||
self.state = [NSNumber numberWithInt:sqlite3_column_int(sqlStatement, 7)];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
[chatId release];
|
||||
[localContact release];
|
||||
[remoteContact release];
|
||||
[message release];
|
||||
[direction release];
|
||||
[time release];
|
||||
[read release];
|
||||
[state release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)isExternalImage {
|
||||
return [message hasPrefix:@"http:"] || [message hasPrefix:@"https:"];
|
||||
}
|
||||
|
||||
- (BOOL)isInternalImage {
|
||||
return [message hasPrefix:@"assets-library:"];
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - CRUD Functions
|
||||
|
||||
- (void)create {
|
||||
sqlite3* database = [[LinphoneManager instance] database];
|
||||
if(database == NULL) {
|
||||
[LinphoneLogger logc:LinphoneLoggerError format:"Database not ready"];
|
||||
return;
|
||||
}
|
||||
|
||||
const char *sql = "INSERT INTO chat (localContact, remoteContact, direction, message, time, read, state) VALUES (@LOCALCONTACT, @REMOTECONTACT, @DIRECTION, @MESSAGE, @TIME, @READ, @STATE)";
|
||||
sqlite3_stmt *sqlStatement;
|
||||
if (sqlite3_prepare_v2(database, sql, -1, &sqlStatement, NULL) != SQLITE_OK) {
|
||||
[LinphoneLogger logc:LinphoneLoggerError format:"Can't prepare the query: %s (%s)", sql, sqlite3_errmsg(database)];
|
||||
return;
|
||||
}
|
||||
|
||||
// Prepare statement
|
||||
sqlite3_bind_text(sqlStatement, 1, [localContact UTF8String], -1, SQLITE_STATIC);
|
||||
sqlite3_bind_text(sqlStatement, 2, [remoteContact UTF8String], -1, SQLITE_STATIC);
|
||||
sqlite3_bind_int(sqlStatement, 3, [direction intValue]);
|
||||
sqlite3_bind_text(sqlStatement, 4, [message UTF8String], -1, SQLITE_STATIC);
|
||||
sqlite3_bind_double(sqlStatement, 5, [time timeIntervalSince1970]);
|
||||
sqlite3_bind_int(sqlStatement, 6, [read intValue]);
|
||||
sqlite3_bind_int(sqlStatement, 7, [state intValue]);
|
||||
|
||||
if (sqlite3_step(sqlStatement) != SQLITE_DONE) {
|
||||
[LinphoneLogger logc:LinphoneLoggerError format:"Error during execution of query: %s (%s)", sql, sqlite3_errmsg(database)];
|
||||
sqlite3_finalize(sqlStatement);
|
||||
}
|
||||
|
||||
if([self chatId] != nil) {
|
||||
[chatId release];
|
||||
}
|
||||
chatId = [[NSNumber alloc] initWithInt:(int)sqlite3_last_insert_rowid(database)];
|
||||
sqlite3_finalize(sqlStatement);
|
||||
}
|
||||
|
||||
+ (ChatModel*)read:(NSNumber*)chatId {
|
||||
sqlite3* database = [[LinphoneManager instance] database];
|
||||
if(database == NULL) {
|
||||
[LinphoneLogger logc:LinphoneLoggerError format:"Database not ready"];
|
||||
return nil;
|
||||
}
|
||||
|
||||
const char *sql = "SELECT id, localContact, remoteContact, direction, message, time, read FROM chat WHERE id=@ID";
|
||||
sqlite3_stmt *sqlStatement;
|
||||
if (sqlite3_prepare_v2(database, sql, -1, &sqlStatement, NULL) != SQLITE_OK) {
|
||||
[LinphoneLogger logc:LinphoneLoggerError format:"Can't prepare the query: %s (%s)", sql, sqlite3_errmsg(database)];
|
||||
return nil;
|
||||
}
|
||||
|
||||
// Prepare statement
|
||||
sqlite3_bind_int(sqlStatement, 1, [chatId intValue]);
|
||||
|
||||
ChatModel* line = nil;
|
||||
int err = sqlite3_step(sqlStatement);
|
||||
if (err == SQLITE_ROW) {
|
||||
line = [[[ChatModel alloc] initWithData:sqlStatement] autorelease];
|
||||
} else if (err != SQLITE_DONE) {
|
||||
[LinphoneLogger logc:LinphoneLoggerError format:"Error during execution of query: %s (%s)", sql, sqlite3_errmsg(database)];
|
||||
sqlite3_finalize(sqlStatement);
|
||||
return nil;
|
||||
}
|
||||
|
||||
sqlite3_finalize(sqlStatement);
|
||||
return line;
|
||||
}
|
||||
|
||||
- (void)update {
|
||||
sqlite3* database = [[LinphoneManager instance] database];
|
||||
if(database == NULL) {
|
||||
[LinphoneLogger logc:LinphoneLoggerError format:"Database not ready"];
|
||||
return;
|
||||
}
|
||||
|
||||
const char *sql = "UPDATE chat SET localContact=@LOCALCONTACT, remoteContact=@REMOTECONTACT, direction=@DIRECTION, message=@MESSAGE, time=@TIME, read=@READ, state=@STATE WHERE id=@ID";
|
||||
sqlite3_stmt *sqlStatement;
|
||||
if (sqlite3_prepare_v2(database, sql, -1, &sqlStatement, NULL) != SQLITE_OK) {
|
||||
[LinphoneLogger logc:LinphoneLoggerError format:"Can't prepare the query: %s (%s)", sql, sqlite3_errmsg(database)];
|
||||
return;
|
||||
}
|
||||
|
||||
// Prepare statement
|
||||
sqlite3_bind_text(sqlStatement, 1, [localContact UTF8String], -1, SQLITE_STATIC);
|
||||
sqlite3_bind_text(sqlStatement, 2, [remoteContact UTF8String], -1, SQLITE_STATIC);
|
||||
sqlite3_bind_int(sqlStatement, 3, [direction intValue]);
|
||||
sqlite3_bind_text(sqlStatement, 4, [message UTF8String], -1, SQLITE_STATIC);
|
||||
sqlite3_bind_double(sqlStatement, 5, [time timeIntervalSince1970]);
|
||||
sqlite3_bind_int(sqlStatement, 6, [read intValue]);
|
||||
sqlite3_bind_int(sqlStatement, 7, [state intValue]);
|
||||
sqlite3_bind_int(sqlStatement, 8, [chatId intValue]);
|
||||
|
||||
if (sqlite3_step(sqlStatement) != SQLITE_DONE) {
|
||||
[LinphoneLogger logc:LinphoneLoggerError format:"Error during execution of query: %s (%s)", sql, sqlite3_errmsg(database)];
|
||||
sqlite3_finalize(sqlStatement);
|
||||
return;
|
||||
}
|
||||
|
||||
sqlite3_finalize(sqlStatement);
|
||||
}
|
||||
|
||||
- (void)delete {
|
||||
sqlite3* database = [[LinphoneManager instance] database];
|
||||
if(database == NULL) {
|
||||
[LinphoneLogger logc:LinphoneLoggerError format:"Database not ready"];
|
||||
return;
|
||||
}
|
||||
|
||||
const char *sql = "DELETE FROM chat WHERE id=@ID";
|
||||
sqlite3_stmt *sqlStatement;
|
||||
if (sqlite3_prepare_v2(database, sql, -1, &sqlStatement, NULL) != SQLITE_OK) {
|
||||
[LinphoneLogger logc:LinphoneLoggerError format:"Can't prepare the query: %s (%s)", sql, sqlite3_errmsg(database)];
|
||||
return;
|
||||
}
|
||||
|
||||
// Prepare statement
|
||||
sqlite3_bind_int(sqlStatement, 1, [chatId intValue]);
|
||||
|
||||
if (sqlite3_step(sqlStatement) != SQLITE_DONE) {
|
||||
[LinphoneLogger logc:LinphoneLoggerError format:"Error during execution of query: %s (%s)", sql, sqlite3_errmsg(database)];
|
||||
sqlite3_finalize(sqlStatement);
|
||||
return;
|
||||
}
|
||||
|
||||
sqlite3_finalize(sqlStatement);
|
||||
}
|
||||
|
||||
|
||||
#pragma mark -
|
||||
|
||||
+ (NSMutableArray *)listConversations {
|
||||
NSMutableArray *array = [NSMutableArray array];
|
||||
sqlite3* database = [[LinphoneManager instance] database];
|
||||
if(database == NULL) {
|
||||
[LinphoneLogger logc:LinphoneLoggerError format:"Database not ready"];
|
||||
return array;
|
||||
}
|
||||
|
||||
const char *sql = "SELECT id, localContact, remoteContact, direction, message, time, read, state FROM chat GROUP BY remoteContact ORDER BY time DESC";
|
||||
sqlite3_stmt *sqlStatement;
|
||||
if (sqlite3_prepare_v2(database, sql, -1, &sqlStatement, NULL) != SQLITE_OK) {
|
||||
[LinphoneLogger logc:LinphoneLoggerError format:"Can't execute the query: %s (%s)", sql, sqlite3_errmsg(database)];
|
||||
return array;
|
||||
}
|
||||
|
||||
int err;
|
||||
while ((err = sqlite3_step(sqlStatement)) == SQLITE_ROW) {
|
||||
ChatModel *line = [[ChatModel alloc] initWithData:sqlStatement];
|
||||
[array addObject:line];
|
||||
[line release];
|
||||
}
|
||||
|
||||
if (err != SQLITE_DONE) {
|
||||
[LinphoneLogger logc:LinphoneLoggerError format:"Error during execution of query: %s (%s)", sql, sqlite3_errmsg(database)];
|
||||
return array;
|
||||
}
|
||||
|
||||
sqlite3_finalize(sqlStatement);
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
+ (NSMutableArray *)listMessages:(NSString *)contact {
|
||||
NSMutableArray *array = [NSMutableArray array];
|
||||
sqlite3* database = [[LinphoneManager instance] database];
|
||||
if(database == NULL) {
|
||||
[LinphoneLogger logc:LinphoneLoggerError format:"Database not ready"];
|
||||
return array;
|
||||
}
|
||||
|
||||
const char *sql = "SELECT id, localContact, remoteContact, direction, message, time, read, state FROM chat WHERE remoteContact=@REMOTECONTACT ORDER BY time ASC";
|
||||
sqlite3_stmt *sqlStatement;
|
||||
if (sqlite3_prepare_v2(database, sql, -1, &sqlStatement, NULL) != SQLITE_OK) {
|
||||
[LinphoneLogger logc:LinphoneLoggerError format:"Can't execute the query: %s (%s)", sql, sqlite3_errmsg(database)];
|
||||
return array;
|
||||
}
|
||||
|
||||
// Prepare statement
|
||||
sqlite3_bind_text(sqlStatement, 1, [contact UTF8String], -1, SQLITE_STATIC);
|
||||
|
||||
int err;
|
||||
while ((err = sqlite3_step(sqlStatement)) == SQLITE_ROW) {
|
||||
ChatModel *line = [[ChatModel alloc] initWithData:sqlStatement];
|
||||
[array addObject:line];
|
||||
[line release];
|
||||
}
|
||||
|
||||
if (err != SQLITE_DONE) {
|
||||
[LinphoneLogger logc:LinphoneLoggerError format:"Error during execution of query: %s (%s)", sql, sqlite3_errmsg(database)];
|
||||
return array;
|
||||
}
|
||||
|
||||
sqlite3_finalize(sqlStatement);
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
+ (void)removeConversation:(NSString *)contact {
|
||||
sqlite3* database = [[LinphoneManager instance] database];
|
||||
if(database == NULL) {
|
||||
[LinphoneLogger logc:LinphoneLoggerError format:"Database not ready"];
|
||||
return;
|
||||
}
|
||||
|
||||
const char *sql = "DELETE FROM chat WHERE remoteContact=@REMOTECONTACT";
|
||||
sqlite3_stmt *sqlStatement;
|
||||
if (sqlite3_prepare_v2(database, sql, -1, &sqlStatement, NULL) != SQLITE_OK) {
|
||||
[LinphoneLogger logc:LinphoneLoggerError format:"Can't prepare the query: %s (%s)", sql, sqlite3_errmsg(database)];
|
||||
return;
|
||||
}
|
||||
|
||||
// Prepare statement
|
||||
sqlite3_bind_text(sqlStatement, 1, [contact UTF8String], -1, SQLITE_STATIC);
|
||||
|
||||
if (sqlite3_step(sqlStatement) != SQLITE_DONE) {
|
||||
[LinphoneLogger logc:LinphoneLoggerError format:"Error during execution of query: %s (%s)", sql, sqlite3_errmsg(database)];
|
||||
sqlite3_finalize(sqlStatement);
|
||||
return;
|
||||
}
|
||||
|
||||
sqlite3_finalize(sqlStatement);
|
||||
}
|
||||
|
||||
+ (int)unreadMessages {
|
||||
int count = -1;
|
||||
sqlite3* database = [[LinphoneManager instance] database];
|
||||
if(database == NULL) {
|
||||
[LinphoneLogger logc:LinphoneLoggerError format:"Database not ready"];
|
||||
return count;
|
||||
}
|
||||
|
||||
const char *sql = "SELECT count(*) FROM chat WHERE read=0";
|
||||
sqlite3_stmt *sqlStatement;
|
||||
if (sqlite3_prepare_v2(database, sql, -1, &sqlStatement, NULL) != SQLITE_OK) {
|
||||
[LinphoneLogger logc:LinphoneLoggerError format:"Can't prepare the query: %s (%s)", sql, sqlite3_errmsg(database)];
|
||||
return count;
|
||||
}
|
||||
|
||||
if (sqlite3_step(sqlStatement) != SQLITE_ROW) {
|
||||
[LinphoneLogger logc:LinphoneLoggerError format:"Error during execution of query: %s (%s)", sql, sqlite3_errmsg(database)];
|
||||
sqlite3_finalize(sqlStatement);
|
||||
return count;
|
||||
}
|
||||
|
||||
count = sqlite3_column_int(sqlStatement, 0);
|
||||
|
||||
sqlite3_finalize(sqlStatement);
|
||||
return count;
|
||||
}
|
||||
|
||||
+ (int)unreadMessages:(NSString *)contact {
|
||||
int count = -1;
|
||||
sqlite3* database = [[LinphoneManager instance] database];
|
||||
if(database == NULL) {
|
||||
[LinphoneLogger logc:LinphoneLoggerError format:"Database not ready"];
|
||||
return count;
|
||||
}
|
||||
|
||||
const char *sql = "SELECT count(*) FROM chat WHERE read=0 AND remoteContact=@REMOTECONTACT";
|
||||
sqlite3_stmt *sqlStatement;
|
||||
if (sqlite3_prepare_v2(database, sql, -1, &sqlStatement, NULL) != SQLITE_OK) {
|
||||
[LinphoneLogger logc:LinphoneLoggerError format:"Can't prepare the query: %s (%s)", sql, sqlite3_errmsg(database)];
|
||||
return count;
|
||||
}
|
||||
|
||||
// Prepare statement
|
||||
sqlite3_bind_text(sqlStatement, 1, [contact UTF8String], -1, SQLITE_STATIC);
|
||||
|
||||
if (sqlite3_step(sqlStatement) != SQLITE_ROW) {
|
||||
[LinphoneLogger logc:LinphoneLoggerError format:"Error during execution of query: %s (%s)", sql, sqlite3_errmsg(database)];
|
||||
sqlite3_finalize(sqlStatement);
|
||||
return count;
|
||||
}
|
||||
|
||||
count = sqlite3_column_int(sqlStatement, 0);
|
||||
|
||||
sqlite3_finalize(sqlStatement);
|
||||
return count;
|
||||
}
|
||||
|
||||
+ (void)readConversation:(NSString *)contact {
|
||||
sqlite3* database = [[LinphoneManager instance] database];
|
||||
if(database == NULL) {
|
||||
[LinphoneLogger logc:LinphoneLoggerError format:"Database not ready"];
|
||||
return;
|
||||
}
|
||||
|
||||
const char *sql = "UPDATE chat SET read=1 WHERE remoteContact=@REMOTECONTACT";
|
||||
sqlite3_stmt *sqlStatement;
|
||||
if (sqlite3_prepare_v2(database, sql, -1, &sqlStatement, NULL) != SQLITE_OK) {
|
||||
[LinphoneLogger logc:LinphoneLoggerError format:"Can't prepare the query: %s (%s)", sql, sqlite3_errmsg(database)];
|
||||
return;
|
||||
}
|
||||
|
||||
// Prepare statement
|
||||
sqlite3_bind_text(sqlStatement, 1, [contact UTF8String], -1, SQLITE_STATIC);
|
||||
|
||||
if (sqlite3_step(sqlStatement) != SQLITE_DONE) {
|
||||
[LinphoneLogger logc:LinphoneLoggerError format:"Error during execution of query: %s (%s)", sql, sqlite3_errmsg(database)];
|
||||
sqlite3_finalize(sqlStatement);
|
||||
return;
|
||||
}
|
||||
|
||||
sqlite3_finalize(sqlStatement);
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
@ -219,9 +219,9 @@ static PhoneMainView* phoneMainViewInstance=nil;
|
|||
#pragma mark - Event Functions
|
||||
|
||||
- (void)textReceived:(NSNotification*)notif {
|
||||
ChatModel *chat = [[notif userInfo] objectForKey:@"chat"];
|
||||
if(chat != nil) {
|
||||
[self displayMessage:chat];
|
||||
LinphoneAddress*from = [[notif.userInfo objectForKey:@"from_address"] pointerValue];
|
||||
if(from != nil) {
|
||||
[self playMessageSound];
|
||||
}
|
||||
[self updateApplicationBadgeNumber];
|
||||
}
|
||||
|
|
@ -377,7 +377,7 @@ static PhoneMainView* phoneMainViewInstance=nil;
|
|||
- (void)updateApplicationBadgeNumber {
|
||||
int count = 0;
|
||||
count += linphone_core_get_missed_calls_count([LinphoneManager getLc]);
|
||||
count += [ChatModel unreadMessages];
|
||||
count += [LinphoneManager unreadMessageCount];
|
||||
count += linphone_core_get_calls_nb([LinphoneManager getLc]);
|
||||
[[UIApplication sharedApplication] setApplicationIconBadgeNumber:count];
|
||||
}
|
||||
|
|
@ -598,7 +598,7 @@ static PhoneMainView* phoneMainViewInstance=nil;
|
|||
|
||||
#pragma mark - ActionSheet Functions
|
||||
|
||||
- (void)displayMessage:(ChatModel*)chat {
|
||||
- (void)playMessageSound {
|
||||
if (![[UIDevice currentDevice] respondsToSelector:@selector(isMultitaskingSupported)]
|
||||
|| [UIApplication sharedApplication].applicationState == UIApplicationStateActive) {
|
||||
if(![self removeInhibitedEvent:kLinphoneTextReceived]) {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue