--> 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.
This commit is contained in:
ylecollen 2015-01-19 14:33:57 +01:00
parent ed4dc310aa
commit 5d2e3862bf
11 changed files with 216 additions and 74 deletions

View file

@ -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

View file

@ -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];

View file

@ -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;

View file

@ -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);

View file

@ -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;

View file

@ -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;
}

View file

@ -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

View file

@ -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];

View file

@ -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"];
}

View file

@ -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) {

View file

@ -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"];
}