From 1f8d455e7760c013814117e3ac1e18e236987c1e Mon Sep 17 00:00:00 2001 From: Guillaume BIENKOWSKI Date: Tue, 3 Jun 2014 18:09:33 +0200 Subject: [PATCH] Use app-data storage in Chat messages for image path storage. Implemented with a JSON dictionary for subsequent evolution. --- Classes/ChatRoomViewController.m | 63 ++++++++++++++++------------- Classes/LinphoneManager.h | 4 ++ Classes/LinphoneManager.m | 27 +++++++++++++ Classes/LinphoneUI/UIChatRoomCell.m | 15 ++++--- 4 files changed, 75 insertions(+), 34 deletions(-) diff --git a/Classes/ChatRoomViewController.m b/Classes/ChatRoomViewController.m index 23baa2827..cdfc82e09 100644 --- a/Classes/ChatRoomViewController.m +++ b/Classes/ChatRoomViewController.m @@ -311,7 +311,7 @@ static void message_status(LinphoneChatMessage* msg,LinphoneChatMessageState sta [thiz.tableController updateChatEntry:msg]; } -- (BOOL)sendMessage:(NSString *)message withExterlBodyUrl:(NSURL*)externalUrl { +- (BOOL)sendMessage:(NSString *)message withExterlBodyUrl:(NSURL*)externalUrl withInternalURL:(NSURL*)internalUrl { if(![LinphoneManager isLcReady]) { [LinphoneLogger logc:LinphoneLoggerWarning format:"Cannot send message: Linphone core not ready"]; return FALSE; @@ -325,7 +325,14 @@ static void message_status(LinphoneChatMessage* msg,LinphoneChatMessageState sta if(externalUrl) { linphone_chat_message_set_external_body_url(msg, [[externalUrl absoluteString] UTF8String]); } + linphone_chat_room_send_message2(chatRoom, msg, message_status, self); + + if ( internalUrl ) { + // internal url is saved in the appdata for display and later save + [LinphoneManager setValueInMessageAppData:[internalUrl absoluteString] forKey:@"localimage" inMessage:msg]; + } + [tableController addChatEntry:linphone_chat_message_ref(msg)]; [tableController scrollToBottom:true]; return TRUE; @@ -335,27 +342,28 @@ static void message_status(LinphoneChatMessage* msg,LinphoneChatMessageState sta if(url == nil) { [waitView setHidden:FALSE]; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - [[LinphoneManager instance].photoLibrary writeImageToSavedPhotosAlbum:image.CGImage - orientation:(ALAssetOrientation)[image imageOrientation] - completionBlock:^(NSURL *assetURL, NSError *error){ - dispatch_async(dispatch_get_main_queue(), ^{ - [waitView setHidden:TRUE]; - if (error) { - [LinphoneLogger log:LinphoneLoggerError format:@"Cannot save image data downloaded [%@]", [error localizedDescription]]; + [[LinphoneManager instance].photoLibrary + writeImageToSavedPhotosAlbum:image.CGImage + orientation:(ALAssetOrientation)[image imageOrientation] + completionBlock:^(NSURL *assetURL, NSError *error){ + dispatch_async(dispatch_get_main_queue(), ^{ + [waitView setHidden:TRUE]; + if (error) { + [LinphoneLogger log:LinphoneLoggerError format:@"Cannot save image data downloaded [%@]", [error localizedDescription]]; - UIAlertView* errorAlert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Transfer error", nil) - message:NSLocalizedString(@"Cannot write image to photo library", nil) - delegate:nil - cancelButtonTitle:NSLocalizedString(@"Ok",nil) - otherButtonTitles:nil ,nil]; - [errorAlert show]; - [errorAlert release]; - return; - } - [LinphoneLogger log:LinphoneLoggerLog format:@"Image saved to [%@]", [assetURL absoluteString]]; - [self chatRoomStartImageUpload:image url:assetURL]; - }); - }]; + UIAlertView* errorAlert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Transfer error", nil) + message:NSLocalizedString(@"Cannot write image to photo library", nil) + delegate:nil + cancelButtonTitle:NSLocalizedString(@"Ok",nil) + otherButtonTitles:nil ,nil]; + [errorAlert show]; + [errorAlert release]; + return; + } + [LinphoneLogger log:LinphoneLoggerLog format:@"Image saved to [%@]", [assetURL absoluteString]]; + [self chatRoomStartImageUpload:image url:assetURL]; + }); + }]; }); } else { [self chatRoomStartImageUpload:image url:url]; @@ -364,7 +372,7 @@ static void message_status(LinphoneChatMessage* msg,LinphoneChatMessageState sta - (void)chooseImageQuality:(UIImage*)image url:(NSURL*)url { [waitView setHidden:FALSE]; - + DTActionSheet *sheet = [[DTActionSheet alloc] initWithTitle:NSLocalizedString(@"Choose the image size", nil)]; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ //UIImage *image = [original_image normalizedImage]; @@ -372,7 +380,7 @@ static void message_status(LinphoneChatMessage* msg,LinphoneChatMessageState sta NSNumber *number = [imageQualities objectForKey:key]; NSData *data = UIImageJPEGRepresentation(image, [number floatValue]); NSNumber *size = [NSNumber numberWithInteger:[data length]]; - + NSString *text = [NSString stringWithFormat:@"%@ (%@)", key, [size toHumanReadableSize]]; [sheet addButtonWithTitle:text block:^(){ [self saveAndSend:[UIImage imageWithData:data] url:url]; @@ -530,7 +538,7 @@ static void message_status(LinphoneChatMessage* msg,LinphoneChatMessageState sta } - (IBAction)onSendClick:(id)event { - if([self sendMessage:[messageField text] withExterlBodyUrl:nil]) { + if([self sendMessage:[messageField text] withExterlBodyUrl:nil withInternalURL:nil]) { scrollOnGrowingEnabled = FALSE; [messageField setText:@""]; scrollOnGrowingEnabled = TRUE; @@ -627,7 +635,7 @@ static void message_status(LinphoneChatMessage* msg,LinphoneChatMessageState sta } - (void)resendChat:(NSString *)message withExternalUrl:(NSString *)url { - [self sendMessage:message withExterlBodyUrl:[NSURL URLWithString:url]]; + [self sendMessage:message withExterlBodyUrl:[NSURL URLWithString:url] withInternalURL:nil]; } #pragma mark ImageSharingDelegate @@ -670,7 +678,7 @@ static void message_status(LinphoneChatMessage* msg,LinphoneChatMessageState sta } - (void)imageSharingUploadDone:(ImageSharing*)aimageSharing url:(NSURL*)url{ - [self sendMessage:nil withExterlBodyUrl:url]; + [self sendMessage:nil withExterlBodyUrl:url withInternalURL:[aimageSharing userInfo] ]; [messageView setHidden:FALSE]; [transferView setHidden:TRUE]; @@ -698,8 +706,7 @@ static void message_status(LinphoneChatMessage* msg,LinphoneChatMessageState sta return; } [LinphoneLogger log:LinphoneLoggerLog format:@"Image saved to [%@]", [assetURL absoluteString]]; - linphone_chat_message_set_external_body_url(chat, [[assetURL absoluteString] UTF8String]); - linphone_chat_room_update_url(chatRoom, chat); + [LinphoneManager setValueInMessageAppData:[assetURL absoluteString] forKey:@"localimage" inMessage:chat]; [tableController updateChatEntry:chat]; }]; imageSharing = nil; diff --git a/Classes/LinphoneManager.h b/Classes/LinphoneManager.h index a527c4f6a..6fa0e1fd7 100644 --- a/Classes/LinphoneManager.h +++ b/Classes/LinphoneManager.h @@ -161,6 +161,10 @@ typedef struct _LinphoneManagerSounds { - (void)acceptCall:(LinphoneCall *)call; - (void)call:(NSString *)address displayName:(NSString*)displayName transfer:(BOOL)transfer; + ++(id)getMessageAppDataForKey:(NSString*)key inMessage:(LinphoneChatMessage*)msg; ++(void)setValueInMessageAppData:(id)value forKey:(NSString*)key inMessage:(LinphoneChatMessage*)msg; + - (void)lpConfigSetString:(NSString*)value forKey:(NSString*)key; - (NSString*)lpConfigStringForKey:(NSString*)key; - (NSString*)lpConfigStringForKey:(NSString*)key withDefault:(NSString*)value; diff --git a/Classes/LinphoneManager.m b/Classes/LinphoneManager.m index 4f3802a13..2305b807c 100644 --- a/Classes/LinphoneManager.m +++ b/Classes/LinphoneManager.m @@ -1782,6 +1782,33 @@ static void audioRouteChangeListenerCallback ( } } ++(id)getMessageAppDataForKey:(NSString*)key inMessage:(LinphoneChatMessage*)msg { + + if(msg == nil ) return nil; + + id value = nil; + const char* appData = linphone_chat_message_get_appdata(msg); + if( appData) { + NSDictionary* appDataDict = [NSJSONSerialization JSONObjectWithData:[NSData dataWithBytes:appData length:strlen(appData)] options:0 error:nil]; + value = [appDataDict objectForKey:key]; + } + return value; +} + ++(void)setValueInMessageAppData:(id)value forKey:(NSString*)key inMessage:(LinphoneChatMessage*)msg { + + NSMutableDictionary* appDataDict = [NSMutableDictionary dictionary]; + const char* appData = linphone_chat_message_get_appdata(msg); + if( appData) { + appDataDict = [NSJSONSerialization JSONObjectWithData:[NSData dataWithBytes:appData length:strlen(appData)] options:NSJSONReadingMutableContainers error:nil]; + } + + [appDataDict setValue:value forKey:key]; + + NSData* data = [NSJSONSerialization dataWithJSONObject:appDataDict options:0 error:nil]; + NSString* appdataJSON = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; + linphone_chat_message_set_appdata(msg, [appdataJSON UTF8String] ); +} #pragma mark - LPConfig Functions diff --git a/Classes/LinphoneUI/UIChatRoomCell.m b/Classes/LinphoneUI/UIChatRoomCell.m index 3bc0b6d71..be5fb2d36 100644 --- a/Classes/LinphoneUI/UIChatRoomCell.m +++ b/Classes/LinphoneUI/UIChatRoomCell.m @@ -115,19 +115,21 @@ static UIFont *CELL_FONT = nil; [LinphoneLogger logc:LinphoneLoggerWarning format:"Cannot update chat room cell: null chat"]; return; } - 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); + 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); + NSString* localImage = [LinphoneManager getMessageAppDataForKey:@"localimage" inMessage:chat]; - if(is_external) { + + if(is_external && !localImage ) { [messageText setHidden:TRUE]; [messageImageView setImage:nil]; [messageImageView setHidden:TRUE]; [downloadButton setHidden:FALSE]; - } else if(url) { + } else if(localImage) { - NSURL* imageUrl = [NSURL URLWithString:[NSString stringWithUTF8String:url]]; + NSURL* imageUrl = [NSURL URLWithString:localImage]; [messageText setHidden:TRUE]; [messageImageView setImage:nil]; @@ -152,6 +154,7 @@ static UIFont *CELL_FONT = nil; [messageImageView setHidden:FALSE]; [downloadButton setHidden:TRUE]; } else { + // simple text message [messageText setHidden:FALSE]; [messageText setText:[NSString stringWithUTF8String:text]];