diff --git a/Signal/src/ViewControllers/MediaGalleryViewController.swift b/Signal/src/ViewControllers/MediaGalleryViewController.swift index 903511ead..10b94da74 100644 --- a/Signal/src/ViewControllers/MediaGalleryViewController.swift +++ b/Signal/src/ViewControllers/MediaGalleryViewController.swift @@ -33,13 +33,9 @@ public struct MediaGalleryItem: Equatable, Hashable { return attachmentStream.isImage() } - var thumbnailImage: UIImage { - guard let image = attachmentStream.thumbnailImage() else { - owsFail("\(logTag) in \(#function) unexpectedly unable to build attachment thumbnail") - return UIImage() - } - - return image + public typealias AsyncThumbnailBlock = (UIImage) -> Void + func thumbnailImage(async:@escaping AsyncThumbnailBlock) -> UIImage? { + return attachmentStream.thumbnailImageSmall(completion: async) } var fullSizedImage: UIImage { diff --git a/Signal/src/ViewControllers/MediaTileViewController.swift b/Signal/src/ViewControllers/MediaTileViewController.swift index 33cb6adbd..dd94ae094 100644 --- a/Signal/src/ViewControllers/MediaTileViewController.swift +++ b/Signal/src/ViewControllers/MediaTileViewController.swift @@ -922,7 +922,24 @@ private class MediaGalleryCell: UICollectionViewCell { public func configure(item: MediaGalleryItem) { self.item = item - self.imageView.image = item.thumbnailImage + if let image = item.thumbnailImage(async: { + [weak self] (image) in + guard let strongSelf = self else { + return + } + guard strongSelf.item == item else { + return + } + strongSelf.imageView.image = image + strongSelf.imageView.backgroundColor = UIColor.clear + }) { + self.imageView.image = image + self.imageView.backgroundColor = UIColor.clear + } else { + // TODO: Show a placeholder? + self.imageView.backgroundColor = Theme.offBackgroundColor + } + if item.isVideo { self.contentTypeBadgeView.isHidden = false self.contentTypeBadgeView.image = MediaGalleryCell.videoBadgeImage diff --git a/Signal/src/util/OWSOrphanDataCleaner.m b/Signal/src/util/OWSOrphanDataCleaner.m index a70b10d4c..1773450a5 100644 --- a/Signal/src/util/OWSOrphanDataCleaner.m +++ b/Signal/src/util/OWSOrphanDataCleaner.m @@ -323,7 +323,7 @@ typedef void (^OrphanDataBlock)(OWSOrphanData *); OWSFail(@"%@ attachment has no file path.", self.logTag); } - NSString *_Nullable thumbnailPath = [attachmentStream thumbnailPath]; + NSString *_Nullable thumbnailPath = [attachmentStream legacyThumbnailPath]; if (thumbnailPath.length > 0) { [allAttachmentFilePaths addObject:thumbnailPath]; } diff --git a/SignalMessaging/ViewModels/OWSQuotedReplyModel.m b/SignalMessaging/ViewModels/OWSQuotedReplyModel.m index 6c355c348..e48b83ccc 100644 --- a/SignalMessaging/ViewModels/OWSQuotedReplyModel.m +++ b/SignalMessaging/ViewModels/OWSQuotedReplyModel.m @@ -227,7 +227,7 @@ NS_ASSUME_NONNULL_BEGIN authorId:authorId body:quotedText bodySource:TSQuotedMessageContentSourceLocal - thumbnailImage:quotedAttachment.thumbnailImage + thumbnailImage:quotedAttachment.legacyThumbnailImage contentType:quotedAttachment.contentType sourceFilename:quotedAttachment.sourceFilename attachmentStream:quotedAttachment diff --git a/SignalServiceKit/src/Messages/Attachments/OWSThumbnailService.swift b/SignalServiceKit/src/Messages/Attachments/OWSThumbnailService.swift index f18f7af99..97aaac571 100644 --- a/SignalServiceKit/src/Messages/Attachments/OWSThumbnailService.swift +++ b/SignalServiceKit/src/Messages/Attachments/OWSThumbnailService.swift @@ -142,17 +142,17 @@ private struct OWSThumbnailRequest { var thumbnailSize = CGSize.zero if originalSize.width > originalSize.height { thumbnailSize.width = CGFloat(thumbnailRequest.thumbnailDimensionPoints) - thumbnailSize.height = round(CGFloat(thumbnailRequest.thumbnailDimensionPoints) * thumbnailSize.height / thumbnailSize.width) + thumbnailSize.height = round(CGFloat(thumbnailRequest.thumbnailDimensionPoints) * originalSize.height / originalSize.width) } else { - thumbnailSize.width = round(CGFloat(thumbnailRequest.thumbnailDimensionPoints) * thumbnailSize.width / thumbnailSize.height) + thumbnailSize.width = round(CGFloat(thumbnailRequest.thumbnailDimensionPoints) * originalSize.width / originalSize.height) thumbnailSize.height = CGFloat(thumbnailRequest.thumbnailDimensionPoints) } guard thumbnailSize.width > 0 && thumbnailSize.height > 0 else { owsFail("Thumbnail has invalid size.") return nil } - guard originalSize.width < thumbnailSize.width && - originalSize.height < thumbnailSize.height else { + guard originalSize.width > thumbnailSize.width && + originalSize.height > thumbnailSize.height else { owsFail("Thumbnail isn't smaller than the original.") return nil } diff --git a/SignalServiceKit/src/Messages/Attachments/TSAttachmentStream.h b/SignalServiceKit/src/Messages/Attachments/TSAttachmentStream.h index 649d9cfc4..66e908663 100644 --- a/SignalServiceKit/src/Messages/Attachments/TSAttachmentStream.h +++ b/SignalServiceKit/src/Messages/Attachments/TSAttachmentStream.h @@ -67,9 +67,9 @@ typedef void (^OWSThumbnailCompletion)(UIImage *image); - (nullable NSURL *)originalMediaURL; // TODO: Rename to legacy... -- (nullable UIImage *)thumbnailImage; -- (nullable NSData *)thumbnailData; -- (nullable NSString *)thumbnailPath; +- (nullable UIImage *)legacyThumbnailImage; +//- (nullable NSData *)legacyThumbnailData; +- (nullable NSString *)legacyThumbnailPath; + (BOOL)hasThumbnailForMimeType:(NSString *)contentType; diff --git a/SignalServiceKit/src/Messages/Attachments/TSAttachmentStream.m b/SignalServiceKit/src/Messages/Attachments/TSAttachmentStream.m index 8f449d780..99fe956b9 100644 --- a/SignalServiceKit/src/Messages/Attachments/TSAttachmentStream.m +++ b/SignalServiceKit/src/Messages/Attachments/TSAttachmentStream.m @@ -16,7 +16,7 @@ NS_ASSUME_NONNULL_BEGIN const CGFloat kMaxVideoStillSize = 1 * 1024; -const NSUInteger kThumbnailDimensionPointsSmall = 200; +const NSUInteger kThumbnailDimensionPointsSmall = 300; const NSUInteger kThumbnailDimensionPointsMedium = 800; // This size is large enough to render full screen. const NSUInteger ThumbnailDimensionPointsLarge() { @@ -129,7 +129,7 @@ const NSUInteger ThumbnailDimensionPointsLarge() { } // This is going to be slow the first time it runs. - [self ensureThumbnail]; + [self ensureLegacyThumbnail]; return self; } @@ -137,7 +137,7 @@ const NSUInteger ThumbnailDimensionPointsLarge() { - (void)saveWithTransaction:(YapDatabaseReadWriteTransaction *)transaction { [super saveWithTransaction:transaction]; - [self ensureThumbnail]; + [self ensureLegacyThumbnail]; } - (void)upgradeFromAttachmentSchemaVersion:(NSUInteger)attachmentSchemaVersion @@ -271,7 +271,7 @@ const NSUInteger ThumbnailDimensionPointsLarge() { return [[[self class] attachmentsFolder] stringByAppendingPathComponent:self.localRelativeFilePath]; } -- (nullable NSString *)thumbnailPath +- (nullable NSString *)legacyThumbnailPath { NSString *filePath = self.originalFilePath; if (!filePath) { @@ -326,9 +326,9 @@ const NSUInteger ThumbnailDimensionPointsLarge() { } } - NSString *_Nullable thumbnailPath = self.thumbnailPath; - if (thumbnailPath) { - BOOL success = [[NSFileManager defaultManager] removeItemAtPath:thumbnailPath error:&error]; + NSString *_Nullable legacyThumbnailPath = self.legacyThumbnailPath; + if (legacyThumbnailPath) { + BOOL success = [[NSFileManager defaultManager] removeItemAtPath:legacyThumbnailPath error:&error]; if (error || !success) { DDLogError(@"%@ remove legacy thumbnail failed with: %@", self.logTag, error); @@ -429,28 +429,9 @@ const NSUInteger ThumbnailDimensionPointsLarge() { [MIMETypeUtil isAnimated:contentType]); } -- (nullable UIImage *)thumbnailImage +- (nullable NSData *)legacyThumbnailData { - NSString *thumbnailPath = self.thumbnailPath; - if (!thumbnailPath) { - OWSAssert(!self.isImage && !self.isVideo && !self.isAnimated); - - return nil; - } - - if (![[NSFileManager defaultManager] fileExistsAtPath:thumbnailPath]) { - // This isn't true for some useful edge cases tested by the Debug UI. - DDLogError(@"%@ missing thumbnail for attachmentId: %@", self.logTag, self.uniqueId); - - return nil; - } - - return [UIImage imageWithContentsOfFile:self.thumbnailPath]; -} - -- (nullable NSData *)thumbnailData -{ - NSString *thumbnailPath = self.thumbnailPath; + NSString *thumbnailPath = self.legacyThumbnailPath; if (!thumbnailPath) { OWSAssert(!self.isImage && !self.isVideo && !self.isAnimated); @@ -463,12 +444,12 @@ const NSUInteger ThumbnailDimensionPointsLarge() { return nil; } - return [NSData dataWithContentsOfFile:self.thumbnailPath]; + return [NSData dataWithContentsOfFile:thumbnailPath]; } -- (void)ensureThumbnail +- (void)ensureLegacyThumbnail { - NSString *thumbnailPath = self.thumbnailPath; + NSString *thumbnailPath = self.legacyThumbnailPath; if (!thumbnailPath) { return; } @@ -877,7 +858,7 @@ const NSUInteger ThumbnailDimensionPointsLarge() { - (nullable TSAttachmentStream *)cloneAsThumbnail { - NSData *thumbnailData = self.thumbnailData; + NSData *thumbnailData = self.legacyThumbnailData; // Only some media types have thumbnails if (!thumbnailData) { return nil;