From f041a7df2ec8d7db804cd6ec3f401c13dc389951 Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Thu, 16 Jul 2020 17:07:16 +0300 Subject: [PATCH 1/4] Video avatar fixes --- .../LegacyComponents/TGVideoEditAdjustments.h | 2 +- .../Sources/TGAttachmentCarouselItemView.m | 32 +++++++++- .../Sources/TGCameraController.m | 2 +- .../Sources/TGMediaAssetsController.m | 2 +- .../Sources/TGMediaAssetsPickerController.m | 29 ++++++++- .../Sources/TGPhotoEditorController.m | 7 ++- .../Sources/TGPhotoPaintController.m | 6 +- .../Sources/TGVideoEditAdjustments.m | 4 +- .../Sources/PeerInfo/PeerInfoScreen.swift | 61 ------------------- .../Sources/LegacyWebSearchGallery.swift | 2 +- 10 files changed, 71 insertions(+), 76 deletions(-) diff --git a/submodules/LegacyComponents/PublicHeaders/LegacyComponents/TGVideoEditAdjustments.h b/submodules/LegacyComponents/PublicHeaders/LegacyComponents/TGVideoEditAdjustments.h index 0c426975f8..32dcbcc3a9 100644 --- a/submodules/LegacyComponents/PublicHeaders/LegacyComponents/TGVideoEditAdjustments.h +++ b/submodules/LegacyComponents/PublicHeaders/LegacyComponents/TGVideoEditAdjustments.h @@ -37,7 +37,7 @@ typedef enum - (instancetype)editAdjustmentsWithPreset:(TGMediaVideoConversionPreset)preset maxDuration:(NSTimeInterval)maxDuration; - (instancetype)editAdjustmentsWithPreset:(TGMediaVideoConversionPreset)preset videoStartValue:(NSTimeInterval)videoStartValue trimStartValue:(NSTimeInterval)trimStartValue trimEndValue:(NSTimeInterval)trimEndValue; + (instancetype)editAdjustmentsWithOriginalSize:(CGSize)originalSize preset:(TGMediaVideoConversionPreset)preset; -+ (instancetype)editAdjustmentsWithPhotoEditorValues:(PGPhotoEditorValues *)values; ++ (instancetype)editAdjustmentsWithPhotoEditorValues:(PGPhotoEditorValues *)values preset:(TGMediaVideoConversionPreset)preset; + (instancetype)editAdjustmentsWithDictionary:(NSDictionary *)dictionary; + (instancetype)editAdjustmentsWithOriginalSize:(CGSize)originalSize diff --git a/submodules/LegacyComponents/Sources/TGAttachmentCarouselItemView.m b/submodules/LegacyComponents/Sources/TGAttachmentCarouselItemView.m index d1f45ee224..37da1a71a1 100644 --- a/submodules/LegacyComponents/Sources/TGAttachmentCarouselItemView.m +++ b/submodules/LegacyComponents/Sources/TGAttachmentCarouselItemView.m @@ -898,7 +898,7 @@ const NSUInteger TGAttachmentDisplayedAssetLimit = 500; }; __weak TGPhotoEditorController *weakController = controller; - controller.didFinishEditing = ^(__unused id adjustments, UIImage *resultImage, __unused UIImage *thumbnailImage, __unused bool hasChanges) + controller.didFinishEditing = ^(id adjustments, UIImage *resultImage, __unused UIImage *thumbnailImage, __unused bool hasChanges) { if (!hasChanges) return; @@ -911,8 +911,34 @@ const NSUInteger TGAttachmentDisplayedAssetLimit = 500; if (strongController == nil) return; - if (strongSelf.avatarCompletionBlock != nil) - strongSelf.avatarCompletionBlock(resultImage); + if (adjustments.paintingData.hasAnimation) { + TGVideoEditAdjustments *videoAdjustments = adjustments; + if ([videoAdjustments isKindOfClass:[PGPhotoEditorValues class]]) { + videoAdjustments = [TGVideoEditAdjustments editAdjustmentsWithPhotoEditorValues:(PGPhotoEditorValues *)adjustments preset:TGMediaVideoConversionPresetProfileVeryHigh]; + } + + NSString *filePath = [NSTemporaryDirectory() stringByAppendingPathComponent:[[NSString alloc] initWithFormat:@"gifvideo_%x.jpg", (int)arc4random()]]; + NSData *data = UIImageJPEGRepresentation(resultImage, 0.8); + [data writeToFile:filePath atomically:true]; + + UIImage *previewImage = resultImage; + if ([adjustments cropAppliedForAvatar:false] || adjustments.hasPainting || adjustments.toolsApplied) + { + UIImage *paintingImage = adjustments.paintingData.stillImage; + if (paintingImage == nil) { + paintingImage = adjustments.paintingData.image; + } + UIImage *thumbnailImage = TGPhotoEditorVideoExtCrop(resultImage, paintingImage, adjustments.cropOrientation, adjustments.cropRotation, adjustments.cropRect, adjustments.cropMirrored, TGScaleToFill(asset.dimensions, CGSizeMake(800, 800)), adjustments.originalSize, true, true, true); + if (thumbnailImage != nil) { + previewImage = thumbnailImage; + } + } + if (strongSelf.avatarVideoCompletionBlock != nil) + strongSelf.avatarVideoCompletionBlock(previewImage, [NSURL fileURLWithPath:filePath], videoAdjustments); + } else { + if (strongSelf.avatarCompletionBlock != nil) + strongSelf.avatarCompletionBlock(resultImage); + } }; controller.didFinishEditingVideo = ^(AVAsset *asset, id adjustments, UIImage *resultImage, UIImage *thumbnailImage, bool hasChanges) { if (!hasChanges) diff --git a/submodules/LegacyComponents/Sources/TGCameraController.m b/submodules/LegacyComponents/Sources/TGCameraController.m index 8a7e0e8f45..638153c61f 100644 --- a/submodules/LegacyComponents/Sources/TGCameraController.m +++ b/submodules/LegacyComponents/Sources/TGCameraController.m @@ -2592,7 +2592,7 @@ static CGPoint TGCameraControllerClampPointToScreenSize(__unused id self, __unus if (animated) { dict[@"isAnimation"] = @true; if ([adjustments isKindOfClass:[PGPhotoEditorValues class]]) { - dict[@"adjustments"] = [TGVideoEditAdjustments editAdjustmentsWithPhotoEditorValues:(PGPhotoEditorValues *)adjustments]; + dict[@"adjustments"] = [TGVideoEditAdjustments editAdjustmentsWithPhotoEditorValues:(PGPhotoEditorValues *)adjustments preset:TGMediaVideoConversionPresetAnimation]; } else { dict[@"adjustments"] = adjustments; } diff --git a/submodules/LegacyComponents/Sources/TGMediaAssetsController.m b/submodules/LegacyComponents/Sources/TGMediaAssetsController.m index 87202ef3e0..7c295a7652 100644 --- a/submodules/LegacyComponents/Sources/TGMediaAssetsController.m +++ b/submodules/LegacyComponents/Sources/TGMediaAssetsController.m @@ -904,7 +904,7 @@ if (animated) { dict[@"isAnimation"] = @true; if ([adjustments isKindOfClass:[PGPhotoEditorValues class]]) { - dict[@"adjustments"] = [TGVideoEditAdjustments editAdjustmentsWithPhotoEditorValues:(PGPhotoEditorValues *)adjustments]; + dict[@"adjustments"] = [TGVideoEditAdjustments editAdjustmentsWithPhotoEditorValues:(PGPhotoEditorValues *)adjustments preset:TGMediaVideoConversionPresetAnimation]; } else { dict[@"adjustments"] = adjustments; } diff --git a/submodules/LegacyComponents/Sources/TGMediaAssetsPickerController.m b/submodules/LegacyComponents/Sources/TGMediaAssetsPickerController.m index 2408a9916d..f885339c4e 100644 --- a/submodules/LegacyComponents/Sources/TGMediaAssetsPickerController.m +++ b/submodules/LegacyComponents/Sources/TGMediaAssetsPickerController.m @@ -415,7 +415,7 @@ [[strongSelf->_assetsLibrary saveAssetWithImage:resultImage] startWithNext:nil]; }; - controller.didFinishEditing = ^(__unused id adjustments, UIImage *resultImage, __unused UIImage *thumbnailImage, bool hasChanges) + controller.didFinishEditing = ^(id adjustments, UIImage *resultImage, __unused UIImage *thumbnailImage, bool hasChanges) { if (!hasChanges) return; @@ -424,7 +424,32 @@ if (strongSelf == nil) return; - [(TGMediaAssetsController *)strongSelf.navigationController completeWithAvatarImage:resultImage]; + if (adjustments.paintingData.hasAnimation) { + TGVideoEditAdjustments *videoAdjustments = adjustments; + if ([videoAdjustments isKindOfClass:[PGPhotoEditorValues class]]) { + videoAdjustments = [TGVideoEditAdjustments editAdjustmentsWithPhotoEditorValues:(PGPhotoEditorValues *)adjustments preset:TGMediaVideoConversionPresetProfileVeryHigh]; + } + + NSString *filePath = [NSTemporaryDirectory() stringByAppendingPathComponent:[[NSString alloc] initWithFormat:@"gifvideo_%x.jpg", (int)arc4random()]]; + NSData *data = UIImageJPEGRepresentation(resultImage, 0.8); + [data writeToFile:filePath atomically:true]; + + UIImage *previewImage = resultImage; + if ([adjustments cropAppliedForAvatar:false] || adjustments.hasPainting || adjustments.toolsApplied) + { + UIImage *paintingImage = adjustments.paintingData.stillImage; + if (paintingImage == nil) { + paintingImage = adjustments.paintingData.image; + } + UIImage *thumbnailImage = TGPhotoEditorVideoExtCrop(resultImage, paintingImage, adjustments.cropOrientation, adjustments.cropRotation, adjustments.cropRect, adjustments.cropMirrored, TGScaleToFill(asset.dimensions, CGSizeMake(800, 800)), adjustments.originalSize, true, true, true); + if (thumbnailImage != nil) { + previewImage = thumbnailImage; + } + } + [(TGMediaAssetsController *)strongSelf.navigationController completeWithAvatarVideo:[NSURL fileURLWithPath:filePath] adjustments:videoAdjustments image:previewImage]; + } else { + [(TGMediaAssetsController *)strongSelf.navigationController completeWithAvatarImage:resultImage]; + } }; controller.didFinishEditingVideo = ^(AVAsset *asset, id adjustments, UIImage *resultImage, UIImage *thumbnailImage, bool hasChanges) { if (!hasChanges) diff --git a/submodules/LegacyComponents/Sources/TGPhotoEditorController.m b/submodules/LegacyComponents/Sources/TGPhotoEditorController.m index 5ab940f53d..52a42133d0 100644 --- a/submodules/LegacyComponents/Sources/TGPhotoEditorController.m +++ b/submodules/LegacyComponents/Sources/TGPhotoEditorController.m @@ -1061,8 +1061,13 @@ UIImage *image = result[@"image"]; UIImage *thumbnailImage = result[@"thumbnail"]; - if (avatar && completion != nil) + if (avatar && image.size.width < 150.0) { + image = TGScaleImageToPixelSize(image, CGSizeMake(150.0, 150.0)); + } + + if (avatar && completion != nil) { completion(image); + } if (!saveOnly && didFinishEditing != nil) didFinishEditing(editorValues, image, thumbnailImage, true); diff --git a/submodules/LegacyComponents/Sources/TGPhotoPaintController.m b/submodules/LegacyComponents/Sources/TGPhotoPaintController.m index 8ea03393d0..05fc3583a3 100644 --- a/submodules/LegacyComponents/Sources/TGPhotoPaintController.m +++ b/submodules/LegacyComponents/Sources/TGPhotoPaintController.m @@ -1900,6 +1900,8 @@ const CGFloat TGPhotoPaintStickerKeyboardSize = 260.0f; - (void)transitionOutSwitching:(bool)__unused switching completion:(void (^)(void))completion { + [_stickersScreen invalidate]; + TGPhotoEditorPreviewView *previewView = self.previewView; previewView.interactionEnded = nil; @@ -1931,9 +1933,7 @@ const CGFloat TGPhotoPaintStickerKeyboardSize = 260.0f; - (void)_animatePreviewViewTransitionOutToFrame:(CGRect)targetFrame saving:(bool)saving parentView:(UIView *)parentView completion:(void (^)(void))completion { _dismissing = true; - - [_stickersScreen invalidate]; - + [_entitySelectionView removeFromSuperview]; _entitySelectionView = nil; diff --git a/submodules/LegacyComponents/Sources/TGVideoEditAdjustments.m b/submodules/LegacyComponents/Sources/TGVideoEditAdjustments.m index abd845c063..f6b96bb53d 100644 --- a/submodules/LegacyComponents/Sources/TGVideoEditAdjustments.m +++ b/submodules/LegacyComponents/Sources/TGVideoEditAdjustments.m @@ -136,7 +136,7 @@ const NSTimeInterval TGVideoEditMaximumGifDuration = 30.5; return adjustments; } -+ (instancetype)editAdjustmentsWithPhotoEditorValues:(PGPhotoEditorValues *)values { ++ (instancetype)editAdjustmentsWithPhotoEditorValues:(PGPhotoEditorValues *)values preset:(TGMediaVideoConversionPreset)preset { TGVideoEditAdjustments *adjustments = [[[self class] alloc] init]; adjustments->_originalSize = values.originalSize; CGRect cropRect = values.cropRect; @@ -150,7 +150,7 @@ const NSTimeInterval TGVideoEditMaximumGifDuration = 30.5; adjustments->_cropMirrored = values.cropMirrored; adjustments->_paintingData = [values.paintingData dataForAnimation]; adjustments->_sendAsGif = true; - adjustments->_preset = TGMediaVideoConversionPresetAnimation; + adjustments->_preset = preset; return adjustments; } diff --git a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift index 5d590a8832..107878889b 100644 --- a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift +++ b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift @@ -3846,68 +3846,7 @@ private final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewD } } } - - private func editAvatarItem(_ item: PeerInfoAvatarListItem) { - guard case let .image(reference, representations, videoRepresentations, _) = item else { - return - } - let mediaReference: AnyMediaReference - if let video = videoRepresentations.last { - mediaReference = .standalone(media: TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: 0), partialReference: nil, resource: video.representation.resource, previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: "video/mp4", size: nil, attributes: [.Animated, .Video(duration: 0, size: video.representation.dimensions, flags: [])])) - } else { - let media = TelegramMediaImage(imageId: MediaId(namespace: 0, id: 0), representations: representations.map({ $0.representation }), immediateThumbnailData: nil, reference: nil, partialReference: nil, flags: []) - mediaReference = .standalone(media: media) - } - - var dismissStatus: (() -> Void)? - let statusController = OverlayStatusController(theme: self.presentationData.theme, type: .loading(cancelled: { - dismissStatus?() - })) - dismissStatus = { [weak self, weak statusController] in - self?.editAvatarDisposable.set(nil) - statusController?.dismiss() - } - self.controller?.present(statusController, in: .window(.root)) - - self.editAvatarDisposable.set((fetchMediaData(context: self.context, postbox: self.context.account.postbox, mediaReference: mediaReference) - |> deliverOnMainQueue).start(next: { [weak self] state, isImage in - guard let strongSelf = self else { - return - } - switch state { - case .progress: - break - case let .data(data): - dismissStatus?() - - let image: UIImage? - let video: URL? - if isImage { - if let fileData = try? Data(contentsOf: URL(fileURLWithPath: data.path)) { - image = UIImage(data: fileData) - } else { - image = nil - } - video = nil - } else { - image = nil - video = URL(fileURLWithPath: data.path) - } - -// presentLegacyAvatarEditor(theme: strongSelf.presentationData.theme, image: image, video: video, present: { [weak self] c, a in -// if let strongSelf = self { -// strongSelf.controller?.present(c, in: .window(.root), with: a, blockInteraction: true) -// } -// }, imageCompletion: { [weak self] image in -// self?.updateProfilePhoto(image) -// }, videoCompletion: { [weak self] image, url, adjustments in -// self?.updateProfileVideo(image, url: url, adjustments: adjustments) -// }) - } - })) - } - private func setMainAvatar(_ item: PeerInfoAvatarListItem) { if self.data?.peer?.id == self.context.account.peerId { if case let .image(reference, _, _, _) = item { diff --git a/submodules/WebSearchUI/Sources/LegacyWebSearchGallery.swift b/submodules/WebSearchUI/Sources/LegacyWebSearchGallery.swift index dbf1098e8f..99e7fab29a 100644 --- a/submodules/WebSearchUI/Sources/LegacyWebSearchGallery.swift +++ b/submodules/WebSearchUI/Sources/LegacyWebSearchGallery.swift @@ -443,7 +443,7 @@ public func legacyEnqueueWebSearchMessages(_ selectionState: TGMediaSelectionCon if animated { dict["isAnimation"] = true if let photoEditorValues = adjustments as? PGPhotoEditorValues { - dict["adjustments"] = TGVideoEditAdjustments(photoEditorValues: photoEditorValues) + dict["adjustments"] = TGVideoEditAdjustments(photoEditorValues: photoEditorValues, preset: TGMediaVideoConversionPresetAnimation) } let filePath = NSTemporaryDirectory().appending("/gifvideo_\(arc4random()).jpg") From ee64d32ccff8169a684ef09858ef78d55a6680f4 Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Thu, 16 Jul 2020 18:09:49 +0300 Subject: [PATCH 2/4] Video avatar fixes --- .../TGMediaPickerGalleryVideoItemView.m | 2 +- .../Sources/TGPhotoAvatarCropView.m | 13 ++++++-- .../Sources/TGPhotoEditorController.m | 3 +- .../Sources/TGPhotoPaintController.m | 8 ++++- .../Sources/TGPhotoToolsController.m | 33 +++++++++++++++++++ .../Sources/DrawingStickersScreen.swift | 1 - 6 files changed, 54 insertions(+), 6 deletions(-) diff --git a/submodules/LegacyComponents/Sources/TGMediaPickerGalleryVideoItemView.m b/submodules/LegacyComponents/Sources/TGMediaPickerGalleryVideoItemView.m index 7f8e0c90a0..4e8c6bcaea 100644 --- a/submodules/LegacyComponents/Sources/TGMediaPickerGalleryVideoItemView.m +++ b/submodules/LegacyComponents/Sources/TGMediaPickerGalleryVideoItemView.m @@ -800,7 +800,7 @@ CGRect fittedCropRect = [TGPhotoPaintController fittedCropRect:cropRect originalSize:originalSize keepOriginalSize:false]; _contentWrapperView.frame = CGRectMake(0.0f, 0.0f, fittedContentSize.width, fittedContentSize.height); - CGFloat contentScale = ratio;//_contentView.bounds.size.width / fittedCropRect.size.width; + CGFloat contentScale = ratio; _contentWrapperView.transform = CGAffineTransformMakeScale(contentScale, contentScale); _contentWrapperView.frame = CGRectMake(0.0f, 0.0f, _contentView.bounds.size.width, _contentView.bounds.size.height); diff --git a/submodules/LegacyComponents/Sources/TGPhotoAvatarCropView.m b/submodules/LegacyComponents/Sources/TGPhotoAvatarCropView.m index 7c8c1d69e0..ddc7a2d393 100644 --- a/submodules/LegacyComponents/Sources/TGPhotoAvatarCropView.m +++ b/submodules/LegacyComponents/Sources/TGPhotoAvatarCropView.m @@ -42,6 +42,8 @@ const CGFloat TGPhotoAvatarCropViewCurtainMargin = 200; CGFloat _currentDiameter; + UIView *_entitiesWrapperView; + __weak PGPhotoEditorView *_fullPreviewView; __weak UIImageView *_fullPaintingView; __weak TGPhotoEntitiesContainerView *_fullEntitiesView; @@ -91,9 +93,16 @@ const CGFloat TGPhotoAvatarCropViewCurtainMargin = 200; _fullPaintingView.frame = _fullPreviewView.frame; [_wrapperView addSubview:_fullPaintingView]; + _entitiesWrapperView = [[UIView alloc] init]; _fullEntitiesView = fullEntitiesView; - _fullEntitiesView.frame = _fullPreviewView.frame; - [_wrapperView addSubview:_fullEntitiesView]; + _fullEntitiesView.frame = CGRectMake(0.0, 0.0, _fullEntitiesView.frame.size.width, _fullEntitiesView.frame.size.height); + _entitiesWrapperView.frame = _fullEntitiesView.frame; + + CGFloat entitiesScale = _fullPreviewView.frame.size.width / _entitiesWrapperView.frame.size.width; + _entitiesWrapperView.transform = CGAffineTransformMakeScale(entitiesScale, entitiesScale); + _entitiesWrapperView.frame = _fullPreviewView.frame; + [_entitiesWrapperView addSubview:_fullEntitiesView]; + [_wrapperView addSubview:_entitiesWrapperView]; _flashView = [[UIView alloc] init]; _flashView.alpha = 0.0; diff --git a/submodules/LegacyComponents/Sources/TGPhotoEditorController.m b/submodules/LegacyComponents/Sources/TGPhotoEditorController.m index 52a42133d0..ed1d18f949 100644 --- a/submodules/LegacyComponents/Sources/TGPhotoEditorController.m +++ b/submodules/LegacyComponents/Sources/TGPhotoEditorController.m @@ -346,7 +346,8 @@ _fullEntitiesView = [[TGPhotoEntitiesContainerView alloc] init]; _fullEntitiesView.userInteractionEnabled = false; - _fullEntitiesView.frame = _fullPreviewView.frame; + CGRect rect = [TGPhotoPaintController fittedCropRect:_photoEditor.cropRect originalSize:_photoEditor.originalSize keepOriginalSize:true]; + _fullEntitiesView.frame = CGRectMake(0, 0, rect.size.width, rect.size.height); } _dotMarkerView = [[UIImageView alloc] initWithImage:TGCircleImage(7.0, [TGPhotoEditorInterfaceAssets accentColor])]; diff --git a/submodules/LegacyComponents/Sources/TGPhotoPaintController.m b/submodules/LegacyComponents/Sources/TGPhotoPaintController.m index 05fc3583a3..e554aef9a2 100644 --- a/submodules/LegacyComponents/Sources/TGPhotoPaintController.m +++ b/submodules/LegacyComponents/Sources/TGPhotoPaintController.m @@ -98,6 +98,7 @@ const CGFloat TGPhotoPaintStickerKeyboardSize = 260.0f; id _stickersScreen; bool _appeared; + bool _skipEntitiesSetup; TGPhotoPaintFont *_selectedTextFont; TGPhotoPaintTextEntityStyle _selectedTextStyle; @@ -152,6 +153,9 @@ const CGFloat TGPhotoPaintStickerKeyboardSize = 260.0f; self.photoEditor = photoEditor; self.previewView = previewView; _entitiesContainerView = entitiesView; + if (entitiesView != nil) { + _skipEntitiesSetup = true; + } entitiesView.userInteractionEnabled = true; _brushes = @ @@ -509,7 +513,9 @@ const CGFloat TGPhotoPaintStickerKeyboardSize = 260.0f; [super viewDidLoad]; PGPhotoEditor *photoEditor = _photoEditor; - [_entitiesContainerView setupWithPaintingData:photoEditor.paintingData]; + if (!_skipEntitiesSetup) { + [_entitiesContainerView setupWithPaintingData:photoEditor.paintingData]; + } for (TGPhotoPaintEntityView *view in _entitiesContainerView.subviews) { if (![view isKindOfClass:[TGPhotoPaintEntityView class]]) diff --git a/submodules/LegacyComponents/Sources/TGPhotoToolsController.m b/submodules/LegacyComponents/Sources/TGPhotoToolsController.m index 46c4751724..1d610335e2 100644 --- a/submodules/LegacyComponents/Sources/TGPhotoToolsController.m +++ b/submodules/LegacyComponents/Sources/TGPhotoToolsController.m @@ -22,6 +22,9 @@ #import "TGPhotoEditorPreviewView.h" #import "TGPhotoEditorHUDView.h" #import "TGPhotoEditorSparseView.h" +#import "TGPhotoEntitiesContainerView.h" + +#import "TGPhotoPaintController.h" const CGFloat TGPhotoEditorToolsPanelSize = 180.0f; const CGFloat TGPhotoEditorToolsLandscapePanelSize = TGPhotoEditorToolsPanelSize + 40.0f; @@ -53,6 +56,8 @@ const CGFloat TGPhotoEditorToolsLandscapePanelSize = TGPhotoEditorToolsPanelSize bool _preview; TGPhotoEditorTab _currentTab; + UIView *_entitiesWrapperView; + UIView *_toolAreaView; UIView *_portraitToolControlView; UIView *_landscapeToolControlView; @@ -101,6 +106,29 @@ const CGFloat TGPhotoEditorToolsLandscapePanelSize = TGPhotoEditorToolsPanelSize _landscapeCollectionView.toolsDataSource = nil; } +- (void)layoutEntitiesView { + CGSize fittedContentSize = [TGPhotoPaintController fittedContentSize:_photoEditor.cropRect orientation:_photoEditor.cropOrientation originalSize:_photoEditor.originalSize]; + CGRect fittedCropRect = [TGPhotoPaintController fittedCropRect:_photoEditor.cropRect originalSize:_photoEditor.originalSize keepOriginalSize:false]; + _entitiesWrapperView.frame = CGRectMake(0.0f, 0.0f, fittedContentSize.width, fittedContentSize.height); + + CGRect rect = [TGPhotoPaintController fittedCropRect:self.photoEditor.cropRect originalSize:self.photoEditor.originalSize keepOriginalSize:true]; + _entitiesView.frame = CGRectMake(0, 0, rect.size.width, rect.size.height); + _entitiesView.transform = CGAffineTransformMakeRotation(_photoEditor.cropRotation); + + CGSize fittedOriginalSize = TGScaleToSize(_photoEditor.originalSize, [TGPhotoPaintController maximumPaintingSize]); + CGSize rotatedSize = TGRotatedContentSize(fittedOriginalSize, _photoEditor.cropRotation); + CGPoint centerPoint = CGPointMake(rotatedSize.width / 2.0f, rotatedSize.height / 2.0f); + + CGFloat scale = fittedOriginalSize.width / _photoEditor.originalSize.width; + CGPoint offset = TGPaintSubtractPoints(centerPoint, [TGPhotoPaintController fittedCropRect:_photoEditor.cropRect centerScale:scale]); + + CGPoint boundsCenter = TGPaintCenterOfRect(_entitiesWrapperView.bounds); + _entitiesView.center = TGPaintAddPoints(boundsCenter, offset); + if (_entitiesView.superview != _entitiesWrapperView) { + [_entitiesWrapperView addSubview:_entitiesView]; + } +} + - (void)loadView { [super loadView]; @@ -191,6 +219,10 @@ const CGFloat TGPhotoEditorToolsLandscapePanelSize = TGPhotoEditorToolsPanelSize _wrapperView = [[TGPhotoEditorSparseView alloc] initWithFrame:CGRectZero]; [self.view addSubview:_wrapperView]; + _entitiesWrapperView = [[UIView alloc] init]; + _entitiesWrapperView.userInteractionEnabled = false; + [_wrapperView addSubview:_entitiesWrapperView]; + _portraitToolsWrapperView = [[UIView alloc] initWithFrame:CGRectZero]; _portraitToolsWrapperView.alpha = 0.0f; [_wrapperView addSubview:_portraitToolsWrapperView]; @@ -977,6 +1009,7 @@ const CGFloat TGPhotoEditorToolsLandscapePanelSize = TGPhotoEditorToolsPanelSize [_landscapeCollectionView.collectionViewLayout invalidateLayout]; [self updatePreviewView]; + [self layoutEntitiesView]; } - (TGPhotoEditorTab)availableTabs diff --git a/submodules/TelegramUI/Sources/DrawingStickersScreen.swift b/submodules/TelegramUI/Sources/DrawingStickersScreen.swift index 323e978896..d3ee0bcda8 100644 --- a/submodules/TelegramUI/Sources/DrawingStickersScreen.swift +++ b/submodules/TelegramUI/Sources/DrawingStickersScreen.swift @@ -1307,7 +1307,6 @@ private final class DrawingStickersScreenNode: ViewControllerTracingNode { strongSelf.hiddenPane?.removeFromSupernode() strongSelf.hiddenListView?.removeFromSupernode() strongSelf.isHidden = true - strongSelf.dismiss?() } }) } From 4ac6678182aa744241565baf08ff432e1de1af8a Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Thu, 16 Jul 2020 18:23:50 +0300 Subject: [PATCH 3/4] Video avatar fixes --- .../Source/Navigation/NavigationSplitContainer.swift | 2 +- submodules/LegacyComponents/Sources/TGMediaVideoConverter.m | 6 +++++- submodules/TelegramUI/Sources/CreateChannelController.swift | 2 +- submodules/TelegramUI/Sources/CreateGroupController.swift | 2 +- submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift | 2 +- 5 files changed, 9 insertions(+), 5 deletions(-) diff --git a/submodules/Display/Source/Navigation/NavigationSplitContainer.swift b/submodules/Display/Source/Navigation/NavigationSplitContainer.swift index d95b026dd7..82d7cf2d23 100644 --- a/submodules/Display/Source/Navigation/NavigationSplitContainer.swift +++ b/submodules/Display/Source/Navigation/NavigationSplitContainer.swift @@ -84,7 +84,7 @@ final class NavigationSplitContainer: ASDisplayNode { } func update(layout: ContainerViewLayout, masterControllers: [ViewController], detailControllers: [ViewController], transition: ContainedViewLayoutTransition) { - let masterWidth: CGFloat = 375.0 // min(max(320.0, floor(layout.size.width / 3.0)), floor(layout.size.width / 2.0)) + let masterWidth: CGFloat = min(max(320.0, floor(layout.size.width / 3.0)), floor(layout.size.width / 2.0)) let detailWidth = layout.size.width - masterWidth self.masterScrollToTopView.frame = CGRect(origin: CGPoint(x: 0.0, y: -1.0), size: CGSize(width: masterWidth, height: 1.0)) diff --git a/submodules/LegacyComponents/Sources/TGMediaVideoConverter.m b/submodules/LegacyComponents/Sources/TGMediaVideoConverter.m index 8c0ddae431..070ea4892e 100644 --- a/submodules/LegacyComponents/Sources/TGMediaVideoConverter.m +++ b/submodules/LegacyComponents/Sources/TGMediaVideoConverter.m @@ -240,6 +240,9 @@ return; TGMediaVideoConversionPreset preset = TGMediaVideoConversionPresetAnimation; + if (adjustments.preset == TGMediaVideoConversionPresetProfile || adjustments.preset == TGMediaVideoConversionPresetProfileHigh || adjustments.preset == TGMediaVideoConversionPresetProfileVeryHigh) { + preset = adjustments.preset; + } NSError *error = nil; @@ -283,7 +286,8 @@ if (watcher != nil) liveUploadData = [watcher fileUpdated:true]; - contextResult = [TGMediaVideoConversionResult resultWithFileURL:outputUrl fileSize:0 duration:CMTimeGetSeconds(resultContext.timeRange.duration) dimensions:resultContext.dimensions coverImage:coverImage liveUploadData:liveUploadData]; + NSUInteger fileSize = [[[NSFileManager defaultManager] attributesOfItemAtPath:outputUrl.path error:nil] fileSize]; + contextResult = [TGMediaVideoConversionResult resultWithFileURL:outputUrl fileSize:fileSize duration:CMTimeGetSeconds(resultContext.timeRange.duration) dimensions:resultContext.dimensions coverImage:coverImage liveUploadData:liveUploadData]; return [resultContext finishedContext]; }]; diff --git a/submodules/TelegramUI/Sources/CreateChannelController.swift b/submodules/TelegramUI/Sources/CreateChannelController.swift index d860f171ab..1828a3d8b5 100644 --- a/submodules/TelegramUI/Sources/CreateChannelController.swift +++ b/submodules/TelegramUI/Sources/CreateChannelController.swift @@ -369,7 +369,7 @@ public func createChannelController(context: AccountContext) -> ViewController { }) signal = durationSignal.map(toSignal: { duration -> SSignal? in if let duration = duration as? Double { - return TGMediaVideoConverter.renderUIImage(image, duration: duration, adjustments: adjustments, watcher: uploadInterface, entityRenderer: entityRenderer)! + return TGMediaVideoConverter.renderUIImage(image, duration: duration, adjustments: adjustments, watcher: nil, entityRenderer: entityRenderer)! } else { return SSignal.single(nil) } diff --git a/submodules/TelegramUI/Sources/CreateGroupController.swift b/submodules/TelegramUI/Sources/CreateGroupController.swift index 38f7dd16b2..6ec14a0c8b 100644 --- a/submodules/TelegramUI/Sources/CreateGroupController.swift +++ b/submodules/TelegramUI/Sources/CreateGroupController.swift @@ -628,7 +628,7 @@ public func createGroupControllerImpl(context: AccountContext, peerIds: [PeerId] }) signal = durationSignal.map(toSignal: { duration -> SSignal? in if let duration = duration as? Double { - return TGMediaVideoConverter.renderUIImage(image, duration: duration, adjustments: adjustments, watcher: uploadInterface, entityRenderer: entityRenderer)! + return TGMediaVideoConverter.renderUIImage(image, duration: duration, adjustments: adjustments, watcher: nil, entityRenderer: entityRenderer)! } else { return SSignal.single(nil) } diff --git a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift index 107878889b..fff0b678d0 100644 --- a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift +++ b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift @@ -4014,7 +4014,7 @@ private final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewD }) signal = durationSignal.map(toSignal: { duration -> SSignal? in if let duration = duration as? Double { - return TGMediaVideoConverter.renderUIImage(image, duration: duration, adjustments: adjustments, watcher: uploadInterface, entityRenderer: entityRenderer)! + return TGMediaVideoConverter.renderUIImage(image, duration: duration, adjustments: adjustments, watcher: nil, entityRenderer: entityRenderer)! } else { return SSignal.single(nil) } From 262cddc4d97158038295bfee5eeedd8ca9cc836b Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Thu, 16 Jul 2020 19:19:07 +0300 Subject: [PATCH 4/4] Video avatar fixes --- .../Sources/TGMediaAssetsPickerController.m | 1 + .../Sources/TGPhotoEditorTabController.m | 22 ------------------- .../Sources/PeerInfo/PeerInfoHeaderNode.swift | 20 +++++++++++++++++ 3 files changed, 21 insertions(+), 22 deletions(-) diff --git a/submodules/LegacyComponents/Sources/TGMediaAssetsPickerController.m b/submodules/LegacyComponents/Sources/TGMediaAssetsPickerController.m index f885339c4e..28e2407007 100644 --- a/submodules/LegacyComponents/Sources/TGMediaAssetsPickerController.m +++ b/submodules/LegacyComponents/Sources/TGMediaAssetsPickerController.m @@ -406,6 +406,7 @@ } TGPhotoEditorController *controller = [[TGPhotoEditorController alloc] initWithContext:_context item:editableItem intent:intent adjustments:nil caption:nil screenImage:thumbnailImage availableTabs:[TGPhotoEditorController defaultTabsForAvatarIntent] selectedTab:TGPhotoEditorCropTab]; + controller.stickersContext = self.stickersContext; controller.editingContext = self.editingContext; controller.didFinishRenderingFullSizeImage = ^(UIImage *resultImage) { diff --git a/submodules/LegacyComponents/Sources/TGPhotoEditorTabController.m b/submodules/LegacyComponents/Sources/TGPhotoEditorTabController.m index 1f5a122725..842172cf41 100644 --- a/submodules/LegacyComponents/Sources/TGPhotoEditorTabController.m +++ b/submodules/LegacyComponents/Sources/TGPhotoEditorTabController.m @@ -186,28 +186,6 @@ const CGFloat TGPhotoEditorToolbarSize = 49.0f; [self _finishedTransitionInWithView:transitionView]; }]; - -// POPSpringAnimation *animation = [TGPhotoEditorAnimation prepareTransitionAnimationForPropertyNamed:kPOPViewFrame]; -// if (self.transitionSpeed > FLT_EPSILON) -// animation.springSpeed = self.transitionSpeed; -// animation.fromValue = [NSValue valueWithCGRect:_transitionView.frame]; -// animation.toValue = [NSValue valueWithCGRect:_transitionTargetFrame]; -// animation.completionBlock = ^(__unused POPAnimation *animation, __unused BOOL finished) -// { -// _transitionInProgress = false; -// -// UIView *transitionView = _transitionView; -// _transitionView = nil; -// -// if (self.finishedTransitionIn != nil) -// { -// self.finishedTransitionIn(); -// self.finishedTransitionIn = nil; -// } -// -// [self _finishedTransitionInWithView:transitionView]; -// }; -// [_transitionView pop_addAnimation:animation forKey:@"frame"]; } - (void)prepareForCustomTransitionOut diff --git a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoHeaderNode.swift b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoHeaderNode.swift index 54a85b9f6a..a7cc1fabaa 100644 --- a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoHeaderNode.swift +++ b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoHeaderNode.swift @@ -916,9 +916,13 @@ final class PeerInfoAvatarListContainerNode: ASDisplayNode { guard case let .image(image) = item else { return false } + var items: [PeerInfoAvatarListItem] = [] var entries: [AvatarGalleryEntry] = [] let previousIndex = self.currentIndex + + var index = 0 + var deletedIndex: Int? for entry in self.galleryEntries { switch entry { case let .topImage(representations, videoRepresentations, _, _, immediateThumbnailData, _): @@ -928,9 +932,25 @@ final class PeerInfoAvatarListContainerNode: ASDisplayNode { if image.0 != reference { entries.append(entry) items.append(.image(reference, representations, videoRepresentations, immediateThumbnailData)) + } else { + deletedIndex = index } } + index += 1 } + + + if let peer = self.peer, peer is TelegramGroup || peer is TelegramChannel, deletedIndex == 0 { + self.galleryEntries = [] + self.items = [] + self.itemsUpdated?([]) + self.currentIndex = 0 + if let size = self.validLayout { + self.updateItems(size: size, update: true, transition: .immediate, stripTransition: .immediate, synchronous: true) + } + return true + } + self.galleryEntries = normalizeEntries(entries) self.items = items self.itemsUpdated?(items)