mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-08-01 07:57:01 +00:00
Merge commit '262cddc4d97158038295bfee5eeedd8ca9cc836b'
This commit is contained in:
commit
dce811f80b
@ -84,7 +84,7 @@ final class NavigationSplitContainer: ASDisplayNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func update(layout: ContainerViewLayout, masterControllers: [ViewController], detailControllers: [ViewController], transition: ContainedViewLayoutTransition) {
|
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
|
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))
|
self.masterScrollToTopView.frame = CGRect(origin: CGPoint(x: 0.0, y: -1.0), size: CGSize(width: masterWidth, height: 1.0))
|
||||||
|
@ -37,7 +37,7 @@ typedef enum
|
|||||||
- (instancetype)editAdjustmentsWithPreset:(TGMediaVideoConversionPreset)preset maxDuration:(NSTimeInterval)maxDuration;
|
- (instancetype)editAdjustmentsWithPreset:(TGMediaVideoConversionPreset)preset maxDuration:(NSTimeInterval)maxDuration;
|
||||||
- (instancetype)editAdjustmentsWithPreset:(TGMediaVideoConversionPreset)preset videoStartValue:(NSTimeInterval)videoStartValue trimStartValue:(NSTimeInterval)trimStartValue trimEndValue:(NSTimeInterval)trimEndValue;
|
- (instancetype)editAdjustmentsWithPreset:(TGMediaVideoConversionPreset)preset videoStartValue:(NSTimeInterval)videoStartValue trimStartValue:(NSTimeInterval)trimStartValue trimEndValue:(NSTimeInterval)trimEndValue;
|
||||||
+ (instancetype)editAdjustmentsWithOriginalSize:(CGSize)originalSize preset:(TGMediaVideoConversionPreset)preset;
|
+ (instancetype)editAdjustmentsWithOriginalSize:(CGSize)originalSize preset:(TGMediaVideoConversionPreset)preset;
|
||||||
+ (instancetype)editAdjustmentsWithPhotoEditorValues:(PGPhotoEditorValues *)values;
|
+ (instancetype)editAdjustmentsWithPhotoEditorValues:(PGPhotoEditorValues *)values preset:(TGMediaVideoConversionPreset)preset;
|
||||||
+ (instancetype)editAdjustmentsWithDictionary:(NSDictionary *)dictionary;
|
+ (instancetype)editAdjustmentsWithDictionary:(NSDictionary *)dictionary;
|
||||||
|
|
||||||
+ (instancetype)editAdjustmentsWithOriginalSize:(CGSize)originalSize
|
+ (instancetype)editAdjustmentsWithOriginalSize:(CGSize)originalSize
|
||||||
|
@ -898,7 +898,7 @@ const NSUInteger TGAttachmentDisplayedAssetLimit = 500;
|
|||||||
};
|
};
|
||||||
|
|
||||||
__weak TGPhotoEditorController *weakController = controller;
|
__weak TGPhotoEditorController *weakController = controller;
|
||||||
controller.didFinishEditing = ^(__unused id<TGMediaEditAdjustments> adjustments, UIImage *resultImage, __unused UIImage *thumbnailImage, __unused bool hasChanges)
|
controller.didFinishEditing = ^(id<TGMediaEditAdjustments> adjustments, UIImage *resultImage, __unused UIImage *thumbnailImage, __unused bool hasChanges)
|
||||||
{
|
{
|
||||||
if (!hasChanges)
|
if (!hasChanges)
|
||||||
return;
|
return;
|
||||||
@ -911,8 +911,34 @@ const NSUInteger TGAttachmentDisplayedAssetLimit = 500;
|
|||||||
if (strongController == nil)
|
if (strongController == nil)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (strongSelf.avatarCompletionBlock != nil)
|
if (adjustments.paintingData.hasAnimation) {
|
||||||
strongSelf.avatarCompletionBlock(resultImage);
|
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<TGMediaEditAdjustments> adjustments, UIImage *resultImage, UIImage *thumbnailImage, bool hasChanges) {
|
controller.didFinishEditingVideo = ^(AVAsset *asset, id<TGMediaEditAdjustments> adjustments, UIImage *resultImage, UIImage *thumbnailImage, bool hasChanges) {
|
||||||
if (!hasChanges)
|
if (!hasChanges)
|
||||||
|
@ -2592,7 +2592,7 @@ static CGPoint TGCameraControllerClampPointToScreenSize(__unused id self, __unus
|
|||||||
if (animated) {
|
if (animated) {
|
||||||
dict[@"isAnimation"] = @true;
|
dict[@"isAnimation"] = @true;
|
||||||
if ([adjustments isKindOfClass:[PGPhotoEditorValues class]]) {
|
if ([adjustments isKindOfClass:[PGPhotoEditorValues class]]) {
|
||||||
dict[@"adjustments"] = [TGVideoEditAdjustments editAdjustmentsWithPhotoEditorValues:(PGPhotoEditorValues *)adjustments];
|
dict[@"adjustments"] = [TGVideoEditAdjustments editAdjustmentsWithPhotoEditorValues:(PGPhotoEditorValues *)adjustments preset:TGMediaVideoConversionPresetAnimation];
|
||||||
} else {
|
} else {
|
||||||
dict[@"adjustments"] = adjustments;
|
dict[@"adjustments"] = adjustments;
|
||||||
}
|
}
|
||||||
|
@ -904,7 +904,7 @@
|
|||||||
if (animated) {
|
if (animated) {
|
||||||
dict[@"isAnimation"] = @true;
|
dict[@"isAnimation"] = @true;
|
||||||
if ([adjustments isKindOfClass:[PGPhotoEditorValues class]]) {
|
if ([adjustments isKindOfClass:[PGPhotoEditorValues class]]) {
|
||||||
dict[@"adjustments"] = [TGVideoEditAdjustments editAdjustmentsWithPhotoEditorValues:(PGPhotoEditorValues *)adjustments];
|
dict[@"adjustments"] = [TGVideoEditAdjustments editAdjustmentsWithPhotoEditorValues:(PGPhotoEditorValues *)adjustments preset:TGMediaVideoConversionPresetAnimation];
|
||||||
} else {
|
} else {
|
||||||
dict[@"adjustments"] = adjustments;
|
dict[@"adjustments"] = adjustments;
|
||||||
}
|
}
|
||||||
|
@ -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];
|
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.editingContext = self.editingContext;
|
||||||
controller.didFinishRenderingFullSizeImage = ^(UIImage *resultImage)
|
controller.didFinishRenderingFullSizeImage = ^(UIImage *resultImage)
|
||||||
{
|
{
|
||||||
@ -415,7 +416,7 @@
|
|||||||
|
|
||||||
[[strongSelf->_assetsLibrary saveAssetWithImage:resultImage] startWithNext:nil];
|
[[strongSelf->_assetsLibrary saveAssetWithImage:resultImage] startWithNext:nil];
|
||||||
};
|
};
|
||||||
controller.didFinishEditing = ^(__unused id<TGMediaEditAdjustments> adjustments, UIImage *resultImage, __unused UIImage *thumbnailImage, bool hasChanges)
|
controller.didFinishEditing = ^(id<TGMediaEditAdjustments> adjustments, UIImage *resultImage, __unused UIImage *thumbnailImage, bool hasChanges)
|
||||||
{
|
{
|
||||||
if (!hasChanges)
|
if (!hasChanges)
|
||||||
return;
|
return;
|
||||||
@ -424,7 +425,32 @@
|
|||||||
if (strongSelf == nil)
|
if (strongSelf == nil)
|
||||||
return;
|
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<TGMediaEditAdjustments> adjustments, UIImage *resultImage, UIImage *thumbnailImage, bool hasChanges) {
|
controller.didFinishEditingVideo = ^(AVAsset *asset, id<TGMediaEditAdjustments> adjustments, UIImage *resultImage, UIImage *thumbnailImage, bool hasChanges) {
|
||||||
if (!hasChanges)
|
if (!hasChanges)
|
||||||
|
@ -800,7 +800,7 @@
|
|||||||
CGRect fittedCropRect = [TGPhotoPaintController fittedCropRect:cropRect originalSize:originalSize keepOriginalSize:false];
|
CGRect fittedCropRect = [TGPhotoPaintController fittedCropRect:cropRect originalSize:originalSize keepOriginalSize:false];
|
||||||
_contentWrapperView.frame = CGRectMake(0.0f, 0.0f, fittedContentSize.width, fittedContentSize.height);
|
_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.transform = CGAffineTransformMakeScale(contentScale, contentScale);
|
||||||
_contentWrapperView.frame = CGRectMake(0.0f, 0.0f, _contentView.bounds.size.width, _contentView.bounds.size.height);
|
_contentWrapperView.frame = CGRectMake(0.0f, 0.0f, _contentView.bounds.size.width, _contentView.bounds.size.height);
|
||||||
|
|
||||||
|
@ -240,6 +240,9 @@
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
TGMediaVideoConversionPreset preset = TGMediaVideoConversionPresetAnimation;
|
TGMediaVideoConversionPreset preset = TGMediaVideoConversionPresetAnimation;
|
||||||
|
if (adjustments.preset == TGMediaVideoConversionPresetProfile || adjustments.preset == TGMediaVideoConversionPresetProfileHigh || adjustments.preset == TGMediaVideoConversionPresetProfileVeryHigh) {
|
||||||
|
preset = adjustments.preset;
|
||||||
|
}
|
||||||
|
|
||||||
NSError *error = nil;
|
NSError *error = nil;
|
||||||
|
|
||||||
@ -283,7 +286,8 @@
|
|||||||
if (watcher != nil)
|
if (watcher != nil)
|
||||||
liveUploadData = [watcher fileUpdated:true];
|
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];
|
return [resultContext finishedContext];
|
||||||
}];
|
}];
|
||||||
|
|
||||||
|
@ -42,6 +42,8 @@ const CGFloat TGPhotoAvatarCropViewCurtainMargin = 200;
|
|||||||
|
|
||||||
CGFloat _currentDiameter;
|
CGFloat _currentDiameter;
|
||||||
|
|
||||||
|
UIView *_entitiesWrapperView;
|
||||||
|
|
||||||
__weak PGPhotoEditorView *_fullPreviewView;
|
__weak PGPhotoEditorView *_fullPreviewView;
|
||||||
__weak UIImageView *_fullPaintingView;
|
__weak UIImageView *_fullPaintingView;
|
||||||
__weak TGPhotoEntitiesContainerView *_fullEntitiesView;
|
__weak TGPhotoEntitiesContainerView *_fullEntitiesView;
|
||||||
@ -91,9 +93,16 @@ const CGFloat TGPhotoAvatarCropViewCurtainMargin = 200;
|
|||||||
_fullPaintingView.frame = _fullPreviewView.frame;
|
_fullPaintingView.frame = _fullPreviewView.frame;
|
||||||
[_wrapperView addSubview:_fullPaintingView];
|
[_wrapperView addSubview:_fullPaintingView];
|
||||||
|
|
||||||
|
_entitiesWrapperView = [[UIView alloc] init];
|
||||||
_fullEntitiesView = fullEntitiesView;
|
_fullEntitiesView = fullEntitiesView;
|
||||||
_fullEntitiesView.frame = _fullPreviewView.frame;
|
_fullEntitiesView.frame = CGRectMake(0.0, 0.0, _fullEntitiesView.frame.size.width, _fullEntitiesView.frame.size.height);
|
||||||
[_wrapperView addSubview:_fullEntitiesView];
|
_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 = [[UIView alloc] init];
|
||||||
_flashView.alpha = 0.0;
|
_flashView.alpha = 0.0;
|
||||||
|
@ -346,7 +346,8 @@
|
|||||||
|
|
||||||
_fullEntitiesView = [[TGPhotoEntitiesContainerView alloc] init];
|
_fullEntitiesView = [[TGPhotoEntitiesContainerView alloc] init];
|
||||||
_fullEntitiesView.userInteractionEnabled = false;
|
_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])];
|
_dotMarkerView = [[UIImageView alloc] initWithImage:TGCircleImage(7.0, [TGPhotoEditorInterfaceAssets accentColor])];
|
||||||
@ -1061,8 +1062,13 @@
|
|||||||
UIImage *image = result[@"image"];
|
UIImage *image = result[@"image"];
|
||||||
UIImage *thumbnailImage = result[@"thumbnail"];
|
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);
|
completion(image);
|
||||||
|
}
|
||||||
|
|
||||||
if (!saveOnly && didFinishEditing != nil)
|
if (!saveOnly && didFinishEditing != nil)
|
||||||
didFinishEditing(editorValues, image, thumbnailImage, true);
|
didFinishEditing(editorValues, image, thumbnailImage, true);
|
||||||
|
@ -186,28 +186,6 @@ const CGFloat TGPhotoEditorToolbarSize = 49.0f;
|
|||||||
|
|
||||||
[self _finishedTransitionInWithView:transitionView];
|
[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
|
- (void)prepareForCustomTransitionOut
|
||||||
|
@ -98,6 +98,7 @@ const CGFloat TGPhotoPaintStickerKeyboardSize = 260.0f;
|
|||||||
id<TGPhotoPaintStickersScreen> _stickersScreen;
|
id<TGPhotoPaintStickersScreen> _stickersScreen;
|
||||||
|
|
||||||
bool _appeared;
|
bool _appeared;
|
||||||
|
bool _skipEntitiesSetup;
|
||||||
|
|
||||||
TGPhotoPaintFont *_selectedTextFont;
|
TGPhotoPaintFont *_selectedTextFont;
|
||||||
TGPhotoPaintTextEntityStyle _selectedTextStyle;
|
TGPhotoPaintTextEntityStyle _selectedTextStyle;
|
||||||
@ -152,6 +153,9 @@ const CGFloat TGPhotoPaintStickerKeyboardSize = 260.0f;
|
|||||||
self.photoEditor = photoEditor;
|
self.photoEditor = photoEditor;
|
||||||
self.previewView = previewView;
|
self.previewView = previewView;
|
||||||
_entitiesContainerView = entitiesView;
|
_entitiesContainerView = entitiesView;
|
||||||
|
if (entitiesView != nil) {
|
||||||
|
_skipEntitiesSetup = true;
|
||||||
|
}
|
||||||
entitiesView.userInteractionEnabled = true;
|
entitiesView.userInteractionEnabled = true;
|
||||||
|
|
||||||
_brushes = @
|
_brushes = @
|
||||||
@ -509,7 +513,9 @@ const CGFloat TGPhotoPaintStickerKeyboardSize = 260.0f;
|
|||||||
[super viewDidLoad];
|
[super viewDidLoad];
|
||||||
|
|
||||||
PGPhotoEditor *photoEditor = _photoEditor;
|
PGPhotoEditor *photoEditor = _photoEditor;
|
||||||
[_entitiesContainerView setupWithPaintingData:photoEditor.paintingData];
|
if (!_skipEntitiesSetup) {
|
||||||
|
[_entitiesContainerView setupWithPaintingData:photoEditor.paintingData];
|
||||||
|
}
|
||||||
for (TGPhotoPaintEntityView *view in _entitiesContainerView.subviews)
|
for (TGPhotoPaintEntityView *view in _entitiesContainerView.subviews)
|
||||||
{
|
{
|
||||||
if (![view isKindOfClass:[TGPhotoPaintEntityView class]])
|
if (![view isKindOfClass:[TGPhotoPaintEntityView class]])
|
||||||
@ -1900,6 +1906,8 @@ const CGFloat TGPhotoPaintStickerKeyboardSize = 260.0f;
|
|||||||
|
|
||||||
- (void)transitionOutSwitching:(bool)__unused switching completion:(void (^)(void))completion
|
- (void)transitionOutSwitching:(bool)__unused switching completion:(void (^)(void))completion
|
||||||
{
|
{
|
||||||
|
[_stickersScreen invalidate];
|
||||||
|
|
||||||
TGPhotoEditorPreviewView *previewView = self.previewView;
|
TGPhotoEditorPreviewView *previewView = self.previewView;
|
||||||
previewView.interactionEnded = nil;
|
previewView.interactionEnded = nil;
|
||||||
|
|
||||||
@ -1931,9 +1939,7 @@ const CGFloat TGPhotoPaintStickerKeyboardSize = 260.0f;
|
|||||||
- (void)_animatePreviewViewTransitionOutToFrame:(CGRect)targetFrame saving:(bool)saving parentView:(UIView *)parentView completion:(void (^)(void))completion
|
- (void)_animatePreviewViewTransitionOutToFrame:(CGRect)targetFrame saving:(bool)saving parentView:(UIView *)parentView completion:(void (^)(void))completion
|
||||||
{
|
{
|
||||||
_dismissing = true;
|
_dismissing = true;
|
||||||
|
|
||||||
[_stickersScreen invalidate];
|
|
||||||
|
|
||||||
[_entitySelectionView removeFromSuperview];
|
[_entitySelectionView removeFromSuperview];
|
||||||
_entitySelectionView = nil;
|
_entitySelectionView = nil;
|
||||||
|
|
||||||
|
@ -22,6 +22,9 @@
|
|||||||
#import "TGPhotoEditorPreviewView.h"
|
#import "TGPhotoEditorPreviewView.h"
|
||||||
#import "TGPhotoEditorHUDView.h"
|
#import "TGPhotoEditorHUDView.h"
|
||||||
#import "TGPhotoEditorSparseView.h"
|
#import "TGPhotoEditorSparseView.h"
|
||||||
|
#import "TGPhotoEntitiesContainerView.h"
|
||||||
|
|
||||||
|
#import "TGPhotoPaintController.h"
|
||||||
|
|
||||||
const CGFloat TGPhotoEditorToolsPanelSize = 180.0f;
|
const CGFloat TGPhotoEditorToolsPanelSize = 180.0f;
|
||||||
const CGFloat TGPhotoEditorToolsLandscapePanelSize = TGPhotoEditorToolsPanelSize + 40.0f;
|
const CGFloat TGPhotoEditorToolsLandscapePanelSize = TGPhotoEditorToolsPanelSize + 40.0f;
|
||||||
@ -53,6 +56,8 @@ const CGFloat TGPhotoEditorToolsLandscapePanelSize = TGPhotoEditorToolsPanelSize
|
|||||||
bool _preview;
|
bool _preview;
|
||||||
TGPhotoEditorTab _currentTab;
|
TGPhotoEditorTab _currentTab;
|
||||||
|
|
||||||
|
UIView *_entitiesWrapperView;
|
||||||
|
|
||||||
UIView <TGPhotoEditorToolView> *_toolAreaView;
|
UIView <TGPhotoEditorToolView> *_toolAreaView;
|
||||||
UIView <TGPhotoEditorToolView> *_portraitToolControlView;
|
UIView <TGPhotoEditorToolView> *_portraitToolControlView;
|
||||||
UIView <TGPhotoEditorToolView> *_landscapeToolControlView;
|
UIView <TGPhotoEditorToolView> *_landscapeToolControlView;
|
||||||
@ -101,6 +106,29 @@ const CGFloat TGPhotoEditorToolsLandscapePanelSize = TGPhotoEditorToolsPanelSize
|
|||||||
_landscapeCollectionView.toolsDataSource = nil;
|
_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
|
- (void)loadView
|
||||||
{
|
{
|
||||||
[super loadView];
|
[super loadView];
|
||||||
@ -191,6 +219,10 @@ const CGFloat TGPhotoEditorToolsLandscapePanelSize = TGPhotoEditorToolsPanelSize
|
|||||||
_wrapperView = [[TGPhotoEditorSparseView alloc] initWithFrame:CGRectZero];
|
_wrapperView = [[TGPhotoEditorSparseView alloc] initWithFrame:CGRectZero];
|
||||||
[self.view addSubview:_wrapperView];
|
[self.view addSubview:_wrapperView];
|
||||||
|
|
||||||
|
_entitiesWrapperView = [[UIView alloc] init];
|
||||||
|
_entitiesWrapperView.userInteractionEnabled = false;
|
||||||
|
[_wrapperView addSubview:_entitiesWrapperView];
|
||||||
|
|
||||||
_portraitToolsWrapperView = [[UIView alloc] initWithFrame:CGRectZero];
|
_portraitToolsWrapperView = [[UIView alloc] initWithFrame:CGRectZero];
|
||||||
_portraitToolsWrapperView.alpha = 0.0f;
|
_portraitToolsWrapperView.alpha = 0.0f;
|
||||||
[_wrapperView addSubview:_portraitToolsWrapperView];
|
[_wrapperView addSubview:_portraitToolsWrapperView];
|
||||||
@ -977,6 +1009,7 @@ const CGFloat TGPhotoEditorToolsLandscapePanelSize = TGPhotoEditorToolsPanelSize
|
|||||||
[_landscapeCollectionView.collectionViewLayout invalidateLayout];
|
[_landscapeCollectionView.collectionViewLayout invalidateLayout];
|
||||||
|
|
||||||
[self updatePreviewView];
|
[self updatePreviewView];
|
||||||
|
[self layoutEntitiesView];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (TGPhotoEditorTab)availableTabs
|
- (TGPhotoEditorTab)availableTabs
|
||||||
|
@ -136,7 +136,7 @@ const NSTimeInterval TGVideoEditMaximumGifDuration = 30.5;
|
|||||||
return adjustments;
|
return adjustments;
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (instancetype)editAdjustmentsWithPhotoEditorValues:(PGPhotoEditorValues *)values {
|
+ (instancetype)editAdjustmentsWithPhotoEditorValues:(PGPhotoEditorValues *)values preset:(TGMediaVideoConversionPreset)preset {
|
||||||
TGVideoEditAdjustments *adjustments = [[[self class] alloc] init];
|
TGVideoEditAdjustments *adjustments = [[[self class] alloc] init];
|
||||||
adjustments->_originalSize = values.originalSize;
|
adjustments->_originalSize = values.originalSize;
|
||||||
CGRect cropRect = values.cropRect;
|
CGRect cropRect = values.cropRect;
|
||||||
@ -150,7 +150,7 @@ const NSTimeInterval TGVideoEditMaximumGifDuration = 30.5;
|
|||||||
adjustments->_cropMirrored = values.cropMirrored;
|
adjustments->_cropMirrored = values.cropMirrored;
|
||||||
adjustments->_paintingData = [values.paintingData dataForAnimation];
|
adjustments->_paintingData = [values.paintingData dataForAnimation];
|
||||||
adjustments->_sendAsGif = true;
|
adjustments->_sendAsGif = true;
|
||||||
adjustments->_preset = TGMediaVideoConversionPresetAnimation;
|
adjustments->_preset = preset;
|
||||||
|
|
||||||
return adjustments;
|
return adjustments;
|
||||||
}
|
}
|
||||||
|
@ -369,7 +369,7 @@ public func createChannelController(context: AccountContext) -> ViewController {
|
|||||||
})
|
})
|
||||||
signal = durationSignal.map(toSignal: { duration -> SSignal? in
|
signal = durationSignal.map(toSignal: { duration -> SSignal? in
|
||||||
if let duration = duration as? Double {
|
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 {
|
} else {
|
||||||
return SSignal.single(nil)
|
return SSignal.single(nil)
|
||||||
}
|
}
|
||||||
|
@ -628,7 +628,7 @@ public func createGroupControllerImpl(context: AccountContext, peerIds: [PeerId]
|
|||||||
})
|
})
|
||||||
signal = durationSignal.map(toSignal: { duration -> SSignal? in
|
signal = durationSignal.map(toSignal: { duration -> SSignal? in
|
||||||
if let duration = duration as? Double {
|
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 {
|
} else {
|
||||||
return SSignal.single(nil)
|
return SSignal.single(nil)
|
||||||
}
|
}
|
||||||
|
@ -1307,7 +1307,6 @@ private final class DrawingStickersScreenNode: ViewControllerTracingNode {
|
|||||||
strongSelf.hiddenPane?.removeFromSupernode()
|
strongSelf.hiddenPane?.removeFromSupernode()
|
||||||
strongSelf.hiddenListView?.removeFromSupernode()
|
strongSelf.hiddenListView?.removeFromSupernode()
|
||||||
strongSelf.isHidden = true
|
strongSelf.isHidden = true
|
||||||
strongSelf.dismiss?()
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -916,9 +916,13 @@ final class PeerInfoAvatarListContainerNode: ASDisplayNode {
|
|||||||
guard case let .image(image) = item else {
|
guard case let .image(image) = item else {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
var items: [PeerInfoAvatarListItem] = []
|
var items: [PeerInfoAvatarListItem] = []
|
||||||
var entries: [AvatarGalleryEntry] = []
|
var entries: [AvatarGalleryEntry] = []
|
||||||
let previousIndex = self.currentIndex
|
let previousIndex = self.currentIndex
|
||||||
|
|
||||||
|
var index = 0
|
||||||
|
var deletedIndex: Int?
|
||||||
for entry in self.galleryEntries {
|
for entry in self.galleryEntries {
|
||||||
switch entry {
|
switch entry {
|
||||||
case let .topImage(representations, videoRepresentations, _, _, immediateThumbnailData, _):
|
case let .topImage(representations, videoRepresentations, _, _, immediateThumbnailData, _):
|
||||||
@ -928,9 +932,25 @@ final class PeerInfoAvatarListContainerNode: ASDisplayNode {
|
|||||||
if image.0 != reference {
|
if image.0 != reference {
|
||||||
entries.append(entry)
|
entries.append(entry)
|
||||||
items.append(.image(reference, representations, videoRepresentations, immediateThumbnailData))
|
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.galleryEntries = normalizeEntries(entries)
|
||||||
self.items = items
|
self.items = items
|
||||||
self.itemsUpdated?(items)
|
self.itemsUpdated?(items)
|
||||||
|
@ -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) {
|
private func setMainAvatar(_ item: PeerInfoAvatarListItem) {
|
||||||
if self.data?.peer?.id == self.context.account.peerId {
|
if self.data?.peer?.id == self.context.account.peerId {
|
||||||
if case let .image(reference, _, _, _) = item {
|
if case let .image(reference, _, _, _) = item {
|
||||||
@ -4075,7 +4014,7 @@ private final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewD
|
|||||||
})
|
})
|
||||||
signal = durationSignal.map(toSignal: { duration -> SSignal? in
|
signal = durationSignal.map(toSignal: { duration -> SSignal? in
|
||||||
if let duration = duration as? Double {
|
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 {
|
} else {
|
||||||
return SSignal.single(nil)
|
return SSignal.single(nil)
|
||||||
}
|
}
|
||||||
|
@ -443,7 +443,7 @@ public func legacyEnqueueWebSearchMessages(_ selectionState: TGMediaSelectionCon
|
|||||||
if animated {
|
if animated {
|
||||||
dict["isAnimation"] = true
|
dict["isAnimation"] = true
|
||||||
if let photoEditorValues = adjustments as? PGPhotoEditorValues {
|
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")
|
let filePath = NSTemporaryDirectory().appending("/gifvideo_\(arc4random()).jpg")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user