From ec0d6c8b3d5bdd799340a59823e71ad8a4245be0 Mon Sep 17 00:00:00 2001 From: Gautier Pelloux-Prayer Date: Wed, 9 Sep 2015 12:42:59 +0200 Subject: [PATCH] handle avatar --- Classes/Base.lproj/ChatRoomViewController.xib | 1 - .../HistoryDetailsViewController.xib | 1 - .../Base.lproj/IncomingCallViewController.xib | 1 - .../Base.lproj/OutgoingCallViewController.xib | 1 - Classes/ChatRoomViewController.m | 53 +----------------- Classes/ImagePickerViewController.h | 4 ++ Classes/ImagePickerViewController.m | 55 +++++++++++++++++++ Classes/LinphoneUI/Base.lproj/UICallCell.xib | 1 - Classes/LinphoneUI/Base.lproj/UIChatCell.xib | 1 - .../LinphoneUI/Base.lproj/UIContactCell.xib | 9 +-- .../LinphoneUI/Base.lproj/UIHistoryCell.xib | 1 - Classes/LinphoneUI/UIChatRoomCell.m | 3 +- Classes/LinphoneUI/UIRoundedImageView.m | 4 ++ Classes/SideMenuTableViewController.m | 1 + Classes/SideMenuViewController.h | 7 ++- Classes/SideMenuViewController.m | 34 ++++++++++++ Classes/SideMenuViewController.xib | 20 +++++-- Classes/Utils/FastAddressBook.m | 25 +-------- Classes/Utils/Utils.h | 6 ++ Classes/Utils/Utils.m | 27 +++++++++ 20 files changed, 156 insertions(+), 99 deletions(-) diff --git a/Classes/Base.lproj/ChatRoomViewController.xib b/Classes/Base.lproj/ChatRoomViewController.xib index 7bcc87e71..de363f169 100644 --- a/Classes/Base.lproj/ChatRoomViewController.xib +++ b/Classes/Base.lproj/ChatRoomViewController.xib @@ -1,7 +1,6 @@ - diff --git a/Classes/Base.lproj/HistoryDetailsViewController.xib b/Classes/Base.lproj/HistoryDetailsViewController.xib index c7c80de01..c95b809e4 100644 --- a/Classes/Base.lproj/HistoryDetailsViewController.xib +++ b/Classes/Base.lproj/HistoryDetailsViewController.xib @@ -1,7 +1,6 @@ - diff --git a/Classes/Base.lproj/IncomingCallViewController.xib b/Classes/Base.lproj/IncomingCallViewController.xib index 7615542c4..0364d5f6d 100644 --- a/Classes/Base.lproj/IncomingCallViewController.xib +++ b/Classes/Base.lproj/IncomingCallViewController.xib @@ -1,7 +1,6 @@ - diff --git a/Classes/Base.lproj/OutgoingCallViewController.xib b/Classes/Base.lproj/OutgoingCallViewController.xib index 06f1bff5a..710706c99 100644 --- a/Classes/Base.lproj/OutgoingCallViewController.xib +++ b/Classes/Base.lproj/OutgoingCallViewController.xib @@ -1,7 +1,6 @@ - diff --git a/Classes/ChatRoomViewController.m b/Classes/ChatRoomViewController.m index 197cf8da5..0a59bd1a0 100644 --- a/Classes/ChatRoomViewController.m +++ b/Classes/ChatRoomViewController.m @@ -21,7 +21,6 @@ #import "PhoneMainView.h" #import "UILinphone.h" #import "Utils/FileTransferDelegate.h" -#import #import "UIChatRoomCell.h" @implementation ChatRoomViewController @@ -461,56 +460,8 @@ static void message_status(LinphoneChatMessage *msg, LinphoneChatMessageState st - (IBAction)onPictureClick:(id)event { [messageField resignFirstResponder]; - - void (^block)(UIImagePickerControllerSourceType) = ^(UIImagePickerControllerSourceType type) { - UICompositeViewDescription *description = [ImagePickerViewController compositeViewDescription]; - ImagePickerViewController *controller; - if ([LinphoneManager runningOnIpad]) { - controller = - DYNAMIC_CAST([[PhoneMainView instance].mainViewController getCachedController:description.content], - ImagePickerViewController); - } else { - controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:description push:TRUE], - ImagePickerViewController); - } - if (controller != nil) { - controller.sourceType = type; - - // Displays a control that allows the user to choose picture or - // movie capture, if both are available: - controller.mediaTypes = [NSArray arrayWithObject:(NSString *)kUTTypeImage]; - - // Hides the controls for moving & scaling pictures, or for - // trimming movies. To instead show the controls, use YES. - controller.allowsEditing = NO; - controller.imagePickerDelegate = self; - - if ([LinphoneManager runningOnIpad]) { - CGRect rect = [self.messageView convertRect:[pictureButton frame] toView:self.view]; - [controller.popoverController presentPopoverFromRect:rect - inView:self.view - permittedArrowDirections:UIPopoverArrowDirectionAny - animated:FALSE]; - } - } - }; - - DTActionSheet *sheet = [[DTActionSheet alloc] initWithTitle:NSLocalizedString(@"Select picture source", nil)]; - if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) { - [sheet addButtonWithTitle:NSLocalizedString(@"Camera", nil) - block:^() { - block(UIImagePickerControllerSourceTypeCamera); - }]; - } - if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) { - [sheet addButtonWithTitle:NSLocalizedString(@"Photo library", nil) - block:^() { - block(UIImagePickerControllerSourceTypePhotoLibrary); - }]; - } - [sheet addCancelButtonWithTitle:NSLocalizedString(@"Cancel", nil) block:nil]; - - [sheet showInView:[PhoneMainView instance].view]; + CGRect rect = [self.messageView convertRect:[pictureButton frame] toView:self.view]; + [ImagePickerViewController SelectImageFromDevice:self atPosition:rect inView:self.view]; } #pragma mark ChatRoomDelegate diff --git a/Classes/ImagePickerViewController.h b/Classes/ImagePickerViewController.h index 2902fb539..ca71b60a9 100644 --- a/Classes/ImagePickerViewController.h +++ b/Classes/ImagePickerViewController.h @@ -36,4 +36,8 @@ @property(nonatomic) BOOL allowsEditing; @property(nonatomic, readonly) UIPopoverController *popoverController; ++ (void)SelectImageFromDevice:(id)delegate + atPosition:(CGRect)ipadPopoverPosition + inView:(UIView *)view; + @end diff --git a/Classes/ImagePickerViewController.m b/Classes/ImagePickerViewController.m index 6ebea0adb..d2cc90ed8 100644 --- a/Classes/ImagePickerViewController.m +++ b/Classes/ImagePickerViewController.m @@ -17,6 +17,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#import + #import "ImagePickerViewController.h" #import "PhoneMainView.h" @@ -161,4 +163,57 @@ static UICompositeViewDescription *compositeDescription = nil; } } ++ (void)SelectImageFromDevice:(id)delegate + atPosition:(CGRect)ipadPopoverPosition + inView:(UIView *)view { + void (^block)(UIImagePickerControllerSourceType) = ^(UIImagePickerControllerSourceType type) { + UICompositeViewDescription *description = [ImagePickerViewController compositeViewDescription]; + ImagePickerViewController *controller; + if ([LinphoneManager runningOnIpad] && view) { + controller = + DYNAMIC_CAST([[PhoneMainView instance].mainViewController getCachedController:description.content], + ImagePickerViewController); + } else { + controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:description push:TRUE], + ImagePickerViewController); + } + if (controller != nil) { + controller.sourceType = type; + + // Displays a control that allows the user to choose picture or + // movie capture, if both are available: + controller.mediaTypes = [NSArray arrayWithObject:(NSString *)kUTTypeImage]; + + // Hides the controls for moving & scaling pictures, or for + // trimming movies. To instead show the controls, use YES. + controller.allowsEditing = NO; + controller.imagePickerDelegate = delegate; + + if ([LinphoneManager runningOnIpad] && view) { + [controller.popoverController presentPopoverFromRect:ipadPopoverPosition + inView:view + permittedArrowDirections:UIPopoverArrowDirectionAny + animated:FALSE]; + } + } + }; + + DTActionSheet *sheet = [[DTActionSheet alloc] initWithTitle:NSLocalizedString(@"Select picture source", nil)]; + if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) { + [sheet addButtonWithTitle:NSLocalizedString(@"Camera", nil) + block:^() { + block(UIImagePickerControllerSourceTypeCamera); + }]; + } + if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) { + [sheet addButtonWithTitle:NSLocalizedString(@"Photo library", nil) + block:^() { + block(UIImagePickerControllerSourceTypePhotoLibrary); + }]; + } + [sheet addCancelButtonWithTitle:NSLocalizedString(@"Cancel", nil) block:nil]; + + [sheet showInView:[PhoneMainView instance].view]; +} + @end diff --git a/Classes/LinphoneUI/Base.lproj/UICallCell.xib b/Classes/LinphoneUI/Base.lproj/UICallCell.xib index 178e0a6d4..2977e89a3 100644 --- a/Classes/LinphoneUI/Base.lproj/UICallCell.xib +++ b/Classes/LinphoneUI/Base.lproj/UICallCell.xib @@ -1,7 +1,6 @@ - diff --git a/Classes/LinphoneUI/Base.lproj/UIChatCell.xib b/Classes/LinphoneUI/Base.lproj/UIChatCell.xib index 34524bcb4..060319461 100644 --- a/Classes/LinphoneUI/Base.lproj/UIChatCell.xib +++ b/Classes/LinphoneUI/Base.lproj/UIChatCell.xib @@ -1,7 +1,6 @@ - diff --git a/Classes/LinphoneUI/Base.lproj/UIContactCell.xib b/Classes/LinphoneUI/Base.lproj/UIContactCell.xib index 28c94bfa2..a25535ce8 100644 --- a/Classes/LinphoneUI/Base.lproj/UIContactCell.xib +++ b/Classes/LinphoneUI/Base.lproj/UIContactCell.xib @@ -1,7 +1,7 @@ - 1536 + 2048 14D136 7706 1347.57 @@ -33,7 +33,7 @@ IBCocoaTouchFramework - + 274 @@ -41,7 +41,6 @@ 300 {{6, 6}, {32, 32}} - _NS:9 NO @@ -56,7 +55,6 @@ 274 {{46, 0}, {273, 44}} - _NS:328 @@ -115,7 +113,6 @@ 297 {{327, 11}, {25, 22}} - _NS:9 NO IBCocoaTouchFramework @@ -126,8 +123,6 @@ {360, 44} - - _NS:9 diff --git a/Classes/LinphoneUI/Base.lproj/UIHistoryCell.xib b/Classes/LinphoneUI/Base.lproj/UIHistoryCell.xib index 2cc0065da..391957bd8 100644 --- a/Classes/LinphoneUI/Base.lproj/UIHistoryCell.xib +++ b/Classes/LinphoneUI/Base.lproj/UIHistoryCell.xib @@ -1,7 +1,6 @@ - diff --git a/Classes/LinphoneUI/UIChatRoomCell.m b/Classes/LinphoneUI/UIChatRoomCell.m index 06fb1f4ca..5bb0ac0d8 100644 --- a/Classes/LinphoneUI/UIChatRoomCell.m +++ b/Classes/LinphoneUI/UIChatRoomCell.m @@ -159,8 +159,7 @@ static UIFont *CELL_FONT = nil; messageText.hidden = YES; [messageImageView startLoading]; __block LinphoneChatMessage *achat = chat; - [[LinphoneManager instance] - .photoLibrary assetForURL:imageUrl + [LinphoneManager.instance.photoLibrary assetForURL:imageUrl resultBlock:^(ALAsset *asset) { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, (unsigned long)NULL), ^(void) { diff --git a/Classes/LinphoneUI/UIRoundedImageView.m b/Classes/LinphoneUI/UIRoundedImageView.m index 5a4fcd3e1..3946b09f4 100644 --- a/Classes/LinphoneUI/UIRoundedImageView.m +++ b/Classes/LinphoneUI/UIRoundedImageView.m @@ -8,6 +8,7 @@ #import "UIRoundedImageView.h" #import +#import "Utils.h" @implementation UIRoundedImageView @@ -25,6 +26,9 @@ - (void)setImage:(UIImage *)image withRoundedRadius:(BOOL)rounded { [super setImage:image]; + if (image.size.width != image.size.height) { + LOGI(@"Image is not squared (%dx%d) - cropping it", image.size.width, image.size.height); + } [self setRoundRadius:rounded]; } diff --git a/Classes/SideMenuTableViewController.m b/Classes/SideMenuTableViewController.m index c1c060624..2e8376bc2 100644 --- a/Classes/SideMenuTableViewController.m +++ b/Classes/SideMenuTableViewController.m @@ -77,6 +77,7 @@ ms_list_nth_data(linphone_core_get_proxy_config_list([LinphoneManager getLc]), (int)indexPath.row); cell.textLabel.text = [NSString stringWithUTF8String:linphone_address_get_username(linphone_proxy_config_get_identity_address(proxy))]; + cell.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"color_F"]]; } else { SideMenuEntry *entry = [_sideMenuEntries objectAtIndex:indexPath.row]; cell.textLabel.text = entry->title; diff --git a/Classes/SideMenuViewController.h b/Classes/SideMenuViewController.h index 8816e5f39..b2ef6ad46 100644 --- a/Classes/SideMenuViewController.h +++ b/Classes/SideMenuViewController.h @@ -9,13 +9,16 @@ #import #import "SideMenuTableViewController.h" +#import "PhoneMainView.h" -@interface SideMenuViewController : UIViewController -@property(weak, nonatomic) IBOutlet UIImageView *avatarImage; +@interface SideMenuViewController : UIViewController + +@property(weak, nonatomic) IBOutlet UIRoundedImageView *avatarImage; @property(weak, nonatomic) IBOutlet UILabel *nameLabel; @property(weak, nonatomic) IBOutlet UILabel *addressLabel; @property(strong, nonatomic) IBOutlet SideMenuTableViewController *sideMenuTableViewController; - (IBAction)onLateralSwipe:(id)sender; - (IBAction)onHeaderClick:(id)sender; +- (IBAction)onAvatarClick:(id)sender; @end diff --git a/Classes/SideMenuViewController.m b/Classes/SideMenuViewController.m index a5c51bc28..709de09a8 100644 --- a/Classes/SideMenuViewController.m +++ b/Classes/SideMenuViewController.m @@ -6,6 +6,8 @@ // // +#import + #import "SideMenuViewController.h" #import "LinphoneManager.h" #import "PhoneMainView.h" @@ -28,6 +30,23 @@ ms_free(as_string); [FastAddressBook getContactImage:[FastAddressBook getContactWithLinphoneAddress:addr] thumbnail:NO]; } + NSURL *url = [NSURL URLWithString:[LinphoneManager.instance lpConfigStringForKey:@"avatar"]]; + if (url) { + [LinphoneManager.instance.photoLibrary assetForURL:url + resultBlock:^(ALAsset *asset) { + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, (unsigned long)NULL), ^(void) { + UIImage *decodedImage = [[UIImage alloc] initWithCGImage:[asset thumbnail]]; + dispatch_async(dispatch_get_main_queue(), ^{ + [_avatarImage setImage:decodedImage]; + }); + }); + } + failureBlock:^(NSError *error) { + LOGE(@"Can't read image"); + }]; + } else { + [_avatarImage setImage:[UIImage imageNamed:@"avatar"]]; + } } - (void)viewWillAppear:(BOOL)animated { @@ -43,4 +62,19 @@ [PhoneMainView.instance changeCurrentView:SettingsViewController.compositeViewDescription]; [PhoneMainView.instance.mainViewController hideSideMenu:YES]; } + +- (IBAction)onAvatarClick:(id)sender { + // hide ourself because we are on top of image picker + [PhoneMainView.instance.mainViewController hideSideMenu:YES]; + [ImagePickerViewController SelectImageFromDevice:self atPosition:CGRectNull inView:nil]; +} + +#pragma mark - Image picker delegate + +- (void)imagePickerDelegateImage:(UIImage *)image info:(NSDictionary *)info { + NSURL *url = [info valueForKey:UIImagePickerControllerReferenceURL]; + [LinphoneManager.instance lpConfigSetString:url.absoluteString forKey:@"avatar"]; + [PhoneMainView.instance.mainViewController hideSideMenu:NO]; +} + @end diff --git a/Classes/SideMenuViewController.xib b/Classes/SideMenuViewController.xib index ad863af43..479d821e8 100644 --- a/Classes/SideMenuViewController.xib +++ b/Classes/SideMenuViewController.xib @@ -15,7 +15,7 @@ - + @@ -33,13 +33,16 @@ - + - - + + + + + - + @@ -89,7 +92,12 @@ - + + + + + + diff --git a/Classes/Utils/FastAddressBook.m b/Classes/Utils/FastAddressBook.m index 3c0d17155..c4ee798f3 100644 --- a/Classes/Utils/FastAddressBook.m +++ b/Classes/Utils/FastAddressBook.m @@ -34,29 +34,6 @@ static void sync_address_book(ABAddressBookRef addressBook, CFDictionaryRef info return retString; } -+ (UIImage *)squareImageCrop:(UIImage *)image { - UIImage *ret = nil; - - // This calculates the crop area. - - float originalWidth = image.size.width; - float originalHeight = image.size.height; - - float edge = fminf(originalWidth, originalHeight); - - float posX = (originalWidth - edge) / 2.0f; - float posY = (originalHeight - edge) / 2.0f; - - CGRect cropSquare = CGRectMake(posX, posY, edge, edge); - - CGImageRef imageRef = CGImageCreateWithImageInRect([image CGImage], cropSquare); - ret = [UIImage imageWithCGImage:imageRef scale:image.scale orientation:image.imageOrientation]; - - CGImageRelease(imageRef); - - return ret; -} - + (UIImage *)getContactImage:(ABRecordRef)contact thumbnail:(BOOL)thumbnail { UIImage *retImage = nil; if (contact && ABPersonHasImageData(contact)) { @@ -70,7 +47,7 @@ static void sync_address_book(ABAddressBookRef addressBook, CFDictionaryRef info } if (retImage.size.width != retImage.size.height) { LOGW(@"Image is not square (%@): cropping it.", retImage.size); - retImage = [self squareImageCrop:retImage]; + retImage = [retImage squareCrop]; } return retImage; } diff --git a/Classes/Utils/Utils.h b/Classes/Utils/Utils.h index b047b2bf0..1f0447b5d 100644 --- a/Classes/Utils/Utils.h +++ b/Classes/Utils/Utils.h @@ -66,6 +66,12 @@ void linphone_iphone_log_handler(int lev, const char *fmt, va_list args); @end +@interface UIImage (squareCrop) + +- (UIImage *)squareCrop; + +@end + @interface ContactDisplay : NSObject + (void)setDisplayNameLabel:(UILabel *)label forContact:(ABRecordRef)contact; + (void)setDisplayNameLabel:(UILabel *)label forAddress:(const LinphoneAddress *)addr; diff --git a/Classes/Utils/Utils.m b/Classes/Utils/Utils.m index 438788f64..5470198ec 100644 --- a/Classes/Utils/Utils.m +++ b/Classes/Utils/Utils.m @@ -353,4 +353,31 @@ void linphone_iphone_log_handler(int lev, const char *fmt, va_list args) { label.text = [FastAddressBook displayNameForAddress:addr]; } +@end + +@implementation UIImage (squareCrop) + +- (UIImage *)squareCrop { + UIImage *ret = nil; + + // This calculates the crop area. + + float originalWidth = self.size.width; + float originalHeight = self.size.height; + + float edge = fminf(originalWidth, originalHeight); + + float posX = (originalWidth - edge) / 2.0f; + float posY = (originalHeight - edge) / 2.0f; + + CGRect cropSquare = CGRectMake(posX, posY, edge, edge); + + CGImageRef imageRef = CGImageCreateWithImageInRect([self CGImage], cropSquare); + ret = [UIImage imageWithCGImage:imageRef scale:self.scale orientation:self.imageOrientation]; + + CGImageRelease(imageRef); + + return ret; +} + @end \ No newline at end of file