From 5d2e3862bf392bcef79212de89eeb03bb92caaf3 Mon Sep 17 00:00:00 2001 From: ylecollen Date: Mon, 19 Jan 2015 14:33:57 +0100 Subject: [PATCH] --> The media folder has a new dirtree : each media are stored in 1 - its related room folder 2 - or the thumbnails folder --> the medias downloads/uploads are cancelled when the mediaManager cache is cleared. --- matrixConsole/matrixConsole/API/MediaLoader.h | 5 +- matrixConsole/matrixConsole/API/MediaLoader.m | 10 +- .../matrixConsole/API/MediaManager.h | 26 ++- .../matrixConsole/API/MediaManager.m | 162 +++++++++++++++--- .../matrixConsole/View/CustomImageView.h | 3 + .../matrixConsole/View/CustomImageView.m | 12 +- .../matrixConsole/View/RoomMemberTableCell.m | 2 + .../matrixConsole/View/RoomMessageTableCell.m | 6 +- .../ViewController/MemberViewController.m | 8 +- .../ViewController/RoomViewController.m | 46 ++--- .../ViewController/SettingsViewController.m | 10 +- 11 files changed, 216 insertions(+), 74 deletions(-) diff --git a/matrixConsole/matrixConsole/API/MediaLoader.h b/matrixConsole/matrixConsole/API/MediaLoader.h index 2a9b475a4..7be378e23 100644 --- a/matrixConsole/matrixConsole/API/MediaLoader.h +++ b/matrixConsole/matrixConsole/API/MediaLoader.h @@ -48,6 +48,8 @@ typedef void (^blockMediaLoader_onError)(NSError *error); blockMediaLoader_onSuccess onSuccess; blockMediaLoader_onError onError; + NSString *folder; + // Download NSString *mediaURL; long long expectedSize; @@ -73,6 +75,7 @@ typedef void (^blockMediaLoader_onError)(NSError *error); // Download - (void)downloadMedia:(NSString *)aMediaURL mimeType:(NSString *)aMimeType + folder:(NSString*)folder success:(blockMediaLoader_onSuccess)success failure:(blockMediaLoader_onError)failure; @@ -82,7 +85,7 @@ typedef void (^blockMediaLoader_onError)(NSError *error); // e.g. : Upload a media can be split in two parts : // 1 - upload the thumbnail -> initialRange = 0, range = 0.1 : assume that the thumbnail upload is 10% of the upload process // 2 - upload the media -> initialRange = 0.1, range = 0.9 : the media upload is 90% of the global upload -- (id)initWithUploadId:(NSString *)anUploadId initialRange:(CGFloat)anInitialRange andRange:(CGFloat)aRange; +- (id)initWithUploadId:(NSString *)anUploadId initialRange:(CGFloat)anInitialRange andRange:(CGFloat)aRange folder:(NSString*)aFolder; - (void)uploadData:(NSData *)data mimeType:(NSString *)aMimeType success:(blockMediaLoader_onSuccess)success diff --git a/matrixConsole/matrixConsole/API/MediaLoader.m b/matrixConsole/matrixConsole/API/MediaLoader.m index 5b13da1e8..debada960 100644 --- a/matrixConsole/matrixConsole/API/MediaLoader.m +++ b/matrixConsole/matrixConsole/API/MediaLoader.m @@ -49,6 +49,7 @@ NSString *const kMediaLoaderProgressDownloadRateKey = @"kMediaLoaderProgressDown onSuccess = nil; onError = nil; } + folder = nil; statisticsDict = nil; } @@ -60,11 +61,13 @@ NSString *const kMediaLoaderProgressDownloadRateKey = @"kMediaLoaderProgressDown - (void)downloadMedia:(NSString*)aMediaURL mimeType:(NSString *)aMimeType + folder:(NSString*)aFolder success:(blockMediaLoader_onSuccess)success failure:(blockMediaLoader_onError)failure { // Report provided params mediaURL = aMediaURL; mimeType = aMimeType; + folder = aFolder; onSuccess = success; onError = failure; @@ -82,6 +85,7 @@ NSString *const kMediaLoaderProgressDownloadRateKey = @"kMediaLoaderProgressDown // Start downloading NSURL *url = [NSURL URLWithString:absoluteMediaURL]; downloadData = [[NSMutableData alloc] init]; + downloadConnection = [[NSURLConnection alloc] initWithRequest:[NSURLRequest requestWithURL:url] delegate:self]; } @@ -163,7 +167,7 @@ NSString *const kMediaLoaderProgressDownloadRateKey = @"kMediaLoaderProgressDown if (downloadData.length) { // Cache the downloaded data - NSString *cacheFilePath = [MediaManager cacheMediaData:downloadData forURL:mediaURL andType:mimeType]; + NSString *cacheFilePath = [MediaManager cacheMediaData:downloadData forURL:mediaURL andType:mimeType inFolder:folder]; // Call registered block if (onSuccess) { onSuccess(cacheFilePath); @@ -181,18 +185,18 @@ NSString *const kMediaLoaderProgressDownloadRateKey = @"kMediaLoaderProgressDown #pragma mark - Upload -- (id)initWithUploadId:(NSString *)anUploadId initialRange:(CGFloat)anInitialRange andRange:(CGFloat)aRange { +- (id)initWithUploadId:(NSString *)anUploadId initialRange:(CGFloat)anInitialRange andRange:(CGFloat)aRange folder:(NSString*)aFolder { if (self = [super init]) { uploadId = anUploadId; initialRange = anInitialRange; range = aRange; + folder = aFolder; } return self; } - (void)uploadData:(NSData *)data mimeType:(NSString *)aMimeType success:(blockMediaLoader_onSuccess)success failure:(blockMediaLoader_onError)failure { mimeType = aMimeType; - statsStartTime = CFAbsoluteTimeGetCurrent(); MatrixHandler *mxHandler = [MatrixHandler sharedHandler]; diff --git a/matrixConsole/matrixConsole/API/MediaManager.h b/matrixConsole/matrixConsole/API/MediaManager.h index 090109cb5..c84d02390 100644 --- a/matrixConsole/matrixConsole/API/MediaManager.h +++ b/matrixConsole/matrixConsole/API/MediaManager.h @@ -18,7 +18,7 @@ #import "MediaLoader.h" extern NSString *const kMediaManagerPrefixForDummyURL; -extern NSString *const kMediaManagerThumbnailDirectory; +extern NSString *const kMediaManagerThumbnailFolder; // notify when a media download is finished (object: URL) extern NSString *const kMediaDownloadDidFinishNotification; @@ -27,9 +27,13 @@ extern NSString *const kMediaDownloadDidFailNotification; @interface MediaManager : NSObject // Download data from the provided URL. Return a mediaLoader reference in order to let the user cancel this action. -+ (MediaLoader*)downloadMediaFromURL:(NSString *)mediaURL withType:(NSString *)mimeType; ++ (MediaLoader*)downloadMediaFromURL:(NSString *)mediaURL withType:(NSString *)mimeType inFolder:(NSString*)folder; // Check whether a download is already running for this media url. Return loader if any -+ (MediaLoader*)existingDownloaderForURL:(NSString*)url; ++ (MediaLoader*)existingDownloaderForURL:(NSString*)url inFolder:(NSString*)folder; +// cancel any pending download, within the folder ++ (void)cancelDownloadsInFolder:(NSString*)folder; +// cancel any pending download ++ (void)cancelDownloads; // Prepares and returns a media loader to upload data to matrix content repository. // initialRange / range: an upload could be a subpart of uploads. initialRange defines the global upload progress already did done before this current upload. @@ -37,17 +41,21 @@ extern NSString *const kMediaDownloadDidFailNotification; // e.g. : Upload a media can be split in two parts : // 1 - upload the thumbnail -> initialRange = 0, range = 0.1 : assume that the thumbnail upload is 10% of the upload process // 2 - upload the media -> initialRange = 0.1, range = 0.9 : the media upload is 90% of the global upload -+ (MediaLoader*)prepareUploaderWithId:(NSString *)uploadId initialRange:(CGFloat)initialRange andRange:(CGFloat)range; ++ (MediaLoader*)prepareUploaderWithId:(NSString *)uploadId initialRange:(CGFloat)initialRange andRange:(CGFloat)range inFolder:(NSString*)folder; // Check whether an upload is already running with this id. Return loader if any -+ (MediaLoader*)existingUploaderWithId:(NSString*)uploadId; -+ (void)removeUploaderWithId:(NSString*)uploadId; ++ (MediaLoader*)existingUploaderWithId:(NSString*)uploadId inFolder:(NSString*)folder; ++ (void)removeUploaderWithId:(NSString*)uploadId inFolder:(NSString*)folder; +// cancel pending MediaLoader in folder ++ (void)cancelUploadsInFolder:(NSString*)folder; +// cancel any pending upload ++ (void)cancelUploads; // Load a picture from the local cache (Do not start any remote requests) -+ (UIImage*)loadCachePictureForURL:(NSString*)pictureURL; ++ (UIImage*)loadCachePictureForURL:(NSString*)pictureURL inFolder:(NSString*)folder; // Store in cache the provided data for the media URL, return the path of the resulting file -+ (NSString*)cacheMediaData:(NSData *)mediaData forURL:(NSString *)mediaURL andType:(NSString *)mimeType; ++ (NSString*)cacheMediaData:(NSData *)mediaData forURL:(NSString *)mediaURL andType:(NSString *)mimeType inFolder:(NSString*)folder; // Return the cache path deduced from media URL and type -+ (NSString*)cachePathForMediaURL:(NSString*)mediaURL andType:(NSString *)mimeType; ++ (NSString*)cachePathForMediaURL:(NSString*)mediaURL andType:(NSString *)mimeType inFolder:(NSString*)folder; // cache size management (values are in bytes) + (NSUInteger)cacheSize; diff --git a/matrixConsole/matrixConsole/API/MediaManager.m b/matrixConsole/matrixConsole/API/MediaManager.m index d628462c1..eaaa7e18f 100644 --- a/matrixConsole/matrixConsole/API/MediaManager.m +++ b/matrixConsole/matrixConsole/API/MediaManager.m @@ -24,7 +24,7 @@ NSString *const kMediaManagerPrefixForDummyURL = @"dummyUrl-"; NSString *const kMediaDownloadDidFinishNotification = @"kMediaDownloadDidFinishNotification"; NSString *const kMediaDownloadDidFailNotification = @"kMediaDownloadDidFailNotification"; -NSString *const kMediaManagerThumbnailDirectory = @"kMediaManagerThumbnailDirectory"; +NSString *const kMediaManagerThumbnailFolder = @"kMediaManagerThumbnailFolder"; static NSString* mediaCachePath = nil; static NSString *mediaDir = @"mediacache"; @@ -40,7 +40,18 @@ static NSMutableDictionary* uploadTableById = nil; #pragma mark - Media Download -+ (MediaLoader*)downloadMediaFromURL:(NSString*)mediaURL withType:(NSString *)mimeType { ++ (NSString*)downloadKey:mediaURL andFolder:(NSString*)folder { + NSMutableString* key = [[NSMutableString alloc] init]; + + [key appendString:mediaURL]; + + if (folder.length > 0) { + [key appendFormat:@"_download_%@", folder]; + } + return key; +} + ++ (MediaLoader*)downloadMediaFromURL:(NSString*)mediaURL withType:(NSString *)mimeType inFolder:(NSString*)folder { if (mediaURL && [mediaURL hasPrefix:kMediaManagerPrefixForDummyURL] == NO) { // Create a media loader to download data MediaLoader *mediaLoader = [[MediaLoader alloc] init]; @@ -48,14 +59,14 @@ static NSMutableDictionary* uploadTableById = nil; if (!downloadTableByURL) { downloadTableByURL = [[NSMutableDictionary alloc] init]; } - [downloadTableByURL setValue:mediaLoader forKey:mediaURL]; + [downloadTableByURL setValue:mediaLoader forKey:[MediaManager downloadKey:mediaURL andFolder:folder]]; // Launch download - [mediaLoader downloadMedia:mediaURL mimeType:mimeType success:^(NSString *cacheFilePath) { - [downloadTableByURL removeObjectForKey:mediaURL]; + [mediaLoader downloadMedia:mediaURL mimeType:mimeType folder:folder success:^(NSString *cacheFilePath) { + [downloadTableByURL removeObjectForKey:[MediaManager downloadKey:mediaURL andFolder:folder]]; [[NSNotificationCenter defaultCenter] postNotificationName:kMediaDownloadDidFinishNotification object:mediaURL userInfo:nil]; } failure:^(NSError *error) { - [downloadTableByURL removeObjectForKey:mediaURL]; + [downloadTableByURL removeObjectForKey:[MediaManager downloadKey:mediaURL andFolder:folder]]; NSLog(@"Failed to download image (%@): %@", mediaURL, error); [[NSNotificationCenter defaultCenter] postNotificationName:kMediaDownloadDidFailNotification object:mediaURL userInfo:nil]; }]; @@ -66,47 +77,140 @@ static NSMutableDictionary* uploadTableById = nil; } // try to find out a media loader from a media URL -+ (id)existingDownloaderForURL:(NSString*)url { ++ (id)existingDownloaderForURL:(NSString*)url inFolder:(NSString*)folder { if (downloadTableByURL && url) { - return [downloadTableByURL valueForKey:url]; + return [downloadTableByURL valueForKey:[MediaManager downloadKey:url andFolder:folder]]; } return nil; } ++ (void)cancelDownloadsInFolder:(NSString*)folder { + NSMutableArray* pendingLoaders =[[NSMutableArray alloc] init]; + NSArray* allKeys = [downloadTableByURL allKeys]; + + // any folder name ? + if (folder.length > 0) { + + NSString* keySuffix = [NSString stringWithFormat:@"_download_%@", folder]; + + for(NSString* key in allKeys) { + if ([key hasSuffix:keySuffix]) { + [pendingLoaders addObject:[downloadTableByURL valueForKey:key]]; + [downloadTableByURL removeObjectForKey:key]; + } + } + } else { + for(NSString* key in allKeys) { + if ([key rangeOfString:@"_download_"].location == NSNotFound) { + [pendingLoaders addObject:[downloadTableByURL valueForKey:key]]; + [downloadTableByURL removeObjectForKey:key]; + } + } + } + + if (pendingLoaders > 0) { + for (MediaLoader* loader in pendingLoaders) { + [loader cancel]; + } + } +} + +// cancel any pending download ++ (void)cancelDownloads { + NSArray* allKeys = [downloadTableByURL allKeys]; + + for(NSString* key in allKeys) { + [[downloadTableByURL valueForKey:key] cancel]; + [downloadTableByURL removeObjectForKey:key]; + } +} + #pragma mark - Media Uploader -+ (MediaLoader*)prepareUploaderWithId:(NSString *)uploadId initialRange:(CGFloat)initialRange andRange:(CGFloat)range { ++ (NSString*)uploadKey:uploadId andFolder:(NSString*)folder { + NSMutableString* key = [[NSMutableString alloc] init]; + + [key appendString:uploadId]; + + if (folder.length > 0) { + [key appendFormat:@"_upload_%@", folder]; + } + return key; +} + ++ (MediaLoader*)prepareUploaderWithId:(NSString *)uploadId initialRange:(CGFloat)initialRange andRange:(CGFloat)range inFolder:(NSString*)aFolder { if (uploadId) { // Create a media loader to upload data - MediaLoader *mediaLoader = [[MediaLoader alloc] initWithUploadId:uploadId initialRange:initialRange andRange:range]; + MediaLoader *mediaLoader = [[MediaLoader alloc] initWithUploadId:uploadId initialRange:initialRange andRange:range folder:aFolder]; // Report this loader if (!uploadTableById) { uploadTableById = [[NSMutableDictionary alloc] init]; } - [uploadTableById setValue:mediaLoader forKey:uploadId]; + [uploadTableById setValue:mediaLoader forKey:[MediaManager uploadKey:uploadId andFolder:aFolder]]; return mediaLoader; } return nil; } -+ (MediaLoader*)existingUploaderWithId:(NSString*)uploadId { ++ (MediaLoader*)existingUploaderWithId:(NSString*)uploadId inFolder:(NSString*)folder { if (uploadTableById && uploadId) { - return [uploadTableById valueForKey:uploadId]; + return [uploadTableById valueForKey:[MediaManager uploadKey:uploadId andFolder:folder]]; } return nil; } -+ (void)removeUploaderWithId:(NSString*)uploadId { ++ (void)removeUploaderWithId:(NSString*)uploadId inFolder:(NSString*)folder { if (uploadTableById && uploadId) { - return [uploadTableById removeObjectForKey:uploadId]; + return [uploadTableById removeObjectForKey:[MediaManager uploadKey:uploadId andFolder:folder]]; + } +} + ++ (void)cancelUploadsInFolder:(NSString*)folder { + NSMutableArray* pendingLoaders =[[NSMutableArray alloc] init]; + NSArray* allKeys = [uploadTableById allKeys]; + + // + if (folder.length > 0) { + + NSString* keySuffix = [NSString stringWithFormat:@"_upload_%@", folder]; + + for(NSString* key in allKeys) { + if ([key hasSuffix:keySuffix]) { + [pendingLoaders addObject:[uploadTableById valueForKey:key]]; + [uploadTableById removeObjectForKey:key]; + } + } + } else { + for(NSString* key in allKeys) { + if ([key rangeOfString:@"_upload_"].location == NSNotFound) { + [pendingLoaders addObject:[uploadTableById valueForKey:key]]; + [uploadTableById removeObjectForKey:key]; + } + } + } + + if (pendingLoaders > 0) { + for (MediaLoader* loader in pendingLoaders) { + [loader cancel]; + } + } +} + +// cancel any pending download ++ (void)cancelUploads { + NSArray* allKeys = [uploadTableById allKeys]; + + for(NSString* key in allKeys) { + [[uploadTableById valueForKey:key] cancel]; + [uploadTableById removeObjectForKey:key]; } } #pragma mark - Cache Handling -+ (UIImage*)loadCachePictureForURL:(NSString*)pictureURL { ++ (UIImage*)loadCachePictureForURL:(NSString*)pictureURL inFolder:(NSString*)folder { UIImage* res = nil; - NSString* filename = [MediaManager cachePathForMediaURL:pictureURL andType:@"image/jpeg"]; + NSString* filename = [MediaManager cachePathForMediaURL:pictureURL andType:@"image/jpeg" inFolder:folder]; if ([[NSFileManager defaultManager] fileExistsAtPath:filename]) { NSData* imageContent = [NSData dataWithContentsOfFile:filename options:(NSDataReadingMappedAlways | NSDataReadingUncached) error:nil]; @@ -118,8 +222,8 @@ static NSMutableDictionary* uploadTableById = nil; return res; } -+ (NSString*)cacheMediaData:(NSData*)mediaData forURL:(NSString *)mediaURL andType:(NSString *)mimeType { - NSString* filename = [MediaManager cachePathForMediaURL:mediaURL andType:mimeType]; ++ (NSString*)cacheMediaData:(NSData*)mediaData forURL:(NSString *)mediaURL andType:(NSString *)mimeType inFolder:(NSString*)folder { + NSString* filename = [MediaManager cachePathForMediaURL:mediaURL andType:mimeType inFolder:folder]; if ([mediaData writeToFile:filename atomically:YES]) { return filename; @@ -128,8 +232,7 @@ static NSMutableDictionary* uploadTableById = nil; } } -+ (NSString*)cachePathForMediaURL:(NSString*)mediaURL andType:(NSString *)mimeType { - ++ (NSString*)cachePathForMediaURL:(NSString*)mediaURL andType:(NSString *)mimeType inFolder:(NSString*)folder { NSString* fileExt = [ConsoleTools fileExtensionFromContentType:mimeType]; NSString* fileBase = @""; @@ -139,9 +242,19 @@ static NSMutableDictionary* uploadTableById = nil; fileBase = [components objectAtIndex:0]; } - NSString *fileName = [NSString stringWithFormat:@"%@%lu%@", [fileBase substringToIndex:3], (unsigned long)mediaURL.hash, fileExt]; + NSString* path = [MediaManager getCachePath]; - return [[MediaManager getCachePath] stringByAppendingPathComponent:fileName]; + // update the path if the folder is provided + if (folder.length > 0) { + path = [[MediaManager getCachePath] stringByAppendingPathComponent:[NSString stringWithFormat:@"%lu", folder.hash]]; + } + + // create the folder it does not exist + if (![[NSFileManager defaultManager] fileExistsAtPath:path]) { + [[NSFileManager defaultManager] createDirectoryAtPath:path withIntermediateDirectories:NO attributes:nil error:nil]; + } + + return [path stringByAppendingPathComponent:[NSString stringWithFormat:@"%@%lu%@", [fileBase substringToIndex:3], (unsigned long)mediaURL.hash, fileExt]]; } + (NSUInteger)cacheSize { @@ -192,6 +305,9 @@ static NSMutableDictionary* uploadTableById = nil; mediaCachePath = [MediaManager getCachePath]; } + [MediaManager cancelDownloads]; + [MediaManager cancelUploads]; + if (mediaCachePath) { if (![[NSFileManager defaultManager] removeItemAtPath:mediaCachePath error:&error]) { NSLog(@"Fails to delete media cache dir : %@", error); diff --git a/matrixConsole/matrixConsole/View/CustomImageView.h b/matrixConsole/matrixConsole/View/CustomImageView.h index 7a080fab8..567cd3ecd 100644 --- a/matrixConsole/matrixConsole/View/CustomImageView.h +++ b/matrixConsole/matrixConsole/View/CustomImageView.h @@ -34,6 +34,9 @@ typedef void (^blockCustomImageView_onClick)(CustomImageView *imageView, NSStrin @property (nonatomic) BOOL stretchable; @property (nonatomic) BOOL fullScreen; +// mediaManager folder where the image is stored +@property (nonatomic, readwrite) NSString* mediaFolder; + // Let the user defines some custom buttons over the tabbar - (void)setLeftButtonTitle :leftButtonTitle handler:(blockCustomImageView_onClick)handler; - (void)setRightButtonTitle:rightButtonTitle handler:(blockCustomImageView_onClick)handler; diff --git a/matrixConsole/matrixConsole/View/CustomImageView.m b/matrixConsole/matrixConsole/View/CustomImageView.m index ca8ed808a..fdf049f30 100644 --- a/matrixConsole/matrixConsole/View/CustomImageView.m +++ b/matrixConsole/matrixConsole/View/CustomImageView.m @@ -51,7 +51,7 @@ @end @implementation CustomImageView -@synthesize stretchable; +@synthesize stretchable, mediaFolder; #define CUSTOM_IMAGE_VIEW_BUTTON_WIDTH 100 @@ -403,7 +403,7 @@ _hideActivityIndicator = hideActivityIndicator; if (hideActivityIndicator) { [self stopActivityIndicator]; - } else if ([MediaManager existingDownloaderForURL:imageURL]) { + } else if ([MediaManager existingDownloaderForURL:imageURL inFolder:mediaFolder]) { // Loading is in progress, start activity indicator [self startActivityIndicator]; } @@ -421,7 +421,7 @@ } // Check whether the image download is in progress - MediaLoader* loader = [MediaManager existingDownloaderForURL:imageURL]; + MediaLoader* loader = [MediaManager existingDownloaderForURL:imageURL inFolder:mediaFolder]; if (loader) { // Set preview until the image is loaded self.image = previewImage; @@ -434,7 +434,7 @@ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onMediaDownloadEnd:) name:kMediaDownloadDidFailNotification object:nil]; } else { // Retrieve the image from cache - UIImage* image = [MediaManager loadCachePictureForURL:imageURL]; + UIImage* image = [MediaManager loadCachePictureForURL:imageURL inFolder:mediaFolder]; if (image) { self.image = image; [self stopActivityIndicator]; @@ -449,7 +449,7 @@ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onMediaDownloadProgress:) name:kMediaDownloadProgressNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onMediaDownloadEnd:) name:kMediaDownloadDidFinishNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onMediaDownloadEnd:) name:kMediaDownloadDidFailNotification object:nil]; - [MediaManager downloadMediaFromURL:imageURL withType:@"image/jpeg"]; + [MediaManager downloadMediaFromURL:imageURL withType:@"image/jpeg" inFolder:mediaFolder]; } } } @@ -462,7 +462,7 @@ if ([url isEqualToString:imageURL]) { [self stopActivityIndicator]; // update the image - UIImage* image = [MediaManager loadCachePictureForURL:imageURL]; + UIImage* image = [MediaManager loadCachePictureForURL:imageURL inFolder:mediaFolder]; if (image) { self.image = image; } diff --git a/matrixConsole/matrixConsole/View/RoomMemberTableCell.m b/matrixConsole/matrixConsole/View/RoomMemberTableCell.m index f7f098784..d4b5df57b 100644 --- a/matrixConsole/matrixConsole/View/RoomMemberTableCell.m +++ b/matrixConsole/matrixConsole/View/RoomMemberTableCell.m @@ -16,6 +16,7 @@ #import "RoomMemberTableCell.h" #import "MatrixHandler.h" +#import "MediaManager.h" @implementation RoomMemberTableCell @@ -111,6 +112,7 @@ MatrixHandler *mxHandler = [MatrixHandler sharedHandler]; thumbnailURL = [mxHandler thumbnailURLForContent:roomMember.avatarUrl inViewSize:self.pictureView.frame.size withMethod:MXThumbnailingMethodCrop]; } + self.pictureView.mediaFolder = kMediaManagerThumbnailFolder; [self.pictureView setImageURL:thumbnailURL withPreviewImage:[UIImage imageNamed:@"default-profile"]]; // Round image view diff --git a/matrixConsole/matrixConsole/View/RoomMessageTableCell.m b/matrixConsole/matrixConsole/View/RoomMessageTableCell.m index 888a62b85..e06efd4d4 100644 --- a/matrixConsole/matrixConsole/View/RoomMessageTableCell.m +++ b/matrixConsole/matrixConsole/View/RoomMessageTableCell.m @@ -94,7 +94,7 @@ if (self.message.attachmentURL) { // check if there is a downlad in progress - MediaLoader *loader = [MediaManager existingDownloaderForURL:self.message.attachmentURL]; + MediaLoader *loader = [MediaManager existingDownloaderForURL:self.message.attachmentURL inFolder:self.attachmentView.mediaFolder]; NSDictionary *dict = loader.statisticsDict; @@ -123,7 +123,7 @@ - (void)cancelDownload { // get the linked medida loader - MediaLoader *loader = [MediaManager existingDownloaderForURL:self.message.attachmentURL]; + MediaLoader *loader = [MediaManager existingDownloaderForURL:self.message.attachmentURL inFolder:self.attachmentView.mediaFolder]; if (loader) { [loader cancel]; } @@ -156,7 +156,7 @@ self.activityIndicator.hidden = NO; [self.activityIndicator startAnimating]; - MediaLoader *uploader = [MediaManager existingUploaderWithId:self.message.uploadId]; + MediaLoader *uploader = [MediaManager existingUploaderWithId:self.message.uploadId inFolder:self.attachmentView.mediaFolder]; if (uploader && uploader.statisticsDict) { self.activityIndicator.hidden = YES; [self updateProgressUI:uploader.statisticsDict]; diff --git a/matrixConsole/matrixConsole/ViewController/MemberViewController.m b/matrixConsole/matrixConsole/ViewController/MemberViewController.m index d81161bd8..2561aea3e 100644 --- a/matrixConsole/matrixConsole/ViewController/MemberViewController.m +++ b/matrixConsole/matrixConsole/ViewController/MemberViewController.m @@ -170,14 +170,14 @@ thumbnailURL = [mxHandler thumbnailURLForContent:_mxRoomMember.avatarUrl inViewSize:self.memberThumbnailButton.frame.size withMethod:MXThumbnailingMethodCrop]; // Check whether the image download is in progress - id loader = [MediaManager existingDownloaderForURL:thumbnailURL]; + id loader = [MediaManager existingDownloaderForURL:thumbnailURL inFolder:kMediaManagerThumbnailFolder]; if (loader) { // Add observers [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onMediaDownloadEnd:) name:kMediaDownloadDidFinishNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onMediaDownloadEnd:) name:kMediaDownloadDidFailNotification object:nil]; } else { // Retrieve the image from cache - UIImage* image = [MediaManager loadCachePictureForURL:thumbnailURL]; + UIImage* image = [MediaManager loadCachePictureForURL:thumbnailURL inFolder:kMediaManagerThumbnailFolder]; if (image) { [self.memberThumbnailButton setImage:image forState:UIControlStateNormal]; [self.memberThumbnailButton setImage:image forState:UIControlStateHighlighted]; @@ -189,7 +189,7 @@ // Add observers [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onMediaDownloadEnd:) name:kMediaDownloadDidFinishNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onMediaDownloadEnd:) name:kMediaDownloadDidFailNotification object:nil]; - imageLoader = [MediaManager downloadMediaFromURL:thumbnailURL withType:@"image/jpeg"]; + imageLoader = [MediaManager downloadMediaFromURL:thumbnailURL withType:@"image/jpeg" inFolder:kMediaManagerThumbnailFolder]; } } } else { @@ -210,7 +210,7 @@ if ([url isEqualToString:thumbnailURL]) { // update the image - UIImage* image = [MediaManager loadCachePictureForURL:thumbnailURL]; + UIImage* image = [MediaManager loadCachePictureForURL:thumbnailURL inFolder:kMediaManagerThumbnailFolder]; if (image == nil) { image = [UIImage imageNamed:@"default-profile"]; } diff --git a/matrixConsole/matrixConsole/ViewController/RoomViewController.m b/matrixConsole/matrixConsole/ViewController/RoomViewController.m index 742c16447..fb6f727ae 100644 --- a/matrixConsole/matrixConsole/ViewController/RoomViewController.m +++ b/matrixConsole/matrixConsole/ViewController/RoomViewController.m @@ -405,7 +405,7 @@ NSString *const kCmdResetUserPowerLevel = @"/deop"; __weak typeof(self) weakSelf = self; NSString* url = ((RoomMessageTableCell*)view).message.attachmentURL; - MediaLoader *loader = [MediaManager existingDownloaderForURL:url]; + MediaLoader *loader = [MediaManager existingDownloaderForURL:url inFolder:self.roomId]; // offer to cancel a download only if there is a pending one if (loader) { @@ -416,7 +416,7 @@ NSString *const kCmdResetUserPowerLevel = @"/deop"; self.actionMenu.cancelButtonIndex = [self.actionMenu addActionWithTitle:@"OK" style:CustomAlertActionStyleDefault handler:^(CustomAlert *alert) { // get again the loader, the cell could have been reused. - MediaLoader *loader = [MediaManager existingDownloaderForURL:url]; + MediaLoader *loader = [MediaManager existingDownloaderForURL:url inFolder:weakSelf.roomId]; if (loader) { [loader cancel]; } @@ -1109,6 +1109,7 @@ NSString *const kCmdResetUserPowerLevel = @"/deop"; highResImageView = [[CustomImageView alloc] initWithFrame:self.membersView.frame]; highResImageView.stretchable = YES; highResImageView.fullScreen = YES; + highResImageView.mediaFolder = self.roomId; [highResImageView setImageURL:url withPreviewImage:attachment.image]; // Add tap recognizer to hide attachment @@ -1147,7 +1148,7 @@ NSString *const kCmdResetUserPowerLevel = @"/deop"; if ([[NSFileManager defaultManager] fileExistsAtPath:selectedVideoURL]) { selectedVideoCachePath = selectedVideoURL; } else { - selectedVideoCachePath = [MediaManager cachePathForMediaURL:selectedVideoURL andType:mimetype]; + selectedVideoCachePath = [MediaManager cachePathForMediaURL:selectedVideoURL andType:mimetype inFolder:self.roomId]; } if ([[NSFileManager defaultManager] fileExistsAtPath:selectedVideoCachePath]) { @@ -1156,7 +1157,7 @@ NSString *const kCmdResetUserPowerLevel = @"/deop"; } else { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onMediaDownloadEnd:) name:kMediaDownloadDidFinishNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onMediaDownloadEnd:) name:kMediaDownloadDidFailNotification object:nil]; - [MediaManager downloadMediaFromURL:selectedVideoURL withType:mimetype]; + [MediaManager downloadMediaFromURL:selectedVideoURL withType:mimetype inFolder:self.roomId]; } } } @@ -1246,22 +1247,22 @@ NSString *const kCmdResetUserPowerLevel = @"/deop"; if (videoData) { NSMutableDictionary* videoInfo = [videoContent valueForKey:@"info"]; - MediaLoader *videoUploader = [MediaManager prepareUploaderWithId:localEvent.eventId initialRange:0.1 andRange:0.9]; + MediaLoader *videoUploader = [MediaManager prepareUploaderWithId:localEvent.eventId initialRange:0.1 andRange:0.9 inFolder:self.roomId]; [videoUploader uploadData:videoData mimeType:videoInfo[@"mimetype"] success:^(NSString *url) { // remove the tmp file [[NSFileManager defaultManager] removeItemAtPath:[videoInfo valueForKey:@"url"] error:nil]; // remove the related uploadLoader - [MediaManager removeUploaderWithId:localEvent.eventId]; + [MediaManager removeUploaderWithId:localEvent.eventId inFolder:self.roomId]; // store the video file in the cache // there is no reason to download an oneself uploaded media - [MediaManager cacheMediaData:videoData forURL:url andType:videoInfo[@"mimetype"]]; + [MediaManager cacheMediaData:videoData forURL:url andType:videoInfo[@"mimetype"] inFolder:self.roomId]; [videoContent setValue:url forKey:@"url"]; [self sendMessage:videoContent withLocalEvent:localEvent]; } failure:^(NSError *error) { NSLog(@"Video upload failed"); - [MediaManager removeUploaderWithId:localEvent.eventId]; + [MediaManager removeUploaderWithId:localEvent.eventId inFolder:self.roomId]; [self handleError:error forLocalEvent:localEvent]; }]; } @@ -1282,12 +1283,12 @@ NSString *const kCmdResetUserPowerLevel = @"/deop"; NSMutableDictionary *infoDict = [localEvent.content valueForKey:@"info"]; NSMutableDictionary *thumbnailInfo = [infoDict valueForKey:@"thumbnail_info"]; - NSData *thumbnailData = [NSData dataWithContentsOfFile:[MediaManager cachePathForMediaURL:[infoDict valueForKey:@"thumbnail_url"] andType:[thumbnailInfo objectForKey:@"mimetype"]]]; + NSData *thumbnailData = [NSData dataWithContentsOfFile:[MediaManager cachePathForMediaURL:[infoDict valueForKey:@"thumbnail_url"] andType:[thumbnailInfo objectForKey:@"mimetype"] inFolder:self.roomId]]; // Upload thumbnail - MediaLoader *uploader = [MediaManager prepareUploaderWithId:localEvent.eventId initialRange:0 andRange:0.1]; + MediaLoader *uploader = [MediaManager prepareUploaderWithId:localEvent.eventId initialRange:0 andRange:0.1 inFolder:self.roomId]; [uploader uploadData:thumbnailData mimeType:[thumbnailInfo valueForKey:@"mimetype"] success:^(NSString *url) { - [MediaManager removeUploaderWithId:localEvent.eventId]; + [MediaManager removeUploaderWithId:localEvent.eventId inFolder:self.roomId]; // Prepare content of attached video NSMutableDictionary *videoContent = [[NSMutableDictionary alloc] init]; NSMutableDictionary *videoInfo = [[NSMutableDictionary alloc] init]; @@ -1351,7 +1352,7 @@ NSString *const kCmdResetUserPowerLevel = @"/deop"; }]; } failure:^(NSError *error) { NSLog(@"Video thumbnail upload failed"); - [MediaManager removeUploaderWithId:localEvent.eventId]; + [MediaManager removeUploaderWithId:localEvent.eventId inFolder:self.roomId]; [self handleError:error forLocalEvent:localEvent]; }]; } @@ -1630,6 +1631,10 @@ NSString *const kCmdResetUserPowerLevel = @"/deop"; // Keep reference on message cell.message = message; + // set the media folders + cell.pictureView.mediaFolder = kMediaManagerThumbnailFolder; + cell.attachmentView.mediaFolder = self.roomId; + // Remove all gesture recognizer while (cell.attachmentView.gestureRecognizers.count) { [cell.attachmentView removeGestureRecognizer:cell.attachmentView.gestureRecognizers[0]]; @@ -1756,7 +1761,7 @@ NSString *const kCmdResetUserPowerLevel = @"/deop"; } UIImage *preview = nil; if (message.previewURL) { - preview = [MediaManager loadCachePictureForURL:message.previewURL]; + preview = [MediaManager loadCachePictureForURL:message.previewURL inFolder:self.roomId]; } [cell.attachmentView setImageURL:url withPreviewImage:preview]; @@ -2278,7 +2283,7 @@ NSString *const kCmdResetUserPowerLevel = @"/deop"; } if (index != NSNotFound) { - UIImage* image = [MediaManager loadCachePictureForURL:roomMessage.attachmentURL]; + UIImage* image = [MediaManager loadCachePictureForURL:roomMessage.attachmentURL inFolder:weakSelf.roomId]; // if the URL is still a local one if (image) { @@ -2313,7 +2318,7 @@ NSString *const kCmdResetUserPowerLevel = @"/deop"; if (index != NSNotFound) { // if the URL is still a local one if (![NSURL URLWithString:roomMessage.thumbnailURL].scheme) { - UIImage* image = [MediaManager loadCachePictureForURL:roomMessage.thumbnailURL]; + UIImage* image = [MediaManager loadCachePictureForURL:roomMessage.thumbnailURL inFolder:weakSelf.roomId]; // it should mean that the thumbnail upload fails [weakSelf sendVideo:[NSURL fileURLWithPath:roomMessage.attachmentURL] withThumbnail:image]; } else { @@ -2514,7 +2519,7 @@ NSString *const kCmdResetUserPowerLevel = @"/deop"; - (NSData*)cachedImageData:(UIImage*)image withURL:(NSString*)url { NSData *imageData = UIImageJPEGRepresentation(image, 0.8); - NSString *cacheFilePath = [MediaManager cacheMediaData:imageData forURL:url andType:@"image/jpeg"]; + NSString *cacheFilePath = [MediaManager cacheMediaData:imageData forURL:url andType:@"image/jpeg" inFolder:self.roomId]; if (cacheFilePath) { if (tmpCachedAttachments == nil) { tmpCachedAttachments = [NSMutableArray array]; @@ -2900,12 +2905,12 @@ NSString *const kCmdResetUserPowerLevel = @"/deop"; // use the generated info dict to retrieve useful data NSMutableDictionary *infoDict = [localEvent.content valueForKey:@"info"]; - NSData *imageData = [NSData dataWithContentsOfFile:[MediaManager cachePathForMediaURL:[localEvent.content valueForKey:@"url"] andType:[infoDict objectForKey:@"mimetype"]]]; + NSData *imageData = [NSData dataWithContentsOfFile:[MediaManager cachePathForMediaURL:[localEvent.content valueForKey:@"url"] andType:[infoDict objectForKey:@"mimetype"] inFolder:self.roomId]]; // Upload data - MediaLoader *mediaLoader = [MediaManager prepareUploaderWithId:localEvent.eventId initialRange:0 andRange:1.0]; + MediaLoader *mediaLoader = [MediaManager prepareUploaderWithId:localEvent.eventId initialRange:0 andRange:1.0 inFolder:self.roomId]; [mediaLoader uploadData:imageData mimeType:[infoDict objectForKey:@"mimetype"] success:^(NSString *url) { - [MediaManager removeUploaderWithId:localEvent.eventId]; + [MediaManager removeUploaderWithId:localEvent.eventId inFolder:self.roomId]; NSMutableDictionary *imageMessage = [[NSMutableDictionary alloc] init]; [imageMessage setValue:kMXMessageTypeImage forKey:@"msgtype"]; @@ -2915,7 +2920,7 @@ NSString *const kCmdResetUserPowerLevel = @"/deop"; // Send message for this attachment [self sendMessage:imageMessage withLocalEvent:localEvent]; } failure:^(NSError *error) { - [MediaManager removeUploaderWithId:localEvent.eventId]; + [MediaManager removeUploaderWithId:localEvent.eventId inFolder:self.roomId]; NSLog(@"Failed to upload image: %@", error); [self handleError:error forLocalEvent:localEvent]; }]; @@ -2955,6 +2960,7 @@ NSString *const kCmdResetUserPowerLevel = @"/deop"; self.imageValidationView = [[CustomImageView alloc] initWithFrame:self.membersView.frame]; self.imageValidationView.stretchable = YES; self.imageValidationView.fullScreen = YES; + self.imageValidationView.mediaFolder = self.roomId; // the user validates the image [self.imageValidationView setRightButtonTitle:@"OK" handler:^(CustomImageView* imageView, NSString* buttonTitle) { diff --git a/matrixConsole/matrixConsole/ViewController/SettingsViewController.m b/matrixConsole/matrixConsole/ViewController/SettingsViewController.m index 0728208cf..992c660d2 100644 --- a/matrixConsole/matrixConsole/ViewController/SettingsViewController.m +++ b/matrixConsole/matrixConsole/ViewController/SettingsViewController.m @@ -374,7 +374,7 @@ NSString* const kCommandsDescriptionText = @"The following commands are availabl if (uploadedPictureURL == nil) { // Upload picture - MediaLoader *uploader = [[MediaLoader alloc] initWithUploadId:nil initialRange:0 andRange:1.0]; + MediaLoader *uploader = [[MediaLoader alloc] initWithUploadId:nil initialRange:0 andRange:1.0 folder:kMediaManagerThumbnailFolder]; [uploader uploadData:UIImageJPEGRepresentation([self.userPicture imageForState:UIControlStateNormal], 0.5) mimeType:@"image/jpeg" success:^(NSString *url) { // Store uploaded picture url and trigger picture saving uploadedPictureURL = url; @@ -461,14 +461,14 @@ NSString* const kCommandsDescriptionText = @"The following commands are availabl currentPictureThumbURL = [mxHandler thumbnailURLForContent:currentPictureURL inViewSize:self.userPicture.frame.size withMethod:MXThumbnailingMethodCrop]; // Check whether the image download is in progress - id loader = [MediaManager existingDownloaderForURL:currentPictureThumbURL]; + id loader = [MediaManager existingDownloaderForURL:currentPictureThumbURL inFolder:kMediaManagerThumbnailFolder]; if (loader) { // Add observers [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onMediaDownloadEnd:) name:kMediaDownloadDidFinishNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onMediaDownloadEnd:) name:kMediaDownloadDidFailNotification object:nil]; } else { // Retrieve the image from cache - UIImage* image = [MediaManager loadCachePictureForURL:currentPictureThumbURL]; + UIImage* image = [MediaManager loadCachePictureForURL:currentPictureThumbURL inFolder:kMediaManagerThumbnailFolder]; if (image) { [self updateAvatarImage:image]; } else { @@ -479,7 +479,7 @@ NSString* const kCommandsDescriptionText = @"The following commands are availabl // Add observers [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onMediaDownloadEnd:) name:kMediaDownloadDidFinishNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onMediaDownloadEnd:) name:kMediaDownloadDidFailNotification object:nil]; - imageLoader = [MediaManager downloadMediaFromURL:currentPictureThumbURL withType:@"image/jpeg"]; + imageLoader = [MediaManager downloadMediaFromURL:currentPictureThumbURL withType:@"image/jpeg" inFolder:kMediaManagerThumbnailFolder]; } } } else { @@ -496,7 +496,7 @@ NSString* const kCommandsDescriptionText = @"The following commands are availabl if ([url isEqualToString:currentPictureThumbURL]) { // update the image - UIImage* image = [MediaManager loadCachePictureForURL:currentPictureThumbURL]; + UIImage* image = [MediaManager loadCachePictureForURL:currentPictureThumbURL inFolder:kMediaManagerThumbnailFolder]; if (image == nil) { image = [UIImage imageNamed:@"default-profile"]; }