MediaBrowserFile.m 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. // _____ _
  2. // |_ _| |_ _ _ ___ ___ _ __ __ _
  3. // | | | ' \| '_/ -_) -_) ' \/ _` |_
  4. // |_| |_||_|_| \___\___|_|_|_\__,_(_)
  5. //
  6. // Threema iOS Client
  7. // Copyright (c) 2016-2020 Threema GmbH
  8. //
  9. // This program is free software: you can redistribute it and/or modify
  10. // it under the terms of the GNU Affero General Public License, version 3,
  11. // as published by the Free Software Foundation.
  12. //
  13. // This program is distributed in the hope that it will be useful,
  14. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. // GNU Affero General Public License for more details.
  17. //
  18. // You should have received a copy of the GNU Affero General Public License
  19. // along with this program. If not, see <https://www.gnu.org/licenses/>.
  20. #import "MediaBrowserFile.h"
  21. #import "ImageData.h"
  22. #import "FileMessagePreview.h"
  23. #import "AnimGifMessageLoader.h"
  24. #import "UIImage+ColoredImage.h"
  25. #import "Utils.h"
  26. #import "UTIConverter.h"
  27. @interface MediaBrowserFile ()
  28. @property FileMessage *fileMessage;
  29. @end
  30. @implementation MediaBrowserFile
  31. @synthesize underlyingImage = _underlyingImage; // synth property from protocol
  32. + (instancetype)fileWithFileMessage:(FileMessage *)fileMessage thumbnail:(BOOL)forThumbnail {
  33. MediaBrowserFile *file = [[self alloc] initWithFileMessage:fileMessage thumbnail:forThumbnail];
  34. return file;
  35. }
  36. - (instancetype)initWithFileMessage:(FileMessage *)fileMessage thumbnail:(BOOL)forThumbnail
  37. {
  38. self = [super init];
  39. if (self) {
  40. _fileMessage = fileMessage;
  41. BOOL isRenderingFileMessage = false;
  42. if (_fileMessage.data != nil) {
  43. if (_fileMessage.data.data != nil) {
  44. if ([_fileMessage renderFileImageMessage] == true) {
  45. isRenderingFileMessage = true;
  46. }
  47. }
  48. }
  49. if (isRenderingFileMessage == true) {
  50. _isUtiPreview = false;
  51. _underlyingImage = [[UIImage alloc] initWithData:_fileMessage.data.data];
  52. }
  53. else {
  54. UIImage *thumbnail = [FileMessagePreview thumbnailForFileMessage:fileMessage];
  55. _isUtiPreview = !fileMessage.thumbnail;
  56. if (fileMessage.thumbnail == nil) {
  57. UIImage *colorizedThumbnail = [thumbnail imageWithTint:[Colors white]];
  58. _underlyingImage = colorizedThumbnail;
  59. } else {
  60. if ([UTIConverter isGifMimeType:fileMessage.mimeType]) {
  61. thumbnail = [Utils makeThumbWithOverlayFor:thumbnail];
  62. }
  63. _underlyingImage = thumbnail;
  64. }
  65. }
  66. }
  67. return self;
  68. }
  69. - (BOOL)isVideo {
  70. if ([_fileMessage renderFileVideoMessage] == true) {
  71. return true;
  72. }
  73. return false;
  74. }
  75. - (UIImage *)padImage:(UIImage *)image toSize:(CGSize)size {
  76. UIGraphicsBeginImageContext(size);
  77. CGFloat x = (size.width - image.size.width)/2.0;
  78. CGFloat y = (size.height - image.size.height)/2.0;
  79. [image drawInRect:CGRectMake(x, y, image.size.width, image.size.height) blendMode:kCGBlendModeNormal alpha:0.8];
  80. UIImage *resultImage = UIGraphicsGetImageFromCurrentImageContext();
  81. UIGraphicsEndImageContext();
  82. return resultImage;
  83. }
  84. - (id)sourceReference {
  85. return _fileMessage;
  86. }
  87. #pragma mark - MWPhoto Protocol Methods
  88. -(BOOL)showControls {
  89. return YES;
  90. }
  91. -(void)handleSingleTap:(CGPoint)touchPoint {
  92. if (_fileMessage.data != nil) {
  93. if ([_fileMessage renderFileImageMessage] == true) {
  94. [_delegate toggleControls];
  95. }
  96. else if ([_fileMessage renderFileVideoMessage] == true) {
  97. [self play];
  98. }
  99. else {
  100. [_delegate showFile: _fileMessage];
  101. }
  102. } else {
  103. [self loadUnderlyingImageAndNotify];
  104. }
  105. }
  106. - (void)play {
  107. if (_delegate) {
  108. [_delegate playFileVideo: _fileMessage];
  109. }
  110. }
  111. -(BOOL)canScaleImage {
  112. if ([_fileMessage renderFileImageMessage] == true) {
  113. return true;
  114. }
  115. return NO;
  116. }
  117. -(NSURL *)urlForExportData:(NSString *)tmpFileName {
  118. if (_fileMessage == nil || _fileMessage.data == nil) {
  119. return nil;
  120. }
  121. NSURL *url = [_fileMessage tmpURL:tmpFileName];
  122. [_fileMessage exportDataToURL:url];
  123. return url;
  124. }
  125. - (UIImage *)underlyingImage {
  126. return _underlyingImage;
  127. }
  128. - (void)loadUnderlyingImageAndNotify {
  129. // loaded already
  130. if (_fileMessage.data != nil) {
  131. return;
  132. }
  133. // loading
  134. if (_fileMessage.progress != nil) {
  135. return;
  136. }
  137. [self performLoadUnderlyingImageAndNotify];
  138. }
  139. - (void)performLoadUnderlyingImageAndNotify {
  140. BlobMessageLoader *loader;
  141. if ([UTIConverter isGifMimeType:_fileMessage.mimeType]) {
  142. loader = [[AnimGifMessageLoader alloc] init];
  143. } else {
  144. loader = [[BlobMessageLoader alloc] init];
  145. }
  146. [loader startWithMessage:_fileMessage onCompletion:^(BaseMessage *message) {
  147. [self postCompleteNotification];
  148. } onError:^(NSError *error) {
  149. [self postCompleteNotification];
  150. }];
  151. }
  152. - (void)postCompleteNotification {
  153. [[NSNotificationCenter defaultCenter] postNotificationName:MWPHOTO_LOADING_DID_END_NOTIFICATION object:self];
  154. }
  155. - (void)unloadUnderlyingImage {
  156. _underlyingImage = nil;
  157. }
  158. - (void)cancelAnyLoading {
  159. }
  160. - (void)getVideoURL:(void (^)(NSURL *))completion {
  161. completion([self urlForExportData:@"video"]);
  162. }
  163. - (NSString *)accessibilityLabelForContent {
  164. NSString *date = [DateFormatter accessibilityDateTime:_fileMessage.remoteSentDate];
  165. return [NSString stringWithFormat:@"%@. %@", NSLocalizedString(@"file", nil), date];
  166. }
  167. @end