enable multipart send and recv

This commit is contained in:
Danmei Chen 2021-05-03 08:44:34 +02:00
parent c9e189e0ae
commit 6ef77ebdaa
15 changed files with 614 additions and 125 deletions

View file

@ -25,10 +25,22 @@
#import "UICheckBoxTableView.h"
@interface FileContext : NSObject
@property NSMutableArray <NSString *> *typesArray;
@property NSMutableArray <NSData *> *datasArray;
@property NSMutableArray <UIImage *> *previewsArray;
@property NSMutableArray <NSString *> *namesArray;
@property NSMutableArray <NSUUID *> *uuidsArray;
- (void)clear;
- (NSUInteger)count;
- (void)addObject:(NSData *)data name:(NSString *)name type:(NSString *)type;
@end
@protocol ChatConversationDelegate <NSObject>
- (BOOL)resendMultiFiles:(FileContext *)newFileContext message:(NSString *)message;
- (BOOL)resendFile:(NSData *)data withName:(NSString *)name type:(NSString *)type key:(NSString *)key message:(NSString *)message;
- (BOOL)startImageUpload:(UIImage *)image withQuality:(float)quality andMessage:(NSString *)message;
- (BOOL)startFileUpload:(NSData *)data withName:(NSString *)name;
- (void)resendChat:(NSString *)message withExternalUrl:(NSString *)url;
- (void)tableViewIsScrolling;
@ -45,6 +57,7 @@
@property(nonatomic) NSInteger currentIndex;
@property(nonatomic, strong) id<ChatConversationDelegate> chatRoomDelegate;
@property NSMutableDictionary<NSString *, UIImage *> *imagesInChatroom;
@property(nonatomic) BOOL vfsEnabled;
- (void)addEventEntry:(LinphoneEventLog *)event;
- (void)scrollToBottom:(BOOL)animated;

View file

@ -183,6 +183,10 @@
#pragma mark - Property Functions
- (void)setChatRoom:(LinphoneChatRoom *)room {
if (room) {
_vfsEnabled = [[LinphoneManager instance] lpConfigBoolForKey:@"vfs_enabled_preference"] && (linphone_chat_room_get_capabilities(room) & LinphoneChatRoomCapabilitiesEncrypted);
}
_chatRoom = room;
[self reloadData];
}
@ -246,6 +250,12 @@ static const int BASIC_EVENT_LIST=15;
return eventList.count;
}
- (void)tableView:(UITableView *)tableView didEndDisplayingCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath*)indexPath {
if ([[cell reuseIdentifier] isEqualToString:@"UIChatBubblePhotoCell"]) {
[(UIChatBubbleTextCell *)cell clearEncryptedFiles];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *kCellId = nil;
LinphoneEventLog *event = [[eventList objectAtIndex:indexPath.row] pointerValue];
@ -260,7 +270,7 @@ static const int BASIC_EVENT_LIST=15;
UIChatBubbleTextCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellId];
cell = [[NSClassFromString(kCellId) alloc] initWithIdentifier:kCellId];
[cell setEvent:event];
[cell setEvent:event vfsEnabled:_vfsEnabled];
if (chat) {
cell.isFirst = [self isFirstIndexInTableView:indexPath chat:chat];
cell.isLast = [self isLastIndexInTableView:indexPath chat:chat];

View file

@ -35,6 +35,7 @@
#include "linphone/linphonecore.h"
//Quicklook Preview Item
@interface PreviewItem : NSObject <QLPreviewItem>
@property(readonly, nonatomic) NSURL *previewItemURL;
@ -43,7 +44,7 @@
//QuickLook Datasource for rending PDF docs
@interface FileDataSource : NSObject <QLPreviewControllerDataSource>
@property (strong, nonatomic) PreviewItem *item;
@property NSMutableArray<NSURL*> *files;
@end
@interface ChatConversationView
@ -81,14 +82,12 @@
@property(weak, nonatomic) IBOutlet UIBackToCallButton *backToCallButton;
@property (weak, nonatomic) IBOutlet UIButton *infoButton;
@property (weak, nonatomic) IBOutlet UILabel *particpantsLabel;
//@property (nonatomic, strong) UIDocumentInteractionController *documentInteractionController;
@property NSMutableArray <UIImage *> *imagesArray;
@property NSMutableArray <NSString *> *assetIdsArray;
@property NSMutableArray <NSNumber *> *qualitySettingsArray;
@property (weak, nonatomic) IBOutlet UICollectionView *imagesCollectionView;
@property (weak, nonatomic) IBOutlet UIView *imagesView;
@property (weak, nonatomic) IBOutlet UIButton *encryptedButton;
@property (weak, nonatomic) IBOutlet UIInterfaceStyleButton *toggleSelectionButton;
@property FileContext *fileContext;
+ (void)markAsRead:(LinphoneChatRoom *)chatRoom;
+ (void)autoDownload:(LinphoneChatMessage *)message;
@ -97,6 +96,8 @@
+ (void)writeFileInCache:(NSData *)data name:(NSString *)name;
+ (NSData *)getCacheFileData:(NSString *)name;
+ (void)writeMediaToGallery:(NSString *)name fileType:(NSString *)fileType;
+(UIImage *)getBasicImage;
+(UIImage*)drawText:(NSString*)text image:(UIImage *)image textSize:(CGFloat)textSize;
- (void)configureForRoom:(BOOL)editing;
- (IBAction)onBackClick:(id)event;
@ -111,6 +112,7 @@
- (IBAction)onEncryptedDevicesClick:(id)sender;
- (void)update;
- (void)openFileWithURL:(NSURL *)url;
- (void)openFileWithURLs:(NSMutableArray<NSURL *>*)urls index:(NSInteger)currentIndex;
- (void)clearMessageView;
- (void)configureMessageField;

View file

@ -27,6 +27,50 @@
#import "DevicesListView.h"
#import "SVProgressHUD.h"
@implementation FileContext
- (void)addObject:(UIImage *)image withQuality:(float)quality {
NSString *name = [NSString stringWithFormat:@"%li-%f.jpg", (long)image.hash, [NSDate timeIntervalSinceReferenceDate]];
NSData *data = UIImageJPEGRepresentation(image, quality);
[self addObject:data name:name type:@"image" image:image];
}
- (void)addObject:(NSData *)data name:(NSString *)name type:(NSString *)type image:(UIImage *)image {
[_previewsArray addObject:image];
[_uuidsArray addObject:[NSUUID UUID]];
[self addObject:data name:name type:type];
}
- (void)addObject:(NSData *)data name:(NSString *)name type:(NSString *)type {
[_namesArray addObject:name];
[_typesArray addObject:type];
[_datasArray addObject:data];
}
- (void)deleteContentWithUuid:(NSUUID *)uuid {
NSUInteger key = [_uuidsArray indexOfObject:uuid];
[_previewsArray removeObjectAtIndex:key];
[_uuidsArray removeObjectAtIndex:key];
[_namesArray removeObjectAtIndex:key];
[_typesArray removeObjectAtIndex:key];
[_datasArray removeObjectAtIndex:key];
}
- (void)clear {
_previewsArray = [NSMutableArray array];
_uuidsArray = [NSMutableArray array];
_namesArray = [NSMutableArray array];
_typesArray = [NSMutableArray array];
_datasArray = [NSMutableArray array];
}
- (NSUInteger)count {
return [_datasArray count];
}
@end
@implementation PreviewItem
- (instancetype)initPreviewURL:(NSURL *)docURL
@ -41,18 +85,19 @@
@end
@implementation FileDataSource
- (instancetype)initWithPreviewItem:(PreviewItem *)item {
- (instancetype)initWithFiles:(NSMutableArray<NSURL*>*)files {
self = [super init];
if (self) {
_item = item;
_files = files;
}
return self;
}
- (NSInteger)numberOfPreviewItemsInPreviewController:(QLPreviewController *)controller {
return 1;
return _files.count;
}
- (id<QLPreviewItem>)previewController:(QLPreviewController *)controller previewItemAtIndex:(NSInteger)index {
return self.item;
NSURL *url = [_files objectAtIndex:index];
return [[PreviewItem alloc] initPreviewURL:url WithTitle:[url lastPathComponent]];
}
@end
@ -175,7 +220,7 @@ static UICompositeViewDescription *compositeDescription = nil;
selector:@selector(onLinphoneCoreReady:)
name:kLinphoneGlobalStateUpdate
object:nil];
if ([_imagesArray count] > 0) {
if ([_fileContext count] > 0) {
[UIView animateWithDuration:0
delay:0
options:UIViewAnimationOptionBeginFromCurrentState
@ -419,11 +464,9 @@ static UICompositeViewDescription *compositeDescription = nil;
}
- (void)saveAndSend:(UIImage *)image assetId:(NSString *)phAssetId withQuality:(float)quality{
[_imagesArray addObject:image];
[_assetIdsArray addObject:phAssetId];
[_qualitySettingsArray addObject:@(quality)];
[self refreshImageDrawer];
[_fileContext addObject:image withQuality:quality];
[_qualitySettingsArray addObject:@(quality)];
[self refreshImageDrawer];
}
- (void)chooseImageQuality:(UIImage *)image assetId:(NSString *)phAssetId {
@ -583,7 +626,7 @@ static UICompositeViewDescription *compositeDescription = nil;
messageRect.size.height += diff;
[_messageView setFrame:messageRect];
if ([_imagesArray count] > 0) {
if ([_fileContext count] > 0) {
CGRect _imagesRect = [_imagesView frame];
_imagesRect.origin.y -= diff;
[_imagesView setFrame:_imagesRect];
@ -626,24 +669,28 @@ 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] withQuality:[_qualitySettingsArray objectAtIndex:i].floatValue andMessage:NULL];
}
if (isOneToOne) {
[self startImageUpload:[_imagesArray objectAtIndex:i] withQuality:[_qualitySettingsArray objectAtIndex:i].floatValue andMessage:NULL];
if (![[self.messageField text] isEqualToString:@""]) {
[self sendMessage:[_messageField text] withExterlBodyUrl:nil];
}
} else {
[self startImageUpload:[_imagesArray objectAtIndex:i] withQuality:[_qualitySettingsArray objectAtIndex:i].floatValue andMessage:[self.messageField text]];
}
[self clearMessageView];
return;
}
[self sendMessageInMessageField];
if ([_fileContext count] > 0) {
if (linphone_chat_room_get_capabilities(_chatRoom) & LinphoneChatRoomCapabilitiesConference) {
[self startMultiFilesUpload];
} else {
int i = 0;
for (i = 0; i < [_fileContext count]-1; ++i) {
[self startUploadData:[_fileContext.datasArray objectAtIndex:i] withType:[_fileContext.typesArray objectAtIndex:i] withName:[_fileContext.namesArray objectAtIndex:i] andMessage:NULL];
}
if (isOneToOne) {
[self startUploadData:[_fileContext.datasArray objectAtIndex:i] withType:[_fileContext.typesArray objectAtIndex:i] withName:[_fileContext.namesArray objectAtIndex:i] andMessage:NULL];
if (![[self.messageField text] isEqualToString:@""]) {
[self sendMessage:[_messageField text] withExterlBodyUrl:nil];
}
} else {
[self startUploadData:[_fileContext.datasArray objectAtIndex:i] withType:[_fileContext.typesArray objectAtIndex:i] withName:[_fileContext.namesArray objectAtIndex:i] andMessage:[self.messageField text]];
}
}
[self clearMessageView];
return;
}
[self sendMessageInMessageField];
}
- (IBAction)onListTap:(id)sender {
@ -739,11 +786,25 @@ static UICompositeViewDescription *compositeDescription = nil;
#pragma mark ChatRoomDelegate
- (BOOL)startImageUpload:(UIImage *)image withQuality:(float)quality andMessage:(NSString *)message {
- (BOOL)startMultiFilesUpload {
FileTransferDelegate *fileTransfer = [[FileTransferDelegate alloc] init];
[fileTransfer setText:[self.messageField text]];
[fileTransfer uploadFileContent:_fileContext forChatRoom:_chatRoom];
[_tableController scrollToBottom:true];
return TRUE;
}
- (BOOL)startUploadData:(NSData *)data withType:(NSString*)type withName:(NSString *)name andMessage:(NSString *)message {
FileTransferDelegate *fileTransfer = [[FileTransferDelegate alloc] init];
if (message)
[fileTransfer setText:message];
[fileTransfer uploadImage:image forChatRoom:_chatRoom withQuality:quality];
NSString *key = @"localfile";
if ([type isEqualToString:@"video"]) {
key = @"localvideo";
} else if ([type isEqualToString:@"image"]) {
key = @"localimage";
}
[fileTransfer uploadData:data forChatRoom:_chatRoom type:type subtype:type name:name key:key];
[_tableController scrollToBottom:true];
return TRUE;
}
@ -755,6 +816,15 @@ static UICompositeViewDescription *compositeDescription = nil;
return TRUE;
}
- (BOOL)resendMultiFiles:(FileContext *)newFileContext message:(NSString *)message {
FileTransferDelegate *fileTransfer = [[FileTransferDelegate alloc] init];
if (message)
[fileTransfer setText:message];
[fileTransfer uploadFileContent:newFileContext forChatRoom:_chatRoom];
[_tableController scrollToBottom:true];
return TRUE;
}
- (BOOL)resendFile: (NSData *)data withName:(NSString *)name type:(NSString *)type key:(NSString *)key message:(NSString *)message {
FileTransferDelegate *fileTransfer = [[FileTransferDelegate alloc] init];
if (message)
@ -805,7 +875,9 @@ static UICompositeViewDescription *compositeDescription = nil;
[exportSession exportAsynchronouslyWithCompletionHandler:^{
dispatch_async(dispatch_get_main_queue(), ^{
[SVProgressHUD dismiss];
[self startFileUpload:[NSData dataWithContentsOfURL:compressedVideoUrl] withName:localname];
UIImage* image = [UIChatBubbleTextCell getImageFromVideoUrl:compressedVideoUrl];
[_fileContext addObject:[NSData dataWithContentsOfURL:compressedVideoUrl] name:localname type:@"video" image:image];
[self refreshImageDrawer];
});
}];
@ -1005,7 +1077,7 @@ static UICompositeViewDescription *compositeDescription = nil;
}
if ([_imagesArray count] > 0){
if ([_fileContext count] > 0){
// resizing imagesView
CGRect imagesFrame = [_imagesView frame];
imagesFrame.origin.y = [_messageView frame].origin.y - heightDiff;
@ -1074,7 +1146,7 @@ static UICompositeViewDescription *compositeDescription = nil;
[_tableController.view setFrame:tableFrame];
}
if ([_imagesArray count] > 0){
if ([_fileContext count] > 0){
// resizing imagesView
CGRect imagesFrame = [_imagesView frame];
imagesFrame.origin.y = [_messageView frame].origin.y - heightDiff;
@ -1213,21 +1285,24 @@ void on_chat_room_conference_alert(LinphoneChatRoom *cr, const LinphoneEventLog
[view.encryptedButton setImage:image forState:UIControlStateNormal];
}
- (void)openFileWithURL:(NSURL *)url
- (void)openFileWithURLs:(NSMutableArray<NSURL *>*)urls index:(NSInteger)currentIndex
{
//create the Quicklook controller.
QLPreviewController *qlController = [[QLPreviewController alloc] init];
PreviewItem *item = [[PreviewItem alloc] initPreviewURL:url WithTitle:[url lastPathComponent]];
self.FileDataSource = [[FileDataSource alloc] initWithPreviewItem:item];
self.FileDataSource = [[FileDataSource alloc] initWithFiles:urls];
qlController.dataSource = self.FileDataSource;
qlController.currentPreviewItemIndex = currentIndex;
qlController.delegate = self;
//present the document.
[self presentViewController:qlController animated:YES completion:nil];
}
- (void)openFileWithURL:(NSURL *)url
{
[self openFileWithURLs:[NSMutableArray arrayWithObject:url] index:0];
}
- (void)previewControllerDidDismiss:(QLPreviewController *)controller
{
@ -1307,23 +1382,21 @@ void on_chat_room_conference_alert(LinphoneChatRoom *cr, const LinphoneEventLog
}
}
- (void)deleteImageWithAssetId:(NSString *)assetId {
NSUInteger key = [_assetIdsArray indexOfObject:assetId];
[_imagesArray removeObjectAtIndex:key];
[_assetIdsArray removeObjectAtIndex:key];
[self refreshImageDrawer];
- (void)deleteFileWithUuid:(NSUUID *)uuid {
[_fileContext deleteContentWithUuid:uuid];
[self refreshImageDrawer];
}
- (void)clearMessageView {
[_messageField setText:@""];
_imagesArray = [NSMutableArray array];
_assetIdsArray = [NSMutableArray array];
if (!_fileContext) _fileContext = [[FileContext alloc] init];
[_fileContext clear];
[self refreshImageDrawer];
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return [_imagesArray count];
return [_fileContext count];
}
- (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
@ -1336,8 +1409,8 @@ void on_chat_room_conference_alert(LinphoneChatRoom *cr, const LinphoneEventLog
imgFrame.size.height = 100;
}
[imgView.image setImage:[UIImage resizeImage:[_imagesArray objectAtIndex:[indexPath item]] withMaxWidth:imgFrame.size.width andMaxHeight:imgFrame.size.height]];
[imgView setAssetId:[_assetIdsArray objectAtIndex:[indexPath item]]];
[imgView.image setImage:[UIImage resizeImage:[_fileContext.previewsArray objectAtIndex:[indexPath item]] withMaxWidth:imgFrame.size.width andMaxHeight:imgFrame.size.height]];
[imgView setUuid:[_fileContext.uuidsArray objectAtIndex:[indexPath item]]];
[imgView setDeleteDelegate:self];
[imgView setFrame:imgFrame];
[_sendButton setEnabled:TRUE];
@ -1347,7 +1420,7 @@ void on_chat_room_conference_alert(LinphoneChatRoom *cr, const LinphoneEventLog
- (void)refreshImageDrawer {
int heightDiff = UIInterfaceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation]) ? 55 : 105;
if ([_imagesArray count] == 0) {
if ([_fileContext count] == 0) {
[UIView animateWithDuration:0
delay:0
options:UIViewAnimationOptionBeginFromCurrentState
@ -1433,10 +1506,38 @@ void on_chat_room_conference_alert(LinphoneChatRoom *cr, const LinphoneEventLog
NSFileCoordinator *co =[[NSFileCoordinator alloc] init];
NSError *error = nil;
[co coordinateReadingItemAtURL:url options:0 error:&error byAccessor:^(NSURL * _Nonnull newURL) {
[self startFileUpload:[NSData dataWithContentsOfURL:newURL] withName:[newURL lastPathComponent]];
UIImage *image = [ChatConversationView drawText:[newURL lastPathComponent] image:[ChatConversationView getBasicImage] textSize:10];
[_fileContext addObject:[NSData dataWithContentsOfURL:newURL] name:[newURL lastPathComponent] type:@"file" image:image];
[self refreshImageDrawer];
}];
[url stopAccessingSecurityScopedResource];
}
+(UIImage *)getBasicImage {
UIColor *color=[UIColor grayColor];
CGRect frame = CGRectMake(0, 0, 200, 200);
UIGraphicsBeginImageContext(frame.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, [color CGColor]);
CGContextFillRect(context, frame);
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
+(UIImage*)drawText:(NSString*)text image:(UIImage *)image textSize:(CGFloat)textSize
{
UIFont *font = [UIFont boldSystemFontOfSize:textSize];
UIGraphicsBeginImageContext(image.size);
[image drawInRect:CGRectMake(0,0,image.size.width,image.size.height)];
CGRect rect = CGRectMake(0, 30, image.size.width, image.size.height);
[[UIColor whiteColor] set];
[text drawInRect:CGRectIntegral(rect) withFont:font];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
@end

View file

@ -24,6 +24,7 @@
#import "FileTransferDelegate.h"
#import "ChatConversationTableView.h"
#import "UIChatBubbleTextCell.h"
#import "UIChatContentView.h"
@interface UIChatBubblePhotoCell : UIChatBubbleTextCell
@ -41,8 +42,10 @@
@property (weak, nonatomic) IBOutlet UIButton *fileButton;
@property (weak, nonatomic) IBOutlet UIView *fileView;
@property (strong, nonatomic) IBOutlet UILongPressGestureRecognizer *plusLongGestureRecognizer;
@property(strong, nonatomic) NSMutableArray<UIChatContentView *> *contentViews;
- (void)setEvent:(LinphoneEventLog *)event;
- (void)setEvent:(LinphoneEventLog *)event vfsEnabled:(BOOL)enabled;
- (void)setChatMessage:(LinphoneChatMessage *)message;
- (void)connectToFileDelegate:(FileTransferDelegate *)ftd;
- (IBAction)onDownloadClick:(id)event;

View file

@ -53,29 +53,21 @@
videoDefaultSize = CGSizeMake(320, 240);
assetIsLoaded = FALSE;
self.contentView.userInteractionEnabled = NO;
_contentViews = [[NSMutableArray alloc] init];
}
return self;
}
- (void)dealloc {
NSString *filePath = [LinphoneManager getMessageAppDataForKey:@"encryptedfile" inMessage:self.message];
if (filePath) {
[[NSFileManager defaultManager] removeItemAtPath:filePath error:NULL];
[LinphoneManager setValueInMessageAppData:NULL forKey:@"encryptedfile" inMessage:self.message];
}
}
- (void)onDelete {
[super onDelete];
}
#pragma mark -
- (void)setEvent:(LinphoneEventLog *)event {
- (void)setEvent:(LinphoneEventLog *)event vfsEnabled:(BOOL)enabled {
if (!event || !(linphone_event_log_get_type(event) == LinphoneEventLogTypeConferenceChatMessage))
return;
super.event = event;
[super setEvent:event vfsEnabled:enabled];
[self setChatMessage:linphone_event_log_get_chat_message(event)];
}
@ -101,7 +93,6 @@
}
[super setChatMessageForCbs:amessage];
[LinphoneManager setValueInMessageAppData:NULL forKey:@"encryptedfile" inMessage:self.message];
}
- (void) loadImageAsset:(PHAsset*) asset image:(UIImage *)image {
@ -117,8 +108,6 @@
});
}
static const CGFloat CELL_IMAGE_X_MARGIN = 100;
- (void) loadAsset:(PHAsset *) asset {
PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init];
options.synchronous = TRUE;
@ -165,6 +154,59 @@ static const CGFloat CELL_IMAGE_X_MARGIN = 100;
return;
}
[super update];
const bctbx_list_t *contents = linphone_chat_message_get_contents(self.message);
BOOL multiParts = ((linphone_chat_message_get_text_content(self.message) != NULL) ? bctbx_list_size(contents) > 2 : bctbx_list_size(contents) > 1);
if (multiParts) {
if (!assetIsLoaded) {
NSMutableDictionary<NSString *, NSString *> *encrptedFilePaths = NULL;
if (self.vfsEnabled) {
encrptedFilePaths = [LinphoneManager getMessageAppDataForKey:@"encryptedfiles" inMessage:self.message];
if (!encrptedFilePaths) {
encrptedFilePaths = [NSMutableDictionary dictionary];
}
}
_imageGestureRecognizer.enabled = NO;
_cancelButton.hidden = _fileTransferProgress.hidden = _downloadButton.hidden = _playButton.hidden = _fileName.hidden = _fileView.hidden = _fileButton.hidden = YES;
const bctbx_list_t *it = contents;
int i;
for (it = contents, i=0; it != NULL; it=bctbx_list_next(it)){
LinphoneContent *content = (LinphoneContent *)it->data;
if (linphone_content_is_file_transfer(content) || linphone_content_is_file(content)){
UIChatContentView *contentView = [[UIChatContentView alloc] initWithFrame: CGRectMake(0,0,0,0)];
if(self.vfsEnabled && (linphone_chat_message_is_outgoing(self.message) || linphone_content_is_file(content))) {
// downloaded or ougoing message
NSString *name = [NSString stringWithUTF8String:linphone_content_get_name(content)];
NSString *filePath = [encrptedFilePaths valueForKey:name];
if (filePath == NULL) {
char *cPath = linphone_content_get_plain_file_path(content);
if (cPath) {
NSString *filePath = [NSString stringWithUTF8String:cPath];
ms_free(cPath);
[encrptedFilePaths setValue:filePath forKey:name];
}
}
contentView.filePath = filePath;
}
[contentView setContent:content message:self.message];
contentView.position = i;
[_contentViews addObject:contentView];
i++;
}
}
if (self.vfsEnabled) {
[LinphoneManager setValueInMessageAppData:encrptedFilePaths forKey:@"encryptedfiles" inMessage:self.message];
}
assetIsLoaded = TRUE;
[self layoutSubviews];
}
return;
}
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,11 +245,13 @@ static const CGFloat CELL_IMAGE_X_MARGIN = 100;
NSString *fileName = [NSString stringWithUTF8String:linphone_content_get_name(fileContent)];
if (!filePath) {
char *cPath = [[LinphoneManager instance] lpConfigBoolForKey:@"vfs_enabled_preference"] ? linphone_content_get_plain_file_path(fileContent) : NULL;
if (cPath) {
filePath = [NSString stringWithUTF8String:cPath];
ms_free(cPath);
[LinphoneManager setValueInMessageAppData:filePath forKey:@"encryptedfile" inMessage:self.message];
if (self.vfsEnabled) {
char *cPath = self.vfsEnabled ? linphone_content_get_plain_file_path(fileContent) : NULL;
if (cPath) {
filePath = [NSString stringWithUTF8String:cPath];
ms_free(cPath);
[LinphoneManager setValueInMessageAppData:filePath forKey:@"encryptedfile" inMessage:self.message];
}
} else {
filePath = [[LinphoneManager cacheDirectory] stringByAppendingPathComponent:fileName];
}
@ -638,20 +682,60 @@ static const CGFloat CELL_IMAGE_X_MARGIN = 100;
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 - CELL_IMAGE_X_MARGIN];
imgFrame.origin.x = (self.innerView.frame.size.width - imgFrame.size.width-17)/2;
self.finalAssetView.frame = imgFrame;
}
if (_contentViews.count > 0) {
// Positioning contentViews
CGFloat imagesw=0;
CGFloat max_imagesh=0;
CGFloat max_imagesw=0;
CGFloat originy=0;
CGFloat originx=0;
CGFloat availableWidth = chatTableView.tableView.frame.size.width-CELL_IMAGE_X_MARGIN;
NSMutableArray<NSURL *> *fileUrls = [[NSMutableArray alloc] init];
for (UIChatContentView *contentView in _contentViews) {
if (contentView.filePath) {
[fileUrls addObject:[NSURL fileURLWithPath:contentView.filePath]];
}
}
for (UIChatContentView *contentView in _contentViews) {
UIImage *image = contentView.image;
CGSize sSize = [UIChatBubbleTextCell getMediaMessageSizefromOriginalSize:image.size withWidth:IMAGE_DEFAULT_WIDTH];
imagesw += sSize.width;
if (imagesw > availableWidth) {
imagesw = sSize.width;
max_imagesw = MAX(max_imagesw, imagesw);
originy = max_imagesh+IMAGE_DEFAULT_MARGIN;
max_imagesh = sSize.height;
originx = sSize.width;
} else {
max_imagesw = MAX(max_imagesw, imagesw);
max_imagesh = MAX(max_imagesh, sSize.height);
originx += (sSize.width+IMAGE_DEFAULT_MARGIN);
}
[contentView setFrame:CGRectMake(originx-sSize.width, originy, sSize.width, sSize.height)];
contentView.fileUrls = fileUrls;
[_finalAssetView addSubview:contentView];
}
_finalImage.hidden = YES;
} else {
// Resizing Image view
if (_finalImage.image) {
CGRect imgFrame = self.finalAssetView.frame;
imgFrame.size = [UIChatBubbleTextCell getMediaMessageSizefromOriginalSize:[_finalImage.image size] withWidth:chatTableView.tableView.frame.size.width - CELL_IMAGE_X_MARGIN];
imgFrame.origin.x = (self.innerView.frame.size.width - imgFrame.size.width-17)/2;
self.finalAssetView.frame = imgFrame;
}
}
// Positioning text message
const char *utf8Text = linphone_chat_message_get_text_content(self.message);
CGRect textFrame = self.messageText.frame;
if (_finalImage.image)
if (_contentViews.count > 0)
textFrame.origin = CGPointMake(textFrame.origin.x, self.finalAssetView.frame.origin.y + self.finalAssetView.frame.size.height-10);
else if (_finalImage.image)
textFrame.origin = CGPointMake(textFrame.origin.x, self.finalAssetView.frame.origin.y + self.finalAssetView.frame.size.height);
else
// When image hasn't be download

View file

@ -23,6 +23,10 @@
#import "ChatConversationTableView.h"
#import "UIRoundedImageView.h"
#define CELL_IMAGE_X_MARGIN 100
#define IMAGE_DEFAULT_WIDTH 120
#define IMAGE_DEFAULT_MARGIN 5
@interface UIChatBubbleTextCell : UITableViewCell <UIDocumentPickerDelegate>
@property(readonly, nonatomic) LinphoneEventLog *event;
@ -42,17 +46,20 @@
@property (nonatomic, strong) UIDocumentPickerViewController *documentPicker;
@property (weak, nonatomic) IBOutlet UIView *innerView;
@property(nonatomic) Boolean isFirst;
@property(nonatomic) Boolean isLast;
@property(nonatomic) Boolean notDelivered;
@property(nonatomic) BOOL isFirst;
@property(nonatomic) BOOL isLast;
@property(nonatomic) BOOL notDelivered;
@property(nonatomic) BOOL vfsEnabled;
+ (CGSize)ViewSizeForMessage:(LinphoneChatMessage *)chat withWidth:(int)width;
+ (CGSize)ViewHeightForMessageText:(LinphoneChatMessage *)chat withWidth:(int)width textForImdn:(NSString *)imdnText;
+ (CGSize)getMediaMessageSizefromOriginalSize:(CGSize)originalSize withWidth:(int)width;
+ (UIImage *)getImageFromVideoUrl:(NSURL *)url;
+ (UIImage *)getImageFromContent:(LinphoneContent *)content filePath:(NSString *)filePath;
- (void)setEvent:(LinphoneEventLog *)event;
- (void)setEvent:(LinphoneEventLog *)event vfsEnabled:(BOOL)enabled;
- (void)setChatMessageForCbs:(LinphoneChatMessage *)message;
- (void)clearEncryptedFiles;
- (void)onDelete;
- (void)onResend;

View file

@ -62,17 +62,38 @@
}
- (void)dealloc {
[self setEvent:NULL];
[self setEvent:NULL vfsEnabled:_vfsEnabled];
[self setChatMessageForCbs:NULL];
}
#pragma mark -
- (void)setEvent:(LinphoneEventLog *)event {
- (void)clearEncryptedFiles {
if (_vfsEnabled) {
NSMutableDictionary<NSString *, NSString *> *encrptedFilePaths = [LinphoneManager getMessageAppDataForKey:@"encryptedfiles" inMessage:_message];
if ([encrptedFilePaths count] > 0) {
for(NSString *path in [encrptedFilePaths allValues]) {
[[NSFileManager defaultManager] removeItemAtPath:path error:NULL];
}
[LinphoneManager setValueInMessageAppData:NULL forKey:@"encryptedfiles" inMessage:_message];
return;
}
NSString *filePath = [LinphoneManager getMessageAppDataForKey:@"encryptedfile" inMessage:_message];
if (filePath) {
if (![filePath isEqualToString:@""])
[[NSFileManager defaultManager] removeItemAtPath:filePath error:NULL];
[LinphoneManager setValueInMessageAppData:NULL forKey:@"encryptedfile" inMessage:_message];
}
}
}
- (void)setEvent:(LinphoneEventLog *)event vfsEnabled:(BOOL)enabled {
if(!event)
return;
_event = event;
_vfsEnabled = enabled;
if (!(linphone_event_log_get_type(event) == LinphoneEventLogTypeConferenceChatMessage)) {
LOGE(@"Impossible to create a ChatBubbleText whit a non message event");
return;
@ -274,33 +295,52 @@
if (state != LinphoneChatMessageStateNotDelivered && state != LinphoneChatMessageStateFileTransferError)
return;
const bctbx_list_t *contents = linphone_chat_message_get_contents(_message);
BOOL multiParts = ((linphone_chat_message_get_text_content(self.message) != NULL) ? bctbx_list_size(contents) > 2 : bctbx_list_size(contents) > 1);
if (multiParts) {
FileContext *newfileContext = [[FileContext alloc] init];
[newfileContext clear];
NSMutableDictionary<NSString *, NSString *> *encrptedFilePaths = encrptedFilePaths = [LinphoneManager getMessageAppDataForKey:@"encryptedfiles" inMessage:_message];
int i;
const bctbx_list_t *it;
for (it = contents, i=0; it != NULL; it=bctbx_list_next(it)){
LinphoneContent *content = (LinphoneContent *)it->data;
if (linphone_content_is_file_transfer(content) || linphone_content_is_file(content)){
NSString *name = [NSString stringWithUTF8String:linphone_content_get_name(content)];
NSString *filePath = [encrptedFilePaths valueForKey:name];
if (filePath == NULL) {
filePath = [[LinphoneManager cacheDirectory] stringByAppendingPathComponent:name];
}
[newfileContext addObject:[NSData dataWithContentsOfFile:filePath] name:name type:[NSString stringWithUTF8String:linphone_content_get_type(content)]];
}
}
[self onDelete];
dispatch_async(dispatch_get_main_queue(), ^ {
const char *text = linphone_chat_message_get_text_content(_message);
[_chatRoomDelegate resendMultiFiles:newfileContext message: text? [NSString stringWithUTF8String:text]: NULL];
});
return;
}
if (linphone_chat_message_get_file_transfer_information(_message) != NULL) {
NSString *localImage = [LinphoneManager getMessageAppDataForKey:@"localimage" inMessage:_message];
NSString *localVideo = [LinphoneManager getMessageAppDataForKey:@"localvideo" inMessage:_message];
NSString *localFile = [LinphoneManager getMessageAppDataForKey:@"localfile" inMessage:_message];
/*FileTransferDelegate *thiz = [FileTransferDelegate messageDelegate:_message];
if (thiz) {
[thiz stop]
}*/
NSString *filePath = [LinphoneManager getMessageAppDataForKey:@"encryptedfile" inMessage:self.message];
[self onDelete];
dispatch_async(dispatch_get_main_queue(), ^ {
LinphoneContent *fileContent = linphone_chat_message_get_file_transfer_information(_message);
NSData *data = NULL;
char *cPath = [[LinphoneManager instance] lpConfigBoolForKey:@"vfs_enabled_preference"] ? linphone_content_get_plain_file_path(fileContent) : NULL;
if (cPath) {
NSString *filePath = [NSString stringWithUTF8String:cPath];
if (filePath) {
data = [NSData dataWithContentsOfFile:filePath];
ms_free(cPath);
[[NSFileManager defaultManager] removeItemAtPath:filePath error:NULL];
}
const char *text = linphone_chat_message_get_text_content(_message);
NSString *str = text ? [NSString stringWithUTF8String:text] : NULL;
if (localImage) {
[_chatRoomDelegate resendFile: (data?:[ChatConversationView getCacheFileData:localImage]) withName:localImage type:@"image" key:@"localimage" message:self.textMessage];
[_chatRoomDelegate resendFile: (data?:[ChatConversationView getCacheFileData:localImage]) withName:localImage type:@"image" key:@"localimage" message:str];
} else if (localVideo) {
[_chatRoomDelegate resendFile:(data?:[ChatConversationView getCacheFileData:localVideo]) withName:localVideo type:@"video" key:@"localvideo" message:self.textMessage];
[_chatRoomDelegate resendFile:(data?:[ChatConversationView getCacheFileData:localVideo]) withName:localVideo type:@"video" key:@"localvideo" message:str];
} else {
[_chatRoomDelegate resendFile:(data?:[ChatConversationView getCacheFileData:localFile]) withName:localFile type:@"image" key:@"localfile" message:self.textMessage];
[_chatRoomDelegate resendFile:(data?:[ChatConversationView getCacheFileData:localFile]) withName:localFile type:@"image" key:@"localfile" message:str];
}
});
} else {
@ -364,7 +404,6 @@ static const CGFloat CELL_MIN_HEIGHT = 65.0f;
static const CGFloat CELL_MIN_WIDTH = 190.0f;
static const CGFloat CELL_MESSAGE_X_MARGIN = 68 + 10.0f;
static const CGFloat CELL_MESSAGE_Y_MARGIN = 44;
static const CGFloat CELL_IMAGE_X_MARGIN = 100;
+ (CGSize)ViewHeightForMessage:(LinphoneChatMessage *)chat withWidth:(int)width {
return [self ViewHeightForMessageText:chat withWidth:width textForImdn:nil];
@ -378,7 +417,28 @@ static const CGFloat CELL_IMAGE_X_MARGIN = 100;
return size;
}
+ (CGSize)ViewHeightForMessageText:(LinphoneChatMessage *)chat withWidth:(int)width textForImdn:(NSString *)imdnText{
+ (UIImage *)getImageFromContent:(LinphoneContent *)content filePath:(NSString *)filePath; {
NSString *type = [NSString stringWithUTF8String:linphone_content_get_type(content)];
NSString *name = [NSString stringWithUTF8String:linphone_content_get_name(content)];
if (!filePath) {
filePath = [[LinphoneManager cacheDirectory] stringByAppendingPathComponent:name];
}
UIImage *image = nil;
if ([type isEqualToString:@"video"]) {
image = [UIChatBubbleTextCell getImageFromVideoUrl:[NSURL fileURLWithPath:filePath]];
} else if ([type isEqualToString:@"image"]) {
NSData* data = [NSData dataWithContentsOfFile:filePath];
image = [[UIImage alloc] initWithData:data];
}
if (image) return image;
UIImage *basicImage = [ChatConversationView getBasicImage];
image = [ChatConversationView drawText:[NSString stringWithFormat:@"📎 %@",name] image:basicImage textSize:25];
return image;
}
+ (CGSize)ViewHeightForMessageText:(LinphoneChatMessage *)chat withWidth:(int)width textForImdn:(NSString *)imdnText {
NSString *messageText = [UIChatBubbleTextCell TextMessageForChat:chat];
static UIFont *messageFont = nil;
@ -399,7 +459,68 @@ static const CGFloat CELL_IMAGE_X_MARGIN = 100;
size.height = MAX(size.height + CELL_MESSAGE_Y_MARGIN + 50, CELL_MIN_HEIGHT);
return size;
}
CGFloat imagesw=0;
CGFloat imagesh=0;
CGFloat max_imagesw=0;
CGFloat max_imagesh=0;
const bctbx_list_t *contents = linphone_chat_message_get_contents(chat);
BOOL multiParts = ((linphone_chat_message_get_text_content(chat) != NULL) ? bctbx_list_size(contents) > 2 : bctbx_list_size(contents) > 1);
if (multiParts) {
const bctbx_list_t *it = contents;
NSMutableDictionary<NSString *, NSString *> *encrptedFilePaths = [LinphoneManager getMessageAppDataForKey:@"encryptedfiles" inMessage:chat];
for (it = contents; it != NULL; it=bctbx_list_next(it)){
LinphoneContent *content = (LinphoneContent *)it->data;
UIImage *image;
if(!linphone_chat_message_is_outgoing(chat) && linphone_content_is_file_transfer(content)) {
// not yet downloaded
UIImage *basicImage = [ChatConversationView getBasicImage];
NSString *name = [NSString stringWithUTF8String:linphone_content_get_name(content)] ;
image = [ChatConversationView drawText:name image:basicImage textSize:25];
} else if (linphone_content_is_file_transfer(content) || linphone_content_is_file(content)) {
NSString *name = [NSString stringWithUTF8String:linphone_content_get_name(content)];
NSString *filePath=[encrptedFilePaths valueForKey:name];
if (filePath == NULL) {
filePath = [[LinphoneManager cacheDirectory] stringByAppendingPathComponent:name];
}
image = [UIChatBubbleTextCell getImageFromContent:content filePath:filePath];
}
if (image) {
CGSize sSize = [self getMediaMessageSizefromOriginalSize:image.size withWidth:IMAGE_DEFAULT_WIDTH];
imagesw += sSize.width;
if (imagesw > width) {
imagesw = sSize.width;
max_imagesw = MAX(max_imagesw, imagesw);
max_imagesh = imagesh;
imagesh = sSize.height;
} else {
max_imagesw = MAX(max_imagesw, imagesw);
imagesh = MAX(imagesh, sSize.height);
}
}
}
max_imagesh += imagesh;
size = CGSizeMake(max_imagesw, max_imagesh);
CGSize textSize = CGSizeMake(0, 0);
if (![messageText isEqualToString:@"🗻"]) {
textSize = [self computeBoundingBox:messageText
size:CGSizeMake(width - CELL_MESSAGE_X_MARGIN - 4, CGFLOAT_MAX)
font:messageFont];
size.height += textSize.height;
}
// add size for message text
size.height += textSize.height;
size.width = MAX(textSize.width, size.width);
size.width = MAX(size.width + CELL_MESSAGE_X_MARGIN, CELL_MIN_WIDTH);
size.height = MAX(size.height + CELL_MESSAGE_Y_MARGIN, CELL_MIN_HEIGHT);
return size;
}
LinphoneContent *fileContent = linphone_chat_message_get_file_transfer_information(chat);
if (url == nil && fileContent == NULL) {
size = [self computeBoundingBox:messageText
@ -410,6 +531,7 @@ static const CGFloat CELL_IMAGE_X_MARGIN = 100;
NSString *localFile = [LinphoneManager getMessageAppDataForKey:@"localfile" inMessage:chat];
NSString *localVideo = [LinphoneManager getMessageAppDataForKey:@"localvideo" inMessage:chat];
NSString *filePath = [LinphoneManager getMessageAppDataForKey:@"encryptedfile" inMessage:chat];
NSString *fileName = [NSString stringWithUTF8String:linphone_content_get_name(fileContent)];
CGSize textSize = CGSizeMake(0, 0);
if (![messageText isEqualToString:@"🗻"]) {
@ -420,12 +542,13 @@ static const CGFloat CELL_IMAGE_X_MARGIN = 100;
}
CGSize originalImageSize = CGSizeMake(230, 50);
if (!filePath) {
filePath = [[LinphoneManager cacheDirectory] stringByAppendingPathComponent:fileName];
}
if (localFile) {
UIImage *image = nil;
NSString *type = [NSString stringWithUTF8String:linphone_content_get_type(fileContent)];
if (!filePath) {
filePath = [[LinphoneManager cacheDirectory] stringByAppendingPathComponent:localFile];
}
if ([type isEqualToString:@"video"]) {
if ([[NSFileManager defaultManager] fileExistsAtPath: filePath]) {
image = [self getImageFromVideoUrl:[NSURL fileURLWithPath:filePath]];
@ -451,13 +574,6 @@ static const CGFloat CELL_IMAGE_X_MARGIN = 100;
return CGSizeMake(CELL_MIN_WIDTH + CELL_MESSAGE_X_MARGIN, CELL_MIN_HEIGHT + CELL_MESSAGE_Y_MARGIN + textSize.height + 20);
}
if (!filePath) {
if (localImage) {
filePath = [[LinphoneManager cacheDirectory] stringByAppendingPathComponent:localImage];
} else {
filePath = [[LinphoneManager cacheDirectory] stringByAppendingPathComponent:localVideo];
}
}
if (localImage && [[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
NSData* data = [NSData dataWithContentsOfFile:filePath];
UIImage *image = [[UIImage alloc] initWithData:data];

View file

@ -0,0 +1,34 @@
/*
* Copyright (c) 2010-2020 Belledonne Communications SARL.
*
* This file is part of linphone-iphone
*
* 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 3 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, see <http://www.gnu.org/licenses/>.
*/
#import <UIKit/UIKit.h>
@interface UIChatContentView : UIImageView
@property(strong, nonatomic) NSMutableArray<NSURL*> *fileUrls;
@property(nonatomic) NSInteger position;
@property(readonly, nonatomic) LinphoneContent *content;
@property(readonly, nonatomic) LinphoneChatMessage *message;
@property(nonatomic) UIButton *downloadButton;
@property(nonatomic) NSString *filePath;
- (void)setContent:(LinphoneContent *)content message:(LinphoneChatMessage *)message;
@end

View file

@ -0,0 +1,75 @@
/*
* Copyright (c) 2010-2020 Belledonne Communications SARL.
*
* This file is part of linphone-iphone
*
* 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 3 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, see <http://www.gnu.org/licenses/>.
*/
#import <Foundation/Foundation.h>
#import "UIChatContentView.h"
#import "ChatConversationView.h"
#import "PhoneMainView.h"
@implementation UIChatContentView
- (void)setContent:(LinphoneContent *)content message:(LinphoneChatMessage *)message {
_content = content;
_message = message;
self.userInteractionEnabled = YES;
if(!linphone_chat_message_is_outgoing(_message) && linphone_content_is_file_transfer(_content)) {
// has not yet downloaded
UIImage *basicImage = [ChatConversationView getBasicImage];
NSString *name = [NSString stringWithUTF8String:linphone_content_get_name(content)] ;
UIImage *image = [ChatConversationView drawText:name image:basicImage textSize:25];
[self setImage:image];
_downloadButton = [UIButton buttonWithType:UIButtonTypeCustom];
[_downloadButton addTarget:self
action:@selector(onDownloadClick:)
forControlEvents:UIControlEventTouchUpInside];
_downloadButton.backgroundColor = [UIColor orangeColor];
UIFont *boldFont = [UIFont systemFontOfSize:10];
NSMutableAttributedString *boldText = [[NSMutableAttributedString alloc] initWithString:@"Download" attributes:@{ NSFontAttributeName : boldFont }];
[_downloadButton setAttributedTitle:boldText forState:UIControlStateNormal];
_downloadButton.frame = CGRectMake(3, 3, 60, 30);
[self addSubview:_downloadButton];
} else {
if (_filePath == NULL) {
NSString *name = [NSString stringWithUTF8String:linphone_content_get_name(content)];
_filePath = [[LinphoneManager cacheDirectory] stringByAppendingPathComponent:name];
}
UIImage *image = [UIChatBubbleTextCell getImageFromContent:content filePath:_filePath];
[self setImage:image];
UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onMultiPartClick:)];
tapGestureRecognizer.numberOfTapsRequired = 1;
tapGestureRecognizer.enabled = YES;
[self addGestureRecognizer:tapGestureRecognizer];
}
}
-(IBAction)onMultiPartClick:(id)sender {
ChatConversationView *view = VIEW(ChatConversationView);
[view openFileWithURLs:_fileUrls index:_position];
}
-(IBAction)onDownloadClick:(id)sender {
_downloadButton.enabled = NO;
linphone_content_set_file_path(_content, [[LinphoneManager cacheDirectory] stringByAppendingPathComponent:[NSString stringWithUTF8String:linphone_content_get_name(_content)]].UTF8String);
linphone_chat_message_download_content(_message, _content);
}
@end

View file

@ -23,13 +23,13 @@
@required
- (void)deleteImageWithAssetId:(NSString *)assetId;
- (void)deleteFileWithUuid:(NSUUID *)uuid;
@end
@interface UIImageViewDeletable : UICollectionViewCell
@property NSString *assetId;
@property NSUUID *uuid;
@property(nonatomic, strong) id<UIImageViewDeletableDelegate> deleteDelegate;
@property (weak, nonatomic) IBOutlet UIImageView *image;

View file

@ -55,7 +55,7 @@
}
- (IBAction)onDeletePressed {
[_deleteDelegate deleteImageWithAssetId:_assetId];
[_deleteDelegate deleteFileWithUuid:_uuid];
}
/*

View file

@ -20,9 +20,11 @@
#import <Foundation/Foundation.h>
#import "LinphoneManager.h"
#import "ChatConversationView.h"
@interface FileTransferDelegate : NSObject
- (void)uploadFileContent: (FileContext *)context forChatRoom:(LinphoneChatRoom *)chatRoom;
- (void)uploadData:(NSData *)data forChatRoom:(LinphoneChatRoom *)chatRoom type:(NSString *)type subtype:(NSString *)subtype name:(NSString *)name key:(NSString *)key;
- (void)uploadImage:(UIImage *)image forChatRoom:(LinphoneChatRoom *)chatRoom withQuality:(float)quality;
- (void)uploadFile:(NSData *)data forChatRoom:(LinphoneChatRoom *)chatRoom withName:(NSString *)name;

View file

@ -108,6 +108,7 @@ static void file_transfer_progress_indication_send(LinphoneChatMessage *message,
return;
}
[LinphoneManager.instance.fileTransferDelegates addObject:self];
[ChatConversationView writeFileInCache:data name:name];
LinphoneContent *content = linphone_core_create_content(linphone_chat_room_get_core(chatRoom));
linphone_content_set_type(content, [type UTF8String]);
@ -128,21 +129,56 @@ static void file_transfer_progress_indication_send(LinphoneChatMessage *message,
linphone_chat_message_send(_message);
}
- (void)uploadFileContent: (FileContext *)context forChatRoom:(LinphoneChatRoom *)chatRoom {
[LinphoneManager.instance.fileTransferDelegates addObject:self];
_message = linphone_chat_room_create_empty_message(chatRoom);
NSMutableArray<NSString *> *names = [[NSMutableArray alloc] init];
NSMutableArray<NSString *> *types = [[NSMutableArray alloc] init];
int i = 0;
for (i = 0; i < [context count]; ++i) {
LinphoneContent *content = linphone_core_create_content(linphone_chat_room_get_core(chatRoom));
NSString *type = [context.typesArray objectAtIndex:i];
NSString *name = [context.namesArray objectAtIndex:i];
NSData *data = [context.datasArray objectAtIndex:i];
[ChatConversationView writeFileInCache:data name:name];
linphone_content_set_type(content, [type UTF8String]);
linphone_content_set_subtype(content, [name.pathExtension UTF8String]);
linphone_content_set_name(content, [name UTF8String]);
linphone_content_set_file_path(content, [[LinphoneManager cacheDirectory] stringByAppendingPathComponent:name].UTF8String);
[names addObject:name];
[types addObject:type];
linphone_chat_message_add_file_content(_message, content);
linphone_content_unref(content);
}
if (_text!=nil && ![_text isEqualToString:@""])
linphone_chat_message_add_text_content(_message, [_text UTF8String]);
// todo indication progress
[LinphoneManager setValueInMessageAppData:names forKey:@"multiparts" inMessage:_message];
[LinphoneManager setValueInMessageAppData:types forKey:@"multipartstypes" inMessage:_message];
LOGI(@"%p Uploading content from message %p", self, _message);
linphone_chat_message_send(_message);
}
- (void)uploadImage:(UIImage *)image forChatRoom:(LinphoneChatRoom *)chatRoom withQuality:(float)quality {
NSString *name = [NSString stringWithFormat:@"%li-%f.jpg", (long)image.hash, [NSDate timeIntervalSinceReferenceDate]];
NSData *data = UIImageJPEGRepresentation(image, quality);
[ChatConversationView writeFileInCache:data name:name];
[self uploadData:data forChatRoom:chatRoom type:@"image" subtype:@"jpg" name:name key:@"localimage"];
}
- (void)uploadVideo:(NSData *)data withassetId:(NSString *)phAssetId forChatRoom:(LinphoneChatRoom *)chatRoom {
NSString *name = [NSString stringWithFormat:@"IMG-%f.MOV", [NSDate timeIntervalSinceReferenceDate]];
[ChatConversationView writeFileInCache:data name:name];
[self uploadData:data forChatRoom:chatRoom type:@"video" subtype:@"mov" name:name key:@"localvideo"];
}
- (void)uploadFile:(NSData *)data forChatRoom:(LinphoneChatRoom *)chatRoom withName:(NSString *)name {
[ChatConversationView writeFileInCache:data name:name];
NSURL *url = [ChatConversationView getCacheFileUrl:name];
AVAsset *asset = [AVURLAsset URLAssetWithURL:url options:nil];
NSString *fileType = [[asset tracksWithMediaType:AVMediaTypeVideo] count] > 0 ? @"video" : @"file";

View file

@ -104,6 +104,7 @@
615A28422180C0870060F920 /* recording.png in Resources */ = {isa = PBXBuildFile; fileRef = 615A28412180C0820060F920 /* recording.png */; };
615A28442180C0900060F920 /* recording@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 615A28432180C08F0060F920 /* recording@2x.png */; };
617B4A60260A2B7800A87337 /* RecordingsListView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 617B4A62260A2B7800A87337 /* RecordingsListView.xib */; };
617C242A263022690042FB4A /* UIChatContentView.m in Sources */ = {isa = PBXBuildFile; fileRef = 617C2429263022690042FB4A /* UIChatContentView.m */; };
6180D6FE21EE41A800AD9CB6 /* QuickLook.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6180D6FD21EE41A800AD9CB6 /* QuickLook.framework */; };
61AE364F20C00B370089D9D3 /* ShareViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 61AE364E20C00B370089D9D3 /* ShareViewController.m */; };
61AE365220C00B370089D9D3 /* MainInterface.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 61AE365020C00B370089D9D3 /* MainInterface.storyboard */; };
@ -962,6 +963,8 @@
617B4A61260A2B7800A87337 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/RecordingsListView.xib; sourceTree = "<group>"; };
617B4A64260A2B8500A87337 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/RecordingsListView.strings; sourceTree = "<group>"; };
617B4A75260A3F5500A87337 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/RecordingsListView.strings; sourceTree = "<group>"; };
617C2428263022430042FB4A /* UIChatContentView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = UIChatContentView.h; sourceTree = "<group>"; };
617C2429263022690042FB4A /* UIChatContentView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = UIChatContentView.m; sourceTree = "<group>"; };
6180D6FD21EE41A800AD9CB6 /* QuickLook.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuickLook.framework; path = System/Library/Frameworks/QuickLook.framework; sourceTree = SDKROOT; };
6187B1B524B3271500D580FB /* hu */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hu; path = hu.lproj/AboutView.strings; sourceTree = "<group>"; };
6187B1B624B3271500D580FB /* hu */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hu; path = hu.lproj/AssistantLinkView.strings; sourceTree = "<group>"; };
@ -2178,6 +2181,8 @@
D3A8BB6E15A6C7D500F96BE5 /* UIChatBubbleTextCell.h */,
D3A8BB6F15A6C7D500F96BE5 /* UIChatBubbleTextCell.m */,
639E9CA51C0DB7EA00019A75 /* UIChatBubbleTextCell.xib */,
617C2428263022430042FB4A /* UIChatContentView.h */,
617C2429263022690042FB4A /* UIChatContentView.m */,
D3EA540F159853750037DC6B /* UIChatCell.h */,
D3EA5410159853750037DC6B /* UIChatCell.m */,
639CEB0B1A1DF4FA004DE38F /* UIChatCell.xib */,
@ -4207,6 +4212,7 @@
6377AC801BDE4069007F7625 /* UIBackToCallButton.m in Sources */,
6308F9C51BF0DD6600D1234B /* XMLRPCHelper.m in Sources */,
D3ED3E871586291E006C0DE4 /* TabBarView.m in Sources */,
617C242A263022690042FB4A /* UIChatContentView.m in Sources */,
D3ED3EA71587334E006C0DE4 /* HistoryListTableView.m in Sources */,
61AEBEBD2191990A00F35E7F /* DevicesListView.m in Sources */,
D3ED3EB81587392C006C0DE4 /* HistoryListView.m in Sources */,