diff --git a/Classes/Base.lproj/ChatConversationView.xib b/Classes/Base.lproj/ChatConversationView.xib
index 604c03dc1..1bb0fba72 100644
--- a/Classes/Base.lproj/ChatConversationView.xib
+++ b/Classes/Base.lproj/ChatConversationView.xib
@@ -18,6 +18,8 @@
+
+
@@ -269,6 +271,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Classes/ChatConversationView.h b/Classes/ChatConversationView.h
index 7a264ca8e..0a2f99c0c 100644
--- a/Classes/ChatConversationView.h
+++ b/Classes/ChatConversationView.h
@@ -27,12 +27,13 @@
#import "UIRoundedImageView.h"
#import "UIBackToCallButton.h"
#import "Utils/HPGrowingTextView/HPGrowingTextView.h"
+#import "UIImageViewDeletable.h"
#include "linphone/linphonecore.h"
@interface ChatConversationView
: TPMultiLayoutViewController {
+ UIDocumentInteractionControllerDelegate, UISearchBarDelegate, UIImageViewDeletableDelegate, UICollectionViewDataSource> {
OrderedDictionary *imageQualities;
BOOL scrollOnGrowingEnabled;
BOOL composingVisible;
@@ -60,6 +61,12 @@
@property (weak, nonatomic) IBOutlet UIIconButton *infoButton;
@property (weak, nonatomic) IBOutlet UILabel *particpantsLabel;
@property (nonatomic, strong) UIDocumentInteractionController *documentInteractionController;
+@property NSMutableArray *imagesArray;
+@property NSMutableArray *assetIdsArray;
+@property NSMutableArray *qualitySettingsArray;
+@property (weak, nonatomic) IBOutlet UICollectionView *imagesCollectionView;
+@property (weak, nonatomic) IBOutlet UIView *imagesView;
+
+ (void)markAsRead:(LinphoneChatRoom *)chatRoom;
- (void)configureForRoom:(BOOL)editing;
@@ -74,5 +81,6 @@
- (IBAction)onEditionChangeClick:(id)sender;
- (void)update;
- (void)openResults:(NSString *) filePath;
+- (void)clearMessageView;
@end
diff --git a/Classes/ChatConversationView.m b/Classes/ChatConversationView.m
index 54077999b..6008b869e 100644
--- a/Classes/ChatConversationView.m
+++ b/Classes/ChatConversationView.m
@@ -101,6 +101,8 @@ static UICompositeViewDescription *compositeDescription = nil;
_messageField.contentInset = UIEdgeInsetsMake(-15, 0, 0, 0);
// _messageField.internalTextView.scrollIndicatorInsets = UIEdgeInsetsMake(0, 0, 0, 10);
[_tableController setChatRoomDelegate:self];
+ [_imagesCollectionView registerClass:[UIImageViewDeletable class] forCellWithReuseIdentifier:NSStringFromClass([UIImageViewDeletable class])];
+ [_imagesCollectionView setDataSource:self];
}
- (void)viewWillAppear:(BOOL)animated {
@@ -125,6 +127,24 @@ static UICompositeViewDescription *compositeDescription = nil;
selector:@selector(callUpdateEvent:)
name:kLinphoneCallUpdate
object:nil];
+
+ if ([_imagesArray count] > 0) {
+ [UIView animateWithDuration:0
+ delay:0
+ options:UIViewAnimationOptionBeginFromCurrentState
+ animations:^{
+ // resizing imagesView
+ CGRect imagesFrame = [_imagesView frame];
+ imagesFrame.origin.y = [_messageView frame].origin.y - 100;
+ imagesFrame.size.height = 100;
+ [_imagesView setFrame:imagesFrame];
+ // resizing chatTable
+ CGRect tableViewFrame = [_tableController.tableView frame];
+ tableViewFrame.size.height -= 100;
+ [_tableController.tableView setFrame:tableViewFrame];
+ }
+ completion:nil];
+ }
}
- (void)viewWillDisappear:(BOOL)animated {
@@ -203,7 +223,6 @@ static UICompositeViewDescription *compositeDescription = nil;
_messageField.editable = !linphone_chat_room_has_been_left(_chatRoom);
_pictureButton.enabled = !linphone_chat_room_has_been_left(_chatRoom);
_messageView.userInteractionEnabled = !linphone_chat_room_has_been_left(_chatRoom);
- [_messageField setText:@""];
[_tableController setChatRoom:_chatRoom];
_chatView.hidden = NO;
@@ -222,7 +241,12 @@ static UICompositeViewDescription *compositeDescription = nil;
//share photo
NSData *data = dict[@"nsData"];
UIImage *image = [[UIImage alloc] initWithData:data];
- [self chooseImageQuality:image assetId:nil];
+ NSString *filename = dict[@"url"];
+ if (filename) {
+ NSMutableDictionary * assetDict = [LinphoneUtils photoAssetsDictionary];
+ [self chooseImageQuality:image assetId:[[assetDict objectForKey:filename] localIdentifier]];
+ } else
+ [self chooseImageQuality:image assetId:@""];
[defaults removeObjectForKey:@"img"];
} else if (dictWeb) {
//share url, if local file, then upload file
@@ -311,7 +335,11 @@ static UICompositeViewDescription *compositeDescription = nil;
}
- (void)saveAndSend:(UIImage *)image assetId:(NSString *)phAssetId withQuality:(float)quality{
- [self startImageUpload:image assetId:phAssetId withQuality:quality];
+
+ [_imagesArray addObject:image];
+ [_assetIdsArray addObject:phAssetId];
+ [_qualitySettingsArray addObject:@(quality)];
+ [self addImageToDrawer:image withAssetId:phAssetId];
}
- (void)chooseImageQuality:(UIImage *)image assetId:(NSString *)phAssetId {
@@ -456,6 +484,12 @@ static UICompositeViewDescription *compositeDescription = nil;
messageRect.size.height += diff;
[_messageView setFrame:messageRect];
+ if ([_imagesArray count] > 0) {
+ CGRect _imagesRect = [_imagesView frame];
+ _imagesRect.origin.y -= diff;
+ [_imagesView setFrame:_imagesRect];
+ }
+
// Always stay at bottom
if (scrollOnGrowingEnabled) {
CGRect tableFrame = [_tableController.view frame];
@@ -493,6 +527,15 @@ static UICompositeViewDescription *compositeDescription = nil;
}
- (IBAction)onSendClick:(id)event {
+ if ([_imagesArray count] > 0) {
+ int i = 0;
+ for (i = 0; i < [_imagesArray count] - 1; ++i) {
+ [self startImageUpload:[_imagesArray objectAtIndex:i] assetId:[_assetIdsArray objectAtIndex:i] withQuality:[_qualitySettingsArray objectAtIndex:i].floatValue];
+ }
+ [self startImageUpload:[_imagesArray objectAtIndex:i] assetId:[_assetIdsArray objectAtIndex:i] withQuality:[_qualitySettingsArray objectAtIndex:i].floatValue andMessage:[self.messageField text]];
+ [self clearMessageView];
+ return;
+ }
if ([self sendMessage:[_messageField text] withExterlBodyUrl:nil withInternalURL:nil]) {
scrollOnGrowingEnabled = FALSE;
[_messageField setText:@""];
@@ -583,6 +626,14 @@ static UICompositeViewDescription *compositeDescription = nil;
return TRUE;
}
+- (BOOL)startImageUpload:(UIImage *)image assetId:(NSString *)phAssetId withQuality:(float)quality andMessage:(NSString *)message {
+ FileTransferDelegate *fileTransfer = [[FileTransferDelegate alloc] init];
+ [fileTransfer setText:message];
+ [fileTransfer upload:image withassetId:phAssetId forChatRoom:_chatRoom withQuality:quality];
+ [_tableController scrollToBottom:true];
+ return TRUE;
+}
+
- (BOOL)startFileUpload:(NSData *)data withUrl:(NSURL *)url {
FileTransferDelegate *fileTransfer = [[FileTransferDelegate alloc] init];
[fileTransfer uploadFile:data forChatRoom:_chatRoom withUrl:url];
@@ -611,6 +662,28 @@ static UICompositeViewDescription *compositeDescription = nil;
[VIEW(ImagePickerView).popoverController dismissPopoverAnimated:TRUE];
}
[self chooseImageQuality:image assetId:phAssetId];
+ //[self chooseImageQuality:image assetId:phAssetId];
+}
+
+- (void)addImageToDrawer:(UIImage *)img withAssetId:(NSString *)assetId {
+ if ([_imagesArray count] == 1) { // We resize chatView to display the image
+ [UIView animateWithDuration:0
+ delay:0
+ options:UIViewAnimationOptionBeginFromCurrentState
+ animations:^{
+ // resizing imagesView
+ CGRect imagesFrame = [_imagesView frame];
+ imagesFrame.origin.y = [_messageView frame].origin.y - 100;
+ imagesFrame.size.height = 100;
+ [_imagesView setFrame:imagesFrame];
+ // resizing chatTable
+ CGRect tableViewFrame = [_tableController.tableView frame];
+ tableViewFrame.size.height -= 100;
+ [_tableController.tableView setFrame:tableViewFrame];
+ }
+ completion:nil];
+ }
+ [_imagesCollectionView reloadData];
}
- (void)tableViewIsScrolling {
@@ -667,6 +740,19 @@ static UICompositeViewDescription *compositeDescription = nil;
}
}
}
+
+
+ if ([_imagesArray count] > 0){
+ // resizing imagesView
+ CGRect imagesFrame = [_imagesView frame];
+ imagesFrame.origin.y = [_messageView frame].origin.y - 100;
+ imagesFrame.size.height = 100;
+ [_imagesView setFrame:imagesFrame];
+ // resizing chatTable
+ CGRect tableViewFrame = [_tableController.tableView frame];
+ tableViewFrame.size.height -= 100;
+ [_tableController.tableView setFrame:tableViewFrame];
+ }
}
completion:^(BOOL finished){
@@ -722,6 +808,18 @@ static UICompositeViewDescription *compositeDescription = nil;
[_messageView frame].origin.y - tableFrame.origin.y - composeIndicatorCompensation;
[_tableController.view setFrame:tableFrame];
}
+
+ if ([_imagesArray count] > 0){
+ // resizing imagesView
+ CGRect imagesFrame = [_imagesView frame];
+ imagesFrame.origin.y = [_messageView frame].origin.y - 100;
+ imagesFrame.size.height = 100;
+ [_imagesView setFrame:imagesFrame];
+ // resizing chatTable
+ CGRect tableViewFrame = [_tableController.tableView frame];
+ tableViewFrame.size.height -= 100;
+ [_tableController.tableView setFrame:tableViewFrame];
+ }
// Scroll
NSInteger lastSection = [_tableController.tableView numberOfSections] - 1;
@@ -734,6 +832,7 @@ static UICompositeViewDescription *compositeDescription = nil;
animated:FALSE];
}
}
+
}
completion:^(BOOL finished){
}];
@@ -839,4 +938,70 @@ void on_chat_room_conference_left(LinphoneChatRoom *cr, const LinphoneEventLog *
}
}
+- (void)deleteImageWithAssetId:(NSString *)assetId {
+ NSUInteger key = [_assetIdsArray indexOfObject:assetId];
+ [_imagesArray removeObjectAtIndex:key];
+ [_assetIdsArray removeObjectAtIndex:key];
+ if ([_imagesArray count] == 0) {
+ [UIView animateWithDuration:0
+ delay:0
+ options:UIViewAnimationOptionBeginFromCurrentState
+ animations:^{
+ // resizing imagesView
+ CGRect imagesFrame = [_imagesView frame];
+ imagesFrame.origin.y = [_messageView frame].origin.y;
+ imagesFrame.size.height = 0;
+ [_imagesView setFrame:imagesFrame];
+ // resizing chatTable
+ CGRect tableViewFrame = [_tableController.tableView frame];
+ tableViewFrame.size.height += 100;
+ [_tableController.tableView setFrame:tableViewFrame];
+ }
+ completion:nil];
+
+ [_sendButton setEnabled:FALSE];
+ }
+ [_imagesCollectionView reloadData];
+}
+
+- (void)clearMessageView {
+ [_messageField setText:@""];
+ _imagesArray = [NSMutableArray array];
+ _assetIdsArray = [NSMutableArray array];
+
+ // resizing imagesView
+ [UIView animateWithDuration:0
+ delay:0
+ options:UIViewAnimationOptionBeginFromCurrentState
+ animations:^{
+ // resizing imagesView
+ CGRect imagesFrame = [_imagesView frame];
+ imagesFrame.origin.y = [_messageView frame].origin.y;
+ imagesFrame.size.height = 0;
+ [_imagesView setFrame:imagesFrame];
+
+ // resizing chatTable
+ CGRect tableViewFrame = [_tableController.tableView frame];
+ CGFloat composeIndicatorCompensation = composingVisible ? _composeIndicatorView.frame.size.height : 0.0f;
+ tableViewFrame.size.height = [_messageView frame].origin.y - tableViewFrame.origin.y - composeIndicatorCompensation;
+ [_tableController.tableView setFrame:tableViewFrame];
+ }
+ completion:nil];
+
+ [_imagesCollectionView reloadData];
+}
+
+- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
+ return [_imagesArray count];
+}
+
+- (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
+ UIImageViewDeletable *imgView = [collectionView dequeueReusableCellWithReuseIdentifier:NSStringFromClass([UIImageViewDeletable class]) forIndexPath:indexPath];
+ [imgView.image setImage:[UIImage resizeImage:[_imagesArray objectAtIndex:[indexPath item]] withMaxWidth:50 andMaxHeight:100]];
+ [imgView setAssetId:[_assetIdsArray objectAtIndex:[indexPath item]]];
+ [imgView setDeleteDelegate:self];
+ [_sendButton setEnabled:TRUE];
+ return imgView;
+}
+
@end
diff --git a/Classes/LinphoneUI/UIChatBubblePhotoCell.m b/Classes/LinphoneUI/UIChatBubblePhotoCell.m
index 99c85c91e..d81c69c3b 100644
--- a/Classes/LinphoneUI/UIChatBubblePhotoCell.m
+++ b/Classes/LinphoneUI/UIChatBubblePhotoCell.m
@@ -38,7 +38,6 @@
- (id)initWithIdentifier:(NSString *)identifier {
if ((self = [super initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier]) != nil) {
- // TODO: remove text cell subview
NSArray *arrayOfViews =
[[NSBundle mainBundle] loadNibNamed:NSStringFromClass(self.class) owner:self options:nil];
// resize cell to match .nib size. It is needed when resized the cell to
@@ -119,7 +118,7 @@
[[PHImageManager defaultManager] requestImageForAsset:asset targetSize:PHImageManagerMaximumSize contentMode:PHImageContentModeDefault options:options
resultHandler:^(UIImage *image, NSDictionary * info) {
if (image) {
- imageSize = [UIChatBubbleTextCell getMediaMessageSizefromOriginalSize:[image size] withWidth:chatTableView.tableView.frame.size.width];
+ imageSize = [UIChatBubbleTextCell getMediaMessageSizefromOriginalSize:[image size] withWidth:chatTableView.tableView.frame.size.width - 40];
UIImage *newImage = [UIImage UIImageResize:image toSize:imageSize];
[chatTableView.imagesInChatroom setObject:newImage forKey:[asset localIdentifier]];
[self loadImageAsset:asset image:newImage];
@@ -167,13 +166,24 @@
});
}
+- (void) loadPlaceholder {
+ dispatch_async(dispatch_get_main_queue(), ^{
+ //[_finalImage setImage:image];
+ //[_messageImageView setAsset:asset];
+ [_messageImageView stopLoading];
+ _messageImageView.hidden = YES;
+ _imageGestureRecognizer.enabled = YES;
+ _finalImage.hidden = NO;
+ [self layoutSubviews];
+ });
+}
+
- (void)update {
if (self.message == nil) {
LOGW(@"Cannot update message room cell: NULL message");
return;
}
- [super update];
-
+ [super update];
const char *url = linphone_chat_message_get_external_body_url(self.message);
BOOL is_external =
(url && (strstr(url, "http") == url)) || linphone_chat_message_get_file_transfer_information(self.message);
@@ -203,7 +213,7 @@
PHFetchResult *assets = [PHAsset fetchAssetsWithLocalIdentifiers:[NSArray arrayWithObject:localImage] options:nil];
UIImage *img = [chatTableView.imagesInChatroom objectForKey:localImage];
if (![assets firstObject])
- return;
+ [self loadPlaceholder];
PHAsset *asset = [assets firstObject];
if (img)
[self loadImageAsset:asset image:img];
@@ -415,6 +425,28 @@
bubbleFrame.origin.x = origin_x;
super.bubbleView.frame = bubbleFrame;
+
+ // Resizing Image view
+ if (_finalImage.image) {
+ CGRect imgFrame = self.finalAssetView.frame;
+ imgFrame.size = [UIChatBubbleTextCell getMediaMessageSizefromOriginalSize:[_finalImage.image size] withWidth:chatTableView.tableView.frame.size.width - 40];
+ imgFrame.origin.x = (bubbleFrame.size.width - imgFrame.size.width)/2;
+ self.finalAssetView.frame = imgFrame;
+
+ // Positioning text message
+ const char *utf8Text = linphone_chat_message_get_text_content(self.message);
+
+ CGRect textFrame = self.messageText.frame;
+ textFrame.origin = CGPointMake(textFrame.origin.x, self.finalAssetView.frame.origin.y + self.finalAssetView.frame.size.height);
+ if (!utf8Text) {
+ textFrame.size.height = 0;
+ } else {
+ textFrame.size.height = bubbleFrame.size.height - textFrame.origin.x;
+ }
+
+ self.messageText.frame = textFrame;
+ LOGD([NSString stringWithFormat:@"Text of the photoCell: %@, size of the text of the photoCell: %@", [self.messageText text], NSStringFromCGSize(textFrame.size)]);
+ }
}
@end
diff --git a/Classes/LinphoneUI/UIImageViewDeletable.h b/Classes/LinphoneUI/UIImageViewDeletable.h
new file mode 100644
index 000000000..f036fd6b7
--- /dev/null
+++ b/Classes/LinphoneUI/UIImageViewDeletable.h
@@ -0,0 +1,26 @@
+//
+// UIImageViewDeletable.h
+// linphone
+//
+// Created by benjamin_verdier on 28/06/2018.
+//
+
+#import
+
+@protocol UIImageViewDeletableDelegate
+
+@required
+
+- (void)deleteImageWithAssetId:(NSString *)assetId;
+
+@end
+
+@interface UIImageViewDeletable : UICollectionViewCell
+
+@property NSString *assetId;
+@property(nonatomic, strong) id deleteDelegate;
+@property (weak, nonatomic) IBOutlet UIImageView *image;
+
+- (IBAction)onDeletePressed;
+
+@end
diff --git a/Classes/LinphoneUI/UIImageViewDeletable.m b/Classes/LinphoneUI/UIImageViewDeletable.m
new file mode 100644
index 000000000..157dd640a
--- /dev/null
+++ b/Classes/LinphoneUI/UIImageViewDeletable.m
@@ -0,0 +1,59 @@
+//
+// UIImageViewDeletable.m
+// linphone
+//
+// Created by benjamin_verdier on 28/06/2018.
+//
+
+#import "UIImageViewDeletable.h"
+
+@interface UIImageViewDeletable ()
+
+@end
+
+@implementation UIImageViewDeletable
+
+- (UIImageViewDeletable *)init {
+ self = [super init];
+ if (self) {
+ NSArray *arrayOfViews =
+ [[NSBundle mainBundle] loadNibNamed:NSStringFromClass(self.class) owner:self options:nil];
+ // resize cell to match .nib size. It is needed when resized the cell to
+ // correctly adapt its height too
+ UIView *sub = ((UIView *)[arrayOfViews objectAtIndex:arrayOfViews.count - 1]);
+ [self setFrame:CGRectMake(0, 0, sub.frame.size.width, sub.frame.size.height)];
+ [self addSubview:sub];
+ }
+ return self;
+}
+
+
+- (UIImageViewDeletable *)initWithFrame:(CGRect)frame {
+ self = [super initWithFrame:frame];
+ if (self) {
+ NSArray *arrayOfViews =
+ [[NSBundle mainBundle] loadNibNamed:NSStringFromClass(self.class) owner:self options:nil];
+ // resize cell to match .nib size. It is needed when resized the cell to
+ // correctly adapt its height too
+ UIView *sub = ((UIView *)[arrayOfViews objectAtIndex:arrayOfViews.count - 1]);
+ [self setFrame:frame];
+ [self addSubview:sub];
+ }
+ return self;
+}
+
+- (IBAction)onDeletePressed {
+ [_deleteDelegate deleteImageWithAssetId:_assetId];
+}
+
+/*
+#pragma mark - Navigation
+
+// In a storyboard-based application, you will often want to do a little preparation before navigation
+- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
+ // Get the new view controller using [segue destinationViewController].
+ // Pass the selected object to the new view controller.
+}
+*/
+
+@end
diff --git a/Classes/LinphoneUI/UIImageViewDeletable.xib b/Classes/LinphoneUI/UIImageViewDeletable.xib
new file mode 100644
index 000000000..2fa5d17e1
--- /dev/null
+++ b/Classes/LinphoneUI/UIImageViewDeletable.xib
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Classes/PhoneMainView.m b/Classes/PhoneMainView.m
index 860c0599a..1f35fae2a 100644
--- a/Classes/PhoneMainView.m
+++ b/Classes/PhoneMainView.m
@@ -934,6 +934,8 @@ static RootViewManager *rootViewManagerInstance = nil;
linphone_chat_room_remove_callbacks(view.chatRoom, view.chatRoomCbs);
view.chatRoomCbs = NULL;
+ if (view.chatRoom != cr)
+ [view clearMessageView];
view.chatRoom = cr;
self.currentRoom = view.chatRoom;
if (PhoneMainView.instance.currentView == view.compositeViewDescription)
diff --git a/Classes/Utils/FileTransferDelegate.h b/Classes/Utils/FileTransferDelegate.h
index 34a63df2a..17a4bcc5a 100644
--- a/Classes/Utils/FileTransferDelegate.h
+++ b/Classes/Utils/FileTransferDelegate.h
@@ -19,4 +19,5 @@
- (void)stopAndDestroy;
@property() LinphoneChatMessage *message;
+@property() NSString *text;
@end
diff --git a/Classes/Utils/FileTransferDelegate.m b/Classes/Utils/FileTransferDelegate.m
index 7b620e216..9268ff0d6 100644
--- a/Classes/Utils/FileTransferDelegate.m
+++ b/Classes/Utils/FileTransferDelegate.m
@@ -208,8 +208,8 @@ static LinphoneBuffer *linphone_iphone_file_transfer_send(LinphoneChatMessage *m
linphone_content_set_subtype(content, [subtype UTF8String]);
linphone_content_set_name(content, [name UTF8String]);
linphone_content_set_size(content, _data.length);
-
_message = linphone_chat_room_create_file_transfer_message(chatRoom, content);
+ linphone_chat_message_add_text_content(_message, [_text UTF8String]);
linphone_content_unref(content);
linphone_chat_message_cbs_set_file_transfer_send(linphone_chat_message_get_callbacks(_message),
diff --git a/Resources/images/delete_img.png b/Resources/images/delete_img.png
new file mode 100644
index 000000000..b9aaa86c9
Binary files /dev/null and b/Resources/images/delete_img.png differ